Ejemplo n.º 1
0
    def balanced(self):
        """
		Returns an equivalent balanced state-space system

		Use ab09ad method from Slicot to get balanced state-space
		see http://slicot.org/objects/software/shared/doc/AB09AD.html

		Returns
		- a dSS object
		"""
        try:
            Nr, Ar, Br, Cr, hsv = ab09ad('D',
                                         'B',
                                         'N',
                                         self.n,
                                         self.q,
                                         self.p,
                                         self.A,
                                         self.B,
                                         self.C,
                                         nr=self.n,
                                         tol=1e-18)
        except NameError:
            raise ImportError("dSS.balanced: slycot is not installed")
        if Nr == 0:
            raise ValueError(
                "dSS: balanced: Cannot compute the balanced system "
                "(the selected order nr is greater than the order of a minimal realization of the given system)"
            )
        return dSS(Ar, Br, Cr, self.D)
Ejemplo n.º 2
0
    def order_reduced(
        self,
        dim,
    ) -> "DynamicQuantizer":
        """
        Returns the quantizer with its order reduced.

        Note that the quantizer with the reduced order
        will generally have larger `E(Q)` and a larger
        `gain_wv` than those of the original quantizer. 
        You should check the performance and gain yourself.

        This function requires slycot. Please install it.

        Parameters
        ----------
        dim : int
            Order of the quantizer to be returned.
            Must be greater than `0` and less than `self.N`.

        Returns
        -------
        Q : DynamicQuantizer

        Raises
        ------
        ImportError
            if NQLib couldn't import slycot.
        """
        try:
            from slycot import ab09ad
        except ImportError as e:
            raise ImportError((
                "Reducing order of a quantizer requires slycot."
                " Please install it."
            ))
        # マルコフパラメータから特異値分解する
        Nr, Ar, Br, Cr, hsv = ab09ad(
            "D",  # means "Discrete time"
            "B",  # balanced (B) or not (N)
            "S",  # scale (S) or not (N)
            self.N,  # np.size(A,0)
            self.m,  # np.size(B,1)
            self.m,  # np.size(C,0)
            self.A, self.B, self.C,
            nr=dim,
            tol=0.0,
        )
        return DynamicQuantizer(Ar, Br, Cr, self.q)
Ejemplo n.º 3
0
def balred(sys, orders, method='truncate'):
    """
    Balanced reduced order model of sys of a given order.  
    States are eliminated based on Hankel singular value.

    Parameters
    ----------
    sys: StateSpace
        Original system to reduce
    orders: integer or array of integer
        Desired order of reduced order model (if a vector, returns a vector 
        of systems)
    method: string
        Method of removing states, either ``'truncate'`` or ``'matchdc'``.

    Returns
    -------
    rsys: StateSpace
        A reduced order model 

    Raises
    ------
    ValueError
        * if `method` is not ``'truncate'``
        * if eigenvalues of `sys.A` are not all in left half plane 
          (`sys` must be stable) 
    ImportError
        if slycot routine ab09ad is not found 

    Examples
    --------
    >>> rsys = balred(sys, order, method='truncate') 

    """

    #Check for ss system object, need a utility for this?

    #TODO: Check for continous or discrete, only continuous supported right now
        # if isCont():
        #    dico = 'C'
        # elif isDisc():
        #    dico = 'D'
        # else:
    dico = 'C'

    #Check system is stable
    D,V = np.linalg.eig(sys.A)
    # print D.shape
    # print D
    for e in D:
        if e.real >= 0:
            raise ValueError("Oops, the system is unstable!")
   
    if method=='matchdc':
        raise ValueError ("MatchDC not yet supported!")
    elif method=='truncate':
        try:
            from slycot import ab09ad
        except ImportError:
            raise ControlSlycot("can't find slycot subroutine ab09ad")
        job = 'B' # balanced (B) or not (N)
        equil = 'N'  # scale (S) or not (N) 
        n = np.size(sys.A,0)
        m = np.size(sys.B,1)
        p = np.size(sys.C,0)
        Nr, Ar, Br, Cr, hsv = ab09ad(dico,job,equil,n,m,p,sys.A,sys.B,sys.C,nr=orders,tol=0.0) 
   
        rsys = StateSpace(Ar, Br, Cr, sys.D)
    else:
        raise ValueError("Oops, method is not supported!")

    return rsys
