I was trying to use Jacobi elliptical function from mpmath
, but getting the error for the simple code given below:
import numpy as np
import scipy.integrate as spi
from scipy import special as sp
import matplotlib.pyplot as plt
from math import sqrt, pow, log
from mpmath import ellipfun
sn = ellipfun('sn')
y=sn(0.5,-1)
print y
y1=y.real
print y1, np.arcsin(y), np.arcsin(y1)
I am getting the error even when I pass only the real part of the function sn(0.5,-1)
.
I don't know whether I am making a mistake. Kindly help.
Thanks in advance.
y
is an mpc
object, and y.real
is an mpf
object. numpy knows nothing about such objects, so when you call np.arcsin(y)
, the numpy code checks to see if the argument has an arcsin()
method (that is, it looks for y.arcsin()
). If it does, it will call that function to compute the arcsin. The mpc
and mpf
objects do not have such a method, which results in the error that you see. (It would be nice if the error message said something like "numpy does not know how to compute the arcsin of an mpf object".)
Here's the same behavior demonstrated with a different object:
In [10]: class Foo:
...: pass
...:
In [11]: f = Foo()
In [12]: np.arcsin(f)
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-12-aa4b1a80cd4e> in <module>()
----> 1 np.arcsin(f)
AttributeError: Foo instance has no attribute 'arcsin'
As pointed out in a comment by Hannebambel, you could use mpmath.asin
instead of np.arcsin
:
In [6]: import mpmath
In [7]: y = sn(0.5, -1)
In [8]: mpmath.asin(y)
Out[8]: mpc(real='0.52001273608158616', imag='0.0')
To use the numpy arcsin
function, first convert to a plain floating point or complex by passing the mpc
and mpf
objects through the builtin functions complex()
and float()
, respectively:
In [19]: y
Out[19]: mpc(real='0.49689119041931196', imag='0.0')
In [20]: np.arcsin(float(y.real))
Out[20]: 0.52001273608158627
In [21]: np.arcsin(complex(y))
Out[21]: (0.52001273608158616+0j)
Or use math.asin
instead of numpy.arcsin
:
In [25]: import math
In [26]: math.asin(y.real)
Out[26]: 0.5200127360815863