Почему применять экспоненциальную скользящую среднюю в направлении 0,0 медленнее?

Это мой код:

#include <math.h>
#include <iostream>

using namespace std;

inline void Task(double start, double target) {
double a0 = 0.0101252;
double z = start;

double value = -1.0;
double temp = 0.0;
int counter = 0;
while (value != temp) {
temp = value;

// exponential moving average
z += a0 * (target - z);
value = z;

counter++;
}

cout << "start: " << start << " | target: " << target << " | iterations: " << counter << std::endl;
}

int main()
{
Task(0.0, 0.01);
Task(0.01, 0.0);

Task(0.01, 0.02);
Task(0.02, 0.01);
}

применение Экспоненциальная скользящая средняя от 0,1 до 0,2 (или от 0,2 до 0,1 или от 0,0 до 0,1) дает примерно 3100 итераций:

start: 0 | target: 0.01 | iterations: 3173
start: 0.01 | target: 0.02 | iterations: 3105
start: 0.02 | target: 0.01 | iterations: 3173

Вместо этого, если я перейду к 0.0, это примерно в 25 раз дороже с точки зрения итераций:

start: 0.01 | target: 0 | iterations: 72305

Зачем? Где здесь самая сложная часть? Я не могу понять это. Денормализованные числа?

0

Решение

Значения, представимые в double более плотные около нуля. Вы нарушаете цикл, когда value == temp — по сути, когда вы находитесь так близко к цели, что ошибка округляется при округлении. Это, в свою очередь, фактически означает, что вы требуете гораздо более высокой точности, когда target ближе к нулю, чем когда target имеет большое абсолютное значение.

Вы, вероятно, хотите выбрать более разумную цель точности, чем «последний бит мантиссы».

3

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

Других решений пока нет …

По вопросам рекламы [email protected]