alglib4 0.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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,4249 @@
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 "integration.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_GQ) || !defined(AE_PARTIAL_BUILD)
45
+ /*************************************************************************
46
+ Computation of nodes and weights for a Gauss quadrature formula
47
+
48
+ The algorithm generates the N-point Gauss quadrature formula with weight
49
+ function given by coefficients alpha and beta of a recurrence relation
50
+ which generates a system of orthogonal polynomials:
51
+
52
+ P-1(x) = 0
53
+ P0(x) = 1
54
+ Pn+1(x) = (x-alpha(n))*Pn(x) - beta(n)*Pn-1(x)
55
+
56
+ and zeroth moment Mu0
57
+
58
+ Mu0 = integral(W(x)dx,a,b)
59
+
60
+ INPUT PARAMETERS:
61
+ Alpha - array[0..N-1], alpha coefficients
62
+ Beta - array[0..N-1], beta coefficients
63
+ Zero-indexed element is not used and may be arbitrary.
64
+ Beta[I]>0.
65
+ Mu0 - zeroth moment of the weight function.
66
+ N - number of nodes of the quadrature formula, N>=1
67
+
68
+ OUTPUT PARAMETERS:
69
+ Info - error code:
70
+ * -3 internal eigenproblem solver hasn't converged
71
+ * -2 Beta[i]<=0
72
+ * -1 incorrect N was passed
73
+ * 1 OK
74
+ X - array[0..N-1] - array of quadrature nodes,
75
+ in ascending order.
76
+ W - array[0..N-1] - array of quadrature weights.
77
+
78
+ -- ALGLIB --
79
+ Copyright 2005-2009 by Bochkanov Sergey
80
+ *************************************************************************/
81
+ void gqgeneraterec(const real_1d_array &alpha, const real_1d_array &beta, const double mu0, const ae_int_t n, ae_int_t &info, real_1d_array &x, real_1d_array &w, const xparams _xparams)
82
+ {
83
+ jmp_buf _break_jump;
84
+ alglib_impl::ae_state _alglib_env_state;
85
+ alglib_impl::ae_state_init(&_alglib_env_state);
86
+ if( setjmp(_break_jump) )
87
+ {
88
+ #if !defined(AE_NO_EXCEPTIONS)
89
+ _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
90
+ #else
91
+ _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
92
+ return;
93
+ #endif
94
+ }
95
+ ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
96
+ if( _xparams.flags!=(alglib_impl::ae_uint64_t)0x0 )
97
+ ae_state_set_flags(&_alglib_env_state, _xparams.flags);
98
+ alglib_impl::gqgeneraterec(alpha.c_ptr(), beta.c_ptr(), mu0, n, &info, x.c_ptr(), w.c_ptr(), &_alglib_env_state);
99
+ alglib_impl::ae_state_clear(&_alglib_env_state);
100
+ return;
101
+ }
102
+
103
+ /*************************************************************************
104
+ Computation of nodes and weights for a Gauss-Lobatto quadrature formula
105
+
106
+ The algorithm generates the N-point Gauss-Lobatto quadrature formula with
107
+ weight function given by coefficients alpha and beta of a recurrence which
108
+ generates a system of orthogonal polynomials.
109
+
110
+ P-1(x) = 0
111
+ P0(x) = 1
112
+ Pn+1(x) = (x-alpha(n))*Pn(x) - beta(n)*Pn-1(x)
113
+
114
+ and zeroth moment Mu0
115
+
116
+ Mu0 = integral(W(x)dx,a,b)
117
+
118
+ INPUT PARAMETERS:
119
+ Alpha - array[0..N-2], alpha coefficients
120
+ Beta - array[0..N-2], beta coefficients.
121
+ Zero-indexed element is not used, may be arbitrary.
122
+ Beta[I]>0
123
+ Mu0 - zeroth moment of the weighting function.
124
+ A - left boundary of the integration interval.
125
+ B - right boundary of the integration interval.
126
+ N - number of nodes of the quadrature formula, N>=3
127
+ (including the left and right boundary nodes).
128
+
129
+ OUTPUT PARAMETERS:
130
+ Info - error code:
131
+ * -3 internal eigenproblem solver hasn't converged
132
+ * -2 Beta[i]<=0
133
+ * -1 incorrect N was passed
134
+ * 1 OK
135
+ X - array[0..N-1] - array of quadrature nodes,
136
+ in ascending order.
137
+ W - array[0..N-1] - array of quadrature weights.
138
+
139
+ -- ALGLIB --
140
+ Copyright 2005-2009 by Bochkanov Sergey
141
+ *************************************************************************/
142
+ void gqgenerategausslobattorec(const real_1d_array &alpha, const real_1d_array &beta, const double mu0, const double a, const double b, const ae_int_t n, ae_int_t &info, real_1d_array &x, real_1d_array &w, const xparams _xparams)
143
+ {
144
+ jmp_buf _break_jump;
145
+ alglib_impl::ae_state _alglib_env_state;
146
+ alglib_impl::ae_state_init(&_alglib_env_state);
147
+ if( setjmp(_break_jump) )
148
+ {
149
+ #if !defined(AE_NO_EXCEPTIONS)
150
+ _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
151
+ #else
152
+ _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
153
+ return;
154
+ #endif
155
+ }
156
+ ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
157
+ if( _xparams.flags!=(alglib_impl::ae_uint64_t)0x0 )
158
+ ae_state_set_flags(&_alglib_env_state, _xparams.flags);
159
+ alglib_impl::gqgenerategausslobattorec(alpha.c_ptr(), beta.c_ptr(), mu0, a, b, n, &info, x.c_ptr(), w.c_ptr(), &_alglib_env_state);
160
+ alglib_impl::ae_state_clear(&_alglib_env_state);
161
+ return;
162
+ }
163
+
164
+ /*************************************************************************
165
+ Computation of nodes and weights for a Gauss-Radau quadrature formula
166
+
167
+ The algorithm generates the N-point Gauss-Radau quadrature formula with
168
+ weight function given by the coefficients alpha and beta of a recurrence
169
+ which generates a system of orthogonal polynomials.
170
+
171
+ P-1(x) = 0
172
+ P0(x) = 1
173
+ Pn+1(x) = (x-alpha(n))*Pn(x) - beta(n)*Pn-1(x)
174
+
175
+ and zeroth moment Mu0
176
+
177
+ Mu0 = integral(W(x)dx,a,b)
178
+
179
+ INPUT PARAMETERS:
180
+ Alpha - array[0..N-2], alpha coefficients.
181
+ Beta - array[0..N-1], beta coefficients
182
+ Zero-indexed element is not used.
183
+ Beta[I]>0
184
+ Mu0 - zeroth moment of the weighting function.
185
+ A - left boundary of the integration interval.
186
+ N - number of nodes of the quadrature formula, N>=2
187
+ (including the left boundary node).
188
+
189
+ OUTPUT PARAMETERS:
190
+ Info - error code:
191
+ * -3 internal eigenproblem solver hasn't converged
192
+ * -2 Beta[i]<=0
193
+ * -1 incorrect N was passed
194
+ * 1 OK
195
+ X - array[0..N-1] - array of quadrature nodes,
196
+ in ascending order.
197
+ W - array[0..N-1] - array of quadrature weights.
198
+
199
+
200
+ -- ALGLIB --
201
+ Copyright 2005-2009 by Bochkanov Sergey
202
+ *************************************************************************/
203
+ void gqgenerategaussradaurec(const real_1d_array &alpha, const real_1d_array &beta, const double mu0, const double a, const ae_int_t n, ae_int_t &info, real_1d_array &x, real_1d_array &w, const xparams _xparams)
204
+ {
205
+ jmp_buf _break_jump;
206
+ alglib_impl::ae_state _alglib_env_state;
207
+ alglib_impl::ae_state_init(&_alglib_env_state);
208
+ if( setjmp(_break_jump) )
209
+ {
210
+ #if !defined(AE_NO_EXCEPTIONS)
211
+ _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
212
+ #else
213
+ _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
214
+ return;
215
+ #endif
216
+ }
217
+ ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
218
+ if( _xparams.flags!=(alglib_impl::ae_uint64_t)0x0 )
219
+ ae_state_set_flags(&_alglib_env_state, _xparams.flags);
220
+ alglib_impl::gqgenerategaussradaurec(alpha.c_ptr(), beta.c_ptr(), mu0, a, n, &info, x.c_ptr(), w.c_ptr(), &_alglib_env_state);
221
+ alglib_impl::ae_state_clear(&_alglib_env_state);
222
+ return;
223
+ }
224
+
225
+ /*************************************************************************
226
+ Returns nodes/weights for Gauss-Legendre quadrature on [-1,1] with N
227
+ nodes.
228
+
229
+ INPUT PARAMETERS:
230
+ N - number of nodes, >=1
231
+
232
+ OUTPUT PARAMETERS:
233
+ Info - error code:
234
+ * -4 an error was detected when calculating
235
+ weights/nodes. N is too large to obtain
236
+ weights/nodes with high enough accuracy.
237
+ Try to use multiple precision version.
238
+ * -3 internal eigenproblem solver hasn't converged
239
+ * -1 incorrect N was passed
240
+ * +1 OK
241
+ X - array[0..N-1] - array of quadrature nodes,
242
+ in ascending order.
243
+ W - array[0..N-1] - array of quadrature weights.
244
+
245
+
246
+ -- ALGLIB --
247
+ Copyright 12.05.2009 by Bochkanov Sergey
248
+ *************************************************************************/
249
+ void gqgenerategausslegendre(const ae_int_t n, ae_int_t &info, real_1d_array &x, real_1d_array &w, const xparams _xparams)
250
+ {
251
+ jmp_buf _break_jump;
252
+ alglib_impl::ae_state _alglib_env_state;
253
+ alglib_impl::ae_state_init(&_alglib_env_state);
254
+ if( setjmp(_break_jump) )
255
+ {
256
+ #if !defined(AE_NO_EXCEPTIONS)
257
+ _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
258
+ #else
259
+ _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
260
+ return;
261
+ #endif
262
+ }
263
+ ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
264
+ if( _xparams.flags!=(alglib_impl::ae_uint64_t)0x0 )
265
+ ae_state_set_flags(&_alglib_env_state, _xparams.flags);
266
+ alglib_impl::gqgenerategausslegendre(n, &info, x.c_ptr(), w.c_ptr(), &_alglib_env_state);
267
+ alglib_impl::ae_state_clear(&_alglib_env_state);
268
+ return;
269
+ }
270
+
271
+ /*************************************************************************
272
+ Returns nodes/weights for Gauss-Jacobi quadrature on [-1,1] with weight
273
+ function W(x)=Power(1-x,Alpha)*Power(1+x,Beta).
274
+
275
+ INPUT PARAMETERS:
276
+ N - number of nodes, >=1
277
+ Alpha - power-law coefficient, Alpha>-1
278
+ Beta - power-law coefficient, Beta>-1
279
+
280
+ OUTPUT PARAMETERS:
281
+ Info - error code:
282
+ * -4 an error was detected when calculating
283
+ weights/nodes. Alpha or Beta are too close
284
+ to -1 to obtain weights/nodes with high enough
285
+ accuracy, or, may be, N is too large. Try to
286
+ use multiple precision version.
287
+ * -3 internal eigenproblem solver hasn't converged
288
+ * -1 incorrect N/Alpha/Beta was passed
289
+ * +1 OK
290
+ X - array[0..N-1] - array of quadrature nodes,
291
+ in ascending order.
292
+ W - array[0..N-1] - array of quadrature weights.
293
+
294
+
295
+ -- ALGLIB --
296
+ Copyright 12.05.2009 by Bochkanov Sergey
297
+ *************************************************************************/
298
+ void gqgenerategaussjacobi(const ae_int_t n, const double alpha, const double beta, ae_int_t &info, real_1d_array &x, real_1d_array &w, const xparams _xparams)
299
+ {
300
+ jmp_buf _break_jump;
301
+ alglib_impl::ae_state _alglib_env_state;
302
+ alglib_impl::ae_state_init(&_alglib_env_state);
303
+ if( setjmp(_break_jump) )
304
+ {
305
+ #if !defined(AE_NO_EXCEPTIONS)
306
+ _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
307
+ #else
308
+ _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
309
+ return;
310
+ #endif
311
+ }
312
+ ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
313
+ if( _xparams.flags!=(alglib_impl::ae_uint64_t)0x0 )
314
+ ae_state_set_flags(&_alglib_env_state, _xparams.flags);
315
+ alglib_impl::gqgenerategaussjacobi(n, alpha, beta, &info, x.c_ptr(), w.c_ptr(), &_alglib_env_state);
316
+ alglib_impl::ae_state_clear(&_alglib_env_state);
317
+ return;
318
+ }
319
+
320
+ /*************************************************************************
321
+ Returns nodes/weights for Gauss-Laguerre quadrature on [0,+inf) with
322
+ weight function W(x)=Power(x,Alpha)*Exp(-x)
323
+
324
+ INPUT PARAMETERS:
325
+ N - number of nodes, >=1
326
+ Alpha - power-law coefficient, Alpha>-1
327
+
328
+ OUTPUT PARAMETERS:
329
+ Info - error code:
330
+ * -4 an error was detected when calculating
331
+ weights/nodes. Alpha is too close to -1 to
332
+ obtain weights/nodes with high enough accuracy
333
+ or, may be, N is too large. Try to use
334
+ multiple precision version.
335
+ * -3 internal eigenproblem solver hasn't converged
336
+ * -1 incorrect N/Alpha was passed
337
+ * +1 OK
338
+ X - array[0..N-1] - array of quadrature nodes,
339
+ in ascending order.
340
+ W - array[0..N-1] - array of quadrature weights.
341
+
342
+
343
+ -- ALGLIB --
344
+ Copyright 12.05.2009 by Bochkanov Sergey
345
+ *************************************************************************/
346
+ void gqgenerategausslaguerre(const ae_int_t n, const double alpha, ae_int_t &info, real_1d_array &x, real_1d_array &w, const xparams _xparams)
347
+ {
348
+ jmp_buf _break_jump;
349
+ alglib_impl::ae_state _alglib_env_state;
350
+ alglib_impl::ae_state_init(&_alglib_env_state);
351
+ if( setjmp(_break_jump) )
352
+ {
353
+ #if !defined(AE_NO_EXCEPTIONS)
354
+ _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
355
+ #else
356
+ _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
357
+ return;
358
+ #endif
359
+ }
360
+ ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
361
+ if( _xparams.flags!=(alglib_impl::ae_uint64_t)0x0 )
362
+ ae_state_set_flags(&_alglib_env_state, _xparams.flags);
363
+ alglib_impl::gqgenerategausslaguerre(n, alpha, &info, x.c_ptr(), w.c_ptr(), &_alglib_env_state);
364
+ alglib_impl::ae_state_clear(&_alglib_env_state);
365
+ return;
366
+ }
367
+
368
+ /*************************************************************************
369
+ Returns nodes/weights for Gauss-Hermite quadrature on (-inf,+inf) with
370
+ weight function W(x)=Exp(-x*x)
371
+
372
+ INPUT PARAMETERS:
373
+ N - number of nodes, >=1
374
+
375
+ OUTPUT PARAMETERS:
376
+ Info - error code:
377
+ * -4 an error was detected when calculating
378
+ weights/nodes. May be, N is too large. Try to
379
+ use multiple precision version.
380
+ * -3 internal eigenproblem solver hasn't converged
381
+ * -1 incorrect N/Alpha was passed
382
+ * +1 OK
383
+ X - array[0..N-1] - array of quadrature nodes,
384
+ in ascending order.
385
+ W - array[0..N-1] - array of quadrature weights.
386
+
387
+
388
+ -- ALGLIB --
389
+ Copyright 12.05.2009 by Bochkanov Sergey
390
+ *************************************************************************/
391
+ void gqgenerategausshermite(const ae_int_t n, ae_int_t &info, real_1d_array &x, real_1d_array &w, const xparams _xparams)
392
+ {
393
+ jmp_buf _break_jump;
394
+ alglib_impl::ae_state _alglib_env_state;
395
+ alglib_impl::ae_state_init(&_alglib_env_state);
396
+ if( setjmp(_break_jump) )
397
+ {
398
+ #if !defined(AE_NO_EXCEPTIONS)
399
+ _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
400
+ #else
401
+ _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
402
+ return;
403
+ #endif
404
+ }
405
+ ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
406
+ if( _xparams.flags!=(alglib_impl::ae_uint64_t)0x0 )
407
+ ae_state_set_flags(&_alglib_env_state, _xparams.flags);
408
+ alglib_impl::gqgenerategausshermite(n, &info, x.c_ptr(), w.c_ptr(), &_alglib_env_state);
409
+ alglib_impl::ae_state_clear(&_alglib_env_state);
410
+ return;
411
+ }
412
+ #endif
413
+
414
+ #if defined(AE_COMPILE_GKQ) || !defined(AE_PARTIAL_BUILD)
415
+ /*************************************************************************
416
+ Computation of nodes and weights of a Gauss-Kronrod quadrature formula
417
+
418
+ The algorithm generates the N-point Gauss-Kronrod quadrature formula with
419
+ weight function given by coefficients alpha and beta of a recurrence
420
+ relation which generates a system of orthogonal polynomials:
421
+
422
+ P-1(x) = 0
423
+ P0(x) = 1
424
+ Pn+1(x) = (x-alpha(n))*Pn(x) - beta(n)*Pn-1(x)
425
+
426
+ and zero moment Mu0
427
+
428
+ Mu0 = integral(W(x)dx,a,b)
429
+
430
+
431
+ INPUT PARAMETERS:
432
+ Alpha - alpha coefficients, array[0..floor(3*K/2)].
433
+ Beta - beta coefficients, array[0..ceil(3*K/2)].
434
+ Beta[0] is not used and may be arbitrary.
435
+ Beta[I]>0.
436
+ Mu0 - zeroth moment of the weight function.
437
+ N - number of nodes of the Gauss-Kronrod quadrature formula,
438
+ N >= 3,
439
+ N = 2*K+1.
440
+
441
+ OUTPUT PARAMETERS:
442
+ Info - error code:
443
+ * -5 no real and positive Gauss-Kronrod formula can
444
+ be created for such a weight function with a
445
+ given number of nodes.
446
+ * -4 N is too large, task may be ill conditioned -
447
+ x[i]=x[i+1] found.
448
+ * -3 internal eigenproblem solver hasn't converged
449
+ * -2 Beta[i]<=0
450
+ * -1 incorrect N was passed
451
+ * +1 OK
452
+ X - array[0..N-1] - array of quadrature nodes,
453
+ in ascending order.
454
+ WKronrod - array[0..N-1] - Kronrod weights
455
+ WGauss - array[0..N-1] - Gauss weights (interleaved with zeros
456
+ corresponding to extended Kronrod nodes).
457
+
458
+ -- ALGLIB --
459
+ Copyright 08.05.2009 by Bochkanov Sergey
460
+ *************************************************************************/
461
+ void gkqgeneraterec(const real_1d_array &alpha, const real_1d_array &beta, const double mu0, const ae_int_t n, ae_int_t &info, real_1d_array &x, real_1d_array &wkronrod, real_1d_array &wgauss, const xparams _xparams)
462
+ {
463
+ jmp_buf _break_jump;
464
+ alglib_impl::ae_state _alglib_env_state;
465
+ alglib_impl::ae_state_init(&_alglib_env_state);
466
+ if( setjmp(_break_jump) )
467
+ {
468
+ #if !defined(AE_NO_EXCEPTIONS)
469
+ _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
470
+ #else
471
+ _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
472
+ return;
473
+ #endif
474
+ }
475
+ ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
476
+ if( _xparams.flags!=(alglib_impl::ae_uint64_t)0x0 )
477
+ ae_state_set_flags(&_alglib_env_state, _xparams.flags);
478
+ alglib_impl::gkqgeneraterec(alpha.c_ptr(), beta.c_ptr(), mu0, n, &info, x.c_ptr(), wkronrod.c_ptr(), wgauss.c_ptr(), &_alglib_env_state);
479
+ alglib_impl::ae_state_clear(&_alglib_env_state);
480
+ return;
481
+ }
482
+
483
+ /*************************************************************************
484
+ Returns Gauss and Gauss-Kronrod nodes/weights for Gauss-Legendre
485
+ quadrature with N points.
486
+
487
+ GKQLegendreCalc (calculation) or GKQLegendreTbl (precomputed table) is
488
+ used depending on machine precision and number of nodes.
489
+
490
+ INPUT PARAMETERS:
491
+ N - number of Kronrod nodes, must be odd number, >=3.
492
+
493
+ OUTPUT PARAMETERS:
494
+ Info - error code:
495
+ * -4 an error was detected when calculating
496
+ weights/nodes. N is too large to obtain
497
+ weights/nodes with high enough accuracy.
498
+ Try to use multiple precision version.
499
+ * -3 internal eigenproblem solver hasn't converged
500
+ * -1 incorrect N was passed
501
+ * +1 OK
502
+ X - array[0..N-1] - array of quadrature nodes, ordered in
503
+ ascending order.
504
+ WKronrod - array[0..N-1] - Kronrod weights
505
+ WGauss - array[0..N-1] - Gauss weights (interleaved with zeros
506
+ corresponding to extended Kronrod nodes).
507
+
508
+
509
+ -- ALGLIB --
510
+ Copyright 12.05.2009 by Bochkanov Sergey
511
+ *************************************************************************/
512
+ void gkqgenerategausslegendre(const ae_int_t n, ae_int_t &info, real_1d_array &x, real_1d_array &wkronrod, real_1d_array &wgauss, const xparams _xparams)
513
+ {
514
+ jmp_buf _break_jump;
515
+ alglib_impl::ae_state _alglib_env_state;
516
+ alglib_impl::ae_state_init(&_alglib_env_state);
517
+ if( setjmp(_break_jump) )
518
+ {
519
+ #if !defined(AE_NO_EXCEPTIONS)
520
+ _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
521
+ #else
522
+ _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
523
+ return;
524
+ #endif
525
+ }
526
+ ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
527
+ if( _xparams.flags!=(alglib_impl::ae_uint64_t)0x0 )
528
+ ae_state_set_flags(&_alglib_env_state, _xparams.flags);
529
+ alglib_impl::gkqgenerategausslegendre(n, &info, x.c_ptr(), wkronrod.c_ptr(), wgauss.c_ptr(), &_alglib_env_state);
530
+ alglib_impl::ae_state_clear(&_alglib_env_state);
531
+ return;
532
+ }
533
+
534
+ /*************************************************************************
535
+ Returns Gauss and Gauss-Kronrod nodes/weights for Gauss-Jacobi
536
+ quadrature on [-1,1] with weight function
537
+
538
+ W(x)=Power(1-x,Alpha)*Power(1+x,Beta).
539
+
540
+ INPUT PARAMETERS:
541
+ N - number of Kronrod nodes, must be odd number, >=3.
542
+ Alpha - power-law coefficient, Alpha>-1
543
+ Beta - power-law coefficient, Beta>-1
544
+
545
+ OUTPUT PARAMETERS:
546
+ Info - error code:
547
+ * -5 no real and positive Gauss-Kronrod formula can
548
+ be created for such a weight function with a
549
+ given number of nodes.
550
+ * -4 an error was detected when calculating
551
+ weights/nodes. Alpha or Beta are too close
552
+ to -1 to obtain weights/nodes with high enough
553
+ accuracy, or, may be, N is too large. Try to
554
+ use multiple precision version.
555
+ * -3 internal eigenproblem solver hasn't converged
556
+ * -1 incorrect N was passed
557
+ * +1 OK
558
+ * +2 OK, but quadrature rule have exterior nodes,
559
+ x[0]<-1 or x[n-1]>+1
560
+ X - array[0..N-1] - array of quadrature nodes, ordered in
561
+ ascending order.
562
+ WKronrod - array[0..N-1] - Kronrod weights
563
+ WGauss - array[0..N-1] - Gauss weights (interleaved with zeros
564
+ corresponding to extended Kronrod nodes).
565
+
566
+
567
+ -- ALGLIB --
568
+ Copyright 12.05.2009 by Bochkanov Sergey
569
+ *************************************************************************/
570
+ void gkqgenerategaussjacobi(const ae_int_t n, const double alpha, const double beta, ae_int_t &info, real_1d_array &x, real_1d_array &wkronrod, real_1d_array &wgauss, const xparams _xparams)
571
+ {
572
+ jmp_buf _break_jump;
573
+ alglib_impl::ae_state _alglib_env_state;
574
+ alglib_impl::ae_state_init(&_alglib_env_state);
575
+ if( setjmp(_break_jump) )
576
+ {
577
+ #if !defined(AE_NO_EXCEPTIONS)
578
+ _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
579
+ #else
580
+ _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
581
+ return;
582
+ #endif
583
+ }
584
+ ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
585
+ if( _xparams.flags!=(alglib_impl::ae_uint64_t)0x0 )
586
+ ae_state_set_flags(&_alglib_env_state, _xparams.flags);
587
+ alglib_impl::gkqgenerategaussjacobi(n, alpha, beta, &info, x.c_ptr(), wkronrod.c_ptr(), wgauss.c_ptr(), &_alglib_env_state);
588
+ alglib_impl::ae_state_clear(&_alglib_env_state);
589
+ return;
590
+ }
591
+
592
+ /*************************************************************************
593
+ Returns Gauss and Gauss-Kronrod nodes for quadrature with N points.
594
+
595
+ Reduction to tridiagonal eigenproblem is used.
596
+
597
+ INPUT PARAMETERS:
598
+ N - number of Kronrod nodes, must be odd number, >=3.
599
+
600
+ OUTPUT PARAMETERS:
601
+ Info - error code:
602
+ * -4 an error was detected when calculating
603
+ weights/nodes. N is too large to obtain
604
+ weights/nodes with high enough accuracy.
605
+ Try to use multiple precision version.
606
+ * -3 internal eigenproblem solver hasn't converged
607
+ * -1 incorrect N was passed
608
+ * +1 OK
609
+ X - array[0..N-1] - array of quadrature nodes, ordered in
610
+ ascending order.
611
+ WKronrod - array[0..N-1] - Kronrod weights
612
+ WGauss - array[0..N-1] - Gauss weights (interleaved with zeros
613
+ corresponding to extended Kronrod nodes).
614
+
615
+ -- ALGLIB --
616
+ Copyright 12.05.2009 by Bochkanov Sergey
617
+ *************************************************************************/
618
+ void gkqlegendrecalc(const ae_int_t n, ae_int_t &info, real_1d_array &x, real_1d_array &wkronrod, real_1d_array &wgauss, const xparams _xparams)
619
+ {
620
+ jmp_buf _break_jump;
621
+ alglib_impl::ae_state _alglib_env_state;
622
+ alglib_impl::ae_state_init(&_alglib_env_state);
623
+ if( setjmp(_break_jump) )
624
+ {
625
+ #if !defined(AE_NO_EXCEPTIONS)
626
+ _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
627
+ #else
628
+ _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
629
+ return;
630
+ #endif
631
+ }
632
+ ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
633
+ if( _xparams.flags!=(alglib_impl::ae_uint64_t)0x0 )
634
+ ae_state_set_flags(&_alglib_env_state, _xparams.flags);
635
+ alglib_impl::gkqlegendrecalc(n, &info, x.c_ptr(), wkronrod.c_ptr(), wgauss.c_ptr(), &_alglib_env_state);
636
+ alglib_impl::ae_state_clear(&_alglib_env_state);
637
+ return;
638
+ }
639
+
640
+ /*************************************************************************
641
+ Returns Gauss and Gauss-Kronrod nodes for quadrature with N points using
642
+ pre-calculated table. Nodes/weights were computed with accuracy up to
643
+ 1.0E-32 (if MPFR version of ALGLIB is used). In standard double precision
644
+ accuracy reduces to something about 2.0E-16 (depending on your compiler's
645
+ handling of long floating point constants).
646
+
647
+ INPUT PARAMETERS:
648
+ N - number of Kronrod nodes.
649
+ N can be 15, 21, 31, 41, 51, 61.
650
+
651
+ OUTPUT PARAMETERS:
652
+ X - array[0..N-1] - array of quadrature nodes, ordered in
653
+ ascending order.
654
+ WKronrod - array[0..N-1] - Kronrod weights
655
+ WGauss - array[0..N-1] - Gauss weights (interleaved with zeros
656
+ corresponding to extended Kronrod nodes).
657
+
658
+
659
+ -- ALGLIB --
660
+ Copyright 12.05.2009 by Bochkanov Sergey
661
+ *************************************************************************/
662
+ void gkqlegendretbl(const ae_int_t n, real_1d_array &x, real_1d_array &wkronrod, real_1d_array &wgauss, double &eps, const xparams _xparams)
663
+ {
664
+ jmp_buf _break_jump;
665
+ alglib_impl::ae_state _alglib_env_state;
666
+ alglib_impl::ae_state_init(&_alglib_env_state);
667
+ if( setjmp(_break_jump) )
668
+ {
669
+ #if !defined(AE_NO_EXCEPTIONS)
670
+ _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
671
+ #else
672
+ _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
673
+ return;
674
+ #endif
675
+ }
676
+ ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
677
+ if( _xparams.flags!=(alglib_impl::ae_uint64_t)0x0 )
678
+ ae_state_set_flags(&_alglib_env_state, _xparams.flags);
679
+ alglib_impl::gkqlegendretbl(n, x.c_ptr(), wkronrod.c_ptr(), wgauss.c_ptr(), &eps, &_alglib_env_state);
680
+ alglib_impl::ae_state_clear(&_alglib_env_state);
681
+ return;
682
+ }
683
+ #endif
684
+
685
+ #if defined(AE_COMPILE_AUTOGK) || !defined(AE_PARTIAL_BUILD)
686
+ /*************************************************************************
687
+ Integration report:
688
+ * TerminationType = completetion code:
689
+ * -5 non-convergence of Gauss-Kronrod nodes
690
+ calculation subroutine.
691
+ * -1 incorrect parameters were specified
692
+ * 1 OK
693
+ * Rep.NFEV countains number of function calculations
694
+ * Rep.NIntervals contains number of intervals [a,b]
695
+ was partitioned into.
696
+ *************************************************************************/
697
+ _autogkreport_owner::_autogkreport_owner()
698
+ {
699
+ jmp_buf _break_jump;
700
+ alglib_impl::ae_state _state;
701
+
702
+ alglib_impl::ae_state_init(&_state);
703
+ if( setjmp(_break_jump) )
704
+ {
705
+ if( p_struct!=NULL )
706
+ {
707
+ alglib_impl::_autogkreport_destroy(p_struct);
708
+ alglib_impl::ae_free(p_struct);
709
+ }
710
+ p_struct = NULL;
711
+ #if !defined(AE_NO_EXCEPTIONS)
712
+ _ALGLIB_CPP_EXCEPTION(_state.error_msg);
713
+ #else
714
+ _ALGLIB_SET_ERROR_FLAG(_state.error_msg);
715
+ return;
716
+ #endif
717
+ }
718
+ alglib_impl::ae_state_set_break_jump(&_state, &_break_jump);
719
+ p_struct = NULL;
720
+ p_struct = (alglib_impl::autogkreport*)alglib_impl::ae_malloc(sizeof(alglib_impl::autogkreport), &_state);
721
+ memset(p_struct, 0, sizeof(alglib_impl::autogkreport));
722
+ alglib_impl::_autogkreport_init(p_struct, &_state, ae_false);
723
+ ae_state_clear(&_state);
724
+ is_attached = false;
725
+ }
726
+
727
+ _autogkreport_owner::_autogkreport_owner(alglib_impl::autogkreport *attach_to)
728
+ {
729
+ p_struct = attach_to;
730
+ is_attached = true;
731
+ }
732
+
733
+ _autogkreport_owner::_autogkreport_owner(const _autogkreport_owner &rhs)
734
+ {
735
+ jmp_buf _break_jump;
736
+ alglib_impl::ae_state _state;
737
+
738
+ alglib_impl::ae_state_init(&_state);
739
+ if( setjmp(_break_jump) )
740
+ {
741
+ if( p_struct!=NULL )
742
+ {
743
+ alglib_impl::_autogkreport_destroy(p_struct);
744
+ alglib_impl::ae_free(p_struct);
745
+ }
746
+ p_struct = NULL;
747
+ #if !defined(AE_NO_EXCEPTIONS)
748
+ _ALGLIB_CPP_EXCEPTION(_state.error_msg);
749
+ #else
750
+ _ALGLIB_SET_ERROR_FLAG(_state.error_msg);
751
+ return;
752
+ #endif
753
+ }
754
+ alglib_impl::ae_state_set_break_jump(&_state, &_break_jump);
755
+ p_struct = NULL;
756
+ alglib_impl::ae_assert(rhs.p_struct!=NULL, "ALGLIB: autogkreport copy constructor failure (source is not initialized)", &_state);
757
+ p_struct = (alglib_impl::autogkreport*)alglib_impl::ae_malloc(sizeof(alglib_impl::autogkreport), &_state);
758
+ memset(p_struct, 0, sizeof(alglib_impl::autogkreport));
759
+ alglib_impl::_autogkreport_init_copy(p_struct, const_cast<alglib_impl::autogkreport*>(rhs.p_struct), &_state, ae_false);
760
+ ae_state_clear(&_state);
761
+ is_attached = false;
762
+ }
763
+
764
+ _autogkreport_owner& _autogkreport_owner::operator=(const _autogkreport_owner &rhs)
765
+ {
766
+ if( this==&rhs )
767
+ return *this;
768
+ jmp_buf _break_jump;
769
+ alglib_impl::ae_state _state;
770
+
771
+ alglib_impl::ae_state_init(&_state);
772
+ if( setjmp(_break_jump) )
773
+ {
774
+ #if !defined(AE_NO_EXCEPTIONS)
775
+ _ALGLIB_CPP_EXCEPTION(_state.error_msg);
776
+ #else
777
+ _ALGLIB_SET_ERROR_FLAG(_state.error_msg);
778
+ return *this;
779
+ #endif
780
+ }
781
+ alglib_impl::ae_state_set_break_jump(&_state, &_break_jump);
782
+ alglib_impl::ae_assert(p_struct!=NULL, "ALGLIB: autogkreport assignment constructor failure (destination is not initialized)", &_state);
783
+ alglib_impl::ae_assert(rhs.p_struct!=NULL, "ALGLIB: autogkreport assignment constructor failure (source is not initialized)", &_state);
784
+ alglib_impl::ae_assert(!is_attached, "ALGLIB: autogkreport assignment constructor failure (can not assign to the structure which is attached to something else)", &_state);
785
+ alglib_impl::_autogkreport_destroy(p_struct);
786
+ memset(p_struct, 0, sizeof(alglib_impl::autogkreport));
787
+ alglib_impl::_autogkreport_init_copy(p_struct, const_cast<alglib_impl::autogkreport*>(rhs.p_struct), &_state, ae_false);
788
+ ae_state_clear(&_state);
789
+ return *this;
790
+ }
791
+
792
+ _autogkreport_owner::~_autogkreport_owner()
793
+ {
794
+ if( p_struct!=NULL && !is_attached )
795
+ {
796
+ alglib_impl::_autogkreport_destroy(p_struct);
797
+ ae_free(p_struct);
798
+ }
799
+ }
800
+
801
+ alglib_impl::autogkreport* _autogkreport_owner::c_ptr()
802
+ {
803
+ return p_struct;
804
+ }
805
+
806
+ const alglib_impl::autogkreport* _autogkreport_owner::c_ptr() const
807
+ {
808
+ return p_struct;
809
+ }
810
+ autogkreport::autogkreport() : _autogkreport_owner() ,terminationtype(p_struct->terminationtype),nfev(p_struct->nfev),nintervals(p_struct->nintervals)
811
+ {
812
+ }
813
+
814
+ autogkreport::autogkreport(alglib_impl::autogkreport *attach_to):_autogkreport_owner(attach_to) ,terminationtype(p_struct->terminationtype),nfev(p_struct->nfev),nintervals(p_struct->nintervals)
815
+ {
816
+ }
817
+
818
+ autogkreport::autogkreport(const autogkreport &rhs):_autogkreport_owner(rhs) ,terminationtype(p_struct->terminationtype),nfev(p_struct->nfev),nintervals(p_struct->nintervals)
819
+ {
820
+ }
821
+
822
+ autogkreport& autogkreport::operator=(const autogkreport &rhs)
823
+ {
824
+ if( this==&rhs )
825
+ return *this;
826
+ _autogkreport_owner::operator=(rhs);
827
+ return *this;
828
+ }
829
+
830
+ autogkreport::~autogkreport()
831
+ {
832
+ }
833
+
834
+
835
+ /*************************************************************************
836
+ This structure stores state of the integration algorithm.
837
+
838
+ Although this class has public fields, they are not intended for external
839
+ use. You should use ALGLIB functions to work with this class:
840
+ * autogksmooth()/AutoGKSmoothW()/... to create objects
841
+ * autogkintegrate() to begin integration
842
+ * autogkresults() to get results
843
+ *************************************************************************/
844
+ _autogkstate_owner::_autogkstate_owner()
845
+ {
846
+ jmp_buf _break_jump;
847
+ alglib_impl::ae_state _state;
848
+
849
+ alglib_impl::ae_state_init(&_state);
850
+ if( setjmp(_break_jump) )
851
+ {
852
+ if( p_struct!=NULL )
853
+ {
854
+ alglib_impl::_autogkstate_destroy(p_struct);
855
+ alglib_impl::ae_free(p_struct);
856
+ }
857
+ p_struct = NULL;
858
+ #if !defined(AE_NO_EXCEPTIONS)
859
+ _ALGLIB_CPP_EXCEPTION(_state.error_msg);
860
+ #else
861
+ _ALGLIB_SET_ERROR_FLAG(_state.error_msg);
862
+ return;
863
+ #endif
864
+ }
865
+ alglib_impl::ae_state_set_break_jump(&_state, &_break_jump);
866
+ p_struct = NULL;
867
+ p_struct = (alglib_impl::autogkstate*)alglib_impl::ae_malloc(sizeof(alglib_impl::autogkstate), &_state);
868
+ memset(p_struct, 0, sizeof(alglib_impl::autogkstate));
869
+ alglib_impl::_autogkstate_init(p_struct, &_state, ae_false);
870
+ ae_state_clear(&_state);
871
+ is_attached = false;
872
+ }
873
+
874
+ _autogkstate_owner::_autogkstate_owner(alglib_impl::autogkstate *attach_to)
875
+ {
876
+ p_struct = attach_to;
877
+ is_attached = true;
878
+ }
879
+
880
+ _autogkstate_owner::_autogkstate_owner(const _autogkstate_owner &rhs)
881
+ {
882
+ jmp_buf _break_jump;
883
+ alglib_impl::ae_state _state;
884
+
885
+ alglib_impl::ae_state_init(&_state);
886
+ if( setjmp(_break_jump) )
887
+ {
888
+ if( p_struct!=NULL )
889
+ {
890
+ alglib_impl::_autogkstate_destroy(p_struct);
891
+ alglib_impl::ae_free(p_struct);
892
+ }
893
+ p_struct = NULL;
894
+ #if !defined(AE_NO_EXCEPTIONS)
895
+ _ALGLIB_CPP_EXCEPTION(_state.error_msg);
896
+ #else
897
+ _ALGLIB_SET_ERROR_FLAG(_state.error_msg);
898
+ return;
899
+ #endif
900
+ }
901
+ alglib_impl::ae_state_set_break_jump(&_state, &_break_jump);
902
+ p_struct = NULL;
903
+ alglib_impl::ae_assert(rhs.p_struct!=NULL, "ALGLIB: autogkstate copy constructor failure (source is not initialized)", &_state);
904
+ p_struct = (alglib_impl::autogkstate*)alglib_impl::ae_malloc(sizeof(alglib_impl::autogkstate), &_state);
905
+ memset(p_struct, 0, sizeof(alglib_impl::autogkstate));
906
+ alglib_impl::_autogkstate_init_copy(p_struct, const_cast<alglib_impl::autogkstate*>(rhs.p_struct), &_state, ae_false);
907
+ ae_state_clear(&_state);
908
+ is_attached = false;
909
+ }
910
+
911
+ _autogkstate_owner& _autogkstate_owner::operator=(const _autogkstate_owner &rhs)
912
+ {
913
+ if( this==&rhs )
914
+ return *this;
915
+ jmp_buf _break_jump;
916
+ alglib_impl::ae_state _state;
917
+
918
+ alglib_impl::ae_state_init(&_state);
919
+ if( setjmp(_break_jump) )
920
+ {
921
+ #if !defined(AE_NO_EXCEPTIONS)
922
+ _ALGLIB_CPP_EXCEPTION(_state.error_msg);
923
+ #else
924
+ _ALGLIB_SET_ERROR_FLAG(_state.error_msg);
925
+ return *this;
926
+ #endif
927
+ }
928
+ alglib_impl::ae_state_set_break_jump(&_state, &_break_jump);
929
+ alglib_impl::ae_assert(p_struct!=NULL, "ALGLIB: autogkstate assignment constructor failure (destination is not initialized)", &_state);
930
+ alglib_impl::ae_assert(rhs.p_struct!=NULL, "ALGLIB: autogkstate assignment constructor failure (source is not initialized)", &_state);
931
+ alglib_impl::ae_assert(!is_attached, "ALGLIB: autogkstate assignment constructor failure (can not assign to the structure which is attached to something else)", &_state);
932
+ alglib_impl::_autogkstate_destroy(p_struct);
933
+ memset(p_struct, 0, sizeof(alglib_impl::autogkstate));
934
+ alglib_impl::_autogkstate_init_copy(p_struct, const_cast<alglib_impl::autogkstate*>(rhs.p_struct), &_state, ae_false);
935
+ ae_state_clear(&_state);
936
+ return *this;
937
+ }
938
+
939
+ _autogkstate_owner::~_autogkstate_owner()
940
+ {
941
+ if( p_struct!=NULL && !is_attached )
942
+ {
943
+ alglib_impl::_autogkstate_destroy(p_struct);
944
+ ae_free(p_struct);
945
+ }
946
+ }
947
+
948
+ alglib_impl::autogkstate* _autogkstate_owner::c_ptr()
949
+ {
950
+ return p_struct;
951
+ }
952
+
953
+ const alglib_impl::autogkstate* _autogkstate_owner::c_ptr() const
954
+ {
955
+ return p_struct;
956
+ }
957
+ autogkstate::autogkstate() : _autogkstate_owner() ,needf(p_struct->needf),x(p_struct->x),xminusa(p_struct->xminusa),bminusx(p_struct->bminusx),f(p_struct->f)
958
+ {
959
+ }
960
+
961
+ autogkstate::autogkstate(alglib_impl::autogkstate *attach_to):_autogkstate_owner(attach_to) ,needf(p_struct->needf),x(p_struct->x),xminusa(p_struct->xminusa),bminusx(p_struct->bminusx),f(p_struct->f)
962
+ {
963
+ }
964
+
965
+ autogkstate::autogkstate(const autogkstate &rhs):_autogkstate_owner(rhs) ,needf(p_struct->needf),x(p_struct->x),xminusa(p_struct->xminusa),bminusx(p_struct->bminusx),f(p_struct->f)
966
+ {
967
+ }
968
+
969
+ autogkstate& autogkstate::operator=(const autogkstate &rhs)
970
+ {
971
+ if( this==&rhs )
972
+ return *this;
973
+ _autogkstate_owner::operator=(rhs);
974
+ return *this;
975
+ }
976
+
977
+ autogkstate::~autogkstate()
978
+ {
979
+ }
980
+
981
+ /*************************************************************************
982
+ Integration of a smooth function F(x) on a finite interval [a,b].
983
+
984
+ Fast-convergent algorithm based on a Gauss-Kronrod formula is used. Result
985
+ is calculated with accuracy close to the machine precision.
986
+
987
+ Algorithm works well only with smooth integrands. It may be used with
988
+ continuous non-smooth integrands, but with less performance.
989
+
990
+ It should never be used with integrands which have integrable singularities
991
+ at lower or upper limits - algorithm may crash. Use AutoGKSingular in such
992
+ cases.
993
+
994
+ INPUT PARAMETERS:
995
+ A, B - interval boundaries (A<B, A=B or A>B)
996
+
997
+ OUTPUT PARAMETERS
998
+ State - structure which stores algorithm state
999
+
1000
+ SEE ALSO
1001
+ AutoGKSmoothW, AutoGKSingular, AutoGKResults.
1002
+
1003
+
1004
+ -- ALGLIB --
1005
+ Copyright 06.05.2009 by Bochkanov Sergey
1006
+ *************************************************************************/
1007
+ void autogksmooth(const double a, const double b, autogkstate &state, const xparams _xparams)
1008
+ {
1009
+ jmp_buf _break_jump;
1010
+ alglib_impl::ae_state _alglib_env_state;
1011
+ alglib_impl::ae_state_init(&_alglib_env_state);
1012
+ if( setjmp(_break_jump) )
1013
+ {
1014
+ #if !defined(AE_NO_EXCEPTIONS)
1015
+ _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
1016
+ #else
1017
+ _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
1018
+ return;
1019
+ #endif
1020
+ }
1021
+ ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
1022
+ if( _xparams.flags!=(alglib_impl::ae_uint64_t)0x0 )
1023
+ ae_state_set_flags(&_alglib_env_state, _xparams.flags);
1024
+ alglib_impl::autogksmooth(a, b, state.c_ptr(), &_alglib_env_state);
1025
+ alglib_impl::ae_state_clear(&_alglib_env_state);
1026
+ return;
1027
+ }
1028
+
1029
+ /*************************************************************************
1030
+ Integration of a smooth function F(x) on a finite interval [a,b].
1031
+
1032
+ This subroutine is same as AutoGKSmooth(), but it guarantees that interval
1033
+ [a,b] is partitioned into subintervals which have width at most XWidth.
1034
+
1035
+ Subroutine can be used when integrating nearly-constant function with
1036
+ narrow "bumps" (about XWidth wide). If "bumps" are too narrow, AutoGKSmooth
1037
+ subroutine can overlook them.
1038
+
1039
+ INPUT PARAMETERS:
1040
+ A, B - interval boundaries (A<B, A=B or A>B)
1041
+
1042
+ OUTPUT PARAMETERS
1043
+ State - structure which stores algorithm state
1044
+
1045
+ SEE ALSO
1046
+ AutoGKSmooth, AutoGKSingular, AutoGKResults.
1047
+
1048
+
1049
+ -- ALGLIB --
1050
+ Copyright 06.05.2009 by Bochkanov Sergey
1051
+ *************************************************************************/
1052
+ void autogksmoothw(const double a, const double b, const double xwidth, autogkstate &state, const xparams _xparams)
1053
+ {
1054
+ jmp_buf _break_jump;
1055
+ alglib_impl::ae_state _alglib_env_state;
1056
+ alglib_impl::ae_state_init(&_alglib_env_state);
1057
+ if( setjmp(_break_jump) )
1058
+ {
1059
+ #if !defined(AE_NO_EXCEPTIONS)
1060
+ _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
1061
+ #else
1062
+ _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
1063
+ return;
1064
+ #endif
1065
+ }
1066
+ ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
1067
+ if( _xparams.flags!=(alglib_impl::ae_uint64_t)0x0 )
1068
+ ae_state_set_flags(&_alglib_env_state, _xparams.flags);
1069
+ alglib_impl::autogksmoothw(a, b, xwidth, state.c_ptr(), &_alglib_env_state);
1070
+ alglib_impl::ae_state_clear(&_alglib_env_state);
1071
+ return;
1072
+ }
1073
+
1074
+ /*************************************************************************
1075
+ Integration on a finite interval [A,B].
1076
+ Integrand have integrable singularities at A/B.
1077
+
1078
+ F(X) must diverge as "(x-A)^alpha" at A, as "(B-x)^beta" at B, with known
1079
+ alpha/beta (alpha>-1, beta>-1). If alpha/beta are not known, estimates
1080
+ from below can be used (but these estimates should be greater than -1 too).
1081
+
1082
+ One of alpha/beta variables (or even both alpha/beta) may be equal to 0,
1083
+ which means than function F(x) is non-singular at A/B. Anyway (singular at
1084
+ bounds or not), function F(x) is supposed to be continuous on (A,B).
1085
+
1086
+ Fast-convergent algorithm based on a Gauss-Kronrod formula is used. Result
1087
+ is calculated with accuracy close to the machine precision.
1088
+
1089
+ INPUT PARAMETERS:
1090
+ A, B - interval boundaries (A<B, A=B or A>B)
1091
+ Alpha - power-law coefficient of the F(x) at A,
1092
+ Alpha>-1
1093
+ Beta - power-law coefficient of the F(x) at B,
1094
+ Beta>-1
1095
+
1096
+ OUTPUT PARAMETERS
1097
+ State - structure which stores algorithm state
1098
+
1099
+ SEE ALSO
1100
+ AutoGKSmooth, AutoGKSmoothW, AutoGKResults.
1101
+
1102
+
1103
+ -- ALGLIB --
1104
+ Copyright 06.05.2009 by Bochkanov Sergey
1105
+ *************************************************************************/
1106
+ void autogksingular(const double a, const double b, const double alpha, const double beta, autogkstate &state, const xparams _xparams)
1107
+ {
1108
+ jmp_buf _break_jump;
1109
+ alglib_impl::ae_state _alglib_env_state;
1110
+ alglib_impl::ae_state_init(&_alglib_env_state);
1111
+ if( setjmp(_break_jump) )
1112
+ {
1113
+ #if !defined(AE_NO_EXCEPTIONS)
1114
+ _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
1115
+ #else
1116
+ _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
1117
+ return;
1118
+ #endif
1119
+ }
1120
+ ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
1121
+ if( _xparams.flags!=(alglib_impl::ae_uint64_t)0x0 )
1122
+ ae_state_set_flags(&_alglib_env_state, _xparams.flags);
1123
+ alglib_impl::autogksingular(a, b, alpha, beta, state.c_ptr(), &_alglib_env_state);
1124
+ alglib_impl::ae_state_clear(&_alglib_env_state);
1125
+ return;
1126
+ }
1127
+
1128
+ /*************************************************************************
1129
+ This function provides reverse communication interface
1130
+ Reverse communication interface is not documented or recommended to use.
1131
+ See below for functions which provide better documented API
1132
+ *************************************************************************/
1133
+ bool autogkiteration(autogkstate &state, const xparams _xparams)
1134
+ {
1135
+ jmp_buf _break_jump;
1136
+ alglib_impl::ae_state _alglib_env_state;
1137
+ alglib_impl::ae_state_init(&_alglib_env_state);
1138
+ if( setjmp(_break_jump) )
1139
+ {
1140
+ #if !defined(AE_NO_EXCEPTIONS)
1141
+ _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
1142
+ #else
1143
+ _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
1144
+ return 0;
1145
+ #endif
1146
+ }
1147
+ ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
1148
+ if( _xparams.flags!=(alglib_impl::ae_uint64_t)0x0 )
1149
+ ae_state_set_flags(&_alglib_env_state, _xparams.flags);
1150
+ ae_bool result = alglib_impl::autogkiteration(state.c_ptr(), &_alglib_env_state);
1151
+ alglib_impl::ae_state_clear(&_alglib_env_state);
1152
+ return bool(result);
1153
+ }
1154
+
1155
+
1156
+ void autogkintegrate(autogkstate &state,
1157
+ void (*func)(double x, double xminusa, double bminusx, double &y, void *ptr),
1158
+ void *ptr, const xparams _xparams){
1159
+ jmp_buf _break_jump;
1160
+ alglib_impl::ae_state _alglib_env_state;
1161
+ alglib_impl::ae_state_init(&_alglib_env_state);
1162
+ if( setjmp(_break_jump) )
1163
+ {
1164
+ #if !defined(AE_NO_EXCEPTIONS)
1165
+ _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
1166
+ #else
1167
+ _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
1168
+ return;
1169
+ #endif
1170
+ }
1171
+ ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
1172
+ if( _xparams.flags!=(alglib_impl::ae_uint64_t)0x0 )
1173
+ ae_state_set_flags(&_alglib_env_state, _xparams.flags);
1174
+ alglib_impl::ae_assert(func!=NULL, "ALGLIB: error in 'autogkintegrate()' (func is NULL)", &_alglib_env_state);
1175
+ while( alglib_impl::autogkiteration(state.c_ptr(), &_alglib_env_state) )
1176
+ {
1177
+ _ALGLIB_CALLBACK_EXCEPTION_GUARD_BEGIN
1178
+ if( state.needf )
1179
+ {
1180
+ func(state.x, state.xminusa, state.bminusx, state.f, ptr);
1181
+ continue;
1182
+ }
1183
+ goto lbl_no_callback;
1184
+ _ALGLIB_CALLBACK_EXCEPTION_GUARD_END
1185
+ lbl_no_callback:
1186
+ alglib_impl::ae_assert(ae_false, "ALGLIB: unexpected error in 'autogkintegrate()'", &_alglib_env_state);
1187
+ }
1188
+ alglib_impl::ae_state_clear(&_alglib_env_state);
1189
+ }
1190
+
1191
+
1192
+
1193
+ /*************************************************************************
1194
+ Adaptive integration results
1195
+
1196
+ Called after AutoGKIteration returned False.
1197
+
1198
+ Input parameters:
1199
+ State - algorithm state (used by AutoGKIteration).
1200
+
1201
+ Output parameters:
1202
+ V - integral(f(x)dx,a,b)
1203
+ Rep - optimization report (see AutoGKReport description)
1204
+
1205
+ -- ALGLIB --
1206
+ Copyright 14.11.2007 by Bochkanov Sergey
1207
+ *************************************************************************/
1208
+ void autogkresults(const autogkstate &state, double &v, autogkreport &rep, const xparams _xparams)
1209
+ {
1210
+ jmp_buf _break_jump;
1211
+ alglib_impl::ae_state _alglib_env_state;
1212
+ alglib_impl::ae_state_init(&_alglib_env_state);
1213
+ if( setjmp(_break_jump) )
1214
+ {
1215
+ #if !defined(AE_NO_EXCEPTIONS)
1216
+ _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
1217
+ #else
1218
+ _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
1219
+ return;
1220
+ #endif
1221
+ }
1222
+ ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
1223
+ if( _xparams.flags!=(alglib_impl::ae_uint64_t)0x0 )
1224
+ ae_state_set_flags(&_alglib_env_state, _xparams.flags);
1225
+ alglib_impl::autogkresults(state.c_ptr(), &v, rep.c_ptr(), &_alglib_env_state);
1226
+ alglib_impl::ae_state_clear(&_alglib_env_state);
1227
+ return;
1228
+ }
1229
+ #endif
1230
+ }
1231
+
1232
+ /////////////////////////////////////////////////////////////////////////
1233
+ //
1234
+ // THIS SECTION CONTAINS IMPLEMENTATION OF COMPUTATIONAL CORE
1235
+ //
1236
+ /////////////////////////////////////////////////////////////////////////
1237
+ namespace alglib_impl
1238
+ {
1239
+ #if defined(AE_COMPILE_GQ) || !defined(AE_PARTIAL_BUILD)
1240
+
1241
+
1242
+ #endif
1243
+ #if defined(AE_COMPILE_GKQ) || !defined(AE_PARTIAL_BUILD)
1244
+
1245
+
1246
+ #endif
1247
+ #if defined(AE_COMPILE_AUTOGK) || !defined(AE_PARTIAL_BUILD)
1248
+ static ae_int_t autogk_maxsubintervals = 10000;
1249
+ static void autogk_autogkinternalprepare(double a,
1250
+ double b,
1251
+ double eps,
1252
+ double xwidth,
1253
+ autogkinternalstate* state,
1254
+ ae_state *_state);
1255
+ static ae_bool autogk_autogkinternaliteration(autogkinternalstate* state,
1256
+ ae_state *_state);
1257
+ static void autogk_mheappop(/* Real */ ae_matrix* heap,
1258
+ ae_int_t heapsize,
1259
+ ae_int_t heapwidth,
1260
+ ae_state *_state);
1261
+ static void autogk_mheappush(/* Real */ ae_matrix* heap,
1262
+ ae_int_t heapsize,
1263
+ ae_int_t heapwidth,
1264
+ ae_state *_state);
1265
+ static void autogk_mheapresize(/* Real */ ae_matrix* heap,
1266
+ ae_int_t* heapsize,
1267
+ ae_int_t newheapsize,
1268
+ ae_int_t heapwidth,
1269
+ ae_state *_state);
1270
+
1271
+
1272
+ #endif
1273
+
1274
+ #if defined(AE_COMPILE_GQ) || !defined(AE_PARTIAL_BUILD)
1275
+
1276
+
1277
+ /*************************************************************************
1278
+ Computation of nodes and weights for a Gauss quadrature formula
1279
+
1280
+ The algorithm generates the N-point Gauss quadrature formula with weight
1281
+ function given by coefficients alpha and beta of a recurrence relation
1282
+ which generates a system of orthogonal polynomials:
1283
+
1284
+ P-1(x) = 0
1285
+ P0(x) = 1
1286
+ Pn+1(x) = (x-alpha(n))*Pn(x) - beta(n)*Pn-1(x)
1287
+
1288
+ and zeroth moment Mu0
1289
+
1290
+ Mu0 = integral(W(x)dx,a,b)
1291
+
1292
+ INPUT PARAMETERS:
1293
+ Alpha - array[0..N-1], alpha coefficients
1294
+ Beta - array[0..N-1], beta coefficients
1295
+ Zero-indexed element is not used and may be arbitrary.
1296
+ Beta[I]>0.
1297
+ Mu0 - zeroth moment of the weight function.
1298
+ N - number of nodes of the quadrature formula, N>=1
1299
+
1300
+ OUTPUT PARAMETERS:
1301
+ Info - error code:
1302
+ * -3 internal eigenproblem solver hasn't converged
1303
+ * -2 Beta[i]<=0
1304
+ * -1 incorrect N was passed
1305
+ * 1 OK
1306
+ X - array[0..N-1] - array of quadrature nodes,
1307
+ in ascending order.
1308
+ W - array[0..N-1] - array of quadrature weights.
1309
+
1310
+ -- ALGLIB --
1311
+ Copyright 2005-2009 by Bochkanov Sergey
1312
+ *************************************************************************/
1313
+ void gqgeneraterec(/* Real */ const ae_vector* alpha,
1314
+ /* Real */ const ae_vector* beta,
1315
+ double mu0,
1316
+ ae_int_t n,
1317
+ ae_int_t* info,
1318
+ /* Real */ ae_vector* x,
1319
+ /* Real */ ae_vector* w,
1320
+ ae_state *_state)
1321
+ {
1322
+ ae_frame _frame_block;
1323
+ ae_int_t i;
1324
+ ae_vector d;
1325
+ ae_vector e;
1326
+ ae_matrix z;
1327
+
1328
+ ae_frame_make(_state, &_frame_block);
1329
+ memset(&d, 0, sizeof(d));
1330
+ memset(&e, 0, sizeof(e));
1331
+ memset(&z, 0, sizeof(z));
1332
+ *info = 0;
1333
+ ae_vector_clear(x);
1334
+ ae_vector_clear(w);
1335
+ ae_vector_init(&d, 0, DT_REAL, _state, ae_true);
1336
+ ae_vector_init(&e, 0, DT_REAL, _state, ae_true);
1337
+ ae_matrix_init(&z, 0, 0, DT_REAL, _state, ae_true);
1338
+
1339
+ if( n<1 )
1340
+ {
1341
+ *info = -1;
1342
+ ae_frame_leave(_state);
1343
+ return;
1344
+ }
1345
+ *info = 1;
1346
+
1347
+ /*
1348
+ * Initialize
1349
+ */
1350
+ ae_vector_set_length(&d, n, _state);
1351
+ ae_vector_set_length(&e, n, _state);
1352
+ for(i=1; i<=n-1; i++)
1353
+ {
1354
+ d.ptr.p_double[i-1] = alpha->ptr.p_double[i-1];
1355
+ if( ae_fp_less_eq(beta->ptr.p_double[i],(double)(0)) )
1356
+ {
1357
+ *info = -2;
1358
+ ae_frame_leave(_state);
1359
+ return;
1360
+ }
1361
+ e.ptr.p_double[i-1] = ae_sqrt(beta->ptr.p_double[i], _state);
1362
+ }
1363
+ d.ptr.p_double[n-1] = alpha->ptr.p_double[n-1];
1364
+
1365
+ /*
1366
+ * EVD
1367
+ */
1368
+ if( !smatrixtdevd(&d, &e, n, 3, &z, _state) )
1369
+ {
1370
+ *info = -3;
1371
+ ae_frame_leave(_state);
1372
+ return;
1373
+ }
1374
+
1375
+ /*
1376
+ * Generate
1377
+ */
1378
+ ae_vector_set_length(x, n, _state);
1379
+ ae_vector_set_length(w, n, _state);
1380
+ for(i=1; i<=n; i++)
1381
+ {
1382
+ x->ptr.p_double[i-1] = d.ptr.p_double[i-1];
1383
+ w->ptr.p_double[i-1] = mu0*ae_sqr(z.ptr.pp_double[0][i-1], _state);
1384
+ }
1385
+ ae_frame_leave(_state);
1386
+ }
1387
+
1388
+
1389
+ /*************************************************************************
1390
+ Computation of nodes and weights for a Gauss-Lobatto quadrature formula
1391
+
1392
+ The algorithm generates the N-point Gauss-Lobatto quadrature formula with
1393
+ weight function given by coefficients alpha and beta of a recurrence which
1394
+ generates a system of orthogonal polynomials.
1395
+
1396
+ P-1(x) = 0
1397
+ P0(x) = 1
1398
+ Pn+1(x) = (x-alpha(n))*Pn(x) - beta(n)*Pn-1(x)
1399
+
1400
+ and zeroth moment Mu0
1401
+
1402
+ Mu0 = integral(W(x)dx,a,b)
1403
+
1404
+ INPUT PARAMETERS:
1405
+ Alpha - array[0..N-2], alpha coefficients
1406
+ Beta - array[0..N-2], beta coefficients.
1407
+ Zero-indexed element is not used, may be arbitrary.
1408
+ Beta[I]>0
1409
+ Mu0 - zeroth moment of the weighting function.
1410
+ A - left boundary of the integration interval.
1411
+ B - right boundary of the integration interval.
1412
+ N - number of nodes of the quadrature formula, N>=3
1413
+ (including the left and right boundary nodes).
1414
+
1415
+ OUTPUT PARAMETERS:
1416
+ Info - error code:
1417
+ * -3 internal eigenproblem solver hasn't converged
1418
+ * -2 Beta[i]<=0
1419
+ * -1 incorrect N was passed
1420
+ * 1 OK
1421
+ X - array[0..N-1] - array of quadrature nodes,
1422
+ in ascending order.
1423
+ W - array[0..N-1] - array of quadrature weights.
1424
+
1425
+ -- ALGLIB --
1426
+ Copyright 2005-2009 by Bochkanov Sergey
1427
+ *************************************************************************/
1428
+ void gqgenerategausslobattorec(/* Real */ const ae_vector* _alpha,
1429
+ /* Real */ const ae_vector* _beta,
1430
+ double mu0,
1431
+ double a,
1432
+ double b,
1433
+ ae_int_t n,
1434
+ ae_int_t* info,
1435
+ /* Real */ ae_vector* x,
1436
+ /* Real */ ae_vector* w,
1437
+ ae_state *_state)
1438
+ {
1439
+ ae_frame _frame_block;
1440
+ ae_vector alpha;
1441
+ ae_vector beta;
1442
+ ae_int_t i;
1443
+ ae_vector d;
1444
+ ae_vector e;
1445
+ ae_matrix z;
1446
+ double pim1a;
1447
+ double pia;
1448
+ double pim1b;
1449
+ double pib;
1450
+ double t;
1451
+ double a11;
1452
+ double a12;
1453
+ double a21;
1454
+ double a22;
1455
+ double b1;
1456
+ double b2;
1457
+ double alph;
1458
+ double bet;
1459
+
1460
+ ae_frame_make(_state, &_frame_block);
1461
+ memset(&alpha, 0, sizeof(alpha));
1462
+ memset(&beta, 0, sizeof(beta));
1463
+ memset(&d, 0, sizeof(d));
1464
+ memset(&e, 0, sizeof(e));
1465
+ memset(&z, 0, sizeof(z));
1466
+ ae_vector_init_copy(&alpha, _alpha, _state, ae_true);
1467
+ ae_vector_init_copy(&beta, _beta, _state, ae_true);
1468
+ *info = 0;
1469
+ ae_vector_clear(x);
1470
+ ae_vector_clear(w);
1471
+ ae_vector_init(&d, 0, DT_REAL, _state, ae_true);
1472
+ ae_vector_init(&e, 0, DT_REAL, _state, ae_true);
1473
+ ae_matrix_init(&z, 0, 0, DT_REAL, _state, ae_true);
1474
+
1475
+ if( n<=2 )
1476
+ {
1477
+ *info = -1;
1478
+ ae_frame_leave(_state);
1479
+ return;
1480
+ }
1481
+ *info = 1;
1482
+
1483
+ /*
1484
+ * Initialize, D[1:N+1], E[1:N]
1485
+ */
1486
+ n = n-2;
1487
+ ae_vector_set_length(&d, n+2, _state);
1488
+ ae_vector_set_length(&e, n+1, _state);
1489
+ for(i=1; i<=n+1; i++)
1490
+ {
1491
+ d.ptr.p_double[i-1] = alpha.ptr.p_double[i-1];
1492
+ }
1493
+ for(i=1; i<=n; i++)
1494
+ {
1495
+ if( ae_fp_less_eq(beta.ptr.p_double[i],(double)(0)) )
1496
+ {
1497
+ *info = -2;
1498
+ ae_frame_leave(_state);
1499
+ return;
1500
+ }
1501
+ e.ptr.p_double[i-1] = ae_sqrt(beta.ptr.p_double[i], _state);
1502
+ }
1503
+
1504
+ /*
1505
+ * Caclulate Pn(a), Pn+1(a), Pn(b), Pn+1(b)
1506
+ */
1507
+ beta.ptr.p_double[0] = (double)(0);
1508
+ pim1a = (double)(0);
1509
+ pia = (double)(1);
1510
+ pim1b = (double)(0);
1511
+ pib = (double)(1);
1512
+ for(i=1; i<=n+1; i++)
1513
+ {
1514
+
1515
+ /*
1516
+ * Pi(a)
1517
+ */
1518
+ t = (a-alpha.ptr.p_double[i-1])*pia-beta.ptr.p_double[i-1]*pim1a;
1519
+ pim1a = pia;
1520
+ pia = t;
1521
+
1522
+ /*
1523
+ * Pi(b)
1524
+ */
1525
+ t = (b-alpha.ptr.p_double[i-1])*pib-beta.ptr.p_double[i-1]*pim1b;
1526
+ pim1b = pib;
1527
+ pib = t;
1528
+ }
1529
+
1530
+ /*
1531
+ * Calculate alpha'(n+1), beta'(n+1)
1532
+ */
1533
+ a11 = pia;
1534
+ a12 = pim1a;
1535
+ a21 = pib;
1536
+ a22 = pim1b;
1537
+ b1 = a*pia;
1538
+ b2 = b*pib;
1539
+ if( ae_fp_greater(ae_fabs(a11, _state),ae_fabs(a21, _state)) )
1540
+ {
1541
+ a22 = a22-a12*a21/a11;
1542
+ b2 = b2-b1*a21/a11;
1543
+ bet = b2/a22;
1544
+ alph = (b1-bet*a12)/a11;
1545
+ }
1546
+ else
1547
+ {
1548
+ a12 = a12-a22*a11/a21;
1549
+ b1 = b1-b2*a11/a21;
1550
+ bet = b1/a12;
1551
+ alph = (b2-bet*a22)/a21;
1552
+ }
1553
+ if( ae_fp_less(bet,(double)(0)) )
1554
+ {
1555
+ *info = -3;
1556
+ ae_frame_leave(_state);
1557
+ return;
1558
+ }
1559
+ d.ptr.p_double[n+1] = alph;
1560
+ e.ptr.p_double[n] = ae_sqrt(bet, _state);
1561
+
1562
+ /*
1563
+ * EVD
1564
+ */
1565
+ if( !smatrixtdevd(&d, &e, n+2, 3, &z, _state) )
1566
+ {
1567
+ *info = -3;
1568
+ ae_frame_leave(_state);
1569
+ return;
1570
+ }
1571
+
1572
+ /*
1573
+ * Generate
1574
+ */
1575
+ ae_vector_set_length(x, n+2, _state);
1576
+ ae_vector_set_length(w, n+2, _state);
1577
+ for(i=1; i<=n+2; i++)
1578
+ {
1579
+ x->ptr.p_double[i-1] = d.ptr.p_double[i-1];
1580
+ w->ptr.p_double[i-1] = mu0*ae_sqr(z.ptr.pp_double[0][i-1], _state);
1581
+ }
1582
+ ae_frame_leave(_state);
1583
+ }
1584
+
1585
+
1586
+ /*************************************************************************
1587
+ Computation of nodes and weights for a Gauss-Radau quadrature formula
1588
+
1589
+ The algorithm generates the N-point Gauss-Radau quadrature formula with
1590
+ weight function given by the coefficients alpha and beta of a recurrence
1591
+ which generates a system of orthogonal polynomials.
1592
+
1593
+ P-1(x) = 0
1594
+ P0(x) = 1
1595
+ Pn+1(x) = (x-alpha(n))*Pn(x) - beta(n)*Pn-1(x)
1596
+
1597
+ and zeroth moment Mu0
1598
+
1599
+ Mu0 = integral(W(x)dx,a,b)
1600
+
1601
+ INPUT PARAMETERS:
1602
+ Alpha - array[0..N-2], alpha coefficients.
1603
+ Beta - array[0..N-1], beta coefficients
1604
+ Zero-indexed element is not used.
1605
+ Beta[I]>0
1606
+ Mu0 - zeroth moment of the weighting function.
1607
+ A - left boundary of the integration interval.
1608
+ N - number of nodes of the quadrature formula, N>=2
1609
+ (including the left boundary node).
1610
+
1611
+ OUTPUT PARAMETERS:
1612
+ Info - error code:
1613
+ * -3 internal eigenproblem solver hasn't converged
1614
+ * -2 Beta[i]<=0
1615
+ * -1 incorrect N was passed
1616
+ * 1 OK
1617
+ X - array[0..N-1] - array of quadrature nodes,
1618
+ in ascending order.
1619
+ W - array[0..N-1] - array of quadrature weights.
1620
+
1621
+
1622
+ -- ALGLIB --
1623
+ Copyright 2005-2009 by Bochkanov Sergey
1624
+ *************************************************************************/
1625
+ void gqgenerategaussradaurec(/* Real */ const ae_vector* _alpha,
1626
+ /* Real */ const ae_vector* _beta,
1627
+ double mu0,
1628
+ double a,
1629
+ ae_int_t n,
1630
+ ae_int_t* info,
1631
+ /* Real */ ae_vector* x,
1632
+ /* Real */ ae_vector* w,
1633
+ ae_state *_state)
1634
+ {
1635
+ ae_frame _frame_block;
1636
+ ae_vector alpha;
1637
+ ae_vector beta;
1638
+ ae_int_t i;
1639
+ ae_vector d;
1640
+ ae_vector e;
1641
+ ae_matrix z;
1642
+ double polim1;
1643
+ double poli;
1644
+ double t;
1645
+
1646
+ ae_frame_make(_state, &_frame_block);
1647
+ memset(&alpha, 0, sizeof(alpha));
1648
+ memset(&beta, 0, sizeof(beta));
1649
+ memset(&d, 0, sizeof(d));
1650
+ memset(&e, 0, sizeof(e));
1651
+ memset(&z, 0, sizeof(z));
1652
+ ae_vector_init_copy(&alpha, _alpha, _state, ae_true);
1653
+ ae_vector_init_copy(&beta, _beta, _state, ae_true);
1654
+ *info = 0;
1655
+ ae_vector_clear(x);
1656
+ ae_vector_clear(w);
1657
+ ae_vector_init(&d, 0, DT_REAL, _state, ae_true);
1658
+ ae_vector_init(&e, 0, DT_REAL, _state, ae_true);
1659
+ ae_matrix_init(&z, 0, 0, DT_REAL, _state, ae_true);
1660
+
1661
+ if( n<2 )
1662
+ {
1663
+ *info = -1;
1664
+ ae_frame_leave(_state);
1665
+ return;
1666
+ }
1667
+ *info = 1;
1668
+
1669
+ /*
1670
+ * Initialize, D[1:N], E[1:N]
1671
+ */
1672
+ n = n-1;
1673
+ ae_vector_set_length(&d, n+1, _state);
1674
+ ae_vector_set_length(&e, n, _state);
1675
+ for(i=1; i<=n; i++)
1676
+ {
1677
+ d.ptr.p_double[i-1] = alpha.ptr.p_double[i-1];
1678
+ if( ae_fp_less_eq(beta.ptr.p_double[i],(double)(0)) )
1679
+ {
1680
+ *info = -2;
1681
+ ae_frame_leave(_state);
1682
+ return;
1683
+ }
1684
+ e.ptr.p_double[i-1] = ae_sqrt(beta.ptr.p_double[i], _state);
1685
+ }
1686
+
1687
+ /*
1688
+ * Caclulate Pn(a), Pn-1(a), and D[N+1]
1689
+ */
1690
+ beta.ptr.p_double[0] = (double)(0);
1691
+ polim1 = (double)(0);
1692
+ poli = (double)(1);
1693
+ for(i=1; i<=n; i++)
1694
+ {
1695
+ t = (a-alpha.ptr.p_double[i-1])*poli-beta.ptr.p_double[i-1]*polim1;
1696
+ polim1 = poli;
1697
+ poli = t;
1698
+ }
1699
+ d.ptr.p_double[n] = a-beta.ptr.p_double[n]*polim1/poli;
1700
+
1701
+ /*
1702
+ * EVD
1703
+ */
1704
+ if( !smatrixtdevd(&d, &e, n+1, 3, &z, _state) )
1705
+ {
1706
+ *info = -3;
1707
+ ae_frame_leave(_state);
1708
+ return;
1709
+ }
1710
+
1711
+ /*
1712
+ * Generate
1713
+ */
1714
+ ae_vector_set_length(x, n+1, _state);
1715
+ ae_vector_set_length(w, n+1, _state);
1716
+ for(i=1; i<=n+1; i++)
1717
+ {
1718
+ x->ptr.p_double[i-1] = d.ptr.p_double[i-1];
1719
+ w->ptr.p_double[i-1] = mu0*ae_sqr(z.ptr.pp_double[0][i-1], _state);
1720
+ }
1721
+ ae_frame_leave(_state);
1722
+ }
1723
+
1724
+
1725
+ /*************************************************************************
1726
+ Returns nodes/weights for Gauss-Legendre quadrature on [-1,1] with N
1727
+ nodes.
1728
+
1729
+ INPUT PARAMETERS:
1730
+ N - number of nodes, >=1
1731
+
1732
+ OUTPUT PARAMETERS:
1733
+ Info - error code:
1734
+ * -4 an error was detected when calculating
1735
+ weights/nodes. N is too large to obtain
1736
+ weights/nodes with high enough accuracy.
1737
+ Try to use multiple precision version.
1738
+ * -3 internal eigenproblem solver hasn't converged
1739
+ * -1 incorrect N was passed
1740
+ * +1 OK
1741
+ X - array[0..N-1] - array of quadrature nodes,
1742
+ in ascending order.
1743
+ W - array[0..N-1] - array of quadrature weights.
1744
+
1745
+
1746
+ -- ALGLIB --
1747
+ Copyright 12.05.2009 by Bochkanov Sergey
1748
+ *************************************************************************/
1749
+ void gqgenerategausslegendre(ae_int_t n,
1750
+ ae_int_t* info,
1751
+ /* Real */ ae_vector* x,
1752
+ /* Real */ ae_vector* w,
1753
+ ae_state *_state)
1754
+ {
1755
+ ae_frame _frame_block;
1756
+ ae_vector alpha;
1757
+ ae_vector beta;
1758
+ ae_int_t i;
1759
+
1760
+ ae_frame_make(_state, &_frame_block);
1761
+ memset(&alpha, 0, sizeof(alpha));
1762
+ memset(&beta, 0, sizeof(beta));
1763
+ *info = 0;
1764
+ ae_vector_clear(x);
1765
+ ae_vector_clear(w);
1766
+ ae_vector_init(&alpha, 0, DT_REAL, _state, ae_true);
1767
+ ae_vector_init(&beta, 0, DT_REAL, _state, ae_true);
1768
+
1769
+ if( n<1 )
1770
+ {
1771
+ *info = -1;
1772
+ ae_frame_leave(_state);
1773
+ return;
1774
+ }
1775
+ ae_vector_set_length(&alpha, n, _state);
1776
+ ae_vector_set_length(&beta, n, _state);
1777
+ for(i=0; i<=n-1; i++)
1778
+ {
1779
+ alpha.ptr.p_double[i] = (double)(0);
1780
+ }
1781
+ beta.ptr.p_double[0] = (double)(2);
1782
+ for(i=1; i<=n-1; i++)
1783
+ {
1784
+ beta.ptr.p_double[i] = (double)1/((double)4-(double)1/ae_sqr((double)(i), _state));
1785
+ }
1786
+ gqgeneraterec(&alpha, &beta, beta.ptr.p_double[0], n, info, x, w, _state);
1787
+
1788
+ /*
1789
+ * test basic properties to detect errors
1790
+ */
1791
+ if( *info>0 )
1792
+ {
1793
+ if( ae_fp_less(x->ptr.p_double[0],(double)(-1))||ae_fp_greater(x->ptr.p_double[n-1],(double)(1)) )
1794
+ {
1795
+ *info = -4;
1796
+ }
1797
+ for(i=0; i<=n-2; i++)
1798
+ {
1799
+ if( ae_fp_greater_eq(x->ptr.p_double[i],x->ptr.p_double[i+1]) )
1800
+ {
1801
+ *info = -4;
1802
+ }
1803
+ }
1804
+ }
1805
+ ae_frame_leave(_state);
1806
+ }
1807
+
1808
+
1809
+ /*************************************************************************
1810
+ Returns nodes/weights for Gauss-Jacobi quadrature on [-1,1] with weight
1811
+ function W(x)=Power(1-x,Alpha)*Power(1+x,Beta).
1812
+
1813
+ INPUT PARAMETERS:
1814
+ N - number of nodes, >=1
1815
+ Alpha - power-law coefficient, Alpha>-1
1816
+ Beta - power-law coefficient, Beta>-1
1817
+
1818
+ OUTPUT PARAMETERS:
1819
+ Info - error code:
1820
+ * -4 an error was detected when calculating
1821
+ weights/nodes. Alpha or Beta are too close
1822
+ to -1 to obtain weights/nodes with high enough
1823
+ accuracy, or, may be, N is too large. Try to
1824
+ use multiple precision version.
1825
+ * -3 internal eigenproblem solver hasn't converged
1826
+ * -1 incorrect N/Alpha/Beta was passed
1827
+ * +1 OK
1828
+ X - array[0..N-1] - array of quadrature nodes,
1829
+ in ascending order.
1830
+ W - array[0..N-1] - array of quadrature weights.
1831
+
1832
+
1833
+ -- ALGLIB --
1834
+ Copyright 12.05.2009 by Bochkanov Sergey
1835
+ *************************************************************************/
1836
+ void gqgenerategaussjacobi(ae_int_t n,
1837
+ double alpha,
1838
+ double beta,
1839
+ ae_int_t* info,
1840
+ /* Real */ ae_vector* x,
1841
+ /* Real */ ae_vector* w,
1842
+ ae_state *_state)
1843
+ {
1844
+ ae_frame _frame_block;
1845
+ ae_vector a;
1846
+ ae_vector b;
1847
+ double alpha2;
1848
+ double beta2;
1849
+ double apb;
1850
+ double t;
1851
+ ae_int_t i;
1852
+ double s;
1853
+
1854
+ ae_frame_make(_state, &_frame_block);
1855
+ memset(&a, 0, sizeof(a));
1856
+ memset(&b, 0, sizeof(b));
1857
+ *info = 0;
1858
+ ae_vector_clear(x);
1859
+ ae_vector_clear(w);
1860
+ ae_vector_init(&a, 0, DT_REAL, _state, ae_true);
1861
+ ae_vector_init(&b, 0, DT_REAL, _state, ae_true);
1862
+
1863
+ if( (n<1||ae_fp_less_eq(alpha,(double)(-1)))||ae_fp_less_eq(beta,(double)(-1)) )
1864
+ {
1865
+ *info = -1;
1866
+ ae_frame_leave(_state);
1867
+ return;
1868
+ }
1869
+ ae_vector_set_length(&a, n, _state);
1870
+ ae_vector_set_length(&b, n, _state);
1871
+ apb = alpha+beta;
1872
+ a.ptr.p_double[0] = (beta-alpha)/(apb+(double)2);
1873
+ t = (apb+(double)1)*ae_log((double)(2), _state)+lngamma(alpha+(double)1, &s, _state)+lngamma(beta+(double)1, &s, _state)-lngamma(apb+(double)2, &s, _state);
1874
+ if( ae_fp_greater(t,ae_log(ae_maxrealnumber, _state)) )
1875
+ {
1876
+ *info = -4;
1877
+ ae_frame_leave(_state);
1878
+ return;
1879
+ }
1880
+ b.ptr.p_double[0] = ae_exp(t, _state);
1881
+ if( n>1 )
1882
+ {
1883
+ alpha2 = ae_sqr(alpha, _state);
1884
+ beta2 = ae_sqr(beta, _state);
1885
+ a.ptr.p_double[1] = (beta2-alpha2)/((apb+(double)2)*(apb+(double)4));
1886
+ b.ptr.p_double[1] = (double)4*(alpha+(double)1)*(beta+(double)1)/((apb+(double)3)*ae_sqr(apb+(double)2, _state));
1887
+ for(i=2; i<=n-1; i++)
1888
+ {
1889
+ a.ptr.p_double[i] = 0.25*(beta2-alpha2)/((double)(i*i)*((double)1+0.5*apb/(double)i)*((double)1+0.5*(apb+(double)2)/(double)i));
1890
+ b.ptr.p_double[i] = 0.25*((double)1+alpha/(double)i)*((double)1+beta/(double)i)*((double)1+apb/(double)i)/(((double)1+0.5*(apb+(double)1)/(double)i)*((double)1+0.5*(apb-(double)1)/(double)i)*ae_sqr((double)1+0.5*apb/(double)i, _state));
1891
+ }
1892
+ }
1893
+ gqgeneraterec(&a, &b, b.ptr.p_double[0], n, info, x, w, _state);
1894
+
1895
+ /*
1896
+ * test basic properties to detect errors
1897
+ */
1898
+ if( *info>0 )
1899
+ {
1900
+ if( ae_fp_less(x->ptr.p_double[0],(double)(-1))||ae_fp_greater(x->ptr.p_double[n-1],(double)(1)) )
1901
+ {
1902
+ *info = -4;
1903
+ }
1904
+ for(i=0; i<=n-2; i++)
1905
+ {
1906
+ if( ae_fp_greater_eq(x->ptr.p_double[i],x->ptr.p_double[i+1]) )
1907
+ {
1908
+ *info = -4;
1909
+ }
1910
+ }
1911
+ }
1912
+ ae_frame_leave(_state);
1913
+ }
1914
+
1915
+
1916
+ /*************************************************************************
1917
+ Returns nodes/weights for Gauss-Laguerre quadrature on [0,+inf) with
1918
+ weight function W(x)=Power(x,Alpha)*Exp(-x)
1919
+
1920
+ INPUT PARAMETERS:
1921
+ N - number of nodes, >=1
1922
+ Alpha - power-law coefficient, Alpha>-1
1923
+
1924
+ OUTPUT PARAMETERS:
1925
+ Info - error code:
1926
+ * -4 an error was detected when calculating
1927
+ weights/nodes. Alpha is too close to -1 to
1928
+ obtain weights/nodes with high enough accuracy
1929
+ or, may be, N is too large. Try to use
1930
+ multiple precision version.
1931
+ * -3 internal eigenproblem solver hasn't converged
1932
+ * -1 incorrect N/Alpha was passed
1933
+ * +1 OK
1934
+ X - array[0..N-1] - array of quadrature nodes,
1935
+ in ascending order.
1936
+ W - array[0..N-1] - array of quadrature weights.
1937
+
1938
+
1939
+ -- ALGLIB --
1940
+ Copyright 12.05.2009 by Bochkanov Sergey
1941
+ *************************************************************************/
1942
+ void gqgenerategausslaguerre(ae_int_t n,
1943
+ double alpha,
1944
+ ae_int_t* info,
1945
+ /* Real */ ae_vector* x,
1946
+ /* Real */ ae_vector* w,
1947
+ ae_state *_state)
1948
+ {
1949
+ ae_frame _frame_block;
1950
+ ae_vector a;
1951
+ ae_vector b;
1952
+ double t;
1953
+ ae_int_t i;
1954
+ double s;
1955
+
1956
+ ae_frame_make(_state, &_frame_block);
1957
+ memset(&a, 0, sizeof(a));
1958
+ memset(&b, 0, sizeof(b));
1959
+ *info = 0;
1960
+ ae_vector_clear(x);
1961
+ ae_vector_clear(w);
1962
+ ae_vector_init(&a, 0, DT_REAL, _state, ae_true);
1963
+ ae_vector_init(&b, 0, DT_REAL, _state, ae_true);
1964
+
1965
+ if( n<1||ae_fp_less_eq(alpha,(double)(-1)) )
1966
+ {
1967
+ *info = -1;
1968
+ ae_frame_leave(_state);
1969
+ return;
1970
+ }
1971
+ ae_vector_set_length(&a, n, _state);
1972
+ ae_vector_set_length(&b, n, _state);
1973
+ a.ptr.p_double[0] = alpha+(double)1;
1974
+ t = lngamma(alpha+(double)1, &s, _state);
1975
+ if( ae_fp_greater_eq(t,ae_log(ae_maxrealnumber, _state)) )
1976
+ {
1977
+ *info = -4;
1978
+ ae_frame_leave(_state);
1979
+ return;
1980
+ }
1981
+ b.ptr.p_double[0] = ae_exp(t, _state);
1982
+ if( n>1 )
1983
+ {
1984
+ for(i=1; i<=n-1; i++)
1985
+ {
1986
+ a.ptr.p_double[i] = (double)(2*i)+alpha+(double)1;
1987
+ b.ptr.p_double[i] = (double)i*((double)i+alpha);
1988
+ }
1989
+ }
1990
+ gqgeneraterec(&a, &b, b.ptr.p_double[0], n, info, x, w, _state);
1991
+
1992
+ /*
1993
+ * test basic properties to detect errors
1994
+ */
1995
+ if( *info>0 )
1996
+ {
1997
+ if( ae_fp_less(x->ptr.p_double[0],(double)(0)) )
1998
+ {
1999
+ *info = -4;
2000
+ }
2001
+ for(i=0; i<=n-2; i++)
2002
+ {
2003
+ if( ae_fp_greater_eq(x->ptr.p_double[i],x->ptr.p_double[i+1]) )
2004
+ {
2005
+ *info = -4;
2006
+ }
2007
+ }
2008
+ }
2009
+ ae_frame_leave(_state);
2010
+ }
2011
+
2012
+
2013
+ /*************************************************************************
2014
+ Returns nodes/weights for Gauss-Hermite quadrature on (-inf,+inf) with
2015
+ weight function W(x)=Exp(-x*x)
2016
+
2017
+ INPUT PARAMETERS:
2018
+ N - number of nodes, >=1
2019
+
2020
+ OUTPUT PARAMETERS:
2021
+ Info - error code:
2022
+ * -4 an error was detected when calculating
2023
+ weights/nodes. May be, N is too large. Try to
2024
+ use multiple precision version.
2025
+ * -3 internal eigenproblem solver hasn't converged
2026
+ * -1 incorrect N/Alpha was passed
2027
+ * +1 OK
2028
+ X - array[0..N-1] - array of quadrature nodes,
2029
+ in ascending order.
2030
+ W - array[0..N-1] - array of quadrature weights.
2031
+
2032
+
2033
+ -- ALGLIB --
2034
+ Copyright 12.05.2009 by Bochkanov Sergey
2035
+ *************************************************************************/
2036
+ void gqgenerategausshermite(ae_int_t n,
2037
+ ae_int_t* info,
2038
+ /* Real */ ae_vector* x,
2039
+ /* Real */ ae_vector* w,
2040
+ ae_state *_state)
2041
+ {
2042
+ ae_frame _frame_block;
2043
+ ae_vector a;
2044
+ ae_vector b;
2045
+ ae_int_t i;
2046
+
2047
+ ae_frame_make(_state, &_frame_block);
2048
+ memset(&a, 0, sizeof(a));
2049
+ memset(&b, 0, sizeof(b));
2050
+ *info = 0;
2051
+ ae_vector_clear(x);
2052
+ ae_vector_clear(w);
2053
+ ae_vector_init(&a, 0, DT_REAL, _state, ae_true);
2054
+ ae_vector_init(&b, 0, DT_REAL, _state, ae_true);
2055
+
2056
+ if( n<1 )
2057
+ {
2058
+ *info = -1;
2059
+ ae_frame_leave(_state);
2060
+ return;
2061
+ }
2062
+ ae_vector_set_length(&a, n, _state);
2063
+ ae_vector_set_length(&b, n, _state);
2064
+ for(i=0; i<=n-1; i++)
2065
+ {
2066
+ a.ptr.p_double[i] = (double)(0);
2067
+ }
2068
+ b.ptr.p_double[0] = ae_sqrt((double)4*ae_atan((double)(1), _state), _state);
2069
+ if( n>1 )
2070
+ {
2071
+ for(i=1; i<=n-1; i++)
2072
+ {
2073
+ b.ptr.p_double[i] = 0.5*(double)i;
2074
+ }
2075
+ }
2076
+ gqgeneraterec(&a, &b, b.ptr.p_double[0], n, info, x, w, _state);
2077
+
2078
+ /*
2079
+ * test basic properties to detect errors
2080
+ */
2081
+ if( *info>0 )
2082
+ {
2083
+ for(i=0; i<=n-2; i++)
2084
+ {
2085
+ if( ae_fp_greater_eq(x->ptr.p_double[i],x->ptr.p_double[i+1]) )
2086
+ {
2087
+ *info = -4;
2088
+ }
2089
+ }
2090
+ }
2091
+ ae_frame_leave(_state);
2092
+ }
2093
+
2094
+
2095
+ #endif
2096
+ #if defined(AE_COMPILE_GKQ) || !defined(AE_PARTIAL_BUILD)
2097
+
2098
+
2099
+ /*************************************************************************
2100
+ Computation of nodes and weights of a Gauss-Kronrod quadrature formula
2101
+
2102
+ The algorithm generates the N-point Gauss-Kronrod quadrature formula with
2103
+ weight function given by coefficients alpha and beta of a recurrence
2104
+ relation which generates a system of orthogonal polynomials:
2105
+
2106
+ P-1(x) = 0
2107
+ P0(x) = 1
2108
+ Pn+1(x) = (x-alpha(n))*Pn(x) - beta(n)*Pn-1(x)
2109
+
2110
+ and zero moment Mu0
2111
+
2112
+ Mu0 = integral(W(x)dx,a,b)
2113
+
2114
+
2115
+ INPUT PARAMETERS:
2116
+ Alpha - alpha coefficients, array[0..floor(3*K/2)].
2117
+ Beta - beta coefficients, array[0..ceil(3*K/2)].
2118
+ Beta[0] is not used and may be arbitrary.
2119
+ Beta[I]>0.
2120
+ Mu0 - zeroth moment of the weight function.
2121
+ N - number of nodes of the Gauss-Kronrod quadrature formula,
2122
+ N >= 3,
2123
+ N = 2*K+1.
2124
+
2125
+ OUTPUT PARAMETERS:
2126
+ Info - error code:
2127
+ * -5 no real and positive Gauss-Kronrod formula can
2128
+ be created for such a weight function with a
2129
+ given number of nodes.
2130
+ * -4 N is too large, task may be ill conditioned -
2131
+ x[i]=x[i+1] found.
2132
+ * -3 internal eigenproblem solver hasn't converged
2133
+ * -2 Beta[i]<=0
2134
+ * -1 incorrect N was passed
2135
+ * +1 OK
2136
+ X - array[0..N-1] - array of quadrature nodes,
2137
+ in ascending order.
2138
+ WKronrod - array[0..N-1] - Kronrod weights
2139
+ WGauss - array[0..N-1] - Gauss weights (interleaved with zeros
2140
+ corresponding to extended Kronrod nodes).
2141
+
2142
+ -- ALGLIB --
2143
+ Copyright 08.05.2009 by Bochkanov Sergey
2144
+ *************************************************************************/
2145
+ void gkqgeneraterec(/* Real */ const ae_vector* _alpha,
2146
+ /* Real */ const ae_vector* _beta,
2147
+ double mu0,
2148
+ ae_int_t n,
2149
+ ae_int_t* info,
2150
+ /* Real */ ae_vector* x,
2151
+ /* Real */ ae_vector* wkronrod,
2152
+ /* Real */ ae_vector* wgauss,
2153
+ ae_state *_state)
2154
+ {
2155
+ ae_frame _frame_block;
2156
+ ae_vector alpha;
2157
+ ae_vector beta;
2158
+ ae_vector ta;
2159
+ ae_int_t i;
2160
+ ae_int_t j;
2161
+ ae_vector t;
2162
+ ae_vector s;
2163
+ ae_int_t wlen;
2164
+ ae_int_t woffs;
2165
+ double u;
2166
+ ae_int_t m;
2167
+ ae_int_t l;
2168
+ ae_int_t k;
2169
+ ae_vector xgtmp;
2170
+ ae_vector wgtmp;
2171
+
2172
+ ae_frame_make(_state, &_frame_block);
2173
+ memset(&alpha, 0, sizeof(alpha));
2174
+ memset(&beta, 0, sizeof(beta));
2175
+ memset(&ta, 0, sizeof(ta));
2176
+ memset(&t, 0, sizeof(t));
2177
+ memset(&s, 0, sizeof(s));
2178
+ memset(&xgtmp, 0, sizeof(xgtmp));
2179
+ memset(&wgtmp, 0, sizeof(wgtmp));
2180
+ ae_vector_init_copy(&alpha, _alpha, _state, ae_true);
2181
+ ae_vector_init_copy(&beta, _beta, _state, ae_true);
2182
+ *info = 0;
2183
+ ae_vector_clear(x);
2184
+ ae_vector_clear(wkronrod);
2185
+ ae_vector_clear(wgauss);
2186
+ ae_vector_init(&ta, 0, DT_REAL, _state, ae_true);
2187
+ ae_vector_init(&t, 0, DT_REAL, _state, ae_true);
2188
+ ae_vector_init(&s, 0, DT_REAL, _state, ae_true);
2189
+ ae_vector_init(&xgtmp, 0, DT_REAL, _state, ae_true);
2190
+ ae_vector_init(&wgtmp, 0, DT_REAL, _state, ae_true);
2191
+
2192
+ if( n%2!=1||n<3 )
2193
+ {
2194
+ *info = -1;
2195
+ ae_frame_leave(_state);
2196
+ return;
2197
+ }
2198
+ for(i=0; i<=ae_iceil((double)(3*(n/2))/(double)2, _state); i++)
2199
+ {
2200
+ if( ae_fp_less_eq(beta.ptr.p_double[i],(double)(0)) )
2201
+ {
2202
+ *info = -2;
2203
+ ae_frame_leave(_state);
2204
+ return;
2205
+ }
2206
+ }
2207
+ *info = 1;
2208
+
2209
+ /*
2210
+ * from external conventions about N/Beta/Mu0 to internal
2211
+ */
2212
+ n = n/2;
2213
+ beta.ptr.p_double[0] = mu0;
2214
+
2215
+ /*
2216
+ * Calculate Gauss nodes/weights, save them for later processing
2217
+ */
2218
+ gqgeneraterec(&alpha, &beta, mu0, n, info, &xgtmp, &wgtmp, _state);
2219
+ if( *info<0 )
2220
+ {
2221
+ ae_frame_leave(_state);
2222
+ return;
2223
+ }
2224
+
2225
+ /*
2226
+ * Resize:
2227
+ * * A from 0..floor(3*n/2) to 0..2*n
2228
+ * * B from 0..ceil(3*n/2) to 0..2*n
2229
+ */
2230
+ ae_vector_set_length(&ta, ae_ifloor((double)(3*n)/(double)2, _state)+1, _state);
2231
+ ae_v_move(&ta.ptr.p_double[0], 1, &alpha.ptr.p_double[0], 1, ae_v_len(0,ae_ifloor((double)(3*n)/(double)2, _state)));
2232
+ ae_vector_set_length(&alpha, 2*n+1, _state);
2233
+ ae_v_move(&alpha.ptr.p_double[0], 1, &ta.ptr.p_double[0], 1, ae_v_len(0,ae_ifloor((double)(3*n)/(double)2, _state)));
2234
+ for(i=ae_ifloor((double)(3*n)/(double)2, _state)+1; i<=2*n; i++)
2235
+ {
2236
+ alpha.ptr.p_double[i] = (double)(0);
2237
+ }
2238
+ ae_vector_set_length(&ta, ae_iceil((double)(3*n)/(double)2, _state)+1, _state);
2239
+ ae_v_move(&ta.ptr.p_double[0], 1, &beta.ptr.p_double[0], 1, ae_v_len(0,ae_iceil((double)(3*n)/(double)2, _state)));
2240
+ ae_vector_set_length(&beta, 2*n+1, _state);
2241
+ ae_v_move(&beta.ptr.p_double[0], 1, &ta.ptr.p_double[0], 1, ae_v_len(0,ae_iceil((double)(3*n)/(double)2, _state)));
2242
+ for(i=ae_iceil((double)(3*n)/(double)2, _state)+1; i<=2*n; i++)
2243
+ {
2244
+ beta.ptr.p_double[i] = (double)(0);
2245
+ }
2246
+
2247
+ /*
2248
+ * Initialize T, S
2249
+ */
2250
+ wlen = 2+n/2;
2251
+ ae_vector_set_length(&t, wlen, _state);
2252
+ ae_vector_set_length(&s, wlen, _state);
2253
+ ae_vector_set_length(&ta, wlen, _state);
2254
+ woffs = 1;
2255
+ for(i=0; i<=wlen-1; i++)
2256
+ {
2257
+ t.ptr.p_double[i] = (double)(0);
2258
+ s.ptr.p_double[i] = (double)(0);
2259
+ }
2260
+
2261
+ /*
2262
+ * Algorithm from Dirk P. Laurie, "Calculation of Gauss-Kronrod quadrature rules", 1997.
2263
+ */
2264
+ t.ptr.p_double[woffs+0] = beta.ptr.p_double[n+1];
2265
+ for(m=0; m<=n-2; m++)
2266
+ {
2267
+ u = (double)(0);
2268
+ for(k=(m+1)/2; k>=0; k--)
2269
+ {
2270
+ l = m-k;
2271
+ u = u+(alpha.ptr.p_double[k+n+1]-alpha.ptr.p_double[l])*t.ptr.p_double[woffs+k]+beta.ptr.p_double[k+n+1]*s.ptr.p_double[woffs+k-1]-beta.ptr.p_double[l]*s.ptr.p_double[woffs+k];
2272
+ s.ptr.p_double[woffs+k] = u;
2273
+ }
2274
+ ae_v_move(&ta.ptr.p_double[0], 1, &t.ptr.p_double[0], 1, ae_v_len(0,wlen-1));
2275
+ ae_v_move(&t.ptr.p_double[0], 1, &s.ptr.p_double[0], 1, ae_v_len(0,wlen-1));
2276
+ ae_v_move(&s.ptr.p_double[0], 1, &ta.ptr.p_double[0], 1, ae_v_len(0,wlen-1));
2277
+ }
2278
+ for(j=n/2; j>=0; j--)
2279
+ {
2280
+ s.ptr.p_double[woffs+j] = s.ptr.p_double[woffs+j-1];
2281
+ }
2282
+ for(m=n-1; m<=2*n-3; m++)
2283
+ {
2284
+ u = (double)(0);
2285
+ for(k=m+1-n; k<=(m-1)/2; k++)
2286
+ {
2287
+ l = m-k;
2288
+ j = n-1-l;
2289
+ u = u-(alpha.ptr.p_double[k+n+1]-alpha.ptr.p_double[l])*t.ptr.p_double[woffs+j]-beta.ptr.p_double[k+n+1]*s.ptr.p_double[woffs+j]+beta.ptr.p_double[l]*s.ptr.p_double[woffs+j+1];
2290
+ s.ptr.p_double[woffs+j] = u;
2291
+ }
2292
+ if( m%2==0 )
2293
+ {
2294
+ k = m/2;
2295
+ alpha.ptr.p_double[k+n+1] = alpha.ptr.p_double[k]+(s.ptr.p_double[woffs+j]-beta.ptr.p_double[k+n+1]*s.ptr.p_double[woffs+j+1])/t.ptr.p_double[woffs+j+1];
2296
+ }
2297
+ else
2298
+ {
2299
+ k = (m+1)/2;
2300
+ beta.ptr.p_double[k+n+1] = s.ptr.p_double[woffs+j]/s.ptr.p_double[woffs+j+1];
2301
+ }
2302
+ ae_v_move(&ta.ptr.p_double[0], 1, &t.ptr.p_double[0], 1, ae_v_len(0,wlen-1));
2303
+ ae_v_move(&t.ptr.p_double[0], 1, &s.ptr.p_double[0], 1, ae_v_len(0,wlen-1));
2304
+ ae_v_move(&s.ptr.p_double[0], 1, &ta.ptr.p_double[0], 1, ae_v_len(0,wlen-1));
2305
+ }
2306
+ alpha.ptr.p_double[2*n] = alpha.ptr.p_double[n-1]-beta.ptr.p_double[2*n]*s.ptr.p_double[woffs+0]/t.ptr.p_double[woffs+0];
2307
+
2308
+ /*
2309
+ * calculation of Kronrod nodes and weights, unpacking of Gauss weights
2310
+ */
2311
+ gqgeneraterec(&alpha, &beta, mu0, 2*n+1, info, x, wkronrod, _state);
2312
+ if( *info==-2 )
2313
+ {
2314
+ *info = -5;
2315
+ }
2316
+ if( *info<0 )
2317
+ {
2318
+ ae_frame_leave(_state);
2319
+ return;
2320
+ }
2321
+ for(i=0; i<=2*n-1; i++)
2322
+ {
2323
+ if( ae_fp_greater_eq(x->ptr.p_double[i],x->ptr.p_double[i+1]) )
2324
+ {
2325
+ *info = -4;
2326
+ }
2327
+ }
2328
+ if( *info<0 )
2329
+ {
2330
+ ae_frame_leave(_state);
2331
+ return;
2332
+ }
2333
+ ae_vector_set_length(wgauss, 2*n+1, _state);
2334
+ for(i=0; i<=2*n; i++)
2335
+ {
2336
+ wgauss->ptr.p_double[i] = (double)(0);
2337
+ }
2338
+ for(i=0; i<=n-1; i++)
2339
+ {
2340
+ wgauss->ptr.p_double[2*i+1] = wgtmp.ptr.p_double[i];
2341
+ }
2342
+ ae_frame_leave(_state);
2343
+ }
2344
+
2345
+
2346
+ /*************************************************************************
2347
+ Returns Gauss and Gauss-Kronrod nodes/weights for Gauss-Legendre
2348
+ quadrature with N points.
2349
+
2350
+ GKQLegendreCalc (calculation) or GKQLegendreTbl (precomputed table) is
2351
+ used depending on machine precision and number of nodes.
2352
+
2353
+ INPUT PARAMETERS:
2354
+ N - number of Kronrod nodes, must be odd number, >=3.
2355
+
2356
+ OUTPUT PARAMETERS:
2357
+ Info - error code:
2358
+ * -4 an error was detected when calculating
2359
+ weights/nodes. N is too large to obtain
2360
+ weights/nodes with high enough accuracy.
2361
+ Try to use multiple precision version.
2362
+ * -3 internal eigenproblem solver hasn't converged
2363
+ * -1 incorrect N was passed
2364
+ * +1 OK
2365
+ X - array[0..N-1] - array of quadrature nodes, ordered in
2366
+ ascending order.
2367
+ WKronrod - array[0..N-1] - Kronrod weights
2368
+ WGauss - array[0..N-1] - Gauss weights (interleaved with zeros
2369
+ corresponding to extended Kronrod nodes).
2370
+
2371
+
2372
+ -- ALGLIB --
2373
+ Copyright 12.05.2009 by Bochkanov Sergey
2374
+ *************************************************************************/
2375
+ void gkqgenerategausslegendre(ae_int_t n,
2376
+ ae_int_t* info,
2377
+ /* Real */ ae_vector* x,
2378
+ /* Real */ ae_vector* wkronrod,
2379
+ /* Real */ ae_vector* wgauss,
2380
+ ae_state *_state)
2381
+ {
2382
+ double eps;
2383
+
2384
+ *info = 0;
2385
+ ae_vector_clear(x);
2386
+ ae_vector_clear(wkronrod);
2387
+ ae_vector_clear(wgauss);
2388
+
2389
+ if( ae_fp_greater(ae_machineepsilon,1.0E-32)&&(((((n==15||n==21)||n==31)||n==41)||n==51)||n==61) )
2390
+ {
2391
+ *info = 1;
2392
+ gkqlegendretbl(n, x, wkronrod, wgauss, &eps, _state);
2393
+ }
2394
+ else
2395
+ {
2396
+ gkqlegendrecalc(n, info, x, wkronrod, wgauss, _state);
2397
+ }
2398
+ }
2399
+
2400
+
2401
+ /*************************************************************************
2402
+ Returns Gauss and Gauss-Kronrod nodes/weights for Gauss-Jacobi
2403
+ quadrature on [-1,1] with weight function
2404
+
2405
+ W(x)=Power(1-x,Alpha)*Power(1+x,Beta).
2406
+
2407
+ INPUT PARAMETERS:
2408
+ N - number of Kronrod nodes, must be odd number, >=3.
2409
+ Alpha - power-law coefficient, Alpha>-1
2410
+ Beta - power-law coefficient, Beta>-1
2411
+
2412
+ OUTPUT PARAMETERS:
2413
+ Info - error code:
2414
+ * -5 no real and positive Gauss-Kronrod formula can
2415
+ be created for such a weight function with a
2416
+ given number of nodes.
2417
+ * -4 an error was detected when calculating
2418
+ weights/nodes. Alpha or Beta are too close
2419
+ to -1 to obtain weights/nodes with high enough
2420
+ accuracy, or, may be, N is too large. Try to
2421
+ use multiple precision version.
2422
+ * -3 internal eigenproblem solver hasn't converged
2423
+ * -1 incorrect N was passed
2424
+ * +1 OK
2425
+ * +2 OK, but quadrature rule have exterior nodes,
2426
+ x[0]<-1 or x[n-1]>+1
2427
+ X - array[0..N-1] - array of quadrature nodes, ordered in
2428
+ ascending order.
2429
+ WKronrod - array[0..N-1] - Kronrod weights
2430
+ WGauss - array[0..N-1] - Gauss weights (interleaved with zeros
2431
+ corresponding to extended Kronrod nodes).
2432
+
2433
+
2434
+ -- ALGLIB --
2435
+ Copyright 12.05.2009 by Bochkanov Sergey
2436
+ *************************************************************************/
2437
+ void gkqgenerategaussjacobi(ae_int_t n,
2438
+ double alpha,
2439
+ double beta,
2440
+ ae_int_t* info,
2441
+ /* Real */ ae_vector* x,
2442
+ /* Real */ ae_vector* wkronrod,
2443
+ /* Real */ ae_vector* wgauss,
2444
+ ae_state *_state)
2445
+ {
2446
+ ae_frame _frame_block;
2447
+ ae_int_t clen;
2448
+ ae_vector a;
2449
+ ae_vector b;
2450
+ double alpha2;
2451
+ double beta2;
2452
+ double apb;
2453
+ double t;
2454
+ ae_int_t i;
2455
+ double s;
2456
+
2457
+ ae_frame_make(_state, &_frame_block);
2458
+ memset(&a, 0, sizeof(a));
2459
+ memset(&b, 0, sizeof(b));
2460
+ *info = 0;
2461
+ ae_vector_clear(x);
2462
+ ae_vector_clear(wkronrod);
2463
+ ae_vector_clear(wgauss);
2464
+ ae_vector_init(&a, 0, DT_REAL, _state, ae_true);
2465
+ ae_vector_init(&b, 0, DT_REAL, _state, ae_true);
2466
+
2467
+ if( n%2!=1||n<3 )
2468
+ {
2469
+ *info = -1;
2470
+ ae_frame_leave(_state);
2471
+ return;
2472
+ }
2473
+ if( ae_fp_less_eq(alpha,(double)(-1))||ae_fp_less_eq(beta,(double)(-1)) )
2474
+ {
2475
+ *info = -1;
2476
+ ae_frame_leave(_state);
2477
+ return;
2478
+ }
2479
+ clen = ae_iceil((double)(3*(n/2))/(double)2, _state)+1;
2480
+ ae_vector_set_length(&a, clen, _state);
2481
+ ae_vector_set_length(&b, clen, _state);
2482
+ for(i=0; i<=clen-1; i++)
2483
+ {
2484
+ a.ptr.p_double[i] = (double)(0);
2485
+ }
2486
+ apb = alpha+beta;
2487
+ a.ptr.p_double[0] = (beta-alpha)/(apb+(double)2);
2488
+ t = (apb+(double)1)*ae_log((double)(2), _state)+lngamma(alpha+(double)1, &s, _state)+lngamma(beta+(double)1, &s, _state)-lngamma(apb+(double)2, &s, _state);
2489
+ if( ae_fp_greater(t,ae_log(ae_maxrealnumber, _state)) )
2490
+ {
2491
+ *info = -4;
2492
+ ae_frame_leave(_state);
2493
+ return;
2494
+ }
2495
+ b.ptr.p_double[0] = ae_exp(t, _state);
2496
+ if( clen>1 )
2497
+ {
2498
+ alpha2 = ae_sqr(alpha, _state);
2499
+ beta2 = ae_sqr(beta, _state);
2500
+ a.ptr.p_double[1] = (beta2-alpha2)/((apb+(double)2)*(apb+(double)4));
2501
+ b.ptr.p_double[1] = (double)4*(alpha+(double)1)*(beta+(double)1)/((apb+(double)3)*ae_sqr(apb+(double)2, _state));
2502
+ for(i=2; i<=clen-1; i++)
2503
+ {
2504
+ a.ptr.p_double[i] = 0.25*(beta2-alpha2)/((double)(i*i)*((double)1+0.5*apb/(double)i)*((double)1+0.5*(apb+(double)2)/(double)i));
2505
+ b.ptr.p_double[i] = 0.25*((double)1+alpha/(double)i)*((double)1+beta/(double)i)*((double)1+apb/(double)i)/(((double)1+0.5*(apb+(double)1)/(double)i)*((double)1+0.5*(apb-(double)1)/(double)i)*ae_sqr((double)1+0.5*apb/(double)i, _state));
2506
+ }
2507
+ }
2508
+ gkqgeneraterec(&a, &b, b.ptr.p_double[0], n, info, x, wkronrod, wgauss, _state);
2509
+
2510
+ /*
2511
+ * test basic properties to detect errors
2512
+ */
2513
+ if( *info>0 )
2514
+ {
2515
+ if( ae_fp_less(x->ptr.p_double[0],(double)(-1))||ae_fp_greater(x->ptr.p_double[n-1],(double)(1)) )
2516
+ {
2517
+ *info = 2;
2518
+ }
2519
+ for(i=0; i<=n-2; i++)
2520
+ {
2521
+ if( ae_fp_greater_eq(x->ptr.p_double[i],x->ptr.p_double[i+1]) )
2522
+ {
2523
+ *info = -4;
2524
+ }
2525
+ }
2526
+ }
2527
+ ae_frame_leave(_state);
2528
+ }
2529
+
2530
+
2531
+ /*************************************************************************
2532
+ Returns Gauss and Gauss-Kronrod nodes for quadrature with N points.
2533
+
2534
+ Reduction to tridiagonal eigenproblem is used.
2535
+
2536
+ INPUT PARAMETERS:
2537
+ N - number of Kronrod nodes, must be odd number, >=3.
2538
+
2539
+ OUTPUT PARAMETERS:
2540
+ Info - error code:
2541
+ * -4 an error was detected when calculating
2542
+ weights/nodes. N is too large to obtain
2543
+ weights/nodes with high enough accuracy.
2544
+ Try to use multiple precision version.
2545
+ * -3 internal eigenproblem solver hasn't converged
2546
+ * -1 incorrect N was passed
2547
+ * +1 OK
2548
+ X - array[0..N-1] - array of quadrature nodes, ordered in
2549
+ ascending order.
2550
+ WKronrod - array[0..N-1] - Kronrod weights
2551
+ WGauss - array[0..N-1] - Gauss weights (interleaved with zeros
2552
+ corresponding to extended Kronrod nodes).
2553
+
2554
+ -- ALGLIB --
2555
+ Copyright 12.05.2009 by Bochkanov Sergey
2556
+ *************************************************************************/
2557
+ void gkqlegendrecalc(ae_int_t n,
2558
+ ae_int_t* info,
2559
+ /* Real */ ae_vector* x,
2560
+ /* Real */ ae_vector* wkronrod,
2561
+ /* Real */ ae_vector* wgauss,
2562
+ ae_state *_state)
2563
+ {
2564
+ ae_frame _frame_block;
2565
+ ae_vector alpha;
2566
+ ae_vector beta;
2567
+ ae_int_t alen;
2568
+ ae_int_t blen;
2569
+ double mu0;
2570
+ ae_int_t k;
2571
+ ae_int_t i;
2572
+
2573
+ ae_frame_make(_state, &_frame_block);
2574
+ memset(&alpha, 0, sizeof(alpha));
2575
+ memset(&beta, 0, sizeof(beta));
2576
+ *info = 0;
2577
+ ae_vector_clear(x);
2578
+ ae_vector_clear(wkronrod);
2579
+ ae_vector_clear(wgauss);
2580
+ ae_vector_init(&alpha, 0, DT_REAL, _state, ae_true);
2581
+ ae_vector_init(&beta, 0, DT_REAL, _state, ae_true);
2582
+
2583
+ if( n%2!=1||n<3 )
2584
+ {
2585
+ *info = -1;
2586
+ ae_frame_leave(_state);
2587
+ return;
2588
+ }
2589
+ mu0 = (double)(2);
2590
+ alen = ae_ifloor((double)(3*(n/2))/(double)2, _state)+1;
2591
+ blen = ae_iceil((double)(3*(n/2))/(double)2, _state)+1;
2592
+ ae_vector_set_length(&alpha, alen, _state);
2593
+ ae_vector_set_length(&beta, blen, _state);
2594
+ for(k=0; k<=alen-1; k++)
2595
+ {
2596
+ alpha.ptr.p_double[k] = (double)(0);
2597
+ }
2598
+ beta.ptr.p_double[0] = (double)(2);
2599
+ for(k=1; k<=blen-1; k++)
2600
+ {
2601
+ beta.ptr.p_double[k] = (double)1/((double)4-(double)1/ae_sqr((double)(k), _state));
2602
+ }
2603
+ gkqgeneraterec(&alpha, &beta, mu0, n, info, x, wkronrod, wgauss, _state);
2604
+
2605
+ /*
2606
+ * test basic properties to detect errors
2607
+ */
2608
+ if( *info>0 )
2609
+ {
2610
+ if( ae_fp_less(x->ptr.p_double[0],(double)(-1))||ae_fp_greater(x->ptr.p_double[n-1],(double)(1)) )
2611
+ {
2612
+ *info = -4;
2613
+ }
2614
+ for(i=0; i<=n-2; i++)
2615
+ {
2616
+ if( ae_fp_greater_eq(x->ptr.p_double[i],x->ptr.p_double[i+1]) )
2617
+ {
2618
+ *info = -4;
2619
+ }
2620
+ }
2621
+ }
2622
+ ae_frame_leave(_state);
2623
+ }
2624
+
2625
+
2626
+ /*************************************************************************
2627
+ Returns Gauss and Gauss-Kronrod nodes for quadrature with N points using
2628
+ pre-calculated table. Nodes/weights were computed with accuracy up to
2629
+ 1.0E-32 (if MPFR version of ALGLIB is used). In standard double precision
2630
+ accuracy reduces to something about 2.0E-16 (depending on your compiler's
2631
+ handling of long floating point constants).
2632
+
2633
+ INPUT PARAMETERS:
2634
+ N - number of Kronrod nodes.
2635
+ N can be 15, 21, 31, 41, 51, 61.
2636
+
2637
+ OUTPUT PARAMETERS:
2638
+ X - array[0..N-1] - array of quadrature nodes, ordered in
2639
+ ascending order.
2640
+ WKronrod - array[0..N-1] - Kronrod weights
2641
+ WGauss - array[0..N-1] - Gauss weights (interleaved with zeros
2642
+ corresponding to extended Kronrod nodes).
2643
+
2644
+
2645
+ -- ALGLIB --
2646
+ Copyright 12.05.2009 by Bochkanov Sergey
2647
+ *************************************************************************/
2648
+ void gkqlegendretbl(ae_int_t n,
2649
+ /* Real */ ae_vector* x,
2650
+ /* Real */ ae_vector* wkronrod,
2651
+ /* Real */ ae_vector* wgauss,
2652
+ double* eps,
2653
+ ae_state *_state)
2654
+ {
2655
+ ae_frame _frame_block;
2656
+ ae_int_t i;
2657
+ ae_int_t ng;
2658
+ ae_vector p1;
2659
+ ae_vector p2;
2660
+ double tmp;
2661
+
2662
+ ae_frame_make(_state, &_frame_block);
2663
+ memset(&p1, 0, sizeof(p1));
2664
+ memset(&p2, 0, sizeof(p2));
2665
+ ae_vector_clear(x);
2666
+ ae_vector_clear(wkronrod);
2667
+ ae_vector_clear(wgauss);
2668
+ *eps = 0.0;
2669
+ ae_vector_init(&p1, 0, DT_INT, _state, ae_true);
2670
+ ae_vector_init(&p2, 0, DT_INT, _state, ae_true);
2671
+
2672
+
2673
+ /*
2674
+ * these initializers are not really necessary,
2675
+ * but without them compiler complains about uninitialized locals
2676
+ */
2677
+ ng = 0;
2678
+
2679
+ /*
2680
+ * Process
2681
+ */
2682
+ ae_assert(((((n==15||n==21)||n==31)||n==41)||n==51)||n==61, "GKQNodesTbl: incorrect N!", _state);
2683
+ ae_vector_set_length(x, n, _state);
2684
+ ae_vector_set_length(wkronrod, n, _state);
2685
+ ae_vector_set_length(wgauss, n, _state);
2686
+ for(i=0; i<=n-1; i++)
2687
+ {
2688
+ x->ptr.p_double[i] = (double)(0);
2689
+ wkronrod->ptr.p_double[i] = (double)(0);
2690
+ wgauss->ptr.p_double[i] = (double)(0);
2691
+ }
2692
+ *eps = ae_maxreal(ae_machineepsilon, 1.0E-32, _state);
2693
+ if( n==15 )
2694
+ {
2695
+ ng = 4;
2696
+ wgauss->ptr.p_double[0] = 0.129484966168869693270611432679082;
2697
+ wgauss->ptr.p_double[1] = 0.279705391489276667901467771423780;
2698
+ wgauss->ptr.p_double[2] = 0.381830050505118944950369775488975;
2699
+ wgauss->ptr.p_double[3] = 0.417959183673469387755102040816327;
2700
+ x->ptr.p_double[0] = 0.991455371120812639206854697526329;
2701
+ x->ptr.p_double[1] = 0.949107912342758524526189684047851;
2702
+ x->ptr.p_double[2] = 0.864864423359769072789712788640926;
2703
+ x->ptr.p_double[3] = 0.741531185599394439863864773280788;
2704
+ x->ptr.p_double[4] = 0.586087235467691130294144838258730;
2705
+ x->ptr.p_double[5] = 0.405845151377397166906606412076961;
2706
+ x->ptr.p_double[6] = 0.207784955007898467600689403773245;
2707
+ x->ptr.p_double[7] = 0.000000000000000000000000000000000;
2708
+ wkronrod->ptr.p_double[0] = 0.022935322010529224963732008058970;
2709
+ wkronrod->ptr.p_double[1] = 0.063092092629978553290700663189204;
2710
+ wkronrod->ptr.p_double[2] = 0.104790010322250183839876322541518;
2711
+ wkronrod->ptr.p_double[3] = 0.140653259715525918745189590510238;
2712
+ wkronrod->ptr.p_double[4] = 0.169004726639267902826583426598550;
2713
+ wkronrod->ptr.p_double[5] = 0.190350578064785409913256402421014;
2714
+ wkronrod->ptr.p_double[6] = 0.204432940075298892414161999234649;
2715
+ wkronrod->ptr.p_double[7] = 0.209482141084727828012999174891714;
2716
+ }
2717
+ if( n==21 )
2718
+ {
2719
+ ng = 5;
2720
+ wgauss->ptr.p_double[0] = 0.066671344308688137593568809893332;
2721
+ wgauss->ptr.p_double[1] = 0.149451349150580593145776339657697;
2722
+ wgauss->ptr.p_double[2] = 0.219086362515982043995534934228163;
2723
+ wgauss->ptr.p_double[3] = 0.269266719309996355091226921569469;
2724
+ wgauss->ptr.p_double[4] = 0.295524224714752870173892994651338;
2725
+ x->ptr.p_double[0] = 0.995657163025808080735527280689003;
2726
+ x->ptr.p_double[1] = 0.973906528517171720077964012084452;
2727
+ x->ptr.p_double[2] = 0.930157491355708226001207180059508;
2728
+ x->ptr.p_double[3] = 0.865063366688984510732096688423493;
2729
+ x->ptr.p_double[4] = 0.780817726586416897063717578345042;
2730
+ x->ptr.p_double[5] = 0.679409568299024406234327365114874;
2731
+ x->ptr.p_double[6] = 0.562757134668604683339000099272694;
2732
+ x->ptr.p_double[7] = 0.433395394129247190799265943165784;
2733
+ x->ptr.p_double[8] = 0.294392862701460198131126603103866;
2734
+ x->ptr.p_double[9] = 0.148874338981631210884826001129720;
2735
+ x->ptr.p_double[10] = 0.000000000000000000000000000000000;
2736
+ wkronrod->ptr.p_double[0] = 0.011694638867371874278064396062192;
2737
+ wkronrod->ptr.p_double[1] = 0.032558162307964727478818972459390;
2738
+ wkronrod->ptr.p_double[2] = 0.054755896574351996031381300244580;
2739
+ wkronrod->ptr.p_double[3] = 0.075039674810919952767043140916190;
2740
+ wkronrod->ptr.p_double[4] = 0.093125454583697605535065465083366;
2741
+ wkronrod->ptr.p_double[5] = 0.109387158802297641899210590325805;
2742
+ wkronrod->ptr.p_double[6] = 0.123491976262065851077958109831074;
2743
+ wkronrod->ptr.p_double[7] = 0.134709217311473325928054001771707;
2744
+ wkronrod->ptr.p_double[8] = 0.142775938577060080797094273138717;
2745
+ wkronrod->ptr.p_double[9] = 0.147739104901338491374841515972068;
2746
+ wkronrod->ptr.p_double[10] = 0.149445554002916905664936468389821;
2747
+ }
2748
+ if( n==31 )
2749
+ {
2750
+ ng = 8;
2751
+ wgauss->ptr.p_double[0] = 0.030753241996117268354628393577204;
2752
+ wgauss->ptr.p_double[1] = 0.070366047488108124709267416450667;
2753
+ wgauss->ptr.p_double[2] = 0.107159220467171935011869546685869;
2754
+ wgauss->ptr.p_double[3] = 0.139570677926154314447804794511028;
2755
+ wgauss->ptr.p_double[4] = 0.166269205816993933553200860481209;
2756
+ wgauss->ptr.p_double[5] = 0.186161000015562211026800561866423;
2757
+ wgauss->ptr.p_double[6] = 0.198431485327111576456118326443839;
2758
+ wgauss->ptr.p_double[7] = 0.202578241925561272880620199967519;
2759
+ x->ptr.p_double[0] = 0.998002298693397060285172840152271;
2760
+ x->ptr.p_double[1] = 0.987992518020485428489565718586613;
2761
+ x->ptr.p_double[2] = 0.967739075679139134257347978784337;
2762
+ x->ptr.p_double[3] = 0.937273392400705904307758947710209;
2763
+ x->ptr.p_double[4] = 0.897264532344081900882509656454496;
2764
+ x->ptr.p_double[5] = 0.848206583410427216200648320774217;
2765
+ x->ptr.p_double[6] = 0.790418501442465932967649294817947;
2766
+ x->ptr.p_double[7] = 0.724417731360170047416186054613938;
2767
+ x->ptr.p_double[8] = 0.650996741297416970533735895313275;
2768
+ x->ptr.p_double[9] = 0.570972172608538847537226737253911;
2769
+ x->ptr.p_double[10] = 0.485081863640239680693655740232351;
2770
+ x->ptr.p_double[11] = 0.394151347077563369897207370981045;
2771
+ x->ptr.p_double[12] = 0.299180007153168812166780024266389;
2772
+ x->ptr.p_double[13] = 0.201194093997434522300628303394596;
2773
+ x->ptr.p_double[14] = 0.101142066918717499027074231447392;
2774
+ x->ptr.p_double[15] = 0.000000000000000000000000000000000;
2775
+ wkronrod->ptr.p_double[0] = 0.005377479872923348987792051430128;
2776
+ wkronrod->ptr.p_double[1] = 0.015007947329316122538374763075807;
2777
+ wkronrod->ptr.p_double[2] = 0.025460847326715320186874001019653;
2778
+ wkronrod->ptr.p_double[3] = 0.035346360791375846222037948478360;
2779
+ wkronrod->ptr.p_double[4] = 0.044589751324764876608227299373280;
2780
+ wkronrod->ptr.p_double[5] = 0.053481524690928087265343147239430;
2781
+ wkronrod->ptr.p_double[6] = 0.062009567800670640285139230960803;
2782
+ wkronrod->ptr.p_double[7] = 0.069854121318728258709520077099147;
2783
+ wkronrod->ptr.p_double[8] = 0.076849680757720378894432777482659;
2784
+ wkronrod->ptr.p_double[9] = 0.083080502823133021038289247286104;
2785
+ wkronrod->ptr.p_double[10] = 0.088564443056211770647275443693774;
2786
+ wkronrod->ptr.p_double[11] = 0.093126598170825321225486872747346;
2787
+ wkronrod->ptr.p_double[12] = 0.096642726983623678505179907627589;
2788
+ wkronrod->ptr.p_double[13] = 0.099173598721791959332393173484603;
2789
+ wkronrod->ptr.p_double[14] = 0.100769845523875595044946662617570;
2790
+ wkronrod->ptr.p_double[15] = 0.101330007014791549017374792767493;
2791
+ }
2792
+ if( n==41 )
2793
+ {
2794
+ ng = 10;
2795
+ wgauss->ptr.p_double[0] = 0.017614007139152118311861962351853;
2796
+ wgauss->ptr.p_double[1] = 0.040601429800386941331039952274932;
2797
+ wgauss->ptr.p_double[2] = 0.062672048334109063569506535187042;
2798
+ wgauss->ptr.p_double[3] = 0.083276741576704748724758143222046;
2799
+ wgauss->ptr.p_double[4] = 0.101930119817240435036750135480350;
2800
+ wgauss->ptr.p_double[5] = 0.118194531961518417312377377711382;
2801
+ wgauss->ptr.p_double[6] = 0.131688638449176626898494499748163;
2802
+ wgauss->ptr.p_double[7] = 0.142096109318382051329298325067165;
2803
+ wgauss->ptr.p_double[8] = 0.149172986472603746787828737001969;
2804
+ wgauss->ptr.p_double[9] = 0.152753387130725850698084331955098;
2805
+ x->ptr.p_double[0] = 0.998859031588277663838315576545863;
2806
+ x->ptr.p_double[1] = 0.993128599185094924786122388471320;
2807
+ x->ptr.p_double[2] = 0.981507877450250259193342994720217;
2808
+ x->ptr.p_double[3] = 0.963971927277913791267666131197277;
2809
+ x->ptr.p_double[4] = 0.940822633831754753519982722212443;
2810
+ x->ptr.p_double[5] = 0.912234428251325905867752441203298;
2811
+ x->ptr.p_double[6] = 0.878276811252281976077442995113078;
2812
+ x->ptr.p_double[7] = 0.839116971822218823394529061701521;
2813
+ x->ptr.p_double[8] = 0.795041428837551198350638833272788;
2814
+ x->ptr.p_double[9] = 0.746331906460150792614305070355642;
2815
+ x->ptr.p_double[10] = 0.693237656334751384805490711845932;
2816
+ x->ptr.p_double[11] = 0.636053680726515025452836696226286;
2817
+ x->ptr.p_double[12] = 0.575140446819710315342946036586425;
2818
+ x->ptr.p_double[13] = 0.510867001950827098004364050955251;
2819
+ x->ptr.p_double[14] = 0.443593175238725103199992213492640;
2820
+ x->ptr.p_double[15] = 0.373706088715419560672548177024927;
2821
+ x->ptr.p_double[16] = 0.301627868114913004320555356858592;
2822
+ x->ptr.p_double[17] = 0.227785851141645078080496195368575;
2823
+ x->ptr.p_double[18] = 0.152605465240922675505220241022678;
2824
+ x->ptr.p_double[19] = 0.076526521133497333754640409398838;
2825
+ x->ptr.p_double[20] = 0.000000000000000000000000000000000;
2826
+ wkronrod->ptr.p_double[0] = 0.003073583718520531501218293246031;
2827
+ wkronrod->ptr.p_double[1] = 0.008600269855642942198661787950102;
2828
+ wkronrod->ptr.p_double[2] = 0.014626169256971252983787960308868;
2829
+ wkronrod->ptr.p_double[3] = 0.020388373461266523598010231432755;
2830
+ wkronrod->ptr.p_double[4] = 0.025882133604951158834505067096153;
2831
+ wkronrod->ptr.p_double[5] = 0.031287306777032798958543119323801;
2832
+ wkronrod->ptr.p_double[6] = 0.036600169758200798030557240707211;
2833
+ wkronrod->ptr.p_double[7] = 0.041668873327973686263788305936895;
2834
+ wkronrod->ptr.p_double[8] = 0.046434821867497674720231880926108;
2835
+ wkronrod->ptr.p_double[9] = 0.050944573923728691932707670050345;
2836
+ wkronrod->ptr.p_double[10] = 0.055195105348285994744832372419777;
2837
+ wkronrod->ptr.p_double[11] = 0.059111400880639572374967220648594;
2838
+ wkronrod->ptr.p_double[12] = 0.062653237554781168025870122174255;
2839
+ wkronrod->ptr.p_double[13] = 0.065834597133618422111563556969398;
2840
+ wkronrod->ptr.p_double[14] = 0.068648672928521619345623411885368;
2841
+ wkronrod->ptr.p_double[15] = 0.071054423553444068305790361723210;
2842
+ wkronrod->ptr.p_double[16] = 0.073030690332786667495189417658913;
2843
+ wkronrod->ptr.p_double[17] = 0.074582875400499188986581418362488;
2844
+ wkronrod->ptr.p_double[18] = 0.075704497684556674659542775376617;
2845
+ wkronrod->ptr.p_double[19] = 0.076377867672080736705502835038061;
2846
+ wkronrod->ptr.p_double[20] = 0.076600711917999656445049901530102;
2847
+ }
2848
+ if( n==51 )
2849
+ {
2850
+ ng = 13;
2851
+ wgauss->ptr.p_double[0] = 0.011393798501026287947902964113235;
2852
+ wgauss->ptr.p_double[1] = 0.026354986615032137261901815295299;
2853
+ wgauss->ptr.p_double[2] = 0.040939156701306312655623487711646;
2854
+ wgauss->ptr.p_double[3] = 0.054904695975835191925936891540473;
2855
+ wgauss->ptr.p_double[4] = 0.068038333812356917207187185656708;
2856
+ wgauss->ptr.p_double[5] = 0.080140700335001018013234959669111;
2857
+ wgauss->ptr.p_double[6] = 0.091028261982963649811497220702892;
2858
+ wgauss->ptr.p_double[7] = 0.100535949067050644202206890392686;
2859
+ wgauss->ptr.p_double[8] = 0.108519624474263653116093957050117;
2860
+ wgauss->ptr.p_double[9] = 0.114858259145711648339325545869556;
2861
+ wgauss->ptr.p_double[10] = 0.119455763535784772228178126512901;
2862
+ wgauss->ptr.p_double[11] = 0.122242442990310041688959518945852;
2863
+ wgauss->ptr.p_double[12] = 0.123176053726715451203902873079050;
2864
+ x->ptr.p_double[0] = 0.999262104992609834193457486540341;
2865
+ x->ptr.p_double[1] = 0.995556969790498097908784946893902;
2866
+ x->ptr.p_double[2] = 0.988035794534077247637331014577406;
2867
+ x->ptr.p_double[3] = 0.976663921459517511498315386479594;
2868
+ x->ptr.p_double[4] = 0.961614986425842512418130033660167;
2869
+ x->ptr.p_double[5] = 0.942974571228974339414011169658471;
2870
+ x->ptr.p_double[6] = 0.920747115281701561746346084546331;
2871
+ x->ptr.p_double[7] = 0.894991997878275368851042006782805;
2872
+ x->ptr.p_double[8] = 0.865847065293275595448996969588340;
2873
+ x->ptr.p_double[9] = 0.833442628760834001421021108693570;
2874
+ x->ptr.p_double[10] = 0.797873797998500059410410904994307;
2875
+ x->ptr.p_double[11] = 0.759259263037357630577282865204361;
2876
+ x->ptr.p_double[12] = 0.717766406813084388186654079773298;
2877
+ x->ptr.p_double[13] = 0.673566368473468364485120633247622;
2878
+ x->ptr.p_double[14] = 0.626810099010317412788122681624518;
2879
+ x->ptr.p_double[15] = 0.577662930241222967723689841612654;
2880
+ x->ptr.p_double[16] = 0.526325284334719182599623778158010;
2881
+ x->ptr.p_double[17] = 0.473002731445714960522182115009192;
2882
+ x->ptr.p_double[18] = 0.417885382193037748851814394594572;
2883
+ x->ptr.p_double[19] = 0.361172305809387837735821730127641;
2884
+ x->ptr.p_double[20] = 0.303089538931107830167478909980339;
2885
+ x->ptr.p_double[21] = 0.243866883720988432045190362797452;
2886
+ x->ptr.p_double[22] = 0.183718939421048892015969888759528;
2887
+ x->ptr.p_double[23] = 0.122864692610710396387359818808037;
2888
+ x->ptr.p_double[24] = 0.061544483005685078886546392366797;
2889
+ x->ptr.p_double[25] = 0.000000000000000000000000000000000;
2890
+ wkronrod->ptr.p_double[0] = 0.001987383892330315926507851882843;
2891
+ wkronrod->ptr.p_double[1] = 0.005561932135356713758040236901066;
2892
+ wkronrod->ptr.p_double[2] = 0.009473973386174151607207710523655;
2893
+ wkronrod->ptr.p_double[3] = 0.013236229195571674813656405846976;
2894
+ wkronrod->ptr.p_double[4] = 0.016847817709128298231516667536336;
2895
+ wkronrod->ptr.p_double[5] = 0.020435371145882835456568292235939;
2896
+ wkronrod->ptr.p_double[6] = 0.024009945606953216220092489164881;
2897
+ wkronrod->ptr.p_double[7] = 0.027475317587851737802948455517811;
2898
+ wkronrod->ptr.p_double[8] = 0.030792300167387488891109020215229;
2899
+ wkronrod->ptr.p_double[9] = 0.034002130274329337836748795229551;
2900
+ wkronrod->ptr.p_double[10] = 0.037116271483415543560330625367620;
2901
+ wkronrod->ptr.p_double[11] = 0.040083825504032382074839284467076;
2902
+ wkronrod->ptr.p_double[12] = 0.042872845020170049476895792439495;
2903
+ wkronrod->ptr.p_double[13] = 0.045502913049921788909870584752660;
2904
+ wkronrod->ptr.p_double[14] = 0.047982537138836713906392255756915;
2905
+ wkronrod->ptr.p_double[15] = 0.050277679080715671963325259433440;
2906
+ wkronrod->ptr.p_double[16] = 0.052362885806407475864366712137873;
2907
+ wkronrod->ptr.p_double[17] = 0.054251129888545490144543370459876;
2908
+ wkronrod->ptr.p_double[18] = 0.055950811220412317308240686382747;
2909
+ wkronrod->ptr.p_double[19] = 0.057437116361567832853582693939506;
2910
+ wkronrod->ptr.p_double[20] = 0.058689680022394207961974175856788;
2911
+ wkronrod->ptr.p_double[21] = 0.059720340324174059979099291932562;
2912
+ wkronrod->ptr.p_double[22] = 0.060539455376045862945360267517565;
2913
+ wkronrod->ptr.p_double[23] = 0.061128509717053048305859030416293;
2914
+ wkronrod->ptr.p_double[24] = 0.061471189871425316661544131965264;
2915
+ wkronrod->ptr.p_double[25] = 0.061580818067832935078759824240055;
2916
+ }
2917
+ if( n==61 )
2918
+ {
2919
+ ng = 15;
2920
+ wgauss->ptr.p_double[0] = 0.007968192496166605615465883474674;
2921
+ wgauss->ptr.p_double[1] = 0.018466468311090959142302131912047;
2922
+ wgauss->ptr.p_double[2] = 0.028784707883323369349719179611292;
2923
+ wgauss->ptr.p_double[3] = 0.038799192569627049596801936446348;
2924
+ wgauss->ptr.p_double[4] = 0.048402672830594052902938140422808;
2925
+ wgauss->ptr.p_double[5] = 0.057493156217619066481721689402056;
2926
+ wgauss->ptr.p_double[6] = 0.065974229882180495128128515115962;
2927
+ wgauss->ptr.p_double[7] = 0.073755974737705206268243850022191;
2928
+ wgauss->ptr.p_double[8] = 0.080755895229420215354694938460530;
2929
+ wgauss->ptr.p_double[9] = 0.086899787201082979802387530715126;
2930
+ wgauss->ptr.p_double[10] = 0.092122522237786128717632707087619;
2931
+ wgauss->ptr.p_double[11] = 0.096368737174644259639468626351810;
2932
+ wgauss->ptr.p_double[12] = 0.099593420586795267062780282103569;
2933
+ wgauss->ptr.p_double[13] = 0.101762389748405504596428952168554;
2934
+ wgauss->ptr.p_double[14] = 0.102852652893558840341285636705415;
2935
+ x->ptr.p_double[0] = 0.999484410050490637571325895705811;
2936
+ x->ptr.p_double[1] = 0.996893484074649540271630050918695;
2937
+ x->ptr.p_double[2] = 0.991630996870404594858628366109486;
2938
+ x->ptr.p_double[3] = 0.983668123279747209970032581605663;
2939
+ x->ptr.p_double[4] = 0.973116322501126268374693868423707;
2940
+ x->ptr.p_double[5] = 0.960021864968307512216871025581798;
2941
+ x->ptr.p_double[6] = 0.944374444748559979415831324037439;
2942
+ x->ptr.p_double[7] = 0.926200047429274325879324277080474;
2943
+ x->ptr.p_double[8] = 0.905573307699907798546522558925958;
2944
+ x->ptr.p_double[9] = 0.882560535792052681543116462530226;
2945
+ x->ptr.p_double[10] = 0.857205233546061098958658510658944;
2946
+ x->ptr.p_double[11] = 0.829565762382768397442898119732502;
2947
+ x->ptr.p_double[12] = 0.799727835821839083013668942322683;
2948
+ x->ptr.p_double[13] = 0.767777432104826194917977340974503;
2949
+ x->ptr.p_double[14] = 0.733790062453226804726171131369528;
2950
+ x->ptr.p_double[15] = 0.697850494793315796932292388026640;
2951
+ x->ptr.p_double[16] = 0.660061064126626961370053668149271;
2952
+ x->ptr.p_double[17] = 0.620526182989242861140477556431189;
2953
+ x->ptr.p_double[18] = 0.579345235826361691756024932172540;
2954
+ x->ptr.p_double[19] = 0.536624148142019899264169793311073;
2955
+ x->ptr.p_double[20] = 0.492480467861778574993693061207709;
2956
+ x->ptr.p_double[21] = 0.447033769538089176780609900322854;
2957
+ x->ptr.p_double[22] = 0.400401254830394392535476211542661;
2958
+ x->ptr.p_double[23] = 0.352704725530878113471037207089374;
2959
+ x->ptr.p_double[24] = 0.304073202273625077372677107199257;
2960
+ x->ptr.p_double[25] = 0.254636926167889846439805129817805;
2961
+ x->ptr.p_double[26] = 0.204525116682309891438957671002025;
2962
+ x->ptr.p_double[27] = 0.153869913608583546963794672743256;
2963
+ x->ptr.p_double[28] = 0.102806937966737030147096751318001;
2964
+ x->ptr.p_double[29] = 0.051471842555317695833025213166723;
2965
+ x->ptr.p_double[30] = 0.000000000000000000000000000000000;
2966
+ wkronrod->ptr.p_double[0] = 0.001389013698677007624551591226760;
2967
+ wkronrod->ptr.p_double[1] = 0.003890461127099884051267201844516;
2968
+ wkronrod->ptr.p_double[2] = 0.006630703915931292173319826369750;
2969
+ wkronrod->ptr.p_double[3] = 0.009273279659517763428441146892024;
2970
+ wkronrod->ptr.p_double[4] = 0.011823015253496341742232898853251;
2971
+ wkronrod->ptr.p_double[5] = 0.014369729507045804812451432443580;
2972
+ wkronrod->ptr.p_double[6] = 0.016920889189053272627572289420322;
2973
+ wkronrod->ptr.p_double[7] = 0.019414141193942381173408951050128;
2974
+ wkronrod->ptr.p_double[8] = 0.021828035821609192297167485738339;
2975
+ wkronrod->ptr.p_double[9] = 0.024191162078080601365686370725232;
2976
+ wkronrod->ptr.p_double[10] = 0.026509954882333101610601709335075;
2977
+ wkronrod->ptr.p_double[11] = 0.028754048765041292843978785354334;
2978
+ wkronrod->ptr.p_double[12] = 0.030907257562387762472884252943092;
2979
+ wkronrod->ptr.p_double[13] = 0.032981447057483726031814191016854;
2980
+ wkronrod->ptr.p_double[14] = 0.034979338028060024137499670731468;
2981
+ wkronrod->ptr.p_double[15] = 0.036882364651821229223911065617136;
2982
+ wkronrod->ptr.p_double[16] = 0.038678945624727592950348651532281;
2983
+ wkronrod->ptr.p_double[17] = 0.040374538951535959111995279752468;
2984
+ wkronrod->ptr.p_double[18] = 0.041969810215164246147147541285970;
2985
+ wkronrod->ptr.p_double[19] = 0.043452539701356069316831728117073;
2986
+ wkronrod->ptr.p_double[20] = 0.044814800133162663192355551616723;
2987
+ wkronrod->ptr.p_double[21] = 0.046059238271006988116271735559374;
2988
+ wkronrod->ptr.p_double[22] = 0.047185546569299153945261478181099;
2989
+ wkronrod->ptr.p_double[23] = 0.048185861757087129140779492298305;
2990
+ wkronrod->ptr.p_double[24] = 0.049055434555029778887528165367238;
2991
+ wkronrod->ptr.p_double[25] = 0.049795683427074206357811569379942;
2992
+ wkronrod->ptr.p_double[26] = 0.050405921402782346840893085653585;
2993
+ wkronrod->ptr.p_double[27] = 0.050881795898749606492297473049805;
2994
+ wkronrod->ptr.p_double[28] = 0.051221547849258772170656282604944;
2995
+ wkronrod->ptr.p_double[29] = 0.051426128537459025933862879215781;
2996
+ wkronrod->ptr.p_double[30] = 0.051494729429451567558340433647099;
2997
+ }
2998
+
2999
+ /*
3000
+ * copy nodes
3001
+ */
3002
+ for(i=n-1; i>=n/2; i--)
3003
+ {
3004
+ x->ptr.p_double[i] = -x->ptr.p_double[n-1-i];
3005
+ }
3006
+
3007
+ /*
3008
+ * copy Kronrod weights
3009
+ */
3010
+ for(i=n-1; i>=n/2; i--)
3011
+ {
3012
+ wkronrod->ptr.p_double[i] = wkronrod->ptr.p_double[n-1-i];
3013
+ }
3014
+
3015
+ /*
3016
+ * copy Gauss weights
3017
+ */
3018
+ for(i=ng-1; i>=0; i--)
3019
+ {
3020
+ wgauss->ptr.p_double[n-2-2*i] = wgauss->ptr.p_double[i];
3021
+ wgauss->ptr.p_double[1+2*i] = wgauss->ptr.p_double[i];
3022
+ }
3023
+ for(i=0; i<=n/2; i++)
3024
+ {
3025
+ wgauss->ptr.p_double[2*i] = (double)(0);
3026
+ }
3027
+
3028
+ /*
3029
+ * reorder
3030
+ */
3031
+ tagsort(x, n, &p1, &p2, _state);
3032
+ for(i=0; i<=n-1; i++)
3033
+ {
3034
+ tmp = wkronrod->ptr.p_double[i];
3035
+ wkronrod->ptr.p_double[i] = wkronrod->ptr.p_double[p2.ptr.p_int[i]];
3036
+ wkronrod->ptr.p_double[p2.ptr.p_int[i]] = tmp;
3037
+ tmp = wgauss->ptr.p_double[i];
3038
+ wgauss->ptr.p_double[i] = wgauss->ptr.p_double[p2.ptr.p_int[i]];
3039
+ wgauss->ptr.p_double[p2.ptr.p_int[i]] = tmp;
3040
+ }
3041
+ ae_frame_leave(_state);
3042
+ }
3043
+
3044
+
3045
+ #endif
3046
+ #if defined(AE_COMPILE_AUTOGK) || !defined(AE_PARTIAL_BUILD)
3047
+
3048
+
3049
+ /*************************************************************************
3050
+ Integration of a smooth function F(x) on a finite interval [a,b].
3051
+
3052
+ Fast-convergent algorithm based on a Gauss-Kronrod formula is used. Result
3053
+ is calculated with accuracy close to the machine precision.
3054
+
3055
+ Algorithm works well only with smooth integrands. It may be used with
3056
+ continuous non-smooth integrands, but with less performance.
3057
+
3058
+ It should never be used with integrands which have integrable singularities
3059
+ at lower or upper limits - algorithm may crash. Use AutoGKSingular in such
3060
+ cases.
3061
+
3062
+ INPUT PARAMETERS:
3063
+ A, B - interval boundaries (A<B, A=B or A>B)
3064
+
3065
+ OUTPUT PARAMETERS
3066
+ State - structure which stores algorithm state
3067
+
3068
+ SEE ALSO
3069
+ AutoGKSmoothW, AutoGKSingular, AutoGKResults.
3070
+
3071
+
3072
+ -- ALGLIB --
3073
+ Copyright 06.05.2009 by Bochkanov Sergey
3074
+ *************************************************************************/
3075
+ void autogksmooth(double a,
3076
+ double b,
3077
+ autogkstate* state,
3078
+ ae_state *_state)
3079
+ {
3080
+
3081
+ _autogkstate_clear(state);
3082
+
3083
+ ae_assert(ae_isfinite(a, _state), "AutoGKSmooth: A is not finite!", _state);
3084
+ ae_assert(ae_isfinite(b, _state), "AutoGKSmooth: B is not finite!", _state);
3085
+ autogksmoothw(a, b, 0.0, state, _state);
3086
+ }
3087
+
3088
+
3089
+ /*************************************************************************
3090
+ Integration of a smooth function F(x) on a finite interval [a,b].
3091
+
3092
+ This subroutine is same as AutoGKSmooth(), but it guarantees that interval
3093
+ [a,b] is partitioned into subintervals which have width at most XWidth.
3094
+
3095
+ Subroutine can be used when integrating nearly-constant function with
3096
+ narrow "bumps" (about XWidth wide). If "bumps" are too narrow, AutoGKSmooth
3097
+ subroutine can overlook them.
3098
+
3099
+ INPUT PARAMETERS:
3100
+ A, B - interval boundaries (A<B, A=B or A>B)
3101
+
3102
+ OUTPUT PARAMETERS
3103
+ State - structure which stores algorithm state
3104
+
3105
+ SEE ALSO
3106
+ AutoGKSmooth, AutoGKSingular, AutoGKResults.
3107
+
3108
+
3109
+ -- ALGLIB --
3110
+ Copyright 06.05.2009 by Bochkanov Sergey
3111
+ *************************************************************************/
3112
+ void autogksmoothw(double a,
3113
+ double b,
3114
+ double xwidth,
3115
+ autogkstate* state,
3116
+ ae_state *_state)
3117
+ {
3118
+
3119
+ _autogkstate_clear(state);
3120
+
3121
+ ae_assert(ae_isfinite(a, _state), "AutoGKSmoothW: A is not finite!", _state);
3122
+ ae_assert(ae_isfinite(b, _state), "AutoGKSmoothW: B is not finite!", _state);
3123
+ ae_assert(ae_isfinite(xwidth, _state), "AutoGKSmoothW: XWidth is not finite!", _state);
3124
+ state->wrappermode = 0;
3125
+ state->a = a;
3126
+ state->b = b;
3127
+ state->xwidth = xwidth;
3128
+ state->needf = ae_false;
3129
+ ae_vector_set_length(&state->rstate.ra, 10+1, _state);
3130
+ state->rstate.stage = -1;
3131
+ }
3132
+
3133
+
3134
+ /*************************************************************************
3135
+ Integration on a finite interval [A,B].
3136
+ Integrand have integrable singularities at A/B.
3137
+
3138
+ F(X) must diverge as "(x-A)^alpha" at A, as "(B-x)^beta" at B, with known
3139
+ alpha/beta (alpha>-1, beta>-1). If alpha/beta are not known, estimates
3140
+ from below can be used (but these estimates should be greater than -1 too).
3141
+
3142
+ One of alpha/beta variables (or even both alpha/beta) may be equal to 0,
3143
+ which means than function F(x) is non-singular at A/B. Anyway (singular at
3144
+ bounds or not), function F(x) is supposed to be continuous on (A,B).
3145
+
3146
+ Fast-convergent algorithm based on a Gauss-Kronrod formula is used. Result
3147
+ is calculated with accuracy close to the machine precision.
3148
+
3149
+ INPUT PARAMETERS:
3150
+ A, B - interval boundaries (A<B, A=B or A>B)
3151
+ Alpha - power-law coefficient of the F(x) at A,
3152
+ Alpha>-1
3153
+ Beta - power-law coefficient of the F(x) at B,
3154
+ Beta>-1
3155
+
3156
+ OUTPUT PARAMETERS
3157
+ State - structure which stores algorithm state
3158
+
3159
+ SEE ALSO
3160
+ AutoGKSmooth, AutoGKSmoothW, AutoGKResults.
3161
+
3162
+
3163
+ -- ALGLIB --
3164
+ Copyright 06.05.2009 by Bochkanov Sergey
3165
+ *************************************************************************/
3166
+ void autogksingular(double a,
3167
+ double b,
3168
+ double alpha,
3169
+ double beta,
3170
+ autogkstate* state,
3171
+ ae_state *_state)
3172
+ {
3173
+
3174
+ _autogkstate_clear(state);
3175
+
3176
+ ae_assert(ae_isfinite(a, _state), "AutoGKSingular: A is not finite!", _state);
3177
+ ae_assert(ae_isfinite(b, _state), "AutoGKSingular: B is not finite!", _state);
3178
+ ae_assert(ae_isfinite(alpha, _state), "AutoGKSingular: Alpha is not finite!", _state);
3179
+ ae_assert(ae_isfinite(beta, _state), "AutoGKSingular: Beta is not finite!", _state);
3180
+ state->wrappermode = 1;
3181
+ state->a = a;
3182
+ state->b = b;
3183
+ state->alpha = alpha;
3184
+ state->beta = beta;
3185
+ state->xwidth = 0.0;
3186
+ state->needf = ae_false;
3187
+ ae_vector_set_length(&state->rstate.ra, 10+1, _state);
3188
+ state->rstate.stage = -1;
3189
+ }
3190
+
3191
+
3192
+ /*************************************************************************
3193
+
3194
+ -- ALGLIB --
3195
+ Copyright 07.05.2009 by Bochkanov Sergey
3196
+ *************************************************************************/
3197
+ ae_bool autogkiteration(autogkstate* state, ae_state *_state)
3198
+ {
3199
+ double s;
3200
+ double tmp;
3201
+ double eps;
3202
+ double a;
3203
+ double b;
3204
+ double x;
3205
+ double t;
3206
+ double alpha;
3207
+ double beta;
3208
+ double v1;
3209
+ double v2;
3210
+ ae_bool result;
3211
+
3212
+
3213
+
3214
+ /*
3215
+ * Reverse communication preparations
3216
+ * I know it looks ugly, but it works the same way
3217
+ * anywhere from C++ to Python.
3218
+ *
3219
+ * This code initializes locals by:
3220
+ * * random values determined during code
3221
+ * generation - on first subroutine call
3222
+ * * values from previous call - on subsequent calls
3223
+ */
3224
+ if( state->rstate.stage>=0 )
3225
+ {
3226
+ s = state->rstate.ra.ptr.p_double[0];
3227
+ tmp = state->rstate.ra.ptr.p_double[1];
3228
+ eps = state->rstate.ra.ptr.p_double[2];
3229
+ a = state->rstate.ra.ptr.p_double[3];
3230
+ b = state->rstate.ra.ptr.p_double[4];
3231
+ x = state->rstate.ra.ptr.p_double[5];
3232
+ t = state->rstate.ra.ptr.p_double[6];
3233
+ alpha = state->rstate.ra.ptr.p_double[7];
3234
+ beta = state->rstate.ra.ptr.p_double[8];
3235
+ v1 = state->rstate.ra.ptr.p_double[9];
3236
+ v2 = state->rstate.ra.ptr.p_double[10];
3237
+ }
3238
+ else
3239
+ {
3240
+ s = 359.0;
3241
+ tmp = -58.0;
3242
+ eps = -919.0;
3243
+ a = -909.0;
3244
+ b = 81.0;
3245
+ x = 255.0;
3246
+ t = 74.0;
3247
+ alpha = -788.0;
3248
+ beta = 809.0;
3249
+ v1 = 205.0;
3250
+ v2 = -838.0;
3251
+ }
3252
+ if( state->rstate.stage==0 )
3253
+ {
3254
+ goto lbl_0;
3255
+ }
3256
+ if( state->rstate.stage==1 )
3257
+ {
3258
+ goto lbl_1;
3259
+ }
3260
+ if( state->rstate.stage==2 )
3261
+ {
3262
+ goto lbl_2;
3263
+ }
3264
+
3265
+ /*
3266
+ * Routine body
3267
+ */
3268
+ eps = (double)(0);
3269
+ a = state->a;
3270
+ b = state->b;
3271
+ alpha = state->alpha;
3272
+ beta = state->beta;
3273
+ state->terminationtype = -1;
3274
+ state->nfev = 0;
3275
+ state->nintervals = 0;
3276
+
3277
+ /*
3278
+ * smooth function at a finite interval
3279
+ */
3280
+ if( state->wrappermode!=0 )
3281
+ {
3282
+ goto lbl_3;
3283
+ }
3284
+
3285
+ /*
3286
+ * special case
3287
+ */
3288
+ if( ae_fp_eq(a,b) )
3289
+ {
3290
+ state->terminationtype = 1;
3291
+ state->v = (double)(0);
3292
+ result = ae_false;
3293
+ return result;
3294
+ }
3295
+
3296
+ /*
3297
+ * general case
3298
+ */
3299
+ autogk_autogkinternalprepare(a, b, eps, state->xwidth, &state->internalstate, _state);
3300
+ lbl_5:
3301
+ if( !autogk_autogkinternaliteration(&state->internalstate, _state) )
3302
+ {
3303
+ goto lbl_6;
3304
+ }
3305
+ x = state->internalstate.x;
3306
+ state->x = x;
3307
+ state->xminusa = x-a;
3308
+ state->bminusx = b-x;
3309
+ state->needf = ae_true;
3310
+ state->rstate.stage = 0;
3311
+ goto lbl_rcomm;
3312
+ lbl_0:
3313
+ state->needf = ae_false;
3314
+ state->nfev = state->nfev+1;
3315
+ state->internalstate.f = state->f;
3316
+ goto lbl_5;
3317
+ lbl_6:
3318
+ state->v = state->internalstate.r;
3319
+ state->terminationtype = state->internalstate.info;
3320
+ state->nintervals = state->internalstate.heapused;
3321
+ result = ae_false;
3322
+ return result;
3323
+ lbl_3:
3324
+
3325
+ /*
3326
+ * function with power-law singularities at the ends of a finite interval
3327
+ */
3328
+ if( state->wrappermode!=1 )
3329
+ {
3330
+ goto lbl_7;
3331
+ }
3332
+
3333
+ /*
3334
+ * test coefficients
3335
+ */
3336
+ if( ae_fp_less_eq(alpha,(double)(-1))||ae_fp_less_eq(beta,(double)(-1)) )
3337
+ {
3338
+ state->terminationtype = -1;
3339
+ state->v = (double)(0);
3340
+ result = ae_false;
3341
+ return result;
3342
+ }
3343
+
3344
+ /*
3345
+ * special cases
3346
+ */
3347
+ if( ae_fp_eq(a,b) )
3348
+ {
3349
+ state->terminationtype = 1;
3350
+ state->v = (double)(0);
3351
+ result = ae_false;
3352
+ return result;
3353
+ }
3354
+
3355
+ /*
3356
+ * reduction to general form
3357
+ */
3358
+ if( ae_fp_less(a,b) )
3359
+ {
3360
+ s = (double)(1);
3361
+ }
3362
+ else
3363
+ {
3364
+ s = (double)(-1);
3365
+ tmp = a;
3366
+ a = b;
3367
+ b = tmp;
3368
+ tmp = alpha;
3369
+ alpha = beta;
3370
+ beta = tmp;
3371
+ }
3372
+ alpha = ae_minreal(alpha, (double)(0), _state);
3373
+ beta = ae_minreal(beta, (double)(0), _state);
3374
+
3375
+ /*
3376
+ * first, integrate left half of [a,b]:
3377
+ * integral(f(x)dx, a, (b+a)/2) =
3378
+ * = 1/(1+alpha) * integral(t^(-alpha/(1+alpha))*f(a+t^(1/(1+alpha)))dt, 0, (0.5*(b-a))^(1+alpha))
3379
+ */
3380
+ autogk_autogkinternalprepare((double)(0), ae_pow(0.5*(b-a), (double)1+alpha, _state), eps, state->xwidth, &state->internalstate, _state);
3381
+ lbl_9:
3382
+ if( !autogk_autogkinternaliteration(&state->internalstate, _state) )
3383
+ {
3384
+ goto lbl_10;
3385
+ }
3386
+
3387
+ /*
3388
+ * Fill State.X, State.XMinusA, State.BMinusX.
3389
+ * Latter two are filled correctly even if B<A.
3390
+ */
3391
+ x = state->internalstate.x;
3392
+ t = ae_pow(x, (double)1/((double)1+alpha), _state);
3393
+ state->x = a+t;
3394
+ if( ae_fp_greater(s,(double)(0)) )
3395
+ {
3396
+ state->xminusa = t;
3397
+ state->bminusx = b-(a+t);
3398
+ }
3399
+ else
3400
+ {
3401
+ state->xminusa = a+t-b;
3402
+ state->bminusx = -t;
3403
+ }
3404
+ state->needf = ae_true;
3405
+ state->rstate.stage = 1;
3406
+ goto lbl_rcomm;
3407
+ lbl_1:
3408
+ state->needf = ae_false;
3409
+ if( ae_fp_neq(alpha,(double)(0)) )
3410
+ {
3411
+ state->internalstate.f = state->f*ae_pow(x, -alpha/((double)1+alpha), _state)/((double)1+alpha);
3412
+ }
3413
+ else
3414
+ {
3415
+ state->internalstate.f = state->f;
3416
+ }
3417
+ state->nfev = state->nfev+1;
3418
+ goto lbl_9;
3419
+ lbl_10:
3420
+ v1 = state->internalstate.r;
3421
+ state->nintervals = state->nintervals+state->internalstate.heapused;
3422
+
3423
+ /*
3424
+ * then, integrate right half of [a,b]:
3425
+ * integral(f(x)dx, (b+a)/2, b) =
3426
+ * = 1/(1+beta) * integral(t^(-beta/(1+beta))*f(b-t^(1/(1+beta)))dt, 0, (0.5*(b-a))^(1+beta))
3427
+ */
3428
+ autogk_autogkinternalprepare((double)(0), ae_pow(0.5*(b-a), (double)1+beta, _state), eps, state->xwidth, &state->internalstate, _state);
3429
+ lbl_11:
3430
+ if( !autogk_autogkinternaliteration(&state->internalstate, _state) )
3431
+ {
3432
+ goto lbl_12;
3433
+ }
3434
+
3435
+ /*
3436
+ * Fill State.X, State.XMinusA, State.BMinusX.
3437
+ * Latter two are filled correctly (X-A, B-X) even if B<A.
3438
+ */
3439
+ x = state->internalstate.x;
3440
+ t = ae_pow(x, (double)1/((double)1+beta), _state);
3441
+ state->x = b-t;
3442
+ if( ae_fp_greater(s,(double)(0)) )
3443
+ {
3444
+ state->xminusa = b-t-a;
3445
+ state->bminusx = t;
3446
+ }
3447
+ else
3448
+ {
3449
+ state->xminusa = -t;
3450
+ state->bminusx = a-(b-t);
3451
+ }
3452
+ state->needf = ae_true;
3453
+ state->rstate.stage = 2;
3454
+ goto lbl_rcomm;
3455
+ lbl_2:
3456
+ state->needf = ae_false;
3457
+ if( ae_fp_neq(beta,(double)(0)) )
3458
+ {
3459
+ state->internalstate.f = state->f*ae_pow(x, -beta/((double)1+beta), _state)/((double)1+beta);
3460
+ }
3461
+ else
3462
+ {
3463
+ state->internalstate.f = state->f;
3464
+ }
3465
+ state->nfev = state->nfev+1;
3466
+ goto lbl_11;
3467
+ lbl_12:
3468
+ v2 = state->internalstate.r;
3469
+ state->nintervals = state->nintervals+state->internalstate.heapused;
3470
+
3471
+ /*
3472
+ * final result
3473
+ */
3474
+ state->v = s*(v1+v2);
3475
+ state->terminationtype = 1;
3476
+ result = ae_false;
3477
+ return result;
3478
+ lbl_7:
3479
+ result = ae_false;
3480
+ return result;
3481
+
3482
+ /*
3483
+ * Saving state
3484
+ */
3485
+ lbl_rcomm:
3486
+ result = ae_true;
3487
+ state->rstate.ra.ptr.p_double[0] = s;
3488
+ state->rstate.ra.ptr.p_double[1] = tmp;
3489
+ state->rstate.ra.ptr.p_double[2] = eps;
3490
+ state->rstate.ra.ptr.p_double[3] = a;
3491
+ state->rstate.ra.ptr.p_double[4] = b;
3492
+ state->rstate.ra.ptr.p_double[5] = x;
3493
+ state->rstate.ra.ptr.p_double[6] = t;
3494
+ state->rstate.ra.ptr.p_double[7] = alpha;
3495
+ state->rstate.ra.ptr.p_double[8] = beta;
3496
+ state->rstate.ra.ptr.p_double[9] = v1;
3497
+ state->rstate.ra.ptr.p_double[10] = v2;
3498
+ return result;
3499
+ }
3500
+
3501
+
3502
+ /*************************************************************************
3503
+ Adaptive integration results
3504
+
3505
+ Called after AutoGKIteration returned False.
3506
+
3507
+ Input parameters:
3508
+ State - algorithm state (used by AutoGKIteration).
3509
+
3510
+ Output parameters:
3511
+ V - integral(f(x)dx,a,b)
3512
+ Rep - optimization report (see AutoGKReport description)
3513
+
3514
+ -- ALGLIB --
3515
+ Copyright 14.11.2007 by Bochkanov Sergey
3516
+ *************************************************************************/
3517
+ void autogkresults(const autogkstate* state,
3518
+ double* v,
3519
+ autogkreport* rep,
3520
+ ae_state *_state)
3521
+ {
3522
+
3523
+ *v = 0.0;
3524
+ _autogkreport_clear(rep);
3525
+
3526
+ *v = state->v;
3527
+ rep->terminationtype = state->terminationtype;
3528
+ rep->nfev = state->nfev;
3529
+ rep->nintervals = state->nintervals;
3530
+ }
3531
+
3532
+
3533
+ /*************************************************************************
3534
+ Internal AutoGK subroutine
3535
+ eps<0 - error
3536
+ eps=0 - automatic eps selection
3537
+
3538
+ width<0 - error
3539
+ width=0 - no width requirements
3540
+ *************************************************************************/
3541
+ static void autogk_autogkinternalprepare(double a,
3542
+ double b,
3543
+ double eps,
3544
+ double xwidth,
3545
+ autogkinternalstate* state,
3546
+ ae_state *_state)
3547
+ {
3548
+
3549
+
3550
+
3551
+ /*
3552
+ * Save settings
3553
+ */
3554
+ state->a = a;
3555
+ state->b = b;
3556
+ state->eps = eps;
3557
+ state->xwidth = xwidth;
3558
+
3559
+ /*
3560
+ * Prepare RComm structure
3561
+ */
3562
+ ae_vector_set_length(&state->rstate.ia, 3+1, _state);
3563
+ ae_vector_set_length(&state->rstate.ra, 8+1, _state);
3564
+ state->rstate.stage = -1;
3565
+ }
3566
+
3567
+
3568
+ /*************************************************************************
3569
+ Internal AutoGK subroutine
3570
+ *************************************************************************/
3571
+ static ae_bool autogk_autogkinternaliteration(autogkinternalstate* state,
3572
+ ae_state *_state)
3573
+ {
3574
+ double c1;
3575
+ double c2;
3576
+ ae_int_t i;
3577
+ ae_int_t j;
3578
+ double intg;
3579
+ double intk;
3580
+ double inta;
3581
+ double v;
3582
+ double ta;
3583
+ double tb;
3584
+ ae_int_t ns;
3585
+ double qeps;
3586
+ ae_int_t info;
3587
+ ae_bool result;
3588
+
3589
+
3590
+
3591
+ /*
3592
+ * Reverse communication preparations
3593
+ * I know it looks ugly, but it works the same way
3594
+ * anywhere from C++ to Python.
3595
+ *
3596
+ * This code initializes locals by:
3597
+ * * random values determined during code
3598
+ * generation - on first subroutine call
3599
+ * * values from previous call - on subsequent calls
3600
+ */
3601
+ if( state->rstate.stage>=0 )
3602
+ {
3603
+ i = state->rstate.ia.ptr.p_int[0];
3604
+ j = state->rstate.ia.ptr.p_int[1];
3605
+ ns = state->rstate.ia.ptr.p_int[2];
3606
+ info = state->rstate.ia.ptr.p_int[3];
3607
+ c1 = state->rstate.ra.ptr.p_double[0];
3608
+ c2 = state->rstate.ra.ptr.p_double[1];
3609
+ intg = state->rstate.ra.ptr.p_double[2];
3610
+ intk = state->rstate.ra.ptr.p_double[3];
3611
+ inta = state->rstate.ra.ptr.p_double[4];
3612
+ v = state->rstate.ra.ptr.p_double[5];
3613
+ ta = state->rstate.ra.ptr.p_double[6];
3614
+ tb = state->rstate.ra.ptr.p_double[7];
3615
+ qeps = state->rstate.ra.ptr.p_double[8];
3616
+ }
3617
+ else
3618
+ {
3619
+ i = 939;
3620
+ j = -526;
3621
+ ns = 763;
3622
+ info = -541;
3623
+ c1 = -698.0;
3624
+ c2 = -900.0;
3625
+ intg = -318.0;
3626
+ intk = -940.0;
3627
+ inta = 1016.0;
3628
+ v = -229.0;
3629
+ ta = -536.0;
3630
+ tb = 487.0;
3631
+ qeps = -115.0;
3632
+ }
3633
+ if( state->rstate.stage==0 )
3634
+ {
3635
+ goto lbl_0;
3636
+ }
3637
+ if( state->rstate.stage==1 )
3638
+ {
3639
+ goto lbl_1;
3640
+ }
3641
+ if( state->rstate.stage==2 )
3642
+ {
3643
+ goto lbl_2;
3644
+ }
3645
+
3646
+ /*
3647
+ * Routine body
3648
+ */
3649
+
3650
+ /*
3651
+ * initialize quadratures.
3652
+ * use 15-point Gauss-Kronrod formula.
3653
+ */
3654
+ state->n = 15;
3655
+ gkqgenerategausslegendre(state->n, &info, &state->qn, &state->wk, &state->wg, _state);
3656
+ if( info<0 )
3657
+ {
3658
+ state->info = -5;
3659
+ state->r = (double)(0);
3660
+ result = ae_false;
3661
+ return result;
3662
+ }
3663
+ ae_vector_set_length(&state->wr, state->n, _state);
3664
+ for(i=0; i<=state->n-1; i++)
3665
+ {
3666
+ if( i==0 )
3667
+ {
3668
+ state->wr.ptr.p_double[i] = 0.5*ae_fabs(state->qn.ptr.p_double[1]-state->qn.ptr.p_double[0], _state);
3669
+ continue;
3670
+ }
3671
+ if( i==state->n-1 )
3672
+ {
3673
+ state->wr.ptr.p_double[state->n-1] = 0.5*ae_fabs(state->qn.ptr.p_double[state->n-1]-state->qn.ptr.p_double[state->n-2], _state);
3674
+ continue;
3675
+ }
3676
+ state->wr.ptr.p_double[i] = 0.5*ae_fabs(state->qn.ptr.p_double[i-1]-state->qn.ptr.p_double[i+1], _state);
3677
+ }
3678
+
3679
+ /*
3680
+ * special case
3681
+ */
3682
+ if( ae_fp_eq(state->a,state->b) )
3683
+ {
3684
+ state->info = 1;
3685
+ state->r = (double)(0);
3686
+ result = ae_false;
3687
+ return result;
3688
+ }
3689
+
3690
+ /*
3691
+ * test parameters
3692
+ */
3693
+ if( ae_fp_less(state->eps,(double)(0))||ae_fp_less(state->xwidth,(double)(0)) )
3694
+ {
3695
+ state->info = -1;
3696
+ state->r = (double)(0);
3697
+ result = ae_false;
3698
+ return result;
3699
+ }
3700
+ state->info = 1;
3701
+ if( ae_fp_eq(state->eps,(double)(0)) )
3702
+ {
3703
+ state->eps = (double)100000*ae_machineepsilon;
3704
+ }
3705
+
3706
+ /*
3707
+ * First, prepare heap
3708
+ * * column 0 - absolute error
3709
+ * * column 1 - integral of a F(x) (calculated using Kronrod extension nodes)
3710
+ * * column 2 - integral of a |F(x)| (calculated using modified rect. method)
3711
+ * * column 3 - left boundary of a subinterval
3712
+ * * column 4 - right boundary of a subinterval
3713
+ */
3714
+ if( ae_fp_neq(state->xwidth,(double)(0)) )
3715
+ {
3716
+ goto lbl_3;
3717
+ }
3718
+
3719
+ /*
3720
+ * no maximum width requirements
3721
+ * start from one big subinterval
3722
+ */
3723
+ state->heapwidth = 5;
3724
+ state->heapsize = 1;
3725
+ state->heapused = 1;
3726
+ ae_matrix_set_length(&state->heap, state->heapsize, state->heapwidth, _state);
3727
+ c1 = 0.5*(state->b-state->a);
3728
+ c2 = 0.5*(state->b+state->a);
3729
+ intg = (double)(0);
3730
+ intk = (double)(0);
3731
+ inta = (double)(0);
3732
+ i = 0;
3733
+ lbl_5:
3734
+ if( i>state->n-1 )
3735
+ {
3736
+ goto lbl_7;
3737
+ }
3738
+
3739
+ /*
3740
+ * obtain F
3741
+ */
3742
+ state->x = c1*state->qn.ptr.p_double[i]+c2;
3743
+ state->rstate.stage = 0;
3744
+ goto lbl_rcomm;
3745
+ lbl_0:
3746
+ v = state->f;
3747
+
3748
+ /*
3749
+ * Gauss-Kronrod formula
3750
+ */
3751
+ intk = intk+v*state->wk.ptr.p_double[i];
3752
+ if( i%2==1 )
3753
+ {
3754
+ intg = intg+v*state->wg.ptr.p_double[i];
3755
+ }
3756
+
3757
+ /*
3758
+ * Integral |F(x)|
3759
+ * Use rectangles method
3760
+ */
3761
+ inta = inta+ae_fabs(v, _state)*state->wr.ptr.p_double[i];
3762
+ i = i+1;
3763
+ goto lbl_5;
3764
+ lbl_7:
3765
+ intk = intk*(state->b-state->a)*0.5;
3766
+ intg = intg*(state->b-state->a)*0.5;
3767
+ inta = inta*(state->b-state->a)*0.5;
3768
+ state->heap.ptr.pp_double[0][0] = ae_fabs(intg-intk, _state);
3769
+ state->heap.ptr.pp_double[0][1] = intk;
3770
+ state->heap.ptr.pp_double[0][2] = inta;
3771
+ state->heap.ptr.pp_double[0][3] = state->a;
3772
+ state->heap.ptr.pp_double[0][4] = state->b;
3773
+ state->sumerr = state->heap.ptr.pp_double[0][0];
3774
+ state->sumabs = ae_fabs(inta, _state);
3775
+ goto lbl_4;
3776
+ lbl_3:
3777
+
3778
+ /*
3779
+ * maximum subinterval should be no more than XWidth.
3780
+ * so we create Ceil((B-A)/XWidth)+1 small subintervals
3781
+ */
3782
+ ns = ae_iceil(ae_fabs(state->b-state->a, _state)/state->xwidth, _state)+1;
3783
+ state->heapsize = ns;
3784
+ state->heapused = ns;
3785
+ state->heapwidth = 5;
3786
+ ae_matrix_set_length(&state->heap, state->heapsize, state->heapwidth, _state);
3787
+ state->sumerr = (double)(0);
3788
+ state->sumabs = (double)(0);
3789
+ j = 0;
3790
+ lbl_8:
3791
+ if( j>ns-1 )
3792
+ {
3793
+ goto lbl_10;
3794
+ }
3795
+ ta = state->a+(double)j*(state->b-state->a)/(double)ns;
3796
+ tb = state->a+(double)(j+1)*(state->b-state->a)/(double)ns;
3797
+ c1 = 0.5*(tb-ta);
3798
+ c2 = 0.5*(tb+ta);
3799
+ intg = (double)(0);
3800
+ intk = (double)(0);
3801
+ inta = (double)(0);
3802
+ i = 0;
3803
+ lbl_11:
3804
+ if( i>state->n-1 )
3805
+ {
3806
+ goto lbl_13;
3807
+ }
3808
+
3809
+ /*
3810
+ * obtain F
3811
+ */
3812
+ state->x = c1*state->qn.ptr.p_double[i]+c2;
3813
+ state->rstate.stage = 1;
3814
+ goto lbl_rcomm;
3815
+ lbl_1:
3816
+ v = state->f;
3817
+
3818
+ /*
3819
+ * Gauss-Kronrod formula
3820
+ */
3821
+ intk = intk+v*state->wk.ptr.p_double[i];
3822
+ if( i%2==1 )
3823
+ {
3824
+ intg = intg+v*state->wg.ptr.p_double[i];
3825
+ }
3826
+
3827
+ /*
3828
+ * Integral |F(x)|
3829
+ * Use rectangles method
3830
+ */
3831
+ inta = inta+ae_fabs(v, _state)*state->wr.ptr.p_double[i];
3832
+ i = i+1;
3833
+ goto lbl_11;
3834
+ lbl_13:
3835
+ intk = intk*(tb-ta)*0.5;
3836
+ intg = intg*(tb-ta)*0.5;
3837
+ inta = inta*(tb-ta)*0.5;
3838
+ state->heap.ptr.pp_double[j][0] = ae_fabs(intg-intk, _state);
3839
+ state->heap.ptr.pp_double[j][1] = intk;
3840
+ state->heap.ptr.pp_double[j][2] = inta;
3841
+ state->heap.ptr.pp_double[j][3] = ta;
3842
+ state->heap.ptr.pp_double[j][4] = tb;
3843
+ state->sumerr = state->sumerr+state->heap.ptr.pp_double[j][0];
3844
+ state->sumabs = state->sumabs+ae_fabs(inta, _state);
3845
+ j = j+1;
3846
+ goto lbl_8;
3847
+ lbl_10:
3848
+ lbl_4:
3849
+
3850
+ /*
3851
+ * method iterations
3852
+ */
3853
+ lbl_14:
3854
+ if( ae_false )
3855
+ {
3856
+ goto lbl_15;
3857
+ }
3858
+
3859
+ /*
3860
+ * additional memory if needed
3861
+ */
3862
+ if( state->heapused==state->heapsize )
3863
+ {
3864
+ autogk_mheapresize(&state->heap, &state->heapsize, 4*state->heapsize, state->heapwidth, _state);
3865
+ }
3866
+
3867
+ /*
3868
+ * TODO: every 20 iterations recalculate errors/sums
3869
+ */
3870
+ if( ae_fp_less_eq(state->sumerr,state->eps*state->sumabs)||state->heapused>=autogk_maxsubintervals )
3871
+ {
3872
+ state->r = (double)(0);
3873
+ for(j=0; j<=state->heapused-1; j++)
3874
+ {
3875
+ state->r = state->r+state->heap.ptr.pp_double[j][1];
3876
+ }
3877
+ result = ae_false;
3878
+ return result;
3879
+ }
3880
+
3881
+ /*
3882
+ * Exclude interval with maximum absolute error
3883
+ */
3884
+ autogk_mheappop(&state->heap, state->heapused, state->heapwidth, _state);
3885
+ state->sumerr = state->sumerr-state->heap.ptr.pp_double[state->heapused-1][0];
3886
+ state->sumabs = state->sumabs-state->heap.ptr.pp_double[state->heapused-1][2];
3887
+
3888
+ /*
3889
+ * Divide interval, create subintervals
3890
+ */
3891
+ ta = state->heap.ptr.pp_double[state->heapused-1][3];
3892
+ tb = state->heap.ptr.pp_double[state->heapused-1][4];
3893
+ state->heap.ptr.pp_double[state->heapused-1][3] = ta;
3894
+ state->heap.ptr.pp_double[state->heapused-1][4] = 0.5*(ta+tb);
3895
+ state->heap.ptr.pp_double[state->heapused][3] = 0.5*(ta+tb);
3896
+ state->heap.ptr.pp_double[state->heapused][4] = tb;
3897
+ j = state->heapused-1;
3898
+ lbl_16:
3899
+ if( j>state->heapused )
3900
+ {
3901
+ goto lbl_18;
3902
+ }
3903
+ c1 = 0.5*(state->heap.ptr.pp_double[j][4]-state->heap.ptr.pp_double[j][3]);
3904
+ c2 = 0.5*(state->heap.ptr.pp_double[j][4]+state->heap.ptr.pp_double[j][3]);
3905
+ intg = (double)(0);
3906
+ intk = (double)(0);
3907
+ inta = (double)(0);
3908
+ i = 0;
3909
+ lbl_19:
3910
+ if( i>state->n-1 )
3911
+ {
3912
+ goto lbl_21;
3913
+ }
3914
+
3915
+ /*
3916
+ * F(x)
3917
+ */
3918
+ state->x = c1*state->qn.ptr.p_double[i]+c2;
3919
+ state->rstate.stage = 2;
3920
+ goto lbl_rcomm;
3921
+ lbl_2:
3922
+ v = state->f;
3923
+
3924
+ /*
3925
+ * Gauss-Kronrod formula
3926
+ */
3927
+ intk = intk+v*state->wk.ptr.p_double[i];
3928
+ if( i%2==1 )
3929
+ {
3930
+ intg = intg+v*state->wg.ptr.p_double[i];
3931
+ }
3932
+
3933
+ /*
3934
+ * Integral |F(x)|
3935
+ * Use rectangles method
3936
+ */
3937
+ inta = inta+ae_fabs(v, _state)*state->wr.ptr.p_double[i];
3938
+ i = i+1;
3939
+ goto lbl_19;
3940
+ lbl_21:
3941
+ intk = intk*(state->heap.ptr.pp_double[j][4]-state->heap.ptr.pp_double[j][3])*0.5;
3942
+ intg = intg*(state->heap.ptr.pp_double[j][4]-state->heap.ptr.pp_double[j][3])*0.5;
3943
+ inta = inta*(state->heap.ptr.pp_double[j][4]-state->heap.ptr.pp_double[j][3])*0.5;
3944
+ state->heap.ptr.pp_double[j][0] = ae_fabs(intg-intk, _state);
3945
+ state->heap.ptr.pp_double[j][1] = intk;
3946
+ state->heap.ptr.pp_double[j][2] = inta;
3947
+ state->sumerr = state->sumerr+state->heap.ptr.pp_double[j][0];
3948
+ state->sumabs = state->sumabs+state->heap.ptr.pp_double[j][2];
3949
+ j = j+1;
3950
+ goto lbl_16;
3951
+ lbl_18:
3952
+ autogk_mheappush(&state->heap, state->heapused-1, state->heapwidth, _state);
3953
+ autogk_mheappush(&state->heap, state->heapused, state->heapwidth, _state);
3954
+ state->heapused = state->heapused+1;
3955
+ goto lbl_14;
3956
+ lbl_15:
3957
+ result = ae_false;
3958
+ return result;
3959
+
3960
+ /*
3961
+ * Saving state
3962
+ */
3963
+ lbl_rcomm:
3964
+ result = ae_true;
3965
+ state->rstate.ia.ptr.p_int[0] = i;
3966
+ state->rstate.ia.ptr.p_int[1] = j;
3967
+ state->rstate.ia.ptr.p_int[2] = ns;
3968
+ state->rstate.ia.ptr.p_int[3] = info;
3969
+ state->rstate.ra.ptr.p_double[0] = c1;
3970
+ state->rstate.ra.ptr.p_double[1] = c2;
3971
+ state->rstate.ra.ptr.p_double[2] = intg;
3972
+ state->rstate.ra.ptr.p_double[3] = intk;
3973
+ state->rstate.ra.ptr.p_double[4] = inta;
3974
+ state->rstate.ra.ptr.p_double[5] = v;
3975
+ state->rstate.ra.ptr.p_double[6] = ta;
3976
+ state->rstate.ra.ptr.p_double[7] = tb;
3977
+ state->rstate.ra.ptr.p_double[8] = qeps;
3978
+ return result;
3979
+ }
3980
+
3981
+
3982
+ static void autogk_mheappop(/* Real */ ae_matrix* heap,
3983
+ ae_int_t heapsize,
3984
+ ae_int_t heapwidth,
3985
+ ae_state *_state)
3986
+ {
3987
+ ae_int_t i;
3988
+ ae_int_t p;
3989
+ double t;
3990
+ ae_int_t maxcp;
3991
+
3992
+
3993
+ if( heapsize==1 )
3994
+ {
3995
+ return;
3996
+ }
3997
+ for(i=0; i<=heapwidth-1; i++)
3998
+ {
3999
+ t = heap->ptr.pp_double[heapsize-1][i];
4000
+ heap->ptr.pp_double[heapsize-1][i] = heap->ptr.pp_double[0][i];
4001
+ heap->ptr.pp_double[0][i] = t;
4002
+ }
4003
+ p = 0;
4004
+ while(2*p+1<heapsize-1)
4005
+ {
4006
+ maxcp = 2*p+1;
4007
+ if( 2*p+2<heapsize-1 )
4008
+ {
4009
+ if( ae_fp_greater(heap->ptr.pp_double[2*p+2][0],heap->ptr.pp_double[2*p+1][0]) )
4010
+ {
4011
+ maxcp = 2*p+2;
4012
+ }
4013
+ }
4014
+ if( ae_fp_less(heap->ptr.pp_double[p][0],heap->ptr.pp_double[maxcp][0]) )
4015
+ {
4016
+ for(i=0; i<=heapwidth-1; i++)
4017
+ {
4018
+ t = heap->ptr.pp_double[p][i];
4019
+ heap->ptr.pp_double[p][i] = heap->ptr.pp_double[maxcp][i];
4020
+ heap->ptr.pp_double[maxcp][i] = t;
4021
+ }
4022
+ p = maxcp;
4023
+ }
4024
+ else
4025
+ {
4026
+ break;
4027
+ }
4028
+ }
4029
+ }
4030
+
4031
+
4032
+ static void autogk_mheappush(/* Real */ ae_matrix* heap,
4033
+ ae_int_t heapsize,
4034
+ ae_int_t heapwidth,
4035
+ ae_state *_state)
4036
+ {
4037
+ ae_int_t i;
4038
+ ae_int_t p;
4039
+ double t;
4040
+ ae_int_t parent;
4041
+
4042
+
4043
+ if( heapsize==0 )
4044
+ {
4045
+ return;
4046
+ }
4047
+ p = heapsize;
4048
+ while(p!=0)
4049
+ {
4050
+ parent = (p-1)/2;
4051
+ if( ae_fp_greater(heap->ptr.pp_double[p][0],heap->ptr.pp_double[parent][0]) )
4052
+ {
4053
+ for(i=0; i<=heapwidth-1; i++)
4054
+ {
4055
+ t = heap->ptr.pp_double[p][i];
4056
+ heap->ptr.pp_double[p][i] = heap->ptr.pp_double[parent][i];
4057
+ heap->ptr.pp_double[parent][i] = t;
4058
+ }
4059
+ p = parent;
4060
+ }
4061
+ else
4062
+ {
4063
+ break;
4064
+ }
4065
+ }
4066
+ }
4067
+
4068
+
4069
+ static void autogk_mheapresize(/* Real */ ae_matrix* heap,
4070
+ ae_int_t* heapsize,
4071
+ ae_int_t newheapsize,
4072
+ ae_int_t heapwidth,
4073
+ ae_state *_state)
4074
+ {
4075
+ ae_frame _frame_block;
4076
+ ae_matrix tmp;
4077
+ ae_int_t i;
4078
+
4079
+ ae_frame_make(_state, &_frame_block);
4080
+ memset(&tmp, 0, sizeof(tmp));
4081
+ ae_matrix_init(&tmp, 0, 0, DT_REAL, _state, ae_true);
4082
+
4083
+ ae_matrix_set_length(&tmp, *heapsize, heapwidth, _state);
4084
+ for(i=0; i<=*heapsize-1; i++)
4085
+ {
4086
+ ae_v_move(&tmp.ptr.pp_double[i][0], 1, &heap->ptr.pp_double[i][0], 1, ae_v_len(0,heapwidth-1));
4087
+ }
4088
+ ae_matrix_set_length(heap, newheapsize, heapwidth, _state);
4089
+ for(i=0; i<=*heapsize-1; i++)
4090
+ {
4091
+ ae_v_move(&heap->ptr.pp_double[i][0], 1, &tmp.ptr.pp_double[i][0], 1, ae_v_len(0,heapwidth-1));
4092
+ }
4093
+ *heapsize = newheapsize;
4094
+ ae_frame_leave(_state);
4095
+ }
4096
+
4097
+
4098
+ void _autogkreport_init(void* _p, ae_state *_state, ae_bool make_automatic)
4099
+ {
4100
+ autogkreport *p = (autogkreport*)_p;
4101
+ ae_touch_ptr((void*)p);
4102
+ }
4103
+
4104
+
4105
+ void _autogkreport_init_copy(void* _dst, const void* _src, ae_state *_state, ae_bool make_automatic)
4106
+ {
4107
+ autogkreport *dst = (autogkreport*)_dst;
4108
+ const autogkreport *src = (const autogkreport*)_src;
4109
+ dst->terminationtype = src->terminationtype;
4110
+ dst->nfev = src->nfev;
4111
+ dst->nintervals = src->nintervals;
4112
+ }
4113
+
4114
+
4115
+ void _autogkreport_clear(void* _p)
4116
+ {
4117
+ autogkreport *p = (autogkreport*)_p;
4118
+ ae_touch_ptr((void*)p);
4119
+ }
4120
+
4121
+
4122
+ void _autogkreport_destroy(void* _p)
4123
+ {
4124
+ autogkreport *p = (autogkreport*)_p;
4125
+ ae_touch_ptr((void*)p);
4126
+ }
4127
+
4128
+
4129
+ void _autogkinternalstate_init(void* _p, ae_state *_state, ae_bool make_automatic)
4130
+ {
4131
+ autogkinternalstate *p = (autogkinternalstate*)_p;
4132
+ ae_touch_ptr((void*)p);
4133
+ ae_matrix_init(&p->heap, 0, 0, DT_REAL, _state, make_automatic);
4134
+ ae_vector_init(&p->qn, 0, DT_REAL, _state, make_automatic);
4135
+ ae_vector_init(&p->wg, 0, DT_REAL, _state, make_automatic);
4136
+ ae_vector_init(&p->wk, 0, DT_REAL, _state, make_automatic);
4137
+ ae_vector_init(&p->wr, 0, DT_REAL, _state, make_automatic);
4138
+ _rcommstate_init(&p->rstate, _state, make_automatic);
4139
+ }
4140
+
4141
+
4142
+ void _autogkinternalstate_init_copy(void* _dst, const void* _src, ae_state *_state, ae_bool make_automatic)
4143
+ {
4144
+ autogkinternalstate *dst = (autogkinternalstate*)_dst;
4145
+ const autogkinternalstate *src = (const autogkinternalstate*)_src;
4146
+ dst->a = src->a;
4147
+ dst->b = src->b;
4148
+ dst->eps = src->eps;
4149
+ dst->xwidth = src->xwidth;
4150
+ dst->x = src->x;
4151
+ dst->f = src->f;
4152
+ dst->info = src->info;
4153
+ dst->r = src->r;
4154
+ ae_matrix_init_copy(&dst->heap, &src->heap, _state, make_automatic);
4155
+ dst->heapsize = src->heapsize;
4156
+ dst->heapwidth = src->heapwidth;
4157
+ dst->heapused = src->heapused;
4158
+ dst->sumerr = src->sumerr;
4159
+ dst->sumabs = src->sumabs;
4160
+ ae_vector_init_copy(&dst->qn, &src->qn, _state, make_automatic);
4161
+ ae_vector_init_copy(&dst->wg, &src->wg, _state, make_automatic);
4162
+ ae_vector_init_copy(&dst->wk, &src->wk, _state, make_automatic);
4163
+ ae_vector_init_copy(&dst->wr, &src->wr, _state, make_automatic);
4164
+ dst->n = src->n;
4165
+ _rcommstate_init_copy(&dst->rstate, &src->rstate, _state, make_automatic);
4166
+ }
4167
+
4168
+
4169
+ void _autogkinternalstate_clear(void* _p)
4170
+ {
4171
+ autogkinternalstate *p = (autogkinternalstate*)_p;
4172
+ ae_touch_ptr((void*)p);
4173
+ ae_matrix_clear(&p->heap);
4174
+ ae_vector_clear(&p->qn);
4175
+ ae_vector_clear(&p->wg);
4176
+ ae_vector_clear(&p->wk);
4177
+ ae_vector_clear(&p->wr);
4178
+ _rcommstate_clear(&p->rstate);
4179
+ }
4180
+
4181
+
4182
+ void _autogkinternalstate_destroy(void* _p)
4183
+ {
4184
+ autogkinternalstate *p = (autogkinternalstate*)_p;
4185
+ ae_touch_ptr((void*)p);
4186
+ ae_matrix_destroy(&p->heap);
4187
+ ae_vector_destroy(&p->qn);
4188
+ ae_vector_destroy(&p->wg);
4189
+ ae_vector_destroy(&p->wk);
4190
+ ae_vector_destroy(&p->wr);
4191
+ _rcommstate_destroy(&p->rstate);
4192
+ }
4193
+
4194
+
4195
+ void _autogkstate_init(void* _p, ae_state *_state, ae_bool make_automatic)
4196
+ {
4197
+ autogkstate *p = (autogkstate*)_p;
4198
+ ae_touch_ptr((void*)p);
4199
+ _autogkinternalstate_init(&p->internalstate, _state, make_automatic);
4200
+ _rcommstate_init(&p->rstate, _state, make_automatic);
4201
+ }
4202
+
4203
+
4204
+ void _autogkstate_init_copy(void* _dst, const void* _src, ae_state *_state, ae_bool make_automatic)
4205
+ {
4206
+ autogkstate *dst = (autogkstate*)_dst;
4207
+ const autogkstate *src = (const autogkstate*)_src;
4208
+ dst->a = src->a;
4209
+ dst->b = src->b;
4210
+ dst->alpha = src->alpha;
4211
+ dst->beta = src->beta;
4212
+ dst->xwidth = src->xwidth;
4213
+ dst->x = src->x;
4214
+ dst->xminusa = src->xminusa;
4215
+ dst->bminusx = src->bminusx;
4216
+ dst->needf = src->needf;
4217
+ dst->f = src->f;
4218
+ dst->wrappermode = src->wrappermode;
4219
+ _autogkinternalstate_init_copy(&dst->internalstate, &src->internalstate, _state, make_automatic);
4220
+ _rcommstate_init_copy(&dst->rstate, &src->rstate, _state, make_automatic);
4221
+ dst->v = src->v;
4222
+ dst->terminationtype = src->terminationtype;
4223
+ dst->nfev = src->nfev;
4224
+ dst->nintervals = src->nintervals;
4225
+ }
4226
+
4227
+
4228
+ void _autogkstate_clear(void* _p)
4229
+ {
4230
+ autogkstate *p = (autogkstate*)_p;
4231
+ ae_touch_ptr((void*)p);
4232
+ _autogkinternalstate_clear(&p->internalstate);
4233
+ _rcommstate_clear(&p->rstate);
4234
+ }
4235
+
4236
+
4237
+ void _autogkstate_destroy(void* _p)
4238
+ {
4239
+ autogkstate *p = (autogkstate*)_p;
4240
+ ae_touch_ptr((void*)p);
4241
+ _autogkinternalstate_destroy(&p->internalstate);
4242
+ _rcommstate_destroy(&p->rstate);
4243
+ }
4244
+
4245
+
4246
+ #endif
4247
+
4248
+ }
4249
+