def setup(self): self.prefix = 'boogly_bee' sys = multi_mass_spring_damper(6, True, True) self.matrices = (sys.eom_method.mass_matrix, sys.eom_method.forcing) # NOTE : ordered is used here because this order is different in # different versions of SymPy. self.arguments = (list(sm.ordered(sys.constants_symbols)), sys.coordinates, sys.speeds, list(sm.ordered(sys.specifieds_symbols))) self.generator = CMatrixGenerator(self.arguments, self.matrices)
def fibonacci_search(f, X, d, lower, upper, r): v = list(ordered(f.free_symbols)) N = 0 while fibonacci_num(N) < ((1 + 2 * 0.05) * (upper - lower) / r): N += 1 N -= 1 x1 = .0 x2 = .0 for i in range(N, 1, -1): L = upper - lower t1 = fibonacci_num(i - 2) t2 = fibonacci_num(i) x1 = lower + ((t1 / t2) * L) x2 = upper - (t1 / t2 * L) param2 = X - np.dot(x2, d) param2 = param2.tolist() param1 = X - np.dot(x1, d) param1 = param1.tolist() f1 = f.subs(list(zip(v, param1))) f2 = f.subs(list(zip(v, param2))) + (0.05 if i == 2 else 0.0) if f1 > f2: lower = x1 else: upper = x2 return x1
def fibonacci_searcher(f, X, d, lower, upper, epslon): v = list(ordered(f.free_symbols)) N = 0 while fibonacci_num(N) < ((1 + 2 * 0.05) * (upper - lower) / .23): N += 1 N -= 1 x1 = .0 x2 = .0 for i in range(N): L = upper - lower t1 = fibonacci_num(N + 2 - i) t2 = fibonacci_num(N + 3 - i) if i != N: roh = 1 - (t1 / t2) else: roh = 0.5 - epslon x1 = lower + roh * L x2 = lower + (1 - roh) * L param2 = X - np.dot(x2, d) param2 = param2.tolist() param1 = X - np.dot(x1, d) param1 = param1.tolist() f1 = f.subs(list(zip(v, param1))) f2 = f.subs(list(zip(v, param2))) + (0.05 if i == 2 else 0.0) if f1 > f2: lower = x1 else: upper = x2 return x1
def get_hessian(func_str, all_vals, eval_func_map=FUNC_MAP, math_func_map=MATH_FUNC_MAP): """ Returns the hessian matrix of the input function over the input variables :param func_str: A string of input math function :param all_vals: A list of real scalar values :param eval_func_map: A mapping of math expression to python's math function :param math_func_map: A mapping of math expression to python's math function :return: """ # Assume func is a valid expression D = len(all_vals) assert D > 0, "There should be at least 1 variable!" H = np.zeros((D, D)) if D == 1: H[0][0] = get_ord2_der(func_str, all_vals, 0, eval_func_map) else: var_map = {"x%d" % i: val for i, val in enumerate(all_vals)} var_map.update(math_func_map) f = sympify(func_str) vs = f.free_symbols hess = hessian(f, list(ordered(vs))) # print(hess) for i in range(D): for j in range(D): didj_func = hess[i * D + j] H[i][j] = eval(str(didj_func), var_map) return H
def _preprocess(self, args, expr): """Preprocess args, expr to replace arguments that do not map to valid Python identifiers. Returns string form of args, and updated expr. """ from sympy import Dummy, Function, flatten, Derivative, ordered, Basic from sympy.matrices import DeferredVector # Args of type Dummy can cause name collisions with args # of type Symbol. Force dummify of everything in this # situation. dummify = self._dummify or any( isinstance(arg, Dummy) for arg in flatten(args)) argstrs = [None]*len(args) for arg, i in reversed(list(ordered(zip(args, range(len(args)))))): if iterable(arg): s, expr = self._preprocess(arg, expr) elif isinstance(arg, DeferredVector): s = str(arg) elif isinstance(arg, Basic) and arg.is_symbol: s = self._argrepr(arg) if dummify or not self._is_safe_ident(s): dummy = Dummy() s = self._argrepr(dummy) expr = self._subexpr(expr, {arg: dummy}) elif dummify or isinstance(arg, (Function, Derivative)): dummy = Dummy() s = self._argrepr(dummy) expr = self._subexpr(expr, {arg: dummy}) else: s = str(arg) argstrs[i] = s return argstrs, expr
def Gradient(f, X=None): v = list(ordered(f.free_symbols)) grd = lambda fn, vn: Matrix([fn]).jacobian(vn) if X: return list(grd(f, v).subs(list(zip(v, X)))) else: return grd(f, v)
def secant_search(g, X, d, lower=-10, upper=10, epsilon=0.00001): v = list(ordered(g.free_symbols)) max = 500 alpha_curr = 0 alpha = epsilon dphi_zero = np.dot(np.array(list(g.subs(list(zip(v, X)))), dtype=np.float), d) dphi_curr = dphi_zero i = 0 while abs(dphi_curr) > epsilon * abs(dphi_zero): alpha_old = alpha_curr alpha_curr = alpha dphi_old = dphi_curr dphi_curr = np.dot( np.array(list(g.subs(list(zip(v, X + (alpha_curr * d))))), dtype=np.float), d) alpha = (dphi_curr * alpha_old - dphi_old * alpha_curr) / (dphi_curr - dphi_old) i += 1 if i % 2 == 0: print("i={}, alpha_curr={}, alpha_old={}, alpha={}".format( i, alpha_curr, alpha_old, alpha)) if (i >= max) or (abs(dphi_curr) > epsilon * abs(dphi_zero)): #print('alpha: ', alpha) return alpha
def __init__( self, clauses, variables, var_settings, symbols=None, heuristic="vsids", clause_learning="none", INTERVAL=500, ): self.var_settings = var_settings self.heuristic = heuristic self.is_unsatisfied = False self._unit_prop_queue = [] self.update_functions = [] self.INTERVAL = INTERVAL if symbols is None: self.symbols = list(ordered(variables)) else: self.symbols = symbols self._initialize_variables(variables) self._initialize_clauses(clauses) if "vsids" == heuristic: self._vsids_init() self.heur_calculate = self._vsids_calculate self.heur_lit_assigned = self._vsids_lit_assigned self.heur_lit_unset = self._vsids_lit_unset self.heur_clause_added = self._vsids_clause_added # Note: Uncomment this if/when clause learning is enabled # self.update_functions.append(self._vsids_decay) else: raise NotImplementedError if "simple" == clause_learning: self.add_learned_clause = self._simple_add_learned_clause self.compute_conflict = self.simple_compute_conflict self.update_functions.append(self.simple_clean_clauses) elif "none" == clause_learning: self.add_learned_clause = lambda x: None self.compute_conflict = lambda: None else: raise NotImplementedError # Create the base level self.levels = [Level(0)] self._current_level.varsettings = var_settings # Keep stats self.num_decisions = 0 self.num_learned_clauses = 0 self.original_num_clauses = len(self.clauses)
def __init__( self, clauses, variables, var_settings, symbols=None, heuristic="vsids", clause_learning="none", INTERVAL=500 ): self.var_settings = var_settings self.heuristic = heuristic self.is_unsatisfied = False self._unit_prop_queue = [] self.update_functions = [] self.INTERVAL = INTERVAL if symbols is None: self.symbols = list(ordered(variables)) else: self.symbols = symbols self._initialize_variables(variables) self._initialize_clauses(clauses) if "vsids" == heuristic: self._vsids_init() self.heur_calculate = self._vsids_calculate self.heur_lit_assigned = self._vsids_lit_assigned self.heur_lit_unset = self._vsids_lit_unset self.heur_clause_added = self._vsids_clause_added # Note: Uncomment this if/when clause learning is enabled # self.update_functions.append(self._vsids_decay) else: raise NotImplementedError if "simple" == clause_learning: self.add_learned_clause = self._simple_add_learned_clause self.compute_conflict = self.simple_compute_conflict self.update_functions.append(self.simple_clean_clauses) elif "none" == clause_learning: self.add_learned_clause = lambda x: None self.compute_conflict = lambda: None else: raise NotImplementedError # Create the base level self.levels = [Level(0)] self._current_level.varsettings = var_settings # Keep stats self.num_decisions = 0 self.num_learned_clauses = 0 self.original_num_clauses = len(self.clauses)
def get_variables(objective_func=0, lmis=None): """Extract free variables from objective_func and lmis. """ if lmis is None: lmis = [] variables = sympify(objective_func).free_symbols for lmi in lmis: if lmi.is_Matrix: lm = lmi else: lm = lmi.canonical().gts for expr in lm: variables |= expr.free_symbols return list(ordered(variables))
def secant_search(g, X, d, lower=-10, upper=10, epsilon=0.00001): v = list(ordered(g.free_symbols)) max = 500 alpha_curr = 0 alpha = epsilon dphi_zero = np.dot(np.array(list(g.subs(list(zip(v, X)))), dtype=np.float), d) dphi_curr = dphi_zero i = 0 while abs(dphi_curr) > epsilon * abs(dphi_zero): alpha_old = alpha_curr alpha_curr = alpha dphi_old = dphi_curr dphi_curr = np.dot( np.array(list(g.subs(list(zip(v, X + (alpha_curr * d))))), dtype=np.float), d) alpha = (dphi_curr * alpha_old - dphi_old * alpha_curr) / (dphi_curr - dphi_old) i += 1 if i % 2 == 0: print("i={}, alpha_curr={}, alpha_old={}, alpha={}".format( i, alpha_curr, alpha_old, alpha)) if (i >= max) or (abs(dphi_curr) > epsilon * abs(dphi_zero)): return alpha def bfgs(self, f, x0, d0, g0, Q0, epslon, i, alpha): ''' Broyden-Fletcher-Goldfarb-Shanno ..fun as callable object; must be a function of x0 and return a single number ..x0 as a numeric array; point from which to start ''' g = Gradient(f, x0) if sum(abs(d0)) < epslon or i is not 0: Q = [ self.params['hessian']['initial'] if self.params['hessian']['initial'] else np.identity(len(x0)) ][0] else: q = (g - g0)[np.newaxis].T p = (alpha * d0)[np.newaxis].T Q = Q0 + (1.0 + q.T.dot(Q0).dot(q) / (q.T.dot(p))) * (p.dot(p.T)) / (p.T.dot(q)) - (p.dot( q.T).dot(Q0) + Q0.dot(q).dot(p.T)) / (q.T.dot(p)) d = -Q.dot(g) return d, g, Q
def eval(cls, *args): def normalize_concat(inputs): all_arguments_stored = set() for input in inputs: if isinstance(input, ConcatenationFunction): all_arguments_stored = all_arguments_stored.union( normalize_concat(input._args)) else: all_arguments_stored.add(input) return all_arguments_stored all_arguments = normalize_concat(args) sorted_arguments = list(sympy.ordered(all_arguments)) if len(sorted_arguments) == 1: return sorted_arguments[0] if sorted_arguments != list(args): return cls(*sorted_arguments)
def get_covariance_matrix(force_matrix, equilibrium_point, noise, noise_matrix=None, warning_threshold=1e-5): """ Input: force_matrix: sympy expression, with variables in ALPHABETICAL ORDER!!! noise: standard deviation of the noise, assumes isotropical noise """ dims = len(equilibrium_point) #dimensions of the system alphabet = list(sp.ordered(force_matrix.free_symbols)) assert dims == len( alphabet ), "Dimensions and number of symbols not equal" #later: upgrade by auto completing dictionnary if variable muette subs_dict = dict(zip(alphabet, equilibrium_point)) J = force_matrix.jacobian(sp.Matrix(alphabet)) A = J.evalf(subs=subs_dict) A = np.asarray(A).astype(np.float) if noise_matrix is None: Q = noise**2 * np.identity(dims) else: Q = noise**2 * np.dot(noise_matrix, noise_matrix.T) C = scipy.linalg.solve_lyapunov(A, -Q) residual = np.dot(A, C) + np.dot(C, A.T) + Q if np.linalg.norm(residual) > warning_threshold: print("Warning! Large residual") print(residual) inv_C = np.linalg.inv(C) def quad_form(vector): return np.linalg.multi_dot(((vector - equilibrium_point).T, inv_C, vector - equilibrium_point)) return C, quad_form
def newton(f, X, epsilon=1e-5, repeat=int(1e5)): xk = np.array(X) grad = Gradient(f) hess = Hessian(f) v = list(ordered(f.free_symbols)) for i in range(repeat): g = np.array(list(grad.subs(list(zip(v, xk.tolist())))), dtype=np.float) h = np.array(list(hess.subs(list(zip(v, xk.tolist())))), dtype=np.float).reshape((len(X), len(X))) inverted_h = np.linalg.inv(h) direction = -np.dot(inverted_h, g) length_of_gradient = np.linalg.norm(g, 2) step_length = fibonacci_searcher(f, xk, -direction, -10, 10, 0.0001) if abs(step_length) < epsilon or length_of_gradient < epsilon: break xk = xk + direction * step_length return xk.tolist(), f.subs(list(zip(v, xk.tolist())))
def test_OctaveMatrixGenerator(): expected_m_file = """\ function [output_1] = eval_mats(input_1, input_2, input_3) % function [output_1] = eval_mats(input_1, input_2, input_3) % % input_1 : [x0(t), x1(t), x2(t)] % input_2 : [v0(t), v1(t), v2(t)] % input_3 : [c0, c1, c2, k0, k1, k2, m0, m1, m2] pydy_0 = input_2(1); pydy_1 = input_2(2); pydy_2 = input_2(3); pydy_3 = input_3(8) + input_3(9); pydy_4 = 1./(input_3(7) + pydy_3); pydy_5 = -input_3(1).*pydy_0 - input_3(4).*input_1(1); pydy_6 = input_3(9).*pydy_4; pydy_7 = input_3(9) - pydy_3.*pydy_6; pydy_8 = 1./(-pydy_3.^2.*pydy_4 + pydy_3); pydy_9 = -input_3(2).*pydy_1 - input_3(5).*input_1(2) - ... pydy_3.*pydy_4.*pydy_5; pydy_10 = (-input_3(3).*pydy_2 - input_3(6).*input_1(3) - ... pydy_5.*pydy_6 - pydy_7.*pydy_8.*pydy_9)./(-input_3(9).^2.*pydy_4 + ... input_3(9) - pydy_7.^2.*pydy_8); pydy_11 = pydy_8.*(-pydy_10.*pydy_7 + pydy_9); output_1 = [pydy_0; pydy_1; pydy_2; pydy_4.*(-input_3(9).*pydy_10 - ... pydy_11.*pydy_3 + pydy_5); pydy_11; pydy_10]; end """ sys = multi_mass_spring_damper(3) q = sys.coordinates u = sys.speeds p = list(ordered(sys.constants_symbols)) sym_rhs = sys.eom_method.rhs() g = OctaveMatrixGenerator([q, u, p], [sym_rhs]) assert g.doprint() == expected_m_file
def _canonicalize_indices(term: Term, spec: _AGPFSpec): """Here, we canonicalize the free indices in the tensor expressions - that is replace the higher key indices with lower key ones everywhere """ # get the new term and substs new_amp, substs = _try_simpl_unresolved_deltas(term.amp) # check for overlap in the dlists and unique_indices # if any of the maps contain two indices that are supposed to be unique, # it should return zero/empty term. unique_list = spec.unique_ind # New substitutions based on the chain of delta new_substs = {} if substs: dlists = _delta_map(substs) for s1 in dlists: s1_sorted = list(ordered(s1)) j = 1 while j < len(s1_sorted): new_substs[s1_sorted[j]] = s1_sorted[0] j += 1 if not unique_list: continue for s2 in unique_list: if len(list(s1 & s2)) > 1: return [] else: continue # construct the new term new_term = term.subst(new_substs) return [Term(sums=new_term.sums, amp=new_amp, vecs=new_term.vecs)]
def conjugate_gradient(f, X, iterations, epslon, formula): v = list(ordered(f.free_symbols)) xk = X # c2 = 0.1 #print("x={}, f(x)={}".format(xk, f.subs(list(zip(v, xk))))) grad_f = Gradient(f) gk = np.array(list(grad_f.subs(list(zip(v, xk)))), dtype=np.float) dk = -gk for i in range(iterations): #alpha = golden_section_searcher(f, xk, -dk, 1, -5, 5, 0.0005) alpha = secant_search(grad_f, xk, dk) #print('alpha: ', alpha) #alpha = 0.02 xk1 = xk + alpha * dk gk1 = np.array(list(grad_f.subs(list(zip(v, xk1)))), dtype=np.float) if formula == Hestenes_Stiefel: beta_k1 = np.dot(gk1, (gk1 - gk)) / np.dot(dk, (gk1 - gk)) elif formula == Polak_Ribiere: beta_k1 = np.dot(gk1, (gk1 - gk)) / np.dot(gk, gk) elif formula == Fletcher_Reeves: beta_k1 = np.dot(gk1, gk1) / np.dot(gk, gk) #print('beta_k: ', beta_k1) else: raise ValueError("Illegal value of the argument 'formula'.") dk1 = -gk1 + (beta_k1 * dk) if np.linalg.norm(xk1 - xk) < epslon * np.linalg.norm(xk1): xk = xk1 break xk = xk1 gk = gk1 dk = dk1 #if i % 1 == 0: # print " iter={}, grad={}, alpha={}, x={}, f(x)={}".format(i, pk, alpha, xk, f(xk)) # print(" iter={}, x={}, f(x)={}".format(i, xk, f.subs(list(zip(v, xk))))) return xk, f.subs(list(zip(v, xk)))
def test_OctaveMatrixGenerator(): expected_m_file = """\ function [output_1] = eval_mats(input_1, input_2, input_3) % function [output_1] = eval_mats(input_1, input_2, input_3) % % input_1 : [x0(t), x1(t), x2(t)] % input_2 : [v0(t), v1(t), v2(t)] % input_3 : [c0, c1, c2, k0, k1, k2, m0, m1, m2] pydy_0 = input_2(1); pydy_1 = input_2(2); pydy_2 = input_2(3); pydy_3 = input_3(8) + input_3(9); pydy_4 = 1./(input_3(7) + pydy_3); pydy_5 = -input_3(1).*pydy_0 - input_3(4).*input_1(1); pydy_6 = input_3(9).*pydy_4; pydy_7 = input_3(9) - pydy_3.*pydy_6; pydy_8 = 1./(-pydy_3.^2.*pydy_4 + pydy_3); pydy_9 = -input_3(2).*pydy_1 - input_3(5).*input_1(2) - ... pydy_3.*pydy_4.*pydy_5; pydy_10 = (-input_3(3).*pydy_2 - input_3(6).*input_1(3) - ... pydy_5.*pydy_6 - pydy_7.*pydy_8.*pydy_9)./(-input_3(9).^2.*pydy_4 + ... input_3(9) - pydy_7.^2.*pydy_8); pydy_11 = pydy_8.*(-pydy_10.*pydy_7 + pydy_9); output_1 = [pydy_0; pydy_1; pydy_2; pydy_4.*(-input_3(9).*pydy_10 - ... pydy_11.*pydy_3 + pydy_5); pydy_11; pydy_10]; end """ # SymPy > 1.0 outputs different cse results. expected_m_file_new = """\ function [output_1] = eval_mats(input_1, input_2, input_3) % function [output_1] = eval_mats(input_1, input_2, input_3) % % input_1 : [x0(t), x1(t), x2(t)] % input_2 : [v0(t), v1(t), v2(t)] % input_3 : [c0, c1, c2, k0, k1, k2, m0, m1, m2] pydy_0 = input_2(1); pydy_1 = input_2(2); pydy_2 = input_2(3); pydy_3 = 1./(input_3(7) + input_3(8) + input_3(9)); pydy_4 = -input_3(1).*pydy_0; pydy_5 = -input_3(4).*input_1(1); pydy_6 = input_3(8) + input_3(9); pydy_7 = -input_3(9).*pydy_3.*pydy_6 + input_3(9); pydy_8 = 1./(input_3(8) + input_3(9) - pydy_3.*pydy_6.^2); pydy_9 = 1./(-input_3(9).^2.*pydy_3 + input_3(9) - pydy_7.^2.*pydy_8); pydy_10 = pydy_4 + pydy_5; pydy_11 = -input_3(2).*pydy_1; pydy_12 = -input_3(5).*input_1(2); pydy_13 = -pydy_10.*pydy_3.*pydy_6; pydy_14 = -input_3(3).*pydy_2 - input_3(6).*input_1(3) - ... input_3(9).*pydy_10.*pydy_3 - pydy_7.*pydy_8.*(pydy_11 + pydy_12 + ... pydy_13); pydy_15 = pydy_11 + pydy_12 + pydy_13 - pydy_14.*pydy_7.*pydy_9; output_1 = [pydy_0; pydy_1; pydy_2; ... pydy_3.*(-input_3(9).*pydy_14.*pydy_9 - pydy_15.*pydy_6.*pydy_8 + ... pydy_4 + pydy_5); pydy_15.*pydy_8; pydy_14.*pydy_9]; end """ sys = multi_mass_spring_damper(3) q = sys.coordinates u = sys.speeds p = list(ordered(sys.constants_symbols)) sym_rhs = sys.eom_method.rhs() g = OctaveMatrixGenerator([q, u, p], [sym_rhs]) if parse_version(SYMPY_VERSION) > parse_version('1.0'): assert g.doprint() == expected_m_file_new else: assert g.doprint() == expected_m_file
return True else: head, sep, tail = key.partition(daffsep) if sep and tail: return super(symboltranscript, self).__contains__(head) else: return False # Older SymPy permitted tuple(sorted([f(x),g(x)])) but that breaks on 0.7.4 # (refer to http://stackoverflow.com/questions/24093363/ for more details). if ( distutils.version.LooseVersion(sympy.__version__) < distutils.version.LooseVersion('0.7.4') ): canonical = lambda *exprs: tuple(sorted(exprs)) else: canonical = lambda *exprs: tuple(sympy.ordered(exprs)) # Establish an identical docstring regardless of the implementation canonical.__doc__ = r''' Produce a canonically ordered tuple of the provided SymPy expressions. Canonical sorting of symbols: >>> x, y = map(sympy.Symbol, 'xy') >>> canonical(x, y) (x, y) >>> canonical(y, x) (x, y) >>> canonical(x, x) (x, x)
#verbose parameters plot = 1 #plot output freq = 1 #frequency of verbose (printed every freq iterations) cmap = plt.cm.plasma #%% #diffusion matrix a = sigma_matrix * sigma_matrix.T a_inv = a**-1 #drift vector b = force_matrix #redefine variables dim = len(force_matrix) alphabet_x = list(sp.ordered(b.free_symbols)) new_alphabet_x = sp.symbols(f'x:{dim}') b = b.subs(list(zip(alphabet_x, new_alphabet_x))) alphabet_x = new_alphabet_x x = sp.Matrix(new_alphabet_x) #variable in space alphabet_p = sp.symbols(f'p:{dim}') p = sp.Matrix( alphabet_p ) #conjuguate variable of x in Hamiltonian formalism (referred as theta in Heymann, M. and Vanden-Eijnden, E. (2008)) #%% define hamiltonian, its derivatives and other quantities ham = (b.T * p + 1 / 2 * p.T * a * p) #Hamiltonian of the system (scalar) ham_p = ham.jacobian(
""" import timeit import numpy as np import sympy as sm from pydy import models from pydy.codegen.ode_function_generators import LambdifyODEFunctionGenerator sys = models.n_link_pendulum_on_cart(3, True, True) right_hand_side = sys.eom_method.rhs() constants = list(sm.ordered(sys.constants_symbols)) specifieds = list(sm.ordered(sys.specifieds_symbols)) constants_arg_types = ['array', 'dictionary'] specifieds_arg_types = ['array', 'function', 'dictionary'] p_array = np.array([1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0]) p_dct = dict(zip(constants, p_array)) p = {} p['array'] = p_array p['dictionary'] = p_dct r_array = np.array([1.0, 2.0, 3.0, 4.0])
def single_RK_substep_input_symbolic(commentblock, RHS_str, RHS_input_str, RHS_output_str, RK_lhss_list, RK_rhss_list, post_RHS_list, post_RHS_output_list, enable_SIMD=False, enable_griddata=False, gf_aliases="", post_post_RHS_string=""): return_str = commentblock + "\n" if not isinstance(RK_lhss_list, list): RK_lhss_list = [RK_lhss_list] if not isinstance(RK_rhss_list, list): RK_rhss_list = [RK_rhss_list] if not isinstance(post_RHS_list, list): post_RHS_list = [post_RHS_list] if not isinstance(post_RHS_output_list, list): post_RHS_output_list = [post_RHS_output_list] indent = "" if enable_griddata: return_str += "{\n" + indent_Ccode(gf_aliases, " ") indent = " " # Part 1: RHS evaluation: return_str += indent_Ccode(str(RHS_str).replace( "RK_INPUT_GFS", str(RHS_input_str).replace("gfsL", "gfs")).replace( "RK_OUTPUT_GFS", str(RHS_output_str).replace("gfsL", "gfs")) + "\n", indent=indent) # Part 2: RK update if enable_SIMD: return_str += "#pragma omp parallel for\n" return_str += indent + "for(int i=0;i<Nxx_plus_2NGHOSTS0*Nxx_plus_2NGHOSTS1*Nxx_plus_2NGHOSTS2*NUM_EVOL_GFS;i+=SIMD_width) {\n" else: return_str += indent + "LOOP_ALL_GFS_GPS(i) {\n" type = "REAL" if enable_SIMD: type = "REAL_SIMD_ARRAY" RK_lhss_str_list = [] for i, el in enumerate(RK_lhss_list): if enable_SIMD: RK_lhss_str_list.append(indent + "const REAL_SIMD_ARRAY __RHS_exp_" + str(i)) else: RK_lhss_str_list.append(indent + str(el).replace("gfsL", "gfs[i]")) read_list = [] for el in RK_rhss_list: for read in list(sp.ordered(el.free_symbols)): read_list.append(read) read_list_uniq = superfast_uniq(read_list) for el in read_list_uniq: if str(el) != "dt": if enable_SIMD: return_str += indent + " const " + type + " " + str( el) + " = ReadSIMD(&" + str(el).replace("gfsL", "gfs[i]") + ");\n" else: return_str += indent + " const " + type + " " + str( el) + " = " + str(el).replace("gfsL", "gfs[i]") + ";\n" if enable_SIMD: return_str += indent + " const REAL_SIMD_ARRAY DT = ConstSIMD(dt);\n" preindent = "1" if enable_griddata: preindent = "2" kernel = outputC(RK_rhss_list, RK_lhss_str_list, filename="returnstring", params="includebraces=False,preindent=" + preindent + ",outCverbose=False,enable_SIMD=" + str(enable_SIMD)) if enable_SIMD: return_str += kernel.replace("dt", "DT") for i, el in enumerate(RK_lhss_list): return_str += " WriteSIMD(&" + str(el).replace( "gfsL", "gfs[i]") + ", __RHS_exp_" + str(i) + ");\n" else: return_str += kernel return_str += indent + "}\n" # Part 3: Call post-RHS functions for post_RHS, post_RHS_output in zip(post_RHS_list, post_RHS_output_list): return_str += indent_Ccode( post_RHS.replace("RK_OUTPUT_GFS", str(post_RHS_output).replace("gfsL", "gfs"))) if enable_griddata: return_str += "}\n" for post_RHS, post_RHS_output in zip(post_RHS_list, post_RHS_output_list): return_str += indent_Ccode( post_post_RHS_string.replace( "RK_OUTPUT_GFS", str(post_RHS_output).replace("gfsL", "gfs")), "") return return_str
def eval_sum_symbolic(f, limits): from sympy.functions import harmonic, bernoulli f_orig = f (i, a, b) = limits if not f.has(i): return f*(b - a + 1) # Linearity if f.is_Mul: L, R = f.as_two_terms() if not L.has(i): sR = eval_sum_symbolic(R, (i, a, b)) if sR: return L*sR if not R.has(i): sL = eval_sum_symbolic(L, (i, a, b)) if sL: return R*sL try: f = apart(f, i) # see if it becomes an Add except PolynomialError: pass if f.is_Add: L, R = f.as_two_terms() lrsum = telescopic(L, R, (i, a, b)) if lrsum: return lrsum lsum = eval_sum_symbolic(L, (i, a, b)) rsum = eval_sum_symbolic(R, (i, a, b)) if None not in (lsum, rsum): r = lsum + rsum if not r is S.NaN: return r # Polynomial terms with Faulhaber's formula n = Wild('n') result = f.match(i**n) if result is not None: n = result[n] if n.is_Integer: if n >= 0: if (b is S.Infinity and not a is S.NegativeInfinity) or \ (a is S.NegativeInfinity and not b is S.Infinity): return S.Infinity return ((bernoulli(n + 1, b + 1) - bernoulli(n + 1, a))/(n + 1)).expand() elif a.is_Integer and a >= 1: if n == -1: return harmonic(b) - harmonic(a - 1) else: return harmonic(b, abs(n)) - harmonic(a - 1, abs(n)) if not (a.has(S.Infinity, S.NegativeInfinity) or b.has(S.Infinity, S.NegativeInfinity)): # Geometric terms c1 = Wild('c1', exclude=[i]) c2 = Wild('c2', exclude=[i]) c3 = Wild('c3', exclude=[i]) wexp = Wild('wexp') # Here we first attempt powsimp on f for easier matching with the # exponential pattern, and attempt expansion on the exponent for easier # matching with the linear pattern. e = f.powsimp().match(c1 ** wexp) if e is not None: e_exp = e.pop(wexp).expand().match(c2*i + c3) if e_exp is not None: e.update(e_exp) if e is not None: p = (c1**c3).subs(e) q = (c1**c2).subs(e) r = p*(q**a - q**(b + 1))/(1 - q) l = p*(b - a + 1) return Piecewise((l, Eq(q, S.One)), (r, True)) r = gosper_sum(f, (i, a, b)) if isinstance(r, (Mul,Add)): from sympy import ordered, Tuple non_limit = r.free_symbols - Tuple(*limits[1:]).free_symbols den = denom(together(r)) den_sym = non_limit & den.free_symbols args = [] for v in ordered(den_sym): try: s = solve(den, v) m = Eq(v, s[0]) if s else S.false if m != False: args.append((Sum(f_orig.subs(*m.args), limits).doit(), m)) break except NotImplementedError: continue args.append((r, True)) return Piecewise(*args) if not r in (None, S.NaN): return r h = eval_sum_hyper(f_orig, (i, a, b)) if h is not None: return h factored = f_orig.factor() if factored != f_orig: return eval_sum_symbolic(factored, (i, a, b))
def test_rhs_docstring(self): sys = models.n_link_pendulum_on_cart(2, False, False) right_hand_side = sys.eom_method.rhs() constants = list(sm.ordered(sys.constants_symbols)) constants_arg_types = [None, 'array', 'dictionary'] rhs_doc_template = \ """\ Returns the derivatives of the states, i.e. numerically evaluates the right hand side of the first order differential equation. x' = f(x, t,{specified_call_sig} p) Parameters ========== x : ndarray, shape(6,) The state vector is ordered as such: - q0(t) - q1(t) - q2(t) - u0(t) - u1(t) - u2(t) t : float The current time.{specifieds_explanation}{constants_explanation} Returns ======= dx : ndarray, shape(6,) The derivative of the state vector. """ constants_doc_templates = {} constants_doc_templates['dictionary'] = \ """ p : dictionary len(6) A dictionary that maps the constants symbols to their numerical values with at least these keys: - g - l0 - l1 - m0 - m1 - m2 """ constants_doc_templates['array'] = \ """ p : ndarray shape(6,) A ndarray of floats that give the numerical values of the constants in this order: - g - l0 - l1 - m0 - m1 - m2 """ constants_doc_templates[None] = \ """ p : dictionary len(6) or ndarray shape(6,) Either a dictionary that maps the constants symbols to their numerical values or an array with the constants in the following order: - g - l0 - l1 - m0 - m1 - m2 """ for p_arg_type in constants_arg_types: _rhs_doc_template = rhs_doc_template.format(**{ 'specified_call_sig': '', 'specifieds_explanation': '', 'constants_explanation': constants_doc_templates[p_arg_type] }) g = LambdifyODEFunctionGenerator(right_hand_side, sys.coordinates, sys.speeds, constants, constants_arg_type=p_arg_type) rhs = g.generate() assert (_rhs_doc_template == rhs.__doc__) sys = models.n_link_pendulum_on_cart(2, True, True) right_hand_side = sys.eom_method.rhs() constants = list(sm.ordered(sys.constants_symbols)) specifieds = list(sm.ordered(sys.specifieds_symbols)) specifieds_arg_types = [None, 'array', 'function', 'dictionary'] specifieds_doc_templates = {} specifieds_doc_templates[None] = \ """ r : dictionary; ndarray, shape(3,); function There are three options for this argument. (1) is more flexible but (2) and (3) are much more efficient. (1) A dictionary that maps the specified functions of time to floats, ndarrays, or functions that produce ndarrays. The keys can be a single specified symbolic function of time or a tuple of symbols. The total number of symbols must be equal to 3. If the value is a function it must be of the form g(x, t), where x is the current state vector ndarray and t is the current time float and it must return an ndarray of the correct shape. For example:: r = {a: 1.0, (d, b) : np.array([1.0, 2.0]), (e, f) : lambda x, t: np.array(x[0], x[1]), c: lambda x, t: np.array(x[2])} (2) A ndarray with the specified values in the correct order and of the correct shape. (3) A function that must be of the form g(x, t), where x is the current state vector and t is the current time and it must return an ndarray of the correct shape. The specified inputs are, in order: - F(t) - T1(t) - T2(t)""" specifieds_doc_templates['array'] = \ """ r : ndarray, shape(3,) A ndarray with the specified values in the correct order and of the correct shape. The specified inputs are, in order: - F(t) - T1(t) - T2(t)""" specifieds_doc_templates['dictionary'] = \ """ r : dictionary A dictionary that maps the specified functions of time to floats, ndarrays, or functions that produce ndarrays. The keys can be a single specified symbolic function of time or a tuple of symbols. The total number of symbols must be equal to 3. If the value is a function it must be of the form g(x, t), where x is the current state vector ndarray and t is the current time float and it must return an ndarray of the correct shape. For example:: r = {a: 1.0, (d, b) : np.array([1.0, 2.0]), (e, f) : lambda x, t: np.array(x[0], x[1]), c: lambda x, t: np.array(x[2])} The specified inputs are, in order: - F(t) - T1(t) - T2(t)""" specifieds_doc_templates['function'] = \ """ r : function A function that must be of the form g(x, t), where x is the current state vector and t is the current time and it must return an ndarray of shape(3,). The specified inputs are, in order: - F(t) - T1(t) - T2(t)""" for p_arg_type in constants_arg_types: for r_arg_type in specifieds_arg_types: _rhs_doc_template = rhs_doc_template.format(**{ 'specified_call_sig': ' r,', 'specifieds_explanation': specifieds_doc_templates[r_arg_type], 'constants_explanation': constants_doc_templates[p_arg_type] }) g = LambdifyODEFunctionGenerator(right_hand_side, sys.coordinates, sys.speeds, constants, specifieds=specifieds, constants_arg_type=p_arg_type, specifieds_arg_type=r_arg_type) rhs = g.generate() assert (_rhs_doc_template == rhs.__doc__)
def eval(cls, a, b): if list(sympy.ordered([a, b])) == [b, a]: return cls(b, a)
def __init__(self, statespace, all_names, xw_sym_dicts={}, ss_x_sol_dict={}, par_to_values_dict={}, eq_conditions=[], utility=[], xss_ini_dict={}, theta=3.0): self.statespace = statespace self.A_num = statespace.A_num self.C_num = statespace.C_num self.D_num = statespace.D_num self.G_num = statespace.G_num self.par_to_values_dict = par_to_values_dict self.x_names = all_names['x_names'] self.w_names = all_names['w_names'] self.param_names = all_names['param_names'] self.q = sympy.Symbol('q') self.utility = utility self.beta = sympy.Symbol('beta') self.theta = theta self.psi_x = None self.psi_w = None self.psi_q = None self.psi_x_x = None self.psi_x_w = None self.psi_x_q = None self.psi_w_w = None self.psi_w_q = None self.psi_q_q = None self.param_sym_dict = utils.make_param_sym_dict(self.param_names) if xw_sym_dicts == {}: self.xw_sym_dicts = utils.set_x_w_sym_dicts(self.x_names, self.w_names) else: self.xw_sym_dicts = xw_sym_dicts self.x_s_d, self.w_s_d = self.xw_sym_dicts self.normal_x_s_d = {st: self.x_s_d[st] for st in self.x_s_d.keys() if not ('_q' in st or '_1' in st or '_2' in st or '_0' in st or 'ss' in st or 'q' in st)} self.normal_x_s_tp1 = {st: self.normal_x_s_d[st] for st in self.normal_x_s_d.keys() if 'tp1' in st} self.normal_x_s_t = {st: self.normal_x_s_d[st] for st in self.normal_x_s_d.keys() if not('tm1' in st or 'tp1' in st)} self.normal_x_s_tm1 = {st: self.normal_x_s_d[st] for st in self.normal_x_s_d.keys() if 'tm1' in st} self.normal_w_s_d = {st: self.w_s_d[st] for st in self.w_s_d.keys() if not 'ss' in st} self.normal_w_s_tp1 = {st: self.normal_w_s_d[st] for st in self.normal_w_s_d.keys() if 'tp1' in st} self.normal_w_s_t = {st: self.normal_w_s_d[st] for st in self.normal_w_s_d.keys() if not('tm1' in st or 'tp1' in st)} self.xvar_tp1_sym = self.normal_x_s_tp1.values() self.xvar_t_sym = self.normal_x_s_t.values() self.xvar_tm1_sym = self.normal_x_s_tm1.values() self.wvar_tp1_sym = self.normal_w_s_tp1.values() self.wvar_t_sym = self.normal_w_s_t.values() self.xvar_tp1_sym = list(sympy.ordered(self.xvar_tp1_sym)) self.xvar_t_sym = list(sympy.ordered(self.xvar_t_sym)) self.xvar_tm1_sym = list(sympy.ordered(self.xvar_tm1_sym)) self.wvar_tp1_sym = list(sympy.ordered(self.wvar_tp1_sym)) self.wvar_t_sym = list(sympy.ordered(self.wvar_t_sym)) self.normal_xw_to_q = utils.make_normal_to_q_dict(self.x_names, self.w_names) self.normal_and_0_to_ss = utils.make_normal_to_steady_state( self.x_names, self.w_names) self.x_in_ss_sym_d = {st: self.x_s_d[st] for st in self.x_s_d.keys() if 'ss' in st} self.w_in_ss_zero_d = utils.make_wss_to_zero_dict(self.w_names) self.qdiffs_to_012_d = utils.make_qdiff_to_q012(self.x_names) self.eq_conditions = eq_conditions print "in init, self.eq_conditions", self.eq_conditions self.d_g_dxw_1, self.d_g_dxw_2 = self.d1d2_g_x_w_unevaluated() self.fun_d_first_numpy = None self.fun_d_second_numpy = None self.Need_compile_theano_fn_first = False self.Need_compile_theano_fn_second = False if par_to_values_dict != {}: self.eq_conditions_nopar = [ x.subs(par_to_values_dict) for x in self.eq_conditions] self.eq_conditions_nopar_ss = [x.subs(self.normal_and_0_to_ss).subs( self.w_in_ss_zero_d) for x in self.eq_conditions_nopar] self.eq_conditions_matrix = sympy.Matrix(self.eq_conditions) symbols_per_eq_nopar = [ g.atoms(sympy.Symbol) for g in self.eq_conditions_nopar] self.xw_symbols_eq_cond_nopar = list( set.union(*symbols_per_eq_nopar)) if ss_x_sol_dict == {}: self.ss_solutions_dict = utils.get_sstate_sol_dict_from_sympy_eqs( self.eq_conditions_nopar_ss, self.x_in_ss_sym_d, xini_dict=xss_ini_dict) else: self.ss_solutions_dict = ss_x_sol_dict self.xss_ini_dict = self.ss_solutions_dict normal_x_s_tp1_ss_values = [x.subs(self.normal_and_0_to_ss).subs(self.ss_solutions_dict) for x in self.normal_x_s_tp1.values()] self.normal_x_s_tp1_ss_values_d = dict( zip(self.normal_x_s_tp1.values(), normal_x_s_tp1_ss_values)) normal_x_s_t_ss_values = [x.subs(self.normal_and_0_to_ss).subs(self.ss_solutions_dict) for x in self.normal_x_s_t.values()] self.normal_x_s_t_ss_values_d = dict( zip(self.normal_x_s_t.values(), normal_x_s_t_ss_values)) normal_x_s_tm1_ss_values = [x.subs(self.normal_and_0_to_ss).subs(self.ss_solutions_dict) for x in self.normal_x_s_tm1.values()] self.normal_x_s_tm1_ss_values_d = dict( zip(self.normal_x_s_tm1.values(), normal_x_s_tm1_ss_values)) self.normal_x_s_ss_values_d = {} self.normal_x_s_ss_values_d.update(self.normal_x_s_tp1_ss_values_d) self.normal_x_s_ss_values_d.update(self.normal_x_s_t_ss_values_d) self.normal_x_s_ss_values_d.update(self.normal_x_s_tm1_ss_values_d) self.normal_w_tp1_s_zero_pairs = [ (x, 0) for x in self.normal_w_s_d.values()] self.normal_w_s_ss_values_d = dict(self.normal_w_tp1_s_zero_pairs) self.normal_xw_s_ss_values_d = {} self.normal_xw_s_ss_values_d.update(self.normal_x_s_ss_values_d) self.normal_xw_s_ss_values_d.update(self.normal_w_s_ss_values_d) # args_values_x = [x.subs(self.normal_x_s_ss_values_d) # for x in self.normal_x_s_d.values()] self.args_values_xtp1ss = [x.subs(self.normal_x_s_tp1_ss_values_d) for x in self.xvar_tp1_sym] self.args_values_xtss = [x.subs(self.normal_x_s_t_ss_values_d) for x in self.xvar_t_sym] self.args_values_xtm1ss = [x.subs(self.normal_x_s_tm1_ss_values_d) for x in self.xvar_tm1_sym] self.args_values_x = (self.args_values_xtp1ss + self.args_values_xtss + self.args_values_xtm1ss) args_values_wtss = [w.subs(self.normal_w_s_ss_values_d) for w in self.wvar_t_sym] args_values_wtp1ss = [w.subs(self.normal_w_s_ss_values_d) for w in self.wvar_tp1_sym] args_values_w = args_values_wtss + args_values_wtp1ss args_values_p = [p.subs(par_to_values_dict) for p in self.param_sym_dict.values()] self.args_values = self.args_values_x + args_values_w + args_values_p
dk = dk1 #if i % 1 == 0: # print " iter={}, grad={}, alpha={}, x={}, f(x)={}".format(i, pk, alpha, xk, f(xk)) # print(" iter={}, x={}, f(x)={}".format(i, xk, f.subs(list(zip(v, xk))))) return xk, f.subs(list(zip(v, xk))) if __name__ == '__main__': x1, x2, x3 = sp.symbols('x1 x2 x3') k, m, n = sp.symbols('k m n', integer=True) f, g, h = sp.symbols('f g h', cls=sp.Function) sp.init_printing(use_unicode=True) f = 100 * (x2 - x1**2)**2 + (1 - x1)**2 # f = (x1 - 1) ** 2 + (2 - x2 ** 2) ** 2 + 4 # * (x3 - 3)**4 v = list(ordered(f.free_symbols)) print('\nf = 100*(x2 - x1**2)**2 + (1 - x1)**2\n') hs = conjugate_gradient(f, [-2.0, 2.0], 10000, 0.00001, Hestenes_Stiefel) pr = conjugate_gradient(f, [-2.0, 2.0], 10000, 0.008, Polak_Ribiere) fr = conjugate_gradient(f, [-2.0, 2.0], 10000, 0.0001, Fletcher_Reeves) print('Hestenes Stiefel: ') print('X={} f(X)={}'.format(hs[0], hs[1])) print('') print("Polak Ribiere: ") print('X={} f(X)={}'.format(pr[0], pr[1])) print('') print("Fletcher Reeves: ") print('X={} f(X)={}'.format(fr[0], fr[1]))
def setup(self): self.sys = models.multi_mass_spring_damper() # Best keep these in order, otherwise it may change between SymPy # versions. self.constants = list(sm.ordered(self.sys.constants_symbols))
def Hessian(f, X=None): v = list(ordered(f.free_symbols)) if X: return list(hessian(f, v).subs(list(zip(v, X)))) else: return hessian(f, v)
def test_rhs_args(self): # This test takes a while to run but it checks all the combinations. # There are eight constants and four specified inputs available. sys = models.n_link_pendulum_on_cart(3, True, True) right_hand_side = sys.eom_method.rhs() constants = list(sm.ordered(sys.constants_symbols)) specifieds = list(sm.ordered(sys.specifieds_symbols)) constants_arg_types = [None, 'array', 'dictionary'] specifieds_arg_types = [None, 'array', 'function', 'dictionary'] p_array = np.array([1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0]) p_dct = dict(zip(constants, p_array)) p = {} p[None] = choice([p_array, p_dct]) p['array'] = p_array p['dictionary'] = p_dct r_array = np.array([1.0, 2.0, 3.0, 4.0]) r_dct_1 = dict(zip(specifieds, r_array)) r_dct_2 = {tuple(specifieds): lambda x, t: r_array} r_dct_3 = { specifieds[0]: lambda x, t: np.ones(1), (specifieds[3], specifieds[1]): lambda x, t: np.array([4.0, 2.0]), specifieds[2]: 3.0 * np.ones(1) } r_func = lambda x, t: np.array([1.0, 2.0, 3.0, 4.0]) r = {} r[None] = choice([r_array, r_dct_1, r_dct_2, r_dct_3, r_func]) r['array'] = r_array r['dictionary'] = choice([r_dct_1, r_dct_2, r_dct_3]) r['function'] = r_func x = np.random.random(len(sys.states)) for p_arg_type in constants_arg_types: for r_arg_type in specifieds_arg_types: g = LambdifyODEFunctionGenerator( right_hand_side, sys.coordinates, sys.speeds, constants, specifieds=specifieds, constants_arg_type=p_arg_type, specifieds_arg_type=r_arg_type) rhs = g.generate() xdot = rhs(x, 0.0, r[r_arg_type], p[p_arg_type]) try: np.testing.assert_allclose(xdot, last_xdot) except NameError: pass last_xdot = xdot # Now make sure it all works with specifieds=None sys = models.n_link_pendulum_on_cart(3, False, False) right_hand_side = sys.eom_method.rhs() constants = list(sm.ordered(sys.constants_symbols)) del last_xdot for p_arg_type in constants_arg_types: for r_arg_type in specifieds_arg_types: g = LambdifyODEFunctionGenerator( right_hand_side, sys.coordinates, sys.speeds, constants, constants_arg_type=p_arg_type, specifieds_arg_type=r_arg_type) assert g.specifieds_arg_type is None rhs = g.generate() xdot = rhs(x, 0.0, p[p_arg_type]) try: np.testing.assert_allclose(xdot, last_xdot) except NameError: pass last_xdot = xdot
def __init__(self, equations, u_x_names=[], u_y_names=[], u_z_names=[], x_names=[], w_names=[], param_names=[], block_indices={}, par_to_values_dict={}, fwd_shift_idx=[], aux_eqs=[], vars_initvalues_dict={}, u_trans_dict={}, ss_sol_dict={}): print u_x_names print u_y_names print u_z_names print x_names print w_names ModelBase.__init__(self, equations, x_names, w_names, param_names, par_to_values_dict=par_to_values_dict, vars_initvalues_dict=vars_initvalues_dict, compute_ss=False) u_x_tp1_sym_d = make_basic_sym_dic(u_x_names, 'tp1') u_x_t_sym_d = make_basic_sym_dic(u_x_names, 't') u_x_tm1_sym_d = make_basic_sym_dic(u_x_names, 'tm1') u_y_tp1_sym_d = make_basic_sym_dic(u_y_names, 'tp1') u_y_t_sym_d = make_basic_sym_dic(u_y_names, 't') u_z_tp1_sym_d = make_basic_sym_dic(u_z_names, 'tp1') u_z_t_sym_d = make_basic_sym_dic(u_z_names, 't') u_w_tp1_sym_d = make_basic_sym_dic(w_names, 'tp1') u_w_t_sym_d = make_basic_sym_dic(w_names, 't') self.u_x_tp1_sym = list(sympy.ordered(u_x_tp1_sym_d.values())) self.u_x_t_sym = list(sympy.ordered(u_x_t_sym_d.values())) self.u_x_tm1_sym = list(sympy.ordered(u_x_tm1_sym_d.values())) self.u_y_tp1_sym = list(sympy.ordered(u_y_tp1_sym_d.values())) self.u_y_t_sym = list(sympy.ordered(u_y_t_sym_d.values())) self.u_z_tp1_sym = list(sympy.ordered(u_z_tp1_sym_d.values())) self.u_z_t_sym = list(sympy.ordered(u_z_t_sym_d.values())) self.u_w_tp1_sym = list(sympy.ordered(u_w_tp1_sym_d.values())) self.u_w_t_sym = list(sympy.ordered(u_w_t_sym_d.values())) if fwd_shift_idx != []: equations = self.shift_eqns_fwd(equations, fwd_shift_idx) new_eqs = [x.subs(u_trans_dict) for x in equations] new_eqs.extend(aux_eqs) equations = new_eqs if ss_sol_dict == {}: eqns_no_param = self.make_ss_version_of_eqs(equations) self.ss_solutions_dict = get_sstate_sol_dict_from_sympy_eqs( eqns_no_param, self.x_in_ss_sym, vars_initvalues_dict=vars_initvalues_dict) self.ss_residuals = [x.subs(self.ss_solutions_dict) for x in eqns_no_param] self.block_indices = block_indices # print block_indices non_expec_idx = block_indices['non_expectational_block'] expec_idx = block_indices['expectational_block'] z_idx = block_indices['z_block'] if x_names == []: x_names = u_x_names + u_y_names + u_z_names self.u_param_sym = self.param_sym_d.values() self.u_param_sym = list(sympy.ordered(self.u_param_sym)) self.eqns = equations print "self.eqns" print self.eqns if isinstance(non_expec_idx, int): self.eqns_non_expec = [equations[non_expec_idx]] else: self.eqns_non_expec = [equations[i] for i in non_expec_idx] if isinstance(expec_idx, int): self.eqns_expec = [equations[expec_idx]] else: self.eqns_expec = [equations[i] for i in expec_idx] if isinstance(z_idx, int): self.eqns_z = [equations[z_idx]] else: self.eqns_z = [equations[i] for i in z_idx] print "\nself.eqns_non_expec" print self.eqns_non_expec print "\nself.eqns_expec" print self.eqns_expec print "\nself.eqns_z" print self.eqns_z self.x_to_devss_dict = make_devss_subs_dict(self.x_names, self.x_dates) self.eqns_expec_devss = [x.subs(self.x_to_devss_dict) for x in self.eqns_expec] self.eqns_non_expec_devss = [x.subs(self.x_to_devss_dict) for x in self.eqns_non_expec] self.eqns_z_devss = [x.subs(self.x_to_devss_dict) for x in self.eqns_z] print "\nself.eqns_non_expec_devss" print self.eqns_non_expec_devss print "\nself.eqns_expec_devss" print self.eqns_expec_devss print "\nself.eqns_z_devss" print self.eqns_z_devss self.jacobians_unev, self.jacobians_unev_ss = self.jacobians_sym_uh() self.uA_sym = self.jacobians_unev[0] self.uB_sym = self.jacobians_unev[1] self.uC_sym = self.jacobians_unev[2] self.uD_sym = self.jacobians_unev[3] self.uF_sym = self.jacobians_unev[4] self.uG_sym = self.jacobians_unev[5] self.uH_sym = self.jacobians_unev[6] self.uJ_sym = self.jacobians_unev[7] self.uK_sym = self.jacobians_unev[8] self.uL_sym = self.jacobians_unev[9] self.uM_sym = self.jacobians_unev[10] self.uN_sym = self.jacobians_unev[11] self.uA_sym_ss = self.jacobians_unev_ss[0] self.uB_sym_ss = self.jacobians_unev_ss[1] self.uC_sym_ss = self.jacobians_unev_ss[2] self.uD_sym_ss = self.jacobians_unev_ss[3] self.uF_sym_ss = self.jacobians_unev_ss[4] self.uG_sym_ss = self.jacobians_unev_ss[5] self.uH_sym_ss = self.jacobians_unev_ss[6] self.uJ_sym_ss = self.jacobians_unev_ss[7] self.uK_sym_ss = self.jacobians_unev_ss[8] self.uL_sym_ss = self.jacobians_unev_ss[9] self.uM_sym_ss = self.jacobians_unev_ss[10] self.uN_sym_ss = self.jacobians_unev_ss[11] args = self.x_in_ss_sym + self.u_param_sym self.jac_ss_funcs = sympy.lambdify(args, self.jacobians_unev_ss) x_ss_num = [x.subs(self.ss_solutions_dict) for x in self.x_in_ss_sym] par_ss_num = [x.subs(self.par_to_values_dict) for x in self.param_sym] x_par_ss_num = x_ss_num + par_ss_num self.jac_ss_num = [matrix2numpyfloat(x) for x in self.jac_ss_funcs(*x_par_ss_num)] # # print '\nself.jac_ss_num' # print self.jac_ss_num self.uA_num_ss = self.jac_ss_num[0] self.uB_num_ss = self.jac_ss_num[1] self.uC_num_ss = self.jac_ss_num[2] self.uD_num_ss = self.jac_ss_num[3] # print self.uD_sym # print self.uD_sym_ss # print self.uD_num_ss self.uF_num_ss = self.jac_ss_num[4] self.uG_num_ss = self.jac_ss_num[5] self.uH_num_ss = self.jac_ss_num[6] self.uJ_num_ss = self.jac_ss_num[7] self.uK_num_ss = self.jac_ss_num[8] self.uL_num_ss = self.jac_ss_num[9] self.uM_num_ss = self.jac_ss_num[10] self.uN_num_ss = self.jac_ss_num[11] self.u_x_ss_sym = [x.subs(self.normal_and_0_to_ss) for x in self.u_x_t_sym] self.u_y_ss_sym = [x.subs(self.normal_and_0_to_ss) for x in self.u_y_t_sym] self.u_z_ss_sym = [x.subs(self.normal_and_0_to_ss) for x in self.u_z_t_sym] self.u_x_ss_num = [x.subs(self.ss_solutions_dict) for x in self.u_x_ss_sym] self.u_y_ss_num = [x.subs(self.ss_solutions_dict) for x in self.u_y_ss_sym] self.u_z_ss_num = [x.subs(self.ss_solutions_dict) for x in self.u_z_ss_sym] # self.u_z_ss_num = [0.03, 0.03, 1] # self.u_z_ss_num = [0.03, 1] non_zero_z_idx = np.nonzero(self.u_z_ss_num) z_for_diag = np.ones_like(self.u_z_ss_num) z_for_diag[non_zero_z_idx] = self.u_z_ss_num print "foooooo\n" print self.u_z_ss_num print non_zero_z_idx print z_for_diag print "moooooo\n" self.di_u_x_ss_sym = sympy.diag(*self.u_x_ss_sym) self.di_u_y_ss_sym = sympy.diag(*self.u_y_ss_sym) self.di_u_z_ss_sym = sympy.diag(*self.u_z_ss_sym) self.di_u_x_ss_num = np.diag(self.u_x_ss_num) self.di_u_y_ss_num = np.diag(self.u_y_ss_num) self.di_u_z_ss_num = np.diag(z_for_diag) self.uA_num_ss_log = np.dot(self.uA_num_ss, self.di_u_x_ss_num) self.uB_num_ss_log = np.dot(self.uB_num_ss, self.di_u_x_ss_num) self.uC_num_ss_log = np.dot(self.uC_num_ss, self.di_u_y_ss_num) self.uD_num_ss_log = np.dot(self.uD_num_ss, self.di_u_z_ss_num) self.uF_num_ss_log = np.dot(self.uF_num_ss, self.di_u_x_ss_num) self.uG_num_ss_log = np.dot(self.uG_num_ss, self.di_u_x_ss_num) self.uH_num_ss_log = np.dot(self.uH_num_ss, self.di_u_x_ss_num) self.uJ_num_ss_log = np.dot(self.uJ_num_ss, self.di_u_y_ss_num) self.uK_num_ss_log = np.dot(self.uK_num_ss, self.di_u_y_ss_num) self.uL_num_ss_log = np.dot(self.uL_num_ss, self.di_u_z_ss_num) self.uM_num_ss_log = np.dot(self.uM_num_ss, self.di_u_z_ss_num) self.uN_num_ss_log = np.dot(self.uN_num_ss, self.di_u_z_ss_num)
def __init__(self, equations, x_names, w_names, x_dates=['tm1', 't', 'tp1'], w_dates=['t', 'tp1'], param_names=[], par_to_values_dict={}, vars_initvalues_dict={}, compute_ss=True): self.eqns = equations self.x_names = x_names self.w_names = w_names self.param_names = param_names self.par_to_values_dict = par_to_values_dict self.x_dates = x_dates self.w_dates = w_dates xwp_sym_d = make_x_w_param_sym_dicts( x_names, w_names, param_names) x_s_d, x_in_ss_sym_d, w_s_d, param_sym_d = xwp_sym_d self.x_s_d = x_s_d self.x_in_ss_sym_d = x_in_ss_sym_d self.w_s_d = w_s_d self.param_sym_d = param_sym_d self.param_sym = list(sympy.ordered(param_sym_d.values())) self.x_in_ss_sym = list(sympy.ordered(self.x_in_ss_sym_d.values())) self.normal_x_s_d = {st: self.x_s_d[st] for st in self.x_s_d.keys() if not ('_q' in st or '_1' in st or '_2' in st or '_0' in st or 'ss' in st or 'q' in st)} self.normal_x_s_tp1 = {st: self.normal_x_s_d[st] for st in self.normal_x_s_d.keys() if 'tp1' in st} self.normal_x_s_t = {st: self.normal_x_s_d[st] for st in self.normal_x_s_d.keys() if not( 'tm1' in st or 'tp1' in st)} self.normal_x_s_tm1 = {st: self.normal_x_s_d[st] for st in self.normal_x_s_d.keys() if 'tm1' in st} self.normal_w_s_d = {st: self.w_s_d[st] for st in self.w_s_d.keys() if 'ss' not in st} self.normal_w_s_tp1 = {st: self.normal_w_s_d[st] for st in self.normal_w_s_d.keys() if 'tp1' in st} self.normal_w_s_t = {st: self.normal_w_s_d[st] for st in self.normal_w_s_d.keys() if not('tm1' in st or 'tp1' in st)} self.xvar_tp1_sym = self.normal_x_s_tp1.values() self.xvar_t_sym = self.normal_x_s_t.values() self.xvar_tm1_sym = self.normal_x_s_tm1.values() self.wvar_tp1_sym = self.normal_w_s_tp1.values() self.wvar_t_sym = self.normal_w_s_t.values() self.xvar_tp1_sym = list(sympy.ordered(self.xvar_tp1_sym)) self.xvar_t_sym = list(sympy.ordered(self.xvar_t_sym)) self.xvar_tm1_sym = list(sympy.ordered(self.xvar_tm1_sym)) self.wvar_tp1_sym = list(sympy.ordered(self.wvar_tp1_sym)) self.wvar_t_sym = list(sympy.ordered(self.wvar_t_sym)) self.normal_and_0_to_ss = make_normal_to_steady_state( self.x_names, self.w_names) if compute_ss: eqns_no_param = self.make_ss_version_of_eqs(self.eqns) self.ss_solutions_dict = get_sstate_sol_dict_from_sympy_eqs( eqns_no_param, self.x_in_ss_sym, vars_initvalues_dict=vars_initvalues_dict) self.ss_residuals = [x.subs(self.ss_solutions_dict) for x in eqns_no_param]
def symbols(self): ''' Returns all sympy symbols in alphabetically order ''' return tuple(sp.ordered(self.expression.free_symbols))
def test_rhs_args(self): # This test takes a while to run but it checks all the combinations. # There are eight constants and four specified inputs available. sys = models.n_link_pendulum_on_cart(3, True, True) right_hand_side = sys.eom_method.rhs() constants = list(sm.ordered(sys.constants_symbols)) specifieds = list(sm.ordered(sys.specifieds_symbols)) constants_arg_types = [None, 'array', 'dictionary'] specifieds_arg_types = [None, 'array', 'function', 'dictionary'] p_array = np.array([1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0]) p_dct = dict(zip(constants, p_array)) p = {} p[None] = choice([p_array, p_dct]) p['array'] = p_array p['dictionary'] = p_dct r_array = np.array([1.0, 2.0, 3.0, 4.0]) r_dct_1 = dict(zip(specifieds, r_array)) r_dct_2 = {tuple(specifieds): lambda x, t: r_array} r_dct_3 = {specifieds[0]: lambda x, t: np.ones(1), (specifieds[3], specifieds[1]): lambda x, t: np.array([4.0, 2.0]), specifieds[2]: 3.0 * np.ones(1)} r_func = lambda x, t: np.array([1.0, 2.0, 3.0, 4.0]) r = {} r[None] = choice([r_array, r_dct_1, r_dct_2, r_dct_3, r_func]) r['array'] = r_array r['dictionary'] = choice([r_dct_1, r_dct_2, r_dct_3]) r['function'] = r_func x = np.random.random(len(sys.states)) for p_arg_type in constants_arg_types: for r_arg_type in specifieds_arg_types: g = LambdifyODEFunctionGenerator(right_hand_side, sys.coordinates, sys.speeds, constants, specifieds=specifieds, constants_arg_type=p_arg_type, specifieds_arg_type=r_arg_type) rhs = g.generate() xdot = rhs(x, 0.0, r[r_arg_type], p[p_arg_type]) try: np.testing.assert_allclose(xdot, last_xdot) except NameError: pass last_xdot = xdot # Now make sure it all works with specifieds=None sys = models.n_link_pendulum_on_cart(3, False, False) right_hand_side = sys.eom_method.rhs() constants = list(sm.ordered(sys.constants_symbols)) del last_xdot for p_arg_type in constants_arg_types: for r_arg_type in specifieds_arg_types: g = LambdifyODEFunctionGenerator(right_hand_side, sys.coordinates, sys.speeds, constants, constants_arg_type=p_arg_type, specifieds_arg_type=r_arg_type) assert g.specifieds_arg_type is None rhs = g.generate() xdot = rhs(x, 0.0, p[p_arg_type]) try: np.testing.assert_allclose(xdot, last_xdot) except NameError: pass last_xdot = xdot