Skip to content

Commit

Permalink
Merge pull request #151 from numericalEFT/tao_AD
Browse files Browse the repository at this point in the history
Tao ad
  • Loading branch information
fsxbhyy authored Oct 30, 2023
2 parents 12f821d + 94b8cea commit a7e6573
Show file tree
Hide file tree
Showing 8 changed files with 155 additions and 135 deletions.
11 changes: 6 additions & 5 deletions example/taylor_expansion.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@ using FeynmanDiagram.Taylor
using FeynmanDiagram.ComputationalGraphs:
eval!, forwardAD, node_derivative, backAD, build_all_leaf_derivative, count_operation
using FeynmanDiagram.Utility:
taylorexpansion!, build_derivative_backAD!
taylorexpansion, build_derivative_backAD!
g1 = Graph([])
g2 = Graph([])
g3 = Graph([]) #, factor=2.0)
g4 = Graph([])
g5 = Graph([])
g6 = Graph([])
G3 = g1
G4 = 1.0 * g1 * g1
G4 = 1.0 * g1 * g2
G5 = 1.0 * (3.0 * G3 + 0.5 * G4)
#G6 = (0.5 * g1 * g2 + 0.5 * g2 * g3)
#G6 = (g1 + g2) * (0.5 * g1 + g3) * g1 # (0.5 * g1 + g3)
Expand All @@ -23,10 +23,11 @@ using FeynmanDiagram.Taylor:


# set_variables("x y", order=3)
# @time T5 = taylorexpansion!(G5)
# @time T5 = taylorexpansion(G5)
# print(T5)
set_variables("x y z a", order=7)
@time T5 = taylorexpansion!(G6)
set_variables("x y", order=[3, 2])
#set_variables("x y z a", order=[1, 2, 3, 2])
@time T5 = taylorexpansion(G6)
#order = [0, 0, 0, 0, 0, 0]
#@time print(T5.coeffs[order])
print("$(count_operation(T5.coeffs))\n")
Expand Down
2 changes: 1 addition & 1 deletion src/TaylorSeries/TaylorSeries.jl
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ include("print.jl")
include("arithmetic.jl")
export TaylorSeries

export get_order, get_numvars,
export get_orders, get_numvars,
set_variables, get_variables,
get_variable_names, get_variable_symbols,
displayBigO, use_show_default,
Expand Down
47 changes: 38 additions & 9 deletions src/TaylorSeries/arithmetic.jl
Original file line number Diff line number Diff line change
Expand Up @@ -121,15 +121,15 @@ function Base.:-(g1::TaylorSeries{T}, c::S) where {T,S<:Number}
end

"""
function taylor_binomial(o1::Array{Int,1}, o2::Array{Int,1})
function taylor_binomial(o1::Vector{Int}, o2::Vector{Int})
Return the taylor binomial prefactor when product two high-order derivatives with order o1 and o2.
# Arguments:
- `o1` Order of first derivative
- `o2` Order of second derivative
"""
function taylor_binomial(o1::Array{Int,1}, o2::Array{Int,1})
function taylor_binomial(o1::Vector{Int}, o2::Vector{Int})
@assert length(o1) == length(o2)
result = 1
for i in eachindex(o1)
Expand All @@ -143,14 +143,14 @@ end


"""
function taylor_factorial(o::Array{Int,1})
function taylor_factorial(o::Vector{Int})
Return the taylor factorial prefactor with order o.
# Arguments:
- `o` Order of the taylor coefficient
"""
function taylor_factorial(o::Array{Int,1})
function taylor_factorial(o::Vector{Int})
result = 1
for i in eachindex(o)
result *= factorial(o[i])
Expand All @@ -172,7 +172,7 @@ function Base.:*(g1::TaylorSeries{T}, g2::TaylorSeries{T}) where {T}
for (order1, coeff1) in g1.coeffs
for (order2, coeff2) in g2.coeffs
order = order1 + order2
if sum(order) <= _params_Taylor_.order
if all(order .<= get_orders())
#combination_coeff = taylor_binomial(order1, order2)
if haskey(g.coeffs, order)
#g.coeffs[order] += combination_coeff * coeff1 * coeff2
Expand All @@ -187,17 +187,46 @@ function Base.:*(g1::TaylorSeries{T}, g2::TaylorSeries{T}) where {T}
return g
end

