Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
07/22/10 00:44:01 (14 years ago)
Author:
swagner
Message:

Sorted usings and removed unused usings in entire solution (#1094)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/sources/HeuristicLab.ExtLibs/HeuristicLab.ALGLIB/2.5.0/ALGLIB-2.5.0/ssolve.cs

    r3839 r4068  
    2525*************************************************************************/
    2626
    27 using System;
    28 
    29 namespace alglib
    30 {
    31     public class ssolve
    32     {
    33         /*************************************************************************
    34         Solving  a system  of linear equations  with a system matrix  given by its
    35         LDLT decomposition
    36 
    37         The algorithm solves systems with a square matrix only.
    38 
    39         Input parameters:
    40             A       -   LDLT decomposition of the matrix (the result of the
    41                         SMatrixLDLT subroutine).
    42             Pivots  -   row permutation table (the result of the SMatrixLDLT subroutine).
    43             B       -   right side of a system.
    44                         Array whose index ranges within [0..N-1].
    45             N       -   size of matrix A.
    46             IsUpper -   points to the triangle of matrix A in which the LDLT
    47                         decomposition is stored.
    48                         If IsUpper=True, the decomposition has the form of U*D*U',
    49                         matrix U is stored in the upper triangle of  matrix A  (in
    50                         that case, the lower triangle isn't used and isn't changed
    51                         by the subroutine).
    52                         Similarly, if IsUpper=False, the decomposition has the form
    53                         of L*D*L' and the lower triangle stores matrix L.
    54 
    55         Output parameters:
    56             X       -   solution of a system.
    57                         Array whose index ranges within [0..N-1].
    58 
    59         Result:
    60             True, if the matrix is not singular. X contains the solution.
    61             False, if the matrix is singular (the determinant of matrix D is equal
    62         to 0). In this case, X doesn't contain a solution.
    63         *************************************************************************/
    64         public static bool smatrixldltsolve(ref double[,] a,
    65             ref int[] pivots,
    66             double[] b,
    67             int n,
    68             bool isupper,
    69             ref double[] x)
    70         {
    71             bool result = new bool();
    72             int i = 0;
    73             int k = 0;
    74             int kp = 0;
    75             double ak = 0;
    76             double akm1 = 0;
    77             double akm1k = 0;
    78             double bk = 0;
    79             double bkm1 = 0;
    80             double denom = 0;
    81             double v = 0;
    82             int i_ = 0;
    83 
    84             b = (double[])b.Clone();
    85 
    86            
    87             //
    88             // Quick return if possible
    89             //
    90             result = true;
    91             if( n==0 )
    92             {
    93                 return result;
    94             }
    95            
    96             //
    97             // Check that the diagonal matrix D is nonsingular
    98             //
    99             if( isupper )
    100             {
    101                
    102                 //
    103                 // Upper triangular storage: examine D from bottom to top
    104                 //
    105                 for(i=n-1; i>=0; i--)
    106                 {
    107                     if( pivots[i]>=0 & (double)(a[i,i])==(double)(0) )
    108                     {
    109                         result = false;
    110                         return result;
    111                     }
    112                 }
    113             }
    114             else
    115             {
    116                
    117                 //
    118                 // Lower triangular storage: examine D from top to bottom.
    119                 //
    120                 for(i=0; i<=n-1; i++)
    121                 {
    122                     if( pivots[i]>=0 & (double)(a[i,i])==(double)(0) )
    123                     {
    124                         result = false;
    125                         return result;
    126                     }
    127                 }
    128             }
    129            
    130             //
    131             // Solve Ax = b
    132             //
    133             if( isupper )
    134             {
    135                
    136                 //
    137                 // Solve A*X = B, where A = U*D*U'.
    138                 //
    139                 // First solve U*D*X = B, overwriting B with X.
    140                 //
    141                 // K+1 is the main loop index, decreasing from N to 1 in steps of
    142                 // 1 or 2, depending on the size of the diagonal blocks.
    143                 //
    144                 k = n-1;
    145                 while( k>=0 )
    146                 {
    147                     if( pivots[k]>=0 )
    148                     {
    149                        
    150                         //
    151                         // 1 x 1 diagonal block
    152                         //
    153                         // Interchange rows K+1 and IPIV(K+1).
    154                         //
    155                         kp = pivots[k];
    156                         if( kp!=k )
    157                         {
    158                             v = b[k];
    159                             b[k] = b[kp];
    160                             b[kp] = v;
    161                         }
    162                        
    163                         //
    164                         // Multiply by inv(U(K+1)), where U(K+1) is the transformation
    165                         // stored in column K+1 of A.
    166                         //
    167                         v = b[k];
    168                         for(i_=0; i_<=k-1;i_++)
    169                         {
    170                             b[i_] = b[i_] - v*a[i_,k];
    171                         }
    172                        
    173                         //
    174                         // Multiply by the inverse of the diagonal block.
    175                         //
    176                         b[k] = b[k]/a[k,k];
    177                         k = k-1;
    178                     }
    179                     else
    180                     {
    181                        
    182                         //
    183                         // 2 x 2 diagonal block
    184                         //
    185                         // Interchange rows K+1-1 and -IPIV(K+1).
    186                         //
    187                         kp = pivots[k]+n;
    188                         if( kp!=k-1 )
    189                         {
    190                             v = b[k-1];
    191                             b[k-1] = b[kp];
    192                             b[kp] = v;
    193                         }
    194                        
    195                         //
    196                         // Multiply by inv(U(K+1)), where U(K+1) is the transformation
    197                         // stored in columns K+1-1 and K+1 of A.
    198                         //
    199                         v = b[k];
    200                         for(i_=0; i_<=k-2;i_++)
    201                         {
    202                             b[i_] = b[i_] - v*a[i_,k];
    203                         }
    204                         v = b[k-1];
    205                         for(i_=0; i_<=k-2;i_++)
    206                         {
    207                             b[i_] = b[i_] - v*a[i_,k-1];
    208                         }
    209                        
    210                         //
    211                         // Multiply by the inverse of the diagonal block.
    212                         //
    213                         akm1k = a[k-1,k];
    214                         akm1 = a[k-1,k-1]/akm1k;
    215                         ak = a[k,k]/akm1k;
    216                         denom = akm1*ak-1;
    217                         bkm1 = b[k-1]/akm1k;
    218                         bk = b[k]/akm1k;
    219                         b[k-1] = (ak*bkm1-bk)/denom;
    220                         b[k] = (akm1*bk-bkm1)/denom;
    221                         k = k-2;
    222                     }
    223                 }
    224                
    225                 //
    226                 // Next solve U'*X = B, overwriting B with X.
    227                 //
    228                 // K+1 is the main loop index, increasing from 1 to N in steps of
    229                 // 1 or 2, depending on the size of the diagonal blocks.
    230                 //
    231                 k = 0;
    232                 while( k<=n-1 )
    233                 {
    234                     if( pivots[k]>=0 )
    235                     {
    236                        
    237                         //
    238                         // 1 x 1 diagonal block
    239                         //
    240                         // Multiply by inv(U'(K+1)), where U(K+1) is the transformation
    241                         // stored in column K+1 of A.
    242                         //
    243                         v = 0.0;
    244                         for(i_=0; i_<=k-1;i_++)
    245                         {
    246                             v += b[i_]*a[i_,k];
    247                         }
    248                         b[k] = b[k]-v;
    249                        
    250                         //
    251                         // Interchange rows K+1 and IPIV(K+1).
    252                         //
    253                         kp = pivots[k];
    254                         if( kp!=k )
    255                         {
    256                             v = b[k];
    257                             b[k] = b[kp];
    258                             b[kp] = v;
    259                         }
    260                         k = k+1;
    261                     }
    262                     else
    263                     {
    264                        
    265                         //
    266                         // 2 x 2 diagonal block
    267                         //
    268                         // Multiply by inv(U'(K+1+1)), where U(K+1+1) is the transformation
    269                         // stored in columns K+1 and K+1+1 of A.
    270                         //
    271                         v = 0.0;
    272                         for(i_=0; i_<=k-1;i_++)
    273                         {
    274                             v += b[i_]*a[i_,k];
    275                         }
    276                         b[k] = b[k]-v;
    277                         v = 0.0;
    278                         for(i_=0; i_<=k-1;i_++)
    279                         {
    280                             v += b[i_]*a[i_,k+1];
    281                         }
    282                         b[k+1] = b[k+1]-v;
    283                        
    284                         //
    285                         // Interchange rows K+1 and -IPIV(K+1).
    286                         //
    287                         kp = pivots[k]+n;
    288                         if( kp!=k )
    289                         {
    290                             v = b[k];
    291                             b[k] = b[kp];
    292                             b[kp] = v;
    293                         }
    294                         k = k+2;
    295                     }
    296                 }
    297             }
    298             else
    299             {
    300                
    301                 //
    302                 // Solve A*X = B, where A = L*D*L'.
    303                 //
    304                 // First solve L*D*X = B, overwriting B with X.
    305                 //
    306                 // K+1 is the main loop index, increasing from 1 to N in steps of
    307                 // 1 or 2, depending on the size of the diagonal blocks.
    308                 //
    309                 k = 0;
    310                 while( k<=n-1 )
    311                 {
    312                     if( pivots[k]>=0 )
    313                     {
    314                        
    315                         //
    316                         // 1 x 1 diagonal block
    317                         //
    318                         // Interchange rows K+1 and IPIV(K+1).
    319                         //
    320                         kp = pivots[k];
    321                         if( kp!=k )
    322                         {
    323                             v = b[k];
    324                             b[k] = b[kp];
    325                             b[kp] = v;
    326                         }
    327                        
    328                         //
    329                         // Multiply by inv(L(K+1)), where L(K+1) is the transformation
    330                         // stored in column K+1 of A.
    331                         //
    332                         if( k+1<n )
    333                         {
    334                             v = b[k];
    335                             for(i_=k+1; i_<=n-1;i_++)
    336                             {
    337                                 b[i_] = b[i_] - v*a[i_,k];
    338                             }
    339                         }
    340                        
    341                         //
    342                         // Multiply by the inverse of the diagonal block.
    343                         //
    344                         b[k] = b[k]/a[k,k];
    345                         k = k+1;
    346                     }
    347                     else
    348                     {
    349                        
    350                         //
    351                         // 2 x 2 diagonal block
    352                         //
    353                         // Interchange rows K+1+1 and -IPIV(K+1).
    354                         //
    355                         kp = pivots[k]+n;
    356                         if( kp!=k+1 )
    357                         {
    358                             v = b[k+1];
    359                             b[k+1] = b[kp];
    360                             b[kp] = v;
    361                         }
    362                        
    363                         //
    364                         // Multiply by inv(L(K+1)), where L(K+1) is the transformation
    365                         // stored in columns K+1 and K+1+1 of A.
    366                         //
    367                         if( k+1<n-1 )
    368                         {
    369                             v = b[k];
    370                             for(i_=k+2; i_<=n-1;i_++)
    371                             {
    372                                 b[i_] = b[i_] - v*a[i_,k];
    373                             }
    374                             v = b[k+1];
    375                             for(i_=k+2; i_<=n-1;i_++)
    376                             {
    377                                 b[i_] = b[i_] - v*a[i_,k+1];
    378                             }
    379                         }
    380                        
    381                         //
    382                         // Multiply by the inverse of the diagonal block.
    383                         //
    384                         akm1k = a[k+1,k];
    385                         akm1 = a[k,k]/akm1k;
    386                         ak = a[k+1,k+1]/akm1k;
    387                         denom = akm1*ak-1;
    388                         bkm1 = b[k]/akm1k;
    389                         bk = b[k+1]/akm1k;
    390                         b[k] = (ak*bkm1-bk)/denom;
    391                         b[k+1] = (akm1*bk-bkm1)/denom;
    392                         k = k+2;
    393                     }
    394                 }
    395                
    396                 //
    397                 // Next solve L'*X = B, overwriting B with X.
    398                 //
    399                 // K+1 is the main loop index, decreasing from N to 1 in steps of
    400                 // 1 or 2, depending on the size of the diagonal blocks.
    401                 //
    402                 k = n-1;
    403                 while( k>=0 )
    404                 {
    405                     if( pivots[k]>=0 )
    406                     {
    407                        
    408                         //
    409                         // 1 x 1 diagonal block
    410                         //
    411                         // Multiply by inv(L'(K+1)), where L(K+1) is the transformation
    412                         // stored in column K+1 of A.
    413                         //
    414                         if( k+1<n )
    415                         {
    416                             v = 0.0;
    417                             for(i_=k+1; i_<=n-1;i_++)
    418                             {
    419                                 v += b[i_]*a[i_,k];
    420                             }
    421                             b[k] = b[k]-v;
    422                         }
    423                        
    424                         //
    425                         // Interchange rows K+1 and IPIV(K+1).
    426                         //
    427                         kp = pivots[k];
    428                         if( kp!=k )
    429                         {
    430                             v = b[k];
    431                             b[k] = b[kp];
    432                             b[kp] = v;
    433                         }
    434                         k = k-1;
    435                     }
    436                     else
    437                     {
    438                        
    439                         //
    440                         // 2 x 2 diagonal block
    441                         //
    442                         // Multiply by inv(L'(K+1-1)), where L(K+1-1) is the transformation
    443                         // stored in columns K+1-1 and K+1 of A.
    444                         //
    445                         if( k+1<n )
    446                         {
    447                             v = 0.0;
    448                             for(i_=k+1; i_<=n-1;i_++)
    449                             {
    450                                 v += b[i_]*a[i_,k];
    451                             }
    452                             b[k] = b[k]-v;
    453                             v = 0.0;
    454                             for(i_=k+1; i_<=n-1;i_++)
    455                             {
    456                                 v += b[i_]*a[i_,k-1];
    457                             }
    458                             b[k-1] = b[k-1]-v;
    459                         }
    460                        
    461                         //
    462                         // Interchange rows K+1 and -IPIV(K+1).
    463                         //
    464                         kp = pivots[k]+n;
    465                         if( kp!=k )
    466                         {
    467                             v = b[k];
    468                             b[k] = b[kp];
    469                             b[kp] = v;
    470                         }
    471                         k = k-2;
    472                     }
    473                 }
    474             }
    475             x = new double[n-1+1];
    476             for(i_=0; i_<=n-1;i_++)
    477             {
    478                 x[i_] = b[i_];
    479             }
     27
     28namespace alglib {
     29  public class ssolve {
     30    /*************************************************************************
     31    Solving  a system  of linear equations  with a system matrix  given by its
     32    LDLT decomposition
     33
     34    The algorithm solves systems with a square matrix only.
     35
     36    Input parameters:
     37        A       -   LDLT decomposition of the matrix (the result of the
     38                    SMatrixLDLT subroutine).
     39        Pivots  -   row permutation table (the result of the SMatrixLDLT subroutine).
     40        B       -   right side of a system.
     41                    Array whose index ranges within [0..N-1].
     42        N       -   size of matrix A.
     43        IsUpper -   points to the triangle of matrix A in which the LDLT
     44                    decomposition is stored.
     45                    If IsUpper=True, the decomposition has the form of U*D*U',
     46                    matrix U is stored in the upper triangle of  matrix A  (in
     47                    that case, the lower triangle isn't used and isn't changed
     48                    by the subroutine).
     49                    Similarly, if IsUpper=False, the decomposition has the form
     50                    of L*D*L' and the lower triangle stores matrix L.
     51
     52    Output parameters:
     53        X       -   solution of a system.
     54                    Array whose index ranges within [0..N-1].
     55
     56    Result:
     57        True, if the matrix is not singular. X contains the solution.
     58        False, if the matrix is singular (the determinant of matrix D is equal
     59    to 0). In this case, X doesn't contain a solution.
     60    *************************************************************************/
     61    public static bool smatrixldltsolve(ref double[,] a,
     62        ref int[] pivots,
     63        double[] b,
     64        int n,
     65        bool isupper,
     66        ref double[] x) {
     67      bool result = new bool();
     68      int i = 0;
     69      int k = 0;
     70      int kp = 0;
     71      double ak = 0;
     72      double akm1 = 0;
     73      double akm1k = 0;
     74      double bk = 0;
     75      double bkm1 = 0;
     76      double denom = 0;
     77      double v = 0;
     78      int i_ = 0;
     79
     80      b = (double[])b.Clone();
     81
     82
     83      //
     84      // Quick return if possible
     85      //
     86      result = true;
     87      if (n == 0) {
     88        return result;
     89      }
     90
     91      //
     92      // Check that the diagonal matrix D is nonsingular
     93      //
     94      if (isupper) {
     95
     96        //
     97        // Upper triangular storage: examine D from bottom to top
     98        //
     99        for (i = n - 1; i >= 0; i--) {
     100          if (pivots[i] >= 0 & (double)(a[i, i]) == (double)(0)) {
     101            result = false;
    480102            return result;
    481         }
    482 
    483 
    484         /*************************************************************************
    485         Solving a system of linear equations with a symmetric system matrix
    486 
    487         Input parameters:
    488             A       -   system matrix (upper or lower triangle).
    489                         Array whose indexes range within [0..N-1, 0..N-1].
    490             B       -   right side of a system.
    491                         Array whose index ranges within [0..N-1].
    492             N       -   size of matrix A.
    493             IsUpper -   If IsUpper = True, A contains the upper triangle,
    494                         otherwise A contains the lower triangle.
    495 
    496         Output parameters:
    497             X       -   solution of a system.
    498                         Array whose index ranges within [0..N-1].
    499 
    500         Result:
    501             True, if the matrix is not singular. X contains the solution.
    502             False, if the matrix is singular (the determinant of the matrix is equal
    503         to 0). In this case, X doesn't contain a solution.
    504 
    505           -- ALGLIB --
    506              Copyright 2005 by Bochkanov Sergey
    507         *************************************************************************/
    508         public static bool smatrixsolve(double[,] a,
    509             ref double[] b,
    510             int n,
    511             bool isupper,
    512             ref double[] x)
    513         {
    514             bool result = new bool();
    515             int[] pivots = new int[0];
    516 
    517             a = (double[,])a.Clone();
    518 
    519             ldlt.smatrixldlt(ref a, n, isupper, ref pivots);
    520             result = smatrixldltsolve(ref a, ref pivots, b, n, isupper, ref x);
     103          }
     104        }
     105      } else {
     106
     107        //
     108        // Lower triangular storage: examine D from top to bottom.
     109        //
     110        for (i = 0; i <= n - 1; i++) {
     111          if (pivots[i] >= 0 & (double)(a[i, i]) == (double)(0)) {
     112            result = false;
    521113            return result;
    522         }
    523 
    524 
    525         public static bool solvesystemldlt(ref double[,] a,
    526             ref int[] pivots,
    527             double[] b,
    528             int n,
    529             bool isupper,
    530             ref double[] x)
    531         {
    532             bool result = new bool();
    533             int i = 0;
    534             int k = 0;
    535             int kp = 0;
    536             int km1 = 0;
    537             int km2 = 0;
    538             int kp1 = 0;
    539             int kp2 = 0;
    540             double ak = 0;
    541             double akm1 = 0;
    542             double akm1k = 0;
    543             double bk = 0;
    544             double bkm1 = 0;
    545             double denom = 0;
    546             double v = 0;
    547             int i_ = 0;
    548 
    549             b = (double[])b.Clone();
    550 
    551            
    552             //
    553             // Quick return if possible
    554             //
    555             result = true;
    556             if( n==0 )
    557             {
    558                 return result;
    559             }
    560            
    561             //
    562             // Check that the diagonal matrix D is nonsingular
    563             //
    564             if( isupper )
    565             {
    566                
    567                 //
    568                 // Upper triangular storage: examine D from bottom to top
    569                 //
    570                 for(i=n; i>=1; i--)
    571                 {
    572                     if( pivots[i]>0 & (double)(a[i,i])==(double)(0) )
    573                     {
    574                         result = false;
    575                         return result;
    576                     }
    577                 }
    578             }
    579             else
    580             {
    581                
    582                 //
    583                 // Lower triangular storage: examine D from top to bottom.
    584                 //
    585                 for(i=1; i<=n; i++)
    586                 {
    587                     if( pivots[i]>0 & (double)(a[i,i])==(double)(0) )
    588                     {
    589                         result = false;
    590                         return result;
    591                     }
    592                 }
    593             }
    594            
    595             //
    596             // Solve Ax = b
    597             //
    598             if( isupper )
    599             {
    600                
    601                 //
    602                 // Solve A*X = B, where A = U*D*U'.
    603                 //
    604                 // First solve U*D*X = B, overwriting B with X.
    605                 //
    606                 // K is the main loop index, decreasing from N to 1 in steps of
    607                 // 1 or 2, depending on the size of the diagonal blocks.
    608                 //
    609                 k = n;
    610                 while( k>=1 )
    611                 {
    612                     if( pivots[k]>0 )
    613                     {
    614                        
    615                         //
    616                         // 1 x 1 diagonal block
    617                         //
    618                         // Interchange rows K and IPIV(K).
    619                         //
    620                         kp = pivots[k];
    621                         if( kp!=k )
    622                         {
    623                             v = b[k];
    624                             b[k] = b[kp];
    625                             b[kp] = v;
    626                         }
    627                        
    628                         //
    629                         // Multiply by inv(U(K)), where U(K) is the transformation
    630                         // stored in column K of A.
    631                         //
    632                         km1 = k-1;
    633                         v = b[k];
    634                         for(i_=1; i_<=km1;i_++)
    635                         {
    636                             b[i_] = b[i_] - v*a[i_,k];
    637                         }
    638                        
    639                         //
    640                         // Multiply by the inverse of the diagonal block.
    641                         //
    642                         b[k] = b[k]/a[k,k];
    643                         k = k-1;
    644                     }
    645                     else
    646                     {
    647                        
    648                         //
    649                         // 2 x 2 diagonal block
    650                         //
    651                         // Interchange rows K-1 and -IPIV(K).
    652                         //
    653                         kp = -pivots[k];
    654                         if( kp!=k-1 )
    655                         {
    656                             v = b[k-1];
    657                             b[k-1] = b[kp];
    658                             b[kp] = v;
    659                         }
    660                        
    661                         //
    662                         // Multiply by inv(U(K)), where U(K) is the transformation
    663                         // stored in columns K-1 and K of A.
    664                         //
    665                         km2 = k-2;
    666                         km1 = k-1;
    667                         v = b[k];
    668                         for(i_=1; i_<=km2;i_++)
    669                         {
    670                             b[i_] = b[i_] - v*a[i_,k];
    671                         }
    672                         v = b[k-1];
    673                         for(i_=1; i_<=km2;i_++)
    674                         {
    675                             b[i_] = b[i_] - v*a[i_,km1];
    676                         }
    677                        
    678                         //
    679                         // Multiply by the inverse of the diagonal block.
    680                         //
    681                         akm1k = a[k-1,k];
    682                         akm1 = a[k-1,k-1]/akm1k;
    683                         ak = a[k,k]/akm1k;
    684                         denom = akm1*ak-1;
    685                         bkm1 = b[k-1]/akm1k;
    686                         bk = b[k]/akm1k;
    687                         b[k-1] = (ak*bkm1-bk)/denom;
    688                         b[k] = (akm1*bk-bkm1)/denom;
    689                         k = k-2;
    690                     }
    691                 }
    692                
    693                 //
    694                 // Next solve U'*X = B, overwriting B with X.
    695                 //
    696                 // K is the main loop index, increasing from 1 to N in steps of
    697                 // 1 or 2, depending on the size of the diagonal blocks.
    698                 //
    699                 k = 1;
    700                 while( k<=n )
    701                 {
    702                     if( pivots[k]>0 )
    703                     {
    704                        
    705                         //
    706                         // 1 x 1 diagonal block
    707                         //
    708                         // Multiply by inv(U'(K)), where U(K) is the transformation
    709                         // stored in column K of A.
    710                         //
    711                         km1 = k-1;
    712                         v = 0.0;
    713                         for(i_=1; i_<=km1;i_++)
    714                         {
    715                             v += b[i_]*a[i_,k];
    716                         }
    717                         b[k] = b[k]-v;
    718                        
    719                         //
    720                         // Interchange rows K and IPIV(K).
    721                         //
    722                         kp = pivots[k];
    723                         if( kp!=k )
    724                         {
    725                             v = b[k];
    726                             b[k] = b[kp];
    727                             b[kp] = v;
    728                         }
    729                         k = k+1;
    730                     }
    731                     else
    732                     {
    733                        
    734                         //
    735                         // 2 x 2 diagonal block
    736                         //
    737                         // Multiply by inv(U'(K+1)), where U(K+1) is the transformation
    738                         // stored in columns K and K+1 of A.
    739                         //
    740                         km1 = k-1;
    741                         kp1 = k+1;
    742                         v = 0.0;
    743                         for(i_=1; i_<=km1;i_++)
    744                         {
    745                             v += b[i_]*a[i_,k];
    746                         }
    747                         b[k] = b[k]-v;
    748                         v = 0.0;
    749                         for(i_=1; i_<=km1;i_++)
    750                         {
    751                             v += b[i_]*a[i_,kp1];
    752                         }
    753                         b[k+1] = b[k+1]-v;
    754                        
    755                         //
    756                         // Interchange rows K and -IPIV(K).
    757                         //
    758                         kp = -pivots[k];
    759                         if( kp!=k )
    760                         {
    761                             v = b[k];
    762                             b[k] = b[kp];
    763                             b[kp] = v;
    764                         }
    765                         k = k+2;
    766                     }
    767                 }
    768             }
    769             else
    770             {
    771                
    772                 //
    773                 // Solve A*X = B, where A = L*D*L'.
    774                 //
    775                 // First solve L*D*X = B, overwriting B with X.
    776                 //
    777                 // K is the main loop index, increasing from 1 to N in steps of
    778                 // 1 or 2, depending on the size of the diagonal blocks.
    779                 //
    780                 k = 1;
    781                 while( k<=n )
    782                 {
    783                     if( pivots[k]>0 )
    784                     {
    785                        
    786                         //
    787                         // 1 x 1 diagonal block
    788                         //
    789                         // Interchange rows K and IPIV(K).
    790                         //
    791                         kp = pivots[k];
    792                         if( kp!=k )
    793                         {
    794                             v = b[k];
    795                             b[k] = b[kp];
    796                             b[kp] = v;
    797                         }
    798                        
    799                         //
    800                         // Multiply by inv(L(K)), where L(K) is the transformation
    801                         // stored in column K of A.
    802                         //
    803                         if( k<n )
    804                         {
    805                             kp1 = k+1;
    806                             v = b[k];
    807                             for(i_=kp1; i_<=n;i_++)
    808                             {
    809                                 b[i_] = b[i_] - v*a[i_,k];
    810                             }
    811                         }
    812                        
    813                         //
    814                         // Multiply by the inverse of the diagonal block.
    815                         //
    816                         b[k] = b[k]/a[k,k];
    817                         k = k+1;
    818                     }
    819                     else
    820                     {
    821                        
    822                         //
    823                         // 2 x 2 diagonal block
    824                         //
    825                         // Interchange rows K+1 and -IPIV(K).
    826                         //
    827                         kp = -pivots[k];
    828                         if( kp!=k+1 )
    829                         {
    830                             v = b[k+1];
    831                             b[k+1] = b[kp];
    832                             b[kp] = v;
    833                         }
    834                        
    835                         //
    836                         // Multiply by inv(L(K)), where L(K) is the transformation
    837                         // stored in columns K and K+1 of A.
    838                         //
    839                         if( k<n-1 )
    840                         {
    841                             kp1 = k+1;
    842                             kp2 = k+2;
    843                             v = b[k];
    844                             for(i_=kp2; i_<=n;i_++)
    845                             {
    846                                 b[i_] = b[i_] - v*a[i_,k];
    847                             }
    848                             v = b[k+1];
    849                             for(i_=kp2; i_<=n;i_++)
    850                             {
    851                                 b[i_] = b[i_] - v*a[i_,kp1];
    852                             }
    853                         }
    854                        
    855                         //
    856                         // Multiply by the inverse of the diagonal block.
    857                         //
    858                         akm1k = a[k+1,k];
    859                         akm1 = a[k,k]/akm1k;
    860                         ak = a[k+1,k+1]/akm1k;
    861                         denom = akm1*ak-1;
    862                         bkm1 = b[k]/akm1k;
    863                         bk = b[k+1]/akm1k;
    864                         b[k] = (ak*bkm1-bk)/denom;
    865                         b[k+1] = (akm1*bk-bkm1)/denom;
    866                         k = k+2;
    867                     }
    868                 }
    869                
    870                 //
    871                 // Next solve L'*X = B, overwriting B with X.
    872                 //
    873                 // K is the main loop index, decreasing from N to 1 in steps of
    874                 // 1 or 2, depending on the size of the diagonal blocks.
    875                 //
    876                 k = n;
    877                 while( k>=1 )
    878                 {
    879                     if( pivots[k]>0 )
    880                     {
    881                        
    882                         //
    883                         // 1 x 1 diagonal block
    884                         //
    885                         // Multiply by inv(L'(K)), where L(K) is the transformation
    886                         // stored in column K of A.
    887                         //
    888                         if( k<n )
    889                         {
    890                             kp1 = k+1;
    891                             v = 0.0;
    892                             for(i_=kp1; i_<=n;i_++)
    893                             {
    894                                 v += b[i_]*a[i_,k];
    895                             }
    896                             b[k] = b[k]-v;
    897                         }
    898                        
    899                         //
    900                         // Interchange rows K and IPIV(K).
    901                         //
    902                         kp = pivots[k];
    903                         if( kp!=k )
    904                         {
    905                             v = b[k];
    906                             b[k] = b[kp];
    907                             b[kp] = v;
    908                         }
    909                         k = k-1;
    910                     }
    911                     else
    912                     {
    913                        
    914                         //
    915                         // 2 x 2 diagonal block
    916                         //
    917                         // Multiply by inv(L'(K-1)), where L(K-1) is the transformation
    918                         // stored in columns K-1 and K of A.
    919                         //
    920                         if( k<n )
    921                         {
    922                             kp1 = k+1;
    923                             km1 = k-1;
    924                             v = 0.0;
    925                             for(i_=kp1; i_<=n;i_++)
    926                             {
    927                                 v += b[i_]*a[i_,k];
    928                             }
    929                             b[k] = b[k]-v;
    930                             v = 0.0;
    931                             for(i_=kp1; i_<=n;i_++)
    932                             {
    933                                 v += b[i_]*a[i_,km1];
    934                             }
    935                             b[k-1] = b[k-1]-v;
    936                         }
    937                        
    938                         //
    939                         // Interchange rows K and -IPIV(K).
    940                         //
    941                         kp = -pivots[k];
    942                         if( kp!=k )
    943                         {
    944                             v = b[k];
    945                             b[k] = b[kp];
    946                             b[kp] = v;
    947                         }
    948                         k = k-2;
    949                     }
    950                 }
    951             }
    952             x = new double[n+1];
    953             for(i_=1; i_<=n;i_++)
    954             {
    955                 x[i_] = b[i_];
    956             }
     114          }
     115        }
     116      }
     117
     118      //
     119      // Solve Ax = b
     120      //
     121      if (isupper) {
     122
     123        //
     124        // Solve A*X = B, where A = U*D*U'.
     125        //
     126        // First solve U*D*X = B, overwriting B with X.
     127        //
     128        // K+1 is the main loop index, decreasing from N to 1 in steps of
     129        // 1 or 2, depending on the size of the diagonal blocks.
     130        //
     131        k = n - 1;
     132        while (k >= 0) {
     133          if (pivots[k] >= 0) {
     134
     135            //
     136            // 1 x 1 diagonal block
     137            //
     138            // Interchange rows K+1 and IPIV(K+1).
     139            //
     140            kp = pivots[k];
     141            if (kp != k) {
     142              v = b[k];
     143              b[k] = b[kp];
     144              b[kp] = v;
     145            }
     146
     147            //
     148            // Multiply by inv(U(K+1)), where U(K+1) is the transformation
     149            // stored in column K+1 of A.
     150            //
     151            v = b[k];
     152            for (i_ = 0; i_ <= k - 1; i_++) {
     153              b[i_] = b[i_] - v * a[i_, k];
     154            }
     155
     156            //
     157            // Multiply by the inverse of the diagonal block.
     158            //
     159            b[k] = b[k] / a[k, k];
     160            k = k - 1;
     161          } else {
     162
     163            //
     164            // 2 x 2 diagonal block
     165            //
     166            // Interchange rows K+1-1 and -IPIV(K+1).
     167            //
     168            kp = pivots[k] + n;
     169            if (kp != k - 1) {
     170              v = b[k - 1];
     171              b[k - 1] = b[kp];
     172              b[kp] = v;
     173            }
     174
     175            //
     176            // Multiply by inv(U(K+1)), where U(K+1) is the transformation
     177            // stored in columns K+1-1 and K+1 of A.
     178            //
     179            v = b[k];
     180            for (i_ = 0; i_ <= k - 2; i_++) {
     181              b[i_] = b[i_] - v * a[i_, k];
     182            }
     183            v = b[k - 1];
     184            for (i_ = 0; i_ <= k - 2; i_++) {
     185              b[i_] = b[i_] - v * a[i_, k - 1];
     186            }
     187
     188            //
     189            // Multiply by the inverse of the diagonal block.
     190            //
     191            akm1k = a[k - 1, k];
     192            akm1 = a[k - 1, k - 1] / akm1k;
     193            ak = a[k, k] / akm1k;
     194            denom = akm1 * ak - 1;
     195            bkm1 = b[k - 1] / akm1k;
     196            bk = b[k] / akm1k;
     197            b[k - 1] = (ak * bkm1 - bk) / denom;
     198            b[k] = (akm1 * bk - bkm1) / denom;
     199            k = k - 2;
     200          }
     201        }
     202
     203        //
     204        // Next solve U'*X = B, overwriting B with X.
     205        //
     206        // K+1 is the main loop index, increasing from 1 to N in steps of
     207        // 1 or 2, depending on the size of the diagonal blocks.
     208        //
     209        k = 0;
     210        while (k <= n - 1) {
     211          if (pivots[k] >= 0) {
     212
     213            //
     214            // 1 x 1 diagonal block
     215            //
     216            // Multiply by inv(U'(K+1)), where U(K+1) is the transformation
     217            // stored in column K+1 of A.
     218            //
     219            v = 0.0;
     220            for (i_ = 0; i_ <= k - 1; i_++) {
     221              v += b[i_] * a[i_, k];
     222            }
     223            b[k] = b[k] - v;
     224
     225            //
     226            // Interchange rows K+1 and IPIV(K+1).
     227            //
     228            kp = pivots[k];
     229            if (kp != k) {
     230              v = b[k];
     231              b[k] = b[kp];
     232              b[kp] = v;
     233            }
     234            k = k + 1;
     235          } else {
     236
     237            //
     238            // 2 x 2 diagonal block
     239            //
     240            // Multiply by inv(U'(K+1+1)), where U(K+1+1) is the transformation
     241            // stored in columns K+1 and K+1+1 of A.
     242            //
     243            v = 0.0;
     244            for (i_ = 0; i_ <= k - 1; i_++) {
     245              v += b[i_] * a[i_, k];
     246            }
     247            b[k] = b[k] - v;
     248            v = 0.0;
     249            for (i_ = 0; i_ <= k - 1; i_++) {
     250              v += b[i_] * a[i_, k + 1];
     251            }
     252            b[k + 1] = b[k + 1] - v;
     253
     254            //
     255            // Interchange rows K+1 and -IPIV(K+1).
     256            //
     257            kp = pivots[k] + n;
     258            if (kp != k) {
     259              v = b[k];
     260              b[k] = b[kp];
     261              b[kp] = v;
     262            }
     263            k = k + 2;
     264          }
     265        }
     266      } else {
     267
     268        //
     269        // Solve A*X = B, where A = L*D*L'.
     270        //
     271        // First solve L*D*X = B, overwriting B with X.
     272        //
     273        // K+1 is the main loop index, increasing from 1 to N in steps of
     274        // 1 or 2, depending on the size of the diagonal blocks.
     275        //
     276        k = 0;
     277        while (k <= n - 1) {
     278          if (pivots[k] >= 0) {
     279
     280            //
     281            // 1 x 1 diagonal block
     282            //
     283            // Interchange rows K+1 and IPIV(K+1).
     284            //
     285            kp = pivots[k];
     286            if (kp != k) {
     287              v = b[k];
     288              b[k] = b[kp];
     289              b[kp] = v;
     290            }
     291
     292            //
     293            // Multiply by inv(L(K+1)), where L(K+1) is the transformation
     294            // stored in column K+1 of A.
     295            //
     296            if (k + 1 < n) {
     297              v = b[k];
     298              for (i_ = k + 1; i_ <= n - 1; i_++) {
     299                b[i_] = b[i_] - v * a[i_, k];
     300              }
     301            }
     302
     303            //
     304            // Multiply by the inverse of the diagonal block.
     305            //
     306            b[k] = b[k] / a[k, k];
     307            k = k + 1;
     308          } else {
     309
     310            //
     311            // 2 x 2 diagonal block
     312            //
     313            // Interchange rows K+1+1 and -IPIV(K+1).
     314            //
     315            kp = pivots[k] + n;
     316            if (kp != k + 1) {
     317              v = b[k + 1];
     318              b[k + 1] = b[kp];
     319              b[kp] = v;
     320            }
     321
     322            //
     323            // Multiply by inv(L(K+1)), where L(K+1) is the transformation
     324            // stored in columns K+1 and K+1+1 of A.
     325            //
     326            if (k + 1 < n - 1) {
     327              v = b[k];
     328              for (i_ = k + 2; i_ <= n - 1; i_++) {
     329                b[i_] = b[i_] - v * a[i_, k];
     330              }
     331              v = b[k + 1];
     332              for (i_ = k + 2; i_ <= n - 1; i_++) {
     333                b[i_] = b[i_] - v * a[i_, k + 1];
     334              }
     335            }
     336
     337            //
     338            // Multiply by the inverse of the diagonal block.
     339            //
     340            akm1k = a[k + 1, k];
     341            akm1 = a[k, k] / akm1k;
     342            ak = a[k + 1, k + 1] / akm1k;
     343            denom = akm1 * ak - 1;
     344            bkm1 = b[k] / akm1k;
     345            bk = b[k + 1] / akm1k;
     346            b[k] = (ak * bkm1 - bk) / denom;
     347            b[k + 1] = (akm1 * bk - bkm1) / denom;
     348            k = k + 2;
     349          }
     350        }
     351
     352        //
     353        // Next solve L'*X = B, overwriting B with X.
     354        //
     355        // K+1 is the main loop index, decreasing from N to 1 in steps of
     356        // 1 or 2, depending on the size of the diagonal blocks.
     357        //
     358        k = n - 1;
     359        while (k >= 0) {
     360          if (pivots[k] >= 0) {
     361
     362            //
     363            // 1 x 1 diagonal block
     364            //
     365            // Multiply by inv(L'(K+1)), where L(K+1) is the transformation
     366            // stored in column K+1 of A.
     367            //
     368            if (k + 1 < n) {
     369              v = 0.0;
     370              for (i_ = k + 1; i_ <= n - 1; i_++) {
     371                v += b[i_] * a[i_, k];
     372              }
     373              b[k] = b[k] - v;
     374            }
     375
     376            //
     377            // Interchange rows K+1 and IPIV(K+1).
     378            //
     379            kp = pivots[k];
     380            if (kp != k) {
     381              v = b[k];
     382              b[k] = b[kp];
     383              b[kp] = v;
     384            }
     385            k = k - 1;
     386          } else {
     387
     388            //
     389            // 2 x 2 diagonal block
     390            //
     391            // Multiply by inv(L'(K+1-1)), where L(K+1-1) is the transformation
     392            // stored in columns K+1-1 and K+1 of A.
     393            //
     394            if (k + 1 < n) {
     395              v = 0.0;
     396              for (i_ = k + 1; i_ <= n - 1; i_++) {
     397                v += b[i_] * a[i_, k];
     398              }
     399              b[k] = b[k] - v;
     400              v = 0.0;
     401              for (i_ = k + 1; i_ <= n - 1; i_++) {
     402                v += b[i_] * a[i_, k - 1];
     403              }
     404              b[k - 1] = b[k - 1] - v;
     405            }
     406
     407            //
     408            // Interchange rows K+1 and -IPIV(K+1).
     409            //
     410            kp = pivots[k] + n;
     411            if (kp != k) {
     412              v = b[k];
     413              b[k] = b[kp];
     414              b[kp] = v;
     415            }
     416            k = k - 2;
     417          }
     418        }
     419      }
     420      x = new double[n - 1 + 1];
     421      for (i_ = 0; i_ <= n - 1; i_++) {
     422        x[i_] = b[i_];
     423      }
     424      return result;
     425    }
     426
     427
     428    /*************************************************************************
     429    Solving a system of linear equations with a symmetric system matrix
     430
     431    Input parameters:
     432        A       -   system matrix (upper or lower triangle).
     433                    Array whose indexes range within [0..N-1, 0..N-1].
     434        B       -   right side of a system.
     435                    Array whose index ranges within [0..N-1].
     436        N       -   size of matrix A.
     437        IsUpper -   If IsUpper = True, A contains the upper triangle,
     438                    otherwise A contains the lower triangle.
     439
     440    Output parameters:
     441        X       -   solution of a system.
     442                    Array whose index ranges within [0..N-1].
     443
     444    Result:
     445        True, if the matrix is not singular. X contains the solution.
     446        False, if the matrix is singular (the determinant of the matrix is equal
     447    to 0). In this case, X doesn't contain a solution.
     448
     449      -- ALGLIB --
     450         Copyright 2005 by Bochkanov Sergey
     451    *************************************************************************/
     452    public static bool smatrixsolve(double[,] a,
     453        ref double[] b,
     454        int n,
     455        bool isupper,
     456        ref double[] x) {
     457      bool result = new bool();
     458      int[] pivots = new int[0];
     459
     460      a = (double[,])a.Clone();
     461
     462      ldlt.smatrixldlt(ref a, n, isupper, ref pivots);
     463      result = smatrixldltsolve(ref a, ref pivots, b, n, isupper, ref x);
     464      return result;
     465    }
     466
     467
     468    public static bool solvesystemldlt(ref double[,] a,
     469        ref int[] pivots,
     470        double[] b,
     471        int n,
     472        bool isupper,
     473        ref double[] x) {
     474      bool result = new bool();
     475      int i = 0;
     476      int k = 0;
     477      int kp = 0;
     478      int km1 = 0;
     479      int km2 = 0;
     480      int kp1 = 0;
     481      int kp2 = 0;
     482      double ak = 0;
     483      double akm1 = 0;
     484      double akm1k = 0;
     485      double bk = 0;
     486      double bkm1 = 0;
     487      double denom = 0;
     488      double v = 0;
     489      int i_ = 0;
     490
     491      b = (double[])b.Clone();
     492
     493
     494      //
     495      // Quick return if possible
     496      //
     497      result = true;
     498      if (n == 0) {
     499        return result;
     500      }
     501
     502      //
     503      // Check that the diagonal matrix D is nonsingular
     504      //
     505      if (isupper) {
     506
     507        //
     508        // Upper triangular storage: examine D from bottom to top
     509        //
     510        for (i = n; i >= 1; i--) {
     511          if (pivots[i] > 0 & (double)(a[i, i]) == (double)(0)) {
     512            result = false;
    957513            return result;
    958         }
    959 
    960 
    961         public static bool solvesymmetricsystem(double[,] a,
    962             double[] b,
    963             int n,
    964             bool isupper,
    965             ref double[] x)
    966         {
    967             bool result = new bool();
    968             int[] pivots = new int[0];
    969 
    970             a = (double[,])a.Clone();
    971             b = (double[])b.Clone();
    972 
    973             ldlt.ldltdecomposition(ref a, n, isupper, ref pivots);
    974             result = solvesystemldlt(ref a, ref pivots, b, n, isupper, ref x);
     514          }
     515        }
     516      } else {
     517
     518        //
     519        // Lower triangular storage: examine D from top to bottom.
     520        //
     521        for (i = 1; i <= n; i++) {
     522          if (pivots[i] > 0 & (double)(a[i, i]) == (double)(0)) {
     523            result = false;
    975524            return result;
    976         }
     525          }
     526        }
     527      }
     528
     529      //
     530      // Solve Ax = b
     531      //
     532      if (isupper) {
     533
     534        //
     535        // Solve A*X = B, where A = U*D*U'.
     536        //
     537        // First solve U*D*X = B, overwriting B with X.
     538        //
     539        // K is the main loop index, decreasing from N to 1 in steps of
     540        // 1 or 2, depending on the size of the diagonal blocks.
     541        //
     542        k = n;
     543        while (k >= 1) {
     544          if (pivots[k] > 0) {
     545
     546            //
     547            // 1 x 1 diagonal block
     548            //
     549            // Interchange rows K and IPIV(K).
     550            //
     551            kp = pivots[k];
     552            if (kp != k) {
     553              v = b[k];
     554              b[k] = b[kp];
     555              b[kp] = v;
     556            }
     557
     558            //
     559            // Multiply by inv(U(K)), where U(K) is the transformation
     560            // stored in column K of A.
     561            //
     562            km1 = k - 1;
     563            v = b[k];
     564            for (i_ = 1; i_ <= km1; i_++) {
     565              b[i_] = b[i_] - v * a[i_, k];
     566            }
     567
     568            //
     569            // Multiply by the inverse of the diagonal block.
     570            //
     571            b[k] = b[k] / a[k, k];
     572            k = k - 1;
     573          } else {
     574
     575            //
     576            // 2 x 2 diagonal block
     577            //
     578            // Interchange rows K-1 and -IPIV(K).
     579            //
     580            kp = -pivots[k];
     581            if (kp != k - 1) {
     582              v = b[k - 1];
     583              b[k - 1] = b[kp];
     584              b[kp] = v;
     585            }
     586
     587            //
     588            // Multiply by inv(U(K)), where U(K) is the transformation
     589            // stored in columns K-1 and K of A.
     590            //
     591            km2 = k - 2;
     592            km1 = k - 1;
     593            v = b[k];
     594            for (i_ = 1; i_ <= km2; i_++) {
     595              b[i_] = b[i_] - v * a[i_, k];
     596            }
     597            v = b[k - 1];
     598            for (i_ = 1; i_ <= km2; i_++) {
     599              b[i_] = b[i_] - v * a[i_, km1];
     600            }
     601
     602            //
     603            // Multiply by the inverse of the diagonal block.
     604            //
     605            akm1k = a[k - 1, k];
     606            akm1 = a[k - 1, k - 1] / akm1k;
     607            ak = a[k, k] / akm1k;
     608            denom = akm1 * ak - 1;
     609            bkm1 = b[k - 1] / akm1k;
     610            bk = b[k] / akm1k;
     611            b[k - 1] = (ak * bkm1 - bk) / denom;
     612            b[k] = (akm1 * bk - bkm1) / denom;
     613            k = k - 2;
     614          }
     615        }
     616
     617        //
     618        // Next solve U'*X = B, overwriting B with X.
     619        //
     620        // K is the main loop index, increasing from 1 to N in steps of
     621        // 1 or 2, depending on the size of the diagonal blocks.
     622        //
     623        k = 1;
     624        while (k <= n) {
     625          if (pivots[k] > 0) {
     626
     627            //
     628            // 1 x 1 diagonal block
     629            //
     630            // Multiply by inv(U'(K)), where U(K) is the transformation
     631            // stored in column K of A.
     632            //
     633            km1 = k - 1;
     634            v = 0.0;
     635            for (i_ = 1; i_ <= km1; i_++) {
     636              v += b[i_] * a[i_, k];
     637            }
     638            b[k] = b[k] - v;
     639
     640            //
     641            // Interchange rows K and IPIV(K).
     642            //
     643            kp = pivots[k];
     644            if (kp != k) {
     645              v = b[k];
     646              b[k] = b[kp];
     647              b[kp] = v;
     648            }
     649            k = k + 1;
     650          } else {
     651
     652            //
     653            // 2 x 2 diagonal block
     654            //
     655            // Multiply by inv(U'(K+1)), where U(K+1) is the transformation
     656            // stored in columns K and K+1 of A.
     657            //
     658            km1 = k - 1;
     659            kp1 = k + 1;
     660            v = 0.0;
     661            for (i_ = 1; i_ <= km1; i_++) {
     662              v += b[i_] * a[i_, k];
     663            }
     664            b[k] = b[k] - v;
     665            v = 0.0;
     666            for (i_ = 1; i_ <= km1; i_++) {
     667              v += b[i_] * a[i_, kp1];
     668            }
     669            b[k + 1] = b[k + 1] - v;
     670
     671            //
     672            // Interchange rows K and -IPIV(K).
     673            //
     674            kp = -pivots[k];
     675            if (kp != k) {
     676              v = b[k];
     677              b[k] = b[kp];
     678              b[kp] = v;
     679            }
     680            k = k + 2;
     681          }
     682        }
     683      } else {
     684
     685        //
     686        // Solve A*X = B, where A = L*D*L'.
     687        //
     688        // First solve L*D*X = B, overwriting B with X.
     689        //
     690        // K is the main loop index, increasing from 1 to N in steps of
     691        // 1 or 2, depending on the size of the diagonal blocks.
     692        //
     693        k = 1;
     694        while (k <= n) {
     695          if (pivots[k] > 0) {
     696
     697            //
     698            // 1 x 1 diagonal block
     699            //
     700            // Interchange rows K and IPIV(K).
     701            //
     702            kp = pivots[k];
     703            if (kp != k) {
     704              v = b[k];
     705              b[k] = b[kp];
     706              b[kp] = v;
     707            }
     708
     709            //
     710            // Multiply by inv(L(K)), where L(K) is the transformation
     711            // stored in column K of A.
     712            //
     713            if (k < n) {
     714              kp1 = k + 1;
     715              v = b[k];
     716              for (i_ = kp1; i_ <= n; i_++) {
     717                b[i_] = b[i_] - v * a[i_, k];
     718              }
     719            }
     720
     721            //
     722            // Multiply by the inverse of the diagonal block.
     723            //
     724            b[k] = b[k] / a[k, k];
     725            k = k + 1;
     726          } else {
     727
     728            //
     729            // 2 x 2 diagonal block
     730            //
     731            // Interchange rows K+1 and -IPIV(K).
     732            //
     733            kp = -pivots[k];
     734            if (kp != k + 1) {
     735              v = b[k + 1];
     736              b[k + 1] = b[kp];
     737              b[kp] = v;
     738            }
     739
     740            //
     741            // Multiply by inv(L(K)), where L(K) is the transformation
     742            // stored in columns K and K+1 of A.
     743            //
     744            if (k < n - 1) {
     745              kp1 = k + 1;
     746              kp2 = k + 2;
     747              v = b[k];
     748              for (i_ = kp2; i_ <= n; i_++) {
     749                b[i_] = b[i_] - v * a[i_, k];
     750              }
     751              v = b[k + 1];
     752              for (i_ = kp2; i_ <= n; i_++) {
     753                b[i_] = b[i_] - v * a[i_, kp1];
     754              }
     755            }
     756
     757            //
     758            // Multiply by the inverse of the diagonal block.
     759            //
     760            akm1k = a[k + 1, k];
     761            akm1 = a[k, k] / akm1k;
     762            ak = a[k + 1, k + 1] / akm1k;
     763            denom = akm1 * ak - 1;
     764            bkm1 = b[k] / akm1k;
     765            bk = b[k + 1] / akm1k;
     766            b[k] = (ak * bkm1 - bk) / denom;
     767            b[k + 1] = (akm1 * bk - bkm1) / denom;
     768            k = k + 2;
     769          }
     770        }
     771
     772        //
     773        // Next solve L'*X = B, overwriting B with X.
     774        //
     775        // K is the main loop index, decreasing from N to 1 in steps of
     776        // 1 or 2, depending on the size of the diagonal blocks.
     777        //
     778        k = n;
     779        while (k >= 1) {
     780          if (pivots[k] > 0) {
     781
     782            //
     783            // 1 x 1 diagonal block
     784            //
     785            // Multiply by inv(L'(K)), where L(K) is the transformation
     786            // stored in column K of A.
     787            //
     788            if (k < n) {
     789              kp1 = k + 1;
     790              v = 0.0;
     791              for (i_ = kp1; i_ <= n; i_++) {
     792                v += b[i_] * a[i_, k];
     793              }
     794              b[k] = b[k] - v;
     795            }
     796
     797            //
     798            // Interchange rows K and IPIV(K).
     799            //
     800            kp = pivots[k];
     801            if (kp != k) {
     802              v = b[k];
     803              b[k] = b[kp];
     804              b[kp] = v;
     805            }
     806            k = k - 1;
     807          } else {
     808
     809            //
     810            // 2 x 2 diagonal block
     811            //
     812            // Multiply by inv(L'(K-1)), where L(K-1) is the transformation
     813            // stored in columns K-1 and K of A.
     814            //
     815            if (k < n) {
     816              kp1 = k + 1;
     817              km1 = k - 1;
     818              v = 0.0;
     819              for (i_ = kp1; i_ <= n; i_++) {
     820                v += b[i_] * a[i_, k];
     821              }
     822              b[k] = b[k] - v;
     823              v = 0.0;
     824              for (i_ = kp1; i_ <= n; i_++) {
     825                v += b[i_] * a[i_, km1];
     826              }
     827              b[k - 1] = b[k - 1] - v;
     828            }
     829
     830            //
     831            // Interchange rows K and -IPIV(K).
     832            //
     833            kp = -pivots[k];
     834            if (kp != k) {
     835              v = b[k];
     836              b[k] = b[kp];
     837              b[kp] = v;
     838            }
     839            k = k - 2;
     840          }
     841        }
     842      }
     843      x = new double[n + 1];
     844      for (i_ = 1; i_ <= n; i_++) {
     845        x[i_] = b[i_];
     846      }
     847      return result;
    977848    }
     849
     850
     851    public static bool solvesymmetricsystem(double[,] a,
     852        double[] b,
     853        int n,
     854        bool isupper,
     855        ref double[] x) {
     856      bool result = new bool();
     857      int[] pivots = new int[0];
     858
     859      a = (double[,])a.Clone();
     860      b = (double[])b.Clone();
     861
     862      ldlt.ldltdecomposition(ref a, n, isupper, ref pivots);
     863      result = solvesystemldlt(ref a, ref pivots, b, n, isupper, ref x);
     864      return result;
     865    }
     866  }
    978867}
Note: See TracChangeset for help on using the changeset viewer.