From af08895a3cf9b1bd8b73df94269ee880e2d1ec32 Mon Sep 17 00:00:00 2001 From: jacobhuesman Date: Thu, 30 Aug 2018 18:47:01 -0700 Subject: [PATCH 1/5] Added rounded print output --- src/ControlSystems.jl | 2 +- src/types/polys.jl | 12 ++++++++---- src/types/sisotf.jl | 6 +++--- src/types/sisozpk.jl | 13 +++++++------ src/types/transferfunction.jl | 8 +++++--- 5 files changed, 24 insertions(+), 17 deletions(-) diff --git a/src/ControlSystems.jl b/src/ControlSystems.jl index 926d5f4bb..be71b3753 100644 --- a/src/ControlSystems.jl +++ b/src/ControlSystems.jl @@ -67,7 +67,7 @@ export LTISystem, numpoly, denpoly -using Plots, LaTeXStrings, Requires +using Plots, LaTeXStrings, Requires, Formatting import Base: +, -, *, /, (./), (==), (.+), (.-), (.*), (!=), isapprox, convert, promote_op include("types/lti.jl") diff --git a/src/types/polys.jl b/src/types/polys.jl index 517e02d66..91e96a9ff 100644 --- a/src/types/polys.jl +++ b/src/types/polys.jl @@ -49,10 +49,11 @@ end Base.print(io::IO, p::Poly) = print_poly(io, p) -function print_poly{T}(io::IO, p::Poly{T}, var=:x) +function print_poly{T}(io::IO, p::Poly{T}, var=:x, precision::Int=-1) + pformat = precision >= 0 ? string(".", precision, "g") : "g" n = length(p) if n == 1 - print(io, p[1]) + print(io, format(p[1], conversion=pformat)) else for j = 1:n pj = p[j] @@ -63,11 +64,14 @@ function print_poly{T}(io::IO, p::Poly{T}, var=:x) else real(pj) < 0 ? print(io," - ") : print(io," + ") end + exp = n-j #Print pj if pj is the last coefficient, or pj is not identically 1 if j == n || abs(magpj - 1) > 2*eps(T) - print(io, magpj) + print(io, format(magpj, conversion=pformat)) + if exp > 0 + print(io, "*") + end end - exp = n-j if exp > 0 print(io, var) if exp > 1 diff --git a/src/types/sisotf.jl b/src/types/sisotf.jl index 802d40091..672dbd300 100644 --- a/src/types/sisotf.jl +++ b/src/types/sisotf.jl @@ -18,10 +18,10 @@ function minreal(sys::SisoRational, eps::Real=sqrt(eps())) return SisoRational(minreal(SisoZpk(sys), eps)) end -function print_siso(io::IO, t::SisoRational, var=:s) +function print_siso(io::IO, t::SisoRational, var=:s, precision::Int=-1) # Convert the numerator and denominator to strings - numstr = sprint(print_poly, t.num, var) - denstr = sprint(print_poly, t.den, var) + numstr = sprint(print_poly, t.num, var, precision) + denstr = sprint(print_poly, t.den, var, precision) # Figure out the length of the separating line len_num = length(numstr) diff --git a/src/types/sisozpk.jl b/src/types/sisozpk.jl index 957832d29..be6b26600 100644 --- a/src/types/sisozpk.jl +++ b/src/types/sisozpk.jl @@ -105,19 +105,19 @@ function evalfr(sys::SisoZpk, s::Number) end end -function print_siso(io::IO, t::SisoZpk, var=:s) +function print_siso(io::IO, t::SisoZpk, var=:s, precision::Int=-1) zpolys = zp2polys(t.z) ppolys = zp2polys(t.p) # Convert the numerator and denominator to strings if length(zpolys) < 2 - numstr = ( length(zpolys) == 0 ) ? "1.0" : sprint(print_poly, zpolys[1], var) + numstr = ( length(zpolys) == 0 ) ? "1.0" : sprint(print_poly, zpolys[1], var, precision) else - numstr = reduce(*,"",["("*sprint(print_poly, z, var)*")" for z in zpolys]) + numstr = reduce(*,"",["("*sprint(print_poly, z, var, precision)*")" for z in zpolys]) end if length(ppolys) < 2 - denstr = ( length(ppolys) == 0 ) ? "1.0" : sprint(print_poly, ppolys[1], var) + denstr = ( length(ppolys) == 0 ) ? "1.0" : sprint(print_poly, ppolys[1], var, precision) else - denstr = reduce(*,"",["("*sprint(print_poly, p, var)*")" for p in ppolys]) + denstr = reduce(*,"",["("*sprint(print_poly, p, var, precision)*")" for p in ppolys]) end # Figure out the length of the separating line len_num = length(numstr) @@ -131,7 +131,8 @@ function print_siso(io::IO, t::SisoZpk, var=:s) denstr = "$(repeat(" ", div(dashcount - len_den, 2)))$denstr" end - gainstr = string(t.k) + pformat = precision >= 0 ? string(".", precision, "g") : "g" + gainstr = format(t.k, conversion=pformat) #Add spaces to account for gain string numstr = " "^(length(gainstr))*numstr denstr = " "^(length(gainstr))*denstr diff --git a/src/types/transferfunction.jl b/src/types/transferfunction.jl index 6913730d1..66f94827b 100644 --- a/src/types/transferfunction.jl +++ b/src/types/transferfunction.jl @@ -461,9 +461,10 @@ end ## Display Functions ## ##################################################################### -Base.print(io::IO, t::TransferFunction) = show(io, t) +Base.print(io::IO, t::TransferFunction; precision::Int=-1) = show(io, t, precision=precision) +Base.print(t::TransferFunction; precision::Int=-1) = show(t, precision=precision) -function Base.show(io::IO, t::TransferFunction) +function Base.show(io::IO, t::TransferFunction; precision::Int=-1) # Compose the name vectors inputs = format_names(t.inputnames, "Input ", "?") outputs = format_names(t.outputnames, "Output ", "?") @@ -474,7 +475,7 @@ function Base.show(io::IO, t::TransferFunction) if !issiso(t) println(io, inputs[i], " to ", outputs[o]) end - print_siso(io, t.matrix[o, i], tftype) + print_siso(io, t.matrix[o, i], tftype, precision) if !(i == t.nu && o == t.ny) print(io, "\n") end @@ -492,3 +493,4 @@ function Base.show(io::IO, t::TransferFunction) print(io, "\nDiscrete-time transfer function model") end end +Base.show(t::TransferFunction; precision::Int=-1) = show(STDOUT, t, precision=precision) From fd11bbe94152da833229f46bfcf1105fc4040d58 Mon Sep 17 00:00:00 2001 From: jacobhuesman Date: Thu, 30 Aug 2018 19:39:07 -0700 Subject: [PATCH 2/5] Updated REQUIRE file --- REQUIRE | 1 + 1 file changed, 1 insertion(+) diff --git a/REQUIRE b/REQUIRE index 49e794c12..366f591bb 100644 --- a/REQUIRE +++ b/REQUIRE @@ -3,3 +3,4 @@ Plots 0.7.4 Polynomials LaTeXStrings Requires +Formatting From 1cb783f6d406ccd370d672f37e4aaf66abcdbe2f Mon Sep 17 00:00:00 2001 From: jacobhuesman Date: Thu, 30 Aug 2018 19:39:27 -0700 Subject: [PATCH 3/5] Fixed print tests --- test/test_transferfunction.jl | 57 +++++++++++++++++++++++++++-------- 1 file changed, 45 insertions(+), 12 deletions(-) diff --git a/test/test_transferfunction.jl b/test/test_transferfunction.jl index daa78e6de..7ce0f4e4d 100644 --- a/test/test_transferfunction.jl +++ b/test/test_transferfunction.jl @@ -76,19 +76,52 @@ tf(vecarray(1, 2, [0], [0]), vecarray(1, 2, [1], [1]), 0.005) @test size(C_222[1,[]]) == (1,0) # Printing -res = ("TransferFunction:\nInput 1 to Output 1\ns^2 + 2.0s + 3.0\n-----------"* - "------\ns^2 + 8.0s + 15.0\n\nInput 1 to Output 2\ns^2 + 2.0s + 3.0\n-"* - "----------------\ns^2 + 8.0s + 15.0\n\nInput 2 to Output 1\n s + "* - "2.0\n-----------------\ns^2 + 8.0s + 15.0\n\nInput 2 to Output 2\n "* - " s + 2.0\n-----------------\ns^2 + 8.0s + 15.0\n\nContinuous-time"* - " transfer function model") +res = ("TransferFunction:\n"* + "Input 1 to Output 1\n"* + "s^2 + 2*s + 3\n"* + "--------------\n"* + "s^2 + 8*s + 15\n"* + "\n"* + "Input 1 to Output 2\n"* + "s^2 + 2*s + 3\n"* + "--------------\n"* + "s^2 + 8*s + 15\n"* + "\n"* + "Input 2 to Output 1\n"* + " s + 2\n"* + "--------------\n"* + "s^2 + 8*s + 15\n"* + "\n"* + "Input 2 to Output 2\n"* + " s + 2\n"* + "--------------\n"* + "s^2 + 8*s + 15\n"* + "\n"* + "Continuous-time transfer function model") @test sprint(show, C_222) == res -res = ("TransferFunction:\nInput 1 to Output 1\nz^2 + 2.0z + 3.0\n-----------"* - "------\nz^2 - 0.2z - 0.15\n\nInput 1 to Output 2\nz^2 + 2.0z + 3.0\n-"* - "----------------\nz^2 - 0.2z - 0.15\n\nInput 2 to Output 1\n z + "* - "2.0\n-----------------\nz^2 - 0.2z - 0.15\n\nInput 2 to Output 2\n "* - " z + 2.0\n-----------------\nz^2 - 0.2z - 0.15\n\nSample Time: 0.005 "* - "(seconds)\nDiscrete-time transfer function model") +res = ("TransferFunction:\n"* + "Input 1 to Output 1\n"* + " z^2 + 2*z + 3\n"* + "------------------\n"* + "z^2 - 0.2*z - 0.15\n"* + "\n"* + "Input 1 to Output 2\n"* + " z^2 + 2*z + 3\n"* + "------------------\n"* + "z^2 - 0.2*z - 0.15\n"* + "\n"* + "Input 2 to Output 1\n"* + " z + 2\n"* + "------------------\n"* + "z^2 - 0.2*z - 0.15\n"* + "\n"* + "Input 2 to Output 2\n"* + " z + 2\n"* + "------------------\n"* + "z^2 - 0.2*z - 0.15\n"* + "\n"* + "Sample Time: 0.005 (seconds)\n"* + "Discrete-time transfer function model") @test sprint(show, D_222) == res # Type stability Continuous-time From dcdf5f49f0543171b754d1bb83a10227b83e50b7 Mon Sep 17 00:00:00 2001 From: jacobhuesman Date: Fri, 31 Aug 2018 10:09:39 -0700 Subject: [PATCH 4/5] Removed keyword arguments and added additional tests --- src/types/transferfunction.jl | 8 ++--- test/test_transferfunction.jl | 63 ++++++++++++++++++++++++++++++++++- 2 files changed, 66 insertions(+), 5 deletions(-) diff --git a/src/types/transferfunction.jl b/src/types/transferfunction.jl index 66f94827b..b63a875df 100644 --- a/src/types/transferfunction.jl +++ b/src/types/transferfunction.jl @@ -461,10 +461,10 @@ end ## Display Functions ## ##################################################################### -Base.print(io::IO, t::TransferFunction; precision::Int=-1) = show(io, t, precision=precision) -Base.print(t::TransferFunction; precision::Int=-1) = show(t, precision=precision) +Base.print(io::IO, t::TransferFunction, precision::Int=-1) = show(io, t, precision) +Base.print(t::TransferFunction, precision::Int=-1) = show(t, precision) -function Base.show(io::IO, t::TransferFunction; precision::Int=-1) +function Base.show(io::IO, t::TransferFunction, precision::Int=-1) # Compose the name vectors inputs = format_names(t.inputnames, "Input ", "?") outputs = format_names(t.outputnames, "Output ", "?") @@ -493,4 +493,4 @@ function Base.show(io::IO, t::TransferFunction; precision::Int=-1) print(io, "\nDiscrete-time transfer function model") end end -Base.show(t::TransferFunction; precision::Int=-1) = show(STDOUT, t, precision=precision) +Base.show(t::TransferFunction, precision::Int=-1) = show(STDOUT, t, precision) diff --git a/test/test_transferfunction.jl b/test/test_transferfunction.jl index 7ce0f4e4d..31690e2ce 100644 --- a/test/test_transferfunction.jl +++ b/test/test_transferfunction.jl @@ -75,7 +75,7 @@ tf(vecarray(1, 2, [0], [0]), vecarray(1, 2, [1], [1]), 0.005) @test C_222[1,1:2] == C_221 @test size(C_222[1,[]]) == (1,0) -# Printing +# Printing (default, specific precision, zpk) res = ("TransferFunction:\n"* "Input 1 to Output 1\n"* "s^2 + 2*s + 3\n"* @@ -123,6 +123,67 @@ res = ("TransferFunction:\n"* "Sample Time: 0.005 (seconds)\n"* "Discrete-time transfer function model") @test sprint(show, D_222) == res +res = ("TransferFunction:\n"* + "Input 1 to Output 1\n"* + " s^2 + 2*s + 3\n"* + "-----------------\n"* + "s^2 + 8*s + 2e+01\n"* + "\n"* + "Input 1 to Output 2\n"* + " s^2 + 2*s + 3\n"* + "-----------------\n"* + "s^2 + 8*s + 2e+01\n"* + "\n"* + "Input 2 to Output 1\n"* + " s + 2\n"* + "-----------------\n"* + "s^2 + 8*s + 2e+01\n"* + "\n"* + "Input 2 to Output 2\n"* + " s + 2\n"* + "-----------------\n"* + "s^2 + 8*s + 2e+01\n"* + "\n"* + "Continuous-time transfer function model") +@test sprint(show, C_222, 1) == res +res = ("TransferFunction:\n"* + "Input 1 to Output 1\n"* + " z^2 + 2*z + 3\n"* + "-----------------\n"* + "z^2 - 0.2*z - 0.1\n"* + "\n"* + "Input 1 to Output 2\n"* + " z^2 + 2*z + 3\n"* + "-----------------\n"* + "z^2 - 0.2*z - 0.1\n"* + "\n"* + "Input 2 to Output 1\n"* + " z + 2\n"* + "-----------------\n"* + "z^2 - 0.2*z - 0.1\n"* + "\n"* + "Input 2 to Output 2\n"* + " z + 2\n"* + "-----------------\n"* + "z^2 - 0.2*z - 0.1\n"* + "\n"* + "Sample Time: 0.005 (seconds)\n"* + "Discrete-time transfer function model") +@test sprint(show, D_222, 1) == res +res = ("TransferFunction:\n"* + " s - 1.12345\n"* + "4.45678--------------------------\n"* + " (s - 3.67891)(s - 2.54321)\n"* + "\n"* + "Continuous-time transfer function model") +@test sprint(show, zpk([1.12345], [2.54321;3.67891], 4.45678)) == res +res = ("TransferFunction:\n"* + " s - 1.1\n"* + "4.5------------------\n"* + " (s - 3.7)(s - 2.5)\n"* + "\n"* + "Continuous-time transfer function model") +@test sprint(show, zpk([1.12345], [2.54321;3.67891], 4.45678), 2) == res # Type stability Continuous-time @test eltype(fill(tf("s"),2)) <: TransferFunction From 1d892e6fe0ef56a4c98f9ea322650c23b274c5b7 Mon Sep 17 00:00:00 2001 From: jacobhuesman Date: Fri, 31 Aug 2018 11:46:31 -0700 Subject: [PATCH 5/5] Updated documentation --- docs/mkdocs.yml | 1 + docs/src/index.md | 4 ++-- docs/src/lib/display.md | 10 ++++++++++ src/ControlSystems.jl | 5 ++++- src/types/transferfunction.jl | 26 ++++++++++++++++++++++++++ 5 files changed, 43 insertions(+), 3 deletions(-) create mode 100644 docs/src/lib/display.md diff --git a/docs/mkdocs.yml b/docs/mkdocs.yml index d463e62fb..a00b02608 100644 --- a/docs/mkdocs.yml +++ b/docs/mkdocs.yml @@ -32,3 +32,4 @@ pages: - Synthesis: 'lib/synthesis.md' - 'Time and Frequency response': 'lib/timefreqresponse.md' - Plotting: 'lib/plotting.md' + - Display: 'lib/display.md' diff --git a/docs/src/index.md b/docs/src/index.md index 1dee196f2..60f975d1d 100644 --- a/docs/src/index.md +++ b/docs/src/index.md @@ -20,12 +20,12 @@ Depth = 1 ## Functions ```@contents -Pages = ["lib/constructors.md", "lib/plotting.md"] +Pages = ["lib/constructors.md", "lib/plotting.md", "lib/display.md"] ``` ## Documentation Index ```@index -Pages = ["lib/constructors.md", "lib/plotting.md", "lib/syntheis.md", "lib/timefreqresponse.md", "lib/analysis.md"] +Pages = ["lib/constructors.md", "lib/plotting.md", "lib/syntheis.md", "lib/timefreqresponse.md", "lib/analysis.md", "lib/display.md"] Depth = 1 ``` diff --git a/docs/src/lib/display.md b/docs/src/lib/display.md new file mode 100644 index 000000000..084fc0ee6 --- /dev/null +++ b/docs/src/lib/display.md @@ -0,0 +1,10 @@ +```@index +Pages = ["display.md"] +``` + +# Displaying Transfer Functions + +```@docs +print +show +``` diff --git a/src/ControlSystems.jl b/src/ControlSystems.jl index be71b3753..dc4fd343a 100644 --- a/src/ControlSystems.jl +++ b/src/ControlSystems.jl @@ -65,7 +65,10 @@ export LTISystem, sigma, # utilities numpoly, - denpoly + denpoly, + # display + show, + print using Plots, LaTeXStrings, Requires, Formatting import Base: +, -, *, /, (./), (==), (.+), (.-), (.*), (!=), isapprox, convert, promote_op diff --git a/src/types/transferfunction.jl b/src/types/transferfunction.jl index b63a875df..cfab53e68 100644 --- a/src/types/transferfunction.jl +++ b/src/types/transferfunction.jl @@ -461,9 +461,35 @@ end ## Display Functions ## ##################################################################### +@doc """`print(io::IO, t::TransferFunction, precision::Int=-1)` + +Print a string representation of the transfer function: + +`io`: the `IO` stream to print to + +`t`: the transfer function + +`precision`: the precision to round each number to (default is 5) + +Other uses: + +`print(t::TransferFunction, precision::Int=-1)`: prints to `STDOUT`""" -> Base.print(io::IO, t::TransferFunction, precision::Int=-1) = show(io, t, precision) Base.print(t::TransferFunction, precision::Int=-1) = show(t, precision) +@doc """`show(io::IO, t::TransferFunction, precision::Int=-1)` + +Print a string representation of the transfer function: + +`io`: the `IO` stream to print to + +`t`: the transfer function + +`precision`: the precision to round each number to (default is 5) + +Other uses: + +`show(t::TransferFunction, precision::Int=-1)`: prints to `STDOUT`""" -> function Base.show(io::IO, t::TransferFunction, precision::Int=-1) # Compose the name vectors inputs = format_names(t.inputnames, "Input ", "?")