File: | /tmp/pyrefcon/scipy/scipy/integrate/_odepackmodule.c |
Warning: | line 830, column 9 PyObject ownership leak with reference count of 1 |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | ||||
2 | /* MULTIPACK module by Travis Oliphant | |||
3 | ||||
4 | Copyright (c) 2002 Travis Oliphant all rights reserved | |||
5 | oliphant.travis@ieee.org | |||
6 | Permission to use, modify, and distribute this software is given under the | |||
7 | terms of the SciPy (BSD style) license. See LICENSE.txt that came with | |||
8 | this distribution for specifics. | |||
9 | ||||
10 | NO WARRANTY IS EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. | |||
11 | */ | |||
12 | ||||
13 | ||||
14 | /* This extension module is a collection of wrapper functions around | |||
15 | common FORTRAN code in the package ODEPACK. | |||
16 | ||||
17 | The wrappers are meant to be nearly direct translations between the | |||
18 | FORTRAN code and Python. Some parameters like sizes do not need to be | |||
19 | passed since they are available from the objects. | |||
20 | ||||
21 | It is anticipated that a pure Python module be written to call these lower | |||
22 | level routines and make a simpler user interface. All of the routines define | |||
23 | default values for little-used parameters so that even the raw routines are | |||
24 | quite useful without a separate wrapper. | |||
25 | ||||
26 | FORTRAN Outputs that are not either an error indicator or the sought-after | |||
27 | results are placed in a dictionary and returned as an optional member of | |||
28 | the result tuple when the full_output argument is non-zero. | |||
29 | */ | |||
30 | ||||
31 | #include "Python.h" | |||
32 | ||||
33 | #include "numpy/arrayobject.h" | |||
34 | ||||
35 | #ifdef HAVE_BLAS_ILP64 | |||
36 | #define F_INTint npy_int64 | |||
37 | #define F_INT_NPYNPY_INT NPY_INT64NPY_LONG | |||
38 | #else | |||
39 | #define F_INTint int | |||
40 | #define F_INT_NPYNPY_INT NPY_INT | |||
41 | #endif | |||
42 | ||||
43 | ||||
44 | #define PYERR(errobj,message){ PyErr_SetString(errobj,message); goto fail; } {\ | |||
45 | PyErr_SetString(errobj,message); \ | |||
46 | goto fail; \ | |||
47 | } | |||
48 | #define PYERR2(errobj,message){ PyErr_Print(); PyErr_SetString(errobj, message); goto fail; } { \ | |||
49 | PyErr_Print(); \ | |||
50 | PyErr_SetString(errobj, message); \ | |||
51 | goto fail; \ | |||
52 | } | |||
53 | ||||
54 | typedef struct _odepack_globals { | |||
55 | PyObject *python_function; | |||
56 | PyObject *python_jacobian; | |||
57 | PyObject *extra_arguments; /* a tuple */ | |||
58 | int jac_transpose; | |||
59 | int jac_type; | |||
60 | int tfirst; | |||
61 | } odepack_params; | |||
62 | ||||
63 | static odepack_params global_params = {NULL((void*)0), NULL((void*)0), NULL((void*)0), 0, 0, 0}; | |||
64 | ||||
65 | static | |||
66 | PyObject *call_odeint_user_function(PyObject *func, npy_intp n, double *x, | |||
67 | double t, int tfirst, | |||
68 | PyObject *args, PyObject *error_obj) | |||
69 | { | |||
70 | /* | |||
71 | This function is the C wrapper of the user's Python functions that | |||
72 | define the differential equations (and also the Jacobian function). | |||
73 | The Fortran code calls ode_function() and ode_jacobian_function(), | |||
74 | and those functions call this function to call the Python functions | |||
75 | provided to odeint by the user. | |||
76 | ||||
77 | If an error occurs, NULL is returned. Otherwise, a NumPy array | |||
78 | is returned. | |||
79 | */ | |||
80 | ||||
81 | PyArrayObject *sequence = NULL((void*)0); | |||
82 | PyObject *tfloat = NULL((void*)0); | |||
83 | PyObject *firstargs = NULL((void*)0); | |||
84 | PyObject *arglist = NULL((void*)0); | |||
85 | PyObject *result = NULL((void*)0); | |||
86 | PyArrayObject *result_array = NULL((void*)0); | |||
87 | ||||
88 | /* Build sequence argument from inputs */ | |||
89 | sequence = (PyArrayObject *) PyArray_SimpleNewFromData(1, &n, NPY_DOUBLE,(*(PyObject * (*)(PyTypeObject *, int, npy_intp const *, int, npy_intp const *, void *, int, int, PyObject *)) PyArray_API [93])(&(*(PyTypeObject *)PyArray_API[2]), 1, &n, NPY_DOUBLE , ((void*)0), (char *) x, 0, (0x0001 | (0x0100 | 0x0400)), (( void*)0)) | |||
90 | (char *) x)(*(PyObject * (*)(PyTypeObject *, int, npy_intp const *, int, npy_intp const *, void *, int, int, PyObject *)) PyArray_API [93])(&(*(PyTypeObject *)PyArray_API[2]), 1, &n, NPY_DOUBLE , ((void*)0), (char *) x, 0, (0x0001 | (0x0100 | 0x0400)), (( void*)0)); | |||
91 | if (sequence == NULL((void*)0)) { | |||
92 | goto fail; | |||
93 | } | |||
94 | ||||
95 | tfloat = PyFloat_FromDouble(t); | |||
96 | if (tfloat == NULL((void*)0)) { | |||
97 | goto fail; | |||
98 | } | |||
99 | ||||
100 | /* firstargs is a tuple that will hold the first two arguments. */ | |||
101 | firstargs = PyTuple_New(2); | |||
102 | if (firstargs == NULL((void*)0)) { | |||
103 | goto fail; | |||
104 | } | |||
105 | ||||
106 | if (tfirst == 0) { | |||
107 | PyTuple_SET_ITEM(firstargs, 0, (PyObject *) sequence)PyTuple_SetItem(firstargs, 0, (PyObject *) sequence); | |||
108 | PyTuple_SET_ITEM(firstargs, 1, tfloat)PyTuple_SetItem(firstargs, 1, tfloat); | |||
109 | } else { | |||
110 | PyTuple_SET_ITEM(firstargs, 0, tfloat)PyTuple_SetItem(firstargs, 0, tfloat); | |||
111 | PyTuple_SET_ITEM(firstargs, 1, (PyObject *) sequence)PyTuple_SetItem(firstargs, 1, (PyObject *) sequence); | |||
112 | } | |||
113 | /* firstargs now owns the sequence and tfloat references. */ | |||
114 | sequence = NULL((void*)0); | |||
115 | tfloat = NULL((void*)0); | |||
116 | ||||
117 | arglist = PySequence_Concat(firstargs, args); | |||
118 | if (arglist == NULL((void*)0)) { | |||
119 | goto fail; | |||
120 | } | |||
121 | ||||
122 | /* Call the Python function. */ | |||
123 | result = PyObject_CallObject(func, arglist); | |||
124 | if (result == NULL((void*)0)) { | |||
125 | goto fail; | |||
126 | } | |||
127 | ||||
128 | result_array = (PyArrayObject *) | |||
129 | PyArray_ContiguousFromObject(result, NPY_DOUBLE, 0, 0)(*(PyObject * (*)(PyObject *, PyArray_Descr *, int, int, int, PyObject *)) PyArray_API[69])(result, (*(PyArray_Descr * (*) (int)) PyArray_API[45])(NPY_DOUBLE), 0, 0, ((0x0001 | (0x0100 | 0x0400))) | 0x0040, ((void*)0)); | |||
130 | ||||
131 | fail: | |||
132 | Py_XDECREF(sequence)_Py_XDECREF(((PyObject*)(sequence))); | |||
133 | Py_XDECREF(tfloat)_Py_XDECREF(((PyObject*)(tfloat))); | |||
134 | Py_XDECREF(firstargs)_Py_XDECREF(((PyObject*)(firstargs))); | |||
135 | Py_XDECREF(arglist)_Py_XDECREF(((PyObject*)(arglist))); | |||
136 | Py_XDECREF(result)_Py_XDECREF(((PyObject*)(result))); | |||
137 | return (PyObject *) result_array; | |||
138 | } | |||
139 | ||||
140 | ||||
141 | static PyObject *odepack_error; | |||
142 | ||||
143 | #if defined(UPPERCASE_FORTRAN) | |||
144 | #if defined(NO_APPEND_FORTRAN) | |||
145 | /* nothing to do here */ | |||
146 | #else | |||
147 | #define LSODAlsoda_ LSODA_ | |||
148 | #endif | |||
149 | #else | |||
150 | #if defined(NO_APPEND_FORTRAN) | |||
151 | #define LSODAlsoda_ lsoda | |||
152 | #else | |||
153 | #define LSODAlsoda_ lsoda_ | |||
154 | #endif | |||
155 | #endif | |||
156 | ||||
157 | typedef void lsoda_f_t(F_INTint *n, double *t, double *y, double *ydot); | |||
158 | typedef int lsoda_jac_t(F_INTint *n, double *t, double *y, F_INTint *ml, F_INTint *mu, | |||
159 | double *pd, F_INTint *nrowpd); | |||
160 | ||||
161 | void LSODAlsoda_(lsoda_f_t *f, F_INTint *neq, double *y, double *t, double *tout, F_INTint *itol, | |||
162 | double *rtol, double *atol, F_INTint *itask, F_INTint *istate, F_INTint *iopt, | |||
163 | double *rwork, F_INTint *lrw, F_INTint *iwork, F_INTint *liw, lsoda_jac_t *jac, | |||
164 | F_INTint *jt); | |||
165 | ||||
166 | /* | |||
167 | void ode_function(int *n, double *t, double *y, double *ydot) | |||
168 | { | |||
169 | ydot[0] = -0.04*y[0] + 1e4*y[1]*y[2]; | |||
170 | ydot[2] = 3e7*y[1]*y[1]; | |||
171 | ydot[1] = -ydot[0] - ydot[2]; | |||
172 | return; | |||
173 | } | |||
174 | */ | |||
175 | ||||
176 | void | |||
177 | ode_function(F_INTint *n, double *t, double *y, double *ydot) | |||
178 | { | |||
179 | /* | |||
180 | This is the function called from the Fortran code. It should | |||
181 | -- use call_odeint_user_function to get a multiarrayobject result | |||
182 | -- check for errors and set *n to -1 if any | |||
183 | -- otherwise place result of calculation in ydot | |||
184 | */ | |||
185 | ||||
186 | PyArrayObject *result_array = NULL((void*)0); | |||
187 | ||||
188 | result_array = (PyArrayObject *) | |||
189 | call_odeint_user_function(global_params.python_function, | |||
190 | *n, y, *t, global_params.tfirst, | |||
191 | global_params.extra_arguments, | |||
192 | odepack_error); | |||
193 | if (result_array == NULL((void*)0)) { | |||
194 | *n = -1; | |||
195 | return; | |||
196 | } | |||
197 | ||||
198 | if (PyArray_NDIM(result_array) > 1) { | |||
199 | *n = -1; | |||
200 | PyErr_Format(PyExc_RuntimeError, | |||
201 | "The array return by func must be one-dimensional, but got ndim=%d.", | |||
202 | PyArray_NDIM(result_array)); | |||
203 | Py_DECREF(result_array)_Py_DECREF(((PyObject*)(result_array))); | |||
204 | return; | |||
205 | } | |||
206 | ||||
207 | if (PyArray_Size(*(npy_intp (*)(PyObject *)) PyArray_API[59])((PyObject *)result_array) != *n) { | |||
208 | PyErr_Format(PyExc_RuntimeError, | |||
209 | "The size of the array returned by func (%ld) does not match " | |||
210 | "the size of y0 (%d).", | |||
211 | PyArray_Size(*(npy_intp (*)(PyObject *)) PyArray_API[59])((PyObject *)result_array), *n); | |||
212 | *n = -1; | |||
213 | Py_DECREF(result_array)_Py_DECREF(((PyObject*)(result_array))); | |||
214 | return; | |||
215 | } | |||
216 | ||||
217 | memcpy(ydot, PyArray_DATA(result_array), (*n)*sizeof(double)); | |||
218 | Py_DECREF(result_array)_Py_DECREF(((PyObject*)(result_array))); | |||
219 | return; | |||
220 | } | |||
221 | ||||
222 | ||||
223 | /* | |||
224 | * Copy a contiguous matrix at `c` to a Fortran-ordered matrix at `f`. | |||
225 | * `ldf` is the leading dimension of the Fortran array at `f`. | |||
226 | * `nrows` and `ncols` are the number of rows and columns of the matrix, resp. | |||
227 | * If `transposed` is 0, c[i, j] is *(c + ncols*i + j). | |||
228 | * If `transposed` is nonzero, c[i, j] is *(c + i + nrows*j) (i.e. `c` is | |||
229 | * stored in F-contiguous order). | |||
230 | */ | |||
231 | ||||
232 | static void | |||
233 | copy_array_to_fortran(double *f, F_INTint ldf, F_INTint nrows, F_INTint ncols, | |||
234 | double *c, F_INTint transposed) | |||
235 | { | |||
236 | F_INTint i, j; | |||
237 | F_INTint row_stride, col_stride; | |||
238 | ||||
239 | /* The strides count multiples of sizeof(double), not bytes. */ | |||
240 | if (transposed) { | |||
241 | row_stride = 1; | |||
242 | col_stride = nrows; | |||
243 | } | |||
244 | else { | |||
245 | row_stride = ncols; | |||
246 | col_stride = 1; | |||
247 | } | |||
248 | for (i = 0; i < nrows; ++i) { | |||
249 | for (j = 0; j < ncols; ++j) { | |||
250 | double value; | |||
251 | /* value = c[i,j] */ | |||
252 | value = *(c + row_stride*i + col_stride*j); | |||
253 | /* f[i,j] = value */ | |||
254 | *(f + ldf*j + i) = value; | |||
255 | } | |||
256 | } | |||
257 | } | |||
258 | ||||
259 | ||||
260 | int | |||
261 | ode_jacobian_function(F_INTint *n, double *t, double *y, F_INTint *ml, F_INTint *mu, | |||
262 | double *pd, F_INTint *nrowpd) | |||
263 | { | |||
264 | /* | |||
265 | This is the function called from the Fortran code. It should | |||
266 | -- use call_odeint_user_function to get a multiarrayobject result | |||
267 | -- check for errors and return -1 if any (though this is ignored | |||
268 | by calling program). | |||
269 | -- otherwise place result of calculation in pd | |||
270 | */ | |||
271 | ||||
272 | PyArrayObject *result_array; | |||
273 | npy_intp ndim, nrows, ncols, dim_error; | |||
274 | npy_intp *dims; | |||
275 | ||||
276 | result_array = (PyArrayObject *) | |||
277 | call_odeint_user_function(global_params.python_jacobian, | |||
278 | *n, y, *t, global_params.tfirst, | |||
279 | global_params.extra_arguments, | |||
280 | odepack_error); | |||
281 | if (result_array == NULL((void*)0)) { | |||
282 | *n = -1; | |||
283 | return -1; | |||
284 | } | |||
285 | ||||
286 | ncols = *n; | |||
287 | if (global_params.jac_type == 4) { | |||
288 | nrows = *ml + *mu + 1; | |||
289 | } | |||
290 | else { | |||
291 | nrows = *n; | |||
292 | } | |||
293 | ||||
294 | if (!global_params.jac_transpose) { | |||
295 | npy_intp tmp; | |||
296 | tmp = nrows; | |||
297 | nrows = ncols; | |||
298 | ncols = tmp; | |||
299 | } | |||
300 | ||||
301 | ndim = PyArray_NDIM(result_array); | |||
302 | if (ndim > 2) { | |||
303 | PyErr_Format(PyExc_RuntimeError, | |||
304 | "The Jacobian array must be two dimensional, but got ndim=%d.", | |||
305 | ndim); | |||
306 | *n = -1; | |||
307 | Py_DECREF(result_array)_Py_DECREF(((PyObject*)(result_array))); | |||
308 | return -1; | |||
309 | } | |||
310 | ||||
311 | dims = PyArray_DIMS(result_array); | |||
312 | dim_error = 0; | |||
313 | if (ndim == 0) { | |||
314 | if ((nrows != 1) || (ncols != 1)) { | |||
315 | dim_error = 1; | |||
316 | } | |||
317 | } | |||
318 | if (ndim == 1) { | |||
319 | if ((nrows != 1) || (dims[0] != ncols)) { | |||
320 | dim_error = 1; | |||
321 | } | |||
322 | } | |||
323 | if (ndim == 2) { | |||
324 | if ((dims[0] != nrows) || (dims[1] != ncols)) { | |||
325 | dim_error = 1; | |||
326 | } | |||
327 | } | |||
328 | if (dim_error) { | |||
329 | char *b = ""; | |||
330 | if (global_params.jac_type == 4) { | |||
331 | b = "banded "; | |||
332 | } | |||
333 | PyErr_Format(PyExc_RuntimeError, | |||
334 | "Expected a %sJacobian array with shape (%d, %d)", | |||
335 | b, nrows, ncols); | |||
336 | *n = -1; | |||
337 | Py_DECREF(result_array)_Py_DECREF(((PyObject*)(result_array))); | |||
338 | return -1; | |||
339 | } | |||
340 | ||||
341 | /* | |||
342 | * global_params.jac_type is either 1 (full Jacobian) or 4 (banded Jacobian). | |||
343 | * global_params.jac_transpose is !col_deriv, so if global_params.jac_transpose | |||
344 | * is 0, the array created by the user is already in Fortran order, and | |||
345 | * a transpose is not needed when it is copied to pd. | |||
346 | */ | |||
347 | ||||
348 | if ((global_params.jac_type == 1) && !global_params.jac_transpose) { | |||
349 | /* Full Jacobian, no transpose needed, so we can use memcpy. */ | |||
350 | memcpy(pd, PyArray_DATA(result_array), (*n)*(*nrowpd)*sizeof(double)); | |||
351 | } | |||
352 | else { | |||
353 | /* | |||
354 | * global_params.jac_type == 4 (banded Jacobian), or | |||
355 | * global_params.jac_type == 1 and global_params.jac_transpose == 1. | |||
356 | * | |||
357 | * We can't use memcpy when global_params.jac_type is 4 because the leading | |||
358 | * dimension of pd doesn't necessarily equal the number of rows of the | |||
359 | * matrix. | |||
360 | */ | |||
361 | npy_intp m; /* Number of rows in the (full or packed banded) Jacobian. */ | |||
362 | if (global_params.jac_type == 4) { | |||
363 | m = *ml + *mu + 1; | |||
364 | } | |||
365 | else { | |||
366 | m = *n; | |||
367 | } | |||
368 | copy_array_to_fortran(pd, *nrowpd, m, *n, | |||
369 | (double *) PyArray_DATA(result_array), | |||
370 | !global_params.jac_transpose); | |||
371 | } | |||
372 | ||||
373 | Py_DECREF(result_array)_Py_DECREF(((PyObject*)(result_array))); | |||
374 | return 0; | |||
375 | } | |||
376 | ||||
377 | ||||
378 | int | |||
379 | setup_extra_inputs(PyArrayObject **ap_rtol, PyObject *o_rtol, | |||
380 | PyArrayObject **ap_atol, PyObject *o_atol, | |||
381 | PyArrayObject **ap_tcrit, PyObject *o_tcrit, | |||
382 | long *numcrit, int neq) | |||
383 | { | |||
384 | int itol = 0; | |||
385 | double tol = 1.49012e-8; | |||
386 | npy_intp one = 1; | |||
387 | ||||
388 | /* Setup tolerances */ | |||
389 | if (o_rtol == NULL((void*)0)) { | |||
390 | *ap_rtol = (PyArrayObject *) PyArray_SimpleNew(1, &one, NPY_DOUBLE)(*(PyObject * (*)(PyTypeObject *, int, npy_intp const *, int, npy_intp const *, void *, int, int, PyObject *)) PyArray_API [93])(&(*(PyTypeObject *)PyArray_API[2]), 1, &one, NPY_DOUBLE , ((void*)0), ((void*)0), 0, 0, ((void*)0)); | |||
391 | if (*ap_rtol == NULL((void*)0)) { | |||
392 | PYERR2(odepack_error,"Error constructing relative tolerance."){ PyErr_Print(); PyErr_SetString(odepack_error, "Error constructing relative tolerance." ); goto fail; }; | |||
393 | } | |||
394 | *(double *) PyArray_DATA(*ap_rtol) = tol; /* Default */ | |||
395 | } | |||
396 | else { | |||
397 | *ap_rtol = (PyArrayObject *) PyArray_ContiguousFromObject(o_rtol,(*(PyObject * (*)(PyObject *, PyArray_Descr *, int, int, int, PyObject *)) PyArray_API[69])(o_rtol, (*(PyArray_Descr * (*) (int)) PyArray_API[45])(NPY_DOUBLE), 0, 1, ((0x0001 | (0x0100 | 0x0400))) | 0x0040, ((void*)0)) | |||
398 | NPY_DOUBLE, 0, 1)(*(PyObject * (*)(PyObject *, PyArray_Descr *, int, int, int, PyObject *)) PyArray_API[69])(o_rtol, (*(PyArray_Descr * (*) (int)) PyArray_API[45])(NPY_DOUBLE), 0, 1, ((0x0001 | (0x0100 | 0x0400))) | 0x0040, ((void*)0)); | |||
399 | if (*ap_rtol == NULL((void*)0)) { | |||
400 | PYERR2(odepack_error,"Error converting relative tolerance."){ PyErr_Print(); PyErr_SetString(odepack_error, "Error converting relative tolerance." ); goto fail; }; | |||
401 | } | |||
402 | /* XXX Fix the following. */ | |||
403 | if (PyArray_NDIM(*ap_rtol) == 0); /* rtol is scalar */ | |||
404 | else if (PyArray_DIMS(*ap_rtol)[0] == neq) { | |||
405 | itol |= 2; /* Set rtol array flag */ | |||
406 | } | |||
407 | else { | |||
408 | PYERR(odepack_error, "Tolerances must be an array of the same length as the\n number of equations or a scalar."){ PyErr_SetString(odepack_error,"Tolerances must be an array of the same length as the\n number of equations or a scalar." ); goto fail; }; | |||
409 | } | |||
410 | } | |||
411 | ||||
412 | if (o_atol == NULL((void*)0)) { | |||
413 | *ap_atol = (PyArrayObject *) PyArray_SimpleNew(1, &one, NPY_DOUBLE)(*(PyObject * (*)(PyTypeObject *, int, npy_intp const *, int, npy_intp const *, void *, int, int, PyObject *)) PyArray_API [93])(&(*(PyTypeObject *)PyArray_API[2]), 1, &one, NPY_DOUBLE , ((void*)0), ((void*)0), 0, 0, ((void*)0)); | |||
414 | if (*ap_atol == NULL((void*)0)) { | |||
415 | PYERR2(odepack_error,"Error constructing absolute tolerance"){ PyErr_Print(); PyErr_SetString(odepack_error, "Error constructing absolute tolerance" ); goto fail; }; | |||
416 | } | |||
417 | *(double *)PyArray_DATA(*ap_atol) = tol; | |||
418 | } | |||
419 | else { | |||
420 | *ap_atol = (PyArrayObject *) PyArray_ContiguousFromObject(o_atol, NPY_DOUBLE, 0, 1)(*(PyObject * (*)(PyObject *, PyArray_Descr *, int, int, int, PyObject *)) PyArray_API[69])(o_atol, (*(PyArray_Descr * (*) (int)) PyArray_API[45])(NPY_DOUBLE), 0, 1, ((0x0001 | (0x0100 | 0x0400))) | 0x0040, ((void*)0)); | |||
421 | if (*ap_atol == NULL((void*)0)) { | |||
422 | PYERR2(odepack_error,"Error converting absolute tolerance."){ PyErr_Print(); PyErr_SetString(odepack_error, "Error converting absolute tolerance." ); goto fail; }; | |||
423 | } | |||
424 | /* XXX Fix the following. */ | |||
425 | if (PyArray_NDIM(*ap_atol) == 0); /* atol is scalar */ | |||
426 | else if (PyArray_DIMS(*ap_atol)[0] == neq) { | |||
427 | itol |= 1; /* Set atol array flag */ | |||
428 | } | |||
429 | else { | |||
430 | PYERR(odepack_error,"Tolerances must be an array of the same length as the\n number of equations or a scalar."){ PyErr_SetString(odepack_error,"Tolerances must be an array of the same length as the\n number of equations or a scalar." ); goto fail; }; | |||
431 | } | |||
432 | } | |||
433 | itol++; /* increment to get correct value */ | |||
434 | ||||
435 | /* Setup t-critical */ | |||
436 | if (o_tcrit != NULL((void*)0)) { | |||
437 | *ap_tcrit = (PyArrayObject *) PyArray_ContiguousFromObject(o_tcrit, NPY_DOUBLE, 0, 1)(*(PyObject * (*)(PyObject *, PyArray_Descr *, int, int, int, PyObject *)) PyArray_API[69])(o_tcrit, (*(PyArray_Descr * (* )(int)) PyArray_API[45])(NPY_DOUBLE), 0, 1, ((0x0001 | (0x0100 | 0x0400))) | 0x0040, ((void*)0)); | |||
438 | if (*ap_tcrit == NULL((void*)0)) { | |||
439 | PYERR2(odepack_error,"Error constructing critical times."){ PyErr_Print(); PyErr_SetString(odepack_error, "Error constructing critical times." ); goto fail; }; | |||
440 | } | |||
441 | *numcrit = PyArray_Size(*(npy_intp (*)(PyObject *)) PyArray_API[59])((PyObject *) (*ap_tcrit)); | |||
442 | } | |||
443 | return itol; | |||
444 | ||||
445 | fail: /* Needed for use of PYERR */ | |||
446 | return -1; | |||
447 | } | |||
448 | ||||
449 | ||||
450 | int | |||
451 | compute_lrw_liw(F_INTint *lrw, F_INTint *liw, F_INTint neq, F_INTint jt, F_INTint ml, F_INTint mu, | |||
452 | F_INTint mxordn, F_INTint mxords) | |||
453 | { | |||
454 | F_INTint lrn, lrs, nyh, lmat; | |||
455 | ||||
456 | if (jt == 1 || jt == 2) { | |||
457 | lmat = neq*neq + 2; | |||
458 | } | |||
459 | else if (jt == 4 || jt == 5) { | |||
460 | lmat = (2*ml + mu + 1)*neq + 2; | |||
461 | } | |||
462 | else { | |||
463 | PYERR(odepack_error,"Incorrect value for jt."){ PyErr_SetString(odepack_error,"Incorrect value for jt."); goto fail; }; | |||
464 | } | |||
465 | ||||
466 | if (mxordn < 0) { | |||
467 | PYERR(odepack_error,"Incorrect value for mxordn."){ PyErr_SetString(odepack_error,"Incorrect value for mxordn." ); goto fail; }; | |||
468 | } | |||
469 | if (mxords < 0) { | |||
470 | PYERR(odepack_error,"Incorrect value for mxords."){ PyErr_SetString(odepack_error,"Incorrect value for mxords." ); goto fail; }; | |||
471 | } | |||
472 | nyh = neq; | |||
473 | ||||
474 | lrn = 20 + nyh*(mxordn+1) + 3*neq; | |||
475 | lrs = 20 + nyh*(mxords+1) + 3*neq + lmat; | |||
476 | ||||
477 | *lrw = PyArray_MAX(lrn,lrs)(((lrn)>(lrs))?(lrn):(lrs)); | |||
478 | *liw = 20 + neq; | |||
479 | return 0; | |||
480 | ||||
481 | fail: | |||
482 | return -1; | |||
483 | } | |||
484 | ||||
485 | static char doc_odeint[] = | |||
486 | "[y,{infodict,}istate] = odeint(fun, y0, t, args=(), Dfun=None, " | |||
487 | "col_deriv=0, ml=, mu=, full_output=0, rtol=, atol=, tcrit=, h0=0.0, " | |||
488 | "hmax=0.0, hmin=0.0, ixpr=0.0, mxstep=0.0, mxhnil=0, mxordn=0, " | |||
489 | "mxords=0)\n yprime = fun(y,t,...)"; | |||
490 | ||||
491 | ||||
492 | static PyObject * | |||
493 | odepack_odeint(PyObject *dummy, PyObject *args, PyObject *kwdict) | |||
494 | { | |||
495 | PyObject *fcn, *y0, *p_tout, *o_rtol = NULL((void*)0), *o_atol = NULL((void*)0); | |||
496 | PyArrayObject *ap_y = NULL((void*)0), *ap_yout = NULL((void*)0); | |||
497 | PyArrayObject *ap_rtol = NULL((void*)0), *ap_atol = NULL((void*)0); | |||
498 | PyArrayObject *ap_tout = NULL((void*)0); | |||
499 | PyObject *extra_args = NULL((void*)0); | |||
500 | PyObject *Dfun = Py_None(&_Py_NoneStruct); | |||
501 | F_INTint neq, itol = 1, itask = 1, istate = 1, iopt = 0, lrw, *iwork, liw, jt = 4; | |||
502 | double *y, t, *tout, *rtol, *atol, *rwork; | |||
503 | double h0 = 0.0, hmax = 0.0, hmin = 0.0; | |||
504 | long ixpr = 0, mxstep = 0, mxhnil = 0, mxordn = 12, mxords = 5, ml = -1, mu = -1; | |||
505 | long tfirst; | |||
506 | PyObject *o_tcrit = NULL((void*)0); | |||
507 | PyArrayObject *ap_tcrit = NULL((void*)0); | |||
508 | PyArrayObject *ap_hu = NULL((void*)0), *ap_tcur = NULL((void*)0), *ap_tolsf = NULL((void*)0), *ap_tsw = NULL((void*)0); | |||
509 | PyArrayObject *ap_nst = NULL((void*)0), *ap_nfe = NULL((void*)0), *ap_nje = NULL((void*)0), *ap_nqu = NULL((void*)0); | |||
510 | PyArrayObject *ap_mused = NULL((void*)0); | |||
511 | long imxer = 0, lenrw = 0, leniw = 0, col_deriv = 0; | |||
512 | npy_intp out_sz = 0, dims[2]; | |||
513 | long k, ntimes, crit_ind = 0; | |||
514 | long allocated = 0, full_output = 0, numcrit = 0; | |||
515 | long t0count; | |||
516 | double *yout, *yout_ptr, *tout_ptr, *tcrit = NULL((void*)0); | |||
517 | double *wa; | |||
518 | static char *kwlist[] = {"fun", "y0", "t", "args", "Dfun", "col_deriv", | |||
519 | "ml", "mu", "full_output", "rtol", "atol", "tcrit", | |||
520 | "h0", "hmax", "hmin", "ixpr", "mxstep", "mxhnil", | |||
521 | "mxordn", "mxords", "tfirst", NULL((void*)0)}; | |||
522 | odepack_params save_params; | |||
523 | ||||
524 | if (!PyArg_ParseTupleAndKeywords(args, kwdict, "OOO|OOllllOOOdddllllll", kwlist, | |||
525 | &fcn, &y0, &p_tout, &extra_args, &Dfun, | |||
526 | &col_deriv, &ml, &mu, &full_output, &o_rtol, &o_atol, | |||
527 | &o_tcrit, &h0, &hmax, &hmin, &ixpr, &mxstep, &mxhnil, | |||
528 | &mxordn, &mxords, &tfirst)) { | |||
529 | return NULL((void*)0); | |||
530 | } | |||
531 | ||||
532 | if (o_tcrit == Py_None(&_Py_NoneStruct)) { | |||
533 | o_tcrit = NULL((void*)0); | |||
534 | } | |||
535 | if (o_rtol == Py_None(&_Py_NoneStruct)) { | |||
536 | o_rtol = NULL((void*)0); | |||
537 | } | |||
538 | if (o_atol == Py_None(&_Py_NoneStruct)) { | |||
539 | o_atol = NULL((void*)0); | |||
540 | } | |||
541 | ||||
542 | /* Set up jt, ml, and mu */ | |||
543 | if (Dfun == Py_None(&_Py_NoneStruct)) { | |||
544 | /* set jt for internally generated */ | |||
545 | jt++; | |||
546 | } | |||
547 | if (ml < 0 && mu < 0) { | |||
548 | /* neither ml nor mu given, mark jt for full jacobian */ | |||
549 | jt -= 3; | |||
550 | } | |||
551 | if (ml < 0) { | |||
552 | /* if one but not both are given */ | |||
553 | ml = 0; | |||
554 | } | |||
555 | if (mu < 0) { | |||
556 | mu = 0; | |||
557 | } | |||
558 | ||||
559 | /* Stash the current global_params in save_params. */ | |||
560 | memcpy(&save_params, &global_params, sizeof(save_params)); | |||
561 | ||||
562 | if (extra_args == NULL((void*)0)) { | |||
563 | if ((extra_args = PyTuple_New(0)) == NULL((void*)0)) { | |||
564 | goto fail; | |||
565 | } | |||
566 | } | |||
567 | else { | |||
568 | Py_INCREF(extra_args)_Py_INCREF(((PyObject*)(extra_args))); /* We decrement on exit. */ | |||
569 | } | |||
570 | if (!PyTuple_Check(extra_args)((((((PyObject*)(extra_args))->ob_type))->tp_flags & ((1UL << 26))) != 0)) { | |||
571 | PYERR(odepack_error, "Extra arguments must be in a tuple."){ PyErr_SetString(odepack_error,"Extra arguments must be in a tuple." ); goto fail; }; | |||
572 | } | |||
573 | if (!PyCallable_Check(fcn) || (Dfun != Py_None(&_Py_NoneStruct) && !PyCallable_Check(Dfun))) { | |||
574 | PYERR(odepack_error, "The function and its Jacobian must be callable functions."){ PyErr_SetString(odepack_error,"The function and its Jacobian must be callable functions." ); goto fail; }; | |||
575 | } | |||
576 | ||||
577 | /* Set global_params from the function arguments. */ | |||
578 | global_params.python_function = fcn; | |||
579 | global_params.extra_arguments = extra_args; | |||
580 | global_params.python_jacobian = Dfun; | |||
581 | global_params.jac_transpose = !(col_deriv); | |||
582 | global_params.jac_type = jt; | |||
583 | global_params.tfirst = tfirst; | |||
584 | ||||
585 | /* Initial input vector */ | |||
586 | ap_y = (PyArrayObject *) PyArray_ContiguousFromObject(y0, NPY_DOUBLE, 0, 0)(*(PyObject * (*)(PyObject *, PyArray_Descr *, int, int, int, PyObject *)) PyArray_API[69])(y0, (*(PyArray_Descr * (*)(int )) PyArray_API[45])(NPY_DOUBLE), 0, 0, ((0x0001 | (0x0100 | 0x0400 ))) | 0x0040, ((void*)0)); | |||
587 | if (ap_y == NULL((void*)0)) { | |||
588 | goto fail; | |||
589 | } | |||
590 | if (PyArray_NDIM(ap_y) > 1) { | |||
591 | PyErr_SetString(PyExc_ValueError, "Initial condition y0 must be one-dimensional."); | |||
592 | goto fail; | |||
593 | } | |||
594 | y = (double *) PyArray_DATA(ap_y); | |||
595 | neq = PyArray_Size(*(npy_intp (*)(PyObject *)) PyArray_API[59])((PyObject *) ap_y); | |||
596 | dims[1] = neq; | |||
597 | ||||
598 | /* Set of output times for integration */ | |||
599 | ap_tout = (PyArrayObject *) PyArray_ContiguousFromObject(p_tout, NPY_DOUBLE, 0, 0)(*(PyObject * (*)(PyObject *, PyArray_Descr *, int, int, int, PyObject *)) PyArray_API[69])(p_tout, (*(PyArray_Descr * (*) (int)) PyArray_API[45])(NPY_DOUBLE), 0, 0, ((0x0001 | (0x0100 | 0x0400))) | 0x0040, ((void*)0)); | |||
600 | if (ap_tout == NULL((void*)0)) { | |||
601 | goto fail; | |||
602 | } | |||
603 | if (PyArray_NDIM(ap_tout) > 1) { | |||
604 | PyErr_SetString(PyExc_ValueError, "Output times t must be one-dimensional."); | |||
605 | goto fail; | |||
606 | } | |||
607 | tout = (double *) PyArray_DATA(ap_tout); | |||
608 | ntimes = PyArray_Size(*(npy_intp (*)(PyObject *)) PyArray_API[59])((PyObject *)ap_tout); | |||
609 | dims[0] = ntimes; | |||
610 | ||||
611 | t0count = 0; | |||
612 | if (ntimes > 0) { | |||
613 | /* Copy tout[0] to t, and count how many times it occurs. */ | |||
614 | t = tout[0]; | |||
615 | t0count = 1; | |||
616 | while ((t0count < ntimes) && (tout[t0count] == t)) { | |||
617 | ++t0count; | |||
618 | } | |||
619 | } | |||
620 | ||||
621 | /* Set up array to hold the output evaluations*/ | |||
622 | ap_yout= (PyArrayObject *) PyArray_SimpleNew(2,dims,NPY_DOUBLE)(*(PyObject * (*)(PyTypeObject *, int, npy_intp const *, int, npy_intp const *, void *, int, int, PyObject *)) PyArray_API [93])(&(*(PyTypeObject *)PyArray_API[2]), 2, dims, NPY_DOUBLE , ((void*)0), ((void*)0), 0, 0, ((void*)0)); | |||
623 | if (ap_yout== NULL((void*)0)) { | |||
624 | goto fail; | |||
625 | } | |||
626 | yout = (double *) PyArray_DATA(ap_yout); | |||
627 | ||||
628 | /* Copy initial vector into first row(s) of output */ | |||
629 | yout_ptr = yout; | |||
630 | for (k = 0; k < t0count; ++k) { | |||
631 | memcpy(yout_ptr, y, neq*sizeof(double)); | |||
632 | yout_ptr += neq; | |||
633 | } | |||
634 | ||||
635 | itol = setup_extra_inputs(&ap_rtol, o_rtol, &ap_atol, o_atol, &ap_tcrit, | |||
636 | o_tcrit, &numcrit, neq); | |||
637 | if (itol < 0 ) { | |||
638 | goto fail; /* Something didn't work */ | |||
639 | } | |||
640 | rtol = (double *) PyArray_DATA(ap_rtol); | |||
641 | atol = (double *) PyArray_DATA(ap_atol); | |||
642 | ||||
643 | /* Find size of working arrays*/ | |||
644 | if (compute_lrw_liw(&lrw, &liw, neq, jt, ml, mu, mxordn, mxords) < 0) { | |||
645 | goto fail; | |||
646 | } | |||
647 | ||||
648 | if ((wa = (double *)malloc(lrw*sizeof(double) + liw*sizeof(F_INTint)))==NULL((void*)0)) { | |||
649 | PyErr_NoMemory(); | |||
650 | goto fail; | |||
651 | } | |||
652 | allocated = 1; | |||
653 | rwork = wa; | |||
654 | iwork = (F_INTint *)(wa + lrw); | |||
655 | ||||
656 | iwork[0] = ml; | |||
657 | iwork[1] = mu; | |||
658 | ||||
659 | if (h0 != 0.0 || hmax != 0.0 || hmin != 0.0 || ixpr != 0 || mxstep != 0 || | |||
660 | mxhnil != 0 || mxordn != 0 || mxords != 0) { | |||
661 | rwork[4] = h0; | |||
662 | rwork[5] = hmax; | |||
663 | rwork[6] = hmin; | |||
664 | iwork[4] = ixpr; | |||
665 | iwork[5] = mxstep; | |||
666 | iwork[6] = mxhnil; | |||
667 | iwork[7] = mxordn; | |||
668 | iwork[8] = mxords; | |||
669 | iopt = 1; | |||
670 | } | |||
671 | istate = 1; | |||
672 | k = t0count; | |||
673 | ||||
674 | /* If full output make some useful output arrays */ | |||
675 | if (full_output) { | |||
676 | out_sz = ntimes-1; | |||
677 | ap_hu = (PyArrayObject *) PyArray_SimpleNew(1, &out_sz, NPY_DOUBLE)(*(PyObject * (*)(PyTypeObject *, int, npy_intp const *, int, npy_intp const *, void *, int, int, PyObject *)) PyArray_API [93])(&(*(PyTypeObject *)PyArray_API[2]), 1, &out_sz, NPY_DOUBLE, ((void*)0), ((void*)0), 0, 0, ((void*)0)); | |||
678 | ap_tcur = (PyArrayObject *) PyArray_SimpleNew(1, &out_sz, NPY_DOUBLE)(*(PyObject * (*)(PyTypeObject *, int, npy_intp const *, int, npy_intp const *, void *, int, int, PyObject *)) PyArray_API [93])(&(*(PyTypeObject *)PyArray_API[2]), 1, &out_sz, NPY_DOUBLE, ((void*)0), ((void*)0), 0, 0, ((void*)0)); | |||
679 | ap_tolsf = (PyArrayObject *) PyArray_SimpleNew(1, &out_sz, NPY_DOUBLE)(*(PyObject * (*)(PyTypeObject *, int, npy_intp const *, int, npy_intp const *, void *, int, int, PyObject *)) PyArray_API [93])(&(*(PyTypeObject *)PyArray_API[2]), 1, &out_sz, NPY_DOUBLE, ((void*)0), ((void*)0), 0, 0, ((void*)0)); | |||
680 | ap_tsw = (PyArrayObject *) PyArray_SimpleNew(1, &out_sz, NPY_DOUBLE)(*(PyObject * (*)(PyTypeObject *, int, npy_intp const *, int, npy_intp const *, void *, int, int, PyObject *)) PyArray_API [93])(&(*(PyTypeObject *)PyArray_API[2]), 1, &out_sz, NPY_DOUBLE, ((void*)0), ((void*)0), 0, 0, ((void*)0)); | |||
681 | ap_nst = (PyArrayObject *) PyArray_SimpleNew(1, &out_sz, F_INT_NPY)(*(PyObject * (*)(PyTypeObject *, int, npy_intp const *, int, npy_intp const *, void *, int, int, PyObject *)) PyArray_API [93])(&(*(PyTypeObject *)PyArray_API[2]), 1, &out_sz, NPY_INT, ((void*)0), ((void*)0), 0, 0, ((void*)0)); | |||
682 | ap_nfe = (PyArrayObject *) PyArray_SimpleNew(1, &out_sz, F_INT_NPY)(*(PyObject * (*)(PyTypeObject *, int, npy_intp const *, int, npy_intp const *, void *, int, int, PyObject *)) PyArray_API [93])(&(*(PyTypeObject *)PyArray_API[2]), 1, &out_sz, NPY_INT, ((void*)0), ((void*)0), 0, 0, ((void*)0)); | |||
683 | ap_nje = (PyArrayObject *) PyArray_SimpleNew(1, &out_sz, F_INT_NPY)(*(PyObject * (*)(PyTypeObject *, int, npy_intp const *, int, npy_intp const *, void *, int, int, PyObject *)) PyArray_API [93])(&(*(PyTypeObject *)PyArray_API[2]), 1, &out_sz, NPY_INT, ((void*)0), ((void*)0), 0, 0, ((void*)0)); | |||
684 | ap_nqu = (PyArrayObject *) PyArray_SimpleNew(1, &out_sz, F_INT_NPY)(*(PyObject * (*)(PyTypeObject *, int, npy_intp const *, int, npy_intp const *, void *, int, int, PyObject *)) PyArray_API [93])(&(*(PyTypeObject *)PyArray_API[2]), 1, &out_sz, NPY_INT, ((void*)0), ((void*)0), 0, 0, ((void*)0)); | |||
685 | ap_mused = (PyArrayObject *) PyArray_SimpleNew(1, &out_sz, F_INT_NPY)(*(PyObject * (*)(PyTypeObject *, int, npy_intp const *, int, npy_intp const *, void *, int, int, PyObject *)) PyArray_API [93])(&(*(PyTypeObject *)PyArray_API[2]), 1, &out_sz, NPY_INT, ((void*)0), ((void*)0), 0, 0, ((void*)0)); | |||
686 | if (ap_hu == NULL((void*)0) || ap_tcur == NULL((void*)0) || ap_tolsf == NULL((void*)0) || | |||
687 | ap_tsw == NULL((void*)0) || ap_nst == NULL((void*)0) || ap_nfe == NULL((void*)0) || | |||
688 | ap_nje == NULL((void*)0) || ap_nqu == NULL((void*)0) || ap_mused == NULL((void*)0)) { | |||
689 | goto fail; | |||
690 | } | |||
691 | } | |||
692 | ||||
693 | if (o_tcrit != NULL((void*)0)) { | |||
694 | /* There are critical points */ | |||
695 | itask = 4; | |||
696 | tcrit = (double *)(PyArray_DATA(ap_tcrit)); | |||
697 | rwork[0] = *tcrit; | |||
698 | } | |||
699 | while (k < ntimes && istate > 0) { /* loop over desired times */ | |||
700 | ||||
701 | tout_ptr = tout + k; | |||
702 | /* Use tcrit if relevant */ | |||
703 | if (itask == 4) { | |||
704 | if (!tcrit) { | |||
705 | PYERR(odepack_error, "Internal error - tcrit must be defined!"){ PyErr_SetString(odepack_error,"Internal error - tcrit must be defined!" ); goto fail; }; | |||
706 | } | |||
707 | if (*tout_ptr > *(tcrit + crit_ind)) { | |||
708 | crit_ind++; | |||
709 | rwork[0] = *(tcrit+crit_ind); | |||
710 | } | |||
711 | } | |||
712 | if (crit_ind >= numcrit) { | |||
713 | itask = 1; /* No more critical values */ | |||
714 | } | |||
715 | ||||
716 | LSODAlsoda_(ode_function, &neq, y, &t, tout_ptr, &itol, rtol, atol, &itask, | |||
717 | &istate, &iopt, rwork, &lrw, iwork, &liw, | |||
718 | ode_jacobian_function, &jt); | |||
719 | if (full_output) { | |||
720 | *((double *)PyArray_DATA(ap_hu) + (k-1)) = rwork[10]; | |||
721 | *((double *)PyArray_DATA(ap_tcur) + (k-1)) = rwork[12]; | |||
722 | *((double *)PyArray_DATA(ap_tolsf) + (k-1)) = rwork[13]; | |||
723 | *((double *)PyArray_DATA(ap_tsw) + (k-1)) = rwork[14]; | |||
724 | *((F_INTint *)PyArray_DATA(ap_nst) + (k-1)) = iwork[10]; | |||
725 | *((F_INTint *)PyArray_DATA(ap_nfe) + (k-1)) = iwork[11]; | |||
726 | *((F_INTint *)PyArray_DATA(ap_nje) + (k-1)) = iwork[12]; | |||
727 | *((F_INTint *)PyArray_DATA(ap_nqu) + (k-1)) = iwork[13]; | |||
728 | if (istate == -5 || istate == -4) { | |||
729 | imxer = iwork[15]; | |||
730 | } | |||
731 | else { | |||
732 | imxer = -1; | |||
733 | } | |||
734 | lenrw = iwork[16]; | |||
735 | leniw = iwork[17]; | |||
736 | *((F_INTint *)PyArray_DATA(ap_mused) + (k-1)) = iwork[18]; | |||
737 | } | |||
738 | if (PyErr_Occurred()) { | |||
739 | goto fail; | |||
740 | } | |||
741 | memcpy(yout_ptr, y, neq*sizeof(double)); /* copy integration result to output*/ | |||
742 | yout_ptr += neq; | |||
743 | k++; | |||
744 | } | |||
745 | ||||
746 | /* Restore global_params from the previously stashed save_params. */ | |||
747 | memcpy(&global_params, &save_params, sizeof(save_params)); | |||
748 | ||||
749 | Py_DECREF(extra_args)_Py_DECREF(((PyObject*)(extra_args))); | |||
750 | Py_DECREF(ap_atol)_Py_DECREF(((PyObject*)(ap_atol))); | |||
751 | Py_DECREF(ap_rtol)_Py_DECREF(((PyObject*)(ap_rtol))); | |||
752 | Py_XDECREF(ap_tcrit)_Py_XDECREF(((PyObject*)(ap_tcrit))); | |||
753 | Py_DECREF(ap_y)_Py_DECREF(((PyObject*)(ap_y))); | |||
754 | Py_DECREF(ap_tout)_Py_DECREF(((PyObject*)(ap_tout))); | |||
755 | free(wa); | |||
756 | ||||
757 | /* Do Full output */ | |||
758 | if (full_output) { | |||
759 | return Py_BuildValue("N{s:N,s:N,s:N,s:N,s:N,s:N,s:N,s:N,s:l,s:l,s:l,s:N}l", | |||
760 | PyArray_Return(*(PyObject * (*)(PyArrayObject *)) PyArray_API[76])(ap_yout), | |||
761 | "hu", PyArray_Return(*(PyObject * (*)(PyArrayObject *)) PyArray_API[76])(ap_hu), | |||
762 | "tcur", PyArray_Return(*(PyObject * (*)(PyArrayObject *)) PyArray_API[76])(ap_tcur), | |||
763 | "tolsf", PyArray_Return(*(PyObject * (*)(PyArrayObject *)) PyArray_API[76])(ap_tolsf), | |||
764 | "tsw", PyArray_Return(*(PyObject * (*)(PyArrayObject *)) PyArray_API[76])(ap_tsw), | |||
765 | "nst", PyArray_Return(*(PyObject * (*)(PyArrayObject *)) PyArray_API[76])(ap_nst), | |||
766 | "nfe", PyArray_Return(*(PyObject * (*)(PyArrayObject *)) PyArray_API[76])(ap_nfe), | |||
767 | "nje", PyArray_Return(*(PyObject * (*)(PyArrayObject *)) PyArray_API[76])(ap_nje), | |||
768 | "nqu", PyArray_Return(*(PyObject * (*)(PyArrayObject *)) PyArray_API[76])(ap_nqu), | |||
769 | "imxer", imxer, | |||
770 | "lenrw", lenrw, | |||
771 | "leniw", leniw, | |||
772 | "mused", PyArray_Return(*(PyObject * (*)(PyArrayObject *)) PyArray_API[76])(ap_mused), | |||
773 | (long)istate); | |||
774 | } | |||
775 | else { | |||
776 | return Py_BuildValue("Nl", PyArray_Return(*(PyObject * (*)(PyArrayObject *)) PyArray_API[76])(ap_yout), (long)istate); | |||
777 | } | |||
778 | ||||
779 | fail: | |||
780 | /* Restore global_params from the previously stashed save_params. */ | |||
781 | memcpy(&global_params, &save_params, sizeof(save_params)); | |||
782 | ||||
783 | Py_XDECREF(extra_args)_Py_XDECREF(((PyObject*)(extra_args))); | |||
784 | Py_XDECREF(ap_y)_Py_XDECREF(((PyObject*)(ap_y))); | |||
785 | Py_XDECREF(ap_rtol)_Py_XDECREF(((PyObject*)(ap_rtol))); | |||
786 | Py_XDECREF(ap_atol)_Py_XDECREF(((PyObject*)(ap_atol))); | |||
787 | Py_XDECREF(ap_tcrit)_Py_XDECREF(((PyObject*)(ap_tcrit))); | |||
788 | Py_XDECREF(ap_tout)_Py_XDECREF(((PyObject*)(ap_tout))); | |||
789 | Py_XDECREF(ap_yout)_Py_XDECREF(((PyObject*)(ap_yout))); | |||
790 | if (allocated) { | |||
791 | free(wa); | |||
792 | } | |||
793 | if (full_output) { | |||
794 | Py_XDECREF(ap_hu)_Py_XDECREF(((PyObject*)(ap_hu))); | |||
795 | Py_XDECREF(ap_tcur)_Py_XDECREF(((PyObject*)(ap_tcur))); | |||
796 | Py_XDECREF(ap_tolsf)_Py_XDECREF(((PyObject*)(ap_tolsf))); | |||
797 | Py_XDECREF(ap_tsw)_Py_XDECREF(((PyObject*)(ap_tsw))); | |||
798 | Py_XDECREF(ap_nst)_Py_XDECREF(((PyObject*)(ap_nst))); | |||
799 | Py_XDECREF(ap_nfe)_Py_XDECREF(((PyObject*)(ap_nfe))); | |||
800 | Py_XDECREF(ap_nje)_Py_XDECREF(((PyObject*)(ap_nje))); | |||
801 | Py_XDECREF(ap_nqu)_Py_XDECREF(((PyObject*)(ap_nqu))); | |||
802 | Py_XDECREF(ap_mused)_Py_XDECREF(((PyObject*)(ap_mused))); | |||
803 | } | |||
804 | return NULL((void*)0); | |||
805 | } | |||
806 | ||||
807 | ||||
808 | static struct PyMethodDef odepack_module_methods[] = { | |||
809 | {"odeint", (PyCFunction) odepack_odeint, METH_VARARGS0x0001|METH_KEYWORDS0x0002, doc_odeint}, | |||
810 | {NULL((void*)0), NULL((void*)0), 0, NULL((void*)0)} | |||
811 | }; | |||
812 | ||||
813 | static struct PyModuleDef moduledef = { | |||
814 | PyModuleDef_HEAD_INIT{ { 1, ((void*)0) }, ((void*)0), 0, ((void*)0), }, | |||
815 | "_odepack", | |||
816 | NULL((void*)0), | |||
817 | -1, | |||
818 | odepack_module_methods, | |||
819 | NULL((void*)0), | |||
820 | NULL((void*)0), | |||
821 | NULL((void*)0), | |||
822 | NULL((void*)0) | |||
823 | }; | |||
824 | ||||
825 | PyObject * | |||
826 | PyInit__odepack(void) | |||
827 | { | |||
828 | PyObject *m, *d, *s; | |||
829 | ||||
830 | m = PyModule_Create(&moduledef)PyModule_Create2(&moduledef, 1013); | |||
| ||||
| ||||
831 | import_array(){if (_import_array() < 0) {PyErr_Print(); PyErr_SetString( PyExc_ImportError, "numpy.core.multiarray failed to import"); return ((void*)0); } }; | |||
832 | d = PyModule_GetDict(m); | |||
833 | ||||
834 | s = PyUnicode_FromString(" 1.9 "); | |||
835 | PyDict_SetItemString(d, "__version__", s); | |||
836 | odepack_error = PyErr_NewException ("odepack.error", NULL((void*)0), NULL((void*)0)); | |||
837 | Py_DECREF(s)_Py_DECREF(((PyObject*)(s))); | |||
838 | PyDict_SetItemString(d, "error", odepack_error); | |||
839 | if (PyErr_Occurred()) { | |||
840 | Py_FatalError("can't initialize module odepack"); | |||
841 | } | |||
842 | return m; | |||
843 | } |
1 | #ifndef PyModule_Create2 |
2 | struct _object; |
3 | typedef struct _object PyObject; |
4 | PyObject* clang_analyzer_PyObject_New_Reference(); |
5 | PyObject* PyModule_Create2(PyModuleDef *def, int module_api_version) { |
6 | return clang_analyzer_PyObject_New_Reference(); |
7 | } |
8 | #else |
9 | #warning "API PyModule_Create2 is defined as a macro." |
10 | #endif |