def C(n, a, b): N = np.arange(n, dtype=self.dtype) bands = np.array([N + {+1: b, -1: a}[p]]) if self.normalised: bands[0] *= norm_ratio(0, p, -p, N, a, b) return infinite_csr(banded((bands, [0]), (max(n, 0), max(n, 0))))
def D(n, a, b): N = np.arange(n, dtype=self.dtype) bands = np.array([(N + {+1: a + b + 1, -1: 1}[p]) * 2**(-p)]) if self.normalised: bands[0, (1 + p) // 2:] *= norm_ratio(-p, p, p, N[(1 + p) // 2:], a, b) return infinite_csr( banded((bands, [p]), (max(n - p, 0), max(n, 0))))
def A(n, a, b): N = np.arange(n, dtype=self.dtype) bands = np.array({ +1: [N + (a + b + 1), -(N + b)], -1: [2 * (N + a), -2 * (N + 1)] }[p]) bands[:, 0] = 1 if a + b == -1 else bands[:, 0] / (a + b + 1) bands[:, 1:] /= 2 * N[1:] + a + b + 1 if self.normalised: bands[0] *= norm_ratio(0, p, 0, N, a, b) bands[1, (1 + p) // 2:] *= norm_ratio(-p, p, 0, N[(1 + p) // 2:], a, b) return infinite_csr( banded((bands, [0, p]), (max(n + (1 - p) // 2, 0), max(n, 0))))
def grid_guess(n, a, b, dtype='longdouble', quick=False): """ Approximate solution to P(n,a,b,z) = 0 """ if a == b == -1 / 2: quick = True if n == 1: return operator('Z')(n, a, b).A[0] if quick: return np.cos(np.pi * (np.arange(4 * n - 1, 2, -4, dtype=dtype) + 2 * a) / (4 * n + 2 * (a + b + 1))) from scipy.linalg import eigvalsh_tridiagonal as eigs Z = banded(operator('Z')(n, a, b)) return eigs(Z.diagonal(0), Z.diagonal(1)).astype(dtype)
def S(Lmax,m,s): n = spin2Jacobi(Lmax,m,s)[0] N = s*np.ones(n,dtype=dtype) return infinite_csr(banded((N,[0]),(max(n,0),max(n,0))))
def L(Lmax,m,s): n = spin2Jacobi(Lmax,m,s)[0] N = np.arange(Lmax+1-n,Lmax+1,dtype=dtype) return infinite_csr(banded((N,[0]),(max(n,0),max(n,0))))
def N(n, a, b): return infinite_csr( banded((np.arange(n, dtype=dtype), [0]), (max(n, 0), max(n, 0))))
def P(n, a, b): N = np.arange(n, dtype=dtype) return infinite_csr(banded(((-1)**N, [0]), (max(n, 0), max(n, 0))))
def I(n, a, b): N = np.ones(n, dtype=dtype) return infinite_csr(banded((N, [0]), (max(n, 0), max(n, 0))))
def A(n, a, b): N = a * np.ones(n, dtype=self.dtype) return infinite_csr(banded((N, [0]), (n, n)))
def polynomials(n, a, b, z, init=None, Newton=False, normalised=True, dtype=dtype, internal='longdouble'): """ Jacobi polynomials, P(n,a,b,z), of type (a,b) up to degree n-1. Jacobi.polynomials(n,a,b,z)[k] gives P(k,a,b,z). Newton = True: cubic-converging update of P(n-1,a,b,z) = 0. Parameters ---------- a,b > -1 z: float, np.ndarray. init: float, np.ndarray or None -> 1+0*z, or (1+0*z)/sqrt(mass) if normalised. normalised: classical or unit-integral normalisation. dtype: 'float64','longdouble' output dtype. internal: internal dtype. """ if n < 1: return np.zeros((0, z.size), dtype=dtype) if init is None: init = 1 + 0 * z if normalised: init /= np.sqrt(mass(a, b), dtype=internal) Z = operator('Z', normalised=normalised, dtype=internal) Z = banded(Z(n + 1, a, b).T).data shape = n + 1 if type(z) == np.ndarray: shape = (shape, len(z)) P = np.zeros(shape, dtype=internal) P[0] = init if len(Z) == 2: P[1] = z * P[0] / Z[1, 1] for k in range(2, n + 1): P[k] = (z * P[k - 1] - Z[0, k - 2] * P[k - 2]) / Z[1, k] else: P[1] = (z - Z[1, 0]) * P[0] / Z[2, 1] for k in range(2, n + 1): P[k] = ((z - Z[1, k - 1]) * P[k - 1] - Z[0, k - 2] * P[k - 2]) / Z[2, k] if Newton: L = n + (a + b) / 2 return z + (1 - z**2) * P[n - 1] / ( L * Z[-1, n] * P[n] - (L - 1) * Z[0, n - 2] * P[n - 2]), P[:n - 1] return P[:n].astype(dtype)