diff --git a/README.md b/README.md index d9816473..7a367de0 100644 --- a/README.md +++ b/README.md @@ -3,19 +3,21 @@ [![Dev](https://img.shields.io/badge/docs-dev-blue.svg)](https://bmad-sim.github.io/GTPSA.jl/dev/) [![Build Status](https://github.com/bmad-sim/GTPSA.jl/actions/workflows/CI.yml/badge.svg?branch=main)](https://github.com/bmad-sim/GTPSA.jl/actions/workflows/CI.yml?query=branch%3Amain) -This package provides a full-featured Julia interface to the [Generalised Truncated Power Series Algebra (GTPSA) library](https://mad.web.cern.ch/mad/releases/madng/html/mad_mod_diffalg.html), which computes Taylor expansions, or Truncated Power Series (TPSs) of real and complex multivariable functions to arbitrary orders in the variables. +## Overview -Truncated Power Series Algebra (TPSA) performs forward-mode automatic differentation (AD) similar to the dual-number implementation of `ForwardDiff.jl`. However, instead of nesting derivatives for higher orders, TPSA naturally extends to arbitary orders by directly using the power series expansions. This, paired with a highly optimized monomial indexing function/storage for propagating the partial derivatives, gives `GTPSA.jl` similar performance as `ForwardDiff.jl` to 1st-order, but significantly faster performance for 2nd-order calculations and above. +This package provides a full-featured Julia interface to the [Generalised Truncated Power Series Algebra (GTPSA) library](https://mad.web.cern.ch/mad/releases/madng/html/mad_mod_diffalg.html), which computes Taylor expansions, or Truncated Power Series (TPSs) of real and complex multivariable functions to arbitrary orders. + +Truncated Power Series Algebra (TPSA) performs forward-mode automatic differentation (AD) similar to the dual-number implementation of `ForwardDiff.jl`. However, instead of nesting derivatives for higher orders, TPSA naturally extends to arbitary orders by directly using the power series expansions. This, paired with a highly optimized monomial indexing function/storage for propagating the partial derivatives, makes `GTPSA.jl` significantly faster for 2nd-order calculations and above (for 1st-order +calculations the performance is similar to `ForwardDiff.jl`). +See the [`benchmark/track.jl`](https://github.com/bmad-sim/GTPSA.jl/blob/main/benchmark/track.jl) example for a speed comparison of `GTPSA.jl` with `ForwardDiff.jl` in calculating the partial derivatives for a system with 58 inputs and 6 outputs. **In this example, GTPSA was nearly x3 faster than ForwardDiff to 2nd order, and x15 faster to 3rd order.** GTPSA provides several advantages over current Julia AD packages: 1. **Speed**: `GTPSA.jl` is significantly faster than `ForwardDiff.jl` for 2nd-order calculations and above, and has similar performance at 1st-order -2. **Custom Orders in Individual Variables**: For example, computing the Taylor expansion of $f(x_1,x_2)$ to 2nd order in $x_1$ and 6th order in $x_2$ is done trivially in GTPSA -3. **Complex Numbers**: GTPSA natively supports complex numbers, and allows for mixing of complex and real truncated power series -4. **Distinction Between State Variables and Parameters**: Distinguishing between dependent variables and parameters in the solution of a differential equation expressed as a power series in the dependent variables/parameters is very advantageous in analysis -5. **Fast JIT Compilation**: Because most of the "heavy-lifting" is done in the precompiled C library, the JIT compilation for `GTPSA.jl` is fast, easing iterative REPL development - -See the [`benchmark/track.jl`](https://github.com/bmad-sim/GTPSA.jl/blob/main/benchmark/track.jl) example for a speed comparison of `GTPSA.jl` with `ForwardDiff.jl` in calculating the partial derivatives for a system with 58 inputs and 6 outputs. **We observed GTPSA to be nearly x3 faster than ForwardDiff to 2nd order, and x15 faster to 3rd order in our example.** +2. **Custom Orders in Individual Variables**: Other packages use a single maximum order for all variables. With GTPSA, the +maximum order can be set differently for different variables. For example, computing the Taylor expansion of $f(x_1,x_2)$ to 2nd order in $x_1$ and 6th order in $x_2$ is possible +3. **Complex Numbers**: GTPSA natively supports complex numbers and allows for mixing of complex and real truncated power series +4. **Distinction Between State Variables and Parameters**: Distinguishing between dependent variables and parameters in the solution of a differential equation expressed as a power series in the dependent variables/parameters can be advantageous in analysis ## Setup To use `GTPSA.jl`, in the Julia REPL run @@ -24,12 +26,6 @@ To use `GTPSA.jl`, in the Julia REPL run import Pkg; Pkg.add("GTPSA") ``` -For developers, - -```julia -import Pkg; Pkg.develop("GTPSA") -``` - ## Basic Usage First, a `Descriptor` must be created specifying the number of variables, number of parameters, and truncation order for each variable/parameter in the TPSA. A `TPS` or `ComplexTPS` can then be created based on the `Descriptor`. TPSs can be manipulated using all of the arithmetic operators (`+`,`-`,`*`,`/`,`^`) and math functions (e.g. `abs`, `sqrt`, `sin`, `exp`, `log`, `tanh`, etc.). @@ -42,12 +38,14 @@ d = Descriptor(2, 6) # Get the TPSs corresponding to each variable based on the Descriptor x = vars() +# x[1] corresponds to the first variable and x[2] corresponds to the second variable # Manipulate the TPSs as you would any other mathematical variable in Julia f = cos(x[1]) + im*sin(x[2]) +# This creates a new TPS called f ``` -`f` itself is a TPS. Note that scalars do not need to be defined as TPSs when writing expressions. Running `print(f)` then gives the output +Note that scalars do not need to be defined as TPSs when writing expressions. Running `print(f)` gives the output ``` ComplexTPS: @@ -61,9 +59,10 @@ ComplexTPS: -1.3888888888888887e-03 0.0000000000000000e+00 6 6 0 ``` -For more details, including TPSs with custom orders in individual variables, see [the documentation](https://bmad-sim.github.io/GTPSA.jl/). - -Advanced users are referred to [this paper](https://inspirehep.net/files/286f2ab60e1e7c372cec485337ab5eb6) written by the developers of the GTPSA library for more details. +For more details, including using TPSs with differing truncation orders for each variable, see the [GTPSA documentation](https://bmad-sim.github.io/GTPSA.jl/). ## Acknowledgements -We thank Laurent Deniau, the creator of GTPSA, for very detailed and lengthy discussions on using his C library. +Much thanks must be given to Laurent Deniau, the creator of the C GTPSA library, for his time and great patience in explaining his code. + +Advanced users are referred to [this paper](https://inspirehep.net/files/286f2ab60e1e7c372cec485337ab5eb6) discussing +the inner workings of the C GTPSA library. diff --git a/docs/src/devel.md b/docs/src/devel.md index 800ed99d..4f597ba8 100644 --- a/docs/src/devel.md +++ b/docs/src/devel.md @@ -1,4 +1,12 @@ # For Developers + +Developers may fork [the GTPSA.jl repo](https://github.com/bmad-sim/GTPSA.jl) and then `dev` their forked repo in the REPL. For example, if my Github username is `githubuser`, then after forking GTPSA.jl I would run in the REPL: + +```julia +import Pkg +Pkg.develop(url="https://github.com/githubuser/GTPSA.jl") +``` + The package consists of two layers: a low-level layer written in Julia that is 1-to-1 with the GTPSA C code, and a high-level, user-friendly layer that cleans up the notation for manipulating TPSAs, manages temporaries generated during evaluation, and properly manages the memory in C when variables go out of scope in Julia. The low-level functions, which are exported for developer usage at the moment, are listed below. The C code consists of three C structs: `desc`, `tpsa`, and `ctpsa`. The low-level Julia-equivalent, 1-to-1 structs are respectively `Desc`, `RTPSA`, and `CTPSA`. C pointers `Ptr` to these structs are wrapped by the high-level structs `Descriptor`, `TPSA`, and `ComplexTPSA` respectively. @@ -358,4 +366,4 @@ GTPSA.mad_ctpsa_scan_coef! GTPSA.mad_ctpsa_debug GTPSA.mad_ctpsa_isvalid GTPSA.mad_ctpsa_init! -``` \ No newline at end of file +``` diff --git a/docs/src/index.md b/docs/src/index.md index cfd614e0..372392d2 100644 --- a/docs/src/index.md +++ b/docs/src/index.md @@ -2,19 +2,19 @@ *A full-featured Julia interface to the Generalised Truncated Power Series Algebra library.* -This package provides a full-featured Julia interface to the [Generalised Truncated Power Series Algebra (GTPSA) library](https://mad.web.cern.ch/mad/releases/madng/html/mad_mod_diffalg.html), which computes Taylor expansions, or Truncated Power Series (TPSs) of real and complex multivariable functions to arbitrary orders in the variables. +This package provides a full-featured Julia interface to the [Generalised Truncated Power Series Algebra (GTPSA) library](https://mad.web.cern.ch/mad/releases/madng/html/mad_mod_diffalg.html), which computes Taylor expansions, or Truncated Power Series (TPSs) of real and complex multivariable functions to arbitrary orders. -Truncated Power Series Algebra (TPSA) performs forward-mode automatic differentation (AD) similar to the dual-number implementation of `ForwardDiff.jl`. However, instead of nesting derivatives for higher orders, TPSA naturally extends to arbitary orders by directly using the power series expansions. This, paired with a highly optimized monomial indexing function/storage for propagating the partial derivatives, gives `GTPSA.jl` similar performance as `ForwardDiff.jl` to 1st-order, but significantly faster performance for 2nd-order calculations and above. +Truncated Power Series Algebra (TPSA) performs forward-mode automatic differentation (AD) similar to the dual-number implementation of `ForwardDiff.jl`. However, instead of nesting derivatives for higher orders, TPSA naturally extends to arbitary orders by directly using the power series expansions. This, paired with a highly optimized monomial indexing function/storage for propagating the partial derivatives, makes `GTPSA.jl` significantly faster for 2nd-order calculations and above (for 1st-order +calculations the performance is similar to `ForwardDiff.jl`). +See the [`benchmark/track.jl`](https://github.com/bmad-sim/GTPSA.jl/blob/main/benchmark/track.jl) example for a speed comparison of `GTPSA.jl` with `ForwardDiff.jl` in calculating the partial derivatives for a system with 58 inputs and 6 outputs. **In this example, GTPSA was nearly x3 faster than ForwardDiff to 2nd order, and x15 faster to 3rd order.** GTPSA provides several advantages over current Julia AD packages: 1. **Speed**: `GTPSA.jl` is significantly faster than `ForwardDiff.jl` for 2nd-order calculations and above, and has similar performance at 1st-order -2. **Custom Orders in Individual Variables**: For example, computing the Taylor expansion of ``f(x_1,x_2)`` to 2nd order in ``x_1`` and 6th order in ``x_2`` is done trivially in GTPSA -3. **Complex Numbers**: GTPSA natively supports complex numbers, and allows for mixing of complex and real truncated power series -4. **Distinction Between State Variables and Parameters**: Distinguishing between dependent variables and parameters in the solution of a differential equation expressed as a power series in the dependent variables/parameters is very advantageous in analysis -5. **Fast JIT Compilation**: Because most of the "heavy-lifting" is done in the precompiled C library, the JIT compilation for `GTPSA.jl` is fast, easing iterative REPL development - -See the [`benchmark/track.jl`](https://github.com/bmad-sim/GTPSA.jl/blob/main/benchmark/track.jl) example for a speed comparison of `GTPSA.jl` with `ForwardDiff.jl` in calculating the partial derivatives for a system with 58 inputs and 6 outputs. **We observed GTPSA to be nearly x3 faster than ForwardDiff to 2nd order, and x15 faster to 3rd order in our example.** +2. **Custom Orders in Individual Variables**: Other packages use a single maximum order for all variables. With GTPSA, the +maximum order can be set differently for different variables. For example, computing the Taylor expansion of $f(x_1,x_2)$ to 2nd order in $x_1$ and 6th order in $x_2$ is possible +3. **Complex Numbers**: GTPSA natively supports complex numbers and allows for mixing of complex and real truncated power series +4. **Distinction Between State Variables and Parameters**: Distinguishing between dependent variables and parameters in the solution of a differential equation expressed as a power series in the dependent variables/parameters can be advantageous in analysis ## Setup To use `GTPSA.jl`, in the Julia REPL run @@ -23,30 +23,41 @@ To use `GTPSA.jl`, in the Julia REPL run import Pkg; Pkg.add("GTPSA") ``` -For developers, - -```julia -import Pkg; Pkg.develop("GTPSA") -``` - ## Basic Usage First, a `Descriptor` must be created specifying the number of variables, number of parameters, and truncation order for each variable/parameter in the TPSA. A `TPS` or `ComplexTPS` can then be created based on the `Descriptor`. TPSs can be manipulated using all of the arithmetic operators (`+`,`-`,`*`,`/`,`^`) and math functions (e.g. `abs`, `sqrt`, `sin`, `exp`, `log`, `tanh`, etc.). -TPSs can be viewed as structures containing the coefficients for all of the monomials of a multivariable Taylor expansion up to the orders specified in the `Descriptor`. As an example, to compute the truncated power series of a function ``f(x_1, x_2) = \cos{(x_1)}+i\sin{(x_2)}`` to 6th order in ``x_1`` and ``x_2``: -```@example +TPSs can be viewed as structures containing the coefficients for all of the monomials of a multivariable Taylor expansion up to the orders specified in the `Descriptor`. As an example, to compute the truncated power series of a function $f(x_1, x_2) = \cos{(x_1)}+i\sin{(x_2)}$ to 6th order in $x_1$ and $x_2$: +```julia using GTPSA # Descriptor for TPSA with 2 variables to 6th order -d = Descriptor(2, 6); +d = Descriptor(2, 6) # Get the TPSs corresponding to each variable based on the Descriptor -x = vars(); +x = vars() +# x[1] corresponds to the first variable and x[2] corresponds to the second variable # Manipulate the TPSs as you would any other mathematical variable in Julia -f = cos(x[1]) + 1im*sin(x[2]) +f = cos(x[1]) + im*sin(x[2]) +# This creates a new TPS called f ``` -Advanced users are referred to [this paper](https://inspirehep.net/files/286f2ab60e1e7c372cec485337ab5eb6) written by the developers of the GTPSA library for more details. +Note that scalars do not need to be defined as TPSs when writing expressions. Running `print(f)` gives the output + +``` +ComplexTPS: + Real Imag Order Exponent + 1.0000000000000000e+00 0.0000000000000000e+00 0 0 0 + 0.0000000000000000e+00 1.0000000000000000e+00 1 0 1 + -5.0000000000000000e-01 0.0000000000000000e+00 2 2 0 + 0.0000000000000000e+00 -1.6666666666666666e-01 3 0 3 + 4.1666666666666664e-02 0.0000000000000000e+00 4 4 0 + 0.0000000000000000e+00 8.3333333333333332e-03 5 0 5 + -1.3888888888888887e-03 0.0000000000000000e+00 6 6 0 +``` ## Acknowledgements -We thank Laurent Deniau, the creator of GTPSA, for very detailed and lengthy discussions on using his C library. +Much thanks must be given to Laurent Deniau, the creator of the C GTPSA library, for his time and great patience in explaining his code. + +Advanced users are referred to [this paper](https://inspirehep.net/files/286f2ab60e1e7c372cec485337ab5eb6) discussing +the inner workings of the C GTPSA library.