Skip to content

Commit a465ace

Browse files
committed
TL: added padding for Butcher tables
1 parent 91d6418 commit a465ace

File tree

3 files changed

+52
-4
lines changed

3 files changed

+52
-4
lines changed

docs/notebooks/21_lagrange.ipynb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@
88
"# Tutorial 1 : using the `qmat.lagrange` module\n",
99
"\n",
1010
"📜 _The_ `LagrangeApproximation` _class from the_ `qmat.lagrange` _module is a multi-purpose class to perform interpolation, integration or derivative approximation from a given set of 1D points._\n",
11-
"_It is based on the Barycentric Lagrange interpolation theory, originally developed by Joseph-Louis Lagrange around 1795, and widely popularized by the paper of Jean-Paul Berrut ahd Llyod N. Trefethen : [\"Barycentric Lagrange interpolation\"](https://doi.org/10.1137/S0036144502417715)._\n",
11+
"_It is based on the Barycentric Lagrange interpolation theory, originally developed by Joseph-Louis Lagrange around 1795, and widely popularized by the paper of Jean-Paul Berrut ahd Llyod N. Trefethen: [\"Barycentric Lagrange interpolation\"](https://doi.org/10.1137/S0036144502417715)._\n",
1212
"\n",
13-
"The main concept behind the `LagrangeApproximation` class is to precompute the barycentric weights for any provided set of points, then use them to generate value-independent matrices used later to compute approximations (interpolation, integration or derivative) from values vectors."
13+
"The main concept behind this class is to precompute the barycentric weights for any provided set of points, then use them to generate value-independent matrices used later to compute approximations (interpolation, integration or derivative) from values vectors."
1414
]
1515
},
1616
{
@@ -375,7 +375,7 @@
375375
"source": [
376376
"## Handling duplicated points\n",
377377
"\n",
378-
"📜 _While the base theory behind Barycentric Interpolation required all points to be unique, the `LagrangeApproximation` class can also take interpolation points with duplicates._\n",
378+
"📜 _While the base theory behind Barycentric Interpolation required all points to be unique, the_ `LagrangeApproximation` _class can also take interpolation points with duplicates._\n",
379379
"\n",
380380
"Let's consider the following example :"
381381
]

qmat/qcoeff/butcher.py

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,20 @@
2020

2121

2222
class RK(QGenerator):
23-
"""Base class for Runge-Kutta generators"""
23+
"""
24+
Base class for Runge-Kutta generators
25+
26+
Parameters
27+
----------
28+
padding : str, optional
29+
Eventually add padding to the Butcher table. Can be
30+
31+
- LEFT : add padding corresponding to an additional node at t=0
32+
- RIGHT : add padding corresponding to an additional node at t=1
33+
- BOTH : add both LEFT and RIGHT padding
34+
35+
The default is None.
36+
"""
2437

2538
A = None
2639
""":math:`A` matrix of the Butcher table"""
@@ -31,6 +44,29 @@ class RK(QGenerator):
3144
b2 = None
3245
""":math:`b_2` coefficients for the embedded methods"""
3346

47+
def __init__(self, padding=None):
48+
if padding:
49+
assert padding in ["LEFT", "RIGHT", "BOTH"], "padding choices can only be LEFT, RIGHT or BOTH"
50+
51+
if padding in ["LEFT", "BOTH"]:
52+
self.c = np.array([0] + self.c.tolist())
53+
self.b = np.array([0] + self.b.tolist())
54+
55+
newA = np.zeros((self.nNodes, self.nNodes))
56+
newA[1:, 1:] = self.A
57+
self.A = newA
58+
59+
if padding in ["RIGHT", "BOTH"]:
60+
self.c = np.array(self.c.tolist() + [1])
61+
self.b = np.array(self.b.tolist() + [0])
62+
63+
newA = np.zeros((self.nNodes, self.nNodes))
64+
newA[:-1, :-1] = self.A
65+
newA[-1] = self.b
66+
self.A = newA
67+
68+
self.padding = padding
69+
3470
@property
3571
def nodes(self)->np.ndarray: return self.c
3672

tests/test_qcoeff/test_butcher.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import pytest
2+
import numpy as np
3+
4+
from qmat.qcoeff.butcher import RK_SCHEMES
5+
6+
@pytest.mark.parametrize("lam", [-1, 1j, -0.5+0.5j])
7+
@pytest.mark.parametrize("scheme", RK_SCHEMES.keys())
8+
@pytest.mark.parametrize("which", ["LEFT", "RIGHT", "BOTH"])
9+
def testPadding(which, scheme, lam):
10+
ref = RK_SCHEMES[scheme]().solveDahlquist(lam, 1, 1, 1)
11+
pad = RK_SCHEMES[scheme](padding=which).solveDahlquist(lam, 1, 1, 1)
12+
assert np.allclose(ref, pad), f"{which} padded Butcher table produces inconsistent result for {scheme}"

0 commit comments

Comments
 (0)