Examples¶
1. Four-square identity¶
The first example shows that the four-square identity holds: as proved by Euler. The code can we found in one of the tests 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 the number of independent variables to
julia> using TaylorSeries
julia> # Define the variables α₁, ..., α₄, β₁, ..., β₄
make_variable(name, index::Int) = string(name, TaylorSeries.subscriptify(index))
make_variable (generic function with 1 method)
julia> variable_names = [make_variable("α", i) for i in 1:4]
4-element Array{String,1}:
"α₁"
"α₂"
"α₃"
"α₄"
julia> append!(variable_names, [make_variable("β", i) for i in 1:4])
8-element Array{String,1}:
"α₁"
"α₂"
"α₃"
"α₄"
"β₁"
"β₂"
"β₃"
"β₄"
julia> # Create the Taylor objects (order 4, numvars=8)
a1, a2, a3, a4, b1, b2, b3, b4 = set_variables(variable_names, order=4)
8-element Array{TaylorSeries.TaylorN{Float64},1}:
1.0 α₁ + 𝒪(‖x‖⁵)
1.0 α₂ + 𝒪(‖x‖⁵)
1.0 α₃ + 𝒪(‖x‖⁵)
1.0 α₄ + 𝒪(‖x‖⁵)
1.0 β₁ + 𝒪(‖x‖⁵)
1.0 β₂ + 𝒪(‖x‖⁵)
1.0 β₃ + 𝒪(‖x‖⁵)
1.0 β₄ + 𝒪(‖x‖⁵)
julia> a1 # variable a1
1.0 α₁ + 𝒪(‖x‖⁵)
Now we compute each term appearing in (\ref{eq:Euler}), and compare them
julia> # left-hand side
lhs1 = a1^2 + a2^2 + a3^2 + a4^2 ;
julia> lhs2 = b1^2 + b2^2 + b3^2 + b4^2 ;
julia> lhs = lhs1 * lhs2
1.0 α₁² β₁² + 1.0 α₁² β₂² + 1.0 α₁² β₃² + 1.0 α₁² β₄² + 1.0 α₂² β₁² + 1.0 α₂² β₂² + 1.0 α₂² β₃² + 1.0 α₂² β₄² + 1.0 α₃² β₁² + 1.0 α₃² β₂² + 1.0 α₃² β₃² + 1.0 α₃² β₄² + 1.0 α₄² β₁² + 1.0 α₄² β₂² + 1.0 α₄² β₃² + 1.0 α₄² β₄² + 𝒪(‖x‖⁵)
julia> # right-hand side
rhs1 = (a1*b1 - a2*b2 - a3*b3 - a4*b4)^2 ;
julia> rhs2 = (a1*b2 + a2*b1 + a3*b4 - a4*b3)^2 ;
julia> rhs3 = (a1*b3 - a2*b4 + a3*b1 + a4*b2)^2 ;
julia> rhs4 = (a1*b4 + a2*b3 - a3*b2 + a4*b1)^2 ;
julia> rhs = rhs1 + rhs2 + rhs3 + rhs4
1.0 α₁² β₁² + 1.0 α₁² β₂² + 1.0 α₁² β₃² + 1.0 α₁² β₄² + 1.0 α₂² β₁² + 1.0 α₂² β₂² + 1.0 α₂² β₃² + 1.0 α₂² β₄² + 1.0 α₃² β₁² + 1.0 α₃² β₂² + 1.0 α₃² β₃² + 1.0 α₃² β₄² + 1.0 α₄² β₁² + 1.0 α₄² β₂² + 1.0 α₄² β₃² + 1.0 α₄² β₄² + 𝒪(‖x‖⁵)
Finally, we compare the two sides of the identity,
julia> lhs == rhs
true
The identity is satisfied. $\square$.
2. Fateman test¶
Richard J. Fateman, from Berkley, proposed as a stringent test of polynomial multiplication the evaluation of $s*(s+1)$, where $s = (1+x+y+z+w)^{20}$. This is implemented in the function fateman1
. We shall also evaluate the form $s^2+s$ in fateman2
, which involves fewer operations (and makes a fairer comparison to what Mathematica does). Below we have used Julia v0.4.
julia> using TaylorSeries
julia> set_variables("x", numvars=4, order=40)
4-element Array{TaylorSeries.TaylorN{Float64},1}:
1.0 x₁ + 𝒪(‖x‖⁴¹)
1.0 x₂ + 𝒪(‖x‖⁴¹)
1.0 x₃ + 𝒪(‖x‖⁴¹)
1.0 x₄ + 𝒪(‖x‖⁴¹)
julia> function fateman1(degree::Int)
T = Int128
oneH = HomogeneousPolynomial(one(T), 0)
# s = 1 + x + y + z + w
s = TaylorN([oneH,HomogeneousPolynomial([one(T),one(T),one(T),one(T)],1)],degree)
s = s^degree
# s is converted to order 2*ndeg
s = TaylorN(s, 2*degree)
s * ( s+TaylorN(oneH, 2*degree) )
end
fateman1 (generic function with 1 method)
julia> fateman1(0);
3.021246 seconds (4.36 k allocations: 20.158 MB, 0.18% gc time)
julia> @time f1 = fateman1(20);
Another implementation of the same:
julia> function fateman2(degree::Int)
T = Int128
oneH = HomogeneousPolynomial(one(T), 0)
s = TaylorN([oneH,HomogeneousPolynomial([one(T),one(T),one(T),one(T)],1)],degree)
s = s^degree
# s is converted to order 2*ndeg
s = TaylorN(s, 2*degree)
return s^2 + s
end
fateman2 (generic function with 1 method)
julia> fateman2(0);
1.465666 seconds (4.20 k allocations: 20.149 MB, 0.34% gc time)
julia> @time f2 = fateman2(20);
julia> get_coeff(f2,[1,6,7,20]) # coefficient of x y^6 z^7 w^{20}
128358585324486316800
julia> sum(TaylorSeries.size_table)
135751
The tests above show the necessity of using Int128
, that fateman2
is nearly twice as fast as fateman1
, and that the series has 135751 monomials on 4 variables.
Mathematica (version 10.2) requires 3.139831 seconds. Then, with TaylorSeries v0.1.2, our implementation of fateman1
is about 20% faster, and fateman2
is more than a factor 2 faster. (The original test by Fateman corresponds to fateman1
, which avoids specific optimizations in ^2
.)