Я относительно новичок в C++, но у меня есть некоторый (недостаточный) опыт кодирования и числовых вычислений.
Я знаю, что этот вопрос время от времени публикуется, как вы интегрируете массив. В MATLAB вы можете заставить свой массив быть функцией (я забыл, как это сделать, но я знаю, что делал это раньше) и отправить его встроенным интеграторам, поэтому мой вопрос заключается в том, как вы делаете это в C++.
У меня есть этот интеграл:
I = integral(A(z)*sin(qz)*dz)
q — просто двойная константа, z — интегрирующая переменная, но A(z) — это массив (с этого момента я буду называть его фактической функцией), который имеет то же количество точек, что и ось z в моем коде. Интегрирующие границы: z[0] и z[nz-1].
Я вычислил этот интеграл, используя правило трапеций, и для оси Z из 5000 точек это занимает 0,06 секунды. Моя проблема в том, что этот расчет происходит примерно 300 * 30 * 20 раз (у меня 3 цикла for), и эти 0,06 секунды очень быстро вырастают до 3 часов симуляции. И все узкое место моего кода — вот эта интеграция (я, очевидно, могу ускорить за счет уменьшения z, но не в этом дело).
Я знаю, что библиотечные функции обычно намного лучше, чем написанные пользователем. Я также знаю, что не могу использовать что-то более простое, как правило Симпсона, потому что подынтегральная функция сильно колеблется, и я хочу избежать собственной реализации какого-то сложного числового алгоритма.
GSL нужна функция в форме:
F = f(двойной х, пустота *параметры)
и я, вероятно, могу использовать адаптивную интеграцию QAWO из gsl, но как мне сделать свою функцию в форме, которая превращает мой массив в функцию?
Я думаю что-то вроде:
F(double z, void *params)
{
std::valarray<double> actualfunction = *(std::valarray<double> *) params;
double dz = *(double *) params; // Pretty sure this is wrong
unsigned int actual_index = z / dz; // crazy assumption (my z[0] was 0)
return actualfunction[actual_index];
}
Возможно ли что-то подобное? Я сомневаюсь, что численный алгоритм будет использовать ту же пространственную разницу, что и фактическая функция, должен ли я тогда как-то выполнять интерполяцию фактической функции или что-то в этом роде?
Есть ли что-то лучше, чем gsl?