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

Generated by: LCOV version 1.16