qpmr.quasipoly package#

Submodules#

qpmr.quasipoly.arithmetic module#

Basic arithmetic operations on quasipolynomials#

As of now:
  1. addition

  2. multiplication

Notes

  1. negative quasipolynomial can be constructed simply by -coefs

  2. subtraction = addition + negative

  3. division of two quasipolynomials is meromophic function -> not covered

qpmr.quasipoly.arithmetic.add(coefs1, delays1, coefs2, delays2, **kwargs)#

Adds two quasipolynomials without checks

Parameters:
  • coefs1 (array) – matrix definition of polynomial coefficients (each row represents polynomial coefficients corresponding to delay)

  • delays1 (array) – vector definition of associated delays (each delay corresponds to row in coefs)

  • coefs2 (array) – matrix definition of polynomial coefficients (each row represents polynomial coefficients corresponding to delay)

  • delays2 (array) – vector definition of associated delays (each delay corresponds to row in coefs)

  • **kwargs

    compress (bool): if True compresses the result (converts to minimal

    form), default True

Returns:

  • coefs (array): matrix definition of polynomial coefficients (each row

    represents polynomial coefficients corresponding to delay)

  • delays (array): vector definition of associated delays (each delay

    corresponds to row in coefs)

Return type:

tuple containing

qpmr.quasipoly.arithmetic.multiply(coefs1, delays1, coefs2, delays2, **kwargs)#

Multiply two quasipolynomials without checks

Parameters:
  • coefs1 (array) – matrix definition of polynomial coefficients (each row represents polynomial coefficients corresponding to delay)

  • delays1 (array) – vector definition of associated delays (each delay corresponds to row in coefs)

  • coefs2 (array) – matrix definition of polynomial coefficients (each row represents polynomial coefficients corresponding to delay)

  • delays2 (array) – vector definition of associated delays (each delay corresponds to row in coefs)

  • **kwargs

    compress (bool): if True compresses the result (converts to minimal

    form), default True

Returns:

  • coefs (array): matrix definition of polynomial coefficients (each row

    represents polynomial coefficients corresponding to delay)

  • delays (array): vector definition of associated delays (each delay

    corresponds to row in coefs)

Return type:

tuple containing

qpmr.quasipoly.core module#

qpmr.quasipoly.core.eval(coefs, delays, s)#

Evaluates quasipolynomial on s

Parameters:
  • coefs (array) – matrix definition of polynomial coefficients (each row represents polynomial coefficients corresponding to delay)

  • delays (array) – vector definition of associated delays (each delay corresponds to row in coefs)

  • s (array or number) – complex value (s) to evaluate quasipolynomial on

Returns:

evaluated quasipolynomial at all elements of s

Return type:

array

qpmr.quasipoly.core.compress(coefs, delays)#

Compresses quasipolynomial representation into a form where no duplicates in delays are present and last column vector of coefs is non-zero. Compressed quasipolynomial has also ordered delays in ascending order.

Parameters:
  • coefs (array) – matrix definition of polynomial coefficients (each row represents polynomial coefficients corresponding to delay)

  • delays (array) – vector definition of associated delays (each delay corresponds to row in coefs)

Returns:

  • coefs (array): matrix definition of polynomial coefficients (each row

    represents polynomial coefficients corresponding to delay)

  • delays (array): vector definition of associated delays (each delay

    corresponds to row in coefs)

Return type:

tuple containing

qpmr.quasipoly.core.normalize(coefs, delays)#

Creates normalized quasi-polynomial representation

Normalized quasi-polynomial is the quasi-polynomial with the same spectrum as the original one, but it’s representation is compressed (i.e. unique delays sorted in ascending order, no ending zero-column in coefs). First delay is 0.0 and the leading coefficient is 1.0 (leading coefficient is the coefficient with highest power of \(s\) and smallest delay).

Parameters:
  • coefs (ndarray) – Matrix of polynomial coefficients. Each row represents the coefficients corresponding to a specific delay.

  • delays (ndarray) – Vector of delays associated with each row in coefs.

