Вопрос о вызове функции и оценке в C ++ - PullRequest
1 голос
/ 13 мая 2011

Привет, у меня есть, вероятно, простой вопрос о следующей проблеме:

У меня есть функция

double afunction(double *myarray)
{   
    double ret = 1.0;
    for(int i = 0; i < 4; i++)
        ret *= myarray[i]*myarray[i];
    return ret;
}

Теперь я хочу изменить ее, чтобы передать два новыхпараметры: int index описание того, какой индекс myarray изменить, как показано ниже: myarray[ index ] = *add;.Это будет следующим:

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;
}

Проблема в том, что я не хочу изменять массив myrray, а я не хочу создавать новыймассив для этого из-за памяти (это будет позже вычислено на GPU, и там я все равно не смог выделить целый новый массив в функции ядра. Простое решение для этого? Спасибо!

РЕДАКТИРОВАТЬ Извините, я что-то опечатал. Вместо этого myarray[ index ] = *add; Я хотел сказать myarray[ index ] += *add;

EDIT2 Пример более крупной функции, которая впоследствии может быть легко расширена доОколо 50 различных возвращаемых случаев. Так что иметь оператор if для изменения определенного значения myarray[index] с добавлением *add в каждом возвращаемом случае довольно уродливо: (

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;
}

Ответы [ 3 ]

5 голосов
/ 13 мая 2011
double ret = 1.0;
for(int i = 0; i < 4; i++)
    if (index == i)
        ret *= (*add) * (*add);
    else
        ret *= myarray[i]*myarray[i];

или

double ret = (*add) * (*add);
for(int i = 0; i < 4; i++)
    ret *= myarray[i]*myarray[i];

ret /= myarray[index] * myarray[index];

Что не эквивалентно 100%, поскольку вы используете числа с плавающей запятой.

РЕДАКТИРОВАТЬ: Хорошо, увидел, что вы отредактировали оригинальный вопрос. Одна альтернатива, которая может быть приемлемой, состоит в следующем:

myarray[ indexAdd ] -= *add;

после того, как вы закончите с остальными вычислениями. Опять же, нет никакой гарантии, что myarray[indexAdd] вернется к точно это старое значение.

или даже лучше: сохраните старое значение в верхней части функции и затем восстановите его:

float old = myarray[ indexAdd ];
myarray[ indexAdd ] += *add;
//do work
myarray[ indexAdd ] = old;
4 голосов
/ 13 мая 2011
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;
}
2 голосов
/ 13 мая 2011

Существует несколько возможных решений:

Очевидное:

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;
}

Возможно быстрее (нет, если в цикле), но возможно с другими результатами:

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;
}

Я сомневаюсь, стоит ли возиться с этим из-за массива из четырех элементов: четыре if вероятно не дороже, чем окончательный дополнительный расчет.Однако для более длинных массивов, возможно, стоит подумать.

Наконец, больше для справки, поскольку это действительно некрасиво и работает только в однопоточной среде:

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;
}

В зависимости отфактическая оптимизация оборудования и компилятора, это может быть самым быстрым.(Но, опять же, только для четырех элементов это далеко не точно.)

Два других комментария, касающихся кода: если вы не собираетесь изменять array, вам, вероятно, следует передать его как double const*(что исключает последнюю возможность, указанную выше), и, поскольку все, что вы делаете, это читаете одно значение, на самом деле нет смысла передавать add в качестве указателя;в моем коде выше я передал его по значению.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...