Skip to content

Instantly share code, notes, and snippets.

@iuliadmtru
Last active April 30, 2022 17:44
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save iuliadmtru/0104cad838b8d27ffa5f59a4f86e6b0e to your computer and use it in GitHub Desktop.
Save iuliadmtru/0104cad838b8d27ffa5f59a4f86e6b0e to your computer and use it in GitHub Desktop.
Taylor mapping of the initial state of a particle to the final state.
include("TaylorParams.jl")
include("TaylorParams-DAT.jl")
include("ParticleState.jl")
include("ParticleStateMapper.jl")
# `ParticleStateMapper` type object constructed using data from the mapsy7.dat file
mapper = ParticleStateMapperFromDAT("Bachelor-project\\mapsy7.dat")
# test serialization and deserialization functions
ParticleStateMapperToJLD2(mapper, "Bachelor-project\\test.jld2")
back = ParticleStateMapperFromJLD2("Bachelor-project\\test.jld2")
# test `evaluate` function with the method from ParticleStateMapper.jl -> vector describing the final state
initial_state = ParticleState(0.1, 10.0, 0.01, -0.01, 1, 1)
out = evaluate(mapper, initial_state)
for i in 1:6
println(fieldnames(ParticleStateMapper)[i], ": ", initial_state[i], " -> ", out[i])
end
println("\n")
out = evaluate(back, initial_state)
for i in 1:6
println(fieldnames(ParticleStateMapper)[i], ": ", initial_state[i], " -> ", out[i])
end
using StaticArrays
const ParticleState = SVector{6, Float64}
using StaticArrays
"Composite type that holds the parameters describing the mapping from one particle state to another"
struct ParticleStateMapper <: FieldVector{6, TaylorParams}
x::TaylorParams
u::TaylorParams
y::TaylorParams
v::TaylorParams
τ::TaylorParams
dK_K0::TaylorParams
end
"Constructs a `ParticleStateMapper` type object from the data given by the function `TaylorParamsFromDAT`"
function ParticleStateMapperFromDAT(filename::AbstractString)::ParticleStateMapper
stream = open(filename)
mappers = TaylorParams[]
for _ in 1:6
push!(mappers, TaylorParamsFromDAT(stream))
end
close(stream)
ParticleStateMapper(mappers...)
end
"""
Evaluates the Taylor expansions described by the fields of `mapping` for the state given by
`initial_state` and stores the results in a vector
"""
function evaluate(mapper::ParticleStateMapper, state::ParticleState)::ParticleState
evaluate.(mapper, Ref(state))
end
"""
Serializes the data needed to map the initial state of a particle to the final state,
contained in an object `mapper` of type `ParticleStateMapper`` into a file 'filename'
"""
function ParticleStateMapperToJLD2(mapper::ParticleStateMapper, filename::AbstractString)
save_object(filename, mapper)
end
"Deserializes `filename` to get the mapping data"
function ParticleStateMapperFromJLD2(filename::AbstractString)::ParticleStateMapper
load_object(filename)
end
using SparseArrays, JLD2
"Composite type that holds the parameters of a Taylor expansion"
struct TaylorParams
"Polynomial degree"
n::UInt8
"Matrix containing the exponents of the variables"
order_exponents::SparseMatrixCSC{UInt8, Int64}
"Coefficients of the Taylor expansion"
coeffs::Vector{Float64}
"Constructor that sets `n` as the maximum value in the exponents matrix"
function TaylorParams(order_exponents::SparseMatrixCSC{UInt8, Int64}, coeffs::Vector{Float64})
n = findmax(order_exponents)[1]
new(n, order_exponents, coeffs)
end
end
"Evaluates the Taylor expansion described by `params` for the state given by `initial_state`"
function evaluate(params::TaylorParams, initial_state::AbstractVector{Float64})
# matrix containg the powers of each parameter on each row
pows = initial_state.^(1:params.n)'
# vector that will contain the products of the terms corresponding to each coefficient
prods = ones(size(params.order_exponents)[2])
for (i, j, val) in zip(findnz(params.order_exponents)...)
prods[j] *= pows[i, val]
end
prods' * params.coeffs
end
using SparseArrays
"""
Reads the values for the parameters needed in a TaylorParams object from a file and
returns an object of type TaylorParams
"""
function TaylorParamsFromDAT(stream::IOStream)::TaylorParams
# read the stream up to the line where the needed data is written
readuntil(stream, "I COEFFICIENT ORDER EXPONENTS\r\n", keep = true)
# sparse matrix that will contain on each column the exponent orders corresponding to each coefficient
order_exponents = spzeros(UInt8, 6, 0)
# vector that will contain the coefficients
coeffs = Float64[]
while true
line = readline(stream)
parts = split(line)
if length(parts) != 9
break
end
push!(coeffs, parse(Float64, parts[2]))
order_exponents = hcat(order_exponents, parse.(UInt8, parts[4:9]))
end
TaylorParams(order_exponents, coeffs)
end
@logankilpatrick
Copy link

This is great! It would be cool to turn it into a repository on your GitHub.

@iuliadmtru
Copy link
Author

Thank you @logankilpatrick! I turned it into a repository :). The README is on the way.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment