def test_mpArray_init_(self): n = random.randint(1,5000) #x = [random.random() for i in range(n)] #self.assertRaises(TypeError, mpArray.mpArray, x) y = [mpmath.rand() for i in range(n)] arr = mpArray.mpArray(y) self.assertTrue(numpy.all(arr==y)) z = [mpmath.mpc(mpmath.rand(),mpmath.rand()) for i in range(n)] z_real = [zz.real for zz in z] z_imag = [zz.imag for zz in z] arr = mpArray.mpArray(z) self.assertTrue(numpy.all(arr==z)) self.assertTrue(numpy.all(arr.real() == z_real)) self.assertTrue(numpy.all(arr.imag() == z_imag)) start = time.clock() x=[mpmath.mpc('0','0')]*n t1 = time.clock() - start start = time.clock() x=[mpmath.mpc('0','0') for i in range(n)] t2 = time.clock() -start if self.verbose: print("[]*",n,t1,"vs.[for i in range(n)]",n,t2)
def __cubic_roots(self,a,c,d): from mpmath import mpf, mpc, sqrt, cbrt assert(all([isinstance(_,mpf) for _ in [a,c,d]])) Delta = -4 * a * c*c*c - 27 * a*a * d*d self.__Delta = Delta # NOTE: this was the original function used for root finding. # proots, err = polyroots([a,0,c,d],error=True,maxsteps=5000000) # Computation of the cubic roots. u_list = [mpf(1),mpc(-1,sqrt(3))/2,mpc(-1,-sqrt(3))/2] Delta0 = -3 * a * c Delta1 = 27 * a * a * d # Here we have two choices for the value from sqrt, positive or negative. Since C # is used as a denominator below, we pick the choice with the greatest absolute value. # http://en.wikipedia.org/wiki/Cubic_function # This should handle the case g2 = 0 gracefully. C1 = cbrt((Delta1 + sqrt(Delta1 * Delta1 - 4 * Delta0 * Delta0 * Delta0)) / 2) C2 = cbrt((Delta1 - sqrt(Delta1 * Delta1 - 4 * Delta0 * Delta0 * Delta0)) / 2) if abs(C1) > abs(C2): C = C1 else: C = C2 proots = [(-1 / (3 * a)) * (u * C + Delta0 / (u * C)) for u in u_list] # NOTE: we ignore any residual imaginary part that we know must come from numerical artefacts. if Delta < 0: # Sort the roots following the convention: complex with negative imaginary, real, complex with positive imaginary. # Then assign the roots following the P convention (e2 real root, e1 complex with positive imaginary). e3,e2,e1 = sorted(proots,key = lambda c: c.imag) else: # The convention in this case is to sort in descending order. e1,e2,e3 = sorted([_.real for _ in proots],reverse = True) return e1,e2,e3
def e_ratio(a,b,e,x): # Get S bt2 = mp.beta(a,b-1.0) # Beta function bix = mp.betainc(a,b+1.0,0.0,e) # Incomplete Beta function hf = mp.hyp2f1(1.0,a,a+b-1.0,-1.0) # 2F1, Gauss' hypergeometric function hfre = mp.re(hf) Sval = bix - x*bt2*hfre # Get U c1 = mp.mpc(1.0 + a) c2 = mp.mpc(-b) c3 = mp.mpc(1.0) c4 = mp.mpc(2.0 + a) Uval = mp.appellf1(c1,c2,c3,c4,e,-e) Ure = mp.re(Uval) # Get P & Q Pval = mp.hyp2f1(a+1.0,1.0-b,a+2.0,e) # 2F1, Gauss' hypergeometric function Pre = mp.re(Pval) Qval = mp.hyp2f1(a+1.0,2.0-b,a+2.0,e) # 2F1, Gauss' hypergeometric function Qre = mp.re(Qval) # Get T Tval = ( (e**(1.0+a)) / (1.0+a) )*( 3.0*Pre + 2.0*Qre - Ure ) Tval = Tval + 4.0*Sval # Get Rval (ratio) Rval = 0.25*(1.0-e*e)*( (1.0-e)**(1.0-b) )*( e**(1.0-a) )*Tval return Rval
def __compute_roots(self,a,c,d): from mpmath import mpf, mpc, sqrt, cbrt assert(all([isinstance(_,mpf) for _ in [a,c,d]])) Delta = self.__Delta # NOTE: this was the original function used for root finding. # proots, err = polyroots([a,0,c,d],error=True,maxsteps=5000000) # Computation of the cubic roots. # TODO special casing. u_list = [mpf(1),mpc(-1,sqrt(3))/2,mpc(-1,-sqrt(3))/2] Delta0 = -3 * a * c Delta1 = 27 * a * a * d C1 = cbrt((Delta1 + sqrt(Delta1 * Delta1 - 4 * Delta0 * Delta0 * Delta0)) / 2) C2 = cbrt((Delta1 - sqrt(Delta1 * Delta1 - 4 * Delta0 * Delta0 * Delta0)) / 2) if abs(C1) > abs(C2): C = C1 else: C = C2 proots = [(-1 / (3 * a)) * (u * C + Delta0 / (u * C)) for u in u_list] # NOTE: we ignore any residual imaginary part that we know must come from numerical artefacts. if Delta < 0: # Sort the roots following the convention: complex with negative imaginary, real, complex with positive imaginary. # Then assign the roots following the P convention (e2 real root, e1 complex with positive imaginary). e3,e2,e1 = sorted(proots,key = lambda c: c.imag) else: # The convention in this case is to sort in descending order. e1,e2,e3 = sorted([_.real for _ in proots],reverse = True) return e1,e2,e3
def Pprime(self,z): # A+S 18.9. from mpmath import ellipfun, sqrt, cos, sin, mpc, mpf Delta = self.Delta e1, e2, e3 = self.__roots if self.__ng3: z = mpc(0,1) * z if Delta > 0: zs = sqrt(e1 - e3) * z m = (e2 - e3) / (e1 - e3) retval = -2 * sqrt((e1 - e3)**3) * ellipfun('cn',u=zs,m=m) * ellipfun('dn',u=zs,m=m) / (ellipfun('sn',u=zs,m=m)**3) elif Delta < 0: H2 = (sqrt((e2 - e3) * (e2 - e1))).real assert(H2 > 0) m = mpf(1) / mpf(2) - 3 * e2 / (4 * H2) zp = 2 * z * sqrt(H2) retval = -4 * sqrt(H2**3) * ellipfun('sn',u=zp,m=m) * ellipfun('dn',u=zp,m=m) / ((1 - ellipfun('cn',u=zp,m=m))**2) else: g2, g3 = self.__invariants if g2 == 0 and g3 == 0: retval = -2 / (z**3) else: c = e1 / 2 A = sqrt(3 * c) retval = -6 * c * A * cos(A * z) / (sin(A * z))**3 if self.__ng3: return mpc(0,-1) * retval else: return retval
def __compute_periods(self): # A+S 18.9. from mpmath import sqrt, ellipk, mpc, pi, mpf Delta = self.Delta e1, e2, e3 = self.__roots if Delta > 0: m = (e2 - e3) / (e1 - e3) Km = ellipk(m) Kpm = ellipk(1 - m) om = Km / sqrt(e1 - e3) omp = mpc(0,1) * om * Kpm / Km elif Delta < 0: # NOTE: the expression in the sqrt has to be real and positive, as e1 and e3 are # complex conjugate and e2 is real. H2 = (sqrt((e2 - e3) * (e2 - e1))).real assert(H2 > 0) m = mpf(1) / mpf(2) - 3 * e2 / (4 * H2) Km = ellipk(m) Kpm = ellipk(1 - m) om2 = Km / sqrt(H2) om2p = mpc(0,1) * Kpm * om2 / Km om = (om2 - om2p) / 2 omp = (om2 + om2p) / 2 else: g2, g3 = self.__invariants if g2 == 0 and g3 == 0: om = mpf('+inf') omp = mpc(0,'+inf') else: # NOTE: here there is no need for the dichotomy on the sign of g3 because # we are already working in a regime in which g3 >= 0 by definition. c = e1 / 2 om = 1 / sqrt(12 * c) * pi() omp = mpc(0,'+inf') return 2 * om, 2 * omp
def dedekind(tau, floatpre): """ Algorithm 22 (Dedekind eta) Input : tau in the upper half-plane, k in N Output : eta(tau) """ a = 2 * mpmath.pi / mpmath.mpf(24) b = mpmath.exp(mpmath.mpc(0, a)) p = 1 m = 0 while m <= 0.999: n = nearest_integer(tau.real) if n != 0: tau -= n p *= b ** n m = tau.real * tau.real + tau.imag * tau.imag if m <= 0.999: ro = mpmath.sqrt(mpmath.power(tau, -1) * 1j) if ro.real < 0: ro = -ro p = p * ro tau = (-p.real + p.imag * 1j) / m q1 = mpmath.exp(a * tau * 1j) q = q1 ** 24 s = 1 qs = mpmath.mpc(1, 0) qn = 1 des = mpmath.mpf(10) ** (-floatpre) while abs(qs) > des: t = -q * qn * qn * qs qn = qn * q qs = qn * t s += t + qs return p * q1 * s
def QScomplex(val): if QSMODE == MODE_NORM: return complex(val) else: if type(val) is str or type(val) is unicode: if 'nan' in val: return mpmath.mpc(real='nan',imag='nan') real = None imag = None delim = None if '+' in val[1:]: delim = '+' elif '-' in val[1:]: delim = '-' if delim is None: if 'j' in val: imag = val.replace('j','') else: real = val else: index = val[1:].find(delim) + 1 real = val[:index] imag = val[index:].replace('j','') return mpmath.mpc(real=real,imag=imag) else: return mpmath.mpc(val)
def sph_h2n_exact(n, z): """Return the value of h^{(2)}_n computed using the exact formula. The expression used is http://dlmf.nist.gov/10.49.E7 . """ zm = mpmathify(z) s = sum(mpc(0,-1)**(k-n-1)*_a(k, n)/zm**(k+1) for k in xrange(n+1)) return exp(mpc(0,-1)*zm)*s
def sph_i2n_exact(n, z): """Return the value of i^{(2)}_n computed using the exact formula. The expression used is http://dlmf.nist.gov/10.49.E10 . """ zm = mpmathify(z) s1 = sum(mpc(-1,0)**k * _a(k, n)/zm**(k+1) for k in xrange(n+1)) s2 = sum(_a(k, n)/zm**(k+1) for k in xrange(n+1)) return exp(zm)/2 * s1 + mpc(-1,0)**n*exp(-zm)/2 * s2
def testing_kbes(Rt,Xt): [R0,R1,NR]=Rt [X0,X1,NX]=Xt NRr=mpmath.mpf(NR) NXr=mpmath.mpf(NX) for j in range(1,NR): rj=mpmath.mpf(j) R=R0+R1*rj/NRr iR=mpmath.mpc(0,R) for k in range(1,NX): rk=mpmath.mpf(k) x=X0+X1*rk/NXr print "r,x=",R,x if(x>R): print "kbes_asymp=" timeit( "kbes_asymp(R,x)",repeat=1) else: print "kbes_rec=" timeit( "kbes_rec(R,x)",repeat=1) print "mpmath.besselk=" timeit("mpmath.besselk(iR,x)",repeat=1) #print "t1(",R,x,")=",t1 #print "t2(",R,x,")=",t2 if(R<15.0): if(x<0.3 *R): print "Case 1" elif(x<=max(10.0 +1.2*R,2 *R)): print "Case 2" elif(R>20 and x>4 *R): print "Case 3" else: print "Case 4"
def zp(x): """ plasma dispersion function using complementary error function in mpmath library. """ return -mp.sqrt(mp.pi) * mp.exp(-x**2) * mp.erfi(x) + mpc(0, 1) * mp.sqrt(mp.pi) * mp.exp(-x**2)
def P(self,z): # A+S 18.9. from mpmath import sqrt, mpc, sin, ellipfun, mpf Delta = self.Delta e1, e2, e3 = self.__roots if self.__ng3: z = mpc(0,1) * z if Delta > 0: zs = sqrt(e1 - e3) * z m = (e2 - e3) / (e1 - e3) retval = e3 + (e1 - e3) / ellipfun('sn',u=zs,m=m)**2 elif Delta < 0: H2 = (sqrt((e2 - e3) * (e2 - e1))).real assert(H2 > 0) m = mpf(1) / mpf(2) - 3 * e2 / (4 * H2) zp = 2 * z * sqrt(H2) retval = e2 + H2 * (1 + ellipfun('cn',u=zp,m=m)) / (1 - ellipfun('cn',u=zp,m=m)) else: g2, g3 = self.__invariants if g2 == 0 and g3 == 0: retval = 1 / (z**2) else: c = e1 / 2 retval = -c + 3 * c / (sin(sqrt(3 * c) * z))**2 if self.__ng3: return -retval else: return retval
def test_mpArray_toarray(self): n = random.randint(1,5000) input = numpy.random.random(n) + 1.j*numpy.random.random() y = [mpmath.mpc(x.real, x.imag) for x in input] arr = mpArray.mpArray(y) out = arr.toarray() self.assertTrue(numpy.all(out == input))
def BSLaplace(S,K,T,t,r,sig,N,phi): """Solving the Black Scholes PDE in the Laplace domain""" x = ln(S/K) r = mpf(r);sig = mpf(sig);T = mpf(T);t=mpf(t) S = mpf(S);K = mpf(K);x=mpf(x) mu = r - 0.5*(sig**2) tau = T - t c1 = mpf('0.5017') c2 = mpf('0.6407') c3 = mpf('0.6122') c4 = mpc('0','0.2645') ans = 0.0 h = 2*pi/N h = mpf(h) for k in range(N/2): # Use symmetry theta = -pi + (k+0.5)*h z = N/tau*(c1*theta/tan(c2*theta) - c3 + c4*theta) dz = N/tau*(-c1*c2*theta/(sin(c2*theta)**2) + c1/tan(c2*theta)+c4) eps1 = (-mu + sqrt(mu**2 + 2*(sig**2)*(z+r)))/(sig**2) eps2 = (-mu - sqrt(mu**2 + 2*(sig**2)*(z+r)))/(sig**2) b1 = 1/(eps1-eps2)*(eps2/(z+r) + (1 - eps2)/z) b2 = 1/(eps1-eps2)*(eps1/(z+r) + (1 - eps1)/z) ans += exp(z*tau)*bs(x,b1,b2,eps1,eps2,z,r,phi)*dz val = (K*(h/(2j*pi)*ans)).real return 2*val
def getNthPadovanNumber( arg ): n = fadd( real( arg ), 4 ) a = root( fsub( fdiv( 27, 2 ), fdiv( fmul( 3, sqrt( 69 ) ), 2 ) ), 3 ) b = root( fdiv( fadd( 9, sqrt( 69 ) ), 2 ), 3 ) c = fadd( 1, fmul( mpc( 0, 1 ), sqrt( 3 ) ) ) d = fsub( 1, fmul( mpc( 0, 1 ), sqrt( 3 ) ) ) e = power( 3, fdiv( 2, 3 ) ) r = fadd( fdiv( a, 3 ), fdiv( b, e ) ) s = fsub( fmul( fdiv( d, -6 ), a ), fdiv( fmul( c, b ), fmul( 2, e ) ) ) t = fsub( fmul( fdiv( c, -6 ), a ), fdiv( fmul( d, b ), fmul( 2, e ) ) ) return nint( re( fsum( [ fdiv( power( r, n ), fadd( fmul( 2, r ), 3 ) ), fdiv( power( s, n ), fadd( fmul( 2, s ), 3 ) ), fdiv( power( t, n ), fadd( fmul( 2, t ), 3 ) ) ] ) ) )
def test_Matrix01(self): a = mpmath.mpc(mpmath.pi,"0") b = mpmath.mpc("0","1") m = mpArray.mpArray([[a,b],[b,a]]) mat = mpArray.mpMatrix(m) evals, evecs = mat.eigen(False, 'qeispack', verbose=True) self.assertTrue(mpmath.fabs(mpmath.mpc(mpmath.pi,"1") - evals[0]) < 1e-32) self.assertTrue(mpmath.fabs(mpmath.mpc(mpmath.pi,"-1") - evals[1]) < 1e-32) self.assertTrue(numpy.all([mpmath.fabs(mpmath.mpf(1)/mpmath.sqrt("2") - mpmath.fabs(x)) < 1e-32 for x in evecs[0]])) self.assertTrue(numpy.all([mpmath.fabs(mpmath.mpf(1)/mpmath.sqrt("2") - mpmath.fabs(x)) < 1e-32 for x in evecs[1]])) self.assertTrue(mpmath.fabs(mpmath.fsum(evecs[0]*evecs[0].conj())) - mpmath.mpf(1) < 1e-32) self.assertTrue(numpy.all([vec.abs2() -mpmath.mpf(1) < 1e-32 for vec in evecs])) self.assertTrue(mpmath.fabs(evecs[0].inner(evecs[1])) < 1e-32)
def __new__(cls, input=[], dtype='object'): if isinstance(input, int): data = [mpmath.mpc('0','0')]*input obj = numpy.asarray(data, dtype='object').view(cls) else: obj = numpy.asarray(input, dtype=dtype).view(cls) return obj
def Pinv(self,P): from mpmath import ellipf, sqrt, asin, acos, mpc, mpf Delta = self.Delta e1, e2, e3 = self.__roots if self.__ng3: P = -P if Delta > 0: m = (e2 - e3) / (e1 - e3) retval = (1 / sqrt(e1 - e3)) * ellipf(asin(sqrt((e1 - e3)/(P - e3))),m=m) elif Delta < 0: H2 = (sqrt((e2 - e3) * (e2 - e1))).real assert(H2 > 0) m = mpf(1) / mpf(2) - 3 * e2 / (4 * H2) retval = 1 / (2 * sqrt(H2)) * ellipf(acos((e2-P+H2)/(e2-P-H2)),m=m) else: g2, g3 = self.__invariants if g2 == 0 and g3 == 0: retval = 1 / sqrt(P) else: c = e1 / 2 retval = (1 / sqrt(3 * c)) * asin(sqrt((3 * c)/(P + c))) if self.__ng3: retval /= mpc(0,1) alpha, beta, _, _ = self.reduce_to_fpp(retval) T1, T2 = self.periods return T1 * alpha + T2 * beta
def find_Y_and_M(G,R,ndigs=12,Yset=None,Mset=None): r""" Compute a good value of M and Y for Maass forms on G INPUT: - ''G'' -- group - ''R'' -- real - ''ndigs'' -- integer (number of desired digits of precision) - ''Yset'' -- real (default None) if set we return M corr. to this Y - ''Mset'' -- integer (default None) if set we return Y corr. to this M OUTPUT: - [Y,M] -- good values of Y (real) and M (integer) EXAMPLES:: TODO: Better and more effective bound """ l=G._level if(Mset <> None): # then we get Y corr. to this M Y0=mpmath.sqrt(3.0)/mpmath.mpf(2*l) if(Yset==None): Y0=mpmath.sqrt(3.0)/mpmath.mpf(2*l) Y=mpmath.mpf(0.95*Y0) else: Y=Yset #print "Y=",Y,"Yset=",Yset IR=mpmath.mpc(0,R) eps=mpmath.mpf(10 **-ndigs) twopiY=mpmath.pi()*Y*mpmath.mpf(2) M0=get_M_for_maass(R,Y,eps) if(M0<10): M0=10 ## Do this in low precision dold=mpmath.mp.dps #print "Start M=",M0 #print "dold=",dold #mpmath.mp.dps=100 try: for n in range(M0,10000 ): X=mpmath.pi()*Y*mpmath.mpf(2 *n) #print "X,IR=",X,IR test=mpmath.fp.besselk(IR,X) if(abs(test)<eps): raise StopIteration() except StopIteration: M=n else: M=n raise Exception,"Error: Did not get small enough error:=M=%s gave err=%s" % (M,test) mpmath.mp.dps=dold return [Y,M]
def check(self): np.random.seed(1234) num_args = len(self.arg_spec) # Generate values for the arguments ms = np.asarray([1.5 if isinstance(arg, ComplexArg) else 1.0 for arg in self.arg_spec]) ms = (self.n**(ms/sum(ms))).astype(int) + 1 argvals = [] for arg, m in zip(self.arg_spec, ms): argvals.append(arg.values(m)) argarr = np.array(np.broadcast_arrays(*np.ix_(*argvals))).reshape(num_args, -1).T # Check old_dps, old_prec = mpmath.mp.dps, mpmath.mp.prec try: if self.dps is not None: dps_list = [self.dps] else: dps_list = [20] if self.prec is not None: mpmath.mp.prec = self.prec # Proper casting of mpmath input and output types. Using # native mpmath types as inputs gives improved precision # in some cases. if np.issubdtype(argarr.dtype, np.complexfloating): pytype = complex mptype = lambda x: mpmath.mpc(complex(x)) else: mptype = lambda x: mpmath.mpf(float(x)) def pytype(x): if abs(x.imag) > 1e-16*(1 + abs(x.real)): return np.nan else: return float(x.real) # Try out different dps until one (or none) works for j, dps in enumerate(dps_list): mpmath.mp.dps = dps try: assert_func_equal(self.scipy_func, lambda *a: pytype(self.mpmath_func(*map(mptype, a))), argarr, vectorized=False, rtol=self.rtol, atol=self.atol, ignore_inf_sign=self.ignore_inf_sign, nan_ok=True) break except AssertionError: if j >= len(dps_list)-1: reraise(*sys.exc_info()) finally: mpmath.mp.dps, mpmath.mp.prec = old_dps, old_prec
def mk_mpc(self, x, y): from mpmath import mp, mpc from mpmath import mpmathify as mpify mp.dps = int(self.prec) return mpc( real = mpify(x), imag = mpify(y) )
def QStrace(mat): if QSMODE == MODE_NORM: return np.trace(mat) else: t = mpmath.mpc(0.0) for i in range(mat.rows): t += mat[i,i] return t
def __compute_user_periods(self): from mpmath import mpc Delta = self.__Delta # NOTE: here there is no need to handle Delta == 0 separately, # as it falls under the case of om purely real and omp purely imaginary. if Delta >= 0: T1, T3 = self.__periods if self.__ng3: return T3.imag, T1.real * mpc(0,1) else: return T1, T3 else: T1, T3 = (sum(self.__periods)).real, self.__periods[1] if self.__ng3: return 2 * T3.imag, mpc(-T3.imag,T3.real) else: return T1, T3
def __new__(cls, input, dtype='object'): if isinstance(input, int): data = [[mpmath.mpc("0","0")]*input]*input obj = numpy.asarray(data, dtype=object).view(cls) else: obj = numpy.asarray(input, dtype=dtype).view(cls) if len(obj.shape) != 2 and obj.shape[0] != obj.shape[1]: raise TypeError("excepted: n by n matrix, but input data shape",obj.shape ) return obj
def test_mpArray_div(self): n = random.randint(1,5000) x1 = [mpmath.mpc(mpmath.rand(), mpmath.rand()) for i in range(n)] x2 = [mpmath.mpc(mpmath.rand(), mpmath.rand()) for i in range(n)] arr1 = mpArray.mpArray(x1) arr2 = mpArray.mpArray(x2) start = time.clock() x3 = [x1[i] / x2[i] for i in range(n)] t1 = time.clock() - start start = time.clock() arr3 = arr1 / arr2 t2 = time.clock() -start self.assertTrue(numpy.all(x3==arr3)) if self.verbose: print("-----------------------") print("number of ",n,"data mul(list) time:", t1) print("number of ",n,"data mul(mpArray) time:", t2)
def _eval_evalf(self, prec): """Evaluate this complex root to the given precision. """ with workprec(prec): g = self.poly.gen if not g.is_Symbol: d = Dummy('x') func = lambdify(d, self.expr.subs(g, d)) else: func = lambdify(g, self.expr) interval = self._get_interval() if not self.is_real: # For complex intervals, we need to keep refining until the # imaginary interval is disjunct with other roots, that is, # until both ends get refined. ay = interval.ay by = interval.by while interval.ay == ay or interval.by == by: interval = interval.refine() while True: if self.is_real: x0 = mpf(str(interval.center)) else: x0 = mpc(*map(str, interval.center)) try: root = findroot(func, x0, verify=False) # If the (real or complex) root is not in the 'interval', # then keep refining the interval. This happens if findroot # accidentally finds a different root outside of this # interval because our initial estimate 'x0' was not close # enough. if self.is_real: a = mpf(str(interval.a)) b = mpf(str(interval.b)) if a == b: root = a break if not (a < root < b): raise ValueError("Root not in the interval.") else: ax = mpf(str(interval.ax)) bx = mpf(str(interval.bx)) ay = mpf(str(interval.ay)) by = mpf(str(interval.by)) if ax == bx and ay == by: root = ax + S.ImaginaryUnit*by break if not (ax < root.real < bx and ay < root.imag < by): raise ValueError("Root not in the interval.") except ValueError: interval = interval.refine() continue else: break return Float._new(root.real._mpf_, prec) + I*Float._new(root.imag._mpf_, prec)
def zk(z, k): """ modified dispersion function for Kappa distribution. (Mace and Hellberg, 1995) """ i = mp.mpc(0, 1) coeff = i * (k + 0.5) * (k-0.5) / (mp.sqrt(k**3) * (k+1)) return coeff * hyp2f1(1, 2*k+2, k+2, (1-z/(i * mp.sqrt(k)))/2)
def _eval_evalf(self, prec): """Evaluate this complex root to the given precision.""" with workprec(prec): g = self.poly.gen if not g.is_Symbol: d = Dummy('x') func = lambdify(d, self.expr.subs({g: d}), "mpmath") else: func = lambdify(g, self.expr, "mpmath") try: interval = self.interval except DomainError: return super()._eval_evalf(prec) while True: if self.is_extended_real: a = mpf(str(interval.a)) b = mpf(str(interval.b)) if a == b: root = a break x0 = mpf(str(interval.center)) else: ax = mpf(str(interval.ax)) bx = mpf(str(interval.bx)) ay = mpf(str(interval.ay)) by = mpf(str(interval.by)) x0 = mpc(*map(str, interval.center)) if ax == bx and ay == by: root = x0 break try: root = findroot(func, x0) # If the (real or complex) root is not in the 'interval', # then keep refining the interval. This happens if findroot # accidentally finds a different root outside of this # interval because our initial estimate 'x0' was not close # enough. It is also possible that the secant method will # get trapped by a max/min in the interval; the root # verification by findroot will raise a ValueError in this # case and the interval will then be tightened -- and # eventually the root will be found. if self.is_extended_real: if (a <= root <= b): break elif (ax <= root.real <= bx and ay <= root.imag <= by and (interval.ay > 0 or interval.by < 0)): break except (ValueError, UnboundLocalError): pass self.refine() interval = self.interval return ((Float._new(root.real._mpf_, prec) if not self.is_imaginary else 0) + I*Float._new(root.imag._mpf_, prec))
def zr_mp(self, wc, l, tc): """ Return receiver impedance, assume mainly due to base capacitance. The antenna monopole length 45m is hardwired in. """ ldc = self.ant_len/l nc = permittivity * boltzmann * tc/ ldc**2 / echarge**2 wpc = mp.sqrt( nc * echarge**2 / emass / permittivity) return mp.mpc(0, 1/(wc * wpc * self.base_cap))
def test_sympify_mpmath(): value = sympify(mpmath.mpf(1.0)) assert value == Float(1.0) and type(value) is Float mpmath.mp.dps = 12 assert sympify(mpmath.pi).epsilon_eq(Float("3.14159265359"), Float("1e-12")) == True assert sympify(mpmath.pi).epsilon_eq(Float("3.14159265359"), Float("1e-13")) == False mpmath.mp.dps = 6 assert sympify(mpmath.pi).epsilon_eq(Float("3.14159"), Float("1e-5")) == True assert sympify(mpmath.pi).epsilon_eq(Float("3.14159"), Float("1e-6")) == False assert sympify(mpmath.mpc(1.0 + 2.0j)) == Float(1.0) + Float(2.0) * I assert sympify(mpq(1, 2)) == S.Half
def compute_value(symdict, replaced, reduced, factor): # determine the precision for floating point arithmetic mp.dps = factor * precision # substitute unique random number for each free symbol in symdict # into every common subexpression from CSE and into main expression for var, subexpr in replaced: for symbol in subexpr.free_symbols: subexpr = subexpr.subs(symbol, symdict[symbol]) if subexpr.atoms(sp.pi): subexpr = subexpr.subs(sp.pi, mp.pi) symdict[var] = subexpr reduced = reduced[0] for symbol in reduced.free_symbols: reduced = reduced.subs(symbol, symdict[symbol]) if reduced.atoms(sp.pi): reduced = reduced.subs(sp.pi, mp.pi) reduced = reduced.subs(sp.Function('NRPyAbs'), sp.Abs) value = mpc(sp.N(reduced)) if isinstance(reduced, complex) else mpf(reduced) mp.dps = precision return value
def ln_sigma(self, u): from mpmath import mpc, pi # TODO: test for pathological cases? om1, om3 = self.periods[0] / 2, self.periods[1] / 2 if not (u.imag >= 0 and u.imag < 2 * om3.imag): raise ValueError('invalid input for ln_sigma') further_reduction = False # This is used to further reduce, via the properties # of homogeneity, the computation to a value farther # from the limit where the expansion starts diverging. if u.imag / (2 * om3.imag) > .5: further_reduction = True u = -u + 2 * om1 + 2 * om3 u_F, N = weierstrass_elliptic.__reduce_to_frp(u, om1) eta1 = self.zeta(om1) retval = self.__ln_expansion( u_F) + 2 * N * eta1 * (u_F + N * om1) - mpc(0, 1) * N * pi() if further_reduction: retval -= (u - om1 - om3) * (2 * eta1 + 2 * self.zeta(om3)) return retval
def Hypergeometric1F1(a, b, t, N): # Initiate the stepsize h = 2 * pi / N c1 = mpf('0.5017') c2 = mpf('0.6407') c3 = mpf('0.6122') c4 = mpc('0', '0.2645') # The for loop is evaluating the Laplace inversion at each point theta # which is based on the trapezoidal rule ans = 0.0 for k in range(N): theta = -pi + (k + 0.5) * h z = N / t * (c1 * theta / tan(c2 * theta) - c3 + c4 * theta) dz = N / t * (-c1 * c2 * theta / sin(c2 * theta)**2 + c1 / tan(c2 * theta) + c4) ans += exp(z * t) * F(a, b, t, z) * dz return gamma(b) * t**(1 - b) * exp(t) * ((h / (2j * pi)) * ans)
def get_punctured_torus(precision=15): mp.dps = precision roots = [ (mpf("inf"), mpf(-1)), (mpf(-1), mpf(0)), (mpf(0), mpf(1)), (mpf("inf"), mpf(1)), ] bounds = [Geodesic(x[0], x[1]) for x in roots] torus_fundamental_domain = Domain(bounds) return { "fundamental_domain": torus_fundamental_domain, "initial_point": mpc(-1, 1) / mpf(2), "mobius_transformations": { "a": np.array([[mpf(1), mpf(1)], [mpf(1), mpf(2)]]), "b": np.array([[mpf(1), mpf(-1)], [mpf(-1), mpf(2)]]), "A": np.array([[mpf(2), mpf(-1)], [mpf(-1), mpf(1)]]), "B": np.array([[mpf(2), mpf(1)], [mpf(1), mpf(1)]]), }, }
def test_poly(): output("""\ poly_:{ r:{$[prec>=abs(x:reim x)1;x 0;x]} each .qml.poly x; r iasc {x:reim x;(abs x 1;neg x 1;x 0)} each r};""") for A in poly_subjects: A = sp.Poly(A, sp.Symbol("x")) if A.degree() <= 3 and all(a.is_real for a in A.all_coeffs()): R = [] for r in sp.roots(A, multiple=True): r = sp.simplify(sp.expand_complex(r)) R.append(r) R.sort(key=lambda x: (abs(sp.im(x)), -sp.im(x), sp.re(x))) else: R = mp.polyroots([ mp.mpc(*(a.evalf(mp.mp.dps)).as_real_imag()) for a in A.all_coeffs() ]) R.sort(key=lambda x: (abs(x.imag), -x.imag, x.real)) assert len(R) == A.degree() test("poly_", A.all_coeffs(), R, complex_pair=True)
def solve_single_eq_single_var( eq, var=None, precision=None, logger_name='loom', ): """ Use sage to solve a single polynomial equation in a single variable. """ logger = logging.getLogger(logger_name) sols = [] if precision is not None: mpmath.mp.dps = precision else: precision = 15 if var is None: raise Exception('Must specify variable for solving the equation.') else: try: rv_str = subprocess.check_output([ sage_bin_path, sage_script_dir + 'solve_single_eq_single_var.sage' ] + [str(precision), str(eq), var]) except (KeyboardInterrupt, SystemExit): raise rv = eval(rv_str) sols_str_list, mult_str_list, messages = rv for msg in messages: logger.warning(msg) for i, sols_str in enumerate(sols_str_list): (z_re, z_im) = sols_str for j in range(mult_str_list[i]): sols.append(mpmath.mpc(z_re, z_im)) return sols
def num_str_pair(val, sig_digits=15, strip_zeros=False, min_fixed=-3, max_fixed=3, show_zero_exponent=False, ztol=None): val2 = mpmath.mpc(val) real_str = mpmath.nstr(val2.real, sig_digits, strip_zeros=strip_zeros, min_fixed=min_fixed, max_fixed=max_fixed, show_zero_exponent=show_zero_exponent) real_str = _check_ztol(val2.real, real_str, ztol) imag_str = mpmath.nstr(val2.imag, sig_digits, strip_zeros=strip_zeros, min_fixed=min_fixed, max_fixed=max_fixed, show_zero_exponent=show_zero_exponent) imag_str = _check_ztol(val2.imag, imag_str, ztol) return real_str, imag_str
def __pow__(self, power, modulo=constants.p): """ Complex modular exponentiation :param base: The base (as a complex number) :param exponent: The exponent :return: base^exponent, performing the calculations mod p """ if power == constants.p: # This is the same as a negation (i.e. conjugate) new_imag = -self.imag % constants.p return FieldElement(self.real, new_imag) if modulo == 1: return 0 result = mpmath.mpc(1, 0) base_var = self while power > 0: # check if exponent is odd if power & 1: result = (base_var * result) % modulo power >>= 1 base_var = base_var * base_var base_var %= modulo return result
def get_test_data_nlist(self, z_record, output_dps, n, func): isNeedMoreDPS = False x = str(z_record[0]) mr = str(z_record[1][0]) mi = str(z_record[1][1]) z_str = '' try: mpf_x = mp.mpf(x) mpf_m = mp.mpc(mr, mi) z = mpf_x * mpf_m if self.is_only_x: z = mp.mpf(x) if self.is_xm: mpf_value = func(n, mpf_x, mpf_m) else: mpf_value = func(n, z) z_str = self.compose_result_string(mpf_x, mpf_m, n, mpf_value, output_dps) if mp.nstr(mpf_value.real, output_dps) == '0.0' \ or mp.nstr(mpf_value.imag, output_dps) == '0.0': isNeedMoreDPS = True except: isNeedMoreDPS = True return z_str, isNeedMoreDPS
def main(): print("Executing mandelbrot_orbit version %s." % __version__) print("List of argument strings: %s" % sys.argv[1:]) zx = sys.argv[1] zy = sys.argv[2] num_iterations = int(sys.argv[3]) filepath = sys.argv[4] print("Generation of orbit for point (", zx, " , ", zy, ") with ", num_iterations, " iterations ...") # Calculate orbit c = mpmath.mpc(real=zx, imag=zy) orbit_re, orbit_im = OrbitCalculator.generate(c, num_iterations) # Format data for plot x = range(num_iterations) orbit_re_float = list(map(float, orbit_re)) orbit_im_float = list(map(float, orbit_im)) # Plot real and imaginary parts plt.plot(x, orbit_re_float, color="orange", linewidth=1.5) plt.plot(x, orbit_im_float, color="blue", linewidth=1.5) # Show grid plt.grid(True) # Image size plt.gcf().set_size_inches(12, 4) # x axis plt.xlim([0, 100]) # Save image plt.savefig(filepath, bbox_inches="tight")
def zeta(self, z): # A+S 18.10. from mpmath import pi, jtheta, exp, mpc, cot, sqrt Delta = self.Delta e1, _, _ = self.__roots om = self.__periods[0] / 2 omp = self.__periods[1] / 2 if self.__ng3: z = mpc(0, 1) * z if Delta > 0: tau = omp / om # NOTE: here q has to be real. q = (exp(mpc(0, 1) * pi() * tau)).real eta = -(pi()**2 * jtheta(n=1, z=0, q=q, derivative=3)) / ( 12 * om * jtheta(n=1, z=0, q=q, derivative=1)) v = (pi() * z) / (2 * om) retval = (eta * z) / om + (pi() * jtheta(n=1, z=v, q=q, derivative=1)) / ( 2 * om * jtheta(n=1, z=v, q=q)) elif Delta < 0: om2 = om + omp om2p = omp - om tau2 = om2p / (2 * om2) # NOTE: here q will be pure imaginary. q = mpc(0, (mpc(0, 1) * exp(mpc(0, 1) * pi() * tau2)).imag) eta2 = -(pi()**2 * jtheta(n=1, z=0, q=q, derivative=3)) / ( 12 * om2 * jtheta(n=1, z=0, q=q, derivative=1)) v = (pi() * z) / (2 * om2) retval = (eta2 * z) / om2 + (pi() * jtheta( n=1, z=v, q=q, derivative=1)) / (2 * om2 * jtheta(n=1, z=v, q=q)) else: g2, g3 = self.__invariants if g2 == 0 and g3 == 0: retval = 1 / z else: c = e1 / 2 A = sqrt(3 * c) retval = c * z + A * cot(A * z) if self.__ng3: return mpc(0, 1) * retval else: return retval
def sigma(self, z): # A+S 18.10. from mpmath import pi, jtheta, exp, mpc, sqrt, sin Delta = self.Delta e1, _, _ = self.__roots om = self.__periods[0] / 2 omp = self.__periods[1] / 2 if self.__ng3: z = mpc(0, 1) * z if Delta > 0: tau = omp / om q = (exp(mpc(0, 1) * pi() * tau)).real eta = -(pi()**2 * jtheta(n=1, z=0, q=q, derivative=3)) / ( 12 * om * jtheta(n=1, z=0, q=q, derivative=1)) v = (pi() * z) / (2 * om) retval = (2 * om) / pi() * exp((eta * z**2) / (2 * om)) * jtheta( n=1, z=v, q=q) / jtheta(n=1, z=0, q=q, derivative=1) elif Delta < 0: om2 = om + omp om2p = omp - om tau2 = om2p / (2 * om2) q = mpc(0, (mpc(0, 1) * exp(mpc(0, 1) * pi() * tau2)).imag) eta2 = -(pi()**2 * jtheta(n=1, z=0, q=q, derivative=3)) / ( 12 * om2 * jtheta(n=1, z=0, q=q, derivative=1)) v = (pi() * z) / (2 * om2) retval = (2 * om2) / pi() * exp( (eta2 * z**2) / (2 * om2)) * jtheta(n=1, z=v, q=q) / jtheta( n=1, z=0, q=q, derivative=1) else: g2, g3 = self.__invariants if g2 == 0 and g3 == 0: retval = z else: c = e1 / 2 A = sqrt(3 * c) retval = (1 / A) * sin(A * z) * exp((c * z**2) / 2) if self.__ng3: return mpc(0, -1) * retval else: return retval
def put_price_calc(given, op): #Option data K = given[0] #Strike R = given[1] #Risk free rate of return (in %) T = given[2] #Time to expiry y = given[3] #Annual dividend yield S0 = given[4] #Stock price #Parameters over which data is being optimized sigma = op[0] #Log return diffusion lemu = op[1] #Arrival rate of up jumps lemd = op[2] #Arrival rate of down jumps etau = op[3] #Strength of up jump etad = op[4] #Strength of down jump k = math.log(K) #Log of strike rate r = R / 100 #Risk free rate of return mu = r - y - lemu / (etau - 1) + lemd / ( etad + 1) #Mu for the given data and parameters #Risk neutral probability of finishing in the money pi2 = 0.5 + mp.fdiv(1, mp.pi) * mp.quad( lambda u: mp.re( mp.fdiv( mp.exp(-mp.mpc(0, 1) * u * k) * char_fun( u, mu, sigma, lemu, lemd, etau, etad, T, S0), mp.mpc(0, 1) * u)), [0, mp.inf]) #Delta of the option pi1 = 0.5 + mp.fdiv(1, mp.pi) * mp.quad( lambda u: mp.re( mp.fdiv( mp.exp(-mp.mpc(0, 1) * u * k) * char_fun( u - mp.mpc(0, 1), mu, sigma, lemu, lemd, etau, etad, T, S0), mp.mpc(0, 1) * u * char_fun(-mp.mpc(0, 1), mu, sigma, lemu, lemd, etau, etad, T, S0))), [0, mp.inf]) #Price of the put option P_alternate = K * mp.exp(-r * T) * (1 - pi2) - S0 * mp.exp( -y * T) * (1 - pi1) return P_alternate
def mp_fft(v, inv_fft=False): n = v.shape[0] if n == 1: return v if np.log2(n) % 1 > 0: raise ValueError("size of b must be a power of 2") # inverse op changes this sign, and scaling at the end s_pi = mp.pi * mp.mpc(1j) if not inv_fft: s_pi = -s_pi m = np.array([[mp.mpc(1), mp.mpc(1)], [mp.mpc(1), mp.mpc(-1)]]) m = m.dot(v.reshape((2, -1))) # build-up each level of the recursive calculation all at once while m.shape[0] < n: m_even = m[:, :m.shape[1] / 2] m_odd = m[:, m.shape[1] / 2:] l = m.shape[0] w = mp.exp(s_pi / mp.mpf(l)) a = np.empty(l, dtype=mp.mpc) x = mp.mpc(1) for i in range(l - 1): a[i] = x x *= w a[l - 1] = x a = a[:, None] m = np.vstack([m_even + a * m_odd, m_even - a * m_odd]) # scale the result if inverse if inv_fft: m /= mp.mpf(n) return m.ravel()
mpmath.mpf.shape = () mpmath.mpc.shape = () # Observe that our E7-definitions have 'numerically exact' structure constants. # # So, it actually makes sense to take these as defined, and lift them to mpmath. # # >>> set(e7.t_a_ij_kl.reshape(-1)) # >>> {(-2+0j), (-1+0j), -2j, -1j, 0j, 1j, 2j, (1+0j), (2+0j)} # `mpmath` does not work with numpy.einsum(), so for that reason alone, # we use opt_einsum's generic-no-backend alternative implementation. mpmath_scalar_manifold_evaluator = scalar_sector.get_scalar_manifold_evaluator( frac=lambda p, q: mpmath.mpf(p) / mpmath.mpf(q), to_scaled_constant=( lambda x, scale=1: numpy.array( x, dtype=mpmath.ctx_mp_python.mpc) * scale), # Wrapping up `expm` is somewhat tricky here, as it returns a mpmath # matrix-type that numpy does not understand. expm=lambda m: numpy.array(mpmath.expm(m).tolist()), einsum=lambda spec, *arrs: opt_einsum.contract(spec, *arrs), # trace can stay as-is. eye=lambda n: numpy.eye(n) + mpmath.mpc(0), complexify=lambda a: a + mpmath.mpc(0), # re/im are again tricky, since numpy.array(dtype=object) # does not forward .real / .imag to the contained objects. re=lambda a: numpy.array([z.real for z in a.reshape(-1)]).reshape(a.shape), im=lambda a: numpy.array([z.imag for z in a.reshape(-1)]).reshape(a.shape))
def complex(val): if mode == mode_python: return builtins.complex(val) else: return mpmath.mpc(mpmath.mpmathify(val))
def make_fp(x): if isinstance(x,complex): return mpc(x) if isinstance(x,mpc): return x return mpf(x)
from mpmath import mpf, mp, mpc from UnitTesting.standard_constants import precision mp.dps = precision trusted_values_dict = {} # Generated on: 2019-08-09 trusted_values_dict[ 'WeylScalars_Cartesian__WeylScalars_Cartesian__globals'] = { 'psi4r': mpc(real='6.71936568881256768293042114237323', imag='3.50716640525663647665055577817839'), 'psi4i': mpc(real='-11.7102358497456435770800453610718', imag='-2.61371968686489353217439202126116'), 'psi3r': mpc(real='0.884973387269943123634163839597022', imag='0.205327296474456050257018091542704'), 'psi3i': mpc(real='-3.16957376509790744734118561609648', imag='6.88196288136694445114471818669699'), 'psi2r': mpf('1.76923151768067781302894394962632'), 'psi2i': mpc(real='0.0', imag='3.6603433359376409406138463964453'), 'psi1r': mpc(real='0.884973387269943123634163839597022', imag='-0.205327296474456050257018091542704'), 'psi1i': mpc(real='3.16957376509790744734118561609648', imag='6.88196288136694445114471818669699'),
from mpmath import mpf, mp, mpc from UnitTesting.standard_constants import precision mp.dps = precision trusted_values_dict = {} # Generated on: 2019-11-26 trusted_values_dict['GRFFE__generate_everything_for_UnitTesting__globals'] = { 'B_notildeU[0]': mpc(real='0.0', imag='-0.742452019604170732058889825566439'), 'B_notildeU[1]': mpc(real='0.0', imag='-0.181876983465921737703752114612143'), 'B_notildeU[2]': mpc(real='0.0', imag='-0.117426210366556288411388209169672'), 'smallb4U[0]': mpc(real='0.0', imag='-11.7408903561358624045851684059016'), 'smallb4U[1]': mpc(real='0.0', imag='-37.5633821657357103163121792022139'), 'smallb4U[2]': mpc(real='0.0', imag='-8.94650301228646505080632778117433'), 'smallb4U[3]': mpc(real='0.0', imag='-25.9274360646321255785551329609007'), 'smallbsquared': mpf('-4489.79501344023113453502760648373'), 'TEM4UU[0][0]': mpf('5991.5695409703051373827051475723'), 'TEM4UU[0][1]': mpf('-6598.52015499156408677448047649955'), 'TEM4UU[0][2]': mpf('-2343.18579534750494129000780465075'), 'TEM4UU[0][3]':
def mptype(x): return mpmath.mpc(complex(x))
def solveCubicPolynomial( a, b, c, d ): # pylint: disable=invalid-name ''' This function applies the cubic formula to solve a polynomial with coefficients of a, b, c and d. ''' if mp.dps < 50: mp.dps = 50 if a == 0: return solveQuadraticPolynomial( b, c, d ) f = fdiv( fsub( fdiv( fmul( 3, c ), a ), fdiv( power( b, 2 ), power( a, 2 ) ) ), 3 ) g = fdiv( fadd( fsub( fdiv( fmul( 2, power( b, 3 ) ), power( a, 3 ) ), fdiv( fprod( [ 9, b, c ] ), power( a, 2 ) ) ), fdiv( fmul( 27, d ), a ) ), 27 ) h = fadd( fdiv( power( g, 2 ), 4 ), fdiv( power( f, 3 ), 27 ) ) # all three roots are the same if h == 0: x1 = fneg( root( fdiv( d, a ), 3 ) ) x2 = x1 x3 = x2 # two imaginary and one real root elif h > 0: r = fadd( fneg( fdiv( g, 2 ) ), sqrt( h ) ) if r < 0: s = fneg( root( fneg( r ), 3 ) ) else: s = root( r, 3 ) t = fsub( fneg( fdiv( g, 2 ) ), sqrt( h ) ) if t < 0: u = fneg( root( fneg( t ), 3 ) ) else: u = root( t, 3 ) x1 = fsub( fadd( s, u ), fdiv( b, fmul( 3, a ) ) ) real = fsub( fdiv( fneg( fadd( s, u ) ), 2 ), fdiv( b, fmul( 3, a ) ) ) imaginary = fdiv( fmul( fsub( s, u ), sqrt( 3 ) ), 2 ) x2 = mpc( real, imaginary ) x3 = mpc( real, fneg( imaginary ) ) # all real roots else: j = sqrt( fsub( fdiv( power( g, 2 ), 4 ), h ) ) k = acos( fneg( fdiv( g, fmul( 2, j ) ) ) ) if j < 0: l = fneg( root( fneg( j ), 3 ) ) else: l = root( j, 3 ) m = cos( fdiv( k, 3 ) ) n = fmul( sqrt( 3 ), sin( fdiv( k, 3 ) ) ) p = fneg( fdiv( b, fmul( 3, a ) ) ) x1 = fsub( fmul( fmul( 2, l ), cos( fdiv( k, 3 ) ) ), fdiv( b, fmul( 3, a ) ) ) x2 = fadd( fmul( fneg( l ), fadd( m, n ) ), p ) x3 = fadd( fmul( fneg( l ), fsub( m, n ) ), p ) return [ chop( x1 ), chop( x2 ), chop( x3 ) ]
def _eval_evalf(self, prec): """Evaluate this complex root to the given precision. """ with workprec(prec): g = self.poly.gen if not g.is_Symbol: d = Dummy('x') func = lambdify(d, self.expr.subs(g, d)) else: func = lambdify(g, self.expr) interval = self._get_interval() if not self.is_real: # For complex intervals, we need to keep refining until the # imaginary interval is disjunct with other roots, that is, # until both ends get refined. ay = interval.ay by = interval.by while interval.ay == ay or interval.by == by: interval = interval.refine() while True: if self.is_real: a = mpf(str(interval.a)) b = mpf(str(interval.b)) if a == b: root = a break x0 = mpf(str(interval.center)) else: ax = mpf(str(interval.ax)) bx = mpf(str(interval.bx)) ay = mpf(str(interval.ay)) by = mpf(str(interval.by)) if ax == bx and ay == by: # the sign of the imaginary part will be assigned # according to the desired index using the fact that # roots are sorted with negative imag parts coming # before positive (and all imag roots coming after real # roots) deg = self.poly.degree() i = self.index # a positive attribute after creation if (deg - i) % 2: if ay < 0: ay = -ay else: if ay > 0: ay = -ay root = mpc(ax, ay) break x0 = mpc(*map(str, interval.center)) try: root = findroot(func, x0) # If the (real or complex) root is not in the 'interval', # then keep refining the interval. This happens if findroot # accidentally finds a different root outside of this # interval because our initial estimate 'x0' was not close # enough. It is also possible that the secant method will # get trapped by a max/min in the interval; the root # verification by findroot will raise a ValueError in this # case and the interval will then be tightened -- and # eventually the root will be found. # # It is also possible that findroot will not have any # successful iterations to process (in which case it # will fail to initialize a variable that is tested # after the iterations and raise an UnboundLocalError). if self.is_real: if (a <= root <= b): break elif (ax <= root.real <= bx and ay <= root.imag <= by): break except (UnboundLocalError, ValueError): pass interval = interval.refine() return (Float._new(root.real._mpf_, prec) + I*Float._new(root.imag._mpf_, prec))
def wofz(x, y): z = mpmath.mpc(x, y) w = mpmath.exp(-z**2) * mpmath.erfc(z * -1j) return w.real, w.imag
def solveQuarticPolynomialOperator( _a, _b, _c, _d, _e ): # pylint: disable=invalid-name ''' This function applies the quartic formula to solve a polynomial with coefficients of a, b, c, d, and e. ''' if mp.dps < 50: mp.dps = 50 # maybe it's really an order-3 polynomial if _a == 0: return solveCubicPolynomial( _b, _c, _d, _e ) # degenerate case, just return the two real and two imaginary 4th roots of the # constant term divided by the 4th root of a if _b == 0 and _c == 0 and _d == 0: e = fdiv( _e, _a ) f = root( _a, 4 ) x1 = fdiv( root( fneg( e ), 4 ), f ) x2 = fdiv( fneg( root( fneg( e ), 4 ) ), f ) x3 = fdiv( mpc( 0, root( fneg( e ), 4 ) ), f ) x4 = fdiv( mpc( 0, fneg( root( fneg( e ), 4 ) ) ), f ) return [ x1, x2, x3, x4 ] # otherwise we have a regular quartic to solve b = fdiv( _b, _a ) c = fdiv( _c, _a ) d = fdiv( _d, _a ) e = fdiv( _e, _a ) # we turn the equation into a cubic that we can solve f = fsub( c, fdiv( fmul( 3, power( b, 2 ) ), 8 ) ) g = fsum( [ d, fdiv( power( b, 3 ), 8 ), fneg( fdiv( fmul( b, c ), 2 ) ) ] ) h = fsum( [ e, fneg( fdiv( fmul( 3, power( b, 4 ) ), 256 ) ), fmul( power( b, 2 ), fdiv( c, 16 ) ), fneg( fdiv( fmul( b, d ), 4 ) ) ] ) roots = solveCubicPolynomial( 1, fdiv( f, 2 ), fdiv( fsub( power( f, 2 ), fmul( 4, h ) ), 16 ), fneg( fdiv( power( g, 2 ), 64 ) ) ) y1 = roots[ 0 ] y2 = roots[ 1 ] y3 = roots[ 2 ] # pick two non-zero roots, if there are two imaginary roots, use them if y1 == 0: root1 = y2 root2 = y3 elif y2 == 0: root1 = y1 root2 = y3 elif y3 == 0: root1 = y1 root2 = y2 elif im( y1 ) != 0: root1 = y1 if im( y2 ) != 0: root2 = y2 else: root2 = y3 else: root1 = y2 root2 = y3 # more variables... p = sqrt( root1 ) q = sqrt( root2 ) r = fdiv( fneg( g ), fprod( [ 8, p, q ] ) ) s = fneg( fdiv( b, 4 ) ) # put together the 4 roots x1 = fsum( [ p, q, r, s ] ) x2 = fsum( [ p, fneg( q ), fneg( r ), s ] ) x3 = fsum( [ fneg( p ), q, fneg( r ), s ] ) x4 = fsum( [ fneg( p ), fneg( q ), r, s ] ) return [ chop( x1 ), chop( x2 ), chop( x3 ), chop( x4 ) ]
# f = lambda z: mpmath.mpc('0.5','0') * mpmath.sin(mpmath.mpc('1','0') / z) # f = lambda z: mpmath.mpc('1.0','0') / z # f = lambda z: mpmath.exp(mpmath.mpc('-1.0','0.0') / z) - mpmath.exp(mpmath.mpc('1.0','0.0') / z) # f = lambda z: mpmath.power(mpmath.mpc('0.5', '0'), z) # f = lambda z: mpmath.sin(mpmath.mpc('1','0') / (z + mpmath.mpc('0','0.27'))) # f = lambda z: mpmath.sin(mpmath.mpc('1','0') / (z + mpmath.mpc('0','2.5'))) # f = lambda z: z + mpmath.mpc('5', '0') * mpmath.sin(mpmath.re(z)) + mpmath.mpc('0', '5') * mpmath.sin(mpmath.im(z)) f = lambda z: mpmath.power(z, z) # stop_iteration_near = [mpmath.mpc('0','-2.5')] stop_iteration_near = [0] # point = mpmath.mpc('-1.34','-2.0') # point = mpmath.mpc('0.15530079','0.0') # point = mpmath.mpc('0.3','3.0') point = mpmath.mpc('2.8834', '1.2230') # setup interactive plot parent_conn, child_conn = multiprocessing.Pipe() p = multiprocessing.Process(target=plot_process, args=( child_conn, point, mpmath.mp.dps, inspect.getsource(f).strip(), stop_iteration_near, )) p.start() def reraise_error(): print('Please wait... Generating error message...')
def __reduce_to_frp(z, om1): from mpmath import floor, mpc N = int(floor(z.real / (2 * om1))) xs = z.real - N * 2 * om1 return mpc(xs, z.imag), N
def solve_scattering_equations(n, dict_ss): """Solves the scattering equations given multiplicity and mandelstams.""" if n == 3: return [{}] Mn = M(n) zs = punctures(n) num_coeffs = numerical_coeffs(Mn, n, dict_ss) roots = mpmath.polyroots(num_coeffs, maxsteps=10000, extraprec=300) sols = [{str(zs[-2]): root * zs[-3]} for root in roots] if n == 4: sols = [{ str(zs[-2]): mpmath.mpc(sympy.simplify(sols[0][str(zs[-2])].subs({zs[1]: 1}))) }] else: Mnew = copy.deepcopy(Mn) Mnew[:, 0] += Mnew[:, 1] * zs[1] Mnew.col_del(1) Mnew.row_del(-1) # subs sol = sols[0] Mnew = Mnew.tolist() Mnew = [[ _zs_sub(_ss_sub(str(entry))).replace( "dict_zs['z{}']".format(n - 1), "dict_zs['z{}'] * mpmath.mpc(sol[str(zs[-2])] / zs[-3])". format(n - 2)) for entry in line ] for line in Mnew] # get scaling if n == 5: scaling = 0 elif n == 6: scaling = 2 elif n == 7: scaling = 17 else: # computing from scratch, should work for any multiplicity in principle dict_zs = {str(zs[-3]): 10**-100, str(zs[1]): 1} nMn = mpmath.matrix([[eval(entry, None) for entry in line] for line in Mnew]) a = mpmath.det(nMn) dict_zs = {str(zs[-3]): 10**-101, str(zs[1]): 1} nMn = mpmath.matrix([[eval(entry, None) for entry in line] for line in Mnew]) b = mpmath.det(nMn) scaling = -round(mpmath.log(abs(b) / abs(a)) / mpmath.log(10)) assert (abs( round(mpmath.log(abs(b) / abs(a)) / mpmath.log(10)) - mpmath.log(abs(b) / abs(a)) / mpmath.log(10)) < 10**-30) # solve the linear equations for i in range(1, n - 3): Mnew = copy.deepcopy(Mn) index = V(n).index(zs[i]) Mnew[:, 0] += Mnew[:, index] * zs[i] Mnew.col_del(index) Mnew.row_del(-1) Mnew = Mnew.tolist() if i == 1: Mnew = [[ _zs_sub(_ss_sub(str(entry))).replace( "dict_zs['z{}']".format(n - 1), "dict_zs['z{}'] * mpmath.mpc(sol[str(zs[-2])] / zs[-3])" .format(n - 2)) for entry in line ] for line in Mnew] for sol in sols: A = [[value**exponent for exponent in [1, 0]] for value in [-1, 1]] b = [] for value in [-1, 1]: dict_zs = {str(zs[-3]): value, str(zs[1]): 1} nMn = mpmath.matrix( [[eval(entry, None) for entry in line] for line in Mnew]) b += [mpmath.det(nMn) / (value**scaling)] coeffs = mpmath.lu_solve(A, b).T.tolist()[0] sol[str(zs[-3])] = -coeffs[1] / coeffs[0] sol[str(zs[-2])] = mpmath.mpc((sympy.simplify(sol[str( zs[-2])].subs({zs[-3]: sol[str(zs[-3])]})))) else: Mnew = [[_zs_sub(_ss_sub(str(entry))) for entry in line] for line in Mnew] for sol in sols: A = [[value**exponent for exponent in [1, 0]] for value in [-1, 1]] b = [] for value in [-1, 1]: dict_zs = { str(zs[i]): value, str(zs[-3]): sol[str(zs[-3])], str(zs[-2]): sol[str(zs[-2])] } # noqa --- used in eval function nMn = mpmath.matrix( [[eval(entry, None) for entry in line] for line in Mnew]) b += [mpmath.det(nMn)] coeffs = mpmath.lu_solve(A, b).T.tolist()[0] sol[str(zs[i])] = -coeffs[1] / coeffs[0] return sols
'gammaUU[1][1]': mpf('-1.80649576353102912734623132484412'), 'gammaUU[1][2]': mpf('1.81188776789429056085099706766191'), 'gammaUU[2][0]': mpf('0.0556557158507127226919364696342749'), 'gammaUU[2][1]': mpf('1.81188776789429056085099706766191'), 'gammaUU[2][2]': mpf('-0.361125192285811549808229761941845'), 'gammadet': mpf('-0.249945345858354359323568625780808'), 'u0alpha': mpf('0.367135744642744378541883654490628'), 'alpsqrtgam': mpc(real='0.0', imag='0.287206864362771430165821584523655'), 'Stilde_rhsD[0]': mpc(real='0.0767289543461551343250803824957984', imag='0.185558476328122751164428905212844'), 'Stilde_rhsD[1]': mpc(real='-0.216819936402773860706361119810026', imag='-0.0132406060456689567139676455553854'), 'Stilde_rhsD[2]': mpc(real='0.173943026704519554392902591644088', imag='0.10141259082235179467268437747407'), 'AevolParen': mpc(real='-1.33624532586521493904285762255313', imag='-0.344717596676114568232662804803113'), 'PevolParenU[0]': mpc(real='-0.223244664097171335859215446362214', imag='-0.0705095579135382177771163014767808'),
def eval_approx(self, n): """Evaluate this complex root to the given precision. This uses secant method and root bounds are used to both generate an initial guess and to check that the root returned is valid. If ever the method converges outside the root bounds, the bounds will be made smaller and updated. """ prec = dps_to_prec(n) with workprec(prec): g = self.poly.gen if not g.is_Symbol: d = Dummy('x') if self.is_imaginary: d *= I func = lambdify(d, self.expr.subs(g, d)) else: expr = self.expr if self.is_imaginary: expr = self.expr.subs(g, I * g) func = lambdify(g, expr) interval = self._get_interval() while True: if self.is_real: a = mpf(str(interval.a)) b = mpf(str(interval.b)) if a == b: root = a break x0 = mpf(str(interval.center)) x1 = x0 + mpf(str(interval.dx)) / 4 elif self.is_imaginary: a = mpf(str(interval.ay)) b = mpf(str(interval.by)) if a == b: root = mpc(mpf('0'), a) break x0 = mpf(str(interval.center[1])) x1 = x0 + mpf(str(interval.dy)) / 4 else: ax = mpf(str(interval.ax)) bx = mpf(str(interval.bx)) ay = mpf(str(interval.ay)) by = mpf(str(interval.by)) if ax == bx and ay == by: root = mpc(ax, ay) break x0 = mpc(*map(str, interval.center)) x1 = x0 + mpc(*map(str, (interval.dx, interval.dy))) / 4 try: # without a tolerance, this will return when (to within # the given precision) x_i == x_{i-1} root = findroot(func, (x0, x1)) # If the (real or complex) root is not in the 'interval', # then keep refining the interval. This happens if findroot # accidentally finds a different root outside of this # interval because our initial estimate 'x0' was not close # enough. It is also possible that the secant method will # get trapped by a max/min in the interval; the root # verification by findroot will raise a ValueError in this # case and the interval will then be tightened -- and # eventually the root will be found. # # It is also possible that findroot will not have any # successful iterations to process (in which case it # will fail to initialize a variable that is tested # after the iterations and raise an UnboundLocalError). if self.is_real or self.is_imaginary: if not bool(root.imag) == self.is_real and (a <= root <= b): if self.is_imaginary: root = mpc(mpf('0'), root.real) break elif (ax <= root.real <= bx and ay <= root.imag <= by): break except (UnboundLocalError, ValueError): pass interval = interval.refine() # update the interval so we at least (for this precision or # less) don't have much work to do to recompute the root self._set_interval(interval) return (Float._new(root.real._mpf_, prec) + I * Float._new(root.imag._mpf_, prec))