alglib4 0.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +47 -0
  3. data/ext/alglib/alglib.cpp +537 -0
  4. data/ext/alglib/alglib_array_converters.cpp +86 -0
  5. data/ext/alglib/alglib_array_converters.h +15 -0
  6. data/ext/alglib/alglib_utils.cpp +10 -0
  7. data/ext/alglib/alglib_utils.h +6 -0
  8. data/ext/alglib/alglibinternal.cpp +21749 -0
  9. data/ext/alglib/alglibinternal.h +2168 -0
  10. data/ext/alglib/alglibmisc.cpp +9106 -0
  11. data/ext/alglib/alglibmisc.h +2114 -0
  12. data/ext/alglib/ap.cpp +20094 -0
  13. data/ext/alglib/ap.h +7244 -0
  14. data/ext/alglib/dataanalysis.cpp +52588 -0
  15. data/ext/alglib/dataanalysis.h +10601 -0
  16. data/ext/alglib/diffequations.cpp +1342 -0
  17. data/ext/alglib/diffequations.h +282 -0
  18. data/ext/alglib/extconf.rb +5 -0
  19. data/ext/alglib/fasttransforms.cpp +4696 -0
  20. data/ext/alglib/fasttransforms.h +1018 -0
  21. data/ext/alglib/integration.cpp +4249 -0
  22. data/ext/alglib/integration.h +869 -0
  23. data/ext/alglib/interpolation.cpp +74502 -0
  24. data/ext/alglib/interpolation.h +12264 -0
  25. data/ext/alglib/kernels_avx2.cpp +2171 -0
  26. data/ext/alglib/kernels_avx2.h +201 -0
  27. data/ext/alglib/kernels_fma.cpp +1065 -0
  28. data/ext/alglib/kernels_fma.h +137 -0
  29. data/ext/alglib/kernels_sse2.cpp +735 -0
  30. data/ext/alglib/kernels_sse2.h +100 -0
  31. data/ext/alglib/linalg.cpp +65182 -0
  32. data/ext/alglib/linalg.h +9927 -0
  33. data/ext/alglib/optimization.cpp +135331 -0
  34. data/ext/alglib/optimization.h +19235 -0
  35. data/ext/alglib/solvers.cpp +20488 -0
  36. data/ext/alglib/solvers.h +4781 -0
  37. data/ext/alglib/specialfunctions.cpp +10672 -0
  38. data/ext/alglib/specialfunctions.h +2305 -0
  39. data/ext/alglib/statistics.cpp +19791 -0
  40. data/ext/alglib/statistics.h +1359 -0
  41. data/ext/alglib/stdafx.h +2 -0
  42. data/gpl2.txt +339 -0
  43. data/gpl3.txt +674 -0
  44. data/lib/alglib/version.rb +3 -0
  45. data/lib/alglib.rb +4 -0
  46. metadata +101 -0
@@ -0,0 +1,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
+