Returns:

  • ccoefs (ndarray) – Matrix of normalized polynomial coefficients. Each row represents the coefficients corresponding to a specific delay.

  • ddelays (ndarray) – Vector of delays associated with each row in coefs, non-negative, sorted in ascending order, if non-empty first delay is 0

Return type:

tuple[ndarray[tuple[Any, …], dtype[_ScalarT]], ndarray[tuple[Any, …], dtype[_ScalarT]]]

Examples

>>> import numpy as np
>>> import qpmr.quasipoly
>>> coefs = np.array([[0., 1, 2, 0], [1, 1, 2, 0], [0, 0, 2, 0]])
>>> delays = np.array([-1., 1, 1])
>>> ncoefs, ndelays = qpmr.quasipoly.normalize(coefs, delays)
>>> coefs
array([[0. , 0.5, 1. ],
       [0.5, 0.5, 2. ]])
>>> delays
array([0., 2.])
qpmr.quasipoly.core.normalize_exponent(coefs, delays)#

Creates normalized quasi-polynomial representation - TODO

Normalized quasi-polynomial is the quasi-polynomial with the same spectrum as the original one, but it’s representation is compressed (i.e. unique delays sorted in ascending order, no ending zero-column in coefs). First delay is 0.0 and the leading coefficient is 1.0 (leading coefficient is the coefficient with highest power of \(s\) and smallest delay).

Parameters:
  • coefs (>>>) – Matrix of polynomial coefficients. Each row represents the coefficients corresponding to a specific delay.

  • delays (ndarray) – Vector of delays associated with each row in coefs.

  • TODO (Examples -)

  • -------

  • ccoefs (ndarray) – Matrix of normalized polynomial coefficients. Each row represents the coefficients corresponding to a specific delay.

  • ddelays (ndarray) – Vector of delays associated with each row in coefs, non-negative, sorted in ascending order, if non-empty first delay is 0

  • TODO

  • --------

  • np (>>> import numpy as)

  • qpmr.quasipoly (>>> import)

  • np.array([[0. (>>> coefs =)

  • 1

  • 2

  • 0]

  • [1

  • 1

  • 2

  • 0]

  • [0

  • 0

  • 2

  • 0]])

  • np.array([-1. (>>> delays =)

  • 1

  • 1])

  • ncoefs (>>>)

  • qpmr.quasipoly.normalize(coefs (ndelays =)

  • delays)

  • coefs

  • array([[0. – [0.5, 0.5, 2. ]])

  • 0.5 – [0.5, 0.5, 2. ]])

  • ] (1.) – [0.5, 0.5, 2. ]])

Return type:

tuple[ndarray[tuple[Any, …], dtype[_ScalarT]], ndarray[tuple[Any, …], dtype[_ScalarT]], float]

:param : [0.5, 0.5, 2. ]]) :param >>> delays: :param array([0.: :param 2.]):

qpmr.quasipoly.core.factorize_power(coefs, delays)#

Factor out powers of s from quasi-polynomial

Where original quasi-polynomial is of a form ..math:

h(s) = s^n g(s)

such that \(g(s)\) is quasi-polynomial such that at least one trailing coefficient of polynomials associated with \(g(s)\) is non-zero.

Parameters:
  • coefs (ndarray) – Matrix of polynomial coefficients. Each row represents the coefficients corresponding to a specific delay.

  • delays (ndarray) – Vector of delays associated with each row in coefs.

Returns:

  • ccoefs (ndarray) – Matrix of normalized polynomial coefficients. Each row represents the coefficients corresponding to a specific delay.

  • ddelays (ndarray) – Vector of delays associated with each row in coefs, non-negative, sorted in ascending order, if non-empty first delay is 0

  • spower (int) – Power of s in factorization

  • Examples - TODO

  • ——–

  • >>> import numpy as np

  • >>> import qpmr.quasipoly

  • >>> coefs = np.array([[0., 1, 2, 0], [1, 1, 2, 0], [0, 0, 2, 0]])

  • >>> delays = np.array([-1., 1, 1])

  • >>> ncoefs, ndelays = qpmr.quasipoly.normalize(coefs, delays)

  • >>> coefs

  • array([[0. , 0.5, 1. ], – [0.5, 0.5, 2. ]])

  • >>> delays

  • array([0., 2.])

