A question about function call and evaluation in C++
Hey there, I have a probably straight-forward question about the following problem:
I have a function
double afunction(double *myarray)
{
double ret = 1.0;
for(int i = 0; i < 4; i++)
ret *= myarray[i]*myarray[i];
return ret;
}
Now I want to modify it so that I pass two new parameters: int index
describing which index of myarray
to change like the fo开发者_如何学运维llowing: myarray[ index ] = *add;
. This would be the following:
double afunction(double *myarray, int index, double *add)
{
myarray[ index ] += *add;
double ret = 1.0;
for(int i = 0; i < 4; i++)
ret *= myarray[i]*myarray[i];
return ret;
}
The problem is: I don't want to modify the array myrray
and I don't want to create a new array for this because of memory-regards (this will later be computed on the GPU and there I couldn't allocate a whole new array in a kernel function anyway.
Easy solution to this?
Thanks!
EDIT
Sorry, I mistyped something. Instead myarray[ index ] = *add;
I meant to say myarray[ index ] += *add;
EDIT2
Example of a bigger function which could later on easily be extended to about 50 different return-cases. So to have the if-statement to modify the certain value myarray[index]
with adding *add
in each return-case is pretty ugly :(
double afunction(double *myarray, int funcIndex, int indexAdd, double *add)
{
myarray[ indexAdd ] += *add;
if(funcIndex >= 1 && funcIndex <= 4)
return myarray[1]*myarray[1]*myarray[2];
switch(funcIndex)
{
case 5:
return sin(myarray[3]) * cos(myarray[1]);
case 6:
double ret = exp(myarray[1]);
for(int i = 1; i < 5; i++)
ret *= (myarray[ i ]-myarray[ 5-i ]);
return ret;
case 7:
double ret = 0.0;
for(int i = 1; i < 10; i++)
ret += myarray[ i ];
return ret;
}
return 0.0;
}
double ret = 1.0;
for(int i = 0; i < 4; i++)
if (index == i)
ret *= (*add) * (*add);
else
ret *= myarray[i]*myarray[i];
or:
double ret = (*add) * (*add);
for(int i = 0; i < 4; i++)
ret *= myarray[i]*myarray[i];
ret /= myarray[index] * myarray[index];
Which isn't 100% equivalent though since you're using floating point numbers.
EDIT: Ok, saw that you edited the original question. One alternative which might be acceptable would be to do:
myarray[ indexAdd ] -= *add;
after you're done with the rest of the calculations. Again there's no guarantee that myarray[indexAdd]
will return to exactly it's old value.
or even better, save the old value at the top of the function and then restore it:
float old = myarray[ indexAdd ];
myarray[ indexAdd ] += *add;
//do work
myarray[ indexAdd ] = old;
double afunction(double *myarray, int index, double *add)
{
double ret = (*add) * (*add);
for(int i = 0; i < 4; i++)
if( i != index )
ret *= myarray[i]*myarray[i];
return ret;
}
There are several possible solutions:
The obvious:
double
aFunction( double* array, int index, double add )
{
double result = 1.0;
for ( int i = 0; i != 4; ++ i ) {
double tmp = array[i];
if ( i == index ) {
tmp += add;
}
result *= tmp * tmp;
}
return result;
}
Possibly quicker (no if in the loop), but with possibly different results:
double
aFunction( double* array, int index, double add )
{
double result = 1.0;
for ( int = 0; i != 4; ++ i ) {
result *= array[i] * array[i];
}
// Since we multiplied by array[i]^2, when we should
// have multipied by (array[i] + add)^2...
result *= 2 * array[index] * add + add * add;
return result;
}
I've my doubts as to whether this one is worth bothering with for an
array of four elements: four if
s are likely no more expensive than the
final additional calculation. For longer arrays, however, it might be
worth considering.
Finally, more for reference, since it is really ugly, and only works in a single threaded environment:
double
aFunction( double* array, int index, double add )
{
array[index] += add;
double result = 1.0;
for ( int i = 0; i != 4; ++ i ) {
result *= array[i] * array[i];
}
array[index] -= add;
return result;
}
Depending on the actual hardware and compiler optimizations, this could be the quickest. (But again, for just four elements, it's far from certain.)
Two other comments concerning the code: if you're not going to modify
array
, you should probably pass it as a double const*
(which
eliminates the last possibility above), and since all you do is read
a single value, there's really no point in passing add
as a pointer;
in my code above, I've passed it by value.
精彩评论