# """
# function Base.:*(g1::TaylorSeries{T}, g2::TaylorSeries{T}) where {T}

# Returns a taylor series `g1 * g2` representing the product of `g2` with `g1`.

# # Arguments:
# - `g1` First taylor series
# - `g2` Second taylor series
# """
# function multi_product(glist::Vector{TaylorSeries{T}}) where {T}
# result = TaylorSeries{T}()
# idxtuple = (keys(glist.coeffs) for g in glist)
# for idx in collect(Iterators.product(idxtuple...))
# orderidx = collect(orderidx)
# totalorder = sum(glist[i].coeffs[orderidx[i]] for i in eachindex(glist))
# if all(totalorder .<= get_orders())
# #combination_coeff = taylor_binomial(order1, order2)
# if haskey(g.coeffs, order)
# #g.coeffs[order] += combination_coeff * coeff1 * coeff2
# g.coeffs[order] += coeff1 * coeff2
# else
# #g.coeffs[order] = combination_coeff * coeff1 * coeff2
# g.coeffs[order] = coeff1 * coeff2
# end

# end
# end
# return g
# end

"""
function getcoeff(g::TaylorSeries, order::Array{Int,1})
function getcoeff(g::TaylorSeries, order::Vector{Int})
Return the taylor coefficients with given order in taylor series g.
# Arguments:
- `g` Taylor series
- `order` Order of target coefficients
"""
function getcoeff(g::TaylorSeries, order::Array{Int,1})
function getcoeff(g::TaylorSeries, order::Vector{Int})
if haskey(g.coeffs, order)
return g.coeffs[order]
else
Expand All @@ -206,15 +235,15 @@ function getcoeff(g::TaylorSeries, order::Array{Int,1})
end

"""
function getderivative(g::TaylorSeries, order::Array{Int,1})
function getderivative(g::TaylorSeries, order::Vector{Int})
Return the derivative with given order in taylor series g.
# Arguments:
- `g` Taylor series
- `order` Order of derivative
"""
function getderivative(g::TaylorSeries, order::Array{Int,1})
function getderivative(g::TaylorSeries, order::Vector{Int})
if haskey(g.coeffs, order)
return taylor_factorial(order) * g.coeffs[order]
else
Expand Down
10 changes: 5 additions & 5 deletions src/TaylorSeries/constructors.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,17 @@
# Members:
- `name::Symbol` name of the diagram
- `coeffs::Dict{Array{Int,1},T}` The taylor expansion coefficients. The integer array define the order of corresponding coefficient.
- `coeffs::Dict{Vector{Int},T}` The taylor expansion coefficients. The integer array define the order of corresponding coefficient.
"""
mutable struct TaylorSeries{T}
name::String # "" by default
coeffs::Dict{Array{Int,1},T}
coeffs::Dict{Vector{Int},T}

"""
function TaylorSeries{T}(coeffs::Dict{Array{Int,1},T}=Dict{Array{Int,1},T}(), name::String="") where {T}
function TaylorSeries{T}(coeffs::Dict{Vector{Int},T}=Dict{Vector{Int},T}(), name::String="") where {T}
Create a TaylorSeries based on given coefficients.
"""
function TaylorSeries{T}(coeffs::Dict{Array{Int,1},T}=Dict{Array{Int,1},T}(), name::String="") where {T}
function TaylorSeries{T}(coeffs::Dict{Vector{Int},T}=Dict{Vector{Int},T}(), name::String="") where {T}
return new{T}(name, coeffs)
end
end
Expand All @@ -33,7 +33,7 @@ function TaylorSeries(::Type{T}, nv::Int) where {T}
@assert 0 < nv get_numvars()
v = zeros(Int, get_numvars())
@inbounds v[nv] = 1
return TaylorSeries{T}(Dict{Array{Int,1},T}(v => one(T)))
return TaylorSeries{T}(Dict{Vector{Int},T}(v => one(T)))
end
TaylorSeries(nv::Int) = TaylorSeries(Float64, nv)

Expand Down
75 changes: 33 additions & 42 deletions src/TaylorSeries/parameter.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,27 +6,28 @@
**Fields:**
- `order :: Int` Order (degree) of the polynomials
- `orders :: Int` Orders (degree) of the polynomials
- `num_vars :: Int` Number of variables
- `variable_names :: Vector{String}` Names of the variables
- `variable_symbols :: Vector{Symbol}` Symbols of the variables
These parameters can be changed using [`set_variables`](@ref)
"""
mutable struct ParamsTaylor
order::Int
orders::Vector{Int}
num_vars::Int
variable_names::Vector{String}
variable_symbols::Vector{Symbol}
end


