Существует ли быстрый алгоритм вычисления мощности, кратной половине?

Я пишу программу для решения плоской ограниченной задачи трех тел. Его уравнения ниже. Эта функция вычисляет производные положения и скорости и записывает их в массив.

valarray<double> force(double t, valarray<double> r)
{
valarray<double> f(dim);
valarray<double>r0(r-rb0);
valarray<double>r1(r-rb1);

f[0]=   2 * r[1] + r[2] - (1 - mu)*r0[2]/norm3(r0) - mu*r1[2]/norm3(r1);
f[1]= - 2 * r[0] + r[3] - mu*r0[3]/norm3(r0) - mu*r1[3]/norm3(r1);
f[2] = r[0];
f[3] = r[1];
return f;
}

double norm3(valarray<double> x)
{
return pow(x[2]*x[2]+x[3]*x[3],1.5);
}

Поэтому я должен вычислить квадрат вектора положения и затем увеличить его до степени 3/2. Я думаю, что эти операции занимают большую часть времени вычислений.

Теперь я использую функцию Pow Math.h. Есть ли другой более быстрый алгоритм для вычисления этой мощности? Я пытался использовать быстрый обратный квадратный корень (и нарисуйте это позже), но это дает слишком неточное значение для моих целей и работает дольше (возможно, из-за куба).

Спасибо!

2

Решение

Простым подходом может быть попытка x * sqrt (x), но для уверенности сравните его.

double norm3(valarray<double> x)
{
double result=x[2]*x[2]+x[3]*x[3];
result=result * sqrt(result);
return result;
}
5

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

FSQRT в семействе 15 ч процессор AMD64 занимает 52 такта. Варианты SSE2 принимают 29 для скалярного значения и 38 для упакованной операции. C версия sqrt() вероятно, есть несколько дополнительных инструкций, но я сомневаюсь, что это намного больше.

Если вам нужны относительно точные результаты, я сомневаюсь, что гораздо лучше получить какую-то другую операцию. Скорее всего, все, что производит хорошую точность, включает pow(), exp() а также log()и т. д., займет больше времени.

Тем не менее, запрос в Интернете не побьет ваши собственные критерии. Если это критическая часть вашего кода, попробуйте несколько разных вариантов и посмотрите, что вы получите.

1