From 67f156a33e4b8c1373e6ae9975957ab2b3f198f3 Mon Sep 17 00:00:00 2001 From: Luis Benet Date: Fri, 9 Apr 2021 15:59:41 -0500 Subject: [PATCH] Tests, docs, and minor fixes --- docs/src/userguide.md | 39 ++++++++++++++++++++++++--------------- src/arithmetic.jl | 1 + src/power.jl | 8 ++++++-- test/mixtures.jl | 8 ++++++++ test/onevariable.jl | 3 +++ 5 files changed, 42 insertions(+), 17 deletions(-) diff --git a/docs/src/userguide.md b/docs/src/userguide.md index d8689297..2e0cfc78 100644 --- a/docs/src/userguide.md +++ b/docs/src/userguide.md @@ -8,7 +8,7 @@ CurrentModule = TaylorSeries [TaylorSeries.jl](https://github.com/JuliaDiff/TaylorSeries.jl) is a basic polynomial algebraic manipulator in one or more -variables; these two cases are treated separately. Three new types are defined, +variables; these two cases are treated separately. Three new types are defined, [`Taylor1`](@ref), [`HomogeneousPolynomial`](@ref) and [`TaylorN`](@ref), which correspond to expansions in one independent variable, homogeneous polynomials of various @@ -48,8 +48,8 @@ t = shift_taylor(0.0) # Independent variable `t` !!! warning The information about the maximum order considered is displayed using a big-𝒪 notation. - The convention followed when different orders are combined, or when certain functions - are used that in a way reduce the order (like [`differentiate`](@ref)) is to be consistent + The convention followed when different orders are combined, and when certain functions + are used in a way that they reduce the order (like [`differentiate`](@ref)), is to be consistent with the mathematics and the big-𝒪 notation, i.e., to propagate the lowest order. In some cases, it is desirable to not display the big-𝒪 notation. The function [`displayBigO`](@ref) @@ -76,13 +76,15 @@ The definition of `shift_taylor(a)` uses the method [`Taylor1([::Type{Float64}], order::Int)`](@ref), which is a shortcut to define the independent variable of a Taylor expansion, of given type and order (the default is `Float64`). -This is one of the easiest ways to work with the package. +Defining the independen variable in advance is one of the easiest +ways to use the package. The usual arithmetic operators (`+`, `-`, `*`, `/`, `^`, `==`) have been extended to work with the [`Taylor1`](@ref) type, including promotions that -involve `Number`s. The operations return a valid Taylor expansion of -maximum order. This is apparent in the last example below, where -the answer is beyond the order of the expansion. +involve `Number`s. The operations return a valid Taylor expansion, consistent +with the order of the series. This is apparent in the one-before-last example +below, where the fist non-zero coefficient is beyond the order of the expansion, +and hence the result is zero. ```@repl userguide t*(3t+2.5) @@ -93,10 +95,16 @@ tI = im*t (1+t)^t Taylor1(3) + Taylor1(5) == 2Taylor1(3) # big-𝒪 convention applies t^6 # t is of order 5 +t^2 / t # The result is of order 4, instead of 5 ``` +Note that the last example returns a `Taylor1` series of order 4, instead +of order 5; this is be consistent with the number of known coefficients of the +returned series, since the rersult corresponds to factorize `t` in the numerator +to cancel the samee factor in the denominator. + If no valid Taylor expansion can be computed an error is thrown, for instance, -when a derivative is not defined (or simply diverges): +when a derivative is not defined at the expansion point, or it simply diverges. ```@repl userguide 1/t @@ -111,9 +119,9 @@ are `exp`, `log`, `sqrt`, the trigonometric functions `sinh`, `cosh` and `tanh` and their inverses; 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 +variables. Yet, the implementation is efficient enough, especially for the +integration of ordinary differential equations, which is among the +applications we have in mind (see [TaylorIntegration.jl](https://github.com/PerezHz/TaylorIntegration.jl)). ```@repl userguide @@ -189,7 +197,8 @@ 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 was a function, i.e., `p(x)`: +Another way to evaluate 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) @@ -226,11 +235,11 @@ as a vector whose coefficients are polynomials in ``N-1`` variables. The current implementation of `TaylorSeries.jl` corresponds to the first option, though some infrastructure has been built that permits to develop the second one. An elegant (lazy) implementation of the second representation -was discussed [here](https://groups.google.com/forum/#!msg/julia-users/AkK_UdST3Ig/sNrtyRJHK0AJ). +was discussed [here](https://groups.google.com/forum/#!msg/julia-users/AkK_UdST3Ig/sNrtyRJHK0AJ). The structure [`TaylorN`](@ref) is constructed as a vector of parameterized homogeneous polynomials -defined by the type [`HomogeneousPolynomial`](@ref), which in turn is a vector of +defined by the type [`HomogeneousPolynomial`](@ref), which in turn is an ordered vector of coefficients of given order (degree). This implementation imposes the user to specify the (maximum) order considered and the number of independent variables at the beginning, which can be conveniently done using @@ -315,7 +324,7 @@ 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. +appropriate promotions to deal with the usual numberic types. 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. diff --git a/src/arithmetic.jl b/src/arithmetic.jl index 61196c71..b59ea001 100644 --- a/src/arithmetic.jl +++ b/src/arithmetic.jl @@ -413,6 +413,7 @@ end /(a::Taylor1{T}, b::Taylor1{S}) where {T<:Number, S<:Number} = /(promote(a,b)...) function /(a::Taylor1{T}, b::Taylor1{T}) where {T<:Number} + iszero(a) && !iszero(b) && return zero(a) if a.order != b.order a, b = fixorder(a, b) end diff --git a/src/power.jl b/src/power.jl index 2ccac484..6deb0a54 100644 --- a/src/power.jl +++ b/src/power.jl @@ -85,8 +85,11 @@ end ## Real power ## function ^(a::Taylor1, r::S) where {S<:Real} + # println() a0 = constant_term(a) - aux = one(a0^r) + # @show(a, a0) + aux = one(a0)^r + # @show(aux) iszero(r) && return Taylor1(aux, a.order) aa = aux*a @@ -100,11 +103,12 @@ function ^(a::Taylor1, r::S) where {S<:Real} return Taylor1( zero(aux), a.order) end c_order = l0 == 0 ? a.order : min(a.order, trunc(Int,r*a.order)) + # @show(c_order) c = Taylor1(zero(aux), c_order) for k = 0:c_order pow!(c, aa, r, k) end - + # println() return c end diff --git a/test/mixtures.jl b/test/mixtures.jl index 1c9a9b1b..8d06eef0 100644 --- a/test/mixtures.jl +++ b/test/mixtures.jl @@ -303,4 +303,12 @@ end @test get_order(linear_polynomial(to)) == get_order(to) @test nonlinear_polynomial(to+ti*to^2) == Taylor1([zero(ti), zero(ti), ti], 9) @test ti(1 + to) isa Taylor1{Taylor1{Float64}} + @test sqrt(tito^2) == tito + @test get_order(sqrt(tito^2)) == get_order(to) >> 1 + @test (tito^3)^(1/3) == tito + @test get_order(sqrt(tito^2)) == get_order(to) >> 1 + ti2to = ti^2 * to + tti = (ti2to/to)/ti + @test get_order(tti) == get_order(to)-1 + @test get_order(tti[0]) == get_order(ti)-1 end diff --git a/test/onevariable.jl b/test/onevariable.jl index 3d4a6c5b..41ca9a28 100644 --- a/test/onevariable.jl +++ b/test/onevariable.jl @@ -169,10 +169,12 @@ Base.iszero(::SymbNumber) = false @test (-t)^2 == tsquare @test t^3 == tsquare*t @test zero(t)/t == zero(t) + @test get_order(zero(t)/t) == get_order(t) @test one(t)/one(t) == 1.0 @test tsquare/t == t @test get_order(tsquare/t) == get_order(tsquare)-1 @test t/(t*3) == (1/3)*ot + @test get_order(t/(t*3)) == get_order(t)-1 @test t/3im == -tim/3 @test 1/(1-t) == Taylor1(ones(t.order+1)) @test Taylor1([0,1,1])/t == t+1 @@ -203,6 +205,7 @@ Base.iszero(::SymbNumber) = false # These tests involve some sort of factorization @test t/(t+t^2) == 1/(1+t) + @test get_order(t/(t+t^2)) == get_order(1/(1+t))-1 @test sqrt(t^2+t^3) == t*sqrt(1+t) @test get_order(sqrt(t^2+t^3)) == get_order(t) >> 1 @test get_order(t*sqrt(1+t)) == get_order(t)