diff --git a/docs/src/userguide.md b/docs/src/userguide.md index 737e3fa1..a5b76a5f 100644 --- a/docs/src/userguide.md +++ b/docs/src/userguide.md @@ -47,7 +47,9 @@ t = shift_taylor(0.0) # Independent variable `t` ``` Note that the information about the maximum order considered is displayed -using a big-𝒪 notation. In some cases, it is desirable to not display +using a big-𝒪 notation. The convention followed when different orders are +combined is consistent with the mathematics and the big-𝒪 notation, that is, +to propagate the lowest order. In some cases, it is desirable to not display the big-𝒪 notation. The function [`displayBigO`](@ref) allows to control whether it is displayed or not. ```@repl userguide @@ -69,9 +71,9 @@ t ``` The definition of `shift_taylor(a)` uses the method -[`Taylor1([::Type{Float64}], [order::Int=1])`](@ref), which is a +[`Taylor1([::Type{Float64}], order::Int)`](@ref), which is a shortcut to define the independent variable of a Taylor expansion, -of given type and order (defaults are `Float64` and `order=1`). +of given type and order (the default is `Float64`). This is one of the easiest ways to work with the package. The usual arithmetic operators (`+`, `-`, `*`, `/`, `^`, `==`) have been @@ -87,10 +89,11 @@ t*(t^2-4)/(t+2) tI = im*t (1-t)^3.2 (1+t)^t +Taylor1(3) + Taylor1(5) == 2Taylor1(3) # big-𝒪 convention applies t^6 # t is of order 5 ``` -If no valid Taylor expansion can be computed, an error is thrown, for instance +If no valid Taylor expansion can be computed an error is thrown, for instance, when a derivative is not defined (or simply diverges): ```@repl userguide @@ -104,11 +107,11 @@ are computed recursively. At the moment of this writing, these functions are `exp`, `log`, `sqrt`, the trigonometric functions `sin`, `cos` and `tan`, their inverses, as well as the hyperbolic functions `sinh`, `cosh` and `tanh` and their inverses; -more will be added in the future. Note that this way of obtaining the -Taylor coefficients is not the *laziest* way, in particular for many independent +more functions will be added in the future. Note that this way of obtaining the +Taylor coefficients is not a *lazy* way, in particular for many independent variables. Yet, it is quite efficient, especially for the integration of ordinary differential equations, which is among the applications we have in -mind (see also +mind (see [TaylorIntegration.jl](https://github.com/PerezHz/TaylorIntegration.jl)). ```@repl userguide @@ -144,7 +147,7 @@ functions return the corresponding [`Taylor1`](@ref) expansions. The last coefficient of a derivative is set to zero to keep the same order as the original polynomial; for the integral, an integration constant may be set by the user (the default is zero). The -order of the resulting polynomial is not changed. The value of the +order of the resulting polynomial is kept unchanged. The value of the ``n``-th (``n \ge 0``) derivative is obtained using `derivative(n,a)`, where `a` is a Taylor series. @@ -173,7 +176,7 @@ eBig = evaluate( exp(tBig), one(BigFloat) ) ℯ - eBig ``` -Another way to obtain the value of a `Taylor1` polynomial `p` at a given value `x`, is to call `p` as if it were a function, i.e., `p(x)`: +Another way to obtain the value of a `Taylor1` polynomial `p` at a given value `x`, is to call `p` as if it was a function, i.e., `p(x)`: ```@repl userguide t = Taylor1(15) @@ -186,13 +189,12 @@ p() == p(0.0) # p() is a shortcut to obtain the 0-th order coefficient of `p` ``` Note that the syntax `p(x)` is equivalent to `evaluate(p, x)`, whereas `p()` is -equivalent to `evaluate(p)`. For more details about function-like behavior for a -given type in Julia, see the [Function-like objects](https://docs.julialang.org/en/stable/manual/methods/#Function-like-objects-1) -section of the Julia manual. +equivalent to `evaluate(p)`. -Useful shortcuts are [`taylor_expand`](@ref) are [`update!`](@ref). +Useful shortcuts are [`taylor_expand`](@ref) and [`update!`](@ref). The former returns -the expansion of a function around a given value `t0`. In turn, `update!` +the expansion of a function around a given value `t0`, mimicking the use +of `shift_taylor` above. In turn, `update!` provides an in-place update of a given Taylor polynomial, that is, it shifts it further by the provided amount. @@ -237,7 +239,7 @@ one can specify the variables using a vector of symbols. set_variables([:x, :y], order=10) ``` -Similarly, numbered variables are also available by specifying a single +Similarly, subindexed variables are also available by specifying a single variable name and the optional keyword argument `numvars`: ```@repl userguide @@ -245,7 +247,7 @@ set_variables("α", numvars=3) ``` Alternatively to `set_variables`, [`get_variables`](@ref) can be used if one -doesn't want to change internal dictionaries. `get_variables` returns a vector +does not want to change internal dictionaries. `get_variables` returns a vector of `TaylorN` independent variables of a desired `order` (lesser than `get_order` so the internals doesn't have to change) with the length and variable names defined @@ -300,13 +302,14 @@ the corresponding independent variable, i.e. ``x \to x+a``. As before, the usual arithmetic operators (`+`, `-`, `*`, `/`, `^`, `==`) have been extended to work with [`TaylorN`](@ref) objects, including the -appropriate -promotions to deal with numbers. (Some of the arithmetic operations have -been extended for +appropriate promotions to deal with numbers. +Note that some of the arithmetic operations have been extended for [`HomogeneousPolynomial`](@ref), whenever the result is a -[`HomogeneousPolynomial`](@ref); division, for instance, is not extended.) +[`HomogeneousPolynomial`](@ref); division, for instance, is not extended. +The same convention used for `Taylor1` objects is used when combining +`TaylorN` polynomials of different order. -Also, the elementary functions have been +The elementary functions have also been implemented, again by computing their coefficients recursively: ```@repl userguide diff --git a/src/auxiliary.jl b/src/auxiliary.jl index 4d92cc9e..98741c3b 100644 --- a/src/auxiliary.jl +++ b/src/auxiliary.jl @@ -243,9 +243,11 @@ for T in (:Taylor1, :TaylorN) @eval begin @inline function fixorder(a::$T, b::$T) a.order == b.order && return a, b - a.order < b.order && - return $T(copy(a.coeffs), b.order), $T(copy(b.coeffs), b.order) - return $T(copy(a.coeffs), a.order), $T(copy(b.coeffs), a.order) + minorder, maxorder = minmax(a.order, b.order) + if minorder ≤ 0 + minorder = maxorder + end + return $T(copy(a.coeffs), minorder), $T(copy(b.coeffs), minorder) end end end diff --git a/src/constructors.jl b/src/constructors.jl index 7f3bc0a7..d9ef52f9 100644 --- a/src/constructors.jl +++ b/src/constructors.jl @@ -48,7 +48,6 @@ Taylor1(x::Taylor1{T}) where {T<:Number} = x Taylor1(coeffs::Array{T,1}, order::Int) where {T<:Number} = Taylor1{T}(coeffs, order) Taylor1(coeffs::Array{T,1}) where {T<:Number} = Taylor1(coeffs, length(coeffs)-1) function Taylor1(x::T, order::Int) where {T<:Number} - # v = zeros(T, order+1) v = fill(zero(x), order+1) v[1] = x return Taylor1(v, order) @@ -69,8 +68,8 @@ julia> Taylor1(Rational{Int}, 4) 1//1 t + 𝒪(t⁵) ``` """ -Taylor1(::Type{T}, order::Int=1) where {T<:Number} = Taylor1( [zero(T), one(T)], order) -Taylor1(order::Int=1) = Taylor1(Float64, order) +Taylor1(::Type{T}, order::Int) where {T<:Number} = Taylor1( [zero(T), one(T)], order) +Taylor1(order::Int) = Taylor1(Float64, order) ######################### HomogeneousPolynomial @@ -153,26 +152,31 @@ struct TaylorN{T<:Number} <: AbstractSeries{T} order :: Int function TaylorN{T}(v::Array{HomogeneousPolynomial{T},1}, order::Int) where T<:Number - m = maxorderH(v) - order = max( m, order ) coeffs = zeros(HomogeneousPolynomial{T}, order) - @simd for i in eachindex(v) - @inbounds ord = v[i].order - @inbounds coeffs[ord+1] += v[i] + @inbounds for i in eachindex(v) + ord = v[i].order + if ord ≤ order + coeffs[ord+1] += v[i] + end end new{T}(coeffs, order) end end TaylorN(x::TaylorN{T}) where T<:Number = x -TaylorN(x::Array{HomogeneousPolynomial{T},1}, order::Int) where {T<:Number} = - TaylorN{T}(x, order) -TaylorN(x::Array{HomogeneousPolynomial{T},1}) where {T<:Number} = TaylorN(x,0) -TaylorN(x::HomogeneousPolynomial{T},order::Int) where {T<:Number} = - TaylorN([x], order) -TaylorN(x::HomogeneousPolynomial{T}) where {T<:Number} = TaylorN([x], x.order) +function TaylorN(x::Array{HomogeneousPolynomial{T},1}, order::Int) where {T<:Number} + if order == 0 + order = maxorderH(x) + end + return TaylorN{T}(x, order) +end +TaylorN(x::Array{HomogeneousPolynomial{T},1}) where {T<:Number} = + TaylorN(x, maxorderH(x)) +TaylorN(x::HomogeneousPolynomial{T}, order::Int) where {T<:Number} = + TaylorN( [x], order ) +TaylorN(x::HomogeneousPolynomial{T}) where {T<:Number} = TaylorN(x, x.order) TaylorN(x::T, order::Int) where {T<:Number} = - TaylorN([HomogeneousPolynomial([x], 0)], order) + TaylorN(HomogeneousPolynomial([x], 0), order) # Shortcut to define TaylorN independent variables """ @@ -192,9 +196,11 @@ julia> TaylorN(Rational{Int},2) ``` """ TaylorN(::Type{T}, nv::Int; order::Int=get_order()) where {T<:Number} = - return TaylorN( [HomogeneousPolynomial(T, nv)], order ) + TaylorN( HomogeneousPolynomial(T, nv), order ) TaylorN(nv::Int; order::Int=get_order()) = TaylorN(Float64, nv, order=order) + + # A `Number` which is not an `AbstractSeries` const NumberNotSeries = Union{setdiff(subtypes(Number), [AbstractSeries])...} diff --git a/src/conversion.jl b/src/conversion.jl index 0c8b0dfb..9b82e5d6 100644 --- a/src/conversion.jl +++ b/src/conversion.jl @@ -10,20 +10,16 @@ convert(::Type{Taylor1{T}}, a::Taylor1) where {T<:Number} = Taylor1(convert(Array{T,1}, a.coeffs), a.order) -function convert(::Type{Taylor1{Rational{T}}}, a::Taylor1{S}) where - {T<:Integer, S<:AbstractFloat} +convert(::Type{Taylor1{T}}, a::Taylor1{T}) where {T<:Number} = a - la = length(a.coeffs) - v = Array{Rational{T}}(undef, la) - v .= rationalize.(a[0:la-1]) - return Taylor1(v) -end +convert(::Type{Taylor1{Rational{T}}}, a::Taylor1{S}) where + {T<:Integer, S<:AbstractFloat} = Taylor1(rationalize.(a[:]), a.order) convert(::Type{Taylor1{T}}, b::Array{T,1}) where {T<:Number} = Taylor1(b, length(b)-1) convert(::Type{Taylor1{T}}, b::Array{S,1}) where {T<:Number, S<:Number} = - Taylor1(convert(Array{T,1},b)) + Taylor1(convert(Array{T,1},b), length(b)-1) convert(::Type{Taylor1{T}}, b::S) where {T<:Number, S<:Number} = Taylor1([convert(T,b)], 0) @@ -36,6 +32,9 @@ convert(::Type{Taylor1}, a::T) where {T<:Number} = Taylor1(a, 0) convert(::Type{HomogeneousPolynomial{T}}, a::HomogeneousPolynomial) where {T<:Number} = HomogeneousPolynomial(convert(Array{T,1}, a.coeffs), a.order) +convert(::Type{HomogeneousPolynomial{T}}, a::HomogeneousPolynomial{T}) where {T<:Number} = + a + function convert(::Type{HomogeneousPolynomial{Rational{T}}}, a::HomogeneousPolynomial{S}) where {T<:Integer, S<:AbstractFloat} @@ -63,11 +62,13 @@ convert(::Type{HomogeneousPolynomial}, a::Number) = HomogeneousPolynomial([a],0) convert(::Type{TaylorN{T}}, a::TaylorN) where {T<:Number} = TaylorN( convert(Array{HomogeneousPolynomial{T},1}, a.coeffs), a.order) +convert(::Type{TaylorN{T}}, a::TaylorN{T}) where {T<:Number} = a + convert(::Type{TaylorN{T}}, b::HomogeneousPolynomial{S}) where {T<:Number, S<:Number} = TaylorN( [convert(HomogeneousPolynomial{T}, b)], b.order) convert(::Type{TaylorN{T}}, b::Array{HomogeneousPolynomial{S},1}) where {T<:Number, S<:Number} = - TaylorN( convert(Array{HomogeneousPolynomial{T},1}, b), length(b)-1) + TaylorN( convert(Array{HomogeneousPolynomial{T},1}, b), maxorderH(b)) convert(::Type{TaylorN{T}}, b::S) where {T<:Number, S<:Number} = TaylorN( [HomogeneousPolynomial([convert(T, b)], 0)], 0) @@ -76,7 +77,7 @@ convert(::Type{TaylorN{T}}, b::HomogeneousPolynomial{T}) where {T<:Number} = TaylorN( [b], b.order) convert(::Type{TaylorN{T}}, b::Array{HomogeneousPolynomial{T},1}) where {T<:Number} = - TaylorN( b, length(b)-1) + TaylorN( b, maxorderH(b)) convert(::Type{TaylorN{T}}, b::T) where {T<:Number} = TaylorN( [HomogeneousPolynomial([b], 0)], 0) @@ -84,7 +85,7 @@ convert(::Type{TaylorN{T}}, b::T) where {T<:Number} = convert(::Type{TaylorN}, b::Number) = TaylorN( [HomogeneousPolynomial([b], 0)], 0) -function convert(::Type{TaylorN{Taylor1{T}}}, s::Taylor1{TaylorN{T}}) where {T<:Number} +function convert(::Type{TaylorN{Taylor1{T}}}, s::Taylor1{TaylorN{T}}) where {T<:NumberNotSeries} orderN = get_order() r = zeros(HomogeneousPolynomial{Taylor1{T}}, orderN) @@ -103,7 +104,7 @@ function convert(::Type{TaylorN{Taylor1{T}}}, s::Taylor1{TaylorN{T}}) where {T<: return TaylorN(r) end -function convert(::Type{Taylor1{TaylorN{T}}}, s::TaylorN{Taylor1{T}}) where {T<:Number} +function convert(::Type{Taylor1{TaylorN{T}}}, s::TaylorN{Taylor1{T}}) where {T<:NumberNotSeries} ordert = 0 for ordHP in eachindex(s) @@ -115,12 +116,12 @@ function convert(::Type{Taylor1{TaylorN{T}}}, s::TaylorN{Taylor1{T}}) where {T<: end @inbounds for ordN in eachindex(s) - vHP = HomogeneousPolynomial(zeros(T,length(s[ordN]))) + vHP = HomogeneousPolynomial(zeros(T, length(s[ordN]))) @inbounds for ihp in eachindex(s[ordN].coeffs) @inbounds for ind in eachindex(s[ordN][ihp].coeffs) c = s[ordN][ihp][ind-1] vHP[ihp] = c - vT[ind] += TaylorN(vHP) + vT[ind] += TaylorN(vHP, s.order) vHP[ihp] = zero(T) end end @@ -129,21 +130,21 @@ function convert(::Type{Taylor1{TaylorN{T}}}, s::TaylorN{Taylor1{T}}) where {T<: end function convert(::Type{Array{TaylorN{Taylor1{T}},N}}, - s::Array{Taylor1{TaylorN{T}},N}) where {T<:Number, N} + s::Array{Taylor1{TaylorN{T}},N}) where {T<:NumberNotSeries, N} v = Array{TaylorN{Taylor1{T}}}(undef, size(s)) - for ind in eachindex(s) - v[ind] = convert(TaylorN{Taylor1{T}}, s[ind]) + @simd for ind in eachindex(s) + @inbounds v[ind] = convert(TaylorN{Taylor1{T}}, s[ind]) end return v end function convert(::Type{Array{Taylor1{TaylorN{T}},N}}, - s::Array{TaylorN{Taylor1{T}},N}) where {T<:Number, N} + s::Array{TaylorN{Taylor1{T}},N}) where {T<:NumberNotSeries, N} v = Array{Taylor1{TaylorN{T}}}(undef, size(s)) - for ind in eachindex(s) - v[ind] = convert(Taylor1{TaylorN{T}}, s[ind]) + @simd for ind in eachindex(s) + @inbounds v[ind] = convert(Taylor1{TaylorN{T}}, s[ind]) end return v end @@ -170,10 +171,14 @@ promote_rule(::Type{Taylor1{T}}, ::Type{S}) where {T<:Number, S<:Number} = promote_rule(::Type{Taylor1{Taylor1{T}}}, ::Type{Taylor1{T}}) where {T<:Number} = Taylor1{Taylor1{T}} + promote_rule(::Type{HomogeneousPolynomial{T}}, ::Type{HomogeneousPolynomial{S}}) where {T<:Number, S<:Number} = HomogeneousPolynomial{promote_type(T,S)} +promote_rule(::Type{HomogeneousPolynomial{T}}, + ::Type{HomogeneousPolynomial{T}}) where {T<:Number} = HomogeneousPolynomial{T} + promote_rule(::Type{HomogeneousPolynomial{T}}, ::Type{Array{S,1}}) where {T<:Number, S<:Number} = HomogeneousPolynomial{promote_type(T,S)} @@ -184,6 +189,8 @@ promote_rule(::Type{HomogeneousPolynomial{T}}, ::Type{S}) where promote_rule(::Type{TaylorN{T}}, ::Type{TaylorN{S}}) where {T<:Number, S<:Number}= TaylorN{promote_type(T,S)} +promote_rule(::Type{TaylorN{T}}, ::Type{TaylorN{T}}) where {T<:Number} = TaylorN{T} + promote_rule(::Type{TaylorN{T}}, ::Type{HomogeneousPolynomial{S}}) where {T<:Number, S<:Number} = TaylorN{promote_type(T,S)} @@ -203,3 +210,19 @@ promote_rule(::Type{S}, ::Type{T}) where promote_rule(::Type{Taylor1{T}}, ::Type{TaylorN{S}}) where {T<:NumberNotSeries, S<:NumberNotSeries} = throw(ArgumentError("There is no reasonable promotion among `Taylor1{$T}` and `TaylorN{$S}` types")) + + +# Nested Taylor1's +function promote(a::Taylor1{Taylor1{T}}, b::Taylor1{T}) where {T<:NumberNotSeriesN} + order_a = get_order(a) + order_b = get_order(b) + zb = zero(b) + new_bcoeffs = similar(a.coeffs) + new_bcoeffs[1] = b + @inbounds for ind in 2:order_a+1 + new_bcoeffs[ind] = zb + end + return a, Taylor1(b, order_a) +end +promote(b::Taylor1{T}, a::Taylor1{Taylor1{T}}) where {T<:NumberNotSeriesN} = + reverse(promote(a, b)) diff --git a/src/evaluate.jl b/src/evaluate.jl index d72d1565..c9f1c67b 100644 --- a/src/evaluate.jl +++ b/src/evaluate.jl @@ -38,37 +38,10 @@ representing the dependent variables of an ODE, at *time* δt. Note that the syntax `x(δt)` is equivalent to `evaluate(x, δt)`, and `x()` is equivalent to `evaluate(x)`. """ -function evaluate(x::Union{Array{Taylor1{T},1}, SubArray{Taylor1{T},1}}, δt::S) where {T<:Number, S<:Number} - R = promote_type(T,S) - return evaluate(convert(Array{Taylor1{R},1},x), convert(R,δt)) -end -function evaluate(x::Array{Taylor1{T},1}, δt::T) where {T<:Number} - xnew = Array{T}(undef, length(x) ) - evaluate!(x, δt, xnew) - return xnew -end - -evaluate(a::Array{Taylor1{T},1}) where {T<:Number} = evaluate(a, zero(T)) -evaluate(a::SubArray{Taylor1{T},1}) where {T<:Number} = evaluate(a, zero(T)) - -function evaluate(A::Union{Array{Taylor1{T},2}, SubArray{Taylor1{T},2}}, δt::S) where {T<:Number, S<:Number} - R = promote_type(T,S) - return evaluate(convert(Array{Taylor1{R},2},A), convert(R,δt)) -end -function evaluate(A::Array{Taylor1{T},2}, δt::T) where {T<:Number} - n,m = size(A) - Anew = Array{T}(undef, n, m ) - xnew = Array{T}(undef, n ) - - for i in 1:m - evaluate!(A[:,i], δt, xnew) - Anew[:,i] = xnew - end - - return Anew -end -evaluate(A::Array{Taylor1{T},2}) where {T<:Number} = evaluate.(A) -evaluate(A::SubArray{Taylor1{T},2}) where {T<:Number} = evaluate.(A) +evaluate(x::Union{Array{Taylor1{T}}, SubArray{Taylor1{T}}}, δt::S) where + {T<:Number, S<:Number} = evaluate.(x, δt) +evaluate(a::Union{Array{Taylor1{T}}, SubArray{Taylor1{T}}}) where {T<:Number} = + evaluate.(a, zero(T)) """ evaluate!(x, δt, x0) @@ -134,16 +107,10 @@ evaluate(p::Taylor1{T}, x::Array{S}) where {T<:Number, S<:Number} = (p::Taylor1)() = evaluate(p) #function-like behavior for Vector{Taylor1} -(p::Array{Taylor1{T},1})(x) where {T<:Number} = evaluate(p, x) -(p::SubArray{Taylor1{T},1})(x) where {T<:Number} = evaluate(p, x) -(p::Array{Taylor1{T},1})() where {T<:Number} = evaluate.(p) -(p::SubArray{Taylor1{T},1})() where {T<:Number} = evaluate.(p) - -#function-like behavior for Matrix{Taylor1} -(p::Array{Taylor1{T},2})(x) where {T<:Number} = evaluate(p, x) -(p::SubArray{Taylor1{T},2})(x) where {T<:Number} = evaluate(p, x) -(p::Array{Taylor1{T},2})() where {T<:Number} = evaluate.(p) -(p::SubArray{Taylor1{T},2})() where {T<:Number} = evaluate.(p) +(p::Array{Taylor1{T}})(x) where {T<:Number} = evaluate.(p, x) +(p::SubArray{Taylor1{T}})(x) where {T<:Number} = evaluate.(p, x) +(p::Array{Taylor1{T}})() where {T<:Number} = evaluate.(p) +(p::SubArray{Taylor1{T}})() where {T<:Number} = evaluate.(p) ## Evaluation of multivariable function evaluate!(x::Array{TaylorN{T},1}, δx::Array{T,1}, diff --git a/test/manyvariables.jl b/test/manyvariables.jl index 5f2510f6..973e82a3 100644 --- a/test/manyvariables.jl +++ b/test/manyvariables.jl @@ -12,6 +12,7 @@ eeuler = Base.MathConstants.e @test HomogeneousPolynomial{Int} <: AbstractSeries{Int} @test TaylorN{Float64} <: AbstractSeries{Float64} + set_variables("x", numvars=2, order=6) _taylorNparams = TaylorSeries.ParamsTaylorN(6, 2, String["x₁", "x₂"]) @test _taylorNparams.order == get_order() @test _taylorNparams.num_vars == get_numvars() @@ -86,9 +87,30 @@ eeuler = Base.MathConstants.e hpol_v[1:1:2] = [1,2] @test all(hpol_v[1:1:2] .== [1,2]) @test v == [1,2,3] + hpol_v[:] = zeros(Int, 3) + @test hpol_v == 0 + + tn_v = TaylorN(HomogeneousPolynomial(zeros(Int, 3))) + tn_v[0] = 1 + @test tn_v == 1 + tn_v[0:1] = [0, 1] + @test tn_v[0] == 0 && tn_v[1] == HomogeneousPolynomial(1, 1) + tn_v[0:1] = [HomogeneousPolynomial(0, 0), HomogeneousPolynomial([0,1])] + @test tn_v[0] == 0 && tn_v[1] == HomogeneousPolynomial([0,1], 1) + tn_v[:] = [HomogeneousPolynomial(1, 0), HomogeneousPolynomial(0, 1), hpol_v] + @test tn_v == 1 + tn_v[:] = 0 + @test tn_v == 0 + tn_v[:] = [3,1,0] + @test tn_v == TaylorN([HomogeneousPolynomial(3, 0), HomogeneousPolynomial(1, 1)], 2) + tn_v[0:2] = [HomogeneousPolynomial(3, 0), HomogeneousPolynomial(1, 1), HomogeneousPolynomial(0, 2)] + @test tn_v == TaylorN([HomogeneousPolynomial(3, 0), HomogeneousPolynomial(1, 1)], 2) + tn_v[0:2:2] = [0,0] + @test tn_v == TaylorN(HomogeneousPolynomial(1, 1), 2) xH = HomogeneousPolynomial([1,0]) yH = HomogeneousPolynomial([0,1],1) + @test xH == convert(HomogeneousPolynomial{Float64},xH) @test HomogeneousPolynomial(0,0) == 0 xT = TaylorN(xH, 17) yT = TaylorN(Int, 2, order=17) @@ -101,6 +123,7 @@ eeuler = Base.MathConstants.e @test one(HomogeneousPolynomial(1,1)) == HomogeneousPolynomial([1,1]) uT = one(convert(TaylorN{Float64},yT)) @test uT == one(HomogeneousPolynomial) + @test uT == convert(TaylorN{Float64},uT) @test zeroT[0] == HomogeneousPolynomial(0, 0) @test uT[0] == HomogeneousPolynomial(1, 0) @test ones(xH,1) == [1, xH+yH] @@ -112,6 +135,7 @@ eeuler = Base.MathConstants.e @test TaylorSeries.fixorder(xH,yH) == (xH,yH) @test_throws AssertionError TaylorSeries.fixorder(zeros(xH,0)[1],yH) + @test constant_term(xT) == 0 @test constant_term(uT) == 1.0 @test constant_term(xT) == constant_term(yT) @@ -141,7 +165,7 @@ eeuler = Base.MathConstants.e @test promote(xH, yT)[1] == xT @test promote(xT, [xH,yH])[2] == xT+yT @test typeof(promote(im*xT,[xH,yH])[2]) == TaylorN{Complex{Int}} - # @test TaylorSeries.fixorder(TaylorN(1, order=1),17) == xT + @test iszero(zeroT.coeffs) @test iszero(zero(xH)) @test !iszero(uT) diff --git a/test/mixtures.jl b/test/mixtures.jl index 36b93857..8b909681 100644 --- a/test/mixtures.jl +++ b/test/mixtures.jl @@ -20,7 +20,7 @@ using LinearAlgebra, SparseArrays @test tN.order == 3 @test string(zero(tN)) == " 0.0 + 𝒪(‖x‖¹) + 𝒪(t⁴)" @test string(tN) == " ( 1.0 + 𝒪(‖x‖¹)) t + 𝒪(t⁴)" - @test string(tN + 3Taylor1(Int, 2)) == " ( 4.0 + 𝒪(‖x‖¹)) t + 𝒪(t⁴)" + @test string(tN + 3Taylor1(Int, 2)) == " ( 4.0 + 𝒪(‖x‖¹)) t + 𝒪(t³)" @test string(xH * tN) == " ( 1.0 x₁ + 𝒪(‖x‖²)) t + 𝒪(t⁴)" @test constant_term(xH) == xH @@ -34,8 +34,7 @@ using LinearAlgebra, SparseArrays @test string(tN) == " ( 1.0 + 𝒪(‖x‖⁷)) t + 𝒪(t⁴)" @test string(Taylor1([xH+yH])) == " 1 x₁ + 1 x₂ + 𝒪(t¹)" @test string(Taylor1([zero(xH), xH*yH])) == " ( 1 x₁ x₂) t + 𝒪(t²)" - @test string(tN * Taylor1([0,TaylorN([xH+yH])])) == - " ( 1.0 x₁ + 1.0 x₂ + 𝒪(‖x‖⁷)) t² + 𝒪(t⁴)" + @test string(tN * Taylor1([0,TaylorN([xH+yH])])) == " 0.0 + 𝒪(‖x‖⁷) + 𝒪(t²)" t = Taylor1(3) xHt = HomogeneousPolynomial(typeof(t), 1) @@ -53,7 +52,7 @@ using LinearAlgebra, SparseArrays @test (xHt+yHt)(1, 1) == 1+t @test (xHt+yHt)([1, 1]) == (xHt+yHt)((1, 1)) - tN1 = TaylorN([HomogeneousPolynomial([t]),xHt,yHt^2]) + tN1 = TaylorN([HomogeneousPolynomial([t]), xHt, yHt^2]) @test tN1[0] == HomogeneousPolynomial([t]) @test tN1(t,one(t)) == 2t+t^2 @test tN1([t,one(t)]) == tN1((t,one(t))) @@ -279,3 +278,14 @@ using LinearAlgebra, SparseArrays @test_throws ArgumentError Taylor1(2) * TaylorN(1) @test_throws ArgumentError TaylorN(2) / Taylor1(1) end + +@testset "Tests with nested Taylor1s" begin + ti = Taylor1(3) + to = Taylor1([zero(ti), one(ti)], 9) + @test string(to) == " ( 1.0 + 𝒪(t⁴)) t + 𝒪(t¹⁰)" + @test string(to^2) == " ( 1.0 + 𝒪(t⁴)) t² + 𝒪(t¹⁰)" + @test ti + to == Taylor1([ti, one(ti)], 10) + @test ti * to == Taylor1([zero(ti), ti], 10) + @test ti^2-to^2 == (ti+to)*(ti-to) + @test sin(to) ≈ Taylor1(one(ti) .* sin(Taylor1(10)).coeffs, 10) +end diff --git a/test/onevariable.jl b/test/onevariable.jl index 982be1a1..8893c285 100644 --- a/test/onevariable.jl +++ b/test/onevariable.jl @@ -47,6 +47,10 @@ eeuler = Base.MathConstants.e @test v == zero(v) setindex!(pol_int,1,:) @test v == ones(Int, 4) + setindex!(pol_int, v, :) + @test v == ones(Int, 4) + setindex!(pol_int, zeros(Int, 4), 0:3) + @test v == zeros(Int, 4) pol_int[:] .= 0 @test v == zero(v) pol_int[0:2:end] = 2 @@ -107,7 +111,8 @@ eeuler = Base.MathConstants.e @test eltype(promote(1.0+im, zt)[1]) == Complex{Float64} @test length(Taylor1(10)) == 11 - @test length(TaylorSeries.fixorder(zt,Taylor1([1]))[2]) == 16 + @test length.( TaylorSeries.fixorder(zt, Taylor1([1])) ) == (16, 16) + @test length.( TaylorSeries.fixorder(zt, Taylor1([1], 1)) ) == (2, 2) @test eltype(TaylorSeries.fixorder(zt,Taylor1([1]))[1]) == Int @test TaylorSeries.findfirst(t) == 1 @test TaylorSeries.findfirst(t^2) == 2 diff --git a/test/runtests.jl b/test/runtests.jl index 0d051566..6a810468 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -14,5 +14,7 @@ testfiles = ( ) for file in testfiles + # Skipping tests with intervals, since IntervalArithmetic.jl requires Julia v1.1+ + VERSION < v"1.1" && file == "intervals.jl" && continue include(file) end