Я пытаюсь придумать хороший способ оценить следующую функцию
double foo(std::vector<double> const& x, double c = 0.95)
{
   auto N = x.size(); // Small power of 2 such as 512 or 1024
   double sum = 0;
   for (auto i = 0; i != N; ++i) {
     sum += (x[i] * pow(c, double(i)/N));
   }
   return sum;
}
Две мои основные проблемы с этой наивной реализацией — это производительность и точность.  Поэтому я подозреваю, что самым тривиальным улучшением будет изменение порядка цикла: for (auto i = N-1; i != -1; --i) (-1 зацикливается, это нормально).  Это повышает точность, добавляя сначала меньшие термины.
Хотя это хорошо для точности, это сохраняет проблему производительности pow.  Численно pow(c, double(i)/N) равно pow(c, (i-1)/N) * pow(c, 1/N).  И последнее является константой.  Так что теоретически мы можем заменить pow повторным умножением.  Хотя это хорошо для производительности, это вредит точности — ошибки будут накапливаться.
Я подозреваю, что здесь скрывается значительно лучший алгоритм.  Например, тот факт, что N является степенью двойки, означает, что существует средний член x[N/2], который умножается на sqrt(c).  Это намекает на рекурсивное решение.
В несколько связанном числовом наблюдении это выглядит как умножение сигнала на экспоненту, поэтому я, естественно, думаю: «БПФ, тривиальная свертка = сдвиг, ОБПФ», но это, похоже, не дает реальной выгоды с точки зрения точности или производительности.
Итак, это известная проблема с известными решениями?
                                                                    
                                                                    
                                                                    
expm1кажется важным шагом во избежание потери точности. 10.07.2018x[i] + c^(1/N)*x[i+1]ко всем четнымi, а результат сохранил вx[i]. Затем добавьтеx[i] + c^(2/N) * x[i+2], сохраните вx[i]и так далее. 10.07.2018StDev(x) > Average(x), измеренные образцы непрерывного физического сигнала, поэтому нетривиальная корреляция между соседними значениями (определенно не IID). 10.07.2018