Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.ExtLibs/HeuristicLab.ALGLIB/2.5.0/ALGLIB-2.5.0/ssolve.cs @ 4068

Last change on this file since 4068 was 4068, checked in by swagner, 14 years ago

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

File size: 24.3 KB
Line 
1/*************************************************************************
2Copyright (c) 1992-2007 The University of Tennessee.  All rights reserved.
3
4Contributors:
5    * Sergey Bochkanov (ALGLIB project). Translation from FORTRAN to
6      pseudocode.
7
8See subroutines comments for additional copyrights.
9
10>>> SOURCE LICENSE >>>
11This program is free software; you can redistribute it and/or modify
12it under the terms of the GNU General Public License as published by
13the Free Software Foundation (www.fsf.org); either version 2 of the
14License, or (at your option) any later version.
15
16This program is distributed in the hope that it will be useful,
17but WITHOUT ANY WARRANTY; without even the implied warranty of
18MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19GNU General Public License for more details.
20
21A copy of the GNU General Public License is available at
22http://www.fsf.org/licensing/licenses
23
24>>> END OF LICENSE >>>
25*************************************************************************/
26
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;
102            return result;
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;
113            return result;
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;
513            return result;
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;
524            return result;
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;
848    }
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  }
867}
Note: See TracBrowser for help on using the repository browser.