diff --git a/.travis.yml b/.travis.yml index b608514e..2c90d12b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,7 +5,6 @@ os: - osx julia: - - 0.5 - 0.6 - nightly diff --git a/README.md b/README.md index 02909687..154e11f0 100644 --- a/README.md +++ b/README.md @@ -3,8 +3,8 @@ A [Julia](http://julialang.org) package for Taylor expansions in one or more independent variables. -[![TaylorSeries](http://pkg.julialang.org/badges/TaylorSeries_0.5.svg)](http://pkg.julialang.org/?pkg=TaylorSeries) [![TaylorSeries](http://pkg.julialang.org/badges/TaylorSeries_0.6.svg)](http://pkg.julialang.org/?pkg=TaylorSeries) +[![TaylorSeries](http://pkg.julialang.org/badges/TaylorSeries_0.7.svg)](http://pkg.julialang.org/?pkg=TaylorSeries) [![Coverage Status](https://coveralls.io/repos/JuliaDiff/TaylorSeries.jl/badge.svg?branch=master)](https://coveralls.io/github/JuliaDiff/TaylorSeries.jl?branch=master) [![](https://img.shields.io/badge/docs-stable-blue.svg)](http://www.juliadiff.org/TaylorSeries.jl/stable) diff --git a/REQUIRE b/REQUIRE index 2652857b..137767a4 100644 --- a/REQUIRE +++ b/REQUIRE @@ -1,2 +1 @@ -julia 0.5 -Compat 0.17.0 +julia 0.6 diff --git a/docs/make.jl b/docs/make.jl index fbae6db3..8391d3c5 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -16,7 +16,7 @@ makedocs( deploydocs( repo = "github.com/JuliaDiff/TaylorSeries.jl.git", target = "build", - julia = "0.5", + julia = "0.6", osname = "linux", deps = nothing, make = nothing diff --git a/docs/src/api.md b/docs/src/api.md index ffe9a425..13addfb0 100644 --- a/docs/src/api.md +++ b/docs/src/api.md @@ -31,6 +31,8 @@ show_params_TaylorN get_coeff evaluate evaluate! +taylor_expand +update! derivative integrate gradient @@ -41,6 +43,8 @@ hessian! inverse abs norm +isapprox +isfinite ``` ## Internals diff --git a/docs/src/examples.md b/docs/src/examples.md index c46aa9a3..16440a5c 100644 --- a/docs/src/examples.md +++ b/docs/src/examples.md @@ -20,7 +20,7 @@ The first example shows that the four-square identity holds: \end{eqnarray} ``` which was originally proved by Euler. The code can also be found in -[this test](../../test/identities_Euler.jl) of the package. +[this test](https://github.com/JuliaDiff/TaylorSeries.jl/blob/master/test/identities_Euler.jl) of the package. First, we reset the maximum degree of the polynomial to 4, since the RHS of the equation has *a priori* terms of fourth order, and define the 8 @@ -127,7 +127,8 @@ monomials in 4 variables. ### Bechmarks The functions described above have been compared against Mathematica v11.1. -The relevant files used for benchmarking can be found [here](../../perf/). +The relevant files used for benchmarking can be found +[here](https://github.com/JuliaDiff/TaylorSeries.jl/tree/master/perf). Running on a MacPro with Intel-Xeon processors 2.7GHz, we obtain that Mathematica requires on average (5 runs) 3.075957 seconds for the computation, while for `fateman1` and `fateman2` above we obtain 2.811391 and 1.490256, diff --git a/docs/src/userguide.md b/docs/src/userguide.md index 8bd85cfc..2336f699 100644 --- a/docs/src/userguide.md +++ b/docs/src/userguide.md @@ -34,13 +34,13 @@ monomial, so that etc. This is a dense representation of the polynomial. The order of the polynomial can be omitted in the constructor, which is then fixed by the length of the -vector of coefficients; otherwise, it defines the maximum -degree of the polynomial, and may be used to truncate it. +vector of coefficients. If the length of the vector does not correspond with +the `order`, `order` is used, which effectively truncates polynomial to degree `order`. ```@repl userguide Taylor1([1, 2, 3],4) # Polynomial of order 4 with coefficients 1, 2, 3 Taylor1([0.0, 1im]) # Also works with complex numbers -Taylor1(ones(8), 2) # Polynomial of order 2 +Taylor1(ones(8), 2) # Polynomial truncated to order 2 shift_taylor(a) = a + Taylor1(typeof(a),5) ## a + taylor-polynomial of order 5 t = shift_taylor(0.0) # Independent variable `t` ``` @@ -67,7 +67,7 @@ t*(t^2-4)/(t+2) tI = im*t (1-t)^3.2 (1+t)^t -t^6 # order is 5 +t^6 # t is of order 5 ``` If no valid Taylor expansion can be computed, an error is thrown, for instance @@ -123,7 +123,7 @@ integrate(exp(t)) integrate( exp(t), 1.0) integrate( derivative( exp(-t)), 1.0 ) == exp(-t) derivative(1, exp(shift_taylor(1.0))) == exp(1.0) -derivative(5, exp(shift_taylor(1.0))) == exp(1.0) # Fifth derivative of `exp(1+t)` +derivative(5, exp(shift_taylor(1.0))) == exp(1.0) # 5-th derivative of `exp(1+t)` ``` To evaluate a Taylor series at a given point, Horner's rule is used via the @@ -142,22 +142,34 @@ eBig = evaluate( exp(tBig), one(BigFloat) ) e - 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: +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)`: ```@repl userguide t = Taylor1(15) p = sin(t) -evaluate(p, pi/2) #get value of p at pi/2 using `evaluate` -p(pi/2) #get value of p at pi/2 by calling p as a function +evaluate(p, pi/2) # value of p at pi/2 using `evaluate` +p(pi/2) # value of p at pi/2 by evaluating p as a function p(pi/2) == evaluate(p, pi/2) -p(0.0) #get value of `p` at 0.0 by calling p as a function -evaluate(p) #get p 0-th order coefficient using `evaluate` -p() #a shortcut to get 0-th order coefficient of `p` -p() == evaluate(p) -p() == p(0.0) +p(0.0) +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. + +Useful shortcuts are `taylor_expand` are `update!`. The former returns +the expansion of a function around a given value `t0`. In turn, `update!` +provides an in-place update of a given Taylor polynomial, that is, it shifts +it further by the provided amount. + +```@repl userguide +p = taylor_expand( x -> sin(x), pi/2, order=16) # 16-th order expansion of sin(t) around pi/2 +update!(p, 0.025) # updates the expansion given by p, by shifting it further by 0.025 +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. ## Many variables @@ -172,10 +184,10 @@ was discussed [here](https://groups.google.com/forum/#!msg/julia-users/AkK_UdST 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 -coefficients of given order (degree). This implementation imposes that the user -has to specify the (maximum) order considered and the number of independent -variables, which is done using the [`set_variables`](@ref) function. -A vector of the resulting Taylor variables is returned: +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 +[`set_variables`](@ref). A vector of the resulting Taylor variables is returned: ```@repl userguide x, y = set_variables("x y") @@ -185,13 +197,14 @@ x.coeffs ``` As shown, the resulting objects are of `TaylorN{Float64}` type. -There is an optional `order` keyword argument in [`set_variables`](@ref): +There is an optional `order` keyword argument in [`set_variables`](@ref), +used to specify the maximum order of the `TaylorN` polynomials. ```@repl userguide set_variables("x y", order=10) ``` -Numbered variables are also available by specifying a single +Similarly, numbered variables are also available by specifying a single variable name and the optional keyword argument `numvars`: ```@repl userguide @@ -205,12 +218,6 @@ parameters, in an info block. show_params_TaylorN() ``` - julia> show_params_TaylorN() - INFO: Parameters for `TaylorN` and `HomogeneousPolynomial`: - Maximum order = 10 - Number of variables = 3 - Variable names = UTF8String["α₁","α₂","α₃"] - Internally, changing the parameters (maximum order and number of variables) redefines the hash-tables that translate the index of the coefficients of a [`HomogeneousPolynomial`](@ref) @@ -307,7 +314,18 @@ exy([.1,.02]) exy([.1,.02]) == e^0.12 ``` -Again, note that the syntax `p(x)` for `p::TaylorN` 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. +Again, the syntax `p(x)` for `p::TaylorN` is equivalent to `evaluate(p,x)`, and +`p()` is equivalent to `evaluate(p)`. + +The functions `taylor_expand` and `update!` work as well for `TaylorN`. + +```@repl userguide +xysq = x^2 + y^2 +update!(xysq, [1.0, -2.0]) # expand around (1,-2) +xysq +update!(xysq, [-1.0, 2.0]) # shift-back +xysq == x^2 + y^2 +``` Functions to compute the gradient, Jacobian and Hessian have also been implemented. Using the @@ -326,7 +344,8 @@ jacobian([p,q], [2,1]) hessian(r, [1.0,1.0]) ``` -Other specific applications are described in the next [section](examples). +Other specific applications are described in the +[Examples](@ref). ## Mixtures @@ -338,7 +357,7 @@ somewhat special. ```@repl userguide x, y = set_variables("x y", order=3) -t = Taylor1([zero(x), one(x)], 5) +t1N = Taylor1([zero(x), one(x)], 5) ``` The last line defines a `Taylor1{TaylorN{Float64}}` variable, which is of order @@ -346,7 +365,7 @@ The last line defines a `Taylor1{TaylorN{Float64}}` variable, which is of order such polynomials: ```@repl userguide -cos(2.1+x+t) +cos(2.1+x+t1N) ``` This kind of expansions are of interest when studying the dependence of @@ -355,3 +374,7 @@ the dependence of the solution of a differential equation on the initial conditi around a given solution. In this case, `x` and `y` represent small variations around a given value of the parameters, or around some specific initial condition. Such constructions are exploited in the package [`TaylorIntegration.jl`](https://github.com/PerezHz/TaylorIntegration.jl). + +```@meta +CurrentModule = nothing +``` diff --git a/src/TaylorSeries.jl b/src/TaylorSeries.jl index f2ae5cee..7e9dee9c 100644 --- a/src/TaylorSeries.jl +++ b/src/TaylorSeries.jl @@ -18,18 +18,9 @@ see also [`HomogeneousPolynomial`](@ref). """ module TaylorSeries -using Compat - -if !isdefined(Base, :iszero) - import Compat: iszero - export iszero -else - import Base: iszero -end - import Base: ==, +, -, *, /, ^ -import Base: zero, one, zeros, ones, isinf, isnan, +import Base: zero, one, zeros, ones, isinf, isnan, iszero, convert, promote_rule, promote, eltype, length, show, real, imag, conj, ctranspose, rem, mod, mod2pi, abs, gradient, diff --git a/src/arithmetic.jl b/src/arithmetic.jl index d0943409..ea7f5735 100644 --- a/src/arithmetic.jl +++ b/src/arithmetic.jl @@ -12,9 +12,9 @@ for T in (:Taylor1, :TaylorN) @eval begin - =={T<:Number,S<:Number}(a::$T{T}, b::$T{S}) = ==(promote(a,b)...) + ==(a::$T{T}, b::$T{S}) where {T<:Number, S<:Number} = ==(promote(a,b)...) - function =={T<:Number}(a::$T{T}, b::$T{T}) + function ==(a::$T{T}, b::$T{T}) where {T<:Number} if a.order != b.order a, b = fixorder(a, b) end @@ -35,12 +35,12 @@ for T in (:Taylor1, :TaylorN), f in (:zero, :one) @eval ($f)(a::$T) = $T(($f)(a[1]), a.order) end -function zero{T<:Number}(a::HomogeneousPolynomial{T}) +function zero(a::HomogeneousPolynomial{T}) where {T<:Number} v = zeros(a.coeffs) return HomogeneousPolynomial(v, a.order) end -function zeros{T<:Number}(::HomogeneousPolynomial{T}, order::Int) +function zeros(::HomogeneousPolynomial{T}, order::Int) where {T<:Number} order == 0 && return [HomogeneousPolynomial([zero(T)], 0)] v = Array{HomogeneousPolynomial{T}}(order+1) @simd for ord in eachindex(v) @@ -49,15 +49,15 @@ function zeros{T<:Number}(::HomogeneousPolynomial{T}, order::Int) return v end -zeros{T<:Number}(::Type{HomogeneousPolynomial{T}}, order::Int) = +zeros(::Type{HomogeneousPolynomial{T}}, order::Int) where {T<:Number} = zeros( HomogeneousPolynomial([zero(T)], 0), order) -function one{T<:Number}(a::HomogeneousPolynomial{T}) +function one(a::HomogeneousPolynomial{T}) where {T<:Number} v = ones(a.coeffs) - return HomogeneousPolynomial{T}(v, a.order) + return HomogeneousPolynomial(v, a.order) end -function ones{T<:Number}(a::HomogeneousPolynomial{T}, order::Int) +function ones(a::HomogeneousPolynomial{T}, order::Int) where {T<:Number} order == 0 && return [HomogeneousPolynomial([one(a[1])], 0)] v = Array{HomogeneousPolynomial{T}}(order+1) @simd for ord in eachindex(v) @@ -67,7 +67,7 @@ function ones{T<:Number}(a::HomogeneousPolynomial{T}, order::Int) return v end -ones{T<:Number}(::Type{HomogeneousPolynomial{T}}, order::Int) = +ones(::Type{HomogeneousPolynomial{T}}, order::Int) where {T<:Number} = ones( HomogeneousPolynomial([one(T)], 0), order) @@ -77,9 +77,10 @@ for (f, fc) in ((:+, :(add!)), (:-, :(subst!))) for T in (:Taylor1, :TaylorN) @eval begin - ($f){T<:Number,S<:Number}(a::$T{T}, b::$T{S}) = $f(promote(a,b)...) + ($f)(a::$T{T}, b::$T{S}) where {T<:Number, S<:Number} = + $f(promote(a,b)...) - function $f{T<:Number}(a::$T{T}, b::$T{T}) + function $f(a::$T{T}, b::$T{T}) where {T<:Number} if a.order != b.order a, b = fixorder(a, b) end @@ -94,17 +95,19 @@ for (f, fc) in ((:+, :(add!)), (:-, :(subst!))) return $T(v, a.order) end - ($f){T<:Number,S<:Number}(a::$T{T}, b::S) = $f(promote(a,b)...) + ($f)(a::$T{T}, b::S) where {T<:Number, S<:Number} = + $f(promote(a,b)...) - function $f{T<:Number}(a::$T{T}, b::T) + function $f(a::$T{T}, b::T) where {T<:Number} coeffs = copy(a.coeffs) @inbounds coeffs[1] = $f(a[1], b) return $T(coeffs, a.order) end - ($f){T<:Number,S<:Number}(b::S, a::$T{T}) = $f(promote(b,a)...) + ($f)(b::S, a::$T{T}) where {T<:Number, S<:Number} = + $f(promote(b,a)...) - function $f{T<:Number}(b::T, a::$T{T}) + function $f(b::T, a::$T{T}) where {T<:Number} coeffs = similar(a.coeffs) @__dot__ coeffs = ($f)(a.coeffs) @inbounds coeffs[1] = $f(b, a[1]) @@ -120,11 +123,11 @@ for (f, fc) in ((:+, :(add!)), (:-, :(subst!))) end @eval begin - ($f){T<:NumberNotSeriesN,S<:NumberNotSeriesN}(a::HomogeneousPolynomial{T}, - b::HomogeneousPolynomial{S}) = $f(promote(a,b)...) + ($f)(a::HomogeneousPolynomial{T}, b::HomogeneousPolynomial{S}) where + {T<:NumberNotSeriesN,S<:NumberNotSeriesN} = $f(promote(a,b)...) - function $f{T<:NumberNotSeriesN}(a::HomogeneousPolynomial{T}, - b::HomogeneousPolynomial{T}) + function $f(a::HomogeneousPolynomial{T}, b::HomogeneousPolynomial{T}) where + T<:NumberNotSeriesN @assert a.order == b.order v = similar(a.coeffs) @__dot__ v = $f(a.coeffs, b.coeffs) @@ -137,8 +140,8 @@ for (f, fc) in ((:+, :(add!)), (:-, :(subst!))) return HomogeneousPolynomial(v, a.order) end - function ($f){T<:NumberNotSeries,S<:NumberNotSeries}( - a::TaylorN{Taylor1{T}}, b::Taylor1{S}) + function ($f)(a::TaylorN{Taylor1{T}}, b::Taylor1{S}) where + {T<:NumberNotSeries,S<:NumberNotSeries} @inbounds aux = $f(a[1][1], b) R = eltype(aux) coeffs = Array{HomogeneousPolynomial{Taylor1{R}}}(a.order+1) @@ -147,8 +150,8 @@ for (f, fc) in ((:+, :(add!)), (:-, :(subst!))) return TaylorN(coeffs, a.order) end - function ($f){T<:NumberNotSeries,S<:NumberNotSeries}( - b::Taylor1{S}, a::TaylorN{Taylor1{T}}) + function ($f)(b::Taylor1{S}, a::TaylorN{Taylor1{T}}) where + {T<:NumberNotSeries,S<:NumberNotSeries} @inbounds aux = $f(b, a[1][1]) R = eltype(aux) coeffs = Array{HomogeneousPolynomial{Taylor1{R}}}(a.order+1) @@ -157,8 +160,8 @@ for (f, fc) in ((:+, :(add!)), (:-, :(subst!))) return TaylorN(coeffs, a.order) end - function ($f){T<:NumberNotSeries,S<:NumberNotSeries}( - a::Taylor1{TaylorN{T}}, b::TaylorN{S}) + function ($f)(a::Taylor1{TaylorN{T}}, b::TaylorN{S}) where + {T<:NumberNotSeries,S<:NumberNotSeries} @inbounds aux = $f(a[1], b) R = eltype(aux) coeffs = Array{TaylorN{R}}(a.order+1) @@ -167,8 +170,8 @@ for (f, fc) in ((:+, :(add!)), (:-, :(subst!))) return Taylor1(coeffs, a.order) end - function ($f){T<:NumberNotSeries,S<:NumberNotSeries}( - b::TaylorN{S}, a::Taylor1{TaylorN{T}}) + function ($f)(b::TaylorN{S}, a::Taylor1{TaylorN{T}}) where + {T<:NumberNotSeries,S<:NumberNotSeries} @inbounds aux = $f(b, a[1]) R = eltype(aux) coeffs = Array{TaylorN{R}}(a.order+1) @@ -189,21 +192,23 @@ for T in (:Taylor1, :HomogeneousPolynomial, :TaylorN) *(a::$T, b::Bool) = b * a - function *{T<:NumberNotSeries}(a::T, b::$T) + function *(a::T, b::$T) where {T<:NumberNotSeries} @inbounds aux = a * b[1] v = Array{typeof(aux)}(length(b.coeffs)) @__dot__ v = a * b.coeffs return $T(v, b.order) end - *{T<:NumberNotSeries}(b::$T, a::T) = a * b + *(b::$T, a::T) where {T<:NumberNotSeries} = a * b end end for T in (:HomogeneousPolynomial, :TaylorN) @eval begin - function *{T<:NumberNotSeries,S<:NumberNotSeries}(a::Taylor1{T}, b::$T{Taylor1{S}}) + function *(a::Taylor1{T}, b::$T{Taylor1{S}}) where + {T<:NumberNotSeries, S<:NumberNotSeries} + @inbounds aux = a * b[1] R = typeof(aux) coeffs = Array{R}(length(b.coeffs)) @@ -211,9 +216,10 @@ for T in (:HomogeneousPolynomial, :TaylorN) return $T(coeffs, b.order) end - *{T<:NumberNotSeries,R<:NumberNotSeries}(b::$T{Taylor1{R}}, a::Taylor1{T}) = a * b + *(b::$T{Taylor1{R}}, a::Taylor1{T}) where + {T<:NumberNotSeries,R<:NumberNotSeries} = a * b - function *{T<:NumberNotSeries,S<:NumberNotSeries}(a::$T{T}, b::Taylor1{$T{S}}) + function *(a::$T{T}, b::Taylor1{$T{S}}) where {T<:NumberNotSeries,S<:NumberNotSeries} @inbounds aux = a * b[1] R = typeof(aux) coeffs = Array{R}(length(b.coeffs)) @@ -221,14 +227,15 @@ for T in (:HomogeneousPolynomial, :TaylorN) return Taylor1(coeffs, b.order) end - *{T<:NumberNotSeries,S<:NumberNotSeries}(b::Taylor1{$T{S}}, a::$T{T}) = a * b + *(b::Taylor1{$T{S}}, a::$T{T}) where + {T<:NumberNotSeries,S<:NumberNotSeries} = a * b end end for (T, W) in ((:Taylor1, :Number), (:TaylorN, :NumberNotSeriesN)) - @eval *{T<:$W, S<:$W}(a::$T{T}, b::$T{S}) = *(promote(a,b)...) + @eval *(a::$T{T}, b::$T{S}) where {T<:$W, S<:$W} = *(promote(a,b)...) - @eval function *{T<:$W}(a::$T{T}, b::$T{T}) + @eval function *(a::$T{T}, b::$T{T}) where {T<:$W} if a.order != b.order a, b = fixorder(a, b) end @@ -241,10 +248,11 @@ for (T, W) in ((:Taylor1, :Number), (:TaylorN, :NumberNotSeriesN)) end -*{T<:NumberNotSeriesN,S<:NumberNotSeriesN}(a::HomogeneousPolynomial{T}, - b::HomogeneousPolynomial{S}) = *(promote(a,b)...) +*(a::HomogeneousPolynomial{T}, b::HomogeneousPolynomial{S}) where + {T<:NumberNotSeriesN,S<:NumberNotSeriesN} = *(promote(a,b)...) -function *{T<:NumberNotSeriesN}(a::HomogeneousPolynomial{T}, b::HomogeneousPolynomial{T}) +function *(a::HomogeneousPolynomial{T}, b::HomogeneousPolynomial{T}) where + {T<:NumberNotSeriesN} order = a.order + b.order @@ -329,7 +337,7 @@ end ## Division ## -function /{T<:Integer, S<:NumberNotSeries}(a::Taylor1{Rational{T}}, b::S) +function /(a::Taylor1{Rational{T}}, b::S) where {T<:Integer, S<:NumberNotSeries} R = typeof( a[1] // b) v = Array{R}(a.order+1) @__dot__ v = a.coeffs // b @@ -338,17 +346,17 @@ end for T in (:Taylor1, :HomogeneousPolynomial, :TaylorN) - @eval function /{T<:NumberNotSeries,S<:NumberNotSeries}(a::$T{T}, b::S) + @eval function /(a::$T{T}, b::S) where {T<:NumberNotSeries, S<:NumberNotSeries} R = promote_type(T,S) return convert($T{R}, a) * inv(convert(R, b)) end - @eval /{T<:NumberNotSeries}(a::$T, b::T) = a * inv(b) + @eval /(a::$T, b::T) where {T<:NumberNotSeries} = a * inv(b) end for T in (:HomogeneousPolynomial, :TaylorN) - @eval function /{T<:NumberNotSeries,S<:NumberNotSeries}( - b::$T{Taylor1{S}}, a::Taylor1{T}) + @eval function /(b::$T{Taylor1{S}}, a::Taylor1{T}) where + {T<:NumberNotSeries,S<:NumberNotSeries} @inbounds aux = b[1] / a R = typeof(aux) coeffs = Array{R}(length(b.coeffs)) @@ -356,8 +364,8 @@ for T in (:HomogeneousPolynomial, :TaylorN) return $T(coeffs, b.order) end - @eval function /{T<:NumberNotSeries,S<:NumberNotSeries}( - b::Taylor1{$T{S}}, a::$T{T}) + @eval function /(b::Taylor1{$T{S}}, a::$T{T}) where + {T<:NumberNotSeries,S<:NumberNotSeries} @inbounds aux = b[1] / a R = typeof(aux) coeffs = Array{R}(length(b.coeffs)) @@ -368,9 +376,9 @@ end -/{T<:Number,S<:Number}(a::Taylor1{T}, b::Taylor1{S}) = /(promote(a,b)...) +/(a::Taylor1{T}, b::Taylor1{S}) where {T<:Number, S<:Number} = /(promote(a,b)...) -function /{T<:Number}(a::Taylor1{T}, b::Taylor1{T}) +function /(a::Taylor1{T}, b::Taylor1{T}) where {T<:Number} if a.order != b.order a, b = fixorder(a, b) end @@ -386,10 +394,10 @@ function /{T<:Number}(a::Taylor1{T}, b::Taylor1{T}) return c end -/{T<:NumberNotSeriesN,S<:NumberNotSeriesN}(a::TaylorN{T}, b::TaylorN{S}) = - /(promote(a,b)...) +/(a::TaylorN{T}, b::TaylorN{S}) where + {T<:NumberNotSeriesN, S<:NumberNotSeriesN} = /(promote(a,b)...) -function /{T<:NumberNotSeriesN}(a::TaylorN{T}, b::TaylorN{T}) +function /(a::TaylorN{T}, b::TaylorN{T}) where {T<:NumberNotSeriesN} @assert !iszero(constant_term(b)) if a.order != b.order @@ -479,9 +487,9 @@ end Multiply A*B and save the result in Y. """ -function A_mul_B!{T<:Number}(y::Vector{Taylor1{T}}, +function A_mul_B!(y::Vector{Taylor1{T}}, a::Union{Matrix{T},SparseMatrixCSC{T}}, - b::Vector{Taylor1{T}}) + b::Vector{Taylor1{T}}) where {T<:Number} n, k = size(a) @assert (length(y)== n && length(b)== k) diff --git a/src/auxiliary.jl b/src/auxiliary.jl index 781a0fe1..7e64cd22 100644 --- a/src/auxiliary.jl +++ b/src/auxiliary.jl @@ -14,7 +14,7 @@ If the length of `coeffs` is smaller than `order+1`, it resizes `coeffs` appropriately filling it with zeros. """ -function resize_coeffs1!{T<:Number}(coeffs::Array{T,1}, order::Int) +function resize_coeffs1!(coeffs::Array{T,1}, order::Int) where {T<:Number} lencoef = length(coeffs) resize!(coeffs, order+1) if order > lencoef-1 @@ -31,7 +31,7 @@ If the length of `coeffs` is smaller than the number of coefficients correspondinf to `order` (given by `size_table[order+1]`), it resizes `coeffs` appropriately filling it with zeros. """ -function resize_coeffsHP!{T<:Number}(coeffs::Array{T,1}, order::Int) +function resize_coeffsHP!(coeffs::Array{T,1}, order::Int) where {T<:Number} lencoef = length( coeffs ) @inbounds num_coeffs = size_table[order+1] @assert order ≤ get_order() && lencoef ≤ num_coeffs @@ -43,7 +43,7 @@ function resize_coeffsHP!{T<:Number}(coeffs::Array{T,1}, order::Int) end ## Minimum order of an HomogeneousPolynomial compatible with the vector's length -function orderH{T}(coeffs::Array{T,1}) +function orderH(coeffs::Array{T,1}) where {T<:Number} ord = 0 ll = length(coeffs) for i = 1:get_order()+1 @@ -55,7 +55,7 @@ function orderH{T}(coeffs::Array{T,1}) end ## Maximum order of a HomogeneousPolynomial vector; used by TaylorN constructor -function maxorderH{T<:Number}(v::Array{HomogeneousPolynomial{T},1}) +function maxorderH(v::Array{HomogeneousPolynomial{T},1}) where {T<:Number} m = 0 @inbounds for i in eachindex(v) m = max(m, v[i].order) @@ -77,11 +77,11 @@ get_coeff(a::Taylor1, n::Int) = (@assert 0 ≤ n ≤ a.order+1; getindex(a::Taylor1, n::Int) = a.coeffs[n] getindex(a::Taylor1, n::UnitRange) = view(a.coeffs, n) getindex(a::Taylor1, c::Colon) = view(a.coeffs, c) -setindex!{T<:Number}(a::Taylor1{T}, x::T, n::Int) = a.coeffs[n] = x -setindex!{T<:Number}(a::Taylor1{T}, x::T, n::UnitRange) = a.coeffs[n] = x -setindex!{T<:Number}(a::Taylor1{T}, x::Array{T,1}, n::UnitRange) = a.coeffs[n] = x -setindex!{T<:Number}(a::Taylor1{T}, x::T, c::Colon) = a.coeffs[c] = x -setindex!{T<:Number}(a::Taylor1{T}, x::Array{T,1}, c::Colon) = a.coeffs[c] = x +setindex!(a::Taylor1{T}, x::T, n::Int) where {T<:Number} = a.coeffs[n] = x +setindex!(a::Taylor1{T}, x::T, n::UnitRange) where {T<:Number} = a.coeffs[n] = x +setindex!(a::Taylor1{T}, x::Array{T,1}, n::UnitRange) where {T<:Number} = a.coeffs[n] = x +setindex!(a::Taylor1{T}, x::T, c::Colon) where {T<:Number} = a.coeffs[c] = x +setindex!(a::Taylor1{T}, x::Array{T,1}, c::Colon) where {T<:Number} = a.coeffs[c] = x """ @@ -100,15 +100,15 @@ end getindex(a::HomogeneousPolynomial, n::Int) = a.coeffs[n] getindex(a::HomogeneousPolynomial, n::UnitRange) = view(a.coeffs, n) getindex(a::HomogeneousPolynomial, c::Colon) = view(a.coeffs, c) -setindex!{T<:Number}(a::HomogeneousPolynomial{T}, x::T, n::Int) = +setindex!(a::HomogeneousPolynomial{T}, x::T, n::Int) where {T<:Number} = a.coeffs[n] = x -setindex!{T<:Number}(a::HomogeneousPolynomial{T}, x::T, n::UnitRange) = +setindex!(a::HomogeneousPolynomial{T}, x::T, n::UnitRange) where {T<:Number} = a.coeffs[n] = x -setindex!{T<:Number}(a::HomogeneousPolynomial{T}, x::Array{T,1}, n::UnitRange) = +setindex!(a::HomogeneousPolynomial{T}, x::Array{T,1}, n::UnitRange) where {T<:Number} = a.coeffs[n] = x -setindex!{T<:Number}(a::HomogeneousPolynomial{T}, x::T, c::Colon) = +setindex!(a::HomogeneousPolynomial{T}, x::T, c::Colon) where {T<:Number} = a.coeffs[c] = x -setindex!{T<:Number}(a::HomogeneousPolynomial{T}, x::Array{T,1}, c::Colon) = +setindex!(a::HomogeneousPolynomial{T}, x::Array{T,1}, c::Colon) where {T<:Number} = a.coeffs[c] = x @@ -127,32 +127,32 @@ end getindex(a::TaylorN, n::Int) = a.coeffs[n] getindex(a::TaylorN, n::UnitRange) = view(a.coeffs, n) getindex(a::TaylorN, c::Colon) = view(a.coeffs, c) -setindex!{T<:Number}(a::TaylorN{T}, x::HomogeneousPolynomial{T}, n::Int) = +setindex!(a::TaylorN{T}, x::HomogeneousPolynomial{T}, n::Int) where {T<:Number} = a.coeffs[n] = x -setindex!{T<:Number}(a::TaylorN{T}, x::T, n::Int) = +setindex!(a::TaylorN{T}, x::T, n::Int) where {T<:Number} = a.coeffs[n] = HomogeneousPolynomial(x, n-1) -setindex!{T<:Number}(a::TaylorN{T}, x::HomogeneousPolynomial{T}, n::UnitRange) = +setindex!(a::TaylorN{T}, x::HomogeneousPolynomial{T}, n::UnitRange) where {T<:Number} = a.coeffs[n] = x -setindex!{T<:Number}(a::TaylorN{T}, x::T, n::UnitRange) = +setindex!(a::TaylorN{T}, x::T, n::UnitRange) where {T<:Number} = a.coeffs[n] = x -setindex!{T<:Number}(a::TaylorN{T}, x::Array{HomogeneousPolynomial{T},1}, n::UnitRange) = +setindex!(a::TaylorN{T}, x::Array{HomogeneousPolynomial{T},1}, n::UnitRange) where {T<:Number} = a.coeffs[n] = x -setindex!{T<:Number}(a::TaylorN{T}, x::Array{T,1}, n::UnitRange) = +setindex!(a::TaylorN{T}, x::Array{T,1}, n::UnitRange) where {T<:Number} = a.coeffs[n] = x -setindex!{T<:Number}(a::TaylorN{T}, x::HomogeneousPolynomial{T}, c::Colon) = +setindex!(a::TaylorN{T}, x::HomogeneousPolynomial{T}, c::Colon) where {T<:Number} = a.coeffs[c] = x -setindex!{T<:Number}(a::TaylorN{T}, x::T, c::Colon) = +setindex!(a::TaylorN{T}, x::T, c::Colon) where {T<:Number} = a.coeffs[c] = x -setindex!{T<:Number}(a::TaylorN{T}, x::Array{HomogeneousPolynomial{T},1}, c::Colon) = +setindex!(a::TaylorN{T}, x::Array{HomogeneousPolynomial{T},1}, c::Colon) where {T<:Number} = a.coeffs[c] = x -setindex!{T<:Number}(a::TaylorN{T}, x::Array{T,1}, c::Colon) = +setindex!(a::TaylorN{T}, x::Array{T,1}, c::Colon) where {T<:Number} = a.coeffs[c] = x ## eltype, length, endof, get_order ## for T in (:Taylor1, :HomogeneousPolynomial, :TaylorN) @eval begin - eltype{T<:Number}(::$T{T}) = T + eltype(::$T{S}) where {S<:Number} = S length(a::$T) = length(a.coeffs) @@ -193,7 +193,7 @@ zero_korder(a::TaylorN, k::Int) = HomogeneousPolynomial(zero(a[1][1]), k) # Finds the first non zero entry; extended to Taylor1 -Base.findfirst{T<:Number}(a::Taylor1{T}) = findfirst(a.coeffs)-1 +Base.findfirst(a::Taylor1{T}) where {T<:Number} = findfirst(a.coeffs)-1 """ diff --git a/src/calculus.jl b/src/calculus.jl index 1e9699d2..f09faa2c 100644 --- a/src/calculus.jl +++ b/src/calculus.jl @@ -27,7 +27,7 @@ end Return the value of the `n`-th derivative of the polynomial `a`. """ -function derivative{T<:Number}(n::Int, a::Taylor1{T}) +function derivative(n::Int, a::Taylor1{T}) where {T<:Number} @assert a.order ≥ n ≥ 0 factorial( widen(n) ) * a[n+1] :: T end @@ -39,7 +39,7 @@ end Return the integral of `a::Taylor1`. The constant of integration (0-th order coefficient) is set to `x`, which is zero if ommitted. """ -function integrate{T<:Number, S<:Number}(a::Taylor1{T}, x::S) +function integrate(a::Taylor1{T}, x::S) where {T<:Number, S<:Number} R = promote_type(T, typeof(a[1] / 1), S) coeffs = zeros(R, a.order+1) @inbounds for i = 1:a.order @@ -48,7 +48,7 @@ function integrate{T<:Number, S<:Number}(a::Taylor1{T}, x::S) @inbounds coeffs[1] = convert(R, x) return Taylor1(coeffs, a.order) end -integrate{T<:Number}(a::Taylor1{T}) = integrate(a, zero(T)) +integrate(a::Taylor1{T}) where {T<:Number} = integrate(a, zero(T)) @@ -129,7 +129,7 @@ const ∇ = gradient Compute the jacobian matrix of `vf`, a vector of `TaylorN` polynomials, evaluated at the vector `vals`. If `vals` is ommited, it is evaluated at zero. """ -function jacobian{T<:Number}(vf::Array{TaylorN{T},1}) +function jacobian(vf::Array{TaylorN{T},1}) where {T<:Number} numVars = get_numvars() @assert length(vf) == numVars jac = Array{T}(numVars,numVars) @@ -140,7 +140,9 @@ function jacobian{T<:Number}(vf::Array{TaylorN{T},1}) return transpose(jac) end -function jacobian{T<:Number,S<:Number}(vf::Array{TaylorN{T},1},vals::Array{S,1}) +function jacobian(vf::Array{TaylorN{T},1},vals::Array{S,1}) where + {T<:Number,S<:Number} + R = promote_type(T,S) numVars = get_numvars() @assert length(vf) == numVars == length(vals) @@ -156,7 +158,7 @@ function jacobian{T<:Number,S<:Number}(vf::Array{TaylorN{T},1},vals::Array{S,1}) return transpose(jac) end -function jacobian{T<:Number}(vf::Array{Taylor1{TaylorN{T}},1}) +function jacobian(vf::Array{Taylor1{TaylorN{T}},1}) where {T<:Number} vv = convert(Array{TaylorN{Taylor1{T}},1}, vf) jacobian(vv) end @@ -170,7 +172,7 @@ end Compute the jacobian matrix of `vf`, a vector of `TaylorN` polynomials evaluated at the vector `vals`, and write results to `jac`. If `vals` is ommited, it is evaluated at zero. """ -function jacobian!{T<:Number}(jac::Array{T,2}, vf::Array{TaylorN{T},1}) +function jacobian!(jac::Array{T,2}, vf::Array{TaylorN{T},1}) where {T<:Number} numVars = get_numvars() @assert length(vf) == numVars @assert (numVars, numVars) == size(jac) @@ -181,7 +183,9 @@ function jacobian!{T<:Number}(jac::Array{T,2}, vf::Array{TaylorN{T},1}) end nothing end -function jacobian!{T<:Number}(jac::Array{T,2}, vf::Array{TaylorN{T},1},vals::Array{T,1}) +function jacobian!(jac::Array{T,2}, vf::Array{TaylorN{T},1}, + vals::Array{T,1}) where {T<:Number} + numVars = get_numvars() @assert length(vf) == numVars == length(vals) @assert (numVars, numVars) == size(jac) @@ -204,9 +208,10 @@ Return the hessian matrix (jacobian of the gradient) of `f::TaylorN`, evaluated at the vector `vals`. If `vals` is ommited, it is evaluated at zero. """ -hessian{T<:Number,S<:Number}(f::TaylorN{T}, vals::Array{S,1}) = +hessian(f::TaylorN{T}, vals::Array{S,1}) where {T<:Number, S<:Number} = (R = promote_type(T,S); jacobian( gradient(f), vals::Array{R,1}) ) -hessian{T<:Number}(f::TaylorN{T}) = hessian( f, zeros(T, get_numvars()) ) + +hessian(f::TaylorN{T}) where {T<:Number} = hessian( f, zeros(T, get_numvars()) ) """ ``` @@ -218,7 +223,11 @@ Return the hessian matrix (jacobian of the gradient) of `f::TaylorN`, evaluated at the vector `vals`, and write results to `hes`. If `vals` is ommited, it is evaluated at zero. """ -hessian!{T<:Number}(hes::Array{T,2}, f::TaylorN{T}, vals::Array{T,1}) = jacobian!(hes, gradient(f), vals) -hessian!{T<:Number}(hes::Array{T,2}, f::TaylorN{T}) = jacobian!(hes, gradient(f)) +hessian!(hes::Array{T,2}, f::TaylorN{T}, vals::Array{T,1}) where {T<:Number} = + jacobian!(hes, gradient(f), vals) + +hessian!(hes::Array{T,2}, f::TaylorN{T}) where {T<:Number} = + jacobian!(hes, gradient(f)) + ## TODO: Integration... diff --git a/src/constructors.jl b/src/constructors.jl index bd0782ce..b75724a5 100644 --- a/src/constructors.jl +++ b/src/constructors.jl @@ -12,7 +12,7 @@ Parameterized abstract type for [`Taylor1`](@ref), [`HomogeneousPolynomial`](@ref) and [`TaylorN`](@ref). """ -@compat abstract type AbstractSeries{T<:Number} <: Number end +abstract type AbstractSeries{T<:Number} <: Number end ## Constructors ## @@ -32,22 +32,22 @@ DataType for polynomial expansions in one independent variable. Note that `Taylor1` variables are callable. For more information, see [`evaluate`](@ref). """ -immutable Taylor1{T<:Number} <: AbstractSeries{T} +struct Taylor1{T<:Number} <: AbstractSeries{T} coeffs :: Array{T,1} order :: Int ## Inner constructor ## - function (::Type{Taylor1{T}}){T}(coeffs::Array{T,1}, order::Int) - (order != length(coeffs)-1) && resize_coeffs1!(coeffs, order) + function Taylor1{T}(coeffs::Array{T,1}, order::Int) where T<:Number + resize_coeffs1!(coeffs, order) return new{T}(coeffs, order) end end ## Outer constructors ## -Taylor1{T<:Number}(x::Taylor1{T}) = x -Taylor1{T<:Number}(coeffs::Array{T,1}, order::Int) = Taylor1{T}(coeffs, order) -Taylor1{T<:Number}(coeffs::Array{T,1}) = Taylor1(coeffs, length(coeffs)-1) -function Taylor1{T<:Number}(x::T, order::Int) +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[1] = x return Taylor1(v, order) @@ -68,7 +68,7 @@ julia> Taylor1(Rational{Int}, 4) 1//1 t + 𝒪(t⁵) ``` """ -Taylor1{T<:Number}(::Type{T}, order::Int64=1) = Taylor1{T}( [zero(T), one(T)], order) +Taylor1(::Type{T}, order::Int64=1) where {T<:Number} = Taylor1( [zero(T), one(T)], order) Taylor1(order::Int=1) = Taylor1(Float64, order) @@ -92,19 +92,19 @@ immutable HomogeneousPolynomial{T<:Number} <: AbstractSeries{T} coeffs :: Array{T,1} order :: Int - function (::Type{HomogeneousPolynomial{T}}){T}(coeffs::Array{T,1}, order::Int) + function HomogeneousPolynomial{T}(coeffs::Array{T,1}, order::Int) where T<:Number resize_coeffsHP!(coeffs, order) return new{T}(coeffs, order) end end -HomogeneousPolynomial{T<:Number}(x::HomogeneousPolynomial{T}) = x -HomogeneousPolynomial{T<:Number}(coeffs::Array{T,1}, order::Int) = +HomogeneousPolynomial(x::HomogeneousPolynomial{T}) where {T<:Number} = x +HomogeneousPolynomial(coeffs::Array{T,1}, order::Int) where {T<:Number} = HomogeneousPolynomial{T}(coeffs, order) -HomogeneousPolynomial{T<:Number}(coeffs::Array{T,1}) = - HomogeneousPolynomial{T}(coeffs, orderH(coeffs)) -HomogeneousPolynomial{T<:Number}(x::T, order::Int) = - HomogeneousPolynomial{T}([x], order) +HomogeneousPolynomial(coeffs::Array{T,1}) where {T<:Number} = + HomogeneousPolynomial(coeffs, orderH(coeffs)) +HomogeneousPolynomial(x::T, order::Int) where {T<:Number} = + HomogeneousPolynomial([x], order) # Shortcut to define HomogeneousPolynomial independent variable """ @@ -121,7 +121,7 @@ julia> HomogeneousPolynomial(Rational{Int}, 2) 1//1 x₂ ``` """ -function HomogeneousPolynomial{T<:Number}(::Type{T}, nv::Int) +function HomogeneousPolynomial(::Type{T}, nv::Int) where {T<:Number} @assert 0 < nv ≤ get_numvars() v = zeros(T, get_numvars()) @inbounds v[nv] = one(T) @@ -151,7 +151,7 @@ immutable TaylorN{T<:Number} <: AbstractSeries{T} coeffs :: Array{HomogeneousPolynomial{T},1} order :: Int - function (::Type{TaylorN{T}}){T}(v::Array{HomogeneousPolynomial{T},1}, 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) @@ -163,15 +163,15 @@ immutable TaylorN{T<:Number} <: AbstractSeries{T} end end -TaylorN{T<:Number}(x::TaylorN{T}) = x -TaylorN{T<:Number}(x::Array{HomogeneousPolynomial{T},1}, order::Int) = +TaylorN(x::TaylorN{T}) where T<:Number = x +TaylorN(x::Array{HomogeneousPolynomial{T},1}, order::Int) where {T<:Number} = TaylorN{T}(x, order) -TaylorN{T<:Number}(x::Array{HomogeneousPolynomial{T},1}) = TaylorN{T}(x,0) -TaylorN{T<:Number}(x::HomogeneousPolynomial{T},order::Int) = - TaylorN{T}([x], order) -TaylorN{T<:Number}(x::HomogeneousPolynomial{T}) = TaylorN{T}([x], x.order) -TaylorN{T<:Number}(x::T, order::Int) = - TaylorN{T}([HomogeneousPolynomial([x], 0)], 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) +TaylorN(x::T, order::Int) where {T<:Number} = + TaylorN([HomogeneousPolynomial([x], 0)], order) # Shortcut to define TaylorN independent variables """ @@ -190,7 +190,7 @@ julia> TaylorN(Rational{Int},2) 1//1 x₂ + 𝒪(‖x‖⁷) ``` """ -TaylorN{T<:Number}(::Type{T}, nv::Int; order::Int=get_order()) = +TaylorN(::Type{T}, nv::Int; order::Int=get_order()) where {T<:Number} = return TaylorN( [HomogeneousPolynomial(T, nv)], order ) TaylorN(nv::Int; order::Int=get_order()) = TaylorN(Float64, nv, order=order) diff --git a/src/conversion.jl b/src/conversion.jl index 3b44d4b2..13308e07 100644 --- a/src/conversion.jl +++ b/src/conversion.jl @@ -7,80 +7,85 @@ # ## Conversion -convert{T<:Number}(::Type{Taylor1{T}}, a::Taylor1) = +convert(::Type{Taylor1{T}}, a::Taylor1) where {T<:Number} = Taylor1(convert(Array{T,1}, a.coeffs), a.order) -function convert{T<:Integer, S<:AbstractFloat}(::Type{Taylor1{Rational{T}}}, - a::Taylor1{S}) +function convert(::Type{Taylor1{Rational{T}}}, a::Taylor1{S}) where + {T<:Integer, S<:AbstractFloat} + la = length(a.coeffs) v = Array{Rational{T}}(la) v .= rationalize.(a[1:la]) return Taylor1(v) end -convert{T<:Number}(::Type{Taylor1{T}}, b::Array{T,1}) = Taylor1(b, length(b)-1) +convert(::Type{Taylor1{T}}, b::Array{T,1}) where {T<:Number} = + Taylor1(b, length(b)-1) -convert{T<:Number, S<:Number}(::Type{Taylor1{T}}, b::Array{S,1}) = +convert(::Type{Taylor1{T}}, b::Array{S,1}) where {T<:Number, S<:Number} = Taylor1(convert(Array{T,1},b)) -convert{T<:Number, S<:Number}(::Type{Taylor1{T}}, b::S) = Taylor1([convert(T,b)], 0) +convert(::Type{Taylor1{T}}, b::S) where {T<:Number, S<:Number} = + Taylor1([convert(T,b)], 0) -convert{T<:Number}(::Type{Taylor1{T}}, b::T) = Taylor1([b], 0) +convert(::Type{Taylor1{T}}, b::T) where {T<:Number} = Taylor1([b], 0) convert(::Type{Taylor1}, a::Number) = Taylor1(a, 0) -convert{T<:Number}(::Type{HomogeneousPolynomial{T}}, a::HomogeneousPolynomial) = - HomogeneousPolynomial{T}(convert(Array{T,1}, a.coeffs), a.order) +convert(::Type{HomogeneousPolynomial{T}}, a::HomogeneousPolynomial) where {T<:Number} = + HomogeneousPolynomial(convert(Array{T,1}, a.coeffs), a.order) + +function convert(::Type{HomogeneousPolynomial{Rational{T}}}, + a::HomogeneousPolynomial{S}) where {T<:Integer, S<:AbstractFloat} -function convert{T<:Integer, S<:AbstractFloat}( - ::Type{HomogeneousPolynomial{Rational{T}}}, a::HomogeneousPolynomial{S}) la = length(a.coeffs) v = Array{Rational{T}}(la) v .= rationalize.(a[1:la], tol=eps(one(S))) return HomogeneousPolynomial(v, a.order) end -convert{T<:Number, S<:Number}(::Type{HomogeneousPolynomial{T}}, b::Array{S,1}) = - HomogeneousPolynomial{T}(convert(Array{T,1}, b), orderH(b)) -convert{T<:Number, S<:Number}(::Type{HomogeneousPolynomial{T}}, b::S) = - HomogeneousPolynomial{T}([convert(T,b)], 0) +convert(::Type{HomogeneousPolynomial{T}}, b::Array{S,1}) where {T<:Number, S<:Number} = + HomogeneousPolynomial(convert(Array{T,1}, b), orderH(b)) -convert{T<:Number}(::Type{HomogeneousPolynomial{T}}, b::Array{T,1}) = - HomogeneousPolynomial{T}(b, orderH(b)) +convert(::Type{HomogeneousPolynomial{T}}, b::S) where {T<:Number, S<:Number}= + HomogeneousPolynomial([convert(T,b)], 0) -convert{T<:Number}(::Type{HomogeneousPolynomial{T}}, b::T) = - HomogeneousPolynomial{T}([b], 0) +convert(::Type{HomogeneousPolynomial{T}}, b::Array{T,1}) where {T<:Number} = + HomogeneousPolynomial(b, orderH(b)) + +convert(::Type{HomogeneousPolynomial{T}}, b::T) where {T<:Number} = + HomogeneousPolynomial([b], 0) convert(::Type{HomogeneousPolynomial}, a::Number) = HomogeneousPolynomial([a],0) -convert{T<:Number}(::Type{TaylorN{T}}, a::TaylorN) = - TaylorN{T}( convert(Array{HomogeneousPolynomial{T},1}, a.coeffs), a.order) +convert(::Type{TaylorN{T}}, a::TaylorN) where {T<:Number} = + TaylorN( convert(Array{HomogeneousPolynomial{T},1}, a.coeffs), a.order) -convert{T<:Number, S<:Number}(::Type{TaylorN{T}}, b::HomogeneousPolynomial{S}) = - TaylorN{T}( [convert(HomogeneousPolynomial{T}, b)], b.order) +convert(::Type{TaylorN{T}}, b::HomogeneousPolynomial{S}) where {T<:Number, S<:Number} = + TaylorN( [convert(HomogeneousPolynomial{T}, b)], b.order) -convert{T<:Number, S<:Number}(::Type{TaylorN{T}}, - b::Array{HomogeneousPolynomial{S},1}) = - TaylorN{T}( convert(Array{HomogeneousPolynomial{T},1}, b), length(b)-1) +convert(::Type{TaylorN{T}}, b::Array{HomogeneousPolynomial{S},1}) where {T<:Number, S<:Number} = + TaylorN( convert(Array{HomogeneousPolynomial{T},1}, b), length(b)-1) -convert{T<:Number, S<:Number}(::Type{TaylorN{T}}, b::S) = +convert(::Type{TaylorN{T}}, b::S) where {T<:Number, S<:Number} = TaylorN( [HomogeneousPolynomial([convert(T, b)], 0)], 0) -convert{T<:Number}(::Type{TaylorN{T}}, b::HomogeneousPolynomial{T}) = - TaylorN{T}( [b], b.order) +convert(::Type{TaylorN{T}}, b::HomogeneousPolynomial{T}) where {T<:Number} = + TaylorN( [b], b.order) -convert{T<:Number}(::Type{TaylorN{T}}, b::Array{HomogeneousPolynomial{T},1}) = - TaylorN{T}( b, length(b)-1) +convert(::Type{TaylorN{T}}, b::Array{HomogeneousPolynomial{T},1}) where {T<:Number} = + TaylorN( b, length(b)-1) -convert{T<:Number}(::Type{TaylorN{T}}, b::T) = +convert(::Type{TaylorN{T}}, b::T) where {T<:Number} = TaylorN( [HomogeneousPolynomial([b], 0)], 0) convert(::Type{TaylorN}, b::Number) = TaylorN( [HomogeneousPolynomial([b], 0)], 0) -function convert{T<:Number}(::Type{TaylorN{Taylor1{T}}}, s::Taylor1{TaylorN{T}}) +function convert(::Type{TaylorN{Taylor1{T}}}, s::Taylor1{TaylorN{T}}) where {T<:Number} + orderN = get_order() r = zeros(HomogeneousPolynomial{Taylor1{T}}, orderN) @@ -98,7 +103,8 @@ function convert{T<:Number}(::Type{TaylorN{Taylor1{T}}}, s::Taylor1{TaylorN{T}}) return TaylorN(r) end -function convert{T<:Number}(::Type{Taylor1{TaylorN{T}}}, s::TaylorN{Taylor1{T}}) +function convert(::Type{Taylor1{TaylorN{T}}}, s::TaylorN{Taylor1{T}}) where {T<:Number} + ordert = 0 for ordHP in eachindex(s.coeffs) ordert = max(ordert, s[ordHP][1].order) @@ -122,8 +128,9 @@ function convert{T<:Number}(::Type{Taylor1{TaylorN{T}}}, s::TaylorN{Taylor1{T}}) return Taylor1(vT) end -function convert{T<:Number,N}(::Type{Array{TaylorN{Taylor1{T}},N}}, - s::Array{Taylor1{TaylorN{T}},N}) +function convert(::Type{Array{TaylorN{Taylor1{T}},N}}, + s::Array{Taylor1{TaylorN{T}},N}) where {T<:Number, N} + v = Array{TaylorN{Taylor1{T}}}(size(s)) for ind in eachindex(s) v[ind] = convert(TaylorN{Taylor1{T}}, s[ind]) @@ -131,8 +138,9 @@ function convert{T<:Number,N}(::Type{Array{TaylorN{Taylor1{T}},N}}, return v end -function convert{T<:Number,N}(::Type{Array{Taylor1{TaylorN{T}},N}}, - s::Array{TaylorN{Taylor1{T}},N}) +function convert(::Type{Array{Taylor1{TaylorN{T}},N}}, + s::Array{TaylorN{Taylor1{T}},N}) where {T<:Number, N} + v = Array{Taylor1{TaylorN{T}}}(size(s)) for ind in eachindex(s) v[ind] = convert(Taylor1{TaylorN{T}}, s[ind]) @@ -143,40 +151,41 @@ end # Promotion -promote_rule{T<:Number}(::Type{Taylor1{T}}, ::Type{Taylor1{T}}) = Taylor1{T} +promote_rule(::Type{Taylor1{T}}, ::Type{Taylor1{T}}) where {T<:Number} = Taylor1{T} -promote_rule{T<:Number, S<:Number}(::Type{Taylor1{T}}, ::Type{Taylor1{S}}) = - Taylor1{promote_type(T, S)} +promote_rule(::Type{Taylor1{T}}, ::Type{Taylor1{S}}) where {T<:Number, S<:Number} = + Taylor1{promote_type(T,S)} -promote_rule{T<:Number}(::Type{Taylor1{T}}, ::Type{Array{T,1}}) = Taylor1{T} +promote_rule(::Type{Taylor1{T}}, ::Type{Array{T,1}}) where {T<:Number} = Taylor1{T} -promote_rule{T<:Number, S<:Number}(::Type{Taylor1{T}}, ::Type{Array{S,1}}) = - Taylor1{promote_type(T, S)} +promote_rule(::Type{Taylor1{T}}, ::Type{Array{S,1}}) where {T<:Number, S<:Number} = + Taylor1{promote_type(T,S)} -promote_rule{T<:Number}(::Type{Taylor1{T}}, ::Type{T}) = Taylor1{T} +promote_rule(::Type{Taylor1{T}}, ::Type{T}) where {T<:Number} = Taylor1{T} -promote_rule{T<:Number, S<:Number}(::Type{Taylor1{T}}, ::Type{S}) = - Taylor1{promote_type(T, S)} +promote_rule(::Type{Taylor1{T}}, ::Type{S}) where {T<:Number, S<:Number} = + Taylor1{promote_type(T,S)} -promote_rule{T<:Number, S<:Number}(::Type{HomogeneousPolynomial{T}}, - ::Type{HomogeneousPolynomial{S}}) = HomogeneousPolynomial{promote_type(T,S)} +promote_rule(::Type{HomogeneousPolynomial{T}}, + ::Type{HomogeneousPolynomial{S}}) where {T<:Number, S<:Number} = + HomogeneousPolynomial{promote_type(T,S)} -promote_rule{T<:Number, S<:Number}(::Type{HomogeneousPolynomial{T}}, - ::Type{Array{S,1}}) = HomogeneousPolynomial{promote_type(T, S)} +promote_rule(::Type{HomogeneousPolynomial{T}}, + ::Type{Array{S,1}}) where {T<:Number, S<:Number} = HomogeneousPolynomial{promote_type(T,S)} -promote_rule{T<:Number,S<:Union{Real,Complex}}(::Type{HomogeneousPolynomial{T}}, - ::Type{S}) = HomogeneousPolynomial{promote_type(T,S)} +promote_rule(::Type{HomogeneousPolynomial{T}}, ::Type{S}) where + {T<:Number, S<:NumberNotSeries} = HomogeneousPolynomial{promote_type(T,S)} -promote_rule{T<:Number, S<:Number}(::Type{TaylorN{T}}, ::Type{TaylorN{S}}) = - TaylorN{promote_type(T, S)} +promote_rule(::Type{TaylorN{T}}, ::Type{TaylorN{S}}) where {T<:Number, S<:Number}= + TaylorN{promote_type(T,S)} -promote_rule{T<:Number, S<:Number}(::Type{TaylorN{T}}, - ::Type{HomogeneousPolynomial{S}}) = TaylorN{promote_type(T, S)} +promote_rule(::Type{TaylorN{T}}, ::Type{HomogeneousPolynomial{S}}) where + {T<:Number, S<:Number} = TaylorN{promote_type(T,S)} -promote_rule{T<:Number, S<:Number}(::Type{TaylorN{T}}, - ::Type{Array{HomogeneousPolynomial{S},1}}) = TaylorN{promote_type(T, S)} +promote_rule(::Type{TaylorN{T}}, ::Type{Array{HomogeneousPolynomial{S},1}}) where + {T<:Number, S<:Number} = TaylorN{promote_type(T,S)} -promote_rule{T<:Number, S<:Number}(::Type{TaylorN{T}}, ::Type{S}) = - TaylorN{promote_type(T, S)} +promote_rule(::Type{TaylorN{T}}, ::Type{S}) where {T<:Number, S<:Number} = + TaylorN{promote_type(T,S)} diff --git a/src/evaluate.jl b/src/evaluate.jl index 0e472a8d..6dc4b816 100644 --- a/src/evaluate.jl +++ b/src/evaluate.jl @@ -15,15 +15,14 @@ ommitted, its value is considered as zero. Note that a `Taylor1` polynomial `a` may also be evaluated by calling it as a function; that is, the syntax `a(dx)` is equivalent to `evaluate(a,dx)`, and `a()` is equivalent to `evaluate(a)`. """ -function evaluate{T<:Number}(a::Taylor1{T}, dx::T) +function evaluate(a::Taylor1{T}, dx::T) where {T<:Number} @inbounds suma = a[end] @inbounds for k = a.order:-1:1 suma = suma*dx + a[k] end suma end - -function evaluate{T<:Number,S<:Number}(a::Taylor1{T}, dx::S) +function evaluate(a::Taylor1{T}, dx::S) where {T<:Number, S<:Number} R = promote_type(T,S) @inbounds suma = convert(R, a[end]) @inbounds for k = a.order:-1:1 @@ -31,8 +30,7 @@ function evaluate{T<:Number,S<:Number}(a::Taylor1{T}, dx::S) end suma end - -evaluate{T<:Number}(a::Taylor1{T}) = a[1] +evaluate(a::Taylor1{T}) where {T<:Number} = a[1] doc""" evaluate(x, δt) @@ -43,17 +41,16 @@ the dependent variables of an ODE, at *time* δt. Note that an array `x` of that is, the syntax `x(δt)` is equivalent to `evaluate(x, δt)`, and `x()` is equivalent to `evaluate(x)`. """ -function evaluate{T<:Number, S<:Number}(x::Array{Taylor1{T},1}, δt::S) +function evaluate(x::Array{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{T<:Number}(x::Array{Taylor1{T},1}, δt::T) +function evaluate(x::Array{Taylor1{T},1}, δt::T) where {T<:Number} xnew = Array{T}( length(x) ) evaluate!(x, δt, xnew) return xnew end -evaluate{T<:Number}(a::Array{Taylor1{T},1}) = evaluate.(a) +evaluate(a::Array{Taylor1{T},1}) where {T<:Number} = evaluate(a, zero(T)) doc""" evaluate!(x, δt, x0) @@ -63,15 +60,18 @@ representing the Taylor expansion for the dependent variables of an ODE at *time* `δt`. It updates the vector `x0` with the computed values. """ -function evaluate!{T<:Number}(x::Array{Taylor1{T},1}, δt::T, x0::Union{Array{T,1},SubArray{T,1}}) +function evaluate!(x::Array{Taylor1{T},1}, δt::T, + x0::Union{Array{T,1},SubArray{T,1}}) where {T<:Number} + @assert length(x) == length(x0) @inbounds for i in eachindex(x) x0[i] = evaluate( x[i], δt ) end nothing end +function evaluate!(x::Array{Taylor1{T},1}, δt::S, + x0::Union{Array{T,1},SubArray{T,1}}) where {T<:Number, S<:Number} -function evaluate!{T<:Number, S<:Number}(x::Array{Taylor1{T},1}, δt::S, x0::Union{Array{T,1},SubArray{T,1}}) @assert length(x) == length(x0) @inbounds for i in eachindex(x) x0[i] = evaluate( x[i], δt ) @@ -85,9 +85,10 @@ doc""" Substitute `x::Taylor1` as independent variable in a `a::Taylor1` polynomial. Note that the syntax `a(x)` is equivalent to `evaluate(a, x)`. """ -evaluate{T<:Number,S<:Number}(a::Taylor1{T}, x::Taylor1{S}) = +evaluate(a::Taylor1{T}, x::Taylor1{S}) where {T<:Number, S<:Number} = evaluate(promote(a,x)...) -function evaluate{T<:Number}(a::Taylor1{T}, x::Taylor1{T}) + +function evaluate(a::Taylor1{T}, x::Taylor1{T}) where {T<:Number} if a.order != x.order a, x = fixorder(a, x) end @@ -98,7 +99,7 @@ function evaluate{T<:Number}(a::Taylor1{T}, x::Taylor1{T}) suma end -function evaluate{T<:Number}(a::Taylor1{Taylor1{T}}, x::Taylor1{T}) +function evaluate(a::Taylor1{Taylor1{T}}, x::Taylor1{T}) where {T<:Number} @inbounds suma = a[end] @inbounds for k = a.order:-1:1 suma = suma*x + a[k] @@ -106,7 +107,8 @@ function evaluate{T<:Number}(a::Taylor1{Taylor1{T}}, x::Taylor1{T}) suma end -evaluate{T<:Number,S<:Number}(p::Taylor1{T},x::Array{S}) = evaluate.(p,x) +evaluate(p::Taylor1{T}, x::Array{S}) where {T<:Number, S<:Number} = + evaluate.(p, x) #function-like behavior for Taylor1 (p::Taylor1)(x) = evaluate(p, x) @@ -114,13 +116,14 @@ evaluate{T<:Number,S<:Number}(p::Taylor1{T},x::Array{S}) = evaluate.(p,x) (p::Taylor1)() = evaluate(p) #function-like behavior for Array{Taylor1,1} -(p::Array{Taylor1{T},1}){T<:Number}(x) = evaluate(p, x) +(p::Array{Taylor1{T},1})(x) where {T<:Number} = evaluate(p, x) -(p::Array{Taylor1{T},1}){T<:Number}() = evaluate.(p) +(p::Array{Taylor1{T},1})() where {T<:Number} = evaluate.(p) ## Evaluation of multivariable -function evaluate!{T<:Number}(x::Array{TaylorN{T},1}, δx::Array{T,1}, - x0::Array{T,1}) +function evaluate!(x::Array{TaylorN{T},1}, δx::Array{T,1}, + x0::Array{T,1}) where {T<:Number} + @assert length(x) == length(x0) @inbounds for i in eachindex(x) x0[i] = evaluate( x[i], δx ) @@ -128,8 +131,9 @@ function evaluate!{T<:Number}(x::Array{TaylorN{T},1}, δx::Array{T,1}, nothing end -function evaluate!{T<:NumberNotSeriesN}(x::Array{TaylorN{T},1}, δx::Array{Taylor1{T},1}, - x0::Array{Taylor1{T},1}) +function evaluate!(x::Array{TaylorN{T},1}, δx::Array{Taylor1{T},1}, + x0::Array{Taylor1{T},1}) where {T<:NumberNotSeriesN} + @assert length(x) == length(x0) @inbounds for i in eachindex(x) x0[i] = evaluate( x[i], δx ) @@ -137,8 +141,9 @@ function evaluate!{T<:NumberNotSeriesN}(x::Array{TaylorN{T},1}, δx::Array{Taylo nothing end -function evaluate!{T<:NumberNotSeriesN}(x::Array{TaylorN{T},1}, δx::Array{TaylorN{T},1}, - x0::Array{TaylorN{T},1}) +function evaluate!(x::Array{TaylorN{T},1}, δx::Array{TaylorN{T},1}, + x0::Array{TaylorN{T},1}) where {T<:NumberNotSeriesN} + @assert length(x) == length(x0) @inbounds for i in eachindex(x) x0[i] = evaluate( x[i], δx ) @@ -146,8 +151,9 @@ function evaluate!{T<:NumberNotSeriesN}(x::Array{TaylorN{T},1}, δx::Array{Taylo nothing end -function evaluate!{T<:Number}(x::Array{Taylor1{TaylorN{T}},1}, δt::T, - x0::Array{TaylorN{T},1}) +function evaluate!(x::Array{Taylor1{TaylorN{T}},1}, δt::T, + x0::Array{TaylorN{T},1}) where {T<:Number} + @assert length(x) == length(x0) @inbounds for i in eachindex(x) x0[i] = evaluate( x[i], δt ) @@ -162,8 +168,9 @@ Evaluate a `HomogeneousPolynomial` polynomial at `vals`. If `vals` is ommitted, it's evaluated at zero. Note that the syntax `a(vals)` is equivalent to `evaluate(a, vals)`; and `a()` is equivalent to `evaluate(a)`. """ -function evaluate{T<:Number,S<:NumberNotSeriesN}(a::HomogeneousPolynomial{T}, - vals::Array{S,1} ) +function evaluate(a::HomogeneousPolynomial{T}, vals::Array{S,1} ) where + {T<:Number, S<:NumberNotSeriesN} + @assert length(vals) == get_numvars() num_vars = get_numvars() @@ -197,8 +204,9 @@ If `vals` is ommitted, it's evaluated at zero. Note that the syntax `a(vals)` is equivalent to `evaluate(a, vals)`; and `a()` is equivalent to `evaluate(a)`. """ -function evaluate{T<:Number,S<:NumberNotSeries}(a::TaylorN{T}, - vals::Array{S,1}) +function evaluate(a::TaylorN{T}, vals::Array{S,1}) where + {T<:Number,S<:NumberNotSeriesN} + @assert length(vals) == get_numvars() num_vars = get_numvars() @@ -219,9 +227,9 @@ function evaluate{T<:Number,S<:NumberNotSeries}(a::TaylorN{T}, return sum( sort!(suma, by=abs2) ) end +function evaluate(a::TaylorN{T}, vals::Array{Taylor1{S},1}) where + {T<:Number, S<:NumberNotSeries} -function evaluate{T<:Number,S<:NumberNotSeries}(a::TaylorN{T}, - vals::Array{Taylor1{S},1}) @assert length(vals) == get_numvars() num_vars = get_numvars() @@ -243,8 +251,9 @@ function evaluate{T<:Number,S<:NumberNotSeries}(a::TaylorN{T}, return suma end -function evaluate{T<:NumberNotSeries}(a::TaylorN{Taylor1{T}}, - vals::Array{Taylor1{T},1}) +function evaluate(a::TaylorN{Taylor1{T}}, vals::Array{Taylor1{T},1}) where + {T<:NumberNotSeries} + @assert length(vals) == get_numvars() num_vars = get_numvars() @@ -265,8 +274,9 @@ function evaluate{T<:NumberNotSeries}(a::TaylorN{Taylor1{T}}, return suma end -function evaluate{T<:Number,S<:NumberNotSeries}(a::TaylorN{T}, - vals::Array{TaylorN{S},1}) +function evaluate(a::TaylorN{T}, vals::Array{TaylorN{S},1}) where + {T<:Number, S<:NumberNotSeries} + @assert length(vals) == get_numvars() num_vars = get_numvars() @@ -289,27 +299,31 @@ function evaluate{T<:Number,S<:NumberNotSeries}(a::TaylorN{T}, end -evaluate{T<:Number}(a::TaylorN{T}) = a[1][1] +evaluate(a::TaylorN{T}) where {T<:Number} = a[1][1] -function evaluate{T<:Number}(x::Array{TaylorN{T},1}, δx::Array{T,1}) +function evaluate(x::Array{TaylorN{T},1}, δx::Array{T,1}) where {T<:Number} x0 = Array{T}( length(x) ) evaluate!( x, δx, x0 ) return x0 end -function evaluate{T<:NumberNotSeriesN}(x::Array{TaylorN{T},1}, δx::Array{Taylor1{T},1}) +function evaluate(x::Array{TaylorN{T},1}, δx::Array{Taylor1{T},1}) where + {T<:NumberNotSeriesN} + x0 = Array{Taylor1{T}}( length(x) ) evaluate!( x, δx, x0 ) return x0 end -function evaluate{T<:NumberNotSeriesN}(x::Array{TaylorN{T},1}, δx::Array{TaylorN{T},1}) +function evaluate(x::Array{TaylorN{T},1}, δx::Array{TaylorN{T},1}) where + {T<:NumberNotSeriesN} + x0 = Array{TaylorN{T}}( length(x) ) evaluate!( x, δx, x0 ) return x0 end -evaluate{T<:Number}(x::Array{TaylorN{T},1}) = evaluate.(x) +evaluate(x::Array{TaylorN{T},1}) where {T<:Number} = evaluate.(x) #function-like behavior for TaylorN (p::TaylorN)(x) = evaluate(p, x) diff --git a/src/functions.jl b/src/functions.jl index 60fd23dc..8fe6d941 100644 --- a/src/functions.jl +++ b/src/functions.jl @@ -336,7 +336,7 @@ f^{-1}(t) = \sum_{n=1}^{N} \frac{t^n}{n!} \left. ``` """ -function inverse{T<:Number}(f::Taylor1{T}) +function inverse(f::Taylor1{T}) where {T<:Number} if f[1] != zero(T) throw(ArgumentError( """ diff --git a/src/other_functions.jl b/src/other_functions.jl index bcde6246..c7c3aa38 100644 --- a/src/other_functions.jl +++ b/src/other_functions.jl @@ -13,8 +13,6 @@ for T in (:Taylor1, :HomogeneousPolynomial, :TaylorN) @eval ($f)(a::$T) = $T(($f).(a.coeffs), a.order) end - @eval real{T<:Number}(x::Type{$T{T}}) = typeof(real(zero(x))) - @eval ctranspose(a::$T) = conj.(a) ## isinf and isnan ## @@ -28,13 +26,13 @@ end for op in (:mod, :rem) for T in (:Taylor1, :TaylorN) @eval begin - function ($op){T<:Real}(a::$T{T}, x::T) + function ($op)(a::$T{T}, x::T) where {T<:Real} coeffs = copy(a.coeffs) @inbounds coeffs[1] = ($op)(constant_term(a), x) return $T(coeffs, a.order) end - function ($op){T<:Real, S<:Real}(a::$T{T}, x::S) + function ($op)(a::$T{T}, x::S) where {T<:Real, S<:Real} R = promote_type(T, S) a = convert($T{R}, a) return ($op)(a, convert(R,x)) @@ -43,25 +41,27 @@ for op in (:mod, :rem) end @eval begin - function ($op){T<:Real}(a::TaylorN{Taylor1{T}}, x::T) + function ($op)(a::TaylorN{Taylor1{T}}, x::T) where {T<:Real} coeffs = copy(a.coeffs) @inbounds coeffs[1] = ($op)(constant_term(a), x) return TaylorN( coeffs, a.order ) end - function ($op){T<:Real,S<:Real}(a::TaylorN{Taylor1{T}}, x::S) + function ($op)(a::TaylorN{Taylor1{T}}, x::S) where {T<:Real, S<:Real} R = promote_type(T,S) a = convert(TaylorN{Taylor1{R}}, a) return ($op)(a, convert(R,x)) end - function ($op){T<:Real}(a::Taylor1{TaylorN{T}}, x::T) + function ($op)(a::Taylor1{TaylorN{T}}, x::T) where {T<:Real} coeffs = copy(a.coeffs) @inbounds coeffs[1] = ($op)(constant_term(a), x) return Taylor1( coeffs, a.order ) end - @inbounds function ($op){T<:Real,S<:Real}(a::Taylor1{TaylorN{T}}, x::S) + @inbounds function ($op)(a::Taylor1{TaylorN{T}}, x::S) where + {T<:Real, S<:Real} + R = promote_type(T,S) a = convert(Taylor1{TaylorN{R}}, a) return ($op)(a, convert(R,x)) @@ -73,13 +73,13 @@ end ## mod2pi and abs ## for T in (:Taylor1, :TaylorN) @eval begin - function mod2pi{T<:Real}(a::$T{T}) + function mod2pi(a::$T{T}) where {T<:Real} coeffs = copy(a.coeffs) @inbounds coeffs[1] = mod2pi( constant_term(a) ) return $T( coeffs, a.order) end - function abs{T<:Real}(a::$T{T}) + function abs(a::$T{T}) where {T<:Real} if constant_term(a) > zero(T) return a elseif constant_term(a) < zero(T) @@ -93,20 +93,19 @@ for T in (:Taylor1, :TaylorN) end end - -function mod2pi{T<:Real}(a::TaylorN{Taylor1{T}}) +function mod2pi(a::TaylorN{Taylor1{T}}) where {T<:Real} coeffs = copy(a.coeffs) @inbounds coeffs[1] = mod2pi( constant_term(a) ) return TaylorN( coeffs, a.order ) end -function mod2pi{T<:Real}(a::Taylor1{TaylorN{T}}) +function mod2pi(a::Taylor1{TaylorN{T}}) where {T<:Real} coeffs = copy(a.coeffs) @inbounds coeffs[1] = mod2pi( constant_term(a) ) return Taylor1( coeffs, a.order ) end -function abs{T<:Real}(a::TaylorN{Taylor1{T}}) +function abs(a::TaylorN{Taylor1{T}}) where {T<:Real} if constant_term(a)[1] > zero(T) return a elseif constant_term(a)[1] < zero(T) @@ -118,7 +117,7 @@ function abs{T<:Real}(a::TaylorN{Taylor1{T}}) end end -function abs{T<:Real}(a::Taylor1{TaylorN{T}}) +function abs(a::Taylor1{TaylorN{T}}) where {T<:Real} if constant_term(a[1]) > zero(T) return a elseif constant_term(a[1]) < zero(T) @@ -142,22 +141,26 @@ Notice that `typeof(abs(a)) <: AbstractSeries`. #norm doc""" - norm(x::AbstractSeries,p::Real) -Computes the p-norm of an `AbstractSeries` defined by ``P(\vec{x}) = \sum_k a_k \vec{x}^k`` as + norm(x::AbstractSeries, p::Real) + +Returns the p-norm of an `x::AbstractSeries`, defined by ```math -||P||_p = \left( \sum_k ||a_k||_p^p \right)^{\frac{1}{p}} +\begin{equation*} +\left\Vert x \right\Vert_p = \left( \sum_k | x_k |^p \right)^{\frac{1}{p}}, +\end{equation*} ``` which returns a non-negative number. """ norm(x::AbstractSeries, p::Real=2) = norm( norm.(x.coeffs, p), p) -norm{T<:NumberNotSeries}(x::Union{Taylor1{T}, HomogeneousPolynomial{T}}, p::Real=2) = norm(x.coeffs, p) +norm(x::Union{Taylor1{T},HomogeneousPolynomial{T}}, p::Real=2) where + {T<:NumberNotSeries} = norm(x.coeffs, p) # rtoldefault for T in (:Taylor1, :HomogeneousPolynomial, :TaylorN) - @eval rtoldefault{T<:Number}(::Type{$T{T}}) = rtoldefault(T) + @eval rtoldefault(::Type{$T{T}}) where {T<:Number} = rtoldefault(T) end # isfinite @@ -170,38 +173,47 @@ isfinite(x::AbstractSeries) = !isnan(x) && !isinf(x) # isapprox; modified from Julia's Base.isapprox doc""" - isapprox(x::AbstractSeries, y::AbstractSeries; [rtol::Real=sqrt(eps), atol::Real=0, nans::Bool=false]) + isapprox(x::AbstractSeries, y::AbstractSeries; + rtol::Real=sqrt(eps), atol::Real=0, nans::Bool=false) Inexact equality comparison between polynomials: returns `true` if `norm(x-y,1) <= atol + rtol*max(norm(x,1), norm(y,1))`, where `x` and `y` are polynomials. For more details, see [`Base.isapprox`](@ref). """ -function isapprox{T<:AbstractSeries,S<:AbstractSeries}(x::T, y::S; rtol::Real=rtoldefault(x,y), atol::Real=0, nans::Bool=false) - x == y || (isfinite(x) && isfinite(y) && norm(x-y,1) <= atol + rtol*max(norm(x,1), norm(y,1))) || (nans && isnan(x) && isnan(y)) +function isapprox(x::T, y::S; rtol::Real=rtoldefault(x,y), atol::Real=0, + nans::Bool=false) where {T<:AbstractSeries, S<:AbstractSeries} + + x == y || (isfinite(x) && isfinite(y) && + norm(x-y,1) <= atol + rtol*max(norm(x,1), norm(y,1))) || + (nans && isnan(x) && isnan(y)) end #taylor_expand function for Taylor1 doc""" - taylor_expand(f ,x0 ;order) + taylor_expand(f, x0; order) + +Computes the Taylor expansion of the function `f` around the point `x0`. -Makes a Taylor expansion of the function `f` around the point `x0`. If x0 is a scalar, -a `Taylor1` expansion will be done. If `x0` is a vector, a `TaylorN` expansion will be -computed. If the dimension of x0 (`length(x0)`) is different from the variables set for -`TaylorN` (`get_numvars()`), an `AssertionError` will be thrown. +If `x0` is a scalar, a `Taylor1` expansion will be returned. If `x0` is a vector, +a `TaylorN` expansion will be computed. If the dimension of x0 (`length(x0)`) +is different from the variables set for `TaylorN` (`get_numvars()`), an +`AssertionError` will be thrown. """ function taylor_expand(f::Function; order::Int64=15) a = Taylor1(order) return f(a) end -function taylor_expand{T<:Number}(f::Function, x0::T; order::Int64=15) +function taylor_expand(f::Function, x0::T; order::Int64=15) where {T<:Number} a = Taylor1([x0, one(T)], order) return f(a) end #taylor_expand function for TaylorN -function taylor_expand{T<:Number}(f::Function, x0::Vector{T}; order::Int64=get_order()) #a Taylor expansion around x0 +function taylor_expand(f::Function, x0::Vector{T}; + order::Int64=get_order()) where {T<:Number} + ll = length(x0) @assert ll == get_numvars() && order <= get_order() X = Array{TaylorN{T}}(ll) @@ -213,7 +225,7 @@ function taylor_expand{T<:Number}(f::Function, x0::Vector{T}; order::Int64=get_o return f( X ) end -function taylor_expand(f::Function, x0...; order::Int64=get_order()) #a Taylor expansion around x0 +function taylor_expand(f::Function, x0...; order::Int64=get_order()) x0 = promote(x0...) T = eltype(x0[1]) ll = length(x0) @@ -229,18 +241,18 @@ end #update! function for Taylor1 doc""" - update!(a,x0;order) + update!(a, x0) Takes `a <: Union{Taylo1,TaylorN}` and expands it around the coordinate `x0`. """ -function update!{T<:Number}(a::Taylor1, x0::T) - a.coeffs .= evaluate(a, Taylor1([x0,one(x0)], a.order) ).coeffs +function update!(a::Taylor1, x0::T) where {T<:Number} + a.coeffs .= evaluate(a, Taylor1([x0, one(x0)], a.order) ).coeffs nothing end #update! function for TaylorN -function update!{T<:Number}(a::TaylorN,vals::Vector{T}) - a.coeffs .= evaluate(a,get_variables().+vals).coeffs +function update!(a::TaylorN, vals::Vector{T}) where {T<:Number} + a.coeffs .= evaluate(a, get_variables() .+ vals).coeffs nothing end diff --git a/src/parameters.jl b/src/parameters.jl index fa515f99..63042422 100644 --- a/src/parameters.jl +++ b/src/parameters.jl @@ -17,7 +17,7 @@ DataType holding the current parameters for `TaylorN` and These parameters can be changed using `set_params_TaylorN(order, numVars)`. """ -type ParamsTaylorN +mutable struct ParamsTaylorN order :: Int num_vars :: Int variable_names :: Array{String,1} @@ -31,7 +31,8 @@ get_order() = _params_TaylorN_.order get_numvars() = _params_TaylorN_.num_vars get_variable_names() = _params_TaylorN_.variable_names -set_variable_names{T<:AbstractString}(names::Vector{T}) = _params_TaylorN_.variable_names = names +set_variable_names(names::Vector{T}) where {T<:AbstractString} = + _params_TaylorN_.variable_names = names get_variables() = [TaylorN(i) for i in 1:get_numvars()] @@ -66,7 +67,9 @@ julia> set_variables("x", order=6, numvars=2) 1.0 x₂ + 𝒪(‖x‖⁷) ``` """ -function set_variables{T<:AbstractString}(R::Type, names::Vector{T}; order=get_order()) +function set_variables(R::Type, names::Vector{T}; order=get_order()) where + {T<:AbstractString} + order ≥ 1 || error("Order must be at least 1") num_vars = length(names) @@ -85,7 +88,8 @@ function set_variables{T<:AbstractString}(R::Type, names::Vector{T}; order=get_o resize!(size_table,order+1) resize!(pos_table,order+1) - coeff_table[:], index_table[:], size_table[:], pos_table[:] = generate_tables(num_vars, order) + coeff_table[:], index_table[:], size_table[:], pos_table[:] = + generate_tables(num_vars, order) gc(); end @@ -93,10 +97,12 @@ function set_variables{T<:AbstractString}(R::Type, names::Vector{T}; order=get_o TaylorN{R}[TaylorN(R,i) for i in 1:get_numvars()] end -set_variables{T}(names::Vector{T}; order=get_order()) = +set_variables(names::Vector{T}; order=get_order()) where {T} = set_variables(Float64, names, order=order) -function set_variables{T<:AbstractString}(R::Type, names::T; order=get_order(), numvars=-1) +function set_variables(R::Type, names::T; order=get_order(), numvars=-1) where + {T<:AbstractString} + variable_names = split(names) if length(variable_names) == 1 && numvars ≥ 1 @@ -107,7 +113,7 @@ function set_variables{T<:AbstractString}(R::Type, names::T; order=get_order(), set_variables(R, variable_names, order=order) end -set_variables{T<:AbstractString}(names::T; order=get_order(), numvars=-1) = +set_variables(names::T; order=get_order(), numvars=-1) where {T<:AbstractString} = set_variables(Float64, names, order=order, numvars=numvars) diff --git a/src/power.jl b/src/power.jl index 98bc6bb2..9a45e34a 100644 --- a/src/power.jl +++ b/src/power.jl @@ -16,7 +16,7 @@ function ^(a::HomogeneousPolynomial, n::Integer) end for T in (:Taylor1, :TaylorN) - @eval function ^{T<:Number}(a::$T{T}, n::Integer) + @eval function ^(a::$T{T}, n::Integer) where {T<:Number} n == 0 && return one(a) n == 1 && return copy(a) n == 2 && return square(a) @@ -24,7 +24,7 @@ for T in (:Taylor1, :TaylorN) return power_by_squaring(a, n) end - @eval function ^{T<:Integer}(a::$T{T}, n::Integer) + @eval function ^(a::$T{T}, n::Integer) where {T<:Integer} n == 0 && return one(a) n == 1 && return copy(a) n == 2 && return square(a) @@ -36,7 +36,7 @@ for T in (:Taylor1, :TaylorN) @eval ^(a::$T, b::$T) = exp( b*log(a) ) - @eval ^{T<:Complex}(a::$T, x::T) = exp( x*log(a) ) + @eval ^(a::$T, x::T) where {T<:Complex} = exp( x*log(a) ) end @@ -69,7 +69,7 @@ for T in (:Taylor1, :HomogeneousPolynomial, :TaylorN) end ## Real power ## -function ^{S<:Real}(a::Taylor1, r::S) +function ^(a::Taylor1, r::S) where {S<:Real} r == zero(r) && return one(a) r == one(r)/2 && return sqrt(a) isinteger(r) && return a^round(Int,r) @@ -96,7 +96,7 @@ function ^{S<:Real}(a::Taylor1, r::S) end ## Real power ## -function ^{S<:Real}(a::TaylorN, r::S) +function ^(a::TaylorN, r::S) where {S<:Real} r == zero(r) && return TaylorN( one(eltype(a)), 0 ) r == one(r)/2 && return sqrt(a) isinteger(r) && return a^round(Int,r) @@ -130,7 +130,9 @@ For `Taylor1` polynomials, `k0` is the order of the first non-zero coefficient of `a`. """ -@inline function pow!{S<:Real}(c::Taylor1, a::Taylor1, r::S, k::Int, l0::Int=0) +@inline function pow!(c::Taylor1, a::Taylor1, r::S, k::Int, l0::Int=0) where + S<:Real + if k == l0 @inbounds c[1] = ( a[l0+1] )^r return nothing @@ -146,7 +148,7 @@ coefficient of `a`. return nothing end -@inline function pow!{S<:Real}(c::TaylorN, a::TaylorN, r::S, k::Int) +@inline function pow!(c::TaylorN, a::TaylorN, r::S, k::Int) where {S<:Real} if k == 0 @inbounds c[1] = ( constant_term(a) )^r return nothing diff --git a/src/printing.jl b/src/printing.jl index 08d529b2..0e821925 100644 --- a/src/printing.jl +++ b/src/printing.jl @@ -19,7 +19,7 @@ function superscriptify(n::Int) end -function pretty_print{T<:Number}(a::Taylor1{T}) +function pretty_print(a::Taylor1{T}) where {T<:Number} z = zero(a[1]) space = string(" ") bigO = string("+ 𝒪(t", superscriptify(a.order+1), ")") @@ -38,7 +38,8 @@ function pretty_print{T<:Number}(a::Taylor1{T}) strout = strout * bigO strout end -function pretty_print{T<:Number}(a::Taylor1{HomogeneousPolynomial{T}}) + +function pretty_print(a::Taylor1{HomogeneousPolynomial{T}}) where {T<:Number} z = zero(a[1]) space = string(" ") bigO = string("+ 𝒪(t", superscriptify(a.order+1), ")") @@ -59,7 +60,8 @@ function pretty_print{T<:Number}(a::Taylor1{HomogeneousPolynomial{T}}) strout = strout * bigO strout end -function pretty_print{T<:Number}(a::Taylor1{TaylorN{T}}) + +function pretty_print(a::Taylor1{TaylorN{T}}) where {T<:Number} z = zero(a[1]) space = string(" ") bigO = string("+ 𝒪(t", superscriptify(a.order+1), ")") @@ -80,14 +82,16 @@ function pretty_print{T<:Number}(a::Taylor1{TaylorN{T}}) strout = strout * bigO strout end -function pretty_print{T<:Number}(a::HomogeneousPolynomial{T}) + +function pretty_print(a::HomogeneousPolynomial{T}) where {T<:Number} z = zero(a[1]) space = string(" ") a == zero(a) && return string(space, z) strout::String = homogPol2str(a) strout end -function pretty_print{T<:Number}(a::TaylorN{T}) + +function pretty_print(a::TaylorN{T}) where {T<:Number} z = zero(a[1]) space = string("") bigO::String = string(" + 𝒪(‖x‖", superscriptify(a.order+1), ")") @@ -107,7 +111,7 @@ function pretty_print{T<:Number}(a::TaylorN{T}) strout end -function homogPol2str{T<:Number}(a::HomogeneousPolynomial{T}) +function homogPol2str(a::HomogeneousPolynomial{T}) where {T<:Number} numVars = get_numvars() order = a.order z = zero(T) @@ -134,7 +138,8 @@ function homogPol2str{T<:Number}(a::HomogeneousPolynomial{T}) end return strout[1:prevind(strout, end)] end -function homogPol2str{T<:Number}(a::HomogeneousPolynomial{Taylor1{T}}) + +function homogPol2str(a::HomogeneousPolynomial{Taylor1{T}}) where {T<:Number} numVars = get_numvars() order = a.order z = zero(a[1]) @@ -170,13 +175,16 @@ function numbr2str(zz, ifirst::Bool=false) plusmin = ifelse( ifirst, string(""), string("+ ") ) return string(plusmin, zz) end -function numbr2str{T<:Union{AbstractFloat,Integer,Rational}}(zz::T, ifirst::Bool=false) + +function numbr2str(zz::T, ifirst::Bool=false) where + {T<:Union{AbstractFloat,Integer,Rational}} zz == zero(T) && return string( zz ) plusmin = ifelse( zz < zero(T), string("- "), ifelse( ifirst, string(""), string("+ ")) ) return string(plusmin, abs(zz)) end -function numbr2str{T<:Complex}(zz::T, ifirst::Bool=false) + +function numbr2str(zz::T, ifirst::Bool=false) where {T<:Complex} zT = zero(zz.re) zz == zero(zz) && return string(zT) zre, zim = reim(zz) @@ -220,8 +228,10 @@ end name_taylorNvar(i::Int) = string(" ", get_variable_names()[i]) # summary -summary{T<:Number}(a::Taylor1{T}) = string(a.order, "-order ", typeof(a), ":") -function summary{T<:Number}(a::Union{HomogeneousPolynomial{T}, TaylorN{T}}) +summary(a::Taylor1{T}) where {T<:Number} = + string(a.order, "-order ", typeof(a), ":") + +function summary(a::Union{HomogeneousPolynomial{T}, TaylorN{T}}) where {T<:Number} string(a.order, "-order ", typeof(a), " in ", get_numvars(), " variables:") end