-
-
Notifications
You must be signed in to change notification settings - Fork 5.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
BUG: integrate: Handle y0=[] in odeint. #13278
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -238,6 +238,19 @@ def odeint(func, y0, t, args=(), Dfun=None, col_deriv=0, full_output=0, | |
|
||
t = copy(t) | ||
y0 = copy(y0) | ||
|
||
if np.shape(y0) == (0,): | ||
# y0 is a 1-d sequence with length 0. Handle this edge case here | ||
# instead of passing it to the C code. (The C code can handle a | ||
# scalar, and it will correctly raise an exception if y0.ndim > 1, | ||
# so it is OK to let those cases get passed in.) | ||
n = len(t) | ||
y = np.empty((n, 0)) | ||
if full_output: | ||
return y, _make_empty_info(n) | ||
else: | ||
return y | ||
|
||
output = _odepack.odeint(func, y0, t, args, Dfun, col_deriv, ml, mu, | ||
full_output, rtol, atol, tcrit, h0, hmax, hmin, | ||
ixpr, mxstep, mxhnil, mxordn, mxords, | ||
|
@@ -257,3 +270,31 @@ def odeint(func, y0, t, args=(), Dfun=None, col_deriv=0, full_output=0, | |
return output[0] | ||
else: | ||
return output | ||
|
||
|
||
def _make_empty_info(n): | ||
""" | ||
Create an `info` dictionary for the return value of odeint in the | ||
case where y0 has length 0 and full_output is True. | ||
""" | ||
nm1 = n - 1 | ||
info = { | ||
'hu': np.zeros(nm1, dtype=np.float64), | ||
'tcur': np.zeros(nm1, dtype=np.float64), | ||
'tolsf': np.zeros(nm1, dtype=np.float64), | ||
'tsw': np.zeros(nm1, dtype=np.float64), | ||
'nst': np.zeros(nm1, dtype=np.int32), | ||
'nfe': np.zeros(nm1, dtype=np.int32), | ||
'nje': np.zeros(nm1, dtype=np.int32), | ||
'nqu': np.zeros(nm1, dtype=np.int32), | ||
'imxer': -1, | ||
'lenrw': 0, | ||
'leniw': 0, | ||
'mused': np.zeros(nm1, dtype=np.int32), | ||
} | ||
if nm1 == 0: | ||
info['message'] = 'Nothing was done; the integration time was 0.' | ||
else: | ||
info['message'] = 'Integration successful.' | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Isn't nothing done even in this case? "Integration successful." doesn't sound appropriate to me when there is nothing to integrate. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm preserving the invariants where |
||
|
||
return info |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is a
mused
value of zero documented? (I see only 1 is adams, 2 is bdf.)There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wanted to return an array with the expected shape and dtype for the given length of
t
, but I didn't think it was meaningful to use the values 1 or 2, since neither method was actually used.All these arrays of zeros are just placeholders put there for consistency. An alternative approach that is probably justifiable is to put the value
None
instead of an array. The arrays provide information about the behavior of the solver, and since a solver never ran in this edge case, maybe we shouldn't provide these arrays at all.