def trinomial_precalc(self, N): tri_array = np.zeros([N + 1, N + 1, N + 1]) for i, j, k in nest(lambda: range(N + 1), lambda _i: range(N - _i + 1), lambda _i, _j: range(N - _i - _j + 1) ): tri_array[i, j, k] = self.trinomial(i, j, k) return tri_array
def term_Dabc(self, C1, C2, N): D = np.zeros([N + 1, N + 1, N + 1]) for i, j, k, ii, jj, kk in nest( lambda: range(N + 1), lambda _i: range(N + 1), lambda _i, _j: range(N + 1), lambda _i, _j, _k: range(_i + 1), lambda _i, _j, _k, _ii: range(_j + 1), lambda _i, _j, _k, _ii, _jj: range(_k + 1)): D[i, j, k] += C1[ii, jj, kk] * C2[i - ii, j - jj, k - kk] return D
def mon_comb(self, vertex, tri_array, N, out=None): x, y, z = vertex c = np.zeros([N + 1, N + 1, N + 1]) for i, j, k in nest(lambda: range(N + 1), lambda _i: range(N - _i + 1), lambda _i, _j: range(N - _i - _j + 1), ): c[i, j, k] = tri_array[i, j, k] * \ np.power(x, i) * np.power(y, j) * np.power(z, k) return c
def term_Sijk(self, Cf_list, N): S = np.zeros([N + 1, N + 1, N + 1]) C0, C1, C2 = Cf_list Dabc = self.term_Dabc(C1, C2, N) for i, j, k in nest(lambda: range(N + 1), lambda _i: range(N - _i + 1), lambda _i, _j: range(N - _i - _j + 1), ): C_ijk = C0[:i + 1, :j + 1, :k + 1] D_ijk = threeD_reversed(Dabc[:i + 1, :j + 1, :k + 1]) S[i, j, k] += np.sum(C_ijk * D_ijk) return S
def term_Dabc(self, C1, C2, N): D = np.zeros([N + 1, N + 1, N + 1]) for i, j, k, ii, jj, kk in nest(lambda: range(N + 1), lambda _i: range(N + 1), lambda _i, _j: range(N + 1), lambda _i, _j, _k: range(_i + 1), lambda _i, _j, _k, _ii: range(_j + 1), lambda _i, _j, _k, _ii, _jj: range( _k + 1) ): D[i, j, k] += C1[ii, jj, kk] * C2[i - ii, j - jj, k - kk] return D
def zernike(self, G, N): V = np.zeros([N + 1, N + 1, N + 1], dtype=complex) for a, b, c, alpha in nest(lambda: range(int(N / 2) + 1), lambda _a: range(N - 2 * _a + 1), lambda _a, _b: range(N - 2 * _a - _b + 1), lambda _a, _b, _c: range(_a + _c + 1), ): V[a, b, c] += np.power(IMAG_CONST, alpha) * \ nchoosek(a + c, alpha) * G[2 * a + c - alpha, alpha, b] W = np.zeros([N + 1, N + 1, N + 1], dtype=complex) for a, b, c, alpha in nest(lambda: range(int(N / 2) + 1), lambda _a: range(N - 2 * _a + 1), lambda _a, _b: range(N - 2 * _a - _b + 1), lambda _a, _b, _c: range(_a + 1), ): W[a, b, c] += np.power(-1, alpha) * np.power(2, a - alpha) * \ nchoosek(a, alpha) * V[a - alpha, b, c + 2 * alpha] X = np.zeros([N + 1, N + 1, N + 1], dtype=complex) for a, b, c, alpha in nest(lambda: range(int(N / 2) + 1), lambda _a: range(N - 2 * _a + 1), lambda _a, _b: range(N - 2 * _a - _b + 1), lambda _a, _b, _c: range(_a + 1), ): X[a, b, c] += nchoosek(a, alpha) * W[a - alpha, b + 2 * alpha, c] Y = np.zeros([N + 1, N + 1, N + 1], dtype=complex) for l, nu, m, j in nest(lambda: range(N + 1), lambda _l: range(int((N - _l) / 2) + 1), lambda _l, _nu: range(_l + 1), lambda _l, _nu, _m: range(int((_l - _m) / 2) + 1), ): Y[l, nu, m] += self.Yljm(l, j, m) * X[nu + j, l - m - 2 * j, m] Z = np.zeros([N + 1, N + 1, N + 1], dtype=complex) for n, l, m, nu, in nest(lambda: range(N + 1), lambda _n: range(_n + 1), # there's an if...mod missing in this but it # still works? lambda _n, _l: range(_l + 1), lambda _n, _l, _m: range(int((_n - _l) / 2) + 1), ): # integer required for k when used as power in Qklnu below: k = int((n - l) / 2) Z[n, l, m] += (3 / (4 * PI_CONST)) * \ self.Qklnu(k, l, nu) * np.conj(Y[l, nu, m]) for n, l, m in nest(lambda: range(N + 1), lambda _n: range(n + 1), lambda _n, _l: range(l + 1), ): if np.mod(np.sum([n, l, m]), 2) == 0: Z[n, l, m] = np.real( Z[n, l, m]) - np.imag(Z[n, l, m]) * IMAG_CONST else: Z[n, l, m] = -np.real(Z[n, l, m]) + \ np.imag(Z[n, l, m]) * IMAG_CONST return Z
def term_Sijk(self, Cf_list, N): S = np.zeros([N + 1, N + 1, N + 1]) C0, C1, C2 = Cf_list Dabc = self.term_Dabc(C1, C2, N) for i, j, k, ii, jj, kk in nest(lambda: range(N + 1), lambda _i: range(N - _i + 1), lambda _i, _j: range(N - _i - _j + 1), lambda _i, _j, _k: range(_i + 1), lambda _i, _j, _k, _ii: range(_j + 1), lambda _i, _j, _k, _ii, _jj: range( _k + 1), ): S[i, j, k] += C0[ii, jj, kk] * Dabc[i - ii, j - jj, k - kk] return S