Return type:

tuple[ndarray[tuple[Any, …], dtype[_ScalarT]], ndarray[tuple[Any, …], dtype[_ScalarT]], int]

qpmr.quasipoly.core.shift(coefs, delays, origin)#

Shifts quasi-polynomial to new origin

Input quasi-polynomial \(h(s)\) is shifted to new origin \(a\) resulting in quasi-polynomial

..math:

g(s) = h(s-a)
Parameters:
  • coefs (ndarray) – Matrix of polynomial coefficients. Each row represents the coefficients corresponding to a specific delay.

  • delays (ndarray) – Vector of delays associated with each row in coefs.

  • origin (float or complex) – New origin of complex plane

Returns:

  • ccoefs (ndarray) – Matrix of shifted polynomial coefficients. Each row represents the coefficients corresponding to a specific delay.

  • ddelays (ndarray) – Vector of delays associated with each row in coefs, it is identical to input

Return type:

tuple[ndarray[tuple[Any, …], dtype[_ScalarT]], ndarray[tuple[Any, …], dtype[_ScalarT]]]

Examples

>>> import numpy as np
>>> import qpmr.quasipoly
>>> coefs = np.array([[0., 1], [0, 1]])
>>> delays = np.array([0., 1])
>>> ccoefs, ddelays = qpmr.quasipoly.shift(coefs, delays, 1)
>>> ccoefs
array([[-1.        ,  1.        ],
       [-2.71828183,  2.71828183]])

Try to shift back to the original origin and check the results

>>> ccoefs, ddelays = qpmr.quasipoly.shift(ccoefs, ddelays, -1)
>>> ccoefs
array([[0., 1.],
       [0., 1.]])
qpmr.quasipoly.core.poly_degree(poly, order='reversed')#

assumes 1D array as input

[a0, a1, … am, 0, 0, … 0] -> degree m

reverse order

Parameters:

poly (ndarray[tuple[Any, ...], dtype[_ScalarT]])

Return type:

int

qpmr.quasipoly.core.is_neutral(coefs, delays, **kwargs)#

Checks if quasipolynomial is neutral

Parameters:
  • coefs (array) – matrix definition of polynomial coefficients (each row represents polynomial coefficients corresponding to delay)

  • delays (array) – vector definition of associated delays (each delay corresponds to row in coefs)

  • **kwargs

    compress (bool): if True compresses the result (converts to minimal

    form), default True

Returns:

bool - True if neutral, False if retarded

qpmr.quasipoly.core.create_normalized_delay_difference_eq(coefs, delays, **kwargs)#

Creates characteristic equation of the associated delay difference equation

The characteristic equation is normalized (leading term = 1 and is omitted)

returns None if does not exist

TODO

Parameters:
  • coefs (ndarray[tuple[Any, ...], dtype[_ScalarT]])

  • delays (ndarray[tuple[Any, ...], dtype[_ScalarT]])

Return type:

tuple[ndarray[tuple[Any, …], dtype[_ScalarT]], ndarray[tuple[Any, …], dtype[_ScalarT]]]

qpmr.quasipoly.examples module#

Quasipolynomial examples#

This file contains various examples of quasi-polynomials taken from literature. Some examples are parametrizable, in these cases, calling without passing arguments is always possible and results in article supplied values. Callables constructing quasi-polynomials are named using citation key, for the whole reference and notes read docstring of individual callables.

qpmr.quasipoly.examples.mazanti2021multiplicity(kappa=1.964, k=-0.67036, tau0=0.33, tau1=0.33)#

Example obtained from article [1], for the default setting, there is dominant real pole of multiplicity 6: s = −6.021

