Улучшите время вычисления для математики комплексного числа

Я пытаюсь вычислить комплексные числа для двумерного массива в C ++. Код работает очень медленно, и я сузил основную причину до функции exp (программа запускается быстро, когда я закомментирую эту строку, хотя у меня есть 4 вложенных цикла).

int main() {

typedef vector< complex<double> > complexVect;
typedef vector<double> doubleVect;

const int SIZE = 256;
vector<doubleVect> phi_w(SIZE, doubleVect(SIZE));
vector<complexVect> phi_k(SIZE, complexVect(SIZE));
complex<double> i (0, 1), cmplx (0, 0);
complex<double> temp;
int x, y, t, k, w;
double dk = 2.0*M_PI / (SIZE-1);
double dt = M_PI / (SIZE-1);
int xPos, yPos;
double arg, arg2, arg4;
complex<double> arg3;
double angle;
vector<complexVect> newImg(SIZE, complexVect(SIZE));

for (x = 0; x < SIZE; ++x) {
xPos = -127 + x;
for (y = 0; y < SIZE; ++y) {
yPos = -127 + y;
for (t = 0; t < SIZE; ++t) {
temp = cmplx;
angle = dt * t;
arg = xPos * cos(angle) + yPos * sin(angle);
for (k = 0; k < SIZE; ++k) {
arg2 = -M_PI + dk*k;
arg3 = exp(-i * arg * arg2);
arg4 = abs(arg) * M_PI / (abs(arg) + M_PI);
temp = temp + arg4 * arg3 * phi_k[k][t];
}
}
newImg[y][x] = temp;
}
}
}

Есть ли способ улучшить время вычислений? Я попытался использовать следующую вспомогательную функцию, но она не помогает.

complex<double> complexexp(double arg) {
complex<double> temp (sin(arg), cos(arg));
return temp;
}

Я использую Clang ++ для компиляции моего кода

редактировать: я думаю, что проблема в том, что я пытаюсь вычислить комплексные числа. Было бы быстрее, если бы я просто использовал формулу Эйлера для вычисления действительной и мнимой частей в отдельных массивах и не имел бы дело со сложным классом?

1

Решение

может быть, это будет работать для вас

http://martin.ankerl.com/2007/02/11/optimized-exponential-functions-for-java/

1

Другие решения

Я посмотрел с Callgrind. Единственное незначительное улучшение (~ 1,3% при размере = 50), которое я смог найти, было изменить:

temp = temp + arg4 * arg3 * phi_k[k][t];

в

temp += arg4 * arg3 * phi_k[k][t];
0

Самые дорогие вызовы функций были sin () / cos (). Я подозреваю, что вызов exp () с аргументом комплексного числа вызывает эти функции в фоновом режиме.

Чтобы сохранить точность, функция будет вычисляться очень медленно, и, похоже, не существует способа ее обойти. Тем не менее, вы могли бы обменять точность на точность, что, по-видимому, и сделали бы разработчики игр: грех и cos медленны, есть альтернатива?

0

Вы можете определить номер e в качестве константы и использования std::pow() функция

-1