Skip to content

Commit 723da50

Browse files
committed
update show
1 parent c08fc69 commit 723da50

File tree

3 files changed

+190
-63
lines changed

3 files changed

+190
-63
lines changed

src/Polynomials.jl

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,16 @@ variable(var::Symbol=:x) = poly([0.0], var)
156156
`truncate{T}(p::Poly{T}; reltol = eps(T), abstol = eps(T))`: returns a polynomial with coefficients a_i truncated to zero if |a_i| <= reltol*maxabs(a)+abstol
157157
158158
"""
159+
function truncate{T}(p::Poly{Complex{T}}; reltol = eps(T), abstol = eps(T))
160+
a = coeffs(p)
161+
amax = maxabs(a)
162+
thresh = amax * reltol + abstol
163+
anew = map(ai -> complex(abs(real(ai)) <= thresh ? zero(T) : real(ai),
164+
abs(imag(ai)) <= thresh ? zero(T) : imag(ai)),
165+
a)
166+
return Poly(anew, p.var)
167+
end
168+
159169
function truncate{T}(p::Poly{T}; reltol = eps(T), abstol = eps(T))
160170
a = coeffs(p)
161171
amax = maxabs(a)
@@ -217,7 +227,9 @@ function setindex!(p::Poly, vs, idx::AbstractArray)
217227
[setindex!(p, v, i) for (i,v) in zip(idx, vs)]
218228
p
219229
end
230+
Base.eachindex{T}(p::Poly{T}) = 0:(length(p)-1)
220231

232+
221233
copy(p::Poly) = Poly(copy(p.a), p.var)
222234

223235
zero{T}(p::Poly{T}) = Poly([zero(T)], p.var)

src/show.jl

Lines changed: 160 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,86 +1,183 @@
1+
## real numbers should pritn 1.0, not suppress?
12

2-
function show(io::IO, p::Poly)
3-
print(io,"Poly(")
4-
print(io,p)
5-
print(io,")")
3+
## Poly{T} is basically T[x]
4+
## T[x] may not have an order
5+
6+
## to handle this case we create some functions
7+
## which can be modified by users for other Ts
8+
9+
"`hasneg(::T)` attribute is true if: `pj < zero(T)` is defined."
10+
hasneg{T}(::Type{T}) = true
11+
12+
"Could value possibly be negative and if so, is it?"
13+
isneg{T}(pj::T) = hasneg(T) && pj < zero(T)
14+
15+
"Make `pj` positive if it is negative. (Don't call `abs` as that may not be defined, or appropriate.)"
16+
aspos{T}(pj::T) = (hasneg(T) && isneg(pj)) ? -pj : pj
17+
18+
"Should a value of `one(T)` be shown as a coefficient of monomial `x^i`, `i >= 1`? (`1.0x^2` is shown, `1 x^2` is not)"
19+
showone{T}(::Type{T}) = true
20+
21+
22+
#####
23+
24+
## Numbers
25+
showone{T<:Integer}(::Type{T}) = false
26+
showone{T}(::Type{Rational{T}}) = false
27+
28+
29+
## Polynomials as coefficients
30+
hasneg{S}(::Type{Poly{S}}) = false
31+
showoone{S}(::Type{Poly{S}}) = false
32+
33+
34+
35+
## Complex coefficients
36+
## we say neg if real(z) < 0 || real(z) == 0 and imag(g) < 0
37+
hasneg{T}(::Type{Complex{T}}) = true
38+
39+
function isneg{T}(pj::Complex{T})
40+
real(pj) < 0 && return true
41+
(real(pj) == 0 && imag(pj) < 0) && return(true)
42+
return false
643
end
744

8-
function printexponent(io,var,i)
9-
if i == 0
10-
elseif i == 1
11-
print(io,var)
12-
else
13-
print(io,var,"^",i)
45+
showone{T}(pj::Type{Complex{T}}) = showone(T)
46+
47+
48+
49+
"Show different operations depending on mimetype. `l-` is leading minus sign."
50+
function showop(::MIME"text/html", op)
51+
d = Dict("*" => "&times;", "+" => " &#43; ", "-" => " &#45; ", "l-" => "&#45;")
52+
d[op]
53+
end
54+
55+
function showop(::MIME"text/latex", op)
56+
d = Dict("*" => "\\cdot ", "+" => " + ", "-" => " - ", "l-" => "-")
57+
d[op]
58+
end
59+
60+
function showop(::MIME"text/plain", op)
61+
d = Dict("*" => "", "+" => " + ", "-" => " - ", "l-" => "-")
62+
d[op]
63+
end
64+
65+
66+
67+
###
68+
69+
function printpoly{T}(io::IO, p::Poly{T}, mimetype)
70+
first = true
71+
printed_anything = false
72+
for i in eachindex(p)
73+
printed = showterm(io,p,i,first, mimetype)
74+
first &= !printed
75+
printed_anything |= printed
1476
end
77+
printed_anything || print(io, zero(T))
1578
end
1679

17-
function printterm{T}(io::IO,p::Poly{T},j,first)
80+
function showterm{T}(io::IO,p::Poly{T},j,first, mimetype)
1881
pj = p[j]
19-
if pj == zero(T)
20-
return false
21-
end
22-
neg = pj < zero(T)
23-
if first
24-
neg && print(io, "-") #Prepend - if first and negative
25-
else
26-
neg ? print(io, " - ") : print(io," + ")
27-
end
28-
pj = abs(pj)
29-
if pj != one(T) || j == 0
30-
show(io,pj)
31-
j != 0 && print(io, "")
32-
end
33-
printexponent(io,p.var,j)
82+
pj == zero(T) && return false
83+
84+
pj = printsign(io, pj, j, first, mimetype)
85+
printcoefficient(io, pj, j, mimetype)
86+
printproductsign(io, pj, j, mimetype)
87+
printexponent(io,p.var,j, mimetype)
3488
true
3589
end
3690

37-
function printterm{T<:Complex}(io::IO,p::Poly{T},j,first)
38-
pj = p[j]
39-
abs_repj = abs(real(pj))
40-
abs_impj = abs(imag(pj))
41-
if abs_repj < 2*eps(T) && abs_impj < 2*eps(T)
42-
return false
43-
end
4491

45-
# We show a negative sign either for any complex number with negative
46-
# real part (and then negate the immaginary part) of for complex
47-
# numbers that are pure imaginary with negative imaginary part
48-
49-
neg = ((abs_repj > 2*eps(T)) && real(pj) < 0) ||
50-
((abs_impj > 2*eps(T)) && imag(pj) < 0)
5192

93+
## print the sign
94+
## returns aspos(pj)
95+
function printsign{T}(io::IO, pj::T, j, first, mimetype)
96+
neg = isneg(pj)
5297
if first
53-
neg && print(io, "-") #Prepend - if first and negative
98+
neg && print(io, showop(mimetype, "l-")) #Prepend - if first and negative
5499
else
55-
neg ? print(io," - ") : print(io," + ")
100+
neg ? print(io, showop(mimetype, "-")) : print(io,showop(mimetype, "+"))
56101
end
102+
103+
aspos(pj)
104+
end
105+
106+
## print * or cdot, ...
107+
function printproductsign{T}(io::IO, pj::T, j, mimetype)
108+
j == 0 && return
109+
(showone(T) || pj != one(T)) && print(io, showop(mimetype, "*"))
110+
end
111+
112+
function printcoefficient{T}(io::IO, pj::Complex{T}, j, mimetype)
113+
114+
hasreal = abs(real(pj)) > 0
115+
hasimag = abs(imag(pj)) > 0
57116

58-
if abs_repj > 2*eps(T) #Real part is not 0
59-
if abs_impj > 2*eps(T) #Imag part is not 0
60-
print(io,'(',neg ? -pj : pj,')')
61-
else
62-
print(io, neg ? -real(pj) : real(pj))
63-
end
117+
if hasreal & hasimag
118+
print(io, '(')
119+
showio(io, mimetype, pj)
120+
print(io, ')')
121+
elseif hasreal
122+
a = real(pj)
123+
(showone(T) || a != one(T)) && show(io, mimetype, a)
124+
elseif hasimag
125+
b = imag(pj)
126+
(showone(T) || b != one(T)) && show(io, mimetype, b)
127+
show(io, mimetype, im)
64128
else
65-
if abs_impj > 2*eps(T)
66-
print(io,'(', abs(imag(pj)),"im)")
67-
end
129+
return
68130
end
131+
end
69132

70-
abs(abs_repj) != 1 && j != 0 && print(io, "")
71-
72-
printexponent(io, p.var,j)
73-
true
133+
134+
## show a single term
135+
function printcoefficient{T}(io::IO, pj::T, j, mimetype)
136+
pj == one(T) && !(showone(T) || j == 0) && return
137+
show(io, mimetype, pj)
74138
end
75139

76-
function print{T}(io::IO, p::Poly{T})
77-
first = true
78-
printed_anything = false
79-
n = length(p)-1
80-
for i = 0:n
81-
printed = printterm(io,p,i,first)
82-
first &= !printed
83-
printed_anything |= printed
140+
function printexponent(io,var,i, mimetype::MIME"text/latex")
141+
if i == 0
142+
return
143+
elseif i == 1
144+
print(io,var)
145+
else
146+
print(io,var,"^{$i}")
147+
end
148+
end
149+
150+
function printexponent(io,var,i, mimetype)
151+
if i == 0
152+
return
153+
elseif i == 1
154+
print(io,var)
155+
else
156+
print(io,var,"^",i)
84157
end
85-
printed_anything || print(io,zero(T))
158+
end
159+
160+
161+
####
162+
163+
@compat Base.show{T}(io::IO, p::Poly{T}) = show(io, MIME("text/plain"), p)
164+
@compat function Base.show{T}(io::IO, mimetype::MIME"text/plain", p::Poly{T})
165+
print(io,"Poly(")
166+
printpoly(io, p, mimetype)
167+
print(io,")")
168+
169+
end
170+
171+
@compat function Base.show{T}(io::IO, mimetype::MIME"text/latex", p::Poly{T})
172+
print(io, "\$")
173+
printpoly(io, p, mimetype)
174+
print(io, "\$")
175+
end
176+
177+
@compat function Base.show{T}(io::IO, mimetype::MIME"text/latex", a::Rational{T})
178+
abs(a.den) == one(T) ? print(io, a.num) : print(io, "\\frac{$(a.num)}{$(a.den)}")
179+
end
180+
181+
@compat function Base.show{T<:Number}(io::IO, mimetype::MIME"text/latex", a::T)
182+
print(io, a)
86183
end

test/runtests.jl

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,3 +196,21 @@ p1 = Poly([1,2])
196196
p2 = convert(Poly{Int64}, p1)
197197
p2[3] = 3
198198
@test p1[3] == 3
199+
200+
201+
## changes to show
202+
p = Poly([1,2,3,1]) # leading coefficient of 1
203+
@test string(p) == "Poly(1 + 2⋅x + 3⋅x^2 + x^3)"
204+
p = Poly([1.0, 2.0, 3.0, 1.0])
205+
@test string(p) == "Poly(1.0 + 2.0⋅x + 3.0⋅x^2 + 1.0⋅x^3)"
206+
p = Poly([1+im, 1-im, -1+im, -1 - im])# minus signs
207+
@test string(p) == "Poly((1 + 1im) + (1 - 1im)⋅x - (1 - 1im)⋅x^2 - (1 + 1im)⋅x^3)"
208+
209+
string_eval_poly(p,x) = eval(Expr(:function, Expr(:call, :f, :x), parse(string(p)[6:end-1])))(x)
210+
p = Poly([1,2,3]) # copy and paste
211+
q = Poly([1//1, 2//1, 3//1])
212+
r = Poly([1.0, 2, 3])
213+
@test string_eval_poly(p, 5) == p(5)
214+
@test string_eval_poly(q, 5) == q(5)
215+
@test string_eval_poly(r, 5) == r(5)
216+

0 commit comments

Comments
 (0)