def add_dissipations(self, w, z): """ Add dissipative components with variable :math:`\\mathbf{w}` and \ dissipative function :math:`\\mathrm{z}(\\mathbf{w})`. * Variable :math:`\\mathbf{w}` is appended to the current list of \ variables symbols :code:`core.w`, * Expression :math:`\\mathrm{z}` is appended to the current list of \ dissipative functions :code:`core.z`. Parameters ---------- w: one or several pyphs.symbols Variable symbols. Can be a single symbol or a list of symbols. z: one or several sympy.Expr Must be a valid dissipative function with respect to the variable \ :math:`\\mathbf{w}` with :math:`\\nabla\\mahtrm z(\\mathbf{w}) \succeq 0`. """ try: w = _assert_vec(w) z = _assert_vec(z) assert len(w) == len(z), 'w and z should have same dimension.' except: _assert_expr(w) _assert_expr(w) w = (w, ) z = (z, ) self.w += list(w) self.z += list(map(simplify, list(z)))
def add_storages(self, x, H): """ Add storage components with state :math:`\\mathbf{x}` and energy \ :math:`\\mathrm{H}(\\mathbf{x}) \geq 0`. * State :math:`\\mathbf{x}` is appended to the current list of \ states symbols :code:`core.x`, * Expression :math:`\\mathrm{H}` is added to the current expression \ of the Hamiltonian :code:`core.H`. Parameters ---------- x: one or several pyphs.symbols State symbols. Can be a single symbol or a list of symbols. H: sympy.Expr Must be a valid storage function with respect to the state \ :math:`\\mathbf{x}` with :math:`\\nabla^2\\mahtrm H(\\mathbf{x}) \succeq 0`. """ try: hasattr(x, 'index') x = _assert_vec(x) except: _assert_expr(x) x = (x, ) self.x += list(x) self.H += H self.H.simplify()
def discrete_gradient(H, x, dx, numtol=EPS): """ Symbolic computation here. Return the discrete gradient of scalar function\ H between x and x+dx, with H separable with respect to x: H = sum_i[H_i(x_i)]. Parameters ----------- H : sympy.expression Scalar function of x. x : list or sympy.Matrix 1 dimensional array of sympy symbols. dx : list or sympy.Matrix 1 dimensional array of sympy symbols. Output ------- gradd : list discrete gradient of H with 'gradd[i] = H.diff(x) if norm(dx[i]) < numtol else \ (H(x+dx[i])-H(x))/dx[i]' """ x = _assert_vec(x) dx = _assert_vec(dx) _assert_expr(H) nx = len(x) assert len(dx) == nx, \ 'dim(dx)={0!s} is not equal to dim(x)={1!s}'.format(len(dx), nx) dxHd = [] for i in range(nx): Hpost = H.subs(x[i], x[i] + dx[i]) dxh = simplify((Hpost - H) / dx[i]) dxh0 = simplify(H.diff(x[i]).doit()) dxhi = sympy.Piecewise((dxh, dx[i] < -numtol), (dxh0, dx[i] < numtol), (dxh, True)) dxHd.append(dxhi) return simplify(dxHd)
def gradient_theta(H, x, dx, theta=0.): """ Symbolic computation here. Return the evaluation of the gradient of scalar\ function H at x+theta*dx. Parameters ----------- H : sympy.expression Scalar function of x. x : list or sympy.Matrix 1 dimensional array of sympy symbols. dx : list or sympy.Matrix 1 dimensional array of sympy symbols. Output ------- gradd : list discrete gradient of H with 'gradd[i] = [H.diff(x).subs(x, x+theta*dx)]_i' """ x = _assert_vec(x) dx = _assert_vec(dx) _assert_expr(H) nx = len(x) assert len(dx) == nx, \ 'dim(dx)={0!s} is not equal to dim(x)={1!s}'.format(len(dx), nx) dxHd = gradient(H, x) subs = {} for i, (xi, dxi) in enumerate(zip(x, dx)): subs[xi] = xi + theta * dxi for i, dxh in enumerate(dxHd): dxHd[i] = dxh.subs(subs) return simplify(dxHd)
def add_ports(self, u, y): """ Add one or several ports with input u and output y. Parameters ---------- u : str, symbol, or list of y : str, symbol, or list of """ if hasattr(u, '__len__'): u = _assert_vec(u) y = _assert_vec(y) assert len(u) == len(y), 'u and y should have same dimension.' else: _assert_expr(u) _assert_expr(y) u = (u, ) y = (y, ) self.u += list(u) self.y += list(y)
def add_dissipations(self, w, z): """ Add a dissipative component with dissipation variable w and \ dissipation function z. Parameters ---------- w : str, symbol, or list of z : sympy.Expr or list of """ try: w = _assert_vec(w) z = _assert_vec(z) assert len(w) == len(z), 'w and z should have same dimension.' except: _assert_expr(w) _assert_expr(w) w = (w, ) z = (z, ) self.w += list(w) self.z += map(simplify, list(z))
def jacobian(func, vars_, dosimplify=True): """ Symbolic computation here. Return the jacobian matrix of vector function f w.r.t. vector variable x. Parameters ----------- func : list of sympy.Expr Vector function. vars_ : list or sympy.Matrix List of sympy symbols for variables dosimplify : bool Apply simplification Output ------- Jac : sympy.Matrix Jacobian of f with Jac[i, j] = f[i].diff(x[j]) """ vars_ = _assert_vec(vars_) func = _assert_vec(func) nv, nf = len(vars_), len(func) Jac = sympy.zeros(nf, nv) for i in range(nf): for j in range(nv): Jac[i, j] = func[i].diff(vars_[j]).doit() if dosimplify: Jac = simplify(Jac) return Jac
def add_parameters(self, p): """ Add a continuously varying parameter. Usage ----- core.add_parameters(p) Parameter ---------- p: sympy.Symbol or list of sympy.Symbol Single symbol or list of symbol associated with continuously \ varying parameter(s). """ try: hasattr(p, '__len__') p = _assert_vec(p) except: _assert_expr(p) p = (p, ) self.p += list(p)
def add_storages(self, x, H): """ Add a storage component with state x and energy H. * State x is append to the current list of states symbols, * Expression H is added to the current expression of Hamiltonian. Parameters ---------- x : str, symbol, or list of H : sympy.Expr """ try: hasattr(x, 'index') x = _assert_vec(x) except: _assert_expr(x) x = (x, ) self.x += list(x) self.H += H self.H.simplify()
def gradient(scalar_func, vars_, dosimplify=True): """ Symbolic computation here. Return the gradient of scalar function H w.r.t. vector variable x. Parameters ----------- scalar_func : sympy.Expr Scalar function. vars_ : list or sympy.Matrix array of sympy symbols for variables dosimplify : bool Apply simplification Output ------- grad : list gradient of H with grad[i] = H.diff(x[i]) """ vars_ = _assert_vec(vars_) _assert_expr(scalar_func) nvars = len(vars_) grad = [0, ]*nvars for i in range(nvars): grad[i] = scalar_func.diff(vars_[i]).doit() if dosimplify: grad = simplify(grad) return grad