Ejemplo n.º 1
0
    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)))
Ejemplo n.º 2
0
    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()
Ejemplo n.º 3
0
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)
Ejemplo n.º 4
0
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)
Ejemplo n.º 5
0
    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)
Ejemplo n.º 6
0
    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))
Ejemplo n.º 7
0
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
Ejemplo n.º 8
0
    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)
Ejemplo n.º 9
0
    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()
Ejemplo n.º 10
0
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