Skip to content

Commit ba4d1a0

Browse files
authored
Merge pull request #970 from JuliaControl/inexcessfix
tweak computation of integrator excess
2 parents b644a5d + 57e4629 commit ba4d1a0

File tree

4 files changed

+22
-11
lines changed

4 files changed

+22
-11
lines changed

lib/ControlSystemsBase/Project.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,10 @@ julia = "1.6"
4848
[extras]
4949
Aqua = "4c88cf16-eb10-579e-8560-4a9242c79595"
5050
ComponentArrays = "b0b7db55-cfe3-40fc-9ded-d10e2dbeff66"
51-
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
5251
DSP = "717857b8-e6f2-59f4-9121-6e50c889abd2"
52+
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
5353
FiniteDifferences = "26cc04aa-876d-5657-8c51-4c34ba976000"
54+
GenericLinearAlgebra = "14197337-ba66-59df-a3e3-ca00e7dcff7a"
5455
GR = "28b8d3ca-fb5f-59d9-8090-bfdbd6d07a71"
5556
ImplicitDifferentiation = "57b37032-215b-411a-8a7c-41a003a55207"
5657
Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
@@ -59,5 +60,4 @@ StaticArrays = "90137ffa-7385-5640-81b9-e52037218182"
5960
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
6061

6162
[targets]
62-
test = ["Test", "Aqua", "ComponentArrays", "Documenter", "DSP", "FiniteDifferences", "ImplicitDifferentiation", "GR", "Plots", "SparseArrays", "StaticArrays"]
63-
63+
test = ["Test", "Aqua", "ComponentArrays", "Documenter", "DSP", "FiniteDifferences", "ImplicitDifferentiation", "GenericLinearAlgebra", "GR", "Plots", "SparseArrays", "StaticArrays"]

lib/ControlSystemsBase/src/ControlSystemsBase.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,8 @@ function __init__()
242242
print(io, "\n$(exc.f) with continuous-time systems, including delay systems and nonlinear systems, require the user to first ")
243243
printstyled(io, "install and load ControlSystems.jl, or pass the keyword method = :zoh", color=:green, bold=true)
244244
print(io, " for automatic discretization (applicable to systems without delays or nonlinearities only).")
245+
elseif exc.f (eigvals!, ) && argtypes[1] <: AbstractMatrix{<:Number}
246+
printstyled(io, "\nComputing eigenvalues of a matrix with exotic element types may require `using GenericLinearAlgebra`.", color=:green, bold=true)
245247
end
246248
plots_id = Base.PkgId(UUID("91a5bcdd-55d7-5caf-9e0b-520d859cae80"), "Plots")
247249
if exc.f isa Function && nameof(exc.f) === :plot && parentmodule(argtypes[1]) == @__MODULE__() && !haskey(Base.loaded_modules, plots_id)

lib/ControlSystemsBase/src/analysis.jl

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -38,24 +38,22 @@ function poles(sys::TransferFunction{<:TimeEvolution,SisoZpk{T,TR}}) where {T, T
3838
end
3939

4040

41-
function count_eigval_multiplicity(p, location)
42-
T = float(real(eltype(p)))
41+
function count_eigval_multiplicity(p, location, e=eps(maximum(abs, p)))
4342
n = length(p)
4443
n == 0 && return 0
45-
maximum(1:n) do i
44+
for i = 1:n
4645
# if we count i poles within the circle assuming i integrators, we return i
47-
if count(p->abs(p-location) < (i+1)*(eps(T)^(1/i)), p) >= i
48-
i
49-
else
50-
0
46+
if count(p->abs(p-location) < (e^(1/i)), p) == i
47+
return i
5148
end
5249
end
50+
0
5351
end
5452

5553
"""
5654
count_integrators(P)
5755
58-
Count the number of poles in the origin by finding the maximum value of `n` for which the number of poles within a circle of radius `(n+1)*eps(numeric_type(sys))^(1/n)` arount the origin (1 in discrete time) equals `n`.
56+
Count the number of poles in the origin by finding the first value of `n` for which the number of poles within a circle of radius `eps(maximum(abs, p))^(1/n)` around the origin (1 in discrete time) equals `n`.
5957
6058
See also [`integrator_excess`](@ref).
6159
"""

lib/ControlSystemsBase/test/test_analysis.jl

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
@test_throws MethodError poles(big(1.0)*ssrand(1,1,1)) # This errors before loading GenericLinearAlgebra
2+
using GenericLinearAlgebra # Required to compute eigvals of a matrix with exotic element types
13
@testset "test_analysis" begin
24
## tzeros ##
35
# Examples from the Emami-Naeini & Van Dooren Paper
@@ -269,6 +271,15 @@ for wgm in wgm[]
269271
@test mod(rad2deg(angle(freqresp(OL, wgm)[])), 360)-180 0 atol=1e-1
270272
end
271273

274+
nint = ControlSystemsBase.count_integrators(pade(OL, 2))
275+
nintbig = ControlSystemsBase.count_integrators(big(1.0)*pade(OL, 2))
276+
@test nint == nintbig # This one is very tricky and tests the threshold value of the eigval counting
277+
278+
@test ControlSystemsBase.count_integrators(pade(OL, 3)) == nintbig
279+
@test ControlSystemsBase.count_integrators(pade(OL, 4)) == nintbig
280+
@test ControlSystemsBase.count_integrators(pade(OL, 10)) == nintbig
281+
282+
272283
# RGA
273284
a = 10
274285
P = ss([0 a; -a 0], I(2), [1 a; -a 1], 0)

0 commit comments

Comments
 (0)