def compare3(self, w, nu, qT, h, N, h1): #h1= self.get_h(nu,h,N) #print h,N xbot1 = np.pi / h1 * self.get_psi(h1 / np.pi * jn_zeros(nu, N)[0]) / qT xbot2 = np.pi / h * self.get_psi(h / np.pi * jn_zeros(nu, N)[0]) / qT bot1 = w(xbot1) bot2 = w(xbot2) xtop1 = np.pi / h1 * self.get_psi( h1 / np.pi * jn_zeros(nu, N)[-1]) / qT xtop2 = np.pi / h * self.get_psi(h / np.pi * jn_zeros(nu, N)[-1]) / qT #print jv(nu,xtop1*qT),jv(nu,xtop2*qT) #print h1*jn_zeros(nu, 1000)[-1]#h1,np.pi/h1*self.get_psi(h1/np.pi*jn_zeros(nu, 1000)[-1]) top1 = w(xtop1) top2 = w(xtop2) ##print h #val1=np.exp(-np.pi/h)*w(xbot2)#*jv(nu,xbot2*qT) #val2= w(xtop2)*jv(nu,xbot2*qT) val1 = abs(top1 * jv(nu, xtop1 * qT)) + abs( np.exp(-np.pi**2 / 2 / h1) * bot1) val2 = abs(top2 * jv(nu, xtop2 * qT)) + abs( np.exp(-np.pi**2 / 2 / h) * bot2) print 'adog3', abs(top1 * jv(nu, xtop1 * qT)), abs( top2 * jv(nu, xtop2 * qT)), abs(np.exp(-np.pi**2 / 2 / h1)), abs( np.exp(-np.pi**2 / 2 / h)) #print val1>val2 #print val1<val2 return val1 < val2
def get_modes(V): '''frequency cutoff occurs when b(V) = 0. solve eqn 4.19. checks out w/ the function in the fiber ipynb''' l = 0 m = 1 modes = [] while True: if l == 0: #solving dispersion relation leads us to the zeros of J_1 #1st root of J_1 is 0. modes.append((0,1)) while jn_zeros(1,m)[m-1]< V: modes.append((l,m+1)) m+=1 else: #solving dispersion relation leads us to the zeros of J_l-1, neglecting 0 if jn_zeros(l-1,1)[0]>V: break while jn_zeros(l-1,m)[m-1]<V: modes.append((l,m)) m+=1 m = 1 l += 1 return modes
def _findHEcutoff(self, mode): if mode.m > 1: pm = Mode(mode.family, mode.nu, mode.m - 1) lowbound = self.fiber.cutoff(pm) if isnan(lowbound) or isinf(lowbound): raise AssertionError("_findHEcutoff: no previous cutoff for" "{} mode".format(str(mode))) delta = 1 / lowbound if lowbound else self._MCD lowbound += delta else: lowbound = delta = self._MCD ipoints = numpy.concatenate( (jn_zeros(mode.nu, mode.m), jn_zeros(mode.nu - 2, mode.m))) ipoints.sort() ipoints = list(ipoints[ipoints > lowbound]) co = self._findFirstRoot(self._cutoffHE, args=(mode.nu, ), lowbound=lowbound, ipoints=ipoints, delta=delta) if isnan(co): self.logger.error("_findHEcutoff: no cutoff found for " "{} mode".format(str(mode))) return 0 return co
def radial(r, rmax, m, n): #normalized basis of radial eigenfunctions of laplacian m = np.abs(m) N = (rmax**2 / 2) * (sp.jv(m + 1, sp.jn_zeros(m, n)[n - 1]))**2 #normalization return (1. / np.sqrt(N)) * sp.jv(np.abs(m), r * sp.jn_zeros(m, n)[n - 1] / rmax)
def _findHEcutoff(self, mode): if mode.m > 1: pm = Mode(mode.family, mode.nu, mode.m - 1) lowbound = self.fiber.cutoff(pm) if isnan(lowbound) or isinf(lowbound): raise AssertionError("_findHEcutoff: no previous cutoff for" "{} mode".format(str(mode))) delta = 1 / lowbound if lowbound else self._MCD lowbound += delta else: lowbound = delta = self._MCD ipoints = numpy.concatenate((jn_zeros(mode.nu, mode.m), jn_zeros(mode.nu-2, mode.m))) ipoints.sort() ipoints = list(ipoints[ipoints > lowbound]) co = self._findFirstRoot(self._cutoffHE, args=(mode.nu,), lowbound=lowbound, ipoints=ipoints, delta=delta) if isnan(co): self.logger.error("_findHEcutoff: no cutoff found for " "{} mode".format(str(mode))) return 0 return co
def besel_orth(m, n, phi, r): """ TODO: docstring :parameters: m: n: phi: r: :return: B: """ # fonction de bessel fourier orthogonale (BFOFS) if (m == 0): B = sp.jn(0, sp.jn_zeros(0, n)[n - 1] * r) elif (m > 0): B = sp.jn(m, sp.jn_zeros(m, n)[n - 1] * r) * np.sin(m * phi) else: B = sp.jn(np.abs(m), sp.jn_zeros(np.abs(m), n)[n - 1] * r) * np.cos(np.abs(m) * phi) return B
def __init__(self, fs, fx, v_tip, x_m, T=None, phi_x=None, E_x=None, phi_t=None): u""" fs: sampling frequency [Hz] fx: x modulation frequency [Hz] v_tip: tip velocity [µm/s] x_m: x modulation amplitude [µm] T: total data collection time [s] x_total: total distance in x [µm] phi_x: function describing surface potential as a function of x E_x: function describing electric field as a function of x_m """ self.fs = fs self.dt = 1. / fs if phi_t is not None: self.t = np.arange(phi_t.size) * self.dt self.T = phi_t.size * self.dt else: self.T = T self.t = np.arange(0, self.T, self.dt) self.fx = fx self.v_tip = v_tip self.kx = self.fx / self.v_tip self.dx = self.v_tip / self.fs self.ks = 1 / self.dx self.x_m = x_m self.k0_dc = jn_zeros(0, 1)[0] / (2 * np.pi * x_m) self.k0_ac = jn_zeros(1, 1)[0] / (2 * np.pi * x_m) self.f0_dc = self.k0_dc * self.v_tip self.f0_ac = self.k0_ac * self.v_tip self.x_dc = self.v_tip * self.t self.x_ac = x_m * np.sin(2 * np.pi * self.fx * self.t) self.x = self.x_dc + self.x_ac if phi_x is not None: self.phi_x = phi_x self.phi = self.phi_x(self.x) elif E_x is not None: self.E_x = E_x self.E_x_dc = self.E_x(self.x_dc) self.phi_x = -1 * np.cumsum(self.E_x_dc) * self.dx self.phi = np.interp(self.x, self.x_dc, self.phi_x) elif phi_t is not None: self.phi = phi_t else: raise ValueError("Must specify phi_x or E_x")
def get_mode_cutoffs(l, mmax): from scipy.special import jn_zeros if l > 0: return jn_zeros(l-1, mmax) else: if mmax > 1: return np.concatenate(((0.,),jn_zeros(l-1, mmax-1))) else: return np.array((0.,))
def get_qln(l, nmax, nstop=100, zerolminus2=None, zerolminus1=None): """Returns the zeros of the spherical Bessel function. Begins by assuming that the zeros of the spherical Bessel function for l lie exactly between the zeros of the Bessel function between l and l+1. This allows us to use scipy's jn_zeros function. However, this function fails to return for high n. To work around this we estimate the first 100 zeros using scipy's jn_zero function and then iteratively find the roots of the next zero by assuming the next zero occurs pi away from the last one. Brent's method is then used to find a zero between pi/2 and 3pi/2 from the last zero. Parameters ---------- l : int Spherical Bessel function mode. nmax : int The maximum zero found for the spherical Bessel Function. nstop : int For n <= nstop we use scipy's jn_zeros to guess where the first nstop zeros are. These estimates are improved using Brent's method and assuming zeros lie between -pi/2 and pi/2 from the estimates. """ if nmax <= nstop: nstop = nmax if zerolminus2 is None and zerolminus1 is None: z1 = special.jn_zeros(l, nstop) z2 = special.jn_zeros(l + 1, nstop) zeros_approx = np.ndarray.tolist(0.5 * (z1 + z2)) zeros = [] for i in range(0, len(zeros_approx)): a = zeros_approx[i] - 0.5 * np.pi b = zeros_approx[i] + 0.5 * np.pi val = optimize.brentq(get_jl, a, b, args=(l)) zeros.append(val) if nstop != nmax: n = nstop while n < nmax: zero_last = zeros[-1] a = zero_last + 0.5 * np.pi b = zero_last + 1.5 * np.pi val = optimize.brentq(get_jl, a, b, args=(l)) zeros.append(val) n += 1 else: dz = zerolminus1 - zerolminus2 z1 = zerolminus1 + 0.5 * dz z2 = zerolminus2 + 1.5 * dz zeros_approx = np.ndarray.tolist(0.5 * (z1 + z2)) zeros = [] for i in range(0, len(zeros_approx)): a = zeros_approx[i] - 0.5 * np.pi b = zeros_approx[i] + 0.5 * np.pi val = optimize.brentq(get_jl, a, b, args=(l)) zeros.append(val) zeros = np.array(zeros) return zeros
def get_k_r_j(self,j_nu=0,n_zeros=1000,#rmin=0.1,rmax=100,kmax=10,kmin=1.e-4, n_zeros_step=1000,prune_r=0,prune_log_space=True): while True: if isinstance(j_nu,int): zeros=jn_zeros(j_nu,n_zeros) else: def jv2(x): return jv(j_nu,x) zeros_t=jn_zeros(j_nu-0.5,n_zeros)+0.7852 zeros=np.zeros_like(zeros_t) zeros[:5500]= fsolve(jv2,zeros_t[:5500]) zi=interp1d(zeros_t[:5500],zeros[:5500]-zeros_t[:5500], bounds_error=False,fill_value='extrapolate',kind=0) zeros=zi(zeros_t)+zeros_t #this is bad, but can't find zeros of spherical right now. .7852 does make it #better by ensuring most values are <1.e-3 k=zeros/zeros[-1]*self.kmax[j_nu] r=zeros/self.kmax[j_nu] if min(r)>self.rmin[j_nu]: self.kmax[j_nu]=min(zeros)/self.rmin[j_nu] print('changed kmax to',self.kmax[j_nu],' to cover rmin') continue elif max(r)<self.rmax[j_nu]: n_zeros+=n_zeros_step print('j-nu=',j_nu,' not enough zeros to cover rmax, increasing by ',n_zeros_step,' to',n_zeros) elif min(k)>self.kmin[j_nu]: n_zeros+=n_zeros_step print('j-nu=',j_nu,' not enough zeros to cover kmin, increasing by ',n_zeros_step,' to',n_zeros) else: break rmin2=r[r<=self.rmin[j_nu]][-1] rmax2=r[r>=self.rmax[j_nu]][0] x=r<=rmax2 x*=r>=rmin2 r=r[x] if prune_r!=0: print('pruning r, log_space,n_f:',prune_log_space,prune_r) N=len(r) if prune_log_space: idx=np.unique(np.int64(np.logspace(0,np.log10(N-1),N/prune_r)))#pruning can be worse than prune_r factor due to repeated numbers when logspace number are convereted to int. idx=np.append([0],idx) else: idx=np.arange(0,N-1,step=prune_r) idx=np.append(idx,[N-1]) r=r[idx] print('pruned r:',len(r)) r=np.unique(r) print('nr:',len(r)) J=jn(j_nu,np.outer(r,k)) J_nu1=jn(j_nu+1,zeros) return k,r,J,J_nu1,zeros
def __init__(self, fs, fx, v_tip, x_m, T=None, phi_x=None, E_x=None, phi_t=None): u""" fs: sampling frequency [Hz] fx: x modulation frequency [Hz] v_tip: tip velocity [µm/s] x_m: x modulation amplitude [µm] T: total data collection time [s] x_total: total distance in x [µm] phi_x: function describing surface potential as a function of x E_x: function describing electric field as a function of x_m """ self.fs = fs self.dt = 1./fs if phi_t is not None: self.t = np.arange(phi_t.size) * self.dt self.T = phi_t.size * self.dt else: self.T = T self.t = np.arange(0, self.T, self.dt) self.fx = fx self.v_tip = v_tip self.kx = self.fx / self.v_tip self.dx = self.v_tip / self.fs self.ks = 1 / self.dx self.x_m = x_m self.k0_dc = jn_zeros(0, 1)[0] / (2 * np.pi * x_m) self.k0_ac = jn_zeros(1, 1)[0] / (2 * np.pi * x_m) self.f0_dc = self.k0_dc * self.v_tip self.f0_ac = self.k0_ac * self.v_tip self.x_dc = self.v_tip * self.t self.x_ac = x_m * np.sin(2*np.pi*self.fx*self.t) self.x = self.x_dc + self.x_ac if phi_x is not None: self.phi_x = phi_x self.phi = self.phi_x(self.x) elif E_x is not None: self.E_x = E_x self.E_x_dc = self.E_x(self.x_dc) self.phi_x = -1 * np.cumsum(self.E_x_dc) * self.dx self.phi = np.interp(self.x, self.x_dc, self.phi_x) elif phi_t is not None: self.phi = phi_t else: raise ValueError("Must specify phi_x or E_x")
def test_disk_bessel_zeros(Nphi, Nr, m, radius, dtype): # Bases c = coords.PolarCoordinates('phi', 'r') d = distributor.Distributor((c, )) b = basis.DiskBasis(c, (Nphi, Nr), radius=radius, dtype=dtype) b_S1 = b.S1_basis() phi, r = b.local_grids((1, 1)) # Fields f = field.Field(dist=d, bases=(b, ), dtype=dtype) τ_f = field.Field(dist=d, bases=(b_S1, ), dtype=dtype) k2 = field.Field(name='k2', dist=d, dtype=dtype) # Parameters and operators lap = lambda A: operators.Laplacian(A, c) Lift = lambda A: operators.Lift(A, b, -1) # Bessel equation: k^2*f + lap(f) = 0 problem = problems.EVP([f, τ_f], k2) problem.add_equation((k2 * f + lap(f) + Lift(τ_f), 0)) problem.add_equation((f(r=radius), 0)) # Solver solver = solvers.EigenvalueSolver(problem) print(solver.subproblems[0].group) for sp in solver.subproblems: if sp.group[0] == m: break else: raise ValueError("Could not find subproblem with m = %i" % m) solver.solve_dense(sp) # Compare eigenvalues n_compare = 5 selected_eigenvalues = np.sort(solver.eigenvalues)[:n_compare] analytic_eigenvalues = (spec.jn_zeros(m, n_compare) / radius)**2 assert np.allclose(selected_eigenvalues, analytic_eigenvalues)
def cutoff_wavelength(a, NA, ell=0, q=np.inf): """ Calculate the cutoff wavelength for an optical fiber. The default operation is for this function to calculate the cutoff wavelength for the fundamental mode of a step-index fiber. The cutoff wavelength for higher order modes may be found by specifying a different value of ell. If the cutoff wavelength for a graded index fiber is desired, then specify a different value for q. Args: a : radius of the fiber [m] NA : numerical aperture of the fiber [-] ell : (optional) mode number [-] q : (optional) parameter for graded index fiber [-] Returns: shortest wavelength for operation in the specified mode [m] """ Vc, = jn_zeros(int(ell), 1) if np.isfinite(q): # graded index fiber Vc *= np.sqrt(1 + 2 / q) return 2 * np.pi * a * NA / Vc
def compare(self, w, b_min_half, b_max_dub,nu,storage,peak,bc,qT): zero1 = jn_zeros(nu, 1)[0] try: top = stor[b_max_dub] except: top = w(b_max_dub) storage[b_max_dub] = top try: bot = stor[b_min_half] except: bot = w(b_min_half) storage[b_min_half] = bot if bot > peak: peakval = bot bcc = b_min_half elif top > peak: peakval = top bcc = b_max_dub else: peakval = peak bcc = bc if (b_min_half/np.pi/zero1**2*qT)> 0.05: return True,storage,peakval,bcc else: return (b_min_half/np.pi/zero1**2*qT)**2*bot>top,storage,peakval,bcc
def simulate(self): at = self.__attributes op = self.__options profile, membrane_transmission = self.__build_zone_plate_profile() # Loading the position of the zeros of the 1st order Bessel function, as much position as N+1. c = jn_zeros(0, self.n_points + 1) # Definition of the position where the calculated input and transformed # functions are evaluated. We define also the maximum frequency in the # angular domain. q_max = c[self.n_points] / (2 * numpy.pi * self.max_radius ) # Maximum frequency r = c[:self.n_points] * self.max_radius / c[ self.n_points] # Radius vector q = c[:self.n_points] / (2 * numpy.pi * self.max_radius ) # Frequency vector # Recalculation of the position where the initial profile is defined. profile_h = self.__get_profile_h(profile, r) if op.store_partial_results: map_int = numpy.zeros((self.n_slices + self.n_z, self.n_points)) map_complex = numpy.full((self.n_slices + self.n_z, self.n_points), 0j) else: map_int = numpy.zeros((self.n_z, self.n_points)) map_complex = numpy.full((self.n_z, self.n_points), 0j) # Calculation of the first angular spectrum # -------------------------------------------------------------------------- print("Initialization, (or Slice #: ", 1, ")") field0 = profile_h * membrane_transmission if op.store_partial_results: map_int[0, :] = numpy.multiply(numpy.abs(field0), numpy.abs(field0)) map_complex[0, :] = field0[0:self.n_points] four0 = hankel_transform(field0, self.max_radius, c, multipool=self.multipool) field0 = profile_h if op.with_multi_slicing: four0 = self.__propagate_multislicing(map_int, map_complex, field0, four0, q_max, q, c) if op.with_range: self.__propagate_on_range(map_int, map_complex, four0, q_max, q, c) else: self.__propagate_to_focus(map_int, map_complex, four0, q_max, q, c) efficiency = self.__calculate_efficiency( -1, map_int, profile_h, r, int(numpy.floor(10 * at.b_min / self.step))) return map_int, map_complex, efficiency
def __init__(self, N=32): self.N = N self.roots = jn_zeros(0, N + 1) self.j = self.roots[0:-1] self.j_Np1 = self.roots[-1] # S in Yu et al. self.J1sqd = jv(1, self.j)**2 self.C = 2 * jv(0, outer(self.j, self.j) / self.j_Np1) / self.J1sqd
def rev_bessfc(y, S, phi, ampl, symb): zer = jn_zeros(0, 16) res = lambda x: j0(y * zer[int(x[0])]) return res
def compute_all_robin_roots(beta, n, roots): ''' :param beta: f = beta*J_n(x) + dJ_n(x)/dn = 0 this is how Robin is posed here :param n: order of J_n :param roots: number of roots :return: np array with all the roots of f ''' bessel_roots = ss.jn_zeros(n,roots) der_bessel_roots = ss.jnp_zeros(n,roots) result = np.zeros(roots) for k in range(0,roots): if (n == 0 and k == 0): result[k] = optimize.bisect(alpha_function, 0, bessel_roots[k], args=(n,beta)) else: if (n == 0): result[k] = optimize.bisect(alpha_function, min(der_bessel_roots[k-1], bessel_roots[k]), max(der_bessel_roots[k-1], bessel_roots[k]), args=(n,beta)) else: if (alpha_function(0,n,beta) == 0): result[0] = 0 result[k] = optimize.bisect(alpha_function, min(der_bessel_roots[k - 1], bessel_roots[k - 1]), max(der_bessel_roots[k - 1], bessel_roots[k - 1]), args=(n, beta)) else: result[k] = optimize.bisect(alpha_function, min(der_bessel_roots[k], bessel_roots[k]), max(der_bessel_roots[k], bessel_roots[k]), args=(n,beta)) return result
def check_HankelTransform(s, funcanddoc, funcanddoc_, args, order, m, ng, ng0, shanks_ind): """check if a HankelTransform gives it's analytical solution Parameters ---------- s : float transform variable func, funcdoc: function and functions doc function to transform func_, func_doc : function and functin doc analytical transform of `func` other: see HankelTransform """ (func, funcdoc) = funcanddoc (func_, func_doc) = funcanddoc_ if func == hankel3: points = args[0] / jn_zeros(0, 70) atol = 1e-4 else: points = None atol = 1e-5 h = HankelTransform(func, args, order, m, points, ng, ng0, shanks_ind) assert_allclose(h(s)[0], func_(s, *args), atol=atol)
def plotcutoff(f): for n in (1.46, 1.48, 1.50): if f.n[0] > f.n[1]: f.n[0] = n else: f.n[1] = n mu = abs(f.n[2]**2 - f.n[0]**2) / abs(f.n[2]**2 - f.n[1]**2) if mu > 1: mu = 1 / mu rho = numpy.linspace(0, 1) v0 = numpy.zeros(rho.shape) for i, r in enumerate(rho): f.rho[0] = r * f.rho[1] roots = findRoots(f, Mode("TE", 0, 1), numpy.linspace(2, 15, 500)) if roots: v0[i] = roots[0] v0 = numpy.ma.masked_equal(v0, 0) pyplot.plot(v0, rho, label="$\\mu = {:.2f}$".format(mu) if mu else '') rj0 = jn_zeros(0, 1)[0] pyplot.axvline(rj0, ls='--', color='k') pyplot.xlim((2, 6)) pyplot.ylim((0, 1)) pyplot.legend(loc='best') pyplot.xlabel('Normalized frequency $V_0$') pyplot.ylabel('Radii ratio $\\rho$') pyplot.title(f.name)
def spheromak(Bx, By, Bz, domain, center=(0, 0, 0), B0=1, R=1, L=1): """domain must be a dedalus domain Bx, By, Bz must be Dedalus fields """ # parameters xx, yy, zz = domain.grids() j1_zero1 = jn_zeros(1, 1)[0] kr = j1_zero1 / R kz = np.pi / L lam = np.sqrt(kr**2 + kz**2) # construct cylindrical coordinates centered on center r = np.sqrt((xx - center[0])**2 + (yy - center[1])**2) theta = np.arctan2(yy, xx) z = zz - center[2] # calculate cylindrical fields Br = -B0 * kz / kr * j1(kr * r) * np.cos(kz * z) Bt = B0 * lam / kr * j1(kr * r) * np.sin(kz * z) # convert back to cartesian, place on grid. Bx['g'] = Br * np.cos(theta) - Bt * np.sin(theta) By['g'] = Br * np.sin(theta) + Bt * np.cos(theta) Bz['g'] = B0 * j0(kr * r) * np.sin(kz * z)
def MHCDEigenFrequencies ( dg, r, Uhv=4e3, rho=1.2041, yDirNum=4, xDirNum=4 ): """Eigenfrequency calculatioon of a micro hollow cathode discharge. Args: dg : Distance of electrodes (discharge gap). r : Radius of the discharge hole. Uhv : Voltage between electrodes. rho : Gas density. yDirNum : Col Number of eigenfrequencies. xDirNum : Row number of eigenfrequencies. Returns: Returns the eigenfrequencies of the discharge. """ from scipy.special import jn, jn_zeros import numpy as np k = 3 e0 = 8.854187817e-12 # As x (Vm)^-1 vm = np.sqrt ( e0 / rho ) * Uhv / dg bessel_roots = np.zeros ( ( xDirNum, yDirNum) ) for x in range ( 0, xDirNum): b = jn_zeros (x, yDirNum) for y in range ( 0, yDirNum): bessel_roots[y][x] = b[y] f = bessel_roots * vm * k / ( 2*np.pi*r) return f
def beta_pec(self, w, alpha): """Return phase constant of PEC waveguide Args: w: A complex indicating the angular frequency alpha: A tuple (pol, n, m) where pol is 'M' for TM mode or 'E' for TE mode, n is the order of the mode, and m is the number of modes in the order and the polarization. Returns: h: A complex indicating the phase constant. """ w_comp = w.real + 1j * w.imag pol, n, m = alpha if pol == "E": chi = jnp_zeros(n, m)[-1] elif pol == "M": chi = jn_zeros(n, m)[-1] else: raise ValueError("pol must be 'E' or 'M") val = np.sqrt(self.fill(w_comp) * w_comp**2 - chi**2 / self.r**2) if abs(val.real) > abs(val.imag): if val.real < 0: val *= -1 else: if val.imag < 0: val *= -1 return val
def bessel_order(self, value): self._bessel_order = value krho = self.transversal_wavenumber if krho != 0: self._bessel_spot = ss.jn_zeros(value, 1)[0] / krho else: self._bessel_spot = ma.inf
def __init__(self, ktheta_min, ktheta_max, window_function_a, window_function_b, cosmo_dict=None, **kws): self._j2_limit = special.jn_zeros(2,4)[-1] Kernel.__init__(self, ktheta_min, ktheta_max, window_function_a, window_function_b, cosmo_dict=None, **kws)
def disk_harmonic_energy(n, m, bc='dirichlet'): '''Get the energy of a disk harmonic function. This allows for functions to sort a disk harmonic mode basis on energy. Parameters ---------- n : int Radial order m : int Azimuthal order bc : string The boundary conditions to use. This can be either 'dirichlet', or 'neumann' for a Dirichlet or Neumann boundary condition respectively. Returns ------- scalar The energy corresponding to the mode. ''' m = abs(m) if bc == 'dirichlet': lambda_mn = jn_zeros(m, n)[-1] elif bc == 'neumann': lambda_mn = jnp_zeros(m, n)[-1] else: raise RuntimeError('Boundary condition not recognized.') return lambda_mn**2
def init_rkr_jroot_both(self, Rmax, Nr, dtype): """ Setup radial `r` and spectral `kr` grids, and fix data type. Parameters ---------- Rmax: float (m) Radial size of the calculation domain. Nr: int Number of nodes of the radial grid. dtype: type Data type to be used. """ self.Rmax = Rmax self.Nr = Nr self.dtype = dtype alpha = jn_zeros(0, Nr + 1) alpha_np1 = alpha[-1] alpha = alpha[:-1] self.r = Rmax * alpha / alpha_np1 self.kr = self.bcknd.to_device(alpha / Rmax)
def getSpheromakFieldAtPosition(x, y, z, center=(0,0,1), B0=1, R=1, L=1): """The spheromak center in z must be L. """ # parameters j1_zero1 = jn_zeros(1,1)[0] kr = j1_zero1/R kz = np.pi/L lam = np.sqrt(kr**2 + kz**2) # construct cylindrical coordinates centered on center r = np.sqrt((x- center[0])**2 + (y- center[1])**2) theta = np.arctan2(y,x) centZ = z - center[2] # calculate cylindrical fields Br = -B0 * kz/kr * j1(kr*r) * np.cos(kz*centZ) Bt = B0 * lam/kr * j1(kr*r) * np.sin(kz*centZ) # convert back to cartesian, place on grid. Bx = Br*np.cos(theta) - Bt*np.sin(theta) By = Br*np.sin(theta) + Bt*np.cos(theta) Bz = B0 * j0(kr*r) * np.sin(kz*centZ) return Bx, By, Bz
def kc(self) -> NumberLike: """ Cut-off wave number. Defined as .. math:: k_c = \\frac{u_{mn}}{R} where R is the radius of the waveguide, and u_mn is: * the n-th root of the m-th Bessel function for 'tm' mode * the n-th root of the Derivative of the m-th Bessel function for 'te' mode. Returns ------- kc : number cut-off wavenumber """ if self.mode_type == "te": u = jnp_zeros(self.m, self.n)[-1] elif self.mode_type == "tm": u = jn_zeros(self.m, self.n)[-1] return u / self.r
def gravground( x , y , g , G , *args , **kwargs): ''' def gravground( x , y , g , G , *args , **kwargs): Create the Thomas-Fermi ground state for a gravitational system ''' X,Y = np.meshgrid(x,y) R = np.sqrt( X ** 2. + Y ** 2. ) bj0z1 = jn_zeros( 0, 1 ) #First zero of zeroth order besselj scaling = np.sqrt( 2 * np.pi * G / g ) gr0 = bj0z1 / scaling Rprime = R * scaling gtfsol = j0( Rprime ) * np.array( [ map( int,ii ) for ii in map( lambda rad: rad <= gr0, R ) ] ) gtfsol *= scaling ** 2. / ( 2 * np.pi * j1( bj0z1 ) * bj0z1 ) return gtfsol
def bessel_zeros(order, index): """Returns a Bessel zero given the function's order and zero index. This function is a wrapper around Scipy's Bessel function zero generator. For some reason, the Scipy function returns all zeros between the given number and the first zero. This function extracts only the wanted zero given the index. This is for Bessel functions of the first kind. Parameters ---------- order : int The integer order of the Bessel function of the first kind. index : int The zero's index that is desired. Returns ------- zero : float The value of the zero at the given index of the given Bessel function. """ # Basic type checking. order = int(order) index = int(index) # For some reason, scipy wants to return all zeros from 1 to n. This # function only wants the last one. zero_array = sp_spcl.jn_zeros(order, index) zero = zero_array[-1] return zero
def QDHT_init(self, p, N, rmax): """ Calculate r and nu for the QDHT. Reference : Guizar-Sicairos et al., J. Opt. Soc. Am. A 21 (2004) Also store the auxilary matrix T and vectors J and J_inv required for the transform. Grid : r_n = alpha_{p,n}*rmax/alpha_{p,N+1} where alpha_{p,n} is the n^th zero of the p^th Bessel function """ # Calculate the zeros of the Bessel function zeros = jn_zeros(p, N + 1) # Calculate the grid last_alpha = zeros[-1] # The N+1^{th} zero alphas = zeros[:-1] # The N first zeros numax = last_alpha / (2 * np.pi * rmax) self.N = N self.rmax = rmax self.numax = numax self.r = rmax * alphas / last_alpha self.nu = numax * alphas / last_alpha # Calculate and store the vector J J = abs(jn(p + 1, alphas)) self.J = J self.J_inv = 1. / J # Calculate and store the matrix T denom = J[:, np.newaxis] * J[np.newaxis, :] * last_alpha num = 2 * jn( p, alphas[:, np.newaxis] * alphas[np.newaxis, :] / last_alpha) self.T = num / denom
def test_bessel_zeros(order: int, n_zeros: int, engine): tolerance = 1e-5 matlab_zeros = engine.bessel_zeros(1.0, float(order), float(n_zeros), float(tolerance), nargout=1) matlab_zeros = np.asarray(matlab_zeros).transpose()[0, :] python_zeros = scipy_bessel.jn_zeros(order, n_zeros) assert np.allclose(matlab_zeros, python_zeros)
def wig_d_smoothing(self, s1_s2): if self.wig_d_taper_order_low is None or self.wig_d_taper_order_high is None: return if self.wig_d_taper_order_low <= 0: #try 16, 20 return if self.wig_d_taper_order_high <= 0: self.wig_d_taper_order_high = self.wig_d_taper_order_low + 2 bessel_order = np.absolute(s1_s2[0] - s1_s2[1]) zeros = jn_zeros( bessel_order, max(self.wig_d_taper_order_low, self.wig_d_taper_order_high)) l_max_low = zeros[self.wig_d_taper_order_low - 1] / self.theta[s1_s2] if l_max_low.max() > self.l.max(): print( 'Wigner ell max of ', self.l.max(), ' too low for theta_min. Recommendation based on first few zeros of bessel ', s1_s2, ' :', zeros[:5] / self.theta[s1_s2].min()) l_max_high = zeros[self.wig_d_taper_order_high - 1] / self.theta[s1_s2] if self.wig_d_taper_order_high == 0: l_max_high[:] = self.l.max() l_max_low[l_max_low > self.l.max()] = self.l.max() l_max_high[l_max_high > self.l.max()] = self.l.max() taper_f = np.cos( (self.l[None, :] - l_max_low[:, None]) / (l_max_high[:, None] - l_max_low[:, None]) * np.pi / 2.) x = self.l[None, :] >= l_max_low[:, None] y = self.l[None, :] >= l_max_high[:, None] taper_f[~x] = 1 taper_f[y] = 0 self.wig_d[s1_s2] = self.wig_d[s1_s2] * taper_f
def __init__(self, ktheta_min, ktheta_max, window_function_a, window_function_b, cosmo_multi_epoch=None, force_quad=False, **kws): self._j2_limit = special.jn_zeros( 2, defaults.default_precision["kernel_bessel_limit"])[-1] Kernel.__init__(self, ktheta_min, ktheta_max, window_function_a, window_function_b, cosmo_multi_epoch, force_quad, **kws)
def sine_angular_control(s, t, v=1.0): # Amplitude is the first root of the 0-th order Bessel function A = jn_zeros(0,1)[0] v = v*numpy.ones(t.shape) a = A*numpy.sin(t) return numpy.vstack([v,a]).T
def _transversal_bessel(self,u,p): from scipy.special import jn, jn_zeros first_zero = jn_zeros(self.transversal_bessel_order,1) r = (u-self.transversal_offset[p])/(self.transversal_width[p]/2.0) shape = jn(self.transversal_bessel_order,r*(first_zero[0])) if self.transversal_kill_after_first_zero: shape_kill = np.abs(r*(first_zero[0]))<=(first_zero[0]) shape = shape_kill*shape return shape
def _amplitudeFromPeak(peak, x, y, radius, x_0=10, y_0=10): """ This function can be used to estimate an Airy disc amplitude from the peak pixel, centroid and radius. """ rz = jn_zeros(1, 1)[0] / np.pi r = np.sqrt((x - x_0) ** 2 + (y - y_0) ** 2) / (radius / rz) if r == 0.: return peak rt = np.pi * r z = (2.0 * j1(rt) / rt)**2 amp = peak / z return amp
def __init__(self, amplitude, x_0, y_0, radius, **kwargs): if self._j1 is None: try: from scipy.special import j1, jn_zeros self.__class__._j1 = j1 self.__class__._rz = jn_zeros(1, 1)[0] / np.pi # add a ValueError here for python3 + scipy < 0.12 except ValueError: raise ImportError("AiryDisk2D model requires scipy > 0.11.") super(AiryDisk2D, self).__init__( amplitude=amplitude, x_0=x_0, y_0=y_0, radius=radius, **kwargs)
def _transversal_bessel(self,y): from scipy.special import jn, jn_zeros first_zero = jn_zeros(self.transversal_bessel_order,1) shape = jn(self.transversal_bessel_order,(y-self.transversal_offset)*(first_zero[0])/(self.transversal_width/2.0)) if self.transversal_kill_after_first_zero: shape_kill = np.abs((y-self.transversal_offset)*(first_zero[0])/(self.transversal_width/2.0))<=(first_zero[0]) shape = shape_kill*shape return shape
def __init__(self, ktheta_min, ktheta_max, window_function_a, window_function_b, cosmo_multi_epoch=None, force_quad=False, **kws): self.initialized_spline = False self.ln_ktheta_min = numpy.log(ktheta_min) self.ln_ktheta_max = numpy.log(ktheta_max) self.window_function_a = copy.copy(window_function_a) self.window_function_b = copy.copy(window_function_b) self.z_min = numpy.max([self.window_function_a.z_min, self.window_function_b.z_min]) self.z_max = numpy.min([self.window_function_a.z_max, self.window_function_b.z_max]) if cosmo_multi_epoch is None: cosmo_multi_epoch = cosmology.MultiEpoch( self.z_min, self.z_max) self.cosmo = cosmo_multi_epoch self.window_function_a.set_cosmology_object(self.cosmo) self.window_function_b.write('test_window_before') self.window_function_b.set_cosmology_object(self.cosmo) self.window_function_b.write('test_window_after') self.chi_min = numpy.max([defaults.default_precision["window_precision"], self.cosmo.comoving_distance(self.z_min)]) self.chi_max = self.cosmo.comoving_distance(self.z_max) self._window_norm = integrate.romberg( lambda chi: (self.window_function_a.window_function(chi)* self.window_function_b.window_function(chi)), self.chi_min, self.chi_max, vec_func=True, tol=defaults.default_precision["global_precision"], rtol=defaults.default_precision["kernel_precision"], divmax=defaults.default_precision["divmax"]) self._ln_ktheta_array = numpy.linspace( self.ln_ktheta_min, self.ln_ktheta_max, defaults.default_precision["kernel_npoints"]) self._kernel_array = numpy.zeros_like(self._ln_ktheta_array, dtype='float128') self._j0_limit = special.jn_zeros( 0, defaults.default_precision["kernel_bessel_limit"])[-1] self._force_quad = force_quad self._find_z_bar()
def __call__(self, mode): nu = mode.nu m = mode.m if mode.family is ModeFamily.LP: if nu == 0: nu = 1 m -= 1 else: nu -= 1 elif mode.family is ModeFamily.HE: if nu == 1: m -= 1 else: return self._findHEcutoff(mode) return jn_zeros(nu, m)[m-1]
def f(self, r, theta, t, m, n): """============================================================= (m,n) Modo normal: Calcula el modo normal (m,n) de oscilación de la mebrana circular, donde n es el numero cuantico radial y m el numero angular. ARGUMENTOS: *Variable r r *Variable theta theta *Variable t t *Numero cuantico angular m *Numero cuantico radial n =============================================================""" lambda_mn = sp.jn_zeros(m, n)[-1] return sp.jn(m, lambda_mn * r / self.R) * np.cos(lambda_mn * self.c * t / self.R) * np.cos(m * theta)
def evaluate(cls, x, y, amplitude, x_0, y_0, radius): """Two dimensional Airy model function""" if cls._rz is None: try: from scipy.special import j1, jn_zeros cls._rz = jn_zeros(1, 1)[0] / np.pi cls._j1 = j1 except ValueError: raise ImportError('AiryDisk2D model requires scipy > 0.11.') r = np.sqrt((x - x_0) ** 2 + (y - y_0) ** 2) / (radius / cls._rz) # Since r can be zero, we have to take care to treat that case # separately so as not to raise a numpy warning z = np.ones(r.shape) rt = np.pi * r[r > 0] z[r > 0] = (2.0 * cls._j1(rt) / rt) ** 2 z *= amplitude return z
def __init__(self, cosmo, surv, lmax=1000, **kwargs): self.cosmo = cosmo self.surv = surv self._n_a = 256 + 1 self._lmax = lmax # Number of points in the dsbt self._chimax = self.surv.chimax(cosmo) self._kmax_bessel = 0.5 bess_zeros = jn_zeros(2, 10000) self._nmax = where(bess_zeros > self._kmax_bessel * self._chimax)[0][0] self.besselWindow = BesselWindow(self._nmax, self._lmax, self._kmax_bessel, "qlnTable.dat") self.update(**kwargs)
def _matched_filters(ks, x_m, N_pts, dec=16, window='hann', n_pts_eval_fir=48000): ks = ks / dec N = N_pts // dec k = np.linspace(0, ks/2, n_pts_eval_fir) resp_ac = _j1filt(k * 2 * np.pi * x_m) fir_ac_dec = signal.firwin2(N, k, resp_ac, nyq=k[-1], window=window) fir_dc_dec = signal.firwin(N, jn_zeros(0, 1)[0] / (2*np.pi*x_m), nyq=k[-1], window=window) # Manually force gain to 1 at DC; firwin2 rounding errors probable cause of # minor losses (< 1 percent) fir_ac_dec = fir_ac_dec / np.sum(fir_ac_dec) fir_dc_dec = fir_dc_dec / np.sum(fir_dc_dec) fir_ac = np.fft.irfft(np.fft.rfft(fir_ac_dec), fir_ac_dec.size * dec) fir_dc = np.fft.irfft(np.fft.rfft(fir_dc_dec), fir_dc_dec.size * dec) return fir_ac, fir_dc
def _bessel_pulse(self,x,y,z,t=0): from scipy.special import jn, jn_zeros first_zero = jn_zeros(self.bessel_order,1) wave = np.zeros( [6,x.shape[0],y.shape[1],z.shape[2]], order='F') shapex1 = self.transversal_function(y,z)*jn(self.bessel_order,(x - (self.offset[1] + self.v[0]*t)*(first_zero[0])/(self.pulse_width/2.0))) shapex2 = self.transversal_function(y,z)*jn(self.bessel_order,(x - (self.offset[5] + self.v[0]*t)*(first_zero[0])/(self.pulse_width/2.0))) if self.kill_after_first_zero: shape_kill1 = np.abs((x - (self.offset[1] + self.v[0]*t)*(first_zero[0])/(self.pulse_width/2.0)))<=(first_zero[0]) shape_kill2 = np.abs((x - (self.offset[5] + self.v[0]*t)*(first_zero[0])/(self.pulse_width/2.0)))<=(first_zero[0]) shapex1 = shape_kill1*shapex1 shapex2 = shape_kill2*shapex2 wave[1,:,:,:] = self.amplitude[1]*shapex1 wave[5,:,:,:] = self.amplitude[5]*shapex2 return wave
def __init__(self, ktheta_min, ktheta_max, window_function_a, window_function_b, cosmo_dict=None, **kws): self.initialized_spline = False self.ln_ktheta_min = numpy.log(ktheta_min) self.ln_ktheta_max = numpy.log(ktheta_max) if cosmo_dict is None: cosmo_dict = defaults.default_cosmo_dict self.window_function_a = window_function_a self.window_function_b = window_function_b self.window_function_a.set_cosmology(cosmo_dict) self.window_function_b.set_cosmology(cosmo_dict) self.chi_min = self.window_function_a.chi_min self.z_min = self.window_function_a.z_min if self.window_function_b.chi_min < self.chi_min: self.chi_min = self.window_function_b.chi_min self.z_min = self.window_function_b.z_min self.chi_max = self.window_function_a.chi_max self.z_max = self.window_function_a.z_max if self.window_function_b.chi_max > self.chi_max: self.chi_max = self.window_function_b.chi_max self.z_max = self.window_function_b.z_max self.cosmo = cosmology.MultiEpoch(self.z_min, self.z_max, cosmo_dict) self._ln_ktheta_array = numpy.linspace( self.ln_ktheta_min, self.ln_ktheta_max, defaults.default_precision["kernel_npoints"]) self._kernel_array = numpy.zeros_like(self._ln_ktheta_array) self._j0_limit = special.jn_zeros(0,4)[-1] self._find_z_bar()
def _bessel_pulse(self,x,y,t=0): from scipy.special import jn, jn_zeros first_zero = jn_zeros(self.bessel_order,1) wave = np.zeros( [3,x.shape[0],y.shape[1]], order='F') shapex = jn(self.bessel_order,(x - (self.offset[1] + self.v[0]*t)*(first_zero[0])/(self.pulse_width[0]/2.0))) if self.kill_after_first_zero: shape_kill = np.abs((x - (self.offset[1] + self.v[0]*t)*(first_zero[0])/(self.pulse_width[0]/2.0)))<=(first_zero[0]) shapex = shape_kill*shapex shapey = self.transversal_function(y) shape = shapey*shapex wave[0,:,:] = self.amplitude[0]*shape wave[1,:,:] = self.amplitude[1]*shape wave[2,:,:] = self.amplitude[2]*shape return wave
def TFError( self, verbose = False): ''' TFError( self, verbose = False): A function to evaluate the deviation of the solution from the Thomas-Fermi approximation. Setting verbose to true will produce plots of the wavefunction and TF approximation ''' enList = self.energies( verbose = False ) #mu = <K> + <Vext> + 2 * <Vsi> + 0.5 * <Vgrav> fineX = np.arange(self.xmin , self.xmax, (self.xmax - self.xmin) / ( 1e3 * self.npt ), dtype = float ) fineY = fineX X, Y = np.meshgrid( self.x, self.y ) Rsq = X ** 2. + Y ** 2. R = np.sqrt( Rsq ) if self.g != 0 and self.G == 0. and self.P != 0.: #Harmonic case chmpot = enList[3] + enList[0] + 2 * enList[1] r0sq = 2 * chmpot / self.P tfsol = (chmpot / self.g - Rsq * self.P / ( 2 * self.g ) ) * ( map( lambda rsq: rsq - r0sq < 0, Rsq ) ) tferror = np.real( sum( sum( tfsol - abs( self.psi ) ** 2. ) ) ) print 'Thomas-Fermi Error = ', tferror print 'TF Error per cell = ', tferror / self.npt ** 2. if verbose == True: #diagnostic plots tfx = (chmpot / self.g - fineX ** 2. * self.P / ( 2 * self.g ) ) * ( map( lambda fineX: fineX **2. - r0sq < 0, fineX ) ) fig = plt.figure() ax = fig.add_subplot(111) ax.plot(fineX, tfx, label = 'analytic solution') ax.plot(self.x, abs( self.psi[ self.npt//2, : ] ) ** 2., label = 'numerical solution' ) lgd = plt.legend( loc = 'upper right' ) plt.show() elif self.G != 0. and self.g != 0. and self.P == 0.: #Gravitational case bj0z1 = jn_zeros( 0, 1 ) #First zero of zeroth order besselj scaling = np.sqrt( 2 * np.pi * self.G / self.g ) gr0 = bj0z1 / scaling Rprime = R * scaling gtfsol = j0( Rprime ) * np.array( [ map( int,ii ) for ii in map( lambda rad: rad <= gr0, R ) ] ) gtfsol *= scaling ** 2. / ( 2 * np.pi * j1( bj0z1 ) * bj0z1 ) #(abs(self.psi) ** 2.).max() #gtfsol = 1. / ( 4. * gr0 ** 2. * ( 1 - 2 / np.pi ) ) * np.cos( #np.pi * R / ( 2. * gr0 ) ) * map( lambda rsq: rsq - gr0 ** 2. < 0, Rsq ) gtferror = np.real( sum( sum( gtfsol - abs( self.psi ) ** 2. ) ) ) print 'Grav. TF Error = ', gtferror print 'GTF Error per cell = ', gtferror / self.npt ** 2. print 'Analytic norm = ', sum( sum( gtfsol ) ) * self.dx * self.dy if verbose == True: #diagnostic energies gtfwf = np.sqrt( gtfsol ) Ev = 0. Ei = sum( sum( 0.5 * self.g * abs(gtfwf) ** 4. ) ) * self.dx * self.dy GField = self.G * self.dx * self.dy * ( ff.fftshift( ff.ifft2( ff.fft2( ff.fftshift( gtfsol ) ) * abs( ff.fft2( ff.fftshift( -self.log ) ) ) ) ) ) Eg = sum( sum( -1. * GField * gtfsol ) ) * self.dx * self.dy Ekin = sum( sum( gtfwf.conjugate() * ff.fftshift( ff.ifft2( 0.5 * self.ksquare * ff.fft2( ff.fftshift( gtfwf ) ) ) ) ) ) * self.dx * self.dy TFList = [ Ev, Ei, Eg, Ekin ] #glpg = - 1. * ( np.roll( GField, 1, axis = 0 ) #GField is +ve #+ np.roll( GField,-1, axis = 0 ) #+ np.roll( GField, 1, axis = 1 ) #+ np.roll( GField,-1, axis = 1 ) #- 4 * GField ) / self.dx ** 2. #glpd = 2 * np.pi * self.G * gtfsol print '\nTF solution Energies\n' print 'Harmonic PE = ', np.real( TFList[0] ) print 'Interaction PE = ', np.real( TFList[1] ) print 'Gravitational PE = ', np.real( TFList[2] ) print 'Potential Energy = ', np.real( sum( TFList[0:3] ) ) print 'Kinetic Energy = ', np.real( TFList[3] ) print 'Total Energy = ', np.real( sum( TFList ) ) print 'Chemical Potential = ', np.real( TFList[3] + TFList[0] + 2 * TFList[1] + TFList[2] ) print 'Ek - Ev + Ei - G/4 = ', np.real( TFList[3] - TFList[0] + TFList[1] - self.G / 4. ) #diagnostic plots fineXS = fineX * scaling gtx = j0( fineXS ) * np.where( abs(fineX) < gr0, np.ones( len(fineX) ), np.zeros( len(fineX) ) ) gtx *= scaling ** 2. / ( 2 * np.pi * j1( bj0z1 ) * bj0z1 ) fig = plt.figure() ax = fig.add_subplot(111) ax.plot(fineX, gtx, label = 'analytic solution') ax.plot(self.x, abs( self.psi[ self.npt//2, : ] ) ** 2., label = 'numerical solution' ) lgd = plt.legend( loc = 'upper right' ) plt.show() else: print 'A TF approximation for this scenario has not yet been implemented' print 'Sorry about that...'
def drumhead_height(n, k, distance, angle, t): kth_zero = special.jn_zeros(n, k)[-1] return np.cos(t) * np.cos(n * angle) * special.jn(n, distance * kth_zero)
def test_bessel_zeros(): """ Test that we can compute the zeros of the bessel function """ f = Cheb(j0,(0,100)) roots = f.introots() real_roots = jn_zeros(0,len(roots)) np.testing.assert_allclose(roots,real_roots)
x1,x2 = initial while True: # Find slope of secant line connecting x1 and x2 fprime = (fn(x2) - fn(x1))/(x2-x1) # Find where current secant intersects the x-axIs x3 = x2 - fn(x2)*(1./fprime) # If accuracy not achieved, update x1 and x2 and try again if abs(x3 - x2) > tol: x1 = x2 x2 = x3 # If accuracy achieved, break the loop elif abs(x3 - x2) < tol: break return x3 def approxzero(n): return np.pi*(n-0.25) tol = 1e-5 inits = [[1.0,1.5],[4.5,5.0],[8.0,8.5],[11.0,11.5],[14.0,14.5]] zeros = [] for i in range(len(inits)): zeros.append(secant(inits[i],J0,tol)) zeros = np.array(zeros) sci = jn_zeros(0,5)
def __init__(self,amp=1.,ro=1.,hr=1./3.,hz=1./16., maxiter=_MAXITER,tol=0.001,normalize=False, new=True,kmaxFac=2.,glorder=10): """ NAME: __init__ PURPOSE: initialize a double-exponential disk potential INPUT: amp - amplitude to be applied to the potential (default: 1) hr - disk scale-length in terms of ro hz - scale-height tol - relative accuracy of potential-evaluations maxiter - scipy.integrate keyword normalize - if True, normalize such that vc(1.,0.)=1., or, if given as a number, such that the force is this fraction of the force necessary to make vc(1.,0.)=1. OUTPUT: DoubleExponentialDiskPotential object HISTORY: 2010-04-16 - Written - Bovy (NYU) 2013-01-01 - Re-implemented using faster integration techniques - Bovy (IAS) """ Potential.__init__(self,amp=amp) self.hasC= True self._new= new self._kmaxFac= kmaxFac self._glorder= glorder self._ro= ro self._hr= hr self._scale= self._hr self._hz= hz self._alpha= 1./self._hr self._beta= 1./self._hz self._gamma= self._alpha/self._beta self._maxiter= maxiter self._tol= tol self._zforceNotSetUp= True #We have not calculated a typical Kz yet #Setup j0 zeros etc. self._glx, self._glw= nu.polynomial.legendre.leggauss(self._glorder) self._nzeros=100 #j0 for potential and z self._j0zeros= nu.zeros(self._nzeros+1) self._j0zeros[1:self._nzeros+1]= special.jn_zeros(0,self._nzeros) self._dj0zeros= self._j0zeros-nu.roll(self._j0zeros,1) self._dj0zeros[0]= self._j0zeros[0] #j1 for R self._j1zeros= nu.zeros(self._nzeros+1) self._j1zeros[1:self._nzeros+1]= special.jn_zeros(1,self._nzeros) self._dj1zeros= self._j1zeros-nu.roll(self._j1zeros,1) self._dj1zeros[0]= self._j1zeros[0] #j2 for R2deriv self._j2zeros= nu.zeros(self._nzeros+1) self._j2zeros[1:self._nzeros+1]= special.jn_zeros(2,self._nzeros) self._dj2zeros= self._j2zeros-nu.roll(self._j2zeros,1) self._dj2zeros[0]= self._j2zeros[0] if normalize or \ (isinstance(normalize,(int,float)) \ and not isinstance(normalize,bool)): self.normalize(normalize) #Load Kepler potential for large R self._kp= KeplerPotential(normalize=4.*nu.pi/self._alpha**2./self._beta)
def k(m,n): return jn_zeros(n,m)[m-1] # m is 0-indexed here
ax = fig.add_subplot(111, projection='3d') xs = linspace(-1, 1, 100) ys = linspace(-1, 1, 100) X, Y = meshgrid(xs, ys) Z = generate(X, Y, 0.0) wframe = None tstart = time.time() <<<<<<< HEAD for t in linspace(0, 10, 400): print "here",t ======= periods = 2 frames_per = 50 for t in linspace(0, periods*2*pi/jn_zeros(n,m)[m-1], periods*frames_per): >>>>>>> 465ebad10d8aec98e41a530173f7f94f81438aa1 oldcol = wframe Z = generate(X, Y, t) #wframe = ax.plot_wireframe(X, Y, Z, rstride=4, cstride=4) wframe = ax.plot_surface(X, Y, Z, rstride=4, cstride=4, alpha=0.3) # Remove old line collection before drawing if oldcol is not None: ax.collections.remove(oldcol) if n == 0: ax.set_zlim(-1,1) else: ax.set_zlim(-0.5,0.5) plt.draw()
def Plot(x, y, label, figure, line, loc='true') : plt.figure(figure) plt.plot(x, y, line, label=label) plt.title('this function', fontsize='large', va='bottom', ha='right') plt.xlabel('x') plt.ylabel(figure) plt.legend(loc) plt.grid(True) x = np.linspace(0., 20., 100) y1 = spec.jn(0, x) Plot(x, y1, '$J_0(x)$', 1,'-') y2 = spec.jn(1, x) Plot(x, y2, '$J_2(x)$', 1,'--') y3 = spec.jn(2, x) Plot(x, y3, '$J_3(x)$', 1,'-.') y4 = spec.jn(3, x) Plot(x, y4, '$T_4(x)$', 1,':') zeros = spec.jn_zeros(0,6) for xz in zeros : plt.scatter(xz, 0) plt.show()
def __init__(self,amp=1.,hr=1./3.,hz=1./16., maxiter=_MAXITER,tol=0.001,normalize=False, ro=None,vo=None, new=True,kmaxFac=2.,glorder=10): """ NAME: __init__ PURPOSE: initialize a double-exponential disk potential INPUT: amp - amplitude to be applied to the potential (default: 1); can be a Quantity with units of mass density or Gxmass density hr - disk scale-length (can be Quantity) hz - scale-height (can be Quantity) tol - relative accuracy of potential-evaluations maxiter - scipy.integrate keyword normalize - if True, normalize such that vc(1.,0.)=1., or, if given as a number, such that the force is this fraction of the force necessary to make vc(1.,0.)=1. ro=, vo= distance and velocity scales for translation into internal units (default from configuration file) OUTPUT: DoubleExponentialDiskPotential object HISTORY: 2010-04-16 - Written - Bovy (NYU) 2013-01-01 - Re-implemented using faster integration techniques - Bovy (IAS) """ Potential.__init__(self,amp=amp,ro=ro,vo=vo,amp_units='density') if _APY_LOADED and isinstance(hr,units.Quantity): hr= hr.to(units.kpc).value/self._ro if _APY_LOADED and isinstance(hz,units.Quantity): hz= hz.to(units.kpc).value/self._ro self.hasC= True self._kmaxFac= kmaxFac self._glorder= glorder self._hr= hr self._scale= self._hr self._hz= hz self._alpha= 1./self._hr self._beta= 1./self._hz self._gamma= self._alpha/self._beta self._maxiter= maxiter self._tol= tol self._zforceNotSetUp= True #We have not calculated a typical Kz yet #Setup j0 zeros etc. self._glx, self._glw= nu.polynomial.legendre.leggauss(self._glorder) self._nzeros=100 #j0 for potential and z self._j0zeros= nu.zeros(self._nzeros+1) self._j0zeros[1:self._nzeros+1]= special.jn_zeros(0,self._nzeros) self._dj0zeros= self._j0zeros-nu.roll(self._j0zeros,1) self._dj0zeros[0]= self._j0zeros[0] #j1 for R self._j1zeros= nu.zeros(self._nzeros+1) self._j1zeros[1:self._nzeros+1]= special.jn_zeros(1,self._nzeros) self._dj1zeros= self._j1zeros-nu.roll(self._j1zeros,1) self._dj1zeros[0]= self._j1zeros[0] #j2 for R2deriv self._j2zeros= nu.zeros(self._nzeros+1) self._j2zeros[1:self._nzeros+1]= special.jn_zeros(2,self._nzeros) self._dj2zeros= self._j2zeros-nu.roll(self._j2zeros,1) self._dj2zeros[0]= self._j2zeros[0] if normalize or \ (isinstance(normalize,(int,float)) \ and not isinstance(normalize,bool)): #pragma: no cover self.normalize(normalize) #Load Kepler potential for large R self._kp= KeplerPotential(normalize=4.*nu.pi/self._alpha**2./self._beta)