alglib4 0.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +47 -0
  3. data/ext/alglib/alglib.cpp +537 -0
  4. data/ext/alglib/alglib_array_converters.cpp +86 -0
  5. data/ext/alglib/alglib_array_converters.h +15 -0
  6. data/ext/alglib/alglib_utils.cpp +10 -0
  7. data/ext/alglib/alglib_utils.h +6 -0
  8. data/ext/alglib/alglibinternal.cpp +21749 -0
  9. data/ext/alglib/alglibinternal.h +2168 -0
  10. data/ext/alglib/alglibmisc.cpp +9106 -0
  11. data/ext/alglib/alglibmisc.h +2114 -0
  12. data/ext/alglib/ap.cpp +20094 -0
  13. data/ext/alglib/ap.h +7244 -0
  14. data/ext/alglib/dataanalysis.cpp +52588 -0
  15. data/ext/alglib/dataanalysis.h +10601 -0
  16. data/ext/alglib/diffequations.cpp +1342 -0
  17. data/ext/alglib/diffequations.h +282 -0
  18. data/ext/alglib/extconf.rb +5 -0
  19. data/ext/alglib/fasttransforms.cpp +4696 -0
  20. data/ext/alglib/fasttransforms.h +1018 -0
  21. data/ext/alglib/integration.cpp +4249 -0
  22. data/ext/alglib/integration.h +869 -0
  23. data/ext/alglib/interpolation.cpp +74502 -0
  24. data/ext/alglib/interpolation.h +12264 -0
  25. data/ext/alglib/kernels_avx2.cpp +2171 -0
  26. data/ext/alglib/kernels_avx2.h +201 -0
  27. data/ext/alglib/kernels_fma.cpp +1065 -0
  28. data/ext/alglib/kernels_fma.h +137 -0
  29. data/ext/alglib/kernels_sse2.cpp +735 -0
  30. data/ext/alglib/kernels_sse2.h +100 -0
  31. data/ext/alglib/linalg.cpp +65182 -0
  32. data/ext/alglib/linalg.h +9927 -0
  33. data/ext/alglib/optimization.cpp +135331 -0
  34. data/ext/alglib/optimization.h +19235 -0
  35. data/ext/alglib/solvers.cpp +20488 -0
  36. data/ext/alglib/solvers.h +4781 -0
  37. data/ext/alglib/specialfunctions.cpp +10672 -0
  38. data/ext/alglib/specialfunctions.h +2305 -0
  39. data/ext/alglib/statistics.cpp +19791 -0
  40. data/ext/alglib/statistics.h +1359 -0
  41. data/ext/alglib/stdafx.h +2 -0
  42. data/gpl2.txt +339 -0
  43. data/gpl3.txt +674 -0
  44. data/lib/alglib/version.rb +3 -0
  45. data/lib/alglib.rb +4 -0
  46. metadata +101 -0