Parameters:
  • kappa (float) – parameter from article

  • k (float) – parameter from article

  • tau0 (float) – delay from article, should be positive

  • tau1 (float) – delay from article, should be positive

Returns:

  • coefs (array): matrix definition of polynomial coefficients (each row

    represents polynomial coefficients corresponding to delay)

  • delays (array): vector definition of associated delays (each delay

    corresponds to row in coefs)

Return type:

tuple containing

[1] MAZANTI, Guilherme; BOUSSAADA, Islam; NICULESCU, Silviu-Iulian. Multiplicity-induced-dominancy for delay-differential equations of retarded type. Journal of Differential Equations, 2021, 286: 84-118.

Notes

  • Parameters calculated corresponding to Proposition 6.1, Eq. (6.10a) - (6.10f), see notes in code

  • have in mind that due to rounding, it is expected that the poles are distributed on the disk around -6.021

qpmr.quasipoly.examples.yuksel2023distributed(return_denum=True)#

Internal Model Control Transfer function taken from

YUKSEL, Can Kutlu, et al. A distributed delay based controller for simultaneous periodic disturbance rejection and input-delay compensation. Mechanical Systems and Signal Processing, 2023, 197: 110364.

Parameters:

return_denum (bool) – if True, returns quasipolynomial representing denumerator of transfer function, set to False to obtain numerator, default True

Returns:

  • coefs (array): matrix definition of polynomial coefficients (each row

    represents polynomial coefficients corresponding to delay)

  • delays (array): vector definition of associated delays (each delay

    corresponds to row in coefs)

Return type:

tuple containing

Additional commentary:

Sensitivity is given by Eq. (12) as

1 - C(s) * G_m(s) * exp(-s*tau_m)

S(s) = ————————————————————-

1 + C(s) * ( G_i(s) * exp(-s*tau) - G_m(s) * exp(-s*tau_m))

we are interested in showing zeros and poles of S(s).

The model is considered in the form of non delayd LTI as

K

Gm(s) = ———

T*s + 1

Plant Gi(s) was identified as a non delayed LTI of 3rd order and controller

C(s) is given by

1

C(s) = ——— * D(s)

Gm(s)

with:

1

D(s) = — (a_0 + a_1 * exp(-s * theta) + … a_N * exp(-s * N * theta))

s

To obtain same results as in article, use:

>>> region = (-12, 1, -0.1, 5000)

Numerator is expected to have purely imaginary zeros:

>>> expected_zeros = np.array([4,8,12,16,20,24,28,32]) * 1j * 2 * np.pi
qpmr.quasipoly.examples.vyhlidal2014qpmr_01()#

TODO

Return type:

tuple[ndarray[tuple[Any, …], dtype[_ScalarT]], ndarray[tuple[Any, …], dtype[_ScalarT]]]

qpmr.quasipoly.examples.vyhlidal2014qpmr_02()#

TODO

Return type:

tuple[ndarray[tuple[Any, …], dtype[_ScalarT]], ndarray[tuple[Any, …], dtype[_ScalarT]]]

qpmr.quasipoly.examples.vyhlidal2014qpmr_03()#

TODO

Return type:

tuple[ndarray[tuple[Any, …], dtype[_ScalarT]], ndarray[tuple[Any, …], dtype[_ScalarT]]]

qpmr.quasipoly.examples.vyhlidal2014qpmr(example=1)#
Parameters:

example (str | int)

qpmr.quasipoly.examples.appeltans2023analysis(example=None, **kwargs)#

TODO

Parameters:

example (str)

qpmr.quasipoly.examples.self_inverse_polynomial(center=0.0, radius=1.0, degree=6)#
Parameters:
  • center (float)

  • radius (float)

  • degree (int)

qpmr.quasipoly.examples.empty()#

Constructs emtpy quasi-polynomial representation -> h(s) = 0

qpmr.quasipoly.form module#

Quasipolynomial forms#

class qpmr.quasipoly.form.QuasiPolynomialType(*values)#

Bases: str, Enum