ParamsTaylor(order, num_vars, variable_names) = ParamsTaylor(order, num_vars, variable_names, Symbol.(variable_names))
ParamsTaylor(orders, num_vars, variable_names) = ParamsTaylor(orders, num_vars, variable_names, Symbol.(variable_names))

const _params_Taylor_ = ParamsTaylor(6, 2, ["x₁", "x₂"])
const _params_Taylor_ = ParamsTaylor([2, 2], 2, ["x₁", "x₂"])

## Utilities to get the maximum order, number of variables, their names and symbols
get_order() = _params_Taylor_.order
get_orders() = _params_Taylor_.orders
get_orders(idx::Int) = _params_Taylor_.orders[idx]
get_numvars() = _params_Taylor_.num_vars
get_variable_names() = _params_Taylor_.variable_names
get_variable_symbols() = _params_Taylor_.variable_symbols
Expand All @@ -38,65 +39,55 @@ end


"""
set_variables([T::Type], names::String; [order=get_order(), numvars=-1])
set_variables([T::Type], names::String; [orders=get_orders(), numvars=-1])
Return a `TaylorSeries{T}` vector with each entry representing an
independent variable. `names` defines the output for each variable
(separated by a space). The default type `T` is `Float64`,
and the default for `order` is the one defined globally.
and the default for `orders` is the one defined globally.
If `numvars` is not specified, it is inferred from `names`. If only
one variable name is defined and `numvars>1`, it uses this name with
subscripts for the different variables.
```julia
julia> set_variables(Int, "x y z", order=4)
julia> set_variables(Int, "x y z", orders=[4,4,4])
3-element Array{TaylorSeries.Taylor{Int},1}:
1 x + 𝒪(‖x‖⁵)
1 y + 𝒪(‖x‖⁵)
1 z + 𝒪(‖x‖⁵)
julia> set_variables("α", numvars=2)
2-element Array{TaylorSeries.Taylor{Float64},1}:
1.0 α₁ + 𝒪(‖x‖⁵)
1.0 α₂ + 𝒪(‖x‖⁵)
julia> set_variables("x", order=6, numvars=2)
2-element Array{TaylorSeries.Taylor{Float64},1}:
1.0 x₁ + 𝒪(‖x‖⁷)
1.0 x₂ + 𝒪(‖x‖⁷)
1 x + 𝒪(x⁵y⁵z⁵)
1 y + 𝒪(x⁵y⁵z⁵)
1 z + 𝒪(x⁵y⁵z⁵)
```
"""
function set_variables(::Type{R}, names::Vector{T}; order=get_order()) where
function set_variables(::Type{R}, names::Vector{T}; orders=get_orders()) where
{R,T<:AbstractString}

order 1 || error("Order must be at least 1")

