LCOV - code coverage report
Current view: top level - synthesis/MeasurementEquations/lbfgs - solvers.cc (source / functions) Hit Total Coverage
Test: casacpp_coverage.info Lines: 0 4130 0.0 %
Date: 2024-10-09 13:55:54 Functions: 0 329 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 "solvers.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_DIRECTDENSESOLVERS) || !defined(AE_PARTIAL_BUILD)
      44             : 
      45             : #endif
      46             : 
      47             : #if defined(AE_COMPILE_LINLSQR) || !defined(AE_PARTIAL_BUILD)
      48             : 
      49             : #endif
      50             : 
      51             : #if defined(AE_COMPILE_POLYNOMIALSOLVER) || !defined(AE_PARTIAL_BUILD)
      52             : 
      53             : #endif
      54             : 
      55             : #if defined(AE_COMPILE_NLEQ) || !defined(AE_PARTIAL_BUILD)
      56             : 
      57             : #endif
      58             : 
      59             : #if defined(AE_COMPILE_DIRECTSPARSESOLVERS) || !defined(AE_PARTIAL_BUILD)
      60             : 
      61             : #endif
      62             : 
      63             : #if defined(AE_COMPILE_LINCG) || !defined(AE_PARTIAL_BUILD)
      64             : 
      65             : #endif
      66             : 
      67             : #if defined(AE_COMPILE_DIRECTDENSESOLVERS) || !defined(AE_PARTIAL_BUILD)
      68             : /*************************************************************************
      69             : 
      70             : *************************************************************************/
      71           0 : _densesolverreport_owner::_densesolverreport_owner()
      72             : {
      73             :     jmp_buf _break_jump;
      74             :     alglib_impl::ae_state _state;
      75             :     
      76           0 :     alglib_impl::ae_state_init(&_state);
      77           0 :     if( setjmp(_break_jump) )
      78             :     {
      79           0 :         if( p_struct!=NULL )
      80             :         {
      81           0 :             alglib_impl::_densesolverreport_destroy(p_struct);
      82           0 :             alglib_impl::ae_free(p_struct);
      83             :         }
      84           0 :         p_struct = NULL;
      85             : #if !defined(AE_NO_EXCEPTIONS)
      86           0 :         _ALGLIB_CPP_EXCEPTION(_state.error_msg);
      87             : #else
      88             :         _ALGLIB_SET_ERROR_FLAG(_state.error_msg);
      89             :         return;
      90             : #endif
      91             :     }
      92           0 :     alglib_impl::ae_state_set_break_jump(&_state, &_break_jump);
      93           0 :     p_struct = NULL;
      94           0 :     p_struct = (alglib_impl::densesolverreport*)alglib_impl::ae_malloc(sizeof(alglib_impl::densesolverreport), &_state);
      95           0 :     memset(p_struct, 0, sizeof(alglib_impl::densesolverreport));
      96           0 :     alglib_impl::_densesolverreport_init(p_struct, &_state, ae_false);
      97           0 :     ae_state_clear(&_state);
      98           0 : }
      99             : 
     100           0 : _densesolverreport_owner::_densesolverreport_owner(const _densesolverreport_owner &rhs)
     101             : {
     102             :     jmp_buf _break_jump;
     103             :     alglib_impl::ae_state _state;
     104             :     
     105           0 :     alglib_impl::ae_state_init(&_state);
     106           0 :     if( setjmp(_break_jump) )
     107             :     {
     108           0 :         if( p_struct!=NULL )
     109             :         {
     110           0 :             alglib_impl::_densesolverreport_destroy(p_struct);
     111           0 :             alglib_impl::ae_free(p_struct);
     112             :         }
     113           0 :         p_struct = NULL;
     114             : #if !defined(AE_NO_EXCEPTIONS)
     115           0 :         _ALGLIB_CPP_EXCEPTION(_state.error_msg);
     116             : #else
     117             :         _ALGLIB_SET_ERROR_FLAG(_state.error_msg);
     118             :         return;
     119             : #endif
     120             :     }
     121           0 :     alglib_impl::ae_state_set_break_jump(&_state, &_break_jump);
     122           0 :     p_struct = NULL;
     123           0 :     alglib_impl::ae_assert(rhs.p_struct!=NULL, "ALGLIB: densesolverreport copy constructor failure (source is not initialized)", &_state);
     124           0 :     p_struct = (alglib_impl::densesolverreport*)alglib_impl::ae_malloc(sizeof(alglib_impl::densesolverreport), &_state);
     125           0 :     memset(p_struct, 0, sizeof(alglib_impl::densesolverreport));
     126           0 :     alglib_impl::_densesolverreport_init_copy(p_struct, const_cast<alglib_impl::densesolverreport*>(rhs.p_struct), &_state, ae_false);
     127           0 :     ae_state_clear(&_state);
     128           0 : }
     129             : 
     130           0 : _densesolverreport_owner& _densesolverreport_owner::operator=(const _densesolverreport_owner &rhs)
     131             : {
     132           0 :     if( this==&rhs )
     133           0 :         return *this;
     134             :     jmp_buf _break_jump;
     135             :     alglib_impl::ae_state _state;
     136             :     
     137           0 :     alglib_impl::ae_state_init(&_state);
     138           0 :     if( setjmp(_break_jump) )
     139             :     {
     140             : #if !defined(AE_NO_EXCEPTIONS)
     141           0 :         _ALGLIB_CPP_EXCEPTION(_state.error_msg);
     142             : #else
     143             :         _ALGLIB_SET_ERROR_FLAG(_state.error_msg);
     144             :         return *this;
     145             : #endif
     146             :     }
     147           0 :     alglib_impl::ae_state_set_break_jump(&_state, &_break_jump);
     148           0 :     alglib_impl::ae_assert(p_struct!=NULL, "ALGLIB: densesolverreport assignment constructor failure (destination is not initialized)", &_state);
     149           0 :     alglib_impl::ae_assert(rhs.p_struct!=NULL, "ALGLIB: densesolverreport assignment constructor failure (source is not initialized)", &_state);
     150           0 :     alglib_impl::_densesolverreport_destroy(p_struct);
     151           0 :     memset(p_struct, 0, sizeof(alglib_impl::densesolverreport));
     152           0 :     alglib_impl::_densesolverreport_init_copy(p_struct, const_cast<alglib_impl::densesolverreport*>(rhs.p_struct), &_state, ae_false);
     153           0 :     ae_state_clear(&_state);
     154           0 :     return *this;
     155             : }
     156             : 
     157           0 : _densesolverreport_owner::~_densesolverreport_owner()
     158             : {
     159           0 :     if( p_struct!=NULL )
     160             :     {
     161           0 :         alglib_impl::_densesolverreport_destroy(p_struct);
     162           0 :         ae_free(p_struct);
     163             :     }
     164           0 : }
     165             : 
     166           0 : alglib_impl::densesolverreport* _densesolverreport_owner::c_ptr()
     167             : {
     168           0 :     return p_struct;
     169             : }
     170             : 
     171           0 : alglib_impl::densesolverreport* _densesolverreport_owner::c_ptr() const
     172             : {
     173           0 :     return const_cast<alglib_impl::densesolverreport*>(p_struct);
     174             : }
     175           0 : densesolverreport::densesolverreport() : _densesolverreport_owner() ,r1(p_struct->r1),rinf(p_struct->rinf)
     176             : {
     177           0 : }
     178             : 
     179           0 : densesolverreport::densesolverreport(const densesolverreport &rhs):_densesolverreport_owner(rhs) ,r1(p_struct->r1),rinf(p_struct->rinf)
     180             : {
     181           0 : }
     182             : 
     183           0 : densesolverreport& densesolverreport::operator=(const densesolverreport &rhs)
     184             : {
     185           0 :     if( this==&rhs )
     186           0 :         return *this;
     187           0 :     _densesolverreport_owner::operator=(rhs);
     188           0 :     return *this;
     189             : }
     190             : 
     191           0 : densesolverreport::~densesolverreport()
     192             : {
     193           0 : }
     194             : 
     195             : 
     196             : /*************************************************************************
     197             : 
     198             : *************************************************************************/
     199           0 : _densesolverlsreport_owner::_densesolverlsreport_owner()
     200             : {
     201             :     jmp_buf _break_jump;
     202             :     alglib_impl::ae_state _state;
     203             :     
     204           0 :     alglib_impl::ae_state_init(&_state);
     205           0 :     if( setjmp(_break_jump) )
     206             :     {
     207           0 :         if( p_struct!=NULL )
     208             :         {
     209           0 :             alglib_impl::_densesolverlsreport_destroy(p_struct);
     210           0 :             alglib_impl::ae_free(p_struct);
     211             :         }
     212           0 :         p_struct = NULL;
     213             : #if !defined(AE_NO_EXCEPTIONS)
     214           0 :         _ALGLIB_CPP_EXCEPTION(_state.error_msg);
     215             : #else
     216             :         _ALGLIB_SET_ERROR_FLAG(_state.error_msg);
     217             :         return;
     218             : #endif
     219             :     }
     220           0 :     alglib_impl::ae_state_set_break_jump(&_state, &_break_jump);
     221           0 :     p_struct = NULL;
     222           0 :     p_struct = (alglib_impl::densesolverlsreport*)alglib_impl::ae_malloc(sizeof(alglib_impl::densesolverlsreport), &_state);
     223           0 :     memset(p_struct, 0, sizeof(alglib_impl::densesolverlsreport));
     224           0 :     alglib_impl::_densesolverlsreport_init(p_struct, &_state, ae_false);
     225           0 :     ae_state_clear(&_state);
     226           0 : }
     227             : 
     228           0 : _densesolverlsreport_owner::_densesolverlsreport_owner(const _densesolverlsreport_owner &rhs)
     229             : {
     230             :     jmp_buf _break_jump;
     231             :     alglib_impl::ae_state _state;
     232             :     
     233           0 :     alglib_impl::ae_state_init(&_state);
     234           0 :     if( setjmp(_break_jump) )
     235             :     {
     236           0 :         if( p_struct!=NULL )
     237             :         {
     238           0 :             alglib_impl::_densesolverlsreport_destroy(p_struct);
     239           0 :             alglib_impl::ae_free(p_struct);
     240             :         }
     241           0 :         p_struct = NULL;
     242             : #if !defined(AE_NO_EXCEPTIONS)
     243           0 :         _ALGLIB_CPP_EXCEPTION(_state.error_msg);
     244             : #else
     245             :         _ALGLIB_SET_ERROR_FLAG(_state.error_msg);
     246             :         return;
     247             : #endif
     248             :     }
     249           0 :     alglib_impl::ae_state_set_break_jump(&_state, &_break_jump);
     250           0 :     p_struct = NULL;
     251           0 :     alglib_impl::ae_assert(rhs.p_struct!=NULL, "ALGLIB: densesolverlsreport copy constructor failure (source is not initialized)", &_state);
     252           0 :     p_struct = (alglib_impl::densesolverlsreport*)alglib_impl::ae_malloc(sizeof(alglib_impl::densesolverlsreport), &_state);
     253           0 :     memset(p_struct, 0, sizeof(alglib_impl::densesolverlsreport));
     254           0 :     alglib_impl::_densesolverlsreport_init_copy(p_struct, const_cast<alglib_impl::densesolverlsreport*>(rhs.p_struct), &_state, ae_false);
     255           0 :     ae_state_clear(&_state);
     256           0 : }
     257             : 
     258           0 : _densesolverlsreport_owner& _densesolverlsreport_owner::operator=(const _densesolverlsreport_owner &rhs)
     259             : {
     260           0 :     if( this==&rhs )
     261           0 :         return *this;
     262             :     jmp_buf _break_jump;
     263             :     alglib_impl::ae_state _state;
     264             :     
     265           0 :     alglib_impl::ae_state_init(&_state);
     266           0 :     if( setjmp(_break_jump) )
     267             :     {
     268             : #if !defined(AE_NO_EXCEPTIONS)
     269           0 :         _ALGLIB_CPP_EXCEPTION(_state.error_msg);
     270             : #else
     271             :         _ALGLIB_SET_ERROR_FLAG(_state.error_msg);
     272             :         return *this;
     273             : #endif
     274             :     }
     275           0 :     alglib_impl::ae_state_set_break_jump(&_state, &_break_jump);
     276           0 :     alglib_impl::ae_assert(p_struct!=NULL, "ALGLIB: densesolverlsreport assignment constructor failure (destination is not initialized)", &_state);
     277           0 :     alglib_impl::ae_assert(rhs.p_struct!=NULL, "ALGLIB: densesolverlsreport assignment constructor failure (source is not initialized)", &_state);
     278           0 :     alglib_impl::_densesolverlsreport_destroy(p_struct);
     279           0 :     memset(p_struct, 0, sizeof(alglib_impl::densesolverlsreport));
     280           0 :     alglib_impl::_densesolverlsreport_init_copy(p_struct, const_cast<alglib_impl::densesolverlsreport*>(rhs.p_struct), &_state, ae_false);
     281           0 :     ae_state_clear(&_state);
     282           0 :     return *this;
     283             : }
     284             : 
     285           0 : _densesolverlsreport_owner::~_densesolverlsreport_owner()
     286             : {
     287           0 :     if( p_struct!=NULL )
     288             :     {
     289           0 :         alglib_impl::_densesolverlsreport_destroy(p_struct);
     290           0 :         ae_free(p_struct);
     291             :     }
     292           0 : }
     293             : 
     294           0 : alglib_impl::densesolverlsreport* _densesolverlsreport_owner::c_ptr()
     295             : {
     296           0 :     return p_struct;
     297             : }
     298             : 
     299           0 : alglib_impl::densesolverlsreport* _densesolverlsreport_owner::c_ptr() const
     300             : {
     301           0 :     return const_cast<alglib_impl::densesolverlsreport*>(p_struct);
     302             : }
     303           0 : densesolverlsreport::densesolverlsreport() : _densesolverlsreport_owner() ,r2(p_struct->r2),cx(&p_struct->cx),n(p_struct->n),k(p_struct->k)
     304             : {
     305           0 : }
     306             : 
     307           0 : densesolverlsreport::densesolverlsreport(const densesolverlsreport &rhs):_densesolverlsreport_owner(rhs) ,r2(p_struct->r2),cx(&p_struct->cx),n(p_struct->n),k(p_struct->k)
     308             : {
     309           0 : }
     310             : 
     311           0 : densesolverlsreport& densesolverlsreport::operator=(const densesolverlsreport &rhs)
     312             : {
     313           0 :     if( this==&rhs )
     314           0 :         return *this;
     315           0 :     _densesolverlsreport_owner::operator=(rhs);
     316           0 :     return *this;
     317             : }
     318             : 
     319           0 : densesolverlsreport::~densesolverlsreport()
     320             : {
     321           0 : }
     322             : 
     323             : /*************************************************************************
     324             : Dense solver for A*x=b with N*N real matrix A and N*1 real vectorx  x  and
     325             : b. This is "slow-but-feature rich" version of the  linear  solver.  Faster
     326             : version is RMatrixSolveFast() function.
     327             : 
     328             : Algorithm features:
     329             : * automatic detection of degenerate cases
     330             : * condition number estimation
     331             : * iterative refinement
     332             : * O(N^3) complexity
     333             : 
     334             : IMPORTANT: ! this function is NOT the most efficient linear solver provided
     335             :            ! by ALGLIB. It estimates condition  number  of  linear  system
     336             :            ! and  performs  iterative   refinement,   which   results   in
     337             :            ! significant performance penalty  when  compared  with  "fast"
     338             :            ! version  which  just  performs  LU  decomposition  and  calls
     339             :            ! triangular solver.
     340             :            !
     341             :            ! This  performance  penalty  is  especially  visible  in   the
     342             :            ! multithreaded mode, because both condition number  estimation
     343             :            ! and   iterative    refinement   are   inherently   sequential
     344             :            ! calculations. It is also very significant on small matrices.
     345             :            !
     346             :            ! Thus, if you need high performance and if you are pretty sure
     347             :            ! that your system is well conditioned, we  strongly  recommend
     348             :            ! you to use faster solver, RMatrixSolveFast() function.
     349             : 
     350             :   ! COMMERCIAL EDITION OF ALGLIB:
     351             :   !
     352             :   ! Commercial Edition of ALGLIB includes following important improvements
     353             :   ! of this function:
     354             :   ! * high-performance native backend with same C# interface (C# version)
     355             :   ! * multithreading support (C++ and C# versions)
     356             :   ! * hardware vendor (Intel) implementations of linear algebra primitives
     357             :   !   (C++ and C# versions, x86/x64 platform)
     358             :   !
     359             :   ! We recommend you to read 'Working with commercial version' section  of
     360             :   ! ALGLIB Reference Manual in order to find out how to  use  performance-
     361             :   ! related features provided by commercial edition of ALGLIB.
     362             : 
     363             : INPUT PARAMETERS
     364             :     A       -   array[0..N-1,0..N-1], system matrix
     365             :     N       -   size of A
     366             :     B       -   array[0..N-1], right part
     367             : 
     368             : OUTPUT PARAMETERS
     369             :     Info    -   return code:
     370             :                 * -3    matrix is very badly conditioned or exactly singular.
     371             :                 * -1    N<=0 was passed
     372             :                 *  1    task is solved (but matrix A may be ill-conditioned,
     373             :                         check R1/RInf parameters for condition numbers).
     374             :     Rep     -   additional report, following fields are set:
     375             :                 * rep.r1    condition number in 1-norm
     376             :                 * rep.rinf  condition number in inf-norm
     377             :     X       -   array[N], it contains:
     378             :                 * info>0    =>  solution
     379             :                 * info=-3   =>  filled by zeros
     380             : 
     381             :   -- ALGLIB --
     382             :      Copyright 27.01.2010 by Bochkanov Sergey
     383             : *************************************************************************/
     384           0 : void rmatrixsolve(const real_2d_array &a, const ae_int_t n, const real_1d_array &b, ae_int_t &info, densesolverreport &rep, real_1d_array &x, const xparams _xparams)
     385             : {
     386             :     jmp_buf _break_jump;
     387             :     alglib_impl::ae_state _alglib_env_state;
     388           0 :     alglib_impl::ae_state_init(&_alglib_env_state);
     389           0 :     if( setjmp(_break_jump) )
     390             :     {
     391             : #if !defined(AE_NO_EXCEPTIONS)
     392           0 :         _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
     393             : #else
     394             :         _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
     395             :         return;
     396             : #endif
     397             :     }
     398           0 :     ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
     399           0 :     if( _xparams.flags!=0x0 )
     400           0 :         ae_state_set_flags(&_alglib_env_state, _xparams.flags);
     401           0 :     alglib_impl::rmatrixsolve(const_cast<alglib_impl::ae_matrix*>(a.c_ptr()), n, const_cast<alglib_impl::ae_vector*>(b.c_ptr()), &info, const_cast<alglib_impl::densesolverreport*>(rep.c_ptr()), const_cast<alglib_impl::ae_vector*>(x.c_ptr()), &_alglib_env_state);
     402           0 :     alglib_impl::ae_state_clear(&_alglib_env_state);
     403           0 :     return;
     404             : }
     405             : 
     406             : /*************************************************************************
     407             : Dense solver.
     408             : 
     409             : This  subroutine  solves  a  system  A*x=b,  where A is NxN non-denegerate
     410             : real matrix, x  and  b  are  vectors.  This is a "fast" version of  linear
     411             : solver which does NOT provide  any  additional  functions  like  condition
     412             : number estimation or iterative refinement.
     413             : 
     414             : Algorithm features:
     415             : * efficient algorithm O(N^3) complexity
     416             : * no performance overhead from additional functionality
     417             : 
     418             : If you need condition number estimation or iterative refinement, use  more
     419             : feature-rich version - RMatrixSolve().
     420             : 
     421             :   ! COMMERCIAL EDITION OF ALGLIB:
     422             :   !
     423             :   ! Commercial Edition of ALGLIB includes following important improvements
     424             :   ! of this function:
     425             :   ! * high-performance native backend with same C# interface (C# version)
     426             :   ! * multithreading support (C++ and C# versions)
     427             :   ! * hardware vendor (Intel) implementations of linear algebra primitives
     428             :   !   (C++ and C# versions, x86/x64 platform)
     429             :   !
     430             :   ! We recommend you to read 'Working with commercial version' section  of
     431             :   ! ALGLIB Reference Manual in order to find out how to  use  performance-
     432             :   ! related features provided by commercial edition of ALGLIB.
     433             : 
     434             : INPUT PARAMETERS
     435             :     A       -   array[0..N-1,0..N-1], system matrix
     436             :     N       -   size of A
     437             :     B       -   array[0..N-1], right part
     438             : 
     439             : OUTPUT PARAMETERS
     440             :     Info    -   return code:
     441             :                 * -3    matrix is exactly singular (ill conditioned matrices
     442             :                         are not recognized).
     443             :                 * -1    N<=0 was passed
     444             :                 *  1    task is solved
     445             :     B       -   array[N]:
     446             :                 * info>0    =>  overwritten by solution
     447             :                 * info=-3   =>  filled by zeros
     448             : 
     449             :   -- ALGLIB --
     450             :      Copyright 16.03.2015 by Bochkanov Sergey
     451             : *************************************************************************/
     452           0 : void rmatrixsolvefast(const real_2d_array &a, const ae_int_t n, const real_1d_array &b, ae_int_t &info, const xparams _xparams)
     453             : {
     454             :     jmp_buf _break_jump;
     455             :     alglib_impl::ae_state _alglib_env_state;
     456           0 :     alglib_impl::ae_state_init(&_alglib_env_state);
     457           0 :     if( setjmp(_break_jump) )
     458             :     {
     459             : #if !defined(AE_NO_EXCEPTIONS)
     460           0 :         _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
     461             : #else
     462             :         _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
     463             :         return;
     464             : #endif
     465             :     }
     466           0 :     ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
     467           0 :     if( _xparams.flags!=0x0 )
     468           0 :         ae_state_set_flags(&_alglib_env_state, _xparams.flags);
     469           0 :     alglib_impl::rmatrixsolvefast(const_cast<alglib_impl::ae_matrix*>(a.c_ptr()), n, const_cast<alglib_impl::ae_vector*>(b.c_ptr()), &info, &_alglib_env_state);
     470           0 :     alglib_impl::ae_state_clear(&_alglib_env_state);
     471           0 :     return;
     472             : }
     473             : 
     474             : /*************************************************************************
     475             : Dense solver.
     476             : 
     477             : Similar to RMatrixSolve() but solves task with multiple right parts (where
     478             : b and x are NxM matrices). This is  "slow-but-robust"  version  of  linear
     479             : solver with additional functionality  like  condition  number  estimation.
     480             : There also exists faster version - RMatrixSolveMFast().
     481             : 
     482             : Algorithm features:
     483             : * automatic detection of degenerate cases
     484             : * condition number estimation
     485             : * optional iterative refinement
     486             : * O(N^3+M*N^2) complexity
     487             : 
     488             : IMPORTANT: ! this function is NOT the most efficient linear solver provided
     489             :            ! by ALGLIB. It estimates condition  number  of  linear  system
     490             :            ! and  performs  iterative   refinement,   which   results   in
     491             :            ! significant performance penalty  when  compared  with  "fast"
     492             :            ! version  which  just  performs  LU  decomposition  and  calls
     493             :            ! triangular solver.
     494             :            !
     495             :            ! This  performance  penalty  is  especially  visible  in   the
     496             :            ! multithreaded mode, because both condition number  estimation
     497             :            ! and   iterative    refinement   are   inherently   sequential
     498             :            ! calculations. It also very significant on small matrices.
     499             :            !
     500             :            ! Thus, if you need high performance and if you are pretty sure
     501             :            ! that your system is well conditioned, we  strongly  recommend
     502             :            ! you to use faster solver, RMatrixSolveMFast() function.
     503             : 
     504             :   ! COMMERCIAL EDITION OF ALGLIB:
     505             :   !
     506             :   ! Commercial Edition of ALGLIB includes following important improvements
     507             :   ! of this function:
     508             :   ! * high-performance native backend with same C# interface (C# version)
     509             :   ! * multithreading support (C++ and C# versions)
     510             :   ! * hardware vendor (Intel) implementations of linear algebra primitives
     511             :   !   (C++ and C# versions, x86/x64 platform)
     512             :   !
     513             :   ! We recommend you to read 'Working with commercial version' section  of
     514             :   ! ALGLIB Reference Manual in order to find out how to  use  performance-
     515             :   ! related features provided by commercial edition of ALGLIB.
     516             : 
     517             : INPUT PARAMETERS
     518             :     A       -   array[0..N-1,0..N-1], system matrix
     519             :     N       -   size of A
     520             :     B       -   array[0..N-1,0..M-1], right part
     521             :     M       -   right part size
     522             :     RFS     -   iterative refinement switch:
     523             :                 * True - refinement is used.
     524             :                   Less performance, more precision.
     525             :                 * False - refinement is not used.
     526             :                   More performance, less precision.
     527             : 
     528             : OUTPUT PARAMETERS
     529             :     Info    -   return code:
     530             :                 * -3    A is ill conditioned or singular.
     531             :                         X is filled by zeros in such cases.
     532             :                 * -1    N<=0 was passed
     533             :                 *  1    task is solved (but matrix A may be ill-conditioned,
     534             :                         check R1/RInf parameters for condition numbers).
     535             :     Rep     -   additional report, following fields are set:
     536             :                 * rep.r1    condition number in 1-norm
     537             :                 * rep.rinf  condition number in inf-norm
     538             :     X       -   array[N], it contains:
     539             :                 * info>0    =>  solution
     540             :                 * info=-3   =>  filled by zeros
     541             : 
     542             : 
     543             :   -- ALGLIB --
     544             :      Copyright 27.01.2010 by Bochkanov Sergey
     545             : *************************************************************************/
     546           0 : void rmatrixsolvem(const real_2d_array &a, const ae_int_t n, const real_2d_array &b, const ae_int_t m, const bool rfs, ae_int_t &info, densesolverreport &rep, real_2d_array &x, const xparams _xparams)
     547             : {
     548             :     jmp_buf _break_jump;
     549             :     alglib_impl::ae_state _alglib_env_state;
     550           0 :     alglib_impl::ae_state_init(&_alglib_env_state);
     551           0 :     if( setjmp(_break_jump) )
     552             :     {
     553             : #if !defined(AE_NO_EXCEPTIONS)
     554           0 :         _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
     555             : #else
     556             :         _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
     557             :         return;
     558             : #endif
     559             :     }
     560           0 :     ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
     561           0 :     if( _xparams.flags!=0x0 )
     562           0 :         ae_state_set_flags(&_alglib_env_state, _xparams.flags);
     563           0 :     alglib_impl::rmatrixsolvem(const_cast<alglib_impl::ae_matrix*>(a.c_ptr()), n, const_cast<alglib_impl::ae_matrix*>(b.c_ptr()), m, rfs, &info, const_cast<alglib_impl::densesolverreport*>(rep.c_ptr()), const_cast<alglib_impl::ae_matrix*>(x.c_ptr()), &_alglib_env_state);
     564           0 :     alglib_impl::ae_state_clear(&_alglib_env_state);
     565           0 :     return;
     566             : }
     567             : 
     568             : /*************************************************************************
     569             : Dense solver.
     570             : 
     571             : Similar to RMatrixSolve() but solves task with multiple right parts (where
     572             : b and x are NxM matrices). This is "fast" version of linear  solver  which
     573             : does NOT offer additional functions like condition  number  estimation  or
     574             : iterative refinement.
     575             : 
     576             : Algorithm features:
     577             : * O(N^3+M*N^2) complexity
     578             : * no additional functionality, highest performance
     579             : 
     580             :   ! COMMERCIAL EDITION OF ALGLIB:
     581             :   !
     582             :   ! Commercial Edition of ALGLIB includes following important improvements
     583             :   ! of this function:
     584             :   ! * high-performance native backend with same C# interface (C# version)
     585             :   ! * multithreading support (C++ and C# versions)
     586             :   ! * hardware vendor (Intel) implementations of linear algebra primitives
     587             :   !   (C++ and C# versions, x86/x64 platform)
     588             :   !
     589             :   ! We recommend you to read 'Working with commercial version' section  of
     590             :   ! ALGLIB Reference Manual in order to find out how to  use  performance-
     591             :   ! related features provided by commercial edition of ALGLIB.
     592             : 
     593             : INPUT PARAMETERS
     594             :     A       -   array[0..N-1,0..N-1], system matrix
     595             :     N       -   size of A
     596             :     B       -   array[0..N-1,0..M-1], right part
     597             :     M       -   right part size
     598             :     RFS     -   iterative refinement switch:
     599             :                 * True - refinement is used.
     600             :                   Less performance, more precision.
     601             :                 * False - refinement is not used.
     602             :                   More performance, less precision.
     603             : 
     604             : OUTPUT PARAMETERS
     605             :     Info    -   return code:
     606             :                 * -3    matrix is exactly singular (ill conditioned matrices
     607             :                         are not recognized).
     608             :                         X is filled by zeros in such cases.
     609             :                 * -1    N<=0 was passed
     610             :                 *  1    task is solved
     611             :     Rep     -   additional report, following fields are set:
     612             :                 * rep.r1    condition number in 1-norm
     613             :                 * rep.rinf  condition number in inf-norm
     614             :     B       -   array[N]:
     615             :                 * info>0    =>  overwritten by solution
     616             :                 * info=-3   =>  filled by zeros
     617             : 
     618             : 
     619             :   -- ALGLIB --
     620             :      Copyright 27.01.2010 by Bochkanov Sergey
     621             : *************************************************************************/
     622           0 : void rmatrixsolvemfast(const real_2d_array &a, const ae_int_t n, const real_2d_array &b, const ae_int_t m, ae_int_t &info, const xparams _xparams)
     623             : {
     624             :     jmp_buf _break_jump;
     625             :     alglib_impl::ae_state _alglib_env_state;
     626           0 :     alglib_impl::ae_state_init(&_alglib_env_state);
     627           0 :     if( setjmp(_break_jump) )
     628             :     {
     629             : #if !defined(AE_NO_EXCEPTIONS)
     630           0 :         _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
     631             : #else
     632             :         _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
     633             :         return;
     634             : #endif
     635             :     }
     636           0 :     ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
     637           0 :     if( _xparams.flags!=0x0 )
     638           0 :         ae_state_set_flags(&_alglib_env_state, _xparams.flags);
     639           0 :     alglib_impl::rmatrixsolvemfast(const_cast<alglib_impl::ae_matrix*>(a.c_ptr()), n, const_cast<alglib_impl::ae_matrix*>(b.c_ptr()), m, &info, &_alglib_env_state);
     640           0 :     alglib_impl::ae_state_clear(&_alglib_env_state);
     641           0 :     return;
     642             : }
     643             : 
     644             : /*************************************************************************
     645             : Dense solver.
     646             : 
     647             : This  subroutine  solves  a  system  A*x=b,  where A is NxN non-denegerate
     648             : real matrix given by its LU decomposition, x and b are real vectors.  This
     649             : is "slow-but-robust" version of the linear LU-based solver. Faster version
     650             : is RMatrixLUSolveFast() function.
     651             : 
     652             : Algorithm features:
     653             : * automatic detection of degenerate cases
     654             : * O(N^2) complexity
     655             : * condition number estimation
     656             : 
     657             : No iterative refinement  is provided because exact form of original matrix
     658             : is not known to subroutine. Use RMatrixSolve or RMatrixMixedSolve  if  you
     659             : need iterative refinement.
     660             : 
     661             : IMPORTANT: ! this function is NOT the most efficient linear solver provided
     662             :            ! by ALGLIB. It estimates condition  number  of  linear system,
     663             :            ! which results in 10-15x  performance  penalty  when  compared
     664             :            ! with "fast" version which just calls triangular solver.
     665             :            !
     666             :            ! This performance penalty is insignificant  when compared with
     667             :            ! cost of large LU decomposition.  However,  if you  call  this
     668             :            ! function many times for the same  left  side,  this  overhead
     669             :            ! BECOMES significant. It  also  becomes significant for small-
     670             :            ! scale problems.
     671             :            !
     672             :            ! In such cases we strongly recommend you to use faster solver,
     673             :            ! RMatrixLUSolveFast() function.
     674             : 
     675             : INPUT PARAMETERS
     676             :     LUA     -   array[N,N], LU decomposition, RMatrixLU result
     677             :     P       -   array[N], pivots array, RMatrixLU result
     678             :     N       -   size of A
     679             :     B       -   array[N], right part
     680             : 
     681             : OUTPUT PARAMETERS
     682             :     Info    -   return code:
     683             :                 * -3    matrix is very badly conditioned or exactly singular.
     684             :                 * -1    N<=0 was passed
     685             :                 *  1    task is solved (but matrix A may be ill-conditioned,
     686             :                         check R1/RInf parameters for condition numbers).
     687             :     Rep     -   additional report, following fields are set:
     688             :                 * rep.r1    condition number in 1-norm
     689             :                 * rep.rinf  condition number in inf-norm
     690             :     X       -   array[N], it contains:
     691             :                 * info>0    =>  solution
     692             :                 * info=-3   =>  filled by zeros
     693             : 
     694             : 
     695             :   -- ALGLIB --
     696             :      Copyright 27.01.2010 by Bochkanov Sergey
     697             : *************************************************************************/
     698           0 : void rmatrixlusolve(const real_2d_array &lua, const integer_1d_array &p, const ae_int_t n, const real_1d_array &b, ae_int_t &info, densesolverreport &rep, real_1d_array &x, const xparams _xparams)
     699             : {
     700             :     jmp_buf _break_jump;
     701             :     alglib_impl::ae_state _alglib_env_state;
     702           0 :     alglib_impl::ae_state_init(&_alglib_env_state);
     703           0 :     if( setjmp(_break_jump) )
     704             :     {
     705             : #if !defined(AE_NO_EXCEPTIONS)
     706           0 :         _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
     707             : #else
     708             :         _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
     709             :         return;
     710             : #endif
     711             :     }
     712           0 :     ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
     713           0 :     if( _xparams.flags!=0x0 )
     714           0 :         ae_state_set_flags(&_alglib_env_state, _xparams.flags);
     715           0 :     alglib_impl::rmatrixlusolve(const_cast<alglib_impl::ae_matrix*>(lua.c_ptr()), const_cast<alglib_impl::ae_vector*>(p.c_ptr()), n, const_cast<alglib_impl::ae_vector*>(b.c_ptr()), &info, const_cast<alglib_impl::densesolverreport*>(rep.c_ptr()), const_cast<alglib_impl::ae_vector*>(x.c_ptr()), &_alglib_env_state);
     716           0 :     alglib_impl::ae_state_clear(&_alglib_env_state);
     717           0 :     return;
     718             : }
     719             : 
     720             : /*************************************************************************
     721             : Dense solver.
     722             : 
     723             : This  subroutine  solves  a  system  A*x=b,  where A is NxN non-denegerate
     724             : real matrix given by its LU decomposition, x and b are real vectors.  This
     725             : is "fast-without-any-checks" version of the linear LU-based solver. Slower
     726             : but more robust version is RMatrixLUSolve() function.
     727             : 
     728             : Algorithm features:
     729             : * O(N^2) complexity
     730             : * fast algorithm without ANY additional checks, just triangular solver
     731             : 
     732             : INPUT PARAMETERS
     733             :     LUA     -   array[0..N-1,0..N-1], LU decomposition, RMatrixLU result
     734             :     P       -   array[0..N-1], pivots array, RMatrixLU result
     735             :     N       -   size of A
     736             :     B       -   array[0..N-1], right part
     737             : 
     738             : OUTPUT PARAMETERS
     739             :     Info    -   return code:
     740             :                 * -3    matrix is exactly singular (ill conditioned matrices
     741             :                         are not recognized).
     742             :                         X is filled by zeros in such cases.
     743             :                 * -1    N<=0 was passed
     744             :                 *  1    task is solved
     745             :     B       -   array[N]:
     746             :                 * info>0    =>  overwritten by solution
     747             :                 * info=-3   =>  filled by zeros
     748             : 
     749             :   -- ALGLIB --
     750             :      Copyright 18.03.2015 by Bochkanov Sergey
     751             : *************************************************************************/
     752           0 : void rmatrixlusolvefast(const real_2d_array &lua, const integer_1d_array &p, const ae_int_t n, const real_1d_array &b, ae_int_t &info, const xparams _xparams)
     753             : {
     754             :     jmp_buf _break_jump;
     755             :     alglib_impl::ae_state _alglib_env_state;
     756           0 :     alglib_impl::ae_state_init(&_alglib_env_state);
     757           0 :     if( setjmp(_break_jump) )
     758             :     {
     759             : #if !defined(AE_NO_EXCEPTIONS)
     760           0 :         _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
     761             : #else
     762             :         _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
     763             :         return;
     764             : #endif
     765             :     }
     766           0 :     ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
     767           0 :     if( _xparams.flags!=0x0 )
     768           0 :         ae_state_set_flags(&_alglib_env_state, _xparams.flags);
     769           0 :     alglib_impl::rmatrixlusolvefast(const_cast<alglib_impl::ae_matrix*>(lua.c_ptr()), const_cast<alglib_impl::ae_vector*>(p.c_ptr()), n, const_cast<alglib_impl::ae_vector*>(b.c_ptr()), &info, &_alglib_env_state);
     770           0 :     alglib_impl::ae_state_clear(&_alglib_env_state);
     771           0 :     return;
     772             : }
     773             : 
     774             : /*************************************************************************
     775             : Dense solver.
     776             : 
     777             : Similar to RMatrixLUSolve() but solves  task  with  multiple  right  parts
     778             : (where b and x are NxM matrices). This  is  "robust-but-slow"  version  of
     779             : LU-based solver which performs additional  checks  for  non-degeneracy  of
     780             : inputs (condition number estimation). If you need  best  performance,  use
     781             : "fast-without-any-checks" version, RMatrixLUSolveMFast().
     782             : 
     783             : Algorithm features:
     784             : * automatic detection of degenerate cases
     785             : * O(M*N^2) complexity
     786             : * condition number estimation
     787             : 
     788             : No iterative refinement  is provided because exact form of original matrix
     789             : is not known to subroutine. Use RMatrixSolve or RMatrixMixedSolve  if  you
     790             : need iterative refinement.
     791             : 
     792             : IMPORTANT: ! this function is NOT the most efficient linear solver provided
     793             :            ! by ALGLIB. It estimates condition  number  of  linear system,
     794             :            ! which  results  in  significant  performance   penalty   when
     795             :            ! compared with "fast"  version  which  just  calls  triangular
     796             :            ! solver.
     797             :            !
     798             :            ! This performance penalty is especially apparent when you  use
     799             :            ! ALGLIB parallel capabilities (condition number estimation  is
     800             :            ! inherently  sequential).  It   also   becomes significant for
     801             :            ! small-scale problems.
     802             :            !
     803             :            ! In such cases we strongly recommend you to use faster solver,
     804             :            ! RMatrixLUSolveMFast() function.
     805             : 
     806             :   ! COMMERCIAL EDITION OF ALGLIB:
     807             :   !
     808             :   ! Commercial Edition of ALGLIB includes following important improvements
     809             :   ! of this function:
     810             :   ! * high-performance native backend with same C# interface (C# version)
     811             :   ! * multithreading support (C++ and C# versions)
     812             :   ! * hardware vendor (Intel) implementations of linear algebra primitives
     813             :   !   (C++ and C# versions, x86/x64 platform)
     814             :   !
     815             :   ! We recommend you to read 'Working with commercial version' section  of
     816             :   ! ALGLIB Reference Manual in order to find out how to  use  performance-
     817             :   ! related features provided by commercial edition of ALGLIB.
     818             : 
     819             : INPUT PARAMETERS
     820             :     LUA     -   array[N,N], LU decomposition, RMatrixLU result
     821             :     P       -   array[N], pivots array, RMatrixLU result
     822             :     N       -   size of A
     823             :     B       -   array[0..N-1,0..M-1], right part
     824             :     M       -   right part size
     825             : 
     826             : OUTPUT PARAMETERS
     827             :     Info    -   return code:
     828             :                 * -3    matrix is very badly conditioned or exactly singular.
     829             :                         X is filled by zeros in such cases.
     830             :                 * -1    N<=0 was passed
     831             :                 *  1    task is solved (but matrix A may be ill-conditioned,
     832             :                         check R1/RInf parameters for condition numbers).
     833             :     Rep     -   additional report, following fields are set:
     834             :                 * rep.r1    condition number in 1-norm
     835             :                 * rep.rinf  condition number in inf-norm
     836             :     X       -   array[N,M], it contains:
     837             :                 * info>0    =>  solution
     838             :                 * info=-3   =>  filled by zeros
     839             : 
     840             : 
     841             :   -- ALGLIB --
     842             :      Copyright 27.01.2010 by Bochkanov Sergey
     843             : *************************************************************************/
     844           0 : void rmatrixlusolvem(const real_2d_array &lua, const integer_1d_array &p, const ae_int_t n, const real_2d_array &b, const ae_int_t m, ae_int_t &info, densesolverreport &rep, real_2d_array &x, const xparams _xparams)
     845             : {
     846             :     jmp_buf _break_jump;
     847             :     alglib_impl::ae_state _alglib_env_state;
     848           0 :     alglib_impl::ae_state_init(&_alglib_env_state);
     849           0 :     if( setjmp(_break_jump) )
     850             :     {
     851             : #if !defined(AE_NO_EXCEPTIONS)
     852           0 :         _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
     853             : #else
     854             :         _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
     855             :         return;
     856             : #endif
     857             :     }
     858           0 :     ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
     859           0 :     if( _xparams.flags!=0x0 )
     860           0 :         ae_state_set_flags(&_alglib_env_state, _xparams.flags);
     861           0 :     alglib_impl::rmatrixlusolvem(const_cast<alglib_impl::ae_matrix*>(lua.c_ptr()), const_cast<alglib_impl::ae_vector*>(p.c_ptr()), n, const_cast<alglib_impl::ae_matrix*>(b.c_ptr()), m, &info, const_cast<alglib_impl::densesolverreport*>(rep.c_ptr()), const_cast<alglib_impl::ae_matrix*>(x.c_ptr()), &_alglib_env_state);
     862           0 :     alglib_impl::ae_state_clear(&_alglib_env_state);
     863           0 :     return;
     864             : }
     865             : 
     866             : /*************************************************************************
     867             : Dense solver.
     868             : 
     869             : Similar to RMatrixLUSolve() but solves  task  with  multiple  right parts,
     870             : where b and x are NxM matrices.  This is "fast-without-any-checks" version
     871             : of LU-based solver. It does not estimate  condition number  of  a  system,
     872             : so it is extremely fast. If you need better detection  of  near-degenerate
     873             : cases, use RMatrixLUSolveM() function.
     874             : 
     875             : Algorithm features:
     876             : * O(M*N^2) complexity
     877             : * fast algorithm without ANY additional checks, just triangular solver
     878             : 
     879             :   ! COMMERCIAL EDITION OF ALGLIB:
     880             :   !
     881             :   ! Commercial Edition of ALGLIB includes following important improvements
     882             :   ! of this function:
     883             :   ! * high-performance native backend with same C# interface (C# version)
     884             :   ! * multithreading support (C++ and C# versions)
     885             :   ! * hardware vendor (Intel) implementations of linear algebra primitives
     886             :   !   (C++ and C# versions, x86/x64 platform)
     887             :   !
     888             :   ! We recommend you to read 'Working with commercial version' section  of
     889             :   ! ALGLIB Reference Manual in order to find out how to  use  performance-
     890             :   ! related features provided by commercial edition of ALGLIB.
     891             : 
     892             : INPUT PARAMETERS:
     893             :     LUA     -   array[0..N-1,0..N-1], LU decomposition, RMatrixLU result
     894             :     P       -   array[0..N-1], pivots array, RMatrixLU result
     895             :     N       -   size of A
     896             :     B       -   array[0..N-1,0..M-1], right part
     897             :     M       -   right part size
     898             : 
     899             : OUTPUT PARAMETERS:
     900             :     Info    -   return code:
     901             :                 * -3    matrix is exactly singular (ill conditioned matrices
     902             :                         are not recognized).
     903             :                 * -1    N<=0 was passed
     904             :                 *  1    task is solved
     905             :     B       -   array[N,M]:
     906             :                 * info>0    =>  overwritten by solution
     907             :                 * info=-3   =>  filled by zeros
     908             : 
     909             :   -- ALGLIB --
     910             :      Copyright 18.03.2015 by Bochkanov Sergey
     911             : *************************************************************************/
     912           0 : void rmatrixlusolvemfast(const real_2d_array &lua, const integer_1d_array &p, const ae_int_t n, const real_2d_array &b, const ae_int_t m, ae_int_t &info, const xparams _xparams)
     913             : {
     914             :     jmp_buf _break_jump;
     915             :     alglib_impl::ae_state _alglib_env_state;
     916           0 :     alglib_impl::ae_state_init(&_alglib_env_state);
     917           0 :     if( setjmp(_break_jump) )
     918             :     {
     919             : #if !defined(AE_NO_EXCEPTIONS)
     920           0 :         _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
     921             : #else
     922             :         _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
     923             :         return;
     924             : #endif
     925             :     }
     926           0 :     ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
     927           0 :     if( _xparams.flags!=0x0 )
     928           0 :         ae_state_set_flags(&_alglib_env_state, _xparams.flags);
     929           0 :     alglib_impl::rmatrixlusolvemfast(const_cast<alglib_impl::ae_matrix*>(lua.c_ptr()), const_cast<alglib_impl::ae_vector*>(p.c_ptr()), n, const_cast<alglib_impl::ae_matrix*>(b.c_ptr()), m, &info, &_alglib_env_state);
     930           0 :     alglib_impl::ae_state_clear(&_alglib_env_state);
     931           0 :     return;
     932             : }
     933             : 
     934             : /*************************************************************************
     935             : Dense solver.
     936             : 
     937             : This  subroutine  solves  a  system  A*x=b,  where BOTH ORIGINAL A AND ITS
     938             : LU DECOMPOSITION ARE KNOWN. You can use it if for some  reasons  you  have
     939             : both A and its LU decomposition.
     940             : 
     941             : Algorithm features:
     942             : * automatic detection of degenerate cases
     943             : * condition number estimation
     944             : * iterative refinement
     945             : * O(N^2) complexity
     946             : 
     947             : INPUT PARAMETERS
     948             :     A       -   array[0..N-1,0..N-1], system matrix
     949             :     LUA     -   array[0..N-1,0..N-1], LU decomposition, RMatrixLU result
     950             :     P       -   array[0..N-1], pivots array, RMatrixLU result
     951             :     N       -   size of A
     952             :     B       -   array[0..N-1], right part
     953             : 
     954             : OUTPUT PARAMETERS
     955             :     Info    -   return code:
     956             :                 * -3    matrix is very badly conditioned or exactly singular.
     957             :                 * -1    N<=0 was passed
     958             :                 *  1    task is solved (but matrix A may be ill-conditioned,
     959             :                         check R1/RInf parameters for condition numbers).
     960             :     Rep     -   additional report, following fields are set:
     961             :                 * rep.r1    condition number in 1-norm
     962             :                 * rep.rinf  condition number in inf-norm
     963             :     X       -   array[N], it contains:
     964             :                 * info>0    =>  solution
     965             :                 * info=-3   =>  filled by zeros
     966             : 
     967             :   -- ALGLIB --
     968             :      Copyright 27.01.2010 by Bochkanov Sergey
     969             : *************************************************************************/
     970           0 : void rmatrixmixedsolve(const real_2d_array &a, const real_2d_array &lua, const integer_1d_array &p, const ae_int_t n, const real_1d_array &b, ae_int_t &info, densesolverreport &rep, real_1d_array &x, const xparams _xparams)
     971             : {
     972             :     jmp_buf _break_jump;
     973             :     alglib_impl::ae_state _alglib_env_state;
     974           0 :     alglib_impl::ae_state_init(&_alglib_env_state);
     975           0 :     if( setjmp(_break_jump) )
     976             :     {
     977             : #if !defined(AE_NO_EXCEPTIONS)
     978           0 :         _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
     979             : #else
     980             :         _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
     981             :         return;
     982             : #endif
     983             :     }
     984           0 :     ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
     985           0 :     if( _xparams.flags!=0x0 )
     986           0 :         ae_state_set_flags(&_alglib_env_state, _xparams.flags);
     987           0 :     alglib_impl::rmatrixmixedsolve(const_cast<alglib_impl::ae_matrix*>(a.c_ptr()), const_cast<alglib_impl::ae_matrix*>(lua.c_ptr()), const_cast<alglib_impl::ae_vector*>(p.c_ptr()), n, const_cast<alglib_impl::ae_vector*>(b.c_ptr()), &info, const_cast<alglib_impl::densesolverreport*>(rep.c_ptr()), const_cast<alglib_impl::ae_vector*>(x.c_ptr()), &_alglib_env_state);
     988           0 :     alglib_impl::ae_state_clear(&_alglib_env_state);
     989           0 :     return;
     990             : }
     991             : 
     992             : /*************************************************************************
     993             : Dense solver.
     994             : 
     995             : Similar to RMatrixMixedSolve() but  solves task with multiple right  parts
     996             : (where b and x are NxM matrices).
     997             : 
     998             : Algorithm features:
     999             : * automatic detection of degenerate cases
    1000             : * condition number estimation
    1001             : * iterative refinement
    1002             : * O(M*N^2) complexity
    1003             : 
    1004             : INPUT PARAMETERS
    1005             :     A       -   array[0..N-1,0..N-1], system matrix
    1006             :     LUA     -   array[0..N-1,0..N-1], LU decomposition, RMatrixLU result
    1007             :     P       -   array[0..N-1], pivots array, RMatrixLU result
    1008             :     N       -   size of A
    1009             :     B       -   array[0..N-1,0..M-1], right part
    1010             :     M       -   right part size
    1011             : 
    1012             : OUTPUT PARAMETERS
    1013             :     Info    -   return code:
    1014             :                 * -3    matrix is very badly conditioned or exactly singular.
    1015             :                 * -1    N<=0 was passed
    1016             :                 *  1    task is solved (but matrix A may be ill-conditioned,
    1017             :                         check R1/RInf parameters for condition numbers).
    1018             :     Rep     -   additional report, following fields are set:
    1019             :                 * rep.r1    condition number in 1-norm
    1020             :                 * rep.rinf  condition number in inf-norm
    1021             :     X       -   array[N,M], it contains:
    1022             :                 * info>0    =>  solution
    1023             :                 * info=-3   =>  filled by zeros
    1024             : 
    1025             :   -- ALGLIB --
    1026             :      Copyright 27.01.2010 by Bochkanov Sergey
    1027             : *************************************************************************/
    1028           0 : void rmatrixmixedsolvem(const real_2d_array &a, const real_2d_array &lua, const integer_1d_array &p, const ae_int_t n, const real_2d_array &b, const ae_int_t m, ae_int_t &info, densesolverreport &rep, real_2d_array &x, const xparams _xparams)
    1029             : {
    1030             :     jmp_buf _break_jump;
    1031             :     alglib_impl::ae_state _alglib_env_state;
    1032           0 :     alglib_impl::ae_state_init(&_alglib_env_state);
    1033           0 :     if( setjmp(_break_jump) )
    1034             :     {
    1035             : #if !defined(AE_NO_EXCEPTIONS)
    1036           0 :         _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
    1037             : #else
    1038             :         _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
    1039             :         return;
    1040             : #endif
    1041             :     }
    1042           0 :     ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
    1043           0 :     if( _xparams.flags!=0x0 )
    1044           0 :         ae_state_set_flags(&_alglib_env_state, _xparams.flags);
    1045           0 :     alglib_impl::rmatrixmixedsolvem(const_cast<alglib_impl::ae_matrix*>(a.c_ptr()), const_cast<alglib_impl::ae_matrix*>(lua.c_ptr()), const_cast<alglib_impl::ae_vector*>(p.c_ptr()), n, const_cast<alglib_impl::ae_matrix*>(b.c_ptr()), m, &info, const_cast<alglib_impl::densesolverreport*>(rep.c_ptr()), const_cast<alglib_impl::ae_matrix*>(x.c_ptr()), &_alglib_env_state);
    1046           0 :     alglib_impl::ae_state_clear(&_alglib_env_state);
    1047           0 :     return;
    1048             : }
    1049             : 
    1050             : /*************************************************************************
    1051             : Complex dense solver for A*X=B with N*N  complex  matrix  A,  N*M  complex
    1052             : matrices  X  and  B.  "Slow-but-feature-rich"   version   which   provides
    1053             : additional functions, at the cost of slower  performance.  Faster  version
    1054             : may be invoked with CMatrixSolveMFast() function.
    1055             : 
    1056             : Algorithm features:
    1057             : * automatic detection of degenerate cases
    1058             : * condition number estimation
    1059             : * iterative refinement
    1060             : * O(N^3+M*N^2) complexity
    1061             : 
    1062             : IMPORTANT: ! this function is NOT the most efficient linear solver provided
    1063             :            ! by ALGLIB. It estimates condition  number  of  linear  system
    1064             :            ! and  performs  iterative   refinement,   which   results   in
    1065             :            ! significant performance penalty  when  compared  with  "fast"
    1066             :            ! version  which  just  performs  LU  decomposition  and  calls
    1067             :            ! triangular solver.
    1068             :            !
    1069             :            ! This  performance  penalty  is  especially  visible  in   the
    1070             :            ! multithreaded mode, because both condition number  estimation
    1071             :            ! and   iterative    refinement   are   inherently   sequential
    1072             :            ! calculations.
    1073             :            !
    1074             :            ! Thus, if you need high performance and if you are pretty sure
    1075             :            ! that your system is well conditioned, we  strongly  recommend
    1076             :            ! you to use faster solver, CMatrixSolveMFast() function.
    1077             : 
    1078             :   ! COMMERCIAL EDITION OF ALGLIB:
    1079             :   !
    1080             :   ! Commercial Edition of ALGLIB includes following important improvements
    1081             :   ! of this function:
    1082             :   ! * high-performance native backend with same C# interface (C# version)
    1083             :   ! * multithreading support (C++ and C# versions)
    1084             :   ! * hardware vendor (Intel) implementations of linear algebra primitives
    1085             :   !   (C++ and C# versions, x86/x64 platform)
    1086             :   !
    1087             :   ! We recommend you to read 'Working with commercial version' section  of
    1088             :   ! ALGLIB Reference Manual in order to find out how to  use  performance-
    1089             :   ! related features provided by commercial edition of ALGLIB.
    1090             : 
    1091             : INPUT PARAMETERS
    1092             :     A       -   array[0..N-1,0..N-1], system matrix
    1093             :     N       -   size of A
    1094             :     B       -   array[0..N-1,0..M-1], right part
    1095             :     M       -   right part size
    1096             :     RFS     -   iterative refinement switch:
    1097             :                 * True - refinement is used.
    1098             :                   Less performance, more precision.
    1099             :                 * False - refinement is not used.
    1100             :                   More performance, less precision.
    1101             : 
    1102             : OUTPUT PARAMETERS
    1103             :     Info    -   return code:
    1104             :                 * -3    matrix is very badly conditioned or exactly singular.
    1105             :                         X is filled by zeros in such cases.
    1106             :                 * -1    N<=0 was passed
    1107             :                 *  1    task is solved (but matrix A may be ill-conditioned,
    1108             :                         check R1/RInf parameters for condition numbers).
    1109             :     Rep     -   additional report, following fields are set:
    1110             :                 * rep.r1    condition number in 1-norm
    1111             :                 * rep.rinf  condition number in inf-norm
    1112             :     X       -   array[N,M], it contains:
    1113             :                 * info>0    =>  solution
    1114             :                 * info=-3   =>  filled by zeros
    1115             : 
    1116             :   -- ALGLIB --
    1117             :      Copyright 27.01.2010 by Bochkanov Sergey
    1118             : *************************************************************************/
    1119           0 : void cmatrixsolvem(const complex_2d_array &a, const ae_int_t n, const complex_2d_array &b, const ae_int_t m, const bool rfs, ae_int_t &info, densesolverreport &rep, complex_2d_array &x, const xparams _xparams)
    1120             : {
    1121             :     jmp_buf _break_jump;
    1122             :     alglib_impl::ae_state _alglib_env_state;
    1123           0 :     alglib_impl::ae_state_init(&_alglib_env_state);
    1124           0 :     if( setjmp(_break_jump) )
    1125             :     {
    1126             : #if !defined(AE_NO_EXCEPTIONS)
    1127           0 :         _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
    1128             : #else
    1129             :         _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
    1130             :         return;
    1131             : #endif
    1132             :     }
    1133           0 :     ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
    1134           0 :     if( _xparams.flags!=0x0 )
    1135           0 :         ae_state_set_flags(&_alglib_env_state, _xparams.flags);
    1136           0 :     alglib_impl::cmatrixsolvem(const_cast<alglib_impl::ae_matrix*>(a.c_ptr()), n, const_cast<alglib_impl::ae_matrix*>(b.c_ptr()), m, rfs, &info, const_cast<alglib_impl::densesolverreport*>(rep.c_ptr()), const_cast<alglib_impl::ae_matrix*>(x.c_ptr()), &_alglib_env_state);
    1137           0 :     alglib_impl::ae_state_clear(&_alglib_env_state);
    1138           0 :     return;
    1139             : }
    1140             : 
    1141             : /*************************************************************************
    1142             : Complex dense solver for A*X=B with N*N  complex  matrix  A,  N*M  complex
    1143             : matrices  X  and  B.  "Fast-but-lightweight" version which  provides  just
    1144             : triangular solver - and no additional functions like iterative  refinement
    1145             : or condition number estimation.
    1146             : 
    1147             : Algorithm features:
    1148             : * O(N^3+M*N^2) complexity
    1149             : * no additional time consuming functions
    1150             : 
    1151             :   ! COMMERCIAL EDITION OF ALGLIB:
    1152             :   !
    1153             :   ! Commercial Edition of ALGLIB includes following important improvements
    1154             :   ! of this function:
    1155             :   ! * high-performance native backend with same C# interface (C# version)
    1156             :   ! * multithreading support (C++ and C# versions)
    1157             :   ! * hardware vendor (Intel) implementations of linear algebra primitives
    1158             :   !   (C++ and C# versions, x86/x64 platform)
    1159             :   !
    1160             :   ! We recommend you to read 'Working with commercial version' section  of
    1161             :   ! ALGLIB Reference Manual in order to find out how to  use  performance-
    1162             :   ! related features provided by commercial edition of ALGLIB.
    1163             : 
    1164             : INPUT PARAMETERS
    1165             :     A       -   array[0..N-1,0..N-1], system matrix
    1166             :     N       -   size of A
    1167             :     B       -   array[0..N-1,0..M-1], right part
    1168             :     M       -   right part size
    1169             : 
    1170             : OUTPUT PARAMETERS:
    1171             :     Info    -   return code:
    1172             :                 * -3    matrix is exactly singular (ill conditioned matrices
    1173             :                         are not recognized).
    1174             :                 * -1    N<=0 was passed
    1175             :                 *  1    task is solved
    1176             :     B       -   array[N,M]:
    1177             :                 * info>0    =>  overwritten by solution
    1178             :                 * info=-3   =>  filled by zeros
    1179             : 
    1180             :   -- ALGLIB --
    1181             :      Copyright 16.03.2015 by Bochkanov Sergey
    1182             : *************************************************************************/
    1183           0 : void cmatrixsolvemfast(const complex_2d_array &a, const ae_int_t n, const complex_2d_array &b, const ae_int_t m, ae_int_t &info, const xparams _xparams)
    1184             : {
    1185             :     jmp_buf _break_jump;
    1186             :     alglib_impl::ae_state _alglib_env_state;
    1187           0 :     alglib_impl::ae_state_init(&_alglib_env_state);
    1188           0 :     if( setjmp(_break_jump) )
    1189             :     {
    1190             : #if !defined(AE_NO_EXCEPTIONS)
    1191           0 :         _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
    1192             : #else
    1193             :         _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
    1194             :         return;
    1195             : #endif
    1196             :     }
    1197           0 :     ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
    1198           0 :     if( _xparams.flags!=0x0 )
    1199           0 :         ae_state_set_flags(&_alglib_env_state, _xparams.flags);
    1200           0 :     alglib_impl::cmatrixsolvemfast(const_cast<alglib_impl::ae_matrix*>(a.c_ptr()), n, const_cast<alglib_impl::ae_matrix*>(b.c_ptr()), m, &info, &_alglib_env_state);
    1201           0 :     alglib_impl::ae_state_clear(&_alglib_env_state);
    1202           0 :     return;
    1203             : }
    1204             : 
    1205             : /*************************************************************************
    1206             : Complex dense solver for A*x=B with N*N complex matrix A and  N*1  complex
    1207             : vectors x and b. "Slow-but-feature-rich" version of the solver.
    1208             : 
    1209             : Algorithm features:
    1210             : * automatic detection of degenerate cases
    1211             : * condition number estimation
    1212             : * iterative refinement
    1213             : * O(N^3) complexity
    1214             : 
    1215             : IMPORTANT: ! this function is NOT the most efficient linear solver provided
    1216             :            ! by ALGLIB. It estimates condition  number  of  linear  system
    1217             :            ! and  performs  iterative   refinement,   which   results   in
    1218             :            ! significant performance penalty  when  compared  with  "fast"
    1219             :            ! version  which  just  performs  LU  decomposition  and  calls
    1220             :            ! triangular solver.
    1221             :            !
    1222             :            ! This  performance  penalty  is  especially  visible  in   the
    1223             :            ! multithreaded mode, because both condition number  estimation
    1224             :            ! and   iterative    refinement   are   inherently   sequential
    1225             :            ! calculations.
    1226             :            !
    1227             :            ! Thus, if you need high performance and if you are pretty sure
    1228             :            ! that your system is well conditioned, we  strongly  recommend
    1229             :            ! you to use faster solver, CMatrixSolveFast() function.
    1230             : 
    1231             :   ! COMMERCIAL EDITION OF ALGLIB:
    1232             :   !
    1233             :   ! Commercial Edition of ALGLIB includes following important improvements
    1234             :   ! of this function:
    1235             :   ! * high-performance native backend with same C# interface (C# version)
    1236             :   ! * multithreading support (C++ and C# versions)
    1237             :   ! * hardware vendor (Intel) implementations of linear algebra primitives
    1238             :   !   (C++ and C# versions, x86/x64 platform)
    1239             :   !
    1240             :   ! We recommend you to read 'Working with commercial version' section  of
    1241             :   ! ALGLIB Reference Manual in order to find out how to  use  performance-
    1242             :   ! related features provided by commercial edition of ALGLIB.
    1243             : 
    1244             : INPUT PARAMETERS
    1245             :     A       -   array[0..N-1,0..N-1], system matrix
    1246             :     N       -   size of A
    1247             :     B       -   array[0..N-1], right part
    1248             : 
    1249             : OUTPUT PARAMETERS
    1250             :     Info    -   return code:
    1251             :                 * -3    matrix is very badly conditioned or exactly singular.
    1252             :                 * -1    N<=0 was passed
    1253             :                 *  1    task is solved (but matrix A may be ill-conditioned,
    1254             :                         check R1/RInf parameters for condition numbers).
    1255             :     Rep     -   additional report, following fields are set:
    1256             :                 * rep.r1    condition number in 1-norm
    1257             :                 * rep.rinf  condition number in inf-norm
    1258             :     X       -   array[N], it contains:
    1259             :                 * info>0    =>  solution
    1260             :                 * info=-3   =>  filled by zeros
    1261             : 
    1262             :   -- ALGLIB --
    1263             :      Copyright 27.01.2010 by Bochkanov Sergey
    1264             : *************************************************************************/
    1265           0 : void cmatrixsolve(const complex_2d_array &a, const ae_int_t n, const complex_1d_array &b, ae_int_t &info, densesolverreport &rep, complex_1d_array &x, const xparams _xparams)
    1266             : {
    1267             :     jmp_buf _break_jump;
    1268             :     alglib_impl::ae_state _alglib_env_state;
    1269           0 :     alglib_impl::ae_state_init(&_alglib_env_state);
    1270           0 :     if( setjmp(_break_jump) )
    1271             :     {
    1272             : #if !defined(AE_NO_EXCEPTIONS)
    1273           0 :         _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
    1274             : #else
    1275             :         _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
    1276             :         return;
    1277             : #endif
    1278             :     }
    1279           0 :     ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
    1280           0 :     if( _xparams.flags!=0x0 )
    1281           0 :         ae_state_set_flags(&_alglib_env_state, _xparams.flags);
    1282           0 :     alglib_impl::cmatrixsolve(const_cast<alglib_impl::ae_matrix*>(a.c_ptr()), n, const_cast<alglib_impl::ae_vector*>(b.c_ptr()), &info, const_cast<alglib_impl::densesolverreport*>(rep.c_ptr()), const_cast<alglib_impl::ae_vector*>(x.c_ptr()), &_alglib_env_state);
    1283           0 :     alglib_impl::ae_state_clear(&_alglib_env_state);
    1284           0 :     return;
    1285             : }
    1286             : 
    1287             : /*************************************************************************
    1288             : Complex dense solver for A*x=B with N*N complex matrix A and  N*1  complex
    1289             : vectors x and b. "Fast-but-lightweight" version of the solver.
    1290             : 
    1291             : Algorithm features:
    1292             : * O(N^3) complexity
    1293             : * no additional time consuming features, just triangular solver
    1294             : 
    1295             :   ! COMMERCIAL EDITION OF ALGLIB:
    1296             :   !
    1297             :   ! Commercial Edition of ALGLIB includes following important improvements
    1298             :   ! of this function:
    1299             :   ! * high-performance native backend with same C# interface (C# version)
    1300             :   ! * multithreading support (C++ and C# versions)
    1301             :   ! * hardware vendor (Intel) implementations of linear algebra primitives
    1302             :   !   (C++ and C# versions, x86/x64 platform)
    1303             :   !
    1304             :   ! We recommend you to read 'Working with commercial version' section  of
    1305             :   ! ALGLIB Reference Manual in order to find out how to  use  performance-
    1306             :   ! related features provided by commercial edition of ALGLIB.
    1307             : 
    1308             : INPUT PARAMETERS:
    1309             :     A       -   array[0..N-1,0..N-1], system matrix
    1310             :     N       -   size of A
    1311             :     B       -   array[0..N-1], right part
    1312             : 
    1313             : OUTPUT PARAMETERS:
    1314             :     Info    -   return code:
    1315             :                 * -3    matrix is exactly singular (ill conditioned matrices
    1316             :                         are not recognized).
    1317             :                 * -1    N<=0 was passed
    1318             :                 *  1    task is solved
    1319             :     B       -   array[N]:
    1320             :                 * info>0    =>  overwritten by solution
    1321             :                 * info=-3   =>  filled by zeros
    1322             : 
    1323             :   -- ALGLIB --
    1324             :      Copyright 27.01.2010 by Bochkanov Sergey
    1325             : *************************************************************************/
    1326           0 : void cmatrixsolvefast(const complex_2d_array &a, const ae_int_t n, const complex_1d_array &b, ae_int_t &info, const xparams _xparams)
    1327             : {
    1328             :     jmp_buf _break_jump;
    1329             :     alglib_impl::ae_state _alglib_env_state;
    1330           0 :     alglib_impl::ae_state_init(&_alglib_env_state);
    1331           0 :     if( setjmp(_break_jump) )
    1332             :     {
    1333             : #if !defined(AE_NO_EXCEPTIONS)
    1334           0 :         _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
    1335             : #else
    1336             :         _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
    1337             :         return;
    1338             : #endif
    1339             :     }
    1340           0 :     ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
    1341           0 :     if( _xparams.flags!=0x0 )
    1342           0 :         ae_state_set_flags(&_alglib_env_state, _xparams.flags);
    1343           0 :     alglib_impl::cmatrixsolvefast(const_cast<alglib_impl::ae_matrix*>(a.c_ptr()), n, const_cast<alglib_impl::ae_vector*>(b.c_ptr()), &info, &_alglib_env_state);
    1344           0 :     alglib_impl::ae_state_clear(&_alglib_env_state);
    1345           0 :     return;
    1346             : }
    1347             : 
    1348             : /*************************************************************************
    1349             : Dense solver for A*X=B with N*N complex A given by its  LU  decomposition,
    1350             : and N*M matrices X and B (multiple right sides).   "Slow-but-feature-rich"
    1351             : version of the solver.
    1352             : 
    1353             : Algorithm features:
    1354             : * automatic detection of degenerate cases
    1355             : * O(M*N^2) complexity
    1356             : * condition number estimation
    1357             : 
    1358             : No iterative refinement  is provided because exact form of original matrix
    1359             : is not known to subroutine. Use CMatrixSolve or CMatrixMixedSolve  if  you
    1360             : need iterative refinement.
    1361             : 
    1362             : IMPORTANT: ! this function is NOT the most efficient linear solver provided
    1363             :            ! by ALGLIB. It estimates condition  number  of  linear system,
    1364             :            ! which  results  in  significant  performance   penalty   when
    1365             :            ! compared with "fast"  version  which  just  calls  triangular
    1366             :            ! solver.
    1367             :            !
    1368             :            ! This performance penalty is especially apparent when you  use
    1369             :            ! ALGLIB parallel capabilities (condition number estimation  is
    1370             :            ! inherently  sequential).  It   also   becomes significant for
    1371             :            ! small-scale problems.
    1372             :            !
    1373             :            ! In such cases we strongly recommend you to use faster solver,
    1374             :            ! CMatrixLUSolveMFast() function.
    1375             : 
    1376             :   ! COMMERCIAL EDITION OF ALGLIB:
    1377             :   !
    1378             :   ! Commercial Edition of ALGLIB includes following important improvements
    1379             :   ! of this function:
    1380             :   ! * high-performance native backend with same C# interface (C# version)
    1381             :   ! * multithreading support (C++ and C# versions)
    1382             :   ! * hardware vendor (Intel) implementations of linear algebra primitives
    1383             :   !   (C++ and C# versions, x86/x64 platform)
    1384             :   !
    1385             :   ! We recommend you to read 'Working with commercial version' section  of
    1386             :   ! ALGLIB Reference Manual in order to find out how to  use  performance-
    1387             :   ! related features provided by commercial edition of ALGLIB.
    1388             : 
    1389             : INPUT PARAMETERS
    1390             :     LUA     -   array[0..N-1,0..N-1], LU decomposition, RMatrixLU result
    1391             :     P       -   array[0..N-1], pivots array, RMatrixLU result
    1392             :     N       -   size of A
    1393             :     B       -   array[0..N-1,0..M-1], right part
    1394             :     M       -   right part size
    1395             : 
    1396             : OUTPUT PARAMETERS
    1397             :     Info    -   return code:
    1398             :                 * -3    matrix is very badly conditioned or exactly singular.
    1399             :                 * -1    N<=0 was passed
    1400             :                 *  1    task is solved (but matrix A may be ill-conditioned,
    1401             :                         check R1/RInf parameters for condition numbers).
    1402             :     Rep     -   additional report, following fields are set:
    1403             :                 * rep.r1    condition number in 1-norm
    1404             :                 * rep.rinf  condition number in inf-norm
    1405             :     X       -   array[N,M], it contains:
    1406             :                 * info>0    =>  solution
    1407             :                 * info=-3   =>  filled by zeros
    1408             : 
    1409             :   -- ALGLIB --
    1410             :      Copyright 27.01.2010 by Bochkanov Sergey
    1411             : *************************************************************************/
    1412           0 : void cmatrixlusolvem(const complex_2d_array &lua, const integer_1d_array &p, const ae_int_t n, const complex_2d_array &b, const ae_int_t m, ae_int_t &info, densesolverreport &rep, complex_2d_array &x, const xparams _xparams)
    1413             : {
    1414             :     jmp_buf _break_jump;
    1415             :     alglib_impl::ae_state _alglib_env_state;
    1416           0 :     alglib_impl::ae_state_init(&_alglib_env_state);
    1417           0 :     if( setjmp(_break_jump) )
    1418             :     {
    1419             : #if !defined(AE_NO_EXCEPTIONS)
    1420           0 :         _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
    1421             : #else
    1422             :         _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
    1423             :         return;
    1424             : #endif
    1425             :     }
    1426           0 :     ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
    1427           0 :     if( _xparams.flags!=0x0 )
    1428           0 :         ae_state_set_flags(&_alglib_env_state, _xparams.flags);
    1429           0 :     alglib_impl::cmatrixlusolvem(const_cast<alglib_impl::ae_matrix*>(lua.c_ptr()), const_cast<alglib_impl::ae_vector*>(p.c_ptr()), n, const_cast<alglib_impl::ae_matrix*>(b.c_ptr()), m, &info, const_cast<alglib_impl::densesolverreport*>(rep.c_ptr()), const_cast<alglib_impl::ae_matrix*>(x.c_ptr()), &_alglib_env_state);
    1430           0 :     alglib_impl::ae_state_clear(&_alglib_env_state);
    1431           0 :     return;
    1432             : }
    1433             : 
    1434             : /*************************************************************************
    1435             : Dense solver for A*X=B with N*N complex A given by its  LU  decomposition,
    1436             : and N*M matrices X and B (multiple  right  sides).  "Fast-but-lightweight"
    1437             : version of the solver.
    1438             : 
    1439             : Algorithm features:
    1440             : * O(M*N^2) complexity
    1441             : * no additional time-consuming features
    1442             : 
    1443             :   ! COMMERCIAL EDITION OF ALGLIB:
    1444             :   !
    1445             :   ! Commercial Edition of ALGLIB includes following important improvements
    1446             :   ! of this function:
    1447             :   ! * high-performance native backend with same C# interface (C# version)
    1448             :   ! * multithreading support (C++ and C# versions)
    1449             :   ! * hardware vendor (Intel) implementations of linear algebra primitives
    1450             :   !   (C++ and C# versions, x86/x64 platform)
    1451             :   !
    1452             :   ! We recommend you to read 'Working with commercial version' section  of
    1453             :   ! ALGLIB Reference Manual in order to find out how to  use  performance-
    1454             :   ! related features provided by commercial edition of ALGLIB.
    1455             : 
    1456             : INPUT PARAMETERS
    1457             :     LUA     -   array[0..N-1,0..N-1], LU decomposition, RMatrixLU result
    1458             :     P       -   array[0..N-1], pivots array, RMatrixLU result
    1459             :     N       -   size of A
    1460             :     B       -   array[0..N-1,0..M-1], right part
    1461             :     M       -   right part size
    1462             : 
    1463             : OUTPUT PARAMETERS
    1464             :     Info    -   return code:
    1465             :                 * -3    matrix is exactly singular (ill conditioned matrices
    1466             :                         are not recognized).
    1467             :                 * -1    N<=0 was passed
    1468             :                 *  1    task is solved
    1469             :     B       -   array[N,M]:
    1470             :                 * info>0    =>  overwritten by solution
    1471             :                 * info=-3   =>  filled by zeros
    1472             : 
    1473             : 
    1474             :   -- ALGLIB --
    1475             :      Copyright 27.01.2010 by Bochkanov Sergey
    1476             : *************************************************************************/
    1477           0 : void cmatrixlusolvemfast(const complex_2d_array &lua, const integer_1d_array &p, const ae_int_t n, const complex_2d_array &b, const ae_int_t m, ae_int_t &info, const xparams _xparams)
    1478             : {
    1479             :     jmp_buf _break_jump;
    1480             :     alglib_impl::ae_state _alglib_env_state;
    1481           0 :     alglib_impl::ae_state_init(&_alglib_env_state);
    1482           0 :     if( setjmp(_break_jump) )
    1483             :     {
    1484             : #if !defined(AE_NO_EXCEPTIONS)
    1485           0 :         _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
    1486             : #else
    1487             :         _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
    1488             :         return;
    1489             : #endif
    1490             :     }
    1491           0 :     ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
    1492           0 :     if( _xparams.flags!=0x0 )
    1493           0 :         ae_state_set_flags(&_alglib_env_state, _xparams.flags);
    1494           0 :     alglib_impl::cmatrixlusolvemfast(const_cast<alglib_impl::ae_matrix*>(lua.c_ptr()), const_cast<alglib_impl::ae_vector*>(p.c_ptr()), n, const_cast<alglib_impl::ae_matrix*>(b.c_ptr()), m, &info, &_alglib_env_state);
    1495           0 :     alglib_impl::ae_state_clear(&_alglib_env_state);
    1496           0 :     return;
    1497             : }
    1498             : 
    1499             : /*************************************************************************
    1500             : Complex dense linear solver for A*x=b with complex N*N A  given  by its LU
    1501             : decomposition and N*1 vectors x and b. This is  "slow-but-robust"  version
    1502             : of  the  complex  linear  solver  with  additional  features   which   add
    1503             : significant performance overhead. Faster version  is  CMatrixLUSolveFast()
    1504             : function.
    1505             : 
    1506             : Algorithm features:
    1507             : * automatic detection of degenerate cases
    1508             : * O(N^2) complexity
    1509             : * condition number estimation
    1510             : 
    1511             : No iterative refinement is provided because exact form of original matrix
    1512             : is not known to subroutine. Use CMatrixSolve or CMatrixMixedSolve  if  you
    1513             : need iterative refinement.
    1514             : 
    1515             : IMPORTANT: ! this function is NOT the most efficient linear solver provided
    1516             :            ! by ALGLIB. It estimates condition  number  of  linear system,
    1517             :            ! which results in 10-15x  performance  penalty  when  compared
    1518             :            ! with "fast" version which just calls triangular solver.
    1519             :            !
    1520             :            ! This performance penalty is insignificant  when compared with
    1521             :            ! cost of large LU decomposition.  However,  if you  call  this
    1522             :            ! function many times for the same  left  side,  this  overhead
    1523             :            ! BECOMES significant. It  also  becomes significant for small-
    1524             :            ! scale problems.
    1525             :            !
    1526             :            ! In such cases we strongly recommend you to use faster solver,
    1527             :            ! CMatrixLUSolveFast() function.
    1528             : 
    1529             : INPUT PARAMETERS
    1530             :     LUA     -   array[0..N-1,0..N-1], LU decomposition, CMatrixLU result
    1531             :     P       -   array[0..N-1], pivots array, CMatrixLU result
    1532             :     N       -   size of A
    1533             :     B       -   array[0..N-1], right part
    1534             : 
    1535             : OUTPUT PARAMETERS
    1536             :     Info    -   return code:
    1537             :                 * -3    matrix is very badly conditioned or exactly singular.
    1538             :                 * -1    N<=0 was passed
    1539             :                 *  1    task is solved (but matrix A may be ill-conditioned,
    1540             :                         check R1/RInf parameters for condition numbers).
    1541             :     Rep     -   additional report, following fields are set:
    1542             :                 * rep.r1    condition number in 1-norm
    1543             :                 * rep.rinf  condition number in inf-norm
    1544             :     X       -   array[N], it contains:
    1545             :                 * info>0    =>  solution
    1546             :                 * info=-3   =>  filled by zeros
    1547             : 
    1548             :   -- ALGLIB --
    1549             :      Copyright 27.01.2010 by Bochkanov Sergey
    1550             : *************************************************************************/
    1551           0 : void cmatrixlusolve(const complex_2d_array &lua, const integer_1d_array &p, const ae_int_t n, const complex_1d_array &b, ae_int_t &info, densesolverreport &rep, complex_1d_array &x, const xparams _xparams)
    1552             : {
    1553             :     jmp_buf _break_jump;
    1554             :     alglib_impl::ae_state _alglib_env_state;
    1555           0 :     alglib_impl::ae_state_init(&_alglib_env_state);
    1556           0 :     if( setjmp(_break_jump) )
    1557             :     {
    1558             : #if !defined(AE_NO_EXCEPTIONS)
    1559           0 :         _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
    1560             : #else
    1561             :         _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
    1562             :         return;
    1563             : #endif
    1564             :     }
    1565           0 :     ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
    1566           0 :     if( _xparams.flags!=0x0 )
    1567           0 :         ae_state_set_flags(&_alglib_env_state, _xparams.flags);
    1568           0 :     alglib_impl::cmatrixlusolve(const_cast<alglib_impl::ae_matrix*>(lua.c_ptr()), const_cast<alglib_impl::ae_vector*>(p.c_ptr()), n, const_cast<alglib_impl::ae_vector*>(b.c_ptr()), &info, const_cast<alglib_impl::densesolverreport*>(rep.c_ptr()), const_cast<alglib_impl::ae_vector*>(x.c_ptr()), &_alglib_env_state);
    1569           0 :     alglib_impl::ae_state_clear(&_alglib_env_state);
    1570           0 :     return;
    1571             : }
    1572             : 
    1573             : /*************************************************************************
    1574             : Complex dense linear solver for A*x=b with N*N complex A given by  its  LU
    1575             : decomposition and N*1 vectors x and b. This is  fast  lightweight  version
    1576             : of solver, which is significantly faster than CMatrixLUSolve(),  but  does
    1577             : not provide additional information (like condition numbers).
    1578             : 
    1579             : Algorithm features:
    1580             : * O(N^2) complexity
    1581             : * no additional time-consuming features, just triangular solver
    1582             : 
    1583             : INPUT PARAMETERS
    1584             :     LUA     -   array[0..N-1,0..N-1], LU decomposition, CMatrixLU result
    1585             :     P       -   array[0..N-1], pivots array, CMatrixLU result
    1586             :     N       -   size of A
    1587             :     B       -   array[0..N-1], right part
    1588             : 
    1589             : OUTPUT PARAMETERS
    1590             :     Info    -   return code:
    1591             :                 * -3    matrix is exactly singular (ill conditioned matrices
    1592             :                         are not recognized).
    1593             :                 * -1    N<=0 was passed
    1594             :                 *  1    task is solved
    1595             :     B       -   array[N]:
    1596             :                 * info>0    =>  overwritten by solution
    1597             :                 * info=-3   =>  filled by zeros
    1598             : 
    1599             : NOTE: unlike  CMatrixLUSolve(),  this   function   does   NOT   check  for
    1600             :       near-degeneracy of input matrix. It  checks  for  EXACT  degeneracy,
    1601             :       because this check is easy to do. However,  very  badly  conditioned
    1602             :       matrices may went unnoticed.
    1603             : 
    1604             : 
    1605             :   -- ALGLIB --
    1606             :      Copyright 27.01.2010 by Bochkanov Sergey
    1607             : *************************************************************************/
    1608           0 : void cmatrixlusolvefast(const complex_2d_array &lua, const integer_1d_array &p, const ae_int_t n, const complex_1d_array &b, ae_int_t &info, const xparams _xparams)
    1609             : {
    1610             :     jmp_buf _break_jump;
    1611             :     alglib_impl::ae_state _alglib_env_state;
    1612           0 :     alglib_impl::ae_state_init(&_alglib_env_state);
    1613           0 :     if( setjmp(_break_jump) )
    1614             :     {
    1615             : #if !defined(AE_NO_EXCEPTIONS)
    1616           0 :         _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
    1617             : #else
    1618             :         _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
    1619             :         return;
    1620             : #endif
    1621             :     }
    1622           0 :     ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
    1623           0 :     if( _xparams.flags!=0x0 )
    1624           0 :         ae_state_set_flags(&_alglib_env_state, _xparams.flags);
    1625           0 :     alglib_impl::cmatrixlusolvefast(const_cast<alglib_impl::ae_matrix*>(lua.c_ptr()), const_cast<alglib_impl::ae_vector*>(p.c_ptr()), n, const_cast<alglib_impl::ae_vector*>(b.c_ptr()), &info, &_alglib_env_state);
    1626           0 :     alglib_impl::ae_state_clear(&_alglib_env_state);
    1627           0 :     return;
    1628             : }
    1629             : 
    1630             : /*************************************************************************
    1631             : Dense solver. Same as RMatrixMixedSolveM(), but for complex matrices.
    1632             : 
    1633             : Algorithm features:
    1634             : * automatic detection of degenerate cases
    1635             : * condition number estimation
    1636             : * iterative refinement
    1637             : * O(M*N^2) complexity
    1638             : 
    1639             : INPUT PARAMETERS
    1640             :     A       -   array[0..N-1,0..N-1], system matrix
    1641             :     LUA     -   array[0..N-1,0..N-1], LU decomposition, CMatrixLU result
    1642             :     P       -   array[0..N-1], pivots array, CMatrixLU result
    1643             :     N       -   size of A
    1644             :     B       -   array[0..N-1,0..M-1], right part
    1645             :     M       -   right part size
    1646             : 
    1647             : OUTPUT PARAMETERS
    1648             :     Info    -   return code:
    1649             :                 * -3    matrix is very badly conditioned or exactly singular.
    1650             :                 * -1    N<=0 was passed
    1651             :                 *  1    task is solved (but matrix A may be ill-conditioned,
    1652             :                         check R1/RInf parameters for condition numbers).
    1653             :     Rep     -   additional report, following fields are set:
    1654             :                 * rep.r1    condition number in 1-norm
    1655             :                 * rep.rinf  condition number in inf-norm
    1656             :     X       -   array[N,M], it contains:
    1657             :                 * info>0    =>  solution
    1658             :                 * info=-3   =>  filled by zeros
    1659             : 
    1660             :   -- ALGLIB --
    1661             :      Copyright 27.01.2010 by Bochkanov Sergey
    1662             : *************************************************************************/
    1663           0 : void cmatrixmixedsolvem(const complex_2d_array &a, const complex_2d_array &lua, const integer_1d_array &p, const ae_int_t n, const complex_2d_array &b, const ae_int_t m, ae_int_t &info, densesolverreport &rep, complex_2d_array &x, const xparams _xparams)
    1664             : {
    1665             :     jmp_buf _break_jump;
    1666             :     alglib_impl::ae_state _alglib_env_state;
    1667           0 :     alglib_impl::ae_state_init(&_alglib_env_state);
    1668           0 :     if( setjmp(_break_jump) )
    1669             :     {
    1670             : #if !defined(AE_NO_EXCEPTIONS)
    1671           0 :         _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
    1672             : #else
    1673             :         _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
    1674             :         return;
    1675             : #endif
    1676             :     }
    1677           0 :     ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
    1678           0 :     if( _xparams.flags!=0x0 )
    1679           0 :         ae_state_set_flags(&_alglib_env_state, _xparams.flags);
    1680           0 :     alglib_impl::cmatrixmixedsolvem(const_cast<alglib_impl::ae_matrix*>(a.c_ptr()), const_cast<alglib_impl::ae_matrix*>(lua.c_ptr()), const_cast<alglib_impl::ae_vector*>(p.c_ptr()), n, const_cast<alglib_impl::ae_matrix*>(b.c_ptr()), m, &info, const_cast<alglib_impl::densesolverreport*>(rep.c_ptr()), const_cast<alglib_impl::ae_matrix*>(x.c_ptr()), &_alglib_env_state);
    1681           0 :     alglib_impl::ae_state_clear(&_alglib_env_state);
    1682           0 :     return;
    1683             : }
    1684             : 
    1685             : /*************************************************************************
    1686             : Dense solver. Same as RMatrixMixedSolve(), but for complex matrices.
    1687             : 
    1688             : Algorithm features:
    1689             : * automatic detection of degenerate cases
    1690             : * condition number estimation
    1691             : * iterative refinement
    1692             : * O(N^2) complexity
    1693             : 
    1694             : INPUT PARAMETERS
    1695             :     A       -   array[0..N-1,0..N-1], system matrix
    1696             :     LUA     -   array[0..N-1,0..N-1], LU decomposition, CMatrixLU result
    1697             :     P       -   array[0..N-1], pivots array, CMatrixLU result
    1698             :     N       -   size of A
    1699             :     B       -   array[0..N-1], right part
    1700             : 
    1701             : OUTPUT PARAMETERS
    1702             :     Info    -   return code:
    1703             :                 * -3    matrix is very badly conditioned or exactly singular.
    1704             :                 * -1    N<=0 was passed
    1705             :                 *  1    task is solved (but matrix A may be ill-conditioned,
    1706             :                         check R1/RInf parameters for condition numbers).
    1707             :     Rep     -   additional report, following fields are set:
    1708             :                 * rep.r1    condition number in 1-norm
    1709             :                 * rep.rinf  condition number in inf-norm
    1710             :     X       -   array[N], it contains:
    1711             :                 * info>0    =>  solution
    1712             :                 * info=-3   =>  filled by zeros
    1713             : 
    1714             :   -- ALGLIB --
    1715             :      Copyright 27.01.2010 by Bochkanov Sergey
    1716             : *************************************************************************/
    1717           0 : void cmatrixmixedsolve(const complex_2d_array &a, const complex_2d_array &lua, const integer_1d_array &p, const ae_int_t n, const complex_1d_array &b, ae_int_t &info, densesolverreport &rep, complex_1d_array &x, const xparams _xparams)
    1718             : {
    1719             :     jmp_buf _break_jump;
    1720             :     alglib_impl::ae_state _alglib_env_state;
    1721           0 :     alglib_impl::ae_state_init(&_alglib_env_state);
    1722           0 :     if( setjmp(_break_jump) )
    1723             :     {
    1724             : #if !defined(AE_NO_EXCEPTIONS)
    1725           0 :         _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
    1726             : #else
    1727             :         _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
    1728             :         return;
    1729             : #endif
    1730             :     }
    1731           0 :     ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
    1732           0 :     if( _xparams.flags!=0x0 )
    1733           0 :         ae_state_set_flags(&_alglib_env_state, _xparams.flags);
    1734           0 :     alglib_impl::cmatrixmixedsolve(const_cast<alglib_impl::ae_matrix*>(a.c_ptr()), const_cast<alglib_impl::ae_matrix*>(lua.c_ptr()), const_cast<alglib_impl::ae_vector*>(p.c_ptr()), n, const_cast<alglib_impl::ae_vector*>(b.c_ptr()), &info, const_cast<alglib_impl::densesolverreport*>(rep.c_ptr()), const_cast<alglib_impl::ae_vector*>(x.c_ptr()), &_alglib_env_state);
    1735           0 :     alglib_impl::ae_state_clear(&_alglib_env_state);
    1736           0 :     return;
    1737             : }
    1738             : 
    1739             : /*************************************************************************
    1740             : Dense solver for A*X=B with N*N symmetric positive definite matrix A,  and
    1741             : N*M vectors X and B. It is "slow-but-feature-rich" version of the solver.
    1742             : 
    1743             : Algorithm features:
    1744             : * automatic detection of degenerate cases
    1745             : * condition number estimation
    1746             : * O(N^3+M*N^2) complexity
    1747             : * matrix is represented by its upper or lower triangle
    1748             : 
    1749             : No iterative refinement is provided because such partial representation of
    1750             : matrix does not allow efficient calculation of extra-precise  matrix-vector
    1751             : products for large matrices. Use RMatrixSolve or RMatrixMixedSolve  if  you
    1752             : need iterative refinement.
    1753             : 
    1754             : IMPORTANT: ! this function is NOT the most efficient linear solver provided
    1755             :            ! by ALGLIB. It estimates condition  number  of  linear system,
    1756             :            ! which  results  in  significant   performance   penalty  when
    1757             :            ! compared with "fast" version  which  just  performs  Cholesky
    1758             :            ! decomposition and calls triangular solver.
    1759             :            !
    1760             :            ! This  performance  penalty  is  especially  visible  in   the
    1761             :            ! multithreaded mode, because both condition number  estimation
    1762             :            ! and   iterative    refinement   are   inherently   sequential
    1763             :            ! calculations.
    1764             :            !
    1765             :            ! Thus, if you need high performance and if you are pretty sure
    1766             :            ! that your system is well conditioned, we  strongly  recommend
    1767             :            ! you to use faster solver, SPDMatrixSolveMFast() function.
    1768             : 
    1769             :   ! COMMERCIAL EDITION OF ALGLIB:
    1770             :   !
    1771             :   ! Commercial Edition of ALGLIB includes following important improvements
    1772             :   ! of this function:
    1773             :   ! * high-performance native backend with same C# interface (C# version)
    1774             :   ! * multithreading support (C++ and C# versions)
    1775             :   ! * hardware vendor (Intel) implementations of linear algebra primitives
    1776             :   !   (C++ and C# versions, x86/x64 platform)
    1777             :   !
    1778             :   ! We recommend you to read 'Working with commercial version' section  of
    1779             :   ! ALGLIB Reference Manual in order to find out how to  use  performance-
    1780             :   ! related features provided by commercial edition of ALGLIB.
    1781             : 
    1782             : INPUT PARAMETERS
    1783             :     A       -   array[0..N-1,0..N-1], system matrix
    1784             :     N       -   size of A
    1785             :     IsUpper -   what half of A is provided
    1786             :     B       -   array[0..N-1,0..M-1], right part
    1787             :     M       -   right part size
    1788             : 
    1789             : OUTPUT PARAMETERS
    1790             :     Info    -   return code:
    1791             :                 * -3    matrix is very badly conditioned or non-SPD.
    1792             :                 * -1    N<=0 was passed
    1793             :                 *  1    task is solved (but matrix A may be ill-conditioned,
    1794             :                         check R1/RInf parameters for condition numbers).
    1795             :     Rep     -   additional report, following fields are set:
    1796             :                 * rep.r1    condition number in 1-norm
    1797             :                 * rep.rinf  condition number in inf-norm
    1798             :     X       -   array[N,M], it contains:
    1799             :                 * info>0    =>  solution
    1800             :                 * info=-3   =>  filled by zeros
    1801             : 
    1802             :   -- ALGLIB --
    1803             :      Copyright 27.01.2010 by Bochkanov Sergey
    1804             : *************************************************************************/
    1805           0 : void spdmatrixsolvem(const real_2d_array &a, const ae_int_t n, const bool isupper, const real_2d_array &b, const ae_int_t m, ae_int_t &info, densesolverreport &rep, real_2d_array &x, const xparams _xparams)
    1806             : {
    1807             :     jmp_buf _break_jump;
    1808             :     alglib_impl::ae_state _alglib_env_state;
    1809           0 :     alglib_impl::ae_state_init(&_alglib_env_state);
    1810           0 :     if( setjmp(_break_jump) )
    1811             :     {
    1812             : #if !defined(AE_NO_EXCEPTIONS)
    1813           0 :         _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
    1814             : #else
    1815             :         _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
    1816             :         return;
    1817             : #endif
    1818             :     }
    1819           0 :     ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
    1820           0 :     if( _xparams.flags!=0x0 )
    1821           0 :         ae_state_set_flags(&_alglib_env_state, _xparams.flags);
    1822           0 :     alglib_impl::spdmatrixsolvem(const_cast<alglib_impl::ae_matrix*>(a.c_ptr()), n, isupper, const_cast<alglib_impl::ae_matrix*>(b.c_ptr()), m, &info, const_cast<alglib_impl::densesolverreport*>(rep.c_ptr()), const_cast<alglib_impl::ae_matrix*>(x.c_ptr()), &_alglib_env_state);
    1823           0 :     alglib_impl::ae_state_clear(&_alglib_env_state);
    1824           0 :     return;
    1825             : }
    1826             : 
    1827             : /*************************************************************************
    1828             : Dense solver for A*X=B with N*N symmetric positive definite matrix A,  and
    1829             : N*M vectors X and B. It is "fast-but-lightweight" version of the solver.
    1830             : 
    1831             : Algorithm features:
    1832             : * O(N^3+M*N^2) complexity
    1833             : * matrix is represented by its upper or lower triangle
    1834             : * no additional time consuming features
    1835             : 
    1836             :   ! COMMERCIAL EDITION OF ALGLIB:
    1837             :   !
    1838             :   ! Commercial Edition of ALGLIB includes following important improvements
    1839             :   ! of this function:
    1840             :   ! * high-performance native backend with same C# interface (C# version)
    1841             :   ! * multithreading support (C++ and C# versions)
    1842             :   ! * hardware vendor (Intel) implementations of linear algebra primitives
    1843             :   !   (C++ and C# versions, x86/x64 platform)
    1844             :   !
    1845             :   ! We recommend you to read 'Working with commercial version' section  of
    1846             :   ! ALGLIB Reference Manual in order to find out how to  use  performance-
    1847             :   ! related features provided by commercial edition of ALGLIB.
    1848             : 
    1849             : INPUT PARAMETERS
    1850             :     A       -   array[0..N-1,0..N-1], system matrix
    1851             :     N       -   size of A
    1852             :     IsUpper -   what half of A is provided
    1853             :     B       -   array[0..N-1,0..M-1], right part
    1854             :     M       -   right part size
    1855             : 
    1856             : OUTPUT PARAMETERS
    1857             :     Info    -   return code:
    1858             :                 * -3    A is is exactly singular
    1859             :                 * -1    N<=0 was passed
    1860             :                 *  1    task was solved
    1861             :     B       -   array[N,M], it contains:
    1862             :                 * info>0    =>  solution
    1863             :                 * info=-3   =>  filled by zeros
    1864             : 
    1865             :   -- ALGLIB --
    1866             :      Copyright 17.03.2015 by Bochkanov Sergey
    1867             : *************************************************************************/
    1868           0 : void spdmatrixsolvemfast(const real_2d_array &a, const ae_int_t n, const bool isupper, const real_2d_array &b, const ae_int_t m, ae_int_t &info, const xparams _xparams)
    1869             : {
    1870             :     jmp_buf _break_jump;
    1871             :     alglib_impl::ae_state _alglib_env_state;
    1872           0 :     alglib_impl::ae_state_init(&_alglib_env_state);
    1873           0 :     if( setjmp(_break_jump) )
    1874             :     {
    1875             : #if !defined(AE_NO_EXCEPTIONS)
    1876           0 :         _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
    1877             : #else
    1878             :         _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
    1879             :         return;
    1880             : #endif
    1881             :     }
    1882           0 :     ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
    1883           0 :     if( _xparams.flags!=0x0 )
    1884           0 :         ae_state_set_flags(&_alglib_env_state, _xparams.flags);
    1885           0 :     alglib_impl::spdmatrixsolvemfast(const_cast<alglib_impl::ae_matrix*>(a.c_ptr()), n, isupper, const_cast<alglib_impl::ae_matrix*>(b.c_ptr()), m, &info, &_alglib_env_state);
    1886           0 :     alglib_impl::ae_state_clear(&_alglib_env_state);
    1887           0 :     return;
    1888             : }
    1889             : 
    1890             : /*************************************************************************
    1891             : Dense linear solver for A*x=b with N*N real  symmetric  positive  definite
    1892             : matrix A,  N*1 vectors x and b.  "Slow-but-feature-rich"  version  of  the
    1893             : solver.
    1894             : 
    1895             : Algorithm features:
    1896             : * automatic detection of degenerate cases
    1897             : * condition number estimation
    1898             : * O(N^3) complexity
    1899             : * matrix is represented by its upper or lower triangle
    1900             : 
    1901             : No iterative refinement is provided because such partial representation of
    1902             : matrix does not allow efficient calculation of extra-precise  matrix-vector
    1903             : products for large matrices. Use RMatrixSolve or RMatrixMixedSolve  if  you
    1904             : need iterative refinement.
    1905             : 
    1906             : IMPORTANT: ! this function is NOT the most efficient linear solver provided
    1907             :            ! by ALGLIB. It estimates condition  number  of  linear system,
    1908             :            ! which  results  in  significant   performance   penalty  when
    1909             :            ! compared with "fast" version  which  just  performs  Cholesky
    1910             :            ! decomposition and calls triangular solver.
    1911             :            !
    1912             :            ! This  performance  penalty  is  especially  visible  in   the
    1913             :            ! multithreaded mode, because both condition number  estimation
    1914             :            ! and   iterative    refinement   are   inherently   sequential
    1915             :            ! calculations.
    1916             :            !
    1917             :            ! Thus, if you need high performance and if you are pretty sure
    1918             :            ! that your system is well conditioned, we  strongly  recommend
    1919             :            ! you to use faster solver, SPDMatrixSolveFast() function.
    1920             : 
    1921             :   ! COMMERCIAL EDITION OF ALGLIB:
    1922             :   !
    1923             :   ! Commercial Edition of ALGLIB includes following important improvements
    1924             :   ! of this function:
    1925             :   ! * high-performance native backend with same C# interface (C# version)
    1926             :   ! * multithreading support (C++ and C# versions)
    1927             :   ! * hardware vendor (Intel) implementations of linear algebra primitives
    1928             :   !   (C++ and C# versions, x86/x64 platform)
    1929             :   !
    1930             :   ! We recommend you to read 'Working with commercial version' section  of
    1931             :   ! ALGLIB Reference Manual in order to find out how to  use  performance-
    1932             :   ! related features provided by commercial edition of ALGLIB.
    1933             : 
    1934             : INPUT PARAMETERS
    1935             :     A       -   array[0..N-1,0..N-1], system matrix
    1936             :     N       -   size of A
    1937             :     IsUpper -   what half of A is provided
    1938             :     B       -   array[0..N-1], right part
    1939             : 
    1940             : OUTPUT PARAMETERS
    1941             :     Info    -   return code:
    1942             :                 * -3    matrix is very badly conditioned or non-SPD.
    1943             :                 * -1    N<=0 was passed
    1944             :                 *  1    task is solved (but matrix A may be ill-conditioned,
    1945             :                         check R1/RInf parameters for condition numbers).
    1946             :     Rep     -   additional report, following fields are set:
    1947             :                 * rep.r1    condition number in 1-norm
    1948             :                 * rep.rinf  condition number in inf-norm
    1949             :     X       -   array[N], it contains:
    1950             :                 * info>0    =>  solution
    1951             :                 * info=-3   =>  filled by zeros
    1952             : 
    1953             :   -- ALGLIB --
    1954             :      Copyright 27.01.2010 by Bochkanov Sergey
    1955             : *************************************************************************/
    1956           0 : void spdmatrixsolve(const real_2d_array &a, const ae_int_t n, const bool isupper, const real_1d_array &b, ae_int_t &info, densesolverreport &rep, real_1d_array &x, const xparams _xparams)
    1957             : {
    1958             :     jmp_buf _break_jump;
    1959             :     alglib_impl::ae_state _alglib_env_state;
    1960           0 :     alglib_impl::ae_state_init(&_alglib_env_state);
    1961           0 :     if( setjmp(_break_jump) )
    1962             :     {
    1963             : #if !defined(AE_NO_EXCEPTIONS)
    1964           0 :         _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
    1965             : #else
    1966             :         _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
    1967             :         return;
    1968             : #endif
    1969             :     }
    1970           0 :     ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
    1971           0 :     if( _xparams.flags!=0x0 )
    1972           0 :         ae_state_set_flags(&_alglib_env_state, _xparams.flags);
    1973           0 :     alglib_impl::spdmatrixsolve(const_cast<alglib_impl::ae_matrix*>(a.c_ptr()), n, isupper, const_cast<alglib_impl::ae_vector*>(b.c_ptr()), &info, const_cast<alglib_impl::densesolverreport*>(rep.c_ptr()), const_cast<alglib_impl::ae_vector*>(x.c_ptr()), &_alglib_env_state);
    1974           0 :     alglib_impl::ae_state_clear(&_alglib_env_state);
    1975           0 :     return;
    1976             : }
    1977             : 
    1978             : /*************************************************************************
    1979             : Dense linear solver for A*x=b with N*N real  symmetric  positive  definite
    1980             : matrix A,  N*1 vectors x and  b.  "Fast-but-lightweight"  version  of  the
    1981             : solver.
    1982             : 
    1983             : Algorithm features:
    1984             : * O(N^3) complexity
    1985             : * matrix is represented by its upper or lower triangle
    1986             : * no additional time consuming features like condition number estimation
    1987             : 
    1988             :   ! COMMERCIAL EDITION OF ALGLIB:
    1989             :   !
    1990             :   ! Commercial Edition of ALGLIB includes following important improvements
    1991             :   ! of this function:
    1992             :   ! * high-performance native backend with same C# interface (C# version)
    1993             :   ! * multithreading support (C++ and C# versions)
    1994             :   ! * hardware vendor (Intel) implementations of linear algebra primitives
    1995             :   !   (C++ and C# versions, x86/x64 platform)
    1996             :   !
    1997             :   ! We recommend you to read 'Working with commercial version' section  of
    1998             :   ! ALGLIB Reference Manual in order to find out how to  use  performance-
    1999             :   ! related features provided by commercial edition of ALGLIB.
    2000             : 
    2001             : INPUT PARAMETERS
    2002             :     A       -   array[0..N-1,0..N-1], system matrix
    2003             :     N       -   size of A
    2004             :     IsUpper -   what half of A is provided
    2005             :     B       -   array[0..N-1], right part
    2006             : 
    2007             : OUTPUT PARAMETERS
    2008             :     Info    -   return code:
    2009             :                 * -3    A is is exactly singular or non-SPD
    2010             :                 * -1    N<=0 was passed
    2011             :                 *  1    task was solved
    2012             :     B       -   array[N], it contains:
    2013             :                 * info>0    =>  solution
    2014             :                 * info=-3   =>  filled by zeros
    2015             : 
    2016             :   -- ALGLIB --
    2017             :      Copyright 17.03.2015 by Bochkanov Sergey
    2018             : *************************************************************************/
    2019           0 : void spdmatrixsolvefast(const real_2d_array &a, const ae_int_t n, const bool isupper, const real_1d_array &b, ae_int_t &info, const xparams _xparams)
    2020             : {
    2021             :     jmp_buf _break_jump;
    2022             :     alglib_impl::ae_state _alglib_env_state;
    2023           0 :     alglib_impl::ae_state_init(&_alglib_env_state);
    2024           0 :     if( setjmp(_break_jump) )
    2025             :     {
    2026             : #if !defined(AE_NO_EXCEPTIONS)
    2027           0 :         _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
    2028             : #else
    2029             :         _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
    2030             :         return;
    2031             : #endif
    2032             :     }
    2033           0 :     ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
    2034           0 :     if( _xparams.flags!=0x0 )
    2035           0 :         ae_state_set_flags(&_alglib_env_state, _xparams.flags);
    2036           0 :     alglib_impl::spdmatrixsolvefast(const_cast<alglib_impl::ae_matrix*>(a.c_ptr()), n, isupper, const_cast<alglib_impl::ae_vector*>(b.c_ptr()), &info, &_alglib_env_state);
    2037           0 :     alglib_impl::ae_state_clear(&_alglib_env_state);
    2038           0 :     return;
    2039             : }
    2040             : 
    2041             : /*************************************************************************
    2042             : Dense solver for A*X=B with N*N symmetric positive definite matrix A given
    2043             : by its Cholesky decomposition, and N*M vectors X and B. It  is  "slow-but-
    2044             : feature-rich" version of the solver which estimates  condition  number  of
    2045             : the system.
    2046             : 
    2047             : Algorithm features:
    2048             : * automatic detection of degenerate cases
    2049             : * O(M*N^2) complexity
    2050             : * condition number estimation
    2051             : * matrix is represented by its upper or lower triangle
    2052             : 
    2053             : No iterative refinement is provided because such partial representation of
    2054             : matrix does not allow efficient calculation of extra-precise  matrix-vector
    2055             : products for large matrices. Use RMatrixSolve or RMatrixMixedSolve  if  you
    2056             : need iterative refinement.
    2057             : 
    2058             : IMPORTANT: ! this function is NOT the most efficient linear solver provided
    2059             :            ! by ALGLIB. It estimates condition  number  of  linear system,
    2060             :            ! which  results  in  significant  performance   penalty   when
    2061             :            ! compared with "fast"  version  which  just  calls  triangular
    2062             :            ! solver. Amount of  overhead  introduced  depends  on  M  (the
    2063             :            ! larger - the more efficient).
    2064             :            !
    2065             :            ! This performance penalty is insignificant  when compared with
    2066             :            ! cost of large LU decomposition.  However,  if you  call  this
    2067             :            ! function many times for the same  left  side,  this  overhead
    2068             :            ! BECOMES significant. It  also  becomes significant for small-
    2069             :            ! scale problems (N<50).
    2070             :            !
    2071             :            ! In such cases we strongly recommend you to use faster solver,
    2072             :            ! SPDMatrixCholeskySolveMFast() function.
    2073             : 
    2074             : INPUT PARAMETERS
    2075             :     CHA     -   array[0..N-1,0..N-1], Cholesky decomposition,
    2076             :                 SPDMatrixCholesky result
    2077             :     N       -   size of CHA
    2078             :     IsUpper -   what half of CHA is provided
    2079             :     B       -   array[0..N-1,0..M-1], right part
    2080             :     M       -   right part size
    2081             : 
    2082             : OUTPUT PARAMETERS
    2083             :     Info    -   return code:
    2084             :                 * -3    A is is exactly singular or badly conditioned
    2085             :                         X is filled by zeros in such cases.
    2086             :                 * -1    N<=0 was passed
    2087             :                 *  1    task was solved
    2088             :     Rep     -   additional report, following fields are set:
    2089             :                 * rep.r1    condition number in 1-norm
    2090             :                 * rep.rinf  condition number in inf-norm
    2091             :     X       -   array[N]:
    2092             :                 * for info>0 contains solution
    2093             :                 * for info=-3 filled by zeros
    2094             : 
    2095             :   -- ALGLIB --
    2096             :      Copyright 27.01.2010 by Bochkanov Sergey
    2097             : *************************************************************************/
    2098           0 : void spdmatrixcholeskysolvem(const real_2d_array &cha, const ae_int_t n, const bool isupper, const real_2d_array &b, const ae_int_t m, ae_int_t &info, densesolverreport &rep, real_2d_array &x, const xparams _xparams)
    2099             : {
    2100             :     jmp_buf _break_jump;
    2101             :     alglib_impl::ae_state _alglib_env_state;
    2102           0 :     alglib_impl::ae_state_init(&_alglib_env_state);
    2103           0 :     if( setjmp(_break_jump) )
    2104             :     {
    2105             : #if !defined(AE_NO_EXCEPTIONS)
    2106           0 :         _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
    2107             : #else
    2108             :         _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
    2109             :         return;
    2110             : #endif
    2111             :     }
    2112           0 :     ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
    2113           0 :     if( _xparams.flags!=0x0 )
    2114           0 :         ae_state_set_flags(&_alglib_env_state, _xparams.flags);
    2115           0 :     alglib_impl::spdmatrixcholeskysolvem(const_cast<alglib_impl::ae_matrix*>(cha.c_ptr()), n, isupper, const_cast<alglib_impl::ae_matrix*>(b.c_ptr()), m, &info, const_cast<alglib_impl::densesolverreport*>(rep.c_ptr()), const_cast<alglib_impl::ae_matrix*>(x.c_ptr()), &_alglib_env_state);
    2116           0 :     alglib_impl::ae_state_clear(&_alglib_env_state);
    2117           0 :     return;
    2118             : }
    2119             : 
    2120             : /*************************************************************************
    2121             : Dense solver for A*X=B with N*N symmetric positive definite matrix A given
    2122             : by its Cholesky decomposition, and N*M vectors X and B. It  is  "fast-but-
    2123             : lightweight" version of  the  solver  which  just  solves  linear  system,
    2124             : without any additional functions.
    2125             : 
    2126             : Algorithm features:
    2127             : * O(M*N^2) complexity
    2128             : * matrix is represented by its upper or lower triangle
    2129             : * no additional functionality
    2130             : 
    2131             : INPUT PARAMETERS
    2132             :     CHA     -   array[N,N], Cholesky decomposition,
    2133             :                 SPDMatrixCholesky result
    2134             :     N       -   size of CHA
    2135             :     IsUpper -   what half of CHA is provided
    2136             :     B       -   array[N,M], right part
    2137             :     M       -   right part size
    2138             : 
    2139             : OUTPUT PARAMETERS
    2140             :     Info    -   return code:
    2141             :                 * -3    A is is exactly singular or badly conditioned
    2142             :                         X is filled by zeros in such cases.
    2143             :                 * -1    N<=0 was passed
    2144             :                 *  1    task was solved
    2145             :     B       -   array[N]:
    2146             :                 * for info>0 overwritten by solution
    2147             :                 * for info=-3 filled by zeros
    2148             : 
    2149             :   -- ALGLIB --
    2150             :      Copyright 18.03.2015 by Bochkanov Sergey
    2151             : *************************************************************************/
    2152           0 : void spdmatrixcholeskysolvemfast(const real_2d_array &cha, const ae_int_t n, const bool isupper, const real_2d_array &b, const ae_int_t m, ae_int_t &info, const xparams _xparams)
    2153             : {
    2154             :     jmp_buf _break_jump;
    2155             :     alglib_impl::ae_state _alglib_env_state;
    2156           0 :     alglib_impl::ae_state_init(&_alglib_env_state);
    2157           0 :     if( setjmp(_break_jump) )
    2158             :     {
    2159             : #if !defined(AE_NO_EXCEPTIONS)
    2160           0 :         _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
    2161             : #else
    2162             :         _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
    2163             :         return;
    2164             : #endif
    2165             :     }
    2166           0 :     ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
    2167           0 :     if( _xparams.flags!=0x0 )
    2168           0 :         ae_state_set_flags(&_alglib_env_state, _xparams.flags);
    2169           0 :     alglib_impl::spdmatrixcholeskysolvemfast(const_cast<alglib_impl::ae_matrix*>(cha.c_ptr()), n, isupper, const_cast<alglib_impl::ae_matrix*>(b.c_ptr()), m, &info, &_alglib_env_state);
    2170           0 :     alglib_impl::ae_state_clear(&_alglib_env_state);
    2171           0 :     return;
    2172             : }
    2173             : 
    2174             : /*************************************************************************
    2175             : Dense solver for A*x=b with N*N symmetric positive definite matrix A given
    2176             : by its Cholesky decomposition, and N*1 real vectors x and b. This is "slow-
    2177             : but-feature-rich"  version  of  the  solver  which,  in  addition  to  the
    2178             : solution, performs condition number estimation.
    2179             : 
    2180             : Algorithm features:
    2181             : * automatic detection of degenerate cases
    2182             : * O(N^2) complexity
    2183             : * condition number estimation
    2184             : * matrix is represented by its upper or lower triangle
    2185             : 
    2186             : No iterative refinement is provided because such partial representation of
    2187             : matrix does not allow efficient calculation of extra-precise  matrix-vector
    2188             : products for large matrices. Use RMatrixSolve or RMatrixMixedSolve  if  you
    2189             : need iterative refinement.
    2190             : 
    2191             : IMPORTANT: ! this function is NOT the most efficient linear solver provided
    2192             :            ! by ALGLIB. It estimates condition  number  of  linear system,
    2193             :            ! which results in 10-15x  performance  penalty  when  compared
    2194             :            ! with "fast" version which just calls triangular solver.
    2195             :            !
    2196             :            ! This performance penalty is insignificant  when compared with
    2197             :            ! cost of large LU decomposition.  However,  if you  call  this
    2198             :            ! function many times for the same  left  side,  this  overhead
    2199             :            ! BECOMES significant. It  also  becomes significant for small-
    2200             :            ! scale problems (N<50).
    2201             :            !
    2202             :            ! In such cases we strongly recommend you to use faster solver,
    2203             :            ! SPDMatrixCholeskySolveFast() function.
    2204             : 
    2205             : INPUT PARAMETERS
    2206             :     CHA     -   array[N,N], Cholesky decomposition,
    2207             :                 SPDMatrixCholesky result
    2208             :     N       -   size of A
    2209             :     IsUpper -   what half of CHA is provided
    2210             :     B       -   array[N], right part
    2211             : 
    2212             : OUTPUT PARAMETERS
    2213             :     Info    -   return code:
    2214             :                 * -3    A is is exactly singular or ill conditioned
    2215             :                         X is filled by zeros in such cases.
    2216             :                 * -1    N<=0 was passed
    2217             :                 *  1    task is solved
    2218             :     Rep     -   additional report, following fields are set:
    2219             :                 * rep.r1    condition number in 1-norm
    2220             :                 * rep.rinf  condition number in inf-norm
    2221             :     X       -   array[N]:
    2222             :                 * for info>0  - solution
    2223             :                 * for info=-3 - filled by zeros
    2224             : 
    2225             :   -- ALGLIB --
    2226             :      Copyright 27.01.2010 by Bochkanov Sergey
    2227             : *************************************************************************/
    2228           0 : void spdmatrixcholeskysolve(const real_2d_array &cha, const ae_int_t n, const bool isupper, const real_1d_array &b, ae_int_t &info, densesolverreport &rep, real_1d_array &x, const xparams _xparams)
    2229             : {
    2230             :     jmp_buf _break_jump;
    2231             :     alglib_impl::ae_state _alglib_env_state;
    2232           0 :     alglib_impl::ae_state_init(&_alglib_env_state);
    2233           0 :     if( setjmp(_break_jump) )
    2234             :     {
    2235             : #if !defined(AE_NO_EXCEPTIONS)
    2236           0 :         _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
    2237             : #else
    2238             :         _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
    2239             :         return;
    2240             : #endif
    2241             :     }
    2242           0 :     ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
    2243           0 :     if( _xparams.flags!=0x0 )
    2244           0 :         ae_state_set_flags(&_alglib_env_state, _xparams.flags);
    2245           0 :     alglib_impl::spdmatrixcholeskysolve(const_cast<alglib_impl::ae_matrix*>(cha.c_ptr()), n, isupper, const_cast<alglib_impl::ae_vector*>(b.c_ptr()), &info, const_cast<alglib_impl::densesolverreport*>(rep.c_ptr()), const_cast<alglib_impl::ae_vector*>(x.c_ptr()), &_alglib_env_state);
    2246           0 :     alglib_impl::ae_state_clear(&_alglib_env_state);
    2247           0 :     return;
    2248             : }
    2249             : 
    2250             : /*************************************************************************
    2251             : Dense solver for A*x=b with N*N symmetric positive definite matrix A given
    2252             : by its Cholesky decomposition, and N*1 real vectors x and b. This is "fast-
    2253             : but-lightweight" version of the solver.
    2254             : 
    2255             : Algorithm features:
    2256             : * O(N^2) complexity
    2257             : * matrix is represented by its upper or lower triangle
    2258             : * no additional features
    2259             : 
    2260             : INPUT PARAMETERS
    2261             :     CHA     -   array[N,N], Cholesky decomposition,
    2262             :                 SPDMatrixCholesky result
    2263             :     N       -   size of A
    2264             :     IsUpper -   what half of CHA is provided
    2265             :     B       -   array[N], right part
    2266             : 
    2267             : OUTPUT PARAMETERS
    2268             :     Info    -   return code:
    2269             :                 * -3    A is is exactly singular or ill conditioned
    2270             :                         X is filled by zeros in such cases.
    2271             :                 * -1    N<=0 was passed
    2272             :                 *  1    task is solved
    2273             :     B       -   array[N]:
    2274             :                 * for info>0  - overwritten by solution
    2275             :                 * for info=-3 - filled by zeros
    2276             : 
    2277             :   -- ALGLIB --
    2278             :      Copyright 27.01.2010 by Bochkanov Sergey
    2279             : *************************************************************************/
    2280           0 : void spdmatrixcholeskysolvefast(const real_2d_array &cha, const ae_int_t n, const bool isupper, const real_1d_array &b, ae_int_t &info, const xparams _xparams)
    2281             : {
    2282             :     jmp_buf _break_jump;
    2283             :     alglib_impl::ae_state _alglib_env_state;
    2284           0 :     alglib_impl::ae_state_init(&_alglib_env_state);
    2285           0 :     if( setjmp(_break_jump) )
    2286             :     {
    2287             : #if !defined(AE_NO_EXCEPTIONS)
    2288           0 :         _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
    2289             : #else
    2290             :         _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
    2291             :         return;
    2292             : #endif
    2293             :     }
    2294           0 :     ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
    2295           0 :     if( _xparams.flags!=0x0 )
    2296           0 :         ae_state_set_flags(&_alglib_env_state, _xparams.flags);
    2297           0 :     alglib_impl::spdmatrixcholeskysolvefast(const_cast<alglib_impl::ae_matrix*>(cha.c_ptr()), n, isupper, const_cast<alglib_impl::ae_vector*>(b.c_ptr()), &info, &_alglib_env_state);
    2298           0 :     alglib_impl::ae_state_clear(&_alglib_env_state);
    2299           0 :     return;
    2300             : }
    2301             : 
    2302             : /*************************************************************************
    2303             : Dense solver for A*X=B, with N*N Hermitian positive definite matrix A  and
    2304             : N*M  complex  matrices  X  and  B.  "Slow-but-feature-rich" version of the
    2305             : solver.
    2306             : 
    2307             : Algorithm features:
    2308             : * automatic detection of degenerate cases
    2309             : * condition number estimation
    2310             : * O(N^3+M*N^2) complexity
    2311             : * matrix is represented by its upper or lower triangle
    2312             : 
    2313             : No iterative refinement is provided because such partial representation of
    2314             : matrix does not allow efficient calculation of extra-precise  matrix-vector
    2315             : products for large matrices. Use RMatrixSolve or RMatrixMixedSolve  if  you
    2316             : need iterative refinement.
    2317             : 
    2318             : IMPORTANT: ! this function is NOT the most efficient linear solver provided
    2319             :            ! by ALGLIB. It estimates condition  number  of  linear system,
    2320             :            ! which  results  in  significant  performance   penalty   when
    2321             :            ! compared with "fast"  version  which  just  calls  triangular
    2322             :            ! solver.
    2323             :            !
    2324             :            ! This performance penalty is especially apparent when you  use
    2325             :            ! ALGLIB parallel capabilities (condition number estimation  is
    2326             :            ! inherently  sequential).  It   also   becomes significant for
    2327             :            ! small-scale problems (N<100).
    2328             :            !
    2329             :            ! In such cases we strongly recommend you to use faster solver,
    2330             :            ! HPDMatrixSolveMFast() function.
    2331             : 
    2332             :   ! COMMERCIAL EDITION OF ALGLIB:
    2333             :   !
    2334             :   ! Commercial Edition of ALGLIB includes following important improvements
    2335             :   ! of this function:
    2336             :   ! * high-performance native backend with same C# interface (C# version)
    2337             :   ! * multithreading support (C++ and C# versions)
    2338             :   ! * hardware vendor (Intel) implementations of linear algebra primitives
    2339             :   !   (C++ and C# versions, x86/x64 platform)
    2340             :   !
    2341             :   ! We recommend you to read 'Working with commercial version' section  of
    2342             :   ! ALGLIB Reference Manual in order to find out how to  use  performance-
    2343             :   ! related features provided by commercial edition of ALGLIB.
    2344             : 
    2345             : INPUT PARAMETERS
    2346             :     A       -   array[0..N-1,0..N-1], system matrix
    2347             :     N       -   size of A
    2348             :     IsUpper -   what half of A is provided
    2349             :     B       -   array[0..N-1,0..M-1], right part
    2350             :     M       -   right part size
    2351             : 
    2352             : OUTPUT PARAMETERS
    2353             :     Info    -   same as in RMatrixSolve.
    2354             :                 Returns -3 for non-HPD matrices.
    2355             :     Rep     -   same as in RMatrixSolve
    2356             :     X       -   same as in RMatrixSolve
    2357             : 
    2358             :   -- ALGLIB --
    2359             :      Copyright 27.01.2010 by Bochkanov Sergey
    2360             : *************************************************************************/
    2361           0 : void hpdmatrixsolvem(const complex_2d_array &a, const ae_int_t n, const bool isupper, const complex_2d_array &b, const ae_int_t m, ae_int_t &info, densesolverreport &rep, complex_2d_array &x, const xparams _xparams)
    2362             : {
    2363             :     jmp_buf _break_jump;
    2364             :     alglib_impl::ae_state _alglib_env_state;
    2365           0 :     alglib_impl::ae_state_init(&_alglib_env_state);
    2366           0 :     if( setjmp(_break_jump) )
    2367             :     {
    2368             : #if !defined(AE_NO_EXCEPTIONS)
    2369           0 :         _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
    2370             : #else
    2371             :         _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
    2372             :         return;
    2373             : #endif
    2374             :     }
    2375           0 :     ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
    2376           0 :     if( _xparams.flags!=0x0 )
    2377           0 :         ae_state_set_flags(&_alglib_env_state, _xparams.flags);
    2378           0 :     alglib_impl::hpdmatrixsolvem(const_cast<alglib_impl::ae_matrix*>(a.c_ptr()), n, isupper, const_cast<alglib_impl::ae_matrix*>(b.c_ptr()), m, &info, const_cast<alglib_impl::densesolverreport*>(rep.c_ptr()), const_cast<alglib_impl::ae_matrix*>(x.c_ptr()), &_alglib_env_state);
    2379           0 :     alglib_impl::ae_state_clear(&_alglib_env_state);
    2380           0 :     return;
    2381             : }
    2382             : 
    2383             : /*************************************************************************
    2384             : Dense solver for A*X=B, with N*N Hermitian positive definite matrix A  and
    2385             : N*M complex matrices X and B. "Fast-but-lightweight" version of the solver.
    2386             : 
    2387             : Algorithm features:
    2388             : * O(N^3+M*N^2) complexity
    2389             : * matrix is represented by its upper or lower triangle
    2390             : * no additional time consuming features like condition number estimation
    2391             : 
    2392             :   ! COMMERCIAL EDITION OF ALGLIB:
    2393             :   !
    2394             :   ! Commercial Edition of ALGLIB includes following important improvements
    2395             :   ! of this function:
    2396             :   ! * high-performance native backend with same C# interface (C# version)
    2397             :   ! * multithreading support (C++ and C# versions)
    2398             :   ! * hardware vendor (Intel) implementations of linear algebra primitives
    2399             :   !   (C++ and C# versions, x86/x64 platform)
    2400             :   !
    2401             :   ! We recommend you to read 'Working with commercial version' section  of
    2402             :   ! ALGLIB Reference Manual in order to find out how to  use  performance-
    2403             :   ! related features provided by commercial edition of ALGLIB.
    2404             : 
    2405             : INPUT PARAMETERS
    2406             :     A       -   array[0..N-1,0..N-1], system matrix
    2407             :     N       -   size of A
    2408             :     IsUpper -   what half of A is provided
    2409             :     B       -   array[0..N-1,0..M-1], right part
    2410             :     M       -   right part size
    2411             : 
    2412             : OUTPUT PARAMETERS
    2413             :     Info    -   return code:
    2414             :                 * -3    A is is exactly  singular or is not positive definite.
    2415             :                         B is filled by zeros in such cases.
    2416             :                 * -1    N<=0 was passed
    2417             :                 *  1    task is solved
    2418             :     B       -   array[0..N-1]:
    2419             :                 * overwritten by solution
    2420             :                 * zeros, if problem was not solved
    2421             : 
    2422             :   -- ALGLIB --
    2423             :      Copyright 17.03.2015 by Bochkanov Sergey
    2424             : *************************************************************************/
    2425           0 : void hpdmatrixsolvemfast(const complex_2d_array &a, const ae_int_t n, const bool isupper, const complex_2d_array &b, const ae_int_t m, ae_int_t &info, const xparams _xparams)
    2426             : {
    2427             :     jmp_buf _break_jump;
    2428             :     alglib_impl::ae_state _alglib_env_state;
    2429           0 :     alglib_impl::ae_state_init(&_alglib_env_state);
    2430           0 :     if( setjmp(_break_jump) )
    2431             :     {
    2432             : #if !defined(AE_NO_EXCEPTIONS)
    2433           0 :         _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
    2434             : #else
    2435             :         _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
    2436             :         return;
    2437             : #endif
    2438             :     }
    2439           0 :     ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
    2440           0 :     if( _xparams.flags!=0x0 )
    2441           0 :         ae_state_set_flags(&_alglib_env_state, _xparams.flags);
    2442           0 :     alglib_impl::hpdmatrixsolvemfast(const_cast<alglib_impl::ae_matrix*>(a.c_ptr()), n, isupper, const_cast<alglib_impl::ae_matrix*>(b.c_ptr()), m, &info, &_alglib_env_state);
    2443           0 :     alglib_impl::ae_state_clear(&_alglib_env_state);
    2444           0 :     return;
    2445             : }
    2446             : 
    2447             : /*************************************************************************
    2448             : Dense solver for A*x=b, with N*N Hermitian positive definite matrix A, and
    2449             : N*1 complex vectors  x  and  b.  "Slow-but-feature-rich"  version  of  the
    2450             : solver.
    2451             : 
    2452             : Algorithm features:
    2453             : * automatic detection of degenerate cases
    2454             : * condition number estimation
    2455             : * O(N^3) complexity
    2456             : * matrix is represented by its upper or lower triangle
    2457             : 
    2458             : No iterative refinement is provided because such partial representation of
    2459             : matrix does not allow efficient calculation of extra-precise  matrix-vector
    2460             : products for large matrices. Use RMatrixSolve or RMatrixMixedSolve  if  you
    2461             : need iterative refinement.
    2462             : 
    2463             : IMPORTANT: ! this function is NOT the most efficient linear solver provided
    2464             :            ! by ALGLIB. It estimates condition  number  of  linear system,
    2465             :            ! which  results  in  significant   performance   penalty  when
    2466             :            ! compared with "fast" version  which  just  performs  Cholesky
    2467             :            ! decomposition and calls triangular solver.
    2468             :            !
    2469             :            ! This  performance  penalty  is  especially  visible  in   the
    2470             :            ! multithreaded mode, because both condition number  estimation
    2471             :            ! and   iterative    refinement   are   inherently   sequential
    2472             :            ! calculations.
    2473             :            !
    2474             :            ! Thus, if you need high performance and if you are pretty sure
    2475             :            ! that your system is well conditioned, we  strongly  recommend
    2476             :            ! you to use faster solver, HPDMatrixSolveFast() function.
    2477             : 
    2478             :   ! COMMERCIAL EDITION OF ALGLIB:
    2479             :   !
    2480             :   ! Commercial Edition of ALGLIB includes following important improvements
    2481             :   ! of this function:
    2482             :   ! * high-performance native backend with same C# interface (C# version)
    2483             :   ! * multithreading support (C++ and C# versions)
    2484             :   ! * hardware vendor (Intel) implementations of linear algebra primitives
    2485             :   !   (C++ and C# versions, x86/x64 platform)
    2486             :   !
    2487             :   ! We recommend you to read 'Working with commercial version' section  of
    2488             :   ! ALGLIB Reference Manual in order to find out how to  use  performance-
    2489             :   ! related features provided by commercial edition of ALGLIB.
    2490             : 
    2491             : INPUT PARAMETERS
    2492             :     A       -   array[0..N-1,0..N-1], system matrix
    2493             :     N       -   size of A
    2494             :     IsUpper -   what half of A is provided
    2495             :     B       -   array[0..N-1], right part
    2496             : 
    2497             : OUTPUT PARAMETERS
    2498             :     Info    -   same as in RMatrixSolve
    2499             :                 Returns -3 for non-HPD matrices.
    2500             :     Rep     -   same as in RMatrixSolve
    2501             :     X       -   same as in RMatrixSolve
    2502             : 
    2503             :   -- ALGLIB --
    2504             :      Copyright 27.01.2010 by Bochkanov Sergey
    2505             : *************************************************************************/
    2506           0 : void hpdmatrixsolve(const complex_2d_array &a, const ae_int_t n, const bool isupper, const complex_1d_array &b, ae_int_t &info, densesolverreport &rep, complex_1d_array &x, const xparams _xparams)
    2507             : {
    2508             :     jmp_buf _break_jump;
    2509             :     alglib_impl::ae_state _alglib_env_state;
    2510           0 :     alglib_impl::ae_state_init(&_alglib_env_state);
    2511           0 :     if( setjmp(_break_jump) )
    2512             :     {
    2513             : #if !defined(AE_NO_EXCEPTIONS)
    2514           0 :         _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
    2515             : #else
    2516             :         _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
    2517             :         return;
    2518             : #endif
    2519             :     }
    2520           0 :     ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
    2521           0 :     if( _xparams.flags!=0x0 )
    2522           0 :         ae_state_set_flags(&_alglib_env_state, _xparams.flags);
    2523           0 :     alglib_impl::hpdmatrixsolve(const_cast<alglib_impl::ae_matrix*>(a.c_ptr()), n, isupper, const_cast<alglib_impl::ae_vector*>(b.c_ptr()), &info, const_cast<alglib_impl::densesolverreport*>(rep.c_ptr()), const_cast<alglib_impl::ae_vector*>(x.c_ptr()), &_alglib_env_state);
    2524           0 :     alglib_impl::ae_state_clear(&_alglib_env_state);
    2525           0 :     return;
    2526             : }
    2527             : 
    2528             : /*************************************************************************
    2529             : Dense solver for A*x=b, with N*N Hermitian positive definite matrix A, and
    2530             : N*1 complex vectors  x  and  b.  "Fast-but-lightweight"  version  of   the
    2531             : solver without additional functions.
    2532             : 
    2533             : Algorithm features:
    2534             : * O(N^3) complexity
    2535             : * matrix is represented by its upper or lower triangle
    2536             : * no additional time consuming functions
    2537             : 
    2538             :   ! COMMERCIAL EDITION OF ALGLIB:
    2539             :   !
    2540             :   ! Commercial Edition of ALGLIB includes following important improvements
    2541             :   ! of this function:
    2542             :   ! * high-performance native backend with same C# interface (C# version)
    2543             :   ! * multithreading support (C++ and C# versions)
    2544             :   ! * hardware vendor (Intel) implementations of linear algebra primitives
    2545             :   !   (C++ and C# versions, x86/x64 platform)
    2546             :   !
    2547             :   ! We recommend you to read 'Working with commercial version' section  of
    2548             :   ! ALGLIB Reference Manual in order to find out how to  use  performance-
    2549             :   ! related features provided by commercial edition of ALGLIB.
    2550             : 
    2551             : INPUT PARAMETERS
    2552             :     A       -   array[0..N-1,0..N-1], system matrix
    2553             :     N       -   size of A
    2554             :     IsUpper -   what half of A is provided
    2555             :     B       -   array[0..N-1], right part
    2556             : 
    2557             : OUTPUT PARAMETERS
    2558             :     Info    -   return code:
    2559             :                 * -3    A is is exactly singular or not positive definite
    2560             :                         X is filled by zeros in such cases.
    2561             :                 * -1    N<=0 was passed
    2562             :                 *  1    task was solved
    2563             :     B       -   array[0..N-1]:
    2564             :                 * overwritten by solution
    2565             :                 * zeros, if A is exactly singular (diagonal of its LU
    2566             :                   decomposition has exact zeros).
    2567             : 
    2568             :   -- ALGLIB --
    2569             :      Copyright 17.03.2015 by Bochkanov Sergey
    2570             : *************************************************************************/
    2571           0 : void hpdmatrixsolvefast(const complex_2d_array &a, const ae_int_t n, const bool isupper, const complex_1d_array &b, ae_int_t &info, const xparams _xparams)
    2572             : {
    2573             :     jmp_buf _break_jump;
    2574             :     alglib_impl::ae_state _alglib_env_state;
    2575           0 :     alglib_impl::ae_state_init(&_alglib_env_state);
    2576           0 :     if( setjmp(_break_jump) )
    2577             :     {
    2578             : #if !defined(AE_NO_EXCEPTIONS)
    2579           0 :         _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
    2580             : #else
    2581             :         _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
    2582             :         return;
    2583             : #endif
    2584             :     }
    2585           0 :     ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
    2586           0 :     if( _xparams.flags!=0x0 )
    2587           0 :         ae_state_set_flags(&_alglib_env_state, _xparams.flags);
    2588           0 :     alglib_impl::hpdmatrixsolvefast(const_cast<alglib_impl::ae_matrix*>(a.c_ptr()), n, isupper, const_cast<alglib_impl::ae_vector*>(b.c_ptr()), &info, &_alglib_env_state);
    2589           0 :     alglib_impl::ae_state_clear(&_alglib_env_state);
    2590           0 :     return;
    2591             : }
    2592             : 
    2593             : /*************************************************************************
    2594             : Dense solver for A*X=B with N*N Hermitian positive definite matrix A given
    2595             : by its Cholesky decomposition and N*M complex matrices X  and  B.  This is
    2596             : "slow-but-feature-rich" version of the solver which, in  addition  to  the
    2597             : solution, estimates condition number of the system.
    2598             : 
    2599             : Algorithm features:
    2600             : * automatic detection of degenerate cases
    2601             : * O(M*N^2) complexity
    2602             : * condition number estimation
    2603             : * matrix is represented by its upper or lower triangle
    2604             : 
    2605             : No iterative refinement is provided because such partial representation of
    2606             : matrix does not allow efficient calculation of extra-precise  matrix-vector
    2607             : products for large matrices. Use RMatrixSolve or RMatrixMixedSolve  if  you
    2608             : need iterative refinement.
    2609             : 
    2610             : IMPORTANT: ! this function is NOT the most efficient linear solver provided
    2611             :            ! by ALGLIB. It estimates condition  number  of  linear system,
    2612             :            ! which  results  in  significant  performance   penalty   when
    2613             :            ! compared with "fast"  version  which  just  calls  triangular
    2614             :            ! solver. Amount of  overhead  introduced  depends  on  M  (the
    2615             :            ! larger - the more efficient).
    2616             :            !
    2617             :            ! This performance penalty is insignificant  when compared with
    2618             :            ! cost of large Cholesky decomposition.  However,  if  you call
    2619             :            ! this  function  many  times  for  the same  left  side,  this
    2620             :            ! overhead BECOMES significant. It  also   becomes  significant
    2621             :            ! for small-scale problems (N<50).
    2622             :            !
    2623             :            ! In such cases we strongly recommend you to use faster solver,
    2624             :            ! HPDMatrixCholeskySolveMFast() function.
    2625             : 
    2626             : 
    2627             : INPUT PARAMETERS
    2628             :     CHA     -   array[N,N], Cholesky decomposition,
    2629             :                 HPDMatrixCholesky result
    2630             :     N       -   size of CHA
    2631             :     IsUpper -   what half of CHA is provided
    2632             :     B       -   array[N,M], right part
    2633             :     M       -   right part size
    2634             : 
    2635             : OUTPUT PARAMETERS:
    2636             :     Info    -   return code:
    2637             :                 * -3    A is singular, or VERY close to singular.
    2638             :                         X is filled by zeros in such cases.
    2639             :                 * -1    N<=0 was passed
    2640             :                 *  1    task was solved
    2641             :     Rep     -   additional report, following fields are set:
    2642             :                 * rep.r1    condition number in 1-norm
    2643             :                 * rep.rinf  condition number in inf-norm
    2644             :     X       -   array[N]:
    2645             :                 * for info>0 contains solution
    2646             :                 * for info=-3 filled by zeros
    2647             : 
    2648             :   -- ALGLIB --
    2649             :      Copyright 27.01.2010 by Bochkanov Sergey
    2650             : *************************************************************************/
    2651           0 : void hpdmatrixcholeskysolvem(const complex_2d_array &cha, const ae_int_t n, const bool isupper, const complex_2d_array &b, const ae_int_t m, ae_int_t &info, densesolverreport &rep, complex_2d_array &x, const xparams _xparams)
    2652             : {
    2653             :     jmp_buf _break_jump;
    2654             :     alglib_impl::ae_state _alglib_env_state;
    2655           0 :     alglib_impl::ae_state_init(&_alglib_env_state);
    2656           0 :     if( setjmp(_break_jump) )
    2657             :     {
    2658             : #if !defined(AE_NO_EXCEPTIONS)
    2659           0 :         _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
    2660             : #else
    2661             :         _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
    2662             :         return;
    2663             : #endif
    2664             :     }
    2665           0 :     ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
    2666           0 :     if( _xparams.flags!=0x0 )
    2667           0 :         ae_state_set_flags(&_alglib_env_state, _xparams.flags);
    2668           0 :     alglib_impl::hpdmatrixcholeskysolvem(const_cast<alglib_impl::ae_matrix*>(cha.c_ptr()), n, isupper, const_cast<alglib_impl::ae_matrix*>(b.c_ptr()), m, &info, const_cast<alglib_impl::densesolverreport*>(rep.c_ptr()), const_cast<alglib_impl::ae_matrix*>(x.c_ptr()), &_alglib_env_state);
    2669           0 :     alglib_impl::ae_state_clear(&_alglib_env_state);
    2670           0 :     return;
    2671             : }
    2672             : 
    2673             : /*************************************************************************
    2674             : Dense solver for A*X=B with N*N Hermitian positive definite matrix A given
    2675             : by its Cholesky decomposition and N*M complex matrices X  and  B.  This is
    2676             : "fast-but-lightweight" version of the solver.
    2677             : 
    2678             : Algorithm features:
    2679             : * O(M*N^2) complexity
    2680             : * matrix is represented by its upper or lower triangle
    2681             : * no additional time-consuming features
    2682             : 
    2683             : INPUT PARAMETERS
    2684             :     CHA     -   array[N,N], Cholesky decomposition,
    2685             :                 HPDMatrixCholesky result
    2686             :     N       -   size of CHA
    2687             :     IsUpper -   what half of CHA is provided
    2688             :     B       -   array[N,M], right part
    2689             :     M       -   right part size
    2690             : 
    2691             : OUTPUT PARAMETERS:
    2692             :     Info    -   return code:
    2693             :                 * -3    A is singular, or VERY close to singular.
    2694             :                         X is filled by zeros in such cases.
    2695             :                 * -1    N<=0 was passed
    2696             :                 *  1    task was solved
    2697             :     B       -   array[N]:
    2698             :                 * for info>0 overwritten by solution
    2699             :                 * for info=-3 filled by zeros
    2700             : 
    2701             :   -- ALGLIB --
    2702             :      Copyright 18.03.2015 by Bochkanov Sergey
    2703             : *************************************************************************/
    2704           0 : void hpdmatrixcholeskysolvemfast(const complex_2d_array &cha, const ae_int_t n, const bool isupper, const complex_2d_array &b, const ae_int_t m, ae_int_t &info, const xparams _xparams)
    2705             : {
    2706             :     jmp_buf _break_jump;
    2707             :     alglib_impl::ae_state _alglib_env_state;
    2708           0 :     alglib_impl::ae_state_init(&_alglib_env_state);
    2709           0 :     if( setjmp(_break_jump) )
    2710             :     {
    2711             : #if !defined(AE_NO_EXCEPTIONS)
    2712           0 :         _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
    2713             : #else
    2714             :         _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
    2715             :         return;
    2716             : #endif
    2717             :     }
    2718           0 :     ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
    2719           0 :     if( _xparams.flags!=0x0 )
    2720           0 :         ae_state_set_flags(&_alglib_env_state, _xparams.flags);
    2721           0 :     alglib_impl::hpdmatrixcholeskysolvemfast(const_cast<alglib_impl::ae_matrix*>(cha.c_ptr()), n, isupper, const_cast<alglib_impl::ae_matrix*>(b.c_ptr()), m, &info, &_alglib_env_state);
    2722           0 :     alglib_impl::ae_state_clear(&_alglib_env_state);
    2723           0 :     return;
    2724             : }
    2725             : 
    2726             : /*************************************************************************
    2727             : Dense solver for A*x=b with N*N Hermitian positive definite matrix A given
    2728             : by its Cholesky decomposition, and N*1 complex vectors x and  b.  This  is
    2729             : "slow-but-feature-rich" version of the solver  which  estimates  condition
    2730             : number of the system.
    2731             : 
    2732             : Algorithm features:
    2733             : * automatic detection of degenerate cases
    2734             : * O(N^2) complexity
    2735             : * condition number estimation
    2736             : * matrix is represented by its upper or lower triangle
    2737             : 
    2738             : No iterative refinement is provided because such partial representation of
    2739             : matrix does not allow efficient calculation of extra-precise  matrix-vector
    2740             : products for large matrices. Use RMatrixSolve or RMatrixMixedSolve  if  you
    2741             : need iterative refinement.
    2742             : 
    2743             : IMPORTANT: ! this function is NOT the most efficient linear solver provided
    2744             :            ! by ALGLIB. It estimates condition  number  of  linear system,
    2745             :            ! which results in 10-15x  performance  penalty  when  compared
    2746             :            ! with "fast" version which just calls triangular solver.
    2747             :            !
    2748             :            ! This performance penalty is insignificant  when compared with
    2749             :            ! cost of large LU decomposition.  However,  if you  call  this
    2750             :            ! function many times for the same  left  side,  this  overhead
    2751             :            ! BECOMES significant. It  also  becomes significant for small-
    2752             :            ! scale problems (N<50).
    2753             :            !
    2754             :            ! In such cases we strongly recommend you to use faster solver,
    2755             :            ! HPDMatrixCholeskySolveFast() function.
    2756             : 
    2757             : INPUT PARAMETERS
    2758             :     CHA     -   array[0..N-1,0..N-1], Cholesky decomposition,
    2759             :                 SPDMatrixCholesky result
    2760             :     N       -   size of A
    2761             :     IsUpper -   what half of CHA is provided
    2762             :     B       -   array[0..N-1], right part
    2763             : 
    2764             : OUTPUT PARAMETERS
    2765             :     Info    -   return code:
    2766             :                 * -3    A is is exactly singular or ill conditioned
    2767             :                         X is filled by zeros in such cases.
    2768             :                 * -1    N<=0 was passed
    2769             :                 *  1    task is solved
    2770             :     Rep     -   additional report, following fields are set:
    2771             :                 * rep.r1    condition number in 1-norm
    2772             :                 * rep.rinf  condition number in inf-norm
    2773             :     X       -   array[N]:
    2774             :                 * for info>0  - solution
    2775             :                 * for info=-3 - filled by zeros
    2776             : 
    2777             :   -- ALGLIB --
    2778             :      Copyright 27.01.2010 by Bochkanov Sergey
    2779             : *************************************************************************/
    2780           0 : void hpdmatrixcholeskysolve(const complex_2d_array &cha, const ae_int_t n, const bool isupper, const complex_1d_array &b, ae_int_t &info, densesolverreport &rep, complex_1d_array &x, const xparams _xparams)
    2781             : {
    2782             :     jmp_buf _break_jump;
    2783             :     alglib_impl::ae_state _alglib_env_state;
    2784           0 :     alglib_impl::ae_state_init(&_alglib_env_state);
    2785           0 :     if( setjmp(_break_jump) )
    2786             :     {
    2787             : #if !defined(AE_NO_EXCEPTIONS)
    2788           0 :         _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
    2789             : #else
    2790             :         _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
    2791             :         return;
    2792             : #endif
    2793             :     }
    2794           0 :     ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
    2795           0 :     if( _xparams.flags!=0x0 )
    2796           0 :         ae_state_set_flags(&_alglib_env_state, _xparams.flags);
    2797           0 :     alglib_impl::hpdmatrixcholeskysolve(const_cast<alglib_impl::ae_matrix*>(cha.c_ptr()), n, isupper, const_cast<alglib_impl::ae_vector*>(b.c_ptr()), &info, const_cast<alglib_impl::densesolverreport*>(rep.c_ptr()), const_cast<alglib_impl::ae_vector*>(x.c_ptr()), &_alglib_env_state);
    2798           0 :     alglib_impl::ae_state_clear(&_alglib_env_state);
    2799           0 :     return;
    2800             : }
    2801             : 
    2802             : /*************************************************************************
    2803             : Dense solver for A*x=b with N*N Hermitian positive definite matrix A given
    2804             : by its Cholesky decomposition, and N*1 complex vectors x and  b.  This  is
    2805             : "fast-but-lightweight" version of the solver.
    2806             : 
    2807             : Algorithm features:
    2808             : * O(N^2) complexity
    2809             : * matrix is represented by its upper or lower triangle
    2810             : * no additional time-consuming features
    2811             : 
    2812             : INPUT PARAMETERS
    2813             :     CHA     -   array[0..N-1,0..N-1], Cholesky decomposition,
    2814             :                 SPDMatrixCholesky result
    2815             :     N       -   size of A
    2816             :     IsUpper -   what half of CHA is provided
    2817             :     B       -   array[0..N-1], right part
    2818             : 
    2819             : OUTPUT PARAMETERS
    2820             :     Info    -   return code:
    2821             :                 * -3    A is is exactly singular or ill conditioned
    2822             :                         B is filled by zeros in such cases.
    2823             :                 * -1    N<=0 was passed
    2824             :                 *  1    task is solved
    2825             :     B       -   array[N]:
    2826             :                 * for info>0  - overwritten by solution
    2827             :                 * for info=-3 - filled by zeros
    2828             : 
    2829             :   -- ALGLIB --
    2830             :      Copyright 18.03.2015 by Bochkanov Sergey
    2831             : *************************************************************************/
    2832           0 : void hpdmatrixcholeskysolvefast(const complex_2d_array &cha, const ae_int_t n, const bool isupper, const complex_1d_array &b, ae_int_t &info, const xparams _xparams)
    2833             : {
    2834             :     jmp_buf _break_jump;
    2835             :     alglib_impl::ae_state _alglib_env_state;
    2836           0 :     alglib_impl::ae_state_init(&_alglib_env_state);
    2837           0 :     if( setjmp(_break_jump) )
    2838             :     {
    2839             : #if !defined(AE_NO_EXCEPTIONS)
    2840           0 :         _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
    2841             : #else
    2842             :         _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
    2843             :         return;
    2844             : #endif
    2845             :     }
    2846           0 :     ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
    2847           0 :     if( _xparams.flags!=0x0 )
    2848           0 :         ae_state_set_flags(&_alglib_env_state, _xparams.flags);
    2849           0 :     alglib_impl::hpdmatrixcholeskysolvefast(const_cast<alglib_impl::ae_matrix*>(cha.c_ptr()), n, isupper, const_cast<alglib_impl::ae_vector*>(b.c_ptr()), &info, &_alglib_env_state);
    2850           0 :     alglib_impl::ae_state_clear(&_alglib_env_state);
    2851           0 :     return;
    2852             : }
    2853             : 
    2854             : /*************************************************************************
    2855             : Dense solver.
    2856             : 
    2857             : This subroutine finds solution of the linear system A*X=B with non-square,
    2858             : possibly degenerate A.  System  is  solved in the least squares sense, and
    2859             : general least squares solution  X = X0 + CX*y  which  minimizes |A*X-B| is
    2860             : returned. If A is non-degenerate, solution in the usual sense is returned.
    2861             : 
    2862             : Algorithm features:
    2863             : * automatic detection (and correct handling!) of degenerate cases
    2864             : * iterative refinement
    2865             : * O(N^3) complexity
    2866             : 
    2867             :   ! COMMERCIAL EDITION OF ALGLIB:
    2868             :   !
    2869             :   ! Commercial Edition of ALGLIB includes following important improvements
    2870             :   ! of this function:
    2871             :   ! * high-performance native backend with same C# interface (C# version)
    2872             :   ! * multithreading support (C++ and C# versions)
    2873             :   ! * hardware vendor (Intel) implementations of linear algebra primitives
    2874             :   !   (C++ and C# versions, x86/x64 platform)
    2875             :   !
    2876             :   ! We recommend you to read 'Working with commercial version' section  of
    2877             :   ! ALGLIB Reference Manual in order to find out how to  use  performance-
    2878             :   ! related features provided by commercial edition of ALGLIB.
    2879             : 
    2880             : INPUT PARAMETERS
    2881             :     A       -   array[0..NRows-1,0..NCols-1], system matrix
    2882             :     NRows   -   vertical size of A
    2883             :     NCols   -   horizontal size of A
    2884             :     B       -   array[0..NCols-1], right part
    2885             :     Threshold-  a number in [0,1]. Singular values  beyond  Threshold  are
    2886             :                 considered  zero.  Set  it to 0.0, if you don't understand
    2887             :                 what it means, so the solver will choose good value on its
    2888             :                 own.
    2889             : 
    2890             : OUTPUT PARAMETERS
    2891             :     Info    -   return code:
    2892             :                 * -4    SVD subroutine failed
    2893             :                 * -1    if NRows<=0 or NCols<=0 or Threshold<0 was passed
    2894             :                 *  1    if task is solved
    2895             :     Rep     -   solver report, see below for more info
    2896             :     X       -   array[0..N-1,0..M-1], it contains:
    2897             :                 * solution of A*X=B (even for singular A)
    2898             :                 * zeros, if SVD subroutine failed
    2899             : 
    2900             : SOLVER REPORT
    2901             : 
    2902             : Subroutine sets following fields of the Rep structure:
    2903             : * R2        reciprocal of condition number: 1/cond(A), 2-norm.
    2904             : * N         = NCols
    2905             : * K         dim(Null(A))
    2906             : * CX        array[0..N-1,0..K-1], kernel of A.
    2907             :             Columns of CX store such vectors that A*CX[i]=0.
    2908             : 
    2909             :   -- ALGLIB --
    2910             :      Copyright 24.08.2009 by Bochkanov Sergey
    2911             : *************************************************************************/
    2912           0 : void rmatrixsolvels(const real_2d_array &a, const ae_int_t nrows, const ae_int_t ncols, const real_1d_array &b, const double threshold, ae_int_t &info, densesolverlsreport &rep, real_1d_array &x, const xparams _xparams)
    2913             : {
    2914             :     jmp_buf _break_jump;
    2915             :     alglib_impl::ae_state _alglib_env_state;
    2916           0 :     alglib_impl::ae_state_init(&_alglib_env_state);
    2917           0 :     if( setjmp(_break_jump) )
    2918             :     {
    2919             : #if !defined(AE_NO_EXCEPTIONS)
    2920           0 :         _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
    2921             : #else
    2922             :         _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
    2923             :         return;
    2924             : #endif
    2925             :     }
    2926           0 :     ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
    2927           0 :     if( _xparams.flags!=0x0 )
    2928           0 :         ae_state_set_flags(&_alglib_env_state, _xparams.flags);
    2929           0 :     alglib_impl::rmatrixsolvels(const_cast<alglib_impl::ae_matrix*>(a.c_ptr()), nrows, ncols, const_cast<alglib_impl::ae_vector*>(b.c_ptr()), threshold, &info, const_cast<alglib_impl::densesolverlsreport*>(rep.c_ptr()), const_cast<alglib_impl::ae_vector*>(x.c_ptr()), &_alglib_env_state);
    2930           0 :     alglib_impl::ae_state_clear(&_alglib_env_state);
    2931           0 :     return;
    2932             : }
    2933             : #endif
    2934             : 
    2935             : #if defined(AE_COMPILE_LINLSQR) || !defined(AE_PARTIAL_BUILD)
    2936             : /*************************************************************************
    2937             : This object stores state of the LinLSQR method.
    2938             : 
    2939             : You should use ALGLIB functions to work with this object.
    2940             : *************************************************************************/
    2941           0 : _linlsqrstate_owner::_linlsqrstate_owner()
    2942             : {
    2943             :     jmp_buf _break_jump;
    2944             :     alglib_impl::ae_state _state;
    2945             :     
    2946           0 :     alglib_impl::ae_state_init(&_state);
    2947           0 :     if( setjmp(_break_jump) )
    2948             :     {
    2949           0 :         if( p_struct!=NULL )
    2950             :         {
    2951           0 :             alglib_impl::_linlsqrstate_destroy(p_struct);
    2952           0 :             alglib_impl::ae_free(p_struct);
    2953             :         }
    2954           0 :         p_struct = NULL;
    2955             : #if !defined(AE_NO_EXCEPTIONS)
    2956           0 :         _ALGLIB_CPP_EXCEPTION(_state.error_msg);
    2957             : #else
    2958             :         _ALGLIB_SET_ERROR_FLAG(_state.error_msg);
    2959             :         return;
    2960             : #endif
    2961             :     }
    2962           0 :     alglib_impl::ae_state_set_break_jump(&_state, &_break_jump);
    2963           0 :     p_struct = NULL;
    2964           0 :     p_struct = (alglib_impl::linlsqrstate*)alglib_impl::ae_malloc(sizeof(alglib_impl::linlsqrstate), &_state);
    2965           0 :     memset(p_struct, 0, sizeof(alglib_impl::linlsqrstate));
    2966           0 :     alglib_impl::_linlsqrstate_init(p_struct, &_state, ae_false);
    2967           0 :     ae_state_clear(&_state);
    2968           0 : }
    2969             : 
    2970           0 : _linlsqrstate_owner::_linlsqrstate_owner(const _linlsqrstate_owner &rhs)
    2971             : {
    2972             :     jmp_buf _break_jump;
    2973             :     alglib_impl::ae_state _state;
    2974             :     
    2975           0 :     alglib_impl::ae_state_init(&_state);
    2976           0 :     if( setjmp(_break_jump) )
    2977             :     {
    2978           0 :         if( p_struct!=NULL )
    2979             :         {
    2980           0 :             alglib_impl::_linlsqrstate_destroy(p_struct);
    2981           0 :             alglib_impl::ae_free(p_struct);
    2982             :         }
    2983           0 :         p_struct = NULL;
    2984             : #if !defined(AE_NO_EXCEPTIONS)
    2985           0 :         _ALGLIB_CPP_EXCEPTION(_state.error_msg);
    2986             : #else
    2987             :         _ALGLIB_SET_ERROR_FLAG(_state.error_msg);
    2988             :         return;
    2989             : #endif
    2990             :     }
    2991           0 :     alglib_impl::ae_state_set_break_jump(&_state, &_break_jump);
    2992           0 :     p_struct = NULL;
    2993           0 :     alglib_impl::ae_assert(rhs.p_struct!=NULL, "ALGLIB: linlsqrstate copy constructor failure (source is not initialized)", &_state);
    2994           0 :     p_struct = (alglib_impl::linlsqrstate*)alglib_impl::ae_malloc(sizeof(alglib_impl::linlsqrstate), &_state);
    2995           0 :     memset(p_struct, 0, sizeof(alglib_impl::linlsqrstate));
    2996           0 :     alglib_impl::_linlsqrstate_init_copy(p_struct, const_cast<alglib_impl::linlsqrstate*>(rhs.p_struct), &_state, ae_false);
    2997           0 :     ae_state_clear(&_state);
    2998           0 : }
    2999             : 
    3000           0 : _linlsqrstate_owner& _linlsqrstate_owner::operator=(const _linlsqrstate_owner &rhs)
    3001             : {
    3002           0 :     if( this==&rhs )
    3003           0 :         return *this;
    3004             :     jmp_buf _break_jump;
    3005             :     alglib_impl::ae_state _state;
    3006             :     
    3007           0 :     alglib_impl::ae_state_init(&_state);
    3008           0 :     if( setjmp(_break_jump) )
    3009             :     {
    3010             : #if !defined(AE_NO_EXCEPTIONS)
    3011           0 :         _ALGLIB_CPP_EXCEPTION(_state.error_msg);
    3012             : #else
    3013             :         _ALGLIB_SET_ERROR_FLAG(_state.error_msg);
    3014             :         return *this;
    3015             : #endif
    3016             :     }
    3017           0 :     alglib_impl::ae_state_set_break_jump(&_state, &_break_jump);
    3018           0 :     alglib_impl::ae_assert(p_struct!=NULL, "ALGLIB: linlsqrstate assignment constructor failure (destination is not initialized)", &_state);
    3019           0 :     alglib_impl::ae_assert(rhs.p_struct!=NULL, "ALGLIB: linlsqrstate assignment constructor failure (source is not initialized)", &_state);
    3020           0 :     alglib_impl::_linlsqrstate_destroy(p_struct);
    3021           0 :     memset(p_struct, 0, sizeof(alglib_impl::linlsqrstate));
    3022           0 :     alglib_impl::_linlsqrstate_init_copy(p_struct, const_cast<alglib_impl::linlsqrstate*>(rhs.p_struct), &_state, ae_false);
    3023           0 :     ae_state_clear(&_state);
    3024           0 :     return *this;
    3025             : }
    3026             : 
    3027           0 : _linlsqrstate_owner::~_linlsqrstate_owner()
    3028             : {
    3029           0 :     if( p_struct!=NULL )
    3030             :     {
    3031           0 :         alglib_impl::_linlsqrstate_destroy(p_struct);
    3032           0 :         ae_free(p_struct);
    3033             :     }
    3034           0 : }
    3035             : 
    3036           0 : alglib_impl::linlsqrstate* _linlsqrstate_owner::c_ptr()
    3037             : {
    3038           0 :     return p_struct;
    3039             : }
    3040             : 
    3041           0 : alglib_impl::linlsqrstate* _linlsqrstate_owner::c_ptr() const
    3042             : {
    3043           0 :     return const_cast<alglib_impl::linlsqrstate*>(p_struct);
    3044             : }
    3045           0 : linlsqrstate::linlsqrstate() : _linlsqrstate_owner() 
    3046             : {
    3047           0 : }
    3048             : 
    3049           0 : linlsqrstate::linlsqrstate(const linlsqrstate &rhs):_linlsqrstate_owner(rhs) 
    3050             : {
    3051           0 : }
    3052             : 
    3053           0 : linlsqrstate& linlsqrstate::operator=(const linlsqrstate &rhs)
    3054             : {
    3055           0 :     if( this==&rhs )
    3056           0 :         return *this;
    3057           0 :     _linlsqrstate_owner::operator=(rhs);
    3058           0 :     return *this;
    3059             : }
    3060             : 
    3061           0 : linlsqrstate::~linlsqrstate()
    3062             : {
    3063           0 : }
    3064             : 
    3065             : 
    3066             : /*************************************************************************
    3067             : 
    3068             : *************************************************************************/
    3069           0 : _linlsqrreport_owner::_linlsqrreport_owner()
    3070             : {
    3071             :     jmp_buf _break_jump;
    3072             :     alglib_impl::ae_state _state;
    3073             :     
    3074           0 :     alglib_impl::ae_state_init(&_state);
    3075           0 :     if( setjmp(_break_jump) )
    3076             :     {
    3077           0 :         if( p_struct!=NULL )
    3078             :         {
    3079           0 :             alglib_impl::_linlsqrreport_destroy(p_struct);
    3080           0 :             alglib_impl::ae_free(p_struct);
    3081             :         }
    3082           0 :         p_struct = NULL;
    3083             : #if !defined(AE_NO_EXCEPTIONS)
    3084           0 :         _ALGLIB_CPP_EXCEPTION(_state.error_msg);
    3085             : #else
    3086             :         _ALGLIB_SET_ERROR_FLAG(_state.error_msg);
    3087             :         return;
    3088             : #endif
    3089             :     }
    3090           0 :     alglib_impl::ae_state_set_break_jump(&_state, &_break_jump);
    3091           0 :     p_struct = NULL;
    3092           0 :     p_struct = (alglib_impl::linlsqrreport*)alglib_impl::ae_malloc(sizeof(alglib_impl::linlsqrreport), &_state);
    3093           0 :     memset(p_struct, 0, sizeof(alglib_impl::linlsqrreport));
    3094           0 :     alglib_impl::_linlsqrreport_init(p_struct, &_state, ae_false);
    3095           0 :     ae_state_clear(&_state);
    3096           0 : }
    3097             : 
    3098           0 : _linlsqrreport_owner::_linlsqrreport_owner(const _linlsqrreport_owner &rhs)
    3099             : {
    3100             :     jmp_buf _break_jump;
    3101             :     alglib_impl::ae_state _state;
    3102             :     
    3103           0 :     alglib_impl::ae_state_init(&_state);
    3104           0 :     if( setjmp(_break_jump) )
    3105             :     {
    3106           0 :         if( p_struct!=NULL )
    3107             :         {
    3108           0 :             alglib_impl::_linlsqrreport_destroy(p_struct);
    3109           0 :             alglib_impl::ae_free(p_struct);
    3110             :         }
    3111           0 :         p_struct = NULL;
    3112             : #if !defined(AE_NO_EXCEPTIONS)
    3113           0 :         _ALGLIB_CPP_EXCEPTION(_state.error_msg);
    3114             : #else
    3115             :         _ALGLIB_SET_ERROR_FLAG(_state.error_msg);
    3116             :         return;
    3117             : #endif
    3118             :     }
    3119           0 :     alglib_impl::ae_state_set_break_jump(&_state, &_break_jump);
    3120           0 :     p_struct = NULL;
    3121           0 :     alglib_impl::ae_assert(rhs.p_struct!=NULL, "ALGLIB: linlsqrreport copy constructor failure (source is not initialized)", &_state);
    3122           0 :     p_struct = (alglib_impl::linlsqrreport*)alglib_impl::ae_malloc(sizeof(alglib_impl::linlsqrreport), &_state);
    3123           0 :     memset(p_struct, 0, sizeof(alglib_impl::linlsqrreport));
    3124           0 :     alglib_impl::_linlsqrreport_init_copy(p_struct, const_cast<alglib_impl::linlsqrreport*>(rhs.p_struct), &_state, ae_false);
    3125           0 :     ae_state_clear(&_state);
    3126           0 : }
    3127             : 
    3128           0 : _linlsqrreport_owner& _linlsqrreport_owner::operator=(const _linlsqrreport_owner &rhs)
    3129             : {
    3130           0 :     if( this==&rhs )
    3131           0 :         return *this;
    3132             :     jmp_buf _break_jump;
    3133             :     alglib_impl::ae_state _state;
    3134             :     
    3135           0 :     alglib_impl::ae_state_init(&_state);
    3136           0 :     if( setjmp(_break_jump) )
    3137             :     {
    3138             : #if !defined(AE_NO_EXCEPTIONS)
    3139           0 :         _ALGLIB_CPP_EXCEPTION(_state.error_msg);
    3140             : #else
    3141             :         _ALGLIB_SET_ERROR_FLAG(_state.error_msg);
    3142             :         return *this;
    3143             : #endif
    3144             :     }
    3145           0 :     alglib_impl::ae_state_set_break_jump(&_state, &_break_jump);
    3146           0 :     alglib_impl::ae_assert(p_struct!=NULL, "ALGLIB: linlsqrreport assignment constructor failure (destination is not initialized)", &_state);
    3147           0 :     alglib_impl::ae_assert(rhs.p_struct!=NULL, "ALGLIB: linlsqrreport assignment constructor failure (source is not initialized)", &_state);
    3148           0 :     alglib_impl::_linlsqrreport_destroy(p_struct);
    3149           0 :     memset(p_struct, 0, sizeof(alglib_impl::linlsqrreport));
    3150           0 :     alglib_impl::_linlsqrreport_init_copy(p_struct, const_cast<alglib_impl::linlsqrreport*>(rhs.p_struct), &_state, ae_false);
    3151           0 :     ae_state_clear(&_state);
    3152           0 :     return *this;
    3153             : }
    3154             : 
    3155           0 : _linlsqrreport_owner::~_linlsqrreport_owner()
    3156             : {
    3157           0 :     if( p_struct!=NULL )
    3158             :     {
    3159           0 :         alglib_impl::_linlsqrreport_destroy(p_struct);
    3160           0 :         ae_free(p_struct);
    3161             :     }
    3162           0 : }
    3163             : 
    3164           0 : alglib_impl::linlsqrreport* _linlsqrreport_owner::c_ptr()
    3165             : {
    3166           0 :     return p_struct;
    3167             : }
    3168             : 
    3169           0 : alglib_impl::linlsqrreport* _linlsqrreport_owner::c_ptr() const
    3170             : {
    3171           0 :     return const_cast<alglib_impl::linlsqrreport*>(p_struct);
    3172             : }
    3173           0 : linlsqrreport::linlsqrreport() : _linlsqrreport_owner() ,iterationscount(p_struct->iterationscount),nmv(p_struct->nmv),terminationtype(p_struct->terminationtype)
    3174             : {
    3175           0 : }
    3176             : 
    3177           0 : linlsqrreport::linlsqrreport(const linlsqrreport &rhs):_linlsqrreport_owner(rhs) ,iterationscount(p_struct->iterationscount),nmv(p_struct->nmv),terminationtype(p_struct->terminationtype)
    3178             : {
    3179           0 : }
    3180             : 
    3181           0 : linlsqrreport& linlsqrreport::operator=(const linlsqrreport &rhs)
    3182             : {
    3183           0 :     if( this==&rhs )
    3184           0 :         return *this;
    3185           0 :     _linlsqrreport_owner::operator=(rhs);
    3186           0 :     return *this;
    3187             : }
    3188             : 
    3189           0 : linlsqrreport::~linlsqrreport()
    3190             : {
    3191           0 : }
    3192             : 
    3193             : /*************************************************************************
    3194             : This function initializes linear LSQR Solver. This solver is used to solve
    3195             : non-symmetric (and, possibly, non-square) problems. Least squares solution
    3196             : is returned for non-compatible systems.
    3197             : 
    3198             : USAGE:
    3199             : 1. User initializes algorithm state with LinLSQRCreate() call
    3200             : 2. User tunes solver parameters with  LinLSQRSetCond() and other functions
    3201             : 3. User  calls  LinLSQRSolveSparse()  function which takes algorithm state
    3202             :    and SparseMatrix object.
    3203             : 4. User calls LinLSQRResults() to get solution
    3204             : 5. Optionally, user may call LinLSQRSolveSparse() again to  solve  another
    3205             :    problem  with different matrix and/or right part without reinitializing
    3206             :    LinLSQRState structure.
    3207             : 
    3208             : INPUT PARAMETERS:
    3209             :     M       -   number of rows in A
    3210             :     N       -   number of variables, N>0
    3211             : 
    3212             : OUTPUT PARAMETERS:
    3213             :     State   -   structure which stores algorithm state
    3214             : 
    3215             : NOTE: see also linlsqrcreatebuf()  for  version  which  reuses  previously
    3216             :       allocated place as much as possible.
    3217             : 
    3218             :   -- ALGLIB --
    3219             :      Copyright 30.11.2011 by Bochkanov Sergey
    3220             : *************************************************************************/
    3221           0 : void linlsqrcreate(const ae_int_t m, const ae_int_t n, linlsqrstate &state, const xparams _xparams)
    3222             : {
    3223             :     jmp_buf _break_jump;
    3224             :     alglib_impl::ae_state _alglib_env_state;
    3225           0 :     alglib_impl::ae_state_init(&_alglib_env_state);
    3226           0 :     if( setjmp(_break_jump) )
    3227             :     {
    3228             : #if !defined(AE_NO_EXCEPTIONS)
    3229           0 :         _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
    3230             : #else
    3231             :         _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
    3232             :         return;
    3233             : #endif
    3234             :     }
    3235           0 :     ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
    3236           0 :     if( _xparams.flags!=0x0 )
    3237           0 :         ae_state_set_flags(&_alglib_env_state, _xparams.flags);
    3238           0 :     alglib_impl::linlsqrcreate(m, n, const_cast<alglib_impl::linlsqrstate*>(state.c_ptr()), &_alglib_env_state);
    3239           0 :     alglib_impl::ae_state_clear(&_alglib_env_state);
    3240           0 :     return;
    3241             : }
    3242             : 
    3243             : /*************************************************************************
    3244             : This function initializes linear LSQR Solver.  It  provides  exactly  same
    3245             : functionality as linlsqrcreate(), but reuses  previously  allocated  space
    3246             : as much as possible.
    3247             : 
    3248             : INPUT PARAMETERS:
    3249             :     M       -   number of rows in A
    3250             :     N       -   number of variables, N>0
    3251             : 
    3252             : OUTPUT PARAMETERS:
    3253             :     State   -   structure which stores algorithm state
    3254             : 
    3255             :   -- ALGLIB --
    3256             :      Copyright 14.11.2018 by Bochkanov Sergey
    3257             : *************************************************************************/
    3258           0 : void linlsqrcreatebuf(const ae_int_t m, const ae_int_t n, const linlsqrstate &state, const xparams _xparams)
    3259             : {
    3260             :     jmp_buf _break_jump;
    3261             :     alglib_impl::ae_state _alglib_env_state;
    3262           0 :     alglib_impl::ae_state_init(&_alglib_env_state);
    3263           0 :     if( setjmp(_break_jump) )
    3264             :     {
    3265             : #if !defined(AE_NO_EXCEPTIONS)
    3266           0 :         _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
    3267             : #else
    3268             :         _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
    3269             :         return;
    3270             : #endif
    3271             :     }
    3272           0 :     ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
    3273           0 :     if( _xparams.flags!=0x0 )
    3274           0 :         ae_state_set_flags(&_alglib_env_state, _xparams.flags);
    3275           0 :     alglib_impl::linlsqrcreatebuf(m, n, const_cast<alglib_impl::linlsqrstate*>(state.c_ptr()), &_alglib_env_state);
    3276           0 :     alglib_impl::ae_state_clear(&_alglib_env_state);
    3277           0 :     return;
    3278             : }
    3279             : 
    3280             : /*************************************************************************
    3281             : This  function  changes  preconditioning  settings of LinLSQQSolveSparse()
    3282             : function. By default, SolveSparse() uses diagonal preconditioner,  but  if
    3283             : you want to use solver without preconditioning, you can call this function
    3284             : which forces solver to use unit matrix for preconditioning.
    3285             : 
    3286             : INPUT PARAMETERS:
    3287             :     State   -   structure which stores algorithm state
    3288             : 
    3289             :   -- ALGLIB --
    3290             :      Copyright 19.11.2012 by Bochkanov Sergey
    3291             : *************************************************************************/
    3292           0 : void linlsqrsetprecunit(const linlsqrstate &state, const xparams _xparams)
    3293             : {
    3294             :     jmp_buf _break_jump;
    3295             :     alglib_impl::ae_state _alglib_env_state;
    3296           0 :     alglib_impl::ae_state_init(&_alglib_env_state);
    3297           0 :     if( setjmp(_break_jump) )
    3298             :     {
    3299             : #if !defined(AE_NO_EXCEPTIONS)
    3300           0 :         _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
    3301             : #else
    3302             :         _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
    3303             :         return;
    3304             : #endif
    3305             :     }
    3306           0 :     ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
    3307           0 :     if( _xparams.flags!=0x0 )
    3308           0 :         ae_state_set_flags(&_alglib_env_state, _xparams.flags);
    3309           0 :     alglib_impl::linlsqrsetprecunit(const_cast<alglib_impl::linlsqrstate*>(state.c_ptr()), &_alglib_env_state);
    3310           0 :     alglib_impl::ae_state_clear(&_alglib_env_state);
    3311           0 :     return;
    3312             : }
    3313             : 
    3314             : /*************************************************************************
    3315             : This  function  changes  preconditioning  settings  of  LinCGSolveSparse()
    3316             : function.  LinCGSolveSparse() will use diagonal of the  system  matrix  as
    3317             : preconditioner. This preconditioning mode is active by default.
    3318             : 
    3319             : INPUT PARAMETERS:
    3320             :     State   -   structure which stores algorithm state
    3321             : 
    3322             :   -- ALGLIB --
    3323             :      Copyright 19.11.2012 by Bochkanov Sergey
    3324             : *************************************************************************/
    3325           0 : void linlsqrsetprecdiag(const linlsqrstate &state, const xparams _xparams)
    3326             : {
    3327             :     jmp_buf _break_jump;
    3328             :     alglib_impl::ae_state _alglib_env_state;
    3329           0 :     alglib_impl::ae_state_init(&_alglib_env_state);
    3330           0 :     if( setjmp(_break_jump) )
    3331             :     {
    3332             : #if !defined(AE_NO_EXCEPTIONS)
    3333           0 :         _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
    3334             : #else
    3335             :         _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
    3336             :         return;
    3337             : #endif
    3338             :     }
    3339           0 :     ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
    3340           0 :     if( _xparams.flags!=0x0 )
    3341           0 :         ae_state_set_flags(&_alglib_env_state, _xparams.flags);
    3342           0 :     alglib_impl::linlsqrsetprecdiag(const_cast<alglib_impl::linlsqrstate*>(state.c_ptr()), &_alglib_env_state);
    3343           0 :     alglib_impl::ae_state_clear(&_alglib_env_state);
    3344           0 :     return;
    3345             : }
    3346             : 
    3347             : /*************************************************************************
    3348             : This function sets optional Tikhonov regularization coefficient.
    3349             : It is zero by default.
    3350             : 
    3351             : INPUT PARAMETERS:
    3352             :     LambdaI -   regularization factor, LambdaI>=0
    3353             : 
    3354             : OUTPUT PARAMETERS:
    3355             :     State   -   structure which stores algorithm state
    3356             : 
    3357             :   -- ALGLIB --
    3358             :      Copyright 30.11.2011 by Bochkanov Sergey
    3359             : *************************************************************************/
    3360           0 : void linlsqrsetlambdai(const linlsqrstate &state, const double lambdai, const xparams _xparams)
    3361             : {
    3362             :     jmp_buf _break_jump;
    3363             :     alglib_impl::ae_state _alglib_env_state;
    3364           0 :     alglib_impl::ae_state_init(&_alglib_env_state);
    3365           0 :     if( setjmp(_break_jump) )
    3366             :     {
    3367             : #if !defined(AE_NO_EXCEPTIONS)
    3368           0 :         _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
    3369             : #else
    3370             :         _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
    3371             :         return;
    3372             : #endif
    3373             :     }
    3374           0 :     ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
    3375           0 :     if( _xparams.flags!=0x0 )
    3376           0 :         ae_state_set_flags(&_alglib_env_state, _xparams.flags);
    3377           0 :     alglib_impl::linlsqrsetlambdai(const_cast<alglib_impl::linlsqrstate*>(state.c_ptr()), lambdai, &_alglib_env_state);
    3378           0 :     alglib_impl::ae_state_clear(&_alglib_env_state);
    3379           0 :     return;
    3380             : }
    3381             : 
    3382             : /*************************************************************************
    3383             : Procedure for solution of A*x=b with sparse A.
    3384             : 
    3385             : INPUT PARAMETERS:
    3386             :     State   -   algorithm state
    3387             :     A       -   sparse M*N matrix in the CRS format (you MUST contvert  it
    3388             :                 to CRS format  by  calling  SparseConvertToCRS()  function
    3389             :                 BEFORE you pass it to this function).
    3390             :     B       -   right part, array[M]
    3391             : 
    3392             : RESULT:
    3393             :     This function returns no result.
    3394             :     You can get solution by calling LinCGResults()
    3395             : 
    3396             : NOTE: this function uses lightweight preconditioning -  multiplication  by
    3397             :       inverse of diag(A). If you want, you can turn preconditioning off by
    3398             :       calling LinLSQRSetPrecUnit(). However, preconditioning cost is   low
    3399             :       and preconditioner is very important for solution  of  badly  scaled
    3400             :       problems.
    3401             : 
    3402             :   -- ALGLIB --
    3403             :      Copyright 30.11.2011 by Bochkanov Sergey
    3404             : *************************************************************************/
    3405           0 : void linlsqrsolvesparse(const linlsqrstate &state, const sparsematrix &a, const real_1d_array &b, const xparams _xparams)
    3406             : {
    3407             :     jmp_buf _break_jump;
    3408             :     alglib_impl::ae_state _alglib_env_state;
    3409           0 :     alglib_impl::ae_state_init(&_alglib_env_state);
    3410           0 :     if( setjmp(_break_jump) )
    3411             :     {
    3412             : #if !defined(AE_NO_EXCEPTIONS)
    3413           0 :         _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
    3414             : #else
    3415             :         _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
    3416             :         return;
    3417             : #endif
    3418             :     }
    3419           0 :     ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
    3420           0 :     if( _xparams.flags!=0x0 )
    3421           0 :         ae_state_set_flags(&_alglib_env_state, _xparams.flags);
    3422           0 :     alglib_impl::linlsqrsolvesparse(const_cast<alglib_impl::linlsqrstate*>(state.c_ptr()), const_cast<alglib_impl::sparsematrix*>(a.c_ptr()), const_cast<alglib_impl::ae_vector*>(b.c_ptr()), &_alglib_env_state);
    3423           0 :     alglib_impl::ae_state_clear(&_alglib_env_state);
    3424           0 :     return;
    3425             : }
    3426             : 
    3427             : /*************************************************************************
    3428             : This function sets stopping criteria.
    3429             : 
    3430             : INPUT PARAMETERS:
    3431             :     EpsA    -   algorithm will be stopped if ||A^T*Rk||/(||A||*||Rk||)<=EpsA.
    3432             :     EpsB    -   algorithm will be stopped if ||Rk||<=EpsB*||B||
    3433             :     MaxIts  -   algorithm will be stopped if number of iterations
    3434             :                 more than MaxIts.
    3435             : 
    3436             : OUTPUT PARAMETERS:
    3437             :     State   -   structure which stores algorithm state
    3438             : 
    3439             : NOTE: if EpsA,EpsB,EpsC and MaxIts are zero then these variables will
    3440             : be setted as default values.
    3441             : 
    3442             :   -- ALGLIB --
    3443             :      Copyright 30.11.2011 by Bochkanov Sergey
    3444             : *************************************************************************/
    3445           0 : void linlsqrsetcond(const linlsqrstate &state, const double epsa, const double epsb, const ae_int_t maxits, const xparams _xparams)
    3446             : {
    3447             :     jmp_buf _break_jump;
    3448             :     alglib_impl::ae_state _alglib_env_state;
    3449           0 :     alglib_impl::ae_state_init(&_alglib_env_state);
    3450           0 :     if( setjmp(_break_jump) )
    3451             :     {
    3452             : #if !defined(AE_NO_EXCEPTIONS)
    3453           0 :         _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
    3454             : #else
    3455             :         _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
    3456             :         return;
    3457             : #endif
    3458             :     }
    3459           0 :     ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
    3460           0 :     if( _xparams.flags!=0x0 )
    3461           0 :         ae_state_set_flags(&_alglib_env_state, _xparams.flags);
    3462           0 :     alglib_impl::linlsqrsetcond(const_cast<alglib_impl::linlsqrstate*>(state.c_ptr()), epsa, epsb, maxits, &_alglib_env_state);
    3463           0 :     alglib_impl::ae_state_clear(&_alglib_env_state);
    3464           0 :     return;
    3465             : }
    3466             : 
    3467             : /*************************************************************************
    3468             : LSQR solver: results.
    3469             : 
    3470             : This function must be called after LinLSQRSolve
    3471             : 
    3472             : INPUT PARAMETERS:
    3473             :     State   -   algorithm state
    3474             : 
    3475             : OUTPUT PARAMETERS:
    3476             :     X       -   array[N], solution
    3477             :     Rep     -   optimization report:
    3478             :                 * Rep.TerminationType completetion code:
    3479             :                     *  1    ||Rk||<=EpsB*||B||
    3480             :                     *  4    ||A^T*Rk||/(||A||*||Rk||)<=EpsA
    3481             :                     *  5    MaxIts steps was taken
    3482             :                     *  7    rounding errors prevent further progress,
    3483             :                             X contains best point found so far.
    3484             :                             (sometimes returned on singular systems)
    3485             :                     *  8    user requested termination via calling
    3486             :                             linlsqrrequesttermination()
    3487             :                 * Rep.IterationsCount contains iterations count
    3488             :                 * NMV countains number of matrix-vector calculations
    3489             : 
    3490             :   -- ALGLIB --
    3491             :      Copyright 30.11.2011 by Bochkanov Sergey
    3492             : *************************************************************************/
    3493           0 : void linlsqrresults(const linlsqrstate &state, real_1d_array &x, linlsqrreport &rep, const xparams _xparams)
    3494             : {
    3495             :     jmp_buf _break_jump;
    3496             :     alglib_impl::ae_state _alglib_env_state;
    3497           0 :     alglib_impl::ae_state_init(&_alglib_env_state);
    3498           0 :     if( setjmp(_break_jump) )
    3499             :     {
    3500             : #if !defined(AE_NO_EXCEPTIONS)
    3501           0 :         _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
    3502             : #else
    3503             :         _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
    3504             :         return;
    3505             : #endif
    3506             :     }
    3507           0 :     ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
    3508           0 :     if( _xparams.flags!=0x0 )
    3509           0 :         ae_state_set_flags(&_alglib_env_state, _xparams.flags);
    3510           0 :     alglib_impl::linlsqrresults(const_cast<alglib_impl::linlsqrstate*>(state.c_ptr()), const_cast<alglib_impl::ae_vector*>(x.c_ptr()), const_cast<alglib_impl::linlsqrreport*>(rep.c_ptr()), &_alglib_env_state);
    3511           0 :     alglib_impl::ae_state_clear(&_alglib_env_state);
    3512           0 :     return;
    3513             : }
    3514             : 
    3515             : /*************************************************************************
    3516             : This function turns on/off reporting.
    3517             : 
    3518             : INPUT PARAMETERS:
    3519             :     State   -   structure which stores algorithm state
    3520             :     NeedXRep-   whether iteration reports are needed or not
    3521             : 
    3522             : If NeedXRep is True, algorithm will call rep() callback function if  it is
    3523             : provided to MinCGOptimize().
    3524             : 
    3525             :   -- ALGLIB --
    3526             :      Copyright 30.11.2011 by Bochkanov Sergey
    3527             : *************************************************************************/
    3528           0 : void linlsqrsetxrep(const linlsqrstate &state, const bool needxrep, const xparams _xparams)
    3529             : {
    3530             :     jmp_buf _break_jump;
    3531             :     alglib_impl::ae_state _alglib_env_state;
    3532           0 :     alglib_impl::ae_state_init(&_alglib_env_state);
    3533           0 :     if( setjmp(_break_jump) )
    3534             :     {
    3535             : #if !defined(AE_NO_EXCEPTIONS)
    3536           0 :         _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
    3537             : #else
    3538             :         _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
    3539             :         return;
    3540             : #endif
    3541             :     }
    3542           0 :     ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
    3543           0 :     if( _xparams.flags!=0x0 )
    3544           0 :         ae_state_set_flags(&_alglib_env_state, _xparams.flags);
    3545           0 :     alglib_impl::linlsqrsetxrep(const_cast<alglib_impl::linlsqrstate*>(state.c_ptr()), needxrep, &_alglib_env_state);
    3546           0 :     alglib_impl::ae_state_clear(&_alglib_env_state);
    3547           0 :     return;
    3548             : }
    3549             : 
    3550             : /*************************************************************************
    3551             : This function is used to peek into LSQR solver and get  current  iteration
    3552             : counter. You can safely "peek" into the solver from another thread.
    3553             : 
    3554             : INPUT PARAMETERS:
    3555             :     S           -   solver object
    3556             : 
    3557             : RESULT:
    3558             :     iteration counter, in [0,INF)
    3559             : 
    3560             :   -- ALGLIB --
    3561             :      Copyright 21.05.2018 by Bochkanov Sergey
    3562             : *************************************************************************/
    3563           0 : ae_int_t linlsqrpeekiterationscount(const linlsqrstate &s, const xparams _xparams)
    3564             : {
    3565             :     jmp_buf _break_jump;
    3566             :     alglib_impl::ae_state _alglib_env_state;
    3567           0 :     alglib_impl::ae_state_init(&_alglib_env_state);
    3568           0 :     if( setjmp(_break_jump) )
    3569             :     {
    3570             : #if !defined(AE_NO_EXCEPTIONS)
    3571           0 :         _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
    3572             : #else
    3573             :         _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
    3574             :         return 0;
    3575             : #endif
    3576             :     }
    3577           0 :     ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
    3578           0 :     if( _xparams.flags!=0x0 )
    3579           0 :         ae_state_set_flags(&_alglib_env_state, _xparams.flags);
    3580           0 :     alglib_impl::ae_int_t result = alglib_impl::linlsqrpeekiterationscount(const_cast<alglib_impl::linlsqrstate*>(s.c_ptr()), &_alglib_env_state);
    3581           0 :     alglib_impl::ae_state_clear(&_alglib_env_state);
    3582           0 :     return *(reinterpret_cast<ae_int_t*>(&result));
    3583             : }
    3584             : 
    3585             : /*************************************************************************
    3586             : This subroutine submits request for termination of the running solver.  It
    3587             : can be called from some other thread which wants LSQR solver to  terminate
    3588             : (obviously, the  thread  running  LSQR  solver can not request termination
    3589             : because it is already busy working on LSQR).
    3590             : 
    3591             : As result, solver  stops  at  point  which  was  "current  accepted"  when
    3592             : termination  request  was  submitted  and returns error code 8 (successful
    3593             : termination).  Such   termination   is  a smooth  process  which  properly
    3594             : deallocates all temporaries.
    3595             : 
    3596             : INPUT PARAMETERS:
    3597             :     State   -   solver structure
    3598             : 
    3599             : NOTE: calling this function on solver which is NOT running  will  have  no
    3600             :       effect.
    3601             : 
    3602             : NOTE: multiple calls to this function are possible. First call is counted,
    3603             :       subsequent calls are silently ignored.
    3604             : 
    3605             : NOTE: solver clears termination flag on its start, it means that  if  some
    3606             :       other thread will request termination too soon, its request will went
    3607             :       unnoticed.
    3608             : 
    3609             :   -- ALGLIB --
    3610             :      Copyright 08.10.2014 by Bochkanov Sergey
    3611             : *************************************************************************/
    3612           0 : void linlsqrrequesttermination(const linlsqrstate &state, const xparams _xparams)
    3613             : {
    3614             :     jmp_buf _break_jump;
    3615             :     alglib_impl::ae_state _alglib_env_state;
    3616           0 :     alglib_impl::ae_state_init(&_alglib_env_state);
    3617           0 :     if( setjmp(_break_jump) )
    3618             :     {
    3619             : #if !defined(AE_NO_EXCEPTIONS)
    3620           0 :         _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
    3621             : #else
    3622             :         _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
    3623             :         return;
    3624             : #endif
    3625             :     }
    3626           0 :     ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
    3627           0 :     if( _xparams.flags!=0x0 )
    3628           0 :         ae_state_set_flags(&_alglib_env_state, _xparams.flags);
    3629           0 :     alglib_impl::linlsqrrequesttermination(const_cast<alglib_impl::linlsqrstate*>(state.c_ptr()), &_alglib_env_state);
    3630           0 :     alglib_impl::ae_state_clear(&_alglib_env_state);
    3631           0 :     return;
    3632             : }
    3633             : #endif
    3634             : 
    3635             : #if defined(AE_COMPILE_POLYNOMIALSOLVER) || !defined(AE_PARTIAL_BUILD)
    3636             : /*************************************************************************
    3637             : 
    3638             : *************************************************************************/
    3639           0 : _polynomialsolverreport_owner::_polynomialsolverreport_owner()
    3640             : {
    3641             :     jmp_buf _break_jump;
    3642             :     alglib_impl::ae_state _state;
    3643             :     
    3644           0 :     alglib_impl::ae_state_init(&_state);
    3645           0 :     if( setjmp(_break_jump) )
    3646             :     {
    3647           0 :         if( p_struct!=NULL )
    3648             :         {
    3649           0 :             alglib_impl::_polynomialsolverreport_destroy(p_struct);
    3650           0 :             alglib_impl::ae_free(p_struct);
    3651             :         }
    3652           0 :         p_struct = NULL;
    3653             : #if !defined(AE_NO_EXCEPTIONS)
    3654           0 :         _ALGLIB_CPP_EXCEPTION(_state.error_msg);
    3655             : #else
    3656             :         _ALGLIB_SET_ERROR_FLAG(_state.error_msg);
    3657             :         return;
    3658             : #endif
    3659             :     }
    3660           0 :     alglib_impl::ae_state_set_break_jump(&_state, &_break_jump);
    3661           0 :     p_struct = NULL;
    3662           0 :     p_struct = (alglib_impl::polynomialsolverreport*)alglib_impl::ae_malloc(sizeof(alglib_impl::polynomialsolverreport), &_state);
    3663           0 :     memset(p_struct, 0, sizeof(alglib_impl::polynomialsolverreport));
    3664           0 :     alglib_impl::_polynomialsolverreport_init(p_struct, &_state, ae_false);
    3665           0 :     ae_state_clear(&_state);
    3666           0 : }
    3667             : 
    3668           0 : _polynomialsolverreport_owner::_polynomialsolverreport_owner(const _polynomialsolverreport_owner &rhs)
    3669             : {
    3670             :     jmp_buf _break_jump;
    3671             :     alglib_impl::ae_state _state;
    3672             :     
    3673           0 :     alglib_impl::ae_state_init(&_state);
    3674           0 :     if( setjmp(_break_jump) )
    3675             :     {
    3676           0 :         if( p_struct!=NULL )
    3677             :         {
    3678           0 :             alglib_impl::_polynomialsolverreport_destroy(p_struct);
    3679           0 :             alglib_impl::ae_free(p_struct);
    3680             :         }
    3681           0 :         p_struct = NULL;
    3682             : #if !defined(AE_NO_EXCEPTIONS)
    3683           0 :         _ALGLIB_CPP_EXCEPTION(_state.error_msg);
    3684             : #else
    3685             :         _ALGLIB_SET_ERROR_FLAG(_state.error_msg);
    3686             :         return;
    3687             : #endif
    3688             :     }
    3689           0 :     alglib_impl::ae_state_set_break_jump(&_state, &_break_jump);
    3690           0 :     p_struct = NULL;
    3691           0 :     alglib_impl::ae_assert(rhs.p_struct!=NULL, "ALGLIB: polynomialsolverreport copy constructor failure (source is not initialized)", &_state);
    3692           0 :     p_struct = (alglib_impl::polynomialsolverreport*)alglib_impl::ae_malloc(sizeof(alglib_impl::polynomialsolverreport), &_state);
    3693           0 :     memset(p_struct, 0, sizeof(alglib_impl::polynomialsolverreport));
    3694           0 :     alglib_impl::_polynomialsolverreport_init_copy(p_struct, const_cast<alglib_impl::polynomialsolverreport*>(rhs.p_struct), &_state, ae_false);
    3695           0 :     ae_state_clear(&_state);
    3696           0 : }
    3697             : 
    3698           0 : _polynomialsolverreport_owner& _polynomialsolverreport_owner::operator=(const _polynomialsolverreport_owner &rhs)
    3699             : {
    3700           0 :     if( this==&rhs )
    3701           0 :         return *this;
    3702             :     jmp_buf _break_jump;
    3703             :     alglib_impl::ae_state _state;
    3704             :     
    3705           0 :     alglib_impl::ae_state_init(&_state);
    3706           0 :     if( setjmp(_break_jump) )
    3707             :     {
    3708             : #if !defined(AE_NO_EXCEPTIONS)
    3709           0 :         _ALGLIB_CPP_EXCEPTION(_state.error_msg);
    3710             : #else
    3711             :         _ALGLIB_SET_ERROR_FLAG(_state.error_msg);
    3712             :         return *this;
    3713             : #endif
    3714             :     }
    3715           0 :     alglib_impl::ae_state_set_break_jump(&_state, &_break_jump);
    3716           0 :     alglib_impl::ae_assert(p_struct!=NULL, "ALGLIB: polynomialsolverreport assignment constructor failure (destination is not initialized)", &_state);
    3717           0 :     alglib_impl::ae_assert(rhs.p_struct!=NULL, "ALGLIB: polynomialsolverreport assignment constructor failure (source is not initialized)", &_state);
    3718           0 :     alglib_impl::_polynomialsolverreport_destroy(p_struct);
    3719           0 :     memset(p_struct, 0, sizeof(alglib_impl::polynomialsolverreport));
    3720           0 :     alglib_impl::_polynomialsolverreport_init_copy(p_struct, const_cast<alglib_impl::polynomialsolverreport*>(rhs.p_struct), &_state, ae_false);
    3721           0 :     ae_state_clear(&_state);
    3722           0 :     return *this;
    3723             : }
    3724             : 
    3725           0 : _polynomialsolverreport_owner::~_polynomialsolverreport_owner()
    3726             : {
    3727           0 :     if( p_struct!=NULL )
    3728             :     {
    3729           0 :         alglib_impl::_polynomialsolverreport_destroy(p_struct);
    3730           0 :         ae_free(p_struct);
    3731             :     }
    3732           0 : }
    3733             : 
    3734           0 : alglib_impl::polynomialsolverreport* _polynomialsolverreport_owner::c_ptr()
    3735             : {
    3736           0 :     return p_struct;
    3737             : }
    3738             : 
    3739           0 : alglib_impl::polynomialsolverreport* _polynomialsolverreport_owner::c_ptr() const
    3740             : {
    3741           0 :     return const_cast<alglib_impl::polynomialsolverreport*>(p_struct);
    3742             : }
    3743           0 : polynomialsolverreport::polynomialsolverreport() : _polynomialsolverreport_owner() ,maxerr(p_struct->maxerr)
    3744             : {
    3745           0 : }
    3746             : 
    3747           0 : polynomialsolverreport::polynomialsolverreport(const polynomialsolverreport &rhs):_polynomialsolverreport_owner(rhs) ,maxerr(p_struct->maxerr)
    3748             : {
    3749           0 : }
    3750             : 
    3751           0 : polynomialsolverreport& polynomialsolverreport::operator=(const polynomialsolverreport &rhs)
    3752             : {
    3753           0 :     if( this==&rhs )
    3754           0 :         return *this;
    3755           0 :     _polynomialsolverreport_owner::operator=(rhs);
    3756           0 :     return *this;
    3757             : }
    3758             : 
    3759           0 : polynomialsolverreport::~polynomialsolverreport()
    3760             : {
    3761           0 : }
    3762             : 
    3763             : /*************************************************************************
    3764             : Polynomial root finding.
    3765             : 
    3766             : This function returns all roots of the polynomial
    3767             :     P(x) = a0 + a1*x + a2*x^2 + ... + an*x^n
    3768             : Both real and complex roots are returned (see below).
    3769             : 
    3770             : INPUT PARAMETERS:
    3771             :     A       -   array[N+1], polynomial coefficients:
    3772             :                 * A[0] is constant term
    3773             :                 * A[N] is a coefficient of X^N
    3774             :     N       -   polynomial degree
    3775             : 
    3776             : OUTPUT PARAMETERS:
    3777             :     X       -   array of complex roots:
    3778             :                 * for isolated real root, X[I] is strictly real: IMAGE(X[I])=0
    3779             :                 * complex roots are always returned in pairs - roots occupy
    3780             :                   positions I and I+1, with:
    3781             :                   * X[I+1]=Conj(X[I])
    3782             :                   * IMAGE(X[I]) > 0
    3783             :                   * IMAGE(X[I+1]) = -IMAGE(X[I]) < 0
    3784             :                 * multiple real roots may have non-zero imaginary part due
    3785             :                   to roundoff errors. There is no reliable way to distinguish
    3786             :                   real root of multiplicity 2 from two  complex  roots  in
    3787             :                   the presence of roundoff errors.
    3788             :     Rep     -   report, additional information, following fields are set:
    3789             :                 * Rep.MaxErr - max( |P(xi)| )  for  i=0..N-1.  This  field
    3790             :                   allows to quickly estimate "quality" of the roots  being
    3791             :                   returned.
    3792             : 
    3793             : NOTE:   this function uses companion matrix method to find roots. In  case
    3794             :         internal EVD  solver  fails  do  find  eigenvalues,  exception  is
    3795             :         generated.
    3796             : 
    3797             : NOTE:   roots are not "polished" and  no  matrix  balancing  is  performed
    3798             :         for them.
    3799             : 
    3800             :   -- ALGLIB --
    3801             :      Copyright 24.02.2014 by Bochkanov Sergey
    3802             : *************************************************************************/
    3803           0 : void polynomialsolve(const real_1d_array &a, const ae_int_t n, complex_1d_array &x, polynomialsolverreport &rep, const xparams _xparams)
    3804             : {
    3805             :     jmp_buf _break_jump;
    3806             :     alglib_impl::ae_state _alglib_env_state;
    3807           0 :     alglib_impl::ae_state_init(&_alglib_env_state);
    3808           0 :     if( setjmp(_break_jump) )
    3809             :     {
    3810             : #if !defined(AE_NO_EXCEPTIONS)
    3811           0 :         _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
    3812             : #else
    3813             :         _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
    3814             :         return;
    3815             : #endif
    3816             :     }
    3817           0 :     ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
    3818           0 :     if( _xparams.flags!=0x0 )
    3819           0 :         ae_state_set_flags(&_alglib_env_state, _xparams.flags);
    3820           0 :     alglib_impl::polynomialsolve(const_cast<alglib_impl::ae_vector*>(a.c_ptr()), n, const_cast<alglib_impl::ae_vector*>(x.c_ptr()), const_cast<alglib_impl::polynomialsolverreport*>(rep.c_ptr()), &_alglib_env_state);
    3821           0 :     alglib_impl::ae_state_clear(&_alglib_env_state);
    3822           0 :     return;
    3823             : }
    3824             : #endif
    3825             : 
    3826             : #if defined(AE_COMPILE_NLEQ) || !defined(AE_PARTIAL_BUILD)
    3827             : /*************************************************************************
    3828             : 
    3829             : *************************************************************************/
    3830           0 : _nleqstate_owner::_nleqstate_owner()
    3831             : {
    3832             :     jmp_buf _break_jump;
    3833             :     alglib_impl::ae_state _state;
    3834             :     
    3835           0 :     alglib_impl::ae_state_init(&_state);
    3836           0 :     if( setjmp(_break_jump) )
    3837             :     {
    3838           0 :         if( p_struct!=NULL )
    3839             :         {
    3840           0 :             alglib_impl::_nleqstate_destroy(p_struct);
    3841           0 :             alglib_impl::ae_free(p_struct);
    3842             :         }
    3843           0 :         p_struct = NULL;
    3844             : #if !defined(AE_NO_EXCEPTIONS)
    3845           0 :         _ALGLIB_CPP_EXCEPTION(_state.error_msg);
    3846             : #else
    3847             :         _ALGLIB_SET_ERROR_FLAG(_state.error_msg);
    3848             :         return;
    3849             : #endif
    3850             :     }
    3851           0 :     alglib_impl::ae_state_set_break_jump(&_state, &_break_jump);
    3852           0 :     p_struct = NULL;
    3853           0 :     p_struct = (alglib_impl::nleqstate*)alglib_impl::ae_malloc(sizeof(alglib_impl::nleqstate), &_state);
    3854           0 :     memset(p_struct, 0, sizeof(alglib_impl::nleqstate));
    3855           0 :     alglib_impl::_nleqstate_init(p_struct, &_state, ae_false);
    3856           0 :     ae_state_clear(&_state);
    3857           0 : }
    3858             : 
    3859           0 : _nleqstate_owner::_nleqstate_owner(const _nleqstate_owner &rhs)
    3860             : {
    3861             :     jmp_buf _break_jump;
    3862             :     alglib_impl::ae_state _state;
    3863             :     
    3864           0 :     alglib_impl::ae_state_init(&_state);
    3865           0 :     if( setjmp(_break_jump) )
    3866             :     {
    3867           0 :         if( p_struct!=NULL )
    3868             :         {
    3869           0 :             alglib_impl::_nleqstate_destroy(p_struct);
    3870           0 :             alglib_impl::ae_free(p_struct);
    3871             :         }
    3872           0 :         p_struct = NULL;
    3873             : #if !defined(AE_NO_EXCEPTIONS)
    3874           0 :         _ALGLIB_CPP_EXCEPTION(_state.error_msg);
    3875             : #else
    3876             :         _ALGLIB_SET_ERROR_FLAG(_state.error_msg);
    3877             :         return;
    3878             : #endif
    3879             :     }
    3880           0 :     alglib_impl::ae_state_set_break_jump(&_state, &_break_jump);
    3881           0 :     p_struct = NULL;
    3882           0 :     alglib_impl::ae_assert(rhs.p_struct!=NULL, "ALGLIB: nleqstate copy constructor failure (source is not initialized)", &_state);
    3883           0 :     p_struct = (alglib_impl::nleqstate*)alglib_impl::ae_malloc(sizeof(alglib_impl::nleqstate), &_state);
    3884           0 :     memset(p_struct, 0, sizeof(alglib_impl::nleqstate));
    3885           0 :     alglib_impl::_nleqstate_init_copy(p_struct, const_cast<alglib_impl::nleqstate*>(rhs.p_struct), &_state, ae_false);
    3886           0 :     ae_state_clear(&_state);
    3887           0 : }
    3888             : 
    3889           0 : _nleqstate_owner& _nleqstate_owner::operator=(const _nleqstate_owner &rhs)
    3890             : {
    3891           0 :     if( this==&rhs )
    3892           0 :         return *this;
    3893             :     jmp_buf _break_jump;
    3894             :     alglib_impl::ae_state _state;
    3895             :     
    3896           0 :     alglib_impl::ae_state_init(&_state);
    3897           0 :     if( setjmp(_break_jump) )
    3898             :     {
    3899             : #if !defined(AE_NO_EXCEPTIONS)
    3900           0 :         _ALGLIB_CPP_EXCEPTION(_state.error_msg);
    3901             : #else
    3902             :         _ALGLIB_SET_ERROR_FLAG(_state.error_msg);
    3903             :         return *this;
    3904             : #endif
    3905             :     }
    3906           0 :     alglib_impl::ae_state_set_break_jump(&_state, &_break_jump);
    3907           0 :     alglib_impl::ae_assert(p_struct!=NULL, "ALGLIB: nleqstate assignment constructor failure (destination is not initialized)", &_state);
    3908           0 :     alglib_impl::ae_assert(rhs.p_struct!=NULL, "ALGLIB: nleqstate assignment constructor failure (source is not initialized)", &_state);
    3909           0 :     alglib_impl::_nleqstate_destroy(p_struct);
    3910           0 :     memset(p_struct, 0, sizeof(alglib_impl::nleqstate));
    3911           0 :     alglib_impl::_nleqstate_init_copy(p_struct, const_cast<alglib_impl::nleqstate*>(rhs.p_struct), &_state, ae_false);
    3912           0 :     ae_state_clear(&_state);
    3913           0 :     return *this;
    3914             : }
    3915             : 
    3916           0 : _nleqstate_owner::~_nleqstate_owner()
    3917             : {
    3918           0 :     if( p_struct!=NULL )
    3919             :     {
    3920           0 :         alglib_impl::_nleqstate_destroy(p_struct);
    3921           0 :         ae_free(p_struct);
    3922             :     }
    3923           0 : }
    3924             : 
    3925           0 : alglib_impl::nleqstate* _nleqstate_owner::c_ptr()
    3926             : {
    3927           0 :     return p_struct;
    3928             : }
    3929             : 
    3930           0 : alglib_impl::nleqstate* _nleqstate_owner::c_ptr() const
    3931             : {
    3932           0 :     return const_cast<alglib_impl::nleqstate*>(p_struct);
    3933             : }
    3934           0 : nleqstate::nleqstate() : _nleqstate_owner() ,needf(p_struct->needf),needfij(p_struct->needfij),xupdated(p_struct->xupdated),f(p_struct->f),fi(&p_struct->fi),j(&p_struct->j),x(&p_struct->x)
    3935             : {
    3936           0 : }
    3937             : 
    3938           0 : nleqstate::nleqstate(const nleqstate &rhs):_nleqstate_owner(rhs) ,needf(p_struct->needf),needfij(p_struct->needfij),xupdated(p_struct->xupdated),f(p_struct->f),fi(&p_struct->fi),j(&p_struct->j),x(&p_struct->x)
    3939             : {
    3940           0 : }
    3941             : 
    3942           0 : nleqstate& nleqstate::operator=(const nleqstate &rhs)
    3943             : {
    3944           0 :     if( this==&rhs )
    3945           0 :         return *this;
    3946           0 :     _nleqstate_owner::operator=(rhs);
    3947           0 :     return *this;
    3948             : }
    3949             : 
    3950           0 : nleqstate::~nleqstate()
    3951             : {
    3952           0 : }
    3953             : 
    3954             : 
    3955             : /*************************************************************************
    3956             : 
    3957             : *************************************************************************/
    3958           0 : _nleqreport_owner::_nleqreport_owner()
    3959             : {
    3960             :     jmp_buf _break_jump;
    3961             :     alglib_impl::ae_state _state;
    3962             :     
    3963           0 :     alglib_impl::ae_state_init(&_state);
    3964           0 :     if( setjmp(_break_jump) )
    3965             :     {
    3966           0 :         if( p_struct!=NULL )
    3967             :         {
    3968           0 :             alglib_impl::_nleqreport_destroy(p_struct);
    3969           0 :             alglib_impl::ae_free(p_struct);
    3970             :         }
    3971           0 :         p_struct = NULL;
    3972             : #if !defined(AE_NO_EXCEPTIONS)
    3973           0 :         _ALGLIB_CPP_EXCEPTION(_state.error_msg);
    3974             : #else
    3975             :         _ALGLIB_SET_ERROR_FLAG(_state.error_msg);
    3976             :         return;
    3977             : #endif
    3978             :     }
    3979           0 :     alglib_impl::ae_state_set_break_jump(&_state, &_break_jump);
    3980           0 :     p_struct = NULL;
    3981           0 :     p_struct = (alglib_impl::nleqreport*)alglib_impl::ae_malloc(sizeof(alglib_impl::nleqreport), &_state);
    3982           0 :     memset(p_struct, 0, sizeof(alglib_impl::nleqreport));
    3983           0 :     alglib_impl::_nleqreport_init(p_struct, &_state, ae_false);
    3984           0 :     ae_state_clear(&_state);
    3985           0 : }
    3986             : 
    3987           0 : _nleqreport_owner::_nleqreport_owner(const _nleqreport_owner &rhs)
    3988             : {
    3989             :     jmp_buf _break_jump;
    3990             :     alglib_impl::ae_state _state;
    3991             :     
    3992           0 :     alglib_impl::ae_state_init(&_state);
    3993           0 :     if( setjmp(_break_jump) )
    3994             :     {
    3995           0 :         if( p_struct!=NULL )
    3996             :         {
    3997           0 :             alglib_impl::_nleqreport_destroy(p_struct);
    3998           0 :             alglib_impl::ae_free(p_struct);
    3999             :         }
    4000           0 :         p_struct = NULL;
    4001             : #if !defined(AE_NO_EXCEPTIONS)
    4002           0 :         _ALGLIB_CPP_EXCEPTION(_state.error_msg);
    4003             : #else
    4004             :         _ALGLIB_SET_ERROR_FLAG(_state.error_msg);
    4005             :         return;
    4006             : #endif
    4007             :     }
    4008           0 :     alglib_impl::ae_state_set_break_jump(&_state, &_break_jump);
    4009           0 :     p_struct = NULL;
    4010           0 :     alglib_impl::ae_assert(rhs.p_struct!=NULL, "ALGLIB: nleqreport copy constructor failure (source is not initialized)", &_state);
    4011           0 :     p_struct = (alglib_impl::nleqreport*)alglib_impl::ae_malloc(sizeof(alglib_impl::nleqreport), &_state);
    4012           0 :     memset(p_struct, 0, sizeof(alglib_impl::nleqreport));
    4013           0 :     alglib_impl::_nleqreport_init_copy(p_struct, const_cast<alglib_impl::nleqreport*>(rhs.p_struct), &_state, ae_false);
    4014           0 :     ae_state_clear(&_state);
    4015           0 : }
    4016             : 
    4017           0 : _nleqreport_owner& _nleqreport_owner::operator=(const _nleqreport_owner &rhs)
    4018             : {
    4019           0 :     if( this==&rhs )
    4020           0 :         return *this;
    4021             :     jmp_buf _break_jump;
    4022             :     alglib_impl::ae_state _state;
    4023             :     
    4024           0 :     alglib_impl::ae_state_init(&_state);
    4025           0 :     if( setjmp(_break_jump) )
    4026             :     {
    4027             : #if !defined(AE_NO_EXCEPTIONS)
    4028           0 :         _ALGLIB_CPP_EXCEPTION(_state.error_msg);
    4029             : #else
    4030             :         _ALGLIB_SET_ERROR_FLAG(_state.error_msg);
    4031             :         return *this;
    4032             : #endif
    4033             :     }
    4034           0 :     alglib_impl::ae_state_set_break_jump(&_state, &_break_jump);
    4035           0 :     alglib_impl::ae_assert(p_struct!=NULL, "ALGLIB: nleqreport assignment constructor failure (destination is not initialized)", &_state);
    4036           0 :     alglib_impl::ae_assert(rhs.p_struct!=NULL, "ALGLIB: nleqreport assignment constructor failure (source is not initialized)", &_state);
    4037           0 :     alglib_impl::_nleqreport_destroy(p_struct);
    4038           0 :     memset(p_struct, 0, sizeof(alglib_impl::nleqreport));
    4039           0 :     alglib_impl::_nleqreport_init_copy(p_struct, const_cast<alglib_impl::nleqreport*>(rhs.p_struct), &_state, ae_false);
    4040           0 :     ae_state_clear(&_state);
    4041           0 :     return *this;
    4042             : }
    4043             : 
    4044           0 : _nleqreport_owner::~_nleqreport_owner()
    4045             : {
    4046           0 :     if( p_struct!=NULL )
    4047             :     {
    4048           0 :         alglib_impl::_nleqreport_destroy(p_struct);
    4049           0 :         ae_free(p_struct);
    4050             :     }
    4051           0 : }
    4052             : 
    4053           0 : alglib_impl::nleqreport* _nleqreport_owner::c_ptr()
    4054             : {
    4055           0 :     return p_struct;
    4056             : }
    4057             : 
    4058           0 : alglib_impl::nleqreport* _nleqreport_owner::c_ptr() const
    4059             : {
    4060           0 :     return const_cast<alglib_impl::nleqreport*>(p_struct);
    4061             : }
    4062           0 : nleqreport::nleqreport() : _nleqreport_owner() ,iterationscount(p_struct->iterationscount),nfunc(p_struct->nfunc),njac(p_struct->njac),terminationtype(p_struct->terminationtype)
    4063             : {
    4064           0 : }
    4065             : 
    4066           0 : nleqreport::nleqreport(const nleqreport &rhs):_nleqreport_owner(rhs) ,iterationscount(p_struct->iterationscount),nfunc(p_struct->nfunc),njac(p_struct->njac),terminationtype(p_struct->terminationtype)
    4067             : {
    4068           0 : }
    4069             : 
    4070           0 : nleqreport& nleqreport::operator=(const nleqreport &rhs)
    4071             : {
    4072           0 :     if( this==&rhs )
    4073           0 :         return *this;
    4074           0 :     _nleqreport_owner::operator=(rhs);
    4075           0 :     return *this;
    4076             : }
    4077             : 
    4078           0 : nleqreport::~nleqreport()
    4079             : {
    4080           0 : }
    4081             : 
    4082             : /*************************************************************************
    4083             :                 LEVENBERG-MARQUARDT-LIKE NONLINEAR SOLVER
    4084             : 
    4085             : DESCRIPTION:
    4086             : This algorithm solves system of nonlinear equations
    4087             :     F[0](x[0], ..., x[n-1])   = 0
    4088             :     F[1](x[0], ..., x[n-1])   = 0
    4089             :     ...
    4090             :     F[M-1](x[0], ..., x[n-1]) = 0
    4091             : with M/N do not necessarily coincide.  Algorithm  converges  quadratically
    4092             : under following conditions:
    4093             :     * the solution set XS is nonempty
    4094             :     * for some xs in XS there exist such neighbourhood N(xs) that:
    4095             :       * vector function F(x) and its Jacobian J(x) are continuously
    4096             :         differentiable on N
    4097             :       * ||F(x)|| provides local error bound on N, i.e. there  exists  such
    4098             :         c1, that ||F(x)||>c1*distance(x,XS)
    4099             : Note that these conditions are much more weaker than usual non-singularity
    4100             : conditions. For example, algorithm will converge for any  affine  function
    4101             : F (whether its Jacobian singular or not).
    4102             : 
    4103             : 
    4104             : REQUIREMENTS:
    4105             : Algorithm will request following information during its operation:
    4106             : * function vector F[] and Jacobian matrix at given point X
    4107             : * value of merit function f(x)=F[0]^2(x)+...+F[M-1]^2(x) at given point X
    4108             : 
    4109             : 
    4110             : USAGE:
    4111             : 1. User initializes algorithm state with NLEQCreateLM() call
    4112             : 2. User tunes solver parameters with  NLEQSetCond(),  NLEQSetStpMax()  and
    4113             :    other functions
    4114             : 3. User  calls  NLEQSolve()  function  which  takes  algorithm  state  and
    4115             :    pointers (delegates, etc.) to callback functions which calculate  merit
    4116             :    function value and Jacobian.
    4117             : 4. User calls NLEQResults() to get solution
    4118             : 5. Optionally, user may call NLEQRestartFrom() to  solve  another  problem
    4119             :    with same parameters (N/M) but another starting  point  and/or  another
    4120             :    function vector. NLEQRestartFrom() allows to reuse already  initialized
    4121             :    structure.
    4122             : 
    4123             : 
    4124             : INPUT PARAMETERS:
    4125             :     N       -   space dimension, N>1:
    4126             :                 * if provided, only leading N elements of X are used
    4127             :                 * if not provided, determined automatically from size of X
    4128             :     M       -   system size
    4129             :     X       -   starting point
    4130             : 
    4131             : 
    4132             : OUTPUT PARAMETERS:
    4133             :     State   -   structure which stores algorithm state
    4134             : 
    4135             : 
    4136             : NOTES:
    4137             : 1. you may tune stopping conditions with NLEQSetCond() function
    4138             : 2. if target function contains exp() or other fast growing functions,  and
    4139             :    optimization algorithm makes too large steps which leads  to  overflow,
    4140             :    use NLEQSetStpMax() function to bound algorithm's steps.
    4141             : 3. this  algorithm  is  a  slightly  modified implementation of the method
    4142             :    described  in  'Levenberg-Marquardt  method  for constrained  nonlinear
    4143             :    equations with strong local convergence properties' by Christian Kanzow
    4144             :    Nobuo Yamashita and Masao Fukushima and further  developed  in  'On the
    4145             :    convergence of a New Levenberg-Marquardt Method'  by  Jin-yan  Fan  and
    4146             :    Ya-Xiang Yuan.
    4147             : 
    4148             : 
    4149             :   -- ALGLIB --
    4150             :      Copyright 20.08.2009 by Bochkanov Sergey
    4151             : *************************************************************************/
    4152           0 : void nleqcreatelm(const ae_int_t n, const ae_int_t m, const real_1d_array &x, nleqstate &state, const xparams _xparams)
    4153             : {
    4154             :     jmp_buf _break_jump;
    4155             :     alglib_impl::ae_state _alglib_env_state;
    4156           0 :     alglib_impl::ae_state_init(&_alglib_env_state);
    4157           0 :     if( setjmp(_break_jump) )
    4158             :     {
    4159             : #if !defined(AE_NO_EXCEPTIONS)
    4160           0 :         _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
    4161             : #else
    4162             :         _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
    4163             :         return;
    4164             : #endif
    4165             :     }
    4166           0 :     ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
    4167           0 :     if( _xparams.flags!=0x0 )
    4168           0 :         ae_state_set_flags(&_alglib_env_state, _xparams.flags);
    4169           0 :     alglib_impl::nleqcreatelm(n, m, const_cast<alglib_impl::ae_vector*>(x.c_ptr()), const_cast<alglib_impl::nleqstate*>(state.c_ptr()), &_alglib_env_state);
    4170           0 :     alglib_impl::ae_state_clear(&_alglib_env_state);
    4171           0 :     return;
    4172             : }
    4173             : 
    4174             : /*************************************************************************
    4175             :                 LEVENBERG-MARQUARDT-LIKE NONLINEAR SOLVER
    4176             : 
    4177             : DESCRIPTION:
    4178             : This algorithm solves system of nonlinear equations
    4179             :     F[0](x[0], ..., x[n-1])   = 0
    4180             :     F[1](x[0], ..., x[n-1])   = 0
    4181             :     ...
    4182             :     F[M-1](x[0], ..., x[n-1]) = 0
    4183             : with M/N do not necessarily coincide.  Algorithm  converges  quadratically
    4184             : under following conditions:
    4185             :     * the solution set XS is nonempty
    4186             :     * for some xs in XS there exist such neighbourhood N(xs) that:
    4187             :       * vector function F(x) and its Jacobian J(x) are continuously
    4188             :         differentiable on N
    4189             :       * ||F(x)|| provides local error bound on N, i.e. there  exists  such
    4190             :         c1, that ||F(x)||>c1*distance(x,XS)
    4191             : Note that these conditions are much more weaker than usual non-singularity
    4192             : conditions. For example, algorithm will converge for any  affine  function
    4193             : F (whether its Jacobian singular or not).
    4194             : 
    4195             : 
    4196             : REQUIREMENTS:
    4197             : Algorithm will request following information during its operation:
    4198             : * function vector F[] and Jacobian matrix at given point X
    4199             : * value of merit function f(x)=F[0]^2(x)+...+F[M-1]^2(x) at given point X
    4200             : 
    4201             : 
    4202             : USAGE:
    4203             : 1. User initializes algorithm state with NLEQCreateLM() call
    4204             : 2. User tunes solver parameters with  NLEQSetCond(),  NLEQSetStpMax()  and
    4205             :    other functions
    4206             : 3. User  calls  NLEQSolve()  function  which  takes  algorithm  state  and
    4207             :    pointers (delegates, etc.) to callback functions which calculate  merit
    4208             :    function value and Jacobian.
    4209             : 4. User calls NLEQResults() to get solution
    4210             : 5. Optionally, user may call NLEQRestartFrom() to  solve  another  problem
    4211             :    with same parameters (N/M) but another starting  point  and/or  another
    4212             :    function vector. NLEQRestartFrom() allows to reuse already  initialized
    4213             :    structure.
    4214             : 
    4215             : 
    4216             : INPUT PARAMETERS:
    4217             :     N       -   space dimension, N>1:
    4218             :                 * if provided, only leading N elements of X are used
    4219             :                 * if not provided, determined automatically from size of X
    4220             :     M       -   system size
    4221             :     X       -   starting point
    4222             : 
    4223             : 
    4224             : OUTPUT PARAMETERS:
    4225             :     State   -   structure which stores algorithm state
    4226             : 
    4227             : 
    4228             : NOTES:
    4229             : 1. you may tune stopping conditions with NLEQSetCond() function
    4230             : 2. if target function contains exp() or other fast growing functions,  and
    4231             :    optimization algorithm makes too large steps which leads  to  overflow,
    4232             :    use NLEQSetStpMax() function to bound algorithm's steps.
    4233             : 3. this  algorithm  is  a  slightly  modified implementation of the method
    4234             :    described  in  'Levenberg-Marquardt  method  for constrained  nonlinear
    4235             :    equations with strong local convergence properties' by Christian Kanzow
    4236             :    Nobuo Yamashita and Masao Fukushima and further  developed  in  'On the
    4237             :    convergence of a New Levenberg-Marquardt Method'  by  Jin-yan  Fan  and
    4238             :    Ya-Xiang Yuan.
    4239             : 
    4240             : 
    4241             :   -- ALGLIB --
    4242             :      Copyright 20.08.2009 by Bochkanov Sergey
    4243             : *************************************************************************/
    4244             : #if !defined(AE_NO_EXCEPTIONS)
    4245           0 : void nleqcreatelm(const ae_int_t m, const real_1d_array &x, nleqstate &state, const xparams _xparams)
    4246             : {
    4247             :     jmp_buf _break_jump;
    4248             :     alglib_impl::ae_state _alglib_env_state;    
    4249             :     ae_int_t n;
    4250             : 
    4251           0 :     n = x.length();
    4252           0 :     alglib_impl::ae_state_init(&_alglib_env_state);
    4253           0 :     if( setjmp(_break_jump) )
    4254           0 :         _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
    4255           0 :     ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
    4256           0 :     if( _xparams.flags!=0x0 )
    4257           0 :         ae_state_set_flags(&_alglib_env_state, _xparams.flags);
    4258           0 :     alglib_impl::nleqcreatelm(n, m, const_cast<alglib_impl::ae_vector*>(x.c_ptr()), const_cast<alglib_impl::nleqstate*>(state.c_ptr()), &_alglib_env_state);
    4259             : 
    4260           0 :     alglib_impl::ae_state_clear(&_alglib_env_state);
    4261           0 :     return;
    4262             : }
    4263             : #endif
    4264             : 
    4265             : /*************************************************************************
    4266             : This function sets stopping conditions for the nonlinear solver
    4267             : 
    4268             : INPUT PARAMETERS:
    4269             :     State   -   structure which stores algorithm state
    4270             :     EpsF    -   >=0
    4271             :                 The subroutine finishes  its work if on k+1-th iteration
    4272             :                 the condition ||F||<=EpsF is satisfied
    4273             :     MaxIts  -   maximum number of iterations. If MaxIts=0, the  number  of
    4274             :                 iterations is unlimited.
    4275             : 
    4276             : Passing EpsF=0 and MaxIts=0 simultaneously will lead to  automatic
    4277             : stopping criterion selection (small EpsF).
    4278             : 
    4279             : NOTES:
    4280             : 
    4281             :   -- ALGLIB --
    4282             :      Copyright 20.08.2010 by Bochkanov Sergey
    4283             : *************************************************************************/
    4284           0 : void nleqsetcond(const nleqstate &state, const double epsf, const ae_int_t maxits, const xparams _xparams)
    4285             : {
    4286             :     jmp_buf _break_jump;
    4287             :     alglib_impl::ae_state _alglib_env_state;
    4288           0 :     alglib_impl::ae_state_init(&_alglib_env_state);
    4289           0 :     if( setjmp(_break_jump) )
    4290             :     {
    4291             : #if !defined(AE_NO_EXCEPTIONS)
    4292           0 :         _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
    4293             : #else
    4294             :         _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
    4295             :         return;
    4296             : #endif
    4297             :     }
    4298           0 :     ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
    4299           0 :     if( _xparams.flags!=0x0 )
    4300           0 :         ae_state_set_flags(&_alglib_env_state, _xparams.flags);
    4301           0 :     alglib_impl::nleqsetcond(const_cast<alglib_impl::nleqstate*>(state.c_ptr()), epsf, maxits, &_alglib_env_state);
    4302           0 :     alglib_impl::ae_state_clear(&_alglib_env_state);
    4303           0 :     return;
    4304             : }
    4305             : 
    4306             : /*************************************************************************
    4307             : This function turns on/off reporting.
    4308             : 
    4309             : INPUT PARAMETERS:
    4310             :     State   -   structure which stores algorithm state
    4311             :     NeedXRep-   whether iteration reports are needed or not
    4312             : 
    4313             : If NeedXRep is True, algorithm will call rep() callback function if  it is
    4314             : provided to NLEQSolve().
    4315             : 
    4316             :   -- ALGLIB --
    4317             :      Copyright 20.08.2010 by Bochkanov Sergey
    4318             : *************************************************************************/
    4319           0 : void nleqsetxrep(const nleqstate &state, const bool needxrep, const xparams _xparams)
    4320             : {
    4321             :     jmp_buf _break_jump;
    4322             :     alglib_impl::ae_state _alglib_env_state;
    4323           0 :     alglib_impl::ae_state_init(&_alglib_env_state);
    4324           0 :     if( setjmp(_break_jump) )
    4325             :     {
    4326             : #if !defined(AE_NO_EXCEPTIONS)
    4327           0 :         _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
    4328             : #else
    4329             :         _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
    4330             :         return;
    4331             : #endif
    4332             :     }
    4333           0 :     ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
    4334           0 :     if( _xparams.flags!=0x0 )
    4335           0 :         ae_state_set_flags(&_alglib_env_state, _xparams.flags);
    4336           0 :     alglib_impl::nleqsetxrep(const_cast<alglib_impl::nleqstate*>(state.c_ptr()), needxrep, &_alglib_env_state);
    4337           0 :     alglib_impl::ae_state_clear(&_alglib_env_state);
    4338           0 :     return;
    4339             : }
    4340             : 
    4341             : /*************************************************************************
    4342             : This function sets maximum step length
    4343             : 
    4344             : INPUT PARAMETERS:
    4345             :     State   -   structure which stores algorithm state
    4346             :     StpMax  -   maximum step length, >=0. Set StpMax to 0.0,  if you don't
    4347             :                 want to limit step length.
    4348             : 
    4349             : Use this subroutine when target function  contains  exp()  or  other  fast
    4350             : growing functions, and algorithm makes  too  large  steps  which  lead  to
    4351             : overflow. This function allows us to reject steps that are too large  (and
    4352             : therefore expose us to the possible overflow) without actually calculating
    4353             : function value at the x+stp*d.
    4354             : 
    4355             :   -- ALGLIB --
    4356             :      Copyright 20.08.2010 by Bochkanov Sergey
    4357             : *************************************************************************/
    4358           0 : void nleqsetstpmax(const nleqstate &state, const double stpmax, const xparams _xparams)
    4359             : {
    4360             :     jmp_buf _break_jump;
    4361             :     alglib_impl::ae_state _alglib_env_state;
    4362           0 :     alglib_impl::ae_state_init(&_alglib_env_state);
    4363           0 :     if( setjmp(_break_jump) )
    4364             :     {
    4365             : #if !defined(AE_NO_EXCEPTIONS)
    4366           0 :         _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
    4367             : #else
    4368             :         _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
    4369             :         return;
    4370             : #endif
    4371             :     }
    4372           0 :     ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
    4373           0 :     if( _xparams.flags!=0x0 )
    4374           0 :         ae_state_set_flags(&_alglib_env_state, _xparams.flags);
    4375           0 :     alglib_impl::nleqsetstpmax(const_cast<alglib_impl::nleqstate*>(state.c_ptr()), stpmax, &_alglib_env_state);
    4376           0 :     alglib_impl::ae_state_clear(&_alglib_env_state);
    4377           0 :     return;
    4378             : }
    4379             : 
    4380             : /*************************************************************************
    4381             : This function provides reverse communication interface
    4382             : Reverse communication interface is not documented or recommended to use.
    4383             : See below for functions which provide better documented API
    4384             : *************************************************************************/
    4385           0 : bool nleqiteration(const nleqstate &state, const xparams _xparams)
    4386             : {
    4387             :     jmp_buf _break_jump;
    4388             :     alglib_impl::ae_state _alglib_env_state;
    4389           0 :     alglib_impl::ae_state_init(&_alglib_env_state);
    4390           0 :     if( setjmp(_break_jump) )
    4391             :     {
    4392             : #if !defined(AE_NO_EXCEPTIONS)
    4393           0 :         _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
    4394             : #else
    4395             :         _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
    4396             :         return 0;
    4397             : #endif
    4398             :     }
    4399           0 :     ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
    4400           0 :     if( _xparams.flags!=0x0 )
    4401           0 :         ae_state_set_flags(&_alglib_env_state, _xparams.flags);
    4402           0 :     ae_bool result = alglib_impl::nleqiteration(const_cast<alglib_impl::nleqstate*>(state.c_ptr()), &_alglib_env_state);
    4403           0 :     alglib_impl::ae_state_clear(&_alglib_env_state);
    4404           0 :     return *(reinterpret_cast<bool*>(&result));
    4405             : }
    4406             : 
    4407             : 
    4408           0 : void nleqsolve(nleqstate &state,
    4409             :     void (*func)(const real_1d_array &x, double &func, void *ptr),
    4410             :     void  (*jac)(const real_1d_array &x, real_1d_array &fi, real_2d_array &jac, void *ptr),
    4411             :     void  (*rep)(const real_1d_array &x, double func, void *ptr), 
    4412             :     void *ptr,
    4413             :     const xparams _xparams)
    4414             : {
    4415             :     jmp_buf _break_jump;
    4416             :     alglib_impl::ae_state _alglib_env_state;
    4417           0 :     alglib_impl::ae_state_init(&_alglib_env_state);
    4418           0 :     if( setjmp(_break_jump) )
    4419             :     {
    4420             : #if !defined(AE_NO_EXCEPTIONS)
    4421           0 :         _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
    4422             : #else
    4423             :         _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
    4424             :         return;
    4425             : #endif
    4426             :     }
    4427           0 :     ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
    4428           0 :     if( _xparams.flags!=0x0 )
    4429           0 :         ae_state_set_flags(&_alglib_env_state, _xparams.flags);
    4430           0 :     alglib_impl::ae_assert(func!=NULL, "ALGLIB: error in 'nleqsolve()' (func is NULL)", &_alglib_env_state);
    4431           0 :     alglib_impl::ae_assert(jac!=NULL,  "ALGLIB: error in 'nleqsolve()' (jac is NULL)", &_alglib_env_state);
    4432           0 :     while( alglib_impl::nleqiteration(state.c_ptr(), &_alglib_env_state) )
    4433             :     {
    4434             :         _ALGLIB_CALLBACK_EXCEPTION_GUARD_BEGIN
    4435           0 :                 if( state.needf )
    4436             :                 {
    4437           0 :                     func(state.x, state.f, ptr);
    4438           0 :                     continue;
    4439             :                 }
    4440           0 :                 if( state.needfij )
    4441             :                 {
    4442           0 :                     jac(state.x, state.fi, state.j, ptr);
    4443           0 :                     continue;
    4444             :                 }
    4445           0 :         if( state.xupdated )
    4446             :         {
    4447           0 :             if( rep!=NULL )
    4448           0 :                 rep(state.x, state.f, ptr);
    4449           0 :             continue;
    4450             :         }
    4451           0 :         goto lbl_no_callback;
    4452           0 :         _ALGLIB_CALLBACK_EXCEPTION_GUARD_END
    4453           0 :     lbl_no_callback:
    4454           0 :         alglib_impl::ae_assert(ae_false, "ALGLIB: error in 'nleqsolve' (some derivatives were not provided?)", &_alglib_env_state);
    4455             :     }
    4456           0 :     alglib_impl::ae_state_clear(&_alglib_env_state);
    4457           0 : }
    4458             : 
    4459             : 
    4460             : 
    4461             : /*************************************************************************
    4462             : NLEQ solver results
    4463             : 
    4464             : INPUT PARAMETERS:
    4465             :     State   -   algorithm state.
    4466             : 
    4467             : OUTPUT PARAMETERS:
    4468             :     X       -   array[0..N-1], solution
    4469             :     Rep     -   optimization report:
    4470             :                 * Rep.TerminationType completetion code:
    4471             :                     * -4    ERROR:  algorithm   has   converged   to   the
    4472             :                             stationary point Xf which is local minimum  of
    4473             :                             f=F[0]^2+...+F[m-1]^2, but is not solution  of
    4474             :                             nonlinear system.
    4475             :                     *  1    sqrt(f)<=EpsF.
    4476             :                     *  5    MaxIts steps was taken
    4477             :                     *  7    stopping conditions are too stringent,
    4478             :                             further improvement is impossible
    4479             :                 * Rep.IterationsCount contains iterations count
    4480             :                 * NFEV countains number of function calculations
    4481             :                 * ActiveConstraints contains number of active constraints
    4482             : 
    4483             :   -- ALGLIB --
    4484             :      Copyright 20.08.2009 by Bochkanov Sergey
    4485             : *************************************************************************/
    4486           0 : void nleqresults(const nleqstate &state, real_1d_array &x, nleqreport &rep, const xparams _xparams)
    4487             : {
    4488             :     jmp_buf _break_jump;
    4489             :     alglib_impl::ae_state _alglib_env_state;
    4490           0 :     alglib_impl::ae_state_init(&_alglib_env_state);
    4491           0 :     if( setjmp(_break_jump) )
    4492             :     {
    4493             : #if !defined(AE_NO_EXCEPTIONS)
    4494           0 :         _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
    4495             : #else
    4496             :         _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
    4497             :         return;
    4498             : #endif
    4499             :     }
    4500           0 :     ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
    4501           0 :     if( _xparams.flags!=0x0 )
    4502           0 :         ae_state_set_flags(&_alglib_env_state, _xparams.flags);
    4503           0 :     alglib_impl::nleqresults(const_cast<alglib_impl::nleqstate*>(state.c_ptr()), const_cast<alglib_impl::ae_vector*>(x.c_ptr()), const_cast<alglib_impl::nleqreport*>(rep.c_ptr()), &_alglib_env_state);
    4504           0 :     alglib_impl::ae_state_clear(&_alglib_env_state);
    4505           0 :     return;
    4506             : }
    4507             : 
    4508             : /*************************************************************************
    4509             : NLEQ solver results
    4510             : 
    4511             : Buffered implementation of NLEQResults(), which uses pre-allocated  buffer
    4512             : to store X[]. If buffer size is  too  small,  it  resizes  buffer.  It  is
    4513             : intended to be used in the inner cycles of performance critical algorithms
    4514             : where array reallocation penalty is too large to be ignored.
    4515             : 
    4516             :   -- ALGLIB --
    4517             :      Copyright 20.08.2009 by Bochkanov Sergey
    4518             : *************************************************************************/
    4519           0 : void nleqresultsbuf(const nleqstate &state, real_1d_array &x, nleqreport &rep, const xparams _xparams)
    4520             : {
    4521             :     jmp_buf _break_jump;
    4522             :     alglib_impl::ae_state _alglib_env_state;
    4523           0 :     alglib_impl::ae_state_init(&_alglib_env_state);
    4524           0 :     if( setjmp(_break_jump) )
    4525             :     {
    4526             : #if !defined(AE_NO_EXCEPTIONS)
    4527           0 :         _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
    4528             : #else
    4529             :         _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
    4530             :         return;
    4531             : #endif
    4532             :     }
    4533           0 :     ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
    4534           0 :     if( _xparams.flags!=0x0 )
    4535           0 :         ae_state_set_flags(&_alglib_env_state, _xparams.flags);
    4536           0 :     alglib_impl::nleqresultsbuf(const_cast<alglib_impl::nleqstate*>(state.c_ptr()), const_cast<alglib_impl::ae_vector*>(x.c_ptr()), const_cast<alglib_impl::nleqreport*>(rep.c_ptr()), &_alglib_env_state);
    4537           0 :     alglib_impl::ae_state_clear(&_alglib_env_state);
    4538           0 :     return;
    4539             : }
    4540             : 
    4541             : /*************************************************************************
    4542             : This  subroutine  restarts  CG  algorithm from new point. All optimization
    4543             : parameters are left unchanged.
    4544             : 
    4545             : This  function  allows  to  solve multiple  optimization  problems  (which
    4546             : must have same number of dimensions) without object reallocation penalty.
    4547             : 
    4548             : INPUT PARAMETERS:
    4549             :     State   -   structure used for reverse communication previously
    4550             :                 allocated with MinCGCreate call.
    4551             :     X       -   new starting point.
    4552             :     BndL    -   new lower bounds
    4553             :     BndU    -   new upper bounds
    4554             : 
    4555             :   -- ALGLIB --
    4556             :      Copyright 30.07.2010 by Bochkanov Sergey
    4557             : *************************************************************************/
    4558           0 : void nleqrestartfrom(const nleqstate &state, const real_1d_array &x, const xparams _xparams)
    4559             : {
    4560             :     jmp_buf _break_jump;
    4561             :     alglib_impl::ae_state _alglib_env_state;
    4562           0 :     alglib_impl::ae_state_init(&_alglib_env_state);
    4563           0 :     if( setjmp(_break_jump) )
    4564             :     {
    4565             : #if !defined(AE_NO_EXCEPTIONS)
    4566           0 :         _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
    4567             : #else
    4568             :         _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
    4569             :         return;
    4570             : #endif
    4571             :     }
    4572           0 :     ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
    4573           0 :     if( _xparams.flags!=0x0 )
    4574           0 :         ae_state_set_flags(&_alglib_env_state, _xparams.flags);
    4575           0 :     alglib_impl::nleqrestartfrom(const_cast<alglib_impl::nleqstate*>(state.c_ptr()), const_cast<alglib_impl::ae_vector*>(x.c_ptr()), &_alglib_env_state);
    4576           0 :     alglib_impl::ae_state_clear(&_alglib_env_state);
    4577           0 :     return;
    4578             : }
    4579             : #endif
    4580             : 
    4581             : #if defined(AE_COMPILE_DIRECTSPARSESOLVERS) || !defined(AE_PARTIAL_BUILD)
    4582             : /*************************************************************************
    4583             : This structure is a sparse solver report.
    4584             : 
    4585             : Following fields can be accessed by users:
    4586             : *************************************************************************/
    4587           0 : _sparsesolverreport_owner::_sparsesolverreport_owner()
    4588             : {
    4589             :     jmp_buf _break_jump;
    4590             :     alglib_impl::ae_state _state;
    4591             :     
    4592           0 :     alglib_impl::ae_state_init(&_state);
    4593           0 :     if( setjmp(_break_jump) )
    4594             :     {
    4595           0 :         if( p_struct!=NULL )
    4596             :         {
    4597           0 :             alglib_impl::_sparsesolverreport_destroy(p_struct);
    4598           0 :             alglib_impl::ae_free(p_struct);
    4599             :         }
    4600           0 :         p_struct = NULL;
    4601             : #if !defined(AE_NO_EXCEPTIONS)
    4602           0 :         _ALGLIB_CPP_EXCEPTION(_state.error_msg);
    4603             : #else
    4604             :         _ALGLIB_SET_ERROR_FLAG(_state.error_msg);
    4605             :         return;
    4606             : #endif
    4607             :     }
    4608           0 :     alglib_impl::ae_state_set_break_jump(&_state, &_break_jump);
    4609           0 :     p_struct = NULL;
    4610           0 :     p_struct = (alglib_impl::sparsesolverreport*)alglib_impl::ae_malloc(sizeof(alglib_impl::sparsesolverreport), &_state);
    4611           0 :     memset(p_struct, 0, sizeof(alglib_impl::sparsesolverreport));
    4612           0 :     alglib_impl::_sparsesolverreport_init(p_struct, &_state, ae_false);
    4613           0 :     ae_state_clear(&_state);
    4614           0 : }
    4615             : 
    4616           0 : _sparsesolverreport_owner::_sparsesolverreport_owner(const _sparsesolverreport_owner &rhs)
    4617             : {
    4618             :     jmp_buf _break_jump;
    4619             :     alglib_impl::ae_state _state;
    4620             :     
    4621           0 :     alglib_impl::ae_state_init(&_state);
    4622           0 :     if( setjmp(_break_jump) )
    4623             :     {
    4624           0 :         if( p_struct!=NULL )
    4625             :         {
    4626           0 :             alglib_impl::_sparsesolverreport_destroy(p_struct);
    4627           0 :             alglib_impl::ae_free(p_struct);
    4628             :         }
    4629           0 :         p_struct = NULL;
    4630             : #if !defined(AE_NO_EXCEPTIONS)
    4631           0 :         _ALGLIB_CPP_EXCEPTION(_state.error_msg);
    4632             : #else
    4633             :         _ALGLIB_SET_ERROR_FLAG(_state.error_msg);
    4634             :         return;
    4635             : #endif
    4636             :     }
    4637           0 :     alglib_impl::ae_state_set_break_jump(&_state, &_break_jump);
    4638           0 :     p_struct = NULL;
    4639           0 :     alglib_impl::ae_assert(rhs.p_struct!=NULL, "ALGLIB: sparsesolverreport copy constructor failure (source is not initialized)", &_state);
    4640           0 :     p_struct = (alglib_impl::sparsesolverreport*)alglib_impl::ae_malloc(sizeof(alglib_impl::sparsesolverreport), &_state);
    4641           0 :     memset(p_struct, 0, sizeof(alglib_impl::sparsesolverreport));
    4642           0 :     alglib_impl::_sparsesolverreport_init_copy(p_struct, const_cast<alglib_impl::sparsesolverreport*>(rhs.p_struct), &_state, ae_false);
    4643           0 :     ae_state_clear(&_state);
    4644           0 : }
    4645             : 
    4646           0 : _sparsesolverreport_owner& _sparsesolverreport_owner::operator=(const _sparsesolverreport_owner &rhs)
    4647             : {
    4648           0 :     if( this==&rhs )
    4649           0 :         return *this;
    4650             :     jmp_buf _break_jump;
    4651             :     alglib_impl::ae_state _state;
    4652             :     
    4653           0 :     alglib_impl::ae_state_init(&_state);
    4654           0 :     if( setjmp(_break_jump) )
    4655             :     {
    4656             : #if !defined(AE_NO_EXCEPTIONS)
    4657           0 :         _ALGLIB_CPP_EXCEPTION(_state.error_msg);
    4658             : #else
    4659             :         _ALGLIB_SET_ERROR_FLAG(_state.error_msg);
    4660             :         return *this;
    4661             : #endif
    4662             :     }
    4663           0 :     alglib_impl::ae_state_set_break_jump(&_state, &_break_jump);
    4664           0 :     alglib_impl::ae_assert(p_struct!=NULL, "ALGLIB: sparsesolverreport assignment constructor failure (destination is not initialized)", &_state);
    4665           0 :     alglib_impl::ae_assert(rhs.p_struct!=NULL, "ALGLIB: sparsesolverreport assignment constructor failure (source is not initialized)", &_state);
    4666           0 :     alglib_impl::_sparsesolverreport_destroy(p_struct);
    4667           0 :     memset(p_struct, 0, sizeof(alglib_impl::sparsesolverreport));
    4668           0 :     alglib_impl::_sparsesolverreport_init_copy(p_struct, const_cast<alglib_impl::sparsesolverreport*>(rhs.p_struct), &_state, ae_false);
    4669           0 :     ae_state_clear(&_state);
    4670           0 :     return *this;
    4671             : }
    4672             : 
    4673           0 : _sparsesolverreport_owner::~_sparsesolverreport_owner()
    4674             : {
    4675           0 :     if( p_struct!=NULL )
    4676             :     {
    4677           0 :         alglib_impl::_sparsesolverreport_destroy(p_struct);
    4678           0 :         ae_free(p_struct);
    4679             :     }
    4680           0 : }
    4681             : 
    4682           0 : alglib_impl::sparsesolverreport* _sparsesolverreport_owner::c_ptr()
    4683             : {
    4684           0 :     return p_struct;
    4685             : }
    4686             : 
    4687           0 : alglib_impl::sparsesolverreport* _sparsesolverreport_owner::c_ptr() const
    4688             : {
    4689           0 :     return const_cast<alglib_impl::sparsesolverreport*>(p_struct);
    4690             : }
    4691           0 : sparsesolverreport::sparsesolverreport() : _sparsesolverreport_owner() ,terminationtype(p_struct->terminationtype)
    4692             : {
    4693           0 : }
    4694             : 
    4695           0 : sparsesolverreport::sparsesolverreport(const sparsesolverreport &rhs):_sparsesolverreport_owner(rhs) ,terminationtype(p_struct->terminationtype)
    4696             : {
    4697           0 : }
    4698             : 
    4699           0 : sparsesolverreport& sparsesolverreport::operator=(const sparsesolverreport &rhs)
    4700             : {
    4701           0 :     if( this==&rhs )
    4702           0 :         return *this;
    4703           0 :     _sparsesolverreport_owner::operator=(rhs);
    4704           0 :     return *this;
    4705             : }
    4706             : 
    4707           0 : sparsesolverreport::~sparsesolverreport()
    4708             : {
    4709           0 : }
    4710             : 
    4711             : /*************************************************************************
    4712             : Sparse linear solver for A*x=b with N*N  sparse  real  symmetric  positive
    4713             : definite matrix A, N*1 vectors x and b.
    4714             : 
    4715             : This solver  converts  input  matrix  to  SKS  format,  performs  Cholesky
    4716             : factorization using  SKS  Cholesky  subroutine  (works  well  for  limited
    4717             : bandwidth matrices) and uses sparse triangular solvers to get solution  of
    4718             : the original system.
    4719             : 
    4720             : INPUT PARAMETERS
    4721             :     A       -   sparse matrix, must be NxN exactly
    4722             :     IsUpper -   which half of A is provided (another half is ignored)
    4723             :     B       -   array[0..N-1], right part
    4724             : 
    4725             : OUTPUT PARAMETERS
    4726             :     X       -   array[N], it contains:
    4727             :                 * rep.terminationtype>0    =>  solution
    4728             :                 * rep.terminationtype=-3   =>  filled by zeros
    4729             :     Rep     -   solver report, following fields are set:
    4730             :                 * rep.terminationtype - solver status; >0 for success,
    4731             :                   set to -3 on failure (degenerate or non-SPD system).
    4732             : 
    4733             :   -- ALGLIB --
    4734             :      Copyright 26.12.2017 by Bochkanov Sergey
    4735             : *************************************************************************/
    4736           0 : void sparsespdsolvesks(const sparsematrix &a, const bool isupper, const real_1d_array &b, real_1d_array &x, sparsesolverreport &rep, const xparams _xparams)
    4737             : {
    4738             :     jmp_buf _break_jump;
    4739             :     alglib_impl::ae_state _alglib_env_state;
    4740           0 :     alglib_impl::ae_state_init(&_alglib_env_state);
    4741           0 :     if( setjmp(_break_jump) )
    4742             :     {
    4743             : #if !defined(AE_NO_EXCEPTIONS)
    4744           0 :         _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
    4745             : #else
    4746             :         _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
    4747             :         return;
    4748             : #endif
    4749             :     }
    4750           0 :     ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
    4751           0 :     if( _xparams.flags!=0x0 )
    4752           0 :         ae_state_set_flags(&_alglib_env_state, _xparams.flags);
    4753           0 :     alglib_impl::sparsespdsolvesks(const_cast<alglib_impl::sparsematrix*>(a.c_ptr()), isupper, const_cast<alglib_impl::ae_vector*>(b.c_ptr()), const_cast<alglib_impl::ae_vector*>(x.c_ptr()), const_cast<alglib_impl::sparsesolverreport*>(rep.c_ptr()), &_alglib_env_state);
    4754           0 :     alglib_impl::ae_state_clear(&_alglib_env_state);
    4755           0 :     return;
    4756             : }
    4757             : 
    4758             : /*************************************************************************
    4759             : Sparse linear solver for A*x=b with N*N  sparse  real  symmetric  positive
    4760             : definite matrix A, N*1 vectors x and b.
    4761             : 
    4762             : This solver  converts  input  matrix  to  CRS  format,  performs  Cholesky
    4763             : factorization using supernodal Cholesky  decomposition  with  permutation-
    4764             : reducing ordering and uses sparse triangular solver to get solution of the
    4765             : original system.
    4766             : 
    4767             : INPUT PARAMETERS
    4768             :     A       -   sparse matrix, must be NxN exactly
    4769             :     IsUpper -   which half of A is provided (another half is ignored)
    4770             :     B       -   array[N], right part
    4771             : 
    4772             : OUTPUT PARAMETERS
    4773             :     X       -   array[N], it contains:
    4774             :                 * rep.terminationtype>0    =>  solution
    4775             :                 * rep.terminationtype=-3   =>  filled by zeros
    4776             :     Rep     -   solver report, following fields are set:
    4777             :                 * rep.terminationtype - solver status; >0 for success,
    4778             :                   set to -3 on failure (degenerate or non-SPD system).
    4779             : 
    4780             :   -- ALGLIB --
    4781             :      Copyright 26.12.2017 by Bochkanov Sergey
    4782             : *************************************************************************/
    4783           0 : void sparsespdsolve(const sparsematrix &a, const bool isupper, const real_1d_array &b, real_1d_array &x, sparsesolverreport &rep, const xparams _xparams)
    4784             : {
    4785             :     jmp_buf _break_jump;
    4786             :     alglib_impl::ae_state _alglib_env_state;
    4787           0 :     alglib_impl::ae_state_init(&_alglib_env_state);
    4788           0 :     if( setjmp(_break_jump) )
    4789             :     {
    4790             : #if !defined(AE_NO_EXCEPTIONS)
    4791           0 :         _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
    4792             : #else
    4793             :         _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
    4794             :         return;
    4795             : #endif
    4796             :     }
    4797           0 :     ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
    4798           0 :     if( _xparams.flags!=0x0 )
    4799           0 :         ae_state_set_flags(&_alglib_env_state, _xparams.flags);
    4800           0 :     alglib_impl::sparsespdsolve(const_cast<alglib_impl::sparsematrix*>(a.c_ptr()), isupper, const_cast<alglib_impl::ae_vector*>(b.c_ptr()), const_cast<alglib_impl::ae_vector*>(x.c_ptr()), const_cast<alglib_impl::sparsesolverreport*>(rep.c_ptr()), &_alglib_env_state);
    4801           0 :     alglib_impl::ae_state_clear(&_alglib_env_state);
    4802           0 :     return;
    4803             : }
    4804             : 
    4805             : /*************************************************************************
    4806             : Sparse linear solver for A*x=b with N*N real  symmetric  positive definite
    4807             : matrix A given by its Cholesky decomposition, and N*1 vectors x and b.
    4808             : 
    4809             : IMPORTANT: this solver requires input matrix to be in  the  SKS  (Skyline)
    4810             :            or CRS (compressed row storage) format. An  exception  will  be
    4811             :            generated if you pass matrix in some other format.
    4812             : 
    4813             : INPUT PARAMETERS
    4814             :     A       -   sparse NxN matrix stored in CRs or SKS format, must be NxN
    4815             :                 exactly
    4816             :     IsUpper -   which half of A is provided (another half is ignored)
    4817             :     B       -   array[N], right part
    4818             : 
    4819             : OUTPUT PARAMETERS
    4820             :     X       -   array[N], it contains:
    4821             :                 * rep.terminationtype>0    =>  solution
    4822             :                 * rep.terminationtype=-3   =>  filled by zeros
    4823             :     Rep     -   solver report, following fields are set:
    4824             :                 * rep.terminationtype - solver status; >0 for success,
    4825             :                   set to -3 on failure (degenerate or non-SPD system).
    4826             : 
    4827             :   -- ALGLIB --
    4828             :      Copyright 26.12.2017 by Bochkanov Sergey
    4829             : *************************************************************************/
    4830           0 : void sparsespdcholeskysolve(const sparsematrix &a, const bool isupper, const real_1d_array &b, real_1d_array &x, sparsesolverreport &rep, const xparams _xparams)
    4831             : {
    4832             :     jmp_buf _break_jump;
    4833             :     alglib_impl::ae_state _alglib_env_state;
    4834           0 :     alglib_impl::ae_state_init(&_alglib_env_state);
    4835           0 :     if( setjmp(_break_jump) )
    4836             :     {
    4837             : #if !defined(AE_NO_EXCEPTIONS)
    4838           0 :         _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
    4839             : #else
    4840             :         _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
    4841             :         return;
    4842             : #endif
    4843             :     }
    4844           0 :     ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
    4845           0 :     if( _xparams.flags!=0x0 )
    4846           0 :         ae_state_set_flags(&_alglib_env_state, _xparams.flags);
    4847           0 :     alglib_impl::sparsespdcholeskysolve(const_cast<alglib_impl::sparsematrix*>(a.c_ptr()), isupper, const_cast<alglib_impl::ae_vector*>(b.c_ptr()), const_cast<alglib_impl::ae_vector*>(x.c_ptr()), const_cast<alglib_impl::sparsesolverreport*>(rep.c_ptr()), &_alglib_env_state);
    4848           0 :     alglib_impl::ae_state_clear(&_alglib_env_state);
    4849           0 :     return;
    4850             : }
    4851             : 
    4852             : /*************************************************************************
    4853             : Sparse linear solver for A*x=b with general (nonsymmetric) N*N sparse real
    4854             : matrix A, N*1 vectors x and b.
    4855             : 
    4856             : This solver converts input matrix to CRS format, performs LU factorization
    4857             : and uses sparse triangular solvers to get solution of the original system.
    4858             : 
    4859             : INPUT PARAMETERS
    4860             :     A       -   sparse matrix, must be NxN exactly, any storage format
    4861             :     N       -   size of A, N>0
    4862             :     B       -   array[0..N-1], right part
    4863             : 
    4864             : OUTPUT PARAMETERS
    4865             :     X       -   array[N], it contains:
    4866             :                 * rep.terminationtype>0    =>  solution
    4867             :                 * rep.terminationtype=-3   =>  filled by zeros
    4868             :     Rep     -   solver report, following fields are set:
    4869             :                 * rep.terminationtype - solver status; >0 for success,
    4870             :                   set to -3 on failure (degenerate system).
    4871             : 
    4872             :   -- ALGLIB --
    4873             :      Copyright 26.12.2017 by Bochkanov Sergey
    4874             : *************************************************************************/
    4875           0 : void sparsesolve(const sparsematrix &a, const real_1d_array &b, real_1d_array &x, sparsesolverreport &rep, const xparams _xparams)
    4876             : {
    4877             :     jmp_buf _break_jump;
    4878             :     alglib_impl::ae_state _alglib_env_state;
    4879           0 :     alglib_impl::ae_state_init(&_alglib_env_state);
    4880           0 :     if( setjmp(_break_jump) )
    4881             :     {
    4882             : #if !defined(AE_NO_EXCEPTIONS)
    4883           0 :         _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
    4884             : #else
    4885             :         _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
    4886             :         return;
    4887             : #endif
    4888             :     }
    4889           0 :     ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
    4890           0 :     if( _xparams.flags!=0x0 )
    4891           0 :         ae_state_set_flags(&_alglib_env_state, _xparams.flags);
    4892           0 :     alglib_impl::sparsesolve(const_cast<alglib_impl::sparsematrix*>(a.c_ptr()), const_cast<alglib_impl::ae_vector*>(b.c_ptr()), const_cast<alglib_impl::ae_vector*>(x.c_ptr()), const_cast<alglib_impl::sparsesolverreport*>(rep.c_ptr()), &_alglib_env_state);
    4893           0 :     alglib_impl::ae_state_clear(&_alglib_env_state);
    4894           0 :     return;
    4895             : }
    4896             : 
    4897             : /*************************************************************************
    4898             : Sparse linear solver for A*x=b with general (nonsymmetric) N*N sparse real
    4899             : matrix A given by its LU factorization, N*1 vectors x and b.
    4900             : 
    4901             : IMPORTANT: this solver requires input matrix  to  be  in  the  CRS  sparse
    4902             :            storage format. An exception will  be  generated  if  you  pass
    4903             :            matrix in some other format (HASH or SKS).
    4904             : 
    4905             : INPUT PARAMETERS
    4906             :     A       -   LU factorization of the sparse matrix, must be NxN exactly
    4907             :                 in CRS storage format
    4908             :     P, Q    -   pivot indexes from LU factorization
    4909             :     N       -   size of A, N>0
    4910             :     B       -   array[0..N-1], right part
    4911             : 
    4912             : OUTPUT PARAMETERS
    4913             :     X       -   array[N], it contains:
    4914             :                 * rep.terminationtype>0    =>  solution
    4915             :                 * rep.terminationtype=-3   =>  filled by zeros
    4916             :     Rep     -   solver report, following fields are set:
    4917             :                 * rep.terminationtype - solver status; >0 for success,
    4918             :                   set to -3 on failure (degenerate system).
    4919             : 
    4920             :   -- ALGLIB --
    4921             :      Copyright 26.12.2017 by Bochkanov Sergey
    4922             : *************************************************************************/
    4923           0 : void sparselusolve(const sparsematrix &a, const integer_1d_array &p, const integer_1d_array &q, const real_1d_array &b, real_1d_array &x, sparsesolverreport &rep, const xparams _xparams)
    4924             : {
    4925             :     jmp_buf _break_jump;
    4926             :     alglib_impl::ae_state _alglib_env_state;
    4927           0 :     alglib_impl::ae_state_init(&_alglib_env_state);
    4928           0 :     if( setjmp(_break_jump) )
    4929             :     {
    4930             : #if !defined(AE_NO_EXCEPTIONS)
    4931           0 :         _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
    4932             : #else
    4933             :         _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
    4934             :         return;
    4935             : #endif
    4936             :     }
    4937           0 :     ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
    4938           0 :     if( _xparams.flags!=0x0 )
    4939           0 :         ae_state_set_flags(&_alglib_env_state, _xparams.flags);
    4940           0 :     alglib_impl::sparselusolve(const_cast<alglib_impl::sparsematrix*>(a.c_ptr()), const_cast<alglib_impl::ae_vector*>(p.c_ptr()), const_cast<alglib_impl::ae_vector*>(q.c_ptr()), const_cast<alglib_impl::ae_vector*>(b.c_ptr()), const_cast<alglib_impl::ae_vector*>(x.c_ptr()), const_cast<alglib_impl::sparsesolverreport*>(rep.c_ptr()), &_alglib_env_state);
    4941           0 :     alglib_impl::ae_state_clear(&_alglib_env_state);
    4942           0 :     return;
    4943             : }
    4944             : #endif
    4945             : 
    4946             : #if defined(AE_COMPILE_LINCG) || !defined(AE_PARTIAL_BUILD)
    4947             : /*************************************************************************
    4948             : This object stores state of the linear CG method.
    4949             : 
    4950             : You should use ALGLIB functions to work with this object.
    4951             : Never try to access its fields directly!
    4952             : *************************************************************************/
    4953           0 : _lincgstate_owner::_lincgstate_owner()
    4954             : {
    4955             :     jmp_buf _break_jump;
    4956             :     alglib_impl::ae_state _state;
    4957             :     
    4958           0 :     alglib_impl::ae_state_init(&_state);
    4959           0 :     if( setjmp(_break_jump) )
    4960             :     {
    4961           0 :         if( p_struct!=NULL )
    4962             :         {
    4963           0 :             alglib_impl::_lincgstate_destroy(p_struct);
    4964           0 :             alglib_impl::ae_free(p_struct);
    4965             :         }
    4966           0 :         p_struct = NULL;
    4967             : #if !defined(AE_NO_EXCEPTIONS)
    4968           0 :         _ALGLIB_CPP_EXCEPTION(_state.error_msg);
    4969             : #else
    4970             :         _ALGLIB_SET_ERROR_FLAG(_state.error_msg);
    4971             :         return;
    4972             : #endif
    4973             :     }
    4974           0 :     alglib_impl::ae_state_set_break_jump(&_state, &_break_jump);
    4975           0 :     p_struct = NULL;
    4976           0 :     p_struct = (alglib_impl::lincgstate*)alglib_impl::ae_malloc(sizeof(alglib_impl::lincgstate), &_state);
    4977           0 :     memset(p_struct, 0, sizeof(alglib_impl::lincgstate));
    4978           0 :     alglib_impl::_lincgstate_init(p_struct, &_state, ae_false);
    4979           0 :     ae_state_clear(&_state);
    4980           0 : }
    4981             : 
    4982           0 : _lincgstate_owner::_lincgstate_owner(const _lincgstate_owner &rhs)
    4983             : {
    4984             :     jmp_buf _break_jump;
    4985             :     alglib_impl::ae_state _state;
    4986             :     
    4987           0 :     alglib_impl::ae_state_init(&_state);
    4988           0 :     if( setjmp(_break_jump) )
    4989             :     {
    4990           0 :         if( p_struct!=NULL )
    4991             :         {
    4992           0 :             alglib_impl::_lincgstate_destroy(p_struct);
    4993           0 :             alglib_impl::ae_free(p_struct);
    4994             :         }
    4995           0 :         p_struct = NULL;
    4996             : #if !defined(AE_NO_EXCEPTIONS)
    4997           0 :         _ALGLIB_CPP_EXCEPTION(_state.error_msg);
    4998             : #else
    4999             :         _ALGLIB_SET_ERROR_FLAG(_state.error_msg);
    5000             :         return;
    5001             : #endif
    5002             :     }
    5003           0 :     alglib_impl::ae_state_set_break_jump(&_state, &_break_jump);
    5004           0 :     p_struct = NULL;
    5005           0 :     alglib_impl::ae_assert(rhs.p_struct!=NULL, "ALGLIB: lincgstate copy constructor failure (source is not initialized)", &_state);
    5006           0 :     p_struct = (alglib_impl::lincgstate*)alglib_impl::ae_malloc(sizeof(alglib_impl::lincgstate), &_state);
    5007           0 :     memset(p_struct, 0, sizeof(alglib_impl::lincgstate));
    5008           0 :     alglib_impl::_lincgstate_init_copy(p_struct, const_cast<alglib_impl::lincgstate*>(rhs.p_struct), &_state, ae_false);
    5009           0 :     ae_state_clear(&_state);
    5010           0 : }
    5011             : 
    5012           0 : _lincgstate_owner& _lincgstate_owner::operator=(const _lincgstate_owner &rhs)
    5013             : {
    5014           0 :     if( this==&rhs )
    5015           0 :         return *this;
    5016             :     jmp_buf _break_jump;
    5017             :     alglib_impl::ae_state _state;
    5018             :     
    5019           0 :     alglib_impl::ae_state_init(&_state);
    5020           0 :     if( setjmp(_break_jump) )
    5021             :     {
    5022             : #if !defined(AE_NO_EXCEPTIONS)
    5023           0 :         _ALGLIB_CPP_EXCEPTION(_state.error_msg);
    5024             : #else
    5025             :         _ALGLIB_SET_ERROR_FLAG(_state.error_msg);
    5026             :         return *this;
    5027             : #endif
    5028             :     }
    5029           0 :     alglib_impl::ae_state_set_break_jump(&_state, &_break_jump);
    5030           0 :     alglib_impl::ae_assert(p_struct!=NULL, "ALGLIB: lincgstate assignment constructor failure (destination is not initialized)", &_state);
    5031           0 :     alglib_impl::ae_assert(rhs.p_struct!=NULL, "ALGLIB: lincgstate assignment constructor failure (source is not initialized)", &_state);
    5032           0 :     alglib_impl::_lincgstate_destroy(p_struct);
    5033           0 :     memset(p_struct, 0, sizeof(alglib_impl::lincgstate));
    5034           0 :     alglib_impl::_lincgstate_init_copy(p_struct, const_cast<alglib_impl::lincgstate*>(rhs.p_struct), &_state, ae_false);
    5035           0 :     ae_state_clear(&_state);
    5036           0 :     return *this;
    5037             : }
    5038             : 
    5039           0 : _lincgstate_owner::~_lincgstate_owner()
    5040             : {
    5041           0 :     if( p_struct!=NULL )
    5042             :     {
    5043           0 :         alglib_impl::_lincgstate_destroy(p_struct);
    5044           0 :         ae_free(p_struct);
    5045             :     }
    5046           0 : }
    5047             : 
    5048           0 : alglib_impl::lincgstate* _lincgstate_owner::c_ptr()
    5049             : {
    5050           0 :     return p_struct;
    5051             : }
    5052             : 
    5053           0 : alglib_impl::lincgstate* _lincgstate_owner::c_ptr() const
    5054             : {
    5055           0 :     return const_cast<alglib_impl::lincgstate*>(p_struct);
    5056             : }
    5057           0 : lincgstate::lincgstate() : _lincgstate_owner() 
    5058             : {
    5059           0 : }
    5060             : 
    5061           0 : lincgstate::lincgstate(const lincgstate &rhs):_lincgstate_owner(rhs) 
    5062             : {
    5063           0 : }
    5064             : 
    5065           0 : lincgstate& lincgstate::operator=(const lincgstate &rhs)
    5066             : {
    5067           0 :     if( this==&rhs )
    5068           0 :         return *this;
    5069           0 :     _lincgstate_owner::operator=(rhs);
    5070           0 :     return *this;
    5071             : }
    5072             : 
    5073           0 : lincgstate::~lincgstate()
    5074             : {
    5075           0 : }
    5076             : 
    5077             : 
    5078             : /*************************************************************************
    5079             : 
    5080             : *************************************************************************/
    5081           0 : _lincgreport_owner::_lincgreport_owner()
    5082             : {
    5083             :     jmp_buf _break_jump;
    5084             :     alglib_impl::ae_state _state;
    5085             :     
    5086           0 :     alglib_impl::ae_state_init(&_state);
    5087           0 :     if( setjmp(_break_jump) )
    5088             :     {
    5089           0 :         if( p_struct!=NULL )
    5090             :         {
    5091           0 :             alglib_impl::_lincgreport_destroy(p_struct);
    5092           0 :             alglib_impl::ae_free(p_struct);
    5093             :         }
    5094           0 :         p_struct = NULL;
    5095             : #if !defined(AE_NO_EXCEPTIONS)
    5096           0 :         _ALGLIB_CPP_EXCEPTION(_state.error_msg);
    5097             : #else
    5098             :         _ALGLIB_SET_ERROR_FLAG(_state.error_msg);
    5099             :         return;
    5100             : #endif
    5101             :     }
    5102           0 :     alglib_impl::ae_state_set_break_jump(&_state, &_break_jump);
    5103           0 :     p_struct = NULL;
    5104           0 :     p_struct = (alglib_impl::lincgreport*)alglib_impl::ae_malloc(sizeof(alglib_impl::lincgreport), &_state);
    5105           0 :     memset(p_struct, 0, sizeof(alglib_impl::lincgreport));
    5106           0 :     alglib_impl::_lincgreport_init(p_struct, &_state, ae_false);
    5107           0 :     ae_state_clear(&_state);
    5108           0 : }
    5109             : 
    5110           0 : _lincgreport_owner::_lincgreport_owner(const _lincgreport_owner &rhs)
    5111             : {
    5112             :     jmp_buf _break_jump;
    5113             :     alglib_impl::ae_state _state;
    5114             :     
    5115           0 :     alglib_impl::ae_state_init(&_state);
    5116           0 :     if( setjmp(_break_jump) )
    5117             :     {
    5118           0 :         if( p_struct!=NULL )
    5119             :         {
    5120           0 :             alglib_impl::_lincgreport_destroy(p_struct);
    5121           0 :             alglib_impl::ae_free(p_struct);
    5122             :         }
    5123           0 :         p_struct = NULL;
    5124             : #if !defined(AE_NO_EXCEPTIONS)
    5125           0 :         _ALGLIB_CPP_EXCEPTION(_state.error_msg);
    5126             : #else
    5127             :         _ALGLIB_SET_ERROR_FLAG(_state.error_msg);
    5128             :         return;
    5129             : #endif
    5130             :     }
    5131           0 :     alglib_impl::ae_state_set_break_jump(&_state, &_break_jump);
    5132           0 :     p_struct = NULL;
    5133           0 :     alglib_impl::ae_assert(rhs.p_struct!=NULL, "ALGLIB: lincgreport copy constructor failure (source is not initialized)", &_state);
    5134           0 :     p_struct = (alglib_impl::lincgreport*)alglib_impl::ae_malloc(sizeof(alglib_impl::lincgreport), &_state);
    5135           0 :     memset(p_struct, 0, sizeof(alglib_impl::lincgreport));
    5136           0 :     alglib_impl::_lincgreport_init_copy(p_struct, const_cast<alglib_impl::lincgreport*>(rhs.p_struct), &_state, ae_false);
    5137           0 :     ae_state_clear(&_state);
    5138           0 : }
    5139             : 
    5140           0 : _lincgreport_owner& _lincgreport_owner::operator=(const _lincgreport_owner &rhs)
    5141             : {
    5142           0 :     if( this==&rhs )
    5143           0 :         return *this;
    5144             :     jmp_buf _break_jump;
    5145             :     alglib_impl::ae_state _state;
    5146             :     
    5147           0 :     alglib_impl::ae_state_init(&_state);
    5148           0 :     if( setjmp(_break_jump) )
    5149             :     {
    5150             : #if !defined(AE_NO_EXCEPTIONS)
    5151           0 :         _ALGLIB_CPP_EXCEPTION(_state.error_msg);
    5152             : #else
    5153             :         _ALGLIB_SET_ERROR_FLAG(_state.error_msg);
    5154             :         return *this;
    5155             : #endif
    5156             :     }
    5157           0 :     alglib_impl::ae_state_set_break_jump(&_state, &_break_jump);
    5158           0 :     alglib_impl::ae_assert(p_struct!=NULL, "ALGLIB: lincgreport assignment constructor failure (destination is not initialized)", &_state);
    5159           0 :     alglib_impl::ae_assert(rhs.p_struct!=NULL, "ALGLIB: lincgreport assignment constructor failure (source is not initialized)", &_state);
    5160           0 :     alglib_impl::_lincgreport_destroy(p_struct);
    5161           0 :     memset(p_struct, 0, sizeof(alglib_impl::lincgreport));
    5162           0 :     alglib_impl::_lincgreport_init_copy(p_struct, const_cast<alglib_impl::lincgreport*>(rhs.p_struct), &_state, ae_false);
    5163           0 :     ae_state_clear(&_state);
    5164           0 :     return *this;
    5165             : }
    5166             : 
    5167           0 : _lincgreport_owner::~_lincgreport_owner()
    5168             : {
    5169           0 :     if( p_struct!=NULL )
    5170             :     {
    5171           0 :         alglib_impl::_lincgreport_destroy(p_struct);
    5172           0 :         ae_free(p_struct);
    5173             :     }
    5174           0 : }
    5175             : 
    5176           0 : alglib_impl::lincgreport* _lincgreport_owner::c_ptr()
    5177             : {
    5178           0 :     return p_struct;
    5179             : }
    5180             : 
    5181           0 : alglib_impl::lincgreport* _lincgreport_owner::c_ptr() const
    5182             : {
    5183           0 :     return const_cast<alglib_impl::lincgreport*>(p_struct);
    5184             : }
    5185           0 : lincgreport::lincgreport() : _lincgreport_owner() ,iterationscount(p_struct->iterationscount),nmv(p_struct->nmv),terminationtype(p_struct->terminationtype),r2(p_struct->r2)
    5186             : {
    5187           0 : }
    5188             : 
    5189           0 : lincgreport::lincgreport(const lincgreport &rhs):_lincgreport_owner(rhs) ,iterationscount(p_struct->iterationscount),nmv(p_struct->nmv),terminationtype(p_struct->terminationtype),r2(p_struct->r2)
    5190             : {
    5191           0 : }
    5192             : 
    5193           0 : lincgreport& lincgreport::operator=(const lincgreport &rhs)
    5194             : {
    5195           0 :     if( this==&rhs )
    5196           0 :         return *this;
    5197           0 :     _lincgreport_owner::operator=(rhs);
    5198           0 :     return *this;
    5199             : }
    5200             : 
    5201           0 : lincgreport::~lincgreport()
    5202             : {
    5203           0 : }
    5204             : 
    5205             : /*************************************************************************
    5206             : This function initializes linear CG Solver. This solver is used  to  solve
    5207             : symmetric positive definite problems. If you want  to  solve  nonsymmetric
    5208             : (or non-positive definite) problem you may use LinLSQR solver provided  by
    5209             : ALGLIB.
    5210             : 
    5211             : USAGE:
    5212             : 1. User initializes algorithm state with LinCGCreate() call
    5213             : 2. User tunes solver parameters with  LinCGSetCond() and other functions
    5214             : 3. Optionally, user sets starting point with LinCGSetStartingPoint()
    5215             : 4. User  calls LinCGSolveSparse() function which takes algorithm state and
    5216             :    SparseMatrix object.
    5217             : 5. User calls LinCGResults() to get solution
    5218             : 6. Optionally, user may call LinCGSolveSparse()  again  to  solve  another
    5219             :    problem  with different matrix and/or right part without reinitializing
    5220             :    LinCGState structure.
    5221             : 
    5222             : INPUT PARAMETERS:
    5223             :     N       -   problem dimension, N>0
    5224             : 
    5225             : OUTPUT PARAMETERS:
    5226             :     State   -   structure which stores algorithm state
    5227             : 
    5228             :   -- ALGLIB --
    5229             :      Copyright 14.11.2011 by Bochkanov Sergey
    5230             : *************************************************************************/
    5231           0 : void lincgcreate(const ae_int_t n, lincgstate &state, const xparams _xparams)
    5232             : {
    5233             :     jmp_buf _break_jump;
    5234             :     alglib_impl::ae_state _alglib_env_state;
    5235           0 :     alglib_impl::ae_state_init(&_alglib_env_state);
    5236           0 :     if( setjmp(_break_jump) )
    5237             :     {
    5238             : #if !defined(AE_NO_EXCEPTIONS)
    5239           0 :         _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
    5240             : #else
    5241             :         _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
    5242             :         return;
    5243             : #endif
    5244             :     }
    5245           0 :     ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
    5246           0 :     if( _xparams.flags!=0x0 )
    5247           0 :         ae_state_set_flags(&_alglib_env_state, _xparams.flags);
    5248           0 :     alglib_impl::lincgcreate(n, const_cast<alglib_impl::lincgstate*>(state.c_ptr()), &_alglib_env_state);
    5249           0 :     alglib_impl::ae_state_clear(&_alglib_env_state);
    5250           0 :     return;
    5251             : }
    5252             : 
    5253             : /*************************************************************************
    5254             : This function sets starting point.
    5255             : By default, zero starting point is used.
    5256             : 
    5257             : INPUT PARAMETERS:
    5258             :     X       -   starting point, array[N]
    5259             : 
    5260             : OUTPUT PARAMETERS:
    5261             :     State   -   structure which stores algorithm state
    5262             : 
    5263             :   -- ALGLIB --
    5264             :      Copyright 14.11.2011 by Bochkanov Sergey
    5265             : *************************************************************************/
    5266           0 : void lincgsetstartingpoint(const lincgstate &state, const real_1d_array &x, const xparams _xparams)
    5267             : {
    5268             :     jmp_buf _break_jump;
    5269             :     alglib_impl::ae_state _alglib_env_state;
    5270           0 :     alglib_impl::ae_state_init(&_alglib_env_state);
    5271           0 :     if( setjmp(_break_jump) )
    5272             :     {
    5273             : #if !defined(AE_NO_EXCEPTIONS)
    5274           0 :         _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
    5275             : #else
    5276             :         _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
    5277             :         return;
    5278             : #endif
    5279             :     }
    5280           0 :     ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
    5281           0 :     if( _xparams.flags!=0x0 )
    5282           0 :         ae_state_set_flags(&_alglib_env_state, _xparams.flags);
    5283           0 :     alglib_impl::lincgsetstartingpoint(const_cast<alglib_impl::lincgstate*>(state.c_ptr()), const_cast<alglib_impl::ae_vector*>(x.c_ptr()), &_alglib_env_state);
    5284           0 :     alglib_impl::ae_state_clear(&_alglib_env_state);
    5285           0 :     return;
    5286             : }
    5287             : 
    5288             : /*************************************************************************
    5289             : This  function  changes  preconditioning  settings  of  LinCGSolveSparse()
    5290             : function. By default, SolveSparse() uses diagonal preconditioner,  but  if
    5291             : you want to use solver without preconditioning, you can call this function
    5292             : which forces solver to use unit matrix for preconditioning.
    5293             : 
    5294             : INPUT PARAMETERS:
    5295             :     State   -   structure which stores algorithm state
    5296             : 
    5297             :   -- ALGLIB --
    5298             :      Copyright 19.11.2012 by Bochkanov Sergey
    5299             : *************************************************************************/
    5300           0 : void lincgsetprecunit(const lincgstate &state, const xparams _xparams)
    5301             : {
    5302             :     jmp_buf _break_jump;
    5303             :     alglib_impl::ae_state _alglib_env_state;
    5304           0 :     alglib_impl::ae_state_init(&_alglib_env_state);
    5305           0 :     if( setjmp(_break_jump) )
    5306             :     {
    5307             : #if !defined(AE_NO_EXCEPTIONS)
    5308           0 :         _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
    5309             : #else
    5310             :         _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
    5311             :         return;
    5312             : #endif
    5313             :     }
    5314           0 :     ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
    5315           0 :     if( _xparams.flags!=0x0 )
    5316           0 :         ae_state_set_flags(&_alglib_env_state, _xparams.flags);
    5317           0 :     alglib_impl::lincgsetprecunit(const_cast<alglib_impl::lincgstate*>(state.c_ptr()), &_alglib_env_state);
    5318           0 :     alglib_impl::ae_state_clear(&_alglib_env_state);
    5319           0 :     return;
    5320             : }
    5321             : 
    5322             : /*************************************************************************
    5323             : This  function  changes  preconditioning  settings  of  LinCGSolveSparse()
    5324             : function.  LinCGSolveSparse() will use diagonal of the  system  matrix  as
    5325             : preconditioner. This preconditioning mode is active by default.
    5326             : 
    5327             : INPUT PARAMETERS:
    5328             :     State   -   structure which stores algorithm state
    5329             : 
    5330             :   -- ALGLIB --
    5331             :      Copyright 19.11.2012 by Bochkanov Sergey
    5332             : *************************************************************************/
    5333           0 : void lincgsetprecdiag(const lincgstate &state, const xparams _xparams)
    5334             : {
    5335             :     jmp_buf _break_jump;
    5336             :     alglib_impl::ae_state _alglib_env_state;
    5337           0 :     alglib_impl::ae_state_init(&_alglib_env_state);
    5338           0 :     if( setjmp(_break_jump) )
    5339             :     {
    5340             : #if !defined(AE_NO_EXCEPTIONS)
    5341           0 :         _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
    5342             : #else
    5343             :         _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
    5344             :         return;
    5345             : #endif
    5346             :     }
    5347           0 :     ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
    5348           0 :     if( _xparams.flags!=0x0 )
    5349           0 :         ae_state_set_flags(&_alglib_env_state, _xparams.flags);
    5350           0 :     alglib_impl::lincgsetprecdiag(const_cast<alglib_impl::lincgstate*>(state.c_ptr()), &_alglib_env_state);
    5351           0 :     alglib_impl::ae_state_clear(&_alglib_env_state);
    5352           0 :     return;
    5353             : }
    5354             : 
    5355             : /*************************************************************************
    5356             : This function sets stopping criteria.
    5357             : 
    5358             : INPUT PARAMETERS:
    5359             :     EpsF    -   algorithm will be stopped if norm of residual is less than
    5360             :                 EpsF*||b||.
    5361             :     MaxIts  -   algorithm will be stopped if number of iterations is  more
    5362             :                 than MaxIts.
    5363             : 
    5364             : OUTPUT PARAMETERS:
    5365             :     State   -   structure which stores algorithm state
    5366             : 
    5367             : NOTES:
    5368             : If  both  EpsF  and  MaxIts  are  zero then small EpsF will be set to small
    5369             : value.
    5370             : 
    5371             :   -- ALGLIB --
    5372             :      Copyright 14.11.2011 by Bochkanov Sergey
    5373             : *************************************************************************/
    5374           0 : void lincgsetcond(const lincgstate &state, const double epsf, const ae_int_t maxits, const xparams _xparams)
    5375             : {
    5376             :     jmp_buf _break_jump;
    5377             :     alglib_impl::ae_state _alglib_env_state;
    5378           0 :     alglib_impl::ae_state_init(&_alglib_env_state);
    5379           0 :     if( setjmp(_break_jump) )
    5380             :     {
    5381             : #if !defined(AE_NO_EXCEPTIONS)
    5382           0 :         _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
    5383             : #else
    5384             :         _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
    5385             :         return;
    5386             : #endif
    5387             :     }
    5388           0 :     ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
    5389           0 :     if( _xparams.flags!=0x0 )
    5390           0 :         ae_state_set_flags(&_alglib_env_state, _xparams.flags);
    5391           0 :     alglib_impl::lincgsetcond(const_cast<alglib_impl::lincgstate*>(state.c_ptr()), epsf, maxits, &_alglib_env_state);
    5392           0 :     alglib_impl::ae_state_clear(&_alglib_env_state);
    5393           0 :     return;
    5394             : }
    5395             : 
    5396             : /*************************************************************************
    5397             : Procedure for solution of A*x=b with sparse A.
    5398             : 
    5399             : INPUT PARAMETERS:
    5400             :     State   -   algorithm state
    5401             :     A       -   sparse matrix in the CRS format (you MUST contvert  it  to
    5402             :                 CRS format by calling SparseConvertToCRS() function).
    5403             :     IsUpper -   whether upper or lower triangle of A is used:
    5404             :                 * IsUpper=True  => only upper triangle is used and lower
    5405             :                                    triangle is not referenced at all
    5406             :                 * IsUpper=False => only lower triangle is used and upper
    5407             :                                    triangle is not referenced at all
    5408             :     B       -   right part, array[N]
    5409             : 
    5410             : RESULT:
    5411             :     This function returns no result.
    5412             :     You can get solution by calling LinCGResults()
    5413             : 
    5414             : NOTE: this function uses lightweight preconditioning -  multiplication  by
    5415             :       inverse of diag(A). If you want, you can turn preconditioning off by
    5416             :       calling LinCGSetPrecUnit(). However, preconditioning cost is low and
    5417             :       preconditioner  is  very  important  for  solution  of  badly scaled
    5418             :       problems.
    5419             : 
    5420             :   -- ALGLIB --
    5421             :      Copyright 14.11.2011 by Bochkanov Sergey
    5422             : *************************************************************************/
    5423           0 : void lincgsolvesparse(const lincgstate &state, const sparsematrix &a, const bool isupper, const real_1d_array &b, const xparams _xparams)
    5424             : {
    5425             :     jmp_buf _break_jump;
    5426             :     alglib_impl::ae_state _alglib_env_state;
    5427           0 :     alglib_impl::ae_state_init(&_alglib_env_state);
    5428           0 :     if( setjmp(_break_jump) )
    5429             :     {
    5430             : #if !defined(AE_NO_EXCEPTIONS)
    5431           0 :         _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
    5432             : #else
    5433             :         _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
    5434             :         return;
    5435             : #endif
    5436             :     }
    5437           0 :     ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
    5438           0 :     if( _xparams.flags!=0x0 )
    5439           0 :         ae_state_set_flags(&_alglib_env_state, _xparams.flags);
    5440           0 :     alglib_impl::lincgsolvesparse(const_cast<alglib_impl::lincgstate*>(state.c_ptr()), const_cast<alglib_impl::sparsematrix*>(a.c_ptr()), isupper, const_cast<alglib_impl::ae_vector*>(b.c_ptr()), &_alglib_env_state);
    5441           0 :     alglib_impl::ae_state_clear(&_alglib_env_state);
    5442           0 :     return;
    5443             : }
    5444             : 
    5445             : /*************************************************************************
    5446             : CG-solver: results.
    5447             : 
    5448             : This function must be called after LinCGSolve
    5449             : 
    5450             : INPUT PARAMETERS:
    5451             :     State   -   algorithm state
    5452             : 
    5453             : OUTPUT PARAMETERS:
    5454             :     X       -   array[N], solution
    5455             :     Rep     -   optimization report:
    5456             :                 * Rep.TerminationType completetion code:
    5457             :                     * -5    input matrix is either not positive definite,
    5458             :                             too large or too small
    5459             :                     * -4    overflow/underflow during solution
    5460             :                             (ill conditioned problem)
    5461             :                     *  1    ||residual||<=EpsF*||b||
    5462             :                     *  5    MaxIts steps was taken
    5463             :                     *  7    rounding errors prevent further progress,
    5464             :                             best point found is returned
    5465             :                 * Rep.IterationsCount contains iterations count
    5466             :                 * NMV countains number of matrix-vector calculations
    5467             : 
    5468             :   -- ALGLIB --
    5469             :      Copyright 14.11.2011 by Bochkanov Sergey
    5470             : *************************************************************************/
    5471           0 : void lincgresults(const lincgstate &state, real_1d_array &x, lincgreport &rep, const xparams _xparams)
    5472             : {
    5473             :     jmp_buf _break_jump;
    5474             :     alglib_impl::ae_state _alglib_env_state;
    5475           0 :     alglib_impl::ae_state_init(&_alglib_env_state);
    5476           0 :     if( setjmp(_break_jump) )
    5477             :     {
    5478             : #if !defined(AE_NO_EXCEPTIONS)
    5479           0 :         _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
    5480             : #else
    5481             :         _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
    5482             :         return;
    5483             : #endif
    5484             :     }
    5485           0 :     ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
    5486           0 :     if( _xparams.flags!=0x0 )
    5487           0 :         ae_state_set_flags(&_alglib_env_state, _xparams.flags);
    5488           0 :     alglib_impl::lincgresults(const_cast<alglib_impl::lincgstate*>(state.c_ptr()), const_cast<alglib_impl::ae_vector*>(x.c_ptr()), const_cast<alglib_impl::lincgreport*>(rep.c_ptr()), &_alglib_env_state);
    5489           0 :     alglib_impl::ae_state_clear(&_alglib_env_state);
    5490           0 :     return;
    5491             : }
    5492             : 
    5493             : /*************************************************************************
    5494             : This function sets restart frequency. By default, algorithm  is  restarted
    5495             : after N subsequent iterations.
    5496             : 
    5497             :   -- ALGLIB --
    5498             :      Copyright 14.11.2011 by Bochkanov Sergey
    5499             : *************************************************************************/
    5500           0 : void lincgsetrestartfreq(const lincgstate &state, const ae_int_t srf, const xparams _xparams)
    5501             : {
    5502             :     jmp_buf _break_jump;
    5503             :     alglib_impl::ae_state _alglib_env_state;
    5504           0 :     alglib_impl::ae_state_init(&_alglib_env_state);
    5505           0 :     if( setjmp(_break_jump) )
    5506             :     {
    5507             : #if !defined(AE_NO_EXCEPTIONS)
    5508           0 :         _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
    5509             : #else
    5510             :         _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
    5511             :         return;
    5512             : #endif
    5513             :     }
    5514           0 :     ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
    5515           0 :     if( _xparams.flags!=0x0 )
    5516           0 :         ae_state_set_flags(&_alglib_env_state, _xparams.flags);
    5517           0 :     alglib_impl::lincgsetrestartfreq(const_cast<alglib_impl::lincgstate*>(state.c_ptr()), srf, &_alglib_env_state);
    5518           0 :     alglib_impl::ae_state_clear(&_alglib_env_state);
    5519           0 :     return;
    5520             : }
    5521             : 
    5522             : /*************************************************************************
    5523             : This function sets frequency of residual recalculations.
    5524             : 
    5525             : Algorithm updates residual r_k using iterative formula,  but  recalculates
    5526             : it from scratch after each 10 iterations. It is done to avoid accumulation
    5527             : of numerical errors and to stop algorithm when r_k starts to grow.
    5528             : 
    5529             : Such low update frequence (1/10) gives very  little  overhead,  but  makes
    5530             : algorithm a bit more robust against numerical errors. However, you may
    5531             : change it
    5532             : 
    5533             : INPUT PARAMETERS:
    5534             :     Freq    -   desired update frequency, Freq>=0.
    5535             :                 Zero value means that no updates will be done.
    5536             : 
    5537             :   -- ALGLIB --
    5538             :      Copyright 14.11.2011 by Bochkanov Sergey
    5539             : *************************************************************************/
    5540           0 : void lincgsetrupdatefreq(const lincgstate &state, const ae_int_t freq, const xparams _xparams)
    5541             : {
    5542             :     jmp_buf _break_jump;
    5543             :     alglib_impl::ae_state _alglib_env_state;
    5544           0 :     alglib_impl::ae_state_init(&_alglib_env_state);
    5545           0 :     if( setjmp(_break_jump) )
    5546             :     {
    5547             : #if !defined(AE_NO_EXCEPTIONS)
    5548           0 :         _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
    5549             : #else
    5550             :         _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
    5551             :         return;
    5552             : #endif
    5553             :     }
    5554           0 :     ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
    5555           0 :     if( _xparams.flags!=0x0 )
    5556           0 :         ae_state_set_flags(&_alglib_env_state, _xparams.flags);
    5557           0 :     alglib_impl::lincgsetrupdatefreq(const_cast<alglib_impl::lincgstate*>(state.c_ptr()), freq, &_alglib_env_state);
    5558           0 :     alglib_impl::ae_state_clear(&_alglib_env_state);
    5559           0 :     return;
    5560             : }
    5561             : 
    5562             : /*************************************************************************
    5563             : This function turns on/off reporting.
    5564             : 
    5565             : INPUT PARAMETERS:
    5566             :     State   -   structure which stores algorithm state
    5567             :     NeedXRep-   whether iteration reports are needed or not
    5568             : 
    5569             : If NeedXRep is True, algorithm will call rep() callback function if  it is
    5570             : provided to MinCGOptimize().
    5571             : 
    5572             :   -- ALGLIB --
    5573             :      Copyright 14.11.2011 by Bochkanov Sergey
    5574             : *************************************************************************/
    5575           0 : void lincgsetxrep(const lincgstate &state, const bool needxrep, const xparams _xparams)
    5576             : {
    5577             :     jmp_buf _break_jump;
    5578             :     alglib_impl::ae_state _alglib_env_state;
    5579           0 :     alglib_impl::ae_state_init(&_alglib_env_state);
    5580           0 :     if( setjmp(_break_jump) )
    5581             :     {
    5582             : #if !defined(AE_NO_EXCEPTIONS)
    5583           0 :         _ALGLIB_CPP_EXCEPTION(_alglib_env_state.error_msg);
    5584             : #else
    5585             :         _ALGLIB_SET_ERROR_FLAG(_alglib_env_state.error_msg);
    5586             :         return;
    5587             : #endif
    5588             :     }
    5589           0 :     ae_state_set_break_jump(&_alglib_env_state, &_break_jump);
    5590           0 :     if( _xparams.flags!=0x0 )
    5591           0 :         ae_state_set_flags(&_alglib_env_state, _xparams.flags);
    5592           0 :     alglib_impl::lincgsetxrep(const_cast<alglib_impl::lincgstate*>(state.c_ptr()), needxrep, &_alglib_env_state);
    5593           0 :     alglib_impl::ae_state_clear(&_alglib_env_state);
    5594           0 :     return;
    5595             : }
    5596             : #endif
    5597             : }
    5598             : 
    5599             : /////////////////////////////////////////////////////////////////////////
    5600             : //
    5601             : // THIS SECTION CONTAINS IMPLEMENTATION OF COMPUTATIONAL CORE
    5602             : //
    5603             : /////////////////////////////////////////////////////////////////////////
    5604             : namespace alglib_impl
    5605             : {
    5606             : #if defined(AE_COMPILE_DIRECTDENSESOLVERS) || !defined(AE_PARTIAL_BUILD)
    5607             : static void directdensesolvers_rmatrixlusolveinternal(/* Real    */ ae_matrix* lua,
    5608             :      /* Integer */ ae_vector* p,
    5609             :      ae_int_t n,
    5610             :      /* Real    */ ae_matrix* a,
    5611             :      ae_bool havea,
    5612             :      /* Real    */ ae_matrix* b,
    5613             :      ae_int_t m,
    5614             :      ae_int_t* info,
    5615             :      densesolverreport* rep,
    5616             :      /* Real    */ ae_matrix* x,
    5617             :      ae_state *_state);
    5618             : static void directdensesolvers_spdmatrixcholeskysolveinternal(/* Real    */ ae_matrix* cha,
    5619             :      ae_int_t n,
    5620             :      ae_bool isupper,
    5621             :      /* Real    */ ae_matrix* a,
    5622             :      ae_bool havea,
    5623             :      /* Real    */ ae_matrix* b,
    5624             :      ae_int_t m,
    5625             :      ae_int_t* info,
    5626             :      densesolverreport* rep,
    5627             :      /* Real    */ ae_matrix* x,
    5628             :      ae_state *_state);
    5629             : static void directdensesolvers_cmatrixlusolveinternal(/* Complex */ ae_matrix* lua,
    5630             :      /* Integer */ ae_vector* p,
    5631             :      ae_int_t n,
    5632             :      /* Complex */ ae_matrix* a,
    5633             :      ae_bool havea,
    5634             :      /* Complex */ ae_matrix* b,
    5635             :      ae_int_t m,
    5636             :      ae_int_t* info,
    5637             :      densesolverreport* rep,
    5638             :      /* Complex */ ae_matrix* x,
    5639             :      ae_state *_state);
    5640             : static void directdensesolvers_hpdmatrixcholeskysolveinternal(/* Complex */ ae_matrix* cha,
    5641             :      ae_int_t n,
    5642             :      ae_bool isupper,
    5643             :      /* Complex */ ae_matrix* a,
    5644             :      ae_bool havea,
    5645             :      /* Complex */ ae_matrix* b,
    5646             :      ae_int_t m,
    5647             :      ae_int_t* info,
    5648             :      densesolverreport* rep,
    5649             :      /* Complex */ ae_matrix* x,
    5650             :      ae_state *_state);
    5651             : static ae_int_t directdensesolvers_densesolverrfsmax(ae_int_t n,
    5652             :      double r1,
    5653             :      double rinf,
    5654             :      ae_state *_state);
    5655             : static ae_int_t directdensesolvers_densesolverrfsmaxv2(ae_int_t n,
    5656             :      double r2,
    5657             :      ae_state *_state);
    5658             : static void directdensesolvers_rbasiclusolve(/* Real    */ ae_matrix* lua,
    5659             :      /* Integer */ ae_vector* p,
    5660             :      ae_int_t n,
    5661             :      /* Real    */ ae_vector* xb,
    5662             :      ae_state *_state);
    5663             : static void directdensesolvers_spdbasiccholeskysolve(/* Real    */ ae_matrix* cha,
    5664             :      ae_int_t n,
    5665             :      ae_bool isupper,
    5666             :      /* Real    */ ae_vector* xb,
    5667             :      ae_state *_state);
    5668             : static void directdensesolvers_cbasiclusolve(/* Complex */ ae_matrix* lua,
    5669             :      /* Integer */ ae_vector* p,
    5670             :      ae_int_t n,
    5671             :      /* Complex */ ae_vector* xb,
    5672             :      ae_state *_state);
    5673             : static void directdensesolvers_hpdbasiccholeskysolve(/* Complex */ ae_matrix* cha,
    5674             :      ae_int_t n,
    5675             :      ae_bool isupper,
    5676             :      /* Complex */ ae_vector* xb,
    5677             :      ae_state *_state);
    5678             : 
    5679             : 
    5680             : #endif
    5681             : #if defined(AE_COMPILE_LINLSQR) || !defined(AE_PARTIAL_BUILD)
    5682             : static double linlsqr_atol = 1.0E-6;
    5683             : static double linlsqr_btol = 1.0E-6;
    5684             : static void linlsqr_clearrfields(linlsqrstate* state, ae_state *_state);
    5685             : 
    5686             : 
    5687             : #endif
    5688             : #if defined(AE_COMPILE_POLYNOMIALSOLVER) || !defined(AE_PARTIAL_BUILD)
    5689             : 
    5690             : 
    5691             : #endif
    5692             : #if defined(AE_COMPILE_NLEQ) || !defined(AE_PARTIAL_BUILD)
    5693             : static void nleq_clearrequestfields(nleqstate* state, ae_state *_state);
    5694             : static ae_bool nleq_increaselambda(double* lambdav,
    5695             :      double* nu,
    5696             :      double lambdaup,
    5697             :      ae_state *_state);
    5698             : static void nleq_decreaselambda(double* lambdav,
    5699             :      double* nu,
    5700             :      double lambdadown,
    5701             :      ae_state *_state);
    5702             : 
    5703             : 
    5704             : #endif
    5705             : #if defined(AE_COMPILE_DIRECTSPARSESOLVERS) || !defined(AE_PARTIAL_BUILD)
    5706             : static void directsparsesolvers_initreport(sparsesolverreport* rep,
    5707             :      ae_state *_state);
    5708             : 
    5709             : 
    5710             : #endif
    5711             : #if defined(AE_COMPILE_LINCG) || !defined(AE_PARTIAL_BUILD)
    5712             : static double lincg_defaultprecision = 1.0E-6;
    5713             : static void lincg_clearrfields(lincgstate* state, ae_state *_state);
    5714             : static void lincg_updateitersdata(lincgstate* state, ae_state *_state);
    5715             : 
    5716             : 
    5717             : #endif
    5718             : 
    5719             : #if defined(AE_COMPILE_DIRECTDENSESOLVERS) || !defined(AE_PARTIAL_BUILD)
    5720             : 
    5721             : 
    5722             : /*************************************************************************
    5723             : Dense solver for A*x=b with N*N real matrix A and N*1 real vectorx  x  and
    5724             : b. This is "slow-but-feature rich" version of the  linear  solver.  Faster
    5725             : version is RMatrixSolveFast() function.
    5726             : 
    5727             : Algorithm features:
    5728             : * automatic detection of degenerate cases
    5729             : * condition number estimation
    5730             : * iterative refinement
    5731             : * O(N^3) complexity
    5732             : 
    5733             : IMPORTANT: ! this function is NOT the most efficient linear solver provided
    5734             :            ! by ALGLIB. It estimates condition  number  of  linear  system
    5735             :            ! and  performs  iterative   refinement,   which   results   in
    5736             :            ! significant performance penalty  when  compared  with  "fast"
    5737             :            ! version  which  just  performs  LU  decomposition  and  calls
    5738             :            ! triangular solver.
    5739             :            !
    5740             :            ! This  performance  penalty  is  especially  visible  in   the
    5741             :            ! multithreaded mode, because both condition number  estimation
    5742             :            ! and   iterative    refinement   are   inherently   sequential
    5743             :            ! calculations. It is also very significant on small matrices.
    5744             :            !
    5745             :            ! Thus, if you need high performance and if you are pretty sure
    5746             :            ! that your system is well conditioned, we  strongly  recommend
    5747             :            ! you to use faster solver, RMatrixSolveFast() function.
    5748             : 
    5749             :   ! COMMERCIAL EDITION OF ALGLIB:
    5750             :   ! 
    5751             :   ! Commercial Edition of ALGLIB includes following important improvements
    5752             :   ! of this function:
    5753             :   ! * high-performance native backend with same C# interface (C# version)
    5754             :   ! * multithreading support (C++ and C# versions)
    5755             :   ! * hardware vendor (Intel) implementations of linear algebra primitives
    5756             :   !   (C++ and C# versions, x86/x64 platform)
    5757             :   ! 
    5758             :   ! We recommend you to read 'Working with commercial version' section  of
    5759             :   ! ALGLIB Reference Manual in order to find out how to  use  performance-
    5760             :   ! related features provided by commercial edition of ALGLIB.
    5761             : 
    5762             : INPUT PARAMETERS
    5763             :     A       -   array[0..N-1,0..N-1], system matrix
    5764             :     N       -   size of A
    5765             :     B       -   array[0..N-1], right part
    5766             : 
    5767             : OUTPUT PARAMETERS
    5768             :     Info    -   return code:
    5769             :                 * -3    matrix is very badly conditioned or exactly singular.
    5770             :                 * -1    N<=0 was passed
    5771             :                 *  1    task is solved (but matrix A may be ill-conditioned,
    5772             :                         check R1/RInf parameters for condition numbers).
    5773             :     Rep     -   additional report, following fields are set:
    5774             :                 * rep.r1    condition number in 1-norm
    5775             :                 * rep.rinf  condition number in inf-norm
    5776             :     X       -   array[N], it contains:
    5777             :                 * info>0    =>  solution
    5778             :                 * info=-3   =>  filled by zeros
    5779             : 
    5780             :   -- ALGLIB --
    5781             :      Copyright 27.01.2010 by Bochkanov Sergey
    5782             : *************************************************************************/
    5783           0 : void rmatrixsolve(/* Real    */ ae_matrix* a,
    5784             :      ae_int_t n,
    5785             :      /* Real    */ ae_vector* b,
    5786             :      ae_int_t* info,
    5787             :      densesolverreport* rep,
    5788             :      /* Real    */ ae_vector* x,
    5789             :      ae_state *_state)
    5790             : {
    5791             :     ae_frame _frame_block;
    5792             :     ae_matrix bm;
    5793             :     ae_matrix xm;
    5794             : 
    5795           0 :     ae_frame_make(_state, &_frame_block);
    5796           0 :     memset(&bm, 0, sizeof(bm));
    5797           0 :     memset(&xm, 0, sizeof(xm));
    5798           0 :     *info = 0;
    5799           0 :     _densesolverreport_clear(rep);
    5800           0 :     ae_vector_clear(x);
    5801           0 :     ae_matrix_init(&bm, 0, 0, DT_REAL, _state, ae_true);
    5802           0 :     ae_matrix_init(&xm, 0, 0, DT_REAL, _state, ae_true);
    5803             : 
    5804           0 :     if( n<=0 )
    5805             :     {
    5806           0 :         *info = -1;
    5807           0 :         ae_frame_leave(_state);
    5808           0 :         return;
    5809             :     }
    5810           0 :     ae_matrix_set_length(&bm, n, 1, _state);
    5811           0 :     ae_v_move(&bm.ptr.pp_double[0][0], bm.stride, &b->ptr.p_double[0], 1, ae_v_len(0,n-1));
    5812           0 :     rmatrixsolvem(a, n, &bm, 1, ae_true, info, rep, &xm, _state);
    5813           0 :     ae_vector_set_length(x, n, _state);
    5814           0 :     ae_v_move(&x->ptr.p_double[0], 1, &xm.ptr.pp_double[0][0], xm.stride, ae_v_len(0,n-1));
    5815           0 :     ae_frame_leave(_state);
    5816             : }
    5817             : 
    5818             : 
    5819             : /*************************************************************************
    5820             : Dense solver.
    5821             : 
    5822             : This  subroutine  solves  a  system  A*x=b,  where A is NxN non-denegerate
    5823             : real matrix, x  and  b  are  vectors.  This is a "fast" version of  linear
    5824             : solver which does NOT provide  any  additional  functions  like  condition
    5825             : number estimation or iterative refinement.
    5826             : 
    5827             : Algorithm features:
    5828             : * efficient algorithm O(N^3) complexity
    5829             : * no performance overhead from additional functionality
    5830             : 
    5831             : If you need condition number estimation or iterative refinement, use  more
    5832             : feature-rich version - RMatrixSolve().
    5833             : 
    5834             :   ! COMMERCIAL EDITION OF ALGLIB:
    5835             :   ! 
    5836             :   ! Commercial Edition of ALGLIB includes following important improvements
    5837             :   ! of this function:
    5838             :   ! * high-performance native backend with same C# interface (C# version)
    5839             :   ! * multithreading support (C++ and C# versions)
    5840             :   ! * hardware vendor (Intel) implementations of linear algebra primitives
    5841             :   !   (C++ and C# versions, x86/x64 platform)
    5842             :   ! 
    5843             :   ! We recommend you to read 'Working with commercial version' section  of
    5844             :   ! ALGLIB Reference Manual in order to find out how to  use  performance-
    5845             :   ! related features provided by commercial edition of ALGLIB.
    5846             : 
    5847             : INPUT PARAMETERS
    5848             :     A       -   array[0..N-1,0..N-1], system matrix
    5849             :     N       -   size of A
    5850             :     B       -   array[0..N-1], right part
    5851             : 
    5852             : OUTPUT PARAMETERS
    5853             :     Info    -   return code:
    5854             :                 * -3    matrix is exactly singular (ill conditioned matrices
    5855             :                         are not recognized).
    5856             :                 * -1    N<=0 was passed
    5857             :                 *  1    task is solved 
    5858             :     B       -   array[N]:
    5859             :                 * info>0    =>  overwritten by solution
    5860             :                 * info=-3   =>  filled by zeros
    5861             : 
    5862             :   -- ALGLIB --
    5863             :      Copyright 16.03.2015 by Bochkanov Sergey
    5864             : *************************************************************************/
    5865           0 : void rmatrixsolvefast(/* Real    */ ae_matrix* a,
    5866             :      ae_int_t n,
    5867             :      /* Real    */ ae_vector* b,
    5868             :      ae_int_t* info,
    5869             :      ae_state *_state)
    5870             : {
    5871             :     ae_frame _frame_block;
    5872             :     ae_matrix _a;
    5873             :     ae_int_t i;
    5874             :     ae_int_t j;
    5875             :     ae_vector p;
    5876             : 
    5877           0 :     ae_frame_make(_state, &_frame_block);
    5878           0 :     memset(&_a, 0, sizeof(_a));
    5879           0 :     memset(&p, 0, sizeof(p));
    5880           0 :     ae_matrix_init_copy(&_a, a, _state, ae_true);
    5881           0 :     a = &_a;
    5882           0 :     *info = 0;
    5883           0 :     ae_vector_init(&p, 0, DT_INT, _state, ae_true);
    5884             : 
    5885           0 :     if( n<=0 )
    5886             :     {
    5887           0 :         *info = -1;
    5888           0 :         ae_frame_leave(_state);
    5889           0 :         return;
    5890             :     }
    5891           0 :     rmatrixlu(a, n, n, &p, _state);
    5892           0 :     for(i=0; i<=n-1; i++)
    5893             :     {
    5894           0 :         if( ae_fp_eq(a->ptr.pp_double[i][i],(double)(0)) )
    5895             :         {
    5896           0 :             for(j=0; j<=n-1; j++)
    5897             :             {
    5898           0 :                 b->ptr.p_double[j] = 0.0;
    5899             :             }
    5900           0 :             *info = -3;
    5901           0 :             ae_frame_leave(_state);
    5902           0 :             return;
    5903             :         }
    5904             :     }
    5905           0 :     directdensesolvers_rbasiclusolve(a, &p, n, b, _state);
    5906           0 :     *info = 1;
    5907           0 :     ae_frame_leave(_state);
    5908             : }
    5909             : 
    5910             : 
    5911             : /*************************************************************************
    5912             : Dense solver.
    5913             : 
    5914             : Similar to RMatrixSolve() but solves task with multiple right parts (where
    5915             : b and x are NxM matrices). This is  "slow-but-robust"  version  of  linear
    5916             : solver with additional functionality  like  condition  number  estimation.
    5917             : There also exists faster version - RMatrixSolveMFast().
    5918             : 
    5919             : Algorithm features:
    5920             : * automatic detection of degenerate cases
    5921             : * condition number estimation
    5922             : * optional iterative refinement
    5923             : * O(N^3+M*N^2) complexity
    5924             : 
    5925             : IMPORTANT: ! this function is NOT the most efficient linear solver provided
    5926             :            ! by ALGLIB. It estimates condition  number  of  linear  system
    5927             :            ! and  performs  iterative   refinement,   which   results   in
    5928             :            ! significant performance penalty  when  compared  with  "fast"
    5929             :            ! version  which  just  performs  LU  decomposition  and  calls
    5930             :            ! triangular solver.
    5931             :            !
    5932             :            ! This  performance  penalty  is  especially  visible  in   the
    5933             :            ! multithreaded mode, because both condition number  estimation
    5934             :            ! and   iterative    refinement   are   inherently   sequential
    5935             :            ! calculations. It also very significant on small matrices.
    5936             :            !
    5937             :            ! Thus, if you need high performance and if you are pretty sure
    5938             :            ! that your system is well conditioned, we  strongly  recommend
    5939             :            ! you to use faster solver, RMatrixSolveMFast() function.
    5940             : 
    5941             :   ! COMMERCIAL EDITION OF ALGLIB:
    5942             :   ! 
    5943             :   ! Commercial Edition of ALGLIB includes following important improvements
    5944             :   ! of this function:
    5945             :   ! * high-performance native backend with same C# interface (C# version)
    5946             :   ! * multithreading support (C++ and C# versions)
    5947             :   ! * hardware vendor (Intel) implementations of linear algebra primitives
    5948             :   !   (C++ and C# versions, x86/x64 platform)
    5949             :   ! 
    5950             :   ! We recommend you to read 'Working with commercial version' section  of
    5951             :   ! ALGLIB Reference Manual in order to find out how to  use  performance-
    5952             :   ! related features provided by commercial edition of ALGLIB.
    5953             : 
    5954             : INPUT PARAMETERS
    5955             :     A       -   array[0..N-1,0..N-1], system matrix
    5956             :     N       -   size of A
    5957             :     B       -   array[0..N-1,0..M-1], right part
    5958             :     M       -   right part size
    5959             :     RFS     -   iterative refinement switch:
    5960             :                 * True - refinement is used.
    5961             :                   Less performance, more precision.
    5962             :                 * False - refinement is not used.
    5963             :                   More performance, less precision.
    5964             : 
    5965             : OUTPUT PARAMETERS
    5966             :     Info    -   return code:
    5967             :                 * -3    A is ill conditioned or singular.
    5968             :                         X is filled by zeros in such cases.
    5969             :                 * -1    N<=0 was passed
    5970             :                 *  1    task is solved (but matrix A may be ill-conditioned,
    5971             :                         check R1/RInf parameters for condition numbers).
    5972             :     Rep     -   additional report, following fields are set:
    5973             :                 * rep.r1    condition number in 1-norm
    5974             :                 * rep.rinf  condition number in inf-norm
    5975             :     X       -   array[N], it contains:
    5976             :                 * info>0    =>  solution
    5977             :                 * info=-3   =>  filled by zeros
    5978             : 
    5979             : 
    5980             :   -- ALGLIB --
    5981             :      Copyright 27.01.2010 by Bochkanov Sergey
    5982             : *************************************************************************/
    5983           0 : void rmatrixsolvem(/* Real    */ ae_matrix* a,
    5984             :      ae_int_t n,
    5985             :      /* Real    */ ae_matrix* b,
    5986             :      ae_int_t m,
    5987             :      ae_bool rfs,
    5988             :      ae_int_t* info,
    5989             :      densesolverreport* rep,
    5990             :      /* Real    */ ae_matrix* x,
    5991             :      ae_state *_state)
    5992             : {
    5993             :     ae_frame _frame_block;
    5994             :     ae_matrix da;
    5995             :     ae_matrix emptya;
    5996             :     ae_vector p;
    5997             :     ae_int_t i;
    5998             : 
    5999           0 :     ae_frame_make(_state, &_frame_block);
    6000           0 :     memset(&da, 0, sizeof(da));
    6001           0 :     memset(&emptya, 0, sizeof(emptya));
    6002           0 :     memset(&p, 0, sizeof(p));
    6003           0 :     *info = 0;
    6004           0 :     _densesolverreport_clear(rep);
    6005           0 :     ae_matrix_clear(x);
    6006           0 :     ae_matrix_init(&da, 0, 0, DT_REAL, _state, ae_true);
    6007           0 :     ae_matrix_init(&emptya, 0, 0, DT_REAL, _state, ae_true);
    6008           0 :     ae_vector_init(&p, 0, DT_INT, _state, ae_true);
    6009             : 
    6010             :     
    6011             :     /*
    6012             :      * prepare: check inputs, allocate space...
    6013             :      */
    6014           0 :     if( n<=0||m<=0 )
    6015             :     {
    6016           0 :         *info = -1;
    6017           0 :         ae_frame_leave(_state);
    6018           0 :         return;
    6019             :     }
    6020           0 :     ae_matrix_set_length(&da, n, n, _state);
    6021             :     
    6022             :     /*
    6023             :      * 1. factorize matrix
    6024             :      * 3. solve
    6025             :      */
    6026           0 :     for(i=0; i<=n-1; i++)
    6027             :     {
    6028           0 :         ae_v_move(&da.ptr.pp_double[i][0], 1, &a->ptr.pp_double[i][0], 1, ae_v_len(0,n-1));
    6029             :     }
    6030           0 :     rmatrixlu(&da, n, n, &p, _state);
    6031           0 :     if( rfs )
    6032             :     {
    6033           0 :         directdensesolvers_rmatrixlusolveinternal(&da, &p, n, a, ae_true, b, m, info, rep, x, _state);
    6034             :     }
    6035             :     else
    6036             :     {
    6037           0 :         directdensesolvers_rmatrixlusolveinternal(&da, &p, n, &emptya, ae_false, b, m, info, rep, x, _state);
    6038             :     }
    6039           0 :     ae_frame_leave(_state);
    6040             : }
    6041             : 
    6042             : 
    6043             : /*************************************************************************
    6044             : Dense solver.
    6045             : 
    6046             : Similar to RMatrixSolve() but solves task with multiple right parts (where
    6047             : b and x are NxM matrices). This is "fast" version of linear  solver  which
    6048             : does NOT offer additional functions like condition  number  estimation  or
    6049             : iterative refinement.
    6050             : 
    6051             : Algorithm features:
    6052             : * O(N^3+M*N^2) complexity
    6053             : * no additional functionality, highest performance
    6054             : 
    6055             :   ! COMMERCIAL EDITION OF ALGLIB:
    6056             :   ! 
    6057             :   ! Commercial Edition of ALGLIB includes following important improvements
    6058             :   ! of this function:
    6059             :   ! * high-performance native backend with same C# interface (C# version)
    6060             :   ! * multithreading support (C++ and C# versions)
    6061             :   ! * hardware vendor (Intel) implementations of linear algebra primitives
    6062             :   !   (C++ and C# versions, x86/x64 platform)
    6063             :   ! 
    6064             :   ! We recommend you to read 'Working with commercial version' section  of
    6065             :   ! ALGLIB Reference Manual in order to find out how to  use  performance-
    6066             :   ! related features provided by commercial edition of ALGLIB.
    6067             : 
    6068             : INPUT PARAMETERS
    6069             :     A       -   array[0..N-1,0..N-1], system matrix
    6070             :     N       -   size of A
    6071             :     B       -   array[0..N-1,0..M-1], right part
    6072             :     M       -   right part size
    6073             :     RFS     -   iterative refinement switch:
    6074             :                 * True - refinement is used.
    6075             :                   Less performance, more precision.
    6076             :                 * False - refinement is not used.
    6077             :                   More performance, less precision.
    6078             : 
    6079             : OUTPUT PARAMETERS
    6080             :     Info    -   return code:
    6081             :                 * -3    matrix is exactly singular (ill conditioned matrices
    6082             :                         are not recognized).
    6083             :                         X is filled by zeros in such cases.
    6084             :                 * -1    N<=0 was passed
    6085             :                 *  1    task is solved
    6086             :     Rep     -   additional report, following fields are set:
    6087             :                 * rep.r1    condition number in 1-norm
    6088             :                 * rep.rinf  condition number in inf-norm
    6089             :     B       -   array[N]:
    6090             :                 * info>0    =>  overwritten by solution
    6091             :                 * info=-3   =>  filled by zeros
    6092             : 
    6093             : 
    6094             :   -- ALGLIB --
    6095             :      Copyright 27.01.2010 by Bochkanov Sergey
    6096             : *************************************************************************/
    6097           0 : void rmatrixsolvemfast(/* Real    */ ae_matrix* a,
    6098             :      ae_int_t n,
    6099             :      /* Real    */ ae_matrix* b,
    6100             :      ae_int_t m,
    6101             :      ae_int_t* info,
    6102             :      ae_state *_state)
    6103             : {
    6104             :     ae_frame _frame_block;
    6105             :     ae_matrix _a;
    6106             :     double v;
    6107             :     ae_int_t i;
    6108             :     ae_int_t j;
    6109             :     ae_int_t k;
    6110             :     ae_vector p;
    6111             : 
    6112           0 :     ae_frame_make(_state, &_frame_block);
    6113           0 :     memset(&_a, 0, sizeof(_a));
    6114           0 :     memset(&p, 0, sizeof(p));
    6115           0 :     ae_matrix_init_copy(&_a, a, _state, ae_true);
    6116           0 :     a = &_a;
    6117           0 :     *info = 0;
    6118           0 :     ae_vector_init(&p, 0, DT_INT, _state, ae_true);
    6119             : 
    6120             :     
    6121             :     /*
    6122             :      * Check for exact degeneracy
    6123             :      */
    6124           0 :     if( n<=0||m<=0 )
    6125             :     {
    6126           0 :         *info = -1;
    6127           0 :         ae_frame_leave(_state);
    6128           0 :         return;
    6129             :     }
    6130           0 :     rmatrixlu(a, n, n, &p, _state);
    6131           0 :     for(i=0; i<=n-1; i++)
    6132             :     {
    6133           0 :         if( ae_fp_eq(a->ptr.pp_double[i][i],(double)(0)) )
    6134             :         {
    6135           0 :             for(j=0; j<=n-1; j++)
    6136             :             {
    6137           0 :                 for(k=0; k<=m-1; k++)
    6138             :                 {
    6139           0 :                     b->ptr.pp_double[j][k] = 0.0;
    6140             :                 }
    6141             :             }
    6142           0 :             *info = -3;
    6143           0 :             ae_frame_leave(_state);
    6144           0 :             return;
    6145             :         }
    6146             :     }
    6147             :     
    6148             :     /*
    6149             :      * Solve with TRSM()
    6150             :      */
    6151           0 :     for(i=0; i<=n-1; i++)
    6152             :     {
    6153           0 :         if( p.ptr.p_int[i]!=i )
    6154             :         {
    6155           0 :             for(j=0; j<=m-1; j++)
    6156             :             {
    6157           0 :                 v = b->ptr.pp_double[i][j];
    6158           0 :                 b->ptr.pp_double[i][j] = b->ptr.pp_double[p.ptr.p_int[i]][j];
    6159           0 :                 b->ptr.pp_double[p.ptr.p_int[i]][j] = v;
    6160             :             }
    6161             :         }
    6162             :     }
    6163           0 :     rmatrixlefttrsm(n, m, a, 0, 0, ae_false, ae_true, 0, b, 0, 0, _state);
    6164           0 :     rmatrixlefttrsm(n, m, a, 0, 0, ae_true, ae_false, 0, b, 0, 0, _state);
    6165           0 :     *info = 1;
    6166           0 :     ae_frame_leave(_state);
    6167             : }
    6168             : 
    6169             : 
    6170             : /*************************************************************************
    6171             : Dense solver.
    6172             : 
    6173             : This  subroutine  solves  a  system  A*x=b,  where A is NxN non-denegerate
    6174             : real matrix given by its LU decomposition, x and b are real vectors.  This
    6175             : is "slow-but-robust" version of the linear LU-based solver. Faster version
    6176             : is RMatrixLUSolveFast() function.
    6177             : 
    6178             : Algorithm features:
    6179             : * automatic detection of degenerate cases
    6180             : * O(N^2) complexity
    6181             : * condition number estimation
    6182             : 
    6183             : No iterative refinement  is provided because exact form of original matrix
    6184             : is not known to subroutine. Use RMatrixSolve or RMatrixMixedSolve  if  you
    6185             : need iterative refinement.
    6186             : 
    6187             : IMPORTANT: ! this function is NOT the most efficient linear solver provided
    6188             :            ! by ALGLIB. It estimates condition  number  of  linear system,
    6189             :            ! which results in 10-15x  performance  penalty  when  compared
    6190             :            ! with "fast" version which just calls triangular solver.
    6191             :            !
    6192             :            ! This performance penalty is insignificant  when compared with
    6193             :            ! cost of large LU decomposition.  However,  if you  call  this
    6194             :            ! function many times for the same  left  side,  this  overhead
    6195             :            ! BECOMES significant. It  also  becomes significant for small-
    6196             :            ! scale problems.
    6197             :            !
    6198             :            ! In such cases we strongly recommend you to use faster solver,
    6199             :            ! RMatrixLUSolveFast() function.
    6200             : 
    6201             : INPUT PARAMETERS
    6202             :     LUA     -   array[N,N], LU decomposition, RMatrixLU result
    6203             :     P       -   array[N], pivots array, RMatrixLU result
    6204             :     N       -   size of A
    6205             :     B       -   array[N], right part
    6206             : 
    6207             : OUTPUT PARAMETERS
    6208             :     Info    -   return code:
    6209             :                 * -3    matrix is very badly conditioned or exactly singular.
    6210             :                 * -1    N<=0 was passed
    6211             :                 *  1    task is solved (but matrix A may be ill-conditioned,
    6212             :                         check R1/RInf parameters for condition numbers).
    6213             :     Rep     -   additional report, following fields are set:
    6214             :                 * rep.r1    condition number in 1-norm
    6215             :                 * rep.rinf  condition number in inf-norm
    6216             :     X       -   array[N], it contains:
    6217             :                 * info>0    =>  solution
    6218             :                 * info=-3   =>  filled by zeros
    6219             : 
    6220             :     
    6221             :   -- ALGLIB --
    6222             :      Copyright 27.01.2010 by Bochkanov Sergey
    6223             : *************************************************************************/
    6224           0 : void rmatrixlusolve(/* Real    */ ae_matrix* lua,
    6225             :      /* Integer */ ae_vector* p,
    6226             :      ae_int_t n,
    6227             :      /* Real    */ ae_vector* b,
    6228             :      ae_int_t* info,
    6229             :      densesolverreport* rep,
    6230             :      /* Real    */ ae_vector* x,
    6231             :      ae_state *_state)
    6232             : {
    6233             :     ae_frame _frame_block;
    6234             :     ae_matrix bm;
    6235             :     ae_matrix xm;
    6236             : 
    6237           0 :     ae_frame_make(_state, &_frame_block);
    6238           0 :     memset(&bm, 0, sizeof(bm));
    6239           0 :     memset(&xm, 0, sizeof(xm));
    6240           0 :     *info = 0;
    6241           0 :     _densesolverreport_clear(rep);
    6242           0 :     ae_vector_clear(x);
    6243           0 :     ae_matrix_init(&bm, 0, 0, DT_REAL, _state, ae_true);
    6244           0 :     ae_matrix_init(&xm, 0, 0, DT_REAL, _state, ae_true);
    6245             : 
    6246           0 :     if( n<=0 )
    6247             :     {
    6248           0 :         *info = -1;
    6249           0 :         ae_frame_leave(_state);
    6250           0 :         return;
    6251             :     }
    6252           0 :     ae_matrix_set_length(&bm, n, 1, _state);
    6253           0 :     ae_v_move(&bm.ptr.pp_double[0][0], bm.stride, &b->ptr.p_double[0], 1, ae_v_len(0,n-1));
    6254           0 :     rmatrixlusolvem(lua, p, n, &bm, 1, info, rep, &xm, _state);
    6255           0 :     ae_vector_set_length(x, n, _state);
    6256           0 :     ae_v_move(&x->ptr.p_double[0], 1, &xm.ptr.pp_double[0][0], xm.stride, ae_v_len(0,n-1));
    6257           0 :     ae_frame_leave(_state);
    6258             : }
    6259             : 
    6260             : 
    6261             : /*************************************************************************
    6262             : Dense solver.
    6263             : 
    6264             : This  subroutine  solves  a  system  A*x=b,  where A is NxN non-denegerate
    6265             : real matrix given by its LU decomposition, x and b are real vectors.  This
    6266             : is "fast-without-any-checks" version of the linear LU-based solver. Slower
    6267             : but more robust version is RMatrixLUSolve() function.
    6268             : 
    6269             : Algorithm features:
    6270             : * O(N^2) complexity
    6271             : * fast algorithm without ANY additional checks, just triangular solver
    6272             : 
    6273             : INPUT PARAMETERS
    6274             :     LUA     -   array[0..N-1,0..N-1], LU decomposition, RMatrixLU result
    6275             :     P       -   array[0..N-1], pivots array, RMatrixLU result
    6276             :     N       -   size of A
    6277             :     B       -   array[0..N-1], right part
    6278             : 
    6279             : OUTPUT PARAMETERS
    6280             :     Info    -   return code:
    6281             :                 * -3    matrix is exactly singular (ill conditioned matrices
    6282             :                         are not recognized).
    6283             :                         X is filled by zeros in such cases.
    6284             :                 * -1    N<=0 was passed
    6285             :                 *  1    task is solved 
    6286             :     B       -   array[N]:
    6287             :                 * info>0    =>  overwritten by solution
    6288             :                 * info=-3   =>  filled by zeros
    6289             : 
    6290             :   -- ALGLIB --
    6291             :      Copyright 18.03.2015 by Bochkanov Sergey
    6292             : *************************************************************************/
    6293           0 : void rmatrixlusolvefast(/* Real    */ ae_matrix* lua,
    6294             :      /* Integer */ ae_vector* p,
    6295             :      ae_int_t n,
    6296             :      /* Real    */ ae_vector* b,
    6297             :      ae_int_t* info,
    6298             :      ae_state *_state)
    6299             : {
    6300             :     ae_int_t i;
    6301             :     ae_int_t j;
    6302             : 
    6303           0 :     *info = 0;
    6304             : 
    6305           0 :     if( n<=0 )
    6306             :     {
    6307           0 :         *info = -1;
    6308           0 :         return;
    6309             :     }
    6310           0 :     for(i=0; i<=n-1; i++)
    6311             :     {
    6312           0 :         if( ae_fp_eq(lua->ptr.pp_double[i][i],(double)(0)) )
    6313             :         {
    6314           0 :             for(j=0; j<=n-1; j++)
    6315             :             {
    6316           0 :                 b->ptr.p_double[j] = 0.0;
    6317             :             }
    6318           0 :             *info = -3;
    6319           0 :             return;
    6320             :         }
    6321             :     }
    6322           0 :     directdensesolvers_rbasiclusolve(lua, p, n, b, _state);
    6323           0 :     *info = 1;
    6324             : }
    6325             : 
    6326             : 
    6327             : /*************************************************************************
    6328             : Dense solver.
    6329             : 
    6330             : Similar to RMatrixLUSolve() but solves  task  with  multiple  right  parts
    6331             : (where b and x are NxM matrices). This  is  "robust-but-slow"  version  of
    6332             : LU-based solver which performs additional  checks  for  non-degeneracy  of
    6333             : inputs (condition number estimation). If you need  best  performance,  use
    6334             : "fast-without-any-checks" version, RMatrixLUSolveMFast().
    6335             : 
    6336             : Algorithm features:
    6337             : * automatic detection of degenerate cases
    6338             : * O(M*N^2) complexity
    6339             : * condition number estimation
    6340             : 
    6341             : No iterative refinement  is provided because exact form of original matrix
    6342             : is not known to subroutine. Use RMatrixSolve or RMatrixMixedSolve  if  you
    6343             : need iterative refinement.
    6344             : 
    6345             : IMPORTANT: ! this function is NOT the most efficient linear solver provided
    6346             :            ! by ALGLIB. It estimates condition  number  of  linear system,
    6347             :            ! which  results  in  significant  performance   penalty   when
    6348             :            ! compared with "fast"  version  which  just  calls  triangular
    6349             :            ! solver.
    6350             :            !
    6351             :            ! This performance penalty is especially apparent when you  use
    6352             :            ! ALGLIB parallel capabilities (condition number estimation  is
    6353             :            ! inherently  sequential).  It   also   becomes significant for
    6354             :            ! small-scale problems.
    6355             :            !
    6356             :            ! In such cases we strongly recommend you to use faster solver,
    6357             :            ! RMatrixLUSolveMFast() function.
    6358             : 
    6359             :   ! COMMERCIAL EDITION OF ALGLIB:
    6360             :   ! 
    6361             :   ! Commercial Edition of ALGLIB includes following important improvements
    6362             :   ! of this function:
    6363             :   ! * high-performance native backend with same C# interface (C# version)
    6364             :   ! * multithreading support (C++ and C# versions)
    6365             :   ! * hardware vendor (Intel) implementations of linear algebra primitives
    6366             :   !   (C++ and C# versions, x86/x64 platform)
    6367             :   ! 
    6368             :   ! We recommend you to read 'Working with commercial version' section  of
    6369             :   ! ALGLIB Reference Manual in order to find out how to  use  performance-
    6370             :   ! related features provided by commercial edition of ALGLIB.
    6371             :   
    6372             : INPUT PARAMETERS
    6373             :     LUA     -   array[N,N], LU decomposition, RMatrixLU result
    6374             :     P       -   array[N], pivots array, RMatrixLU result
    6375             :     N       -   size of A
    6376             :     B       -   array[0..N-1,0..M-1], right part
    6377             :     M       -   right part size
    6378             : 
    6379             : OUTPUT PARAMETERS
    6380             :     Info    -   return code:
    6381             :                 * -3    matrix is very badly conditioned or exactly singular.
    6382             :                         X is filled by zeros in such cases.
    6383             :                 * -1    N<=0 was passed
    6384             :                 *  1    task is solved (but matrix A may be ill-conditioned,
    6385             :                         check R1/RInf parameters for condition numbers).
    6386             :     Rep     -   additional report, following fields are set:
    6387             :                 * rep.r1    condition number in 1-norm
    6388             :                 * rep.rinf  condition number in inf-norm
    6389             :     X       -   array[N,M], it contains:
    6390             :                 * info>0    =>  solution
    6391             :                 * info=-3   =>  filled by zeros
    6392             : 
    6393             : 
    6394             :   -- ALGLIB --
    6395             :      Copyright 27.01.2010 by Bochkanov Sergey
    6396             : *************************************************************************/
    6397           0 : void rmatrixlusolvem(/* Real    */ ae_matrix* lua,
    6398             :      /* Integer */ ae_vector* p,
    6399             :      ae_int_t n,
    6400             :      /* Real    */ ae_matrix* b,
    6401             :      ae_int_t m,
    6402             :      ae_int_t* info,
    6403             :      densesolverreport* rep,
    6404             :      /* Real    */ ae_matrix* x,
    6405             :      ae_state *_state)
    6406             : {
    6407             :     ae_frame _frame_block;
    6408             :     ae_matrix emptya;
    6409             : 
    6410           0 :     ae_frame_make(_state, &_frame_block);
    6411           0 :     memset(&emptya, 0, sizeof(emptya));
    6412           0 :     *info = 0;
    6413           0 :     _densesolverreport_clear(rep);
    6414           0 :     ae_matrix_clear(x);
    6415           0 :     ae_matrix_init(&emptya, 0, 0, DT_REAL, _state, ae_true);
    6416             : 
    6417             :     
    6418             :     /*
    6419             :      * prepare: check inputs, allocate space...
    6420             :      */
    6421           0 :     if( n<=0||m<=0 )
    6422             :     {
    6423           0 :         *info = -1;
    6424           0 :         ae_frame_leave(_state);
    6425           0 :         return;
    6426             :     }
    6427             :     
    6428             :     /*
    6429             :      * solve
    6430             :      */
    6431           0 :     directdensesolvers_rmatrixlusolveinternal(lua, p, n, &emptya, ae_false, b, m, info, rep, x, _state);
    6432           0 :     ae_frame_leave(_state);
    6433             : }
    6434             : 
    6435             : 
    6436             : /*************************************************************************
    6437             : Dense solver.
    6438             : 
    6439             : Similar to RMatrixLUSolve() but solves  task  with  multiple  right parts,
    6440             : where b and x are NxM matrices.  This is "fast-without-any-checks" version
    6441             : of LU-based solver. It does not estimate  condition number  of  a  system,
    6442             : so it is extremely fast. If you need better detection  of  near-degenerate
    6443             : cases, use RMatrixLUSolveM() function.
    6444             : 
    6445             : Algorithm features:
    6446             : * O(M*N^2) complexity
    6447             : * fast algorithm without ANY additional checks, just triangular solver
    6448             : 
    6449             :   ! COMMERCIAL EDITION OF ALGLIB:
    6450             :   ! 
    6451             :   ! Commercial Edition of ALGLIB includes following important improvements
    6452             :   ! of this function:
    6453             :   ! * high-performance native backend with same C# interface (C# version)
    6454             :   ! * multithreading support (C++ and C# versions)
    6455             :   ! * hardware vendor (Intel) implementations of linear algebra primitives
    6456             :   !   (C++ and C# versions, x86/x64 platform)
    6457             :   ! 
    6458             :   ! We recommend you to read 'Working with commercial version' section  of
    6459             :   ! ALGLIB Reference Manual in order to find out how to  use  performance-
    6460             :   ! related features provided by commercial edition of ALGLIB.
    6461             : 
    6462             : INPUT PARAMETERS:
    6463             :     LUA     -   array[0..N-1,0..N-1], LU decomposition, RMatrixLU result
    6464             :     P       -   array[0..N-1], pivots array, RMatrixLU result
    6465             :     N       -   size of A
    6466             :     B       -   array[0..N-1,0..M-1], right part
    6467             :     M       -   right part size
    6468             : 
    6469             : OUTPUT PARAMETERS:
    6470             :     Info    -   return code:
    6471             :                 * -3    matrix is exactly singular (ill conditioned matrices
    6472             :                         are not recognized).
    6473             :                 * -1    N<=0 was passed
    6474             :                 *  1    task is solved
    6475             :     B       -   array[N,M]:
    6476             :                 * info>0    =>  overwritten by solution
    6477             :                 * info=-3   =>  filled by zeros
    6478             : 
    6479             :   -- ALGLIB --
    6480             :      Copyright 18.03.2015 by Bochkanov Sergey
    6481             : *************************************************************************/
    6482           0 : void rmatrixlusolvemfast(/* Real    */ ae_matrix* lua,
    6483             :      /* Integer */ ae_vector* p,
    6484             :      ae_int_t n,
    6485             :      /* Real    */ ae_matrix* b,
    6486             :      ae_int_t m,
    6487             :      ae_int_t* info,
    6488             :      ae_state *_state)
    6489             : {
    6490             :     double v;
    6491             :     ae_int_t i;
    6492             :     ae_int_t j;
    6493             :     ae_int_t k;
    6494             : 
    6495           0 :     *info = 0;
    6496             : 
    6497             :     
    6498             :     /*
    6499             :      * Check for exact degeneracy
    6500             :      */
    6501           0 :     if( n<=0||m<=0 )
    6502             :     {
    6503           0 :         *info = -1;
    6504           0 :         return;
    6505             :     }
    6506           0 :     for(i=0; i<=n-1; i++)
    6507             :     {
    6508           0 :         if( ae_fp_eq(lua->ptr.pp_double[i][i],(double)(0)) )
    6509             :         {
    6510           0 :             for(j=0; j<=n-1; j++)
    6511             :             {
    6512           0 :                 for(k=0; k<=m-1; k++)
    6513             :                 {
    6514           0 :                     b->ptr.pp_double[j][k] = 0.0;
    6515             :                 }
    6516             :             }
    6517           0 :             *info = -3;
    6518           0 :             return;
    6519             :         }
    6520             :     }
    6521             :     
    6522             :     /*
    6523             :      * Solve with TRSM()
    6524             :      */
    6525           0 :     for(i=0; i<=n-1; i++)
    6526             :     {
    6527           0 :         if( p->ptr.p_int[i]!=i )
    6528             :         {
    6529           0 :             for(j=0; j<=m-1; j++)
    6530             :             {
    6531           0 :                 v = b->ptr.pp_double[i][j];
    6532           0 :                 b->ptr.pp_double[i][j] = b->ptr.pp_double[p->ptr.p_int[i]][j];
    6533           0 :                 b->ptr.pp_double[p->ptr.p_int[i]][j] = v;
    6534             :             }
    6535             :         }
    6536             :     }
    6537           0 :     rmatrixlefttrsm(n, m, lua, 0, 0, ae_false, ae_true, 0, b, 0, 0, _state);
    6538           0 :     rmatrixlefttrsm(n, m, lua, 0, 0, ae_true, ae_false, 0, b, 0, 0, _state);
    6539           0 :     *info = 1;
    6540             : }
    6541             : 
    6542             : 
    6543             : /*************************************************************************
    6544             : Dense solver.
    6545             : 
    6546             : This  subroutine  solves  a  system  A*x=b,  where BOTH ORIGINAL A AND ITS
    6547             : LU DECOMPOSITION ARE KNOWN. You can use it if for some  reasons  you  have
    6548             : both A and its LU decomposition.
    6549             : 
    6550             : Algorithm features:
    6551             : * automatic detection of degenerate cases
    6552             : * condition number estimation
    6553             : * iterative refinement
    6554             : * O(N^2) complexity
    6555             : 
    6556             : INPUT PARAMETERS
    6557             :     A       -   array[0..N-1,0..N-1], system matrix
    6558             :     LUA     -   array[0..N-1,0..N-1], LU decomposition, RMatrixLU result
    6559             :     P       -   array[0..N-1], pivots array, RMatrixLU result
    6560             :     N       -   size of A
    6561             :     B       -   array[0..N-1], right part
    6562             : 
    6563             : OUTPUT PARAMETERS
    6564             :     Info    -   return code:
    6565             :                 * -3    matrix is very badly conditioned or exactly singular.
    6566             :                 * -1    N<=0 was passed
    6567             :                 *  1    task is solved (but matrix A may be ill-conditioned,
    6568             :                         check R1/RInf parameters for condition numbers).
    6569             :     Rep     -   additional report, following fields are set:
    6570             :                 * rep.r1    condition number in 1-norm
    6571             :                 * rep.rinf  condition number in inf-norm
    6572             :     X       -   array[N], it contains:
    6573             :                 * info>0    =>  solution
    6574             :                 * info=-3   =>  filled by zeros
    6575             : 
    6576             :   -- ALGLIB --
    6577             :      Copyright 27.01.2010 by Bochkanov Sergey
    6578             : *************************************************************************/
    6579           0 : void rmatrixmixedsolve(/* Real    */ ae_matrix* a,
    6580             :      /* Real    */ ae_matrix* lua,
    6581             :      /* Integer */ ae_vector* p,
    6582             :      ae_int_t n,
    6583             :      /* Real    */ ae_vector* b,
    6584             :      ae_int_t* info,
    6585             :      densesolverreport* rep,
    6586             :      /* Real    */ ae_vector* x,
    6587             :      ae_state *_state)
    6588             : {
    6589             :     ae_frame _frame_block;
    6590             :     ae_matrix bm;
    6591             :     ae_matrix xm;
    6592             : 
    6593           0 :     ae_frame_make(_state, &_frame_block);
    6594           0 :     memset(&bm, 0, sizeof(bm));
    6595           0 :     memset(&xm, 0, sizeof(xm));
    6596           0 :     *info = 0;
    6597           0 :     _densesolverreport_clear(rep);
    6598           0 :     ae_vector_clear(x);
    6599           0 :     ae_matrix_init(&bm, 0, 0, DT_REAL, _state, ae_true);
    6600           0 :     ae_matrix_init(&xm, 0, 0, DT_REAL, _state, ae_true);
    6601             : 
    6602           0 :     if( n<=0 )
    6603             :     {
    6604           0 :         *info = -1;
    6605           0 :         ae_frame_leave(_state);
    6606           0 :         return;
    6607             :     }
    6608           0 :     ae_matrix_set_length(&bm, n, 1, _state);
    6609           0 :     ae_v_move(&bm.ptr.pp_double[0][0], bm.stride, &b->ptr.p_double[0], 1, ae_v_len(0,n-1));
    6610           0 :     rmatrixmixedsolvem(a, lua, p, n, &bm, 1, info, rep, &xm, _state);
    6611           0 :     ae_vector_set_length(x, n, _state);
    6612           0 :     ae_v_move(&x->ptr.p_double[0], 1, &xm.ptr.pp_double[0][0], xm.stride, ae_v_len(0,n-1));
    6613           0 :     ae_frame_leave(_state);
    6614             : }
    6615             : 
    6616             : 
    6617             : /*************************************************************************
    6618             : Dense solver.
    6619             : 
    6620             : Similar to RMatrixMixedSolve() but  solves task with multiple right  parts
    6621             : (where b and x are NxM matrices).
    6622             : 
    6623             : Algorithm features:
    6624             : * automatic detection of degenerate cases
    6625             : * condition number estimation
    6626             : * iterative refinement
    6627             : * O(M*N^2) complexity
    6628             : 
    6629             : INPUT PARAMETERS
    6630             :     A       -   array[0..N-1,0..N-1], system matrix
    6631             :     LUA     -   array[0..N-1,0..N-1], LU decomposition, RMatrixLU result
    6632             :     P       -   array[0..N-1], pivots array, RMatrixLU result
    6633             :     N       -   size of A
    6634             :     B       -   array[0..N-1,0..M-1], right part
    6635             :     M       -   right part size
    6636             : 
    6637             : OUTPUT PARAMETERS
    6638             :     Info    -   return code:
    6639             :                 * -3    matrix is very badly conditioned or exactly singular.
    6640             :                 * -1    N<=0 was passed
    6641             :                 *  1    task is solved (but matrix A may be ill-conditioned,
    6642             :                         check R1/RInf parameters for condition numbers).
    6643             :     Rep     -   additional report, following fields are set:
    6644             :                 * rep.r1    condition number in 1-norm
    6645             :                 * rep.rinf  condition number in inf-norm
    6646             :     X       -   array[N,M], it contains:
    6647             :                 * info>0    =>  solution
    6648             :                 * info=-3   =>  filled by zeros
    6649             : 
    6650             :   -- ALGLIB --
    6651             :      Copyright 27.01.2010 by Bochkanov Sergey
    6652             : *************************************************************************/
    6653           0 : void rmatrixmixedsolvem(/* Real    */ ae_matrix* a,
    6654             :      /* Real    */ ae_matrix* lua,
    6655             :      /* Integer */ ae_vector* p,
    6656             :      ae_int_t n,
    6657             :      /* Real    */ ae_matrix* b,
    6658             :      ae_int_t m,
    6659             :      ae_int_t* info,
    6660             :      densesolverreport* rep,
    6661             :      /* Real    */ ae_matrix* x,
    6662             :      ae_state *_state)
    6663             : {
    6664             : 
    6665           0 :     *info = 0;
    6666           0 :     _densesolverreport_clear(rep);
    6667           0 :     ae_matrix_clear(x);
    6668             : 
    6669             :     
    6670             :     /*
    6671             :      * prepare: check inputs, allocate space...
    6672             :      */
    6673           0 :     if( n<=0||m<=0 )
    6674             :     {
    6675           0 :         *info = -1;
    6676           0 :         return;
    6677             :     }
    6678             :     
    6679             :     /*
    6680             :      * solve
    6681             :      */
    6682           0 :     directdensesolvers_rmatrixlusolveinternal(lua, p, n, a, ae_true, b, m, info, rep, x, _state);
    6683             : }
    6684             : 
    6685             : 
    6686             : /*************************************************************************
    6687             : Complex dense solver for A*X=B with N*N  complex  matrix  A,  N*M  complex
    6688             : matrices  X  and  B.  "Slow-but-feature-rich"   version   which   provides
    6689             : additional functions, at the cost of slower  performance.  Faster  version
    6690             : may be invoked with CMatrixSolveMFast() function.
    6691             : 
    6692             : Algorithm features:
    6693             : * automatic detection of degenerate cases
    6694             : * condition number estimation
    6695             : * iterative refinement
    6696             : * O(N^3+M*N^2) complexity
    6697             : 
    6698             : IMPORTANT: ! this function is NOT the most efficient linear solver provided
    6699             :            ! by ALGLIB. It estimates condition  number  of  linear  system
    6700             :            ! and  performs  iterative   refinement,   which   results   in
    6701             :            ! significant performance penalty  when  compared  with  "fast"
    6702             :            ! version  which  just  performs  LU  decomposition  and  calls
    6703             :            ! triangular solver.
    6704             :            !
    6705             :            ! This  performance  penalty  is  especially  visible  in   the
    6706             :            ! multithreaded mode, because both condition number  estimation
    6707             :            ! and   iterative    refinement   are   inherently   sequential
    6708             :            ! calculations.
    6709             :            !
    6710             :            ! Thus, if you need high performance and if you are pretty sure
    6711             :            ! that your system is well conditioned, we  strongly  recommend
    6712             :            ! you to use faster solver, CMatrixSolveMFast() function.
    6713             : 
    6714             :   ! COMMERCIAL EDITION OF ALGLIB:
    6715             :   ! 
    6716             :   ! Commercial Edition of ALGLIB includes following important improvements
    6717             :   ! of this function:
    6718             :   ! * high-performance native backend with same C# interface (C# version)
    6719             :   ! * multithreading support (C++ and C# versions)
    6720             :   ! * hardware vendor (Intel) implementations of linear algebra primitives
    6721             :   !   (C++ and C# versions, x86/x64 platform)
    6722             :   ! 
    6723             :   ! We recommend you to read 'Working with commercial version' section  of
    6724             :   ! ALGLIB Reference Manual in order to find out how to  use  performance-
    6725             :   ! related features provided by commercial edition of ALGLIB.
    6726             : 
    6727             : INPUT PARAMETERS
    6728             :     A       -   array[0..N-1,0..N-1], system matrix
    6729             :     N       -   size of A
    6730             :     B       -   array[0..N-1,0..M-1], right part
    6731             :     M       -   right part size
    6732             :     RFS     -   iterative refinement switch:
    6733             :                 * True - refinement is used.
    6734             :                   Less performance, more precision.
    6735             :                 * False - refinement is not used.
    6736             :                   More performance, less precision.
    6737             : 
    6738             : OUTPUT PARAMETERS
    6739             :     Info    -   return code:
    6740             :                 * -3    matrix is very badly conditioned or exactly singular.
    6741             :                         X is filled by zeros in such cases.
    6742             :                 * -1    N<=0 was passed
    6743             :                 *  1    task is solved (but matrix A may be ill-conditioned,
    6744             :                         check R1/RInf parameters for condition numbers).
    6745             :     Rep     -   additional report, following fields are set:
    6746             :                 * rep.r1    condition number in 1-norm
    6747             :                 * rep.rinf  condition number in inf-norm
    6748             :     X       -   array[N,M], it contains:
    6749             :                 * info>0    =>  solution
    6750             :                 * info=-3   =>  filled by zeros
    6751             : 
    6752             :   -- ALGLIB --
    6753             :      Copyright 27.01.2010 by Bochkanov Sergey
    6754             : *************************************************************************/
    6755           0 : void cmatrixsolvem(/* Complex */ ae_matrix* a,
    6756             :      ae_int_t n,
    6757             :      /* Complex */ ae_matrix* b,
    6758             :      ae_int_t m,
    6759             :      ae_bool rfs,
    6760             :      ae_int_t* info,
    6761             :      densesolverreport* rep,
    6762             :      /* Complex */ ae_matrix* x,
    6763             :      ae_state *_state)
    6764             : {
    6765             :     ae_frame _frame_block;
    6766             :     ae_matrix da;
    6767             :     ae_matrix emptya;
    6768             :     ae_vector p;
    6769             :     ae_int_t i;
    6770             : 
    6771           0 :     ae_frame_make(_state, &_frame_block);
    6772           0 :     memset(&da, 0, sizeof(da));
    6773           0 :     memset(&emptya, 0, sizeof(emptya));
    6774           0 :     memset(&p, 0, sizeof(p));
    6775           0 :     *info = 0;
    6776           0 :     _densesolverreport_clear(rep);
    6777           0 :     ae_matrix_clear(x);
    6778           0 :     ae_matrix_init(&da, 0, 0, DT_COMPLEX, _state, ae_true);
    6779           0 :     ae_matrix_init(&emptya, 0, 0, DT_COMPLEX, _state, ae_true);
    6780           0 :     ae_vector_init(&p, 0, DT_INT, _state, ae_true);
    6781             : 
    6782             :     
    6783             :     /*
    6784             :      * prepare: check inputs, allocate space...
    6785             :      */
    6786           0 :     if( n<=0||m<=0 )
    6787             :     {
    6788           0 :         *info = -1;
    6789           0 :         ae_frame_leave(_state);
    6790           0 :         return;
    6791             :     }
    6792           0 :     ae_matrix_set_length(&da, n, n, _state);
    6793             :     
    6794             :     /*
    6795             :      * factorize, solve
    6796             :      */
    6797           0 :     for(i=0; i<=n-1; i++)
    6798             :     {
    6799           0 :         ae_v_cmove(&da.ptr.pp_complex[i][0], 1, &a->ptr.pp_complex[i][0], 1, "N", ae_v_len(0,n-1));
    6800             :     }
    6801           0 :     cmatrixlu(&da, n, n, &p, _state);
    6802           0 :     if( rfs )
    6803             :     {
    6804           0 :         directdensesolvers_cmatrixlusolveinternal(&da, &p, n, a, ae_true, b, m, info, rep, x, _state);
    6805             :     }
    6806             :     else
    6807             :     {
    6808           0 :         directdensesolvers_cmatrixlusolveinternal(&da, &p, n, &emptya, ae_false, b, m, info, rep, x, _state);
    6809             :     }
    6810           0 :     ae_frame_leave(_state);
    6811             : }
    6812             : 
    6813             : 
    6814             : /*************************************************************************
    6815             : Complex dense solver for A*X=B with N*N  complex  matrix  A,  N*M  complex
    6816             : matrices  X  and  B.  "Fast-but-lightweight" version which  provides  just
    6817             : triangular solver - and no additional functions like iterative  refinement
    6818             : or condition number estimation.
    6819             : 
    6820             : Algorithm features:
    6821             : * O(N^3+M*N^2) complexity
    6822             : * no additional time consuming functions
    6823             : 
    6824             :   ! COMMERCIAL EDITION OF ALGLIB:
    6825             :   ! 
    6826             :   ! Commercial Edition of ALGLIB includes following important improvements
    6827             :   ! of this function:
    6828             :   ! * high-performance native backend with same C# interface (C# version)
    6829             :   ! * multithreading support (C++ and C# versions)
    6830             :   ! * hardware vendor (Intel) implementations of linear algebra primitives
    6831             :   !   (C++ and C# versions, x86/x64 platform)
    6832             :   ! 
    6833             :   ! We recommend you to read 'Working with commercial version' section  of
    6834             :   ! ALGLIB Reference Manual in order to find out how to  use  performance-
    6835             :   ! related features provided by commercial edition of ALGLIB.
    6836             : 
    6837             : INPUT PARAMETERS
    6838             :     A       -   array[0..N-1,0..N-1], system matrix
    6839             :     N       -   size of A
    6840             :     B       -   array[0..N-1,0..M-1], right part
    6841             :     M       -   right part size
    6842             : 
    6843             : OUTPUT PARAMETERS:
    6844             :     Info    -   return code:
    6845             :                 * -3    matrix is exactly singular (ill conditioned matrices
    6846             :                         are not recognized).
    6847             :                 * -1    N<=0 was passed
    6848             :                 *  1    task is solved 
    6849             :     B       -   array[N,M]:
    6850             :                 * info>0    =>  overwritten by solution
    6851             :                 * info=-3   =>  filled by zeros
    6852             : 
    6853             :   -- ALGLIB --
    6854             :      Copyright 16.03.2015 by Bochkanov Sergey
    6855             : *************************************************************************/
    6856           0 : void cmatrixsolvemfast(/* Complex */ ae_matrix* a,
    6857             :      ae_int_t n,
    6858             :      /* Complex */ ae_matrix* b,
    6859             :      ae_int_t m,
    6860             :      ae_int_t* info,
    6861             :      ae_state *_state)
    6862             : {
    6863             :     ae_frame _frame_block;
    6864             :     ae_matrix _a;
    6865             :     ae_complex v;
    6866             :     ae_int_t i;
    6867             :     ae_int_t j;
    6868             :     ae_int_t k;
    6869             :     ae_vector p;
    6870             : 
    6871           0 :     ae_frame_make(_state, &_frame_block);
    6872           0 :     memset(&_a, 0, sizeof(_a));
    6873           0 :     memset(&p, 0, sizeof(p));
    6874           0 :     ae_matrix_init_copy(&_a, a, _state, ae_true);
    6875           0 :     a = &_a;
    6876           0 :     *info = 0;
    6877           0 :     ae_vector_init(&p, 0, DT_INT, _state, ae_true);
    6878             : 
    6879             :     
    6880             :     /*
    6881             :      * Check for exact degeneracy
    6882             :      */
    6883           0 :     if( n<=0||m<=0 )
    6884             :     {
    6885           0 :         *info = -1;
    6886           0 :         ae_frame_leave(_state);
    6887           0 :         return;
    6888             :     }
    6889           0 :     cmatrixlu(a, n, n, &p, _state);
    6890           0 :     for(i=0; i<=n-1; i++)
    6891             :     {
    6892           0 :         if( ae_c_eq_d(a->ptr.pp_complex[i][i],(double)(0)) )
    6893             :         {
    6894           0 :             for(j=0; j<=n-1; j++)
    6895             :             {
    6896           0 :                 for(k=0; k<=m-1; k++)
    6897             :                 {
    6898           0 :                     b->ptr.pp_complex[j][k] = ae_complex_from_d(0.0);
    6899             :                 }
    6900             :             }
    6901           0 :             *info = -3;
    6902           0 :             ae_frame_leave(_state);
    6903           0 :             return;
    6904             :         }
    6905             :     }
    6906             :     
    6907             :     /*
    6908             :      * Solve with TRSM()
    6909             :      */
    6910           0 :     for(i=0; i<=n-1; i++)
    6911             :     {
    6912           0 :         if( p.ptr.p_int[i]!=i )
    6913             :         {
    6914           0 :             for(j=0; j<=m-1; j++)
    6915             :             {
    6916           0 :                 v = b->ptr.pp_complex[i][j];
    6917           0 :                 b->ptr.pp_complex[i][j] = b->ptr.pp_complex[p.ptr.p_int[i]][j];
    6918           0 :                 b->ptr.pp_complex[p.ptr.p_int[i]][j] = v;
    6919             :             }
    6920             :         }
    6921             :     }
    6922           0 :     cmatrixlefttrsm(n, m, a, 0, 0, ae_false, ae_true, 0, b, 0, 0, _state);
    6923           0 :     cmatrixlefttrsm(n, m, a, 0, 0, ae_true, ae_false, 0, b, 0, 0, _state);
    6924           0 :     *info = 1;
    6925           0 :     ae_frame_leave(_state);
    6926             : }
    6927             : 
    6928             : 
    6929             : /*************************************************************************
    6930             : Complex dense solver for A*x=B with N*N complex matrix A and  N*1  complex
    6931             : vectors x and b. "Slow-but-feature-rich" version of the solver.
    6932             : 
    6933             : Algorithm features:
    6934             : * automatic detection of degenerate cases
    6935             : * condition number estimation
    6936             : * iterative refinement
    6937             : * O(N^3) complexity
    6938             : 
    6939             : IMPORTANT: ! this function is NOT the most efficient linear solver provided
    6940             :            ! by ALGLIB. It estimates condition  number  of  linear  system
    6941             :            ! and  performs  iterative   refinement,   which   results   in
    6942             :            ! significant performance penalty  when  compared  with  "fast"
    6943             :            ! version  which  just  performs  LU  decomposition  and  calls
    6944             :            ! triangular solver.
    6945             :            !
    6946             :            ! This  performance  penalty  is  especially  visible  in   the
    6947             :            ! multithreaded mode, because both condition number  estimation
    6948             :            ! and   iterative    refinement   are   inherently   sequential
    6949             :            ! calculations.
    6950             :            !
    6951             :            ! Thus, if you need high performance and if you are pretty sure
    6952             :            ! that your system is well conditioned, we  strongly  recommend
    6953             :            ! you to use faster solver, CMatrixSolveFast() function.
    6954             : 
    6955             :   ! COMMERCIAL EDITION OF ALGLIB:
    6956             :   ! 
    6957             :   ! Commercial Edition of ALGLIB includes following important improvements
    6958             :   ! of this function:
    6959             :   ! * high-performance native backend with same C# interface (C# version)
    6960             :   ! * multithreading support (C++ and C# versions)
    6961             :   ! * hardware vendor (Intel) implementations of linear algebra primitives
    6962             :   !   (C++ and C# versions, x86/x64 platform)
    6963             :   ! 
    6964             :   ! We recommend you to read 'Working with commercial version' section  of
    6965             :   ! ALGLIB Reference Manual in order to find out how to  use  performance-
    6966             :   ! related features provided by commercial edition of ALGLIB.
    6967             : 
    6968             : INPUT PARAMETERS
    6969             :     A       -   array[0..N-1,0..N-1], system matrix
    6970             :     N       -   size of A
    6971             :     B       -   array[0..N-1], right part
    6972             : 
    6973             : OUTPUT PARAMETERS
    6974             :     Info    -   return code:
    6975             :                 * -3    matrix is very badly conditioned or exactly singular.
    6976             :                 * -1    N<=0 was passed
    6977             :                 *  1    task is solved (but matrix A may be ill-conditioned,
    6978             :                         check R1/RInf parameters for condition numbers).
    6979             :     Rep     -   additional report, following fields are set:
    6980             :                 * rep.r1    condition number in 1-norm
    6981             :                 * rep.rinf  condition number in inf-norm
    6982             :     X       -   array[N], it contains:
    6983             :                 * info>0    =>  solution
    6984             :                 * info=-3   =>  filled by zeros
    6985             : 
    6986             :   -- ALGLIB --
    6987             :      Copyright 27.01.2010 by Bochkanov Sergey
    6988             : *************************************************************************/
    6989           0 : void cmatrixsolve(/* Complex */ ae_matrix* a,
    6990             :      ae_int_t n,
    6991             :      /* Complex */ ae_vector* b,
    6992             :      ae_int_t* info,
    6993             :      densesolverreport* rep,
    6994             :      /* Complex */ ae_vector* x,
    6995             :      ae_state *_state)
    6996             : {
    6997             :     ae_frame _frame_block;
    6998             :     ae_matrix bm;
    6999             :     ae_matrix xm;
    7000             : 
    7001           0 :     ae_frame_make(_state, &_frame_block);
    7002           0 :     memset(&bm, 0, sizeof(bm));
    7003           0 :     memset(&xm, 0, sizeof(xm));
    7004           0 :     *info = 0;
    7005           0 :     _densesolverreport_clear(rep);
    7006           0 :     ae_vector_clear(x);
    7007           0 :     ae_matrix_init(&bm, 0, 0, DT_COMPLEX, _state, ae_true);
    7008           0 :     ae_matrix_init(&xm, 0, 0, DT_COMPLEX, _state, ae_true);
    7009             : 
    7010           0 :     if( n<=0 )
    7011             :     {
    7012           0 :         *info = -1;
    7013           0 :         ae_frame_leave(_state);
    7014           0 :         return;
    7015             :     }
    7016           0 :     ae_matrix_set_length(&bm, n, 1, _state);
    7017           0 :     ae_v_cmove(&bm.ptr.pp_complex[0][0], bm.stride, &b->ptr.p_complex[0], 1, "N", ae_v_len(0,n-1));
    7018           0 :     cmatrixsolvem(a, n, &bm, 1, ae_true, info, rep, &xm, _state);
    7019           0 :     ae_vector_set_length(x, n, _state);
    7020           0 :     ae_v_cmove(&x->ptr.p_complex[0], 1, &xm.ptr.pp_complex[0][0], xm.stride, "N", ae_v_len(0,n-1));
    7021           0 :     ae_frame_leave(_state);
    7022             : }
    7023             : 
    7024             : 
    7025             : /*************************************************************************
    7026             : Complex dense solver for A*x=B with N*N complex matrix A and  N*1  complex
    7027             : vectors x and b. "Fast-but-lightweight" version of the solver.
    7028             : 
    7029             : Algorithm features:
    7030             : * O(N^3) complexity
    7031             : * no additional time consuming features, just triangular solver
    7032             : 
    7033             :   ! COMMERCIAL EDITION OF ALGLIB:
    7034             :   ! 
    7035             :   ! Commercial Edition of ALGLIB includes following important improvements
    7036             :   ! of this function:
    7037             :   ! * high-performance native backend with same C# interface (C# version)
    7038             :   ! * multithreading support (C++ and C# versions)
    7039             :   ! * hardware vendor (Intel) implementations of linear algebra primitives
    7040             :   !   (C++ and C# versions, x86/x64 platform)
    7041             :   ! 
    7042             :   ! We recommend you to read 'Working with commercial version' section  of
    7043             :   ! ALGLIB Reference Manual in order to find out how to  use  performance-
    7044             :   ! related features provided by commercial edition of ALGLIB.
    7045             : 
    7046             : INPUT PARAMETERS:
    7047             :     A       -   array[0..N-1,0..N-1], system matrix
    7048             :     N       -   size of A
    7049             :     B       -   array[0..N-1], right part
    7050             : 
    7051             : OUTPUT PARAMETERS:
    7052             :     Info    -   return code:
    7053             :                 * -3    matrix is exactly singular (ill conditioned matrices
    7054             :                         are not recognized).
    7055             :                 * -1    N<=0 was passed
    7056             :                 *  1    task is solved 
    7057             :     B       -   array[N]:
    7058             :                 * info>0    =>  overwritten by solution
    7059             :                 * info=-3   =>  filled by zeros
    7060             : 
    7061             :   -- ALGLIB --
    7062             :      Copyright 27.01.2010 by Bochkanov Sergey
    7063             : *************************************************************************/
    7064           0 : void cmatrixsolvefast(/* Complex */ ae_matrix* a,
    7065             :      ae_int_t n,
    7066             :      /* Complex */ ae_vector* b,
    7067             :      ae_int_t* info,
    7068             :      ae_state *_state)
    7069             : {
    7070             :     ae_frame _frame_block;
    7071             :     ae_matrix _a;
    7072             :     ae_int_t i;
    7073             :     ae_int_t j;
    7074             :     ae_vector p;
    7075             : 
    7076           0 :     ae_frame_make(_state, &_frame_block);
    7077           0 :     memset(&_a, 0, sizeof(_a));
    7078           0 :     memset(&p, 0, sizeof(p));
    7079           0 :     ae_matrix_init_copy(&_a, a, _state, ae_true);
    7080           0 :     a = &_a;
    7081           0 :     *info = 0;
    7082           0 :     ae_vector_init(&p, 0, DT_INT, _state, ae_true);
    7083             : 
    7084           0 :     if( n<=0 )
    7085             :     {
    7086           0 :         *info = -1;
    7087           0 :         ae_frame_leave(_state);
    7088           0 :         return;
    7089             :     }
    7090           0 :     cmatrixlu(a, n, n, &p, _state);
    7091           0 :     for(i=0; i<=n-1; i++)
    7092             :     {
    7093           0 :         if( ae_c_eq_d(a->ptr.pp_complex[i][i],(double)(0)) )
    7094             :         {
    7095           0 :             for(j=0; j<=n-1; j++)
    7096             :             {
    7097           0 :                 b->ptr.p_complex[j] = ae_complex_from_d(0.0);
    7098             :             }
    7099           0 :             *info = -3;
    7100           0 :             ae_frame_leave(_state);
    7101           0 :             return;
    7102             :         }
    7103             :     }
    7104           0 :     directdensesolvers_cbasiclusolve(a, &p, n, b, _state);
    7105           0 :     *info = 1;
    7106           0 :     ae_frame_leave(_state);
    7107             : }
    7108             : 
    7109             : 
    7110             : /*************************************************************************
    7111             : Dense solver for A*X=B with N*N complex A given by its  LU  decomposition,
    7112             : and N*M matrices X and B (multiple right sides).   "Slow-but-feature-rich"
    7113             : version of the solver.
    7114             : 
    7115             : Algorithm features:
    7116             : * automatic detection of degenerate cases
    7117             : * O(M*N^2) complexity
    7118             : * condition number estimation
    7119             : 
    7120             : No iterative refinement  is provided because exact form of original matrix
    7121             : is not known to subroutine. Use CMatrixSolve or CMatrixMixedSolve  if  you
    7122             : need iterative refinement.
    7123             : 
    7124             : IMPORTANT: ! this function is NOT the most efficient linear solver provided
    7125             :            ! by ALGLIB. It estimates condition  number  of  linear system,
    7126             :            ! which  results  in  significant  performance   penalty   when
    7127             :            ! compared with "fast"  version  which  just  calls  triangular
    7128             :            ! solver.
    7129             :            !
    7130             :            ! This performance penalty is especially apparent when you  use
    7131             :            ! ALGLIB parallel capabilities (condition number estimation  is
    7132             :            ! inherently  sequential).  It   also   becomes significant for
    7133             :            ! small-scale problems.
    7134             :            !
    7135             :            ! In such cases we strongly recommend you to use faster solver,
    7136             :            ! CMatrixLUSolveMFast() function.
    7137             : 
    7138             :   ! COMMERCIAL EDITION OF ALGLIB:
    7139             :   ! 
    7140             :   ! Commercial Edition of ALGLIB includes following important improvements
    7141             :   ! of this function:
    7142             :   ! * high-performance native backend with same C# interface (C# version)
    7143             :   ! * multithreading support (C++ and C# versions)
    7144             :   ! * hardware vendor (Intel) implementations of linear algebra primitives
    7145             :   !   (C++ and C# versions, x86/x64 platform)
    7146             :   ! 
    7147             :   ! We recommend you to read 'Working with commercial version' section  of
    7148             :   ! ALGLIB Reference Manual in order to find out how to  use  performance-
    7149             :   ! related features provided by commercial edition of ALGLIB.
    7150             : 
    7151             : INPUT PARAMETERS
    7152             :     LUA     -   array[0..N-1,0..N-1], LU decomposition, RMatrixLU result
    7153             :     P       -   array[0..N-1], pivots array, RMatrixLU result
    7154             :     N       -   size of A
    7155             :     B       -   array[0..N-1,0..M-1], right part
    7156             :     M       -   right part size
    7157             : 
    7158             : OUTPUT PARAMETERS
    7159             :     Info    -   return code:
    7160             :                 * -3    matrix is very badly conditioned or exactly singular.
    7161             :                 * -1    N<=0 was passed
    7162             :                 *  1    task is solved (but matrix A may be ill-conditioned,
    7163             :                         check R1/RInf parameters for condition numbers).
    7164             :     Rep     -   additional report, following fields are set:
    7165             :                 * rep.r1    condition number in 1-norm
    7166             :                 * rep.rinf  condition number in inf-norm
    7167             :     X       -   array[N,M], it contains:
    7168             :                 * info>0    =>  solution
    7169             :                 * info=-3   =>  filled by zeros
    7170             : 
    7171             :   -- ALGLIB --
    7172             :      Copyright 27.01.2010 by Bochkanov Sergey
    7173             : *************************************************************************/
    7174           0 : void cmatrixlusolvem(/* Complex */ ae_matrix* lua,
    7175             :      /* Integer */ ae_vector* p,
    7176             :      ae_int_t n,
    7177             :      /* Complex */ ae_matrix* b,
    7178             :      ae_int_t m,
    7179             :      ae_int_t* info,
    7180             :      densesolverreport* rep,
    7181             :      /* Complex */ ae_matrix* x,
    7182             :      ae_state *_state)
    7183             : {
    7184             :     ae_frame _frame_block;
    7185             :     ae_matrix emptya;
    7186             : 
    7187           0 :     ae_frame_make(_state, &_frame_block);
    7188           0 :     memset(&emptya, 0, sizeof(emptya));
    7189           0 :     *info = 0;
    7190           0 :     _densesolverreport_clear(rep);
    7191           0 :     ae_matrix_clear(x);
    7192           0 :     ae_matrix_init(&emptya, 0, 0, DT_COMPLEX, _state, ae_true);
    7193             : 
    7194             :     
    7195             :     /*
    7196             :      * prepare: check inputs, allocate space...
    7197             :      */
    7198           0 :     if( n<=0||m<=0 )
    7199             :     {
    7200           0 :         *info = -1;
    7201           0 :         ae_frame_leave(_state);
    7202           0 :         return;
    7203             :     }
    7204             :     
    7205             :     /*
    7206             :      * solve
    7207             :      */
    7208           0 :     directdensesolvers_cmatrixlusolveinternal(lua, p, n, &emptya, ae_false, b, m, info, rep, x, _state);
    7209           0 :     ae_frame_leave(_state);
    7210             : }
    7211             : 
    7212             : 
    7213             : /*************************************************************************
    7214             : Dense solver for A*X=B with N*N complex A given by its  LU  decomposition,
    7215             : and N*M matrices X and B (multiple  right  sides).  "Fast-but-lightweight"
    7216             : version of the solver.
    7217             : 
    7218             : Algorithm features:
    7219             : * O(M*N^2) complexity
    7220             : * no additional time-consuming features
    7221             : 
    7222             :   ! COMMERCIAL EDITION OF ALGLIB:
    7223             :   ! 
    7224             :   ! Commercial Edition of ALGLIB includes following important improvements
    7225             :   ! of this function:
    7226             :   ! * high-performance native backend with same C# interface (C# version)
    7227             :   ! * multithreading support (C++ and C# versions)
    7228             :   ! * hardware vendor (Intel) implementations of linear algebra primitives
    7229             :   !   (C++ and C# versions, x86/x64 platform)
    7230             :   ! 
    7231             :   ! We recommend you to read 'Working with commercial version' section  of
    7232             :   ! ALGLIB Reference Manual in order to find out how to  use  performance-
    7233             :   ! related features provided by commercial edition of ALGLIB.
    7234             : 
    7235             : INPUT PARAMETERS
    7236             :     LUA     -   array[0..N-1,0..N-1], LU decomposition, RMatrixLU result
    7237             :     P       -   array[0..N-1], pivots array, RMatrixLU result
    7238             :     N       -   size of A
    7239             :     B       -   array[0..N-1,0..M-1], right part
    7240             :     M       -   right part size
    7241             : 
    7242             : OUTPUT PARAMETERS
    7243             :     Info    -   return code:
    7244             :                 * -3    matrix is exactly singular (ill conditioned matrices
    7245             :                         are not recognized).
    7246             :                 * -1    N<=0 was passed
    7247             :                 *  1    task is solved 
    7248             :     B       -   array[N,M]:
    7249             :                 * info>0    =>  overwritten by solution
    7250             :                 * info=-3   =>  filled by zeros
    7251             : 
    7252             : 
    7253             :   -- ALGLIB --
    7254             :      Copyright 27.01.2010 by Bochkanov Sergey
    7255             : *************************************************************************/
    7256           0 : void cmatrixlusolvemfast(/* Complex */ ae_matrix* lua,
    7257             :      /* Integer */ ae_vector* p,
    7258             :      ae_int_t n,
    7259             :      /* Complex */ ae_matrix* b,
    7260             :      ae_int_t m,
    7261             :      ae_int_t* info,
    7262             :      ae_state *_state)
    7263             : {
    7264             :     ae_complex v;
    7265             :     ae_int_t i;
    7266             :     ae_int_t j;
    7267             :     ae_int_t k;
    7268             : 
    7269           0 :     *info = 0;
    7270             : 
    7271             :     
    7272             :     /*
    7273             :      * Check for exact degeneracy
    7274             :      */
    7275           0 :     if( n<=0||m<=0 )
    7276             :     {
    7277           0 :         *info = -1;
    7278           0 :         return;
    7279             :     }
    7280           0 :     for(i=0; i<=n-1; i++)
    7281             :     {
    7282           0 :         if( ae_c_eq_d(lua->ptr.pp_complex[i][i],(double)(0)) )
    7283             :         {
    7284           0 :             for(j=0; j<=n-1; j++)
    7285             :             {
    7286           0 :                 for(k=0; k<=m-1; k++)
    7287             :                 {
    7288           0 :                     b->ptr.pp_complex[j][k] = ae_complex_from_d(0.0);
    7289             :                 }
    7290             :             }
    7291           0 :             *info = -3;
    7292           0 :             return;
    7293             :         }
    7294             :     }
    7295             :     
    7296             :     /*
    7297             :      * Solve with TRSM()
    7298             :      */
    7299           0 :     for(i=0; i<=n-1; i++)
    7300             :     {
    7301           0 :         if( p->ptr.p_int[i]!=i )
    7302             :         {
    7303           0 :             for(j=0; j<=m-1; j++)
    7304             :             {
    7305           0 :                 v = b->ptr.pp_complex[i][j];
    7306           0 :                 b->ptr.pp_complex[i][j] = b->ptr.pp_complex[p->ptr.p_int[i]][j];
    7307           0 :                 b->ptr.pp_complex[p->ptr.p_int[i]][j] = v;
    7308             :             }
    7309             :         }
    7310             :     }
    7311           0 :     cmatrixlefttrsm(n, m, lua, 0, 0, ae_false, ae_true, 0, b, 0, 0, _state);
    7312           0 :     cmatrixlefttrsm(n, m, lua, 0, 0, ae_true, ae_false, 0, b, 0, 0, _state);
    7313           0 :     *info = 1;
    7314             : }
    7315             : 
    7316             : 
    7317             : /*************************************************************************
    7318             : Complex dense linear solver for A*x=b with complex N*N A  given  by its LU
    7319             : decomposition and N*1 vectors x and b. This is  "slow-but-robust"  version
    7320             : of  the  complex  linear  solver  with  additional  features   which   add
    7321             : significant performance overhead. Faster version  is  CMatrixLUSolveFast()
    7322             : function.
    7323             : 
    7324             : Algorithm features:
    7325             : * automatic detection of degenerate cases
    7326             : * O(N^2) complexity
    7327             : * condition number estimation
    7328             : 
    7329             : No iterative refinement is provided because exact form of original matrix
    7330             : is not known to subroutine. Use CMatrixSolve or CMatrixMixedSolve  if  you
    7331             : need iterative refinement.
    7332             : 
    7333             : IMPORTANT: ! this function is NOT the most efficient linear solver provided
    7334             :            ! by ALGLIB. It estimates condition  number  of  linear system,
    7335             :            ! which results in 10-15x  performance  penalty  when  compared
    7336             :            ! with "fast" version which just calls triangular solver.
    7337             :            !
    7338             :            ! This performance penalty is insignificant  when compared with
    7339             :            ! cost of large LU decomposition.  However,  if you  call  this
    7340             :            ! function many times for the same  left  side,  this  overhead
    7341             :            ! BECOMES significant. It  also  becomes significant for small-
    7342             :            ! scale problems.
    7343             :            !
    7344             :            ! In such cases we strongly recommend you to use faster solver,
    7345             :            ! CMatrixLUSolveFast() function.
    7346             : 
    7347             : INPUT PARAMETERS
    7348             :     LUA     -   array[0..N-1,0..N-1], LU decomposition, CMatrixLU result
    7349             :     P       -   array[0..N-1], pivots array, CMatrixLU result
    7350             :     N       -   size of A
    7351             :     B       -   array[0..N-1], right part
    7352             : 
    7353             : OUTPUT PARAMETERS
    7354             :     Info    -   return code:
    7355             :                 * -3    matrix is very badly conditioned or exactly singular.
    7356             :                 * -1    N<=0 was passed
    7357             :                 *  1    task is solved (but matrix A may be ill-conditioned,
    7358             :                         check R1/RInf parameters for condition numbers).
    7359             :     Rep     -   additional report, following fields are set:
    7360             :                 * rep.r1    condition number in 1-norm
    7361             :                 * rep.rinf  condition number in inf-norm
    7362             :     X       -   array[N], it contains:
    7363             :                 * info>0    =>  solution
    7364             :                 * info=-3   =>  filled by zeros
    7365             : 
    7366             :   -- ALGLIB --
    7367             :      Copyright 27.01.2010 by Bochkanov Sergey
    7368             : *************************************************************************/
    7369           0 : void cmatrixlusolve(/* Complex */ ae_matrix* lua,
    7370             :      /* Integer */ ae_vector* p,
    7371             :      ae_int_t n,
    7372             :      /* Complex */ ae_vector* b,
    7373             :      ae_int_t* info,
    7374             :      densesolverreport* rep,
    7375             :      /* Complex */ ae_vector* x,
    7376             :      ae_state *_state)
    7377             : {
    7378             :     ae_frame _frame_block;
    7379             :     ae_matrix bm;
    7380             :     ae_matrix xm;
    7381             : 
    7382           0 :     ae_frame_make(_state, &_frame_block);
    7383           0 :     memset(&bm, 0, sizeof(bm));
    7384           0 :     memset(&xm, 0, sizeof(xm));
    7385           0 :     *info = 0;
    7386           0 :     _densesolverreport_clear(rep);
    7387           0 :     ae_vector_clear(x);
    7388           0 :     ae_matrix_init(&bm, 0, 0, DT_COMPLEX, _state, ae_true);
    7389           0 :     ae_matrix_init(&xm, 0, 0, DT_COMPLEX, _state, ae_true);
    7390             : 
    7391           0 :     if( n<=0 )
    7392             :     {
    7393           0 :         *info = -1;
    7394           0 :         ae_frame_leave(_state);
    7395           0 :         return;
    7396             :     }
    7397           0 :     ae_matrix_set_length(&bm, n, 1, _state);
    7398           0 :     ae_v_cmove(&bm.ptr.pp_complex[0][0], bm.stride, &b->ptr.p_complex[0], 1, "N", ae_v_len(0,n-1));
    7399           0 :     cmatrixlusolvem(lua, p, n, &bm, 1, info, rep, &xm, _state);
    7400           0 :     ae_vector_set_length(x, n, _state);
    7401           0 :     ae_v_cmove(&x->ptr.p_complex[0], 1, &xm.ptr.pp_complex[0][0], xm.stride, "N", ae_v_len(0,n-1));
    7402           0 :     ae_frame_leave(_state);
    7403             : }
    7404             : 
    7405             : 
    7406             : /*************************************************************************
    7407             : Complex dense linear solver for A*x=b with N*N complex A given by  its  LU
    7408             : decomposition and N*1 vectors x and b. This is  fast  lightweight  version
    7409             : of solver, which is significantly faster than CMatrixLUSolve(),  but  does
    7410             : not provide additional information (like condition numbers).
    7411             : 
    7412             : Algorithm features:
    7413             : * O(N^2) complexity
    7414             : * no additional time-consuming features, just triangular solver
    7415             : 
    7416             : INPUT PARAMETERS
    7417             :     LUA     -   array[0..N-1,0..N-1], LU decomposition, CMatrixLU result
    7418             :     P       -   array[0..N-1], pivots array, CMatrixLU result
    7419             :     N       -   size of A
    7420             :     B       -   array[0..N-1], right part
    7421             : 
    7422             : OUTPUT PARAMETERS
    7423             :     Info    -   return code:
    7424             :                 * -3    matrix is exactly singular (ill conditioned matrices
    7425             :                         are not recognized).
    7426             :                 * -1    N<=0 was passed
    7427             :                 *  1    task is solved 
    7428             :     B       -   array[N]:
    7429             :                 * info>0    =>  overwritten by solution
    7430             :                 * info=-3   =>  filled by zeros
    7431             :     
    7432             : NOTE: unlike  CMatrixLUSolve(),  this   function   does   NOT   check  for
    7433             :       near-degeneracy of input matrix. It  checks  for  EXACT  degeneracy,
    7434             :       because this check is easy to do. However,  very  badly  conditioned
    7435             :       matrices may went unnoticed.
    7436             : 
    7437             : 
    7438             :   -- ALGLIB --
    7439             :      Copyright 27.01.2010 by Bochkanov Sergey
    7440             : *************************************************************************/
    7441           0 : void cmatrixlusolvefast(/* Complex */ ae_matrix* lua,
    7442             :      /* Integer */ ae_vector* p,
    7443             :      ae_int_t n,
    7444             :      /* Complex */ ae_vector* b,
    7445             :      ae_int_t* info,
    7446             :      ae_state *_state)
    7447             : {
    7448             :     ae_int_t i;
    7449             :     ae_int_t j;
    7450             : 
    7451           0 :     *info = 0;
    7452             : 
    7453           0 :     if( n<=0 )
    7454             :     {
    7455           0 :         *info = -1;
    7456           0 :         return;
    7457             :     }
    7458           0 :     for(i=0; i<=n-1; i++)
    7459             :     {
    7460           0 :         if( ae_c_eq_d(lua->ptr.pp_complex[i][i],(double)(0)) )
    7461             :         {
    7462           0 :             for(j=0; j<=n-1; j++)
    7463             :             {
    7464           0 :                 b->ptr.p_complex[j] = ae_complex_from_d(0.0);
    7465             :             }
    7466           0 :             *info = -3;
    7467           0 :             return;
    7468             :         }
    7469             :     }
    7470           0 :     directdensesolvers_cbasiclusolve(lua, p, n, b, _state);
    7471           0 :     *info = 1;
    7472             : }
    7473             : 
    7474             : 
    7475             : /*************************************************************************
    7476             : Dense solver. Same as RMatrixMixedSolveM(), but for complex matrices.
    7477             : 
    7478             : Algorithm features:
    7479             : * automatic detection of degenerate cases
    7480             : * condition number estimation
    7481             : * iterative refinement
    7482             : * O(M*N^2) complexity
    7483             : 
    7484             : INPUT PARAMETERS
    7485             :     A       -   array[0..N-1,0..N-1], system matrix
    7486             :     LUA     -   array[0..N-1,0..N-1], LU decomposition, CMatrixLU result
    7487             :     P       -   array[0..N-1], pivots array, CMatrixLU result
    7488             :     N       -   size of A
    7489             :     B       -   array[0..N-1,0..M-1], right part
    7490             :     M       -   right part size
    7491             : 
    7492             : OUTPUT PARAMETERS
    7493             :     Info    -   return code:
    7494             :                 * -3    matrix is very badly conditioned or exactly singular.
    7495             :                 * -1    N<=0 was passed
    7496             :                 *  1    task is solved (but matrix A may be ill-conditioned,
    7497             :                         check R1/RInf parameters for condition numbers).
    7498             :     Rep     -   additional report, following fields are set:
    7499             :                 * rep.r1    condition number in 1-norm
    7500             :                 * rep.rinf  condition number in inf-norm
    7501             :     X       -   array[N,M], it contains:
    7502             :                 * info>0    =>  solution
    7503             :                 * info=-3   =>  filled by zeros
    7504             : 
    7505             :   -- ALGLIB --
    7506             :      Copyright 27.01.2010 by Bochkanov Sergey
    7507             : *************************************************************************/
    7508           0 : void cmatrixmixedsolvem(/* Complex */ ae_matrix* a,
    7509             :      /* Complex */ ae_matrix* lua,
    7510             :      /* Integer */ ae_vector* p,
    7511             :      ae_int_t n,
    7512             :      /* Complex */ ae_matrix* b,
    7513             :      ae_int_t m,
    7514             :      ae_int_t* info,
    7515             :      densesolverreport* rep,
    7516             :      /* Complex */ ae_matrix* x,
    7517             :      ae_state *_state)
    7518             : {
    7519             : 
    7520           0 :     *info = 0;
    7521           0 :     _densesolverreport_clear(rep);
    7522           0 :     ae_matrix_clear(x);
    7523             : 
    7524             :     
    7525             :     /*
    7526             :      * prepare: check inputs, allocate space...
    7527             :      */
    7528           0 :     if( n<=0||m<=0 )
    7529             :     {
    7530           0 :         *info = -1;
    7531           0 :         return;
    7532             :     }
    7533             :     
    7534             :     /*
    7535             :      * solve
    7536             :      */
    7537           0 :     directdensesolvers_cmatrixlusolveinternal(lua, p, n, a, ae_true, b, m, info, rep, x, _state);
    7538             : }
    7539             : 
    7540             : 
    7541             : /*************************************************************************
    7542             : Dense solver. Same as RMatrixMixedSolve(), but for complex matrices.
    7543             : 
    7544             : Algorithm features:
    7545             : * automatic detection of degenerate cases
    7546             : * condition number estimation
    7547             : * iterative refinement
    7548             : * O(N^2) complexity
    7549             : 
    7550             : INPUT PARAMETERS
    7551             :     A       -   array[0..N-1,0..N-1], system matrix
    7552             :     LUA     -   array[0..N-1,0..N-1], LU decomposition, CMatrixLU result
    7553             :     P       -   array[0..N-1], pivots array, CMatrixLU result
    7554             :     N       -   size of A
    7555             :     B       -   array[0..N-1], right part
    7556             : 
    7557             : OUTPUT PARAMETERS
    7558             :     Info    -   return code:
    7559             :                 * -3    matrix is very badly conditioned or exactly singular.
    7560             :                 * -1    N<=0 was passed
    7561             :                 *  1    task is solved (but matrix A may be ill-conditioned,
    7562             :                         check R1/RInf parameters for condition numbers).
    7563             :     Rep     -   additional report, following fields are set:
    7564             :                 * rep.r1    condition number in 1-norm
    7565             :                 * rep.rinf  condition number in inf-norm
    7566             :     X       -   array[N], it contains:
    7567             :                 * info>0    =>  solution
    7568             :                 * info=-3   =>  filled by zeros
    7569             : 
    7570             :   -- ALGLIB --
    7571             :      Copyright 27.01.2010 by Bochkanov Sergey
    7572             : *************************************************************************/
    7573           0 : void cmatrixmixedsolve(/* Complex */ ae_matrix* a,
    7574             :      /* Complex */ ae_matrix* lua,
    7575             :      /* Integer */ ae_vector* p,
    7576             :      ae_int_t n,
    7577             :      /* Complex */ ae_vector* b,
    7578             :      ae_int_t* info,
    7579             :      densesolverreport* rep,
    7580             :      /* Complex */ ae_vector* x,
    7581             :      ae_state *_state)
    7582             : {
    7583             :     ae_frame _frame_block;
    7584             :     ae_matrix bm;
    7585             :     ae_matrix xm;
    7586             : 
    7587           0 :     ae_frame_make(_state, &_frame_block);
    7588           0 :     memset(&bm, 0, sizeof(bm));
    7589           0 :     memset(&xm, 0, sizeof(xm));
    7590           0 :     *info = 0;
    7591           0 :     _densesolverreport_clear(rep);
    7592           0 :     ae_vector_clear(x);
    7593           0 :     ae_matrix_init(&bm, 0, 0, DT_COMPLEX, _state, ae_true);
    7594           0 :     ae_matrix_init(&xm, 0, 0, DT_COMPLEX, _state, ae_true);
    7595             : 
    7596           0 :     if( n<=0 )
    7597             :     {
    7598           0 :         *info = -1;
    7599           0 :         ae_frame_leave(_state);
    7600           0 :         return;
    7601             :     }
    7602           0 :     ae_matrix_set_length(&bm, n, 1, _state);
    7603           0 :     ae_v_cmove(&bm.ptr.pp_complex[0][0], bm.stride, &b->ptr.p_complex[0], 1, "N", ae_v_len(0,n-1));
    7604           0 :     cmatrixmixedsolvem(a, lua, p, n, &bm, 1, info, rep, &xm, _state);
    7605           0 :     ae_vector_set_length(x, n, _state);
    7606           0 :     ae_v_cmove(&x->ptr.p_complex[0], 1, &xm.ptr.pp_complex[0][0], xm.stride, "N", ae_v_len(0,n-1));
    7607           0 :     ae_frame_leave(_state);
    7608             : }
    7609             : 
    7610             : 
    7611             : /*************************************************************************
    7612             : Dense solver for A*X=B with N*N symmetric positive definite matrix A,  and
    7613             : N*M vectors X and B. It is "slow-but-feature-rich" version of the solver.
    7614             : 
    7615             : Algorithm features:
    7616             : * automatic detection of degenerate cases
    7617             : * condition number estimation
    7618             : * O(N^3+M*N^2) complexity
    7619             : * matrix is represented by its upper or lower triangle
    7620             : 
    7621             : No iterative refinement is provided because such partial representation of
    7622             : matrix does not allow efficient calculation of extra-precise  matrix-vector
    7623             : products for large matrices. Use RMatrixSolve or RMatrixMixedSolve  if  you
    7624             : need iterative refinement.
    7625             : 
    7626             : IMPORTANT: ! this function is NOT the most efficient linear solver provided
    7627             :            ! by ALGLIB. It estimates condition  number  of  linear system,
    7628             :            ! which  results  in  significant   performance   penalty  when
    7629             :            ! compared with "fast" version  which  just  performs  Cholesky
    7630             :            ! decomposition and calls triangular solver.
    7631             :            !
    7632             :            ! This  performance  penalty  is  especially  visible  in   the
    7633             :            ! multithreaded mode, because both condition number  estimation
    7634             :            ! and   iterative    refinement   are   inherently   sequential
    7635             :            ! calculations.
    7636             :            !
    7637             :            ! Thus, if you need high performance and if you are pretty sure
    7638             :            ! that your system is well conditioned, we  strongly  recommend
    7639             :            ! you to use faster solver, SPDMatrixSolveMFast() function.
    7640             : 
    7641             :   ! COMMERCIAL EDITION OF ALGLIB:
    7642             :   ! 
    7643             :   ! Commercial Edition of ALGLIB includes following important improvements
    7644             :   ! of this function:
    7645             :   ! * high-performance native backend with same C# interface (C# version)
    7646             :   ! * multithreading support (C++ and C# versions)
    7647             :   ! * hardware vendor (Intel) implementations of linear algebra primitives
    7648             :   !   (C++ and C# versions, x86/x64 platform)
    7649             :   ! 
    7650             :   ! We recommend you to read 'Working with commercial version' section  of
    7651             :   ! ALGLIB Reference Manual in order to find out how to  use  performance-
    7652             :   ! related features provided by commercial edition of ALGLIB.
    7653             : 
    7654             : INPUT PARAMETERS
    7655             :     A       -   array[0..N-1,0..N-1], system matrix
    7656             :     N       -   size of A
    7657             :     IsUpper -   what half of A is provided
    7658             :     B       -   array[0..N-1,0..M-1], right part
    7659             :     M       -   right part size
    7660             : 
    7661             : OUTPUT PARAMETERS
    7662             :     Info    -   return code:
    7663             :                 * -3    matrix is very badly conditioned or non-SPD.
    7664             :                 * -1    N<=0 was passed
    7665             :                 *  1    task is solved (but matrix A may be ill-conditioned,
    7666             :                         check R1/RInf parameters for condition numbers).
    7667             :     Rep     -   additional report, following fields are set:
    7668             :                 * rep.r1    condition number in 1-norm
    7669             :                 * rep.rinf  condition number in inf-norm
    7670             :     X       -   array[N,M], it contains:
    7671             :                 * info>0    =>  solution
    7672             :                 * info=-3   =>  filled by zeros
    7673             : 
    7674             :   -- ALGLIB --
    7675             :      Copyright 27.01.2010 by Bochkanov Sergey
    7676             : *************************************************************************/
    7677           0 : void spdmatrixsolvem(/* Real    */ ae_matrix* a,
    7678             :      ae_int_t n,
    7679             :      ae_bool isupper,
    7680             :      /* Real    */ ae_matrix* b,
    7681             :      ae_int_t m,
    7682             :      ae_int_t* info,
    7683             :      densesolverreport* rep,
    7684             :      /* Real    */ ae_matrix* x,
    7685             :      ae_state *_state)
    7686             : {
    7687             :     ae_frame _frame_block;
    7688             :     ae_matrix da;
    7689             :     ae_int_t i;
    7690             :     ae_int_t j;
    7691             :     ae_int_t j1;
    7692             :     ae_int_t j2;
    7693             : 
    7694           0 :     ae_frame_make(_state, &_frame_block);
    7695           0 :     memset(&da, 0, sizeof(da));
    7696           0 :     *info = 0;
    7697           0 :     _densesolverreport_clear(rep);
    7698           0 :     ae_matrix_clear(x);
    7699           0 :     ae_matrix_init(&da, 0, 0, DT_REAL, _state, ae_true);
    7700             : 
    7701             :     
    7702             :     /*
    7703             :      * prepare: check inputs, allocate space...
    7704             :      */
    7705           0 :     if( n<=0||m<=0 )
    7706             :     {
    7707           0 :         *info = -1;
    7708           0 :         ae_frame_leave(_state);
    7709           0 :         return;
    7710             :     }
    7711           0 :     ae_matrix_set_length(&da, n, n, _state);
    7712             :     
    7713             :     /*
    7714             :      * factorize
    7715             :      * solve
    7716             :      */
    7717           0 :     for(i=0; i<=n-1; i++)
    7718             :     {
    7719           0 :         if( isupper )
    7720             :         {
    7721           0 :             j1 = i;
    7722           0 :             j2 = n-1;
    7723             :         }
    7724             :         else
    7725             :         {
    7726           0 :             j1 = 0;
    7727           0 :             j2 = i;
    7728             :         }
    7729           0 :         ae_v_move(&da.ptr.pp_double[i][j1], 1, &a->ptr.pp_double[i][j1], 1, ae_v_len(j1,j2));
    7730             :     }
    7731           0 :     if( !spdmatrixcholesky(&da, n, isupper, _state) )
    7732             :     {
    7733           0 :         ae_matrix_set_length(x, n, m, _state);
    7734           0 :         for(i=0; i<=n-1; i++)
    7735             :         {
    7736           0 :             for(j=0; j<=m-1; j++)
    7737             :             {
    7738           0 :                 x->ptr.pp_double[i][j] = (double)(0);
    7739             :             }
    7740             :         }
    7741           0 :         rep->r1 = (double)(0);
    7742           0 :         rep->rinf = (double)(0);
    7743           0 :         *info = -3;
    7744           0 :         ae_frame_leave(_state);
    7745           0 :         return;
    7746             :     }
    7747           0 :     *info = 1;
    7748           0 :     directdensesolvers_spdmatrixcholeskysolveinternal(&da, n, isupper, a, ae_true, b, m, info, rep, x, _state);
    7749           0 :     ae_frame_leave(_state);
    7750             : }
    7751             : 
    7752             : 
    7753             : /*************************************************************************
    7754             : Dense solver for A*X=B with N*N symmetric positive definite matrix A,  and
    7755             : N*M vectors X and B. It is "fast-but-lightweight" version of the solver.
    7756             : 
    7757             : Algorithm features:
    7758             : * O(N^3+M*N^2) complexity
    7759             : * matrix is represented by its upper or lower triangle
    7760             : * no additional time consuming features
    7761             : 
    7762             :   ! COMMERCIAL EDITION OF ALGLIB:
    7763             :   ! 
    7764             :   ! Commercial Edition of ALGLIB includes following important improvements
    7765             :   ! of this function:
    7766             :   ! * high-performance native backend with same C# interface (C# version)
    7767             :   ! * multithreading support (C++ and C# versions)
    7768             :   ! * hardware vendor (Intel) implementations of linear algebra primitives
    7769             :   !   (C++ and C# versions, x86/x64 platform)
    7770             :   ! 
    7771             :   ! We recommend you to read 'Working with commercial version' section  of
    7772             :   ! ALGLIB Reference Manual in order to find out how to  use  performance-
    7773             :   ! related features provided by commercial edition of ALGLIB.
    7774             : 
    7775             : INPUT PARAMETERS
    7776             :     A       -   array[0..N-1,0..N-1], system matrix
    7777             :     N       -   size of A
    7778             :     IsUpper -   what half of A is provided
    7779             :     B       -   array[0..N-1,0..M-1], right part
    7780             :     M       -   right part size
    7781             : 
    7782             : OUTPUT PARAMETERS
    7783             :     Info    -   return code:
    7784             :                 * -3    A is is exactly singular
    7785             :                 * -1    N<=0 was passed
    7786             :                 *  1    task was solved
    7787             :     B       -   array[N,M], it contains:
    7788             :                 * info>0    =>  solution
    7789             :                 * info=-3   =>  filled by zeros
    7790             : 
    7791             :   -- ALGLIB --
    7792             :      Copyright 17.03.2015 by Bochkanov Sergey
    7793             : *************************************************************************/
    7794           0 : void spdmatrixsolvemfast(/* Real    */ ae_matrix* a,
    7795             :      ae_int_t n,
    7796             :      ae_bool isupper,
    7797             :      /* Real    */ ae_matrix* b,
    7798             :      ae_int_t m,
    7799             :      ae_int_t* info,
    7800             :      ae_state *_state)
    7801             : {
    7802             :     ae_frame _frame_block;
    7803             :     ae_matrix _a;
    7804             :     ae_int_t i;
    7805             :     ae_int_t j;
    7806             : 
    7807           0 :     ae_frame_make(_state, &_frame_block);
    7808           0 :     memset(&_a, 0, sizeof(_a));
    7809           0 :     ae_matrix_init_copy(&_a, a, _state, ae_true);
    7810           0 :     a = &_a;
    7811           0 :     *info = 0;
    7812             : 
    7813           0 :     *info = 1;
    7814           0 :     if( n<=0 )
    7815             :     {
    7816           0 :         *info = -1;
    7817           0 :         ae_frame_leave(_state);
    7818           0 :         return;
    7819             :     }
    7820           0 :     if( !spdmatrixcholesky(a, n, isupper, _state) )
    7821             :     {
    7822           0 :         for(i=0; i<=n-1; i++)
    7823             :         {
    7824           0 :             for(j=0; j<=m-1; j++)
    7825             :             {
    7826           0 :                 b->ptr.pp_double[i][j] = 0.0;
    7827             :             }
    7828             :         }
    7829           0 :         *info = -3;
    7830           0 :         ae_frame_leave(_state);
    7831           0 :         return;
    7832             :     }
    7833           0 :     if( isupper )
    7834             :     {
    7835           0 :         rmatrixlefttrsm(n, m, a, 0, 0, ae_true, ae_false, 1, b, 0, 0, _state);
    7836           0 :         rmatrixlefttrsm(n, m, a, 0, 0, ae_true, ae_false, 0, b, 0, 0, _state);
    7837             :     }
    7838             :     else
    7839             :     {
    7840           0 :         rmatrixlefttrsm(n, m, a, 0, 0, ae_false, ae_false, 0, b, 0, 0, _state);
    7841           0 :         rmatrixlefttrsm(n, m, a, 0, 0, ae_false, ae_false, 1, b, 0, 0, _state);
    7842             :     }
    7843           0 :     ae_frame_leave(_state);
    7844             : }
    7845             : 
    7846             : 
    7847             : /*************************************************************************
    7848             : Dense linear solver for A*x=b with N*N real  symmetric  positive  definite
    7849             : matrix A,  N*1 vectors x and b.  "Slow-but-feature-rich"  version  of  the
    7850             : solver.
    7851             : 
    7852             : Algorithm features:
    7853             : * automatic detection of degenerate cases
    7854             : * condition number estimation
    7855             : * O(N^3) complexity
    7856             : * matrix is represented by its upper or lower triangle
    7857             : 
    7858             : No iterative refinement is provided because such partial representation of
    7859             : matrix does not allow efficient calculation of extra-precise  matrix-vector
    7860             : products for large matrices. Use RMatrixSolve or RMatrixMixedSolve  if  you
    7861             : need iterative refinement.
    7862             : 
    7863             : IMPORTANT: ! this function is NOT the most efficient linear solver provided
    7864             :            ! by ALGLIB. It estimates condition  number  of  linear system,
    7865             :            ! which  results  in  significant   performance   penalty  when
    7866             :            ! compared with "fast" version  which  just  performs  Cholesky
    7867             :            ! decomposition and calls triangular solver.
    7868             :            !
    7869             :            ! This  performance  penalty  is  especially  visible  in   the
    7870             :            ! multithreaded mode, because both condition number  estimation
    7871             :            ! and   iterative    refinement   are   inherently   sequential
    7872             :            ! calculations.
    7873             :            !
    7874             :            ! Thus, if you need high performance and if you are pretty sure
    7875             :            ! that your system is well conditioned, we  strongly  recommend
    7876             :            ! you to use faster solver, SPDMatrixSolveFast() function.
    7877             : 
    7878             :   ! COMMERCIAL EDITION OF ALGLIB:
    7879             :   ! 
    7880             :   ! Commercial Edition of ALGLIB includes following important improvements
    7881             :   ! of this function:
    7882             :   ! * high-performance native backend with same C# interface (C# version)
    7883             :   ! * multithreading support (C++ and C# versions)
    7884             :   ! * hardware vendor (Intel) implementations of linear algebra primitives
    7885             :   !   (C++ and C# versions, x86/x64 platform)
    7886             :   ! 
    7887             :   ! We recommend you to read 'Working with commercial version' section  of
    7888             :   ! ALGLIB Reference Manual in order to find out how to  use  performance-
    7889             :   ! related features provided by commercial edition of ALGLIB.
    7890             : 
    7891             : INPUT PARAMETERS
    7892             :     A       -   array[0..N-1,0..N-1], system matrix
    7893             :     N       -   size of A
    7894             :     IsUpper -   what half of A is provided
    7895             :     B       -   array[0..N-1], right part
    7896             : 
    7897             : OUTPUT PARAMETERS
    7898             :     Info    -   return code:
    7899             :                 * -3    matrix is very badly conditioned or non-SPD.
    7900             :                 * -1    N<=0 was passed
    7901             :                 *  1    task is solved (but matrix A may be ill-conditioned,
    7902             :                         check R1/RInf parameters for condition numbers).
    7903             :     Rep     -   additional report, following fields are set:
    7904             :                 * rep.r1    condition number in 1-norm
    7905             :                 * rep.rinf  condition number in inf-norm
    7906             :     X       -   array[N], it contains:
    7907             :                 * info>0    =>  solution
    7908             :                 * info=-3   =>  filled by zeros
    7909             : 
    7910             :   -- ALGLIB --
    7911             :      Copyright 27.01.2010 by Bochkanov Sergey
    7912             : *************************************************************************/
    7913           0 : void spdmatrixsolve(/* Real    */ ae_matrix* a,
    7914             :      ae_int_t n,
    7915             :      ae_bool isupper,
    7916             :      /* Real    */ ae_vector* b,
    7917             :      ae_int_t* info,
    7918             :      densesolverreport* rep,
    7919             :      /* Real    */ ae_vector* x,
    7920             :      ae_state *_state)
    7921             : {
    7922             :     ae_frame _frame_block;
    7923             :     ae_matrix bm;
    7924             :     ae_matrix xm;
    7925             : 
    7926           0 :     ae_frame_make(_state, &_frame_block);
    7927           0 :     memset(&bm, 0, sizeof(bm));
    7928           0 :     memset(&xm, 0, sizeof(xm));
    7929           0 :     *info = 0;
    7930           0 :     _densesolverreport_clear(rep);
    7931           0 :     ae_vector_clear(x);
    7932           0 :     ae_matrix_init(&bm, 0, 0, DT_REAL, _state, ae_true);
    7933           0 :     ae_matrix_init(&xm, 0, 0, DT_REAL, _state, ae_true);
    7934             : 
    7935           0 :     if( n<=0 )
    7936             :     {
    7937           0 :         *info = -1;
    7938           0 :         ae_frame_leave(_state);
    7939           0 :         return;
    7940             :     }
    7941           0 :     ae_matrix_set_length(&bm, n, 1, _state);
    7942           0 :     ae_v_move(&bm.ptr.pp_double[0][0], bm.stride, &b->ptr.p_double[0], 1, ae_v_len(0,n-1));
    7943           0 :     spdmatrixsolvem(a, n, isupper, &bm, 1, info, rep, &xm, _state);
    7944           0 :     ae_vector_set_length(x, n, _state);
    7945           0 :     ae_v_move(&x->ptr.p_double[0], 1, &xm.ptr.pp_double[0][0], xm.stride, ae_v_len(0,n-1));
    7946           0 :     ae_frame_leave(_state);
    7947             : }
    7948             : 
    7949             : 
    7950             : /*************************************************************************
    7951             : Dense linear solver for A*x=b with N*N real  symmetric  positive  definite
    7952             : matrix A,  N*1 vectors x and  b.  "Fast-but-lightweight"  version  of  the
    7953             : solver.
    7954             : 
    7955             : Algorithm features:
    7956             : * O(N^3) complexity
    7957             : * matrix is represented by its upper or lower triangle
    7958             : * no additional time consuming features like condition number estimation
    7959             : 
    7960             :   ! COMMERCIAL EDITION OF ALGLIB:
    7961             :   ! 
    7962             :   ! Commercial Edition of ALGLIB includes following important improvements
    7963             :   ! of this function:
    7964             :   ! * high-performance native backend with same C# interface (C# version)
    7965             :   ! * multithreading support (C++ and C# versions)
    7966             :   ! * hardware vendor (Intel) implementations of linear algebra primitives
    7967             :   !   (C++ and C# versions, x86/x64 platform)
    7968             :   ! 
    7969             :   ! We recommend you to read 'Working with commercial version' section  of
    7970             :   ! ALGLIB Reference Manual in order to find out how to  use  performance-
    7971             :   ! related features provided by commercial edition of ALGLIB.
    7972             : 
    7973             : INPUT PARAMETERS
    7974             :     A       -   array[0..N-1,0..N-1], system matrix
    7975             :     N       -   size of A
    7976             :     IsUpper -   what half of A is provided
    7977             :     B       -   array[0..N-1], right part
    7978             : 
    7979             : OUTPUT PARAMETERS
    7980             :     Info    -   return code:
    7981             :                 * -3    A is is exactly singular or non-SPD
    7982             :                 * -1    N<=0 was passed
    7983             :                 *  1    task was solved
    7984             :     B       -   array[N], it contains:
    7985             :                 * info>0    =>  solution
    7986             :                 * info=-3   =>  filled by zeros
    7987             : 
    7988             :   -- ALGLIB --
    7989             :      Copyright 17.03.2015 by Bochkanov Sergey
    7990             : *************************************************************************/
    7991           0 : void spdmatrixsolvefast(/* Real    */ ae_matrix* a,
    7992             :      ae_int_t n,
    7993             :      ae_bool isupper,
    7994             :      /* Real    */ ae_vector* b,
    7995             :      ae_int_t* info,
    7996             :      ae_state *_state)
    7997             : {
    7998             :     ae_frame _frame_block;
    7999             :     ae_matrix _a;
    8000             :     ae_int_t i;
    8001             : 
    8002           0 :     ae_frame_make(_state, &_frame_block);
    8003           0 :     memset(&_a, 0, sizeof(_a));
    8004           0 :     ae_matrix_init_copy(&_a, a, _state, ae_true);
    8005           0 :     a = &_a;
    8006           0 :     *info = 0;
    8007             : 
    8008           0 :     *info = 1;
    8009           0 :     if( n<=0 )
    8010             :     {
    8011           0 :         *info = -1;
    8012           0 :         ae_frame_leave(_state);
    8013           0 :         return;
    8014             :     }
    8015           0 :     if( !spdmatrixcholesky(a, n, isupper, _state) )
    8016             :     {
    8017           0 :         for(i=0; i<=n-1; i++)
    8018             :         {
    8019           0 :             b->ptr.p_double[i] = 0.0;
    8020             :         }
    8021           0 :         *info = -3;
    8022           0 :         ae_frame_leave(_state);
    8023           0 :         return;
    8024             :     }
    8025           0 :     directdensesolvers_spdbasiccholeskysolve(a, n, isupper, b, _state);
    8026           0 :     ae_frame_leave(_state);
    8027             : }
    8028             : 
    8029             : 
    8030             : /*************************************************************************
    8031             : Dense solver for A*X=B with N*N symmetric positive definite matrix A given
    8032             : by its Cholesky decomposition, and N*M vectors X and B. It  is  "slow-but-
    8033             : feature-rich" version of the solver which estimates  condition  number  of
    8034             : the system.
    8035             : 
    8036             : Algorithm features:
    8037             : * automatic detection of degenerate cases
    8038             : * O(M*N^2) complexity
    8039             : * condition number estimation
    8040             : * matrix is represented by its upper or lower triangle
    8041             : 
    8042             : No iterative refinement is provided because such partial representation of
    8043             : matrix does not allow efficient calculation of extra-precise  matrix-vector
    8044             : products for large matrices. Use RMatrixSolve or RMatrixMixedSolve  if  you
    8045             : need iterative refinement.
    8046             : 
    8047             : IMPORTANT: ! this function is NOT the most efficient linear solver provided
    8048             :            ! by ALGLIB. It estimates condition  number  of  linear system,
    8049             :            ! which  results  in  significant  performance   penalty   when
    8050             :            ! compared with "fast"  version  which  just  calls  triangular
    8051             :            ! solver. Amount of  overhead  introduced  depends  on  M  (the
    8052             :            ! larger - the more efficient).
    8053             :            !
    8054             :            ! This performance penalty is insignificant  when compared with
    8055             :            ! cost of large LU decomposition.  However,  if you  call  this
    8056             :            ! function many times for the same  left  side,  this  overhead
    8057             :            ! BECOMES significant. It  also  becomes significant for small-
    8058             :            ! scale problems (N<50).
    8059             :            !
    8060             :            ! In such cases we strongly recommend you to use faster solver,
    8061             :            ! SPDMatrixCholeskySolveMFast() function.
    8062             : 
    8063             : INPUT PARAMETERS
    8064             :     CHA     -   array[0..N-1,0..N-1], Cholesky decomposition,
    8065             :                 SPDMatrixCholesky result
    8066             :     N       -   size of CHA
    8067             :     IsUpper -   what half of CHA is provided
    8068             :     B       -   array[0..N-1,0..M-1], right part
    8069             :     M       -   right part size
    8070             : 
    8071             : OUTPUT PARAMETERS
    8072             :     Info    -   return code:
    8073             :                 * -3    A is is exactly singular or badly conditioned
    8074             :                         X is filled by zeros in such cases.
    8075             :                 * -1    N<=0 was passed
    8076             :                 *  1    task was solved
    8077             :     Rep     -   additional report, following fields are set:
    8078             :                 * rep.r1    condition number in 1-norm
    8079             :                 * rep.rinf  condition number in inf-norm
    8080             :     X       -   array[N]:
    8081             :                 * for info>0 contains solution
    8082             :                 * for info=-3 filled by zeros
    8083             : 
    8084             :   -- ALGLIB --
    8085             :      Copyright 27.01.2010 by Bochkanov Sergey
    8086             : *************************************************************************/
    8087           0 : void spdmatrixcholeskysolvem(/* Real    */ ae_matrix* cha,
    8088             :      ae_int_t n,
    8089             :      ae_bool isupper,
    8090             :      /* Real    */ ae_matrix* b,
    8091             :      ae_int_t m,
    8092             :      ae_int_t* info,
    8093             :      densesolverreport* rep,
    8094             :      /* Real    */ ae_matrix* x,
    8095             :      ae_state *_state)
    8096             : {
    8097             :     ae_frame _frame_block;
    8098             :     ae_matrix emptya;
    8099             : 
    8100           0 :     ae_frame_make(_state, &_frame_block);
    8101           0 :     memset(&emptya, 0, sizeof(emptya));
    8102           0 :     *info = 0;
    8103           0 :     _densesolverreport_clear(rep);
    8104           0 :     ae_matrix_clear(x);
    8105           0 :     ae_matrix_init(&emptya, 0, 0, DT_REAL, _state, ae_true);
    8106             : 
    8107             :     
    8108             :     /*
    8109             :      * prepare: check inputs, allocate space...
    8110             :      */
    8111           0 :     if( n<=0||m<=0 )
    8112             :     {
    8113           0 :         *info = -1;
    8114           0 :         ae_frame_leave(_state);
    8115           0 :         return;
    8116             :     }
    8117             :     
    8118             :     /*
    8119             :      * solve
    8120             :      */
    8121           0 :     directdensesolvers_spdmatrixcholeskysolveinternal(cha, n, isupper, &emptya, ae_false, b, m, info, rep, x, _state);
    8122           0 :     ae_frame_leave(_state);
    8123             : }
    8124             : 
    8125             : 
    8126             : /*************************************************************************
    8127             : Dense solver for A*X=B with N*N symmetric positive definite matrix A given
    8128             : by its Cholesky decomposition, and N*M vectors X and B. It  is  "fast-but-
    8129             : lightweight" version of  the  solver  which  just  solves  linear  system,
    8130             : without any additional functions.
    8131             : 
    8132             : Algorithm features:
    8133             : * O(M*N^2) complexity
    8134             : * matrix is represented by its upper or lower triangle
    8135             : * no additional functionality
    8136             : 
    8137             : INPUT PARAMETERS
    8138             :     CHA     -   array[N,N], Cholesky decomposition,
    8139             :                 SPDMatrixCholesky result
    8140             :     N       -   size of CHA
    8141             :     IsUpper -   what half of CHA is provided
    8142             :     B       -   array[N,M], right part
    8143             :     M       -   right part size
    8144             : 
    8145             : OUTPUT PARAMETERS
    8146             :     Info    -   return code:
    8147             :                 * -3    A is is exactly singular or badly conditioned
    8148             :                         X is filled by zeros in such cases.
    8149             :                 * -1    N<=0 was passed
    8150             :                 *  1    task was solved
    8151             :     B       -   array[N]:
    8152             :                 * for info>0 overwritten by solution
    8153             :                 * for info=-3 filled by zeros
    8154             : 
    8155             :   -- ALGLIB --
    8156             :      Copyright 18.03.2015 by Bochkanov Sergey
    8157             : *************************************************************************/
    8158           0 : void spdmatrixcholeskysolvemfast(/* Real    */ ae_matrix* cha,
    8159             :      ae_int_t n,
    8160             :      ae_bool isupper,
    8161             :      /* Real    */ ae_matrix* b,
    8162             :      ae_int_t m,
    8163             :      ae_int_t* info,
    8164             :      ae_state *_state)
    8165             : {
    8166             :     ae_int_t i;
    8167             :     ae_int_t j;
    8168             :     ae_int_t k;
    8169             : 
    8170           0 :     *info = 0;
    8171             : 
    8172           0 :     *info = 1;
    8173           0 :     if( n<=0 )
    8174             :     {
    8175           0 :         *info = -1;
    8176           0 :         return;
    8177             :     }
    8178           0 :     for(k=0; k<=n-1; k++)
    8179             :     {
    8180           0 :         if( ae_fp_eq(cha->ptr.pp_double[k][k],0.0) )
    8181             :         {
    8182           0 :             for(i=0; i<=n-1; i++)
    8183             :             {
    8184           0 :                 for(j=0; j<=m-1; j++)
    8185             :                 {
    8186           0 :                     b->ptr.pp_double[i][j] = 0.0;
    8187             :                 }
    8188             :             }
    8189           0 :             *info = -3;
    8190           0 :             return;
    8191             :         }
    8192             :     }
    8193           0 :     if( isupper )
    8194             :     {
    8195           0 :         rmatrixlefttrsm(n, m, cha, 0, 0, ae_true, ae_false, 1, b, 0, 0, _state);
    8196           0 :         rmatrixlefttrsm(n, m, cha, 0, 0, ae_true, ae_false, 0, b, 0, 0, _state);
    8197             :     }
    8198             :     else
    8199             :     {
    8200           0 :         rmatrixlefttrsm(n, m, cha, 0, 0, ae_false, ae_false, 0, b, 0, 0, _state);
    8201           0 :         rmatrixlefttrsm(n, m, cha, 0, 0, ae_false, ae_false, 1, b, 0, 0, _state);
    8202             :     }
    8203             : }
    8204             : 
    8205             : 
    8206             : /*************************************************************************
    8207             : Dense solver for A*x=b with N*N symmetric positive definite matrix A given
    8208             : by its Cholesky decomposition, and N*1 real vectors x and b. This is "slow-
    8209             : but-feature-rich"  version  of  the  solver  which,  in  addition  to  the
    8210             : solution, performs condition number estimation.
    8211             : 
    8212             : Algorithm features:
    8213             : * automatic detection of degenerate cases
    8214             : * O(N^2) complexity
    8215             : * condition number estimation
    8216             : * matrix is represented by its upper or lower triangle
    8217             : 
    8218             : No iterative refinement is provided because such partial representation of
    8219             : matrix does not allow efficient calculation of extra-precise  matrix-vector
    8220             : products for large matrices. Use RMatrixSolve or RMatrixMixedSolve  if  you
    8221             : need iterative refinement.
    8222             : 
    8223             : IMPORTANT: ! this function is NOT the most efficient linear solver provided
    8224             :            ! by ALGLIB. It estimates condition  number  of  linear system,
    8225             :            ! which results in 10-15x  performance  penalty  when  compared
    8226             :            ! with "fast" version which just calls triangular solver.
    8227             :            !
    8228             :            ! This performance penalty is insignificant  when compared with
    8229             :            ! cost of large LU decomposition.  However,  if you  call  this
    8230             :            ! function many times for the same  left  side,  this  overhead
    8231             :            ! BECOMES significant. It  also  becomes significant for small-
    8232             :            ! scale problems (N<50).
    8233             :            !
    8234             :            ! In such cases we strongly recommend you to use faster solver,
    8235             :            ! SPDMatrixCholeskySolveFast() function.
    8236             : 
    8237             : INPUT PARAMETERS
    8238             :     CHA     -   array[N,N], Cholesky decomposition,
    8239             :                 SPDMatrixCholesky result
    8240             :     N       -   size of A
    8241             :     IsUpper -   what half of CHA is provided
    8242             :     B       -   array[N], right part
    8243             : 
    8244             : OUTPUT PARAMETERS
    8245             :     Info    -   return code:
    8246             :                 * -3    A is is exactly singular or ill conditioned
    8247             :                         X is filled by zeros in such cases.
    8248             :                 * -1    N<=0 was passed
    8249             :                 *  1    task is solved
    8250             :     Rep     -   additional report, following fields are set:
    8251             :                 * rep.r1    condition number in 1-norm
    8252             :                 * rep.rinf  condition number in inf-norm
    8253             :     X       -   array[N]:
    8254             :                 * for info>0  - solution
    8255             :                 * for info=-3 - filled by zeros
    8256             : 
    8257             :   -- ALGLIB --
    8258             :      Copyright 27.01.2010 by Bochkanov Sergey
    8259             : *************************************************************************/
    8260           0 : void spdmatrixcholeskysolve(/* Real    */ ae_matrix* cha,
    8261             :      ae_int_t n,
    8262             :      ae_bool isupper,
    8263             :      /* Real    */ ae_vector* b,
    8264             :      ae_int_t* info,
    8265             :      densesolverreport* rep,
    8266             :      /* Real    */ ae_vector* x,
    8267             :      ae_state *_state)
    8268             : {
    8269             :     ae_frame _frame_block;
    8270             :     ae_matrix bm;
    8271             :     ae_matrix xm;
    8272             : 
    8273           0 :     ae_frame_make(_state, &_frame_block);
    8274           0 :     memset(&bm, 0, sizeof(bm));
    8275           0 :     memset(&xm, 0, sizeof(xm));
    8276           0 :     *info = 0;
    8277           0 :     _densesolverreport_clear(rep);
    8278           0 :     ae_vector_clear(x);
    8279           0 :     ae_matrix_init(&bm, 0, 0, DT_REAL, _state, ae_true);
    8280           0 :     ae_matrix_init(&xm, 0, 0, DT_REAL, _state, ae_true);
    8281             : 
    8282           0 :     if( n<=0 )
    8283             :     {
    8284           0 :         *info = -1;
    8285           0 :         ae_frame_leave(_state);
    8286           0 :         return;
    8287             :     }
    8288           0 :     ae_matrix_set_length(&bm, n, 1, _state);
    8289           0 :     ae_v_move(&bm.ptr.pp_double[0][0], bm.stride, &b->ptr.p_double[0], 1, ae_v_len(0,n-1));
    8290           0 :     spdmatrixcholeskysolvem(cha, n, isupper, &bm, 1, info, rep, &xm, _state);
    8291           0 :     ae_vector_set_length(x, n, _state);
    8292           0 :     ae_v_move(&x->ptr.p_double[0], 1, &xm.ptr.pp_double[0][0], xm.stride, ae_v_len(0,n-1));
    8293           0 :     ae_frame_leave(_state);
    8294             : }
    8295             : 
    8296             : 
    8297             : /*************************************************************************
    8298             : Dense solver for A*x=b with N*N symmetric positive definite matrix A given
    8299             : by its Cholesky decomposition, and N*1 real vectors x and b. This is "fast-
    8300             : but-lightweight" version of the solver.
    8301             : 
    8302             : Algorithm features:
    8303             : * O(N^2) complexity
    8304             : * matrix is represented by its upper or lower triangle
    8305             : * no additional features
    8306             : 
    8307             : INPUT PARAMETERS
    8308             :     CHA     -   array[N,N], Cholesky decomposition,
    8309             :                 SPDMatrixCholesky result
    8310             :     N       -   size of A
    8311             :     IsUpper -   what half of CHA is provided
    8312             :     B       -   array[N], right part
    8313             : 
    8314             : OUTPUT PARAMETERS
    8315             :     Info    -   return code:
    8316             :                 * -3    A is is exactly singular or ill conditioned
    8317             :                         X is filled by zeros in such cases.
    8318             :                 * -1    N<=0 was passed
    8319             :                 *  1    task is solved
    8320             :     B       -   array[N]:
    8321             :                 * for info>0  - overwritten by solution
    8322             :                 * for info=-3 - filled by zeros
    8323             : 
    8324             :   -- ALGLIB --
    8325             :      Copyright 27.01.2010 by Bochkanov Sergey
    8326             : *************************************************************************/
    8327           0 : void spdmatrixcholeskysolvefast(/* Real    */ ae_matrix* cha,
    8328             :      ae_int_t n,
    8329             :      ae_bool isupper,
    8330             :      /* Real    */ ae_vector* b,
    8331             :      ae_int_t* info,
    8332             :      ae_state *_state)
    8333             : {
    8334             :     ae_int_t i;
    8335             :     ae_int_t k;
    8336             : 
    8337           0 :     *info = 0;
    8338             : 
    8339           0 :     *info = 1;
    8340           0 :     if( n<=0 )
    8341             :     {
    8342           0 :         *info = -1;
    8343           0 :         return;
    8344             :     }
    8345           0 :     for(k=0; k<=n-1; k++)
    8346             :     {
    8347           0 :         if( ae_fp_eq(cha->ptr.pp_double[k][k],0.0) )
    8348             :         {
    8349           0 :             for(i=0; i<=n-1; i++)
    8350             :             {
    8351           0 :                 b->ptr.p_double[i] = 0.0;
    8352             :             }
    8353           0 :             *info = -3;
    8354           0 :             return;
    8355             :         }
    8356             :     }
    8357           0 :     directdensesolvers_spdbasiccholeskysolve(cha, n, isupper, b, _state);
    8358             : }
    8359             : 
    8360             : 
    8361             : /*************************************************************************
    8362             : Dense solver for A*X=B, with N*N Hermitian positive definite matrix A  and
    8363             : N*M  complex  matrices  X  and  B.  "Slow-but-feature-rich" version of the
    8364             : solver.
    8365             : 
    8366             : Algorithm features:
    8367             : * automatic detection of degenerate cases
    8368             : * condition number estimation
    8369             : * O(N^3+M*N^2) complexity
    8370             : * matrix is represented by its upper or lower triangle
    8371             : 
    8372             : No iterative refinement is provided because such partial representation of
    8373             : matrix does not allow efficient calculation of extra-precise  matrix-vector
    8374             : products for large matrices. Use RMatrixSolve or RMatrixMixedSolve  if  you
    8375             : need iterative refinement.
    8376             : 
    8377             : IMPORTANT: ! this function is NOT the most efficient linear solver provided
    8378             :            ! by ALGLIB. It estimates condition  number  of  linear system,
    8379             :            ! which  results  in  significant  performance   penalty   when
    8380             :            ! compared with "fast"  version  which  just  calls  triangular
    8381             :            ! solver.
    8382             :            !
    8383             :            ! This performance penalty is especially apparent when you  use
    8384             :            ! ALGLIB parallel capabilities (condition number estimation  is
    8385             :            ! inherently  sequential).  It   also   becomes significant for
    8386             :            ! small-scale problems (N<100).
    8387             :            !
    8388             :            ! In such cases we strongly recommend you to use faster solver,
    8389             :            ! HPDMatrixSolveMFast() function.
    8390             : 
    8391             :   ! COMMERCIAL EDITION OF ALGLIB:
    8392             :   ! 
    8393             :   ! Commercial Edition of ALGLIB includes following important improvements
    8394             :   ! of this function:
    8395             :   ! * high-performance native backend with same C# interface (C# version)
    8396             :   ! * multithreading support (C++ and C# versions)
    8397             :   ! * hardware vendor (Intel) implementations of linear algebra primitives
    8398             :   !   (C++ and C# versions, x86/x64 platform)
    8399             :   ! 
    8400             :   ! We recommend you to read 'Working with commercial version' section  of
    8401             :   ! ALGLIB Reference Manual in order to find out how to  use  performance-
    8402             :   ! related features provided by commercial edition of ALGLIB.
    8403             : 
    8404             : INPUT PARAMETERS
    8405             :     A       -   array[0..N-1,0..N-1], system matrix
    8406             :     N       -   size of A
    8407             :     IsUpper -   what half of A is provided
    8408             :     B       -   array[0..N-1,0..M-1], right part
    8409             :     M       -   right part size
    8410             : 
    8411             : OUTPUT PARAMETERS
    8412             :     Info    -   same as in RMatrixSolve.
    8413             :                 Returns -3 for non-HPD matrices.
    8414             :     Rep     -   same as in RMatrixSolve
    8415             :     X       -   same as in RMatrixSolve
    8416             : 
    8417             :   -- ALGLIB --
    8418             :      Copyright 27.01.2010 by Bochkanov Sergey
    8419             : *************************************************************************/
    8420           0 : void hpdmatrixsolvem(/* Complex */ ae_matrix* a,
    8421             :      ae_int_t n,
    8422             :      ae_bool isupper,
    8423             :      /* Complex */ ae_matrix* b,
    8424             :      ae_int_t m,
    8425             :      ae_int_t* info,
    8426             :      densesolverreport* rep,
    8427             :      /* Complex */ ae_matrix* x,
    8428             :      ae_state *_state)
    8429             : {
    8430             :     ae_frame _frame_block;
    8431             :     ae_matrix da;
    8432             :     ae_int_t i;
    8433             :     ae_int_t j;
    8434             :     ae_int_t j1;
    8435             :     ae_int_t j2;
    8436             : 
    8437           0 :     ae_frame_make(_state, &_frame_block);
    8438           0 :     memset(&da, 0, sizeof(da));
    8439           0 :     *info = 0;
    8440           0 :     _densesolverreport_clear(rep);
    8441           0 :     ae_matrix_clear(x);
    8442           0 :     ae_matrix_init(&da, 0, 0, DT_COMPLEX, _state, ae_true);
    8443             : 
    8444             :     
    8445             :     /*
    8446             :      * prepare: check inputs, allocate space...
    8447             :      */
    8448           0 :     if( n<=0||m<=0 )
    8449             :     {
    8450           0 :         *info = -1;
    8451           0 :         ae_frame_leave(_state);
    8452           0 :         return;
    8453             :     }
    8454           0 :     ae_matrix_set_length(&da, n, n, _state);
    8455             :     
    8456             :     /*
    8457             :      * factorize matrix, solve
    8458             :      */
    8459           0 :     for(i=0; i<=n-1; i++)
    8460             :     {
    8461           0 :         if( isupper )
    8462             :         {
    8463           0 :             j1 = i;
    8464           0 :             j2 = n-1;
    8465             :         }
    8466             :         else
    8467             :         {
    8468           0 :             j1 = 0;
    8469           0 :             j2 = i;
    8470             :         }
    8471           0 :         ae_v_cmove(&da.ptr.pp_complex[i][j1], 1, &a->ptr.pp_complex[i][j1], 1, "N", ae_v_len(j1,j2));
    8472             :     }
    8473           0 :     if( !hpdmatrixcholesky(&da, n, isupper, _state) )
    8474             :     {
    8475           0 :         ae_matrix_set_length(x, n, m, _state);
    8476           0 :         for(i=0; i<=n-1; i++)
    8477             :         {
    8478           0 :             for(j=0; j<=m-1; j++)
    8479             :             {
    8480           0 :                 x->ptr.pp_complex[i][j] = ae_complex_from_i(0);
    8481             :             }
    8482             :         }
    8483           0 :         rep->r1 = (double)(0);
    8484           0 :         rep->rinf = (double)(0);
    8485           0 :         *info = -3;
    8486           0 :         ae_frame_leave(_state);
    8487           0 :         return;
    8488             :     }
    8489           0 :     *info = 1;
    8490           0 :     directdensesolvers_hpdmatrixcholeskysolveinternal(&da, n, isupper, a, ae_true, b, m, info, rep, x, _state);
    8491           0 :     ae_frame_leave(_state);
    8492             : }
    8493             : 
    8494             : 
    8495             : /*************************************************************************
    8496             : Dense solver for A*X=B, with N*N Hermitian positive definite matrix A  and
    8497             : N*M complex matrices X and B. "Fast-but-lightweight" version of the solver.
    8498             : 
    8499             : Algorithm features:
    8500             : * O(N^3+M*N^2) complexity
    8501             : * matrix is represented by its upper or lower triangle
    8502             : * no additional time consuming features like condition number estimation
    8503             : 
    8504             :   ! COMMERCIAL EDITION OF ALGLIB:
    8505             :   ! 
    8506             :   ! Commercial Edition of ALGLIB includes following important improvements
    8507             :   ! of this function:
    8508             :   ! * high-performance native backend with same C# interface (C# version)
    8509             :   ! * multithreading support (C++ and C# versions)
    8510             :   ! * hardware vendor (Intel) implementations of linear algebra primitives
    8511             :   !   (C++ and C# versions, x86/x64 platform)
    8512             :   ! 
    8513             :   ! We recommend you to read 'Working with commercial version' section  of
    8514             :   ! ALGLIB Reference Manual in order to find out how to  use  performance-
    8515             :   ! related features provided by commercial edition of ALGLIB.
    8516             : 
    8517             : INPUT PARAMETERS
    8518             :     A       -   array[0..N-1,0..N-1], system matrix
    8519             :     N       -   size of A
    8520             :     IsUpper -   what half of A is provided
    8521             :     B       -   array[0..N-1,0..M-1], right part
    8522             :     M       -   right part size
    8523             : 
    8524             : OUTPUT PARAMETERS
    8525             :     Info    -   return code:
    8526             :                 * -3    A is is exactly  singular or is not positive definite.
    8527             :                         B is filled by zeros in such cases.
    8528             :                 * -1    N<=0 was passed
    8529             :                 *  1    task is solved
    8530             :     B       -   array[0..N-1]:
    8531             :                 * overwritten by solution
    8532             :                 * zeros, if problem was not solved
    8533             : 
    8534             :   -- ALGLIB --
    8535             :      Copyright 17.03.2015 by Bochkanov Sergey
    8536             : *************************************************************************/
    8537           0 : void hpdmatrixsolvemfast(/* Complex */ ae_matrix* a,
    8538             :      ae_int_t n,
    8539             :      ae_bool isupper,
    8540             :      /* Complex */ ae_matrix* b,
    8541             :      ae_int_t m,
    8542             :      ae_int_t* info,
    8543             :      ae_state *_state)
    8544             : {
    8545             :     ae_frame _frame_block;
    8546             :     ae_matrix _a;
    8547             :     ae_int_t i;
    8548             :     ae_int_t j;
    8549             : 
    8550           0 :     ae_frame_make(_state, &_frame_block);
    8551           0 :     memset(&_a, 0, sizeof(_a));
    8552           0 :     ae_matrix_init_copy(&_a, a, _state, ae_true);
    8553           0 :     a = &_a;
    8554           0 :     *info = 0;
    8555             : 
    8556           0 :     *info = 1;
    8557           0 :     if( n<=0 )
    8558             :     {
    8559           0 :         *info = -1;
    8560           0 :         ae_frame_leave(_state);
    8561           0 :         return;
    8562             :     }
    8563           0 :     if( !hpdmatrixcholesky(a, n, isupper, _state) )
    8564             :     {
    8565           0 :         for(i=0; i<=n-1; i++)
    8566             :         {
    8567           0 :             for(j=0; j<=m-1; j++)
    8568             :             {
    8569           0 :                 b->ptr.pp_complex[i][j] = ae_complex_from_d(0.0);
    8570             :             }
    8571             :         }
    8572           0 :         *info = -3;
    8573           0 :         ae_frame_leave(_state);
    8574           0 :         return;
    8575             :     }
    8576           0 :     if( isupper )
    8577             :     {
    8578           0 :         cmatrixlefttrsm(n, m, a, 0, 0, ae_true, ae_false, 2, b, 0, 0, _state);
    8579           0 :         cmatrixlefttrsm(n, m, a, 0, 0, ae_true, ae_false, 0, b, 0, 0, _state);
    8580             :     }
    8581             :     else
    8582             :     {
    8583           0 :         cmatrixlefttrsm(n, m, a, 0, 0, ae_false, ae_false, 0, b, 0, 0, _state);
    8584           0 :         cmatrixlefttrsm(n, m, a, 0, 0, ae_false, ae_false, 2, b, 0, 0, _state);
    8585             :     }
    8586           0 :     ae_frame_leave(_state);
    8587             : }
    8588             : 
    8589             : 
    8590             : /*************************************************************************
    8591             : Dense solver for A*x=b, with N*N Hermitian positive definite matrix A, and
    8592             : N*1 complex vectors  x  and  b.  "Slow-but-feature-rich"  version  of  the
    8593             : solver.
    8594             : 
    8595             : Algorithm features:
    8596             : * automatic detection of degenerate cases
    8597             : * condition number estimation
    8598             : * O(N^3) complexity
    8599             : * matrix is represented by its upper or lower triangle
    8600             : 
    8601             : No iterative refinement is provided because such partial representation of
    8602             : matrix does not allow efficient calculation of extra-precise  matrix-vector
    8603             : products for large matrices. Use RMatrixSolve or RMatrixMixedSolve  if  you
    8604             : need iterative refinement.
    8605             : 
    8606             : IMPORTANT: ! this function is NOT the most efficient linear solver provided
    8607             :            ! by ALGLIB. It estimates condition  number  of  linear system,
    8608             :            ! which  results  in  significant   performance   penalty  when
    8609             :            ! compared with "fast" version  which  just  performs  Cholesky
    8610             :            ! decomposition and calls triangular solver.
    8611             :            !
    8612             :            ! This  performance  penalty  is  especially  visible  in   the
    8613             :            ! multithreaded mode, because both condition number  estimation
    8614             :            ! and   iterative    refinement   are   inherently   sequential
    8615             :            ! calculations.
    8616             :            !
    8617             :            ! Thus, if you need high performance and if you are pretty sure
    8618             :            ! that your system is well conditioned, we  strongly  recommend
    8619             :            ! you to use faster solver, HPDMatrixSolveFast() function.
    8620             : 
    8621             :   ! COMMERCIAL EDITION OF ALGLIB:
    8622             :   ! 
    8623             :   ! Commercial Edition of ALGLIB includes following important improvements
    8624             :   ! of this function:
    8625             :   ! * high-performance native backend with same C# interface (C# version)
    8626             :   ! * multithreading support (C++ and C# versions)
    8627             :   ! * hardware vendor (Intel) implementations of linear algebra primitives
    8628             :   !   (C++ and C# versions, x86/x64 platform)
    8629             :   ! 
    8630             :   ! We recommend you to read 'Working with commercial version' section  of
    8631             :   ! ALGLIB Reference Manual in order to find out how to  use  performance-
    8632             :   ! related features provided by commercial edition of ALGLIB.
    8633             : 
    8634             : INPUT PARAMETERS
    8635             :     A       -   array[0..N-1,0..N-1], system matrix
    8636             :     N       -   size of A
    8637             :     IsUpper -   what half of A is provided
    8638             :     B       -   array[0..N-1], right part
    8639             : 
    8640             : OUTPUT PARAMETERS
    8641             :     Info    -   same as in RMatrixSolve
    8642             :                 Returns -3 for non-HPD matrices.
    8643             :     Rep     -   same as in RMatrixSolve
    8644             :     X       -   same as in RMatrixSolve
    8645             : 
    8646             :   -- ALGLIB --
    8647             :      Copyright 27.01.2010 by Bochkanov Sergey
    8648             : *************************************************************************/
    8649           0 : void hpdmatrixsolve(/* Complex */ ae_matrix* a,
    8650             :      ae_int_t n,
    8651             :      ae_bool isupper,
    8652             :      /* Complex */ ae_vector* b,
    8653             :      ae_int_t* info,
    8654             :      densesolverreport* rep,
    8655             :      /* Complex */ ae_vector* x,
    8656             :      ae_state *_state)
    8657             : {
    8658             :     ae_frame _frame_block;
    8659             :     ae_matrix bm;
    8660             :     ae_matrix xm;
    8661             : 
    8662           0 :     ae_frame_make(_state, &_frame_block);
    8663           0 :     memset(&bm, 0, sizeof(bm));
    8664           0 :     memset(&xm, 0, sizeof(xm));
    8665           0 :     *info = 0;
    8666           0 :     _densesolverreport_clear(rep);
    8667           0 :     ae_vector_clear(x);
    8668           0 :     ae_matrix_init(&bm, 0, 0, DT_COMPLEX, _state, ae_true);
    8669           0 :     ae_matrix_init(&xm, 0, 0, DT_COMPLEX, _state, ae_true);
    8670             : 
    8671           0 :     if( n<=0 )
    8672             :     {
    8673           0 :         *info = -1;
    8674           0 :         ae_frame_leave(_state);
    8675           0 :         return;
    8676             :     }
    8677           0 :     ae_matrix_set_length(&bm, n, 1, _state);
    8678           0 :     ae_v_cmove(&bm.ptr.pp_complex[0][0], bm.stride, &b->ptr.p_complex[0], 1, "N", ae_v_len(0,n-1));
    8679           0 :     hpdmatrixsolvem(a, n, isupper, &bm, 1, info, rep, &xm, _state);
    8680           0 :     ae_vector_set_length(x, n, _state);
    8681           0 :     ae_v_cmove(&x->ptr.p_complex[0], 1, &xm.ptr.pp_complex[0][0], xm.stride, "N", ae_v_len(0,n-1));
    8682           0 :     ae_frame_leave(_state);
    8683             : }
    8684             : 
    8685             : 
    8686             : /*************************************************************************
    8687             : Dense solver for A*x=b, with N*N Hermitian positive definite matrix A, and
    8688             : N*1 complex vectors  x  and  b.  "Fast-but-lightweight"  version  of   the
    8689             : solver without additional functions.
    8690             : 
    8691             : Algorithm features:
    8692             : * O(N^3) complexity
    8693             : * matrix is represented by its upper or lower triangle
    8694             : * no additional time consuming functions
    8695             : 
    8696             :   ! COMMERCIAL EDITION OF ALGLIB:
    8697             :   ! 
    8698             :   ! Commercial Edition of ALGLIB includes following important improvements
    8699             :   ! of this function:
    8700             :   ! * high-performance native backend with same C# interface (C# version)
    8701             :   ! * multithreading support (C++ and C# versions)
    8702             :   ! * hardware vendor (Intel) implementations of linear algebra primitives
    8703             :   !   (C++ and C# versions, x86/x64 platform)
    8704             :   ! 
    8705             :   ! We recommend you to read 'Working with commercial version' section  of
    8706             :   ! ALGLIB Reference Manual in order to find out how to  use  performance-
    8707             :   ! related features provided by commercial edition of ALGLIB.
    8708             : 
    8709             : INPUT PARAMETERS
    8710             :     A       -   array[0..N-1,0..N-1], system matrix
    8711             :     N       -   size of A
    8712             :     IsUpper -   what half of A is provided
    8713             :     B       -   array[0..N-1], right part
    8714             : 
    8715             : OUTPUT PARAMETERS
    8716             :     Info    -   return code:
    8717             :                 * -3    A is is exactly singular or not positive definite
    8718             :                         X is filled by zeros in such cases.
    8719             :                 * -1    N<=0 was passed
    8720             :                 *  1    task was solved 
    8721             :     B       -   array[0..N-1]:
    8722             :                 * overwritten by solution
    8723             :                 * zeros, if A is exactly singular (diagonal of its LU
    8724             :                   decomposition has exact zeros).
    8725             : 
    8726             :   -- ALGLIB --
    8727             :      Copyright 17.03.2015 by Bochkanov Sergey
    8728             : *************************************************************************/
    8729           0 : void hpdmatrixsolvefast(/* Complex */ ae_matrix* a,
    8730             :      ae_int_t n,
    8731             :      ae_bool isupper,
    8732             :      /* Complex */ ae_vector* b,
    8733             :      ae_int_t* info,
    8734             :      ae_state *_state)
    8735             : {
    8736             :     ae_frame _frame_block;
    8737             :     ae_matrix _a;
    8738             :     ae_int_t i;
    8739             : 
    8740           0 :     ae_frame_make(_state, &_frame_block);
    8741           0 :     memset(&_a, 0, sizeof(_a));
    8742           0 :     ae_matrix_init_copy(&_a, a, _state, ae_true);
    8743           0 :     a = &_a;
    8744           0 :     *info = 0;
    8745             : 
    8746           0 :     *info = 1;
    8747           0 :     if( n<=0 )
    8748             :     {
    8749           0 :         *info = -1;
    8750           0 :         ae_frame_leave(_state);
    8751           0 :         return;
    8752             :     }
    8753           0 :     if( !hpdmatrixcholesky(a, n, isupper, _state) )
    8754             :     {
    8755           0 :         for(i=0; i<=n-1; i++)
    8756             :         {
    8757           0 :             b->ptr.p_complex[i] = ae_complex_from_d(0.0);
    8758             :         }
    8759           0 :         *info = -3;
    8760           0 :         ae_frame_leave(_state);
    8761           0 :         return;
    8762             :     }
    8763           0 :     directdensesolvers_hpdbasiccholeskysolve(a, n, isupper, b, _state);
    8764           0 :     ae_frame_leave(_state);
    8765             : }
    8766             : 
    8767             : 
    8768             : /*************************************************************************
    8769             : Dense solver for A*X=B with N*N Hermitian positive definite matrix A given
    8770             : by its Cholesky decomposition and N*M complex matrices X  and  B.  This is
    8771             : "slow-but-feature-rich" version of the solver which, in  addition  to  the
    8772             : solution, estimates condition number of the system.
    8773             : 
    8774             : Algorithm features:
    8775             : * automatic detection of degenerate cases
    8776             : * O(M*N^2) complexity
    8777             : * condition number estimation
    8778             : * matrix is represented by its upper or lower triangle
    8779             : 
    8780             : No iterative refinement is provided because such partial representation of
    8781             : matrix does not allow efficient calculation of extra-precise  matrix-vector
    8782             : products for large matrices. Use RMatrixSolve or RMatrixMixedSolve  if  you
    8783             : need iterative refinement.
    8784             : 
    8785             : IMPORTANT: ! this function is NOT the most efficient linear solver provided
    8786             :            ! by ALGLIB. It estimates condition  number  of  linear system,
    8787             :            ! which  results  in  significant  performance   penalty   when
    8788             :            ! compared with "fast"  version  which  just  calls  triangular
    8789             :            ! solver. Amount of  overhead  introduced  depends  on  M  (the
    8790             :            ! larger - the more efficient).
    8791             :            !
    8792             :            ! This performance penalty is insignificant  when compared with
    8793             :            ! cost of large Cholesky decomposition.  However,  if  you call
    8794             :            ! this  function  many  times  for  the same  left  side,  this
    8795             :            ! overhead BECOMES significant. It  also   becomes  significant
    8796             :            ! for small-scale problems (N<50).
    8797             :            !
    8798             :            ! In such cases we strongly recommend you to use faster solver,
    8799             :            ! HPDMatrixCholeskySolveMFast() function.
    8800             : 
    8801             : 
    8802             : INPUT PARAMETERS
    8803             :     CHA     -   array[N,N], Cholesky decomposition,
    8804             :                 HPDMatrixCholesky result
    8805             :     N       -   size of CHA
    8806             :     IsUpper -   what half of CHA is provided
    8807             :     B       -   array[N,M], right part
    8808             :     M       -   right part size
    8809             : 
    8810             : OUTPUT PARAMETERS:
    8811             :     Info    -   return code:
    8812             :                 * -3    A is singular, or VERY close to singular.
    8813             :                         X is filled by zeros in such cases.
    8814             :                 * -1    N<=0 was passed
    8815             :                 *  1    task was solved
    8816             :     Rep     -   additional report, following fields are set:
    8817             :                 * rep.r1    condition number in 1-norm
    8818             :                 * rep.rinf  condition number in inf-norm
    8819             :     X       -   array[N]:
    8820             :                 * for info>0 contains solution
    8821             :                 * for info=-3 filled by zeros
    8822             : 
    8823             :   -- ALGLIB --
    8824             :      Copyright 27.01.2010 by Bochkanov Sergey
    8825             : *************************************************************************/
    8826           0 : void hpdmatrixcholeskysolvem(/* Complex */ ae_matrix* cha,
    8827             :      ae_int_t n,
    8828             :      ae_bool isupper,
    8829             :      /* Complex */ ae_matrix* b,
    8830             :      ae_int_t m,
    8831             :      ae_int_t* info,
    8832             :      densesolverreport* rep,
    8833             :      /* Complex */ ae_matrix* x,
    8834             :      ae_state *_state)
    8835             : {
    8836             :     ae_frame _frame_block;
    8837             :     ae_matrix emptya;
    8838             : 
    8839           0 :     ae_frame_make(_state, &_frame_block);
    8840           0 :     memset(&emptya, 0, sizeof(emptya));
    8841           0 :     *info = 0;
    8842           0 :     _densesolverreport_clear(rep);
    8843           0 :     ae_matrix_clear(x);
    8844           0 :     ae_matrix_init(&emptya, 0, 0, DT_COMPLEX, _state, ae_true);
    8845             : 
    8846             :     
    8847             :     /*
    8848             :      * prepare: check inputs, allocate space...
    8849             :      */
    8850           0 :     if( n<=0||m<=0 )
    8851             :     {
    8852           0 :         *info = -1;
    8853           0 :         ae_frame_leave(_state);
    8854           0 :         return;
    8855             :     }
    8856             :     
    8857             :     /*
    8858             :      * 1. scale matrix, max(|U[i,j]|)
    8859             :      * 2. factorize scaled matrix
    8860             :      * 3. solve
    8861             :      */
    8862           0 :     directdensesolvers_hpdmatrixcholeskysolveinternal(cha, n, isupper, &emptya, ae_false, b, m, info, rep, x, _state);
    8863           0 :     ae_frame_leave(_state);
    8864             : }
    8865             : 
    8866             : 
    8867             : /*************************************************************************
    8868             : Dense solver for A*X=B with N*N Hermitian positive definite matrix A given
    8869             : by its Cholesky decomposition and N*M complex matrices X  and  B.  This is
    8870             : "fast-but-lightweight" version of the solver.
    8871             : 
    8872             : Algorithm features:
    8873             : * O(M*N^2) complexity
    8874             : * matrix is represented by its upper or lower triangle
    8875             : * no additional time-consuming features
    8876             : 
    8877             : INPUT PARAMETERS
    8878             :     CHA     -   array[N,N], Cholesky decomposition,
    8879             :                 HPDMatrixCholesky result
    8880             :     N       -   size of CHA
    8881             :     IsUpper -   what half of CHA is provided
    8882             :     B       -   array[N,M], right part
    8883             :     M       -   right part size
    8884             : 
    8885             : OUTPUT PARAMETERS:
    8886             :     Info    -   return code:
    8887             :                 * -3    A is singular, or VERY close to singular.
    8888             :                         X is filled by zeros in such cases.
    8889             :                 * -1    N<=0 was passed
    8890             :                 *  1    task was solved
    8891             :     B       -   array[N]:
    8892             :                 * for info>0 overwritten by solution
    8893             :                 * for info=-3 filled by zeros
    8894             : 
    8895             :   -- ALGLIB --
    8896             :      Copyright 18.03.2015 by Bochkanov Sergey
    8897             : *************************************************************************/
    8898           0 : void hpdmatrixcholeskysolvemfast(/* Complex */ ae_matrix* cha,
    8899             :      ae_int_t n,
    8900             :      ae_bool isupper,
    8901             :      /* Complex */ ae_matrix* b,
    8902             :      ae_int_t m,
    8903             :      ae_int_t* info,
    8904             :      ae_state *_state)
    8905             : {
    8906             :     ae_int_t i;
    8907             :     ae_int_t j;
    8908             :     ae_int_t k;
    8909             : 
    8910           0 :     *info = 0;
    8911             : 
    8912           0 :     *info = 1;
    8913           0 :     if( n<=0 )
    8914             :     {
    8915           0 :         *info = -1;
    8916           0 :         return;
    8917             :     }
    8918           0 :     for(k=0; k<=n-1; k++)
    8919             :     {
    8920           0 :         if( ae_fp_eq(cha->ptr.pp_complex[k][k].x,0.0)&&ae_fp_eq(cha->ptr.pp_complex[k][k].y,0.0) )
    8921             :         {
    8922           0 :             for(i=0; i<=n-1; i++)
    8923             :             {
    8924           0 :                 for(j=0; j<=m-1; j++)
    8925             :                 {
    8926           0 :                     b->ptr.pp_complex[i][j] = ae_complex_from_d(0.0);
    8927             :                 }
    8928             :             }
    8929           0 :             *info = -3;
    8930           0 :             return;
    8931             :         }
    8932             :     }
    8933           0 :     if( isupper )
    8934             :     {
    8935           0 :         cmatrixlefttrsm(n, m, cha, 0, 0, ae_true, ae_false, 2, b, 0, 0, _state);
    8936           0 :         cmatrixlefttrsm(n, m, cha, 0, 0, ae_true, ae_false, 0, b, 0, 0, _state);
    8937             :     }
    8938             :     else
    8939             :     {
    8940           0 :         cmatrixlefttrsm(n, m, cha, 0, 0, ae_false, ae_false, 0, b, 0, 0, _state);
    8941           0 :         cmatrixlefttrsm(n, m, cha, 0, 0, ae_false, ae_false, 2, b, 0, 0, _state);
    8942             :     }
    8943             : }
    8944             : 
    8945             : 
    8946             : /*************************************************************************
    8947             : Dense solver for A*x=b with N*N Hermitian positive definite matrix A given
    8948             : by its Cholesky decomposition, and N*1 complex vectors x and  b.  This  is
    8949             : "slow-but-feature-rich" version of the solver  which  estimates  condition
    8950             : number of the system.
    8951             : 
    8952             : Algorithm features:
    8953             : * automatic detection of degenerate cases
    8954             : * O(N^2) complexity
    8955             : * condition number estimation
    8956             : * matrix is represented by its upper or lower triangle
    8957             : 
    8958             : No iterative refinement is provided because such partial representation of
    8959             : matrix does not allow efficient calculation of extra-precise  matrix-vector
    8960             : products for large matrices. Use RMatrixSolve or RMatrixMixedSolve  if  you
    8961             : need iterative refinement.
    8962             : 
    8963             : IMPORTANT: ! this function is NOT the most efficient linear solver provided
    8964             :            ! by ALGLIB. It estimates condition  number  of  linear system,
    8965             :            ! which results in 10-15x  performance  penalty  when  compared
    8966             :            ! with "fast" version which just calls triangular solver.
    8967             :            !
    8968             :            ! This performance penalty is insignificant  when compared with
    8969             :            ! cost of large LU decomposition.  However,  if you  call  this
    8970             :            ! function many times for the same  left  side,  this  overhead
    8971             :            ! BECOMES significant. It  also  becomes significant for small-
    8972             :            ! scale problems (N<50).
    8973             :            !
    8974             :            ! In such cases we strongly recommend you to use faster solver,
    8975             :            ! HPDMatrixCholeskySolveFast() function.
    8976             : 
    8977             : INPUT PARAMETERS
    8978             :     CHA     -   array[0..N-1,0..N-1], Cholesky decomposition,
    8979             :                 SPDMatrixCholesky result
    8980             :     N       -   size of A
    8981             :     IsUpper -   what half of CHA is provided
    8982             :     B       -   array[0..N-1], right part
    8983             : 
    8984             : OUTPUT PARAMETERS
    8985             :     Info    -   return code:
    8986             :                 * -3    A is is exactly singular or ill conditioned
    8987             :                         X is filled by zeros in such cases.
    8988             :                 * -1    N<=0 was passed
    8989             :                 *  1    task is solved
    8990             :     Rep     -   additional report, following fields are set:
    8991             :                 * rep.r1    condition number in 1-norm
    8992             :                 * rep.rinf  condition number in inf-norm
    8993             :     X       -   array[N]:
    8994             :                 * for info>0  - solution
    8995             :                 * for info=-3 - filled by zeros
    8996             : 
    8997             :   -- ALGLIB --
    8998             :      Copyright 27.01.2010 by Bochkanov Sergey
    8999             : *************************************************************************/
    9000           0 : void hpdmatrixcholeskysolve(/* Complex */ ae_matrix* cha,
    9001             :      ae_int_t n,
    9002             :      ae_bool isupper,
    9003             :      /* Complex */ ae_vector* b,
    9004             :      ae_int_t* info,
    9005             :      densesolverreport* rep,
    9006             :      /* Complex */ ae_vector* x,
    9007             :      ae_state *_state)
    9008             : {
    9009             :     ae_frame _frame_block;
    9010             :     ae_matrix bm;
    9011             :     ae_matrix xm;
    9012             : 
    9013           0 :     ae_frame_make(_state, &_frame_block);
    9014           0 :     memset(&bm, 0, sizeof(bm));
    9015           0 :     memset(&xm, 0, sizeof(xm));
    9016           0 :     *info = 0;
    9017           0 :     _densesolverreport_clear(rep);
    9018           0 :     ae_vector_clear(x);
    9019           0 :     ae_matrix_init(&bm, 0, 0, DT_COMPLEX, _state, ae_true);
    9020           0 :     ae_matrix_init(&xm, 0, 0, DT_COMPLEX, _state, ae_true);
    9021             : 
    9022           0 :     if( n<=0 )
    9023             :     {
    9024           0 :         *info = -1;
    9025           0 :         ae_frame_leave(_state);
    9026           0 :         return;
    9027             :     }
    9028           0 :     ae_matrix_set_length(&bm, n, 1, _state);
    9029           0 :     ae_v_cmove(&bm.ptr.pp_complex[0][0], bm.stride, &b->ptr.p_complex[0], 1, "N", ae_v_len(0,n-1));
    9030           0 :     hpdmatrixcholeskysolvem(cha, n, isupper, &bm, 1, info, rep, &xm, _state);
    9031           0 :     ae_vector_set_length(x, n, _state);
    9032           0 :     ae_v_cmove(&x->ptr.p_complex[0], 1, &xm.ptr.pp_complex[0][0], xm.stride, "N", ae_v_len(0,n-1));
    9033           0 :     ae_frame_leave(_state);
    9034             : }
    9035             : 
    9036             : 
    9037             : /*************************************************************************
    9038             : Dense solver for A*x=b with N*N Hermitian positive definite matrix A given
    9039             : by its Cholesky decomposition, and N*1 complex vectors x and  b.  This  is
    9040             : "fast-but-lightweight" version of the solver.
    9041             : 
    9042             : Algorithm features:
    9043             : * O(N^2) complexity
    9044             : * matrix is represented by its upper or lower triangle
    9045             : * no additional time-consuming features
    9046             : 
    9047             : INPUT PARAMETERS
    9048             :     CHA     -   array[0..N-1,0..N-1], Cholesky decomposition,
    9049             :                 SPDMatrixCholesky result
    9050             :     N       -   size of A
    9051             :     IsUpper -   what half of CHA is provided
    9052             :     B       -   array[0..N-1], right part
    9053             : 
    9054             : OUTPUT PARAMETERS
    9055             :     Info    -   return code:
    9056             :                 * -3    A is is exactly singular or ill conditioned
    9057             :                         B is filled by zeros in such cases.
    9058             :                 * -1    N<=0 was passed
    9059             :                 *  1    task is solved
    9060             :     B       -   array[N]:
    9061             :                 * for info>0  - overwritten by solution
    9062             :                 * for info=-3 - filled by zeros
    9063             : 
    9064             :   -- ALGLIB --
    9065             :      Copyright 18.03.2015 by Bochkanov Sergey
    9066             : *************************************************************************/
    9067           0 : void hpdmatrixcholeskysolvefast(/* Complex */ ae_matrix* cha,
    9068             :      ae_int_t n,
    9069             :      ae_bool isupper,
    9070             :      /* Complex */ ae_vector* b,
    9071             :      ae_int_t* info,
    9072             :      ae_state *_state)
    9073             : {
    9074             :     ae_int_t i;
    9075             :     ae_int_t k;
    9076             : 
    9077           0 :     *info = 0;
    9078             : 
    9079           0 :     *info = 1;
    9080           0 :     if( n<=0 )
    9081             :     {
    9082           0 :         *info = -1;
    9083           0 :         return;
    9084             :     }
    9085           0 :     for(k=0; k<=n-1; k++)
    9086             :     {
    9087           0 :         if( ae_fp_eq(cha->ptr.pp_complex[k][k].x,0.0)&&ae_fp_eq(cha->ptr.pp_complex[k][k].y,0.0) )
    9088             :         {
    9089           0 :             for(i=0; i<=n-1; i++)
    9090             :             {
    9091           0 :                 b->ptr.p_complex[i] = ae_complex_from_d(0.0);
    9092             :             }
    9093           0 :             *info = -3;
    9094           0 :             return;
    9095             :         }
    9096             :     }
    9097           0 :     directdensesolvers_hpdbasiccholeskysolve(cha, n, isupper, b, _state);
    9098             : }
    9099             : 
    9100             : 
    9101             : /*************************************************************************
    9102             : Dense solver.
    9103             : 
    9104             : This subroutine finds solution of the linear system A*X=B with non-square,
    9105             : possibly degenerate A.  System  is  solved in the least squares sense, and
    9106             : general least squares solution  X = X0 + CX*y  which  minimizes |A*X-B| is
    9107             : returned. If A is non-degenerate, solution in the usual sense is returned.
    9108             : 
    9109             : Algorithm features:
    9110             : * automatic detection (and correct handling!) of degenerate cases
    9111             : * iterative refinement
    9112             : * O(N^3) complexity
    9113             : 
    9114             :   ! COMMERCIAL EDITION OF ALGLIB:
    9115             :   ! 
    9116             :   ! Commercial Edition of ALGLIB includes following important improvements
    9117             :   ! of this function:
    9118             :   ! * high-performance native backend with same C# interface (C# version)
    9119             :   ! * multithreading support (C++ and C# versions)
    9120             :   ! * hardware vendor (Intel) implementations of linear algebra primitives
    9121             :   !   (C++ and C# versions, x86/x64 platform)
    9122             :   ! 
    9123             :   ! We recommend you to read 'Working with commercial version' section  of
    9124             :   ! ALGLIB Reference Manual in order to find out how to  use  performance-
    9125             :   ! related features provided by commercial edition of ALGLIB.
    9126             : 
    9127             : INPUT PARAMETERS
    9128             :     A       -   array[0..NRows-1,0..NCols-1], system matrix
    9129             :     NRows   -   vertical size of A
    9130             :     NCols   -   horizontal size of A
    9131             :     B       -   array[0..NCols-1], right part
    9132             :     Threshold-  a number in [0,1]. Singular values  beyond  Threshold  are
    9133             :                 considered  zero.  Set  it to 0.0, if you don't understand
    9134             :                 what it means, so the solver will choose good value on its
    9135             :                 own.
    9136             :                 
    9137             : OUTPUT PARAMETERS
    9138             :     Info    -   return code:
    9139             :                 * -4    SVD subroutine failed
    9140             :                 * -1    if NRows<=0 or NCols<=0 or Threshold<0 was passed
    9141             :                 *  1    if task is solved
    9142             :     Rep     -   solver report, see below for more info
    9143             :     X       -   array[0..N-1,0..M-1], it contains:
    9144             :                 * solution of A*X=B (even for singular A)
    9145             :                 * zeros, if SVD subroutine failed
    9146             : 
    9147             : SOLVER REPORT
    9148             : 
    9149             : Subroutine sets following fields of the Rep structure:
    9150             : * R2        reciprocal of condition number: 1/cond(A), 2-norm.
    9151             : * N         = NCols
    9152             : * K         dim(Null(A))
    9153             : * CX        array[0..N-1,0..K-1], kernel of A.
    9154             :             Columns of CX store such vectors that A*CX[i]=0.
    9155             : 
    9156             :   -- ALGLIB --
    9157             :      Copyright 24.08.2009 by Bochkanov Sergey
    9158             : *************************************************************************/
    9159           0 : void rmatrixsolvels(/* Real    */ ae_matrix* a,
    9160             :      ae_int_t nrows,
    9161             :      ae_int_t ncols,
    9162             :      /* Real    */ ae_vector* b,
    9163             :      double threshold,
    9164             :      ae_int_t* info,
    9165             :      densesolverlsreport* rep,
    9166             :      /* Real    */ ae_vector* x,
    9167             :      ae_state *_state)
    9168             : {
    9169             :     ae_frame _frame_block;
    9170             :     ae_vector sv;
    9171             :     ae_matrix u;
    9172             :     ae_matrix vt;
    9173             :     ae_vector rp;
    9174             :     ae_vector utb;
    9175             :     ae_vector sutb;
    9176             :     ae_vector tmp;
    9177             :     ae_vector ta;
    9178             :     ae_vector tx;
    9179             :     ae_vector buf;
    9180             :     ae_vector w;
    9181             :     ae_int_t i;
    9182             :     ae_int_t j;
    9183             :     ae_int_t nsv;
    9184             :     ae_int_t kernelidx;
    9185             :     double v;
    9186             :     double verr;
    9187             :     ae_bool svdfailed;
    9188             :     ae_bool zeroa;
    9189             :     ae_int_t rfs;
    9190             :     ae_int_t nrfs;
    9191             :     ae_bool terminatenexttime;
    9192             :     ae_bool smallerr;
    9193             : 
    9194           0 :     ae_frame_make(_state, &_frame_block);
    9195           0 :     memset(&sv, 0, sizeof(sv));
    9196           0 :     memset(&u, 0, sizeof(u));
    9197           0 :     memset(&vt, 0, sizeof(vt));
    9198           0 :     memset(&rp, 0, sizeof(rp));
    9199           0 :     memset(&utb, 0, sizeof(utb));
    9200           0 :     memset(&sutb, 0, sizeof(sutb));
    9201           0 :     memset(&tmp, 0, sizeof(tmp));
    9202           0 :     memset(&ta, 0, sizeof(ta));
    9203           0 :     memset(&tx, 0, sizeof(tx));
    9204           0 :     memset(&buf, 0, sizeof(buf));
    9205           0 :     memset(&w, 0, sizeof(w));
    9206           0 :     *info = 0;
    9207           0 :     _densesolverlsreport_clear(rep);
    9208           0 :     ae_vector_clear(x);
    9209           0 :     ae_vector_init(&sv, 0, DT_REAL, _state, ae_true);
    9210           0 :     ae_matrix_init(&u, 0, 0, DT_REAL, _state, ae_true);
    9211           0 :     ae_matrix_init(&vt, 0, 0, DT_REAL, _state, ae_true);
    9212           0 :     ae_vector_init(&rp, 0, DT_REAL, _state, ae_true);
    9213           0 :     ae_vector_init(&utb, 0, DT_REAL, _state, ae_true);
    9214           0 :     ae_vector_init(&sutb, 0, DT_REAL, _state, ae_true);
    9215           0 :     ae_vector_init(&tmp, 0, DT_REAL, _state, ae_true);
    9216           0 :     ae_vector_init(&ta, 0, DT_REAL, _state, ae_true);
    9217           0 :     ae_vector_init(&tx, 0, DT_REAL, _state, ae_true);
    9218           0 :     ae_vector_init(&buf, 0, DT_REAL, _state, ae_true);
    9219           0 :     ae_vector_init(&w, 0, DT_REAL, _state, ae_true);
    9220             : 
    9221           0 :     if( (nrows<=0||ncols<=0)||ae_fp_less(threshold,(double)(0)) )
    9222             :     {
    9223           0 :         *info = -1;
    9224           0 :         ae_frame_leave(_state);
    9225           0 :         return;
    9226             :     }
    9227           0 :     if( ae_fp_eq(threshold,(double)(0)) )
    9228             :     {
    9229           0 :         threshold = 1000*ae_machineepsilon;
    9230             :     }
    9231             :     
    9232             :     /*
    9233             :      * Factorize A first
    9234             :      */
    9235           0 :     svdfailed = !rmatrixsvd(a, nrows, ncols, 1, 2, 2, &sv, &u, &vt, _state);
    9236           0 :     zeroa = ae_fp_eq(sv.ptr.p_double[0],(double)(0));
    9237           0 :     if( svdfailed||zeroa )
    9238             :     {
    9239           0 :         if( svdfailed )
    9240             :         {
    9241           0 :             *info = -4;
    9242             :         }
    9243             :         else
    9244             :         {
    9245           0 :             *info = 1;
    9246             :         }
    9247           0 :         ae_vector_set_length(x, ncols, _state);
    9248           0 :         for(i=0; i<=ncols-1; i++)
    9249             :         {
    9250           0 :             x->ptr.p_double[i] = (double)(0);
    9251             :         }
    9252           0 :         rep->n = ncols;
    9253           0 :         rep->k = ncols;
    9254           0 :         ae_matrix_set_length(&rep->cx, ncols, ncols, _state);
    9255           0 :         for(i=0; i<=ncols-1; i++)
    9256             :         {
    9257           0 :             for(j=0; j<=ncols-1; j++)
    9258             :             {
    9259           0 :                 if( i==j )
    9260             :                 {
    9261           0 :                     rep->cx.ptr.pp_double[i][j] = (double)(1);
    9262             :                 }
    9263             :                 else
    9264             :                 {
    9265           0 :                     rep->cx.ptr.pp_double[i][j] = (double)(0);
    9266             :                 }
    9267             :             }
    9268             :         }
    9269           0 :         rep->r2 = (double)(0);
    9270           0 :         ae_frame_leave(_state);
    9271           0 :         return;
    9272             :     }
    9273           0 :     nsv = ae_minint(ncols, nrows, _state);
    9274           0 :     if( nsv==ncols )
    9275             :     {
    9276           0 :         rep->r2 = sv.ptr.p_double[nsv-1]/sv.ptr.p_double[0];
    9277             :     }
    9278             :     else
    9279             :     {
    9280           0 :         rep->r2 = (double)(0);
    9281             :     }
    9282           0 :     rep->n = ncols;
    9283           0 :     *info = 1;
    9284             :     
    9285             :     /*
    9286             :      * Iterative refinement of xc combined with solution:
    9287             :      * 1. xc = 0
    9288             :      * 2. calculate r = bc-A*xc using extra-precise dot product
    9289             :      * 3. solve A*y = r
    9290             :      * 4. update x:=x+r
    9291             :      * 5. goto 2
    9292             :      *
    9293             :      * This cycle is executed until one of two things happens:
    9294             :      * 1. maximum number of iterations reached
    9295             :      * 2. last iteration decreased error to the lower limit
    9296             :      */
    9297           0 :     ae_vector_set_length(&utb, nsv, _state);
    9298           0 :     ae_vector_set_length(&sutb, nsv, _state);
    9299           0 :     ae_vector_set_length(x, ncols, _state);
    9300           0 :     ae_vector_set_length(&tmp, ncols, _state);
    9301           0 :     ae_vector_set_length(&ta, ncols+1, _state);
    9302           0 :     ae_vector_set_length(&tx, ncols+1, _state);
    9303           0 :     ae_vector_set_length(&buf, ncols+1, _state);
    9304           0 :     for(i=0; i<=ncols-1; i++)
    9305             :     {
    9306           0 :         x->ptr.p_double[i] = (double)(0);
    9307             :     }
    9308           0 :     kernelidx = nsv;
    9309           0 :     for(i=0; i<=nsv-1; i++)
    9310             :     {
    9311           0 :         if( ae_fp_less_eq(sv.ptr.p_double[i],threshold*sv.ptr.p_double[0]) )
    9312             :         {
    9313           0 :             kernelidx = i;
    9314           0 :             break;
    9315             :         }
    9316             :     }
    9317           0 :     rep->k = ncols-kernelidx;
    9318           0 :     nrfs = directdensesolvers_densesolverrfsmaxv2(ncols, rep->r2, _state);
    9319           0 :     terminatenexttime = ae_false;
    9320           0 :     ae_vector_set_length(&rp, nrows, _state);
    9321           0 :     for(rfs=0; rfs<=nrfs; rfs++)
    9322             :     {
    9323           0 :         if( terminatenexttime )
    9324             :         {
    9325           0 :             break;
    9326             :         }
    9327             :         
    9328             :         /*
    9329             :          * calculate right part
    9330             :          */
    9331           0 :         if( rfs==0 )
    9332             :         {
    9333           0 :             ae_v_move(&rp.ptr.p_double[0], 1, &b->ptr.p_double[0], 1, ae_v_len(0,nrows-1));
    9334             :         }
    9335             :         else
    9336             :         {
    9337           0 :             smallerr = ae_true;
    9338           0 :             for(i=0; i<=nrows-1; i++)
    9339             :             {
    9340           0 :                 ae_v_move(&ta.ptr.p_double[0], 1, &a->ptr.pp_double[i][0], 1, ae_v_len(0,ncols-1));
    9341           0 :                 ta.ptr.p_double[ncols] = (double)(-1);
    9342           0 :                 ae_v_move(&tx.ptr.p_double[0], 1, &x->ptr.p_double[0], 1, ae_v_len(0,ncols-1));
    9343           0 :                 tx.ptr.p_double[ncols] = b->ptr.p_double[i];
    9344           0 :                 xdot(&ta, &tx, ncols+1, &buf, &v, &verr, _state);
    9345           0 :                 rp.ptr.p_double[i] = -v;
    9346           0 :                 smallerr = smallerr&&ae_fp_less(ae_fabs(v, _state),4*verr);
    9347             :             }
    9348           0 :             if( smallerr )
    9349             :             {
    9350           0 :                 terminatenexttime = ae_true;
    9351             :             }
    9352             :         }
    9353             :         
    9354             :         /*
    9355             :          * solve A*dx = rp
    9356             :          */
    9357           0 :         for(i=0; i<=ncols-1; i++)
    9358             :         {
    9359           0 :             tmp.ptr.p_double[i] = (double)(0);
    9360             :         }
    9361           0 :         for(i=0; i<=nsv-1; i++)
    9362             :         {
    9363           0 :             utb.ptr.p_double[i] = (double)(0);
    9364             :         }
    9365           0 :         for(i=0; i<=nrows-1; i++)
    9366             :         {
    9367           0 :             v = rp.ptr.p_double[i];
    9368           0 :             ae_v_addd(&utb.ptr.p_double[0], 1, &u.ptr.pp_double[i][0], 1, ae_v_len(0,nsv-1), v);
    9369             :         }
    9370           0 :         for(i=0; i<=nsv-1; i++)
    9371             :         {
    9372           0 :             if( i<kernelidx )
    9373             :             {
    9374           0 :                 sutb.ptr.p_double[i] = utb.ptr.p_double[i]/sv.ptr.p_double[i];
    9375             :             }
    9376             :             else
    9377             :             {
    9378           0 :                 sutb.ptr.p_double[i] = (double)(0);
    9379             :             }
    9380             :         }
    9381           0 :         for(i=0; i<=nsv-1; i++)
    9382             :         {
    9383           0 :             v = sutb.ptr.p_double[i];
    9384           0 :             ae_v_addd(&tmp.ptr.p_double[0], 1, &vt.ptr.pp_double[i][0], 1, ae_v_len(0,ncols-1), v);
    9385             :         }
    9386             :         
    9387             :         /*
    9388             :          * update x:  x:=x+dx
    9389             :          */
    9390           0 :         ae_v_add(&x->ptr.p_double[0], 1, &tmp.ptr.p_double[0], 1, ae_v_len(0,ncols-1));
    9391             :     }
    9392             :     
    9393             :     /*
    9394             :      * fill CX
    9395             :      */
    9396           0 :     if( rep->k>0 )
    9397             :     {
    9398           0 :         ae_matrix_set_length(&rep->cx, ncols, rep->k, _state);
    9399           0 :         for(i=0; i<=rep->k-1; i++)
    9400             :         {
    9401           0 :             ae_v_move(&rep->cx.ptr.pp_double[0][i], rep->cx.stride, &vt.ptr.pp_double[kernelidx+i][0], 1, ae_v_len(0,ncols-1));
    9402             :         }
    9403             :     }
    9404           0 :     ae_frame_leave(_state);
    9405             : }
    9406             : 
    9407             : 
    9408             : /*************************************************************************
    9409             : Internal LU solver
    9410             : 
    9411             :   -- ALGLIB --
    9412             :      Copyright 27.01.2010 by Bochkanov Sergey
    9413             : *************************************************************************/
    9414           0 : static void directdensesolvers_rmatrixlusolveinternal(/* Real    */ ae_matrix* lua,
    9415             :      /* Integer */ ae_vector* p,
    9416             :      ae_int_t n,
    9417             :      /* Real    */ ae_matrix* a,
    9418             :      ae_bool havea,
    9419             :      /* Real    */ ae_matrix* b,
    9420             :      ae_int_t m,
    9421             :      ae_int_t* info,
    9422             :      densesolverreport* rep,
    9423             :      /* Real    */ ae_matrix* x,
    9424             :      ae_state *_state)
    9425             : {
    9426             :     ae_frame _frame_block;
    9427             :     ae_int_t i;
    9428             :     ae_int_t j;
    9429             :     ae_int_t k;
    9430             :     ae_int_t rfs;
    9431             :     ae_int_t nrfs;
    9432             :     ae_vector xc;
    9433             :     ae_vector y;
    9434             :     ae_vector bc;
    9435             :     ae_vector xa;
    9436             :     ae_vector xb;
    9437             :     ae_vector tx;
    9438             :     double v;
    9439             :     double verr;
    9440             :     double mxb;
    9441             :     ae_bool smallerr;
    9442             :     ae_bool terminatenexttime;
    9443             : 
    9444           0 :     ae_frame_make(_state, &_frame_block);
    9445           0 :     memset(&xc, 0, sizeof(xc));
    9446           0 :     memset(&y, 0, sizeof(y));
    9447           0 :     memset(&bc, 0, sizeof(bc));
    9448           0 :     memset(&xa, 0, sizeof(xa));
    9449           0 :     memset(&xb, 0, sizeof(xb));
    9450           0 :     memset(&tx, 0, sizeof(tx));
    9451           0 :     *info = 0;
    9452           0 :     _densesolverreport_clear(rep);
    9453           0 :     ae_matrix_clear(x);
    9454           0 :     ae_vector_init(&xc, 0, DT_REAL, _state, ae_true);
    9455           0 :     ae_vector_init(&y, 0, DT_REAL, _state, ae_true);
    9456           0 :     ae_vector_init(&bc, 0, DT_REAL, _state, ae_true);
    9457           0 :     ae_vector_init(&xa, 0, DT_REAL, _state, ae_true);
    9458           0 :     ae_vector_init(&xb, 0, DT_REAL, _state, ae_true);
    9459           0 :     ae_vector_init(&tx, 0, DT_REAL, _state, ae_true);
    9460             : 
    9461             :     
    9462             :     /*
    9463             :      * prepare: check inputs, allocate space...
    9464             :      */
    9465           0 :     if( n<=0||m<=0 )
    9466             :     {
    9467           0 :         *info = -1;
    9468           0 :         ae_frame_leave(_state);
    9469           0 :         return;
    9470             :     }
    9471           0 :     for(i=0; i<=n-1; i++)
    9472             :     {
    9473           0 :         if( p->ptr.p_int[i]>n-1||p->ptr.p_int[i]<i )
    9474             :         {
    9475           0 :             *info = -1;
    9476           0 :             ae_frame_leave(_state);
    9477           0 :             return;
    9478             :         }
    9479             :     }
    9480           0 :     ae_matrix_set_length(x, n, m, _state);
    9481           0 :     ae_vector_set_length(&y, n, _state);
    9482           0 :     ae_vector_set_length(&xc, n, _state);
    9483           0 :     ae_vector_set_length(&bc, n, _state);
    9484           0 :     ae_vector_set_length(&tx, n+1, _state);
    9485           0 :     ae_vector_set_length(&xa, n+1, _state);
    9486           0 :     ae_vector_set_length(&xb, n+1, _state);
    9487             :     
    9488             :     /*
    9489             :      * estimate condition number, test for near singularity
    9490             :      */
    9491           0 :     rep->r1 = rmatrixlurcond1(lua, n, _state);
    9492           0 :     rep->rinf = rmatrixlurcondinf(lua, n, _state);
    9493           0 :     if( ae_fp_less(rep->r1,rcondthreshold(_state))||ae_fp_less(rep->rinf,rcondthreshold(_state)) )
    9494             :     {
    9495           0 :         for(i=0; i<=n-1; i++)
    9496             :         {
    9497           0 :             for(j=0; j<=m-1; j++)
    9498             :             {
    9499           0 :                 x->ptr.pp_double[i][j] = (double)(0);
    9500             :             }
    9501             :         }
    9502           0 :         rep->r1 = (double)(0);
    9503           0 :         rep->rinf = (double)(0);
    9504           0 :         *info = -3;
    9505           0 :         ae_frame_leave(_state);
    9506           0 :         return;
    9507             :     }
    9508           0 :     *info = 1;
    9509             :     
    9510             :     /*
    9511             :      * First stage of solution: rough solution with TRSM()
    9512             :      */
    9513           0 :     mxb = 0.0;
    9514           0 :     for(i=0; i<=n-1; i++)
    9515             :     {
    9516           0 :         for(j=0; j<=m-1; j++)
    9517             :         {
    9518           0 :             v = b->ptr.pp_double[i][j];
    9519           0 :             mxb = ae_maxreal(mxb, ae_fabs(v, _state), _state);
    9520           0 :             x->ptr.pp_double[i][j] = v;
    9521             :         }
    9522             :     }
    9523           0 :     for(i=0; i<=n-1; i++)
    9524             :     {
    9525           0 :         if( p->ptr.p_int[i]!=i )
    9526             :         {
    9527           0 :             for(j=0; j<=m-1; j++)
    9528             :             {
    9529           0 :                 v = x->ptr.pp_double[i][j];
    9530           0 :                 x->ptr.pp_double[i][j] = x->ptr.pp_double[p->ptr.p_int[i]][j];
    9531           0 :                 x->ptr.pp_double[p->ptr.p_int[i]][j] = v;
    9532             :             }
    9533             :         }
    9534             :     }
    9535           0 :     rmatrixlefttrsm(n, m, lua, 0, 0, ae_false, ae_true, 0, x, 0, 0, _state);
    9536           0 :     rmatrixlefttrsm(n, m, lua, 0, 0, ae_true, ae_false, 0, x, 0, 0, _state);
    9537             :     
    9538             :     /*
    9539             :      * Second stage: iterative refinement
    9540             :      */
    9541           0 :     if( havea )
    9542             :     {
    9543           0 :         for(k=0; k<=m-1; k++)
    9544             :         {
    9545           0 :             nrfs = directdensesolvers_densesolverrfsmax(n, rep->r1, rep->rinf, _state);
    9546           0 :             terminatenexttime = ae_false;
    9547           0 :             for(rfs=0; rfs<=nrfs-1; rfs++)
    9548             :             {
    9549           0 :                 if( terminatenexttime )
    9550             :                 {
    9551           0 :                     break;
    9552             :                 }
    9553             :                 
    9554             :                 /*
    9555             :                  * generate right part
    9556             :                  */
    9557           0 :                 smallerr = ae_true;
    9558           0 :                 ae_v_move(&xb.ptr.p_double[0], 1, &x->ptr.pp_double[0][k], x->stride, ae_v_len(0,n-1));
    9559           0 :                 for(i=0; i<=n-1; i++)
    9560             :                 {
    9561           0 :                     ae_v_move(&xa.ptr.p_double[0], 1, &a->ptr.pp_double[i][0], 1, ae_v_len(0,n-1));
    9562           0 :                     xa.ptr.p_double[n] = (double)(-1);
    9563           0 :                     xb.ptr.p_double[n] = b->ptr.pp_double[i][k];
    9564           0 :                     xdot(&xa, &xb, n+1, &tx, &v, &verr, _state);
    9565           0 :                     y.ptr.p_double[i] = -v;
    9566           0 :                     smallerr = smallerr&&ae_fp_less(ae_fabs(v, _state),4*verr);
    9567             :                 }
    9568           0 :                 if( smallerr )
    9569             :                 {
    9570           0 :                     terminatenexttime = ae_true;
    9571             :                 }
    9572             :                 
    9573             :                 /*
    9574             :                  * solve and update
    9575             :                  */
    9576           0 :                 directdensesolvers_rbasiclusolve(lua, p, n, &y, _state);
    9577           0 :                 ae_v_add(&x->ptr.pp_double[0][k], x->stride, &y.ptr.p_double[0], 1, ae_v_len(0,n-1));
    9578             :             }
    9579             :         }
    9580             :     }
    9581           0 :     ae_frame_leave(_state);
    9582             : }
    9583             : 
    9584             : 
    9585             : /*************************************************************************
    9586             : Internal Cholesky solver
    9587             : 
    9588             :   -- ALGLIB --
    9589             :      Copyright 27.01.2010 by Bochkanov Sergey
    9590             : *************************************************************************/
    9591           0 : static void directdensesolvers_spdmatrixcholeskysolveinternal(/* Real    */ ae_matrix* cha,
    9592             :      ae_int_t n,
    9593             :      ae_bool isupper,
    9594             :      /* Real    */ ae_matrix* a,
    9595             :      ae_bool havea,
    9596             :      /* Real    */ ae_matrix* b,
    9597             :      ae_int_t m,
    9598             :      ae_int_t* info,
    9599             :      densesolverreport* rep,
    9600             :      /* Real    */ ae_matrix* x,
    9601             :      ae_state *_state)
    9602             : {
    9603             :     ae_int_t i;
    9604             :     ae_int_t j;
    9605             : 
    9606           0 :     *info = 0;
    9607           0 :     _densesolverreport_clear(rep);
    9608           0 :     ae_matrix_clear(x);
    9609             : 
    9610             :     
    9611             :     /*
    9612             :      * prepare: check inputs, allocate space...
    9613             :      */
    9614           0 :     if( n<=0||m<=0 )
    9615             :     {
    9616           0 :         *info = -1;
    9617           0 :         return;
    9618             :     }
    9619           0 :     ae_matrix_set_length(x, n, m, _state);
    9620             :     
    9621             :     /*
    9622             :      * estimate condition number, test for near singularity
    9623             :      */
    9624           0 :     rep->r1 = spdmatrixcholeskyrcond(cha, n, isupper, _state);
    9625           0 :     rep->rinf = rep->r1;
    9626           0 :     if( ae_fp_less(rep->r1,rcondthreshold(_state)) )
    9627             :     {
    9628           0 :         for(i=0; i<=n-1; i++)
    9629             :         {
    9630           0 :             for(j=0; j<=m-1; j++)
    9631             :             {
    9632           0 :                 x->ptr.pp_double[i][j] = (double)(0);
    9633             :             }
    9634             :         }
    9635           0 :         rep->r1 = (double)(0);
    9636           0 :         rep->rinf = (double)(0);
    9637           0 :         *info = -3;
    9638           0 :         return;
    9639             :     }
    9640           0 :     *info = 1;
    9641             :     
    9642             :     /*
    9643             :      * Solve with TRSM()
    9644             :      */
    9645           0 :     for(i=0; i<=n-1; i++)
    9646             :     {
    9647           0 :         for(j=0; j<=m-1; j++)
    9648             :         {
    9649           0 :             x->ptr.pp_double[i][j] = b->ptr.pp_double[i][j];
    9650             :         }
    9651             :     }
    9652           0 :     if( isupper )
    9653             :     {
    9654           0 :         rmatrixlefttrsm(n, m, cha, 0, 0, ae_true, ae_false, 1, x, 0, 0, _state);
    9655           0 :         rmatrixlefttrsm(n, m, cha, 0, 0, ae_true, ae_false, 0, x, 0, 0, _state);
    9656             :     }
    9657             :     else
    9658             :     {
    9659           0 :         rmatrixlefttrsm(n, m, cha, 0, 0, ae_false, ae_false, 0, x, 0, 0, _state);
    9660           0 :         rmatrixlefttrsm(n, m, cha, 0, 0, ae_false, ae_false, 1, x, 0, 0, _state);
    9661             :     }
    9662             : }
    9663             : 
    9664             : 
    9665             : /*************************************************************************
    9666             : Internal LU solver
    9667             : 
    9668             :   -- ALGLIB --
    9669             :      Copyright 27.01.2010 by Bochkanov Sergey
    9670             : *************************************************************************/
    9671           0 : static void directdensesolvers_cmatrixlusolveinternal(/* Complex */ ae_matrix* lua,
    9672             :      /* Integer */ ae_vector* p,
    9673             :      ae_int_t n,
    9674             :      /* Complex */ ae_matrix* a,
    9675             :      ae_bool havea,
    9676             :      /* Complex */ ae_matrix* b,
    9677             :      ae_int_t m,
    9678             :      ae_int_t* info,
    9679             :      densesolverreport* rep,
    9680             :      /* Complex */ ae_matrix* x,
    9681             :      ae_state *_state)
    9682             : {
    9683             :     ae_frame _frame_block;
    9684             :     ae_int_t i;
    9685             :     ae_int_t j;
    9686             :     ae_int_t k;
    9687             :     ae_int_t rfs;
    9688             :     ae_int_t nrfs;
    9689             :     ae_vector xc;
    9690             :     ae_vector y;
    9691             :     ae_vector bc;
    9692             :     ae_vector xa;
    9693             :     ae_vector xb;
    9694             :     ae_vector tx;
    9695             :     ae_vector tmpbuf;
    9696             :     ae_complex v;
    9697             :     double verr;
    9698             :     ae_bool smallerr;
    9699             :     ae_bool terminatenexttime;
    9700             : 
    9701           0 :     ae_frame_make(_state, &_frame_block);
    9702           0 :     memset(&xc, 0, sizeof(xc));
    9703           0 :     memset(&y, 0, sizeof(y));
    9704           0 :     memset(&bc, 0, sizeof(bc));
    9705           0 :     memset(&xa, 0, sizeof(xa));
    9706           0 :     memset(&xb, 0, sizeof(xb));
    9707           0 :     memset(&tx, 0, sizeof(tx));
    9708           0 :     memset(&tmpbuf, 0, sizeof(tmpbuf));
    9709           0 :     *info = 0;
    9710           0 :     _densesolverreport_clear(rep);
    9711           0 :     ae_matrix_clear(x);
    9712           0 :     ae_vector_init(&xc, 0, DT_COMPLEX, _state, ae_true);
    9713           0 :     ae_vector_init(&y, 0, DT_COMPLEX, _state, ae_true);
    9714           0 :     ae_vector_init(&bc, 0, DT_COMPLEX, _state, ae_true);
    9715           0 :     ae_vector_init(&xa, 0, DT_COMPLEX, _state, ae_true);
    9716           0 :     ae_vector_init(&xb, 0, DT_COMPLEX, _state, ae_true);
    9717           0 :     ae_vector_init(&tx, 0, DT_COMPLEX, _state, ae_true);
    9718           0 :     ae_vector_init(&tmpbuf, 0, DT_REAL, _state, ae_true);
    9719             : 
    9720             :     
    9721             :     /*
    9722             :      * prepare: check inputs, allocate space...
    9723             :      */
    9724           0 :     if( n<=0||m<=0 )
    9725             :     {
    9726           0 :         *info = -1;
    9727           0 :         ae_frame_leave(_state);
    9728           0 :         return;
    9729             :     }
    9730           0 :     for(i=0; i<=n-1; i++)
    9731             :     {
    9732           0 :         if( p->ptr.p_int[i]>n-1||p->ptr.p_int[i]<i )
    9733             :         {
    9734           0 :             *info = -1;
    9735           0 :             ae_frame_leave(_state);
    9736           0 :             return;
    9737             :         }
    9738             :     }
    9739           0 :     ae_matrix_set_length(x, n, m, _state);
    9740           0 :     ae_vector_set_length(&y, n, _state);
    9741           0 :     ae_vector_set_length(&xc, n, _state);
    9742           0 :     ae_vector_set_length(&bc, n, _state);
    9743           0 :     ae_vector_set_length(&tx, n, _state);
    9744           0 :     ae_vector_set_length(&xa, n+1, _state);
    9745           0 :     ae_vector_set_length(&xb, n+1, _state);
    9746           0 :     ae_vector_set_length(&tmpbuf, 2*n+2, _state);
    9747             :     
    9748             :     /*
    9749             :      * estimate condition number, test for near singularity
    9750             :      */
    9751           0 :     rep->r1 = cmatrixlurcond1(lua, n, _state);
    9752           0 :     rep->rinf = cmatrixlurcondinf(lua, n, _state);
    9753           0 :     if( ae_fp_less(rep->r1,rcondthreshold(_state))||ae_fp_less(rep->rinf,rcondthreshold(_state)) )
    9754             :     {
    9755           0 :         for(i=0; i<=n-1; i++)
    9756             :         {
    9757           0 :             for(j=0; j<=m-1; j++)
    9758             :             {
    9759           0 :                 x->ptr.pp_complex[i][j] = ae_complex_from_i(0);
    9760             :             }
    9761             :         }
    9762           0 :         rep->r1 = (double)(0);
    9763           0 :         rep->rinf = (double)(0);
    9764           0 :         *info = -3;
    9765           0 :         ae_frame_leave(_state);
    9766           0 :         return;
    9767             :     }
    9768           0 :     *info = 1;
    9769             :     
    9770             :     /*
    9771             :      * First phase: solve with TRSM()
    9772             :      */
    9773           0 :     for(i=0; i<=n-1; i++)
    9774             :     {
    9775           0 :         for(j=0; j<=m-1; j++)
    9776             :         {
    9777           0 :             x->ptr.pp_complex[i][j] = b->ptr.pp_complex[i][j];
    9778             :         }
    9779             :     }
    9780           0 :     for(i=0; i<=n-1; i++)
    9781             :     {
    9782           0 :         if( p->ptr.p_int[i]!=i )
    9783             :         {
    9784           0 :             for(j=0; j<=m-1; j++)
    9785             :             {
    9786           0 :                 v = x->ptr.pp_complex[i][j];
    9787           0 :                 x->ptr.pp_complex[i][j] = x->ptr.pp_complex[p->ptr.p_int[i]][j];
    9788           0 :                 x->ptr.pp_complex[p->ptr.p_int[i]][j] = v;
    9789             :             }
    9790             :         }
    9791             :     }
    9792           0 :     cmatrixlefttrsm(n, m, lua, 0, 0, ae_false, ae_true, 0, x, 0, 0, _state);
    9793           0 :     cmatrixlefttrsm(n, m, lua, 0, 0, ae_true, ae_false, 0, x, 0, 0, _state);
    9794             :     
    9795             :     /*
    9796             :      * solve
    9797             :      */
    9798           0 :     for(k=0; k<=m-1; k++)
    9799             :     {
    9800           0 :         ae_v_cmove(&bc.ptr.p_complex[0], 1, &b->ptr.pp_complex[0][k], b->stride, "N", ae_v_len(0,n-1));
    9801           0 :         ae_v_cmove(&xc.ptr.p_complex[0], 1, &x->ptr.pp_complex[0][k], x->stride, "N", ae_v_len(0,n-1));
    9802             :         
    9803             :         /*
    9804             :          * Iterative refinement of xc:
    9805             :          * * calculate r = bc-A*xc using extra-precise dot product
    9806             :          * * solve A*y = r
    9807             :          * * update x:=x+r
    9808             :          *
    9809             :          * This cycle is executed until one of two things happens:
    9810             :          * 1. maximum number of iterations reached
    9811             :          * 2. last iteration decreased error to the lower limit
    9812             :          */
    9813           0 :         if( havea )
    9814             :         {
    9815           0 :             nrfs = directdensesolvers_densesolverrfsmax(n, rep->r1, rep->rinf, _state);
    9816           0 :             terminatenexttime = ae_false;
    9817           0 :             for(rfs=0; rfs<=nrfs-1; rfs++)
    9818             :             {
    9819           0 :                 if( terminatenexttime )
    9820             :                 {
    9821           0 :                     break;
    9822             :                 }
    9823             :                 
    9824             :                 /*
    9825             :                  * generate right part
    9826             :                  */
    9827           0 :                 smallerr = ae_true;
    9828           0 :                 ae_v_cmove(&xb.ptr.p_complex[0], 1, &xc.ptr.p_complex[0], 1, "N", ae_v_len(0,n-1));
    9829           0 :                 for(i=0; i<=n-1; i++)
    9830             :                 {
    9831           0 :                     ae_v_cmove(&xa.ptr.p_complex[0], 1, &a->ptr.pp_complex[i][0], 1, "N", ae_v_len(0,n-1));
    9832           0 :                     xa.ptr.p_complex[n] = ae_complex_from_i(-1);
    9833           0 :                     xb.ptr.p_complex[n] = bc.ptr.p_complex[i];
    9834           0 :                     xcdot(&xa, &xb, n+1, &tmpbuf, &v, &verr, _state);
    9835           0 :                     y.ptr.p_complex[i] = ae_c_neg(v);
    9836           0 :                     smallerr = smallerr&&ae_fp_less(ae_c_abs(v, _state),4*verr);
    9837             :                 }
    9838           0 :                 if( smallerr )
    9839             :                 {
    9840           0 :                     terminatenexttime = ae_true;
    9841             :                 }
    9842             :                 
    9843             :                 /*
    9844             :                  * solve and update
    9845             :                  */
    9846           0 :                 directdensesolvers_cbasiclusolve(lua, p, n, &y, _state);
    9847           0 :                 ae_v_cadd(&xc.ptr.p_complex[0], 1, &y.ptr.p_complex[0], 1, "N", ae_v_len(0,n-1));
    9848             :             }
    9849             :         }
    9850             :         
    9851             :         /*
    9852             :          * Store xc.
    9853             :          * Post-scale result.
    9854             :          */
    9855           0 :         ae_v_cmove(&x->ptr.pp_complex[0][k], x->stride, &xc.ptr.p_complex[0], 1, "N", ae_v_len(0,n-1));
    9856             :     }
    9857           0 :     ae_frame_leave(_state);
    9858             : }
    9859             : 
    9860             : 
    9861             : /*************************************************************************
    9862             : Internal Cholesky solver
    9863             : 
    9864             :   -- ALGLIB --
    9865             :      Copyright 27.01.2010 by Bochkanov Sergey
    9866             : *************************************************************************/
    9867           0 : static void directdensesolvers_hpdmatrixcholeskysolveinternal(/* Complex */ ae_matrix* cha,
    9868             :      ae_int_t n,
    9869             :      ae_bool isupper,
    9870             :      /* Complex */ ae_matrix* a,
    9871             :      ae_bool havea,
    9872             :      /* Complex */ ae_matrix* b,
    9873             :      ae_int_t m,
    9874             :      ae_int_t* info,
    9875             :      densesolverreport* rep,
    9876             :      /* Complex */ ae_matrix* x,
    9877             :      ae_state *_state)
    9878             : {
    9879             :     ae_frame _frame_block;
    9880             :     ae_int_t i;
    9881             :     ae_int_t j;
    9882             :     ae_vector xc;
    9883             :     ae_vector y;
    9884             :     ae_vector bc;
    9885             :     ae_vector xa;
    9886             :     ae_vector xb;
    9887             :     ae_vector tx;
    9888             : 
    9889           0 :     ae_frame_make(_state, &_frame_block);
    9890           0 :     memset(&xc, 0, sizeof(xc));
    9891           0 :     memset(&y, 0, sizeof(y));
    9892           0 :     memset(&bc, 0, sizeof(bc));
    9893           0 :     memset(&xa, 0, sizeof(xa));
    9894           0 :     memset(&xb, 0, sizeof(xb));
    9895           0 :     memset(&tx, 0, sizeof(tx));
    9896           0 :     *info = 0;
    9897           0 :     _densesolverreport_clear(rep);
    9898           0 :     ae_matrix_clear(x);
    9899           0 :     ae_vector_init(&xc, 0, DT_COMPLEX, _state, ae_true);
    9900           0 :     ae_vector_init(&y, 0, DT_COMPLEX, _state, ae_true);
    9901           0 :     ae_vector_init(&bc, 0, DT_COMPLEX, _state, ae_true);
    9902           0 :     ae_vector_init(&xa, 0, DT_COMPLEX, _state, ae_true);
    9903           0 :     ae_vector_init(&xb, 0, DT_COMPLEX, _state, ae_true);
    9904           0 :     ae_vector_init(&tx, 0, DT_COMPLEX, _state, ae_true);
    9905             : 
    9906             :     
    9907             :     /*
    9908             :      * prepare: check inputs, allocate space...
    9909             :      */
    9910           0 :     if( n<=0||m<=0 )
    9911             :     {
    9912           0 :         *info = -1;
    9913           0 :         ae_frame_leave(_state);
    9914           0 :         return;
    9915             :     }
    9916           0 :     ae_matrix_set_length(x, n, m, _state);
    9917           0 :     ae_vector_set_length(&y, n, _state);
    9918           0 :     ae_vector_set_length(&xc, n, _state);
    9919           0 :     ae_vector_set_length(&bc, n, _state);
    9920           0 :     ae_vector_set_length(&tx, n+1, _state);
    9921           0 :     ae_vector_set_length(&xa, n+1, _state);
    9922           0 :     ae_vector_set_length(&xb, n+1, _state);
    9923             :     
    9924             :     /*
    9925             :      * estimate condition number, test for near singularity
    9926             :      */
    9927           0 :     rep->r1 = hpdmatrixcholeskyrcond(cha, n, isupper, _state);
    9928           0 :     rep->rinf = rep->r1;
    9929           0 :     if( ae_fp_less(rep->r1,rcondthreshold(_state)) )
    9930             :     {
    9931           0 :         for(i=0; i<=n-1; i++)
    9932             :         {
    9933           0 :             for(j=0; j<=m-1; j++)
    9934             :             {
    9935           0 :                 x->ptr.pp_complex[i][j] = ae_complex_from_i(0);
    9936             :             }
    9937             :         }
    9938           0 :         rep->r1 = (double)(0);
    9939           0 :         rep->rinf = (double)(0);
    9940           0 :         *info = -3;
    9941           0 :         ae_frame_leave(_state);
    9942           0 :         return;
    9943             :     }
    9944           0 :     *info = 1;
    9945             :     
    9946             :     /*
    9947             :      * solve
    9948             :      */
    9949           0 :     for(i=0; i<=n-1; i++)
    9950             :     {
    9951           0 :         for(j=0; j<=m-1; j++)
    9952             :         {
    9953           0 :             x->ptr.pp_complex[i][j] = b->ptr.pp_complex[i][j];
    9954             :         }
    9955             :     }
    9956           0 :     if( isupper )
    9957             :     {
    9958           0 :         cmatrixlefttrsm(n, m, cha, 0, 0, ae_true, ae_false, 2, x, 0, 0, _state);
    9959           0 :         cmatrixlefttrsm(n, m, cha, 0, 0, ae_true, ae_false, 0, x, 0, 0, _state);
    9960             :     }
    9961             :     else
    9962             :     {
    9963           0 :         cmatrixlefttrsm(n, m, cha, 0, 0, ae_false, ae_false, 0, x, 0, 0, _state);
    9964           0 :         cmatrixlefttrsm(n, m, cha, 0, 0, ae_false, ae_false, 2, x, 0, 0, _state);
    9965             :     }
    9966           0 :     ae_frame_leave(_state);
    9967             : }
    9968             : 
    9969             : 
    9970             : /*************************************************************************
    9971             : Internal subroutine.
    9972             : Returns maximum count of RFS iterations as function of:
    9973             : 1. machine epsilon
    9974             : 2. task size.
    9975             : 3. condition number
    9976             : 
    9977             :   -- ALGLIB --
    9978             :      Copyright 27.01.2010 by Bochkanov Sergey
    9979             : *************************************************************************/
    9980           0 : static ae_int_t directdensesolvers_densesolverrfsmax(ae_int_t n,
    9981             :      double r1,
    9982             :      double rinf,
    9983             :      ae_state *_state)
    9984             : {
    9985             :     ae_int_t result;
    9986             : 
    9987             : 
    9988           0 :     result = 5;
    9989           0 :     return result;
    9990             : }
    9991             : 
    9992             : 
    9993             : /*************************************************************************
    9994             : Internal subroutine.
    9995             : Returns maximum count of RFS iterations as function of:
    9996             : 1. machine epsilon
    9997             : 2. task size.
    9998             : 3. norm-2 condition number
    9999             : 
   10000             :   -- ALGLIB --
   10001             :      Copyright 27.01.2010 by Bochkanov Sergey
   10002             : *************************************************************************/
   10003           0 : static ae_int_t directdensesolvers_densesolverrfsmaxv2(ae_int_t n,
   10004             :      double r2,
   10005             :      ae_state *_state)
   10006             : {
   10007             :     ae_int_t result;
   10008             : 
   10009             : 
   10010           0 :     result = directdensesolvers_densesolverrfsmax(n, (double)(0), (double)(0), _state);
   10011           0 :     return result;
   10012             : }
   10013             : 
   10014             : 
   10015             : /*************************************************************************
   10016             : Basic LU solver for PLU*x = y.
   10017             : 
   10018             : This subroutine assumes that:
   10019             : * A=PLU is well-conditioned, so no zero divisions or overflow may occur
   10020             : 
   10021             :   -- ALGLIB --
   10022             :      Copyright 27.01.2010 by Bochkanov Sergey
   10023             : *************************************************************************/
   10024           0 : static void directdensesolvers_rbasiclusolve(/* Real    */ ae_matrix* lua,
   10025             :      /* Integer */ ae_vector* p,
   10026             :      ae_int_t n,
   10027             :      /* Real    */ ae_vector* xb,
   10028             :      ae_state *_state)
   10029             : {
   10030             :     ae_int_t i;
   10031             :     double v;
   10032             : 
   10033             : 
   10034           0 :     for(i=0; i<=n-1; i++)
   10035             :     {
   10036           0 :         if( p->ptr.p_int[i]!=i )
   10037             :         {
   10038           0 :             v = xb->ptr.p_double[i];
   10039           0 :             xb->ptr.p_double[i] = xb->ptr.p_double[p->ptr.p_int[i]];
   10040           0 :             xb->ptr.p_double[p->ptr.p_int[i]] = v;
   10041             :         }
   10042             :     }
   10043           0 :     for(i=1; i<=n-1; i++)
   10044             :     {
   10045           0 :         v = ae_v_dotproduct(&lua->ptr.pp_double[i][0], 1, &xb->ptr.p_double[0], 1, ae_v_len(0,i-1));
   10046           0 :         xb->ptr.p_double[i] = xb->ptr.p_double[i]-v;
   10047             :     }
   10048           0 :     xb->ptr.p_double[n-1] = xb->ptr.p_double[n-1]/lua->ptr.pp_double[n-1][n-1];
   10049           0 :     for(i=n-2; i>=0; i--)
   10050             :     {
   10051           0 :         v = ae_v_dotproduct(&lua->ptr.pp_double[i][i+1], 1, &xb->ptr.p_double[i+1], 1, ae_v_len(i+1,n-1));
   10052           0 :         xb->ptr.p_double[i] = (xb->ptr.p_double[i]-v)/lua->ptr.pp_double[i][i];
   10053             :     }
   10054           0 : }
   10055             : 
   10056             : 
   10057             : /*************************************************************************
   10058             : Basic Cholesky solver for ScaleA*Cholesky(A)'*x = y.
   10059             : 
   10060             : This subroutine assumes that:
   10061             : * A*ScaleA is well scaled
   10062             : * A is well-conditioned, so no zero divisions or overflow may occur
   10063             : 
   10064             :   -- ALGLIB --
   10065             :      Copyright 27.01.2010 by Bochkanov Sergey
   10066             : *************************************************************************/
   10067           0 : static void directdensesolvers_spdbasiccholeskysolve(/* Real    */ ae_matrix* cha,
   10068             :      ae_int_t n,
   10069             :      ae_bool isupper,
   10070             :      /* Real    */ ae_vector* xb,
   10071             :      ae_state *_state)
   10072             : {
   10073             :     ae_int_t i;
   10074             :     double v;
   10075             : 
   10076             : 
   10077             :     
   10078             :     /*
   10079             :      * A = L*L' or A=U'*U
   10080             :      */
   10081           0 :     if( isupper )
   10082             :     {
   10083             :         
   10084             :         /*
   10085             :          * Solve U'*y=b first.
   10086             :          */
   10087           0 :         for(i=0; i<=n-1; i++)
   10088             :         {
   10089           0 :             xb->ptr.p_double[i] = xb->ptr.p_double[i]/cha->ptr.pp_double[i][i];
   10090           0 :             if( i<n-1 )
   10091             :             {
   10092           0 :                 v = xb->ptr.p_double[i];
   10093           0 :                 ae_v_subd(&xb->ptr.p_double[i+1], 1, &cha->ptr.pp_double[i][i+1], 1, ae_v_len(i+1,n-1), v);
   10094             :             }
   10095             :         }
   10096             :         
   10097             :         /*
   10098             :          * Solve U*x=y then.
   10099             :          */
   10100           0 :         for(i=n-1; i>=0; i--)
   10101             :         {
   10102           0 :             if( i<n-1 )
   10103             :             {
   10104           0 :                 v = ae_v_dotproduct(&cha->ptr.pp_double[i][i+1], 1, &xb->ptr.p_double[i+1], 1, ae_v_len(i+1,n-1));
   10105           0 :                 xb->ptr.p_double[i] = xb->ptr.p_double[i]-v;
   10106             :             }
   10107           0 :             xb->ptr.p_double[i] = xb->ptr.p_double[i]/cha->ptr.pp_double[i][i];
   10108             :         }
   10109             :     }
   10110             :     else
   10111             :     {
   10112             :         
   10113             :         /*
   10114             :          * Solve L*y=b first
   10115             :          */
   10116           0 :         for(i=0; i<=n-1; i++)
   10117             :         {
   10118           0 :             if( i>0 )
   10119             :             {
   10120           0 :                 v = ae_v_dotproduct(&cha->ptr.pp_double[i][0], 1, &xb->ptr.p_double[0], 1, ae_v_len(0,i-1));
   10121           0 :                 xb->ptr.p_double[i] = xb->ptr.p_double[i]-v;
   10122             :             }
   10123           0 :             xb->ptr.p_double[i] = xb->ptr.p_double[i]/cha->ptr.pp_double[i][i];
   10124             :         }
   10125             :         
   10126             :         /*
   10127             :          * Solve L'*x=y then.
   10128             :          */
   10129           0 :         for(i=n-1; i>=0; i--)
   10130             :         {
   10131           0 :             xb->ptr.p_double[i] = xb->ptr.p_double[i]/cha->ptr.pp_double[i][i];
   10132           0 :             if( i>0 )
   10133             :             {
   10134           0 :                 v = xb->ptr.p_double[i];
   10135           0 :                 ae_v_subd(&xb->ptr.p_double[0], 1, &cha->ptr.pp_double[i][0], 1, ae_v_len(0,i-1), v);
   10136             :             }
   10137             :         }
   10138             :     }
   10139           0 : }
   10140             : 
   10141             : 
   10142             : /*************************************************************************
   10143             : Basic LU solver for ScaleA*PLU*x = y.
   10144             : 
   10145             : This subroutine assumes that:
   10146             : * L is well-scaled, and it is U which needs scaling by ScaleA.
   10147             : * A=PLU is well-conditioned, so no zero divisions or overflow may occur
   10148             : 
   10149             :   -- ALGLIB --
   10150             :      Copyright 27.01.2010 by Bochkanov Sergey
   10151             : *************************************************************************/
   10152           0 : static void directdensesolvers_cbasiclusolve(/* Complex */ ae_matrix* lua,
   10153             :      /* Integer */ ae_vector* p,
   10154             :      ae_int_t n,
   10155             :      /* Complex */ ae_vector* xb,
   10156             :      ae_state *_state)
   10157             : {
   10158             :     ae_int_t i;
   10159             :     ae_complex v;
   10160             : 
   10161             : 
   10162           0 :     for(i=0; i<=n-1; i++)
   10163             :     {
   10164           0 :         if( p->ptr.p_int[i]!=i )
   10165             :         {
   10166           0 :             v = xb->ptr.p_complex[i];
   10167           0 :             xb->ptr.p_complex[i] = xb->ptr.p_complex[p->ptr.p_int[i]];
   10168           0 :             xb->ptr.p_complex[p->ptr.p_int[i]] = v;
   10169             :         }
   10170             :     }
   10171           0 :     for(i=1; i<=n-1; i++)
   10172             :     {
   10173           0 :         v = ae_v_cdotproduct(&lua->ptr.pp_complex[i][0], 1, "N", &xb->ptr.p_complex[0], 1, "N", ae_v_len(0,i-1));
   10174           0 :         xb->ptr.p_complex[i] = ae_c_sub(xb->ptr.p_complex[i],v);
   10175             :     }
   10176           0 :     xb->ptr.p_complex[n-1] = ae_c_div(xb->ptr.p_complex[n-1],lua->ptr.pp_complex[n-1][n-1]);
   10177           0 :     for(i=n-2; i>=0; i--)
   10178             :     {
   10179           0 :         v = ae_v_cdotproduct(&lua->ptr.pp_complex[i][i+1], 1, "N", &xb->ptr.p_complex[i+1], 1, "N", ae_v_len(i+1,n-1));
   10180           0 :         xb->ptr.p_complex[i] = ae_c_div(ae_c_sub(xb->ptr.p_complex[i],v),lua->ptr.pp_complex[i][i]);
   10181             :     }
   10182           0 : }
   10183             : 
   10184             : 
   10185             : /*************************************************************************
   10186             : Basic Cholesky solver for ScaleA*Cholesky(A)'*x = y.
   10187             : 
   10188             : This subroutine assumes that:
   10189             : * A*ScaleA is well scaled
   10190             : * A is well-conditioned, so no zero divisions or overflow may occur
   10191             : 
   10192             :   -- ALGLIB --
   10193             :      Copyright 27.01.2010 by Bochkanov Sergey
   10194             : *************************************************************************/
   10195           0 : static void directdensesolvers_hpdbasiccholeskysolve(/* Complex */ ae_matrix* cha,
   10196             :      ae_int_t n,
   10197             :      ae_bool isupper,
   10198             :      /* Complex */ ae_vector* xb,
   10199             :      ae_state *_state)
   10200             : {
   10201             :     ae_int_t i;
   10202             :     ae_complex v;
   10203             : 
   10204             : 
   10205             :     
   10206             :     /*
   10207             :      * A = L*L' or A=U'*U
   10208             :      */
   10209           0 :     if( isupper )
   10210             :     {
   10211             :         
   10212             :         /*
   10213             :          * Solve U'*y=b first.
   10214             :          */
   10215           0 :         for(i=0; i<=n-1; i++)
   10216             :         {
   10217           0 :             xb->ptr.p_complex[i] = ae_c_div(xb->ptr.p_complex[i],ae_c_conj(cha->ptr.pp_complex[i][i], _state));
   10218           0 :             if( i<n-1 )
   10219             :             {
   10220           0 :                 v = xb->ptr.p_complex[i];
   10221           0 :                 ae_v_csubc(&xb->ptr.p_complex[i+1], 1, &cha->ptr.pp_complex[i][i+1], 1, "Conj", ae_v_len(i+1,n-1), v);
   10222             :             }
   10223             :         }
   10224             :         
   10225             :         /*
   10226             :          * Solve U*x=y then.
   10227             :          */
   10228           0 :         for(i=n-1; i>=0; i--)
   10229             :         {
   10230           0 :             if( i<n-1 )
   10231             :             {
   10232           0 :                 v = ae_v_cdotproduct(&cha->ptr.pp_complex[i][i+1], 1, "N", &xb->ptr.p_complex[i+1], 1, "N", ae_v_len(i+1,n-1));
   10233           0 :                 xb->ptr.p_complex[i] = ae_c_sub(xb->ptr.p_complex[i],v);
   10234             :             }
   10235           0 :             xb->ptr.p_complex[i] = ae_c_div(xb->ptr.p_complex[i],cha->ptr.pp_complex[i][i]);
   10236             :         }
   10237             :     }
   10238             :     else
   10239             :     {
   10240             :         
   10241             :         /*
   10242             :          * Solve L*y=b first
   10243             :          */
   10244           0 :         for(i=0; i<=n-1; i++)
   10245             :         {
   10246           0 :             if( i>0 )
   10247             :             {
   10248           0 :                 v = ae_v_cdotproduct(&cha->ptr.pp_complex[i][0], 1, "N", &xb->ptr.p_complex[0], 1, "N", ae_v_len(0,i-1));
   10249           0 :                 xb->ptr.p_complex[i] = ae_c_sub(xb->ptr.p_complex[i],v);
   10250             :             }
   10251           0 :             xb->ptr.p_complex[i] = ae_c_div(xb->ptr.p_complex[i],cha->ptr.pp_complex[i][i]);
   10252             :         }
   10253             :         
   10254             :         /*
   10255             :          * Solve L'*x=y then.
   10256             :          */
   10257           0 :         for(i=n-1; i>=0; i--)
   10258             :         {
   10259           0 :             xb->ptr.p_complex[i] = ae_c_div(xb->ptr.p_complex[i],ae_c_conj(cha->ptr.pp_complex[i][i], _state));
   10260           0 :             if( i>0 )
   10261             :             {
   10262           0 :                 v = xb->ptr.p_complex[i];
   10263           0 :                 ae_v_csubc(&xb->ptr.p_complex[0], 1, &cha->ptr.pp_complex[i][0], 1, "Conj", ae_v_len(0,i-1), v);
   10264             :             }
   10265             :         }
   10266             :     }
   10267           0 : }
   10268             : 
   10269             : 
   10270           0 : void _densesolverreport_init(void* _p, ae_state *_state, ae_bool make_automatic)
   10271             : {
   10272           0 :     densesolverreport *p = (densesolverreport*)_p;
   10273           0 :     ae_touch_ptr((void*)p);
   10274           0 : }
   10275             : 
   10276             : 
   10277           0 : void _densesolverreport_init_copy(void* _dst, void* _src, ae_state *_state, ae_bool make_automatic)
   10278             : {
   10279           0 :     densesolverreport *dst = (densesolverreport*)_dst;
   10280           0 :     densesolverreport *src = (densesolverreport*)_src;
   10281           0 :     dst->r1 = src->r1;
   10282           0 :     dst->rinf = src->rinf;
   10283           0 : }
   10284             : 
   10285             : 
   10286           0 : void _densesolverreport_clear(void* _p)
   10287             : {
   10288           0 :     densesolverreport *p = (densesolverreport*)_p;
   10289           0 :     ae_touch_ptr((void*)p);
   10290           0 : }
   10291             : 
   10292             : 
   10293           0 : void _densesolverreport_destroy(void* _p)
   10294             : {
   10295           0 :     densesolverreport *p = (densesolverreport*)_p;
   10296           0 :     ae_touch_ptr((void*)p);
   10297           0 : }
   10298             : 
   10299             : 
   10300           0 : void _densesolverlsreport_init(void* _p, ae_state *_state, ae_bool make_automatic)
   10301             : {
   10302           0 :     densesolverlsreport *p = (densesolverlsreport*)_p;
   10303           0 :     ae_touch_ptr((void*)p);
   10304           0 :     ae_matrix_init(&p->cx, 0, 0, DT_REAL, _state, make_automatic);
   10305           0 : }
   10306             : 
   10307             : 
   10308           0 : void _densesolverlsreport_init_copy(void* _dst, void* _src, ae_state *_state, ae_bool make_automatic)
   10309             : {
   10310           0 :     densesolverlsreport *dst = (densesolverlsreport*)_dst;
   10311           0 :     densesolverlsreport *src = (densesolverlsreport*)_src;
   10312           0 :     dst->r2 = src->r2;
   10313           0 :     ae_matrix_init_copy(&dst->cx, &src->cx, _state, make_automatic);
   10314           0 :     dst->n = src->n;
   10315           0 :     dst->k = src->k;
   10316           0 : }
   10317             : 
   10318             : 
   10319           0 : void _densesolverlsreport_clear(void* _p)
   10320             : {
   10321           0 :     densesolverlsreport *p = (densesolverlsreport*)_p;
   10322           0 :     ae_touch_ptr((void*)p);
   10323           0 :     ae_matrix_clear(&p->cx);
   10324           0 : }
   10325             : 
   10326             : 
   10327           0 : void _densesolverlsreport_destroy(void* _p)
   10328             : {
   10329           0 :     densesolverlsreport *p = (densesolverlsreport*)_p;
   10330           0 :     ae_touch_ptr((void*)p);
   10331           0 :     ae_matrix_destroy(&p->cx);
   10332           0 : }
   10333             : 
   10334             : 
   10335             : #endif
   10336             : #if defined(AE_COMPILE_LINLSQR) || !defined(AE_PARTIAL_BUILD)
   10337             : 
   10338             : 
   10339             : /*************************************************************************
   10340             : This function initializes linear LSQR Solver. This solver is used to solve
   10341             : non-symmetric (and, possibly, non-square) problems. Least squares solution
   10342             : is returned for non-compatible systems.
   10343             : 
   10344             : USAGE:
   10345             : 1. User initializes algorithm state with LinLSQRCreate() call
   10346             : 2. User tunes solver parameters with  LinLSQRSetCond() and other functions
   10347             : 3. User  calls  LinLSQRSolveSparse()  function which takes algorithm state 
   10348             :    and SparseMatrix object.
   10349             : 4. User calls LinLSQRResults() to get solution
   10350             : 5. Optionally, user may call LinLSQRSolveSparse() again to  solve  another  
   10351             :    problem  with different matrix and/or right part without reinitializing 
   10352             :    LinLSQRState structure.
   10353             :   
   10354             : INPUT PARAMETERS:
   10355             :     M       -   number of rows in A
   10356             :     N       -   number of variables, N>0
   10357             : 
   10358             : OUTPUT PARAMETERS:
   10359             :     State   -   structure which stores algorithm state
   10360             :     
   10361             : NOTE: see also linlsqrcreatebuf()  for  version  which  reuses  previously
   10362             :       allocated place as much as possible.
   10363             : 
   10364             :   -- ALGLIB --
   10365             :      Copyright 30.11.2011 by Bochkanov Sergey
   10366             : *************************************************************************/
   10367           0 : void linlsqrcreate(ae_int_t m,
   10368             :      ae_int_t n,
   10369             :      linlsqrstate* state,
   10370             :      ae_state *_state)
   10371             : {
   10372             : 
   10373           0 :     _linlsqrstate_clear(state);
   10374             : 
   10375           0 :     ae_assert(m>0, "LinLSQRCreate: M<=0", _state);
   10376           0 :     ae_assert(n>0, "LinLSQRCreate: N<=0", _state);
   10377           0 :     linlsqrcreatebuf(m, n, state, _state);
   10378           0 : }
   10379             : 
   10380             : 
   10381             : /*************************************************************************
   10382             : This function initializes linear LSQR Solver.  It  provides  exactly  same
   10383             : functionality as linlsqrcreate(), but reuses  previously  allocated  space
   10384             : as much as possible.
   10385             :   
   10386             : INPUT PARAMETERS:
   10387             :     M       -   number of rows in A
   10388             :     N       -   number of variables, N>0
   10389             : 
   10390             : OUTPUT PARAMETERS:
   10391             :     State   -   structure which stores algorithm state
   10392             : 
   10393             :   -- ALGLIB --
   10394             :      Copyright 14.11.2018 by Bochkanov Sergey
   10395             : *************************************************************************/
   10396           0 : void linlsqrcreatebuf(ae_int_t m,
   10397             :      ae_int_t n,
   10398             :      linlsqrstate* state,
   10399             :      ae_state *_state)
   10400             : {
   10401             :     ae_int_t i;
   10402             : 
   10403             : 
   10404           0 :     ae_assert(m>0, "LinLSQRCreateBuf: M<=0", _state);
   10405           0 :     ae_assert(n>0, "LinLSQRCreateBuf: N<=0", _state);
   10406           0 :     state->m = m;
   10407           0 :     state->n = n;
   10408           0 :     state->prectype = 0;
   10409           0 :     state->epsa = linlsqr_atol;
   10410           0 :     state->epsb = linlsqr_btol;
   10411           0 :     state->epsc = 1/ae_sqrt(ae_machineepsilon, _state);
   10412           0 :     state->maxits = 0;
   10413           0 :     state->lambdai = (double)(0);
   10414           0 :     state->xrep = ae_false;
   10415           0 :     state->running = ae_false;
   10416           0 :     state->repiterationscount = 0;
   10417             :     
   10418             :     /*
   10419             :      * * allocate arrays
   10420             :      * * set RX to NAN (just for the case user calls Results() without 
   10421             :      *   calling SolveSparse()
   10422             :      * * set B to zero
   10423             :      */
   10424           0 :     normestimatorcreate(m, n, 2, 2, &state->nes, _state);
   10425           0 :     ae_vector_set_length(&state->rx, state->n, _state);
   10426           0 :     ae_vector_set_length(&state->ui, state->m+state->n, _state);
   10427           0 :     ae_vector_set_length(&state->uip1, state->m+state->n, _state);
   10428           0 :     ae_vector_set_length(&state->vip1, state->n, _state);
   10429           0 :     ae_vector_set_length(&state->vi, state->n, _state);
   10430           0 :     ae_vector_set_length(&state->omegai, state->n, _state);
   10431           0 :     ae_vector_set_length(&state->omegaip1, state->n, _state);
   10432           0 :     ae_vector_set_length(&state->d, state->n, _state);
   10433           0 :     ae_vector_set_length(&state->x, state->m+state->n, _state);
   10434           0 :     ae_vector_set_length(&state->mv, state->m+state->n, _state);
   10435           0 :     ae_vector_set_length(&state->mtv, state->n, _state);
   10436           0 :     ae_vector_set_length(&state->b, state->m, _state);
   10437           0 :     for(i=0; i<=n-1; i++)
   10438             :     {
   10439           0 :         state->rx.ptr.p_double[i] = _state->v_nan;
   10440             :     }
   10441           0 :     for(i=0; i<=m-1; i++)
   10442             :     {
   10443           0 :         state->b.ptr.p_double[i] = (double)(0);
   10444             :     }
   10445           0 :     ae_vector_set_length(&state->rstate.ia, 1+1, _state);
   10446           0 :     ae_vector_set_length(&state->rstate.ra, 0+1, _state);
   10447           0 :     state->rstate.stage = -1;
   10448           0 : }
   10449             : 
   10450             : 
   10451             : /*************************************************************************
   10452             : This function sets right part. By default, right part is zero.
   10453             : 
   10454             : INPUT PARAMETERS:
   10455             :     B       -   right part, array[N].
   10456             : 
   10457             : OUTPUT PARAMETERS:
   10458             :     State   -   structure which stores algorithm state
   10459             : 
   10460             :   -- ALGLIB --
   10461             :      Copyright 30.11.2011 by Bochkanov Sergey
   10462             : *************************************************************************/
   10463           0 : void linlsqrsetb(linlsqrstate* state,
   10464             :      /* Real    */ ae_vector* b,
   10465             :      ae_state *_state)
   10466             : {
   10467             :     ae_int_t i;
   10468             : 
   10469             : 
   10470           0 :     ae_assert(!state->running, "LinLSQRSetB: you can not change B when LinLSQRIteration is running", _state);
   10471           0 :     ae_assert(state->m<=b->cnt, "LinLSQRSetB: Length(B)<M", _state);
   10472           0 :     ae_assert(isfinitevector(b, state->m, _state), "LinLSQRSetB: B contains infinite or NaN values", _state);
   10473           0 :     state->bnorm2 = (double)(0);
   10474           0 :     for(i=0; i<=state->m-1; i++)
   10475             :     {
   10476           0 :         state->b.ptr.p_double[i] = b->ptr.p_double[i];
   10477           0 :         state->bnorm2 = state->bnorm2+b->ptr.p_double[i]*b->ptr.p_double[i];
   10478             :     }
   10479           0 : }
   10480             : 
   10481             : 
   10482             : /*************************************************************************
   10483             : This  function  changes  preconditioning  settings of LinLSQQSolveSparse()
   10484             : function. By default, SolveSparse() uses diagonal preconditioner,  but  if
   10485             : you want to use solver without preconditioning, you can call this function
   10486             : which forces solver to use unit matrix for preconditioning.
   10487             : 
   10488             : INPUT PARAMETERS:
   10489             :     State   -   structure which stores algorithm state
   10490             : 
   10491             :   -- ALGLIB --
   10492             :      Copyright 19.11.2012 by Bochkanov Sergey
   10493             : *************************************************************************/
   10494           0 : void linlsqrsetprecunit(linlsqrstate* state, ae_state *_state)
   10495             : {
   10496             : 
   10497             : 
   10498           0 :     ae_assert(!state->running, "LinLSQRSetPrecUnit: you can not change preconditioner, because function LinLSQRIteration is running!", _state);
   10499           0 :     state->prectype = -1;
   10500           0 : }
   10501             : 
   10502             : 
   10503             : /*************************************************************************
   10504             : This  function  changes  preconditioning  settings  of  LinCGSolveSparse()
   10505             : function.  LinCGSolveSparse() will use diagonal of the  system  matrix  as
   10506             : preconditioner. This preconditioning mode is active by default.
   10507             : 
   10508             : INPUT PARAMETERS:
   10509             :     State   -   structure which stores algorithm state
   10510             : 
   10511             :   -- ALGLIB --
   10512             :      Copyright 19.11.2012 by Bochkanov Sergey
   10513             : *************************************************************************/
   10514           0 : void linlsqrsetprecdiag(linlsqrstate* state, ae_state *_state)
   10515             : {
   10516             : 
   10517             : 
   10518           0 :     ae_assert(!state->running, "LinLSQRSetPrecDiag: you can not change preconditioner, because function LinCGIteration is running!", _state);
   10519           0 :     state->prectype = 0;
   10520           0 : }
   10521             : 
   10522             : 
   10523             : /*************************************************************************
   10524             : This function sets optional Tikhonov regularization coefficient.
   10525             : It is zero by default.
   10526             : 
   10527             : INPUT PARAMETERS:
   10528             :     LambdaI -   regularization factor, LambdaI>=0
   10529             : 
   10530             : OUTPUT PARAMETERS:
   10531             :     State   -   structure which stores algorithm state
   10532             :     
   10533             :   -- ALGLIB --
   10534             :      Copyright 30.11.2011 by Bochkanov Sergey
   10535             : *************************************************************************/
   10536           0 : void linlsqrsetlambdai(linlsqrstate* state,
   10537             :      double lambdai,
   10538             :      ae_state *_state)
   10539             : {
   10540             : 
   10541             : 
   10542           0 :     ae_assert(!state->running, "LinLSQRSetLambdaI: you can not set LambdaI, because function LinLSQRIteration is running", _state);
   10543           0 :     ae_assert(ae_isfinite(lambdai, _state)&&ae_fp_greater_eq(lambdai,(double)(0)), "LinLSQRSetLambdaI: LambdaI is infinite or NaN", _state);
   10544           0 :     state->lambdai = lambdai;
   10545           0 : }
   10546             : 
   10547             : 
   10548             : /*************************************************************************
   10549             : 
   10550             :   -- ALGLIB --
   10551             :      Copyright 30.11.2011 by Bochkanov Sergey
   10552             : *************************************************************************/
   10553           0 : ae_bool linlsqriteration(linlsqrstate* state, ae_state *_state)
   10554             : {
   10555             :     ae_int_t summn;
   10556             :     double bnorm;
   10557             :     ae_int_t i;
   10558             :     ae_bool result;
   10559             : 
   10560             : 
   10561             :     
   10562             :     /*
   10563             :      * Reverse communication preparations
   10564             :      * I know it looks ugly, but it works the same way
   10565             :      * anywhere from C++ to Python.
   10566             :      *
   10567             :      * This code initializes locals by:
   10568             :      * * random values determined during code
   10569             :      *   generation - on first subroutine call
   10570             :      * * values from previous call - on subsequent calls
   10571             :      */
   10572           0 :     if( state->rstate.stage>=0 )
   10573             :     {
   10574           0 :         summn = state->rstate.ia.ptr.p_int[0];
   10575           0 :         i = state->rstate.ia.ptr.p_int[1];
   10576           0 :         bnorm = state->rstate.ra.ptr.p_double[0];
   10577             :     }
   10578             :     else
   10579             :     {
   10580           0 :         summn = 359;
   10581           0 :         i = -58;
   10582           0 :         bnorm = -919;
   10583             :     }
   10584           0 :     if( state->rstate.stage==0 )
   10585             :     {
   10586           0 :         goto lbl_0;
   10587             :     }
   10588           0 :     if( state->rstate.stage==1 )
   10589             :     {
   10590           0 :         goto lbl_1;
   10591             :     }
   10592           0 :     if( state->rstate.stage==2 )
   10593             :     {
   10594           0 :         goto lbl_2;
   10595             :     }
   10596           0 :     if( state->rstate.stage==3 )
   10597             :     {
   10598           0 :         goto lbl_3;
   10599             :     }
   10600           0 :     if( state->rstate.stage==4 )
   10601             :     {
   10602           0 :         goto lbl_4;
   10603             :     }
   10604           0 :     if( state->rstate.stage==5 )
   10605             :     {
   10606           0 :         goto lbl_5;
   10607             :     }
   10608           0 :     if( state->rstate.stage==6 )
   10609             :     {
   10610           0 :         goto lbl_6;
   10611             :     }
   10612             :     
   10613             :     /*
   10614             :      * Routine body
   10615             :      */
   10616           0 :     ae_assert(state->b.cnt>0, "LinLSQRIteration: using non-allocated array B", _state);
   10617           0 :     summn = state->m+state->n;
   10618           0 :     bnorm = ae_sqrt(state->bnorm2, _state);
   10619           0 :     state->userterminationneeded = ae_false;
   10620           0 :     state->running = ae_true;
   10621           0 :     state->repnmv = 0;
   10622           0 :     state->repiterationscount = 0;
   10623           0 :     state->r2 = state->bnorm2;
   10624           0 :     linlsqr_clearrfields(state, _state);
   10625             :     
   10626             :     /*
   10627             :      *estimate for ANorm
   10628             :      */
   10629           0 :     normestimatorrestart(&state->nes, _state);
   10630           0 : lbl_7:
   10631           0 :     if( !normestimatoriteration(&state->nes, _state) )
   10632             :     {
   10633           0 :         goto lbl_8;
   10634             :     }
   10635           0 :     if( !state->nes.needmv )
   10636             :     {
   10637           0 :         goto lbl_9;
   10638             :     }
   10639           0 :     ae_v_move(&state->x.ptr.p_double[0], 1, &state->nes.x.ptr.p_double[0], 1, ae_v_len(0,state->n-1));
   10640           0 :     state->repnmv = state->repnmv+1;
   10641           0 :     linlsqr_clearrfields(state, _state);
   10642           0 :     state->needmv = ae_true;
   10643           0 :     state->rstate.stage = 0;
   10644           0 :     goto lbl_rcomm;
   10645           0 : lbl_0:
   10646           0 :     state->needmv = ae_false;
   10647           0 :     ae_v_move(&state->nes.mv.ptr.p_double[0], 1, &state->mv.ptr.p_double[0], 1, ae_v_len(0,state->m-1));
   10648           0 :     goto lbl_7;
   10649           0 : lbl_9:
   10650           0 :     if( !state->nes.needmtv )
   10651             :     {
   10652           0 :         goto lbl_11;
   10653             :     }
   10654           0 :     ae_v_move(&state->x.ptr.p_double[0], 1, &state->nes.x.ptr.p_double[0], 1, ae_v_len(0,state->m-1));
   10655             :     
   10656             :     /*
   10657             :      *matrix-vector multiplication
   10658             :      */
   10659           0 :     state->repnmv = state->repnmv+1;
   10660           0 :     linlsqr_clearrfields(state, _state);
   10661           0 :     state->needmtv = ae_true;
   10662           0 :     state->rstate.stage = 1;
   10663           0 :     goto lbl_rcomm;
   10664           0 : lbl_1:
   10665           0 :     state->needmtv = ae_false;
   10666           0 :     ae_v_move(&state->nes.mtv.ptr.p_double[0], 1, &state->mtv.ptr.p_double[0], 1, ae_v_len(0,state->n-1));
   10667           0 :     goto lbl_7;
   10668           0 : lbl_11:
   10669           0 :     goto lbl_7;
   10670           0 : lbl_8:
   10671           0 :     normestimatorresults(&state->nes, &state->anorm, _state);
   10672             :     
   10673             :     /*
   10674             :      *initialize .RX by zeros
   10675             :      */
   10676           0 :     for(i=0; i<=state->n-1; i++)
   10677             :     {
   10678           0 :         state->rx.ptr.p_double[i] = (double)(0);
   10679             :     }
   10680             :     
   10681             :     /*
   10682             :      *output first report
   10683             :      */
   10684           0 :     if( !state->xrep )
   10685             :     {
   10686           0 :         goto lbl_13;
   10687             :     }
   10688           0 :     ae_v_move(&state->x.ptr.p_double[0], 1, &state->rx.ptr.p_double[0], 1, ae_v_len(0,state->n-1));
   10689           0 :     linlsqr_clearrfields(state, _state);
   10690           0 :     state->xupdated = ae_true;
   10691           0 :     state->rstate.stage = 2;
   10692           0 :     goto lbl_rcomm;
   10693           0 : lbl_2:
   10694           0 :     state->xupdated = ae_false;
   10695           0 : lbl_13:
   10696             :     
   10697             :     /*
   10698             :      * LSQR, Step 0.
   10699             :      *
   10700             :      * Algorithm outline corresponds to one which was described at p.50 of
   10701             :      * "LSQR - an algorithm for sparse linear equations and sparse least 
   10702             :      * squares" by C.Paige and M.Saunders with one small addition - we
   10703             :      * explicitly extend system matrix by additional N lines in order 
   10704             :      * to handle non-zero lambda, i.e. original A is replaced by
   10705             :      *         [ A        ]
   10706             :      * A_mod = [          ]
   10707             :      *         [ lambda*I ].
   10708             :      *
   10709             :      * Step 0:
   10710             :      *     x[0]          = 0
   10711             :      *     beta[1]*u[1]  = b
   10712             :      *     alpha[1]*v[1] = A_mod'*u[1]
   10713             :      *     w[1]          = v[1]
   10714             :      *     phiBar[1]     = beta[1]
   10715             :      *     rhoBar[1]     = alpha[1]
   10716             :      *     d[0]          = 0
   10717             :      *
   10718             :      * NOTE:
   10719             :      * There are three criteria for stopping:
   10720             :      * (S0) maximum number of iterations
   10721             :      * (S1) ||Rk||<=EpsB*||B||;
   10722             :      * (S2) ||A^T*Rk||/(||A||*||Rk||)<=EpsA.
   10723             :      * It is very important that S2 always checked AFTER S1. It is necessary
   10724             :      * to avoid division by zero when Rk=0.
   10725             :      */
   10726           0 :     state->betai = bnorm;
   10727           0 :     if( ae_fp_eq(state->betai,(double)(0)) )
   10728             :     {
   10729             :         
   10730             :         /*
   10731             :          * Zero right part
   10732             :          */
   10733           0 :         state->running = ae_false;
   10734           0 :         state->repterminationtype = 1;
   10735           0 :         result = ae_false;
   10736           0 :         return result;
   10737             :     }
   10738           0 :     for(i=0; i<=summn-1; i++)
   10739             :     {
   10740           0 :         if( i<state->m )
   10741             :         {
   10742           0 :             state->ui.ptr.p_double[i] = state->b.ptr.p_double[i]/state->betai;
   10743             :         }
   10744             :         else
   10745             :         {
   10746           0 :             state->ui.ptr.p_double[i] = (double)(0);
   10747             :         }
   10748           0 :         state->x.ptr.p_double[i] = state->ui.ptr.p_double[i];
   10749             :     }
   10750           0 :     state->repnmv = state->repnmv+1;
   10751           0 :     linlsqr_clearrfields(state, _state);
   10752           0 :     state->needmtv = ae_true;
   10753           0 :     state->rstate.stage = 3;
   10754           0 :     goto lbl_rcomm;
   10755           0 : lbl_3:
   10756           0 :     state->needmtv = ae_false;
   10757           0 :     for(i=0; i<=state->n-1; i++)
   10758             :     {
   10759           0 :         state->mtv.ptr.p_double[i] = state->mtv.ptr.p_double[i]+state->lambdai*state->ui.ptr.p_double[state->m+i];
   10760             :     }
   10761           0 :     state->alphai = (double)(0);
   10762           0 :     for(i=0; i<=state->n-1; i++)
   10763             :     {
   10764           0 :         state->alphai = state->alphai+state->mtv.ptr.p_double[i]*state->mtv.ptr.p_double[i];
   10765             :     }
   10766           0 :     state->alphai = ae_sqrt(state->alphai, _state);
   10767           0 :     if( ae_fp_eq(state->alphai,(double)(0)) )
   10768             :     {
   10769             :         
   10770             :         /*
   10771             :          * Orthogonality stopping criterion is met
   10772             :          */
   10773           0 :         state->running = ae_false;
   10774           0 :         state->repterminationtype = 4;
   10775           0 :         result = ae_false;
   10776           0 :         return result;
   10777             :     }
   10778           0 :     for(i=0; i<=state->n-1; i++)
   10779             :     {
   10780           0 :         state->vi.ptr.p_double[i] = state->mtv.ptr.p_double[i]/state->alphai;
   10781           0 :         state->omegai.ptr.p_double[i] = state->vi.ptr.p_double[i];
   10782             :     }
   10783           0 :     state->phibari = state->betai;
   10784           0 :     state->rhobari = state->alphai;
   10785           0 :     for(i=0; i<=state->n-1; i++)
   10786             :     {
   10787           0 :         state->d.ptr.p_double[i] = (double)(0);
   10788             :     }
   10789           0 :     state->dnorm = (double)(0);
   10790             :     
   10791             :     /*
   10792             :      * Steps I=1, 2, ...
   10793             :      */
   10794           0 : lbl_15:
   10795             :     if( ae_false )
   10796             :     {
   10797             :         goto lbl_16;
   10798             :     }
   10799             :     
   10800             :     /*
   10801             :      * At I-th step State.RepIterationsCount=I.
   10802             :      */
   10803           0 :     state->repiterationscount = state->repiterationscount+1;
   10804             :     
   10805             :     /*
   10806             :      * Bidiagonalization part:
   10807             :      *     beta[i+1]*u[i+1]  = A_mod*v[i]-alpha[i]*u[i]
   10808             :      *     alpha[i+1]*v[i+1] = A_mod'*u[i+1] - beta[i+1]*v[i]
   10809             :      *     
   10810             :      * NOTE:  beta[i+1]=0 or alpha[i+1]=0 will lead to successful termination
   10811             :      *        in the end of the current iteration. In this case u/v are zero.
   10812             :      * NOTE2: algorithm won't fail on zero alpha or beta (there will be no
   10813             :      *        division by zero because it will be stopped BEFORE division
   10814             :      *        occurs). However, near-zero alpha and beta won't stop algorithm
   10815             :      *        and, although no division by zero will happen, orthogonality 
   10816             :      *        in U and V will be lost.
   10817             :      */
   10818           0 :     ae_v_move(&state->x.ptr.p_double[0], 1, &state->vi.ptr.p_double[0], 1, ae_v_len(0,state->n-1));
   10819           0 :     state->repnmv = state->repnmv+1;
   10820           0 :     linlsqr_clearrfields(state, _state);
   10821           0 :     state->needmv = ae_true;
   10822           0 :     state->rstate.stage = 4;
   10823           0 :     goto lbl_rcomm;
   10824           0 : lbl_4:
   10825           0 :     state->needmv = ae_false;
   10826           0 :     for(i=0; i<=state->n-1; i++)
   10827             :     {
   10828           0 :         state->mv.ptr.p_double[state->m+i] = state->lambdai*state->vi.ptr.p_double[i];
   10829             :     }
   10830           0 :     state->betaip1 = (double)(0);
   10831           0 :     for(i=0; i<=summn-1; i++)
   10832             :     {
   10833           0 :         state->uip1.ptr.p_double[i] = state->mv.ptr.p_double[i]-state->alphai*state->ui.ptr.p_double[i];
   10834           0 :         state->betaip1 = state->betaip1+state->uip1.ptr.p_double[i]*state->uip1.ptr.p_double[i];
   10835             :     }
   10836           0 :     if( ae_fp_neq(state->betaip1,(double)(0)) )
   10837             :     {
   10838           0 :         state->betaip1 = ae_sqrt(state->betaip1, _state);
   10839           0 :         for(i=0; i<=summn-1; i++)
   10840             :         {
   10841           0 :             state->uip1.ptr.p_double[i] = state->uip1.ptr.p_double[i]/state->betaip1;
   10842             :         }
   10843             :     }
   10844           0 :     ae_v_move(&state->x.ptr.p_double[0], 1, &state->uip1.ptr.p_double[0], 1, ae_v_len(0,state->m-1));
   10845           0 :     state->repnmv = state->repnmv+1;
   10846           0 :     linlsqr_clearrfields(state, _state);
   10847           0 :     state->needmtv = ae_true;
   10848           0 :     state->rstate.stage = 5;
   10849           0 :     goto lbl_rcomm;
   10850           0 : lbl_5:
   10851           0 :     state->needmtv = ae_false;
   10852           0 :     for(i=0; i<=state->n-1; i++)
   10853             :     {
   10854           0 :         state->mtv.ptr.p_double[i] = state->mtv.ptr.p_double[i]+state->lambdai*state->uip1.ptr.p_double[state->m+i];
   10855             :     }
   10856           0 :     state->alphaip1 = (double)(0);
   10857           0 :     for(i=0; i<=state->n-1; i++)
   10858             :     {
   10859           0 :         state->vip1.ptr.p_double[i] = state->mtv.ptr.p_double[i]-state->betaip1*state->vi.ptr.p_double[i];
   10860           0 :         state->alphaip1 = state->alphaip1+state->vip1.ptr.p_double[i]*state->vip1.ptr.p_double[i];
   10861             :     }
   10862           0 :     if( ae_fp_neq(state->alphaip1,(double)(0)) )
   10863             :     {
   10864           0 :         state->alphaip1 = ae_sqrt(state->alphaip1, _state);
   10865           0 :         for(i=0; i<=state->n-1; i++)
   10866             :         {
   10867           0 :             state->vip1.ptr.p_double[i] = state->vip1.ptr.p_double[i]/state->alphaip1;
   10868             :         }
   10869             :     }
   10870             :     
   10871             :     /*
   10872             :      * Build next orthogonal transformation
   10873             :      */
   10874           0 :     state->rhoi = safepythag2(state->rhobari, state->betaip1, _state);
   10875           0 :     state->ci = state->rhobari/state->rhoi;
   10876           0 :     state->si = state->betaip1/state->rhoi;
   10877           0 :     state->theta = state->si*state->alphaip1;
   10878           0 :     state->rhobarip1 = -state->ci*state->alphaip1;
   10879           0 :     state->phii = state->ci*state->phibari;
   10880           0 :     state->phibarip1 = state->si*state->phibari;
   10881             :     
   10882             :     /*
   10883             :      * Update .RNorm
   10884             :      *
   10885             :      * This tricky  formula  is  necessary  because  simply  writing
   10886             :      * State.R2:=State.PhiBarIP1*State.PhiBarIP1 does NOT guarantees
   10887             :      * monotonic decrease of R2. Roundoff error combined with 80-bit
   10888             :      * precision used internally by Intel chips allows R2 to increase
   10889             :      * slightly in some rare, but possible cases. This property is
   10890             :      * undesirable, so we prefer to guard against R increase.
   10891             :      */
   10892           0 :     state->r2 = ae_minreal(state->r2, state->phibarip1*state->phibarip1, _state);
   10893             :     
   10894             :     /*
   10895             :      * Update d and DNorm, check condition-related stopping criteria
   10896             :      */
   10897           0 :     for(i=0; i<=state->n-1; i++)
   10898             :     {
   10899           0 :         state->d.ptr.p_double[i] = 1/state->rhoi*(state->vi.ptr.p_double[i]-state->theta*state->d.ptr.p_double[i]);
   10900           0 :         state->dnorm = state->dnorm+state->d.ptr.p_double[i]*state->d.ptr.p_double[i];
   10901             :     }
   10902           0 :     if( ae_fp_greater_eq(ae_sqrt(state->dnorm, _state)*state->anorm,state->epsc) )
   10903             :     {
   10904           0 :         state->running = ae_false;
   10905           0 :         state->repterminationtype = 7;
   10906           0 :         result = ae_false;
   10907           0 :         return result;
   10908             :     }
   10909             :     
   10910             :     /*
   10911             :      * Update x, output report
   10912             :      */
   10913           0 :     for(i=0; i<=state->n-1; i++)
   10914             :     {
   10915           0 :         state->rx.ptr.p_double[i] = state->rx.ptr.p_double[i]+state->phii/state->rhoi*state->omegai.ptr.p_double[i];
   10916             :     }
   10917           0 :     if( !state->xrep )
   10918             :     {
   10919           0 :         goto lbl_17;
   10920             :     }
   10921           0 :     ae_v_move(&state->x.ptr.p_double[0], 1, &state->rx.ptr.p_double[0], 1, ae_v_len(0,state->n-1));
   10922           0 :     linlsqr_clearrfields(state, _state);
   10923           0 :     state->xupdated = ae_true;
   10924           0 :     state->rstate.stage = 6;
   10925           0 :     goto lbl_rcomm;
   10926           0 : lbl_6:
   10927           0 :     state->xupdated = ae_false;
   10928           0 : lbl_17:
   10929             :     
   10930             :     /*
   10931             :      * Check stopping criteria
   10932             :      * 1. achieved required number of iterations;
   10933             :      * 2. ||Rk||<=EpsB*||B||;
   10934             :      * 3. ||A^T*Rk||/(||A||*||Rk||)<=EpsA;
   10935             :      */
   10936           0 :     if( state->maxits>0&&state->repiterationscount>=state->maxits )
   10937             :     {
   10938             :         
   10939             :         /*
   10940             :          * Achieved required number of iterations
   10941             :          */
   10942           0 :         state->running = ae_false;
   10943           0 :         state->repterminationtype = 5;
   10944           0 :         result = ae_false;
   10945           0 :         return result;
   10946             :     }
   10947           0 :     if( ae_fp_less_eq(state->phibarip1,state->epsb*bnorm) )
   10948             :     {
   10949             :         
   10950             :         /*
   10951             :          * ||Rk||<=EpsB*||B||, here ||Rk||=PhiBar
   10952             :          */
   10953           0 :         state->running = ae_false;
   10954           0 :         state->repterminationtype = 1;
   10955           0 :         result = ae_false;
   10956           0 :         return result;
   10957             :     }
   10958           0 :     if( ae_fp_less_eq(state->alphaip1*ae_fabs(state->ci, _state)/state->anorm,state->epsa) )
   10959             :     {
   10960             :         
   10961             :         /*
   10962             :          * ||A^T*Rk||/(||A||*||Rk||)<=EpsA, here ||A^T*Rk||=PhiBar*Alpha[i+1]*|.C|
   10963             :          */
   10964           0 :         state->running = ae_false;
   10965           0 :         state->repterminationtype = 4;
   10966           0 :         result = ae_false;
   10967           0 :         return result;
   10968             :     }
   10969           0 :     if( state->userterminationneeded )
   10970             :     {
   10971             :         
   10972             :         /*
   10973             :          * User requested termination
   10974             :          */
   10975           0 :         state->running = ae_false;
   10976           0 :         state->repterminationtype = 8;
   10977           0 :         result = ae_false;
   10978           0 :         return result;
   10979             :     }
   10980             :     
   10981             :     /*
   10982             :      * Update omega
   10983             :      */
   10984           0 :     for(i=0; i<=state->n-1; i++)
   10985             :     {
   10986           0 :         state->omegaip1.ptr.p_double[i] = state->vip1.ptr.p_double[i]-state->theta/state->rhoi*state->omegai.ptr.p_double[i];
   10987             :     }
   10988             :     
   10989             :     /*
   10990             :      * Prepare for the next iteration - rename variables:
   10991             :      * u[i]   := u[i+1]
   10992             :      * v[i]   := v[i+1]
   10993             :      * rho[i] := rho[i+1]
   10994             :      * ...
   10995             :      */
   10996           0 :     ae_v_move(&state->ui.ptr.p_double[0], 1, &state->uip1.ptr.p_double[0], 1, ae_v_len(0,summn-1));
   10997           0 :     ae_v_move(&state->vi.ptr.p_double[0], 1, &state->vip1.ptr.p_double[0], 1, ae_v_len(0,state->n-1));
   10998           0 :     ae_v_move(&state->omegai.ptr.p_double[0], 1, &state->omegaip1.ptr.p_double[0], 1, ae_v_len(0,state->n-1));
   10999           0 :     state->alphai = state->alphaip1;
   11000           0 :     state->betai = state->betaip1;
   11001           0 :     state->phibari = state->phibarip1;
   11002           0 :     state->rhobari = state->rhobarip1;
   11003           0 :     goto lbl_15;
   11004             : lbl_16:
   11005             :     result = ae_false;
   11006             :     return result;
   11007             :     
   11008             :     /*
   11009             :      * Saving state
   11010             :      */
   11011           0 : lbl_rcomm:
   11012           0 :     result = ae_true;
   11013           0 :     state->rstate.ia.ptr.p_int[0] = summn;
   11014           0 :     state->rstate.ia.ptr.p_int[1] = i;
   11015           0 :     state->rstate.ra.ptr.p_double[0] = bnorm;
   11016           0 :     return result;
   11017             : }
   11018             : 
   11019             : 
   11020             : /*************************************************************************
   11021             : Procedure for solution of A*x=b with sparse A.
   11022             : 
   11023             : INPUT PARAMETERS:
   11024             :     State   -   algorithm state
   11025             :     A       -   sparse M*N matrix in the CRS format (you MUST contvert  it 
   11026             :                 to CRS format  by  calling  SparseConvertToCRS()  function
   11027             :                 BEFORE you pass it to this function).
   11028             :     B       -   right part, array[M]
   11029             : 
   11030             : RESULT:
   11031             :     This function returns no result.
   11032             :     You can get solution by calling LinCGResults()
   11033             :     
   11034             : NOTE: this function uses lightweight preconditioning -  multiplication  by
   11035             :       inverse of diag(A). If you want, you can turn preconditioning off by
   11036             :       calling LinLSQRSetPrecUnit(). However, preconditioning cost is   low
   11037             :       and preconditioner is very important for solution  of  badly  scaled
   11038             :       problems.
   11039             : 
   11040             :   -- ALGLIB --
   11041             :      Copyright 30.11.2011 by Bochkanov Sergey
   11042             : *************************************************************************/
   11043           0 : void linlsqrsolvesparse(linlsqrstate* state,
   11044             :      sparsematrix* a,
   11045             :      /* Real    */ ae_vector* b,
   11046             :      ae_state *_state)
   11047             : {
   11048             :     ae_int_t n;
   11049             :     ae_int_t i;
   11050             :     ae_int_t j;
   11051             :     ae_int_t t0;
   11052             :     ae_int_t t1;
   11053             :     double v;
   11054             : 
   11055             : 
   11056           0 :     n = state->n;
   11057           0 :     ae_assert(!state->running, "LinLSQRSolveSparse: you can not call this function when LinLSQRIteration is running", _state);
   11058           0 :     ae_assert(b->cnt>=state->m, "LinLSQRSolveSparse: Length(B)<M", _state);
   11059           0 :     ae_assert(isfinitevector(b, state->m, _state), "LinLSQRSolveSparse: B contains infinite or NaN values", _state);
   11060             :     
   11061             :     /*
   11062             :      * Allocate temporaries
   11063             :      */
   11064           0 :     rvectorsetlengthatleast(&state->tmpd, n, _state);
   11065           0 :     rvectorsetlengthatleast(&state->tmpx, n, _state);
   11066             :     
   11067             :     /*
   11068             :      * Compute diagonal scaling matrix D
   11069             :      */
   11070           0 :     if( state->prectype==0 )
   11071             :     {
   11072             :         
   11073             :         /*
   11074             :          * Default preconditioner - inverse of column norms
   11075             :          */
   11076           0 :         for(i=0; i<=n-1; i++)
   11077             :         {
   11078           0 :             state->tmpd.ptr.p_double[i] = (double)(0);
   11079             :         }
   11080           0 :         t0 = 0;
   11081           0 :         t1 = 0;
   11082           0 :         while(sparseenumerate(a, &t0, &t1, &i, &j, &v, _state))
   11083             :         {
   11084           0 :             state->tmpd.ptr.p_double[j] = state->tmpd.ptr.p_double[j]+ae_sqr(v, _state);
   11085             :         }
   11086           0 :         for(i=0; i<=n-1; i++)
   11087             :         {
   11088           0 :             if( ae_fp_greater(state->tmpd.ptr.p_double[i],(double)(0)) )
   11089             :             {
   11090           0 :                 state->tmpd.ptr.p_double[i] = 1/ae_sqrt(state->tmpd.ptr.p_double[i], _state);
   11091             :             }
   11092             :             else
   11093             :             {
   11094           0 :                 state->tmpd.ptr.p_double[i] = (double)(1);
   11095             :             }
   11096             :         }
   11097             :     }
   11098             :     else
   11099             :     {
   11100             :         
   11101             :         /*
   11102             :          * No diagonal scaling
   11103             :          */
   11104           0 :         for(i=0; i<=n-1; i++)
   11105             :         {
   11106           0 :             state->tmpd.ptr.p_double[i] = (double)(1);
   11107             :         }
   11108             :     }
   11109             :     
   11110             :     /*
   11111             :      * Solve.
   11112             :      *
   11113             :      * Instead of solving A*x=b we solve preconditioned system (A*D)*(inv(D)*x)=b.
   11114             :      * Transformed A is not calculated explicitly, we just modify multiplication
   11115             :      * by A or A'. After solution we modify State.RX so it will store untransformed
   11116             :      * variables
   11117             :      */
   11118           0 :     linlsqrsetb(state, b, _state);
   11119           0 :     linlsqrrestart(state, _state);
   11120           0 :     while(linlsqriteration(state, _state))
   11121             :     {
   11122           0 :         if( state->needmv )
   11123             :         {
   11124           0 :             for(i=0; i<=n-1; i++)
   11125             :             {
   11126           0 :                 state->tmpx.ptr.p_double[i] = state->tmpd.ptr.p_double[i]*state->x.ptr.p_double[i];
   11127             :             }
   11128           0 :             sparsemv(a, &state->tmpx, &state->mv, _state);
   11129             :         }
   11130           0 :         if( state->needmtv )
   11131             :         {
   11132           0 :             sparsemtv(a, &state->x, &state->mtv, _state);
   11133           0 :             for(i=0; i<=n-1; i++)
   11134             :             {
   11135           0 :                 state->mtv.ptr.p_double[i] = state->tmpd.ptr.p_double[i]*state->mtv.ptr.p_double[i];
   11136             :             }
   11137             :         }
   11138             :     }
   11139           0 :     for(i=0; i<=n-1; i++)
   11140             :     {
   11141           0 :         state->rx.ptr.p_double[i] = state->tmpd.ptr.p_double[i]*state->rx.ptr.p_double[i];
   11142             :     }
   11143           0 : }
   11144             : 
   11145             : 
   11146             : /*************************************************************************
   11147             : This function sets stopping criteria.
   11148             : 
   11149             : INPUT PARAMETERS:
   11150             :     EpsA    -   algorithm will be stopped if ||A^T*Rk||/(||A||*||Rk||)<=EpsA.
   11151             :     EpsB    -   algorithm will be stopped if ||Rk||<=EpsB*||B||
   11152             :     MaxIts  -   algorithm will be stopped if number of iterations
   11153             :                 more than MaxIts.
   11154             : 
   11155             : OUTPUT PARAMETERS:
   11156             :     State   -   structure which stores algorithm state
   11157             : 
   11158             : NOTE: if EpsA,EpsB,EpsC and MaxIts are zero then these variables will
   11159             : be setted as default values.
   11160             :     
   11161             :   -- ALGLIB --
   11162             :      Copyright 30.11.2011 by Bochkanov Sergey
   11163             : *************************************************************************/
   11164           0 : void linlsqrsetcond(linlsqrstate* state,
   11165             :      double epsa,
   11166             :      double epsb,
   11167             :      ae_int_t maxits,
   11168             :      ae_state *_state)
   11169             : {
   11170             : 
   11171             : 
   11172           0 :     ae_assert(!state->running, "LinLSQRSetCond: you can not call this function when LinLSQRIteration is running", _state);
   11173           0 :     ae_assert(ae_isfinite(epsa, _state)&&ae_fp_greater_eq(epsa,(double)(0)), "LinLSQRSetCond: EpsA is negative, INF or NAN", _state);
   11174           0 :     ae_assert(ae_isfinite(epsb, _state)&&ae_fp_greater_eq(epsb,(double)(0)), "LinLSQRSetCond: EpsB is negative, INF or NAN", _state);
   11175           0 :     ae_assert(maxits>=0, "LinLSQRSetCond: MaxIts is negative", _state);
   11176           0 :     if( (ae_fp_eq(epsa,(double)(0))&&ae_fp_eq(epsb,(double)(0)))&&maxits==0 )
   11177             :     {
   11178           0 :         state->epsa = linlsqr_atol;
   11179           0 :         state->epsb = linlsqr_btol;
   11180           0 :         state->maxits = state->n;
   11181             :     }
   11182             :     else
   11183             :     {
   11184           0 :         state->epsa = epsa;
   11185           0 :         state->epsb = epsb;
   11186           0 :         state->maxits = maxits;
   11187             :     }
   11188           0 : }
   11189             : 
   11190             : 
   11191             : /*************************************************************************
   11192             : LSQR solver: results.
   11193             : 
   11194             : This function must be called after LinLSQRSolve
   11195             : 
   11196             : INPUT PARAMETERS:
   11197             :     State   -   algorithm state
   11198             : 
   11199             : OUTPUT PARAMETERS:
   11200             :     X       -   array[N], solution
   11201             :     Rep     -   optimization report:
   11202             :                 * Rep.TerminationType completetion code:
   11203             :                     *  1    ||Rk||<=EpsB*||B||
   11204             :                     *  4    ||A^T*Rk||/(||A||*||Rk||)<=EpsA
   11205             :                     *  5    MaxIts steps was taken
   11206             :                     *  7    rounding errors prevent further progress,
   11207             :                             X contains best point found so far.
   11208             :                             (sometimes returned on singular systems)
   11209             :                     *  8    user requested termination via calling
   11210             :                             linlsqrrequesttermination()
   11211             :                 * Rep.IterationsCount contains iterations count
   11212             :                 * NMV countains number of matrix-vector calculations
   11213             :                 
   11214             :   -- ALGLIB --
   11215             :      Copyright 30.11.2011 by Bochkanov Sergey
   11216             : *************************************************************************/
   11217           0 : void linlsqrresults(linlsqrstate* state,
   11218             :      /* Real    */ ae_vector* x,
   11219             :      linlsqrreport* rep,
   11220             :      ae_state *_state)
   11221             : {
   11222             : 
   11223           0 :     ae_vector_clear(x);
   11224           0 :     _linlsqrreport_clear(rep);
   11225             : 
   11226           0 :     ae_assert(!state->running, "LinLSQRResult: you can not call this function when LinLSQRIteration is running", _state);
   11227           0 :     if( x->cnt<state->n )
   11228             :     {
   11229           0 :         ae_vector_set_length(x, state->n, _state);
   11230             :     }
   11231           0 :     ae_v_move(&x->ptr.p_double[0], 1, &state->rx.ptr.p_double[0], 1, ae_v_len(0,state->n-1));
   11232           0 :     rep->iterationscount = state->repiterationscount;
   11233           0 :     rep->nmv = state->repnmv;
   11234           0 :     rep->terminationtype = state->repterminationtype;
   11235           0 : }
   11236             : 
   11237             : 
   11238             : /*************************************************************************
   11239             : This function turns on/off reporting.
   11240             : 
   11241             : INPUT PARAMETERS:
   11242             :     State   -   structure which stores algorithm state
   11243             :     NeedXRep-   whether iteration reports are needed or not
   11244             : 
   11245             : If NeedXRep is True, algorithm will call rep() callback function if  it is
   11246             : provided to MinCGOptimize().
   11247             : 
   11248             :   -- ALGLIB --
   11249             :      Copyright 30.11.2011 by Bochkanov Sergey
   11250             : *************************************************************************/
   11251           0 : void linlsqrsetxrep(linlsqrstate* state,
   11252             :      ae_bool needxrep,
   11253             :      ae_state *_state)
   11254             : {
   11255             : 
   11256             : 
   11257           0 :     state->xrep = needxrep;
   11258           0 : }
   11259             : 
   11260             : 
   11261             : /*************************************************************************
   11262             : This function restarts LinLSQRIteration
   11263             : 
   11264             :   -- ALGLIB --
   11265             :      Copyright 30.11.2011 by Bochkanov Sergey
   11266             : *************************************************************************/
   11267           0 : void linlsqrrestart(linlsqrstate* state, ae_state *_state)
   11268             : {
   11269             : 
   11270             : 
   11271           0 :     ae_vector_set_length(&state->rstate.ia, 1+1, _state);
   11272           0 :     ae_vector_set_length(&state->rstate.ra, 0+1, _state);
   11273           0 :     state->rstate.stage = -1;
   11274           0 :     linlsqr_clearrfields(state, _state);
   11275           0 :     state->repiterationscount = 0;
   11276           0 : }
   11277             : 
   11278             : 
   11279             : /*************************************************************************
   11280             : This function is used to peek into LSQR solver and get  current  iteration
   11281             : counter. You can safely "peek" into the solver from another thread.
   11282             : 
   11283             : INPUT PARAMETERS:
   11284             :     S           -   solver object
   11285             : 
   11286             : RESULT:
   11287             :     iteration counter, in [0,INF)
   11288             : 
   11289             :   -- ALGLIB --
   11290             :      Copyright 21.05.2018 by Bochkanov Sergey
   11291             : *************************************************************************/
   11292           0 : ae_int_t linlsqrpeekiterationscount(linlsqrstate* s, ae_state *_state)
   11293             : {
   11294             :     ae_int_t result;
   11295             : 
   11296             : 
   11297           0 :     result = s->repiterationscount;
   11298           0 :     return result;
   11299             : }
   11300             : 
   11301             : 
   11302             : /*************************************************************************
   11303             : This subroutine submits request for termination of the running solver.  It
   11304             : can be called from some other thread which wants LSQR solver to  terminate
   11305             : (obviously, the  thread  running  LSQR  solver can not request termination
   11306             : because it is already busy working on LSQR).
   11307             : 
   11308             : As result, solver  stops  at  point  which  was  "current  accepted"  when
   11309             : termination  request  was  submitted  and returns error code 8 (successful
   11310             : termination).  Such   termination   is  a smooth  process  which  properly
   11311             : deallocates all temporaries.
   11312             : 
   11313             : INPUT PARAMETERS:
   11314             :     State   -   solver structure
   11315             : 
   11316             : NOTE: calling this function on solver which is NOT running  will  have  no
   11317             :       effect.
   11318             :       
   11319             : NOTE: multiple calls to this function are possible. First call is counted,
   11320             :       subsequent calls are silently ignored.
   11321             : 
   11322             : NOTE: solver clears termination flag on its start, it means that  if  some
   11323             :       other thread will request termination too soon, its request will went
   11324             :       unnoticed.
   11325             : 
   11326             :   -- ALGLIB --
   11327             :      Copyright 08.10.2014 by Bochkanov Sergey
   11328             : *************************************************************************/
   11329           0 : void linlsqrrequesttermination(linlsqrstate* state, ae_state *_state)
   11330             : {
   11331             : 
   11332             : 
   11333           0 :     state->userterminationneeded = ae_true;
   11334           0 : }
   11335             : 
   11336             : 
   11337             : /*************************************************************************
   11338             : Clears request fileds (to be sure that we don't forgot to clear something)
   11339             : *************************************************************************/
   11340           0 : static void linlsqr_clearrfields(linlsqrstate* state, ae_state *_state)
   11341             : {
   11342             : 
   11343             : 
   11344           0 :     state->xupdated = ae_false;
   11345           0 :     state->needmv = ae_false;
   11346           0 :     state->needmtv = ae_false;
   11347           0 :     state->needmv2 = ae_false;
   11348           0 :     state->needvmv = ae_false;
   11349           0 :     state->needprec = ae_false;
   11350           0 : }
   11351             : 
   11352             : 
   11353           0 : void _linlsqrstate_init(void* _p, ae_state *_state, ae_bool make_automatic)
   11354             : {
   11355           0 :     linlsqrstate *p = (linlsqrstate*)_p;
   11356           0 :     ae_touch_ptr((void*)p);
   11357           0 :     _normestimatorstate_init(&p->nes, _state, make_automatic);
   11358           0 :     ae_vector_init(&p->rx, 0, DT_REAL, _state, make_automatic);
   11359           0 :     ae_vector_init(&p->b, 0, DT_REAL, _state, make_automatic);
   11360           0 :     ae_vector_init(&p->ui, 0, DT_REAL, _state, make_automatic);
   11361           0 :     ae_vector_init(&p->uip1, 0, DT_REAL, _state, make_automatic);
   11362           0 :     ae_vector_init(&p->vi, 0, DT_REAL, _state, make_automatic);
   11363           0 :     ae_vector_init(&p->vip1, 0, DT_REAL, _state, make_automatic);
   11364           0 :     ae_vector_init(&p->omegai, 0, DT_REAL, _state, make_automatic);
   11365           0 :     ae_vector_init(&p->omegaip1, 0, DT_REAL, _state, make_automatic);
   11366           0 :     ae_vector_init(&p->d, 0, DT_REAL, _state, make_automatic);
   11367           0 :     ae_vector_init(&p->x, 0, DT_REAL, _state, make_automatic);
   11368           0 :     ae_vector_init(&p->mv, 0, DT_REAL, _state, make_automatic);
   11369           0 :     ae_vector_init(&p->mtv, 0, DT_REAL, _state, make_automatic);
   11370           0 :     ae_vector_init(&p->tmpd, 0, DT_REAL, _state, make_automatic);
   11371           0 :     ae_vector_init(&p->tmpx, 0, DT_REAL, _state, make_automatic);
   11372           0 :     _rcommstate_init(&p->rstate, _state, make_automatic);
   11373           0 : }
   11374             : 
   11375             : 
   11376           0 : void _linlsqrstate_init_copy(void* _dst, void* _src, ae_state *_state, ae_bool make_automatic)
   11377             : {
   11378           0 :     linlsqrstate *dst = (linlsqrstate*)_dst;
   11379           0 :     linlsqrstate *src = (linlsqrstate*)_src;
   11380           0 :     _normestimatorstate_init_copy(&dst->nes, &src->nes, _state, make_automatic);
   11381           0 :     ae_vector_init_copy(&dst->rx, &src->rx, _state, make_automatic);
   11382           0 :     ae_vector_init_copy(&dst->b, &src->b, _state, make_automatic);
   11383           0 :     dst->n = src->n;
   11384           0 :     dst->m = src->m;
   11385           0 :     dst->prectype = src->prectype;
   11386           0 :     ae_vector_init_copy(&dst->ui, &src->ui, _state, make_automatic);
   11387           0 :     ae_vector_init_copy(&dst->uip1, &src->uip1, _state, make_automatic);
   11388           0 :     ae_vector_init_copy(&dst->vi, &src->vi, _state, make_automatic);
   11389           0 :     ae_vector_init_copy(&dst->vip1, &src->vip1, _state, make_automatic);
   11390           0 :     ae_vector_init_copy(&dst->omegai, &src->omegai, _state, make_automatic);
   11391           0 :     ae_vector_init_copy(&dst->omegaip1, &src->omegaip1, _state, make_automatic);
   11392           0 :     dst->alphai = src->alphai;
   11393           0 :     dst->alphaip1 = src->alphaip1;
   11394           0 :     dst->betai = src->betai;
   11395           0 :     dst->betaip1 = src->betaip1;
   11396           0 :     dst->phibari = src->phibari;
   11397           0 :     dst->phibarip1 = src->phibarip1;
   11398           0 :     dst->phii = src->phii;
   11399           0 :     dst->rhobari = src->rhobari;
   11400           0 :     dst->rhobarip1 = src->rhobarip1;
   11401           0 :     dst->rhoi = src->rhoi;
   11402           0 :     dst->ci = src->ci;
   11403           0 :     dst->si = src->si;
   11404           0 :     dst->theta = src->theta;
   11405           0 :     dst->lambdai = src->lambdai;
   11406           0 :     ae_vector_init_copy(&dst->d, &src->d, _state, make_automatic);
   11407           0 :     dst->anorm = src->anorm;
   11408           0 :     dst->bnorm2 = src->bnorm2;
   11409           0 :     dst->dnorm = src->dnorm;
   11410           0 :     dst->r2 = src->r2;
   11411           0 :     ae_vector_init_copy(&dst->x, &src->x, _state, make_automatic);
   11412           0 :     ae_vector_init_copy(&dst->mv, &src->mv, _state, make_automatic);
   11413           0 :     ae_vector_init_copy(&dst->mtv, &src->mtv, _state, make_automatic);
   11414           0 :     dst->epsa = src->epsa;
   11415           0 :     dst->epsb = src->epsb;
   11416           0 :     dst->epsc = src->epsc;
   11417           0 :     dst->maxits = src->maxits;
   11418           0 :     dst->xrep = src->xrep;
   11419           0 :     dst->xupdated = src->xupdated;
   11420           0 :     dst->needmv = src->needmv;
   11421           0 :     dst->needmtv = src->needmtv;
   11422           0 :     dst->needmv2 = src->needmv2;
   11423           0 :     dst->needvmv = src->needvmv;
   11424           0 :     dst->needprec = src->needprec;
   11425           0 :     dst->repiterationscount = src->repiterationscount;
   11426           0 :     dst->repnmv = src->repnmv;
   11427           0 :     dst->repterminationtype = src->repterminationtype;
   11428           0 :     dst->running = src->running;
   11429           0 :     dst->userterminationneeded = src->userterminationneeded;
   11430           0 :     ae_vector_init_copy(&dst->tmpd, &src->tmpd, _state, make_automatic);
   11431           0 :     ae_vector_init_copy(&dst->tmpx, &src->tmpx, _state, make_automatic);
   11432           0 :     _rcommstate_init_copy(&dst->rstate, &src->rstate, _state, make_automatic);
   11433           0 : }
   11434             : 
   11435             : 
   11436           0 : void _linlsqrstate_clear(void* _p)
   11437             : {
   11438           0 :     linlsqrstate *p = (linlsqrstate*)_p;
   11439           0 :     ae_touch_ptr((void*)p);
   11440           0 :     _normestimatorstate_clear(&p->nes);
   11441           0 :     ae_vector_clear(&p->rx);
   11442           0 :     ae_vector_clear(&p->b);
   11443           0 :     ae_vector_clear(&p->ui);
   11444           0 :     ae_vector_clear(&p->uip1);
   11445           0 :     ae_vector_clear(&p->vi);
   11446           0 :     ae_vector_clear(&p->vip1);
   11447           0 :     ae_vector_clear(&p->omegai);
   11448           0 :     ae_vector_clear(&p->omegaip1);
   11449           0 :     ae_vector_clear(&p->d);
   11450           0 :     ae_vector_clear(&p->x);
   11451           0 :     ae_vector_clear(&p->mv);
   11452           0 :     ae_vector_clear(&p->mtv);
   11453           0 :     ae_vector_clear(&p->tmpd);
   11454           0 :     ae_vector_clear(&p->tmpx);
   11455           0 :     _rcommstate_clear(&p->rstate);
   11456           0 : }
   11457             : 
   11458             : 
   11459           0 : void _linlsqrstate_destroy(void* _p)
   11460             : {
   11461           0 :     linlsqrstate *p = (linlsqrstate*)_p;
   11462           0 :     ae_touch_ptr((void*)p);
   11463           0 :     _normestimatorstate_destroy(&p->nes);
   11464           0 :     ae_vector_destroy(&p->rx);
   11465           0 :     ae_vector_destroy(&p->b);
   11466           0 :     ae_vector_destroy(&p->ui);
   11467           0 :     ae_vector_destroy(&p->uip1);
   11468           0 :     ae_vector_destroy(&p->vi);
   11469           0 :     ae_vector_destroy(&p->vip1);
   11470           0 :     ae_vector_destroy(&p->omegai);
   11471           0 :     ae_vector_destroy(&p->omegaip1);
   11472           0 :     ae_vector_destroy(&p->d);
   11473           0 :     ae_vector_destroy(&p->x);
   11474           0 :     ae_vector_destroy(&p->mv);
   11475           0 :     ae_vector_destroy(&p->mtv);
   11476           0 :     ae_vector_destroy(&p->tmpd);
   11477           0 :     ae_vector_destroy(&p->tmpx);
   11478           0 :     _rcommstate_destroy(&p->rstate);
   11479           0 : }
   11480             : 
   11481             : 
   11482           0 : void _linlsqrreport_init(void* _p, ae_state *_state, ae_bool make_automatic)
   11483             : {
   11484           0 :     linlsqrreport *p = (linlsqrreport*)_p;
   11485           0 :     ae_touch_ptr((void*)p);
   11486           0 : }
   11487             : 
   11488             : 
   11489           0 : void _linlsqrreport_init_copy(void* _dst, void* _src, ae_state *_state, ae_bool make_automatic)
   11490             : {
   11491           0 :     linlsqrreport *dst = (linlsqrreport*)_dst;
   11492           0 :     linlsqrreport *src = (linlsqrreport*)_src;
   11493           0 :     dst->iterationscount = src->iterationscount;
   11494           0 :     dst->nmv = src->nmv;
   11495           0 :     dst->terminationtype = src->terminationtype;
   11496           0 : }
   11497             : 
   11498             : 
   11499           0 : void _linlsqrreport_clear(void* _p)
   11500             : {
   11501           0 :     linlsqrreport *p = (linlsqrreport*)_p;
   11502           0 :     ae_touch_ptr((void*)p);
   11503           0 : }
   11504             : 
   11505             : 
   11506           0 : void _linlsqrreport_destroy(void* _p)
   11507             : {
   11508           0 :     linlsqrreport *p = (linlsqrreport*)_p;
   11509           0 :     ae_touch_ptr((void*)p);
   11510           0 : }
   11511             : 
   11512             : 
   11513             : #endif
   11514             : #if defined(AE_COMPILE_POLYNOMIALSOLVER) || !defined(AE_PARTIAL_BUILD)
   11515             : 
   11516             : 
   11517             : /*************************************************************************
   11518             : Polynomial root finding.
   11519             : 
   11520             : This function returns all roots of the polynomial
   11521             :     P(x) = a0 + a1*x + a2*x^2 + ... + an*x^n
   11522             : Both real and complex roots are returned (see below).
   11523             : 
   11524             : INPUT PARAMETERS:
   11525             :     A       -   array[N+1], polynomial coefficients:
   11526             :                 * A[0] is constant term
   11527             :                 * A[N] is a coefficient of X^N
   11528             :     N       -   polynomial degree
   11529             : 
   11530             : OUTPUT PARAMETERS:
   11531             :     X       -   array of complex roots:
   11532             :                 * for isolated real root, X[I] is strictly real: IMAGE(X[I])=0
   11533             :                 * complex roots are always returned in pairs - roots occupy
   11534             :                   positions I and I+1, with:
   11535             :                   * X[I+1]=Conj(X[I])
   11536             :                   * IMAGE(X[I]) > 0
   11537             :                   * IMAGE(X[I+1]) = -IMAGE(X[I]) < 0
   11538             :                 * multiple real roots may have non-zero imaginary part due
   11539             :                   to roundoff errors. There is no reliable way to distinguish
   11540             :                   real root of multiplicity 2 from two  complex  roots  in
   11541             :                   the presence of roundoff errors.
   11542             :     Rep     -   report, additional information, following fields are set:
   11543             :                 * Rep.MaxErr - max( |P(xi)| )  for  i=0..N-1.  This  field
   11544             :                   allows to quickly estimate "quality" of the roots  being
   11545             :                   returned.
   11546             : 
   11547             : NOTE:   this function uses companion matrix method to find roots. In  case
   11548             :         internal EVD  solver  fails  do  find  eigenvalues,  exception  is
   11549             :         generated.
   11550             : 
   11551             : NOTE:   roots are not "polished" and  no  matrix  balancing  is  performed
   11552             :         for them.
   11553             : 
   11554             :   -- ALGLIB --
   11555             :      Copyright 24.02.2014 by Bochkanov Sergey
   11556             : *************************************************************************/
   11557           0 : void polynomialsolve(/* Real    */ ae_vector* a,
   11558             :      ae_int_t n,
   11559             :      /* Complex */ ae_vector* x,
   11560             :      polynomialsolverreport* rep,
   11561             :      ae_state *_state)
   11562             : {
   11563             :     ae_frame _frame_block;
   11564             :     ae_vector _a;
   11565             :     ae_matrix c;
   11566             :     ae_matrix vl;
   11567             :     ae_matrix vr;
   11568             :     ae_vector wr;
   11569             :     ae_vector wi;
   11570             :     ae_int_t i;
   11571             :     ae_int_t j;
   11572             :     ae_bool status;
   11573             :     ae_int_t nz;
   11574             :     ae_int_t ne;
   11575             :     ae_complex v;
   11576             :     ae_complex vv;
   11577             : 
   11578           0 :     ae_frame_make(_state, &_frame_block);
   11579           0 :     memset(&_a, 0, sizeof(_a));
   11580           0 :     memset(&c, 0, sizeof(c));
   11581           0 :     memset(&vl, 0, sizeof(vl));
   11582           0 :     memset(&vr, 0, sizeof(vr));
   11583           0 :     memset(&wr, 0, sizeof(wr));
   11584           0 :     memset(&wi, 0, sizeof(wi));
   11585           0 :     ae_vector_init_copy(&_a, a, _state, ae_true);
   11586           0 :     a = &_a;
   11587           0 :     ae_vector_clear(x);
   11588           0 :     _polynomialsolverreport_clear(rep);
   11589           0 :     ae_matrix_init(&c, 0, 0, DT_REAL, _state, ae_true);
   11590           0 :     ae_matrix_init(&vl, 0, 0, DT_REAL, _state, ae_true);
   11591           0 :     ae_matrix_init(&vr, 0, 0, DT_REAL, _state, ae_true);
   11592           0 :     ae_vector_init(&wr, 0, DT_REAL, _state, ae_true);
   11593           0 :     ae_vector_init(&wi, 0, DT_REAL, _state, ae_true);
   11594             : 
   11595           0 :     ae_assert(n>0, "PolynomialSolve: N<=0", _state);
   11596           0 :     ae_assert(a->cnt>=n+1, "PolynomialSolve: Length(A)<N+1", _state);
   11597           0 :     ae_assert(isfinitevector(a, n+1, _state), "PolynomialSolve: A contains infitite numbers", _state);
   11598           0 :     ae_assert(ae_fp_neq(a->ptr.p_double[n],(double)(0)), "PolynomialSolve: A[N]=0", _state);
   11599             :     
   11600             :     /*
   11601             :      * Prepare
   11602             :      */
   11603           0 :     ae_vector_set_length(x, n, _state);
   11604             :     
   11605             :     /*
   11606             :      * Normalize A:
   11607             :      * * analytically determine NZ zero roots
   11608             :      * * quick exit for NZ=N
   11609             :      * * make residual NE-th degree polynomial monic
   11610             :      *   (here NE=N-NZ)
   11611             :      */
   11612           0 :     nz = 0;
   11613           0 :     while(nz<n&&ae_fp_eq(a->ptr.p_double[nz],(double)(0)))
   11614             :     {
   11615           0 :         nz = nz+1;
   11616             :     }
   11617           0 :     ne = n-nz;
   11618           0 :     for(i=nz; i<=n; i++)
   11619             :     {
   11620           0 :         a->ptr.p_double[i-nz] = a->ptr.p_double[i]/a->ptr.p_double[n];
   11621             :     }
   11622             :     
   11623             :     /*
   11624             :      * For NZ<N, build companion matrix and find NE non-zero roots
   11625             :      */
   11626           0 :     if( ne>0 )
   11627             :     {
   11628           0 :         ae_matrix_set_length(&c, ne, ne, _state);
   11629           0 :         for(i=0; i<=ne-1; i++)
   11630             :         {
   11631           0 :             for(j=0; j<=ne-1; j++)
   11632             :             {
   11633           0 :                 c.ptr.pp_double[i][j] = (double)(0);
   11634             :             }
   11635             :         }
   11636           0 :         c.ptr.pp_double[0][ne-1] = -a->ptr.p_double[0];
   11637           0 :         for(i=1; i<=ne-1; i++)
   11638             :         {
   11639           0 :             c.ptr.pp_double[i][i-1] = (double)(1);
   11640           0 :             c.ptr.pp_double[i][ne-1] = -a->ptr.p_double[i];
   11641             :         }
   11642           0 :         status = rmatrixevd(&c, ne, 0, &wr, &wi, &vl, &vr, _state);
   11643           0 :         ae_assert(status, "PolynomialSolve: inernal error - EVD solver failed", _state);
   11644           0 :         for(i=0; i<=ne-1; i++)
   11645             :         {
   11646           0 :             x->ptr.p_complex[i].x = wr.ptr.p_double[i];
   11647           0 :             x->ptr.p_complex[i].y = wi.ptr.p_double[i];
   11648             :         }
   11649             :     }
   11650             :     
   11651             :     /*
   11652             :      * Remaining NZ zero roots
   11653             :      */
   11654           0 :     for(i=ne; i<=n-1; i++)
   11655             :     {
   11656           0 :         x->ptr.p_complex[i] = ae_complex_from_i(0);
   11657             :     }
   11658             :     
   11659             :     /*
   11660             :      * Rep
   11661             :      */
   11662           0 :     rep->maxerr = (double)(0);
   11663           0 :     for(i=0; i<=ne-1; i++)
   11664             :     {
   11665           0 :         v = ae_complex_from_i(0);
   11666           0 :         vv = ae_complex_from_i(1);
   11667           0 :         for(j=0; j<=ne; j++)
   11668             :         {
   11669           0 :             v = ae_c_add(v,ae_c_mul_d(vv,a->ptr.p_double[j]));
   11670           0 :             vv = ae_c_mul(vv,x->ptr.p_complex[i]);
   11671             :         }
   11672           0 :         rep->maxerr = ae_maxreal(rep->maxerr, ae_c_abs(v, _state), _state);
   11673             :     }
   11674           0 :     ae_frame_leave(_state);
   11675           0 : }
   11676             : 
   11677             : 
   11678           0 : void _polynomialsolverreport_init(void* _p, ae_state *_state, ae_bool make_automatic)
   11679             : {
   11680           0 :     polynomialsolverreport *p = (polynomialsolverreport*)_p;
   11681           0 :     ae_touch_ptr((void*)p);
   11682           0 : }
   11683             : 
   11684             : 
   11685           0 : void _polynomialsolverreport_init_copy(void* _dst, void* _src, ae_state *_state, ae_bool make_automatic)
   11686             : {
   11687           0 :     polynomialsolverreport *dst = (polynomialsolverreport*)_dst;
   11688           0 :     polynomialsolverreport *src = (polynomialsolverreport*)_src;
   11689           0 :     dst->maxerr = src->maxerr;
   11690           0 : }
   11691             : 
   11692             : 
   11693           0 : void _polynomialsolverreport_clear(void* _p)
   11694             : {
   11695           0 :     polynomialsolverreport *p = (polynomialsolverreport*)_p;
   11696           0 :     ae_touch_ptr((void*)p);
   11697           0 : }
   11698             : 
   11699             : 
   11700           0 : void _polynomialsolverreport_destroy(void* _p)
   11701             : {
   11702           0 :     polynomialsolverreport *p = (polynomialsolverreport*)_p;
   11703           0 :     ae_touch_ptr((void*)p);
   11704           0 : }
   11705             : 
   11706             : 
   11707             : #endif
   11708             : #if defined(AE_COMPILE_NLEQ) || !defined(AE_PARTIAL_BUILD)
   11709             : 
   11710             : 
   11711             : /*************************************************************************
   11712             :                 LEVENBERG-MARQUARDT-LIKE NONLINEAR SOLVER
   11713             : 
   11714             : DESCRIPTION:
   11715             : This algorithm solves system of nonlinear equations
   11716             :     F[0](x[0], ..., x[n-1])   = 0
   11717             :     F[1](x[0], ..., x[n-1])   = 0
   11718             :     ...
   11719             :     F[M-1](x[0], ..., x[n-1]) = 0
   11720             : with M/N do not necessarily coincide.  Algorithm  converges  quadratically
   11721             : under following conditions:
   11722             :     * the solution set XS is nonempty
   11723             :     * for some xs in XS there exist such neighbourhood N(xs) that:
   11724             :       * vector function F(x) and its Jacobian J(x) are continuously
   11725             :         differentiable on N
   11726             :       * ||F(x)|| provides local error bound on N, i.e. there  exists  such
   11727             :         c1, that ||F(x)||>c1*distance(x,XS)
   11728             : Note that these conditions are much more weaker than usual non-singularity
   11729             : conditions. For example, algorithm will converge for any  affine  function
   11730             : F (whether its Jacobian singular or not).
   11731             : 
   11732             : 
   11733             : REQUIREMENTS:
   11734             : Algorithm will request following information during its operation:
   11735             : * function vector F[] and Jacobian matrix at given point X
   11736             : * value of merit function f(x)=F[0]^2(x)+...+F[M-1]^2(x) at given point X
   11737             : 
   11738             : 
   11739             : USAGE:
   11740             : 1. User initializes algorithm state with NLEQCreateLM() call
   11741             : 2. User tunes solver parameters with  NLEQSetCond(),  NLEQSetStpMax()  and
   11742             :    other functions
   11743             : 3. User  calls  NLEQSolve()  function  which  takes  algorithm  state  and
   11744             :    pointers (delegates, etc.) to callback functions which calculate  merit
   11745             :    function value and Jacobian.
   11746             : 4. User calls NLEQResults() to get solution
   11747             : 5. Optionally, user may call NLEQRestartFrom() to  solve  another  problem
   11748             :    with same parameters (N/M) but another starting  point  and/or  another
   11749             :    function vector. NLEQRestartFrom() allows to reuse already  initialized
   11750             :    structure.
   11751             : 
   11752             : 
   11753             : INPUT PARAMETERS:
   11754             :     N       -   space dimension, N>1:
   11755             :                 * if provided, only leading N elements of X are used
   11756             :                 * if not provided, determined automatically from size of X
   11757             :     M       -   system size
   11758             :     X       -   starting point
   11759             : 
   11760             : 
   11761             : OUTPUT PARAMETERS:
   11762             :     State   -   structure which stores algorithm state
   11763             : 
   11764             : 
   11765             : NOTES:
   11766             : 1. you may tune stopping conditions with NLEQSetCond() function
   11767             : 2. if target function contains exp() or other fast growing functions,  and
   11768             :    optimization algorithm makes too large steps which leads  to  overflow,
   11769             :    use NLEQSetStpMax() function to bound algorithm's steps.
   11770             : 3. this  algorithm  is  a  slightly  modified implementation of the method
   11771             :    described  in  'Levenberg-Marquardt  method  for constrained  nonlinear
   11772             :    equations with strong local convergence properties' by Christian Kanzow
   11773             :    Nobuo Yamashita and Masao Fukushima and further  developed  in  'On the
   11774             :    convergence of a New Levenberg-Marquardt Method'  by  Jin-yan  Fan  and
   11775             :    Ya-Xiang Yuan.
   11776             : 
   11777             : 
   11778             :   -- ALGLIB --
   11779             :      Copyright 20.08.2009 by Bochkanov Sergey
   11780             : *************************************************************************/
   11781           0 : void nleqcreatelm(ae_int_t n,
   11782             :      ae_int_t m,
   11783             :      /* Real    */ ae_vector* x,
   11784             :      nleqstate* state,
   11785             :      ae_state *_state)
   11786             : {
   11787             : 
   11788           0 :     _nleqstate_clear(state);
   11789             : 
   11790           0 :     ae_assert(n>=1, "NLEQCreateLM: N<1!", _state);
   11791           0 :     ae_assert(m>=1, "NLEQCreateLM: M<1!", _state);
   11792           0 :     ae_assert(x->cnt>=n, "NLEQCreateLM: Length(X)<N!", _state);
   11793           0 :     ae_assert(isfinitevector(x, n, _state), "NLEQCreateLM: X contains infinite or NaN values!", _state);
   11794             :     
   11795             :     /*
   11796             :      * Initialize
   11797             :      */
   11798           0 :     state->n = n;
   11799           0 :     state->m = m;
   11800           0 :     nleqsetcond(state, (double)(0), 0, _state);
   11801           0 :     nleqsetxrep(state, ae_false, _state);
   11802           0 :     nleqsetstpmax(state, (double)(0), _state);
   11803           0 :     ae_vector_set_length(&state->x, n, _state);
   11804           0 :     ae_vector_set_length(&state->xbase, n, _state);
   11805           0 :     ae_matrix_set_length(&state->j, m, n, _state);
   11806           0 :     ae_vector_set_length(&state->fi, m, _state);
   11807           0 :     ae_vector_set_length(&state->rightpart, n, _state);
   11808           0 :     ae_vector_set_length(&state->candstep, n, _state);
   11809           0 :     nleqrestartfrom(state, x, _state);
   11810           0 : }
   11811             : 
   11812             : 
   11813             : /*************************************************************************
   11814             : This function sets stopping conditions for the nonlinear solver
   11815             : 
   11816             : INPUT PARAMETERS:
   11817             :     State   -   structure which stores algorithm state
   11818             :     EpsF    -   >=0
   11819             :                 The subroutine finishes  its work if on k+1-th iteration
   11820             :                 the condition ||F||<=EpsF is satisfied
   11821             :     MaxIts  -   maximum number of iterations. If MaxIts=0, the  number  of
   11822             :                 iterations is unlimited.
   11823             : 
   11824             : Passing EpsF=0 and MaxIts=0 simultaneously will lead to  automatic
   11825             : stopping criterion selection (small EpsF).
   11826             : 
   11827             : NOTES:
   11828             : 
   11829             :   -- ALGLIB --
   11830             :      Copyright 20.08.2010 by Bochkanov Sergey
   11831             : *************************************************************************/
   11832           0 : void nleqsetcond(nleqstate* state,
   11833             :      double epsf,
   11834             :      ae_int_t maxits,
   11835             :      ae_state *_state)
   11836             : {
   11837             : 
   11838             : 
   11839           0 :     ae_assert(ae_isfinite(epsf, _state), "NLEQSetCond: EpsF is not finite number!", _state);
   11840           0 :     ae_assert(ae_fp_greater_eq(epsf,(double)(0)), "NLEQSetCond: negative EpsF!", _state);
   11841           0 :     ae_assert(maxits>=0, "NLEQSetCond: negative MaxIts!", _state);
   11842           0 :     if( ae_fp_eq(epsf,(double)(0))&&maxits==0 )
   11843             :     {
   11844           0 :         epsf = 1.0E-6;
   11845             :     }
   11846           0 :     state->epsf = epsf;
   11847           0 :     state->maxits = maxits;
   11848           0 : }
   11849             : 
   11850             : 
   11851             : /*************************************************************************
   11852             : This function turns on/off reporting.
   11853             : 
   11854             : INPUT PARAMETERS:
   11855             :     State   -   structure which stores algorithm state
   11856             :     NeedXRep-   whether iteration reports are needed or not
   11857             : 
   11858             : If NeedXRep is True, algorithm will call rep() callback function if  it is
   11859             : provided to NLEQSolve().
   11860             : 
   11861             :   -- ALGLIB --
   11862             :      Copyright 20.08.2010 by Bochkanov Sergey
   11863             : *************************************************************************/
   11864           0 : void nleqsetxrep(nleqstate* state, ae_bool needxrep, ae_state *_state)
   11865             : {
   11866             : 
   11867             : 
   11868           0 :     state->xrep = needxrep;
   11869           0 : }
   11870             : 
   11871             : 
   11872             : /*************************************************************************
   11873             : This function sets maximum step length
   11874             : 
   11875             : INPUT PARAMETERS:
   11876             :     State   -   structure which stores algorithm state
   11877             :     StpMax  -   maximum step length, >=0. Set StpMax to 0.0,  if you don't
   11878             :                 want to limit step length.
   11879             : 
   11880             : Use this subroutine when target function  contains  exp()  or  other  fast
   11881             : growing functions, and algorithm makes  too  large  steps  which  lead  to
   11882             : overflow. This function allows us to reject steps that are too large  (and
   11883             : therefore expose us to the possible overflow) without actually calculating
   11884             : function value at the x+stp*d.
   11885             : 
   11886             :   -- ALGLIB --
   11887             :      Copyright 20.08.2010 by Bochkanov Sergey
   11888             : *************************************************************************/
   11889           0 : void nleqsetstpmax(nleqstate* state, double stpmax, ae_state *_state)
   11890             : {
   11891             : 
   11892             : 
   11893           0 :     ae_assert(ae_isfinite(stpmax, _state), "NLEQSetStpMax: StpMax is not finite!", _state);
   11894           0 :     ae_assert(ae_fp_greater_eq(stpmax,(double)(0)), "NLEQSetStpMax: StpMax<0!", _state);
   11895           0 :     state->stpmax = stpmax;
   11896           0 : }
   11897             : 
   11898             : 
   11899             : /*************************************************************************
   11900             : 
   11901             :   -- ALGLIB --
   11902             :      Copyright 20.03.2009 by Bochkanov Sergey
   11903             : *************************************************************************/
   11904           0 : ae_bool nleqiteration(nleqstate* state, ae_state *_state)
   11905             : {
   11906             :     ae_int_t n;
   11907             :     ae_int_t m;
   11908             :     ae_int_t i;
   11909             :     double lambdaup;
   11910             :     double lambdadown;
   11911             :     double lambdav;
   11912             :     double rho;
   11913             :     double mu;
   11914             :     double stepnorm;
   11915             :     ae_bool b;
   11916             :     ae_bool result;
   11917             : 
   11918             : 
   11919             :     
   11920             :     /*
   11921             :      * Reverse communication preparations
   11922             :      * I know it looks ugly, but it works the same way
   11923             :      * anywhere from C++ to Python.
   11924             :      *
   11925             :      * This code initializes locals by:
   11926             :      * * random values determined during code
   11927             :      *   generation - on first subroutine call
   11928             :      * * values from previous call - on subsequent calls
   11929             :      */
   11930           0 :     if( state->rstate.stage>=0 )
   11931             :     {
   11932           0 :         n = state->rstate.ia.ptr.p_int[0];
   11933           0 :         m = state->rstate.ia.ptr.p_int[1];
   11934           0 :         i = state->rstate.ia.ptr.p_int[2];
   11935           0 :         b = state->rstate.ba.ptr.p_bool[0];
   11936           0 :         lambdaup = state->rstate.ra.ptr.p_double[0];
   11937           0 :         lambdadown = state->rstate.ra.ptr.p_double[1];
   11938           0 :         lambdav = state->rstate.ra.ptr.p_double[2];
   11939           0 :         rho = state->rstate.ra.ptr.p_double[3];
   11940           0 :         mu = state->rstate.ra.ptr.p_double[4];
   11941           0 :         stepnorm = state->rstate.ra.ptr.p_double[5];
   11942             :     }
   11943             :     else
   11944             :     {
   11945           0 :         n = 359;
   11946           0 :         m = -58;
   11947           0 :         i = -919;
   11948           0 :         b = ae_true;
   11949           0 :         lambdaup = 81;
   11950           0 :         lambdadown = 255;
   11951           0 :         lambdav = 74;
   11952           0 :         rho = -788;
   11953           0 :         mu = 809;
   11954           0 :         stepnorm = 205;
   11955             :     }
   11956           0 :     if( state->rstate.stage==0 )
   11957             :     {
   11958           0 :         goto lbl_0;
   11959             :     }
   11960           0 :     if( state->rstate.stage==1 )
   11961             :     {
   11962           0 :         goto lbl_1;
   11963             :     }
   11964           0 :     if( state->rstate.stage==2 )
   11965             :     {
   11966           0 :         goto lbl_2;
   11967             :     }
   11968           0 :     if( state->rstate.stage==3 )
   11969             :     {
   11970           0 :         goto lbl_3;
   11971             :     }
   11972           0 :     if( state->rstate.stage==4 )
   11973             :     {
   11974           0 :         goto lbl_4;
   11975             :     }
   11976             :     
   11977             :     /*
   11978             :      * Routine body
   11979             :      */
   11980             :     
   11981             :     /*
   11982             :      * Prepare
   11983             :      */
   11984           0 :     n = state->n;
   11985           0 :     m = state->m;
   11986           0 :     state->repterminationtype = 0;
   11987           0 :     state->repiterationscount = 0;
   11988           0 :     state->repnfunc = 0;
   11989           0 :     state->repnjac = 0;
   11990             :     
   11991             :     /*
   11992             :      * Calculate F/G, initialize algorithm
   11993             :      */
   11994           0 :     nleq_clearrequestfields(state, _state);
   11995           0 :     state->needf = ae_true;
   11996           0 :     state->rstate.stage = 0;
   11997           0 :     goto lbl_rcomm;
   11998           0 : lbl_0:
   11999           0 :     state->needf = ae_false;
   12000           0 :     state->repnfunc = state->repnfunc+1;
   12001           0 :     ae_v_move(&state->xbase.ptr.p_double[0], 1, &state->x.ptr.p_double[0], 1, ae_v_len(0,n-1));
   12002           0 :     state->fbase = state->f;
   12003           0 :     state->fprev = ae_maxrealnumber;
   12004           0 :     if( !state->xrep )
   12005             :     {
   12006           0 :         goto lbl_5;
   12007             :     }
   12008             :     
   12009             :     /*
   12010             :      * progress report
   12011             :      */
   12012           0 :     nleq_clearrequestfields(state, _state);
   12013           0 :     state->xupdated = ae_true;
   12014           0 :     state->rstate.stage = 1;
   12015           0 :     goto lbl_rcomm;
   12016           0 : lbl_1:
   12017           0 :     state->xupdated = ae_false;
   12018           0 : lbl_5:
   12019           0 :     if( ae_fp_less_eq(state->f,ae_sqr(state->epsf, _state)) )
   12020             :     {
   12021           0 :         state->repterminationtype = 1;
   12022           0 :         result = ae_false;
   12023           0 :         return result;
   12024             :     }
   12025             :     
   12026             :     /*
   12027             :      * Main cycle
   12028             :      */
   12029           0 :     lambdaup = (double)(10);
   12030           0 :     lambdadown = 0.3;
   12031           0 :     lambdav = 0.001;
   12032           0 :     rho = (double)(1);
   12033           0 : lbl_7:
   12034             :     if( ae_false )
   12035             :     {
   12036             :         goto lbl_8;
   12037             :     }
   12038             :     
   12039             :     /*
   12040             :      * Get Jacobian;
   12041             :      * before we get to this point we already have State.XBase filled
   12042             :      * with current point and State.FBase filled with function value
   12043             :      * at XBase
   12044             :      */
   12045           0 :     nleq_clearrequestfields(state, _state);
   12046           0 :     state->needfij = ae_true;
   12047           0 :     ae_v_move(&state->x.ptr.p_double[0], 1, &state->xbase.ptr.p_double[0], 1, ae_v_len(0,n-1));
   12048           0 :     state->rstate.stage = 2;
   12049           0 :     goto lbl_rcomm;
   12050           0 : lbl_2:
   12051           0 :     state->needfij = ae_false;
   12052           0 :     state->repnfunc = state->repnfunc+1;
   12053           0 :     state->repnjac = state->repnjac+1;
   12054           0 :     rmatrixmv(n, m, &state->j, 0, 0, 1, &state->fi, 0, &state->rightpart, 0, _state);
   12055           0 :     ae_v_muld(&state->rightpart.ptr.p_double[0], 1, ae_v_len(0,n-1), -1);
   12056             :     
   12057             :     /*
   12058             :      * Inner cycle: find good lambda
   12059             :      */
   12060           0 : lbl_9:
   12061             :     if( ae_false )
   12062             :     {
   12063             :         goto lbl_10;
   12064             :     }
   12065             :     
   12066             :     /*
   12067             :      * Solve (J^T*J + (Lambda+Mu)*I)*y = J^T*F
   12068             :      * to get step d=-y where:
   12069             :      * * Mu=||F|| - is damping parameter for nonlinear system
   12070             :      * * Lambda   - is additional Levenberg-Marquardt parameter
   12071             :      *              for better convergence when far away from minimum
   12072             :      */
   12073           0 :     for(i=0; i<=n-1; i++)
   12074             :     {
   12075           0 :         state->candstep.ptr.p_double[i] = (double)(0);
   12076             :     }
   12077           0 :     fblssolvecgx(&state->j, m, n, lambdav, &state->rightpart, &state->candstep, &state->cgbuf, _state);
   12078             :     
   12079             :     /*
   12080             :      * Normalize step (it must be no more than StpMax)
   12081             :      */
   12082           0 :     stepnorm = (double)(0);
   12083           0 :     for(i=0; i<=n-1; i++)
   12084             :     {
   12085           0 :         if( ae_fp_neq(state->candstep.ptr.p_double[i],(double)(0)) )
   12086             :         {
   12087           0 :             stepnorm = (double)(1);
   12088           0 :             break;
   12089             :         }
   12090             :     }
   12091           0 :     linminnormalized(&state->candstep, &stepnorm, n, _state);
   12092           0 :     if( ae_fp_neq(state->stpmax,(double)(0)) )
   12093             :     {
   12094           0 :         stepnorm = ae_minreal(stepnorm, state->stpmax, _state);
   12095             :     }
   12096             :     
   12097             :     /*
   12098             :      * Test new step - is it good enough?
   12099             :      * * if not, Lambda is increased and we try again.
   12100             :      * * if step is good, we decrease Lambda and move on.
   12101             :      *
   12102             :      * We can break this cycle on two occasions:
   12103             :      * * step is so small that x+step==x (in floating point arithmetics)
   12104             :      * * lambda is so large
   12105             :      */
   12106           0 :     ae_v_move(&state->x.ptr.p_double[0], 1, &state->xbase.ptr.p_double[0], 1, ae_v_len(0,n-1));
   12107           0 :     ae_v_addd(&state->x.ptr.p_double[0], 1, &state->candstep.ptr.p_double[0], 1, ae_v_len(0,n-1), stepnorm);
   12108           0 :     b = ae_true;
   12109           0 :     for(i=0; i<=n-1; i++)
   12110             :     {
   12111           0 :         if( ae_fp_neq(state->x.ptr.p_double[i],state->xbase.ptr.p_double[i]) )
   12112             :         {
   12113           0 :             b = ae_false;
   12114           0 :             break;
   12115             :         }
   12116             :     }
   12117           0 :     if( b )
   12118             :     {
   12119             :         
   12120             :         /*
   12121             :          * Step is too small, force zero step and break
   12122             :          */
   12123           0 :         stepnorm = (double)(0);
   12124           0 :         ae_v_move(&state->x.ptr.p_double[0], 1, &state->xbase.ptr.p_double[0], 1, ae_v_len(0,n-1));
   12125           0 :         state->f = state->fbase;
   12126           0 :         goto lbl_10;
   12127             :     }
   12128           0 :     nleq_clearrequestfields(state, _state);
   12129           0 :     state->needf = ae_true;
   12130           0 :     state->rstate.stage = 3;
   12131           0 :     goto lbl_rcomm;
   12132           0 : lbl_3:
   12133           0 :     state->needf = ae_false;
   12134           0 :     state->repnfunc = state->repnfunc+1;
   12135           0 :     if( ae_fp_less(state->f,state->fbase) )
   12136             :     {
   12137             :         
   12138             :         /*
   12139             :          * function value decreased, move on
   12140             :          */
   12141           0 :         nleq_decreaselambda(&lambdav, &rho, lambdadown, _state);
   12142           0 :         goto lbl_10;
   12143             :     }
   12144           0 :     if( !nleq_increaselambda(&lambdav, &rho, lambdaup, _state) )
   12145             :     {
   12146             :         
   12147             :         /*
   12148             :          * Lambda is too large (near overflow), force zero step and break
   12149             :          */
   12150           0 :         stepnorm = (double)(0);
   12151           0 :         ae_v_move(&state->x.ptr.p_double[0], 1, &state->xbase.ptr.p_double[0], 1, ae_v_len(0,n-1));
   12152           0 :         state->f = state->fbase;
   12153           0 :         goto lbl_10;
   12154             :     }
   12155           0 :     goto lbl_9;
   12156           0 : lbl_10:
   12157             :     
   12158             :     /*
   12159             :      * Accept step:
   12160             :      * * new position
   12161             :      * * new function value
   12162             :      */
   12163           0 :     state->fbase = state->f;
   12164           0 :     ae_v_addd(&state->xbase.ptr.p_double[0], 1, &state->candstep.ptr.p_double[0], 1, ae_v_len(0,n-1), stepnorm);
   12165           0 :     state->repiterationscount = state->repiterationscount+1;
   12166             :     
   12167             :     /*
   12168             :      * Report new iteration
   12169             :      */
   12170           0 :     if( !state->xrep )
   12171             :     {
   12172           0 :         goto lbl_11;
   12173             :     }
   12174           0 :     nleq_clearrequestfields(state, _state);
   12175           0 :     state->xupdated = ae_true;
   12176           0 :     state->f = state->fbase;
   12177           0 :     ae_v_move(&state->x.ptr.p_double[0], 1, &state->xbase.ptr.p_double[0], 1, ae_v_len(0,n-1));
   12178           0 :     state->rstate.stage = 4;
   12179           0 :     goto lbl_rcomm;
   12180           0 : lbl_4:
   12181           0 :     state->xupdated = ae_false;
   12182           0 : lbl_11:
   12183             :     
   12184             :     /*
   12185             :      * Test stopping conditions on F, step (zero/non-zero) and MaxIts;
   12186             :      * If one of the conditions is met, RepTerminationType is changed.
   12187             :      */
   12188           0 :     if( ae_fp_less_eq(ae_sqrt(state->f, _state),state->epsf) )
   12189             :     {
   12190           0 :         state->repterminationtype = 1;
   12191             :     }
   12192           0 :     if( ae_fp_eq(stepnorm,(double)(0))&&state->repterminationtype==0 )
   12193             :     {
   12194           0 :         state->repterminationtype = -4;
   12195             :     }
   12196           0 :     if( state->repiterationscount>=state->maxits&&state->maxits>0 )
   12197             :     {
   12198           0 :         state->repterminationtype = 5;
   12199             :     }
   12200           0 :     if( state->repterminationtype!=0 )
   12201             :     {
   12202           0 :         goto lbl_8;
   12203             :     }
   12204             :     
   12205             :     /*
   12206             :      * Now, iteration is finally over
   12207             :      */
   12208           0 :     goto lbl_7;
   12209           0 : lbl_8:
   12210           0 :     result = ae_false;
   12211           0 :     return result;
   12212             :     
   12213             :     /*
   12214             :      * Saving state
   12215             :      */
   12216           0 : lbl_rcomm:
   12217           0 :     result = ae_true;
   12218           0 :     state->rstate.ia.ptr.p_int[0] = n;
   12219           0 :     state->rstate.ia.ptr.p_int[1] = m;
   12220           0 :     state->rstate.ia.ptr.p_int[2] = i;
   12221           0 :     state->rstate.ba.ptr.p_bool[0] = b;
   12222           0 :     state->rstate.ra.ptr.p_double[0] = lambdaup;
   12223           0 :     state->rstate.ra.ptr.p_double[1] = lambdadown;
   12224           0 :     state->rstate.ra.ptr.p_double[2] = lambdav;
   12225           0 :     state->rstate.ra.ptr.p_double[3] = rho;
   12226           0 :     state->rstate.ra.ptr.p_double[4] = mu;
   12227           0 :     state->rstate.ra.ptr.p_double[5] = stepnorm;
   12228           0 :     return result;
   12229             : }
   12230             : 
   12231             : 
   12232             : /*************************************************************************
   12233             : NLEQ solver results
   12234             : 
   12235             : INPUT PARAMETERS:
   12236             :     State   -   algorithm state.
   12237             : 
   12238             : OUTPUT PARAMETERS:
   12239             :     X       -   array[0..N-1], solution
   12240             :     Rep     -   optimization report:
   12241             :                 * Rep.TerminationType completetion code:
   12242             :                     * -4    ERROR:  algorithm   has   converged   to   the
   12243             :                             stationary point Xf which is local minimum  of
   12244             :                             f=F[0]^2+...+F[m-1]^2, but is not solution  of
   12245             :                             nonlinear system.
   12246             :                     *  1    sqrt(f)<=EpsF.
   12247             :                     *  5    MaxIts steps was taken
   12248             :                     *  7    stopping conditions are too stringent,
   12249             :                             further improvement is impossible
   12250             :                 * Rep.IterationsCount contains iterations count
   12251             :                 * NFEV countains number of function calculations
   12252             :                 * ActiveConstraints contains number of active constraints
   12253             : 
   12254             :   -- ALGLIB --
   12255             :      Copyright 20.08.2009 by Bochkanov Sergey
   12256             : *************************************************************************/
   12257           0 : void nleqresults(nleqstate* state,
   12258             :      /* Real    */ ae_vector* x,
   12259             :      nleqreport* rep,
   12260             :      ae_state *_state)
   12261             : {
   12262             : 
   12263           0 :     ae_vector_clear(x);
   12264           0 :     _nleqreport_clear(rep);
   12265             : 
   12266           0 :     nleqresultsbuf(state, x, rep, _state);
   12267           0 : }
   12268             : 
   12269             : 
   12270             : /*************************************************************************
   12271             : NLEQ solver results
   12272             : 
   12273             : Buffered implementation of NLEQResults(), which uses pre-allocated  buffer
   12274             : to store X[]. If buffer size is  too  small,  it  resizes  buffer.  It  is
   12275             : intended to be used in the inner cycles of performance critical algorithms
   12276             : where array reallocation penalty is too large to be ignored.
   12277             : 
   12278             :   -- ALGLIB --
   12279             :      Copyright 20.08.2009 by Bochkanov Sergey
   12280             : *************************************************************************/
   12281           0 : void nleqresultsbuf(nleqstate* state,
   12282             :      /* Real    */ ae_vector* x,
   12283             :      nleqreport* rep,
   12284             :      ae_state *_state)
   12285             : {
   12286             : 
   12287             : 
   12288           0 :     if( x->cnt<state->n )
   12289             :     {
   12290           0 :         ae_vector_set_length(x, state->n, _state);
   12291             :     }
   12292           0 :     ae_v_move(&x->ptr.p_double[0], 1, &state->xbase.ptr.p_double[0], 1, ae_v_len(0,state->n-1));
   12293           0 :     rep->iterationscount = state->repiterationscount;
   12294           0 :     rep->nfunc = state->repnfunc;
   12295           0 :     rep->njac = state->repnjac;
   12296           0 :     rep->terminationtype = state->repterminationtype;
   12297           0 : }
   12298             : 
   12299             : 
   12300             : /*************************************************************************
   12301             : This  subroutine  restarts  CG  algorithm from new point. All optimization
   12302             : parameters are left unchanged.
   12303             : 
   12304             : This  function  allows  to  solve multiple  optimization  problems  (which
   12305             : must have same number of dimensions) without object reallocation penalty.
   12306             : 
   12307             : INPUT PARAMETERS:
   12308             :     State   -   structure used for reverse communication previously
   12309             :                 allocated with MinCGCreate call.
   12310             :     X       -   new starting point.
   12311             :     BndL    -   new lower bounds
   12312             :     BndU    -   new upper bounds
   12313             : 
   12314             :   -- ALGLIB --
   12315             :      Copyright 30.07.2010 by Bochkanov Sergey
   12316             : *************************************************************************/
   12317           0 : void nleqrestartfrom(nleqstate* state,
   12318             :      /* Real    */ ae_vector* x,
   12319             :      ae_state *_state)
   12320             : {
   12321             : 
   12322             : 
   12323           0 :     ae_assert(x->cnt>=state->n, "NLEQRestartFrom: Length(X)<N!", _state);
   12324           0 :     ae_assert(isfinitevector(x, state->n, _state), "NLEQRestartFrom: X contains infinite or NaN values!", _state);
   12325           0 :     ae_v_move(&state->x.ptr.p_double[0], 1, &x->ptr.p_double[0], 1, ae_v_len(0,state->n-1));
   12326           0 :     ae_vector_set_length(&state->rstate.ia, 2+1, _state);
   12327           0 :     ae_vector_set_length(&state->rstate.ba, 0+1, _state);
   12328           0 :     ae_vector_set_length(&state->rstate.ra, 5+1, _state);
   12329           0 :     state->rstate.stage = -1;
   12330           0 :     nleq_clearrequestfields(state, _state);
   12331           0 : }
   12332             : 
   12333             : 
   12334             : /*************************************************************************
   12335             : Clears request fileds (to be sure that we don't forgot to clear something)
   12336             : *************************************************************************/
   12337           0 : static void nleq_clearrequestfields(nleqstate* state, ae_state *_state)
   12338             : {
   12339             : 
   12340             : 
   12341           0 :     state->needf = ae_false;
   12342           0 :     state->needfij = ae_false;
   12343           0 :     state->xupdated = ae_false;
   12344           0 : }
   12345             : 
   12346             : 
   12347             : /*************************************************************************
   12348             : Increases lambda, returns False when there is a danger of overflow
   12349             : *************************************************************************/
   12350           0 : static ae_bool nleq_increaselambda(double* lambdav,
   12351             :      double* nu,
   12352             :      double lambdaup,
   12353             :      ae_state *_state)
   12354             : {
   12355             :     double lnlambda;
   12356             :     double lnnu;
   12357             :     double lnlambdaup;
   12358             :     double lnmax;
   12359             :     ae_bool result;
   12360             : 
   12361             : 
   12362           0 :     result = ae_false;
   12363           0 :     lnlambda = ae_log(*lambdav, _state);
   12364           0 :     lnlambdaup = ae_log(lambdaup, _state);
   12365           0 :     lnnu = ae_log(*nu, _state);
   12366           0 :     lnmax = 0.5*ae_log(ae_maxrealnumber, _state);
   12367           0 :     if( ae_fp_greater(lnlambda+lnlambdaup+lnnu,lnmax) )
   12368             :     {
   12369           0 :         return result;
   12370             :     }
   12371           0 :     if( ae_fp_greater(lnnu+ae_log((double)(2), _state),lnmax) )
   12372             :     {
   12373           0 :         return result;
   12374             :     }
   12375           0 :     *lambdav = *lambdav*lambdaup*(*nu);
   12376           0 :     *nu = *nu*2;
   12377           0 :     result = ae_true;
   12378           0 :     return result;
   12379             : }
   12380             : 
   12381             : 
   12382             : /*************************************************************************
   12383             : Decreases lambda, but leaves it unchanged when there is danger of underflow.
   12384             : *************************************************************************/
   12385           0 : static void nleq_decreaselambda(double* lambdav,
   12386             :      double* nu,
   12387             :      double lambdadown,
   12388             :      ae_state *_state)
   12389             : {
   12390             : 
   12391             : 
   12392           0 :     *nu = (double)(1);
   12393           0 :     if( ae_fp_less(ae_log(*lambdav, _state)+ae_log(lambdadown, _state),ae_log(ae_minrealnumber, _state)) )
   12394             :     {
   12395           0 :         *lambdav = ae_minrealnumber;
   12396             :     }
   12397             :     else
   12398             :     {
   12399           0 :         *lambdav = *lambdav*lambdadown;
   12400             :     }
   12401           0 : }
   12402             : 
   12403             : 
   12404           0 : void _nleqstate_init(void* _p, ae_state *_state, ae_bool make_automatic)
   12405             : {
   12406           0 :     nleqstate *p = (nleqstate*)_p;
   12407           0 :     ae_touch_ptr((void*)p);
   12408           0 :     ae_vector_init(&p->x, 0, DT_REAL, _state, make_automatic);
   12409           0 :     ae_vector_init(&p->fi, 0, DT_REAL, _state, make_automatic);
   12410           0 :     ae_matrix_init(&p->j, 0, 0, DT_REAL, _state, make_automatic);
   12411           0 :     _rcommstate_init(&p->rstate, _state, make_automatic);
   12412           0 :     ae_vector_init(&p->xbase, 0, DT_REAL, _state, make_automatic);
   12413           0 :     ae_vector_init(&p->candstep, 0, DT_REAL, _state, make_automatic);
   12414           0 :     ae_vector_init(&p->rightpart, 0, DT_REAL, _state, make_automatic);
   12415           0 :     ae_vector_init(&p->cgbuf, 0, DT_REAL, _state, make_automatic);
   12416           0 : }
   12417             : 
   12418             : 
   12419           0 : void _nleqstate_init_copy(void* _dst, void* _src, ae_state *_state, ae_bool make_automatic)
   12420             : {
   12421           0 :     nleqstate *dst = (nleqstate*)_dst;
   12422           0 :     nleqstate *src = (nleqstate*)_src;
   12423           0 :     dst->n = src->n;
   12424           0 :     dst->m = src->m;
   12425           0 :     dst->epsf = src->epsf;
   12426           0 :     dst->maxits = src->maxits;
   12427           0 :     dst->xrep = src->xrep;
   12428           0 :     dst->stpmax = src->stpmax;
   12429           0 :     ae_vector_init_copy(&dst->x, &src->x, _state, make_automatic);
   12430           0 :     dst->f = src->f;
   12431           0 :     ae_vector_init_copy(&dst->fi, &src->fi, _state, make_automatic);
   12432           0 :     ae_matrix_init_copy(&dst->j, &src->j, _state, make_automatic);
   12433           0 :     dst->needf = src->needf;
   12434           0 :     dst->needfij = src->needfij;
   12435           0 :     dst->xupdated = src->xupdated;
   12436           0 :     _rcommstate_init_copy(&dst->rstate, &src->rstate, _state, make_automatic);
   12437           0 :     dst->repiterationscount = src->repiterationscount;
   12438           0 :     dst->repnfunc = src->repnfunc;
   12439           0 :     dst->repnjac = src->repnjac;
   12440           0 :     dst->repterminationtype = src->repterminationtype;
   12441           0 :     ae_vector_init_copy(&dst->xbase, &src->xbase, _state, make_automatic);
   12442           0 :     dst->fbase = src->fbase;
   12443           0 :     dst->fprev = src->fprev;
   12444           0 :     ae_vector_init_copy(&dst->candstep, &src->candstep, _state, make_automatic);
   12445           0 :     ae_vector_init_copy(&dst->rightpart, &src->rightpart, _state, make_automatic);
   12446           0 :     ae_vector_init_copy(&dst->cgbuf, &src->cgbuf, _state, make_automatic);
   12447           0 : }
   12448             : 
   12449             : 
   12450           0 : void _nleqstate_clear(void* _p)
   12451             : {
   12452           0 :     nleqstate *p = (nleqstate*)_p;
   12453           0 :     ae_touch_ptr((void*)p);
   12454           0 :     ae_vector_clear(&p->x);
   12455           0 :     ae_vector_clear(&p->fi);
   12456           0 :     ae_matrix_clear(&p->j);
   12457           0 :     _rcommstate_clear(&p->rstate);
   12458           0 :     ae_vector_clear(&p->xbase);
   12459           0 :     ae_vector_clear(&p->candstep);
   12460           0 :     ae_vector_clear(&p->rightpart);
   12461           0 :     ae_vector_clear(&p->cgbuf);
   12462           0 : }
   12463             : 
   12464             : 
   12465           0 : void _nleqstate_destroy(void* _p)
   12466             : {
   12467           0 :     nleqstate *p = (nleqstate*)_p;
   12468           0 :     ae_touch_ptr((void*)p);
   12469           0 :     ae_vector_destroy(&p->x);
   12470           0 :     ae_vector_destroy(&p->fi);
   12471           0 :     ae_matrix_destroy(&p->j);
   12472           0 :     _rcommstate_destroy(&p->rstate);
   12473           0 :     ae_vector_destroy(&p->xbase);
   12474           0 :     ae_vector_destroy(&p->candstep);
   12475           0 :     ae_vector_destroy(&p->rightpart);
   12476           0 :     ae_vector_destroy(&p->cgbuf);
   12477           0 : }
   12478             : 
   12479             : 
   12480           0 : void _nleqreport_init(void* _p, ae_state *_state, ae_bool make_automatic)
   12481             : {
   12482           0 :     nleqreport *p = (nleqreport*)_p;
   12483           0 :     ae_touch_ptr((void*)p);
   12484           0 : }
   12485             : 
   12486             : 
   12487           0 : void _nleqreport_init_copy(void* _dst, void* _src, ae_state *_state, ae_bool make_automatic)
   12488             : {
   12489           0 :     nleqreport *dst = (nleqreport*)_dst;
   12490           0 :     nleqreport *src = (nleqreport*)_src;
   12491           0 :     dst->iterationscount = src->iterationscount;
   12492           0 :     dst->nfunc = src->nfunc;
   12493           0 :     dst->njac = src->njac;
   12494           0 :     dst->terminationtype = src->terminationtype;
   12495           0 : }
   12496             : 
   12497             : 
   12498           0 : void _nleqreport_clear(void* _p)
   12499             : {
   12500           0 :     nleqreport *p = (nleqreport*)_p;
   12501           0 :     ae_touch_ptr((void*)p);
   12502           0 : }
   12503             : 
   12504             : 
   12505           0 : void _nleqreport_destroy(void* _p)
   12506             : {
   12507           0 :     nleqreport *p = (nleqreport*)_p;
   12508           0 :     ae_touch_ptr((void*)p);
   12509           0 : }
   12510             : 
   12511             : 
   12512             : #endif
   12513             : #if defined(AE_COMPILE_DIRECTSPARSESOLVERS) || !defined(AE_PARTIAL_BUILD)
   12514             : 
   12515             : 
   12516             : /*************************************************************************
   12517             : Sparse linear solver for A*x=b with N*N  sparse  real  symmetric  positive
   12518             : definite matrix A, N*1 vectors x and b.
   12519             : 
   12520             : This solver  converts  input  matrix  to  SKS  format,  performs  Cholesky
   12521             : factorization using  SKS  Cholesky  subroutine  (works  well  for  limited
   12522             : bandwidth matrices) and uses sparse triangular solvers to get solution  of
   12523             : the original system.
   12524             : 
   12525             : INPUT PARAMETERS
   12526             :     A       -   sparse matrix, must be NxN exactly
   12527             :     IsUpper -   which half of A is provided (another half is ignored)
   12528             :     B       -   array[0..N-1], right part
   12529             : 
   12530             : OUTPUT PARAMETERS
   12531             :     X       -   array[N], it contains:
   12532             :                 * rep.terminationtype>0    =>  solution
   12533             :                 * rep.terminationtype=-3   =>  filled by zeros
   12534             :     Rep     -   solver report, following fields are set:
   12535             :                 * rep.terminationtype - solver status; >0 for success,
   12536             :                   set to -3 on failure (degenerate or non-SPD system).
   12537             : 
   12538             :   -- ALGLIB --
   12539             :      Copyright 26.12.2017 by Bochkanov Sergey
   12540             : *************************************************************************/
   12541           0 : void sparsespdsolvesks(sparsematrix* a,
   12542             :      ae_bool isupper,
   12543             :      /* Real    */ ae_vector* b,
   12544             :      /* Real    */ ae_vector* x,
   12545             :      sparsesolverreport* rep,
   12546             :      ae_state *_state)
   12547             : {
   12548             :     ae_frame _frame_block;
   12549             :     ae_int_t i;
   12550             :     sparsematrix a2;
   12551             :     ae_int_t n;
   12552             : 
   12553           0 :     ae_frame_make(_state, &_frame_block);
   12554           0 :     memset(&a2, 0, sizeof(a2));
   12555           0 :     ae_vector_clear(x);
   12556           0 :     _sparsesolverreport_clear(rep);
   12557           0 :     _sparsematrix_init(&a2, _state, ae_true);
   12558             : 
   12559           0 :     n = sparsegetnrows(a, _state);
   12560           0 :     ae_assert(n>0, "SparseSPDSolveSKS: N<=0", _state);
   12561           0 :     ae_assert(sparsegetnrows(a, _state)==n, "SparseSPDSolveSKS: rows(A)!=N", _state);
   12562           0 :     ae_assert(sparsegetncols(a, _state)==n, "SparseSPDSolveSKS: cols(A)!=N", _state);
   12563           0 :     ae_assert(b->cnt>=n, "SparseSPDSolveSKS: length(B)<N", _state);
   12564           0 :     ae_assert(isfinitevector(b, n, _state), "SparseSPDSolveSKS: B contains infinities or NANs", _state);
   12565           0 :     directsparsesolvers_initreport(rep, _state);
   12566           0 :     ae_vector_set_length(x, n, _state);
   12567           0 :     sparsecopytosks(a, &a2, _state);
   12568           0 :     if( !sparsecholeskyskyline(&a2, n, isupper, _state) )
   12569             :     {
   12570           0 :         rep->terminationtype = -3;
   12571           0 :         for(i=0; i<=n-1; i++)
   12572             :         {
   12573           0 :             x->ptr.p_double[i] = (double)(0);
   12574             :         }
   12575           0 :         ae_frame_leave(_state);
   12576           0 :         return;
   12577             :     }
   12578           0 :     for(i=0; i<=n-1; i++)
   12579             :     {
   12580           0 :         x->ptr.p_double[i] = b->ptr.p_double[i];
   12581             :     }
   12582           0 :     if( isupper )
   12583             :     {
   12584           0 :         sparsetrsv(&a2, isupper, ae_false, 1, x, _state);
   12585           0 :         sparsetrsv(&a2, isupper, ae_false, 0, x, _state);
   12586             :     }
   12587             :     else
   12588             :     {
   12589           0 :         sparsetrsv(&a2, isupper, ae_false, 0, x, _state);
   12590           0 :         sparsetrsv(&a2, isupper, ae_false, 1, x, _state);
   12591             :     }
   12592           0 :     rep->terminationtype = 1;
   12593           0 :     ae_frame_leave(_state);
   12594             : }
   12595             : 
   12596             : 
   12597             : /*************************************************************************
   12598             : Sparse linear solver for A*x=b with N*N  sparse  real  symmetric  positive
   12599             : definite matrix A, N*1 vectors x and b.
   12600             : 
   12601             : This solver  converts  input  matrix  to  CRS  format,  performs  Cholesky
   12602             : factorization using supernodal Cholesky  decomposition  with  permutation-
   12603             : reducing ordering and uses sparse triangular solver to get solution of the
   12604             : original system.
   12605             : 
   12606             : INPUT PARAMETERS
   12607             :     A       -   sparse matrix, must be NxN exactly
   12608             :     IsUpper -   which half of A is provided (another half is ignored)
   12609             :     B       -   array[N], right part
   12610             : 
   12611             : OUTPUT PARAMETERS
   12612             :     X       -   array[N], it contains:
   12613             :                 * rep.terminationtype>0    =>  solution
   12614             :                 * rep.terminationtype=-3   =>  filled by zeros
   12615             :     Rep     -   solver report, following fields are set:
   12616             :                 * rep.terminationtype - solver status; >0 for success,
   12617             :                   set to -3 on failure (degenerate or non-SPD system).
   12618             : 
   12619             :   -- ALGLIB --
   12620             :      Copyright 26.12.2017 by Bochkanov Sergey
   12621             : *************************************************************************/
   12622           0 : void sparsespdsolve(sparsematrix* a,
   12623             :      ae_bool isupper,
   12624             :      /* Real    */ ae_vector* b,
   12625             :      /* Real    */ ae_vector* x,
   12626             :      sparsesolverreport* rep,
   12627             :      ae_state *_state)
   12628             : {
   12629             :     ae_frame _frame_block;
   12630             :     ae_int_t i;
   12631             :     ae_int_t j;
   12632             :     sparsematrix a2;
   12633             :     ae_int_t n;
   12634             :     double v;
   12635             :     ae_vector p;
   12636             : 
   12637           0 :     ae_frame_make(_state, &_frame_block);
   12638           0 :     memset(&a2, 0, sizeof(a2));
   12639           0 :     memset(&p, 0, sizeof(p));
   12640           0 :     ae_vector_clear(x);
   12641           0 :     _sparsesolverreport_clear(rep);
   12642           0 :     _sparsematrix_init(&a2, _state, ae_true);
   12643           0 :     ae_vector_init(&p, 0, DT_INT, _state, ae_true);
   12644             : 
   12645           0 :     n = sparsegetnrows(a, _state);
   12646           0 :     ae_assert(n>0, "SparseSPDSolve: N<=0", _state);
   12647           0 :     ae_assert(sparsegetnrows(a, _state)==n, "SparseSPDSolve: rows(A)!=N", _state);
   12648           0 :     ae_assert(sparsegetncols(a, _state)==n, "SparseSPDSolve: cols(A)!=N", _state);
   12649           0 :     ae_assert(b->cnt>=n, "SparseSPDSolve: length(B)<N", _state);
   12650           0 :     ae_assert(isfinitevector(b, n, _state), "SparseSPDSolve: B contains infinities or NANs", _state);
   12651           0 :     directsparsesolvers_initreport(rep, _state);
   12652           0 :     sparsecopytocrs(a, &a2, _state);
   12653           0 :     if( !sparsecholeskyp(&a2, isupper, &p, _state) )
   12654             :     {
   12655           0 :         rep->terminationtype = -3;
   12656           0 :         rsetallocv(n, 0.0, x, _state);
   12657           0 :         ae_frame_leave(_state);
   12658           0 :         return;
   12659             :     }
   12660           0 :     rcopyallocv(n, b, x, _state);
   12661           0 :     for(i=0; i<=n-1; i++)
   12662             :     {
   12663           0 :         j = p.ptr.p_int[i];
   12664           0 :         v = x->ptr.p_double[i];
   12665           0 :         x->ptr.p_double[i] = x->ptr.p_double[j];
   12666           0 :         x->ptr.p_double[j] = v;
   12667             :     }
   12668           0 :     if( isupper )
   12669             :     {
   12670           0 :         sparsetrsv(&a2, isupper, ae_false, 1, x, _state);
   12671           0 :         sparsetrsv(&a2, isupper, ae_false, 0, x, _state);
   12672             :     }
   12673             :     else
   12674             :     {
   12675           0 :         sparsetrsv(&a2, isupper, ae_false, 0, x, _state);
   12676           0 :         sparsetrsv(&a2, isupper, ae_false, 1, x, _state);
   12677             :     }
   12678           0 :     for(i=n-1; i>=0; i--)
   12679             :     {
   12680           0 :         j = p.ptr.p_int[i];
   12681           0 :         v = x->ptr.p_double[i];
   12682           0 :         x->ptr.p_double[i] = x->ptr.p_double[j];
   12683           0 :         x->ptr.p_double[j] = v;
   12684             :     }
   12685           0 :     rep->terminationtype = 1;
   12686           0 :     ae_frame_leave(_state);
   12687             : }
   12688             : 
   12689             : 
   12690             : /*************************************************************************
   12691             : Sparse linear solver for A*x=b with N*N real  symmetric  positive definite
   12692             : matrix A given by its Cholesky decomposition, and N*1 vectors x and b.
   12693             : 
   12694             : IMPORTANT: this solver requires input matrix to be in  the  SKS  (Skyline)
   12695             :            or CRS (compressed row storage) format. An  exception  will  be
   12696             :            generated if you pass matrix in some other format.
   12697             : 
   12698             : INPUT PARAMETERS
   12699             :     A       -   sparse NxN matrix stored in CRs or SKS format, must be NxN
   12700             :                 exactly
   12701             :     IsUpper -   which half of A is provided (another half is ignored)
   12702             :     B       -   array[N], right part
   12703             : 
   12704             : OUTPUT PARAMETERS
   12705             :     X       -   array[N], it contains:
   12706             :                 * rep.terminationtype>0    =>  solution
   12707             :                 * rep.terminationtype=-3   =>  filled by zeros
   12708             :     Rep     -   solver report, following fields are set:
   12709             :                 * rep.terminationtype - solver status; >0 for success,
   12710             :                   set to -3 on failure (degenerate or non-SPD system).
   12711             : 
   12712             :   -- ALGLIB --
   12713             :      Copyright 26.12.2017 by Bochkanov Sergey
   12714             : *************************************************************************/
   12715           0 : void sparsespdcholeskysolve(sparsematrix* a,
   12716             :      ae_bool isupper,
   12717             :      /* Real    */ ae_vector* b,
   12718             :      /* Real    */ ae_vector* x,
   12719             :      sparsesolverreport* rep,
   12720             :      ae_state *_state)
   12721             : {
   12722             :     ae_int_t i;
   12723             :     ae_int_t n;
   12724             : 
   12725           0 :     ae_vector_clear(x);
   12726           0 :     _sparsesolverreport_clear(rep);
   12727             : 
   12728           0 :     n = sparsegetnrows(a, _state);
   12729           0 :     ae_assert(n>0, "SparseSPDCholeskySolve: N<=0", _state);
   12730           0 :     ae_assert(sparsegetnrows(a, _state)==n, "SparseSPDCholeskySolve: rows(A)!=N", _state);
   12731           0 :     ae_assert(sparsegetncols(a, _state)==n, "SparseSPDCholeskySolve: cols(A)!=N", _state);
   12732           0 :     ae_assert(sparseissks(a, _state)||sparseiscrs(a, _state), "SparseSPDCholeskySolve: A is not an SKS/CRS matrix", _state);
   12733           0 :     ae_assert(b->cnt>=n, "SparseSPDCholeskySolve: length(B)<N", _state);
   12734           0 :     ae_assert(isfinitevector(b, n, _state), "SparseSPDCholeskySolve: B contains infinities or NANs", _state);
   12735           0 :     directsparsesolvers_initreport(rep, _state);
   12736           0 :     ae_vector_set_length(x, n, _state);
   12737           0 :     for(i=0; i<=n-1; i++)
   12738             :     {
   12739           0 :         if( ae_fp_eq(sparseget(a, i, i, _state),0.0) )
   12740             :         {
   12741           0 :             rep->terminationtype = -3;
   12742           0 :             for(i=0; i<=n-1; i++)
   12743             :             {
   12744           0 :                 x->ptr.p_double[i] = (double)(0);
   12745             :             }
   12746           0 :             return;
   12747             :         }
   12748             :     }
   12749           0 :     for(i=0; i<=n-1; i++)
   12750             :     {
   12751           0 :         x->ptr.p_double[i] = b->ptr.p_double[i];
   12752             :     }
   12753           0 :     if( isupper )
   12754             :     {
   12755           0 :         sparsetrsv(a, isupper, ae_false, 1, x, _state);
   12756           0 :         sparsetrsv(a, isupper, ae_false, 0, x, _state);
   12757             :     }
   12758             :     else
   12759             :     {
   12760           0 :         sparsetrsv(a, isupper, ae_false, 0, x, _state);
   12761           0 :         sparsetrsv(a, isupper, ae_false, 1, x, _state);
   12762             :     }
   12763           0 :     rep->terminationtype = 1;
   12764             : }
   12765             : 
   12766             : 
   12767             : /*************************************************************************
   12768             : Sparse linear solver for A*x=b with general (nonsymmetric) N*N sparse real
   12769             : matrix A, N*1 vectors x and b.
   12770             : 
   12771             : This solver converts input matrix to CRS format, performs LU factorization
   12772             : and uses sparse triangular solvers to get solution of the original system.
   12773             : 
   12774             : INPUT PARAMETERS
   12775             :     A       -   sparse matrix, must be NxN exactly, any storage format
   12776             :     N       -   size of A, N>0
   12777             :     B       -   array[0..N-1], right part
   12778             : 
   12779             : OUTPUT PARAMETERS
   12780             :     X       -   array[N], it contains:
   12781             :                 * rep.terminationtype>0    =>  solution
   12782             :                 * rep.terminationtype=-3   =>  filled by zeros
   12783             :     Rep     -   solver report, following fields are set:
   12784             :                 * rep.terminationtype - solver status; >0 for success,
   12785             :                   set to -3 on failure (degenerate system).
   12786             : 
   12787             :   -- ALGLIB --
   12788             :      Copyright 26.12.2017 by Bochkanov Sergey
   12789             : *************************************************************************/
   12790           0 : void sparsesolve(sparsematrix* a,
   12791             :      /* Real    */ ae_vector* b,
   12792             :      /* Real    */ ae_vector* x,
   12793             :      sparsesolverreport* rep,
   12794             :      ae_state *_state)
   12795             : {
   12796             :     ae_frame _frame_block;
   12797             :     ae_int_t i;
   12798             :     ae_int_t j;
   12799             :     ae_int_t n;
   12800             :     double v;
   12801             :     sparsematrix a2;
   12802             :     ae_vector pivp;
   12803             :     ae_vector pivq;
   12804             : 
   12805           0 :     ae_frame_make(_state, &_frame_block);
   12806           0 :     memset(&a2, 0, sizeof(a2));
   12807           0 :     memset(&pivp, 0, sizeof(pivp));
   12808           0 :     memset(&pivq, 0, sizeof(pivq));
   12809           0 :     ae_vector_clear(x);
   12810           0 :     _sparsesolverreport_clear(rep);
   12811           0 :     _sparsematrix_init(&a2, _state, ae_true);
   12812           0 :     ae_vector_init(&pivp, 0, DT_INT, _state, ae_true);
   12813           0 :     ae_vector_init(&pivq, 0, DT_INT, _state, ae_true);
   12814             : 
   12815           0 :     n = sparsegetnrows(a, _state);
   12816           0 :     ae_assert(n>0, "SparseSolve: N<=0", _state);
   12817           0 :     ae_assert(sparsegetnrows(a, _state)==n, "SparseSolve: rows(A)!=N", _state);
   12818           0 :     ae_assert(sparsegetncols(a, _state)==n, "SparseSolve: cols(A)!=N", _state);
   12819           0 :     ae_assert(b->cnt>=n, "SparseSolve: length(B)<N", _state);
   12820           0 :     ae_assert(isfinitevector(b, n, _state), "SparseSolve: B contains infinities or NANs", _state);
   12821           0 :     directsparsesolvers_initreport(rep, _state);
   12822           0 :     ae_vector_set_length(x, n, _state);
   12823           0 :     sparsecopytocrs(a, &a2, _state);
   12824           0 :     if( !sparselu(&a2, 0, &pivp, &pivq, _state) )
   12825             :     {
   12826           0 :         rep->terminationtype = -3;
   12827           0 :         for(i=0; i<=n-1; i++)
   12828             :         {
   12829           0 :             x->ptr.p_double[i] = (double)(0);
   12830             :         }
   12831           0 :         ae_frame_leave(_state);
   12832           0 :         return;
   12833             :     }
   12834           0 :     for(i=0; i<=n-1; i++)
   12835             :     {
   12836           0 :         x->ptr.p_double[i] = b->ptr.p_double[i];
   12837             :     }
   12838           0 :     for(i=0; i<=n-1; i++)
   12839             :     {
   12840           0 :         j = pivp.ptr.p_int[i];
   12841           0 :         v = x->ptr.p_double[i];
   12842           0 :         x->ptr.p_double[i] = x->ptr.p_double[j];
   12843           0 :         x->ptr.p_double[j] = v;
   12844             :     }
   12845           0 :     sparsetrsv(&a2, ae_false, ae_true, 0, x, _state);
   12846           0 :     sparsetrsv(&a2, ae_true, ae_false, 0, x, _state);
   12847           0 :     for(i=n-1; i>=0; i--)
   12848             :     {
   12849           0 :         j = pivq.ptr.p_int[i];
   12850           0 :         v = x->ptr.p_double[i];
   12851           0 :         x->ptr.p_double[i] = x->ptr.p_double[j];
   12852           0 :         x->ptr.p_double[j] = v;
   12853             :     }
   12854           0 :     rep->terminationtype = 1;
   12855           0 :     ae_frame_leave(_state);
   12856             : }
   12857             : 
   12858             : 
   12859             : /*************************************************************************
   12860             : Sparse linear solver for A*x=b with general (nonsymmetric) N*N sparse real
   12861             : matrix A given by its LU factorization, N*1 vectors x and b.
   12862             : 
   12863             : IMPORTANT: this solver requires input matrix  to  be  in  the  CRS  sparse
   12864             :            storage format. An exception will  be  generated  if  you  pass
   12865             :            matrix in some other format (HASH or SKS).
   12866             : 
   12867             : INPUT PARAMETERS
   12868             :     A       -   LU factorization of the sparse matrix, must be NxN exactly
   12869             :                 in CRS storage format
   12870             :     P, Q    -   pivot indexes from LU factorization
   12871             :     N       -   size of A, N>0
   12872             :     B       -   array[0..N-1], right part
   12873             : 
   12874             : OUTPUT PARAMETERS
   12875             :     X       -   array[N], it contains:
   12876             :                 * rep.terminationtype>0    =>  solution
   12877             :                 * rep.terminationtype=-3   =>  filled by zeros
   12878             :     Rep     -   solver report, following fields are set:
   12879             :                 * rep.terminationtype - solver status; >0 for success,
   12880             :                   set to -3 on failure (degenerate system).
   12881             : 
   12882             :   -- ALGLIB --
   12883             :      Copyright 26.12.2017 by Bochkanov Sergey
   12884             : *************************************************************************/
   12885           0 : void sparselusolve(sparsematrix* a,
   12886             :      /* Integer */ ae_vector* p,
   12887             :      /* Integer */ ae_vector* q,
   12888             :      /* Real    */ ae_vector* b,
   12889             :      /* Real    */ ae_vector* x,
   12890             :      sparsesolverreport* rep,
   12891             :      ae_state *_state)
   12892             : {
   12893             :     ae_int_t i;
   12894             :     ae_int_t j;
   12895             :     double v;
   12896             :     ae_int_t n;
   12897             : 
   12898           0 :     ae_vector_clear(x);
   12899           0 :     _sparsesolverreport_clear(rep);
   12900             : 
   12901           0 :     n = sparsegetnrows(a, _state);
   12902           0 :     ae_assert(n>0, "SparseLUSolve: N<=0", _state);
   12903           0 :     ae_assert(sparsegetnrows(a, _state)==n, "SparseLUSolve: rows(A)!=N", _state);
   12904           0 :     ae_assert(sparsegetncols(a, _state)==n, "SparseLUSolve: cols(A)!=N", _state);
   12905           0 :     ae_assert(sparseiscrs(a, _state), "SparseLUSolve: A is not an SKS matrix", _state);
   12906           0 :     ae_assert(b->cnt>=n, "SparseLUSolve: length(B)<N", _state);
   12907           0 :     ae_assert(isfinitevector(b, n, _state), "SparseLUSolve: B contains infinities or NANs", _state);
   12908           0 :     ae_assert(p->cnt>=n, "SparseLUSolve: length(P)<N", _state);
   12909           0 :     ae_assert(q->cnt>=n, "SparseLUSolve: length(Q)<N", _state);
   12910           0 :     for(i=0; i<=n-1; i++)
   12911             :     {
   12912           0 :         ae_assert(p->ptr.p_int[i]>=i&&p->ptr.p_int[i]<n, "SparseLUSolve: P is corrupted", _state);
   12913           0 :         ae_assert(q->ptr.p_int[i]>=i&&q->ptr.p_int[i]<n, "SparseLUSolve: Q is corrupted", _state);
   12914             :     }
   12915           0 :     directsparsesolvers_initreport(rep, _state);
   12916           0 :     ae_vector_set_length(x, n, _state);
   12917           0 :     for(i=0; i<=n-1; i++)
   12918             :     {
   12919           0 :         if( a->didx.ptr.p_int[i]==a->uidx.ptr.p_int[i]||a->vals.ptr.p_double[a->didx.ptr.p_int[i]]==0.0 )
   12920             :         {
   12921           0 :             rep->terminationtype = -3;
   12922           0 :             for(i=0; i<=n-1; i++)
   12923             :             {
   12924           0 :                 x->ptr.p_double[i] = (double)(0);
   12925             :             }
   12926           0 :             return;
   12927             :         }
   12928             :     }
   12929           0 :     for(i=0; i<=n-1; i++)
   12930             :     {
   12931           0 :         x->ptr.p_double[i] = b->ptr.p_double[i];
   12932             :     }
   12933           0 :     for(i=0; i<=n-1; i++)
   12934             :     {
   12935           0 :         j = p->ptr.p_int[i];
   12936           0 :         v = x->ptr.p_double[i];
   12937           0 :         x->ptr.p_double[i] = x->ptr.p_double[j];
   12938           0 :         x->ptr.p_double[j] = v;
   12939             :     }
   12940           0 :     sparsetrsv(a, ae_false, ae_true, 0, x, _state);
   12941           0 :     sparsetrsv(a, ae_true, ae_false, 0, x, _state);
   12942           0 :     for(i=n-1; i>=0; i--)
   12943             :     {
   12944           0 :         j = q->ptr.p_int[i];
   12945           0 :         v = x->ptr.p_double[i];
   12946           0 :         x->ptr.p_double[i] = x->ptr.p_double[j];
   12947           0 :         x->ptr.p_double[j] = v;
   12948             :     }
   12949           0 :     rep->terminationtype = 1;
   12950             : }
   12951             : 
   12952             : 
   12953             : /*************************************************************************
   12954             : Reset report fields
   12955             : 
   12956             :   -- ALGLIB --
   12957             :      Copyright 26.12.2017 by Bochkanov Sergey
   12958             : *************************************************************************/
   12959           0 : static void directsparsesolvers_initreport(sparsesolverreport* rep,
   12960             :      ae_state *_state)
   12961             : {
   12962             : 
   12963           0 :     _sparsesolverreport_clear(rep);
   12964             : 
   12965           0 :     rep->terminationtype = 0;
   12966           0 : }
   12967             : 
   12968             : 
   12969           0 : void _sparsesolverreport_init(void* _p, ae_state *_state, ae_bool make_automatic)
   12970             : {
   12971           0 :     sparsesolverreport *p = (sparsesolverreport*)_p;
   12972           0 :     ae_touch_ptr((void*)p);
   12973           0 : }
   12974             : 
   12975             : 
   12976           0 : void _sparsesolverreport_init_copy(void* _dst, void* _src, ae_state *_state, ae_bool make_automatic)
   12977             : {
   12978           0 :     sparsesolverreport *dst = (sparsesolverreport*)_dst;
   12979           0 :     sparsesolverreport *src = (sparsesolverreport*)_src;
   12980           0 :     dst->terminationtype = src->terminationtype;
   12981           0 : }
   12982             : 
   12983             : 
   12984           0 : void _sparsesolverreport_clear(void* _p)
   12985             : {
   12986           0 :     sparsesolverreport *p = (sparsesolverreport*)_p;
   12987           0 :     ae_touch_ptr((void*)p);
   12988           0 : }
   12989             : 
   12990             : 
   12991           0 : void _sparsesolverreport_destroy(void* _p)
   12992             : {
   12993           0 :     sparsesolverreport *p = (sparsesolverreport*)_p;
   12994           0 :     ae_touch_ptr((void*)p);
   12995           0 : }
   12996             : 
   12997             : 
   12998             : #endif
   12999             : #if defined(AE_COMPILE_LINCG) || !defined(AE_PARTIAL_BUILD)
   13000             : 
   13001             : 
   13002             : /*************************************************************************
   13003             : This function initializes linear CG Solver. This solver is used  to  solve
   13004             : symmetric positive definite problems. If you want  to  solve  nonsymmetric
   13005             : (or non-positive definite) problem you may use LinLSQR solver provided  by
   13006             : ALGLIB.
   13007             : 
   13008             : USAGE:
   13009             : 1. User initializes algorithm state with LinCGCreate() call
   13010             : 2. User tunes solver parameters with  LinCGSetCond() and other functions
   13011             : 3. Optionally, user sets starting point with LinCGSetStartingPoint()
   13012             : 4. User  calls LinCGSolveSparse() function which takes algorithm state and
   13013             :    SparseMatrix object.
   13014             : 5. User calls LinCGResults() to get solution
   13015             : 6. Optionally, user may call LinCGSolveSparse()  again  to  solve  another
   13016             :    problem  with different matrix and/or right part without reinitializing
   13017             :    LinCGState structure.
   13018             :   
   13019             : INPUT PARAMETERS:
   13020             :     N       -   problem dimension, N>0
   13021             : 
   13022             : OUTPUT PARAMETERS:
   13023             :     State   -   structure which stores algorithm state
   13024             : 
   13025             :   -- ALGLIB --
   13026             :      Copyright 14.11.2011 by Bochkanov Sergey
   13027             : *************************************************************************/
   13028           0 : void lincgcreate(ae_int_t n, lincgstate* state, ae_state *_state)
   13029             : {
   13030             :     ae_int_t i;
   13031             : 
   13032           0 :     _lincgstate_clear(state);
   13033             : 
   13034           0 :     ae_assert(n>0, "LinCGCreate: N<=0", _state);
   13035           0 :     state->n = n;
   13036           0 :     state->prectype = 0;
   13037           0 :     state->itsbeforerestart = n;
   13038           0 :     state->itsbeforerupdate = 10;
   13039           0 :     state->epsf = lincg_defaultprecision;
   13040           0 :     state->maxits = 0;
   13041           0 :     state->xrep = ae_false;
   13042           0 :     state->running = ae_false;
   13043             :     
   13044             :     /*
   13045             :      * * allocate arrays
   13046             :      * * set RX to NAN (just for the case user calls Results() without 
   13047             :      *   calling SolveSparse()
   13048             :      * * set starting point to zero
   13049             :      * * we do NOT initialize B here because we assume that user should
   13050             :      *   initializate it using LinCGSetB() function. In case he forgets
   13051             :      *   to do so, exception will be thrown in the LinCGIteration().
   13052             :      */
   13053           0 :     ae_vector_set_length(&state->rx, state->n, _state);
   13054           0 :     ae_vector_set_length(&state->startx, state->n, _state);
   13055           0 :     ae_vector_set_length(&state->b, state->n, _state);
   13056           0 :     for(i=0; i<=state->n-1; i++)
   13057             :     {
   13058           0 :         state->rx.ptr.p_double[i] = _state->v_nan;
   13059           0 :         state->startx.ptr.p_double[i] = 0.0;
   13060           0 :         state->b.ptr.p_double[i] = (double)(0);
   13061             :     }
   13062           0 :     ae_vector_set_length(&state->cx, state->n, _state);
   13063           0 :     ae_vector_set_length(&state->p, state->n, _state);
   13064           0 :     ae_vector_set_length(&state->r, state->n, _state);
   13065           0 :     ae_vector_set_length(&state->cr, state->n, _state);
   13066           0 :     ae_vector_set_length(&state->z, state->n, _state);
   13067           0 :     ae_vector_set_length(&state->cz, state->n, _state);
   13068           0 :     ae_vector_set_length(&state->x, state->n, _state);
   13069           0 :     ae_vector_set_length(&state->mv, state->n, _state);
   13070           0 :     ae_vector_set_length(&state->pv, state->n, _state);
   13071           0 :     lincg_updateitersdata(state, _state);
   13072           0 :     ae_vector_set_length(&state->rstate.ia, 0+1, _state);
   13073           0 :     ae_vector_set_length(&state->rstate.ra, 2+1, _state);
   13074           0 :     state->rstate.stage = -1;
   13075           0 : }
   13076             : 
   13077             : 
   13078             : /*************************************************************************
   13079             : This function sets starting point.
   13080             : By default, zero starting point is used.
   13081             : 
   13082             : INPUT PARAMETERS:
   13083             :     X       -   starting point, array[N]
   13084             : 
   13085             : OUTPUT PARAMETERS:
   13086             :     State   -   structure which stores algorithm state
   13087             : 
   13088             :   -- ALGLIB --
   13089             :      Copyright 14.11.2011 by Bochkanov Sergey
   13090             : *************************************************************************/
   13091           0 : void lincgsetstartingpoint(lincgstate* state,
   13092             :      /* Real    */ ae_vector* x,
   13093             :      ae_state *_state)
   13094             : {
   13095             : 
   13096             : 
   13097           0 :     ae_assert(!state->running, "LinCGSetStartingPoint: you can not change starting point because LinCGIteration() function is running", _state);
   13098           0 :     ae_assert(state->n<=x->cnt, "LinCGSetStartingPoint: Length(X)<N", _state);
   13099           0 :     ae_assert(isfinitevector(x, state->n, _state), "LinCGSetStartingPoint: X contains infinite or NaN values!", _state);
   13100           0 :     ae_v_move(&state->startx.ptr.p_double[0], 1, &x->ptr.p_double[0], 1, ae_v_len(0,state->n-1));
   13101           0 : }
   13102             : 
   13103             : 
   13104             : /*************************************************************************
   13105             : This function sets right part. By default, right part is zero.
   13106             : 
   13107             : INPUT PARAMETERS:
   13108             :     B       -   right part, array[N].
   13109             : 
   13110             : OUTPUT PARAMETERS:
   13111             :     State   -   structure which stores algorithm state
   13112             : 
   13113             :   -- ALGLIB --
   13114             :      Copyright 14.11.2011 by Bochkanov Sergey
   13115             : *************************************************************************/
   13116           0 : void lincgsetb(lincgstate* state,
   13117             :      /* Real    */ ae_vector* b,
   13118             :      ae_state *_state)
   13119             : {
   13120             : 
   13121             : 
   13122           0 :     ae_assert(!state->running, "LinCGSetB: you can not set B, because function LinCGIteration is running!", _state);
   13123           0 :     ae_assert(b->cnt>=state->n, "LinCGSetB: Length(B)<N", _state);
   13124           0 :     ae_assert(isfinitevector(b, state->n, _state), "LinCGSetB: B contains infinite or NaN values!", _state);
   13125           0 :     ae_v_move(&state->b.ptr.p_double[0], 1, &b->ptr.p_double[0], 1, ae_v_len(0,state->n-1));
   13126           0 : }
   13127             : 
   13128             : 
   13129             : /*************************************************************************
   13130             : This  function  changes  preconditioning  settings  of  LinCGSolveSparse()
   13131             : function. By default, SolveSparse() uses diagonal preconditioner,  but  if
   13132             : you want to use solver without preconditioning, you can call this function
   13133             : which forces solver to use unit matrix for preconditioning.
   13134             : 
   13135             : INPUT PARAMETERS:
   13136             :     State   -   structure which stores algorithm state
   13137             : 
   13138             :   -- ALGLIB --
   13139             :      Copyright 19.11.2012 by Bochkanov Sergey
   13140             : *************************************************************************/
   13141           0 : void lincgsetprecunit(lincgstate* state, ae_state *_state)
   13142             : {
   13143             : 
   13144             : 
   13145           0 :     ae_assert(!state->running, "LinCGSetPrecUnit: you can not change preconditioner, because function LinCGIteration is running!", _state);
   13146           0 :     state->prectype = -1;
   13147           0 : }
   13148             : 
   13149             : 
   13150             : /*************************************************************************
   13151             : This  function  changes  preconditioning  settings  of  LinCGSolveSparse()
   13152             : function.  LinCGSolveSparse() will use diagonal of the  system  matrix  as
   13153             : preconditioner. This preconditioning mode is active by default.
   13154             : 
   13155             : INPUT PARAMETERS:
   13156             :     State   -   structure which stores algorithm state
   13157             : 
   13158             :   -- ALGLIB --
   13159             :      Copyright 19.11.2012 by Bochkanov Sergey
   13160             : *************************************************************************/
   13161           0 : void lincgsetprecdiag(lincgstate* state, ae_state *_state)
   13162             : {
   13163             : 
   13164             : 
   13165           0 :     ae_assert(!state->running, "LinCGSetPrecDiag: you can not change preconditioner, because function LinCGIteration is running!", _state);
   13166           0 :     state->prectype = 0;
   13167           0 : }
   13168             : 
   13169             : 
   13170             : /*************************************************************************
   13171             : This function sets stopping criteria.
   13172             : 
   13173             : INPUT PARAMETERS:
   13174             :     EpsF    -   algorithm will be stopped if norm of residual is less than 
   13175             :                 EpsF*||b||.
   13176             :     MaxIts  -   algorithm will be stopped if number of iterations is  more 
   13177             :                 than MaxIts.
   13178             : 
   13179             : OUTPUT PARAMETERS:
   13180             :     State   -   structure which stores algorithm state
   13181             : 
   13182             : NOTES:
   13183             : If  both  EpsF  and  MaxIts  are  zero then small EpsF will be set to small 
   13184             : value.
   13185             : 
   13186             :   -- ALGLIB --
   13187             :      Copyright 14.11.2011 by Bochkanov Sergey
   13188             : *************************************************************************/
   13189           0 : void lincgsetcond(lincgstate* state,
   13190             :      double epsf,
   13191             :      ae_int_t maxits,
   13192             :      ae_state *_state)
   13193             : {
   13194             : 
   13195             : 
   13196           0 :     ae_assert(!state->running, "LinCGSetCond: you can not change stopping criteria when LinCGIteration() is running", _state);
   13197           0 :     ae_assert(ae_isfinite(epsf, _state)&&ae_fp_greater_eq(epsf,(double)(0)), "LinCGSetCond: EpsF is negative or contains infinite or NaN values", _state);
   13198           0 :     ae_assert(maxits>=0, "LinCGSetCond: MaxIts is negative", _state);
   13199           0 :     if( ae_fp_eq(epsf,(double)(0))&&maxits==0 )
   13200             :     {
   13201           0 :         state->epsf = lincg_defaultprecision;
   13202           0 :         state->maxits = maxits;
   13203             :     }
   13204             :     else
   13205             :     {
   13206           0 :         state->epsf = epsf;
   13207           0 :         state->maxits = maxits;
   13208             :     }
   13209           0 : }
   13210             : 
   13211             : 
   13212             : /*************************************************************************
   13213             : Reverse communication version of linear CG.
   13214             : 
   13215             :   -- ALGLIB --
   13216             :      Copyright 14.11.2011 by Bochkanov Sergey
   13217             : *************************************************************************/
   13218           0 : ae_bool lincgiteration(lincgstate* state, ae_state *_state)
   13219             : {
   13220             :     ae_int_t i;
   13221             :     double uvar;
   13222             :     double bnorm;
   13223             :     double v;
   13224             :     ae_bool result;
   13225             : 
   13226             : 
   13227             :     
   13228             :     /*
   13229             :      * Reverse communication preparations
   13230             :      * I know it looks ugly, but it works the same way
   13231             :      * anywhere from C++ to Python.
   13232             :      *
   13233             :      * This code initializes locals by:
   13234             :      * * random values determined during code
   13235             :      *   generation - on first subroutine call
   13236             :      * * values from previous call - on subsequent calls
   13237             :      */
   13238           0 :     if( state->rstate.stage>=0 )
   13239             :     {
   13240           0 :         i = state->rstate.ia.ptr.p_int[0];
   13241           0 :         uvar = state->rstate.ra.ptr.p_double[0];
   13242           0 :         bnorm = state->rstate.ra.ptr.p_double[1];
   13243           0 :         v = state->rstate.ra.ptr.p_double[2];
   13244             :     }
   13245             :     else
   13246             :     {
   13247           0 :         i = 359;
   13248           0 :         uvar = -58;
   13249           0 :         bnorm = -919;
   13250           0 :         v = -909;
   13251             :     }
   13252           0 :     if( state->rstate.stage==0 )
   13253             :     {
   13254           0 :         goto lbl_0;
   13255             :     }
   13256           0 :     if( state->rstate.stage==1 )
   13257             :     {
   13258           0 :         goto lbl_1;
   13259             :     }
   13260           0 :     if( state->rstate.stage==2 )
   13261             :     {
   13262           0 :         goto lbl_2;
   13263             :     }
   13264           0 :     if( state->rstate.stage==3 )
   13265             :     {
   13266           0 :         goto lbl_3;
   13267             :     }
   13268           0 :     if( state->rstate.stage==4 )
   13269             :     {
   13270           0 :         goto lbl_4;
   13271             :     }
   13272           0 :     if( state->rstate.stage==5 )
   13273             :     {
   13274           0 :         goto lbl_5;
   13275             :     }
   13276           0 :     if( state->rstate.stage==6 )
   13277             :     {
   13278           0 :         goto lbl_6;
   13279             :     }
   13280           0 :     if( state->rstate.stage==7 )
   13281             :     {
   13282           0 :         goto lbl_7;
   13283             :     }
   13284             :     
   13285             :     /*
   13286             :      * Routine body
   13287             :      */
   13288           0 :     ae_assert(state->b.cnt>0, "LinCGIteration: B is not initialized (you must initialize B by LinCGSetB() call", _state);
   13289           0 :     state->running = ae_true;
   13290           0 :     state->repnmv = 0;
   13291           0 :     lincg_clearrfields(state, _state);
   13292           0 :     lincg_updateitersdata(state, _state);
   13293             :     
   13294             :     /*
   13295             :      * Start 0-th iteration
   13296             :      */
   13297           0 :     ae_v_move(&state->rx.ptr.p_double[0], 1, &state->startx.ptr.p_double[0], 1, ae_v_len(0,state->n-1));
   13298           0 :     ae_v_move(&state->x.ptr.p_double[0], 1, &state->rx.ptr.p_double[0], 1, ae_v_len(0,state->n-1));
   13299           0 :     state->repnmv = state->repnmv+1;
   13300           0 :     lincg_clearrfields(state, _state);
   13301           0 :     state->needvmv = ae_true;
   13302           0 :     state->rstate.stage = 0;
   13303           0 :     goto lbl_rcomm;
   13304           0 : lbl_0:
   13305           0 :     state->needvmv = ae_false;
   13306           0 :     bnorm = (double)(0);
   13307           0 :     state->r2 = (double)(0);
   13308           0 :     state->meritfunction = (double)(0);
   13309           0 :     for(i=0; i<=state->n-1; i++)
   13310             :     {
   13311           0 :         state->r.ptr.p_double[i] = state->b.ptr.p_double[i]-state->mv.ptr.p_double[i];
   13312           0 :         state->r2 = state->r2+state->r.ptr.p_double[i]*state->r.ptr.p_double[i];
   13313           0 :         state->meritfunction = state->meritfunction+state->mv.ptr.p_double[i]*state->rx.ptr.p_double[i]-2*state->b.ptr.p_double[i]*state->rx.ptr.p_double[i];
   13314           0 :         bnorm = bnorm+state->b.ptr.p_double[i]*state->b.ptr.p_double[i];
   13315             :     }
   13316           0 :     bnorm = ae_sqrt(bnorm, _state);
   13317             :     
   13318             :     /*
   13319             :      * Output first report
   13320             :      */
   13321           0 :     if( !state->xrep )
   13322             :     {
   13323           0 :         goto lbl_8;
   13324             :     }
   13325           0 :     ae_v_move(&state->x.ptr.p_double[0], 1, &state->rx.ptr.p_double[0], 1, ae_v_len(0,state->n-1));
   13326           0 :     lincg_clearrfields(state, _state);
   13327           0 :     state->xupdated = ae_true;
   13328           0 :     state->rstate.stage = 1;
   13329           0 :     goto lbl_rcomm;
   13330           0 : lbl_1:
   13331           0 :     state->xupdated = ae_false;
   13332           0 : lbl_8:
   13333             :     
   13334             :     /*
   13335             :      * Is x0 a solution?
   13336             :      */
   13337           0 :     if( !ae_isfinite(state->r2, _state)||ae_fp_less_eq(ae_sqrt(state->r2, _state),state->epsf*bnorm) )
   13338             :     {
   13339           0 :         state->running = ae_false;
   13340           0 :         if( ae_isfinite(state->r2, _state) )
   13341             :         {
   13342           0 :             state->repterminationtype = 1;
   13343             :         }
   13344             :         else
   13345             :         {
   13346           0 :             state->repterminationtype = -4;
   13347             :         }
   13348           0 :         result = ae_false;
   13349           0 :         return result;
   13350             :     }
   13351             :     
   13352             :     /*
   13353             :      * Calculate Z and P
   13354             :      */
   13355           0 :     ae_v_move(&state->x.ptr.p_double[0], 1, &state->r.ptr.p_double[0], 1, ae_v_len(0,state->n-1));
   13356           0 :     state->repnmv = state->repnmv+1;
   13357           0 :     lincg_clearrfields(state, _state);
   13358           0 :     state->needprec = ae_true;
   13359           0 :     state->rstate.stage = 2;
   13360           0 :     goto lbl_rcomm;
   13361           0 : lbl_2:
   13362           0 :     state->needprec = ae_false;
   13363           0 :     for(i=0; i<=state->n-1; i++)
   13364             :     {
   13365           0 :         state->z.ptr.p_double[i] = state->pv.ptr.p_double[i];
   13366           0 :         state->p.ptr.p_double[i] = state->z.ptr.p_double[i];
   13367             :     }
   13368             :     
   13369             :     /*
   13370             :      * Other iterations(1..N)
   13371             :      */
   13372           0 :     state->repiterationscount = 0;
   13373           0 : lbl_10:
   13374             :     if( ae_false )
   13375             :     {
   13376             :         goto lbl_11;
   13377             :     }
   13378           0 :     state->repiterationscount = state->repiterationscount+1;
   13379             :     
   13380             :     /*
   13381             :      * Calculate Alpha
   13382             :      */
   13383           0 :     ae_v_move(&state->x.ptr.p_double[0], 1, &state->p.ptr.p_double[0], 1, ae_v_len(0,state->n-1));
   13384           0 :     state->repnmv = state->repnmv+1;
   13385           0 :     lincg_clearrfields(state, _state);
   13386           0 :     state->needvmv = ae_true;
   13387           0 :     state->rstate.stage = 3;
   13388           0 :     goto lbl_rcomm;
   13389           0 : lbl_3:
   13390           0 :     state->needvmv = ae_false;
   13391           0 :     if( !ae_isfinite(state->vmv, _state)||ae_fp_less_eq(state->vmv,(double)(0)) )
   13392             :     {
   13393             :         
   13394             :         /*
   13395             :          * a) Overflow when calculating VMV
   13396             :          * b) non-positive VMV (non-SPD matrix)
   13397             :          */
   13398           0 :         state->running = ae_false;
   13399           0 :         if( ae_isfinite(state->vmv, _state) )
   13400             :         {
   13401           0 :             state->repterminationtype = -5;
   13402             :         }
   13403             :         else
   13404             :         {
   13405           0 :             state->repterminationtype = -4;
   13406             :         }
   13407           0 :         result = ae_false;
   13408           0 :         return result;
   13409             :     }
   13410           0 :     state->alpha = (double)(0);
   13411           0 :     for(i=0; i<=state->n-1; i++)
   13412             :     {
   13413           0 :         state->alpha = state->alpha+state->r.ptr.p_double[i]*state->z.ptr.p_double[i];
   13414             :     }
   13415           0 :     state->alpha = state->alpha/state->vmv;
   13416           0 :     if( !ae_isfinite(state->alpha, _state) )
   13417             :     {
   13418             :         
   13419             :         /*
   13420             :          * Overflow when calculating Alpha
   13421             :          */
   13422           0 :         state->running = ae_false;
   13423           0 :         state->repterminationtype = -4;
   13424           0 :         result = ae_false;
   13425           0 :         return result;
   13426             :     }
   13427             :     
   13428             :     /*
   13429             :      * Next step toward solution
   13430             :      */
   13431           0 :     for(i=0; i<=state->n-1; i++)
   13432             :     {
   13433           0 :         state->cx.ptr.p_double[i] = state->rx.ptr.p_double[i]+state->alpha*state->p.ptr.p_double[i];
   13434             :     }
   13435             :     
   13436             :     /*
   13437             :      * Calculate R:
   13438             :      * * use recurrent relation to update R
   13439             :      * * at every ItsBeforeRUpdate-th iteration recalculate it from scratch, using matrix-vector product
   13440             :      *   in case R grows instead of decreasing, algorithm is terminated with positive completion code
   13441             :      */
   13442           0 :     if( !(state->itsbeforerupdate==0||state->repiterationscount%state->itsbeforerupdate!=0) )
   13443             :     {
   13444           0 :         goto lbl_12;
   13445             :     }
   13446             :     
   13447             :     /*
   13448             :      * Calculate R using recurrent formula
   13449             :      */
   13450           0 :     for(i=0; i<=state->n-1; i++)
   13451             :     {
   13452           0 :         state->cr.ptr.p_double[i] = state->r.ptr.p_double[i]-state->alpha*state->mv.ptr.p_double[i];
   13453           0 :         state->x.ptr.p_double[i] = state->cr.ptr.p_double[i];
   13454             :     }
   13455           0 :     goto lbl_13;
   13456           0 : lbl_12:
   13457             :     
   13458             :     /*
   13459             :      * Calculate R using matrix-vector multiplication
   13460             :      */
   13461           0 :     ae_v_move(&state->x.ptr.p_double[0], 1, &state->cx.ptr.p_double[0], 1, ae_v_len(0,state->n-1));
   13462           0 :     state->repnmv = state->repnmv+1;
   13463           0 :     lincg_clearrfields(state, _state);
   13464           0 :     state->needmv = ae_true;
   13465           0 :     state->rstate.stage = 4;
   13466           0 :     goto lbl_rcomm;
   13467           0 : lbl_4:
   13468           0 :     state->needmv = ae_false;
   13469           0 :     for(i=0; i<=state->n-1; i++)
   13470             :     {
   13471           0 :         state->cr.ptr.p_double[i] = state->b.ptr.p_double[i]-state->mv.ptr.p_double[i];
   13472           0 :         state->x.ptr.p_double[i] = state->cr.ptr.p_double[i];
   13473             :     }
   13474             :     
   13475             :     /*
   13476             :      * Calculating merit function
   13477             :      * Check emergency stopping criterion
   13478             :      */
   13479           0 :     v = (double)(0);
   13480           0 :     for(i=0; i<=state->n-1; i++)
   13481             :     {
   13482           0 :         v = v+state->mv.ptr.p_double[i]*state->cx.ptr.p_double[i]-2*state->b.ptr.p_double[i]*state->cx.ptr.p_double[i];
   13483             :     }
   13484           0 :     if( ae_fp_less(v,state->meritfunction) )
   13485             :     {
   13486           0 :         goto lbl_14;
   13487             :     }
   13488           0 :     for(i=0; i<=state->n-1; i++)
   13489             :     {
   13490           0 :         if( !ae_isfinite(state->rx.ptr.p_double[i], _state) )
   13491             :         {
   13492           0 :             state->running = ae_false;
   13493           0 :             state->repterminationtype = -4;
   13494           0 :             result = ae_false;
   13495           0 :             return result;
   13496             :         }
   13497             :     }
   13498             :     
   13499             :     /*
   13500             :      *output last report
   13501             :      */
   13502           0 :     if( !state->xrep )
   13503             :     {
   13504           0 :         goto lbl_16;
   13505             :     }
   13506           0 :     ae_v_move(&state->x.ptr.p_double[0], 1, &state->rx.ptr.p_double[0], 1, ae_v_len(0,state->n-1));
   13507           0 :     lincg_clearrfields(state, _state);
   13508           0 :     state->xupdated = ae_true;
   13509           0 :     state->rstate.stage = 5;
   13510           0 :     goto lbl_rcomm;
   13511           0 : lbl_5:
   13512           0 :     state->xupdated = ae_false;
   13513           0 : lbl_16:
   13514           0 :     state->running = ae_false;
   13515           0 :     state->repterminationtype = 7;
   13516           0 :     result = ae_false;
   13517           0 :     return result;
   13518           0 : lbl_14:
   13519           0 :     state->meritfunction = v;
   13520           0 : lbl_13:
   13521           0 :     ae_v_move(&state->rx.ptr.p_double[0], 1, &state->cx.ptr.p_double[0], 1, ae_v_len(0,state->n-1));
   13522             :     
   13523             :     /*
   13524             :      * calculating RNorm
   13525             :      *
   13526             :      * NOTE: monotonic decrease of R2 is not guaranteed by algorithm.
   13527             :      */
   13528           0 :     state->r2 = (double)(0);
   13529           0 :     for(i=0; i<=state->n-1; i++)
   13530             :     {
   13531           0 :         state->r2 = state->r2+state->cr.ptr.p_double[i]*state->cr.ptr.p_double[i];
   13532             :     }
   13533             :     
   13534             :     /*
   13535             :      *output report
   13536             :      */
   13537           0 :     if( !state->xrep )
   13538             :     {
   13539           0 :         goto lbl_18;
   13540             :     }
   13541           0 :     ae_v_move(&state->x.ptr.p_double[0], 1, &state->rx.ptr.p_double[0], 1, ae_v_len(0,state->n-1));
   13542           0 :     lincg_clearrfields(state, _state);
   13543           0 :     state->xupdated = ae_true;
   13544           0 :     state->rstate.stage = 6;
   13545           0 :     goto lbl_rcomm;
   13546           0 : lbl_6:
   13547           0 :     state->xupdated = ae_false;
   13548           0 : lbl_18:
   13549             :     
   13550             :     /*
   13551             :      *stopping criterion
   13552             :      *achieved the required precision
   13553             :      */
   13554           0 :     if( !ae_isfinite(state->r2, _state)||ae_fp_less_eq(ae_sqrt(state->r2, _state),state->epsf*bnorm) )
   13555             :     {
   13556           0 :         state->running = ae_false;
   13557           0 :         if( ae_isfinite(state->r2, _state) )
   13558             :         {
   13559           0 :             state->repterminationtype = 1;
   13560             :         }
   13561             :         else
   13562             :         {
   13563           0 :             state->repterminationtype = -4;
   13564             :         }
   13565           0 :         result = ae_false;
   13566           0 :         return result;
   13567             :     }
   13568           0 :     if( state->repiterationscount>=state->maxits&&state->maxits>0 )
   13569             :     {
   13570           0 :         for(i=0; i<=state->n-1; i++)
   13571             :         {
   13572           0 :             if( !ae_isfinite(state->rx.ptr.p_double[i], _state) )
   13573             :             {
   13574           0 :                 state->running = ae_false;
   13575           0 :                 state->repterminationtype = -4;
   13576           0 :                 result = ae_false;
   13577           0 :                 return result;
   13578             :             }
   13579             :         }
   13580             :         
   13581             :         /*
   13582             :          *if X is finite number
   13583             :          */
   13584           0 :         state->running = ae_false;
   13585           0 :         state->repterminationtype = 5;
   13586           0 :         result = ae_false;
   13587           0 :         return result;
   13588             :     }
   13589           0 :     ae_v_move(&state->x.ptr.p_double[0], 1, &state->cr.ptr.p_double[0], 1, ae_v_len(0,state->n-1));
   13590             :     
   13591             :     /*
   13592             :      *prepere of parameters for next iteration
   13593             :      */
   13594           0 :     state->repnmv = state->repnmv+1;
   13595           0 :     lincg_clearrfields(state, _state);
   13596           0 :     state->needprec = ae_true;
   13597           0 :     state->rstate.stage = 7;
   13598           0 :     goto lbl_rcomm;
   13599           0 : lbl_7:
   13600           0 :     state->needprec = ae_false;
   13601           0 :     ae_v_move(&state->cz.ptr.p_double[0], 1, &state->pv.ptr.p_double[0], 1, ae_v_len(0,state->n-1));
   13602           0 :     if( state->repiterationscount%state->itsbeforerestart!=0 )
   13603             :     {
   13604           0 :         state->beta = (double)(0);
   13605           0 :         uvar = (double)(0);
   13606           0 :         for(i=0; i<=state->n-1; i++)
   13607             :         {
   13608           0 :             state->beta = state->beta+state->cz.ptr.p_double[i]*state->cr.ptr.p_double[i];
   13609           0 :             uvar = uvar+state->z.ptr.p_double[i]*state->r.ptr.p_double[i];
   13610             :         }
   13611             :         
   13612             :         /*
   13613             :          *check that UVar is't INF or is't zero
   13614             :          */
   13615           0 :         if( !ae_isfinite(uvar, _state)||ae_fp_eq(uvar,(double)(0)) )
   13616             :         {
   13617           0 :             state->running = ae_false;
   13618           0 :             state->repterminationtype = -4;
   13619           0 :             result = ae_false;
   13620           0 :             return result;
   13621             :         }
   13622             :         
   13623             :         /*
   13624             :          *calculate .BETA
   13625             :          */
   13626           0 :         state->beta = state->beta/uvar;
   13627             :         
   13628             :         /*
   13629             :          *check that .BETA neither INF nor NaN
   13630             :          */
   13631           0 :         if( !ae_isfinite(state->beta, _state) )
   13632             :         {
   13633           0 :             state->running = ae_false;
   13634           0 :             state->repterminationtype = -1;
   13635           0 :             result = ae_false;
   13636           0 :             return result;
   13637             :         }
   13638           0 :         for(i=0; i<=state->n-1; i++)
   13639             :         {
   13640           0 :             state->p.ptr.p_double[i] = state->cz.ptr.p_double[i]+state->beta*state->p.ptr.p_double[i];
   13641             :         }
   13642             :     }
   13643             :     else
   13644             :     {
   13645           0 :         ae_v_move(&state->p.ptr.p_double[0], 1, &state->cz.ptr.p_double[0], 1, ae_v_len(0,state->n-1));
   13646             :     }
   13647             :     
   13648             :     /*
   13649             :      *prepere data for next iteration
   13650             :      */
   13651           0 :     for(i=0; i<=state->n-1; i++)
   13652             :     {
   13653             :         
   13654             :         /*
   13655             :          *write (k+1)th iteration to (k )th iteration
   13656             :          */
   13657           0 :         state->r.ptr.p_double[i] = state->cr.ptr.p_double[i];
   13658           0 :         state->z.ptr.p_double[i] = state->cz.ptr.p_double[i];
   13659             :     }
   13660           0 :     goto lbl_10;
   13661             : lbl_11:
   13662             :     result = ae_false;
   13663             :     return result;
   13664             :     
   13665             :     /*
   13666             :      * Saving state
   13667             :      */
   13668           0 : lbl_rcomm:
   13669           0 :     result = ae_true;
   13670           0 :     state->rstate.ia.ptr.p_int[0] = i;
   13671           0 :     state->rstate.ra.ptr.p_double[0] = uvar;
   13672           0 :     state->rstate.ra.ptr.p_double[1] = bnorm;
   13673           0 :     state->rstate.ra.ptr.p_double[2] = v;
   13674           0 :     return result;
   13675             : }
   13676             : 
   13677             : 
   13678             : /*************************************************************************
   13679             : Procedure for solution of A*x=b with sparse A.
   13680             : 
   13681             : INPUT PARAMETERS:
   13682             :     State   -   algorithm state
   13683             :     A       -   sparse matrix in the CRS format (you MUST contvert  it  to 
   13684             :                 CRS format by calling SparseConvertToCRS() function).
   13685             :     IsUpper -   whether upper or lower triangle of A is used:
   13686             :                 * IsUpper=True  => only upper triangle is used and lower
   13687             :                                    triangle is not referenced at all 
   13688             :                 * IsUpper=False => only lower triangle is used and upper
   13689             :                                    triangle is not referenced at all
   13690             :     B       -   right part, array[N]
   13691             : 
   13692             : RESULT:
   13693             :     This function returns no result.
   13694             :     You can get solution by calling LinCGResults()
   13695             :     
   13696             : NOTE: this function uses lightweight preconditioning -  multiplication  by
   13697             :       inverse of diag(A). If you want, you can turn preconditioning off by
   13698             :       calling LinCGSetPrecUnit(). However, preconditioning cost is low and
   13699             :       preconditioner  is  very  important  for  solution  of  badly scaled
   13700             :       problems.
   13701             : 
   13702             :   -- ALGLIB --
   13703             :      Copyright 14.11.2011 by Bochkanov Sergey
   13704             : *************************************************************************/
   13705           0 : void lincgsolvesparse(lincgstate* state,
   13706             :      sparsematrix* a,
   13707             :      ae_bool isupper,
   13708             :      /* Real    */ ae_vector* b,
   13709             :      ae_state *_state)
   13710             : {
   13711             :     ae_int_t n;
   13712             :     ae_int_t i;
   13713             :     double v;
   13714             :     double vmv;
   13715             : 
   13716             : 
   13717           0 :     n = state->n;
   13718           0 :     ae_assert(b->cnt>=state->n, "LinCGSetB: Length(B)<N", _state);
   13719           0 :     ae_assert(isfinitevector(b, state->n, _state), "LinCGSetB: B contains infinite or NaN values!", _state);
   13720             :     
   13721             :     /*
   13722             :      * Allocate temporaries
   13723             :      */
   13724           0 :     rvectorsetlengthatleast(&state->tmpd, n, _state);
   13725             :     
   13726             :     /*
   13727             :      * Compute diagonal scaling matrix D
   13728             :      */
   13729           0 :     if( state->prectype==0 )
   13730             :     {
   13731             :         
   13732             :         /*
   13733             :          * Default preconditioner - inverse of matrix diagonal
   13734             :          */
   13735           0 :         for(i=0; i<=n-1; i++)
   13736             :         {
   13737           0 :             v = sparsegetdiagonal(a, i, _state);
   13738           0 :             if( ae_fp_greater(v,(double)(0)) )
   13739             :             {
   13740           0 :                 state->tmpd.ptr.p_double[i] = 1/ae_sqrt(v, _state);
   13741             :             }
   13742             :             else
   13743             :             {
   13744           0 :                 state->tmpd.ptr.p_double[i] = (double)(1);
   13745             :             }
   13746             :         }
   13747             :     }
   13748             :     else
   13749             :     {
   13750             :         
   13751             :         /*
   13752             :          * No diagonal scaling
   13753             :          */
   13754           0 :         for(i=0; i<=n-1; i++)
   13755             :         {
   13756           0 :             state->tmpd.ptr.p_double[i] = (double)(1);
   13757             :         }
   13758             :     }
   13759             :     
   13760             :     /*
   13761             :      * Solve
   13762             :      */
   13763           0 :     lincgrestart(state, _state);
   13764           0 :     lincgsetb(state, b, _state);
   13765           0 :     while(lincgiteration(state, _state))
   13766             :     {
   13767             :         
   13768             :         /*
   13769             :          * Process different requests from optimizer
   13770             :          */
   13771           0 :         if( state->needmv )
   13772             :         {
   13773           0 :             sparsesmv(a, isupper, &state->x, &state->mv, _state);
   13774             :         }
   13775           0 :         if( state->needvmv )
   13776             :         {
   13777           0 :             sparsesmv(a, isupper, &state->x, &state->mv, _state);
   13778           0 :             vmv = ae_v_dotproduct(&state->x.ptr.p_double[0], 1, &state->mv.ptr.p_double[0], 1, ae_v_len(0,state->n-1));
   13779           0 :             state->vmv = vmv;
   13780             :         }
   13781           0 :         if( state->needprec )
   13782             :         {
   13783           0 :             for(i=0; i<=n-1; i++)
   13784             :             {
   13785           0 :                 state->pv.ptr.p_double[i] = state->x.ptr.p_double[i]*ae_sqr(state->tmpd.ptr.p_double[i], _state);
   13786             :             }
   13787             :         }
   13788             :     }
   13789           0 : }
   13790             : 
   13791             : 
   13792             : /*************************************************************************
   13793             : CG-solver: results.
   13794             : 
   13795             : This function must be called after LinCGSolve
   13796             : 
   13797             : INPUT PARAMETERS:
   13798             :     State   -   algorithm state
   13799             : 
   13800             : OUTPUT PARAMETERS:
   13801             :     X       -   array[N], solution
   13802             :     Rep     -   optimization report:
   13803             :                 * Rep.TerminationType completetion code:
   13804             :                     * -5    input matrix is either not positive definite,
   13805             :                             too large or too small                            
   13806             :                     * -4    overflow/underflow during solution
   13807             :                             (ill conditioned problem)
   13808             :                     *  1    ||residual||<=EpsF*||b||
   13809             :                     *  5    MaxIts steps was taken
   13810             :                     *  7    rounding errors prevent further progress,
   13811             :                             best point found is returned
   13812             :                 * Rep.IterationsCount contains iterations count
   13813             :                 * NMV countains number of matrix-vector calculations
   13814             : 
   13815             :   -- ALGLIB --
   13816             :      Copyright 14.11.2011 by Bochkanov Sergey
   13817             : *************************************************************************/
   13818           0 : void lincgresults(lincgstate* state,
   13819             :      /* Real    */ ae_vector* x,
   13820             :      lincgreport* rep,
   13821             :      ae_state *_state)
   13822             : {
   13823             : 
   13824           0 :     ae_vector_clear(x);
   13825           0 :     _lincgreport_clear(rep);
   13826             : 
   13827           0 :     ae_assert(!state->running, "LinCGResult: you can not get result, because function LinCGIteration has been launched!", _state);
   13828           0 :     if( x->cnt<state->n )
   13829             :     {
   13830           0 :         ae_vector_set_length(x, state->n, _state);
   13831             :     }
   13832           0 :     ae_v_move(&x->ptr.p_double[0], 1, &state->rx.ptr.p_double[0], 1, ae_v_len(0,state->n-1));
   13833           0 :     rep->iterationscount = state->repiterationscount;
   13834           0 :     rep->nmv = state->repnmv;
   13835           0 :     rep->terminationtype = state->repterminationtype;
   13836           0 :     rep->r2 = state->r2;
   13837           0 : }
   13838             : 
   13839             : 
   13840             : /*************************************************************************
   13841             : This function sets restart frequency. By default, algorithm  is  restarted
   13842             : after N subsequent iterations.
   13843             : 
   13844             :   -- ALGLIB --
   13845             :      Copyright 14.11.2011 by Bochkanov Sergey
   13846             : *************************************************************************/
   13847           0 : void lincgsetrestartfreq(lincgstate* state,
   13848             :      ae_int_t srf,
   13849             :      ae_state *_state)
   13850             : {
   13851             : 
   13852             : 
   13853           0 :     ae_assert(!state->running, "LinCGSetRestartFreq: you can not change restart frequency when LinCGIteration() is running", _state);
   13854           0 :     ae_assert(srf>0, "LinCGSetRestartFreq: non-positive SRF", _state);
   13855           0 :     state->itsbeforerestart = srf;
   13856           0 : }
   13857             : 
   13858             : 
   13859             : /*************************************************************************
   13860             : This function sets frequency of residual recalculations.
   13861             : 
   13862             : Algorithm updates residual r_k using iterative formula,  but  recalculates
   13863             : it from scratch after each 10 iterations. It is done to avoid accumulation
   13864             : of numerical errors and to stop algorithm when r_k starts to grow.
   13865             : 
   13866             : Such low update frequence (1/10) gives very  little  overhead,  but  makes
   13867             : algorithm a bit more robust against numerical errors. However, you may
   13868             : change it 
   13869             : 
   13870             : INPUT PARAMETERS:
   13871             :     Freq    -   desired update frequency, Freq>=0.
   13872             :                 Zero value means that no updates will be done.
   13873             : 
   13874             :   -- ALGLIB --
   13875             :      Copyright 14.11.2011 by Bochkanov Sergey
   13876             : *************************************************************************/
   13877           0 : void lincgsetrupdatefreq(lincgstate* state,
   13878             :      ae_int_t freq,
   13879             :      ae_state *_state)
   13880             : {
   13881             : 
   13882             : 
   13883           0 :     ae_assert(!state->running, "LinCGSetRUpdateFreq: you can not change update frequency when LinCGIteration() is running", _state);
   13884           0 :     ae_assert(freq>=0, "LinCGSetRUpdateFreq: non-positive Freq", _state);
   13885           0 :     state->itsbeforerupdate = freq;
   13886           0 : }
   13887             : 
   13888             : 
   13889             : /*************************************************************************
   13890             : This function turns on/off reporting.
   13891             : 
   13892             : INPUT PARAMETERS:
   13893             :     State   -   structure which stores algorithm state
   13894             :     NeedXRep-   whether iteration reports are needed or not
   13895             : 
   13896             : If NeedXRep is True, algorithm will call rep() callback function if  it is
   13897             : provided to MinCGOptimize().
   13898             : 
   13899             :   -- ALGLIB --
   13900             :      Copyright 14.11.2011 by Bochkanov Sergey
   13901             : *************************************************************************/
   13902           0 : void lincgsetxrep(lincgstate* state, ae_bool needxrep, ae_state *_state)
   13903             : {
   13904             : 
   13905             : 
   13906           0 :     state->xrep = needxrep;
   13907           0 : }
   13908             : 
   13909             : 
   13910             : /*************************************************************************
   13911             : Procedure for restart function LinCGIteration
   13912             : 
   13913             :   -- ALGLIB --
   13914             :      Copyright 14.11.2011 by Bochkanov Sergey
   13915             : *************************************************************************/
   13916           0 : void lincgrestart(lincgstate* state, ae_state *_state)
   13917             : {
   13918             : 
   13919             : 
   13920           0 :     ae_vector_set_length(&state->rstate.ia, 0+1, _state);
   13921           0 :     ae_vector_set_length(&state->rstate.ra, 2+1, _state);
   13922           0 :     state->rstate.stage = -1;
   13923           0 :     lincg_clearrfields(state, _state);
   13924           0 : }
   13925             : 
   13926             : 
   13927             : /*************************************************************************
   13928             : Clears request fileds (to be sure that we don't forgot to clear something)
   13929             : *************************************************************************/
   13930           0 : static void lincg_clearrfields(lincgstate* state, ae_state *_state)
   13931             : {
   13932             : 
   13933             : 
   13934           0 :     state->xupdated = ae_false;
   13935           0 :     state->needmv = ae_false;
   13936           0 :     state->needmtv = ae_false;
   13937           0 :     state->needmv2 = ae_false;
   13938           0 :     state->needvmv = ae_false;
   13939           0 :     state->needprec = ae_false;
   13940           0 : }
   13941             : 
   13942             : 
   13943             : /*************************************************************************
   13944             : Clears request fileds (to be sure that we don't forgot to clear something)
   13945             : *************************************************************************/
   13946           0 : static void lincg_updateitersdata(lincgstate* state, ae_state *_state)
   13947             : {
   13948             : 
   13949             : 
   13950           0 :     state->repiterationscount = 0;
   13951           0 :     state->repnmv = 0;
   13952           0 :     state->repterminationtype = 0;
   13953           0 : }
   13954             : 
   13955             : 
   13956           0 : void _lincgstate_init(void* _p, ae_state *_state, ae_bool make_automatic)
   13957             : {
   13958           0 :     lincgstate *p = (lincgstate*)_p;
   13959           0 :     ae_touch_ptr((void*)p);
   13960           0 :     ae_vector_init(&p->rx, 0, DT_REAL, _state, make_automatic);
   13961           0 :     ae_vector_init(&p->b, 0, DT_REAL, _state, make_automatic);
   13962           0 :     ae_vector_init(&p->cx, 0, DT_REAL, _state, make_automatic);
   13963           0 :     ae_vector_init(&p->cr, 0, DT_REAL, _state, make_automatic);
   13964           0 :     ae_vector_init(&p->cz, 0, DT_REAL, _state, make_automatic);
   13965           0 :     ae_vector_init(&p->p, 0, DT_REAL, _state, make_automatic);
   13966           0 :     ae_vector_init(&p->r, 0, DT_REAL, _state, make_automatic);
   13967           0 :     ae_vector_init(&p->z, 0, DT_REAL, _state, make_automatic);
   13968           0 :     ae_vector_init(&p->x, 0, DT_REAL, _state, make_automatic);
   13969           0 :     ae_vector_init(&p->mv, 0, DT_REAL, _state, make_automatic);
   13970           0 :     ae_vector_init(&p->pv, 0, DT_REAL, _state, make_automatic);
   13971           0 :     ae_vector_init(&p->startx, 0, DT_REAL, _state, make_automatic);
   13972           0 :     ae_vector_init(&p->tmpd, 0, DT_REAL, _state, make_automatic);
   13973           0 :     _rcommstate_init(&p->rstate, _state, make_automatic);
   13974           0 : }
   13975             : 
   13976             : 
   13977           0 : void _lincgstate_init_copy(void* _dst, void* _src, ae_state *_state, ae_bool make_automatic)
   13978             : {
   13979           0 :     lincgstate *dst = (lincgstate*)_dst;
   13980           0 :     lincgstate *src = (lincgstate*)_src;
   13981           0 :     ae_vector_init_copy(&dst->rx, &src->rx, _state, make_automatic);
   13982           0 :     ae_vector_init_copy(&dst->b, &src->b, _state, make_automatic);
   13983           0 :     dst->n = src->n;
   13984           0 :     dst->prectype = src->prectype;
   13985           0 :     ae_vector_init_copy(&dst->cx, &src->cx, _state, make_automatic);
   13986           0 :     ae_vector_init_copy(&dst->cr, &src->cr, _state, make_automatic);
   13987           0 :     ae_vector_init_copy(&dst->cz, &src->cz, _state, make_automatic);
   13988           0 :     ae_vector_init_copy(&dst->p, &src->p, _state, make_automatic);
   13989           0 :     ae_vector_init_copy(&dst->r, &src->r, _state, make_automatic);
   13990           0 :     ae_vector_init_copy(&dst->z, &src->z, _state, make_automatic);
   13991           0 :     dst->alpha = src->alpha;
   13992           0 :     dst->beta = src->beta;
   13993           0 :     dst->r2 = src->r2;
   13994           0 :     dst->meritfunction = src->meritfunction;
   13995           0 :     ae_vector_init_copy(&dst->x, &src->x, _state, make_automatic);
   13996           0 :     ae_vector_init_copy(&dst->mv, &src->mv, _state, make_automatic);
   13997           0 :     ae_vector_init_copy(&dst->pv, &src->pv, _state, make_automatic);
   13998           0 :     dst->vmv = src->vmv;
   13999           0 :     ae_vector_init_copy(&dst->startx, &src->startx, _state, make_automatic);
   14000           0 :     dst->epsf = src->epsf;
   14001           0 :     dst->maxits = src->maxits;
   14002           0 :     dst->itsbeforerestart = src->itsbeforerestart;
   14003           0 :     dst->itsbeforerupdate = src->itsbeforerupdate;
   14004           0 :     dst->xrep = src->xrep;
   14005           0 :     dst->xupdated = src->xupdated;
   14006           0 :     dst->needmv = src->needmv;
   14007           0 :     dst->needmtv = src->needmtv;
   14008           0 :     dst->needmv2 = src->needmv2;
   14009           0 :     dst->needvmv = src->needvmv;
   14010           0 :     dst->needprec = src->needprec;
   14011           0 :     dst->repiterationscount = src->repiterationscount;
   14012           0 :     dst->repnmv = src->repnmv;
   14013           0 :     dst->repterminationtype = src->repterminationtype;
   14014           0 :     dst->running = src->running;
   14015           0 :     ae_vector_init_copy(&dst->tmpd, &src->tmpd, _state, make_automatic);
   14016           0 :     _rcommstate_init_copy(&dst->rstate, &src->rstate, _state, make_automatic);
   14017           0 : }
   14018             : 
   14019             : 
   14020           0 : void _lincgstate_clear(void* _p)
   14021             : {
   14022           0 :     lincgstate *p = (lincgstate*)_p;
   14023           0 :     ae_touch_ptr((void*)p);
   14024           0 :     ae_vector_clear(&p->rx);
   14025           0 :     ae_vector_clear(&p->b);
   14026           0 :     ae_vector_clear(&p->cx);
   14027           0 :     ae_vector_clear(&p->cr);
   14028           0 :     ae_vector_clear(&p->cz);
   14029           0 :     ae_vector_clear(&p->p);
   14030           0 :     ae_vector_clear(&p->r);
   14031           0 :     ae_vector_clear(&p->z);
   14032           0 :     ae_vector_clear(&p->x);
   14033           0 :     ae_vector_clear(&p->mv);
   14034           0 :     ae_vector_clear(&p->pv);
   14035           0 :     ae_vector_clear(&p->startx);
   14036           0 :     ae_vector_clear(&p->tmpd);
   14037           0 :     _rcommstate_clear(&p->rstate);
   14038           0 : }
   14039             : 
   14040             : 
   14041           0 : void _lincgstate_destroy(void* _p)
   14042             : {
   14043           0 :     lincgstate *p = (lincgstate*)_p;
   14044           0 :     ae_touch_ptr((void*)p);
   14045           0 :     ae_vector_destroy(&p->rx);
   14046           0 :     ae_vector_destroy(&p->b);
   14047           0 :     ae_vector_destroy(&p->cx);
   14048           0 :     ae_vector_destroy(&p->cr);
   14049           0 :     ae_vector_destroy(&p->cz);
   14050           0 :     ae_vector_destroy(&p->p);
   14051           0 :     ae_vector_destroy(&p->r);
   14052           0 :     ae_vector_destroy(&p->z);
   14053           0 :     ae_vector_destroy(&p->x);
   14054           0 :     ae_vector_destroy(&p->mv);
   14055           0 :     ae_vector_destroy(&p->pv);
   14056           0 :     ae_vector_destroy(&p->startx);
   14057           0 :     ae_vector_destroy(&p->tmpd);
   14058           0 :     _rcommstate_destroy(&p->rstate);
   14059           0 : }
   14060             : 
   14061             : 
   14062           0 : void _lincgreport_init(void* _p, ae_state *_state, ae_bool make_automatic)
   14063             : {
   14064           0 :     lincgreport *p = (lincgreport*)_p;
   14065           0 :     ae_touch_ptr((void*)p);
   14066           0 : }
   14067             : 
   14068             : 
   14069           0 : void _lincgreport_init_copy(void* _dst, void* _src, ae_state *_state, ae_bool make_automatic)
   14070             : {
   14071           0 :     lincgreport *dst = (lincgreport*)_dst;
   14072           0 :     lincgreport *src = (lincgreport*)_src;
   14073           0 :     dst->iterationscount = src->iterationscount;
   14074           0 :     dst->nmv = src->nmv;
   14075           0 :     dst->terminationtype = src->terminationtype;
   14076           0 :     dst->r2 = src->r2;
   14077           0 : }
   14078             : 
   14079             : 
   14080           0 : void _lincgreport_clear(void* _p)
   14081             : {
   14082           0 :     lincgreport *p = (lincgreport*)_p;
   14083           0 :     ae_touch_ptr((void*)p);
   14084           0 : }
   14085             : 
   14086             : 
   14087           0 : void _lincgreport_destroy(void* _p)
   14088             : {
   14089           0 :     lincgreport *p = (lincgreport*)_p;
   14090           0 :     ae_touch_ptr((void*)p);
   14091           0 : }
   14092             : 
   14093             : 
   14094             : #endif
   14095             : 
   14096             : }
   14097             : 

Generated by: LCOV version 1.16