Skip to content

Commit 9e26ca1

Browse files
Jonas BreulingCopilot
andcommitted
More tests and minor cleanup.
Co-authored-by: Copilot <copilot@github.com>
1 parent fb10bbc commit 9e26ca1

2 files changed

Lines changed: 81 additions & 25 deletions

File tree

solve_dae/integrate/_dae/base.py

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
)
99
from scipy.optimize._numdiff import approx_derivative
1010
from scipy.linalg import lu_factor, lu_solve
11-
from scipy.sparse import csc_matrix, issparse, eye
11+
from scipy.sparse import csc_matrix, issparse
1212
from scipy.sparse.linalg import splu
1313
from .common import select_initial_step
1414

@@ -359,8 +359,7 @@ def step(self):
359359
otherwise.
360360
"""
361361
if self.status != 'running':
362-
raise RuntimeError("Attempt to step on a failed or finished "
363-
"solver.")
362+
raise RuntimeError("Attempt to step on a failed or finished solver.")
364363

365364
# if self.n == 0 or self.t == self.t_bound:
366365
# # Handle corner cases of empty solver or no integration.
@@ -390,15 +389,14 @@ def dense_output(self):
390389
Local interpolant over the last successful step.
391390
"""
392391
if self.t_old is None:
393-
raise RuntimeError("Dense output is available after a successful "
394-
"step was made.")
392+
raise RuntimeError("Dense output is available after a successful step was made.")
395393
return self._dense_output_impl()
396394

397-
def _step_impl(self):
398-
raise NotImplementedError
395+
# def _step_impl(self):
396+
# raise NotImplementedError
399397

400-
def _dense_output_impl(self):
401-
raise NotImplementedError
398+
# def _dense_output_impl(self):
399+
# raise NotImplementedError
402400

403401

404402
class DAEDenseOutput:
@@ -438,5 +436,5 @@ def __call__(self, t):
438436
raise ValueError("`t` must be a float or a 1-D array.")
439437
return self._call_impl(t)
440438

441-
def _call_impl(self, t):
442-
raise NotImplementedError
439+
# def _call_impl(self, t):
440+
# raise NotImplementedError

solve_dae/integrate/_dae/tests/test_base.py

Lines changed: 72 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,30 +5,66 @@
55
from solve_dae.integrate import solve_dae
66

77

8-
# initial conditions
98
y0 = [1]
109
yp0 = [0.5 * y0[0]]
11-
t_span = (0, 1)
10+
t_span = (0, 1.2)
1211

1312

1413
def F(t, y, yp):
1514
return yp - 0.5 * y
1615

1716
def jac_dense(t, y, yp):
18-
return np.eye(len(y)), -0.5 * np.eye(len(yp))
17+
return -0.5 * np.eye(len(y)), np.eye(len(yp))
1918

2019
def jac_sparse(t, y, yp):
21-
return csc_matrix(np.eye(len(y))), csc_matrix(-0.5 * np.eye(len(yp)))
20+
return csc_matrix(-0.5 * np.eye(len(y))), csc_matrix(np.eye(len(yp)))
2221

23-
def jac_wrong_shape_dense(t, y, yp):
24-
return np.eye(len(y) + 1), -0.5 * np.eye(len(yp) + 1)
22+
def jac_wrong_shape_Jyp_dense(t, y, yp):
23+
return -0.5 * np.eye(len(y)), np.eye(len(yp) + 1),
2524

