def old_asymptotic_series(a, b, z, maxiters=500, tol=tol): """Compute hyp1f1 using an asymptotic series. This uses DLMF 13.7.2 and DLMF 13.2.4. Note that the series is divergent (as one would expect); this can be seen by the ratio test. """ # S1 is the first sum; the ith term is # (1 - a)_i * (b - a)_i * z^(-s) / i! # S2 is the second sum; the ith term is # (a)_i * (a - b + 1)_i * (-z)^(-s) / i! A1 = 1 S1 = A1 A2 = 1 S2 = A2 # Is 8 terms optimal? Not sure. for i in range(1, 9): A1 = A1*(i - a)*(b - a + i - 1) / (z*i) S1 += A1 A2 = -A2*(a + i - 1)*(a - b + i) / (z*i) S2 += A2 phi = np.angle(z) if np.imag(z) == 0: expfac = np.cos(pi*a) elif phi > -0.5*pi and phi < 1.5*pi: expfac = np.exp(1J*pi*a) elif phi > -1.5*pi and phi <= -0.5*pi: expfac = np.exp(-1J*pi*a) else: raise Exception("Shouldn't be able to get here!") c1 = np.exp(z)*z**(a - b)*rgamma(a) c2 = expfac*z**(-a)*rgamma(b - a) return gamma(b)*(c1*S1 + c2*S2)
def b_forward_recurrence(a, b, z, w0, N, tol, maxiter=500): """Use the recurrence relation (3.14) from _[pop] to compute hyp1f1(a, b + N, z) given w0 = hyp1f1(a, b, z). The minimal solution is gamma(b - a)*hyp1f1(a, b, z)/gamma(b), so we use Olver's algorithm. Here we follow the notation from the DLMF 3.6. """ # TODO: use the log of gamma to prevent blowup w0 *= gamma(b - a)*rgamma(b) p, e = [0, 1], [w0] curmin, n = 1e100, 1 # Forward substitution while True: an, bn, cn = 1, -(1 - b - n - z)/z, (b - a + n - 1)/z p.append((bn*p[-1] - cn*p[-2])/an) e.append(cn*e[-1]/an) testmin = abs(e[-1]/(p[-2]*p[-1])) if n <= N: if testmin < curmin: curmin = testmin else: if testmin <= tol*curmin or n - N > maxiter: break n += 1 # Back substitution wn = 0 for i in range(n, N, -1): wn = (p[i-1]*wn + e[i-1])/p[i] return rgamma(b + N - a)*gamma(b + N)*wn
def __calculate_single_term_cst_alpha__(self, t, i, alpha): i_alpha = i * alpha if i_alpha.is_integer(): return len(t) * [0] else: sign = (-1)**i i_fact = math.factorial(i) def catch(func, func_hp, *args, exceptions=Exception, filter_name='error', **kwargs): with warnings.catch_warnings(): warnings.filterwarnings(filter_name) try: res = func(*args, **kwargs) if res is None: raise exceptions else: return res except exceptions: return func_hp(*args, **kwargs) def L_ai_func(): try: i_fact_recip = i_fact**(-1) L_i_alpha = self.L**i_alpha return sign * L_i_alpha * i_fact_recip except: return def L_ai_hp_func(): return fdiv(sign * power(self.L, i_alpha), i_fact) L_ai = catch(L_ai_func, L_ai_hp_func, exceptions=OverflowError) rec_gamma = rgamma(-i_alpha) if math.isinf( sc.rgamma(-i_alpha)) else sc.rgamma(-i_alpha) const = L_ai * rec_gamma def single_term_func(ti): if const < sys.float_info.max: return ti**(-i_alpha - 1) * const else: return fmul(ti**(-i_alpha - 1), const) def single_term_hp_func(ti): return fmul(power(ti, (-i_alpha - 1)), const) single_term = [ catch(single_term_func, single_term_hp_func, time) for time in t ] return single_term
def asymptotic_series_full(a, b, z, maxterms=200): """Compute hyp1f1 using an asymptotic series. This uses DLMF 13.7.2 and DLMF 13.2.4. Note that the series is divergent (as one would expect); this can be seen by the ratio test. In this implementation, the asymptotic series is summed "to the hilt": terms are added until they have no effect on the final result. """ if np.real(z) < 0 and np.imag(z) == 0: # The series is not valid on the negative real axis. return np.nan phi = np.angle(z) if np.imag(z) == 0: expfac = np.cos(pi*a) elif phi > -0.5*pi and phi < 1.5*pi: expfac = np.exp(1J*pi*a) elif phi > -1.5*pi and phi <= -0.5*pi: expfac = np.exp(-1J*pi*a) else: raise Exception("Shouldn't be able to get here!") if (a > 0 and z > 0) or (a < 0 and z < 0): # rgamma is a small number when a > 0 and a large number # when a < 0. Multipling in this order makes overflow less likely. c1 = (rgamma(a)*np.exp(z))*z**(a - b) else: c1 = (np.exp(z)*rgamma(a))*z**(a - b) c2 = expfac*z**(-a)*rgamma(b - a) # S1 is the first sum; the ith term is # (1 - a)_i * (b - a)_i * z^(-s) / i! # S2 is the second sum; the ith term is # (a)_i * (a - b + 1)_i * (-z)^(-s) / i! A1 = 1 S1 = A1 A2 = 1 S2 = A2 for i in range(1, maxterms + 1): A1 = A1*(i - a)*(b - a + i - 1) / (z*i) A2 = -A2*(a + i - 1)*(a - b + i) / (z*i) current_sum = c1*S1 + c2*S2 if c1*(S1 + A1) + c2*(S2 + A2) == current_sum or not np.isfinite(current_sum): break S1 += A1 S2 += A2 return gamma(b)*(c1*S1 + c2*S2)
def randFunc(x, sdev): functions = [ np.sin(x), np.cos(x), special.gammaln(x), np.sqrt(x), np.log(x), np.log10(x), special.erf(x), np.square(x), special.struve(np.random.uniform(0, 2), x), special.rgamma(x) ] index = np.random.randint(0, int(len(functions))) choice = functions[index] / max(functions[index]) choice = (choice**2)**0.5 choice *= np.random.uniform(0, 150) choice += 10 for k in range(len(x)): devSN = np.random.normal(0, sdev) choice[k] += devSN return (choice)
def asymptotic_series_muller(a, b, z, maxiters=500, tol=tol): """The asymptotic series for real argument given by Muller (2001) as Method 2. """ A1 = 1 S1 = 1 if z > 0: for i in xrange(1, 9): A1 = A1*(b - a + i - 1)*(i - a) / (z*i) S1 += A1 return np.exp(z)*gamma(b)*z**(a-b)*rgamma(a)*S1 elif z < 0: for i in xrange(1, 9): A1 = A1*(a - b + i)*(a + i - 1) / ((-z)*i) S1 += A1 return gamma(b)*(-z)**a*rgamma(b - a)*S1 else: # At z == 0 an asymptotic series makes no sense. return taylor_series(a, b, z)
def caputoEuler(self, a, f, y0, tspan): """Use one-step Adams-Bashforth (Euler) method to integrate Caputo equation D^a y(t) = f(y,t) Args: a: fractional exponent in the range (0,1) f: callable(y,t) returning a numpy array of shape (d,) Vector-valued function to define the right hand side of the system y0: array of shape (d,) giving the initial state vector y(t==0) tspan (array): The sequence of time points for which to solve for y. These must be equally spaced, e.g. np.arange(0,10,0.005) tspan[0] is the intial time corresponding to the initial state y0. Returns: y: array, with shape (len(tspan), len(y0)) With the initial value y0 in the first row See also: K. Diethelm et al. (2004) Detailed error analysis for a fractional Adams method C. Li and F. Zeng (2012) Finite Difference Methods for Fractional Differential Equations """ d = len(y0) N = len(tspan) h = (tspan[N-1] - tspan[0])/(N - 1) if a<1: c = special.rgamma(a) * np.power(h, a) / a w = c * np.diff(np.power(np.arange(N), a)) fhistory = np.zeros((N - 1, d), dtype=type(y0[0])) y = np.zeros((N, d), dtype=type(y0[0])) y[0] = y0 for n in range(0, N - 1): tn = tspan[n] yn = y[n] fhistory[n] = f(tn, yn) y[n+1] = y0 + np.dot(w[0:n+1], fhistory[n::-1]) return y elif a>1: # Sun and Wu 2006 cc = special.gamma(3-a)*np.power(h,a) bb = np.diff(np.power(np.arange(N), 2-a)) fhistory = np.zeros((N - 1, d), dtype=type(y0[0])) y = np.zeros((N, d), dtype=type(y0[0])) y[0] = y0 for n in range(0, N - 1): tn = tspan[n] yn = y[n] fhistory[n] = f(tn, yn) y[n + 1] = y[n] + cc*fhistory[n] if n>1: y[n + 1] += np.dot( bb[:n-1] - bb[1:n], (y[1:n]-y[0:n-1])[::-1] ) return y
def dvol(n,d): analytic=np.pi**(float(d)/2.)*rgamma(float(d)/2.+1) count = 0 Narea=[] x=np.zeros(d) for j in xrange(n): #sample x_i from -1 to 1 for i in xrange(d): x[i]=2.* random.random()-1. if (x*x).sum()<=1: count += 1. #only add the result if it is inside the cicle if j%100 ==0 and j!=0: Narea.append(np.abs(2**(d)*float(count)/float(j)-analytic)) return Narea
def gaussvol(n,d,sigma): analytic=np.pi**(float(d)/2.)*rgamma(float(d)/2.+1) count = 0 Narea=[] x=np.zeros(d) for j in xrange(n): random.seed() #sample x_i from -1 to 1 for i in xrange(d): x[i]=random.gauss(0,sigma) if (x*x).sum()<=1: # Here we use importance sampling to weight the result count += np.sqrt(2*np.pi*sigma**2)**(d)*np.exp((x*x).sum()/(2.*sigma**2)) #only add the result if it is inside the cicle if j%100 ==0 and j!=0: Narea.append(np.abs(float(count)/float(j)-analytic)) return Narea
def test_wright_bessel_zero(a, b): """Test at x = 0.""" assert_equal(wright_bessel(a, b, 0.), rgamma(b))
def test_rgamma_zeros(self): x = np.array([0, -10, -100, -1000, -10000]) assert np.all(sc.rgamma(x) == 0)
def test_gh_11315(self): assert sc.rgamma(-35) == 0
def compute_f(self): ncomp = ((self.L * 2)**2) * 2 terms = np.zeros(ncomp, dtype=self.dtype) extent = self.domain.extent ivolume = 1./(extent[0]*extent[1]*extent[2]) gx = np.array((1./extent[0], 0., 0.)) gy = np.array((0., 1./extent[1], 0.)) gz = np.array((0., 0., 1./extent[2])) gxl = np.linalg.norm(gx) gyl = np.linalg.norm(gy) gzl = np.linalg.norm(gz) for lx in range(2, self.L*2, 2): rc, vc = self._compute_parameters(lx) kappa = self.kappa kappa2 = kappa * kappa mpi2okappa2 = -1.0 * (math.pi ** 2.) / kappa2 ll = 6 if int(ceil(vc/gxl)) < ll: vc = gxl*ll nmax = int(ceil(vc/gxl)) #nmax = 1 for hxi in itertools.product(range(- 1*nmax, nmax+1), range(-1*nmax, nmax+1), range(-1*nmax, nmax+1)): hx = hxi[0]*gz + hxi[1]*gy + hxi[2]*gx dispt = self._cart_to_sph(hx) if 10.**-10 < dispt[0] <= vc: exp_coeff = math.exp(mpi2okappa2 * dispt[0] * dispt[0]) #mval = list(range(0, lx+1, 2)) mval = list(range(-1*lx, lx+1, 2)) mxval = [abs(mx) for mx in mval] scipy_p = lpmv(mxval, lx, math.cos(dispt[2])) vhnm2 = ((dispt[0] ** (lx - 2.)) * ((0 + 1.j) ** lx) * \ (math.pi ** (lx - 0.5))).real coeff = vhnm2 * exp_coeff for mxi, mx in enumerate(mval): val = math.sqrt(float(math.factorial( lx - abs(mx)))/math.factorial(lx + abs(mx))) re_exp = np.cos(mx * dispt[1]) * val assert abs(scipy_p[mxi].imag) < 10.**-16 sph_nm = re_exp * scipy_p[mxi].real contrib = sph_nm * coeff terms[self.re_lm(lx, mx)] += contrib.real for lx in range(2, self.L*2, 2): igamma = rgamma(lx + 0.5) * ivolume for mx in range(-1*lx, lx+1, 2): terms[self.re_lm(lx, mx)] *= igamma return terms
import numpy as np from scipy import special from matplotlib import pyplot as plt tempDM = np.linspace(0.001, 10, 10000) # X-vals to evaluate the distributions over functions = np.array([ # Possible distributions that noise can follow special.gammaln(tempDM), np.sqrt(tempDM), np.log(tempDM), -special.gammaln(tempDM), -np.sqrt(tempDM), -np.log(tempDM), special.erf(tempDM), np.square(tempDM), -special.erf(tempDM), -np.square(tempDM), special.struve(0,tempDM), special.struve(1,tempDM), special.struve(2,tempDM), -special.struve(0,tempDM), -special.struve(1,tempDM), -special.struve(2,tempDM), [np.random.uniform(0, 5)]*len(tempDM), tempDM, -tempDM, special.rgamma(tempDM) ]) def generation(numPoints, upperDM): """Randomly pick shapes for noise to follow. With probability of multiple, different, distributions (as well as their inverted counterparts) to be convolved with each other and form unpredictable shapes. Keyword arguments: numPoints -- the number of points that the noise/fake signal will have upperDM -- the highest DM for the data (w.r.t. 0), to be multiplied by the normalised plot in the end """ np.random.seed() # As random seeds are used at some points this just ensure it is reset every time convProb = 3/4 # Probability of convolution of a signal taking place
def __calculate_single_term_var_alpha__(self, t, i, alpha): i_alpha = [i * a for a in alpha] sign = (-1)**i i_fact = math.factorial(i) def catch(func, func_hp, *args, exceptions=Exception, filter_name='error', **kwargs): with warnings.catch_warnings(): warnings.filterwarnings(filter_name) try: res = func(*args, **kwargs) if res is None: raise exceptions else: return res except exceptions: return func_hp(*args, **kwargs) def L_ai_func(ia): try: i_fact_recip = i_fact**(-1) L_i_alpha = self.L**ia return sign * L_i_alpha * i_fact_recip except: return def L_ai_hp_func(ia): return fdiv(sign * power(self.L, ia), i_fact) L_ai = [ 0 if ia.is_integer() else catch(L_ai_func, L_ai_hp_func, ia, exceptions=(OverflowError, Exception)) for ia in i_alpha ] rec_gamma = [ 1 if ia.is_integer() else rgamma(-ia) if math.isinf(sc.rgamma(-ia)) else sc.rgamma(-ia) for ia in i_alpha ] const = [Lai * rec_g for Lai, rec_g in zip(L_ai, rec_gamma)] def single_term_func(ti, ia, c): if c < sys.float_info.max: return ti**(-ia - 1) * c else: return fmul(ti**(-ia - 1), c) def single_term_hp_func(ti, ia, c): return fmul(power(ti, (-ia - 1)), c) single_term = [ 0 if ia.is_integer() else catch(single_term_func, single_term_hp_func, time, ia, c) for time, ia, c in zip(t, i_alpha, const) ] return single_term