Найти - Пользователи
Полная версия: Глюк с комплексными числами
Начало » Python для экспертов » Глюк с комплексными числами
1 2
Jenyay
Пишу сейчас для работы скрипт на питоне, который должен обрабатывать данные. И наткнулся на такой глюк.

Есть кусок кода:

# -*- coding: utf-8 -*-

import cmath
import numpy
import math

count = 64

dt = 25.0e-12
df = 1.0 / (count * dt)

r = 0.85
c = 3.0e8

i = complex (0.0, 1.0)

e =

e_abs =

print e_abs
Смотрим на результат и медленно офигеваем:


[1.0, 1.0, 1.0, 1.0, 0.99999999999999989, 1.0000000000000002, 1.0, 1.0, 1.0, 1.0, 1.4161689365379793e+019, 1.5577858301917772e+019, 1.6994027238455753e+019, 1.8410196174993732e+019, 1.9826365111531713e+019, 2.1242534048069689e+019, 2.265870298460767e+019, 2.4074871921145647e+019, 2.5491040857683628e+019, 2.6907209794221605e+019, 2.8323378730759586e+019, 2.9739547667297563e+019, 3.1155716603835544e+019, 3.257188554037352e+019, 3.3988054476911505e+019, 3.5404223413449486e+019, 3.6820392349987463e+019, 3.8236561286525444e+019, 3.9652730223063425e+019, 4.1068899159601398e+019, 4.2485068096139379e+019, 4.390123703267736e+019, 4.5317405969215341e+019, 4.6733574905753313e+019, 4.8149743842291294e+019, 4.9565912778829275e+019, 5.0982081715367256e+019, 5.2398250651905229e+019, 5.381441958844321e+019, 5.5230588524981191e+019, 5.6646757461519172e+019, 5.8062926398057144e+019, 5.9479095334595125e+019, 6.0895264271133106e+019, 6.2311433207671087e+019, 6.372760214420906e+019, 6.5143771080747041e+019, 6.6559940017285022e+019, 6.7976108953823011e+019, 6.9392277890360992e+019, 7.0808446826898973e+019, 7.2224615763436945e+019, 7.3640784699974926e+019, 7.5056953636512907e+019, 7.6473122573050888e+019, 7.7889291509588869e+019, 7.930546044612685e+019, 8.0721629382664815e+019, 8.2137798319202796e+019, 8.3553967255740776e+019, 8.4970136192278757e+019, 8.6386305128816738e+019, 8.7802474065354719e+019, 8.92186430018927e+019]


Модуль чисто мнимого числа скачком становится вместо 1.0 каким-то здоровенным числом, которое еще линейно растет:



Теперь заменяем модуль cmath на numpy:

# -*- coding: utf-8 -*-

import cmath
import numpy
import math

count = 64

dt = 25.0e-12
df = 1.0 / (count * dt)

r = 0.85
c = 3.0e8

i = complex (0.0, 1.0)

e =

e_abs =
И получаем вполне нормальный результат.




PS. Все это проверял на Python 2.5, WinXP + SP2.

PPS. А как на этом форуме можно раскрасить питоновский код?
bialix
раскрасить: code:python
Jenyay
Спасибо, раскрасил.
bialix
в багтрекере питона не искали упоминание про такой глюк? может он уже известен?
Jenyay
Нет, еще не смотрел. Сегодня вечером поищу. Заодно можно попробовать питон 2.5.1 поставить.
Jenyay
В питоне 2.5.1 ничего не изменилось, и в багтрекере такого бага не нашел. В
bialix
а вы смотрели сами комплексные числа, их значения?
Striver
около 9.3e18 достигается предел точности типа float64:

>>> x1=9.2e18j
>>> x2=9.3e18j
>>> cmath.exp(x1)
(0.8892436064235012+0.45743393887524936j)
>>> cmath.exp(x2)
(9.3e+018+9.3e+018j)

Если посчитать двоичный логарифм от 9.3e18, видно, что используются все 63 разряда плюс 1 на знак:

>>> math.log(9.3e18)/math.log(2)
63.011936424193195

Так что это не глюк, а достижение предела точности. Дальше идет линейная зависимость, т.к. значимым оказывается только первый член ряда Тэйлора при вычислении функции. Видимо, модуль numpy либо использует большую разрядность, либо перед применением numpy.exp делает проверку на x.real==0.

А зачем Вам нужны такие огромные числа?
Jenyay
Сами числа еще не смотрел, пока руки не дошли. Надо будет действительно глянуть что там возвращает numpy. А вообще это для обработки сигналов. Там в формуле частота большая (гигагерцы), да еще и на скорость света умножается.
bialix
согласен про точность. именно это и пришло в голову когда начал смотреть на величину экспоненты.

Jenyay: у вас при вычислении экспоненты там куча констант. Попробуйте их немного переработать, чтобы уменьшить порядок чисел. Все равно на таких частотах единицы Герц никому не интересны.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB