Using function object in stl algorithm - c++

When trying to use a conditional copy_if algorithm to copy only the values that are lower than mean of values in a vector into another vector, I hit a snag with my function object:
struct Lower_than_mean
{
private:
double mean;
vector<double>d1;
public:
Lower_than_mean(vector<double>a)
:d1{a}
{
double sum = accumulate(d1.begin(), d1.end(), 0.0);
mean = sum / (d1.size());
}
bool operator()(double& x)
{
return x < mean;
}
};
int main()
{
vector<double>vd{ 3.4,5.6, 7, 3,4,5.6,9,2 };
vector<double>vd2(vd.size());
copy_if(vd.begin(), vd.end(), vd2, Lower_than_mean(vd));
}
What is the right way of going about this?

You used vd instead of vd.begin() in the call to std::copy_if.
But, seriously, you didn't bother to even read your compiler output...
Also, like #zch suggests - your approach doesn't make sense: Don't keep re-calculating the mean again and again. Instead, calculate it once, and then your function becomes as simple [mean](double x) { return x < mean; } lambda.

Related

forward_list iterators incompatible

I'm trying to complete a program that evaluates polynomials when given an x-value.
The polynomials are stored using the STL's forward_list in objects of the class.
class PolyTerm {
private:
int _order = 0;
double _coeff = 0.0;
public:
PolyTerm() = default;
PolyTerm(int order, double coefficient) : _order(order), _coeff(coefficient) {}
void setOrder(int order) { _order = order; }
void setCoeff(double coeff) { _coeff = coeff; }
int getOrder() const { return _order; }
double getCoeff() const { return _coeff; }
};
My function which takes the object and the x-value is written as follows:
double evaluate(const forward_list<PolyTerm>& terms, double x) {
double answer = 0;
forward_list<PolyTerm>::iterator it;
while (it != terms.end()) {
answer += it->getCoeff() * pow(x, it->getOrder());
it++;
}
return answer;
}
My compiler doesn't show any errors but once I try to run the program, I get a pop-up saying "Debug Assertion Failed!" with Expression: forward_list iterators incompatible
Image of pop-up
I'm pretty sure I declared the iterator to be of the same type as the list holding the polynomial so I'm not sure why I'm getting this error.
Can anyone explain to me what's wrong?
Thanks in advance for any help.
forward_list<PolyTerm>::iterator it; it's not initialized. It must be initialized with the first element of the forward list.
forward_list<PolyTerm>::iterator it = terms.begin();
You may simplify you loop, and you will not use it
for (const auto& term : terms)
answer += term.getCoeff() * pow(x, term.getOrder());
You also could have used std::accumulate, as that will enforce the initialization using the third argument to the function. Also, since there is no need to declare and initialize iterators, there is no chance you will forget to initialize the iterator.
Here is an example. Note that there are no hand-written loops:
#include <numeric>
//...
double evaluate(const forward_list<PolyTerm>& terms, double x)
{
return std::accumulate(terms.begin(), terms.end(), 0.0, // <-- Note the initial value is 0.0 -- you can't miss it
[&](double total, const PolyTerm& p)
{ return total + p.getCoeff() * pow(x, p.getOrder()); });
}
You never initialize it.
You should have used a for loop.
You should have used a C++11 for(auto it: terms) as I think it would go.

C++, different function output when called multiple times

I have the following code:
int countLatticePoints(const double radius, const int dimension) {
static std::vector<int> point {};
static int R = static_cast<int>(std::floor(radius));
static int latticePointCount = 0;
for(int i = -R; i <= R; i++) {
point.push_back(i);
if(point.size() == dimension) {
if(PointIsWithinSphere(point,R)) latticePointCount++;
} else {
countLatticePoints(R, dimension);
}
point.pop_back();
}
return latticePointCount;
}
When I make the call countLatticePoints(2.05, 3) I get the result 13 which is correct. Now I change the parameters and then call countLatticePoints(25.5, 1) I get 51 which is also correct.
Now when I call countLatticePoints(2.05, 3) and countLatticePoints(25.5, 1) right after each other in the main program I get 13 and then 18 (instead of 51), I really don't understand what i'm doing wrong ? When I call each one individually without the other I get the correct result but when I call the functions together one after the other my results change.
You're misusing static.
The second time you call the function, you push additional values into point.
Edit: I hadn't spotted the recursion. that makes things more complex, but static is still the wrong answer.
I'd create a 'state' object, and split the function into two. One that recurses, and takes a reference to the 'state' object, and a second one which initialises the state object and calls the first.
struct RecurState
{
std::vector<int> point;
int latticePointCount
RecurState() : latticePointCount(0)
{
}
}
Outer function:
int countLatticePoints(const double radius, const int dimension)
{
RecurState state;
return countLatticeRecurse(radius, dimension, state)
}
Recursive function
int countLatticeRecurse(const double radius, const int dimension, RecurseState &state)
{
...
}
Local, static variables only get initialized once, on the first function call.

