Numpy - квадратный корень из -1 оставляет небольшую реальную часть
возможно, это алгоритмическая проблема, но следующий кусок кода
numpy.power((-1+0j),0.5)
производит следующий вывод
(6.1230317691118863e-17+1j)
аналогичные выражения, например,numpy.power(complex(-1),.5)
даст тот же результат, однако - numpy.sqrt(complex(-1))
дает ожидаемый результат 1j
. Очевидно, что результат не должен иметь реальной части, поэтому я упускаю что-то важное или мне нужно сообщить об этом numpy dev.
в случае, если кто-нибудь спросит, нет, я не могу круглые прочь реальную часть (мне нужна полная точность для этого расчета), и да, мне нужно использовать функцию питания.
3 ответов
это побочный эффект реализации numpy.power()
для комплексных чисел. Stdlib демонстрирует ту же проблему.
>>> numpy.power(-1+0j, 0.5)
(6.123233995736766e-17+1j)
>>> cmath.exp(cmath.log(-1)/2)
(6.123233995736766e-17+1j)
что происходит, так это то, что квадратный корень из -1 вычисляется как exp (I phase/2), где фаза (из -1)примерно π. На самом деле,
>>> import cmath, math
>>> z = -1+0j
>>> cmath.phase(z)
3.141592653589793
>>> math.cos(_/2)
6.123233995736766e-17
это показывает, что фаза -1 равна π только до нескольких 1e-17; фаза, разделенная на 2, также приблизительно равна π / 2, а ее Косинус-только приблизительно 0, следовательно, ваш результат (реальная часть вашего результата-этот Косинус).
проблема в конечном счете исходит из того, что существует только фиксированное, конечное число чисел с плавающей запятой. Число π не входит в список чисел с плавающей запятой и поэтому может быть представлено только приблизительно. π/2 также не может быть точно представлен, так что действительная часть квадратного корня -1 является Косинусом приближения с плавающей запятой π / 2 (следовательно, Косинус, который отличается от 0).
Итак, приблизительное значение Python для numpy.power(complex(-1), .5)
в конечном счете из-за ограничения чисел с плавающей запятой, и вероятно, можно найти на многих языках.
то, что вы наблюдаете, связано с этим ограничением с плавающей запятой через реализацию мощности числа. В вашем примере квадратный корень вычисляется путем вычисления модуля и аргумента вашего комплексного числа(по существу, через функцию log, которая возвращает log (module) + I phase). С другой стороны,--2--> дает именно 1j
потому что он использует другой метод и не страдает от плавающей точки задача аппроксимации (-1+0j)**0.5
(как полагают TonyK).