This package is python implementation of QPmR v2
algorithm described in [1], [2]. This project is still in development
The QPmR v2
algorithm is designed to find all roots of the quasi-polynomial
located in the complex plane region
The following table may clarify quasi-polynomial representation:
[1] Vyhlidal, T., and ZÃtek, P. (2009). Mapping based algorithm for large-scale computation of quasi-polynomial zeros. IEEE Transactions on Automatic Control, 54(1), 171-177.
[2] Vyhlidal, T. and Zitek, P. (2014). QPmR-Quasi-polynomial root-finder: Algorithm update and examples Editors: VyhÃdal T., Lafay J.F., Sipahi R., Sringer 2014.
We will follow 3 examples from the 2014 paper. Please not that matplotlib
is not required (as qpmr
is built on contourpy
, which is dependency of matplotlib
).
Find all the roots of the quasi-polynomial
located in region
import logging
import matplotlib.pyplot as plt
import numpy as np
from qpmr import qpmr
delays = np.array([0., 1])
coefs = np.array([[0., 1], [1, 0]])
region = [-10, 2, 0, 30]
roots, meta = qpmr(region, coefs, delays)
matlab_roots = np.array([-0.3181 + 1.3372j,
-2.0623 + 7.5886j,
-2.6532 +13.9492j,
-3.0202 +20.2725j,
-3.2878 +26.5805j,])
complex_grid = meta.complex_grid
value = meta.z_value
plt.figure()
plt.subplot(121)
plt.contour(np.real(complex_grid), np.imag(complex_grid), np.real(value), levels=[0], colors='blue')
plt.contour(np.real(complex_grid), np.imag(complex_grid), np.imag(value), levels=[0], colors='green')
plt.scatter(np.real(roots), np.imag(roots), marker="o", color="r")
plt.subplot(122)
plt.scatter(np.real(roots), np.imag(roots), marker="o", color="r")
plt.scatter(np.real(matlab_roots), np.imag(matlab_roots), marker="x", color="b")
plt.show()
DEBUG:qpmr.qpmr_v2:Grid size not specified, setting as ds=0.36 (solved by heuristic)
DEBUG:qpmr.qpmr_v2:Estimated size of complex grid = 57600.0 bytes
DEBUG:qpmr.numerical_methods:Numerical Newton converged in 3/100 steps, last MAX(|res|) = 9.994753622376123e-09
DEBUG:qpmr.argument_principle:Using argument principle, contour integral = 5.020734859071829
DEBUG:qpmr.argument_principle:Using argument principle, contour integral = 5.020753819340232
Resulting in the following figure (left contours and roots, right roots compared with matlab output)
qpmr
package has logger with NullHandler
, you can for example use
logger = logging.getLogger("qpmr")
logger.setLevel(logging.DEBUG)
handler = logging.StreamHandler()
formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
handler.setFormatter(formatter)
logger.addHandler(handler)
Please, cite the following article
@article{vyhlidal2009mapping,
title={Mapping based algorithm for large-scale computation of quasi-polynomial zeros},
author={Vyhlidal, Tomas and Z{\'\i}tek, Pavel},
journal={IEEE Transactions on Automatic Control},
volume={54},
number={1},
pages={171--177},
year={2009},
publisher={IEEE}
}
Alternatively, this chapter of book
@incollection{vyhlidal2014qpmr,
title={QPmR-Quasi-polynomial root-finder: Algorithm update and examples},
author={Vyhl{\'\i}dal, Tom{\'a}{\v{s}} and Z{\'\i}tek, Pavel},
booktitle={Delay Systems: From Theory to Numerics and Applications},
pages={299--312},
year={2014},
publisher={Springer}
}
From github
pip install qpmr@git+https://github.com/LockeErasmus/qpmr
Local install
pip install <path-to-qpmr>
Clone repository
git clone https://github.com/LockeErasmus/qpmr.git
install from source with -e
pip install -e qpmr
TODO <- move examples and additional comments to this section.
This package is available under GNU GPLv3 license.