How do I create a function with multiple identifiers?

I want to make a function, and in different contexts it is better called by different names.
class box(){
private:
float posX;
float size = 10;
public:
float speedX;
float left(){ return posX; } //Any way to combine these?
float posX(){ return posX; } //Any way to combine these?
float right(){ return posX + size; }
};
box a;
box b;
bool checkCollide(){
if(a.right() < b.left()){ return 0; } //Not colliding
if(b.right() < a.left()){ return 0; } //Not colliding
return 1; //Colliding
} //Comparing right and left makes more sense than anything else
void physics(){
a.posX() += a.speedX;
b.posX() += b.speedX;
//Adding speed to position makes more sense than
//adding speed to "left"
}
//Loop physics X times per second, and do something if there's a collision
or, is there a better way to do this? Can I make the left/right member automatically update any time the position or size changes, instead of recalculating for every call?
If you are really obliged to do this, then just make the one function call the other:
// the function that does the hard job
float foo(float a, float b)
{
// some heavy and complicated code
// ...
// some more black magic, etc.
// finally:
return sqrt(a * a + b * b);
}
// the function that pretends to do the hard job
float bar(float a, float b)
{
return foo(a, b);
}
But you better not do this, it's quite bad style. Different names => different tasks. Same task => same name. Don't hurt the intuition of your fellows... ;-)
Yes - Not write two functions that at the start do the same thing. I just hope that they do not diverge. Then you have problems!
If you're on C++11, or when using Boost, you can bind the left() function to an std::function variable. With C++11:
class box {
// ...
public:
// ...
float left() { return posX; }
const std::function<float()> posx = std::bind(&box::left, this);
The const is needed, otherwise posx could be changed at runtime to point to a different function.
If you're not using a C++11 compiler but use Boost instead, then it's not that expressive, since you have to initialize posx in the ctor:
class box {
// ...
public:
box() : posx = boost::bind(&box::left, this);
// ...
float left() { return posX; }
const boost::function<float()> posx;
In both cases, you can now do:
box b;
b.left();
b.posx();
This method doesn't really have any advantages I can think of compared to having a posx() function and calling left() in it. But it's possible and so deserves a mention.
But I agree with what H2CO3 said: don't have two names for the same function. It's confusing.

optimize output value using a class and public member

Suppose you have a function, and you call it a lot of times, every time the function return a big object. I've optimized the problem using a functor that return void, and store the returning value in a public member:
#include <vector>
const int N = 100;
std::vector<double> fun(const std::vector<double> & v, const int n)
{
std::vector<double> output = v;
output[n] *= output[n];
return output;
}
class F
{
public:
F() : output(N) {};
std::vector<double> output;
void operator()(const std::vector<double> & v, const int n)
{
output = v;
output[n] *= n;
}
};
int main()
{
std::vector<double> start(N,10.);
std::vector<double> end(N);
double a;
// first solution
for (unsigned long int i = 0; i != 10000000; ++i)
a = fun(start, 2)[3];
// second solution
F f;
for (unsigned long int i = 0; i != 10000000; ++i)
{
f(start, 2);
a = f.output[3];
}
}
Yes, I can use inline or optimize in an other way this problem, but here I want to stress on this problem: with the functor I declare and construct the output variable output only one time, using the function I do that every time it is called. The second solution is two time faster than the first with g++ -O1 or g++ -O2. What do you think about it, is it an ugly optimization?
Edit:
to clarify my aim. I have to evaluate the function >10M times, but I need the output only few random times. It's important that the input is not changed, in fact I declared it as a const reference. In this example the input is always the same, but in real world the input change and it is function of the previous output of the function.
More common scenario is to create object with reserved large enough size outside the function and pass large object to the function by pointer or by reference. You could reuse this object on several calls to your function. Thus you could reduce continual memory allocation.
In both cases you are allocating new vector many many times.
What you should do is to pass both input and output objects to your class/function:
void fun(const std::vector<double> & in, const int n, std::vector<double> & out)
{
out[n] *= in[n];
}
this way you separate your logic from the algorithm. You'll have to create a new std::vector once and pass it to the function as many time as you want. Notice that there's unnecessary no copy/allocation made.
p.s. it's been awhile since I did c++. It may not compile right away.
It's not an ugly optimization. It's actually a fairly decent one.
I would, however, hide output and make an operator[] member to access its members. Why? Because you just might be able to perform a lazy evaluation optimization by moving all the math to that function, thus only doing that math when the client requests that value. Until the user asks for it, why do it if you don't need to?
Edit:
Just checked the standard. Behavior of the assignment operator is based on insert(). Notes for that function state that an allocation occurs if new size exceeds current capacity. Of course this does not seem to explicitly disallow an implementation from reallocating even if otherwise...I'm pretty sure you'll find none that do and I'm sure the standard says something about it somewhere else. Thus you've improved speed by removing allocation calls.
You should still hide the internal vector. You'll have more chance to change implementation if you use encapsulation. You could also return a reference (maybe const) to the vector from the function and retain the original syntax.
I played with this a bit, and came up with the code below. I keep thinking there's a better way to do this, but it's escaping me for now.
The key differences:
I'm allergic to public member variables, so I made output private, and put getters around it.
Having the operator return void isn't necessary for the optimization, so I have it return the value as a const reference so we can preserve return value semantics.
I took a stab at generalizing the approach into a templated base class, so you can then define derived classes for a particular return type, and not re-define the plumbing. This assumes the object you want to create takes a one-arg constructor, and the function you want to call takes in one additional argument. I think you'd have to define other templates if this varies.
Enjoy...
#include <vector>
template<typename T, typename ConstructArg, typename FuncArg>
class ReturnT
{
public:
ReturnT(ConstructArg arg): output(arg){}
virtual ~ReturnT() {}
const T& operator()(const T& in, FuncArg arg)
{
output = in;
this->doOp(arg);
return this->getOutput();
}
const T& getOutput() const {return output;}
protected:
T& getOutput() {return output;}
private:
virtual void doOp(FuncArg arg) = 0;
T output;
};
class F : public ReturnT<std::vector<double>, std::size_t, const int>
{
public:
F(std::size_t size) : ReturnT<std::vector<double>, std::size_t, const int>(size) {}
private:
virtual void doOp(const int n)
{
this->getOutput()[n] *= n;
}
};
int main()
{
const int N = 100;
std::vector<double> start(N,10.);
double a;
// second solution
F f(N);
for (unsigned long int i = 0; i != 10000000; ++i)
{
a = f(start, 2)[3];
}
}
It seems quite strange(I mean the need for optimization at all) - I think that a decent compiler should perform return value optimization in such cases. Maybe all you need is to enable it.

How to convert for loop to STL for_each statement

I would like to convert my for loop to STL std::for_each loop.
bool CMyclass::SomeMember()
{
int ii;
for(int i=0;i<iR20;i++)
{
ii=indexR[i];
ishell=static_cast<int>(R[ii]/xStep);
theta=atan2(data->pPOS[ii*3+1], data->pPOS[ii*3]);
al2[ishell] += massp*cos(fm*theta);
}
}
Actually I was planning to use parallel STL from g++4.4
g++ -D_GLIBCXX_PARALLEL -fopenmp
which is allow to run code in parallel without changes if the code is written in standard STL library.
You need to seperate out the loop body into a seperate function or functor; I've assumed all the undeclared variables are member variables.
void CMyclass::LoopFunc(int ii) {
ishell=static_cast<int>(R[ii]/xStep);
theta=atan2(data->pPOS[ii*3+1],
data->pPOS[ii*3]);
al2[ishell] += massp*cos(fm*theta);
}
bool CMyclass::SomeMember() {
std::for_each(&indexR[0],&indexR[iR20],std::tr1::bind(&CMyclass::LoopFunc,std::tr1::ref(*this));
}
class F {
public:
void operator()(int ii) {
ishell=static_cast<int>(R[ii]/xStep);
theta=atan2(data->pPOS[ii*3+1], data->pPOS[ii*3]);
al2[ishell] += massp*cos(fm*theta);
}
F(int[] r): //and other parameters should also be passed into the constructor
r_(r) {}
void:
int[] r_; // refers to R[ii] array
// and other parameters should also be stored
};
F f(R); // pass other parameters too
for_each(&indexR[0], &indexR[iR20], f);
However it might not be a good idea to use this "automatic parallelization" since you need to keep in mind the grainsize of each parallel computation -- I am not sure how well the compiler takes the grain size into account.
You cannot just separate cycle body into functor and assume that it will be paralellised because you have too many dependencies inside cycle body.
Cycle will be able to run in parallel only if you have no global arrays or pointers. If you provide full function body then we can think how to change it to parallel version.
You'll need to convert the loop body into a function or functor. There are a lot of undeclared variables in there, so I can't easily tell how to separate out the loop body. Here's a stab at it:
class DoStuff
{
int* R;
int xStep;
Data* data;
double massp;
double fm;
double* al2;
public:
DoStuff(int* R_, int xStep_, Data* data_, double massp_, double fm_, double* al2_) :
R(R_), xStep(xStep_), data(data_), massp(massp_), fm(fm_), al2(al2_) {}
void operator()(int ii)
{
int ishell = static_cast<int>(R[ii]/xStep);
double theta = atan2(data->pPOS[ii*3+1], data->pPOS[ii*3]);
al2[ishell] += massp*cos(fm*theta);
}
};
for_each(indexR, indexR+iR20, DoStuff(R, xStep, data, massp, fm, al2));