Дискретное интегрирование по комплексным числам дает неправильные результаты

#go

#Вперед

Вопрос:

В настоящее время я пытаюсь реализовать дискретное интегрирование по комплексным числам для комплексного преобразования Фурье.
Однако реализация, которую я сделал в go, дает неверный результат.

Вот моя реализация:

 n = input() //It is a function argument
cumulativeValue := 0   0i
currentTime := 0.00
const deltaTime = 0.001
const precision = 0.0001
for cmpFloat(currentTime, 1.00, precision) < 0 {

    currentPoint := findPointForTime(currentTime)
    cumulativeValue  = complex(float64(currentPoint.X), float64(currentPoint.Y)) * cmplx.Exp(complex(0.0, -2.0*math.Pi*float64(n)*currentTime))

    currentTime  = deltaTime
}

cumulativeValue *= deltaTime
  

Этот алгоритм возвращает элемент из ряда Фурье. Но когда я пытаюсь вернуть функцию из серии, она нигде не приближается к исходному вводу.
Я попытался реализовать тот же алгоритм на Python, без преобразований, и он работает безупречно.


Исследование

Сначала я подумал, что проблема связана с findPointForTime функцией, но я уже подтвердил, что это не так.

Затем, во время отладки, я увидел, что первые несколько значений вполне эквивалентны в Python, но не так сильно после 500-го добавления (средний алгоритм).

Тогда проблема может заключаться в том, что либо точность комплексных чисел go недостаточна, либо что cmplx.Exp неверен (что кажется невероятным).

Итак, есть ли способ повысить точность complex128 в go?


TLDR: Проблема может заключаться в точности go с плавающей запятой. Есть ли способ улучшить это?

  • Примечание 1: Как ни странно, код пока работает для одного ввода и ни для какого другого.
  • Примечание 2: Мой код (в значительной степени) вдохновлен кем-то другим, и он сработал в их случае, что наводит меня на мысль, что нет никакой необходимости в других библиотеках, таких как «math / big» (хотя, возможно, стоит попробовать).

Правки

  • Редактировать 1: Интегрирование не зависит от deltaTime, потому что это интервал, по которому я интегрирую (таким образом, это коэффициент мультипликации, и, как константа, он может быть либо внутри подразделения, либо вне цикла), однако это зависит от переменной currentTime.
    В соответствии с тем, как работает сложное преобразование Фурье, интегрирование такоеинтеграл
    , что сначала я получаю значение f (t), затем вычисляю экспоненциальную часть, умножаю их вместе с deltaTime (который я оставил снаружи — в конце цикла) и добавляю их в накопитель. наконец, я повторяю это, пока текущее время меньше 1 секунды. (который, я полагаю, является методом интеграции с лестницами => может быть, трапеции лучше?)
  • Редактировать 2: Я использую сложную систему Python по умолчанию, поэтому я сомневаюсь, что это 128 бит. Код Python выглядит следующим образом:
 currentTime = 0
deltaTime = 0.001
cumulativeValue = complex(0)
while currentTime < 1.0:
    point = getPointforTime(currentTime)
    cumulativeValue  = point * cmath.exp(-2.0j*cmath.pi*n*currentTime)*deltaTime

    currentTime  = deltatime
  

Комментарии:

1. Какую функцию по какому пути вы интегрируете?

2. Я не думаю, что ваш код может быть правильным — термины, которые вы суммируете, должны зависеть от deltaTime. Можете ли вы описать в тексте в вашем вопросе, как вы выполняете интеграцию?

3. Используете ли вы 128-битные значения в коде Python? Если нет, то, скорее всего, у вас другая ошибка в коде go или он отличается от реализации pyton. Может быть, также опубликовать код pyton?

4. @PaulHankin Я отредактировал свой пост, чтобы ответить на ваши комментарии

5. @BurakSerdar Вторая правка отвечает на ваш вопрос