def plot_pulsar_obliquity(): from numpy import linspace, array, arange from pylab import rc, plot, xlim, xticks, xlabel, ylabel import matplotlib.pyplot as plt import mpmath rc('text', usetex=True) fig = plt.figure() # Initial params. rot1 = 1.76e-4 rot2 = 1256. params = {'m2': 1.4 * 1.98892e30,'r2':20000.0,'rot2':rot2,\ 'r1':70000.e3/2,'rot1':rot1,'i_a':.5,'ht':0.,\ 'a':600000.e3,'e':.1,'i':0.8,'h':2} # Set parameters. sp.parameters = params # Period. period = sp.wp_period ob = sp.obliquity_time lspace = linspace(0,5*period,250) xlim(0,float(lspace[-1])) xlabel(r'$\textnormal{Time (years)}$') ylabel(r'$\textnormal{Obliquity }\left( ^\circ \right)$') ob_series = array([ob(t).real*(360/(2*mpmath.pi())) for t in lspace]) plot(lspace,ob_series,'k-',linewidth=2) xticks(arange(xlim()[0],xlim()[1],365*24*3600*20),[r'$'+str(int(_)*20)+r'$' for _ in [t[0] for t in enumerate(arange(xlim()[0],xlim()[1],365*24*3600*20))]]) return params = {'m2': 1.4 * 1.98892e30,'r2':20000.0,'rot2':rot2,\ 'r1':15000.e3/2,'rot1':rot1,'i_a':.5,'ht':0.,\ 'a':600000.e3,'e':.1,'i':0.8,'h':2} # Set parameters. sp.parameters = params # Period. ob = sp.obliquity_time ob_series2 = array([ob(t).real*(360/(2*mpmath.pi())) for t in lspace]) plot(lspace,ob_series-ob_series2,'k-',linewidth=2)
def plot_probe_earth_obliquity(): from numpy import linspace, array, arange from pylab import rc, plot, xlim, xticks, xlabel, ylabel import matplotlib.pyplot as plt import mpmath rc('text', usetex=True) fig = plt.figure() # Initial params. #params = {'m2':5.97E24,'r2':6371.e3,'rot2':6.28/(24.*3600),\ #'r1':0.038,'rot1':6.28*3500/60,'i_a':0.5,'ht': 0,\ #'a':7027E3,'e':0.01,'i':0.8,'h':2} params = {'m2':5.97E24,'r2':6371.e3,'rot2':6.28/(24.*3600),\ 'r1':0.038,'rot1':6.28*3400/60,'i_a':90.007 * 2*mpmath.pi()/360,'ht': 0,\ 'a':7013E3,'e':0.0014,'i':mpmath.pi()/2,'h':-mpmath.pi()/2} # Set parameters. sp.parameters = params # Period. period = sp.wp_period ob = sp.obliquity_time lspace = linspace(0,5*period,250) xlim(0,float(lspace[-1])) xlabel(r'$\textnormal{Time (ka)}$') ylabel(r'$\textnormal{Obliquity }\left( ^\circ \right)$') ob_series = array([ob(t).real*(360/(2*mpmath.pi())) for t in lspace]) plot(lspace,ob_series,'k-',linewidth=2)
def plot_earth_moon_obliquity(): from numpy import linspace, array, arange from pylab import rc, plot, xlim, xticks, xlabel, ylabel import matplotlib.pyplot as plt import mpmath rc('text', usetex=True) fig = plt.figure() # Initial params. #params = {'m2':1.9e27,'r2':70000.e3,'rot2':0.00017585125448028,\ # 'r1':1,'rot1':6.28*100,'i_a':0.5,'ht': 0,\ # 'a':421700E3 / 4,'e':0.01,'i':0.8,'h':2} rot1 = 7.978282018665196e-08 rot2 = 2.972e-06 params = {'m2':1.98892e30,'r2':695500000.0,'rot2':rot2,\ 'r1':384748.e3,'rot1':rot1,'i_a':10. * 2*mpmath.pi()/360,'ht': 0,\ 'a':149597870700. * 0.1,'e':0.017,'i':7. * 2*mpmath.pi()/360,'h':mpmath.pi()/2} # Set parameters. sp.parameters = params # Period. period = sp.wp_period ob = sp.obliquity_time lspace = linspace(0,5*period,250) xlim(0,float(lspace[-1])) xlabel(r'$\textnormal{Time (Ma)}$') ylabel(r'$\textnormal{Obliquity }\left( ^\circ \right)$') ob_series = array([ob(t).real*(360/(2*mpmath.pi())) for t in lspace]) plot(lspace,ob_series,'k-',linewidth=2) xticks(arange(xlim()[0],xlim()[1],365*24*3600*100000000),[r'$'+str(int(_)*100)+r'$' for _ in [t[0] for t in enumerate(arange(xlim()[0],xlim()[1],365*24*3600*100000000))]])
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 plot_pulsar_g(): from pylab import plot, subplot, title, rc, xlim, ylim, xlabel, ylabel, xticks, yticks, title from numpy import linspace, arange, array import mpmath rc('text', usetex=True) # Initial params. rot1 = 1.76e-4 rot2 = 1256. params = {'m2': 1.4 * 1.98892e30,'r2':20000.0,'rot2':rot2,\ 'r1':70000.e3/2,'rot1':rot1,'i_a':.5,'ht':0.,\ 'a':600000.e3,'e':.1,'i':0.8,'h':2} # Kill spins. params['rot2'] = 1E-30 params['rot1'] = 1E-30 # Set parameters. sp.parameters = params ein_period = sp.wp_period g_time = sp.g_time ein_rate = (g_time(ein_period) - g_time(0))/ein_period lspace = linspace(0,5*ein_period,250) subplot(1,3,1) title('(a)') xlim(0,float(lspace[-1])) xlabel(r'$\textnormal{Time (years)}$') ylabel(r'$g\left( ^\circ \right)$') plot(lspace,[g_time(t).real*(360/(2*mpmath.pi())) for t in lspace],'k-',linewidth=2) xticks(arange(xlim()[0],xlim()[1],365*24*3600*20),[r'$'+str(int(_)*20)+r'$' for _ in [t[0] for t in enumerate(arange(xlim()[0],xlim()[1],365*24*3600*20))]]) yticks(arange(ylim()[0],ylim()[1],360),[r'$'+str(int(_))+r'$' for _ in arange(ylim()[0],ylim()[1],360)]) subplot(1,3,2) title('(b)') # Restore spins. params['rot2'] = rot2 params['rot1'] = rot1 sp.parameters = params g_time = sp.g_time xlim(0,float(lspace[-1])) xlabel(r'$\textnormal{Time (years)}$') ylabel(r'$\Delta g\left( ^\circ \right)$') g_t_vec = array([g_time(t).real for t in lspace]) delta_1 = g_t_vec - array([(ein_rate*t).real for t in lspace]) plot(lspace,delta_1*(360/(2*mpmath.pi())),'k-',linewidth=2) xticks(arange(xlim()[0],xlim()[1],365*24*3600*20),[r'$'+str(int(_)*20)+r'$' for _ in [t[0] for t in enumerate(arange(xlim()[0],xlim()[1],365*24*3600*20))]]) subplot(1,3,3) title('(c)') xlim(0,float(lspace[-1])) xlabel(r'$\textnormal{Time (years)}$') ylabel(r'$\Delta g\left( ^\circ \right)$') rate_spin = (g_time(sp.wp_period) / sp.wp_period).real delta_2 = g_t_vec - array([(rate_spin*t).real for t in lspace]) plot(lspace,delta_2*(360/(2*mpmath.pi())),'k-',linewidth=2) xticks(arange(xlim()[0],xlim()[1],365*24*3600*20),[r'$'+str(int(_)*20)+r'$' for _ in [t[0] for t in enumerate(arange(xlim()[0],xlim()[1],365*24*3600*20))]])
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 __ln_expansion(self,u,n_iter = 50): from mpmath import ln, pi, sin, exp, mpc # TODO: test for pathological cases? om1, om3 = self.periods[0]/2, self.periods[1]/2 assert(u.real < 2*om1 and u.real >= 0) assert(u.imag < 2*om3.imag and u.imag >= 0) tau = om3/om1 q = exp(mpc(0,1)*pi()*tau) eta1 = self.zeta(om1) om1_2 = om1 * 2 retval = ln(om1_2/pi()) + eta1*u**2/(om1_2) + ln(sin(pi()*u/(om1_2))) for r in range(1,n_iter + 1): q_2 = q**(2*r) retval += q_2/(r * (1 - q_2))*(2. * sin(r*pi()*u/(om1_2)))**2 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 ln_expansion(wp,u,n_iter = 50): from mpmath import ln, pi, sin, exp, mpc # TODO: test for pathological cases? if wp.periods[1].real == 0: om1, om3 = wp.periods[0]/2, wp.periods[1]/2 else: om1, om3 = wp.periods[1].conjugate()/2, wp.periods[1]/2 tau = om3/om1 q = exp(mpc(0,1)*pi()*tau) eta1 = wp.zeta(om1) om1_2 = om1 * 2 retval = ln(om1_2/pi()) + eta1*u**2/(om1_2) + ln(sin(pi()*u/(om1_2))) for r in range(1,n_iter + 1): q_2 = q**(2*r) retval += q_2/(r * (1 - q_2))*(2. * sin(r*pi()*u/(om1_2)))**2 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 ln_expansion2(wp, u, n_iter=25): from mpmath import ln, pi, sin, exp, mpc # TODO: test for pathological cases? om1, om3 = wp.periods[0] / 2, wp.periods[1] / 2 assert (u.real < 2 * om1 and u.real >= 0) assert (abs(u.imag) < 2 * om3.imag) tau = om3 / om1 q = exp(mpc(0, 1) * pi() * tau) eta1 = wp.zeta(om1) om1_2 = om1 * 2 retval = ln(om1_2 / pi()) + eta1 * u**2 / (om1_2) + ln( sin(pi() * u / (om1_2))) for r in range(1, n_iter + 1): q_2 = q**(2 * r) retval += q_2 / (r * (1 - q_2)) * (2. * sin(r * pi() * u / (om1_2)))**2 return retval
def plot_io_obliquity_2(): from numpy import linspace, array, arange from pylab import rc, plot, xlim, xticks, xlabel, ylabel import matplotlib.pyplot as plt import mpmath rc('text', usetex=True) fig = plt.figure() # Initial params. #params = {'m2':1.9e27,'r2':70000.e3,'rot2':0.00017585125448028,\ # 'r1':1,'rot1':6.28*100,'i_a':0.5,'ht': 0,\ # 'a':421700E3 / 4,'e':0.01,'i':0.8,'h':2} params = {'m2':1.9e27,'r2':70000.e3,'rot2':0.00017585125448028,\ 'r1':1821E3,'rot1':6.28/(21 * 3600),'i_a':0.17453,'ht': 0,\ 'a':421700E3,'e':0.05,'i':0.349,'h':0.35} # Set parameters. sp.parameters = params # Period. period = sp.wp_period ob = sp.obliquity_time lspace = linspace(0,5*period,250) xlim(0,float(lspace[-1])) xlabel(r'$\textnormal{Time (Ma)}$') ylabel(r'$\textnormal{Obliquity }\left( ^\circ \right)$') ob_series = array([ob(t).real*(360/(2*mpmath.pi())) for t in lspace]) plot(lspace,ob_series,'k-',linewidth=2) xticks(arange(xlim()[0],xlim()[1],365*24*3600*1000000),[r'$'+str(int(_)*1)+r'$' for _ in [t[0] for t in enumerate(arange(xlim()[0],xlim()[1],365*24*3600*1000000))]])
def ln_expansion(wp, u, n_iter=50): from mpmath import ln, pi, sin, exp, mpc # TODO: test for pathological cases? if wp.periods[1].real == 0: om1, om3 = wp.periods[0] / 2, wp.periods[1] / 2 else: om1, om3 = wp.periods[1].conjugate() / 2, wp.periods[1] / 2 tau = om3 / om1 q = exp(mpc(0, 1) * pi() * tau) eta1 = wp.zeta(om1) om1_2 = om1 * 2 retval = ln(om1_2 / pi()) + eta1 * u**2 / (om1_2) + ln( sin(pi() * u / (om1_2))) for r in range(1, n_iter + 1): q_2 = q**(2 * r) retval += q_2 / (r * (1 - q_2)) * (2. * sin(r * pi() * u / (om1_2)))**2 return retval
def psr_sgr_h(): from pylab import plot, subplot, title, rc, xlim, ylim, xlabel, ylabel, xticks, yticks, title from numpy import linspace, arange, array import mpmath rc('text', usetex=True) # Initial params. rot1 = 1256 rot2 = 0.0019 params = {'m2':1.98892e30 * 4.3E6,'r2':44E9,'rot2':rot2,\ 'r1':20E3,'rot1':rot1,'i_a':.5,'ht':0.,\ 'a':90000000000000.,'e':.8,'i':0.8,'h':2} # Kill the secondary spin. params['rot1'] = 1E-30 # Set parameters. sp.parameters = params # Restore secondary spins. params['rot1'] = rot1 sp.parameters = params return lt_period = sp.wp_period h_time = lambda t: sp.hs_time(t) + sp.ht_time(t) lt_rate = (h_time(lt_period) - h_time(0))/lt_period lspace = linspace(0,5*lt_period,250) subplot(1,2,1) title('(a)') xlim(0,float(lspace[-1])) xlabel(r'$\textnormal{Time (ka)}$') ylabel(r'$h\left( ^\circ \right)$') plot(lspace,[h_time(t).real*(360/(2*mpmath.pi())) for t in lspace],'k-',linewidth=2) xticks(arange(xlim()[0],xlim()[1],365*24*3600*20000),[r'$'+str(int(_)*20)+r'$' for _ in [t[0] for t in enumerate(arange(xlim()[0],xlim()[1],365*24*3600*20000))]]) #yticks(arange(ylim()[0],ylim()[1],400),[r'$'+str(int(_))+r'$' for _ in arange(ylim()[0],ylim()[1],400)]) subplot(1,2,2) title('(b)') # Restore secondary spins. params['rot1'] = rot1 sp.parameters = params h_time = lambda t: sp.hs_time(t) + sp.ht_time(t) xlim(0,float(lspace[-1])) xlabel(r'$\textnormal{Time (ka)}$') ylabel(r'$\Delta h\left( ^{\prime\prime} \right)$') h_t_vec = array([h_time(t).real for t in lspace]) delta_1 = h_t_vec - array([(lt_rate*t + h_time(0)).real for t in lspace]) plot(lspace,delta_1*(360/(2*mpmath.pi()))*3600,'k-',linewidth=2) xticks(arange(xlim()[0],xlim()[1],365*24*3600*20000),[r'$'+str(int(_)*20)+r'$' for _ in [t[0] for t in enumerate(arange(xlim()[0],xlim()[1],365*24*3600*20000))]])
def plot_earth_moon_ht(): from pylab import plot, subplot, title, rc, xlim, ylim, xlabel, ylabel, xticks, yticks, title from numpy import linspace, arange, array import mpmath rc('text', usetex=True) # Initial params. rot1 = 7.978282018665196e-08 rot2 = 2.972e-06 params = {'m2':1.98892e30,'r2':695500000.0,'rot2':rot2,\ 'r1':384748.e3,'rot1':rot1,'i_a':10. * 2*mpmath.pi()/360,'ht': 0,\ 'a':149597870700.,'e':0.017,'i':7. * 2*mpmath.pi()/360,'h':mpmath.pi()/2} # Kill the primary spin. params['rot2'] = 1E-30 # Set parameters. sp.parameters = params ds_period = sp.wp_period ht_time = sp.ht_time lspace = linspace(0,5*ds_period,250) subplot(1,2,1) title('(a)') xlim(0,float(lspace[-1])) xlabel(r'$\textnormal{Time (Ma)}$') ylabel(r'$\tilde{h}\left( ^\circ \right)$') ds_series = array([ht_time(t).real*(360/(2*mpmath.pi())) for t in lspace]) plot(lspace,ds_series,'k-',linewidth=2) xticks(arange(xlim()[0],xlim()[1],365*24*3600*100000000),[r'$'+str(int(_)*100)+r'$' for _ in [t[0] for t in enumerate(arange(xlim()[0],xlim()[1],365*24*3600*100000000))]]) yticks(arange(ylim()[0],ylim()[1],360),[r'$'+str(int(_))+r'$' for _ in arange(ylim()[0],ylim()[1],360)]) subplot(1,2,2) title('(b)') # Restore primary spins. params['rot2'] = rot2 sp.parameters = params ht_time = sp.ht_time xlim(0,float(lspace[-1])) xlabel(r'$\textnormal{Time (Ma)}$') ylabel(r'$\Delta \tilde{h}\left( ^\circ \right)$') ht_t_vec = array([ht_time(t).real*(360/(2*mpmath.pi())) for t in lspace]) plot(lspace,ds_series - ht_t_vec,'k-',linewidth=2) xticks(arange(xlim()[0],xlim()[1],365*24*3600*100000000),[r'$'+str(int(_)*100)+r'$' for _ in [t[0] for t in enumerate(arange(xlim()[0],xlim()[1],365*24*3600*100000000))]])
def plot_psr_sgr_ht(): from pylab import plot, subplot, title, rc, xlim, ylim, xlabel, ylabel, xticks, yticks, title from numpy import linspace, arange, array import mpmath rc('text', usetex=True) # Initial params. rot1 = 1256 rot2 = 0.0019 params = {'m2':1.98892e30 * 4.3E6,'r2':44E9,'rot2':rot2,\ 'r1':20E3,'rot1':rot1,'i_a':.5,'ht':0.,\ 'a':90000000000000.,'e':.8,'i':0.8,'h':2} # Kill the primary spin. params['rot2'] = 1E-30 # Set parameters. sp.parameters = params ds_period = sp.wp_period ht_time = sp.ht_time lspace = linspace(0,5*ds_period,250) subplot(1,2,1) title('(a)') xlim(0,float(lspace[-1])) xlabel(r'$\textnormal{Time (ka)}$') ylabel(r'$\tilde{h}\left( ^\circ \right)$') ds_series = array([ht_time(t).real*(360/(2*mpmath.pi())) for t in lspace]) plot(lspace,ds_series,'k-',linewidth=2) xticks(arange(xlim()[0],xlim()[1],365*24*3600*20000),[r'$'+str(int(_)*20)+r'$' for _ in [t[0] for t in enumerate(arange(xlim()[0],xlim()[1],365*24*3600*20000))]]) yticks(arange(ylim()[0],ylim()[1],360),[r'$'+str(int(_))+r'$' for _ in arange(ylim()[0],ylim()[1],360)]) subplot(1,2,2) title('(b)') # Restore primary spins. params['rot2'] = rot2 sp.parameters = params ht_time = sp.ht_time xlim(0,float(lspace[-1])) xlabel(r'$\textnormal{Time (ka)}$') ylabel(r'$\Delta \tilde{h}\left( ^\circ \right)$') ht_t_vec = array([ht_time(t).real*(360/(2*mpmath.pi())) for t in lspace]) plot(lspace,ds_series - ht_t_vec,'k-',linewidth=2) xticks(arange(xlim()[0],xlim()[1],365*24*3600*20000),[r'$'+str(int(_)*20)+r'$' for _ in [t[0] for t in enumerate(arange(xlim()[0],xlim()[1],365*24*3600*20000))]])
def plot_probe_earth_ht(): from pylab import plot, subplot, title, rc, xlim, ylim, xlabel, ylabel, xticks, yticks, title from numpy import linspace, arange, array import mpmath rc('text', usetex=True) # Initial params. rot1 = 6.28*3400/60 rot2 = 6.28/(24.*3600) params = {'m2':5.97E24,'r2':6371.e3,'rot2':rot2,\ 'r1':0.038,'rot1':rot1,'i_a':90.007 * 2*mpmath.pi()/360,'ht': 0,\ 'a':7013E3,'e':0.0014,'i':mpmath.pi()/2,'h':-mpmath.pi()/2} # Kill the primary spin. params['rot2'] = 1E-30 # Set parameters. sp.parameters = params ds_period = sp.wp_period ht_time = sp.ht_time lspace = linspace(0,ds_period,250) subplot(1,2,1) title('(a)') xlim(0,float(lspace[-1])) xlabel(r'$\textnormal{Time (ka)}$') ylabel(r'$\tilde{h}\left( ^\circ \right)$') ds_series = array([ht_time(t).real*(360/(2*mpmath.pi())) for t in lspace]) plot(lspace,ds_series,'k-',linewidth=2) #xticks(arange(xlim()[0],xlim()[1],365*24*3600*20000),[r'$'+str(int(_)*20)+r'$' for _ in [t[0] for t in enumerate(arange(xlim()[0],xlim()[1],365*24*3600*20000))]]) #yticks(arange(ylim()[0],ylim()[1],360),[r'$'+str(int(_))+r'$' for _ in arange(ylim()[0],ylim()[1],360)]) subplot(1,2,2) title('(b)') # Restore primary spins. params['rot2'] = rot2 sp.parameters = params ht_time = sp.ht_time xlim(0,float(lspace[-1])) xlabel(r'$\textnormal{Time (ka)}$') ylabel(r'$\Delta \tilde{h}\left( ^\circ \right)$') ht_t_vec = array([ht_time(t).real*(360/(2*mpmath.pi())) for t in lspace]) plot(lspace,ht_t_vec,'k-',linewidth=2)
def eval(cls,t,g2,g3,alpha,beta,gamma): import weierstrass_elliptic from mpmath import mpc, pi, mpf, mp # Check that everything is mpf. assert(all([isinstance(x,mpf) for x in [t,g2,g3,alpha,beta,gamma]])) invs = (g2,g3) if invs in integral_func._wp_cache: wp = integral_func._wp_cache[invs] else: wp = weierstrass_elliptic.weierstrass_elliptic(g2,g3) integral_func._wp_cache[invs] = wp v = wp.Pinv(beta) retval = alpha/wp.Pprime(v) * (mpf(2)*t*wp.zeta(v) + mpc(0,pi()) + wp.ln_sigma(-t+v) - wp.ln_sigma(t+v)) + gamma*t return retval
def __ln_sigma(wp,u): from mpmath import mpc, pi # TODO: test for pathological cases? om1, om3 = wp.periods[0]/2, wp.periods[1]/2 assert(u.imag >= 0 and u.imag < 2*om3.imag) further_reduction = False if u.imag/(2*om3.imag) > .5: further_reduction = True u = -u + 2*om1 + 2*om3 u_F,N = stark.__reduce_to_frp(u,om1) eta1 = wp.zeta(om1) retval = stark.__ln_expansion(wp,u_F) + 2*N*eta1*(u_F + N*om1) - mpc(0,1)*N*pi() if further_reduction: retval -= (u - om1 - om3) * (2*eta1 + 2*wp.zeta(om3)) return retval
def calc_arclength_coeff(amp): # Arc length of sinusoidal surface from 0 to pi/2 (one quarter wave) # is Complete Elliptic Integral of Second Kind, E(m) # The argument m is m = -A^2, where A is amplitude of sinusoid. amplitude = float(amp) m = - amplitude*amplitude arclength = mpmath.ellipe(m) domainlength = mpmath.pi()/2 arc_coeff = float(arclength/domainlength) return arc_coeff
def __ln_sigma(wp, u): from mpmath import mpc, pi # TODO: test for pathological cases? om1, om3 = wp.periods[0] / 2, wp.periods[1] / 2 assert (u.imag >= 0 and u.imag < 2 * om3.imag) further_reduction = False if u.imag / (2 * om3.imag) > .5: further_reduction = True u = -u + 2 * om1 + 2 * om3 u_F, N = stark.__reduce_to_frp(u, om1) eta1 = wp.zeta(om1) retval = stark.__ln_expansion( wp, u_F) + 2 * N * eta1 * (u_F + N * om1) - mpc(0, 1) * N * pi() if further_reduction: retval -= (u - om1 - om3) * (2 * eta1 + 2 * wp.zeta(om3)) return retval
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 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 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 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 plot_probe_obliquity(): from numpy import linspace, array, arange from pylab import rc, plot, xlim, xticks, xlabel, ylabel import matplotlib.pyplot as plt import mpmath rc('text', usetex=True) fig = plt.figure() # Initial params. params = {'m2':1.98892e30,'r2':695500000.0,'rot2':2.972e-06,\ 'r1':1,'rot1':6.28*100,'i_a':0.5,'ht': 0,\ 'a':57909100.e3 / 2000,'e':0.01,'i':0.8,'h':2} # Set parameters. sp.parameters = params # Period. period = sp.wp_period ob = sp.obliquity_time lspace = linspace(0,5*period,250) xlim(0,float(lspace[-1])) xlabel(r'$\textnormal{Time (ka)}$') ylabel(r'$\textnormal{Obliquity }\left( ^\circ \right)$') ob_series = array([ob(t).real*(360/(2*mpmath.pi())) for t in lspace]) plot(lspace,ob_series,'k-',linewidth=2)
def plot_mercury_obliquity(): from numpy import linspace, array, arange from pylab import rc, plot, xlim, xticks, xlabel, ylabel import matplotlib.pyplot as plt import mpmath rc('text', usetex=True) fig = plt.figure() # Initial params. params = {'m2':1.98892e30,'r2':695500000.0,'rot2':2.972e-06,\ 'r1':2440.e3,'rot1':1.24e-06,'i_a':0.0524,'ht': 0.1,\ 'a':57909100.e3,'e':0.206,'i':0.122,'h':0.2} # Set parameters. sp.parameters = params # Period. period = sp.wp_period ob = sp.obliquity_time lspace = linspace(0,5*period,250) xlim(0,float(lspace[-1])) xlabel(r'$\textnormal{Time (Ma)}$') ylabel(r'$\textnormal{Obliquity }\left( ^\circ \right)$') ob_series = array([ob(t).real*(360/(2*mpmath.pi())) for t in lspace]) plot(lspace,ob_series,'k-',linewidth=2) xticks(arange(xlim()[0],xlim()[1],365*24*3600*5E6),[r'$'+str(int(_)*5)+r'$' for _ in [t[0] for t in enumerate(arange(xlim()[0],xlim()[1],365*24*3600*5E6))]])
def mpmath_pi(prec): print(mpmath.pi(prec)) return (0, 0), 0
def __set_params(self,d): from copy import deepcopy from mpmath import mpf, sqrt, polyroots, cos, acos, pi, mp from weierstrass_elliptic import weierstrass_elliptic as we names = ['m2','r2','rot2','r1','rot1','i_a','ht','a','e','i','h'] if not all([s in d for s in names]): raise ValueError('invalid set of parameters') # Convert all the values to mpf and introduce convenience shortcuts. m2, r2, rot2, r1, rot1, i_a, ht_in, a, e, i, h_in = [mpf(d[s]) for s in names] L_in = sqrt(self.__GG_val * m2 * a) G_in = L_in * sqrt(1. - e**2) H_in = G_in * cos(i) Gt_in = (2 * r1**2 * rot1) / 5 Ht_in = Gt_in * cos(i_a) Hts_in = H_in + Ht_in hs_in = h_in - ht_in Gxy_in = sqrt(G_in**2 - H_in**2) Gtxys_in = sqrt(Gt_in**2 - Ht_in**2) J2 = (2 * m2 * r2**2 * rot2) / 5 II_1 = mpf(5) / (2 * r1**2) # Evaluation dictionary. eval_names = ['L','G','H','\\tilde{G}','\\tilde{H}_\\ast','h_\\ast','\\tilde{G}_{xy\\ast}','m_2','\\mathcal{G}','J_2','G_{xy}',\ '\\varepsilon','\\mathcal{I}_1'] eval_values = [L_in,G_in,H_in,Gt_in,Hts_in,hs_in,Gtxys_in,m2,self.__GG_val,J2,Gxy_in,self.__eps_val,II_1] d_eval = dict(zip(eval_names,eval_values)) # Evaluate Hamiltonian with initial conditions. HHp_val = self.__HHp.trim().evaluate(d_eval) # Add the value of the Hamiltonian to the eval dictionary. d_eval['\\mathcal{H}^\\prime'] = HHp_val # Evaluate g2 and g3. g2_val, g3_val = self.__g2.trim().evaluate(d_eval), self.__g3.trim().evaluate(d_eval) # Create the Weierstrass object. wp = we(g2_val,g3_val) # Store the period. self.__wp_period = wp.periods[0] # Now let's find the roots of the quartic polynomial. # NOTE: in theory here we could use the exact solution for the quartic. p4coeffs = [t[0] * t[1].trim().evaluate(d_eval) for t in zip([1,4,6,4,1],self.__f4_cf)] p4roots, err = polyroots(p4coeffs,error = True, maxsteps = 1000) # Find a reachable root. Hr, H_max, n_lobes, lobe_idx = self.__reachable_root(p4roots,H_in) # Determine t_r t_r = self.__compute_t_r(n_lobes,lobe_idx,H_in,Hr,d_eval,p4roots,p4coeffs[0]) # Now evaluate the derivatives of the polynomial. We will need to replace H_in with Hr in the eval dict. d_eval['H'] = Hr _, f4Hp, f4Hpp, _, _ = self.__f4 f4p_eval = f4Hp.trim().evaluate(d_eval) f4pp_eval = f4Hpp.trim().evaluate(d_eval) # Build and store the expression for H(t). self.__H_time = lambda t: Hr + f4p_eval / (4 * (wp.P(t - t_r) - f4pp_eval / 24)) # H will not be needed any more, replace with H_r del d_eval['H'] d_eval['H_r'] = Hr # Inject the invariants and the other two constants into the evaluation dictionary. d_eval['g_2'] = g2_val d_eval['g_3'] = g3_val d_eval['A'] = f4p_eval / 4 d_eval['B'] = f4pp_eval / 24 # Verify the formulae in solutions.py self.__verify_solutions(d_eval) # Assuming g = 0 as initial angle. self.__g_time = spin_gr_theory.__get_g_time(d_eval,t_r,0.) self.__hs_time = spin_gr_theory.__get_hs_time(d_eval,t_r,hs_in) self.__ht_time = spin_gr_theory.__get_ht_time(d_eval,t_r,ht_in) def obliquity(t): from mpmath import acos, cos, sqrt H = self.__H_time(t) hs = self.__hs_time(t) G = d_eval['G'] Gt = d_eval['\\tilde{G}'] Hts = d_eval['\\tilde{H}_\\ast'] Gxy = sqrt(G**2-H**2) Gtxys = sqrt(Gt**2-(Hts-H)**2) retval = (Gxy*Gtxys*cos(hs)+H*(Hts-H))/(G*Gt) return acos(retval) self.__obliquity_time = obliquity def spin_vector(t): import numpy ht = self.__ht_time(t) H = self.__H_time(t) G = d_eval['G'] Gt = d_eval['\\tilde{G}'] Hts = d_eval['\\tilde{H}_\\ast'] Gtxys = sqrt(Gt**2-(Hts-H)**2) return numpy.array([x.real for x in [Gtxys*sin(ht),-Gtxys*cos(ht),Hts-H]]) self.__spin_vector_time = spin_vector def orbit_vector(t): import numpy ht = self.__ht_time(t) hs = self.__hs_time(t) h = hs + ht H = self.__H_time(t) G = d_eval['G'] Gxy = sqrt(G**2-H**2) return numpy.array([x.real for x in [Gxy*sin(h),-Gxy*cos(h),H]]) self.__orbit_vector_time = orbit_vector # Store the params of the system. self.__params = dict(zip(names,[mpf(d[s]) for s in names])) # Final report. rad_conv = 360 / (2 * pi()) print("\x1b[31mAccuracy in the identification of the poly roots:\x1b[0m") print(err) print("\n\x1b[31mPeriod (years):\x1b[0m") print(wp.periods[0] / (3600*24*365)) print("\n\x1b[31mMin and max orbital inclination (deg):\x1b[0m") print(acos(Hr/G_in) * rad_conv,acos(H_max/G_in) * rad_conv) print("\n\x1b[31mMin and max axial inclination (deg):\x1b[0m") print(acos((Hts_in - Hr)/Gt_in) * rad_conv,acos((Hts_in-H_max)/Gt_in) * rad_conv) print("\n\x1b[31mNumber of lobes:\x1b[0m " + str(n_lobes)) print("\n\x1b[31mLobe idx:\x1b[0m " + str(lobe_idx)) # Report the known results for simplified system for comparison. H = H_in HHp,G,L,GG,eps,m2,Hts,Gt,J2 = [d_eval[s] for s in ['\\mathcal{H}^\\prime','G','L','\\mathcal{G}',\ '\\varepsilon','m_2','\\tilde{H}_\\ast','\\tilde{G}','J_2']] print("\n\x1b[31mEinstein (g):\x1b[0m " + str((3 * eps * GG**4 * m2**4/(G**2*L**3)))) print("\n\x1b[31mLense-Thirring (g):\x1b[0m " + str(((eps * ((-6*H*J2*GG**4*m2**3)/(G**4*L**3)+3*GG**4*m2**4/(G**2*L**3)))))) print("\n\x1b[31mLense-Thirring (h):\x1b[0m " + str((2*eps*J2*GG**4*m2**3/(G**3*L**3)))) # These are the Delta_ constants of quasi-periodicity. f_period = self.wp_period print("\n\x1b[31mDelta_g:\x1b[0m " + str(self.g_time(f_period) - self.g_time(0))) print("\n\x1b[31mg_rate:\x1b[0m " + str((self.g_time(f_period) - self.g_time(0))/f_period)) Delta_hs = self.hs_time(f_period) - self.hs_time(0) print("\n\x1b[31mDelta_hs:\x1b[0m " + str(Delta_hs)) print("\n\x1b[31mhs_rate:\x1b[0m " + str(Delta_hs/f_period)) Delta_ht = self.ht_time(f_period) - self.ht_time(0) print("\n\x1b[31mDelta_ht:\x1b[0m " + str(Delta_ht)) print("\n\x1b[31mht_rate:\x1b[0m " + str(Delta_ht/f_period)) print("\n\x1b[31mDelta_h:\x1b[0m " + str(Delta_ht+Delta_hs)) print("\n\x1b[31mh_rate:\x1b[0m " + str((Delta_ht+Delta_hs)/f_period)) print("\n\n")