RETARDED = 'RETARDED'#
NEUTRAL = 'NEUTRAL'#
ADVANCED = 'ADVANCED'#
POLYNOMIAL = 'POLYNOMIAL'#
CONSTANT = 'CONSTANT'#
qpmr.quasipoly.form.qp_type(coefs, delays)#

qpmr.quasipoly.obj module#

class qpmr.quasipoly.obj.QuasiPolynomial(coefs, delays)#

Bases: object

Parameters:
  • coefs (ndarray[tuple[Any, ...], dtype[_ScalarT]])

  • delays (ndarray[tuple[Any, ...], dtype[_ScalarT]])

property is_empty: bool#

Checks if qp empty, equivalent to p(s) = 0

property degree: int#

maximal degree polynomials

property m#

number of powers = degree + 1 for non is_empty

property n#

number of delays

property is_constant: bool#
property is_polynomial: bool#
property is_retarded: bool#

checks if qp is of retarded type

property is_neutral: bool#
property is_advanced: bool#
property derivative: QuasiPolynomial#
property antiderivative: QuasiPolynomial#
property compressed: QuasiPolynomial#

Compressed quasipolynomial representation

Compresses quasipolynomial (converts to minimal form) in such way that:
  1. delays are unique and sorted

  2. coefs do not end with zero column

property poly_degrees: ndarray[tuple[Any, ...], dtype[_ScalarT]]#
eval(s)#
Parameters:

s (complex | ndarray[tuple[Any, ...], dtype[_ScalarT]])

classmethod from_constant(const, dtype=<class 'numpy.float64'>)#

Creates constant represetation of a quasipolynomial

Parameters:

const (float)

classmethod from_array(coefs, dtype=<class 'numpy.float64'>)#

Creates crepresetation of non-delayed polynomial

Assumes coefs=[a_0, a_1, …, a_d] representing polynomial:

p(s) = a_0 + a_1 * s + … + a_d * s^d

Parameters:

coefs (ndarray[tuple[Any, ...], dtype[_ScalarT]])

class qpmr.quasipoly.obj.TransferFunction(num, denum)#

Bases: object

Parameters:
property numerator: QuasiPolynomial#
property denumerator: QuasiPolynomial#

qpmr.quasipoly.operation module#

More complex operations on quasipolynomials#

qpmr.quasipoly.operation.derivative(coefs, delays, **kwargs)#

Derivative of quasipolynomial

Assume quasipolynomial h(s) in a form of sum of products of polynomials of order m_i <= m and exp(.)

n

h(s) = SUM p_i(s) * exp(-tau_i*s)

i=0

derivative can be solved via product rule applied on all those products.

Parameters:
  • coefs (array) – matrix definition of polynomial coefficients (each row represents polynomial coefficients corresponding to delay)

  • delays (array) – vector definition of associated delays (each delay corresponds to row in coefs)

  • **kwargs

    compress (bool): if True compresses the result (converts to minimal

    form), default True

Returns:

  • coefs (array): matrix definition of polynomial coefficients (each row

    represents polynomial coefficients corresponding to delay)

  • delays (array): vector definition of associated delays (each delay

    corresponds to row in coefs)

Return type:

tuple containing

qpmr.quasipoly.operation.antiderivative(coefs, delays, **kwargs)#

Antiderivative of quasipolynomial

Assume quasipolynomial h(s) in a form of sum of products of polynomials of order m_i <= m and exp(.)

n

h(s) = SUM p_i(s) * exp(-tau_i*s)

i=0

antiderivative can be solved … TODO

Parameters:
  • coefs (array) – matrix definition of polynomial coefficients (each row represents polynomial coefficients corresponding to delay)

  • delays (array) – vector definition of associated delays (each delay corresponds to row in coefs)

  • **kwargs

    compress (bool): if True compresses the result (converts to minimal

    form), default True

Returns:

  • coefs (array): matrix definition of polynomial coefficients (each row

    represents polynomial coefficients corresponding to delay)

  • delays (array): vector definition of associated delays (each delay

    corresponds to row in coefs)

Return type:

tuple containing

Module contents#