Ejemplo n.º 4
0
def balred(sys, orders, method='truncate'):
    """
    Balanced reduced order model of sys of a given order.
    States are eliminated based on Hankel singular value.

    Parameters
    ----------
    sys: StateSpace
        Original system to reduce
    orders: integer or array of integer
        Desired order of reduced order model (if a vector, returns a vector
        of systems)
    method: string
        Method of removing states, either ``'truncate'`` or ``'matchdc'``.

    Returns
    -------
    rsys: StateSpace
        A reduced order model

    Raises
    ------
    ValueError
        * if `method` is not ``'truncate'``
        * if eigenvalues of `sys.A` are not all in left half plane
          (`sys` must be stable)
    ImportError
        if slycot routine ab09ad is not found

    Examples
    --------
    >>> rsys = balred(sys, order, method='truncate')

    """

    #Check for ss system object, need a utility for this?

    #TODO: Check for continous or discrete, only continuous supported right now
        # if isCont():
        #    dico = 'C'
        # elif isDisc():
        #    dico = 'D'
        # else:
    dico = 'C'

    #Check system is stable
    D,V = np.linalg.eig(sys.A)
    # print D.shape
    # print D
    for e in D:
        if e.real >= 0:
            raise ValueError("Oops, the system is unstable!")

    if method=='matchdc':
        raise ValueError ("MatchDC not yet supported!")
    elif method=='truncate':
        try:
            from slycot import ab09ad
        except ImportError:
            raise ControlSlycot("can't find slycot subroutine ab09ad")
        job = 'B' # balanced (B) or not (N)
        equil = 'N'  # scale (S) or not (N)
        n = np.size(sys.A,0)
        m = np.size(sys.B,1)
        p = np.size(sys.C,0)
        Nr, Ar, Br, Cr, hsv = ab09ad(dico,job,equil,n,m,p,sys.A,sys.B,sys.C,nr=orders,tol=0.0)

        rsys = StateSpace(Ar, Br, Cr, sys.D)
    else:
        raise ValueError("Oops, method is not supported!")

    return rsys
Ejemplo n.º 5
0
def balred(sys, orders, method='truncate', alpha=None):
    """
    Balanced reduced order model of sys of a given order.
    States are eliminated based on Hankel singular value.
    If sys has unstable modes, they are removed, the
    balanced realization is done on the stable part, then
    reinserted in accordance with the reference below.

    Reference: Hsu,C.S., and Hou,D., 1991,
    Reducing unstable linear control systems via real Schur transformation.
    Electronics Letters, 27, 984-986.

    Parameters
    ----------
    sys: StateSpace
        Original system to reduce
    orders: integer or array of integer
        Desired order of reduced order model (if a vector, returns a vector
        of systems)
    method: string
        Method of removing states, either ``'truncate'`` or ``'matchdc'``.
    alpha: float
        Redefines the stability boundary for eigenvalues of the system matrix A.
        By default for continuous-time systems, alpha <= 0 defines the stability
        boundary for the real part of A's eigenvalues and for discrete-time
        systems, 0 <= alpha <= 1 defines the stability boundary for the modulus
        of A's eigenvalues. See SLICOT routines AB09MD and AB09ND for more
        information.

    Returns
    -------
    rsys: StateSpace
        A reduced order model or a list of reduced order models if orders is a list

    Raises
    ------
    ValueError
        * if `method` is not ``'truncate'`` or ``'matchdc'``
    ImportError
        if slycot routine ab09ad, ab09md, or ab09nd is not found

    ValueError
        if there are more unstable modes than any value in orders

    Examples
    --------
    >>> rsys = balred(sys, orders, method='truncate')

    """
    if method != 'truncate' and method != 'matchdc':
        raise ValueError("supported methods are 'truncate' or 'matchdc'")
    elif method == 'truncate':
        try:
            from slycot import ab09md, ab09ad
        except ImportError:
            raise ControlSlycot(
                "can't find slycot subroutine ab09md or ab09ad")
    elif method == 'matchdc':
        try:
            from slycot import ab09nd
        except ImportError:
            raise ControlSlycot("can't find slycot subroutine ab09nd")

    #Check for ss system object, need a utility for this?

    #TODO: Check for continous or discrete, only continuous supported right now
    # if isCont():
    #    dico = 'C'
    # elif isDisc():
    #    dico = 'D'
    # else:
    dico = 'C'

    job = 'B'  # balanced (B) or not (N)
    equil = 'N'  # scale (S) or not (N)
    if alpha is None:
        if dico == 'C':
            alpha = 0.
        elif dico == 'D':
            alpha = 1.

    rsys = []  #empty list for reduced systems

    #check if orders is a list or a scalar
    try:
        order = iter(orders)
    except TypeError:  #if orders is a scalar
        orders = [orders]

    for i in orders:
        n = np.size(sys.A, 0)
        m = np.size(sys.B, 1)
        p = np.size(sys.C, 0)
        if method == 'truncate':
            #check system stability
            if np.any(np.linalg.eigvals(sys.A).real >= 0.0):
                #unstable branch
                Nr, Ar, Br, Cr, Ns, hsv = ab09md(dico,
                                                 job,
                                                 equil,
                                                 n,
                                                 m,
                                                 p,
                                                 sys.A,
                                                 sys.B,
                                                 sys.C,
                                                 alpha=alpha,
                                                 nr=i,
                                                 tol=0.0)
            else:
                #stable branch
                Nr, Ar, Br, Cr, hsv = ab09ad(dico,
                                             job,
                                             equil,
                                             n,
                                             m,
                                             p,
                                             sys.A,
                                             sys.B,
                                             sys.C,
                                             nr=i,
                                             tol=0.0)
            rsys.append(StateSpace(Ar, Br, Cr, sys.D))

        elif method == 'matchdc':
            Nr, Ar, Br, Cr, Dr, Ns, hsv = ab09nd(dico,
                                                 job,
                                                 equil,
                                                 n,
                                                 m,
                                                 p,
                                                 sys.A,
                                                 sys.B,
                                                 sys.C,
                                                 sys.D,
                                                 alpha=alpha,
                                                 nr=i,
                                                 tol1=0.0,
                                                 tol2=0.0)
            rsys.append(StateSpace(Ar, Br, Cr, Dr))

    #if orders was a scalar, just return the single reduced model, not a list
    if len(orders) == 1:
        return rsys[0]
    #if orders was a list/vector, return a list/vector of systems
    else:
        return rsys
