LCOV - code coverage report
Current view: top level - synthesis/MeasurementEquations/lbfgs - integration.cc (source / functions) Hit Total Coverage
Test: casacpp_coverage.info Lines: 0 1729 0.0 %
Date: 2024-12-11 20:54:31 Functions: 0 76 0.0 %

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

Generated by: LCOV version 1.16