Skip to content

Commit

Permalink
Merge pull request #2114 from awkwardPotato812/master
Browse files Browse the repository at this point in the history
Add argument for spline boundary conditions
  • Loading branch information
Ericgig committed Mar 15, 2023
2 parents afd160b + e701ecc commit 8ae215a
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 8 deletions.
2 changes: 2 additions & 0 deletions doc/changes/2114.misc
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Added new argument bc_type to take boundary conditions when creating QobjEvo

7 changes: 6 additions & 1 deletion qutip/core/coefficient.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ def _return(base, **kwargs):


def coefficient(base, *, tlist=None, args={}, args_ctypes={},
order=3, compile_opt=None, function_style=None, **kwargs):
order=3, compile_opt=None, function_style=None,
boundary_conditions=None, **kwargs):
"""Build ``Coefficient`` for time dependent systems:
```
Expand Down Expand Up @@ -149,6 +150,9 @@ def f2_t(t, args):
compile_opt : CompilationOptions, optional
Sets of options for the compilation of string based coefficients.
boundary_conditions: 2-tupule, str or None, optional
Specify boundary conditions for spline interpolation.
**kwargs
Extra arguments to pass the the coefficients.
"""
Expand All @@ -159,6 +163,7 @@ def f2_t(t, args):
'order': order,
'compile_opt': compile_opt,
'function_style': function_style,
'boundary_conditions': boundary_conditions
})

for type_ in coefficient_builders:
Expand Down
11 changes: 9 additions & 2 deletions qutip/core/cy/coefficient.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -387,14 +387,20 @@ cdef class InterCoefficient(Coefficient):
order : int
Order of the interpolation. Order ``0`` uses the previous (i.e. left)
value. The order will be reduced to ``len(tlist) - 1`` if it is larger.
boundary_conditions : 2-Tuple, str or None, optional
Boundary conditions for spline evaluation. Default value is `None`.
Correspond to `bc_type` of scipy.interpolate.make_interp_spline.
Refer to Scipy's documentation for further details:
https://docs.scipy.org/doc/scipy/reference/generated/scipy.interpolate.make_interp_spline.html
"""
cdef int order
cdef double dt
cdef double[::1] tlist
cdef complex[:, :] poly
cdef object np_arrays

def __init__(self, coeff_arr, tlist, int order, **_):
def __init__(self, coeff_arr, tlist, int order, boundary_conditions, **_):
tlist = np.array(tlist, dtype=np.float64)
coeff_arr = np.array(coeff_arr, dtype=np.complex128)

Expand All @@ -418,7 +424,8 @@ cdef class InterCoefficient(Coefficient):
elif order >= 2:
# Use scipy to compute the spline and transform it to polynomes
# as used in scipy's PPoly which is easier for us to use.
spline = make_interp_spline(tlist, coeff_arr, k=order)
spline = make_interp_spline(tlist, coeff_arr, k=order,
bc_type=boundary_conditions)
# Scipy can move knots, we add them to tlist
tlist = np.sort(np.unique(np.concatenate([spline.t, tlist])))
a = np.arange(spline.k+1)
Expand Down
22 changes: 17 additions & 5 deletions qutip/core/cy/qobjevo.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,14 @@ cdef class QobjEvo:
``qutip.settings.core["function_coefficient_style"]``
is used. Otherwise the supplied value overrides the global setting.
boundary_conditions : 2-Tuple, str or None, optional
Boundary conditions for spline evaluation. Default value is `None`.
Correspond to `bc_type` of scipy.interpolate.make_interp_spline.
Refer to Scipy's documentation for further details:
https://docs.scipy.org/doc/scipy/reference/generated/scipy.interpolate.make_interp_spline.html
Attributes
----------
dims : list
Expand Down Expand Up @@ -182,7 +190,7 @@ cdef class QobjEvo:
"""
def __init__(QobjEvo self, Q_object, args=None, tlist=None,
order=3, copy=True, compress=True,
function_style=None):
function_style=None, boundary_conditions=None):
if isinstance(Q_object, QobjEvo):
self.dims = Q_object.dims.copy()
self.shape = Q_object.shape
Expand Down Expand Up @@ -217,29 +225,33 @@ cdef class QobjEvo:
self.elements.append(
self._read_element(
op, copy=copy, tlist=tlist, args=args, order=order,
function_style=function_style
function_style=function_style,
boundary_conditions=boundary_conditions
)
)
else:
self.elements.append(
self._read_element(
Q_object, copy=copy, tlist=tlist, args=args, order=order,
function_style=function_style
function_style=function_style,
boundary_conditions=boundary_conditions
)
)

if compress:
self.compress()

def _read_element(self, op, copy, tlist, args, order, function_style):
def _read_element(self, op, copy, tlist, args, order, function_style,
boundary_conditions):
""" Read a Q_object item and return an element for that item. """
if isinstance(op, Qobj):
out = _ConstantElement(op.copy() if copy else op)
qobj = op
elif isinstance(op, list):
out = _EvoElement(
op[0].copy() if copy else op[0],
coefficient(op[1], tlist=tlist, args=args, order=order)
coefficient(op[1], tlist=tlist, args=args, order=order,
boundary_conditions=boundary_conditions)
)
qobj = op[0]
elif isinstance(op, _BaseElement):
Expand Down
4 changes: 4 additions & 0 deletions qutip/tests/core/test_coefficient.py
Original file line number Diff line number Diff line change
Expand Up @@ -372,6 +372,10 @@ def test_CoeffFromScipy():
from_scipy = coefficient(interp.make_interp_spline(tlist, y, k=3))
_assert_eq_over_interval(coeff, from_scipy, rtol=1e-8, inside=True)

coeff = coefficient(y, tlist=tlist, order=3, boundary_conditions="natural")
from_scipy = coefficient(interp.make_interp_spline(tlist, y, k=3, bc_type="natural"))
_assert_eq_over_interval(coeff, from_scipy, rtol=1e-8, inside=True)


@pytest.mark.parametrize('map_func', [
pytest.param(qutip.solver.parallel.parallel_map, id='parallel_map'),
Expand Down

0 comments on commit 8ae215a

Please sign in to comment.