qpmr package#

Subpackages#

Submodules#

qpmr.argument_principle module#

Argument Principle implementation#

qpmr.argument_principle.rectangular_contour(re_min, re_max, im_min, im_max)#
Return type:

tuple[Callable, Callable, tuple[float, float]]

qpmr.argument_principle.circle_contour(center, radius)#

TODO

Parameters:
  • center (complex)

  • radius (float)

qpmr.argument_principle.argument_principle(f, region, ds, eps)#

Evaluates number of roots in given rectangular region via argument principle

Parameters:
  • func (Callable) – vector-suitable callable for quassipolynomial

  • region (list of float) – region in complex plane

  • ds (float) – grid stepsize

  • eps (float) – step for finite difference method

  • f (Callable)

Returns:

rounded number of complex roots in region based on numerical

integration and argument principle

Return type:

n (float)

qpmr.argument_principle.argument_principle_rectangle(f, region, ds, eps, f_prime=None)#

Evaluates number of roots in given rectangular region via argument principle

Parameters:
  • func (Callable) – vector-suitable callable for quassipolynomial

  • region (list of float) – region in complex plane

  • ds (float) – grid stepsize

  • eps (float) – step for finite difference method

  • f (Callable)

Returns:

rounded number of complex roots in region based on numerical

integration and argument principle

Return type:

n (float)

qpmr.argument_principle.argument_principle_circle(f, circle, ds, eps, f_prime=None)#
Parameters:
  • circle (tuple[complex, float])

  • ds (float)

  • eps (float)

  • f_prime (Callable)

qpmr.common module#

Compilation of mathematical utility functions

qpmr.common.find_crossings(x, y, remove_consequent=True, interpolate=False)#

Finds 0-level crossings by checking consequent difference in signs

Parameters:
  • x (array) – complex vector representing real contour

  • y (array) – real vector representing Im( h(z) )

  • TODO

  • remove_consequent (bool)

  • interpolate (bool)

Return type:

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

qpmr.grid module#

Grid#

Notes

qpmr.grid.grid_size_heuristic(region, coefs, delays)#

Grid size heuristic original 2009

Parameters:
  • region (tuple[float, float, float, float])

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

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

Return type:

float

qpmr.grid.complex_grid_rect(region, ds)#

Creates complex grid from rectangular region

Parameters:
  • region (tuple)

  • ds (float)

qpmr.qpmr_metadata module#

QPmR Info object#

class qpmr.qpmr_metadata.QpmrInfo#

Bases: object

real_range: ndarray[tuple[Any, ...], dtype[_ScalarT]] = None#
imag_range: ndarray[tuple[Any, ...], dtype[_ScalarT]] = None#
z_value: ndarray[tuple[Any, ...], dtype[_ScalarT]] = None#
roots0: ndarray[tuple[Any, ...], dtype[_ScalarT]] = None#
roots_numerical: ndarray[tuple[Any, ...], dtype[_ScalarT]] = None#
contours_real: list[ndarray[tuple[Any, ...], dtype[_ScalarT]]] = None#
property complex_grid: ndarray[tuple[Any, ...], dtype[_ScalarT]]#
property contours_imag: list[ndarray[tuple[Any, ...], dtype[_ScalarT]]]#
class qpmr.qpmr_metadata.QpmrSubInfo(parent=None)#

Bases: Node

region: tuple = None#
ds: float = None#
e: float = None#
status: str = 'UNPROCESSED'#
status_message: str = None#
roots: ndarray[tuple[Any, ...], dtype[_ScalarT]] = None#
z_value: ndarray[tuple[Any, ...], dtype[_ScalarT]] = None#
roots0: ndarray[tuple[Any, ...], dtype[_ScalarT]] = None#
roots_numerical: ndarray[tuple[Any, ...], dtype[_ScalarT]] = None#
contours_real: list[ndarray[tuple[Any, ...], dtype[_ScalarT]]] = None#
property expanded_region: tuple[float, float, float, float]#
property real_range: ndarray[tuple[Any, ...], dtype[_ScalarT]]#
property imag_range: ndarray[tuple[Any, ...], dtype[_ScalarT]]#
property complex_grid: ndarray[tuple[Any, ...], dtype[_ScalarT]]#
property contours_imag: list[ndarray[tuple[Any, ...], dtype[_ScalarT]]]#
property name: str#
class qpmr.qpmr_metadata.QpmrRecursionContext(coefs, delays)#

