Skip to content

Commit df43e64

Browse files
Jonas BreulingCopilot
andcommitted
Minor cleanup.
Co-authored-by: Copilot <copilot@github.com>
1 parent 2875783 commit df43e64

4 files changed

Lines changed: 64 additions & 43 deletions

File tree

solve_dae/integrate/_dae/base.py

Lines changed: 4 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ def __init__(self, fun, t0, y0, yp0, t_bound, rtol, atol,
180180
self.nfev = 0
181181
self.njev = 0
182182
self.nlu = 0
183-
self._nlusove = 0
183+
self._nlusolve = 0
184184

185185
if vectorized:
186186
def fun_single(t, y, yp):
@@ -224,20 +224,17 @@ def lu(A):
224224
return splu(A)
225225

226226
def solve_lu(LU, b):
227-
self._nlusove += 1
227+
self._nlusolve += 1
228228
return LU.solve(b)
229-
230-
self.I = eye(self.n, format='csc')
231229
else:
232230
def lu(A):
233231
self.nlu += 1
234232
return lu_factor(A, overwrite_a=True)
235233

236234
def solve_lu(LU, b):
237-
self._nlusove += 1
235+
self._nlusolve += 1
238236
return lu_solve(LU, b, overwrite_b=True)
239237

240-
self.I = np.identity(self.n)
241238
self.lu = lu
242239
self.solve_lu = solve_lu
243240

@@ -402,12 +399,7 @@ def dense_output(self):
402399
if self.t_old is None:
403400
raise RuntimeError("Dense output is available after a successful "
404401
"step was made.")
405-
406-
if self.n == 0 or self.t == self.t_old:
407-
# Handle corner cases of empty solver and no integration.
408-
return ConstantDAEDenseOutput(self.t_old, self.t, self.y, self.yp)
409-
else:
410-
return self._dense_output_impl()
402+
return self._dense_output_impl()
411403

412404
def _step_impl(self):
413405
raise NotImplementedError
@@ -455,25 +447,3 @@ def __call__(self, t):
455447

456448
def _call_impl(self, t):
457449
raise NotImplementedError
458-
459-
460-
class ConstantDAEDenseOutput(DAEDenseOutput):
461-
"""Constant value interpolator.
462-
463-
This class used for degenerate integration cases: equal integration limits
464-
or a system with 0 equations.
465-
"""
466-
def __init__(self, t_old, t, value, derivative):
467-
super().__init__(t_old, t)
468-
self.value = value
469-
self.derivative = derivative
470-
471-
def _call_impl(self, t):
472-
if t.ndim == 0:
473-
return self.value, self.derivative
474-
else:
475-
ret = np.empty((self.value.shape[0], t.shape[0]))
476-
ret[:] = self.value[:, None]
477-
ret_der = np.empty((self.derivative.shape[0], t.shape[0]))
478-
ret_der[:] = self.derivative[:, None]
479-
return ret, ret_der

solve_dae/integrate/_dae/bdf.py

Lines changed: 57 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ class BDFDAE(DaeSolver):
104104
max_order : int, optional
105105
Highest order of the method with 1 <= max_order <= 6, although
106106
max_order = 6 should be used with care due to the limited stability
107-
propoerties of the corresponding BDF method.
107+
properties of the corresponding BDF method.
108108
NDF_strategy : string, optional
109109
The strategy that is applied for obtaining numerical differentiation
110110
formulas (NDF):
@@ -235,7 +235,7 @@ def __init__(self, fun, t0, y0, yp0, t_bound, max_step=np.inf,
235235

236236
assert 1 <= max_order <= 6, "Ensure that 1 <= max_order <= 6."
237237
if max_order == 6:
238-
warn("Choosing `max_order = 6` is not recomended due to its poor stability properties.",
238+
warn("Choosing `max_order = 6` is not recommended due to its poor stability properties.",
239239
stacklevel=3)
240240
self.max_order = max_order
241241

@@ -565,3 +565,58 @@ def _call_impl(self, t):
565565
# yp3 = np.squeeze(yp3)
566566

567567
# return y3, yp3
568+
569+
570+
# class BdfDenseOutput(DAEDenseOutput):
571+
# """Newton backward-difference interpolant for the BDF solution.
572+
573+
# Both y(t) and yp(t) are evaluated in a single O(order) Horner pass
574+
# using dual-number differentiation.
575+
576+
# The interpolant P(t) satisfies P(t_n - j·h) = y_{n-j} for j = 0..order-1.
577+
# P'(t) is the analytical time-derivative of P.
578+
# """
579+
580+
# def __init__(self, t_old, t, h, order, D):
581+
# super().__init__(t_old, t)
582+
# self.order = order
583+
# self.h = h # signed step size: h = direction * h_abs
584+
# self.t_n = t # current time = right end of the interpolation window
585+
# self.D = D # shape (order+1, n): divided differences
586+
587+
# def _call_impl(self, t):
588+
# """Evaluate (y(t), yp(t)) using Horner's rule with dual-number derivative.
589+
590+
# The Newton form of P(t) is:
591+
# P = D[0] + x_1*(D[1] + x_2*(D[2] + ... + x_q*D[q]))
592+
# where x_j = (t - (t_n - (j-1)*h)) / (j*h).
593+
594+
# Carrying dual variables (v, dv/dt) through the Horner recurrence gives
595+
# both P(t) and P'(t) in a single O(order) pass — no second traversal needed.
596+
# """
597+
# scalar = t.ndim == 0
598+
# t = np.atleast_1d(t) # (n_pts,)
599+
# n_pts = len(t)
600+
# n = self.D.shape[1] # state dimension
601+
602+
# # Initialise with the innermost term D[order] (constant in t)
603+
# # v : (n, n_pts) — running polynomial value
604+
# # dv: (n, n_pts) — running derivative d/dt of v
605+
# v = np.tile(self.D[self.order, :, None], (1, n_pts)) # (n, n_pts)
606+
# dv = np.zeros_like(v)
607+
608+
# for j in range(self.order, 0, -1):
609+
# # Node for this Horner step
610+
# node = self.t_n - (j - 1) * self.h # scalar
611+
# x_j = (t - node) / (j * self.h) # (n_pts,)
612+
# dx_j = 1.0 / (j * self.h) # scalar (same for all pts)
613+
614+
# # Dual-number multiply: new = D[j-1] + x_j * v
615+
# # d(new)/dt = dx_j * v + x_j * dv
616+
# new_v = self.D[j - 1, :, None] + x_j[None, :] * v
617+
# new_dv = dx_j * v + x_j[None, :] * dv
618+
# v, dv = new_v, new_dv
619+
620+
# if scalar:
621+
# return np.squeeze(v), np.squeeze(dv)
622+
# return v, dv

solve_dae/integrate/_dae/radau.py

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,7 @@ class RadauDAE(DaeSolver):
288288
bounded and determined solely by the solver.
289289
rtol, atol : float and array_like, optional
290290
Relative and absolute tolerances. The solver keeps the local error
291-
estimates less than ``atol + rtol * abs(y)``. HHere `rtol` controls a
291+
estimates less than ``atol + rtol * abs(y)``. Here `rtol` controls a
292292
relative accuracy (number of correct digits), while `atol` controls
293293
absolute accuracy (number of correct decimal places). To achieve the
294294
desired `rtol`, set `atol` to be smaller than the smallest value that
@@ -413,9 +413,7 @@ def __init__(self, fun, t0, y0, yp0, t_bound, stages=3,
413413
) = radau_constants(stages)
414414

415415
self.h_abs_old = None
416-
self.h_abs_oldold = None
417416
self.error_norm_old = None
418-
self.error_norm_oldold = None
419417

420418
# modify tolerances as in radau.f line 824ff and 920ff
421419
# TODO: Document this rescaling
@@ -460,7 +458,6 @@ def __init__(self, fun, t0, y0, yp0, t_bound, stages=3,
460458
self.current_jac = True
461459
self.LU_real = None
462460
self.LU_complex = None
463-
self.Z = None
464461

465462
def _step_impl(self):
466463
t = self.t
@@ -643,7 +640,6 @@ def _step_impl(self):
643640
self.y = y_new
644641
self.yp = yp_new
645642

646-
self.Z = Z
647643
self.Y = Y
648644
self.Yp = Yp
649645

solve_dae/integrate/_dae/tests/test_integration_robertson.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ def F_robertson(t, state, statep):
3434
):
3535
with suppress_warnings() as sup:
3636
sup.filter(UserWarning,
37-
"Choosing `max_order = 6` is not recomended due to its "
37+
"Choosing `max_order = 6` is not recommended due to its "
3838
"poor stability properties.")
3939
res = solve_dae(F_robertson, tspan, y0, yp0, rtol=rtol,
4040
atol=atol, method=method, max_order=max_order,
@@ -93,7 +93,7 @@ def F_robertson(t, y, yp):
9393
):
9494
with suppress_warnings() as sup:
9595
sup.filter(UserWarning,
96-
"Choosing `max_order = 6` is not recomended due to its "
96+
"Choosing `max_order = 6` is not recommended due to its "
9797
"poor stability properties.")
9898
res = solve_dae(F_robertson, tspan, y0, yp0, rtol=rtol,
9999
atol=atol, method=method, max_order=max_order,

0 commit comments

Comments
 (0)