changeset 24008:6e7bb85e32b8

Allow ode15s and ode15i to work with row initial vectors (bug #50192). * check_default_input.m: Validate that inputs Y0 and YP0 are numeric vectors. Transform Y0 and YP0 to column vectors unconditionally. * ode15s.m, ode15i.m: Add BIST tests for initial row vector.
author Marco Caliari <marco.caliari@univr.it>
date Tue, 05 Sep 2017 11:45:43 -0700
parents e8a74d95b4f3
children eef8c31ffe97
files scripts/ode/ode15i.m scripts/ode/ode15s.m scripts/ode/private/check_default_input.m
diffstat 3 files changed, 45 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/scripts/ode/ode15i.m	Tue Sep 05 11:36:08 2017 -0700
+++ b/scripts/ode/ode15i.m	Tue Sep 05 11:45:43 2017 -0700
@@ -514,6 +514,19 @@
 %!                              [-1e-4; 1e-4; 0], opt);
 %! assert ([t(end), te', ie'], [10, 10, 10, 0, 1], [1, 0.2, 0.2, 0, 0]);
 
+## Initial solutions as row vectors
+%!testif HAVE_SUNDIALS
+%! A = eye (2);
+%! [tout, yout] = ode15i (@(t, y, yp) A * y - A * yp, ...
+%! [0, 1], [1, 1], [1, 1]);
+%! assert (size (yout), [20, 2])
+
+%!testif HAVE_SUNDIALS
+%! A = eye (2);
+%! [tout, yout] = ode15i (@(t, y, yp) A * y - A * yp, ...
+%! [0, 1], [1, 1], [1; 1]);
+%! assert (size (yout), [20, 2])
+
 ## Jacobian fun wrong dimension
 %!testif HAVE_SUNDIALS
 %! opt = odeset ("Jacobian", @jacwrong);
@@ -637,3 +650,13 @@
 %! opt = odeset ("AbsTol", [1, 1, 1]);
 %! fail ("[t, y] = ode15i (@fun, [0, 2], 2, 2, opt)",
 %!       "ode15i: invalid value assigned to field 'AbsTol'");
+
+%!testif HAVE_SUNDIALS
+%! A = zeros (2);
+%! fail ("ode15i (@(t, y, yp) A * y - A * yp, [0, 1], eye (2), [1, 1])",
+%!       "ode15i: Y0 must be a numeric vector");
+
+%!testif HAVE_SUNDIALS
+%! A = zeros (2);
+%! fail ("ode15i (@(t, y, yp) A * y - A * yp, [0, 1], [1, 1], eye (2))",
+%!       "ode15i: YP0 must be a numeric vector");
--- a/scripts/ode/ode15s.m	Tue Sep 05 11:36:08 2017 -0700
+++ b/scripts/ode/ode15s.m	Tue Sep 05 11:45:43 2017 -0700
@@ -728,3 +728,14 @@
 %!               "MStateDependence", "none");
 %! [t, y, te, ye, ie] = ode15s (@rob, [0, 100], [1; 0; 0], opt);
 %! assert ([t(end), te', ie'], [10, 10, 10, 0, 1], [1, 0.5, 0.5, 0, 0]);
+
+## Initial solution as row vector
+%!testif HAVE_SUNDIALS
+%! A = zeros (2);
+%! [tout, yout] = ode15s (@(t, y) A * y, [0, 1], [1, 1]);
+%! assert (yout, ones (18, 2))
+
+%!testif HAVE_SUNDIALS
+%! A = zeros (2);
+%! fail ("ode15s (@(t, y) A * y, [0, 1], eye (2))",
+%!       "ode15s: YP0 must be a numeric vector");
--- a/scripts/ode/private/check_default_input.m	Tue Sep 05 11:36:08 2017 -0700
+++ b/scripts/ode/private/check_default_input.m	Tue Sep 05 11:45:43 2017 -0700
@@ -51,9 +51,20 @@
 
   ## Check y0 and yp0
   y0 = varargin{1};
+  if (! isnumeric (y0) || ! isvector (y0))
+    error ("Octave:invalid-input-arg",
+           [solver ": Y0 must be a numeric vector"]);
+  endif
+  y0 = y0(:);
 
   if (nargin == 5)
     yp0 = varargin{2};
+    if (! isnumeric (yp0) || ! isvector (yp0))
+      error ("Octave:invalid-input-arg",
+             [solver ": YP0 must be a numeric vector"]);
+    endif
+    yp0 = yp0(:);
+
     n = numel (feval (fun, trange(1), y0, yp0));
     validateattributes (yp0, {"float"}, {"numel", n}, solver, "yp0");
   else