@@ -0,0 +1,1342 @@
1
+ /*************************************************************************
2
+ ALGLIB 4.04.0 (source code generated 2024-12-21)
3
+ Copyright (c) Sergey Bochkanov (ALGLIB project).
4
+
5
+ >>> SOURCE LICENSE >>>
6
+ This program is free software; you can redistribute it and/or modify
7
+ it under the terms of the GNU General Public License as published by
8
+ the Free Software Foundation (www.fsf.org); either version 2 of the
9
+ License, or (at your option) any later version.
10
+
11
+ This program is distributed in the hope that it will be useful,
12
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ GNU General Public License for more details.
15
+
16
+ A copy of the GNU General Public License is available at
17
+ http://www.fsf.org/licensing/licenses
18
+ >>> END OF LICENSE >>>
19
+ *************************************************************************/
20
+ #ifdef _MSC_VER
21
+ #define _CRT_SECURE_NO_WARNINGS
22
+ #endif
23
+ #include "stdafx.h"
24
+ #include "diffequations.h"
25
+
26
+ // disable some irrelevant warnings
27
+ #if (AE_COMPILER==AE_MSVC) && !defined(AE_ALL_WARNINGS)
28
+ #pragma warning(disable:4100)
29
+ #pragma warning(disable:4127)
30
+ #pragma warning(disable:4611)
31
+ #pragma warning(disable:4702)
32
+ #pragma warning(disable:4996)
33
+ #endif
34
+
35
+ /////////////////////////////////////////////////////////////////////////
36
+ //
37
+ // THIS SECTION CONTAINS IMPLEMENTATION OF C++ INTERFACE
38
+ //
39
+ /////////////////////////////////////////////////////////////////////////
40
+ namespace alglib
41
+ {
42
+
43
+
44
+ #if defined(AE_COMPILE_ODESOLVER) || !defined(AE_PARTIAL_BUILD)
45
+ /*************************************************************************
46
+
47
+ *************************************************************************/
48
+ _odesolverstate_owner::_odesolverstate_owner()
49
+ {
50
+ jmp_buf _break_jump;
51
+ alglib_impl::ae_state _state;
52
+
53
+ alglib_impl::ae_state_init(&_state);
54
+ if( setjmp(_break_jump) )
55
+ {
56
+ if( p_struct!=NULL )
57
+ {
58
+ alglib_impl::_odesolverstate_destroy(p_struct);
59
+ alglib_impl::ae_free(p_struct);
60
+ }
61
+ p_struct = NULL;
62
+ #if !defined(AE_NO_EXCEPTIONS)
63
+ _ALGLIB_CPP_EXCEPTION(_state.error_msg);
64
+ #else
65
+ _ALGLIB_SET_ERROR_FLAG(_state.error_msg);
66
+ return;
67
+ #endif
68
+ }
69
+ alglib_impl::ae_state_set_break_jump(&_state, &_break_jump);
70
+ p_struct = NULL;
71
+ p_struct = (alglib_impl::odesolverstate*)alglib_impl::ae_malloc(sizeof(alglib_impl::odesolverstate), &_state);
72
+ memset(p_struct, 0, sizeof(alglib_impl::odesolverstate));
73
+ alglib_impl::_odesolverstate_init(p_struct, &_state, ae_false);
74
+ ae_state_clear(&_state);
75
+ is_attached = false;
76
+ }
77
+
78
+ _odesolverstate_owner::_odesolverstate_owner(alglib_impl::odesolverstate *attach_to)
79
+ {
80
+ p_struct = attach_to;
81
+ is_attached = true;
82
+ }
83
+
84
+ _odesolverstate_owner::_odesolverstate_owner(const _odesolverstate_owner &rhs)
85
+ {
86
+ jmp_buf _break_jump;
87
+ alglib_impl::ae_state _state;
88
+
89
+ alglib_impl::ae_state_init(&_state);
90
+ if( setjmp(_break_jump) )
91
+ {
92
+ if( p_struct!=NULL )
93
+ {
94
+ alglib_impl::_odesolverstate_destroy(p_struct);
95
+ alglib_impl::ae_free(p_struct);
96
+ }
97
+ p_struct = NULL;
98
+ #if !defined(AE_NO_EXCEPTIONS)
99
+ _ALGLIB_CPP_EXCEPTION(_state.error_msg);
100
+ #else
101
+ _ALGLIB_SET_ERROR_FLAG(_state.error_msg);
102
+ return;
103
+ #endif
104
+ }
105
+ alglib_impl::ae_state_set_break_jump(&_state, &_break_jump);
106
+ p_struct = NULL;
107
+ alglib_impl::ae_assert(rhs.p_struct!=NULL, "ALGLIB: odesolverstate copy constructor failure (source is not initialized)", &_state);
108
+ p_struct = (alglib_impl::odesolverstate*)alglib_impl::ae_malloc(sizeof(alglib_impl::odesolverstate), &_state);
109
+ memset(p_struct, 0, sizeof(alglib_impl::odesolverstate));
110
+ alglib_impl::_odesolverstate_init_copy(p_struct, const_cast<alglib_impl::odesolverstate*>(rhs.p_struct), &_state, ae_false);
111
+ ae_state_clear(&_state);
112
+ is_attached = false;
113
+ }
114
+
115
+ _odesolverstate_owner& _odesolverstate_owner::operator=(const _odesolverstate_owner &rhs)
116
+ {
117
+ if( this==&rhs )
118
+ return *this;
119
+ jmp_buf _break_jump;
120
+ alglib_impl::ae_state _state;
121
+
122
+ alglib_impl::ae_state_init(&_state);
123
+ if( setjmp(_break_jump) )
124
+ {
125
+ #if !defined(AE_NO_EXCEPTIONS)
126
+ _ALGLIB_CPP_EXCEPTION(_state.error_msg);
127
+ #else
128
+ _ALGLIB_SET_ERROR_FLAG(_state.error_msg);
129
+ return *this;
130
+ #endif
131
+ }
132
+ alglib_impl::ae_state_set_break_jump(&_state, &_break_jump);
133
+ alglib_impl::ae_assert(p_struct!=NULL, "ALGLIB: odesolverstate assignment constructor failure (destination is not initialized)", &_state);
134
+ alglib_impl::ae_assert(rhs.p_struct!=NULL, "ALGLIB: odesolverstate assignment constructor failure (source is not initialized)", &_state);
135
+ alglib_impl::ae_assert(!is_attached, "ALGLIB: odesolverstate assignment constructor failure (can not assign to the structure which is attached to something else)", &_state);
136
+ alglib_impl::_odesolverstate_destroy(p_struct);
137
+ memset(p_struct, 0, sizeof(alglib_impl::odesolverstate));
138
+ alglib_impl::_odesolverstate_init_copy(p_struct, const_cast<alglib_impl::odesolverstate*>(rhs.p_struct), &_state, ae_false);
139
+ ae_state_clear(&_state);
140
+ return *this;
141
+ }
142
+
143
+ _odesolverstate_owner::~_odesolverstate_owner()
144
+ {
145
+ if( p_struct!=NULL && !is_attached )
146
+ {
147
+ alglib_impl::_odesolverstate_destroy(p_struct);
148
+ ae_free(p_struct);
149
+ }
150
+ }
151
+
152
+ alglib_impl::odesolverstate* _odesolverstate_owner::c_ptr()
153
+ {
154
+ return p_struct;
155
+ }
156
+
157
+ const alglib_impl::odesolverstate* _odesolverstate_owner::c_ptr() const
158
+ {
159
+ return p_struct;
160
+ }
161
+ odesolverstate::odesolverstate() : _odesolverstate_owner() ,needdy(p_struct->needdy),y(&p_struct->y),dy(&p_struct->dy),x(p_struct->x)
162
+ {
163
+ }
164
+
165
+ odesolverstate::odesolverstate(alglib_impl::odesolverstate *attach_to):_odesolverstate_owner(attach_to) ,needdy(p_struct->needdy),y(&p_struct->y),dy(&p_struct->dy),x(p_struct->x)
166
+ {
167
+ }
168
+
169
+ odesolverstate::odesolverstate(const odesolverstate &rhs):_odesolverstate_owner(rhs) ,needdy(p_struct->needdy),y(&p_struct->y),dy(&p_struct->dy),x(p_struct->x)
170
+ {
171
+ }
172
+
173
+ odesolverstate& odesolverstate::operator=(const odesolverstate &rhs)
174
+ {
175
+ if( this==&rhs )
176
+ return *this;
177
+ _odesolverstate_owner::operator=(rhs);
178
+ return *this;
179
+ }
180
+
181
+ odesolverstate::~odesolverstate()
182
+ {
183
+ }
184
+
185
+
186
+ /*************************************************************************
187
+
188
+ *************************************************************************/
189
+ _odesolverreport_owner::_odesolverreport_owner()
190
+ {
191
+ jmp_buf _break_jump;
192
+ alglib_impl::ae_state _state;
193
+
194
+ alglib_impl::ae_state_init(&_state);
195
+ if( setjmp(_break_jump) )
196
+ {
197
+ if( p_struct!=NULL )
198
+ {
199
+ alglib_impl::_odesolverreport_destroy(p_struct);
200
+ alglib_impl::ae_free(p_struct);
201
+ }
202
+ p_struct = NULL;
203
+ #if !defined(AE_NO_EXCEPTIONS)
204
+ _ALGLIB_CPP_EXCEPTION(_state.error_msg);
205
+ #else
206
+ _ALGLIB_SET_ERROR_FLAG(_state.error_msg);
207
+ return;
208
+ #endif
209
+ }
210
+ alglib_impl::ae_state_set_break_jump(&_state, &_break_jump);
211
+ p_struct = NULL;
212
+ p_struct = (alglib_impl::odesolverreport*)alglib_impl::ae_malloc(sizeof(alglib_impl::odesolverreport), &_state);
213
+ memset(p_struct, 0, sizeof(alglib_impl::odesolverreport));
214
+ alglib_impl::_odesolverreport_init(p_struct, &_state, ae_false);
215
+ ae_state_clear(&_state);
216
+ is_attached = false;
217
+ }
218
+
219
+ _odesolverreport_owner::_odesolverreport_owner(alglib_impl::odesolverreport *attach_to)
220
+ {
221
+ p_struct = attach_to;
222
+ is_attached = true;
223
+ }
224
+
225
+ _odesolverreport_owner::_odesolverreport_owner(const _odesolverreport_owner &rhs)
226
+ {
227
+ jmp_buf _break_jump;
228
+ alglib_impl::ae_state _state;
229
+
230
+ alglib_impl::ae_state_init(&_state);
231
+ if( setjmp(_break_jump) )
232
+ {
233
+ if( p_struct!=NULL )
234
+ {
235
+ alglib_impl::_odesolverreport_destroy(p_struct);
236
+ alglib_impl::ae_free(p_struct);
237
+ }
238
+ p_struct = NULL;
239
+ #if !defined(AE_NO_EXCEPTIONS)
240
+ _ALGLIB_CPP_EXCEPTION(_state.error_msg);
241
+ #else
242
+ _ALGLIB_SET_ERROR_FLAG(_state.error_msg);
243
+ return;
244
+ #endif
245
+ }
246
+ alglib_impl::ae_state_set_break_jump(&_state, &_break_jump);
247
+ p_struct = NULL;
248
+ alglib_impl::ae_assert(rhs.p_struct!=NULL, "ALGLIB: odesolverreport copy constructor failure (source is not initialized)", &_state);
249
+ p_struct = (alglib_impl::odesolverreport*)alglib_impl::ae_malloc(sizeof(alglib_impl::odesolverreport), &_state);
250
+ memset(p_struct, 0, sizeof(alglib_impl::odesolverreport));
251
+ alglib_impl::_odesolverreport_init_copy(p_struct, const_cast<alglib_impl::odesolverreport*>(rhs.p_struct), &_state, ae_false);
252
+ ae_state_clear(&_state);
253
+ is_attached = false;
254
+ }
255
+
256
+ _odesolverreport_owner& _odesolverreport_owner::operator=(const _odesolverreport_owner &rhs)
257
+ {
258
+ if( this==&rhs )
259
+ return *this;
260
+ jmp_buf _break_jump;
261
+ alglib_impl::ae_state _state;
262
+
263
+ alglib_impl::ae_state_init(&_state);
264
+ if( setjmp(_break_jump) )
265
+ {
266
+ #if !defined(AE_NO_EXCEPTIONS)
267
+ _ALGLIB_CPP_EXCEPTION(_state.error_msg);
268
+ #else
269
+ _ALGLIB_SET_ERROR_FLAG(_state.error_msg);
270
+ return *this;
271
+ #endif
272
+ }
273
+ alglib_impl::ae_state_set_break_jump(&_state, &_break_jump);
274
+ alglib_impl::ae_assert(p_struct!=NULL, "ALGLIB: odesolverreport assignment constructor failure (destination is not initialized)", &_state);
275
+ alglib_impl::ae_assert(rhs.p_struct!=NULL, "ALGLIB: odesolverreport assignment constructor failure (source is not initialized)", &_state);
276
+ alglib_impl::ae_assert(!is_attached, "ALGLIB: odesolverreport assignment constructor failure (can not assign to the structure which is attached to something else)", &_state);
277
+ alglib_impl::_odesolverreport_destroy(p_struct);
278
+ memset(p_struct, 0, sizeof(alglib_impl::odesolverreport));
279
+ alglib_impl::_odesolverreport_init_copy(p_struct, const_cast<alglib_impl::odesolverreport*>(rhs.p_struct), &_state, ae_false);
280
+ ae_state_clear(&_state);
281
+ return *this;
282
+ }
283
+
284
+ _odesolverreport_owner::~_odesolverreport_owner()
285
+ {
286
+ if( p_struct!=NULL && !is_attached )
287
+ {
288
+ alglib_impl::_odesolverreport_destroy(p_struct);
289
+ ae_free(p_struct);
290
+ }
291
+ }
292
+
293
+ alglib_impl::odesolverreport* _odesolverreport_owner::c_ptr()
294
+ {
295
+ return p_struct;
296
+ }
297
+
298
+ const alglib_impl::odesolverreport* _odesolverreport_owner::c_ptr() const
299
+ {
300
+ return p_struct;
301
+ }
302
+ odesolverreport::odesolverreport() : _odesolverreport_owner() ,nfev(p_struct->nfev),terminationtype(p_struct->terminationtype)
303
+ {
304
+ }
305
+
306
+ odesolverreport::odesolverreport(alglib_impl::odesolverreport *attach_to):_odesolverreport_owner(attach_to) ,nfev(p_struct->nfev),terminationtype(p_struct->terminationtype)
307
+ {
308
+ }
309
+
310
+ odesolverreport::odesolverreport(const odesolverreport &rhs):_odesolverreport_owner(rhs) ,nfev(p_struct->nfev),terminationtype(p_struct->terminationtype)
311
+ {
312
+ }
313
+
314
+ odesolverreport& odesolverreport::operator=(const odesolverreport &rhs)
315
+ {
316
+ if( this==&rhs )
317
+ return *this;
318
+ _odesolverreport_owner::operator=(rhs);
319
+ return *this;
320
+ }
321
+
322
+ odesolverreport::~odesolverreport()
323
+ {
324
+ }
325
+
326
+ /*************************************************************************
327
+ Cash-Karp adaptive ODE solver.
328
+
329
+ This subroutine solves ODE Y'=f(Y,x) with initial conditions Y(xs)=Ys
330
+ (here Y may be single variable or vector of N variables).
331
+
332
+ INPUT PARAMETERS:
333
+ Y - initial conditions, array[0..N-1].
334
+ contains values of Y[] at X[0]
335
+ N - system size
336
+ X - points at which Y should be tabulated, array[0..M-1]
337
+ integrations starts at X[0], ends at X[M-1], intermediate
338
+ values at X[i] are returned too.
339
+ SHOULD BE ORDERED BY ASCENDING OR BY DESCENDING!
340
+ M - number of intermediate points + first point + last point:
341
+ * M>2 means that you need both Y(X[M-1]) and M-2 values at
342
+ intermediate points
343
+ * M=2 means that you want just to integrate from X[0] to
344
+ X[1] and don't interested in intermediate values.
345
+ * M=1 means that you don't want to integrate :)
346
+ it is degenerate case, but it will be handled correctly.
347
+ * M<1 means error
348
+ Eps - tolerance (absolute/relative error on each step will be
349
+ less than Eps). When passing:
350
+ * Eps>0, it means desired ABSOLUTE error
351
+ * Eps<0, it means desired RELATIVE error. Relative errors
352
+ are calculated with respect to maximum values of Y seen
353
+ so far. Be careful to use this criterion when starting
354
+ from Y[] that are close to zero.
355
+ H - initial step lenth, it will be adjusted automatically
356
+ after the first step. If H=0, step will be selected
357
+ automatically (usualy it will be equal to 0.001 of
358
+ min(x[i]-x[j])).
359
+
360
+ OUTPUT PARAMETERS
361
+ State - structure which stores algorithm state between subsequent
362
+ calls of OdeSolverIteration. Used for reverse communication.
363
+ This structure should be passed to the OdeSolverIteration
364
+ subroutine.
365
+
366
+ SEE ALSO
367
+ AutoGKSmoothW, AutoGKSingular, AutoGKIteration, AutoGKResults.
368
+
369
+
370
+ -- ALGLIB --
371
+ Copyright 01.09.2009 by Bochkanov Sergey
372
+ *************************************************************************/
373
+ void odesolverrkck(const real_1d_array &y, const ae_int_t n, const real_1d_array &x, const ae_int_t m, const double eps, const double h, odesolverstate &state, const xparams _xparams)
374
+ {
375
+ jmp_buf _break_jump;
376
+ alglib_impl::ae_state _alglib_env_state;
377
+ alglib_impl::ae_state_init(&_alglib_env_state);
378
+ if( setjmp(_break_jump) )
379
+ {
380
+ #if !defined(AE_NO_EXCEPTIONS)
381
+ _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
382
+ #else
383
+ _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
384
+ return;
385
+ #endif
386
+ }
387
+ ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
388
+ if( _xparams.flags!=(alglib_impl::ae_uint64_t)0x0 )
389
+ ae_state_set_flags(&_alglib_env_state, _xparams.flags);
390
+ alglib_impl::odesolverrkck(y.c_ptr(), n, x.c_ptr(), m, eps, h, state.c_ptr(), &_alglib_env_state);
391
+ alglib_impl::ae_state_clear(&_alglib_env_state);
392
+ return;
393
+ }
394
+
395
+ /*************************************************************************
396
+ Cash-Karp adaptive ODE solver.
397
+
398
+ This subroutine solves ODE Y'=f(Y,x) with initial conditions Y(xs)=Ys
399
+ (here Y may be single variable or vector of N variables).
400
+
401
+ INPUT PARAMETERS:
402
+ Y - initial conditions, array[0..N-1].
403
+ contains values of Y[] at X[0]
404
+ N - system size
405
+ X - points at which Y should be tabulated, array[0..M-1]
406
+ integrations starts at X[0], ends at X[M-1], intermediate
407
+ values at X[i] are returned too.
408
+ SHOULD BE ORDERED BY ASCENDING OR BY DESCENDING!
409
+ M - number of intermediate points + first point + last point:
410
+ * M>2 means that you need both Y(X[M-1]) and M-2 values at
411
+ intermediate points
412
+ * M=2 means that you want just to integrate from X[0] to
413
+ X[1] and don't interested in intermediate values.
414
+ * M=1 means that you don't want to integrate :)
415
+ it is degenerate case, but it will be handled correctly.
416
+ * M<1 means error
417
+ Eps - tolerance (absolute/relative error on each step will be
418
+ less than Eps). When passing:
419
+ * Eps>0, it means desired ABSOLUTE error
420
+ * Eps<0, it means desired RELATIVE error. Relative errors
421
+ are calculated with respect to maximum values of Y seen
422
+ so far. Be careful to use this criterion when starting
423
+ from Y[] that are close to zero.
424
+ H - initial step lenth, it will be adjusted automatically
425
+ after the first step. If H=0, step will be selected
426
+ automatically (usualy it will be equal to 0.001 of
427
+ min(x[i]-x[j])).
428
+
429
+ OUTPUT PARAMETERS
430
+ State - structure which stores algorithm state between subsequent
431
+ calls of OdeSolverIteration. Used for reverse communication.
432
+ This structure should be passed to the OdeSolverIteration
433
+ subroutine.
434
+
435
+ SEE ALSO
436
+ AutoGKSmoothW, AutoGKSingular, AutoGKIteration, AutoGKResults.
437
+
438
+
439
+ -- ALGLIB --
440
+ Copyright 01.09.2009 by Bochkanov Sergey
441
+ *************************************************************************/
442
+ #if !defined(AE_NO_EXCEPTIONS)
443
+ void odesolverrkck(const real_1d_array &y, const real_1d_array &x, const double eps, const double h, odesolverstate &state, const xparams _xparams)
444
+ {
445
+ jmp_buf _break_jump;
446
+ alglib_impl::ae_state _alglib_env_state;
447
+ ae_int_t n;
448
+ ae_int_t m;
449
+
450
+ n = y.length();
451
+ m = x.length();
452
+ alglib_impl::ae_state_init(&_alglib_env_state);
453
+ if( setjmp(_break_jump) )
454
+ _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
455
+ ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
456
+ if( _xparams.flags!=(alglib_impl::ae_uint64_t)0x0 )
457
+ ae_state_set_flags(&_alglib_env_state, _xparams.flags);
458
+ alglib_impl::odesolverrkck(y.c_ptr(), n, x.c_ptr(), m, eps, h, state.c_ptr(), &_alglib_env_state);
459
+
460
+ alglib_impl::ae_state_clear(&_alglib_env_state);
461
+ return;
462
+ }
463
+ #endif
464
+
465
+ /*************************************************************************
466
+ This function provides reverse communication interface
467
+ Reverse communication interface is not documented or recommended to use.
468
+ See below for functions which provide better documented API
469
+ *************************************************************************/
470
+ bool odesolveriteration(odesolverstate &state, const xparams _xparams)
471
+ {
472
+ jmp_buf _break_jump;
473
+ alglib_impl::ae_state _alglib_env_state;
474
+ alglib_impl::ae_state_init(&_alglib_env_state);
475
+ if( setjmp(_break_jump) )
476
+ {
477
+ #if !defined(AE_NO_EXCEPTIONS)
478
+ _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
479
+ #else
480
+ _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
481
+ return 0;
482
+ #endif
483
+ }
484
+ ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
485
+ if( _xparams.flags!=(alglib_impl::ae_uint64_t)0x0 )
486
+ ae_state_set_flags(&_alglib_env_state, _xparams.flags);
487
+ ae_bool result = alglib_impl::odesolveriteration(state.c_ptr(), &_alglib_env_state);
488
+ alglib_impl::ae_state_clear(&_alglib_env_state);
489
+ return bool(result);
490
+ }
491
+
492
+
493
+ void odesolversolve(odesolverstate &state,
494
+ void (*diff)(const real_1d_array &y, double x, real_1d_array &dy, void *ptr),
495
+ void *ptr, const xparams _xparams){
496
+ jmp_buf _break_jump;
497
+ alglib_impl::ae_state _alglib_env_state;
498
+ alglib_impl::ae_state_init(&_alglib_env_state);
499
+ if( setjmp(_break_jump) )
500
+ {
501
+ #if !defined(AE_NO_EXCEPTIONS)
502
+ _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
503
+ #else
504
+ _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
505
+ return;
506
+ #endif
507
+ }
508
+ ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
509
+ if( _xparams.flags!=(alglib_impl::ae_uint64_t)0x0 )
510
+ ae_state_set_flags(&_alglib_env_state, _xparams.flags);
511
+ alglib_impl::ae_assert(diff!=NULL, "ALGLIB: error in 'odesolversolve()' (diff is NULL)", &_alglib_env_state);
512
+ while( alglib_impl::odesolveriteration(state.c_ptr(), &_alglib_env_state) )
513
+ {
514
+ _ALGLIB_CALLBACK_EXCEPTION_GUARD_BEGIN
515
+ if( state.needdy )
516
+ {
517
+ diff(state.y, state.x, state.dy, ptr);
518
+ continue;
519
+ }
520
+ goto lbl_no_callback;
521
+ _ALGLIB_CALLBACK_EXCEPTION_GUARD_END
522
+ lbl_no_callback:
523
+ alglib_impl::ae_assert(ae_false, "ALGLIB: unexpected error in 'odesolversolve'", &_alglib_env_state);
524
+ }
525
+ alglib_impl::ae_state_clear(&_alglib_env_state);
526
+ }
527
+
528
+
529
+
530
+ /*************************************************************************
531
+ ODE solver results
532
+
533
+ Called after OdeSolverIteration returned False.
534
+
535
+ INPUT PARAMETERS:
536
+ State - algorithm state (used by OdeSolverIteration).
537
+
538
+ OUTPUT PARAMETERS:
539
+ M - number of tabulated values, M>=1
540
+ XTbl - array[0..M-1], values of X
541
+ YTbl - array[0..M-1,0..N-1], values of Y in X[i]
542
+ Rep - solver report:
543
+ * Rep.TerminationType completetion code:
544
+ * -2 X is not ordered by ascending/descending or
545
+ there are non-distinct X[], i.e. X[i]=X[i+1]
546
+ * -1 incorrect parameters were specified
547
+ * 1 task has been solved
548
+ * Rep.NFEV contains number of function calculations
549
+
550
+ -- ALGLIB --
551
+ Copyright 01.09.2009 by Bochkanov Sergey
552
+ *************************************************************************/
553
+ void odesolverresults(const odesolverstate &state, ae_int_t &m, real_1d_array &xtbl, real_2d_array &ytbl, odesolverreport &rep, const xparams _xparams)
554
+ {
555
+ jmp_buf _break_jump;
556
+ alglib_impl::ae_state _alglib_env_state;
557
+ alglib_impl::ae_state_init(&_alglib_env_state);
558
+ if( setjmp(_break_jump) )
559
+ {
560
+ #if !defined(AE_NO_EXCEPTIONS)
561
+ _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
562
+ #else
563
+ _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
564
+ return;
565
+ #endif
566
+ }
567
+ ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
568
+ if( _xparams.flags!=(alglib_impl::ae_uint64_t)0x0 )
569
+ ae_state_set_flags(&_alglib_env_state, _xparams.flags);
570
+ alglib_impl::odesolverresults(state.c_ptr(), &m, xtbl.c_ptr(), ytbl.c_ptr(), rep.c_ptr(), &_alglib_env_state);
571
+ alglib_impl::ae_state_clear(&_alglib_env_state);
572
+ return;
573
+ }
574
+ #endif
575
+ }
576
+
577
+ /////////////////////////////////////////////////////////////////////////
578
+ //
579
+ // THIS SECTION CONTAINS IMPLEMENTATION OF COMPUTATIONAL CORE
580
+ //
581
+ /////////////////////////////////////////////////////////////////////////
582
+ namespace alglib_impl
583
+ {
584
+ #if defined(AE_COMPILE_ODESOLVER) || !defined(AE_PARTIAL_BUILD)
585
+ static double odesolver_odesolvermaxgrow = 3.0;
586
+ static double odesolver_odesolvermaxshrink = 10.0;
587
+ static double odesolver_odesolverguaranteeddecay = 0.9;
588
+ static void odesolver_odesolverinit(ae_int_t solvertype,
589
+ /* Real */ const ae_vector* y,
590
+ ae_int_t n,
591
+ /* Real */ const ae_vector* x,
592
+ ae_int_t m,
593
+ double eps,
594
+ double h,
595
+ odesolverstate* state,
596
+ ae_state *_state);
597
+
598
+
599
+ #endif
600
+
601
+ #if defined(AE_COMPILE_ODESOLVER) || !defined(AE_PARTIAL_BUILD)
602
+
603
+
604
+ /*************************************************************************
605
+ Cash-Karp adaptive ODE solver.
606
+
607
+ This subroutine solves ODE Y'=f(Y,x) with initial conditions Y(xs)=Ys
608
+ (here Y may be single variable or vector of N variables).
609
+
610
+ INPUT PARAMETERS:
611
+ Y - initial conditions, array[0..N-1].
612
+ contains values of Y[] at X[0]
613
+ N - system size
614
+ X - points at which Y should be tabulated, array[0..M-1]
615
+ integrations starts at X[0], ends at X[M-1], intermediate
616
+ values at X[i] are returned too.
617
+ SHOULD BE ORDERED BY ASCENDING OR BY DESCENDING!
618
+ M - number of intermediate points + first point + last point:
619
+ * M>2 means that you need both Y(X[M-1]) and M-2 values at
620
+ intermediate points
621
+ * M=2 means that you want just to integrate from X[0] to
622
+ X[1] and don't interested in intermediate values.
623
+ * M=1 means that you don't want to integrate :)
624
+ it is degenerate case, but it will be handled correctly.
625
+ * M<1 means error
626
+ Eps - tolerance (absolute/relative error on each step will be
627
+ less than Eps). When passing:
628
+ * Eps>0, it means desired ABSOLUTE error
629
+ * Eps<0, it means desired RELATIVE error. Relative errors
630
+ are calculated with respect to maximum values of Y seen
631
+ so far. Be careful to use this criterion when starting
632
+ from Y[] that are close to zero.
633
+ H - initial step lenth, it will be adjusted automatically
634
+ after the first step. If H=0, step will be selected
635
+ automatically (usualy it will be equal to 0.001 of
636
+ min(x[i]-x[j])).
637
+
638
+ OUTPUT PARAMETERS
639
+ State - structure which stores algorithm state between subsequent
640
+ calls of OdeSolverIteration. Used for reverse communication.
641
+ This structure should be passed to the OdeSolverIteration
642
+ subroutine.
643
+
644
+ SEE ALSO
645
+ AutoGKSmoothW, AutoGKSingular, AutoGKIteration, AutoGKResults.
646
+
647
+
648
+ -- ALGLIB --
649
+ Copyright 01.09.2009 by Bochkanov Sergey
650
+ *************************************************************************/
651
+ void odesolverrkck(/* Real */ const ae_vector* y,
652
+ ae_int_t n,
653
+ /* Real */ const ae_vector* x,
654
+ ae_int_t m,
655
+ double eps,
656
+ double h,
657
+ odesolverstate* state,
658
+ ae_state *_state)
659
+ {
660
+
661
+ _odesolverstate_clear(state);
662
+
663
+ ae_assert(n>=1, "ODESolverRKCK: N<1!", _state);
664
+ ae_assert(m>=1, "ODESolverRKCK: M<1!", _state);
665
+ ae_assert(y->cnt>=n, "ODESolverRKCK: Length(Y)<N!", _state);
666
+ ae_assert(x->cnt>=m, "ODESolverRKCK: Length(X)<M!", _state);
667
+ ae_assert(isfinitevector(y, n, _state), "ODESolverRKCK: Y contains infinite or NaN values!", _state);
668
+ ae_assert(isfinitevector(x, m, _state), "ODESolverRKCK: Y contains infinite or NaN values!", _state);
669
+ ae_assert(ae_isfinite(eps, _state), "ODESolverRKCK: Eps is not finite!", _state);
670
+ ae_assert(ae_fp_neq(eps,(double)(0)), "ODESolverRKCK: Eps is zero!", _state);
671
+ ae_assert(ae_isfinite(h, _state), "ODESolverRKCK: H is not finite!", _state);
672
+ odesolver_odesolverinit(0, y, n, x, m, eps, h, state, _state);
673
+ }
674
+
675
+
676
+ /*************************************************************************
677
+
678
+ -- ALGLIB --
679
+ Copyright 01.09.2009 by Bochkanov Sergey
680
+ *************************************************************************/
681
+ ae_bool odesolveriteration(odesolverstate* state, ae_state *_state)
682
+ {
683
+ ae_int_t n;
684
+ ae_int_t m;
685
+ ae_int_t i;
686
+ ae_int_t j;
687
+ ae_int_t k;
688
+ double xc;
689
+ double v;
690
+ double h;
691
+ double h2;
692
+ ae_bool gridpoint;
693
+ double err;
694
+ double maxgrowpow;
695
+ ae_int_t klimit;
696
+ ae_bool result;
697
+
698
+
699
+
700
+ /*
701
+ * Reverse communication preparations
702
+ * I know it looks ugly, but it works the same way
703
+ * anywhere from C++ to Python.
704
+ *
705
+ * This code initializes locals by:
706
+ * * random values determined during code
707
+ * generation - on first subroutine call
708
+ * * values from previous call - on subsequent calls
709
+ */
710
+ if( state->rstate.stage>=0 )
711
+ {
712
+ n = state->rstate.ia.ptr.p_int[0];
713
+ m = state->rstate.ia.ptr.p_int[1];
714
+ i = state->rstate.ia.ptr.p_int[2];
715
+ j = state->rstate.ia.ptr.p_int[3];
716
+ k = state->rstate.ia.ptr.p_int[4];
717
+ klimit = state->rstate.ia.ptr.p_int[5];
718
+ gridpoint = state->rstate.ba.ptr.p_bool[0];
719
+ xc = state->rstate.ra.ptr.p_double[0];
720
+ v = state->rstate.ra.ptr.p_double[1];
721
+ h = state->rstate.ra.ptr.p_double[2];
722
+ h2 = state->rstate.ra.ptr.p_double[3];
723
+ err = state->rstate.ra.ptr.p_double[4];
724
+ maxgrowpow = state->rstate.ra.ptr.p_double[5];
725
+ }
726
+ else
727
+ {
728
+ n = 359;
729
+ m = -58;
730
+ i = -919;
731
+ j = -909;
732
+ k = 81;
733
+ klimit = 255;
734
+ gridpoint = ae_false;
735
+ xc = -788.0;
736
+ v = 809.0;
737
+ h = 205.0;
738
+ h2 = -838.0;
739
+ err = 939.0;
740
+ maxgrowpow = -526.0;
741
+ }
742
+ if( state->rstate.stage==0 )
743
+ {
744
+ goto lbl_0;
745
+ }
746
+
747
+ /*
748
+ * Routine body
749
+ */
750
+
751
+ /*
752
+ * prepare
753
+ */
754
+ if( state->repterminationtype!=0 )
755
+ {
756
+ result = ae_false;
757
+ return result;
758
+ }
759
+ n = state->n;
760
+ m = state->m;
761
+ h = state->h;
762
+ maxgrowpow = ae_pow(odesolver_odesolvermaxgrow, (double)(5), _state);
763
+ state->repnfev = 0;
764
+
765
+ /*
766
+ * some preliminary checks for internal errors
767
+ * after this we assume that H>0 and M>1
768
+ */
769
+ ae_assert(ae_fp_greater(state->h,(double)(0)), "ODESolver: internal error", _state);
770
+ ae_assert(m>1, "ODESolverIteration: internal error", _state);
771
+
772
+ /*
773
+ * choose solver
774
+ */
775
+ if( state->solvertype!=0 )
776
+ {
777
+ goto lbl_1;
778
+ }
779
+
780
+ /*
781
+ * Cask-Karp solver
782
+ * Prepare coefficients table.
783
+ * Check it for errors
784
+ */
785
+ ae_vector_set_length(&state->rka, 6, _state);
786
+ state->rka.ptr.p_double[0] = (double)(0);
787
+ state->rka.ptr.p_double[1] = (double)1/(double)5;
788
+ state->rka.ptr.p_double[2] = (double)3/(double)10;
789
+ state->rka.ptr.p_double[3] = (double)3/(double)5;
790
+ state->rka.ptr.p_double[4] = (double)(1);
791
+ state->rka.ptr.p_double[5] = (double)7/(double)8;
792
+ ae_matrix_set_length(&state->rkb, 6, 5, _state);
793
+ state->rkb.ptr.pp_double[1][0] = (double)1/(double)5;
794
+ state->rkb.ptr.pp_double[2][0] = (double)3/(double)40;
795
+ state->rkb.ptr.pp_double[2][1] = (double)9/(double)40;
796
+ state->rkb.ptr.pp_double[3][0] = (double)3/(double)10;
797
+ state->rkb.ptr.pp_double[3][1] = -(double)9/(double)10;
798
+ state->rkb.ptr.pp_double[3][2] = (double)6/(double)5;
799
+ state->rkb.ptr.pp_double[4][0] = -(double)11/(double)54;
800
+ state->rkb.ptr.pp_double[4][1] = (double)5/(double)2;
801
+ state->rkb.ptr.pp_double[4][2] = -(double)70/(double)27;
802
+ state->rkb.ptr.pp_double[4][3] = (double)35/(double)27;
803
+ state->rkb.ptr.pp_double[5][0] = (double)1631/(double)55296;
804
+ state->rkb.ptr.pp_double[5][1] = (double)175/(double)512;
805
+ state->rkb.ptr.pp_double[5][2] = (double)575/(double)13824;
806
+ state->rkb.ptr.pp_double[5][3] = (double)44275/(double)110592;
807
+ state->rkb.ptr.pp_double[5][4] = (double)253/(double)4096;
808
+ ae_vector_set_length(&state->rkc, 6, _state);
809
+ state->rkc.ptr.p_double[0] = (double)37/(double)378;
810
+ state->rkc.ptr.p_double[1] = (double)(0);
811
+ state->rkc.ptr.p_double[2] = (double)250/(double)621;
812
+ state->rkc.ptr.p_double[3] = (double)125/(double)594;
813
+ state->rkc.ptr.p_double[4] = (double)(0);
814
+ state->rkc.ptr.p_double[5] = (double)512/(double)1771;
815
+ ae_vector_set_length(&state->rkcs, 6, _state);
816
+ state->rkcs.ptr.p_double[0] = (double)2825/(double)27648;
817
+ state->rkcs.ptr.p_double[1] = (double)(0);
818
+ state->rkcs.ptr.p_double[2] = (double)18575/(double)48384;
819
+ state->rkcs.ptr.p_double[3] = (double)13525/(double)55296;
820
+ state->rkcs.ptr.p_double[4] = (double)277/(double)14336;
821
+ state->rkcs.ptr.p_double[5] = (double)1/(double)4;
822
+ ae_matrix_set_length(&state->rkk, 6, n, _state);
823
+
824
+ /*
825
+ * Main cycle consists of two iterations:
826
+ * * outer where we travel from X[i-1] to X[i]
827
+ * * inner where we travel inside [X[i-1],X[i]]
828
+ */
829
+ ae_matrix_set_length(&state->ytbl, m, n, _state);
830
+ ae_vector_set_length(&state->escale, n, _state);
831
+ ae_vector_set_length(&state->yn, n, _state);
832
+ ae_vector_set_length(&state->yns, n, _state);
833
+ xc = state->xg.ptr.p_double[0];
834
+ ae_v_move(&state->ytbl.ptr.pp_double[0][0], 1, &state->yc.ptr.p_double[0], 1, ae_v_len(0,n-1));
835
+ for(j=0; j<=n-1; j++)
836
+ {
837
+ state->escale.ptr.p_double[j] = (double)(0);
838
+ }
839
+ i = 1;
840
+ lbl_3:
841
+ if( i>m-1 )
842
+ {
843
+ goto lbl_5;
844
+ }
845
+
846
+ /*
847
+ * begin inner iteration
848
+ */
849
+ lbl_6:
850
+ if( ae_false )
851
+ {
852
+ goto lbl_7;
853
+ }
854
+
855
+ /*
856
+ * truncate step if needed (beyond right boundary).
857
+ * determine should we store X or not
858
+ */
859
+ if( ae_fp_greater_eq(xc+h,state->xg.ptr.p_double[i]) )
860
+ {
861
+ h = state->xg.ptr.p_double[i]-xc;
862
+ gridpoint = ae_true;
863
+ }
864
+ else
865
+ {
866
+ gridpoint = ae_false;
867
+ }
868
+
869
+ /*
870
+ * Update error scale maximums
871
+ *
872
+ * These maximums are initialized by zeros,
873
+ * then updated every iterations.
874
+ */
875
+ for(j=0; j<=n-1; j++)
876
+ {
877
+ state->escale.ptr.p_double[j] = ae_maxreal(state->escale.ptr.p_double[j], ae_fabs(state->yc.ptr.p_double[j], _state), _state);
878
+ }
879
+
880
+ /*
881
+ * make one step:
882
+ * 1. calculate all info needed to do step
883
+ * 2. update errors scale maximums using values/derivatives
884
+ * obtained during (1)
885
+ *
886
+ * Take into account that we use scaling of X to reduce task
887
+ * to the form where x[0] < x[1] < ... < x[n-1]. So X is
888
+ * replaced by x=xscale*t, and dy/dx=f(y,x) is replaced
889
+ * by dy/dt=xscale*f(y,xscale*t).
890
+ */
891
+ ae_v_move(&state->yn.ptr.p_double[0], 1, &state->yc.ptr.p_double[0], 1, ae_v_len(0,n-1));
892
+ ae_v_move(&state->yns.ptr.p_double[0], 1, &state->yc.ptr.p_double[0], 1, ae_v_len(0,n-1));
893
+ k = 0;
894
+ lbl_8:
895
+ if( k>5 )
896
+ {
897
+ goto lbl_10;
898
+ }
899
+
900
+ /*
901
+ * prepare data for the next update of YN/YNS
902
+ */
903
+ state->x = state->xscale*(xc+state->rka.ptr.p_double[k]*h);
904
+ ae_v_move(&state->y.ptr.p_double[0], 1, &state->yc.ptr.p_double[0], 1, ae_v_len(0,n-1));
905
+ for(j=0; j<=k-1; j++)
906
+ {
907
+ v = state->rkb.ptr.pp_double[k][j];
908
+ ae_v_addd(&state->y.ptr.p_double[0], 1, &state->rkk.ptr.pp_double[j][0], 1, ae_v_len(0,n-1), v);
909
+ }
910
+ state->needdy = ae_true;
911
+ state->rstate.stage = 0;
912
+ goto lbl_rcomm;
913
+ lbl_0:
914
+ state->needdy = ae_false;
915
+ state->repnfev = state->repnfev+1;
916
+ v = h*state->xscale;
917
+ ae_v_moved(&state->rkk.ptr.pp_double[k][0], 1, &state->dy.ptr.p_double[0], 1, ae_v_len(0,n-1), v);
918
+
919
+ /*
920
+ * update YN/YNS
921
+ */
922
+ v = state->rkc.ptr.p_double[k];
923
+ ae_v_addd(&state->yn.ptr.p_double[0], 1, &state->rkk.ptr.pp_double[k][0], 1, ae_v_len(0,n-1), v);
924
+ v = state->rkcs.ptr.p_double[k];
925
+ ae_v_addd(&state->yns.ptr.p_double[0], 1, &state->rkk.ptr.pp_double[k][0], 1, ae_v_len(0,n-1), v);
926
+ k = k+1;
927
+ goto lbl_8;
928
+ lbl_10:
929
+
930
+ /*
931
+ * estimate error
932
+ */
933
+ err = (double)(0);
934
+ for(j=0; j<=n-1; j++)
935
+ {
936
+ if( !state->fraceps )
937
+ {
938
+
939
+ /*
940
+ * absolute error is estimated
941
+ */
942
+ err = ae_maxreal(err, ae_fabs(state->yn.ptr.p_double[j]-state->yns.ptr.p_double[j], _state), _state);
943
+ }
944
+ else
945
+ {
946
+
947
+ /*
948
+ * Relative error is estimated
949
+ */
950
+ v = state->escale.ptr.p_double[j];
951
+ if( ae_fp_eq(v,(double)(0)) )
952
+ {
953
+ v = (double)(1);
954
+ }
955
+ err = ae_maxreal(err, ae_fabs(state->yn.ptr.p_double[j]-state->yns.ptr.p_double[j], _state)/v, _state);
956
+ }
957
+ }
958
+
959
+ /*
960
+ * calculate new step, restart if necessary
961
+ */
962
+ if( ae_fp_less_eq(maxgrowpow*err,state->eps) )
963
+ {
964
+ h2 = odesolver_odesolvermaxgrow*h;
965
+ }
966
+ else
967
+ {
968
+ h2 = h*ae_pow(state->eps/err, 0.2, _state);
969
+ }
970
+ if( ae_fp_less(h2,h/odesolver_odesolvermaxshrink) )
971
+ {
972
+ h2 = h/odesolver_odesolvermaxshrink;
973
+ }
974
+ if( ae_fp_greater(err,state->eps) )
975
+ {
976
+ h = ae_minreal(h2, odesolver_odesolverguaranteeddecay*h, _state);
977
+ goto lbl_6;
978
+ }
979
+
980
+ /*
981
+ * advance position
982
+ */
983
+ xc = xc+h;
984
+ ae_v_move(&state->yc.ptr.p_double[0], 1, &state->yn.ptr.p_double[0], 1, ae_v_len(0,n-1));
985
+
986
+ /*
987
+ * update H
988
+ */
989
+ h = h2;
990
+
991
+ /*
992
+ * break on grid point
993
+ */
994
+ if( gridpoint )
995
+ {
996
+ goto lbl_7;
997
+ }
998
+ goto lbl_6;
999
+ lbl_7:
1000
+
1001
+ /*
1002
+ * save result
1003
+ */
1004
+ ae_v_move(&state->ytbl.ptr.pp_double[i][0], 1, &state->yc.ptr.p_double[0], 1, ae_v_len(0,n-1));
1005
+ i = i+1;
1006
+ goto lbl_3;
1007
+ lbl_5:
1008
+ state->repterminationtype = 1;
1009
+ result = ae_false;
1010
+ return result;
1011
+ lbl_1:
1012
+ result = ae_false;
1013
+ return result;
1014
+
1015
+ /*
1016
+ * Saving state
1017
+ */
1018
+ lbl_rcomm:
1019
+ result = ae_true;
1020
+ state->rstate.ia.ptr.p_int[0] = n;
1021
+ state->rstate.ia.ptr.p_int[1] = m;
1022
+ state->rstate.ia.ptr.p_int[2] = i;
1023
+ state->rstate.ia.ptr.p_int[3] = j;
1024
+ state->rstate.ia.ptr.p_int[4] = k;
1025
+ state->rstate.ia.ptr.p_int[5] = klimit;
1026
+ state->rstate.ba.ptr.p_bool[0] = gridpoint;
1027
+ state->rstate.ra.ptr.p_double[0] = xc;
1028
+ state->rstate.ra.ptr.p_double[1] = v;
1029
+ state->rstate.ra.ptr.p_double[2] = h;
1030
+ state->rstate.ra.ptr.p_double[3] = h2;
1031
+ state->rstate.ra.ptr.p_double[4] = err;
1032
+ state->rstate.ra.ptr.p_double[5] = maxgrowpow;
1033
+ return result;
1034
+ }
1035
+
1036
+
1037
+ /*************************************************************************
1038
+ ODE solver results
1039
+
1040
+ Called after OdeSolverIteration returned False.
1041
+
1042
+ INPUT PARAMETERS:
1043
+ State - algorithm state (used by OdeSolverIteration).
1044
+
1045
+ OUTPUT PARAMETERS:
1046
+ M - number of tabulated values, M>=1
1047
+ XTbl - array[0..M-1], values of X
1048
+ YTbl - array[0..M-1,0..N-1], values of Y in X[i]
1049
+ Rep - solver report:
1050
+ * Rep.TerminationType completetion code:
1051
+ * -2 X is not ordered by ascending/descending or
1052
+ there are non-distinct X[], i.e. X[i]=X[i+1]
1053
+ * -1 incorrect parameters were specified
1054
+ * 1 task has been solved
1055
+ * Rep.NFEV contains number of function calculations
1056
+
1057
+ -- ALGLIB --
1058
+ Copyright 01.09.2009 by Bochkanov Sergey
1059
+ *************************************************************************/
1060
+ void odesolverresults(const odesolverstate* state,
1061
+ ae_int_t* m,
1062
+ /* Real */ ae_vector* xtbl,
1063
+ /* Real */ ae_matrix* ytbl,
1064
+ odesolverreport* rep,
1065
+ ae_state *_state)
1066
+ {
1067
+ double v;
1068
+ ae_int_t i;
1069
+
1070
+ *m = 0;
1071
+ ae_vector_clear(xtbl);
1072
+ ae_matrix_clear(ytbl);
1073
+ _odesolverreport_clear(rep);
1074
+
1075
+ rep->terminationtype = state->repterminationtype;
1076
+ if( rep->terminationtype>0 )
1077
+ {
1078
+ *m = state->m;
1079
+ rep->nfev = state->repnfev;
1080
+ ae_vector_set_length(xtbl, state->m, _state);
1081
+ v = state->xscale;
1082
+ ae_v_moved(&xtbl->ptr.p_double[0], 1, &state->xg.ptr.p_double[0], 1, ae_v_len(0,state->m-1), v);
1083
+ ae_matrix_set_length(ytbl, state->m, state->n, _state);
1084
+ for(i=0; i<=state->m-1; i++)
1085
+ {
1086
+ ae_v_move(&ytbl->ptr.pp_double[i][0], 1, &state->ytbl.ptr.pp_double[i][0], 1, ae_v_len(0,state->n-1));
1087
+ }
1088
+ }
1089
+ else
1090
+ {
1091
+ rep->nfev = 0;
1092
+ }
1093
+ }
1094
+
1095
+
1096
+ /*************************************************************************
1097
+ Internal initialization subroutine
1098
+ *************************************************************************/
1099
+ static void odesolver_odesolverinit(ae_int_t solvertype,
1100
+ /* Real */ const ae_vector* y,
1101
+ ae_int_t n,
1102
+ /* Real */ const ae_vector* x,
1103
+ ae_int_t m,
1104
+ double eps,
1105
+ double h,
1106
+ odesolverstate* state,
1107
+ ae_state *_state)
1108
+ {
1109
+ ae_int_t i;
1110
+ double v;
1111
+
1112
+ _odesolverstate_clear(state);
1113
+
1114
+
1115
+ /*
1116
+ * Prepare RComm
1117
+ */
1118
+ ae_vector_set_length(&state->rstate.ia, 5+1, _state);
1119
+ ae_vector_set_length(&state->rstate.ba, 0+1, _state);
1120
+ ae_vector_set_length(&state->rstate.ra, 5+1, _state);
1121
+ state->rstate.stage = -1;
1122
+ state->needdy = ae_false;
1123
+
1124
+ /*
1125
+ * check parameters.
1126
+ */
1127
+ if( (n<=0||m<1)||ae_fp_eq(eps,(double)(0)) )
1128
+ {
1129
+ state->repterminationtype = -1;
1130
+ return;
1131
+ }
1132
+ if( ae_fp_less(h,(double)(0)) )
1133
+ {
1134
+ h = -h;
1135
+ }
1136
+
1137
+ /*
1138
+ * quick exit if necessary.
1139
+ * after this block we assume that M>1
1140
+ */
1141
+ if( m==1 )
1142
+ {
1143
+ state->repnfev = 0;
1144
+ state->repterminationtype = 1;
1145
+ ae_matrix_set_length(&state->ytbl, 1, n, _state);
1146
+ ae_v_move(&state->ytbl.ptr.pp_double[0][0], 1, &y->ptr.p_double[0], 1, ae_v_len(0,n-1));
1147
+ ae_vector_set_length(&state->xg, m, _state);
1148
+ ae_v_move(&state->xg.ptr.p_double[0], 1, &x->ptr.p_double[0], 1, ae_v_len(0,m-1));
1149
+ return;
1150
+ }
1151
+
1152
+ /*
1153
+ * check again: correct order of X[]
1154
+ */
1155
+ if( ae_fp_eq(x->ptr.p_double[1],x->ptr.p_double[0]) )
1156
+ {
1157
+ state->repterminationtype = -2;
1158
+ return;
1159
+ }
1160
+ for(i=1; i<=m-1; i++)
1161
+ {
1162
+ if( (ae_fp_greater(x->ptr.p_double[1],x->ptr.p_double[0])&&ae_fp_less_eq(x->ptr.p_double[i],x->ptr.p_double[i-1]))||(ae_fp_less(x->ptr.p_double[1],x->ptr.p_double[0])&&ae_fp_greater_eq(x->ptr.p_double[i],x->ptr.p_double[i-1])) )
1163
+ {
1164
+ state->repterminationtype = -2;
1165
+ return;
1166
+ }
1167
+ }
1168
+
1169
+ /*
1170
+ * auto-select H if necessary
1171
+ */
1172
+ if( ae_fp_eq(h,(double)(0)) )
1173
+ {
1174
+ v = ae_fabs(x->ptr.p_double[1]-x->ptr.p_double[0], _state);
1175
+ for(i=2; i<=m-1; i++)
1176
+ {
1177
+ v = ae_minreal(v, ae_fabs(x->ptr.p_double[i]-x->ptr.p_double[i-1], _state), _state);
1178
+ }
1179
+ h = 0.001*v;
1180
+ }
1181
+
1182
+ /*
1183
+ * store parameters
1184
+ */
1185
+ state->n = n;
1186
+ state->m = m;
1187
+ state->h = h;
1188
+ state->eps = ae_fabs(eps, _state);
1189
+ state->fraceps = ae_fp_less(eps,(double)(0));
1190
+ ae_vector_set_length(&state->xg, m, _state);
1191
+ ae_v_move(&state->xg.ptr.p_double[0], 1, &x->ptr.p_double[0], 1, ae_v_len(0,m-1));
1192
+ if( ae_fp_greater(x->ptr.p_double[1],x->ptr.p_double[0]) )
1193
+ {
1194
+ state->xscale = (double)(1);
1195
+ }
1196
+ else
1197
+ {
1198
+ state->xscale = (double)(-1);
1199
+ ae_v_muld(&state->xg.ptr.p_double[0], 1, ae_v_len(0,m-1), -1.0);
1200
+ }
1201
+ ae_vector_set_length(&state->yc, n, _state);
1202
+ ae_v_move(&state->yc.ptr.p_double[0], 1, &y->ptr.p_double[0], 1, ae_v_len(0,n-1));
1203
+ state->solvertype = solvertype;
1204
+ state->repterminationtype = 0;
1205
+
1206
+ /*
1207
+ * Allocate arrays
1208
+ */
1209
+ ae_vector_set_length(&state->y, n, _state);
1210
+ ae_vector_set_length(&state->dy, n, _state);
1211
+ }
1212
+
1213
+
1214
+ void _odesolverstate_init(void* _p, ae_state *_state, ae_bool make_automatic)
1215
+ {
1216
+ odesolverstate *p = (odesolverstate*)_p;
1217
+ ae_touch_ptr((void*)p);
1218
+ ae_vector_init(&p->yc, 0, DT_REAL, _state, make_automatic);
1219
+ ae_vector_init(&p->escale, 0, DT_REAL, _state, make_automatic);
1220
+ ae_vector_init(&p->xg, 0, DT_REAL, _state, make_automatic);
1221
+ ae_vector_init(&p->y, 0, DT_REAL, _state, make_automatic);
1222
+ ae_vector_init(&p->dy, 0, DT_REAL, _state, make_automatic);
1223
+ ae_matrix_init(&p->ytbl, 0, 0, DT_REAL, _state, make_automatic);
1224
+ ae_vector_init(&p->yn, 0, DT_REAL, _state, make_automatic);
1225
+ ae_vector_init(&p->yns, 0, DT_REAL, _state, make_automatic);
1226
+ ae_vector_init(&p->rka, 0, DT_REAL, _state, make_automatic);
1227
+ ae_vector_init(&p->rkc, 0, DT_REAL, _state, make_automatic);
1228
+ ae_vector_init(&p->rkcs, 0, DT_REAL, _state, make_automatic);
1229
+ ae_matrix_init(&p->rkb, 0, 0, DT_REAL, _state, make_automatic);
1230
+ ae_matrix_init(&p->rkk, 0, 0, DT_REAL, _state, make_automatic);
1231
+ _rcommstate_init(&p->rstate, _state, make_automatic);
1232
+ }
1233
+
1234
+
1235
+ void _odesolverstate_init_copy(void* _dst, const void* _src, ae_state *_state, ae_bool make_automatic)
1236
+ {
1237
+ odesolverstate *dst = (odesolverstate*)_dst;
1238
+ const odesolverstate *src = (const odesolverstate*)_src;
1239
+ dst->n = src->n;
1240
+ dst->m = src->m;
1241
+ dst->xscale = src->xscale;
1242
+ dst->h = src->h;
1243
+ dst->eps = src->eps;
1244
+ dst->fraceps = src->fraceps;
1245
+ ae_vector_init_copy(&dst->yc, &src->yc, _state, make_automatic);
1246
+ ae_vector_init_copy(&dst->escale, &src->escale, _state, make_automatic);
1247
+ ae_vector_init_copy(&dst->xg, &src->xg, _state, make_automatic);
1248
+ dst->solvertype = src->solvertype;
1249
+ dst->needdy = src->needdy;
1250
+ dst->x = src->x;
1251
+ ae_vector_init_copy(&dst->y, &src->y, _state, make_automatic);
1252
+ ae_vector_init_copy(&dst->dy, &src->dy, _state, make_automatic);
1253
+ ae_matrix_init_copy(&dst->ytbl, &src->ytbl, _state, make_automatic);
1254
+ dst->repterminationtype = src->repterminationtype;
1255
+ dst->repnfev = src->repnfev;
1256
+ ae_vector_init_copy(&dst->yn, &src->yn, _state, make_automatic);
1257
+ ae_vector_init_copy(&dst->yns, &src->yns, _state, make_automatic);
1258
+ ae_vector_init_copy(&dst->rka, &src->rka, _state, make_automatic);
1259
+ ae_vector_init_copy(&dst->rkc, &src->rkc, _state, make_automatic);
1260
+ ae_vector_init_copy(&dst->rkcs, &src->rkcs, _state, make_automatic);
1261
+ ae_matrix_init_copy(&dst->rkb, &src->rkb, _state, make_automatic);
1262
+ ae_matrix_init_copy(&dst->rkk, &src->rkk, _state, make_automatic);
1263
+ _rcommstate_init_copy(&dst->rstate, &src->rstate, _state, make_automatic);
1264
+ }
1265
+
1266
+
1267
+ void _odesolverstate_clear(void* _p)
1268
+ {
1269
+ odesolverstate *p = (odesolverstate*)_p;
1270
+ ae_touch_ptr((void*)p);
1271
+ ae_vector_clear(&p->yc);
1272
+ ae_vector_clear(&p->escale);
1273
+ ae_vector_clear(&p->xg);
1274
+ ae_vector_clear(&p->y);
1275
+ ae_vector_clear(&p->dy);
1276
+ ae_matrix_clear(&p->ytbl);
1277
+ ae_vector_clear(&p->yn);
1278
+ ae_vector_clear(&p->yns);
1279
+ ae_vector_clear(&p->rka);
1280
+ ae_vector_clear(&p->rkc);
1281
+ ae_vector_clear(&p->rkcs);
1282
+ ae_matrix_clear(&p->rkb);
1283
+ ae_matrix_clear(&p->rkk);
1284
+ _rcommstate_clear(&p->rstate);
1285
+ }
1286
+
1287
+
1288
+ void _odesolverstate_destroy(void* _p)
1289
+ {
1290
+ odesolverstate *p = (odesolverstate*)_p;
1291
+ ae_touch_ptr((void*)p);
1292
+ ae_vector_destroy(&p->yc);
1293
+ ae_vector_destroy(&p->escale);
1294
+ ae_vector_destroy(&p->xg);
1295
+ ae_vector_destroy(&p->y);
1296
+ ae_vector_destroy(&p->dy);
1297
+ ae_matrix_destroy(&p->ytbl);
1298
+ ae_vector_destroy(&p->yn);
1299
+ ae_vector_destroy(&p->yns);
1300
+ ae_vector_destroy(&p->rka);
1301
+ ae_vector_destroy(&p->rkc);
1302
+ ae_vector_destroy(&p->rkcs);
1303
+ ae_matrix_destroy(&p->rkb);
1304
+ ae_matrix_destroy(&p->rkk);
1305
+ _rcommstate_destroy(&p->rstate);
1306
+ }
1307
+
1308
+
1309
+ void _odesolverreport_init(void* _p, ae_state *_state, ae_bool make_automatic)
1310
+ {
1311
+ odesolverreport *p = (odesolverreport*)_p;
1312
+ ae_touch_ptr((void*)p);
1313
+ }
1314
+
1315
+
1316
+ void _odesolverreport_init_copy(void* _dst, const void* _src, ae_state *_state, ae_bool make_automatic)
1317
+ {
1318
+ odesolverreport *dst = (odesolverreport*)_dst;
1319
+ const odesolverreport *src = (const odesolverreport*)_src;
1320
+ dst->nfev = src->nfev;
1321
+ dst->terminationtype = src->terminationtype;
1322
+ }
1323
+
1324
+
1325
+ void _odesolverreport_clear(void* _p)
1326
+ {
1327
+ odesolverreport *p = (odesolverreport*)_p;
1328
+ ae_touch_ptr((void*)p);
1329
+ }
1330
+
1331
+
1332
+ void _odesolverreport_destroy(void* _p)
1333
+ {
1334
+ odesolverreport *p = (odesolverreport*)_p;
1335
+ ae_touch_ptr((void*)p);
1336
+ }
1337
+
1338
+
1339
+ #endif
1340
+
1341
+ }
1342
+