def any_f_to_poly(f, a, b, order): # remap [a, b] to [-1, 1] for better conditioning p = mpmath.lu_solve( vandermonde(mpmath.matrix([a, b]), 2), mpmath.matrix([-1., 1.]) ) # fit polynomial to [-1, 1], then compose with mapping function p_x = mpmath.matrix( [mpmath.cos((i + .5) * mpmath.pi / order) for i in range(order)] ) x = mpmath.matrix( [a + (b - a) * (.5 + .5 * p_x[i]) for i in range(order)] ) q = utils.poly.compose( mpmath.lu_solve(vandermonde(p_x, order), f(x)), p ) # checking p_x = mpmath.matrix( [mpmath.cos(i * mpmath.pi / order) for i in range(order + 1)] ) x = mpmath.matrix( [a + (b - a) * (.5 + .5 * p_x[i]) for i in range(order + 1)] ) y = utils.poly.eval_multi(q, x) - f(x) est_err = max([abs(y[i]) for i in range(y.rows)]) print('est_err', est_err) return q
def generate_basis_polynomials(samples, n, precision, calc_condition=False): mpmath.mp.prec = precision A = [] for i in range(samples): line = [] for j in range(samples + 2): t = mpmath.mpf(1) / (samples - 1) * i line.append(t**j) A.append(line) for t in range(2): line = [] for j in range(samples + 2): if j == 0: line.append(mpmath.mpf(0.0)) else: line.append(mpmath.mpf(j) * (t**(j - 1))) A.append(line) b = [mpmath.mpf(0)] * n + [mpmath.mpf(1) ] + [mpmath.mpf(0)] * (samples + 2 - n - 1) if calc_condition: basis_condition = mpmath.cond(A) return basis_condition x = mpmath.lu_solve(A, b) # x = [float(v) for v in mpmath.mp.lu_solve(A,b)] return PolynomialSection(0, 1, coefficients=[element for element in x])
def least_squares_non_verbose(f, psi, Omega, symbolic=True): """ Given a function f(x) on an interval Omega (2-list) return the best approximation to f(x) in the space V spanned by the functions in the list psi. """ N = len(psi) - 1 A = sym.zeros(N + 1, N + 1) b = sym.zeros(N + 1, 1) x = sym.Symbol('x') for i in range(N + 1): for j in range(i, N + 1): integrand = psi[i] * psi[j] integrand = sym.lambdify([x], integrand, 'mpmath') I = mpmath.quad(integrand, [Omega[0], Omega[1]]) A[i, j] = A[j, i] = I integrand = psi[i] * f integrand = sym.lambdify([x], integrand, 'mpmath') I = mpmath.quad(integrand, [Omega[0], Omega[1]]) b[i, 0] = I c = mpmath.lu_solve(A, b) # numerical solve c = [c[i, 0] for i in range(c.rows)] u = sum(c[i] * psi[i] for i in range(len(psi))) return u, c
def numerical_coeffs(Mn, n, dict_ss): """Numerical coefficients of polynomial of order (n - 3)! obtianed from determinant of elimination theory matrix.""" Mn = Mn.tolist() Mn = [[_zs_sub(_ss_sub(str(entry))) for entry in line] for line in Mn] zs = punctures(n) values = [ mpmath.e**(2 * mpmath.pi * 1j * j / (math.factorial(n - 3) + 1)) for j in range(math.factorial(n - 3) + 1) ] A = [[ value**exponent for exponent in range(math.factorial(n - 3) + 1)[::-1] ] for value in values] b = [] for i, value in enumerate(values): dict_zs = { str(zs[-2]): value, str(zs[-3]): 1 } # noqa --- used in eval function nMn = mpmath.matrix([[eval(entry, None) for entry in line] for line in Mn]) b += [mpmath.det(nMn)] return mpmath.lu_solve(A, b).T.tolist()[0]
def solve_lu_mp(A, b): """ Solve a linear system using mpmath :param ndarray A: The linear system :param ndarray b: The right hand side :return: ndarray """ A_mp = mpmath.matrix([list(row) for row in A]) b_mp = mpmath.matrix([list(row) for row in b]) x_mp = mpmath.lu_solve(A_mp, b_mp) x = numpy.array(x_mp.tolist(), 'f8') return x
def fit(x, y, order): a = min(x) b = max(x) # remap [a, b] to [-1, 1] for better conditioning p = mpmath.lu_solve( vandermonde(mpmath.matrix([a, b]), 2), mpmath.matrix([-1., 1.]) ) # fit polynomial to remapped x, then compose with mapping function q = utils.poly.compose( mpmath.lu_solve( vandermonde(utils.poly.eval_multi(p, x), order), y ), p ) # checking #err = utils.poly.eval_multi(x) - y #print('err', err) return q
def reduce_to_fpp(self,z): # TODO: need to check what happens here when periods are infinite. from mpmath import floor, matrix, lu_solve T1, T2 = self.__periods R1, R2 = T1.real, T2.real I1, I2 = T1.imag, T2.imag A = matrix([[R1,R2],[I1,I2]]) b = matrix([z.real,z.imag]) x = lu_solve(A,b) N = int(floor(x[0])) M = int(floor(x[1])) alpha = x[0] - N beta = x[1] - M assert(alpha >= 0 and beta >= 0) return alpha,beta,N,M
def reduce_to_fpp(self, z): # TODO: need to check what happens here when periods are infinite. from mpmath import floor, matrix, lu_solve T1, T2 = self.periods R1, R2 = T1.real, T2.real I1, I2 = T1.imag, T2.imag A = matrix([[R1, R2], [I1, I2]]) b = matrix([z.real, z.imag]) x = lu_solve(A, b) N = int(floor(x[0])) M = int(floor(x[1])) alpha = x[0] - N beta = x[1] - M assert (alpha >= 0 and beta >= 0) return alpha, beta, N, M
def polish(self, init_shapes, flag_initial_error=True): """Use Newton's method to compute precise shapes from rough ones.""" precision = self._precision manifold = self.manifold #working_prec = precision + 32 working_prec = precision + 64 mpmath.mp.prec = working_prec target_epsilon = mpmath.mpmathify(2.0)**-precision det_epsilon = mpmath.mpmathify(2.0)**(32 - precision) #shapes = [mpmath.mpmathify(z) for z in init_shapes] shapes = mpmath.matrix(init_shapes) init_equations = manifold.gluing_equations('rect') target = mpmath.mpmathify(self.target_holonomy) error = self._gluing_equation_error(init_equations, shapes, target) if flag_initial_error and error > 0.000001: raise GoodShapesNotFound( 'Initial solution not very good: error=%s' % error) # Now begin the actual computation eqns = enough_gluing_equations(manifold) assert eqns[-1] == manifold.gluing_equations('rect')[-1] for i in range(100): errors = self._gluing_equation_errors(eqns, shapes, target) if infinity_norm(errors) < target_epsilon: break derivative = [[ int(eqn[0][i]) / z - int(eqn[1][i]) / (1 - z) for i, z in enumerate(shapes) ] for eqn in eqns] derivative[-1] = [target * x for x in derivative[-1]] derivative = mpmath.matrix(derivative) #det = derivative.matdet().abs() det = abs(mpmath.det(derivative)) if min(det, 1 / det) < det_epsilon: raise GoodShapesNotFound( 'Gluing system is too singular (|det| = %s).' % det) delta = mpmath.lu_solve(derivative, errors) shapes = shapes - delta # Check to make sure things worked out ok. error = self._gluing_equation_error(init_equations, shapes, target) #total_change = infinity_norm(init_shapes - shapes) if error > 1000 * target_epsilon: raise GoodShapesNotFound('Failed to find solution') #if flag_initial_error and total_change > pari(0.0000001): # raise GoodShapesNotFound('Moved too far finding a good solution') self.shapelist = [Number(z, precision=precision) for z in shapes]
def least_squares(f, psi, Omega, symbolic=True): """ Given a function f(x) on an interval Omega (2-list) return the best approximation to f(x) in the space V spanned by the functions in the list psi. """ N = len(psi) - 1 A = sym.zeros(N + 1, N + 1) b = sym.zeros(N + 1, 1) x = sym.Symbol('x') print('...evaluating matrix...', end=' ') for i in range(N + 1): for j in range(i, N + 1): print('(%d,%d)' % (i, j)) integrand = psi[i] * psi[j] if symbolic: I = sym.integrate(integrand, (x, Omega[0], Omega[1])) if not symbolic or isinstance(I, sym.Integral): # Could not integrate symbolically, use numerical int. print('numerical integration of', integrand) integrand = sym.lambdify([x], integrand, 'mpmath') I = mpmath.quad(integrand, [Omega[0], Omega[1]]) A[i, j] = A[j, i] = I integrand = psi[i] * f if symbolic: I = sym.integrate(integrand, (x, Omega[0], Omega[1])) if not symbolic or isinstance(I, sym.Integral): # Could not integrate symbolically, use numerical int. print('numerical integration of', integrand) integrand = sym.lambdify([x], integrand, 'mpmath') I = mpmath.quad(integrand, [Omega[0], Omega[1]]) b[i, 0] = I print() print('A:\n', A, '\nb:\n', b) if symbolic: c = A.LUsolve(b) # symbolic solve # c is a sympy Matrix object, numbers are in c[i,0] c = [sym.simplify(c[i, 0]) for i in range(c.shape[0])] else: c = mpmath.lu_solve(A, b) # numerical solve c = [c[i, 0] for i in range(c.rows)] print('coeff:', c) u = sum(c[i] * psi[i] for i in range(len(psi))) print('approximation:', u) return u, c
def calculate_An(params): ''' ''' av = params['a'] kv = params['k'] Rv = params['R'] alphav = params['alpha'] NN = params.get('NN', int(12 + 2 * kv * av / mpmath.sin(alphav))) M_mat = mpmath.matrix(NN, NN) b_mat = mpmath.matrix(NN, 1) for mm in tqdm.trange(NN): b_mat[mm] = bm_func(mm, alphav, Rv) for nn in range(NN): M_mat[mm, nn] = Mmn_func(mm, nn, kv, Rv, alphav) An = mpmath.lu_solve(M_mat, b_mat) return An
def compute_a(M_mat, b_mat): ''' Keyword Arguments ----------------- M_mat : N x N mpmath.matrix b_mat : N x 1 mpmath.matrix Returns ------- a_matrix : N x 1 The size of the matrix is given by the heuristic described in ```compute_M```. This is the A_{n} used in the summations. See Also -------- compute_M compute_b ''' a_matrix = mpmath.lu_solve(M_mat, b_mat) return a_matrix
def solve_svd_mp(A, b): """ solve a linear system using svd decomposition using mpmath :param ndarray A: The linear system :param ndarray b: The right hand side :return: ndarray """ A_mp = mpmath.matrix([list(row) for row in A]) b_mp = mpmath.matrix([list(row) for row in b]) u, s, v = svd_r(A_mp) # x = V*((U'.b)./ diag(S)) # x = V*( c ./ diag(S)) # x = V*( g ) c = u.T * b_mp w = mpmath.lu_solve(mpmath.diag(s), c) x_mp = v.T * w x = numpy.array(x_mp.tolist(), 'f8') return x
for i, scheme_data in enumerate(data): X = scheme_data["x"] Y = scheme_data["y"] W = scheme_data["w"] print("elif index == %d:" % (i + 1)) print(" bary = np.concatenate([") # generate barycentric coordinate code XY = [[xx, yy] for xx, yy in zip(X, Y)] T = mpmath.matrix([[t1[0] - t0[0], t2[0] - t0[0]], [t1[1] - t0[1], t2[1] - t0[1]]]) tol = 1.0e-10 multiplicities = [] for k, xy in enumerate(XY): b = [xy[0] - t0[0], xy[1] - t0[1]] sol = mpmath.lu_solve(T, b) lmbda = [sol[0], sol[1], 1.0 - sol[0] - sol[1]] assert abs(sum(lmbda) - 1.0) < tol # print('%.15e %.15e %.15e' % (lmbda[0], lmbda[1], lmbda[2])) diffs = [ abs(lmbda[0] - lmbda[1]), abs(lmbda[1] - lmbda[2]), abs(lmbda[2] - lmbda[0]), ] if diffs[0] < tol and diffs[1] < tol and diffs[2] < tol: print(" _s3(),") multiplicities.append(1) elif diffs[0] < tol: print(" _s21(%s)," % lmbda[0]) multiplicities.append(3) elif diffs[1] < tol:
def __init__(self,rang=10,acc=100): # Generates the coefficients of Legendre polynomial of n-th order. # acc is the number of decimal characters of the coefficients. # self.cf is the list with coefficients. self.rang = rang self.acc = mp.dps = acc cn = mpf(0.0) k = mpf(0) n = mpf(rang) m = mpf(n/2) cf = [] for k in range(n+1): cn = (- 1)**(n+k)*factorial(n+k)/(factorial(nk)*factorial(k)*factorial(k)) cf.append(cn) cf.reverse() # Generates the coefficients of of the implicit Runge-Kutta scheme of Gauss-Legendre type. # acc is the number of the decimal characters of the coefficients. # Gives back the cortege (r,b,a), the terms of which correspond to Butcher scheme # # r1 | a11 . . . а1n # . | . . # . | . . # . | . . # rn | an1 . . . ann # ---+-------------- # | b1 . . . bn self.r = polyroots(cf) A1 = matrix(rang) for j in range(n): for k in range(n): A1[k,j] = self.r[j]**k bn = [] for j in range(n): bn.append(mpf(1.0)/mpf(j+1)) B = matrix(bn) self.b = lu_solve(A1,B) self.a = matrix(rang) for i in range(1,n+1): A1 = matrix(rang) cil = [] for l in range(1,n+1): cil.append(mpf(self.r[i- 1])**l/mpf(l)) for j in range(n): A1[l-1,j] = self.r[j]**(l-1) Cil = matrix(cil) an = lu_solve(A1,Cil) for k in range(n): self.a[i-1,k] = an[k] def init(self,f,t,h,initvalues): self.size = len(initvalues) self.f = f 31 self.t = t self.h = h self.yb = matrix(initvalues) self.ks = matrix(self.size,self.rang) for k in range(self.size): for i in range(self.rang): self.ks[k,i] = self.r[i] self.tn = matrix(1,self.rang) for i in range(self.rang): self.tn[i] = t + h*self.r[i] self.y = matrix(self.size,self.rang) for k in range(self.size): for i in range(self.rang): self.y[k,i] = self.yb[k] temp = mpf(0.0) for j in range(self.rang): temp += self.a[i,j]*self.ks[k,j] self.y[k,i] += temp self.yn = matrix(self.yb) def iterate(self,tn,y,yn,ks): # Generates the coefficients of the implicit Runge-Kutta scheme for the given step # with the method of the simple iteration with an initial value, coinciding with the coefficients, # calculated at the previous step. At sufficiently small step this must # work. There exists such a value of the step, Under which convergence is guaranteed. # No automatic re-setup of the step is foreseen in this procedure. mp.dps = self.acc y0 = matrix(yn) norme = mpf(1.0) #eps0 = pow(eps,mpf(3.0)/mpf(4.0)) eps0 = sqrt(eps) ks1 = matrix(self.size,self.rang) yt = matrix(1,self.size) count = 0 while True: count += 1 for i in range(self.rang): for k in range(self.size): yt[k] = y[k,i] for k in range(self.size): ks1[k,i] = self.f(tn,yt)[k] norme = mpf(0.0) 2 for k in range(self.size): for i in range(self.rang): norme += (ks1[k,i]- ks[k,i])*(ks1[k,i]-ks[k,i]) norme = sqrt(norme) for k in range(self.size): for i in range(self.rang): ks[k,i] = ks1[k,i] for k in range(self.size): for i in range(self.rang): y[k,i] = y0[k] for j in range(self.rang): y[k,i] += self.h*self.a[i,j]*ks[k,j] if norme <= eps0: break if count >= 100: print unicode('No convergence','UTF-8') exit(0) return ks1 def step(self): mp.dps = self.acc self.ks = self.iterate(self.tn,self.y,self.yn,self.ks) for k in range(self.size): for i in range(self.rang): self.yn[k] += self.h*self.b[i]*self.ks[k,i] for k in range(self.size): for i in range(self.rang): self.y[k,i] = self.yn[k] for j in range(self.rang): self.y[k,i] += self.a[i,j]*self.ks[k,j] self.t += self.h for i in range(self.rang): self.tn[i] = self.t + self.h*self.r[i] return self.yn
def solve_scattering_equations(n, dict_ss): """Solves the scattering equations given multiplicity and mandelstams.""" if n == 3: return [{}] Mn = M(n) zs = punctures(n) num_coeffs = numerical_coeffs(Mn, n, dict_ss) roots = mpmath.polyroots(num_coeffs, maxsteps=10000, extraprec=300) sols = [{str(zs[-2]): root * zs[-3]} for root in roots] if n == 4: sols = [{ str(zs[-2]): mpmath.mpc(sympy.simplify(sols[0][str(zs[-2])].subs({zs[1]: 1}))) }] else: Mnew = copy.deepcopy(Mn) Mnew[:, 0] += Mnew[:, 1] * zs[1] Mnew.col_del(1) Mnew.row_del(-1) # subs sol = sols[0] Mnew = Mnew.tolist() Mnew = [[ _zs_sub(_ss_sub(str(entry))).replace( "dict_zs['z{}']".format(n - 1), "dict_zs['z{}'] * mpmath.mpc(sol[str(zs[-2])] / zs[-3])". format(n - 2)) for entry in line ] for line in Mnew] # get scaling if n == 5: scaling = 0 elif n == 6: scaling = 2 elif n == 7: scaling = 17 else: # computing from scratch, should work for any multiplicity in principle dict_zs = {str(zs[-3]): 10**-100, str(zs[1]): 1} nMn = mpmath.matrix([[eval(entry, None) for entry in line] for line in Mnew]) a = mpmath.det(nMn) dict_zs = {str(zs[-3]): 10**-101, str(zs[1]): 1} nMn = mpmath.matrix([[eval(entry, None) for entry in line] for line in Mnew]) b = mpmath.det(nMn) scaling = -round(mpmath.log(abs(b) / abs(a)) / mpmath.log(10)) assert (abs( round(mpmath.log(abs(b) / abs(a)) / mpmath.log(10)) - mpmath.log(abs(b) / abs(a)) / mpmath.log(10)) < 10**-30) # solve the linear equations for i in range(1, n - 3): Mnew = copy.deepcopy(Mn) index = V(n).index(zs[i]) Mnew[:, 0] += Mnew[:, index] * zs[i] Mnew.col_del(index) Mnew.row_del(-1) Mnew = Mnew.tolist() if i == 1: Mnew = [[ _zs_sub(_ss_sub(str(entry))).replace( "dict_zs['z{}']".format(n - 1), "dict_zs['z{}'] * mpmath.mpc(sol[str(zs[-2])] / zs[-3])" .format(n - 2)) for entry in line ] for line in Mnew] for sol in sols: A = [[value**exponent for exponent in [1, 0]] for value in [-1, 1]] b = [] for value in [-1, 1]: dict_zs = {str(zs[-3]): value, str(zs[1]): 1} nMn = mpmath.matrix( [[eval(entry, None) for entry in line] for line in Mnew]) b += [mpmath.det(nMn) / (value**scaling)] coeffs = mpmath.lu_solve(A, b).T.tolist()[0] sol[str(zs[-3])] = -coeffs[1] / coeffs[0] sol[str(zs[-2])] = mpmath.mpc((sympy.simplify(sol[str( zs[-2])].subs({zs[-3]: sol[str(zs[-3])]})))) else: Mnew = [[_zs_sub(_ss_sub(str(entry))) for entry in line] for line in Mnew] for sol in sols: A = [[value**exponent for exponent in [1, 0]] for value in [-1, 1]] b = [] for value in [-1, 1]: dict_zs = { str(zs[i]): value, str(zs[-3]): sol[str(zs[-3])], str(zs[-2]): sol[str(zs[-2])] } # noqa --- used in eval function nMn = mpmath.matrix( [[eval(entry, None) for entry in line] for line in Mnew]) b += [mpmath.det(nMn)] coeffs = mpmath.lu_solve(A, b).T.tolist()[0] sol[str(zs[i])] = -coeffs[1] / coeffs[0] return sols
def Bound(U,B,sol,eig,dic,order,condB = "harm pot",condU = 'Inviscid'): lso = len(sol) for s in range(len(sol)): globals() ['C'+str(s)] = Symbol('C'+str(s)) ################################# ### Inviscid solution : ### ### lso=3 --> 1 boundary ### ### lso=6 --> 2 boundaries ### ################################# nn = n.xreplace(dic).doit() U = (U.xreplace(makedic(veigen(eig,sol),order))).xreplace({U0:1}) B = (B.xreplace(makedic(veigen(eig,sol),order))) if (condB == "harm pot"): bchx,bchy,bchz = symbols("bchx,bchy,bchz") bcc =surfcond((bchx*C.i +bchy*C.j + bchz*C.k)*ansatz - gradient(psi),dic).doit() sob = list(linsolve([bcc&C.i,bcc&C.j,bcc&C.k],(bchx,bchy,bchz)))[0] bbc = sob[0]*C.i + sob[1]*C.j + sob[2]*C.k bb = B.xreplace(makedic(veigen(eig,sol),order)) - (bbc*ansatz) Eq_b= surfcond(bb,dic) Eq_bx = Eq_b&C.i; Eq_by = Eq_b&C.j; Eq_bz = Eq_b&C.k if params.Bound_nb ==2: bchx2,bchy2,bchz2 = symbols("bchx2,bchy2,bchz2") bcc2 =surfcond_2((bchx2*C.i +bchy2*C.j +bchz2*C.k)*ansatz - gradient(psi_2b),dic) sob2 = list(linsolve([bcc2&C.i,bcc2&C.j,bcc2&C.k],(bchx2,bchy2,bchz2)))[0] bbc2 = sob2[0]*C.i + sob2[1]*C.j + sob2[2]*C.k bb2 = B.xreplace(makedic(veigen(eig,sol),order)) - (bbc2*ansatz) Eq_b2= surfcond_2(bb2,dic) Eq_b2x = Eq_b2&C.i; Eq_b2y = Eq_b2&C.j; Eq_b2z = Eq_b2&C.k if (condB == "thick"): bchx,bchy,bchz,eta = symbols("bchx,bchy,bchz,eta") kz_t = -sqrt(-kxl**2-kyl**2-I*omega/qRmm) # kz_t = I*1e12 B_mant = (bchx*C.i +bchy*C.j + bchz*C.k)*ansatz.xreplace({kz:kz_t}) eq_ind = (surfcond((diff(B_mant,t)-qRmm*laplacian(B_mant)-diff(B,t) +qRm*laplacian(B) - curl(U.cross(B))).xreplace({kz:kz_t}),dic).xreplace(dic)) eq_E = (qRm*curl(B)-U.cross(B)-qRmm*curl(B_mant)) eq_Et = surfcond(((nn).cross(eq_E)).xreplace({kz:kz_t}),dic) eq_B = surfcond(((B_mant.dot(nn)-B.dot(nn))).xreplace({kz:kz_t}),dic) un = (U.dot(nn)) Eq_n1= surfcond((un).xreplace({kz:kz_t}),dic).xreplace(dic) TEq = [(taylor(eq,order,dic)).xreplace({x:0,y:0,t:0}) for eq in [Eq_n1,eq_ind&C.i,eq_ind&C.j,eq_ind&C.k,eq_Et.dot(tx),eq_Et.dot(ty)]] Mat, res = linear_eq_to_matrix(TEq,(C0,C1,C2,bchx,bchy,bchz)) U = (U.xreplace(makedic(veigen(eig,sol),order))).xreplace({U0:1}) un = U.dot(nn) Eq_n1= surfcond(un,dic).xreplace(dic) if condU == "Inviscid": if params.Bound_nb ==2: nn2 = n2.xreplace(dic).doit() un2 = U.dot(nn2) Eq_n2= surfcond_2(un2,dic) TEq = [(taylor(eq,order,dic)).xreplace({x:0,y:0,t:0}) for eq in [Eq_n1,Eq_n2,Eq_bx,Eq_by,Eq_bz,Eq_b2x,Eq_b2y,Eq_b2z]] Mat, res = linear_eq_to_matrix(TEq,(C0,C1,C2,C3,C4,C5,Symbol("psi"+str(order)),Symbol("psi"+str(order)+"_2b"))) elif params.Bound_nb ==1: TEq = [(taylor(eq,order,dic)).xreplace({x:0,y:0,t:0}) for eq in [Eq_n1,Eq_bx,Eq_by,Eq_bz]] Mat, res = linear_eq_to_matrix(TEq,(C0,C1,C2,Symbol("psi"+str(order)))) elif condU == 'noslip': if params.Bound_nb ==1: U = (U.xreplace(makedic(veigen(eig,sol),order))) ut1 = U.dot(tx) ut2 = U.dot(ty) Eq_BU1= surfcond(ut1,dic) Eq_BU2 = surfcond(ut2,dic) TEq = [(taylor(eq,order,dic)).xreplace({x:0,y:0,t:0}) for eq in [Eq_n1,Eq_BU1,Eq_BU2,Eq_bx,Eq_by,Eq_bz]] Mat, res = linear_eq_to_matrix(TEq,(C0,C1,C2,C3,C4,Symbol("psi"+str(order)))) elif params.Bound_nb ==2: un1 = U.dot(tx2) un2 = U.dot(ty2) Eq2_BU1= surfcond_2(un1,dic) Eq2_BU2 = surfcond_2(un2,dic) TEq = [(taylor(eq,order,dic)).xreplace({x:0,y:0,t:0}) for eq in [Eq_n1,Eq_n2,Eq_BU1,Eq_BU2,Eq2_BU1,Eq2_BU2,Eq_bx,Eq_by,Eq_bz,Eq_b2x,Eq_b2y,Eq_b2z]] Mat, res = linear_eq_to_matrix(TEq,(C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,Symbol("psi"+str(order)),Symbol("psi"+str(order)+"_2b"))) elif condU == 'stressfree': if params.Bound_nb ==1: eu = strain(U)*nn eu1 = eu*tx eu2 = eu*ty Eq_BU1 = surfcond(eu1,dic,realtopo =False) Eq_BU2 = surfcond(eu2,dic,realtopo =False) TEq = [(taylor(eq,order,dic)).xreplace({x:0,y:0,t:0}) for eq in [Eq_n1,Eq_BU1,Eq_BU2,Eq_bx,Eq_by,Eq_bz]] Mat, res = linear_eq_to_matrix(TEq,(C0,C1,C2,C3,C4,Symbol("psi"+str(order)))) elif params.Bound_nb ==2: eu = strain(U)*nn2 eu1 = eu*tx2 eu2 = eu*ty2 Eq2_BU1 = surfcond2(eu1,dic,realtopo =False) Eq2_BU2 = surfcond2(eu2,dic,realtopo =False) TEq = [(taylor(eq,order,dic)).xreplace({x:0,y:0,t:0}) for eq in [Eq_n1,Eq_n2,Eq_BU1,Eq_BU2,Eq2_BU1,Eq2_BU2,Eq_bx,Eq_by,Eq_bz,Eq_b2x,Eq_b2y,Eq_b2z]] Mat, res = linear_eq_to_matrix(TEq,(C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,Symbol("psi"+str(order)),Symbol("psi"+str(order)+"_2b"))) Mat = Mat.evalf(mp.mp.dps) res = res.evalf(mp.mp.dps) Mat = mpmathM(Mat) res = mpmathM(res) try: abc = mp.qr_solve(Mat,res)[0] except: abc = mp.lu_solve(Mat,res) mantle =0 #In progress ... solans = zeros(7,1) for l in range(lso): solans = solans + abc[l]*Matrix(eig[l])*(ansatz).xreplace({kz:sol[l]}) solans = solans.xreplace(dic) return(abc,solans,mantle)
rmep = (rmec).applyfunc(coe) nwkz = simplify((log(ex).expand(force=True)/I).xreplace({x:0,y:0,t:0,z:1})) Mp = simplify(M.xreplace({kz:nwkz})) rmep = subs_k(rmep,i,Bound_nb) Mp = subs_k(Mp,i,Bound_nb) with mp.workdps(int(mp.mp.dps*2)): Mp = mpmathM(Mp) rmep = mpmathM(rmep) try: soluchap = mp.qr_solve(Mp,rmep)[0] except: soluchap = mp.lu_solve(Mp,rmep) print('QR decomposition failed LU used') sop = Matrix(soluchap)*ex so_part = so_part+sop with mp.workdps(int(mp.mp.dps*2)): so_part = so_part.xreplace({**dico0,**dico1}) Usopart = so_part[0]*C.i + so_part[1]*C.j + so_part[2]*C.k Bsopart = so_part[4]*C.i + so_part[5]*C.j + so_part[6]*C.k psopart = so_part[3] Ubnd = U + e**i*Usopart Bbnd = B + e**i*Bsopart pbnd = p + e**i*psopart
def _calculate_coefficients(self): basis_polynomials = [ self.g_c.spline_basis_polynomials(samples=self.degree - 1, n=i, precision=mpmath.mp.prec) for i in range(0, self.degree - 1 + 2) ] basis_polynomials_coefficients = [ b_p.coefficients for b_p in basis_polynomials ] second_derivatives = [ b_p.second_derivation_coefficients for b_p in basis_polynomials ] t_0_factors = [s_d[0] for s_d in second_derivatives] t_1_factors = [sum(s_d) for s_d in second_derivatives] A: List[List[int]] = [] A_prime = [] b: List[Any] = [] step = (self.degree - 2) size = len(self.a_list) // step for i in range(size): row = [] row_prime = [] for j in range(size): pos = (((j + 1) % size) - i) % size h_minus = self.h(i * step - step) h = self.h(i * step) row.append(t_1_factors[-2] / h_minus if pos == 0 else ( t_1_factors[-1] / h_minus - t_0_factors[-2] / h if pos == 1 else -t_0_factors[-1] / h if pos == 2 else 0)) row_prime.append(pos) A.append(row) A_prime.append(row_prime) for i in range(size): h_minus = self.h(i * step - step) h = self.h(i * step) newValue = 0 for j in range(step + 1): newValue += -t_1_factors[j] * self.y_list[i * step - step + j] / h_minus / h_minus + t_0_factors[j] * \ self.y_list[(i * step + j) % len(self.y_list)] / h / h b.append(newValue) derivations = mpmath.lu_solve(A, b) self.coefficients = [] for i in range(size): current_coefficients = [0j] * (self.degree + 1) if len(current_coefficients) != len( basis_polynomials_coefficients): raise for j in range(step + 1): for h in range(len(basis_polynomials_coefficients[j])): current_coefficients[h] += basis_polynomials_coefficients[ j][h] * self.y_list[(i * step + j) % len(self.y_list)] for h in range(len(basis_polynomials_coefficients[-2])): current_coefficients[h] += basis_polynomials_coefficients[-2][ h] * derivations[i] * self.h(i * step) for h in range(len(basis_polynomials_coefficients[-1])): current_coefficients[ h] += basis_polynomials_coefficients[-1][h] * derivations[ (i + 1) % len(derivations)] * self.h(i * step) current_coefficients = [ complex(c_c) for c_c in current_coefficients ] self.coefficients.append(current_coefficients) return
def lu_solve_lsq(M, b): x = mp.lu_solve(M, b) return x
def eqn42_solve( geom, Nmax ): # eqn 4.2 NMAX = Nmax # where to truncate the infinite system of eqns S = geom['S'] distanceqp = geom['distanceqp'] thetaqp = geom['thetaqp'] phiqp = geom['phiqp'] radii = geom['radii'] # coefficient matrix if USEMPMATH: CM = mpmath.zeros( S*NMAX*(2*NMAX+1) ) else: CM = np.zeros( (S*NMAX*(2*NMAX+1), S*NMAX*(2*NMAX+1)) ) for sprimei,sprime in enumerate(range(S)): for nprimei,nprime in enumerate(range(NMAX)): for mprimei,mprime in enumerate(range(-nprime,nprime+1)): # row index ri = sprimei*NMAX*(2*NMAX+1) + nprimei*(2*NMAX+1) + mprimei # row prefactors prefac = (-1)**(nprime+mprime) * radii[sprimei]**(nprime+1) \ * 1./factorial(nprime+mprime) for si,s in enumerate(range(S)): if sprimei != si: for ni,n in enumerate(range(NMAX)): for mi,m in enumerate(range(-n,n+1)): # column index ci = si*NMAX*(2*NMAX+1) + ni*(2*NMAX+1) + mi f1 = distanceqp[sprimei,si]**(-(n+1)) f2 = (radii[sprimei]/distanceqp[sprimei,si])**nprime f3 = factorial(n-m+nprime+mprime)/factorial(n-m) if USEMPMATH: f4 = mpmath.legenp( n+nprime, m-mprime, \ np.cos(thetaqp[sprimei,si]) ) else: f4 = scipy.special.lpmv( m-mprime, n+nprime, \ np.cos(thetaqp[sprimei,si]) ) f5 = np.exp( 1j*(m-mprime)*phiqp[sprimei,si] ) CM[ri,ci] = prefac*f1*f2*f3*f4*f5 if USEMPMATH: CM += mpmath.diag(np.ones(S*NMAX*(2*NMAX+1))) Qs = mpmath.zeros(S) else: CM += np.diag(np.ones(S*NMAX*(2*NMAX+1))) Qs = np.zeros((S,S)) for si in range(S): if USEMPMATH: rhs = mpmath.zeros( S*NMAX*(2*NMAX+1), 1 ) else: rhs = np.zeros((CM.shape[0],)) rhs[si*NMAX*(2*NMAX+1):(si*NMAX+1)*(2*NMAX+1)] = radii[si] if USEMPMATH: sol = mpmath.lu_solve( CM, rhs ) else: sol = np.linalg.solve( CM, rhs ) #print sol[::(NMAX*(2*NMAX+1))] Qs[si,:] = sol[::(NMAX*(2*NMAX+1))] return Qs
def remez(p, a, b, order, err_rel=0, n_iters=N_ITERS): # remap [a, b] to [-1, 1] for better conditioning q = mpmath.lu_solve(utils.poly_fit.vandermonde(mpmath.matrix([a, b]), 2), mpmath.matrix([-1., 1.])) # put minimax nodes halfway between Chebyshev nodes on unit circle q_x = mpmath.matrix( [mpmath.cos(i * mpmath.pi / order) for i in range(order + 1)]) x = mpmath.matrix( [a + (b - a) * (.5 + .5 * q_x[i]) for i in range(order + 1)]) #print('x', x) i = 0 while True: #print('i', i) # let r be approximating polynomial, fitted to nodes with oscillation y = utils.poly.eval_multi(p, x) #print('y', y) A = mpmath.matrix(order + 1) q_x = utils.poly.eval_multi(q, x) A[:, :order] = utils.poly_fit.vandermonde(q_x, order) for j in range(order + 1): A[j, order] = (1 - 2 * (j & 1)) * x[j]**err_rel #print('A', A) r = mpmath.lu_solve(A, y) osc = r[r.rows - 1] print('i', i, 'osc', osc) r = utils.poly.compose(r[:-1], q) #print('r', r) # let s be the error function s = utils.poly.add(r, -p) #print('s', s) if i >= n_iters: break # partition domain into intervals where s is positive or negative intervals = utils.poly.real_roots(s, a, b) #print('intervals', intervals) n_intervals = intervals.rows - 1 #print('n_intervals', n_intervals) if n_intervals < order + 1: # there absolutely have to be at least order + 1 intervals, # because the oscillating fit made r go positive and negative, # if there isn't, it means osc is very tiny or precision error #print('warning: not enough intervals -- we say good enough') #break assert False # determine if s increasing or decreasing through each boundary # have n_intervals - 1 boundaries, must produce n_intervals signs, # then check that the intervals are actually alternating in sign interval_pos = utils.poly.eval_multi(utils.poly.deriv(s), intervals[1:-1]) interval_pos = [ interval_pos[i] >= 0. for i in range(interval_pos.rows) ] #print('interval_pos', interval_pos) interval_polarity = not interval_pos[0] # sign of first interval #print('interval_polarity', interval_polarity) if any([ interval_pos[i] ^ bool(i & 1) == interval_polarity for i in range(len(interval_pos)) ]): # see above #print('warning: intervals not alternating -- we say good enough') #break assert False # within each interval, find the "global" maximum or minimum of s interval_extrema = utils.poly.interval_extrema(s, intervals) x = [] y = [] for j in range(n_intervals): extrema_x, extrema_y = interval_extrema[j] #print('j', j, 'extrema_x', extrema_x, 'extrema_y', extrema_y) k = 0 if (j & 1) == interval_polarity: for l in range(1, extrema_y.rows): if extrema_y[l] < extrema_y[k]: k = l else: for l in range(1, extrema_y.rows): if extrema_y[l] > extrema_y[k]: k = l x.append(extrema_x[k]) y.append(extrema_y[k]) x = mpmath.matrix(x) #print('x', x) y = mpmath.matrix(y) #print('y', y) # trim off unwanted intervals, extra intervals can occur at either end # (the fit can walk left or right in the domain, discovering new nodes) while n_intervals > order + 1: if abs(y[0]) >= abs(y[-1]): print('trim right') x = x[:-1] y = y[:-1] else: print('trim left') x = x[1:] y = y[1:] n_intervals -= 1 # checking #err = utils.poly.eval_multi(s, x) #print('err', err) i += 1 # final minimax error analysis _, y = utils.poly.extrema(s, a, b) err = max([abs(y[i]) for i in range(y.rows)]) print('err', err) return r, err