for o in orders
o 1 || error("Order must be at least 1")
end
num_vars = length(names)
num_vars 1 || error("Number of variables must be at least 1")

@assert length(orders) == num_vars "Input orders should have same length as number of variables."
_params_Taylor_.variable_names = names
_params_Taylor_.variable_symbols = Symbol.(names)
if !(order == get_order() && num_vars == get_numvars())
if !(orders == get_orders() && num_vars == get_numvars())
# if these are unchanged, no need to regenerate tables

_params_Taylor_.order = order
_params_Taylor_.orders = orders
_params_Taylor_.num_vars = num_vars
end
# return a list of the new variables
return TaylorSeries{R}[TaylorSeries(R, i) for i in 1:get_numvars()]
end


set_variables(::Type{R}, symbs::Vector{T}; order=get_order()) where
{R,T<:Symbol} = set_variables(R, string.(symbs), order=order)
set_variables(::Type{R}, symbs::Vector{T}; orders=get_orders()) where
{R,T<:Symbol} = set_variables(R, string.(symbs), orders=orders)

set_variables(names::Vector{T}; order=get_order()) where {T<:AbstractString} =
set_variables(Float64, names, order=order)
set_variables(symbs::Vector{T}; order=get_order()) where {T<:Symbol} =
set_variables(Float64, symbs, order=order)
set_variables(names::Vector{T}; orders=get_orders()) where {T<:AbstractString} =
set_variables(Float64, names, orders=orders)
set_variables(symbs::Vector{T}; orders=get_orders()) where {T<:Symbol} =
set_variables(Float64, symbs, orders=orders)

function set_variables(::Type{R}, names::T; order=get_order(), numvars=-1) where
function set_variables(::Type{R}, names::T; orders=get_orders(), numvars=-1) where
{R,T<:AbstractString}

variable_names = split(names)
Expand All @@ -106,12 +97,12 @@ function set_variables(::Type{R}, names::T; order=get_order(), numvars=-1) where
variable_names = [string(name, subscriptify(i)) for i in 1:numvars]
end

set_variables(R, variable_names, order=order)
set_variables(R, variable_names, orders=orders)
end
set_variables(::Type{R}, symbs::Symbol; order=get_order(), numvars=-1) where {R} =
set_variables(R, string(symbs), order=order, numvars=numvars)
set_variables(::Type{R}, symbs::Symbol; orders=get_orders(), numvars=-1) where {R} =
set_variables(R, string(symbs), orders=orders, numvars=numvars)

set_variables(names::T; order=get_order(), numvars=-1) where {T<:AbstractString} =
set_variables(Float64, names, order=order, numvars=numvars)
set_variables(symbs::Symbol; order=get_order(), numvars=-1) =
set_variables(Float64, string(symbs), order=order, numvars=numvars)
set_variables(names::T; orders=get_orders(), numvars=-1) where {T<:AbstractString} =
set_variables(Float64, names, orders=orders, numvars=numvars)
set_variables(symbs::Symbol; orders=get_orders(), numvars=-1) =
set_variables(Float64, string(symbs), orders=orders, numvars=numvars)
5 changes: 4 additions & 1 deletion src/TaylorSeries/print.jl
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,11 @@ end
function pretty_print(a::TaylorSeries{T}) where {T}
#z = zero(a[0])
space = string("")
# bigO::String = bigOnotation[end] ?
# string(" + 𝒪(‖x‖", superscriptify(_params_Taylor_.orders + 1), ")") :
# string("")
bigO::String = bigOnotation[end] ?
string(" + 𝒪(‖x‖", superscriptify(_params_Taylor_.order + 1), ")") :
string(" + 𝒪(", [_params_Taylor_.variable_names[i] * superscriptify(_params_Taylor_.orders[i] + 1) for i in eachindex(_params_Taylor_.orders)]..., ")") :
string("")
# iszero(a) && return string(space, z, space, bigO)
# strout::String = space
Expand Down
Loading

0 comments on commit a7e6573

Please sign in to comment.