开发者

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 ifs 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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