def get_poly(order, dim, is_simplex=False): """ Construct a polynomial of given `order` in space dimension `dim`, and integrate it symbolically over a rectangular or simplex domain for coordinates in [0, 1]. """ try: xs = sm.symarray('x', dim) except: xs = sm.symarray(dim, 'x') opd = max(1, int((order + 1) / dim)) poly = 1.0 oo = 0 for x in xs: if (oo + opd) > order: opd = order - oo poly *= (x**opd + 1) oo += opd limits = [[xs[ii], 0, 1] for ii in range(dim)] if is_simplex: for ii in range(1, dim): for ip in range(0, ii): limits[ii][2] -= xs[ip] integral = sm.integrate(poly, *reversed(limits)) return xs, poly, limits, integral
def main(y0='1,0', mu=1.0, tend=10., nt=50, savefig='None', plot=False, savetxt='None', integrator='scipy', dpi=100, kwargs='', verbose=False): assert nt > 1 y = sp.symarray('y', 2) p = sp.Symbol('p', real=True) f = [y[1], -y[0] + p*y[1]*(1 - y[0]**2)] odesys = SymbolicSys(zip(y, f), params=[p], names=True) tout = np.linspace(0, tend, nt) y0 = list(map(float, y0.split(','))) kwargs = dict(eval(kwargs) if kwargs else {}) xout, yout, info = odesys.integrate( tout, y0, [mu], integrator=integrator, **kwargs) if verbose: print(info) if savetxt != 'None': np.savetxt(stack_1d_on_left(xout, yout), savetxt) if plot: import matplotlib.pyplot as plt odesys.plot_result() plt.legend() if savefig != 'None': plt.savefig(savefig, dpi=dpi) else: plt.show()
def main(init_conc='1e-7,1e-7,1e-7,1,55.5', lnKa=-21.28, lnKw=-36.25, savetxt='None', verbose=False, rref=False, charge=False, solver='scipy'): # H+, OH- NH4+, NH3, H2O iHp, iOHm, iNH4p, iNH3, iH2O = init_conc = map(float, init_conc.split(',')) lHp, lOHm, lNH4p, lNH3, lH2O = x = sp.symarray('x', 5) Hp, OHm, NH4p, NH3, H2O = map(sp.exp, x) # lHp + lOHm - lH2O - lnKw, # lHp + lNH3 - lNH4p - lnKa, coeffs = [[1, 1, 0, 0, -1], [1, 0, -1, 1, 0]] vals = [lnKw, lnKa] lp = linear_exprs(coeffs, x, vals, rref=rref) f = lp + [ Hp + OHm + 4*NH4p + 3*NH3 + 2*H2O - ( iHp + iOHm + 4*iNH4p + 3*iNH3 + 2*iH2O), # H NH4p + NH3 - (iNH4p + iNH3), # N OHm + H2O - (iOHm + iH2O) ] if charge: f += [Hp - OHm + NH4p - (iHp - iOHm + iNH4p)] neqsys = SymbolicSys(x, f) x, sol = neqsys.solve([0]*5, solver=solver) if verbose: print(np.exp(x), sol) else: print(np.exp(x)) assert sol.success
def initialize(self, args): self.E = args[0] self.A = args[1] self.I = args[2] self.r = args[3] self.rho = args[4] self.l = args[5] self.g = args[6] q = sym.Matrix(sym.symarray('q',6)) E, A, I, r, rho, l, g = sym.symbols('E A I r rho l g') theta = sym.Matrix(['theta_1','theta_2']) omega = sym.Matrix(['omega_1','omega_2']) # Load symbolic needed matricies and vectors M_sym = pickle.load( open( "gebf-mass-matrix.dump", "rb" ) ) beta_sym = pickle.load( open( "gebf-force-vector.dump", "rb" ) ) Gamma1_sym = pickle.load( open( "gebf-1c-matrix.dump", "rb" ) ) Gamma2_sym = pickle.load( open( "gebf-2c-matrix.dump", "rb" ) ) # Create numeric function of needed matrix and vector quantities # this is MUCH MUCH faster than .subs() # .subs() is unusably slow !! self.M = lambdify((E, A, I, r, rho, l, g, q, theta, omega), M_sym, "numpy") self.beta = lambdify((E, A, I, r, rho, l, g, q, theta, omega), beta_sym, "numpy") self.Gamma1 = lambdify((E, A, I, r, rho, l, g, q, theta, omega), Gamma1_sym, "numpy") self.Gamma2 = lambdify((E, A, I, r, rho, l, g, q, theta, omega), Gamma2_sym, "numpy")
def construct_matrix_and_entries(prefix_name,shape): A_entries = matrix(sympy.symarray(prefix_name,shape)) A = sympy.Matrix.zeros(shape[0],shape[1]) for r in range(A.rows): for c in range(A.cols): A[r,c] = A_entries[r,c] return A, A_entries
def __init__(self, modulus, inertia, radius, density, length, state): """ Initializes all of the inertial propertias of the element and assigns values to physical and material properties """ # symbolic system parameters E, I, r, rho, l, = sym.symbols('E I r rho l') # Load symbolic mass matrix and substitute material properties M = pickle.load( open( "gebf-mass-matrix.dump", "rb" ) ).subs([ \ (E, modulus), (I, inertia), (r, radius), (rho, density), (l, length)]) # load the body and applied force vector and substitute material properties self.beta = pickle.load( open( "gebf-beta.dump", "rb" ) ).subs([ \ (E, modulus), (I, inertia), (r, radius), (rho, density), (l, length)]) # Substitute State Variables # re-make symbols for proper substitution and create the paird list q = sym.Matrix(sym.symarray('q',2*8)) q_sub = [(q, qi) for q, qi in zip(q, state)] # Substitute state variables beta = self.beta.subs(q_sub) M = M.subs(q_sub) # Form the binary-DCA algebraic quantities # Partition mass matrix M11 = np.array(M[0:4,0:4]) M12 = np.array(M[0:4,4:8]) M21 = np.array(M[4:8,0:4]) M22 = np.array(M[4:8,4:8]) # For now use these definitions to cast Fic (constraint forces between GEBF elements) # into generalized constraint forces self.gamma11 = np.eye(4) self.gamma12 = np.zeros((4,4)) self.gamma22 = np.eye(4) self.gamma21 = np.zeros((4,4)) # partition beta into lambda13 and lambda23 self.gamma13 = np.array(beta[0:4]) self.gamma23 = np.array(beta[4:8]) # Commonly inverted quantities iM11 = inv(self.M11) iM22 = inv(self.M22) Gamma1 = inv(self.M11 - self.M12*iM22*self.M21) Gamma2 = inv(self.M22 - self.M21*iM11*self.M12) # Compute all terms of the two handle equations self.z11 = Gamma1.dot(self.gamma11 - self.M12.dot(iM22.dot(self.gamma21))) self.z12 = Gamma1.dot(self.gamma12 - self.M12.dot(iM22.dot(self.gamma22))) self.z13 = Gamma1.dot(self.gamma13 - self.M12.dot(iM22.dot(self.gamma23))) self.z21 = Gamma2.dot(self.gamma21 - self.M21.dot(iM11.dot(self.gamma11))) self.z22 = Gamma2.dot(self.gamma22 - self.M21.dot(iM11.dot(self.gamma12))) self.z23 = Gamma2.dot(self.gamma23 - self.M21.dot(iM11.dot(self.gamma13)))
def intProps(self,args): u = args[0] # symbolic system parameters E, A, I, r, rho, l, = sym.symbols('E A, I r rho l') # Load symbolic mass matrix and substitute material properties self.M = pickle.load( open( "gebf-mass-matrix.dump", "rb" ) ).subs([ \ (E, self.E), (A, self.A), (I, self.I), (r, self.r), (rho, self.rho), (l, self.l)]) # load the body and applied force vector and substitute material properties self.beta = pickle.load( open( "gebf-beta.dump", "rb" ) ).subs([ \ (E, self.E), (A, self.A), (I, self.I), (r, self.r), (rho, self.rho), (l, self.l)]) # Substitute State Variables # re-make symbols for proper substitution and create the paird list q = sym.Matrix(sym.symarray('q',2*3)) qe = [self.theta1] + u[:2] + [self.theta2] + u[2:] q_sub = [(q, qi) for q, qi in zip(q, qe)] # Substitute state variables self.beta = self.beta.subs(q_sub).evalf() self.M = self.M.subs(q_sub).evalf() # Form the binary-DCA algebraic quantities # Partition mass matrix self.M11 = np.array(self.M[0:3,0:3]) self.M12 = np.array(self.M[0:3,3:6]) self.M21 = np.array(self.M[3:6,0:3]) self.M22 = np.array(self.M[3:6,3:6]) # For now use these definitions to cast Fic (constraint forces between GEBF elements) # into generalized constraint forces self.gamma11 = np.eye(3) self.gamma12 = np.zeros((3,3)) self.gamma22 = np.eye(3) self.gamma21 = np.zeros((3,3)) # partition beta into lambda13 and lambda23 self.gamma13 = np.array(self.beta[0:3]) self.gamma23 = np.array(self.beta[3:6]) # Commonly inverted quantities self.iM11 = inv(self.M11) self.iM22 = inv(self.M22) self.Gamma1 = inv(self.M11 - self.M12*self.iM22*self.M21) self.Gamma2 = inv(self.M22 - self.M21*self.iM11*self.M12) # Compute all terms of the two handle equations self.z11 = self.Gamma1.dot(self.gamma11 - self.M12.dot(self.iM22.dot(self.gamma21))) self.z12 = self.Gamma1.dot(self.gamma12 - self.M12.dot(self.iM22.dot(self.gamma22))) self.z13 = self.Gamma1.dot(self.gamma13 - self.M12.dot(self.iM22.dot(self.gamma23))) self.z21 = self.Gamma2.dot(self.gamma21 - self.M21.dot(self.iM11.dot(self.gamma11))) self.z22 = self.Gamma2.dot(self.gamma22 - self.M21.dot(self.iM11.dot(self.gamma12))) self.z23 = self.Gamma2.dot(self.gamma23 - self.M21.dot(self.iM11.dot(self.gamma13)))
def test_SymbolicSys_bateman(band): tend, k, y0 = 2, [4, 3], (5, 4, 2) y = sp.symarray('y', len(k)+1) dydt = decay_dydt_factory(k) f = dydt(0, y) odesys = SymbolicSys(zip(y, f), band=band) xout, yout, info = odesys.integrate(tend, y0, integrator='scipy') ref = np.array(bateman_full(y0, k+[0], xout-xout[0], exp=np.exp)).T assert np.allclose(yout, ref)
def test_symarray(): """Test creation of numpy arrays of sympy symbols.""" import numpy as np import numpy.testing as npt syms = symbols('_0 _1 _2') s1 = symarray(3) s2 = symarray(3) npt.assert_array_equal (s1, np.array(syms, dtype=object)) assert s1[0] is s2[0] a = symarray(3, 'a') b = symarray(3, 'b') assert not(a[0] is b[0]) asyms = symbols('a_0 a_1 a_2') npt.assert_array_equal (a, np.array(asyms, dtype=object)) # Multidimensional checks a2d = symarray((2,3), 'a') assert a2d.shape == (2,3) a00, a12 = symbols('a_0_0, a_1_2') assert a2d[0,0] is a00 assert a2d[1,2] is a12 a3d = symarray((2,3,2), 'a') assert a3d.shape == (2,3,2) a000, a120, a121 = symbols('a_0_0_0, a_1_2_0 a_1_2_1') assert a3d[0,0,0] is a000 assert a3d[1,2,0] is a120 assert a3d[1,2,1] is a121
def test_linear_exprs(): a, b, c = x = sp.symarray('x', 3) coeffs = [[1, 3, -2], [3, 5, 6], [2, 4, 3]] vals = [5, 7, 8] exprs = linear_exprs(coeffs, x, vals) known = [1*a + 3*b - 2*c - 5, 3*a + 5*b + 6*c - 7, 2*a + 4*b + 3*c - 8] assert all([(rt - kn).simplify() == 0 for rt, kn in zip(exprs, known)]) rexprs = linear_exprs(coeffs, x, vals, rref=True) rknown = [a + 15, b - 8, c - 2] assert all([(rt - kn).simplify() == 0 for rt, kn in zip(rexprs, rknown)])
def __init__(self,name,func,argnames=None): """ Args: name (str): the symbolic module name of the function. func (sympy.Function): the Sympy function argnames (list of strs, optional): provided if you don't want to use 'x','y', 'z' for the argument names. """ assert isinstance(func,sympy.FunctionClass) if hasattr(func,'nargs'): if len(func.nargs) > 1: print("SympyFunctionAdaptor: can't yet handle multi-argument functions") nargs = None for i in func.nargs: nargs = i else: nargs = 1 if argnames is None: if nargs == 1: argnames = ['x'] elif nargs <= 3: argnames = [['x','y','z'][i] for i in len(nargs)] else: argnames = ['arg'+str(i+1) for i in len(nargs)] Function.__init__(self,name,func,argnames) self.deriv = [None]*len(argnames) self.jacobian = [None]*len(argnames) self.sympy_jacobian = [None]*len(argnames) self.sympy_jacobian_funcs = [None]*len(argnames) xs = sympy.symarray('x',nargs) for i,arg in enumerate(argnames): self.sympy_jacobian[i] = func(*xs).diff(xs[i]) for i in range(len(argnames)): def cache_jacobian(*args): if self.sympy_jacobian_funcs[i] is None: #print "Creating jacobian function",name + "_jac_" + argnames[i] self.sympy_jacobian_funcs[i] = SympyFunction(name + "_jac_" + argnames[i], self.sympy_jacobian[i],argnames) return OperatorExpression(self.sympy_jacobian_funcs[i],args) self.jacobian[i] = cache_jacobian
def generate_jac_lambda(self): """ translates the symbolic Jacobian to a function using SymPy’s `lambdify <http://docs.sympy.org/latest/modules/utilities/lambdify.html>`_ tool. If the symbolic Jacobian has not been generated, it is generated by calling `generate_jac_sym`. """ if self.helpers: warn("Lambdification handles helpers by pluggin them in. This may be very ineficient") self._generate_jac_sym() jac_matrix = sympy.Matrix([ [entry for entry in line] for line in self.jac_sym ]) t,y = provide_basic_symbols() Y = sympy.symarray("Y", self.n) substitutions = self.helpers[::-1] + [(y(i),Y[i]) for i in range(self.n)] jac_subsed = jac_matrix.subs(substitutions) JAC = sympy.lambdify([t]+[Yentry for Yentry in Y], jac_subsed) self.jac = lambda t,ypsilon: array(JAC(t,*ypsilon))
def calculate_moment_expansion_trick(args, expr, order, delete_first_moment=False): # sad hack expansion = expr index_start = 1 if delete_first_moment: index_start = 2 moment_indices = range(index_start, order + 1) spectral_functions = [] for k in moment_indices: deriv_list = moment_derivatives(args, [expr / args[0]], k) spectral_functions += clean_derivatives(deriv_list) moments = list(sym.symarray('w', len(spectral_functions))) if spectral_functions: expansion += sym.Matrix(moments).dot(sym.Matrix(spectral_functions)) return moments, expansion
def trou_formula(self, value_list): can_list = [] # 参数 temp = [] max = len(value_list) _print(type(value_list)) for num in range(1, max + 1): can_list.append([num**x for x in range(1, max + 1)]) a = sympy.Matrix(can_list) b = sympy.Matrix(value_list) x = sympy.symarray('x', (max, 1)) dict = sympy.solve(a * x - b) # return dict for items in dict.items(): temp.append(items[1]) n = sympy.Symbol('n') value = 0 temp_len = len(temp) for i in range(0, temp_len): letter = sympy.simplify(temp[i] * n**(temp_len - i - 1)) value += letter return value
def differentials(f,x,y): """ Returns a basis of the holomorphic differentials defined on the Riemann surface `X: f(x,y) = 0`. Input: - f: a Sympy object describing a complex plane algebraic curve. - x,y: the independent and dependent variables, respectively. """ d = f.as_poly().total_degree() n = sympy.degree(f,y) # coeffiecients and general adjoint polynomial c_arr = sympy.symarray('c',(d-3,d-3)).tolist() c = dict( (cij,(c_arr.index(ci),ci.index(cij))) for ci in c_arr for cij in ci ) P = sum( c_arr[i][j]*x**i*y**j for i in range(d-3) for j in range(d-3) if i+j <= d-3) S = singularities(f,x,y) differentials = set([]) for (alpha, beta, gamma), (m,delta,r) in S: g,u,v,u0,v0 = _transform(f,x,y,(alpha,beta,gamma)) # if delta > m*(m-1)/2: if True: # Use integral basis method. b = integral_basis(g,u,v) for bi in b: monoms = _adjoint_monomials(f,x,y,bi,P,c) differentials.add(monom for monom in monoms) else: # Use Puiseux series method b = integral_basis(g,u,v) return [differential/sympy.diff(f,y) for differential in differentials]
def give_coords(self, distances): distances = np.array(distances) n = len(distances) X = sympy.symarray('x', (n, n - 1)) for row in range(n): X[row, row:] = [0] * (n - 1 - row) for point2 in range(1, n): expressions = [] for point1 in range(point2): expression = np.sum((X[point1] - X[point2])**2) expression -= distances[point1, point2]**2 expressions.append(expression) X[point2, :point2] = sympy.solve(expressions, list(X[point2, :point2]))[1] return X
def preprocess(self, p, _x, config): if not p.eq: return p, _x free_vars = symarray('x', p.n, commutative=False) free_vars = Matrix(free_vars) rhs = self.solve_equitions(to_matrix(p.eq.A), to_matrix(p.eq.b), free_vars) p.eq = None self.vars_mapping = rhs new_free_vars = list(rhs.free_symbols) new_x = self.new_x(free_vars, new_free_vars, _x) self.free_vars = new_free_vars new_free_vars = Matrix(new_free_vars) A, b = self.linear_equitions_var_subs(to_matrix(p.le.A), to_matrix(p.le.b), rhs, new_free_vars) p.le.A = p.le.A.new(A) p.le.b = p.le.b.new(b) if isinstance(p.obj, LinearObjective): b, c = self.linear_expr_var_subs(to_matrix(p.obj.b), float(p.obj.c), rhs, new_free_vars) p.obj.b = p.obj.b.new(b) p.obj.c = c if isinstance(p.obj, QuadraticObjective): A, b, c = self.quadratic_expr_var_subs(to_matrix(p.obj.A), to_matrix(p.obj.b), float(p.obj.c), rhs, new_free_vars) p.obj.A = p.obj.A.new(A) p.obj.b = p.obj.b.new(b) p.obj.c = c return p, new_x
def generate_f_lambda(self, simplify=True): """ translates the symbolic derivative to a function using SymPy’s `lambdify <http://docs.sympy.org/latest/modules/utilities/lambdify.html>`_ tool. Parameters ---------- simplify : boolean Whether the derivative should be `simplified <http://docs.sympy.org/dev/modules/simplify/simplify.html>`_ (with `ratio=1.0`) before translating to C code. The main reason why you could want to disable this is if your derivative is already optimised and so large that simplifying takes a considerable amount of time. """ if self.helpers: warn("Lambdification does not handle helpers in an efficient manner.") t,y = provide_basic_symbols() Y = sympy.symarray("Y", self.n) substitutions = self.helpers[::-1] + [(y(i),Y[i]) for i in range(self.n)] f_sym_wc = (entry.subs(substitutions) for entry in f_sym) if simplify: f_sym_wc = (entry.simplify(ratio=1.0) for entry in f_sym) F = sympy.lambdify([t]+[Yentry for Yentry in Y], list(f_sym_wc)) self.f = lambda t,ypsilon: array(F(t,*ypsilon)).flatten()
def model_format(mode, num_cluster, bound_limit=1e-9): data = np.sort(data, axis = 0) data_length = len(data) raw_probability = np.array([(i - 0.3) / data_length for i in range(1, data_length+1)]) plot_p = np.log(-np.log(1 - raw_probability)) if mode == 'GM': # Gaussian Mixture t = sy.symbols('t') u = sy.symarray('u', num_cluster) var = sy.symarray('var', num_cluster) PDF = [1/(sqrt(2*pi)*j) * sy.exp(((t-i)/(sqrt(2)*j))**2) for i,j in zip(u, var)] variable_list = [t, u, var] bound = ((bound_limit, 1/bound_limit), (None, None), (None, None)) elif mode == 'WM': # Weibull Mixture t = sy.symbols('t') k = sy.symarray('k', num_cluster) tor = sy.symarray('tor', num_cluster) PDF = sy.diff(1 - sy.exp(- (t/tor)**k), t) variable_list = [t, k, tor] bound = ((bound_limit, 1/bound_limit), (None, None), (None, None)) elif mode == 'CM': t = sy.symbols('t') a = sy.symarray('a', num_cluster) b = sy.symarray('b', num_cluster) tor = sy.symarray('tor', num_cluster) PDF = sy.diff(1 - (1 + 1/a*(t/tor)**(b))**(-a), t) variable_list = [t, a, b, tor] bound = ((bound_limit, 1/bound_limit), (None, None), (None, None), (bound_limit, 1/bound_limit)) else: print('Mode Error') PDF = None variable_list = None bound = None return PDF, variable_list, bound
def generate_f_lambda(self, simplify=True): """ translates the symbolic derivative to a function using SymPy’s `lambdify <http://docs.sympy.org/latest/modules/utilities/lambdify.html>`_ tool. Parameters ---------- simplify : boolean Whether the derivative should be `simplified <http://docs.sympy.org/dev/modules/simplify/simplify.html>`_ (with `ratio=1.0`) before translating to C code. The main reason why you could want to disable this is if your derivative is already optimised and so large that simplifying takes a considerable amount of time. """ if self.helpers: warn("Lambdification does not handle helpers in an efficient manner.") t,y = provide_basic_symbols() Y = sympy.symarray("Y", self.n) substitutions = self.helpers[::-1] + [(y(i),Y[i]) for i in range(self.n)] f_sym_wc = (entry.subs(substitutions) for entry in self.f_sym()) if simplify: f_sym_wc = (entry.simplify(ratio=1.0) for entry in f_sym_wc) F = sympy.lambdify([t]+[Yentry for Yentry in Y], list(f_sym_wc)) self.f = lambda t,ypsilon: array(F(t,*ypsilon)).flatten()
def generate_jac_lambda(self): """ translates the symbolic Jacobian to a function using SymPy’s `lambdify <http://docs.sympy.org/latest/modules/utilities/lambdify.html>`_ tool. If the symbolic Jacobian has not been generated, it is generated by calling `generate_jac_sym`. """ if self.helpers: warn( "Lambdification handles helpers by pluggin them in. This may be very ineficient" ) self._generate_jac_sym() jac_matrix = sympy.Matrix([[entry for entry in line] for line in self.jac_sym]) t, y = provide_basic_symbols() Y = sympy.symarray("Y", self.n) substitutions = self.helpers[::-1] + [(y(i), Y[i]) for i in range(self.n)] jac_subsed = jac_matrix.subs(substitutions) JAC = sympy.lambdify([t] + [Yentry for Yentry in Y], jac_subsed) self.jac = lambda t, ypsilon: array(JAC(t, *ypsilon))
import sympy as sp import numpy as np import matplotlib.pyplot as plt from sympy.interactive import printing from sympy.parsing.sympy_parser import parse_expr from sympy.printing.latex import latex import typing x = sp.symarray('x', 5) #C, P, R, T == x[1], x[2], x[3], x[4] respectively xpr = parse_expr some_var = 606 #equation parameters k_c, mu_c, C_0, lambda_c, K_c = sp.symbols("k_c, mu_c, C_0, lambda_c, K_c") k_p, mu_p, K_p, P_0, lambda_p = sp.symbols("k_p, mu_p, K_p, P_0, lambda_p") k_r, lambda_r, gamma_p, gamma_c = sp.symbols("k_r, lambda_r, gamma_p, gamma_c") k_t, K_t, lambda_t = sp.symbols("k_t, K_t, lambda_t") params = {'C_0' : 10**6, 'P_0' : 10**5,'k_c' : 7.5e-2, 'K_c' : 0.1, 'lambda_c' : 10**(-7), \ 'k_p' : 0.2, 'lambda_p' : 0.15, 'k_r' : 0.2, 'lambda_r' : 0.22, 'k_t' : 3300, 'lambda_t' : 0.3} params['mu_c'] = 20 * params['k_c'] / params['P_0'] params['mu_p'] = 20 * params['k_p'] params['K_p'] = params['C_0'] / 100 params['gamma_p'] = 0.02 * params['lambda_r'] / ( params['P_0'] * (1 - params['lambda_p'] / params['k_p'])) params['gamma_c'] = params['gamma_p'] params['K_t'] = params['K_c'] # f1 = (k_c + mu_c*x[2]) * x[1]**(3/4) * (1 - (x[1]/C_0)**(1/4) ) - \
# Kinematic values of previos nodes (generic) # e.g., omega_node = omega + qdot theta = sym.Matrix(['theta_1','theta_2']) omega = sym.Matrix(['omega_1','omega_2']) alpha = sym.Matrix(['alpha_1','alpha_2']) # coordinates of the point in the 2D cross-section # of nodes one and two s1 = sym.Matrix(['r_2','r_3']) s2 = sym.Matrix(['r_2','r_3']) s = sym.Matrix.vstack(s1,s2) # generalized coordinates # one rotation and two displacements per-node (two nodes per element) # in this version generalzied speeds are qdots q = sym.Matrix(sym.symarray('q',6)) qdot = sym.Matrix(sym.symarray('qdot',len(q))) qddot = sym.Matrix(sym.symarray('qddot',len(q))) # Deformations of Nodes (u's are not generalized speeds) u = sym.Matrix([q[1:3,0], q[4:6,0]]) udot = sym.Matrix([qdot[1:3,0], qdot[4:8,0]]) uddot = sym.Matrix([qddot[1:3,0], qddot[4:6,0]]) # ### Needed Matrix Quantities """ Some cheating here: q0,q3 and q0dot,q3dot are really theta_1j, theta_2j and omega_1j, omega_2j """ # angular position and velocity for 2D using relative coordinates # the sum of the respective quantites of bodies 1 - bodyj-1
def __init__( self, params: Dict[str, Any], states: Dict[str, Any], rhs_sympy: Callable[[sym.Symbol, np.ndarray, np.ndarray], Dict[str, Any]], derivative_params: List[Path], coords: Optional[Dict[str, pd.Index]] = None, simplify: Optional[Callable[[sym.Expr], sym.Expr]] = None, ): self.params_subset = dtypesubset.DTypeSubset( params, derivative_params, fixed_dtype=basic.data_dtype, coords=coords) self.coords = self.params_subset.coords self.params_dtype = self.params_subset.dtype self.state_subset = dtypesubset.DTypeSubset( states, [], fixed_dtype=basic.data_dtype, coords=self.coords) self.state_dtype = self.state_subset.dtype self._rhs_sympy_func = rhs_sympy if simplify is None: simplify = lambda x: x self._simplify = np.vectorize(simplify) def check_dtype(dtype: np.dtype, path: Optional[str] = None) -> None: if dtype.fields is None: if dtype.base != basic.data_dtype: raise ValueError( 'Derivative param %s has incorrect dtype %s. Should be %s' % (path, dtype.base, basic.data_dtype)) return for name, (dt, _) in dtype.fields.items(): if path is None: path_ = name else: path_ = '.'.join([path, name]) check_dtype(dt, path_) check_dtype(self.params_subset.subset_dtype) self._sym_time = sym.Symbol('time', real=True) n_fixed = self.params_subset.n_items - self.n_params def make_vars(var_shapes: Dict[Path, Shape], **kwargs: Any) -> Dict[Path, sym.Symbol]: vars = {} for path, shape in var_shapes.items(): name = '_'.join(path) var = sym.symarray(name, shape, **kwargs) vars[path] = var return vars self._sym_states = make_vars(self.state_subset.flat_shapes, positive=True) self._sym_params = make_vars(self.params_subset.flat_shapes, real=True) self._varmap: Dict[str, Tuple[Any, ...]] = {} for path, vars in self._sym_states.items(): for idxs in product(*[range(i) for i in vars.shape]): var = vars[idxs] if idxs == (): self._varmap[var.name] = ('state', *path) else: self._varmap[var.name] = ('state', *path, idxs) for path, vars in self._sym_params.items(): for idxs in product(*[range(i) for i in vars.shape]): var = vars[idxs] if idxs == (): self._varmap[var.name] = ('params', *path) else: self._varmap[var.name] = ('params', *path, idxs) deriv_params = { k: v for k, v in self._sym_params.items() if k in self.params_subset.subset_paths } if deriv_params: raveled_deriv = np.concatenate( [var.ravel() for var in deriv_params.values()]) else: raveled_deriv = np.zeros((0, )) fixed_params = { k: v for k, v in self._sym_params.items() if k not in self.params_subset.subset_paths } if fixed_params: raveled_fixed = np.concatenate( [var.ravel() for var in fixed_params.values()]) else: raveled_fixed = np.zeros((0, )) def item_map(item: np.ndarray) -> np.ndarray: if hasattr(item, 'shape') and item.shape == (): return item.item() return item self._sym_deriv_paramsvec = raveled_deriv self._sym_params = self.params_subset.as_dataclass('Params', raveled_deriv, raveled_fixed, item_map=item_map) self._sym_statevec = np.concatenate( [var.ravel() for var in self._sym_states.values()]) self._sym_states = self.state_subset.as_dataclass('State', [], self._sym_statevec, item_map=item_map) dydt = self._make_dydt() self._sym_dydt = np.array(dydt).ravel() self._sym_sens = sym.symarray('sens', (self.n_params, self.n_states)) self._sym_lamda = sym.symarray('lamda', self.n_states) for idxs in product(*[range(i) for i in self._sym_lamda.shape]): var = self._sym_lamda[idxs] self._varmap[var.name] = ('lamda', idxs) for idxs in product(*[range(i) for i in self._sym_sens.shape]): var = self._sym_sens[idxs] self._varmap[var.name] = ('sens', idxs) self._sym_dydt_jac = np.array(dydt.jacobian(self._sym_statevec)) #self._sym_dydp = np.array([val.diff(self._sym_deriv_paramsvec) for val in self._sym_dydt]) self._sym_dydp = np.array(dydt.jacobian(self._sym_deriv_paramsvec)) #jacprotsens = (self._sym_dydt_jac * self._sym_sens.T.as_explicit()).as_explicit() #self._sym_rhs_sens = (jacprotsens + self._sym_dydp).as_explicit().T self._sym_dlamdadt = -self._sym_lamda @ self._sym_dydt_jac self._sym_quad_rhs = self._sym_lamda @ self._sym_dydp self.user_data_dtype = np.dtype([ ('params', self.params_subset.dtype), ('tmp_nstates_nstates', np.float64, (self.n_states, self.n_states)), ('tmp_nparams_nstates', np.float64, (self.n_params, self.n_states)), ('tmp2_nparams_nstates', np.float64, (self.n_params, self.n_states)), ('error_states', self.state_dtype), ('error_rhs', np.float64, (self.n_states, )), ('error_jac', np.float64, (self.n_states, self.n_states)), ])
sp.linsolve(ftz_from_F_c_expr.values(), l_robot["ftz"].values()).args[0]) # A = l_robot["thrusters_mapping"] # ftz_from_F_c_result = (A.T*A).inv()*A.T*F_c # Least squares return { "lambda": sp.lambdify((F_c, ), ftz_from_F_c_result, 'numpy'), "s_lambda": sp.lambdify((F_c, ), ftz_from_F_c_result, 'sympy'), "result": ftz_from_F_c_result, "expr": ftz_from_F_c_expr, "J_wrt_F_c": ftz_from_F_c_result.jacobian(F_c) } w_c = sp.Matrix(sp.symarray('w_c', 3)) v_c = sp.Matrix(sp.symarray('v_c', 3)) V_c = sp.Matrix([w_c, v_c]) t_sc = sp.Matrix(sp.symarray('t_sc', 3)) q_s_cog = sp.Matrix(sp.symbols('q_sc_w q_sc_x q_sc_y q_sc_z')) # world to COG q_sc = sophus.Quaternion(q_s_cog[0], q_s_cog[1:4, :]) T_sc = sophus.Se3(sophus.So3(q_sc), t_sc) t_st = sp.Matrix(sp.symarray('t_st', 3)) q_s_target = sp.Matrix( sp.symbols('q_st_w q_st_x q_st_y q_st_z')) # world to target q_st = sophus.Quaternion(q_s_target[0], q_s_target[1:4, :]) T_st = sophus.Se3(sophus.So3(q_st), t_st)
""" # Consider the TSP problem with cost matrix: """ $\begin{bmatrix} 0 & 1 & 2 & 9 & 2 & 1 \\ 1 & 0 & 1 & 2 & 9 & 2 \\ 2 & 1 & 0 & 1 & 2 & 9 \\ 9 & 2 & 1 & 0 & 1 & 2 \\ 2 & 9 & 2 & 1 & 0 & 1 \\ 1 & 2 & 9 & 2 & 1 & 0 \end{bmatrix}$ """ # The following equations are just a few of the many which arise C = sympy.symarray("C", (7, 7), nonnegative=True) eqns = [ sympy.Eq(C[1][2] + C[2][3] + C[3][4] + C[4][5] + C[5][6] + C[6][1], 6), sympy.Eq(C[1][2] + C[2][3] + C[3][4] + C[4][6] + C[6][5] + C[5][1], 8), sympy.Eq(C[1][2] + C[2][3] + C[3][5] + C[5][4] + C[4][6] + C[6][1], 8), sympy.Eq(C[1][2] + C[2][4] + C[4][3] + C[3][5] + C[5][6] + C[6][1], 8), sympy.Eq(C[1][3] + C[3][2] + C[2][4] + C[4][5] + C[5][6] + C[6][1], 8), sympy.Eq(C[1][3] + C[3][4] + C[4][5] + C[5][6] + C[6][2] + C[2][1], 8), sympy.Eq(C[1][6] + C[6][2] + C[2][3] + C[3][4] + C[4][5] + C[5][1], 8) ] # If we use sympy to solve, we find multiple solutions, one of which # is the original C. print("Solutions to equations from the original problem:") print(sympy.solve(eqns))
def n_bar_pendulum(N=1, param_values=dict()): ''' Returns the mass matrix :math:`M` and right hand site :math:`B` of motion equations .. math:: M * (d^2/dt^2) x = B for the :math:`N`\ -bar pendulum. Parameters ---------- N : int Number of bars. param_values : dict Numeric values for the system parameters, such as lengths, masses and gravitational acceleration. Returns ------- sympy.Matrix The mass matrix `M` sympy.Matrix The right hand site `B` list List of symbols for state variables list List with symbol for input variable ''' # first we have to create some symbols F = sp.Symbol('F') # the force that acts on the car g = sp.Symbol('g') # the gravitational acceleration m = sp.symarray('m', N+1) # masses of the car (`m0`) and the bars l = sp.symarray('l', N+1)#[1:] # length of the bars (`l0` is not needed nor used) phi = sp.symarray('phi', N+1)#[1:] # deflaction angles of the bars (`phi0` is not needed nor used) dphi = sp.symarray('dphi', N+1)#[1:] # 1st derivative of the deflaction angles (`dphi0` is not needed nor used) if param_values.has_key('F'): F = param_values['F'] elif param_values.has_key(F): F = param_values[F] if param_values.has_key('g'): g = param_values['g'] elif param_values.has_key(g): g = param_values[g] else: g = 9.81 for i, mi in enumerate(m): if param_values.has_key(mi.name): m[i] = param_values[mi.name] elif param_values.has_key(mi): m[i] = param_values[mi] for i, li in enumerate(l): if param_values.has_key(li.name): l[i] = param_values[li.name] elif param_values.has_key(li): l[i] = param_values[li] C = np.empty((N,N), dtype=object) S = np.empty((N,N), dtype=object) I = np.empty((N), dtype=object) for i in xrange(1,N+1): for j in xrange(1,N+1): C[i-1,j-1] = cos(phi[i] - phi[j]) S[i-1,j-1] = sin(phi[i] - phi[j]) for i in xrange(1,N+1): if param_values.has_key('I_%d'%i): I[i-1] = param_values['I_%d'%i] #elif param_values.has_key(Ii): # I[i] = param_values[Ii] else: I[i-1] = 4.0/3.0 * m[i] * l[i]**2 #-------------# # Mass matrix # #-------------# M = np.empty((N+1, N+1), dtype=object) # 1st row M[0,0] = m.sum() for j in xrange(1,N): M[0,j] = (m[j] + 2*m[j+1:].sum()) * l[j] * cos(phi[j]) M[0,N] = m[N] * l[N] * cos(phi[N]) # rest of upper triangular part, except last column for i in xrange(1,N): M[i,i] = I[i-1] + (m[i] + 4.0*m[i+1:].sum()) * l[i]**2 for j in xrange(i+1,N): M[i,j] = 2.0*(m[j] + 2.0*m[j+1:].sum())*l[i]*l[j]*C[j-1,i-1] # the last column for i in xrange(1,N): M[i,N] = 2.0*(m[N]*l[i]*l[N]*C[N-1,i-1]) M[N,N] = I[N-1] + m[N]*l[N]**2 # the rest (lower triangular part) for i in xrange(N+1): for j in xrange(i,N+1): M[j,i] = 1 * M[i,j] #-----------------# # Right hand site # #-----------------# B = np.empty((N+1), dtype=object) # first row B[0] = F for j in xrange(1,N): B[0] += (m[j] + 2.0*m[j+1:].sum())*l[j]*sin(phi[j]) * dphi[j]**2 B[0] += (m[N]*l[N]*sin(phi[N])) * dphi[N]**2 # rest except for last row for i in xrange(1,N): B[i] = (m[i] + 2.0*m[i+1:].sum())*g*l[i]*sin(phi[i]) for j in xrange(1,N): B[i] += (2.0*(m[j] + 2.0*m[j+1:].sum())*l[j]*l[i]*S[j-1,i-1]) * dphi[j]**2 B[i] += (2.0*m[N]*l[N]*l[N]*S[N-1,i-1]) * dphi[N]**2 # last row B[N] = m[N]*g*l[N]*sin(phi[N]) for j in xrange(1,N+1): B[N] += (2.0*m[N]*l[j]*l[N]*S[j-1,N-1]) * dphi[j]**2 # build lists of state and input variables x, dx = sp.symbols('x, dx') state_vars = [x, dx] for i in xrange(1,N+1): state_vars.append(phi[i]) state_vars.append(dphi[i]) input_vars = [F] # return stuff return sp.Matrix(M), sp.Matrix(B), state_vars, input_vars
import sympy as sym # we import the sympy package import math # we import the math package (not used here, but has useful constants such math.pi which might be needed in other cases) import sys # import the sys module used below from pylab import * from gravipy import * ############################################################################################################################################ # if using an integrated environment we recommend restarting the python console after running this script to make sure updates are found location = "/home/jwr/Code/PyTransport/" # this should be the location of the PyTransport folder sys.path.append(location) # we add this location to the python path import PyTransSetup # the above commands allows python to find the PyTransSetup module and import it ############################################################################################################################################ nF=3 # number of fields needed to define the PseudoScalar potential nP=3 # number of parameters needed to define the PseudoScalar potential f=sym.symarray('f',nF) # an array representing the nF fields present for this model p=sym.symarray('p',nP) # an array representing the nP parameters needed to define this model (that we might wish to change) if we don't V= p[0] * f[0]**2 + p[1] * f[1]**2 + p[2] * f[2]**2 # this is the potential written in sympy notation R=(0.9)/((sym.cosh(2.0*((1.0*f[0])-7.0)/0.12))**(2.0)) G=Matrix([[1,R,0],[R,1,0],[0,0,1]]) # selecting the field space metric in this instance. PyTransSetup.potential(V,nF,nP,False,G) # writes this potential and its derivatives into C++ file potential.h when run PyTransSetup.compileName("Pseudo",True) # this compiles a python module using the C++ code, including the edited potential.h file, called PyTransPseudo # and places it in the location folder, ready for use ############################################################################################################################################
variableit = input("elemento de matriz M: ") vcm1.append(variableit) for j in range(a * b): variableit2 = input("elemento de matriz V: ") vcm2.append(variableit2) NewM = sy.Matrix(a, b, vcm1) NewV = sy.Matrix(a, b, vcm2) w2 = sy.symbols("w2") m_v = w2 * NewM - NewV autovalor = sy.solve(m_v.det(), w2) glist = list(sy.symarray("a", a)) vec = [0 for i in range(a)] md0 = sy.Matrix(vec) M_x = [] for i in range(len(autovalor)): z = autovalor[i] M_0 = z * NewM - NewV sol = list(sy.linsolve((M_0, md0), glist)) M_x.append(sol) print("autovalor :", autovalor[i], ", autovector :", sol) #print (NewM)
def add_link(self, dh): new_joint = Joint(dh) if isinstance(dh[0], Expr): self.link_list.append(new_joint) self.transform_list.append(new_joint) self.sym_theta_list = symarray("theta", len(self.link_list))
def __init__(self, f, x, k, f_args=None): self.f = f self.x = x self.k = k if np.array(x).shape == (): n, x = 1, [x] else: n = len(x) # call to f if f_args is None: f_eval = f(*x) else: f_eval = f(*(list(x) + list(f_args))) if np.array(f_eval).shape == (): m = 1 else: # call to f m = len(f_eval) self.m = m self.n = n # list of symbolic variables var = sympy.symarray('x', (n, )) # polynomial basis pb = bases.poly_basis(var) # vector basis vb = bases.vf_basis(pb, m) # k-jet of f centered at x # call to f self.jet = jet.jet(f, x, k, f_args, var, pb) # fundamental operator of normal form theory, Lie bracket with f' self.L1 = lie_operator.lie_operator(self.jet.fun_deg[1], var, 1, pb, vb) # work space of coefficients n_terms = combinatorics.simplicial_list(n, k) wrk = [[np.zeros(m * n_terms[i + j + 1]) for j in range(k - i)] for i in range(k)] # initialize first row of workspace as k-jet for j in range(k): wrk[0][j] = np.concatenate(self.jet.coeff[j + 1]) # generators g = [] # Lie brackets with generators L = [] # equivariant vector fields eqv = [] # list of factorials fac = combinatorics.factorial_list(k) # algorithm based on Murdock for deg in range(2, k + 1): # update workspace and solve for generator for j, l in enumerate(L): wrk[1][deg - 2] += l[deg - 1 - j].dot(wrk[0][deg - 2 - j]) f_coeff = np.zeros(m * n_terms[deg]) for i in range(deg): f_coeff += wrk[i][deg - 1 - i] / fac[i] g_coeff = np.linalg.lstsq(self.L1[deg], f_coeff)[0] # normal form coefficients h_coeff = f_coeff - self.L1[deg].dot(g_coeff) # represent normal form term in L1.T nullspace basis u, s, v = np.linalg.svd(self.L1[deg]) rank = min(self.L1[deg].shape) - np.isclose(s, 0).sum() perp_basis = u[:, rank:] e_coeff = perp_basis.T.conj().dot(h_coeff) e = [ sympy.Matrix(perp_basis[:, i].reshape( m, perp_basis[:, i].shape[0] / m)) * pb[deg] for i in range(perp_basis.shape[1]) ] # truncate roundoff error for coeff in [e_coeff, f_coeff, g_coeff, h_coeff]: coeff[np.isclose(coeff, 0)] = 0 # store generator g.append( sympy.Matrix(np.reshape(g_coeff, (m, len(g_coeff) / m))) * pb[deg]) # update series coeff self.jet.coeff[deg] = np.reshape(h_coeff, (m, len(h_coeff) / m)) # store equivariant vector fields eqv.append((e_coeff, e)) # store Lie operator L.append(lie_operator.lie_operator(g[-1], var, deg, pb, vb)) # update workspace wrk[1][deg - 2] += L[-1][1].dot(wrk[0][0]) for i in range(2, k - deg + 2): for j, l in enumerate(L): wrk[i][deg - 2] += l[deg - 2 + i - j].dot( wrk[i - 1][deg - 2 - j]) self.L = L self.g = g self.eqv = eqv # update series symbolic and lambdified representation self.jet.update_fun() # make jet.fun accessible from this class self.fun = self.jet.fun
def __init__(self, f, x, k, f_args=None, var=None, pb=None): """initialize the jet""" self.f = f self.x = x self.k = k if np.array(x).shape == (): n, x = 1, [x] else: n = len(x) # call to f if f_args is None: f_eval = f(*x) else: f_eval = f(*(list(x) + list(f_args))) if np.array(f_eval).shape == (): m = 1 else: # call to f m = len(f_eval) self.m = m self.n = n if var is None: var = sympy.symarray('x', (n, )) if pb is None: pb = bases.poly_basis(var) self.var = var self.pb = pb # number of terms per degree of expanded form n_terms = combinatorics.simplicial_list(n, k) coeff = [np.empty([m, n_terms[deg]]) for deg in range(k + 1)] basis = [sympy.ones(n_terms[deg], 1) for deg in range(k + 1)] # call to f if f_args is None: f_eval = f(*var) else: f_eval = f(*(list(var) + list(f_args))) coeff[0][:, 0] = list(sympy.Matrix([f_eval]).subs(zip(var, x))) for deg in range(1, k + 1): m_idx = multiindex(deg, n) for term in range(n_terms[deg]): # call to f if f_args is None: f_eval = f(*var) else: f_eval = f(*(list(var) + list(f_args))) coeff[deg][:, term] = list( sympy.diff(sympy.Matrix([f_eval]), * m_idx.to_var(var)).subs(zip(var, x)) / m_idx.factorial()) basis[deg][term] = m_idx.to_polynomial(var, x) m_idx.increment() for deg in range(k + 1): poly = list(sympy.Matrix(coeff[deg]) * basis[deg]) m_idx = multiindex(deg, n) for term in range(n_terms[deg]): for coord in range(m): coeff[deg][coord, term] = poly[coord].coeff(pb[deg][term]) m_idx.increment() self.coeff = coeff self.update_fun()
#SymPy is a non-commercial alternative to Mathematica and Maple # SymPy can map variable to a value or a matrix. # SymPy's Symbolic Statistical Modelling uses scintific computing. import numpy as np import sympy as sp import pandas as pd import sys #give input equation expr = sp.sympify("x_1**2 + x_2*x_3") #get number of columns from X dataframe and y dataframe num_of_columns = 10 + 1 #dataframe features len(X.columns) +1 num_of_y_columns = 2 #dataframe features len(Y.columns) +1 #create equation variables as user prefers to enter like x_1 ** 2 + x_2 * x_3 symbols = sp.symarray('x', num_of_columns) symbols = symbols[1:] y_symbols = sp.symarray('y', num_of_y_columns) y_symbols = y_symbols[1:] df = pd.DataFrame( [[21, 72, 67.1], [23, 78, 69.5], [32, 74, 56.6], [52, 54, 76.2]], columns=['feature1', 'feature2', 'feature3']) #create variables by setattr with dataframe's columns i.e. numpy arrays (series essentially arrays) mod = sys.modules[__name__] for i, c in enumerate(df.columns, start=1): setattr(mod, "x" + str(i), df[c]) #just create variables SymPy way and store it as a stuple for creating f_1(x) -> H_1(x) variable_tuple = tuple([sp.var(s.name) for s in symbols[0:len(df.columns)]]) #define the R.H.S of equation as user inputs and as parsed #expr = x_1**2 + x_2*x_3 #use lambdify with symbols that are actually created as variables and expression and
from time import clock import numpy as np import sympy as sp import symengine as se # Real-life example (ion speciation problem in water chemistry) x = sp.symarray('x', 14) p = sp.symarray('p', 14) args = np.concatenate((x, p)) exp = sp.exp exprs = [x[0] + x[1] - x[4] + 36.252574322669, x[0] - x[2] + x[3] + 21.3219379611249, x[3] + x[5] - x[6] + 9.9011158998744, 2*x[3] + x[5] - x[7] + 18.190422234653, 3*x[3] + x[5] - x[8] + 24.8679190043357, 4*x[3] + x[5] - x[9] + 29.9336062089226, -x[10] + 5*x[3] + x[5] + 28.5520551531262, 2*x[0] + x[11] - 2*x[4] - 2*x[5] + 32.4401680272417, 3*x[1] - x[12] + x[5] + 34.9992934135095, 4*x[1] - x[13] + x[5] + 37.0716199972041, p[0] - p[1] + 2*p[10] + 2*p[11] - p[12] - 2*p[13] + p[2] + 2*p[5] + 2*p[6] + 2*p[7] + 2*p[8] + 2*p[9] - exp(x[0]) + exp(x[1]) - 2*exp(x[10]) - 2*exp(x[11]) + exp(x[12]) + 2*exp(x[13]) - exp(x[2]) - 2*exp(x[5]) - 2*exp(x[6]) - 2*exp(x[7]) - 2*exp(x[8]) - 2*exp(x[9]), -p[0] - p[1] - 15*p[10] - 2*p[11] - 3*p[12] - 4*p[13] - 4*p[2] - 3*p[3] - 2*p[4] - 3*p[6] - 6*p[7] - 9*p[8] - 12*p[9] + exp(x[0]) + exp(x[1]) + 15*exp(x[10]) + 2*exp(x[11]) + 3*exp(x[12]) + 4*exp(x[13]) + 4*exp(x[2]) + 3*exp(x[3]) + 2*exp(x[4]) + 3*exp(x[6]) + 6*exp(x[7]) + 9*exp(x[8]) + 12*exp(x[9]), -5*p[10] - p[2] - p[3] - p[6] - 2*p[7] - 3*p[8] - 4*p[9] + 5*exp(x[10]) + exp(x[2]) + exp(x[3]) + exp(x[6]) + 2*exp(x[7]) + 3*exp(x[8]) + 4*exp(x[9]), -p[1] - 2*p[11] - 3*p[12] - 4*p[13] - p[4] + exp(x[1]) + 2*exp(x[11]) + 3*exp(x[12]) + 4*exp(x[13]) + exp(x[4]), -p[10] - 2*p[11] - p[12] - p[13] - p[5] - p[6] - p[7] - p[8] - p[9] + exp(x[10]) + 2*exp(x[11]) + exp(x[12]) + exp(x[13]) + exp(x[5]) + exp(x[6]) + exp(x[7]) + exp(x[8]) + exp(x[9])] lmb_symengine = se.Lambdify(args, exprs) lmb_sympy = sp.lambdify(args, exprs) inp = np.ones(28) tim_symengine = clock() res_symengine = np.empty(len(exprs)) for i in range(500): res_symengine = lmb_symengine(inp) #lmb_symengine.unsafe_real_real(inp, res_symengine) tim_symengine = clock() - tim_symengine tim_sympy = clock() for i in range(500): res_sympy = lmb_sympy(*inp) tim_sympy = clock() - tim_sympy print('symengine speed-up factor (higher is better) vs sympy: %12.5g' % (tim_sympy/tim_symengine))
def exprToSympy(expr): if isinstance(expr,Variable): if expr.type.is_scalar(): return sympy.Symbol(expr.name) elif expr.type.type in ARRAY_TYPES: #1D column vector assert expr.type.size is not None,"Can't convert variable-sized arrays to Sympy Matrix's" entries = sympy.symarray(expr.name,expr.type.size) return sympy.Matrix(entries) else: raise ValueError("Invalid Variable") elif isinstance(expr,VariableExpression): return exprToSympy(expr.var) elif isinstance(expr,UserDataExpression): return sympy.Symbol(expr.name) elif isinstance(expr,ConstantExpression): return exprToSympy(expr.value) elif isinstance(expr,OperatorExpression): fname = expr.functionInfo.name sname = fname.capitalize() sargs = [exprToSympy(a) for a in expr.args] if fname in _sympySpecialConstructors: return _sympySpecialConstructors[fname](expr.args,sargs) if fname in _sympyOperators: try: return getattr(operator,fname)(*sargs) except Exception as e: print("exprToSympy: Error raised while performing operator %s on arguments %s"%(fname,str(expr))) raise if hasattr(sympy,sname): #try capitalized version first try: return getattr(sympy,sname)(*sargs) except Exception: print("exprToSympy: Error raised while trying sympy.%s on arguments %s"%(sname,str(expr))) if hasattr(sympy,fname): #numpy equivalents, like eye try: return getattr(sympy,fname)(*sargs) except Exception: print("exprToSympy: Error raised while trying sympy.%s on arguments %s"%(fname,str(expr))) if isinstance(expr.functionInfo.func, collections.Callable): print("exprToSympy: Function %s does not have Sympy equivalent, returning adaptor "%(fname,)) return _make_sympy_adaptor(expr.functionInfo)(*sargs) else: print("exprToSympy: Function %s does not have Sympy equivalent, expanding expression"%(fname,)) assert isinstance(expr.functionInfo.func,Expression) sfunc = exprToSympy(expr.functionInfo.func) return sfunc.subs(list(zip(expr.functionInfo.argNames,sargs))) print("exprToSympy: Function %s does not have Sympy equivalent, returning generic Function"%(fname,)) return sympy.Function(fname)(*sargs) else: if hasattr(expr,'__iter__'): if hasattr(expr[0],'__iter__'): #Matrix assert not hasattr(expr[0][0],'__iter__'),"Sympy can't handle tensors yet" return sympy.Matrix(expr) else: #1-D vector -- treat as column vector return sympy.Matrix(expr) if isinstance(expr,(float,int,bool)): return sympify(expr)
############################################################################################################################################ # if using an integrated environment we recommend restarting the python console after running this script to make sure updates are found location = "/Users/david/Dropbox/PyTransportDist/PyTransport/" # this should be the location of the PyTransport folder sys.path.append(location) # we add this location to the python path import PyTransSetup # the above commands allows python to find the PyTransSetup module and import it ############################################################################################################################################ ### Sets potential and compiles PyTransport, users may prefer to do this only once in a separate file (or comment after running below once) ### ### Restart the python kernel after running this file nF = 2 nP = 5 f = sym.symarray('f', nF) p = sym.symarray('p', nP) V = 1. / 2. * p[0]**2 * f[0]**2 + 1 / 2. * p[1]**2 * sym.cos(p[2] / 2.)**2 * ( f[1] - (f[0] - p[3]) * sym.tan(p[2] / math.pi * sym.atan(p[4] * (f[0] - p[3]))))**2 PyTransSetup.potential(V, nF, nP) # writes this potential into c file when run PyTransSetup.compileName( "LH" ) # this compiles the module with the new potential and places it in the location folder, and adds this folder to the path ready for use ############################################################################################################################################
self.desiredxyzijk = Matrix([x_coord, y_coord, z_coord, xr, yr, zr]) self.start_time = time.perf_counter() self.damping_coefficient = damping_coefficient # zero arm thetas to start position for link in self.link_list: link.theta = 0 while arm.ee_jacobian(1) == 1: arm.main_update() self.desiredxyzijk += Matrix([0, 0, 0, 0, 0, 0]) arm.plot_arm() fig = plt.figure(1) ax = fig.add_subplot(111, projection='3d') sym_theta_list = symarray("theta", 8) arm = Armature() arm.add_link((sym_theta_list[0], -pi / 2, 0, 100)) arm.add_link((sym_theta_list[1], pi / 2, 100, 0)) arm.add_link((sym_theta_list[2], pi / 2, 100, 0)) arm.add_link((sym_theta_list[3], -pi / 2, 100, 0)) arm.add_link((sym_theta_list[4], -pi / 2, 100, 0)) arm.add_link((sym_theta_list[5], pi / 2, 100, 0)) arm.add_link((sym_theta_list[6], 0, 100, 0)) arm.add_link((pi / 2, pi / 2, 0, 0)) arm.add_link((sym_theta_list[7], pi / 2, 0, 0)) arm.main_update() # arm.plot_arm()
def __init__(self, a=0.0, b=1.0, n=5, bv={}, tag='', use_std_approach=False, **kwargs): # there are two different approaches implemented for evaluating # the splines which mainly differ in the node that is used in the # evaluation of the polynomial parts # # the reason for this is that in the project thesis from which # PyTrajectory emerged, the author didn't use the standard approach # usually used when dealing with spline interpolation # # later this standard approach has been implemented and was intended # to replace the other one, but it turned out that when using this # standard approach some examples suddendly fail # # until this issue is resolved the user is enabled to choose between # the two approaches be altering the following attribute self._use_std_approach = use_std_approach # interval boundaries assert a < b self.a = a self.b = b # number of polynomial parts self.n = int(n) # 'name' of the spline self.tag = tag # dictionary with boundary values # key: order of the spline's derivative to which the values belong # values: the boundary values the derivative should satisfy self._boundary_values = bv # create array of symbolic coefficients self._coeffs = sp.symarray('c' + tag, (self.n, 4)) self._coeffs_sym = self._coeffs.copy() # calculate nodes of the spline self.nodes = get_spline_nodes(self.a, self.b, self.n + 1, nodes_type='equidistant') self._nodes_type = 'equidistant' #nodes_type # size of each polynomial part self._h = (self.b - self.a) / float(self.n) # the polynomial spline parts # key: spline part # value: corresponding polynomial self._P = dict() for i in xrange(self.n): # create polynomials, e.g. for cubic spline: # P_i(t)= c_i_3*t^3 + c_i_2*t^2 + c_i_1*t + c_i_0 self._P[i] = np.poly1d(self._coeffs[i]) # initialise array for provisionally evaluation of the spline # if there are no values for its free parameters # # they show how the spline coefficients depend on the free coefficients self._dep_array = None #np.array([]) self._dep_array_abs = None #np.array([]) # steady flag is True if smoothness and boundary conditions are solved # --> make_steady() self._steady_flag = False # provisionally flag is True as long as there are no numerical values # for the free parameters of the spline # --> set_coefficients() self._prov_flag = True # the free parameters of the spline self._indep_coeffs = None #np.array([])
"Please, choose the min value of hyperparameter (lambda) (default = 0.0001): " ) lambda_par = input() if lambda_par == '': lambda_par = 0.0001 else: lambda_par = float(lambda_par) # max lambda value (starting one) max_lambda = 0.1 #lambda_par = 0.000001 # just to save your value (e.g. png(s)) under correct prefix prefix = 'real' ''' Generating Data Set ''' # generating an array of symbolic variables # based on the desired amount of variables x_symb = sp.symarray('x', n_vars, real=True) # making a copy of this array x_vals = x_symb.copy() x_vals[0] = np.linspace(0, len(dataset[0]), len(dataset[0])) x_vals[1] = np.linspace(0, len(dataset), len(dataset)) # library object instantiation lib = rl.RegressionLibrary(x_symb, x_vals) # generating output data - first setting-up the proper grid x, y = np.meshgrid(x_vals[0], x_vals[1]) z = dataset #terrain # Working with generated (Fake) data elif value == False: print(''' #========================# # Working with Fake Data #
def potential(G,V,nF,nP): f=sym.symarray('f',nF) p=sym.symarray('p',nP) vd=sym.symarray('vd',nF) vdd=sym.symarray('vdd',nF*nF) vddd=sym.symarray('vddd',nF*nF*nF) g, Ga, Ri, Rm =fieldmetric(G,nF) FMP=0 for i in range(nF): vd[i] = sym.simplify(V.diff(f[i])) for i in range(nF): for j in range(nF): for l in range(nF): FMP=FMP-Ga(-(l+1),i+1,j+1) * vd[l] vdd[i+j*nF] = sym.simplify(V.diff(f[i]).diff(f[j]))+FMP FMP=0 for i in range(nF): for j in range(nF): for k in range(nF): for l in range(nF): FMP=FMP-Ga(-(l+1),k+1,i+1)*vdd[l+j*nF] - Ga(-(l+1),k+1,j+1)*vdd[i+l*nF] vddd[i+j*nF+k*nF*nF] = sym.simplify(V.diff(f[i]).diff(f[j]).diff(f[k])) FMP=0 import os dir = os.path.dirname(__file__) filename1 = os.path.join(dir, 'MTeasyC/potentialProto.h') filename2 = os.path.join(dir, 'MTeasyC/potential.h') f = open(filename1, 'r') g = open(filename2, 'w') for line in f: g.write(line) if line == "// #FP\n": g.write('nF='+str(nF)+';\n'+'nP='+str(nP)+';\n') #if line == "// pdef\n": #for i in range(nP): # g.write('p['+str(i)+']='+str(pp[i])+';\n') if line == "// Pot\n": expr=str(sym.ccode(V)) for l in range(max(nP,nF)): expr=expr.replace("_"+str(l),"["+str(l)+"]") g.write('\n sum='+str(expr)+';\n') if line == "// dPot\n": for i in range(nF): expr=str(sym.ccode(vd[i])) for l in range(max(nF,nP)): expr=expr.replace("_"+str(l),"["+str(l)+"]") g.write('\n sum['+str(i)+']='+str(expr)+';\n') if line == "// ddPot\n": for i in range(nF): for j in range(nF): expr=str(sym.ccode(vdd[i+nF*j])) for l in range(max(nF,nP)): expr=expr.replace("_"+str(l),"["+str(l)+"]") g.write('\n sum['+str(i)+'+nF*'+str(j)+']='+str(expr)+';\n') if line == "// dddPot\n": for i in range(nF): for j in range(nF): for k in range(nF): expr=str(sym.ccode(vddd[i+nF*j+nF*nF*k])) for l in range(max(nF,nP)): expr=expr.replace("_"+str(l),"["+str(l)+"]") g.write('\n sum['+str(i)+'+nF*'+str(j)+'+nF*nF*'+str(k)+']='+str(expr)+';\n') g.close() f.close()
def fieldmetric(G,nF,nP,simple=False,silent=True): f=sym.symarray('f',nF) p=sym.symarray('p',nP) COR = Coordinates('\chi', f) g = MetricTensor('g',COR , G) Ga = Christoffel('Ga', g) Ri = Ricci('Ri', g) Rm = Riemann('Rm',g) import os dir = os.path.dirname(__file__) filename1 = os.path.join(dir, 'CppTrans', 'fieldmetricProto.h') filename2 = os.path.join(dir, 'CppTrans', 'fieldmetric.h') e = open(filename1, 'r') h = open(filename2, 'w') G_array = sym.symarray('G', 2*nF * 2*nF) Gamma_array = sym.symarray('Gamma', 2*nF * 2*nF * 2*nF) R_array = sym.symarray('Riemann', nF*nF*nF*nF) gradR_array = sym.symarray('gradRiemann', nF*nF*nF*nF*nF) # populate Riemann matrix for i in range(2 * nF): for j in range(2 * nF): if i < nF: ii = -i - 1 else: ii = i - (nF - 1) if j < nF: jj = -j - 1 else: jj = j - (nF - 1) if simple is True: G_array[(2 * nF) * i + j] = sym.simplify(g(ii, jj)) else: G_array[(2 * nF) * i + j] = g(ii, jj) # populate connexion matrix for i in range(2 * nF): for j in range(2 * nF): for k in range(2 * nF): if i < nF: ii = -i - 1 else: ii = i - (nF - 1) if j < nF: jj = -j - 1 else: jj = j - (nF - 1) if k < nF: kk = -k - 1 else: kk = k - (nF - 1) if kk < 0 or jj < 0 or ii > 0: Gamma_array[(2*nF)*(2*nF)*i+(2*nF)*j+k] = sym.simplify(0) else: if simple is True: Gamma_array[(2*nF)*(2*nF)*i+(2*nF)*j+k] = sym.simplify(Ga(ii, jj, kk)) else: Gamma_array[(2*nF)*(2*nF)*i+(2*nF)*j+k] = Ga(ii, jj, kk) # populate Riemann matrix for i in range(nF): for j in range(nF): for k in range(nF): for l in range(nF): ii=i+1 jj=j+1 kk=k+1 ll=l+1 if simple is True: R_array[(nF)*(nF)*(nF)*i+(nF)*(nF)*j+(nF)*k+l] = sym.simplify(Rm(ii,jj,kk,ll)) else: R_array[(nF)*(nF)*(nF)*i+(nF)*(nF)*j+(nF)*k+l] = Rm(ii,jj,kk,ll) # populate covariant-derivative of Riemann matrix for i in range(nF): for j in range(nF): for k in range(nF): for l in range(nF): for m in range(nF): ii = i + 1 jj = j + 1 kk = k + 1 ll = l + 1 mm = m + 1 if simple is True: gradR_array[(nF)*(nF)*(nF)*(nF)*i+(nF)*(nF)*(nF)*j+(nF)*(nF)*k+(nF)*l+m] = sym.simplify(Rm.covariantD(ii, jj, kk, ll, mm)) else: gradR_array[(nF)*(nF)*(nF)*(nF)*i+(nF)*(nF)*(nF)*j+(nF)*(nF)*k+(nF)*l+m] = Rm.covariantD(ii, jj, kk, ll, mm) for line in e: h.write(line) if line == "// #FP\n": #h.write('nF='+str(nF)+';\n') h.write('nF='+str(nF)+';\n'+'nP='+str(nP)+';\n') if line == "// metric\n": if not silent: timer_cse = time.clock() print(' [{time}] performing CSE for field metric'.format(time=time.ctime())) decls, new_expr = sym.cse(G_array, order='none') if not silent: print(' [{time}] complete in {x} sec'.format(time=time.ctime(), x=time.clock() - timer_cse)) # emit declarations for CSE variables write_cse_decls(decls, h, nF, nP) for i in range(2*nF): for j in range(2*nF): # emit main expression emit_expr = sym.printing.cxxcode(new_expr[(2*nF)*i+j]) rw_expr = rewrite_indices(emit_expr, nF, nP) h.write('\n FM['+str((2*nF)*i+j)+']=' + str(rw_expr) + ';\n') if line == "// Christoffel\n": if not silent: timer_cse = time.clock() print(' [{time}] performing CSE for Christoffel symbols'.format(time=time.ctime())) decls, new_expr = sym.cse(Gamma_array, order='none') if not silent: print(' [{time}] complete in {x} sec'.format(time=time.ctime(), x=time.clock() - timer_cse)) # emit declarations for CSE variables write_cse_decls(decls, h, nF, nP) for i in range(2 * nF): for j in range(2 * nF): for k in range(2 * nF): # emit main expression emit_expr = sym.printing.cxxcode(new_expr[(2*nF)*(2*nF)*i+(2*nF)*j+k]) rw_expr = rewrite_indices(emit_expr, nF, nP) h.write('\n CS['+str((2*nF)*(2*nF)*i+(2*nF)*j+k)+']=' + str(rw_expr) + ';\n') if line == "// Riemann\n": if not silent: timer_cse = time.clock() print(' [{time}] performing CSE for Riemann tensor'.format(time=time.ctime())) decls, new_expr = sym.cse(R_array, order='none') if not silent: print(' [{time}] complete in {x} sec'.format(time=time.ctime(), x=time.clock() - timer_cse)) # emit declarations for CSE variables write_cse_decls(decls, h, nF, nP) for i in range(nF): for j in range(nF): for k in range(nF): for l in range(nF): # emit main expression emit_expr = sym.printing.cxxcode(new_expr[(nF)*(nF)*(nF)*i+(nF)*(nF)*j+(nF)*k+l]) rw_expr = rewrite_indices(emit_expr, nF, nP) h.write('\n RM['+str((nF)*(nF)*(nF)*i+(nF)*(nF)*j+(nF)*k+l)+']=' + str(rw_expr) + ';\n') if line == "// Riemanncd\n": if not silent: timer_cse = time.clock() print(' [{time}] performing CSE for Riemann tensor'.format(time=time.ctime())) decls, new_expr = sym.cse(gradR_array, order='none') if not silent: print(' [{time}] complete in {x} sec'.format(time=time.ctime(), x=time.clock() - timer_cse)) # emit declarations for CSE variables write_cse_decls(decls, h, nF, nP) for i in range(nF): for j in range(nF): for k in range(nF): for l in range(nF): for m in range(nF): # emit main expression emit_expr = sym.printing.cxxcode(new_expr[(nF)*(nF)*(nF)*(nF)*i+(nF)*(nF)*(nF)*j+(nF)*(nF)*k+(nF)*l+m]) rw_expr = rewrite_indices(emit_expr, nF, nP) h.write('\n RMcd['+str((nF)*(nF)*(nF)*(nF)*i+(nF)*(nF)*(nF)*j+(nF)*(nF)*k+(nF)*l+m)+']=' + str(rw_expr) + ';\n') h.close() e.close() return g, Ga, Ri, Rm
def __init__(self, a=0.0, b=1.0, n=5, bv=None, tag='', use_std_approach=False, **kwargs): # there are two different approaches implemented for evaluating # the splines which mainly differ in the node that is used in the # evaluation of the polynomial parts # # the reason for this is that in the project thesis from which # PyTrajectory emerged, the author didn't use the standard approach # usually used when dealing with spline interpolation # # later this standard approach has been implemented and was intended # to replace the other one, but it turned out that # convergence properties of the whole algorithm for some examples got worse # # until this issue is resolved the user is enabled to choose between # the two approaches be altering the following attribute self.masterobject = kwargs.get("masterobject") self.init_logger(self.masterobject) self._init_bc(bv) self._use_std_approach = use_std_approach # interval boundaries assert a < b self.a = a self.b = b # number of polynomial parts self.n = int(n) # 'name' of the spline self.tag = tag # dictionary with boundary values # key: order of the spline's derivative to which the values belong # values: the boundary values the derivative should satisfy # create array of symbolic coefficients self._coeffs = sp.symarray( 'c' + tag, (self.n, 4) ) ##:: e.g.: array([[cxi_0_0, cxi_0_1, cxi_0_2, cxi_0_3],...,[cxi_9_0, cxi_9_1, cxi_9_2, cxi_9_3]]) self._coeffs_sym = self._coeffs.copy() # calculate nodes of the spline self.nodes = get_spline_nodes(self.a, self.b, self.n + 1, nodes_type='equidistant') self._nodes_type = 'equidistant' # size of each polynomial part self._h = (self.b - self.a) / float(self.n) # the polynomial spline parts # key: spline part # value: corresponding polynomial self._P = dict() for i in xrange(self.n): # create polynomials, e.g. for cubic spline: # P_i(t)= c_i_3*t^3 + c_i_2*t^2 + c_i_1*t + c_i_0 # poly1d expects coeffs in decreasing order -> [::-1] self._P[i] = np.poly1d(self._coeffs[i][::-1]) ## note: here _P is only for one state/input-component!! # initialise array for provisionally evaluation of the spline # if there are no values for its free parameters # they show how the spline coefficients depend on the free coefficients self._dep_array = None #np.array([]) self._dep_array_abs = None #np.array([]) # steady flag is True if smoothness and boundary conditions are solved # --> make_steady() self._steady_flag = False # provisionally flag is True as long as there are no numerical values # for the free parameters of the spline # --> set_coefficients() self._prov_flag = True # the free parameters of the spline self._indep_coeffs = None self._indep_coeffs_sym = None # cache for a frequently used part of a block-matrix self._node_eval_block = None self._steady_flag = False
def linear_equation_solution(): from sympy import Matrix, symarray, solve a = Matrix([[2, 3, 1], [4, 2, 3], [7, 1, -1]]) b = Matrix([[4], [17], [1]]) x = symarray('x', 3).reshape(3, 1) print(solve(a * x - b))
v = sym.simplify(udot + R*Omega_skew*s) print('v = ') display(v) # Define acceleration of element endpoints (nodes) a = sym.simplify(uddot + R*Omega_skew*Omega_skew*s + R*Alpha_skew*s) print('\na = ') display(a) # ### Compute the Mass Matrix # In[ ]: # Define shape function for element with one node at each end h = sym.symarray('h', 2) h[0] = sym.Rational(1,2)*(1 - x) h[1] = sym.Rational(1,2)*(1 + x) # Compute shape function matrix H = sym.expand(sym.Matrix([h[0]*sym.eye(3), h[1]*sym.eye(3)])).T print('\nH = ') display(H.T) # Define velocity of any point Vp = H*v print('\nV = ') display(Vp) # Define velocity of any point
import sys # import the sys module used below ############################################################################################################################################ # if using an integrated environment we recommend restarting the python console after running this script to make sure updates are found location = "/home/jwr/Code/June/PyTransport2Dist/PyTransport/" # this should be the location of the PyTransport folder sys.path.append(location) # we add this location to the python path import PyTransSetup # the above commands allows python to find the PyTransSetup module and import it ############################################################################################################################################ nF = 2 # number of fields needed to define the double quadratic potential nP = 2 # number of parameters needed to define the double quadtartic potential f = sym.symarray( 'f', nF) # an array representing the nF fields present for this model p = sym.symarray( 'p', nP ) # an array representing the nP parameters needed to define this model (that we might wish to change) if we don't # wish to change them they could be typed explicitly in the potential below V = 1. / 2. * p[0]**2.0 * f[0]**2.0 + 1. / 2. * p[1]**2.0 * f[ 1]**2.0 # this is the potential written in sympy notation #The last argument is for whether the sympy's simplify is used to on derivatives of the potential and field geometric quantites. #Caution is recomended as sympy's simplify is known to have bugs. Simplification can increase the speed of numerically evolutions, but at the cost of compling more slowly. PyTransSetup.potential( V, nF, nP, True ) # writes this potential and its derivatives into C++ file potential.h when run PyTransSetup.compileName(
def __init__(self, *args, **kwargs): """ Initialises a new `Symbol` object in one of three ways:: u=Symbol('u') returns a scalar symbol by the name 'u'. alpha=Symbol('alpha', (4,3)) returns a rank 2 symbol with the shape (4,3), whose elements are named '[alpha]_i_j' (with i=0..3, j=0..2). a,b,c=symbols('a,b,c') x=Symbol([[a+b,0,0],[0,b-c,0],[0,0,c-a]]) returns a rank 2 symbol with the shape (3,3) whose elements are explicitly specified by numeric values and other symbols/expressions within a list or numpy array. The dimensionality of the symbol can be specified through the ``dim`` keyword. All other keywords are passed to the underlying symbolic library (currently sympy). :param args: initialisation arguments as described above :keyword dim: dimensionality of the new Symbol (default: 2) :type dim: ``int`` """ if not HAVE_SYMBOLS: raise RuntimeError("Trying to instantiate a Symbol but sympy not available") if 'dim' in kwargs: self._dim=kwargs.pop('dim') else: self._dim=-1 # undefined if 'subs' in kwargs: self._subs=kwargs.pop('subs') else: self._subs={} if len(args)==1: arg=args[0] if isinstance(arg, str): if arg.find('[')>=0 or arg.find(']')>=0: raise ValueError("Name must not contain '[' or ']'") self._arr=numpy.array(sympy.Symbol(arg, **kwargs)) elif hasattr(arg, "__array__") or isinstance(arg, list): if isinstance(arg, list): arg=numpy.array(arg) arr=arg.__array__() if len(arr.shape)>4: raise ValueError("Symbol only supports tensors up to order 4") res=numpy.empty(arr.shape, dtype=object) for idx in numpy.ndindex(arr.shape): if hasattr(arr[idx], "item"): res[idx]=arr[idx].item() else: res[idx]=arr[idx] self._arr=res if isinstance(arg, Symbol): self._subs.update(arg._subs) if self._dim==-1: self._dim=arg._dim elif isinstance(arg, sympy.Basic): self._arr=numpy.array(arg) else: raise TypeError("Unsupported argument type %s"%str(type(arg))) elif len(args)==2: if not isinstance(args[0], str): raise TypeError("First argument must be a string") if not isinstance(args[1], tuple): raise TypeError("Second argument must be a tuple") name=args[0] shape=args[1] if name.find('[')>=0 or name.find(']')>=0: raise ValueError("Name must not contain '[' or ']'") if len(shape)>4: raise ValueError("Symbol only supports tensors up to order 4") if len(shape)==0: self._arr=numpy.array(sympy.Symbol(name, **kwargs)) else: try: self._arr=sympy.symarray(shape, '['+name+']') except TypeError: self._arr=sympy.symarray('['+name+']', shape) else: raise TypeError("Unsupported number of arguments") if self._arr.ndim==0: self.name=str(self._arr.item()) else: self.name=str(self._arr.tolist())
#sample script: calculate covariant derivatives #----------by Zhiqi Huang--for the course ''General Relativity''------------- import sympy as sym sym.init_printing() dim = 2 #coordinates theta and phi u = sym.symarray('u', dim) #r = sym.symbols('r') #gdown = sym.diag( r**2, r**2*sym.sin(u[0])**2 ) gdown = sym.diag(1, sym.sin(u[0])**2) #gdown = sym.diag(1, sym.exp(2*u[0])) #gdown = sym.diag(1/(1+u[0]**2+u[1]**2),1/(1+u[0]**2+u[1]**2)) #gdown = sym.diag(1/(1+u[0]**2+u[1]**2)**2,1/(1+u[0]**2+u[1]**2)**2) #gdown = sym.Matrix([[1/(u[0]**2+u[1]**2+1), 1/(u[0]**2+u[1]**2+1)/2],[1/(u[0]**2+u[1]**2+1)/2, 1/(u[0]**2+u[1]**2+1)]]) gup = gdown**-1 detg = gdown.det() def connection_down(i, j, k): return (sym.diff(gdown[i, j], u[k]) + sym.diff(gdown[i, k], u[j]) - sym.diff(gdown[j, k], u[i])) / 2 ##allocate space to save connections
#!/usr/bin/env python from time import clock import numpy as np import sympy as sp import symengine as se import warnings # Real-life example (ion speciation problem in water chemistry) x = sp.symarray('x', 14) p = sp.symarray('p', 14) args = np.concatenate((x, p)) exp = sp.exp exprs = [ x[0] + x[1] - x[4] + 36.252574322669, x[0] - x[2] + x[3] + 21.3219379611249, x[3] + x[5] - x[6] + 9.9011158998744, 2 * x[3] + x[5] - x[7] + 18.190422234653, 3 * x[3] + x[5] - x[8] + 24.8679190043357, 4 * x[3] + x[5] - x[9] + 29.9336062089226, -x[10] + 5 * x[3] + x[5] + 28.5520551531262, 2 * x[0] + x[11] - 2 * x[4] - 2 * x[5] + 32.4401680272417, 3 * x[1] - x[12] + x[5] + 34.9992934135095, 4 * x[1] - x[13] + x[5] + 37.0716199972041, p[0] - p[1] + 2 * p[10] + 2 * p[11] - p[12] - 2 * p[13] + p[2] + 2 * p[5] + 2 * p[6] + 2 * p[7] + 2 * p[8] + 2 * p[9] - exp(x[0]) + exp(x[1]) - 2 * exp(x[10]) - 2 * exp(x[11]) + exp(x[12]) + 2 * exp(x[13]) - exp(x[2]) - 2 * exp(x[5]) - 2 * exp(x[6]) - 2 * exp(x[7]) - 2 * exp(x[8]) - 2 * exp(x[9]), -p[0] - p[1] - 15 * p[10] - 2 * p[11] - 3 * p[12] - 4 * p[13] - 4 * p[2] - 3 * p[3] - 2 * p[4] - 3 * p[6] - 6 * p[7] - 9 * p[8] - 12 * p[9] + exp(x[0]) + exp(x[1]) + 15 * exp(x[10]) + 2 * exp(x[11]) + 3 * exp(x[12]) + 4 * exp(x[13]) + 4 * exp(x[2]) + 3 * exp(x[3]) + 2 * exp(x[4]) +
def createNullSpaceFunction(SciPyModel): ''' Generate the NullSpace of the kinetic parameters (parameters which enter the derivative matrix linearly). The nullspace in this case can be used to solve the system for the steady-state condition. This operation happens using the SymPy module to solve the homogenous equation A*x = 0. To Do ----- 1. Implement a method for manually setting parameters to be considered kinetic parameters. 2. Investigate method for sampling using restriction given by N*g = k > 0. Parameters ---------- SciPyModel : internal object instance Returns ------- SciPyModel : internal object instance SciPyModel with NullSpaceFunction based on model parameterization. See Also -------- Notes ----- The anonymous function can be called as follows: NullSpaceFunction( E, X ) This produces a SymPy matrix of the nullspace given the desired steady state condition as specified by the user choice in E and X. ''' import sympy, datetime, numpy # Automatically flag kinetic parameters. for rxn in SciPyModel.Reactions.Formulas: if SciPyModel.Reactions.Formulas[0][0] == 'p': SciPyModel.Parameters.KineticFlag[int( rxn.split(']')[0].split('[')[1])] = True # Write derivative function to file TempName = (SciPyModel.MetaData.Name + datetime.datetime.now().strftime("%I%M%p%B%d%Y") + '.py') open(TempName, 'w+').write(SciPyModel.ToolboxFunctions.DerivativeFunction) # Import derivative function from temporary file. TempModule = __import__(TempName[:-3]) # Create symbolic species and parameter vectors y = sympy.symarray('y', len(SciPyModel.Species.Names)) p = sympy.symarray('p', len(SciPyModel.Parameters.Names)) # Create symbolic reaction and stoichiometry matrices R = sympy.Matrix(TempModule.rxn_fun(y, 0, p)) S = sympy.Matrix(SciPyModel.Reactions.Stoichiometry) # Create symbolic derivative matrix DerivativeMatrix = sympy.Matrix([S[:, i] * R[i] for i in range(len(R)) ]).reshape(S.shape[1], S.shape[0]).transpose() # Extract kinetic parameters M = sympy.Matrix( sympy.lambdify( (p[SciPyModel.Parameters.KineticFlag]), DerivativeMatrix, 'sympy')( *sympy.ones(len(p[SciPyModel.Parameters.KineticFlag]), 1))) # Obtain basis for nullspace NullBasis = M.nullspace() SciPyModel.Parameters.NullSpaceDimension = len(NullBasis) # Assemble nullspace matrix from basis NullSpace = sympy.Matrix([NullBasis[i] for i in range(len(NullBasis))]) NullSpace = NullSpace.reshape(len(NullBasis), len(NullSpace) / len(NullBasis)).transpose() # Create anonymous sampling function SciPyModel.ToolboxFunctions.NullSpaceFunction = sympy.lambdify( (p[numpy.invert(SciPyModel.Parameters.KineticFlag)], y), NullSpace, 'numpy', dummify=False) return SciPyModel
def check_input(self, inputs): """check_input Checks the input and create a list of function handle strings with T as argument. Inputs can be strings, floats, ints, or pint quantaties. Args: inputs (list[str, int, float, Quantity]): list of strings, int, floats, or Pint quantities. Returns: (tuple): - *output (list[@lambda])* - list of lambda functions. - *output_strs (list[str])* - list of string-representations. """ output = [] output_strs = [] # if the input is not a list, we convert it to one if not isinstance(inputs, list): inputs = [inputs] # update number of subsystems K = self.num_sub_systems k = len(inputs) if k != K: print('Number of subsystems changed from {:d} to {:d}.'.format( K, k)) self.num_sub_systems = k T = symbols('T') # traverse each list element and convert it to a function handle for input in inputs: if isfunction(input): raise ValueError( 'Please use string representation of function!') elif isinstance(input, str): try: # backwards compatibility for direct lambda definition if ':' in input: # strip lambda prefix input = input.split(':')[1] # backwards compatibility for []-indexing input = input.replace('[', '_').replace(']', '') # check for presence of indexing and use symarray as argument if '_' in input: T = symarray('T', k) output.append(lambdify([T], input, modules='numpy')) else: output.append(lambdify(T, input, modules='numpy')) output_strs.append(input.strip()) except Exception as e: print('String input for layer property ' + input + ' \ cannot be converted to function handle!') print(e) elif isinstance(input, (int, float)): output.append(lambdify(T, input, modules='numpy')) output_strs.append(str(input)) elif isinstance(input, object): output.append( lambdify(T, input.to_base_units().magnitude, modules='numpy')) output_strs.append(str(input.to_base_units().magnitude)) else: raise ValueError( 'Layer property input has to be a single or ' 'list of numerics, Quantities, or function handle strings ' 'which can be converted into a lambda function!') return output, output_strs
def _bondgraph_to_residuals(model, control_vars=None): dX = sp.IndexedBase('dX') X = sp.IndexedBase('X') U = sp.IndexedBase('U') x_subs = [] dx_subs = [] u_subs = [] u_func = [] n = len(model.state_vars) m = 0 for i, x in enumerate(model.state_vars): x_subs.append((x, X[i])) dx_subs.append((sp.S(f'dx_{i}'), dX[i])) if len(model.control_vars) > 0: u_func_dict = {} u_constants = {} if isinstance(control_vars, list): u_func_dict.update({i: f for i, f in enumerate(control_vars)}) elif isinstance(control_vars, dict): u_func_dict.update( {int(v[2:]): f for v, f in control_vars.items()}) elif len(model.control_vars) == 1: u_func_dict[0] = control_vars else: raise TypeError(f"Control argument {control_vars} is invalid") test_x = np.zeros(shape=(n, ), dtype=np.float32) for idx, f in u_func_dict.items(): try: if isinstance(f, str): f = _to_function(f, X, dX, dx_subs + x_subs) u_func_dict[idx] = f if isinstance(f, (float, int, sp.Number)): u_constants[idx] = f if n == 1: r = f(0, 0, 0) else: r = f(0, test_x, test_x) assert isinstance( r, (float, int, sp.Number)), "Invalid output from control" except Exception as ex: message = f"Invalid control function for var: {idx}.\n " \ "Control functions should be of the form:\n" \ f"{idx} = f(t, x, dx/dt)" raise ModelException(message) for i, u in enumerate(model.control_vars): if i in u_constants: u_subs.append((u, u_constants[i])) continue u_subs.append((u, U[m])) try: u_func.append(u_func_dict[i]) except KeyError: raise ModelException(f"Control variable {u} must be specified") m += 1 rels = [ r.subs(dx_subs).subs(x_subs).subs(u_subs) for r in model.constitutive_relations ] if len(rels) != n: raise ModelException( "Model simplification error: system is under-determined") Fsym = sp.symarray('F', shape=n) for i, r in enumerate(rels): Fsym[i] = r t = sp.S('t') _r = np.empty(shape=(n, ), dtype=np.float64) if not u_func: F = sp.lambdify((t, X, dX), Fsym) def residual(_t, _x, _dx, _res): _r = F(_t, _x, _dx) for i in range(n): _res[i] = _r[i] else: _u = np.empty(shape=(m, ), dtype=np.float64) Fsym_u = sp.lambdify((t, X, dX, U), Fsym) def residual(_t, _x, _dx, _res): _u = [u_f(_t, _x, _dx) for u_f in u_func] _r = Fsym_u(_t, _x, _dx, _u) for i in range(n): _res[i] = _r[i] return residual, X
def __init__(self, a=0.0, b=1.0, n=5, bv={}, tag='', use_std_approach=False, **kwargs): # there are two different approaches implemented for evaluating # the splines which mainly differ in the node that is used in the # evaluation of the polynomial parts # # the reason for this is that in the project thesis from which # PyTrajectory emerged, the author didn't use the standard approach # usually used when dealing with spline interpolation # # later this standard approach has been implemented and was intended # to replace the other one, but it turned out that when using this # standard approach some examples suddendly fail # # until this issue is resolved the user is enabled to choose between # the two approaches be altering the following attribute self._use_std_approach = use_std_approach # interval boundaries assert a < b self.a = a self.b = b # number of polynomial parts self.n = int(n) # 'name' of the spline self.tag = tag # dictionary with boundary values # key: order of the spline's derivative to which the values belong # values: the boundary values the derivative should satisfy self._boundary_values = bv # create array of symbolic coefficients self._coeffs = sp.symarray('c'+tag, (self.n, 4)) self._coeffs_sym = self._coeffs.copy() # calculate nodes of the spline self.nodes = get_spline_nodes(self.a, self.b, self.n+1, nodes_type='equidistant') self._nodes_type = 'equidistant' #nodes_type # size of each polynomial part self._h = (self.b - self.a) / float(self.n) # the polynomial spline parts # key: spline part # value: corresponding polynomial self._P = dict() for i in xrange(self.n): # create polynomials, e.g. for cubic spline: # P_i(t)= c_i_3*t^3 + c_i_2*t^2 + c_i_1*t + c_i_0 self._P[i] = np.poly1d(self._coeffs[i]) # initialise array for provisionally evaluation of the spline # if there are no values for its free parameters # # they show how the spline coefficients depend on the free coefficients self._dep_array = None #np.array([]) self._dep_array_abs = None #np.array([]) # steady flag is True if smoothness and boundary conditions are solved # --> make_steady() self._steady_flag = False # provisionally flag is True as long as there are no numerical values # for the free parameters of the spline # --> set_coefficients() self._prov_flag = True # the free parameters of the spline self._indep_coeffs = None #np.array([])
import math import sys ############################################################################################################################################ ############################################################################################################################################ # if using an integrated environment we recommend restarting the python console after running this script to make sure updates are found location = "/Users/david/Dropbox/PyTransportDist/PyTransport/" # this should be the location of the PyTransport folder sys.path.append(location) # we add this location to the python path import PyTransSetup # the above commands allows python to find the PyTransSetup module and import it ############################################################################################################################################ ### Sets potential and compiles PyTransport, users may prefer to do this only once in a separate file (or comment after running below once) ### ### Restart the python kernel after running this file nF=2 nP=5 f=sym.symarray('f',nF) p=sym.symarray('p',nP) V= 1./2. * p[0]**2 * f[0]**2 + 1/2.*p[1]**2 * sym.cos(p[2]/2.)**2*(f[1] - (f[0]-p[3])*sym.tan(p[2]/math.pi*sym.atan(p[4]*(f[0]-p[3]))))**2 PyTransSetup.potential(V,nF,nP) # writes this potential into c file when run PyTransSetup.compileName("LH") # this compiles the module with the new potential and places it in the location folder, and adds this folder to the path ready for use ############################################################################################################################################
def potential(V,nF,nP,simple=False,G=0,silent=True): f=sym.symarray('f',nF) p=sym.symarray('p',nP) vd=sym.symarray('vd',nF) vdd=sym.symarray('vdd',nF*nF) vddd=sym.symarray('vddd',nF*nF*nF) if not silent: timer = time.clock() print('[{time}] computing symbolic potential derivatives'.format(time=time.ctime())) if G!=0: if not silent: timer2 = time.clock() print(' [{time}] computing curvature quantities'.format(time=time.ctime())) g, Ga, Ri, Rm =fieldmetric(G,nF,nP,simple=simple,silent=silent) if not silent: print(' [{time}] complete in {x} sec'.format(time=time.ctime(), x=time.clock() - timer2)) FMP=0 for i in range(nF): if simple==True: vd[i] = sym.simplify(V.diff(f[i])) else: vd[i] = V.diff(f[i]) for i in range(nF): for j in range(nF): for l in range(nF): FMP=FMP+Ga(-(l+1),i+1,j+1) * vd[l] if simple==True: vdd[i+j*nF] = sym.simplify(V.diff(f[i]).diff(f[j])-FMP) else: vdd[i+j*nF] = V.diff(f[i]).diff(f[j])-FMP FMP=0 for i in range(nF): for j in range(nF): for k in range(nF): for l in range(nF): FMP=FMP+Ga(-(l+1),i+1,k+1)*vdd[l+j*nF] + Ga(-(l+1),j+1,k+1)*vdd[i+l*nF] +sym.expand(Ga(-(1+l),1+i,1+j)).diff(f[k])*vd[l]+sym.expand(Ga(-(1+l),1+i,j+1))*vd[l].diff(f[k])# +sym.expand(Ga(-(l+1),i+1,j+1)).diff(f[k]) * vd[l] +Ga(-(l+1),i+1,j+1)* (sym.expand(vd[l]).diff(f[k])) if simple==True: vddd[i+j*nF+k*nF*nF] =sym.simplify(V.diff(f[i]).diff(f[j]).diff(f[k]) -FMP) else: vddd[i+j*nF+k*nF*nF] =V.diff(f[i]).diff(f[j]).diff(f[k]) -FMP FMP=0 else: for i in range(nF): if simple==True: vd[i] = sym.simplify(V.diff(f[i])) else: vd[i] = V.diff(f[i]) for j in range(nF): if simple==True: vdd[i+j*nF] = sym.simplify(V.diff(f[i]).diff(f[j]) ) else: vdd[i+j*nF] = V.diff(f[i]).diff(f[j]) for k in range(nF): if simple==True: vddd[i+j*nF+k*nF*nF] = sym.simplify(V.diff(f[i]).diff(f[j]).diff(f[k])) else: vddd[i+j*nF+k*nF*nF] = V.diff(f[i]).diff(f[j]).diff(f[k]) if not silent: print('[{time}] complete in {x} sec'.format(time=time.ctime(), x=time.clock() - timer)) import os dir = os.path.dirname(__file__) filename1 = os.path.join(dir, 'CppTrans', 'potentialProto.h') filename2 = os.path.join(dir, 'CppTrans', 'potential.h') f = open(filename1, 'r') g = open(filename2, 'w') if not silent: timer = time.clock() print('[{time}] writing to potential.h'.format(time=time.ctime())) for line in f: g.write(line) if line == "// #Rewrite\n": g.write('// Potential file rewriten at' + ' ' + time.strftime("%c") +'\n') if line == "// #FP\n": g.write('nF='+str(nF)+';\n'+'nP='+str(nP)+';\n') if line == "// Pot\n": # extract common subexpressions from V if not silent: timer_cse = time.clock() print(' [{time}] performing CSE for V'.format(time=time.ctime())) decls, new_expr = sym.cse(V, order='none') if not silent: print(' [{time}] complete in {x} sec'.format(time=time.ctime(), x=time.clock() - timer_cse)) # emit declarations for CSE variables write_cse_decls(decls, g, nF, nP) # emit main expression emit_expr = sym.printing.cxxcode(new_expr[0]) rw_expr = rewrite_indices(emit_expr, nF, nP) g.write(' sum='+str(rw_expr)+';\n') if line == "// dPot\n": if not silent: timer_cse = time.clock() print(' [{time}] performing CSE for dV'.format(time=time.ctime())) decls, new_exprs = sym.cse(vd, order='none') if not silent: print(' [{time}] complete in {x} sec'.format(time=time.ctime(), x=time.clock() - timer_cse)) # emit declarations for CSE variables write_cse_decls(decls, g, nF, nP) for i in range(nF): emit_expr = sym.printing.cxxcode(new_exprs[i]) rw_expr = rewrite_indices(emit_expr, nF, nP) g.write('\n sum[' + str(i) + ']=' + str(rw_expr) + ';\n') if line == "// ddPot\n": if not silent: timer_cse = time.clock() print(' [{time}] performing CSE for ddV'.format(time=time.ctime())) decls, new_exprs = sym.cse(vdd, order='none') if not silent: print(' [{time}] complete in {x} sec'.format(time=time.ctime(), x=time.clock() - timer_cse)) # emit declarations for CSE variables write_cse_decls(decls, g, nF, nP) for i in range(nF): for j in range(nF): emit_expr = sym.printing.cxxcode(new_exprs[i + nF * j]) rw_expr = rewrite_indices(emit_expr, nF, nP) g.write('\n sum[' + str(i + nF * j) + ']=' + str(rw_expr) + ';\n') if line == "// dddPot\n": if not silent: timer_cse = time.clock() print(' [{time}] performing CSE for dddV'.format(time=time.ctime())) decls, new_exprs = sym.cse(vddd, order='none') if not silent: print(' [{time}] complete in {x} sec'.format(time=time.ctime(), x=time.clock() - timer_cse)) # emit declarations for CSE variables write_cse_decls(decls, g, nF, nP) for i in range(nF): for j in range(nF): for k in range(nF): emit_expr = sym.printing.cxxcode(new_exprs[i + nF * j + nF * nF * k]) rw_expr = rewrite_indices(emit_expr, nF, nP) g.write('\n sum[' + str(i + nF * j + nF * nF * k) + ']=' + str(rw_expr) + ';\n') if not silent: print('[{time}] complete in {x} sec'.format(time=time.ctime(), x=time.clock() - timer)) g.close() f.close()