from scipy import integrate # ## Symbolic ODE solving with SymPy # ## Newton's law of cooling # In[5]: t, k, T0, Ta = sympy.symbols("t, k, T_0, T_a") # In[6]: T = sympy.Function("T") # In[7]: ode = T(t).diff(t) + k*(T(t) - Ta) # In[8]: ode # In[9]: ode_sol = sympy.dsolve(ode)
def convert_func(func): if func.func_normal(): if func.L_PAREN(): # function called with parenthesis arg = convert_func_arg(func.func_arg()) else: arg = convert_func_arg(func.func_arg_noparens()) name = func.func_normal().start.text[1:] # change arc<trig> -> a<trig> if name in [ "arcsin", "arccos", "arctan", "arccsc", "arcsec", "arccot" ]: name = "a" + name[3:] expr = getattr(sympy.functions, name)(arg, evaluate=False) if name in ["arsinh", "arcosh", "artanh"]: name = "a" + name[2:] expr = getattr(sympy.functions, name)(arg, evaluate=False) if name == "exp": expr = sympy.exp(arg, evaluate=False) if (name == "log" or name == "ln"): if func.subexpr(): base = convert_expr(func.subexpr().expr()) elif name == "log": base = 10 elif name == "ln": base = sympy.E expr = sympy.log(arg, base, evaluate=False) func_pow = None should_pow = True if func.supexpr(): if func.supexpr().expr(): func_pow = convert_expr(func.supexpr().expr()) else: func_pow = convert_atom(func.supexpr().atom()) if name in [ "sin", "cos", "tan", "csc", "sec", "cot", "sinh", "cosh", "tanh" ]: if func_pow == -1: name = "a" + name should_pow = False expr = getattr(sympy.functions, name)(arg, evaluate=False) if func_pow and should_pow: expr = sympy.Pow(expr, func_pow, evaluate=False) return expr elif func.LETTER() or func.SYMBOL(): if func.LETTER(): fname = func.LETTER().getText() elif func.SYMBOL(): fname = func.SYMBOL().getText()[1:] fname = str(fname) # can't be unicode if func.subexpr(): subscript = None if func.subexpr().expr(): # subscript is expr subscript = convert_expr(func.subexpr().expr()) else: # subscript is atom subscript = convert_atom(func.subexpr().atom()) subscriptName = StrPrinter().doprint(subscript) fname += '_{' + subscriptName + '}' input_args = func.args() output_args = [] while input_args.args(): # handle multiple arguments to function output_args.append(convert_expr(input_args.expr())) input_args = input_args.args() output_args.append(convert_expr(input_args.expr())) return sympy.Function(fname)(*output_args) elif func.FUNC_INT(): return handle_integral(func) elif func.FUNC_SQRT(): expr = convert_expr(func.base) if func.root: r = convert_expr(func.root) return sympy.root(expr, r) else: return sympy.sqrt(expr) elif func.FUNC_SUM(): return handle_sum_or_prod(func, "summation") elif func.FUNC_PROD(): return handle_sum_or_prod(func, "product") elif func.FUNC_LIM(): return handle_limit(func)
def my_sympify(expr, normphase=False, matrix=False, abcsym=False, do_qubit=False, symtab=None): """ Version of sympify to import expression into sympy """ # make all lowercase real? if symtab: varset = symtab else: varset = { 'p': sympy.Symbol('p'), 'g': sympy.Symbol('g'), 'e': sympy.E, # for exp 'i': sympy.I, # lowercase i is also sqrt(-1) 'Q': sympy.Symbol('Q'), # otherwise it is a sympy "ask key" 'I': sympy.Symbol('I'), # otherwise it is sqrt(-1) 'N': sympy.Symbol('N'), # or it is some kind of sympy function 'ZZ': sympy.Symbol('ZZ'), # otherwise it is the PythonIntegerRing 'XI': sympy.Symbol('XI'), # otherwise it is the capital \XI 'hat': sympy.Function('hat'), # for unit vectors (8.02) } if do_qubit: # turn qubit(...) into Qubit instance varset.update({ 'qubit': Qubit, 'Ket': Ket, 'dot': dot, 'bit': sympy.Function('bit'), }) if abcsym: # consider all lowercase letters as real symbols, in the parsing for letter in string.ascii_lowercase: if letter in varset: # exclude those already done continue varset.update({letter: sympy.Symbol(letter, real=True)}) sexpr = sympify(expr, locals=varset) if normphase: # remove overall phase if sexpr is a list if isinstance(sexpr, list): if sexpr[0].is_number: ophase = sympy.sympify('exp(-I*arg(%s))' % sexpr[0]) sexpr = [sympy.Mul(x, ophase) for x in sexpr] def to_matrix(expr): """ Convert a list, or list of lists to a matrix. """ # if expr is a list of lists, and is rectangular, then return Matrix(expr) if not isinstance(expr, list): return expr for row in expr: if not isinstance(row, list): return expr rdim = len(expr[0]) for row in expr: if not len(row) == rdim: return expr return sympy.Matrix(expr) if matrix: sexpr = to_matrix(sexpr) return sexpr
#=============================================================================== # Class for simple definition of explicit state updaters #=============================================================================== def _symbol(name, positive=None): ''' Shorthand for ``sympy.Symbol(name, real=True)``. ''' return sympy.Symbol(name, real=True, positive=positive) #: reserved standard symbols SYMBOLS = {'__x' : _symbol('__x'), '__t' : _symbol('__t', positive=True), 'dt': _symbol('dt', positive=True), 't': _symbol('t', positive=True), '__f' : sympy.Function('__f'), '__g' : sympy.Function('__g'), '__dW': _symbol('__dW')} def split_expression(expr): ''' Split an expression into a part containing the function ``f`` and another one containing the function ``g``. Returns a tuple of the two expressions (as sympy expressions). Parameters ---------- expr : str An expression containing references to functions ``f`` and ``g``.
import numpy as np import sympy as sm from sympy import Derivative from itertools import groupby import matplotlib.pyplot as plt from tabulate import tabulate from pprint import pprint from IPython.display import display, Latex, clear_output from sympy import latex sm.init_printing(use_latex='mathjax') x, y, c = sm.symbols('x, y, c', real=True) C1, C2 = sm.symbols("C1, C2", real=True) c = sm.symbols("c") u = sm.Function('u') ux = u(x) ux1 = Derivative(u(x), x) ux2 = Derivative(u(x), (x, 2)) h, uup1, uum1, uu0 = sm.symbols('h, u_i+1, u_i-1, u_i') uux1 = (uup1 - uum1) / (2 * h) uux2 = (uup1 - 2 * uu0 + uum1) / (h**2) zad1 = { 'p': sm.sqrt(1 + x**2) * 0.4, 'q': 4 * (1 + x**2), 'f': 20 * sm.exp(-x), 'a': 0, 'UA': 0, 'b': 2.5,
#coding:utf-8 ''' 函数 ''' import sympy sympy.init_printing() from sympy import I, pi, oo x, y, z = sympy.symbols("x, y, z") # 创建函数符号 f = sympy.Function('f') fx = f(x) print(fx) g = sympy.Function('g')(x,y,z) print(g) print(g.free_symbols) # 常用函数符号 sinx = sympy.sin(x) print(sinx) # 函数简单计算 print(sympy.sin(1.5 * pi)) # 指定函数变量的数据类型 n = sympy.Symbol('n',integer=True) print(sympy.sin(n * pi)) # Lambda h = sympy.Lambda(x, x**2) print(h) print(h(5))
def apply(self, eqn, y, x, evaluation): 'DSolve[eqn_, y_, x_]' if eqn.has_form('List', eqn): #TODO: Try and solve BVPs using Solve or something analagous OR add this functonality to sympy. evaluation.message('DSolve', 'symsys') return if eqn.get_head_name() != 'Equal': evaluation.message('DSolve', 'deqn', eqn) return if (x.is_atom() and not x.is_symbol()) or \ x.get_head_name() in ('Plus', 'Times', 'Power') or \ 'Constant' in x.get_attributes(evaluation.definitions): evaluation.message('DSolve', 'dsvar') return # Fixes pathalogical DSolve[y''[x] == y[x], y, x] try: y.leaves function_form = None func = y except AttributeError: func = Expression(y, x) function_form = Expression('List', x) if func.is_atom(): evaluation.message('DSolve', 'dsfun', y) return if len(func.leaves) != 1: evaluation.message('DSolve', 'symmua') return if x not in func.leaves: evaluation.message('DSolve', 'deqx') return left, right = eqn.leaves eqn = Expression('Plus', left, Expression('Times', -1, right)).evaluate(evaluation) sym_eq = eqn.to_sympy(converted_functions = set([func.get_head_name()])) sym_x = sympy.symbols(str(sympy_symbol_prefix + x.name)) sym_func = sympy.Function(str(sympy_symbol_prefix + func.get_head_name())) (sym_x) try: sym_result = sympy.dsolve(sym_eq, sym_func) if not isinstance(sym_result, list): sym_result = [sym_result] except ValueError as e: evaluation.message('DSolve', 'symimp') return except NotImplementedError as e: evaluation.message('DSolve', 'symimp') return except AttributeError as e: evaluation.message('DSolve', 'litarg', eqn) return except KeyError: evaluation.message('DSolve', 'litarg', eqn) return if function_form is None: return Expression('List', *[Expression('List', Expression('Rule', *from_sympy(soln).leaves)) for soln in sym_result]) else: return Expression('List', *[Expression('List', Expression('Rule', y, Expression('Function', function_form, *from_sympy(soln).leaves[1:]))) for soln in sym_result])
# sorted_evalues = evalues[sorted_indices] # # return sorted_evectors, np.diag(sorted_evalues), sorted_evalues # # # print(pca(np.array([[1,2],[3,4],[5,6]]))) # # total = 20 # red = 2 # white = 8 # blue = 3 # black = 1 # purple = 6 # def calcuateEntropy(x): H = 0 total = np.sum(x) for i in x: p_x = float(i) / float(total) H = H - p_x * np.log2(p_x) return H x = [2, 8, 3, 1, 6] print(calcuateEntropy(x)) sym.Function('y')
def parse_expression(string: str, mark_categorical: bool = False) -> sp.Expr: """Parse a SymPy expression from a string. Optionally, preserve the categorical marker function instead of treating it like the identify function. """ # list reserved patsy and SymPy names that represent special functions and classes patsy_function_names = {'I', 'C'} sympy_function_names = {'log', 'exp'} sympy_class_names = {'Add', 'Mul', 'Pow', 'Integer', 'Float', 'Symbol'} # build a mapping from reserved names to the functions and classes that they represent (patsy functions are dealt # with after parsing) mapping = {n: sp.Function(n) for n in patsy_function_names} mapping.update( {n: getattr(sp, n) for n in sympy_function_names | sympy_class_names}) # define a function that validates a list of tokens into which the string is broken and adds new symbols def transform_tokens(tokens: List[Tuple[int, str]], *_: Any) -> List[Tuple[int, str]]: """Validate a list of tokens and add any unrecognized names as new SymPy symbols.""" transformed: List[Tuple[int, str]] = [] symbol_candidate = None for code, value in tokens: if code not in { token.NAME, token.OP, token.NUMBER, token.NEWLINE, token.ENDMARKER }: raise ValueError(f"The token '{value}' is invalid.") if code == token.OP and value not in { '+', '-', '*', '/', '**', '(', ')' }: raise ValueError(f"The operation '{value}' is invalid.") if code == token.OP and value == '(' and symbol_candidate is not None: raise ValueError( f"The function '{symbol_candidate}' is invalid.") if code != token.NAME or value in set(mapping) - sympy_class_names: transformed.append((code, value)) symbol_candidate = None continue if value in sympy_class_names | {'Intercept'}: raise ValueError(f"The name '{value}' is invalid.") transformed.extend([(token.NAME, 'Symbol'), (token.OP, '('), (token.NAME, repr(value)), (token.OP, ')')]) symbol_candidate = value return transformed # define a function that validates the appearance of categorical marker functions def validate_categorical(candidate: sp.Expr, depth: int = 0, categorical: bool = False) -> None: """Recursively validate that all categorical marker functions in an expression accept only a single variable argument and that they are not arguments to other functions. """ if categorical and depth > 1: raise ValueError( "The C function must not be an argument to another function.") for arg in candidate.args: if categorical and not isinstance(arg, sp.Symbol): raise ValueError( "The C function accepts only a single variable.") validate_categorical(arg, depth + 1, candidate.func == mapping['C']) # parse the expression, validate it by attempting to represent it as a string, and validate categorical markers try: expression = sympy.parsing.sympy_parser.parse_expr(string, mapping, [transform_tokens], evaluate=False) str(expression) validate_categorical(expression) except (TypeError, ValueError) as exception: raise ValueError( f"The expression '{string}' is malformed.") from exception # replace patsy functions with the identity function, unless categorical variables are to be explicitly marked for name in patsy_function_names: if name != 'C' or not mark_categorical: expression = expression.replace(mapping[name], sp.Id) return expression
def params(cls): return { 'β': sym.symbols('β', real=True, positive=True), 'Vp': sym.Function('Vp')(cls.x) }
def __call__(self, equations, variables=None, method_options=None): logger.warn( "The 'independent' state updater is deprecated and might be " "removed in future versions of Brian.", 'deprecated_independent', once=True) extract_method_options(method_options, {}) if equations.is_stochastic: raise UnsupportedEquationsException('Cannot solve stochastic ' 'equations with this state ' 'updater') if variables is None: variables = {} diff_eqs = equations.get_substituted_expressions(variables) t = Symbol('t', real=True, positive=True) dt = Symbol('dt', real=True, positive=True) t0 = Symbol('t0', real=True, positive=True) code = [] for name, expression in diff_eqs: rhs = str_to_sympy(expression.code, variables) # We have to be careful and use the real=True assumption as well, # otherwise sympy doesn't consider the symbol a match to the content # of the equation var = Symbol(name, real=True) f = sp.Function(name) rhs = rhs.subs(var, f(t)) derivative = sp.Derivative(f(t), t) diff_eq = sp.Eq(derivative, rhs) # TODO: simplify=True sometimes fails with 0.7.4, see: # https://github.com/sympy/sympy/issues/2666 try: general_solution = sp.dsolve(diff_eq, f(t), simplify=True) except RuntimeError: general_solution = sp.dsolve(diff_eq, f(t), simplify=False) # Check whether this is an explicit solution if not getattr(general_solution, 'lhs', None) == f(t): raise UnsupportedEquationsException( 'Cannot explicitly solve: ' + str(diff_eq)) # Solve for C1 (assuming "var" as the initial value and "t0" as time) if general_solution.has(Symbol('C1')): if general_solution.has(Symbol('C2')): raise UnsupportedEquationsException( 'Too many constants in solution: %s' % str(general_solution)) constant_solution = sp.solve(general_solution, Symbol('C1')) if len(constant_solution) != 1: raise UnsupportedEquationsException( ("Couldn't solve for the constant " "C1 in : %s ") % str(general_solution)) constant = constant_solution[0].subs(t, t0).subs(f(t0), var) solution = general_solution.rhs.subs('C1', constant) else: solution = general_solution.rhs.subs(t, t0).subs(f(t0), var) # Evaluate the expression for one timestep solution = solution.subs(t, t + dt).subs(t0, t) # only try symplifying it -- it sometimes raises an error try: solution = solution.simplify() except ValueError: pass code.append(name + ' = ' + sympy_to_str(solution)) return '\n'.join(code)
class Generalized_Langevin: # Order different than in Langevin! # x = q, y = p, z = z1, w = z2 (velocities are y and z2) variables = sym.symbols('x y z w', real=True) x, y, z, w = variables # Unknown functions fL = sym.Function('f')(x, y) f1 = sym.Function('f')(x, y, z) f2 = sym.Function('f')(x, y, z, w) @classmethod def params(cls, n_extra): assert n_extra == 1 or n_extra == 2 params, functions = {}, {} # Real positive parameters options = {'real': True, 'positive': True} params['β'] = sym.symbols('β', **options) if n_extra == 1: params['λ'] = sym.symbols('λ', **options) params['α'] = sym.symbols('α', **options) elif n_extra == 2: params['λ1'] = sym.symbols('λ1', **options) params['λ2'] = sym.symbols('λ2', **options) for param in ['A11', 'A12', 'A21', 'A22']: params[param] = sym.symbols(param, real=True) # Potential function functions['Vx'] = sym.Function('Vx')(cls.x) return {**params, **functions} @classmethod def backward(cls, params): # Common parameters β, Vx = params['β'], params['Vx'] d, x, y, z, w = sym.diff, cls.x, cls.y, cls.z, cls.w # 1 auxiliary process if 'α' in params: f = cls.f1 z_vec = sym.Matrix([z]) lamb = sym.Matrix([params['λ']]) A = sym.Matrix([[params['α']]]) # 2 auxiliary processes elif 'A11' in params: f = cls.f2 z_vec = sym.Matrix([z, w]) lamb = sym.Matrix([params['λ1'], params['λ2']]) A = sym.Matrix([[params['A11'], params['A12']], [params['A21'], params['A22']]]) # Usual Langevin equation else: if 'γ' not in params: raise ValueError("Invalid argument, γ must be specified!") f, γ = cls.fL, params['γ'] # Backward Kolmogorov operator operator = (y*d(f, x) - d(Vx, x)*d(f, y))\ + γ*(- y*d(f, y) + (1/β)*d(f, y, y)) return operator # Computation of diffusion matrix # Σ = sym.sqrt((A + A.T)/β).doit() # Auxiliary quantities dfdz = sym.Matrix([f.diff(v) for v in z_vec]) ddfdzdz = sym.Matrix([dfdz.diff(v).T for v in z_vec]) # Backward Kolmogorov operator operator = y*d(f, x) - d(Vx, x)*d(f, y)\ + (lamb.dot(z_vec))*d(f, y)\ - y*lamb.dot(dfdz)\ - (A*z_vec).dot(dfdz)\ + (1/β)*(A*ddfdzdz).trace() γ = lamb.dot(A.inv() * lamb) print("Effective friction: {}".format(γ)) return operator
class McKean_Vlasov_harmonic_noise: # Space variables variables = sym.symbols('x y z', real=True) # Sharthand notations x, y, z = variables # Unknown f = sym.Function('f')(x, y, z) @classmethod def params(cls): params, functions = {}, {} # Real positive parameters options = {'real': True, 'positive': True} for param in ['β', 'γ', 'ε']: params[param] = sym.symbols(param, **options) # Real parameters options = {'real': True} for param in ['θ', 'm']: params[param] = sym.symbols(param, **options) # Potential function functions['Vp'] = sym.Function('Vp')(cls.x) return {**params, **functions} @classmethod def fluxes(cls, params): # Real parameters β, γ, ε, θ, m = (params[x] for x in ['β', 'γ', 'ε', 'θ', 'm']) # Functional parameter Vp = params['Vp'] # Shorthand notations d, x, y, z, f = sym.diff, cls.x, cls.y, cls.z, cls.f # Friction coefficient λ = 1 # Fokker planck operator flux_x = -(d(Vp, x) * f + θ * (x - m) * f - (1 - γ) * sym.sqrt(1 / β) * z * f / ε + γ**2 / β * d(f, x)) flux_y = -(1 / ε**2) * (f * z + λ * (f * y + d(f, y))) flux_z = -(1 / ε**2) * (-y * f) return [flux_x, flux_y, flux_z] @classmethod def equation(cls, params): # Shorthand notations x, y, z = cls.x, cls.y, cls.z # Compute fluxes fx, fy, fz = cls.fluxes(params) # Fokker planck operator return -fx.diff(x) - fy.diff(y) - fz.diff(z)
class McKean_Vlasov: # Space variables variables = sym.symbols('x y', real=True) # Sharthand notations x, y = variables # Unknown f = sym.Function('f')(variables[0], variables[1]) @classmethod def params(cls): params, functions = {}, {} # Real positive parameters options = {'real': True, 'positive': True} for param in ['β', 'γ', 'ε']: params[param] = sym.symbols(param, **options) # Real parameters options = {'real': True} for param in ['θ', 'm']: params[param] = sym.symbols(param, **options) # Potential functions functions['Vp'] = sym.Function('Vp')(cls.x) functions['Vy'] = sym.Function('Vy')(cls.y) return {**params, **functions} @classmethod def fluxes(cls, params): # Shorthand notations d, x, y, f = sym.diff, cls.x, cls.y, cls.f # Real parameters β, γ, ε, θ, m = (params[x] for x in ['β', 'γ', 'ε', 'θ', 'm']) # Functional parameter Vp, Vy = params['Vp'], params['Vy'] # Effective diffusion functions = Vy.atoms(sym.core.function.AppliedUndef) if functions == set(): degree, n_points, q = 100, 201, quad.Quad.gauss_hermite fy = sym.Function('f')(y) gen = Vy.diff(y) * fy.diff(y) - fy.diff(y, y) σy, density = .2, sym.exp(-Vy) gaussian = sym.exp(-y * y / (2 * σy)) / sym.sqrt(2 * sym.pi * σy) integral = q(n_points, dirs=[1]).integrate(density, flat=True) factor = sym.sqrt(gaussian / (density / integral)) qy = q(n_points, dirs=[1], factor=factor, cov=[[σy]]) L0 = qy.discretize_op(gen, degree, sparse=False, index_set="triangle") rhs = qy.transform('y', degree) solution = la.solve(L0.matrix, rhs.coeffs) coeff_noise = np.dot(solution, rhs.coeffs) coeff_noise = sym.Rational(coeff_noise).limit_denominator(1e8) coeff_noise = sym.sqrt(1 / β / coeff_noise) # effective_noise = float(1/sym.sqrt(2*coeff_noise)) # print("Effective noise (ζ): " + str(effective_noise)) else: # Assume Vy is y*y/2 coeff_noise = sym.sqrt(1 / β) # Fokker planck operator flux_x = -(d(Vp, x) * f + θ * (x - m) * f - (1 - γ) * coeff_noise * y * f / ε + γ**2 / β * d(f, x)) flux_y = -(1 / ε**2) * (f * Vy.diff(y) + d(f, y)) return [flux_x, flux_y] @classmethod def equation(cls, params): # Shorthand notations x, y = cls.x, cls.y # Compute fluxes fx, fy = cls.fluxes(params) # Fokker planck operator return -fx.diff(x) - fy.diff(y)
def chunked_search(): """ Computational complexity of building one kd-tree and searching vs building many and searching. -------------------------------- Normal Running Time: Indexing: D⋅log(D⋅p) Query: Q⋅log(D⋅p) -------------------------------- -------------------------------- Chunked Running Time: Indexing: ⎛D⋅p⎞ D⋅log⎜───⎟ ⎝ C ⎠ Query: ⎛D⋅p⎞ C⋅Q⋅log⎜───⎟ ⎝ C ⎠ -------------------------------- Conclusion: chunking provides a tradeoff in running time. It can make indexing, faster, but it makes query-time slower. However, it does allow for partial database search, which can speed up response time of queries. It can also short-circuit itself once a match has been found. """ import sympy as sym import utool as ut ceil = sym.ceiling ceil = ut.identity log = sym.log # # ==================== # Define basic symbols # ==================== # Number of database and query annotations n_dannots, n_qannots = sym.symbols('D, Q') # Average number of descriptors per annotation n_vecs_per_annot = sym.symbols('p') # Size of the shortlist to rerank n_rr = sym.symbols('L') # The number of chunks C = sym.symbols('C') # # =============================================== # Define helper functions and intermediate values # =============================================== n_dvecs = n_vecs_per_annot * n_dannots # Could compute the maximum average matches something gets # but for now just hack it fmatch = sym.Function('fmatch') n_fmatches = fmatch(n_vecs_per_annot) # The complexity of spatial verification is roughly that of SVD # SV_fn = lambda N: N ** 3 # NOQA SV_fn = sym.Function('SV') SV = SV_fn(n_fmatches) class KDTree(object): # A bit of a simplification n_trees = sym.symbols('T') params = {n_trees} @classmethod def build(self, N): return N * log(N) * self.n_trees @classmethod def search(self, N): # This is average case return log(N) * self.n_trees Indexer = KDTree def sort(N): return N * log(N) # # ======================== # Define normal complexity # ======================== # The computational complexity of the normal hotspotter pipeline normal = {} normal['indexing'] = Indexer.build(n_dvecs) normal['search'] = n_vecs_per_annot * Indexer.search(n_dvecs) normal['rerank'] = (SV * n_rr) normal['query'] = (normal['search'] + normal['rerank']) * n_qannots normal['total'] = normal['indexing'] + normal['query'] n_cannots = ceil(n_dannots / C) n_cvecs = n_vecs_per_annot * n_cannots # How many annots should be re-ranked in each chunk? # _n_rr_chunk = sym.Max(n_rr / C * log(n_rr / C), 1) # _n_rr_chunk = n_rr / C _n_rr_chunk = n_rr _index_chunk = Indexer.build(n_cvecs) _search_chunk = n_vecs_per_annot * Indexer.search(n_cvecs) chunked = {} chunked['indexing'] = C * _index_chunk chunked['search'] = C * _search_chunk # Cost to rerank in every chunk and then merge chunks into a single list chunked['rerank'] = C * (SV * _n_rr_chunk) + sort(C * _n_rr_chunk) chunked['query'] = (chunked['search'] + chunked['rerank']) * n_qannots chunked['total'] = chunked['indexing'] + chunked['query'] typed_steps = { 'normal': normal, 'chunked': chunked, } # # =============== # Inspect results # =============== # Symbols that will not go to infinity const_symbols = {n_rr, n_vecs_per_annot}.union(Indexer.params) def measure_num(n_steps, step, type_): print('nsteps(%s %s)' % ( step, type_, )) sym.pprint(n_steps) def measure_order(n_steps, step, type_): print('O(%s %s)' % ( step, type_, )) limiting = [(s, sym.oo) for s in n_steps.free_symbols - const_symbols] step_order = sym.Order(n_steps, *limiting) sym.pprint(step_order.args[0]) measure_dict = { 'num': measure_num, 'order': measure_order, } # Different methods for choosing C C_methods = ut.odict([ ('none', C), ('const', 512), ('linear', n_dannots / 512), ('log', log(n_dannots)), ]) # --- # What to measure? # --- steps = ['indexing', 'query'] types_ = ['normal', 'chunked'] measures = [ # 'num', 'order' ] C_method_keys = [ 'none' # 'const' ] grid = ut.odict([ ('step', steps), ('measure', measures), ('k', C_method_keys), ('type_', types_), ]) last = None for params in ut.all_dict_combinations(grid): type_ = params['type_'] step = params['step'] k = params['k'] # now = k now = step if last != now: print('=========') print('\n\n=========') last = now print('') print(ut.repr2(params, stritems=True)) measure_fn = measure_dict[params['measure']] info = typed_steps[type_] n_steps = info[step] n_steps = n_steps.subs(C, C_methods[k]) measure_fn(n_steps, step, type_)
def modeling(linearized=True): t = sp.Symbol('t') # time params = sp.symbols( 'm0, m1, m2, J1, J2, l1, l2, g, d0, d1, d2') # system parameters m0, m1, m2, J1, J2, l1, l2, g, d0, d1, d2 = params params_values = [(m0, 3.34), (m1, 0.3583), (m2, 0.5383), (J1, 0.0379999), (J2, 0.12596), (l1, 0.5), (l2, 0.75), (g, 9.81), (d0, 0.1), (d1, 0.006588), (d2, 0.006588)] # force F = sp.Symbol('F') # generalized coordinates q0_t = Function('q0')(t) dq0_t = q0_t.diff(t) ddq0_t = q0_t.diff(t, 2) q1_t = Function('q1')(t) dq1_t = q1_t.diff(t) ddq1_t = q1_t.diff(t, 2) q2_t = Function('q2')(t) dq2_t = q2_t.diff(t) ddq2_t = q2_t.diff(t, 2) # position vectors p0 = sp.Matrix([q0_t, 0]) p1 = sp.Matrix([q0_t - 0.5 * l1 * sin(q1_t), 0.5 * l1 * cos(q1_t)]) p2 = sp.Matrix([q0_t - 0.5 * l2 * sin(q2_t), 0.5 * l2 * cos(q2_t)]) # velocity vectors dp0 = p0.diff(t) dp1 = p1.diff(t) dp2 = p2.diff(t) # kinetic energy T T0 = m0 / 2 * (dp0.T * dp0)[0] T1 = (m1 * (dp1.T * dp1)[0] + J1 * dq1_t**2) / 2 T2 = (m2 * (dp2.T * dp2)[0] + J2 * dq2_t**2) / 2 T = T0 + T1 + T2 # potential energy V V = m1 * g * p1[1] + m2 * g * p2[1] # lagrangian L L = T - V # Lagrange equations of the second kind # d/dt(dL/d(dq_i/dt)) - dL/dq_i = Q_i Q0 = F - d0 * dq0_t Q1 = -d1 * dq1_t Q2 = -d2 * dq2_t Eq0 = L.diff(dq0_t, t) - L.diff(q0_t) - Q0 # = 0 Eq1 = L.diff(dq1_t, t) - L.diff(q1_t) - Q1 # = 0 Eq2 = L.diff(dq2_t, t) - L.diff(q2_t) - Q2 # = 0 # equations of motion Eq = sp.Matrix([Eq0, Eq1, Eq2]) # partial linerization / acceleration as input, not force/torque # new input - acceleration of the cart a = sp.Function('a')(t) # replace ddq0 with a Eq_a = Eq.subs(ddq0_t, a) # solve for F sol = sp.solve(Eq_a, F) Fa = sol[F] # F(a) # partial linearization Eq_lin = Eq.subs(F, Fa) # solve for ddq/dt ddq_t = sp.Matrix([ddq0_t, ddq1_t, ddq2_t]) if linearized: ddq = sp.solve(Eq_lin, ddq_t) else: ddq = sp.solve(Eq, ddq_t) # state space model # functions of x, u x1_t = sp.Function('x1')(t) x2_t = sp.Function('x2')(t) x3_t = sp.Function('x3')(t) x4_t = sp.Function('x4')(t) x5_t = sp.Function('x5')(t) x6_t = sp.Function('x6')(t) x_t = sp.Matrix([x1_t, x2_t, x3_t, x4_t, x5_t, x6_t]) u_t = sp.Function('u')(t) # symbols of x, u x1, x2, x3, x4, x5, x6, u = sp.symbols("x1, x2, x3, x4, x5, x6, u") xx = [x1, x2, x3, x4, x5, x6] # replace generalized coordinates with states if linearized: xu_subs = [(dq0_t, x4_t), (dq1_t, x5_t), (dq2_t, x6_t), (q0_t, x1_t), (q1_t, x2_t), (q2_t, x3_t), (a, u_t)] else: xu_subs = [(dq0_t, x4_t), (dq1_t, x5_t), (dq2_t, x6_t), (q0_t, x1_t), (q1_t, x2_t), (q2_t, x3_t), (F, u_t)] # first order ODE (right hand side) dx_t = sp.Matrix([x4_t, x5_t, x6_t, ddq[ddq0_t], ddq[ddq1_t], ddq[ddq2_t]]) dx_t = dx_t.subs(xu_subs) # linearized dynamics A = dx_t.jacobian(x_t) B = dx_t.diff(u_t) # symbolic expressions of A and B with parameter values Asym = A.subs(list(zip(x_t, xx))).subs(u_t, u).subs(params_values) Bsym = B.subs(list(zip(x_t, xx))).subs(u_t, u).subs(params_values) dx_t_sym = dx_t.subs(list(zip(x_t, xx))).subs(u_t, u).subs( params_values) # replacing all symbolic functions with symbols print(dx_t_sym) if linearized: lin = '_lin' else: lin = '' with open('c_files/cart_pole_double_parallel' + lin + '_ode.p', 'wb') as opened_file: pickle.dump(dx_t_sym, opened_file) with open('c_files/cart_pole_double_parallel' + lin + '_A.p', 'wb') as opened_file: pickle.dump(Asym, opened_file) with open('c_files/cart_pole_double_parallel' + lin + '_B.p', 'wb') as opened_file: pickle.dump(Bsym, opened_file) # RHS as callable function dxdt, A, B = load_existing() return dxdt, A, B
import sympy as sp import numpy as np from IPython.display import display ## Felipe Gomes #display(yourobject) sp.init_printing() t = sp.Symbol("t", positive=True) # Propriedades da cabeça m_c, J_c = sp.symbols("m_c J_c", positive=True) x_c = sp.Function("x_c", real=True)(t) y_c = sp.Function("y_c", real=True)(t) theta_c = sp.Function("theta_c", real=True)(t) # Propriedades do torço m_t, J_t, L_t = sp.symbols("m_t J_t L_t", positive=True) x_t = sp.Function("x_t", real=True)(t) y_t = sp.Function("y_t", real=True)(t) theta_t = sp.Function("theta_t", real=True)(t) L_t = sp.Symbol("L_t", real=True) L_p = sp.Symbol("L_p", real=True) # Propriedades dos membros inferiores x_i = sp.Function("x_i", real=True)(t) m_i = sp.Symbol("m_i", positive=True) # Interação air bag-cabeça
# benchmark SymFields module import sympy from SymFields import * pi = sympy.pi # cylinder coordinates r, phi, z = sympy.symbols('r, phi, z') X = [r, phi, z] U = sympy.Function('U') U = U(r, phi, z) grad = Grad(U, X, coordinate='Cylinder') curl_grad = Curl(grad, X, coordinate='Cylinder') A_r = sympy.Function('A_r') A_phi = sympy.Function('A_phi') A_z = sympy.Function('A_z') A_r = A_r(r, phi, z) A_phi = A_phi(r, phi, z) A_z = A_z(r, phi, z) A = [A_r, A_phi, A_z] divergence = Div(A, X, coordinate='Cylinder') curl = Curl(A, X, coordinate='Cylinder') div_curl = Div(curl, X, coordinate='Cylinder') div_curl.doit() # Laplacian operator L = Div(grad, X, coordinate='Cylinder', evaluation=1)
def define_variable(name, namespace=globals(), order=1): if not name in namespace: namespace[name] = sympy.Function(name, perturbation_order=order)(t) return namespace[name]
import loop as lp # NRPy+: C code loop interface import NRPy_param_funcs as par # NRPy+: parameter interface from SIMD import expr_convert_to_SIMD_intrins # NRPy+: SymPy expression => SIMD intrinsics interface from cse_helpers import cse_preprocess,cse_postprocess # NRPy+: CSE preprocessing and postprocessing import sympy as sp # SymPy: The Python computer algebra package upon which NRPy+ depends import re, sys, os, stat # Standard Python: regular expressions, system, and multiplatform OS funcs from collections import namedtuple # Standard Python: Enable namedtuple data type lhrh = namedtuple('lhrh', 'lhs rhs') outCparams = namedtuple('outCparams', 'preindent includebraces declareoutputvars outCfileaccess outCverbose CSE_enable CSE_varprefix CSE_sorting CSE_preprocess enable_SIMD SIMD_find_more_subs SIMD_find_more_FMAsFMSs SIMD_debug enable_TYPE gridsuffix') # Sometimes SymPy has problems evaluating complicated expressions involving absolute # values, resulting in hangs. So instead of using sp.Abs(), if we instead use # nrpyAbs, we can sidestep the internal SymPy evaluation and force the C # codegen to output our desired fabs(). nrpyAbs = sp.Function('nrpyAbs') custom_functions_for_SymPy_ccode = { "nrpyAbs": "fabs", 'Pow': [(lambda b, e: e == 0.5, lambda b, e: 'sqrt(%s)' % (b)), (lambda b, e: e ==-0.5, lambda b, e: '(1.0/sqrt(%s))' % (b)), (lambda b, e: e == sp.S.One/3, lambda b, e: 'cbrt(%s)' % (b)), (lambda b, e: e ==-sp.S.One/3, lambda b, e: '(1.0/cbrt(%s))' % (b)), (lambda b, e: e == 2, lambda b, e: '((%s)*(%s))' % (b,b)), (lambda b, e: e == 3, lambda b, e: '((%s)*(%s)*(%s))' % (b,b,b)), (lambda b, e: e == 4, lambda b, e: '((%s)*(%s)*(%s)*(%s))' % (b,b,b,b)), (lambda b, e: e == 5, lambda b, e: '((%s)*(%s)*(%s)*(%s)*(%s))' % (b,b,b,b,b)), (lambda b, e: e ==-1, lambda b, e: '(1.0/(%s))' % (b)), (lambda b, e: e ==-2, lambda b, e: '(1.0/((%s)*(%s)))' % (b,b)), (lambda b, e: e ==-3, lambda b, e: '(1.0/((%s)*(%s)*(%s)))' % (b,b,b)), (lambda b, e: e ==-4, lambda b, e: '(1.0/((%s)*(%s)*(%s)*(%s)))' % (b,b,b,b)), (lambda b, e: e ==-5, lambda b, e: '(1.0/((%s)*(%s)*(%s)*(%s)*(%s)))' % (b,b,b,b,b)),
import sympy as sp import numpy as np import matplotlib.pyplot as plt # parameter k, m = sp.symbols("k m") # time t = sp.Symbol("t") # generalized coordinate q_fn = sp.Function("q") q = q_fn(t) q_dot = q.diff(t) # cartesian coordinates in terms of q x = q y = 0 z = 0 print("generalized coordinates:") print("x =", x, "\ny =", y, "\nz =", z) # compute cartesian derivates in terms of q x_dot = sp.diff(x, t) y_dot = sp.diff(y, t) z_dot = sp.diff(z, t) print("x_dot =", x_dot, "\ny_dot =", y_dot, "\nz_dot =", z_dot) # construct lagrangian T = m * (x_dot**2 + y_dot**2 + z_dot**2) / 2 V = k * x**2 / 2
def generate_cross_section(atom_list, arg, q, real_list, recip_list): """Generates the Cross-Section Formula for the one magnon case""" N = len(atom_list) gam = 1.913 #sp.Symbol('gamma', commutative = True) r = sp.Symbol('r0', commutative=True) h = 1. # 1.05457148*10**(-34) #sp.Symbol('hbar', commutative = True) k = sp.Symbol('k', commutative=True) kp = sp.Symbol('kp', commutative=True) g = sp.Symbol('g', commutative=True) F = sp.Function('F') def FF(arg): F = sp.Function('F') if arg.shape == (3, 1) or arg.shape == (1, 3): return sp.Symbol("%r" % (F(arg.tolist()), ), commutative=False) kap = spm.Matrix([ sp.Symbol('kapx', commutative=False), sp.Symbol('kapy', commutative=False), sp.Symbol('kapz', commutative=False) ]) t = sp.Symbol('t', commutative=True) w = sp.Symbol('w', commutative=True) W = sp.Symbol('W', commutative=False) kappa = sp.Symbol('kappa', commutative=False) tau = sp.Symbol('tau', commutative=False) # Wilds for sub_in method A = sp.Wild('A', exclude=[0]) B = sp.Wild('B', exclude=[0]) C = sp.Wild('C') D = sp.Wild('D') front_constant = (gam * r)**2 / (2 * pi * h) * (kp / k) * N front_func = (1. / 2.) * g #*F(k) vanderwaals = exp(-2 * W) temp2 = [] temp3 = [] temp4 = [] # Grabs the unit vectors from the back of the lists. unit_vect = [] kapx = sp.Symbol('kapxhat', ) kapy = sp.Symbol('kapyhat', commutative=False) kapz = sp.Symbol('kapzhat', commutative=False) for i in range(len(arg)): unit_vect.append(arg[i].pop()) # for ele in unit_vect: # ele = ele.subs(kapx,spm.Matrix([1,0,0])) # ele = ele.subs(kapy,spm.Matrix([0,1,0])) # ele = ele.subs(kapz,spm.Matrix([0,0,1])) # This is were the heart of the calculation comes in. # First the exponentials are turned into delta functions: for i in range(len(arg)): for j in range(N): arg[i][j] = sp.powsimp(arg[i][j], deep=True, combine='all') arg[i][j] = arg[i][j] * exp(-I * w * t) * exp( I * inner_prod(spm.Matrix(atom_list[j].pos).T, kap)) arg[i][j] = sp.powsimp(arg[i][j], deep=True, combine='all') arg[i][j] = sub_in(arg[i][j], exp(I * t * A + I * t * B + C), sp.DiracDelta(A * t + B * t + C / I)) #*sp.DiracDelta(C)) arg[i][j] = sub_in( arg[i][j], sp.DiracDelta(A * t + B * t + C), sp.DiracDelta(A * h + B * h) * sp.DiracDelta(C + tau)) arg[i][j] = sub_in(arg[i][j], sp.DiracDelta(-A - B), sp.DiracDelta(A + B)) print arg[i][j] print "Applied: Delta Function Conversion" # for ele in arg: # for subele in ele: # temp2.append(subele) # temp3.append(sum(temp2)) # # for i in range(len(temp3)): # temp4.append(unit_vect[i] * temp3[i]) for k in range(len(arg)): temp4.append(arg[k][q]) dif = (front_func**2 * front_constant * vanderwaals * sum(temp4) ) #.expand()#sp.simplify(sum(temp4))).expand() print "Complete: Cross-section Calculation" return dif
def generate_sympy_expr(expr: gp.PrimitiveTree, ccl_objects: dict) -> sympy.Expr: """Generates optimized sympy expression from an individual""" string = '' stack = [] distance_name = ccl_objects.get('distance', None) variables = {} atom_names = ccl_objects['atom_objects'] if distance_name is not None: variables[distance_name] = sympy.Function(distance_name, positive=True, real=True) for fn in ccl_objects['single_argument']: variables[fn] = sympy.Function(fn, real=True) for node in expr: stack.append((node, [])) while len(stack[-1][1]) == stack[-1][0].arity: prim, args = stack.pop() if prim.name == 'add': string = f'({args[0]}) + ({args[1]})' elif prim.name == 'sub': string = f'({args[0]}) - ({args[1]})' elif prim.name == 'mul': string = f'({args[0]}) * ({args[1]})' elif prim.name == 'div': string = f'({args[0]}) / ({args[1]})' elif prim.name in {'sqrt', 'cbrt', 'exp'}: string = f'{prim.name}({args[0]})' elif prim.name == 'square': string = f'({args[0]}) ** 2' elif prim.name == 'cube': string = f'({args[0]}) ** 3' elif prim.name == 'inv': string = f'(1 / ({args[0]}))' elif prim.name == 'double': string = f'(2 * ({args[0]}))' elif prim.name == 'half': string = f'(0.5 * ({args[0]}))' elif distance_name is not None and prim.name == distance_name: string = f'{distance_name}({atom_names[0]}{atom_names[1]})' elif prim.name.startswith('_term'): name, atom_name = prim.name.split('_')[-2:] string = f'{name}({atom_name})' elif prim.name.startswith('_sym_add'): name = prim.name.split('_')[-1] string = f'({name}({atom_names[0]}) + {name}({atom_names[1]}))' elif prim.name.startswith('_sym_inv_add'): name = prim.name.split('_')[-1] string = f'(1 / {name}({atom_names[0]}) + 1 / {name}({atom_names[1]}))' elif prim.name.startswith('_sym_mul'): name = prim.name.split('_')[-1] string = f'({name}({atom_names[0]}) * {name}({atom_names[1]}))' else: string = prim.format(*args) if len(stack) == 0: break # If stack is empty, all nodes should have been seen stack[-1][1].append(string) try: sympy_expr = sympy.sympify(string, locals=variables).evalf(2) except: raise RuntimeError('Sympy cannot process the expression') return sympy_expr
def FF(arg): F = sp.Function('F') if arg.shape == (3, 1) or arg.shape == (1, 3): return sp.Symbol("%r" % (F(arg.tolist()), ), commutative=False)
from sympy import I, pi, oo sympy.init_printing() #### 적분 #### # sympy.integrate(ft, (symbol, start, end)) ## 또는 아래의 순서를 따라 출력하는 것도 가능 # d = sympy.Integral(expr, symbols) #적분 표현 # d.doit() #적분 계산 결과 x, y, z = sympy.symbols("x, y, z") a, b, c = sympy.symbols("a, b, c") #### 적분 #### print(">>> 적분 <<<") f = sympy.Function('f')(x) print(f) print(sympy.integrate(f, x)) ##콘솔에서 선언하면 아래와 같이 출력됨 """ ⌠ ⎮ f(x) dx ⌡ """ print(sympy.integrate(f, (x, a, b))) """ b ⌠ ⎮ f(x) dx ⌡ a """
])for k in range(N)] ####################################### # Putting it all together and plotting. figure1=dict(data=data, layout=layout, frames=frames) iplot(figure1) m, g, J, w, l,lam = sym.symbols('m g J W L lam') m=1 g=9.81 J=1 w=0.25 l=1 x = sym.Function('x')(t) y = sym.Function('y')(t) th1 = sym.Function(r'\theta_1')(t) th2 = sym.Function(r'\theta_2')(t) th3 = sym.Function(r'\theta_3')(t) q = sym.Matrix([x,y,th1,th2,th3]) qdot = q.diff(t) qddot = qdot.diff(t) w = sym.Matrix([0,0,1]) Tw1=sym.simplify(T(w,0,[0,3,0])*T(w,-sym.pi/2,[0,0,0])*T(w,th1,[0,0,0])*T(w,0,[l/2,0,0])) Tw2=sym.simplify(Tw1*T(w,0,[l/2,0,0])*T(w,th2,[0,0,0])*T(w,0,[l/2,0,0])) Tw3=sym.simplify(T(w,0,[x,y,0])*T(w,th3,[0,0,0])) triangleI=sym.simplify(T(w,0,[-0.25,1.5,0]))
import sympy as sp import perforad # Define symbols for all examples c = sp.Function("c") u_1 = sp.Function("u_1") u_1_b = sp.Function("u_1_b") u_2 = sp.Function("u_2") u_2_b = sp.Function("u_2_b") u = sp.Function("u") u_b = sp.Function("u_b") i, j, k, C, D, n = sp.symbols("i,j,k,C,D,n") ######## 1D Wave Equation Example ######## # Build stencil expression u_xx = u_1(i - 1) - 2 * u_1(i) + u_1(i + 1) expr = 2.0 * u_1(i) - u_2(i) + c(i) * D * u_xx # Build LoopNest object for this expression lp = perforad.makeLoopNest(lhs=u(i), rhs=expr, counters=[i], bounds={i: [1, n - 2]}) # Output primal and adjoint files perforad.printfunction(name="wave1d", loopnestlist=[lp]) perforad.printfunction(name="wave1d_perf_b", loopnestlist=lp.diff({ u: u_b, u_1: u_1_b, u_2: u_2_b })) ######## 3D Wave Equation Example ########
def padeDiretoPrecisaoFinita(objeto, grauDoNumerador, grauDoDenominador, prec): # Fixar precisão de 'prec' algarismos significativos mp.dps = prec # Matriz dos coeficientes do sistema Ab = a A = matrizDosCoeficientes(objeto, grauDoNumerador, grauDoDenominador, prec) # erro if (A is None): return ("A = None") if (type(A) is str): return (A) # Se a matriz é nula if (A == 0): return ("A matriz dos coeficientes não é invertível. ") # Se a matriz A é invertível if (A.det() != 0): ##-- Construção do denominador --## # Cálculo dos coeficientes do denominador do aproximante de Padé B = sp.transpose( matrizDosTermosIndependentes(objeto, grauDoNumerador, grauDoDenominador, prec)) Bn = A.LUsolve(B) # Potências de x do denominador Dx = sp.Matrix(np.zeros((grauDoDenominador + 1, 1))) for linha in range(0, grauDoDenominador + 1): Dx[linha] = x**(linha) # Vetor para os coeficientes do denominador bn = sp.Matrix(np.zeros((1, grauDoDenominador + 1))) # Definir b_0 = 1 para a função racional em x = 0 tomar o valor N(0) = c_0 bn[0] = 1 # Matriz transposta dos coeficientes do denominador for coluna in range(1, grauDoDenominador + 1): bn[coluna] = Bn[-coluna] # Denominador do aproximante de Padé Denominador = sp.Function('Denominador') Denominador = bn * Dx ##-- Construção do numerador --## # Vetor para os coeficientes do numerador cn = sp.Matrix(np.zeros((1, grauDoNumerador + 1))) # Potências do numerador Nx = sp.Matrix(np.zeros((grauDoNumerador + 1, 1))) for linha in range(0, grauDoNumerador + 1): Nx[linha] = x**(linha) # Se o grau do numerador é menor do que o grau do denominador if (grauDoNumerador < grauDoDenominador): coluna = 1 while (coluna <= grauDoNumerador + 1): An = sp.Matrix( coeficientesParaCalcularCoeficentesDoNumerador( objeto, grauDoNumerador, grauDoDenominador, prec)[-coluna:]) Bn = sp.Matrix(bn[0:coluna]) cn[coluna - 1] = sp.Transpose(An) * Bn coluna += 1 # Numerador do aproximante de Padé Numerador = sp.Function('Numerador') Numerador = cn * Nx # Função racional R = sp.Function('R') R = Numerador[0] / Denominador[0] # Aproximante de Padé Pade = sp.Function('Pade') Pade = R return (Pade) # Se o grau do mumerador é maior do que o grau do denominador else: # Cálculo dos coeficientes c_n até n = grau do denominador coluna = 1 while (coluna <= grauDoDenominador + 1): An = sp.Matrix( coeficientesParaCalcularCoeficentesDoNumerador( objeto, grauDoNumerador, grauDoDenominador, prec)[-coluna:]) Bn = sp.Matrix(bn[0:coluna]) cn[coluna - 1] = sp.Transpose(An) * Bn coluna += 1 # Cálculo dos coeficiente c_n para n > grau do denominador j = -1 while (coluna <= grauDoNumerador + 1): An = sp.Matrix( coeficientesParaCalcularCoeficentesDoNumerador( objeto, grauDoNumerador, grauDoDenominador, prec)[-coluna:j]) Bn = sp.Matrix(bn[0:]) cn[coluna - 1] = sp.Transpose(An) * Bn coluna += 1 j -= 1 # Numerador do aproximante de Padé Numerador = sp.Function('Numerador') Numerador = cn * Nx # Função racional R = sp.Function('R') R = Numerador[0] / Denominador[0] # Aproximante de Padé Pade = sp.Function('Pade') Pade = R return (Pade) # Se a matriz não é invertível else: return ("A matriz dos coeficientes não é invertível. ") return
def create_Equations_of_Motion(self): # Create symbols g, m, R, theta1, theta2, theta3 = sym.symbols('g m R theta1 theta2 theta3') # Create the functions of time theta1 = sym.Function('theta1')(t) theta2 = sym.Function('theta2')(t) theta3 = sym.Function('theta3')(t) theta1_dot = theta1.diff(t) theta1_dot_dot = theta1.diff(t, t) theta2_dot = theta2.diff(t) theta2_dot_dot = theta2.diff(t,t) theta3_dot = theta3.diff(t) theta3_dot_dot = theta3.diff(t,t) # First, write out the position of the two masses # We will differentiate these to get the mass's velocities x1 = R * sym.sin(theta1) y1 = -1 * (R * sym.cos(theta1) ) x2 = x1 + (R * sym.sin(theta1 + theta2) ) y2 = (y1 - R * sym.cos(theta1 + theta2) ) x3 = x2 + (R * sym.sin(theta1 + theta2 + theta3) ) y3 = y2 - (R * sym.cos(theta1 + theta2 + theta3) ) x1_dt = x1.diff(t) y1_dt = y1.diff(t) x2_dt = x2.diff(t) y2_dt = y2.diff(t) x3_dt = x3.diff(t) y3_dt = y3.diff(t) # Kinetic Energy of Mass 1 KE1 = (0.5) * (m) * ( (x1_dt**2) + (y1_dt**2) ) # Potential Energy of Mass 1 # Note how we defined the height V1 = m * g * y1 # Kinetic Energy of Mass2 KE2 = (0.5) * (m) * ( (x2_dt**2) + (y2_dt**2) ) # Potential Energy of Mass 2 V2 = m * g * y2 # Kinetic Energy of Mass3 KE3 = (0.5) * (m) * ( (x3_dt**2) + (y3_dt**2) ) # Potential Energy of Mass 3 V3 = m * g * y3 Lagrangian = KE1 + KE2 + KE3 - V1 - V2 - V3 # Compute the Euler-Lagrange Equations EL1 = (KE1 + KE2 + KE3 - V1 - V2 - V3).diff(theta1_dot, t) - ( (KE1 + KE2 + KE3 - V1 - V2 - V3).diff(theta1) ) EL2 = (KE1 + KE2 + KE3 - V1 - V2 - V3).diff(theta2_dot, t) - ( (KE1 + KE2 + KE3 - V1 - V2 - V3).diff(theta2) ) EL3 = (KE1 + KE2 + KE3 - V1 - V2 - V3).diff(theta3_dot, t) - ( (KE1 + KE2 + KE3 - V1 - V2 - V3).diff(theta3) ) # Call sym.simplify EL1 = sym.simplify(EL1) EL2 = sym.simplify(EL2) EL3 = sym.simplify(EL3) EL1 = sym.Eq( EL1, 0.0 ) EL2 = sym.Eq( EL2, 0.0 ) EL3 = sym.Eq( EL3, 0.0 ) # Substitute dummy values a, b, c, d, e, f = sym.symbols('a b c d e f') EL1 = EL1.subs( { theta1.diff(t): a, theta1.diff(t,t): b, theta2.diff(t): c, theta2.diff(t,t): d, theta3.diff(t): e, theta3.diff(t,t): f } ) EL2 = EL2.subs( { theta1.diff(t): a, theta1.diff(t,t): b, theta2.diff(t): c, theta2.diff(t,t): d, theta3.diff(t): e, theta3.diff(t,t): f } ) EL3 = EL3.subs( { theta1.diff(t): a, theta1.diff(t,t): b, theta2.diff(t): c, theta2.diff(t,t): d, theta3.diff(t): e, theta3.diff(t,t): f } ) matrix_eq = sym.Matrix( [EL1, EL2, EL3] ) # Solve the matrix for theta1_dot_dot and theta2_dot_dot desiredVars = sym.Matrix( [b, d, f] ) matrix_sol = sym.solve( matrix_eq, desiredVars ) subs1 = matrix_sol[b].subs( {g: 9.81, R: 1, m: 1} ) subs2 = matrix_sol[d].subs( {g: 9.81, R: 1, m: 1} ) subs3 = matrix_sol[f].subs( {g: 9.81, R: 1, m: 1} ) # Keep the lambdified expressions in the class structure to use later self.computeTheta1_dt_dt = sym.lambdify( [theta1, a, theta2, c, theta3, e], subs1) self.computeTheta2_dt_dt = sym.lambdify( [theta1, a, theta2, c, theta3, e], subs2) self.computeTheta3_dt_dt = sym.lambdify( [theta1, a, theta2, c, theta3, e], subs3)
def fixed_points_analysis(): """ Exercise 3a - Compute and analyse fixed points """ g, L, d, time = sp.symbols("g, L, d, t") params = PendulumParameters(g=g, L=L, d=d, sin=sp.sin) theta = sp.Function('theta')(time) dt_sym = theta.diff(time) d2t_sym = theta.diff(time, 2) # System sys_matrix = sp.Matrix(pendulum_system([theta, dt_sym], parameters=params)) sys = sp.Equality( sp.Matrix(np.array([[dt_sym], [d2t_sym]])), sys_matrix ) pylog.info(u"Pendulum system:\n{}".format(sp.pretty(sys))) # Solve when dtheta = 0 and d2theta=0 dt = 0 d2t = 0 t_sol = sp.solveset( sp.Equality(d2t, pendulum_equation(theta, dt, parameters=params)), theta # Theta, the variable to be solved ) sys_fixed = sp.Equality( sp.Matrix(np.array([[0], [0]])), sys_matrix ) pylog.info(u"Solution for fixed points:\n{}\n{}\n{}\n{}".format( sp.pretty(sys_fixed), sp.pretty(sp.Equality(theta, t_sol)), sp.pretty(sp.Equality(dt_sym, dt)), sp.pretty(sp.Equality(d2t_sym, d2t)) )) # Alternative way of solving sol = sp.solve(sys_fixed, [theta, dt_sym]) pylog.info(u"Solution using an alternative way of solving:\n{}".format( sp.pretty(sol) )) # Jacobian, eigenvalues and eigenvectors jac = sys_matrix.jacobian( sp.Matrix([theta, dt_sym]) ) eigenvals = jac.eigenvals() eigenvects = jac.eigenvects() pylog.info(u"Jacobian:\n{}\nEigenvalues:\n{}\nEigenvectors:\n{}".format( sp.pretty(jac), sp.pretty(eigenvals), sp.pretty(eigenvects) )) # Stability analysis for i, s in enumerate(sol): pylog.info(u"Case {}:\n{}".format( i+1, sp.pretty(sp.Equality(sp.Matrix([theta, dt_sym]), sp.Matrix(s))) )) res = [None for _ in eigenvals.keys()] for j, e in enumerate(eigenvals.keys()): res[j] = e.subs({ theta: s[0], dt_sym: s[1], g: 9.81, L: 1, d: 0.1 }) pylog.info(u"{}\n{}".format( sp.pretty( sp.Equality( e, res[j] ) ), "{} {}".format( sp.re(res[j]), "> 0" if sp.re(res[j]) > 0 else "< 0" ) )) fixed_point_type = None if all([sp.re(r) < 0 for r in res]): fixed_point_type = " stable point" elif all([sp.re(r) > 0 for r in res]): fixed_point_type = "n unstable point" else: fixed_point_type = " saddle point" pylog.info("Fixed point is a{}".format(fixed_point_type))