You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: src/polynomials/LaurentPolynomial.jl
+51-17Lines changed: 51 additions & 17 deletions
Original file line number
Diff line number
Diff line change
@@ -8,7 +8,7 @@ A [Laurent](https://en.wikipedia.org/wiki/Laurent_polynomial) polynomial is of t
8
8
The `coeffs` specify `a_{m}, a_{m-1}, ..., a_{n}`. The range specified is of the form `m:n`, if left empty, `0:length(coeffs)-1` is used (i.e., the coefficients refer to the standard basis). Alternatively, the coefficients can be specified using an `OffsetVector` from the `OffsetArrays` package.
9
9
10
10
Laurent polynomials and standard basis polynomials promote to Laurent polynomials. Laurent polynomials may be converted to a standard basis polynomial when `m >= 0`
11
-
.
11
+
.
12
12
13
13
Integration will fail if there is a `x⁻¹` term in the polynomial.
14
14
@@ -203,7 +203,7 @@ function Base.setindex!(p::LaurentPolynomial{T}, value::Number, idx::Int) where
Call `p̂ = paraconj(p)` and `p̄` = conj(p)`, then this satisfies
317
+
Call `p̂ = paraconj(p)` and `p̄` = conj(p)`, then this satisfies
318
318
`conj(p(z)) = p̂(1/conj(z))` or `p̂(z) = p̄(1/z) = (conj ∘ p ∘ conj ∘ inf)(z)`.
319
319
320
320
Examples:
@@ -364,7 +364,7 @@ julia> s = 2im
364
364
julia> p = LaurentPolynomial([im,-1, -im, 1], 1:2, :s)
365
365
LaurentPolynomial(im*s - s² - im*s³ + s⁴)
366
366
367
-
julia> Polynomials.cconj(p)(s) ≈ conj(p(s))
367
+
julia> Polynomials.cconj(p)(s) ≈ conj(p(s))
368
368
true
369
369
370
370
julia> a = LaurentPolynomial([-0.12, -0.29, 1],:s)
@@ -415,8 +415,8 @@ function (p::LaurentPolynomial{T})(x::S) where {T,S}
415
415
l + r - mid
416
416
end
417
417
end
418
-
419
-
418
+
419
+
420
420
421
421
# scalar operattoinis
422
422
Base.:-(p::P) where {P <:LaurentPolynomial} =P(-coeffs(p), range(p), p.var)
@@ -447,7 +447,7 @@ function Base.:+(p1::P1, p2::P2) where {T,P1<:LaurentPolynomial{T}, S, P2<:Laure
447
447
elseifisconstant(p2)
448
448
p2 =P2(p2.coeffs, range(p2), p1.var)
449
449
end
450
-
450
+
451
451
p1.var != p2.var &&error("LaurentPolynomials must have same variable")
452
452
453
453
R =promote_type(T,S)
@@ -465,7 +465,7 @@ function Base.:+(p1::P1, p2::P2) where {T,P1<:LaurentPolynomial{T}, S, P2<:Laure
465
465
chop!(q)
466
466
467
467
return q
468
-
468
+
469
469
end
470
470
471
471
function Base.:*(p1::LaurentPolynomial{T}, p2::LaurentPolynomial{S}) where {T,S}
@@ -495,11 +495,45 @@ function Base.:*(p1::LaurentPolynomial{T}, p2::LaurentPolynomial{S}) where {T,S}
495
495
return p
496
496
end
497
497
498
+
##
499
+
## roots
500
+
##
501
+
"""
502
+
roots(p)
503
+
504
+
Compute the roots of the Laurent polynomial `p`.
505
+
506
+
The roots of a function (Laurent polynomial in this case) `a(z)` are the values of `z` for which the function vanishes. A Laurent polynomial ``a(z) = a_m z^m + a_{m+1} z^{m+1} + ... + a_{-1} z^{-1} + a_0 + a_1 z + ... + a_{n-1} z^{n-1} + a_n z^n`` can equivalently be viewed as a rational function with a multiple singularity (pole) at the origin. The roots are then the roots of the numerator polynomial. For example, ``a(z) = 1/z + 2 + z`` can be written as ``a(z) = (1+2z+z^2) / z`` and the roots of `a` are the roots of ``1+2z+z^2``.
507
+
508
+
# Example
509
+
510
+
```julia
511
+
julia> p = LaurentPolynomial([24,10,-15,0,1],-2:1,:z)
512
+
LaurentPolynomial(24*z⁻² + 10*z⁻¹ - 15 + z²)
513
+
514
+
julia> roots(a)
515
+
4-element Array{Float64,1}:
516
+
-3.999999999999999
517
+
-0.9999999999999994
518
+
1.9999999999999998
519
+
2.9999999999999982
520
+
```
521
+
"""
522
+
functionroots(p::P; kwargs...) where {T, P <:LaurentPolynomial{T}}
523
+
c =coeffs(p)
524
+
r =range(p)
525
+
d = r[end]-min(0,r[1])+1# Length of the coefficient vector, taking into consideration the case when the lower degree is strictly positive (like p=3z^2).
526
+
z =zeros(T,d) # Reserves space for the coefficient vector.
527
+
z[max(0,r[1])+1:end] = c # Leaves the coeffs of the lower powers as zeros.
528
+
a =Polynomial(z,p.var) # The root is then the root of the numerator polynomial.
529
+
returnroots(a; kwargs...)
530
+
end
531
+
498
532
##
499
533
## d/dx, ∫
500
534
##
501
535
functionderivative(p::P, order::Integer=1) where {T, P<:LaurentPolynomial{T}}
502
-
536
+
503
537
order <0&&error("Order of derivative must be non-negative")
504
538
order ==0&&return p
505
539
@@ -518,9 +552,9 @@ function derivative(p::P, order::Integer = 1) where {T, P<:LaurentPolynomial{T}}
518
552
as[idx] =reduce(*, (k - order +1):k, init = p[k])
519
553
end
520
554
end
521
-
555
+
522
556
chop!(LaurentPolynomial(as, m:n, p.var))
523
-
557
+
524
558
end
525
559
526
560
@@ -546,15 +580,15 @@ function integrate(p::P, k::S) where {T, P<: LaurentPolynomial{T}, S<:Number}
546
580
m =0
547
581
end
548
582
as =zeros(R, length(m:n))
549
-
583
+
550
584
for k ineachindex(p)
551
585
as[1+ k+1-m] = p[k]/(k+1)
552
586
end
553
587
554
588
as[1-m] = k
555
589
556
590
return⟒(P)(as, m:n, p.var)
557
-
591
+
558
592
end
559
593
560
594
@@ -568,7 +602,7 @@ function Base.gcd(p::LaurentPolynomial{T}, q::LaurentPolynomial{T}, args...; kwa
568
602
degree(p) ==0&&returniszero(p) ? q :one(q)
569
603
degree(q) ==0&&returniszero(q) ? p :one(p)
570
604
check_same_variable(p,q) ||throw(ArgumentError("p and q have different symbols"))
0 commit comments