@@ -14,15 +14,14 @@ export Pade, padeval
14
14
15
15
import Base: length, endof, getindex, setindex!, copy, zero, one, convert, norm, gcd
16
16
import Base: show, print, * , / , // , - , + , == , divrem, div, rem, eltype, .* , .- , .+
17
- import Base: promote_rule, truncate, chop
18
- if VERSION >= v " 0.4"
19
- import Base. call
20
- end
17
+ import Base: promote_rule, truncate, chop, call, conj, transpose, dot, hash
18
+ import Base: isequal
21
19
22
20
eps {T} (:: Type{T} ) = zero (T)
23
21
eps {F<:AbstractFloat} (x:: Type{F} ) = Base. eps (F)
24
22
eps {T} (x:: Type{Complex{T}} ) = eps (T)
25
23
24
+ typealias SymbolLike Union{AbstractString,Char,Symbol}
26
25
27
26
"""
28
27
@@ -60,22 +59,22 @@ p + q # ERROR: Polynomials must have same variable.
60
59
```
61
60
62
61
"""
63
- immutable Poly{T<: Number }
64
- a:: Vector{T}
65
- var:: Symbol
66
- function Poly (a:: Vector{T} , var)
67
- # if a == [] we replace it with a = [0]
68
- if length (a) == 0
69
- return new (zeros (T,1 ), @compat Symbol (var))
70
- else
71
- # determine the last nonzero element and truncate a accordingly
72
- a_last = max (1 ,findlast (x-> x!= zero (T), a))
73
- new (a[1 : a_last], @compat Symbol (var))
74
- end
62
+ immutable Poly{T}
63
+ a:: Vector{T}
64
+ var:: Symbol
65
+ @compat function (:: Type{Poly} ){T<: Number }(a:: Vector{T} , var:: SymbolLike = :x )
66
+ # if a == [] we replace it with a = [0]
67
+ if length (a) == 0
68
+ return new {T} (zeros (T,1 ), @compat Symbol (var))
69
+ else
70
+ # determine the last nonzero element and truncate a accordingly
71
+ a_last = max (1 ,findlast (x-> x!= zero (T), a))
72
+ new {T} (a[1 : a_last], @compat Symbol (var))
75
73
end
74
+ end
76
75
end
77
76
78
- @compat Poly {T<:Number} (a :: Vector{T} , var:: Union{AbstractString,Symbol,Char} = :x ) = Poly {T} (a , var)
77
+ Poly (n :: Number , var:: SymbolLike = :x ) = Poly ([n] , var)
79
78
80
79
# create a Poly object from its roots
81
80
"""
@@ -90,7 +89,7 @@ Example:
90
89
poly([1,2,3]) # Poly(-6 + 11x - 6x^2 + x^3)
91
90
```
92
91
"""
93
- function poly {T} (r:: AbstractVector{T} , var= :x )
92
+ function poly {T} (r:: AbstractVector{T} , var:: SymbolLike = :x )
94
93
n = length (r)
95
94
c = zeros (T, n+ 1 )
96
95
c[1 ] = one (T)
@@ -101,9 +100,7 @@ function poly{T}(r::AbstractVector{T}, var=:x)
101
100
end
102
101
return Poly (reverse (c), var)
103
102
end
104
- poly (A:: Matrix , var= :x ) = poly (eigvals (A), var)
105
- poly (A:: Matrix , var:: AbstractString ) = poly (eigvals (A), @compat Symbol (var))
106
- poly (A:: Matrix , var:: Char ) = poly (eig (A)[1 ], @compat Symbol (var))
103
+ poly (A:: Matrix , var:: SymbolLike = :x ) = poly (eigvals (A), var)
107
104
108
105
109
106
include (" show.jl" ) # display polynomials.
@@ -148,9 +145,9 @@ Return the indeterminate of a polynomial, `x`.
148
145
* `variable([var::Symbol])`: return polynomial 1x over `Float64`.
149
146
150
147
"""
151
- variable {T<:Number} (:: Type{T} , var= :x ) = Poly ([zero (T), one (T)], var)
148
+ variable {T<:Number} (:: Type{T} , var:: SymbolLike = :x ) = Poly ([zero (T), one (T)], var)
152
149
variable {T} (p:: Poly{T} ) = variable (T, p. var)
153
- variable (var:: Symbol = :x ) = variable (Float64, var)
150
+ variable (var:: SymbolLike = :x ) = variable (Float64, var)
154
151
155
152
"""
156
153
@@ -206,7 +203,10 @@ norm(q::Poly, args...) = norm(coeffs(q), args...)
206
203
* `conj(p::Poly`): return conjugate of polynomial `p`. (Polynomial with conjugate of each coefficient.)
207
204
208
205
"""
209
- Base. conj {T<:Complex} (p:: Poly{T} ) = Poly (conj (coeffs (p)))
206
+ conj {T<:Complex} (p:: Poly{T} ) = Poly (conj (coeffs (p)))
207
+
208
+ # Define the no-op `transpose` explicitly to avoid future warnings in Julia
209
+ transpose (p:: Poly ) = p
210
210
211
211
"""
212
212
@@ -228,21 +228,22 @@ function setindex!(p::Poly, vs, idx::AbstractArray)
228
228
[setindex! (p, v, i) for (i,v) in zip (idx, vs)]
229
229
p
230
230
end
231
- Base. eachindex {T} (p:: Poly{T} ) = 0 : (length (p)- 1 )
231
+ eachindex {T} (p:: Poly{T} ) = 0 : (length (p)- 1 )
232
+
232
233
233
-
234
234
copy (p:: Poly ) = Poly (copy (p. a), p. var)
235
235
236
- zero {T} (p:: Poly{T} ) = Poly ([ zero (T) ], p. var)
236
+ zero {T} (p:: Poly{T} ) = Poly (T[ ], p. var)
237
237
zero {T} (:: Type{Poly{T}} ) = Poly (T[])
238
238
one {T} (p:: Poly{T} ) = Poly ([one (T)], p. var)
239
239
one {T} (:: Type{Poly{T}} ) = Poly ([one (T)])
240
240
241
241
# # Overload arithmetic operators for polynomial operations between polynomials and scalars
242
242
* {T<: Number ,S}(c:: T , p:: Poly{S} ) = Poly (c * p. a, p. var)
243
243
* {T<: Number ,S}(p:: Poly{S} , c:: T ) = Poly (p. a * c, p. var)
244
- Base. dot {T<:Number,S} (p:: Poly{S} , c:: T ) = p * c
245
- Base. dot {T<:Number,S} (c:: T , p:: Poly{S} ) = c * p
244
+ dot {T<:Number,S} (p:: Poly{S} , c:: T ) = p * c
245
+ dot {T<:Number,S} (c:: T , p:: Poly{S} ) = c * p
246
+ dot (p1:: Poly , p2:: Poly ) = p1 * p2
246
247
.* {T<: Number ,S}(c:: T , p:: Poly{S} ) = Poly (c * p. a, p. var)
247
248
.* {T<: Number ,S}(p:: Poly{S} , c:: T ) = Poly (p. a * c, p. var)
248
249
/ (p:: Poly , c:: Number ) = Poly (p. a / c, p. var)
@@ -336,7 +337,6 @@ function divrem{T, S}(num::Poly{T}, den::Poly{S})
336
337
return pQ, pR
337
338
end
338
339
339
- @deprecate / (num:: Poly , den:: Poly ) div (num:: Poly , den:: Poly )
340
340
div (num:: Poly , den:: Poly ) = divrem (num, den)[1 ]
341
341
rem (num:: Poly , den:: Poly ) = divrem (num, den)[2 ]
342
342
@@ -348,7 +348,8 @@ function ==(p1::Poly, p2::Poly)
348
348
end
349
349
end
350
350
351
- Base. hash (f:: Poly , h:: UInt ) = hash (f. var, hash (f. a, h))
351
+ hash (f:: Poly , h:: UInt ) = hash (f. var, hash (f. a, h))
352
+ isequal (p1:: Poly , p2:: Poly ) = hash (p1) == hash (p2)
352
353
353
354
"""
354
355
* `polyval(p::Poly, x::Number)`: Evaluate the polynomial `p` at `x` using Horner's method.
@@ -372,19 +373,17 @@ function polyval{T,S}(p::Poly{T}, x::S)
372
373
if lenp == 0
373
374
return zero (R) * x
374
375
else
375
- y = convert (R, p[end ]) + zero (T) * x
376
+ y = convert (R, p[end ])
376
377
for i = (endof (p)- 1 ): - 1 : 0
377
378
y = p[i] + x* y
378
379
end
379
380
return y
380
381
end
381
382
end
382
383
383
- polyval (p:: Poly , v:: AbstractVector ) = map (x-> polyval (p, x), v)
384
+ polyval (p:: Poly , v:: AbstractArray ) = map (x-> polyval (p, x), v)
384
385
385
- if VERSION >= v " 0.4"
386
- @compat (p:: Poly )(x) = polyval (p, x)
387
- end
386
+ @compat (p:: Poly )(x) = polyval (p, x)
388
387
389
388
"""
390
389
@@ -399,9 +398,33 @@ polyint(Poly([1, 0, -1]), 2) # Poly(2.0 + x - 0.3333333333333333x^3)
399
398
```
400
399
401
400
"""
402
- function polyint {T} (p:: Poly{T} , k:: Number = 0 )
401
+ # if we do not have any initial condition, assume k = zero(Int)
402
+ polyint {T} (p:: Poly{T} ) = polyint (p, 0 )
403
+
404
+ # if we have coefficients that have `NaN` representation
405
+ function polyint {T<:Union{Real,Complex},S<:Number} (p:: Poly{T} , k:: S )
406
+ any (isnan (p. a)) && return Poly (promote_type (T,S)[NaN ])
407
+ _polyint (p, k)
408
+ end
409
+
410
+ # if we have initial condition that can represent `NaN`
411
+ function polyint {T,S<:Union{Real,Complex}} (p:: Poly{T} , k:: S )
412
+ isnan (k) && return Poly (promote_type (T,S)[NaN ])
413
+ _polyint (p, k)
414
+ end
415
+
416
+ # if we have both coefficients and initial condition that can take `NaN`
417
+ function polyint {T<:Union{Real,Complex},S<:Union{Real,Complex}} (p:: Poly{T} , k:: S )
418
+ (any (isnan (p. a)) || isnan (k)) && return Poly (promote_type (T,S)[NaN ])
419
+ _polyint (p, k)
420
+ end
421
+
422
+ # otherwise, catch all
423
+ polyint {T,S<:Number} (p:: Poly{T} , k:: S ) = _polyint (p, k)
424
+
425
+ function _polyint {T,S<:Number} (p:: Poly{T} , k:: S )
403
426
n = length (p)
404
- R = typeof (one (T)/ 1 )
427
+ R = promote_type ( typeof (one (T)/ 1 ), S )
405
428
a2 = Array (R, n+ 1 )
406
429
a2[1 ] = k
407
430
for i = 1 : n
@@ -421,30 +444,37 @@ Example:
421
444
polyder(Poly([1, 3, -1])) # Poly(3 - 2x)
422
445
```
423
446
"""
447
+ # if we have coefficients that can represent `NaN`s
448
+ function polyder {T<:Union{Real,Complex}} (p:: Poly{T} , order:: Int = 1 )
449
+ n = length (p)
450
+ order < 0 && error (" Order of derivative must be non-negative" )
451
+ order == 0 && return p
452
+ any (isnan (p. a)) && return Poly (T[NaN ], p. var)
453
+ n <= order && return Poly (T[], p. var)
454
+ _polyder (p, order)
455
+ end
456
+
457
+ # otherwise
424
458
function polyder {T} (p:: Poly{T} , order:: Int = 1 )
425
- n = length (p)
426
- if order < 0
427
- error (" Order of derivative must be non-negative" )
428
- elseif n <= order
429
- return Poly (zeros (T,0 ),p. var)
430
- elseif order == 0
431
- return p
432
- else
433
- a2 = Array (T, n- order)
434
- for i = order: n- 1
435
- a2[i- order+ 1 ] = p[i] * prod ((i- order+ 1 ): i)
436
- end
437
- return Poly (a2, p. var)
438
- end
459
+ n = length (p)
460
+ order < 0 && error (" Order of derivative must be non-negative" )
461
+ order == 0 && return p
462
+ n <= order && return Poly (T[], p. var)
463
+ _polyder (p, order)
439
464
end
440
- Base. ctranspose {T} (p:: Poly{T} ) = polyder (p)
441
465
442
- polyint {T} (a:: Array{Poly{T},1} , k:: Number = 0 ) = [ polyint (p,k) for p in a ]
443
- polyder {T} (a:: Array{Poly{T},1} , order:: Int = 1 ) = [ polyder (p,order) for p in a ]
444
- polyint {n,T} (a:: Array{Poly{T},n} , k:: Number = 0 ) = map (p-> polyint (p,k),a)
445
- polyder {n,T} (a:: Array{Poly{T},n} , order:: Int = 1 ) = map (p-> polyder (p,order),a)
466
+ function _polyder {T} (p:: Poly{T} , order:: Int = 1 )
467
+ n = length (p)
468
+ a2 = Array (T, n- order)
469
+ for i = order: n- 1
470
+ a2[i- order+ 1 ] = p[i] * prod ((i- order+ 1 ): i)
471
+ end
446
472
473
+ return Poly (a2, p. var)
474
+ end
447
475
476
+ polyint {T} (a:: AbstractArray{Poly{T}} , k:: Number = 0 ) = map (p-> polyint (p,k), a)
477
+ polyder {T} (a:: AbstractArray{Poly{T}} , order:: Int = 1 ) = map (p-> polyder (p,order),a)
448
478
449
479
# #################################################
450
480
# #
0 commit comments