Ejemplo n.º 6
0
def balred(sys, orders, method='truncate', alpha=None):
    """
    Balanced reduced order model of sys of a given order.
    States are eliminated based on Hankel singular value.
    If sys has unstable modes, they are removed, the
    balanced realization is done on the stable part, then
    reinserted in accordance with the reference below.

    Reference: Hsu,C.S., and Hou,D., 1991,
    Reducing unstable linear control systems via real Schur transformation.
    Electronics Letters, 27, 984-986.

    Parameters
    ----------
    sys: StateSpace
        Original system to reduce
    orders: integer or array of integer
        Desired order of reduced order model (if a vector, returns a vector
        of systems)
    method: string
        Method of removing states, either ``'truncate'`` or ``'matchdc'``.
    alpha: float
        Redefines the stability boundary for eigenvalues of the system matrix A.
        By default for continuous-time systems, alpha <= 0 defines the stability
        boundary for the real part of A's eigenvalues and for discrete-time
        systems, 0 <= alpha <= 1 defines the stability boundary for the modulus
        of A's eigenvalues. See SLICOT routines AB09MD and AB09ND for more
        information.

    Returns
    -------
    rsys: StateSpace
        A reduced order model or a list of reduced order models if orders is a list

    Raises
    ------
    ValueError
        * if `method` is not ``'truncate'`` or ``'matchdc'``
    ImportError
        if slycot routine ab09ad, ab09md, or ab09nd is not found

    ValueError
        if there are more unstable modes than any value in orders

    Examples
    --------
    >>> rsys = balred(sys, orders, method='truncate')

    """
    if method!='truncate' and method!='matchdc':
        raise ValueError("supported methods are 'truncate' or 'matchdc'")
    elif method=='truncate':
        try:
            from slycot import ab09md, ab09ad
        except ImportError:
            raise ControlSlycot("can't find slycot subroutine ab09md or ab09ad")
    elif method=='matchdc':
        try:
            from slycot import ab09nd
        except ImportError:
            raise ControlSlycot("can't find slycot subroutine ab09nd")

    #Check for ss system object, need a utility for this?

    #TODO: Check for continous or discrete, only continuous supported right now
        # if isCont():
        #    dico = 'C'
        # elif isDisc():
        #    dico = 'D'
        # else:
    dico = 'C'

    job = 'B' # balanced (B) or not (N)
    equil = 'N'  # scale (S) or not (N)
    if alpha is None:
        if dico == 'C':
            alpha = 0.
        elif dico == 'D':
            alpha = 1.

    rsys = [] #empty list for reduced systems

    #check if orders is a list or a scalar
    try:
        order = iter(orders)
    except TypeError: #if orders is a scalar
        orders = [orders]

    for i in orders:
        n = np.size(sys.A,0)
        m = np.size(sys.B,1)
        p = np.size(sys.C,0)
        if method == 'truncate':
            #check system stability
            if np.any(np.linalg.eigvals(sys.A).real >= 0.0):
                #unstable branch
                Nr, Ar, Br, Cr, Ns, hsv = ab09md(dico,job,equil,n,m,p,sys.A,sys.B,sys.C,alpha=alpha,nr=i,tol=0.0)
            else:
                #stable branch
                Nr, Ar, Br, Cr, hsv = ab09ad(dico,job,equil,n,m,p,sys.A,sys.B,sys.C,nr=i,tol=0.0)
            rsys.append(StateSpace(Ar, Br, Cr, sys.D))

        elif method == 'matchdc':
            Nr, Ar, Br, Cr, Dr, Ns, hsv = ab09nd(dico,job,equil,n,m,p,sys.A,sys.B,sys.C,sys.D,alpha=alpha,nr=i,tol1=0.0,tol2=0.0)
            rsys.append(StateSpace(Ar, Br, Cr, Dr))

    #if orders was a scalar, just return the single reduced model, not a list
    if len(orders) == 1:
        return rsys[0]
    #if orders was a list/vector, return a list/vector of systems
    else:
        return rsys