-
Notifications
You must be signed in to change notification settings - Fork 11
Implementing CSRK code in BSeries.jl #144
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 12 commits
7853dcb
aaf5940
afe7373
e4d79cc
823684d
0df736b
09d4629
335265f
8c4e0b1
7ad5325
5d82c87
c0a724d
c45de1c
6616b9c
1227e1a
3691f69
68cecb0
5d30865
7387ffc
53fd493
d6a23d6
c0ba86f
b5813d2
691507f
02acff4
fd1a23e
0c29499
c8113e6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -17,8 +17,9 @@ end | |
|
|
||
| using Latexify: Latexify, LaTeXString | ||
| using Combinatorics: Combinatorics, permutations | ||
| using LinearAlgebra: LinearAlgebra, rank | ||
| using LinearAlgebra: LinearAlgebra, rank, dot | ||
| using SparseArrays: SparseArrays, sparse | ||
| using SymPy | ||
|
|
||
| @reexport using Polynomials: Polynomials, Polynomial | ||
|
|
||
|
|
@@ -40,6 +41,8 @@ export renormalize! | |
|
|
||
| export is_energy_preserving, energy_preserving_order | ||
|
|
||
| export ContinuousStageRungeKuttaMethod | ||
|
|
||
| # Types used for traits | ||
| # These traits may decide between different algorithms based on the | ||
| # corresponding complexity etc. | ||
|
|
@@ -74,6 +77,7 @@ end | |
|
|
||
| TruncatedBSeries{T, V}() where {T, V} = TruncatedBSeries{T, V}(OrderedDict{T, V}()) | ||
|
|
||
|
|
||
| # general interface methods of `AbstractDict` for `TruncatedBSeries` | ||
| @inline Base.iterate(series::TruncatedBSeries) = iterate(series.coef) | ||
| @inline Base.iterate(series::TruncatedBSeries, state) = iterate(series.coef, state) | ||
|
|
@@ -612,6 +616,93 @@ function bseries(ros::RosenbrockMethod, order) | |
| return series | ||
| end | ||
|
|
||
| """ | ||
| ContinuousStageRungeKuttaMethod | ||
|
|
||
| A struct that describes a CSRK method. This kind of 'struct' should be constructed | ||
| via [`CSRK`] | ||
| 'csrk = CSRK(M)' | ||
| in order to later call the 'bseries' function. | ||
|
|
||
| # References | ||
| - Yuto Miyatake and John C. Butcher. | ||
| "A characterization of energy-preserving methods and the construction of | ||
| parallel integrators for Hamiltonian systems." | ||
| SIAM Journal on Numerical Analysis 54, no. 3 (2016): | ||
| [DOI: 10.1137/15M1020861](https://doi.org/10.1137/15M1020861) | ||
|
Sondar74 marked this conversation as resolved.
Outdated
|
||
| """ | ||
|
Sondar74 marked this conversation as resolved.
|
||
| struct ContinuousStageRungeKuttaMethod{MatT <: AbstractMatrix} | ||
| matrix::MatT | ||
| end | ||
|
|
||
|
|
||
| """ | ||
| bseries(csrk::ContinuousStageRungeKuttaMethod, order) | ||
|
|
||
|
Sondar74 marked this conversation as resolved.
|
||
| Compute the B-series of the [`ContinuousStageRungeKuttaMethod`](@ref) `csrk` | ||
| up to the prescribed integer `order` as described by Miyatake & Butcher (2015). | ||
|
|
||
| !!! note "Normalization by elementary differentials" | ||
| The coefficients of the B-series returned by this method need to be | ||
| multiplied by a power of the time step divided by the `symmetry` of the | ||
| rooted tree and multiplied by the corresponding elementary differential | ||
| of the input vector field ``f``. | ||
| See also [`evaluate`](@ref). | ||
|
Sondar74 marked this conversation as resolved.
Outdated
|
||
|
|
||
| # Example: | ||
| The energy-preserving 4x4 matrix given by Miyatake & Butcher (2015) is | ||
| ``` | ||
| M = [-6//5 72//5 -36//1 24//1; | ||
| 72//5 -144//5 -48//1 72//1; | ||
| -36//1 -48//1 720//1 -720//1; | ||
| 24//1 72//1 -720//1 720//1] | ||
| ``` | ||
|
|
||
| Then, we calculate the bseries with the following code: | ||
|
Sondar74 marked this conversation as resolved.
Outdated
|
||
|
|
||
| ``` | ||
| csrk = CSRK(M) | ||
| series = bseries(csrk, 4) | ||
| TruncatedBSeries{RootedTree{Int64, Vector{Int64}}, Rational{Int64}} with 9 entries: | ||
| RootedTree{Int64}: Int64[] => 1//1 | ||
| RootedTree{Int64}: [1] => 1//1 | ||
| RootedTree{Int64}: [1, 2] => 1//2 | ||
| RootedTree{Int64}: [1, 2, 3] => 6004799503160661//36028797018963968 | ||
| RootedTree{Int64}: [1, 2, 2] => 6004799503160661//18014398509481984 | ||
| RootedTree{Int64}: [1, 2, 3, 4] => 6004799503160661//144115188075855872 | ||
| RootedTree{Int64}: [1, 2, 3, 3] => 6004799503160661//72057594037927936 | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this really correct?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No, sorry: seems like there is something happening with the definition of so that, although the output of
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Seems like the numerical function
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's see. First, please add more tests etc. - and fix the CI problems. Then, possible problem can show up already |
||
| RootedTree{Int64}: [1, 2, 3, 2] => 1//8 | ||
| RootedTree{Int64}: [1, 2, 2, 2] => 1//4 | ||
|
|
||
| ``` | ||
|
Sondar74 marked this conversation as resolved.
|
||
| # References | ||
| - Yuto Miyatake and John C. Butcher. | ||
| "A characterization of energy-preserving methods and the construction of | ||
| parallel integrators for Hamiltonian systems." | ||
| SIAM Journal on Numerical Analysis 54, no. 3 (2016): | ||
| [DOI: 10.1137/15M1020861](https://doi.org/10.1137/15M1020861) | ||
|
Sondar74 marked this conversation as resolved.
Outdated
|
||
| """ | ||
| function bseries(csrk::ContinuousStageRungeKuttaMethod, order) | ||
|
Sondar74 marked this conversation as resolved.
|
||
| csrk = csrk.matrix | ||
| V_tmp = eltype(csrk) | ||
| if V_tmp <: Integer | ||
| # If people use integer coefficients, they will likely want to have results | ||
| # as exact as possible. However, general terms are not integers. Thus, we | ||
| # use rationals instead. | ||
| V = Rational{V_tmp} | ||
| else | ||
| V = V_tmp | ||
| end | ||
| series = TruncatedBSeries{RootedTree{Int, Vector{Int}}, V}() | ||
| series[rootedtree(Int[])] = one(V) | ||
| for o in 1:order | ||
| for t in RootedTreeIterator(o) | ||
| series[copy(t)] = elementary_differentials_csrk(csrk, t) | ||
| end | ||
| end | ||
| return series | ||
| end | ||
|
Comment on lines
+675
to
+707
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please add tests. This does not work correctly right now.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Okey, I'm working on this.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. When working with the function
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What is the
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It is the
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Use struct ContinuousStageRungeKuttaMethod{T, MatT <: AbstractMatrix{T}} <: RootedTrees.AbstractTimeIntegrationMethod
A::MatT
end
Base.eltype(::ContinuousStageRungeKuttaMethod{T}) where {T} = T |
||
|
|
||
| # TODO: bseries(ros::RosenbrockMethod) | ||
| # should create a lazy version, optionally a memoized one | ||
|
|
||
|
|
@@ -2016,4 +2107,86 @@ function equivalent_trees(tree) | |
| return equivalent_trees_set | ||
| end | ||
|
|
||
|
|
||
| # This function generates a polynomial | ||
| # A_{t,z} = [t,t^2/2,..., t^s/s]*M*[1, z, ..., z^(s-1)]^T | ||
| # for a given square matrix M of dimension s and chars 't' and 'z'. | ||
| function PolynomialA(M,t,z) | ||
| # get the dimension of the matrix | ||
| s = size(M,1) | ||
| # we need symbolic variables to work with | ||
| variable1 = Sym(t) | ||
| variable2 = Sym(z) | ||
| # conjugate the variable 1, since this will be the variable of the left polynomial | ||
| # and the function 'dot' assumes it to be conjugated | ||
| variable1 = conjugate(variable1) | ||
| # generate the components of the polynomial with powers of t | ||
| poli_z = Array{SymPy.Sym}(undef, s) | ||
| for i in 1:s | ||
| poli_z[i] = variable2^(i-1) | ||
| end | ||
| # generate the components of the polynomial with powers of z | ||
| poli_t = Array{SymPy.Sym}(undef, s) | ||
| for i in 1:s | ||
| poli_t[i] = (1 // i)*(variable1^i) | ||
| end | ||
| # multiply matrix times vector | ||
| result = M * poli_z | ||
| # use dot product for the two vectors | ||
| return dot(poli_t,result) | ||
| end | ||
|
|
||
|
|
||
| """ | ||
| elementary_differentials_csrk(M,tree) | ||
|
|
||
| This function calculates the CSRK elementary differential for a given | ||
| square matrix 'M' and a given RootedTree according to [@ref]. | ||
|
|
||
| # References | ||
| Butcher, John & Miyatake, Yuto. (2015). A Characterization of Energy-Preserving | ||
| Methods and the Construction of Parallel Integrators for Hamiltonian Systems. | ||
| SIAM Journal on Numerical Analysis. 54. 10.1137/15M1020861. | ||
| (https://www.researchgate.net/publication/276211444_A_Characterization_of_Energy-Preserving_Methods_and_the_Construction_of_Parallel_Integrators_for_Hamiltonian_Systems) | ||
|
|
||
| """ | ||
| function elementary_differentials_csrk(M,rootedtree) | ||
| # we extract the level_sequence of 'rootedtree' | ||
| tree = rootedtree.level_sequence | ||
| m = maximum(tree) | ||
| l = length(tree) | ||
| # Since we will integrate with symbolic variables for | ||
| # every node in the tree, we create the variables called | ||
| # 'xi' for 1 <= i <= m, because m is the most distant node from the root. | ||
| variables = [] | ||
| for i in 1:m | ||
| var_name = "x$i" | ||
| var = Sym(var_name) | ||
| push!(variables, var) | ||
| end | ||
| # we will calculate an integral for every node in the level_sequence from right to left | ||
| inverse_counter = l-1 | ||
| # stablish initial integrand, which is the rightmost leaf (last node of the level sequence) | ||
| if l > 1 | ||
| integrand = integrate(PolynomialA(M,variables[tree[end]-1],variables[tree[end]]),(variables[tree[end]],0,1)) | ||
| else | ||
| # if the RootedTree is [1] or [], the elementary differential will be 1. | ||
| return 1 | ||
| end | ||
| # Start a cycle for integrating | ||
| while inverse_counter > 1 | ||
| # we define the pseudo_integrand as the product between the last integral and the new polynomial (since the polynomials are | ||
| # multiplying each others inside the biggest integral). For a node 'i', this new Polynomial is computed for the variables | ||
| # 'xi' and 'x(i-1)'. | ||
| pseudo_integrand = PolynomialA(M,variables[tree[inverse_counter]-1],variables[tree[inverse_counter]])*integrand | ||
| # integrate this new pseudo_integrand with respect to the variable 'xi' | ||
| integrand = integrate(pseudo_integrand,(variables[tree[inverse_counter]],0,1)) | ||
| inverse_counter -= 1 | ||
| end | ||
| # Once we have covered every node except for the base, multiply for the Basis_Polynomial, i.e. the Polynomial B | ||
| # defined by B_{x1} = A_{1, x1}. | ||
| # return the integral with respect to x1. | ||
| return integrate(PolynomialA(M,1,variables[1])*integrand,(variables[1],0,1)) | ||
| end | ||
|
|
||
| end # module | ||
Uh oh!
There was an error while loading. Please reload this page.