Bases: object

stuff that does not change in recursion + memory for results

grid_nbytes_max: int = 128000000#
recursion_level_max: int = 5#
multiplicity_heuristic: bool = False#
numerical_method: str = None#
numerical_method_kwargs: dict = {}#
complex_plane_shift: complex = 0j#
complex_plane_scale: float = 1.0#
ds: float = None#
solution_tree: QpmrSubInfo#
node: QpmrSubInfo#
property render_tree: str#
property roots: ndarray[tuple[Any, ...], dtype[_ScalarT]]#
property zeros: ndarray[tuple[Any, ...], dtype[_ScalarT]]#

alias for roots

property coefs_prime: ndarray[tuple[Any, ...], dtype[_ScalarT]]#
property delays_prime: ndarray[tuple[Any, ...], dtype[_ScalarT]]#
property f: Callable#
property f_prime: Callable#

qpmr.qpmr_v2 module#

QPmR v2 implementation#

Set of funtions implement original QPmR v2 algorithm, based on [1].

[1] Vyhlidal, Tomas, and Pavel Zitek. “Mapping based algorithm for large-scale

computation of quasi-polynomial zeros.” IEEE Transactions on Automatic Control 54.1 (2009): 171-177.

qpmr.qpmr_v2.qpmr(region: list[float, float, float, float], coefs: ndarray[tuple[Any, ...], dtype[_ScalarT]], delays: ndarray[tuple[Any, ...], dtype[_ScalarT]], **kwargs) tuple[ndarray[tuple[Any, ...], dtype[complex128]], QpmrInfo]#
qpmr.qpmr_v2.qpmr(region: list[float, float, float, float], qp: QuasiPolynomial, **kwargs) tuple[ndarray[tuple[Any, ...], dtype[complex128]], QpmrInfo]

Quasi-polynomial Root Finder V2

Attempts to find all roots of quasi-polynomial in rectangular subregion of complex plane. For more details, see:

[1] Vyhlidal, Tomas, and Pavel Zitek. “Mapping based algorithm for large-scale computation of quasi-polynomial zeros.” IEEE Transactions on Automatic Control 54.1 (2009): 171-177.

TODO Overload:

Parameters:
  • region (list) – definition of rectangular region in the complex plane of a form [Re_min, Re_max, Im_min, Im_max]

  • 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

    e (float) - computation accuracy, default = 1e-6 ds (float) - grid step, default obtained by heuristic numerical_method (str) - numerical method for increasing precission

    of roots, default “newton”, other options: “secant”

    numerical_method_kwargs (dict) - keyword arguments for numerical

    method, default None

    grid_nbytes_max (int): maximal allowed size of grid in bytes,

    default 250e6 bytes, set to None to disregard maximum size check of the grid

Return type:

tuple[ndarray[tuple[Any, …], dtype[complex128]], QpmrInfo]

qpmr.qpmr_v3 module#

QPmR v2 implementation#

Set of funtions implement original QPmR v2 algorithm, based on [1].

[1] Vyhlidal, Tomas, and Pavel Zitek. “Mapping based algorithm for large-scale

computation of quasi-polynomial zeros.” IEEE Transactions on Automatic Control 54.1 (2009): 171-177.

qpmr.qpmr_v3.qpmr(coefs: ndarray[tuple[Any, ...], dtype[_ScalarT]], delays: ndarray[tuple[Any, ...], dtype[_ScalarT]], region: tuple[float, float, float, float] = None, **kwargs) tuple[ndarray[tuple[Any, ...], dtype[complex128]], QpmrInfo]#
qpmr.qpmr_v3.qpmr(qp: QuasiPolynomial, region: tuple[float, float, float, float] = None, **kwargs) tuple[ndarray[tuple[Any, ...], dtype[complex128]], QpmrInfo]

Quasi-polynomial Root Finder V3

Attempts to find all roots of quasi-polynomial in rectangular subregion of complex plane using Quasi-polynomial Root Finder [1].

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.

  • region (tuple of float, optional) – Definition of the rectangular region in the complex plane, specified as [Re_min, Re_max, Im_min, Im_max]. Defaults to None, which selects the region such that QPmR caputres 50 rightmost roots.

  • e (float, optional) – Computation accuracy. Defaults to 1e-6.

  • ds (float, optional) – Grid step. If not provided, a heuristic will be used to determine the step size.

  • numerical_method ({'newton', 'secant'}, optional) – Numerical method used to refine the roots. Defaults to ‘newton’.

  • numerical_method_kwargs (dict, optional) – Additional keyword arguments passed to the numerical method. Defaults to None.

  • grid_nbytes_max (int or None, optional) – Maximum allowed grid size in bytes. Defaults to 250e6. Set to None to disable the size check.

Returns:

  • roots (ndarray) – Matrix of polynomial coefficients. Each row corresponds to a delay value.

  • ctx (QpmrRecursionContext) – Tree-like object containing the computation metadata

    ivar TODO:

Return type:

tuple[ndarray[tuple[Any, …], dtype[complex128]], QpmrRecursionContext]

Notes

\[h(s) = \sum_{i=0}^n p_i(s)e^{-s au_i}\]

TODO

References

Examples

Example 1 from [1], i.e. quasi-polynomial :math: h(s) = s + e^{-s}``

>>> import numpy as np
>>> import qpmr
>>> coefs = np.array([[0, 1],[1, 0.]])
>>> delays = np.array([0, 1.])
>>> roots, ctx = qpmr.qpmr(coefs, delays, region=(-10, 2, 0, 30))

Visualize roots:

>>> import matplotlib.pyplot as plt
>>> import qpmr.plot
>>> qpmr.plot.roots(roots)
>>> plt.show()

qpmr.qpmr_validation module#

Functions for validating QPmR inputs#

qpmr.qpmr_validation.validate_region(region)#

Validates rectangular complex region definition and returns as tuple

Return type:

tuple[float, float, float, float]

qpmr.qpmr_validation.validate_qp(coefs, delays)#

Validates quasipolynomial (coefs, delays) definition and returns as tuple

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

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

Return type:

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

qpmr.region_heuristic module#

Region heuristic#

As of now, assuming retarded quasi-polynomial and goal is to find smallest possible rectangular region that contains n rightmost roots.

qpmr.region_heuristic.region_heuristic(coefs, delays, **kwargs)#

TODO

Idea of this heuristic is that number of imaginary contours =approx= number of zeros in region.

Return type:

tuple[float, float, float, float]

qpmr.utils module#

Set of utility functions .. todo:: 1. make sure handlers added only once?

qpmr.utils.init_qpmr_logger(level=20, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')#

Initializes QPmR logger with Streamhandler and level

Parameters:

format (str)

Return type:

Logger

qpmr.zero_multiplicity module#

Functions for determining zero multiplicity#

qpmr.zero_multiplicity.cluster_roots(roots0, eps)#

Simple implementation of DBScan with min_neighbors=1

Approach: cluster -> refine -> count multiplicities (-> verify - this will be done outside of the function)

Assumptions:

zeros are separated by more than 4 epsilon

Parameters:
  • roots0 (array) – root candidates

  • eps (float)

Return type:

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

Notes

  1. isolation =def= no edges between points in different clusters

  2. eps < ds (grid and eps relationship)

Module contents#