comparison liboctave/numeric/LSODE.cc @ 31249:de6fc38c78c6

Make Jacobian types offered by dlsode.f accessible by lsode (bug #31626). * liboctave/numeric/LSODE-opts.in: Add options "jacobian type", "lower jacobian subdiagonals", and "upper jacobian subdiagonals". * liboctave/numeric/LSODE.cc (file scope, lsode_j, LSODE::do_integrate (double)): Handle new configurable Jacobian types. * build-aux/mk-opts.pl: Don't implicitly convert to integer in condition.
author Olaf Till <olaf.till@uni-jena.de>
date Fri, 12 Nov 2010 08:53:05 +0100
parents 51a3d3a69193
children a40c0b7aa376
comparison
equal deleted inserted replaced
31248:8b75954a4670 31249:de6fc38c78c6
53 } 53 }
54 54
55 static ODEFunc::ODERHSFunc user_fcn; 55 static ODEFunc::ODERHSFunc user_fcn;
56 static ODEFunc::ODEJacFunc user_jac; 56 static ODEFunc::ODEJacFunc user_jac;
57 static ColumnVector *tmp_x; 57 static ColumnVector *tmp_x;
58 static bool user_jac_ignore_ml_mu;
58 59
59 static F77_INT 60 static F77_INT
60 lsode_f (const F77_INT& neq, const double& time, double *, double *deriv, 61 lsode_f (const F77_INT& neq, const double& time, double *, double *deriv,
61 F77_INT& ierr) 62 F77_INT& ierr)
62 { 63 {
78 79
79 return 0; 80 return 0;
80 } 81 }
81 82
82 static F77_INT 83 static F77_INT
83 lsode_j (const F77_INT& neq, const double& time, double *, const F77_INT&, 84 lsode_j (const F77_INT& neq, const double& time, double *,
84 const F77_INT&, double *pd, const F77_INT& nrowpd) 85 const F77_INT& ml, const F77_INT& mu,
86 double *pd, const F77_INT& nrowpd)
85 { 87 {
86 Matrix tmp_jac (neq, neq); 88 Matrix tmp_jac (neq, neq);
87 89
88 // NOTE: this won't work if LSODE passes copies of the state vector. 90 // NOTE: this won't work if LSODE passes copies of the state vector.
89 // In that case we have to create a temporary vector object 91 // In that case we have to create a temporary vector object
90 // and copy. 92 // and copy.
91 93
92 tmp_jac = (*user_jac) (*tmp_x, time); 94 tmp_jac = (*user_jac) (*tmp_x, time);
93 95
94 for (F77_INT j = 0; j < neq; j++) 96 if (user_jac_ignore_ml_mu)
95 for (F77_INT i = 0; i < neq; i++) 97 for (F77_INT j = 0; j < neq; j++)
96 pd[nrowpd * j + i] = tmp_jac (i, j); 98 for (F77_INT i = 0; i < neq; i++)
97 99 pd[nrowpd * j + i] = tmp_jac (i, j);
100 else
101 // upper left ends of subdiagonals in tmp_jac
102 for (F77_INT i = 0, j = mu; i <= ml; j == 0 ? i++ : j--)
103 // walk down the subdiagonal in tmp_jac
104 for (F77_INT k = i, l = j; k < neq && l < neq; k++, l++)
105 pd[nrowpd * l + k + mu - l] = tmp_jac (k, l);
106
98 return 0; 107 return 0;
99 } 108 }
100 109
101 ColumnVector 110 ColumnVector
102 LSODE::do_integrate (double tout) 111 LSODE::do_integrate (double tout)
118 127
119 nn = n; 128 nn = n;
120 129
121 octave_idx_type max_maxord = 0; 130 octave_idx_type max_maxord = 0;
122 131
132 user_jac_ignore_ml_mu = true;
133
134 m_iwork(0) = lower_jacobian_subdiagonals (); // 'ML' in dlsode.f
135
136 m_iwork(1) = upper_jacobian_subdiagonals (); // 'MU' in dlsode.f
137
123 if (integration_method () == "stiff") 138 if (integration_method () == "stiff")
124 { 139 {
125 max_maxord = 5; 140 max_maxord = 5;
126 141
127 if (m_jac) 142 if (m_jac)
128 m_method_flag = 21; 143 {
144 if (jacobian_type () == "banded")
145 {
146 m_method_flag = 24;
147 user_jac_ignore_ml_mu = false;
148 }
149 else
150 m_method_flag = 21;
151 }
129 else 152 else
130 m_method_flag = 22; 153 {
154 if (jacobian_type () == "full")
155 m_method_flag = 22;
156 else if (jacobian_type () == "banded")
157 m_method_flag = 25;
158 else if (jacobian_type () == "diagonal")
159 m_method_flag = 23;
160 else
161 {
162 // should be prevented by lsode_options
163 (*current_liboctave_error_handler)
164 ("lsode: internal error, wrong jacobian type");
165 m_integration_error = true;
166 return retval;
167 }
168 }
131 169
132 m_liw = 20 + n; 170 m_liw = 20 + n;
133 m_lrw = 22 + n * (9 + n); 171 m_lrw = 22 + n * (9 + n);
134 } 172 }
135 else 173 else