MayaFlux 0.5.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches

◆ max_pole_magnitude()

MAYAFLUX_API double MayaFlux::Kinesis::Discrete::max_pole_magnitude ( std::span< const double >  a)

Largest pole magnitude of a denominator polynomial.

Roots of a[0] + a[1]z^-1 + ... are found via the companion matrix eigenvalues. A return value below 1.0 indicates a stable recurrence; at or above 1.0 the recurrence diverges.

Orders 1 and 2 are closed-form. Higher orders carry an Eigen dependency.

Parameters
aDenominator coefficients, a[0] must be non-zero
Returns
Largest |root|, or 0.0 for a constant polynomial

Definition at line 311 of file Coefficients.cpp.

312{
313 size_t order = a.size();
314 while (order > 1 && a[order - 1] == 0.0)
315 --order;
316
317 if (order <= 1)
318 return 0.0;
319
320 const double a0 = a[0];
321
322 if (order == 2)
323 return std::abs(a[1] / a0);
324
325 if (order == 3) {
326 const double p = a[1] / a0;
327 const double q = a[2] / a0;
328 const double disc = p * p - 4.0 * q;
329 if (disc >= 0.0) {
330 const double r = std::sqrt(disc);
331 return std::max(std::abs((-p + r) * 0.5), std::abs((-p - r) * 0.5));
332 }
333 return std::sqrt(q);
334 }
335
336 const Eigen::Index n = static_cast<Eigen::Index>(order) - 1;
337 Eigen::MatrixXd companion = Eigen::MatrixXd::Zero(n, n);
338 for (Eigen::Index i = 0; i < n; ++i)
339 companion(0, i) = -a[static_cast<size_t>(i) + 1] / a0;
340 for (Eigen::Index i = 1; i < n; ++i)
341 companion(i, i - 1) = 1.0;
342
343 Eigen::EigenSolver<Eigen::MatrixXd> solver(companion, false);
344 double largest = 0.0;
345 for (Eigen::Index i = 0; i < solver.eigenvalues().size(); ++i)
346 largest = std::max(largest, std::abs(solver.eigenvalues()(i)));
347 return largest;
348}
size_t a
double q

References a, and q.

Referenced by MayaFlux::Nodes::Filters::Filter::max_pole_magnitude().

+ Here is the caller graph for this function: