Skip to content

Commit

Permalink
Evaluate with tuples (#159)
Browse files Browse the repository at this point in the history
* Add methods of evaluate to handle NTuples

* Extend evaluate with varargs.

* Use zero./one. (instead of ugly fill!)

* Fix a problem with evaluate and Pairs
  • Loading branch information
lbenet authored Mar 1, 2018
1 parent 21d786c commit c5f366c
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 30 deletions.
6 changes: 3 additions & 3 deletions src/arithmetic.jl
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ for T in (:Taylor1, :TaylorN), f in (:zero, :one)
end

function zero(a::HomogeneousPolynomial{T}) where {T<:Number}
v = fill!(copy(a.coeffs), zero(T))
v = zero.(a.coeffs)
return HomogeneousPolynomial(v, a.order)
end

Expand All @@ -55,7 +55,7 @@ zeros(::Type{HomogeneousPolynomial{T}}, order::Int) where {T<:Number} =
zeros( HomogeneousPolynomial([zero(T)], 0), order)

function one(a::HomogeneousPolynomial{T}) where {T<:Number}
v = fill!(copy(a.coeffs), one(T))
v = one.(a.coeffs)
return HomogeneousPolynomial(v, a.order)
end

Expand Down Expand Up @@ -540,7 +540,7 @@ function mul!(y::Vector{Taylor1{T}},
# Use matrices of coefficients (of proper size) and mul!
# B = zeros(T, k, order+1)
@compat B = Array{T}(uninitialized, k, order+1)
B = fill!(B, zero(T))
B = zero.(B)
for i = 1:k
@inbounds ord = b[i].order
@inbounds for j = 1:ord+1
Expand Down
66 changes: 43 additions & 23 deletions src/evaluate.jl
Original file line number Diff line number Diff line change
Expand Up @@ -196,19 +196,18 @@ 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(a::HomogeneousPolynomial{T}, vals::Array{S,1} ) where
{T<:Number, S<:NumberNotSeriesN}
function evaluate(a::HomogeneousPolynomial{T}, vals::NTuple{N,S} ) where
{T<:Number, S<:NumberNotSeriesN, N}

@assert length(vals) == get_numvars()
@assert N == get_numvars()

num_vars = get_numvars()
ct = coeff_table[a.order+1]
R = promote_type(T,S)
suma = zero(R)

for (i,a_coeffs) in enumerate(a.coeffs)
tmp = vals[1]^(ct[i][1])
for n in 2:num_vars
for n in 2:N
tmp *= vals[n]^(ct[i][n])
end
suma += a_coeffs * tmp
Expand All @@ -217,6 +216,11 @@ function evaluate(a::HomogeneousPolynomial{T}, vals::Array{S,1} ) where
return suma
end

evaluate(a::HomogeneousPolynomial{T}, vals::Array{S,1} ) where
{T<:Number, S<:NumberNotSeriesN} = evaluate(a, (vals...,))

evaluate(a::HomogeneousPolynomial, v, vals...) = evaluate(a, (v, vals...,))

function evaluate(a::HomogeneousPolynomial)
a.order == 0 && return a[1]
zero(a[1])
Expand All @@ -225,6 +229,8 @@ end
#function-like behavior for HomogeneousPolynomial
(p::HomogeneousPolynomial)(x) = evaluate(p, x)

(p::HomogeneousPolynomial)(x, v...) = evaluate(p, (x, v...,))

(p::HomogeneousPolynomial)() = evaluate(p)

@doc doc"""
Expand All @@ -235,20 +241,19 @@ 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(a::TaylorN{T}, vals::Array{S,1}) where
{T<:Number,S<:NumberNotSeriesN}
function evaluate(a::TaylorN{T}, vals::NTuple{N,S}) where
{T<:Number,S<:NumberNotSeries, N}

@assert length(vals) == get_numvars()
@assert N == get_numvars()

num_vars = get_numvars()
R = promote_type(T,S)
a_length = length(a)
suma = zeros(R, a_length)
for homPol in 1:length(a)
sun = zero(R)
for (i, a_coeff) in enumerate(a.coeffs[homPol].coeffs)
tmp = vals[1]^(coeff_table[homPol][i][1])
for n in 2:num_vars
for n in 2:N
tmp *= vals[n]^(coeff_table[homPol][i][n])
end
sun += a_coeff * tmp
Expand All @@ -258,12 +263,17 @@ function evaluate(a::TaylorN{T}, vals::Array{S,1}) where

return sum( sort!(suma, by=abs2) )
end
function evaluate(a::TaylorN{T}, vals::Array{Taylor1{S},1}) where
{T<:Number, S<:NumberNotSeries}

@assert length(vals) == get_numvars()
evaluate(a::TaylorN{T}, vals::Array{S,1}) where
{T<:Number, S<:NumberNotSeriesN} = evaluate(a, (vals...,))

evaluate(a::TaylorN, v, vals...) = evaluate(a, (v, vals...,))

function evaluate(a::TaylorN{T}, vals::NTuple{N,Taylor1{S}}) where
{T<:Number, S<:NumberNotSeries, N}

@assert N == get_numvars()

num_vars = get_numvars()
R = promote_type(T,S)
a_length = length(a)
ord = maximum( get_order.(vals) )
Expand All @@ -272,7 +282,7 @@ function evaluate(a::TaylorN{T}, vals::Array{Taylor1{S},1}) where
for homPol in 1:length(a)
for (i, a_coeff) in enumerate(a.coeffs[homPol].coeffs)
tmp = vals[1]^(coeff_table[homPol][i][1])
for n in 2:num_vars
for n in 2:N
tmp *= vals[n]^(coeff_table[homPol][i][n])
end
suma += a_coeff * tmp
Expand All @@ -282,20 +292,22 @@ function evaluate(a::TaylorN{T}, vals::Array{Taylor1{S},1}) where
return suma
end

function evaluate(a::TaylorN{Taylor1{T}}, vals::Array{Taylor1{T},1}) where
{T<:NumberNotSeries}
evaluate(a::TaylorN{T}, vals::Array{Taylor1{S},1}) where
{T<:Number, S<:NumberNotSeriesN} = evaluate(a, (vals...,))

# @assert length(vals) == get_numvars()
function evaluate(a::TaylorN{Taylor1{T}}, vals::NTuple{N, Taylor1{T}}) where
{T<:NumberNotSeries, N}

@assert N == get_numvars()

num_vars = get_numvars()
a_length = length(a)
ord = maximum( get_order.(vals) )
suma = Taylor1(zeros(T, ord))

for homPol in 1:length(a)
for (i, a_coeff) in enumerate(a.coeffs[homPol].coeffs)
tmp = vals[1]^(coeff_table[homPol][i][1])
for n in 2:num_vars
for n in 2:N
tmp *= vals[n]^(coeff_table[homPol][i][n])
end
suma += a_coeff * tmp
Expand All @@ -305,8 +317,11 @@ function evaluate(a::TaylorN{Taylor1{T}}, vals::Array{Taylor1{T},1}) where
return suma
end

function evaluate(a::TaylorN{T}, vals::Array{TaylorN{S},1}) where
{T<:Number, S<:NumberNotSeries}
evaluate(a::TaylorN{Taylor1{T}}, vals::Array{Taylor1{T},1}) where
{T<:NumberNotSeries} = evaluate(a, (vals...,))

function evaluate(a::TaylorN{T}, vals::NTuple{N, TaylorN{S}}) where
{T<:Number, S<:NumberNotSeries, N}

@assert length(vals) == get_numvars()

Expand All @@ -329,15 +344,19 @@ function evaluate(a::TaylorN{T}, vals::Array{TaylorN{S},1}) where
return suma
end

evaluate(a::TaylorN{T}, vals::Array{TaylorN{S},1}) where
{T<:Number, S<:NumberNotSeries} = evaluate(a, (vals...,))

function evaluate(a::TaylorN{T}, s::Symbol, val::S) where
{T<:Number, S<:NumberNotSeriesN}
vars = get_variables()
ind = lookupvar(s)
vars[ind] = val
evaluate(a, vars)
end

evaluate(a::TaylorN{T}, x::Pair{Symbol,S}) where {T<:Number, S<:NumberNotSeriesN} =
evaluate(p, first(x), last(x))
evaluate(a, first(x), last(x))

evaluate(a::TaylorN{T}) where {T<:Number} = a[0][1]

Expand Down Expand Up @@ -381,6 +400,7 @@ evaluate(A::SubArray{TaylorN{T},2}) where {T<:Number} = evaluate.(A)
(p::TaylorN)() = evaluate(p)
(p::TaylorN)(s::Symbol, x) = evaluate(p, s, x)
(p::TaylorN)(x::Pair) = evaluate(p, first(x), last(x))
(p::TaylorN)(x, v...) = evaluate(p, (x, v...,))

#function-like behavior for Vector{TaylorN}
(p::Array{TaylorN{T},1})(x) where {T<:Number} = evaluate(p, x)
Expand Down
16 changes: 13 additions & 3 deletions test/manyvariables.jl
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ end
@test evaluate(xH) == zero(eltype(xH))
@test xH() == zero(eltype(xH))
@test xH([1,1]) == evaluate(xH, [1,1])
@test xH((1,1)) == 1
hp = -5.4xH+6.89yH
@test hp([1,1]) == evaluate(hp, [1,1])
vr = rand(2)
Expand Down Expand Up @@ -293,16 +294,25 @@ end
@test imag((exp(yT))^(-1im)') == sin(yT)
exy = exp( xT+yT )
@test evaluate(exy) == 1
@test evaluate(exy,[0.1im,0.01im]) == exp(0.11im)
@test isapprox(evaluate(exy, [1,1]), eeuler^2)
@test evaluate(exy, 0.1im, 0.01im) == exp(0.11im)
@test exy(0.1im, 0.01im) == exp(0.11im)
@test evaluate(exy,(0.1im, 0.01im)) == exp(0.11im)
@test exy((0.1im, 0.01im)) == exp(0.11im)
@test evaluate(exy,[0.1im, 0.01im]) == exp(0.11im)
@test exy([0.1im, 0.01im]) == exp(0.11im)
@test isapprox(evaluate(exy, (1,1)), eeuler^2)
@test exy(:x₁, 0.0) == exp(yT)
txy = tan(xT+yT)
@test getcoeff(txy,[8,7]) == 929569/99225
ptxy = xT + yT + (1/3)*( xT^3 + yT^3 ) + xT^2*yT + xT*yT^2
@test getindex(tan(TaylorN(1)+TaylorN(2)),0:4) == ptxy.coeffs[1:5]
@test evaluate(xH*yH, [1.0,2.0]) == 2.0
@test evaluate(xH*yH, 1.0, 2.0) == (xH*yH)(1.0, 2.0) == 2.0
@test evaluate(xH*yH, (1.0, 2.0)) == 2.0
@test evaluate(xH*yH, [1.0, 2.0]) == 2.0
@test ptxy(:x₁, -1.0) == -1 + yT + (-1.0+yT^3)/3 + yT - yT^2
@test ptxy(:x₁ => -1.0) == -1 + yT + (-1.0+yT^3)/3 + yT - yT^2
@test evaluate(ptxy, :x₁ => -1.0) == -1 + yT + (-1.0+yT^3)/3 + yT - yT^2
@test evaluate(ptxy, :x₁, -1.0) == -1 + yT + (-1.0+yT^3)/3 + yT - yT^2
v = zeros(Int, 2)
@test evaluate!([xT, yT], ones(Int, 2), v) == nothing
@test v == ones(2)
Expand Down
7 changes: 6 additions & 1 deletion test/mixtures.jl
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,13 @@ end
@test t*xHt == HomogeneousPolynomial([t, zero(t)])
@test complex(0,1)*xHt == HomogeneousPolynomial([1im*one(t), zero(1im*t)])
@test eltype(complex(0,1)*xHt) == Taylor1{Complex{Float64}}
@test (xHt+yHt)(1, 1) == 1+t
@test (xHt+yHt)([1, 1]) == (xHt+yHt)((1, 1))

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)))
t1N = convert(Taylor1{TaylorN{Float64}}, tN1)
@test t1N[0] == HomogeneousPolynomial(1)
ctN1 = convert(TaylorN{Taylor1{Float64}}, t1N)
Expand Down Expand Up @@ -165,7 +169,8 @@ end
@test (aT1.^2)(Q[3]) == evaluate(aT1.^2, Q[3])
#evaluate a TaylorN at an array of Taylor1s
@test P[1](aT1) == evaluate(P[1], aT1)
@test Q[2](aT1) == evaluate(Q[2], aT1)
@test P[1](aT1) == evaluate(P[1], (aT1...,))
@test Q[2](aT1) == evaluate(Q[2], [aT1...])
#evaluate an array of TaylorN{Float64} at an array of Taylor1{Float64}
@test P(aT1) == evaluate(P, aT1)
@test Q(aT1) == evaluate(Q, aT1)
Expand Down

0 comments on commit c5f366c

Please sign in to comment.