26-
def jac_wrong_shape_sparse(t, y, yp):
27-
return csc_matrix(np.eye(len(y) + 1)), csc_matrix(-0.5 * np.eye(len(yp) + 1))
25+
def jac_wrong_shape_Jy_dense(t, y, yp):
26+
return -0.5 * np.eye(len(y) + 1), np.eye(len(yp))
27+
28+
def jac_wrong_shape_Jyp_sparse(t, y, yp):
29+
return csc_matrix(-0.5 * np.eye(len(y))), csc_matrix(np.eye(len(yp) + 1))
30+
31+
def jac_wrong_shape_Jy_sparse(t, y, yp):
32+
return csc_matrix(-0.5 * np.eye(len(y) + 1)), csc_matrix(np.eye(len(yp)))
33+
34+
jac_wrong_shape_Jyp_dense_constant = (
35+
np.eye(2),
36+
-0.5 * np.eye(1),
37+
)
38+
39+
jac_wrong_shape_Jy_dense_constant = (
40+
np.eye(1),
41+
-0.5 * np.eye(2),
42+
)
43+
44+
jac_wrong_shape_Jyp_sparse_constant = (
45+
csc_matrix(np.eye(2)),
46+
csc_matrix(-0.5 * np.eye(1)),
47+
)
48+
49+
jac_wrong_shape_Jy_sparse_constant = (
50+
csc_matrix(np.eye(1)),
51+
csc_matrix(-0.5 * np.eye(2)),
52+
)
2853

2954

3055
parameters_method = ["BDF", "Radau"]
31-
parameters_jac = [jac_dense, jac_sparse, jac_wrong_shape_dense, jac_wrong_shape_sparse]
56+
parameters_jac_correct_shape = [jac_dense, jac_sparse]
57+
parameters_jac_wrong_shape = [
58+
jac_wrong_shape_Jyp_dense,
59+
jac_wrong_shape_Jy_dense,
60+
jac_wrong_shape_Jyp_sparse,
61+
jac_wrong_shape_Jy_sparse,
62+
jac_wrong_shape_Jyp_dense_constant,
63+
jac_wrong_shape_Jy_dense_constant,
64+
jac_wrong_shape_Jyp_sparse_constant,
65+
jac_wrong_shape_Jy_sparse_constant,
66+
]
67+
parameters_jac = parameters_jac_correct_shape + parameters_jac_wrong_shape
3268

3369

3470
parameters = product(
@@ -39,7 +75,7 @@ def jac_wrong_shape_sparse(t, y, yp):
3975

4076
@pytest.mark.parametrize("method, jac", parameters)
4177
def test_jacobian_shape(method, jac):
42-
if jac in [jac_wrong_shape_dense, jac_wrong_shape_sparse]:
78+
if not callable(jac) or jac in parameters_jac_wrong_shape:
4379
with pytest.raises(ValueError) as excinfo:
4480
solve_dae(F, t_span, y0, yp0, method=method, jac=jac)
4581

@@ -61,12 +97,34 @@ def test_jacobian_shape(method, jac):
6197
solve_dae(F, t_span, y0, yp0, method=method, jac=jac)
6298

6399

64-
# @pytest.mark.parametrize("method,", parameters_method)
65-
# def test_step(method):
66-
# sol = solve_dae(F, t_span, y0, yp0, method=method)
67-
# pass
100+
@pytest.mark.parametrize("method", parameters_method)
101+
def test_small_max_step(method):
102+
solve_dae(F, t_span, y0, yp0, method=method, max_step=1e-2)
103+
104+
105+
def F(t, y, yp):
106+
return yp - 1 / (1 - t)
107+
108+
y0 = [0]
109+
yp0 = [1]
110+
t_span = (0, 1.2)
111+
112+
113+
@pytest.mark.filterwarnings("ignore:divide by zero encountered in scalar divide")
114+
@pytest.mark.parametrize("method", parameters_method)
115+
def test_overflow(method):
116+
sol = solve_dae(F, t_span, y0, yp0, method=method)
117+
assert sol.status == -1
118+
assert sol.success == False
119+
assert sol.message == "Required step size is less than spacing between numbers."
68120

69121

70122
# if __name__ == "__main__":
71123
# for params in parameters:
72124
# test_jacobian_shape(*params)
125+
126+
# for params in parameters_method:
127+
# test_small_max_step(params)
128+
129+
# for params in parameters_method:
130+
# test_overflow(params)

0 commit comments

Comments
 (0)