Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HivePerformance/sources/HeuristicLab.ExtLibs/HeuristicLab.ALGLIB/3.6.0/ALGLIB-3.6.0/solvers.cs @ 9368

Last change on this file since 9368 was 8418, checked in by abeham, 12 years ago

#1905: Added ALGLIB 3.6.0 to ExtLibs

File size: 251.9 KB
Line 
1/*************************************************************************
2Copyright (c) Sergey Bochkanov (ALGLIB project).
3
4>>> SOURCE LICENSE >>>
5This program is free software; you can redistribute it and/or modify
6it under the terms of the GNU General Public License as published by
7the Free Software Foundation (www.fsf.org); either version 2 of the
8License, or (at your option) any later version.
9
10This program is distributed in the hope that it will be useful,
11but WITHOUT ANY WARRANTY; without even the implied warranty of
12MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13GNU General Public License for more details.
14
15A copy of the GNU General Public License is available at
16http://www.fsf.org/licensing/licenses
17>>> END OF LICENSE >>>
18*************************************************************************/
19#pragma warning disable 162
20#pragma warning disable 219
21using System;
22
23public partial class alglib
24{
25
26
27    /*************************************************************************
28
29    *************************************************************************/
30    public class densesolverreport
31    {
32        //
33        // Public declarations
34        //
35        public double r1 { get { return _innerobj.r1; } set { _innerobj.r1 = value; } }
36        public double rinf { get { return _innerobj.rinf; } set { _innerobj.rinf = value; } }
37
38        public densesolverreport()
39        {
40            _innerobj = new densesolver.densesolverreport();
41        }
42
43        //
44        // Although some of declarations below are public, you should not use them
45        // They are intended for internal use only
46        //
47        private densesolver.densesolverreport _innerobj;
48        public densesolver.densesolverreport innerobj { get { return _innerobj; } }
49        public densesolverreport(densesolver.densesolverreport obj)
50        {
51            _innerobj = obj;
52        }
53    }
54
55
56    /*************************************************************************
57
58    *************************************************************************/
59    public class densesolverlsreport
60    {
61        //
62        // Public declarations
63        //
64        public double r2 { get { return _innerobj.r2; } set { _innerobj.r2 = value; } }
65        public double[,] cx { get { return _innerobj.cx; } set { _innerobj.cx = value; } }
66        public int n { get { return _innerobj.n; } set { _innerobj.n = value; } }
67        public int k { get { return _innerobj.k; } set { _innerobj.k = value; } }
68
69        public densesolverlsreport()
70        {
71            _innerobj = new densesolver.densesolverlsreport();
72        }
73
74        //
75        // Although some of declarations below are public, you should not use them
76        // They are intended for internal use only
77        //
78        private densesolver.densesolverlsreport _innerobj;
79        public densesolver.densesolverlsreport innerobj { get { return _innerobj; } }
80        public densesolverlsreport(densesolver.densesolverlsreport obj)
81        {
82            _innerobj = obj;
83        }
84    }
85
86    /*************************************************************************
87    Dense solver.
88
89    This  subroutine  solves  a  system  A*x=b,  where A is NxN non-denegerate
90    real matrix, x and b are vectors.
91
92    Algorithm features:
93    * automatic detection of degenerate cases
94    * condition number estimation
95    * iterative refinement
96    * O(N^3) complexity
97
98    INPUT PARAMETERS
99        A       -   array[0..N-1,0..N-1], system matrix
100        N       -   size of A
101        B       -   array[0..N-1], right part
102
103    OUTPUT PARAMETERS
104        Info    -   return code:
105                    * -3    A is singular, or VERY close to singular.
106                            X is filled by zeros in such cases.
107                    * -1    N<=0 was passed
108                    *  1    task is solved (but matrix A may be ill-conditioned,
109                            check R1/RInf parameters for condition numbers).
110        Rep     -   solver report, see below for more info
111        X       -   array[0..N-1], it contains:
112                    * solution of A*x=b if A is non-singular (well-conditioned
113                      or ill-conditioned, but not very close to singular)
114                    * zeros,  if  A  is  singular  or  VERY  close to singular
115                      (in this case Info=-3).
116
117    SOLVER REPORT
118
119    Subroutine sets following fields of the Rep structure:
120    * R1        reciprocal of condition number: 1/cond(A), 1-norm.
121    * RInf      reciprocal of condition number: 1/cond(A), inf-norm.
122
123      -- ALGLIB --
124         Copyright 27.01.2010 by Bochkanov Sergey
125    *************************************************************************/
126    public static void rmatrixsolve(double[,] a, int n, double[] b, out int info, out densesolverreport rep, out double[] x)
127    {
128        info = 0;
129        rep = new densesolverreport();
130        x = new double[0];
131        densesolver.rmatrixsolve(a, n, b, ref info, rep.innerobj, ref x);
132        return;
133    }
134
135    /*************************************************************************
136    Dense solver.
137
138    Similar to RMatrixSolve() but solves task with multiple right parts (where
139    b and x are NxM matrices).
140
141    Algorithm features:
142    * automatic detection of degenerate cases
143    * condition number estimation
144    * optional iterative refinement
145    * O(N^3+M*N^2) complexity
146
147    INPUT PARAMETERS
148        A       -   array[0..N-1,0..N-1], system matrix
149        N       -   size of A
150        B       -   array[0..N-1,0..M-1], right part
151        M       -   right part size
152        RFS     -   iterative refinement switch:
153                    * True - refinement is used.
154                      Less performance, more precision.
155                    * False - refinement is not used.
156                      More performance, less precision.
157
158    OUTPUT PARAMETERS
159        Info    -   same as in RMatrixSolve
160        Rep     -   same as in RMatrixSolve
161        X       -   same as in RMatrixSolve
162
163      -- ALGLIB --
164         Copyright 27.01.2010 by Bochkanov Sergey
165    *************************************************************************/
166    public static void rmatrixsolvem(double[,] a, int n, double[,] b, int m, bool rfs, out int info, out densesolverreport rep, out double[,] x)
167    {
168        info = 0;
169        rep = new densesolverreport();
170        x = new double[0,0];
171        densesolver.rmatrixsolvem(a, n, b, m, rfs, ref info, rep.innerobj, ref x);
172        return;
173    }
174
175    /*************************************************************************
176    Dense solver.
177
178    This  subroutine  solves  a  system  A*X=B,  where A is NxN non-denegerate
179    real matrix given by its LU decomposition, X and B are NxM real matrices.
180
181    Algorithm features:
182    * automatic detection of degenerate cases
183    * O(N^2) complexity
184    * condition number estimation
185
186    No iterative refinement  is provided because exact form of original matrix
187    is not known to subroutine. Use RMatrixSolve or RMatrixMixedSolve  if  you
188    need iterative refinement.
189
190    INPUT PARAMETERS
191        LUA     -   array[0..N-1,0..N-1], LU decomposition, RMatrixLU result
192        P       -   array[0..N-1], pivots array, RMatrixLU result
193        N       -   size of A
194        B       -   array[0..N-1], right part
195
196    OUTPUT PARAMETERS
197        Info    -   same as in RMatrixSolve
198        Rep     -   same as in RMatrixSolve
199        X       -   same as in RMatrixSolve
200
201      -- ALGLIB --
202         Copyright 27.01.2010 by Bochkanov Sergey
203    *************************************************************************/
204    public static void rmatrixlusolve(double[,] lua, int[] p, int n, double[] b, out int info, out densesolverreport rep, out double[] x)
205    {
206        info = 0;
207        rep = new densesolverreport();
208        x = new double[0];
209        densesolver.rmatrixlusolve(lua, p, n, b, ref info, rep.innerobj, ref x);
210        return;
211    }
212
213    /*************************************************************************
214    Dense solver.
215
216    Similar to RMatrixLUSolve() but solves task with multiple right parts
217    (where b and x are NxM matrices).
218
219    Algorithm features:
220    * automatic detection of degenerate cases
221    * O(M*N^2) complexity
222    * condition number estimation
223
224    No iterative refinement  is provided because exact form of original matrix
225    is not known to subroutine. Use RMatrixSolve or RMatrixMixedSolve  if  you
226    need iterative refinement.
227
228    INPUT PARAMETERS
229        LUA     -   array[0..N-1,0..N-1], LU decomposition, RMatrixLU result
230        P       -   array[0..N-1], pivots array, RMatrixLU result
231        N       -   size of A
232        B       -   array[0..N-1,0..M-1], right part
233        M       -   right part size
234
235    OUTPUT PARAMETERS
236        Info    -   same as in RMatrixSolve
237        Rep     -   same as in RMatrixSolve
238        X       -   same as in RMatrixSolve
239
240      -- ALGLIB --
241         Copyright 27.01.2010 by Bochkanov Sergey
242    *************************************************************************/
243    public static void rmatrixlusolvem(double[,] lua, int[] p, int n, double[,] b, int m, out int info, out densesolverreport rep, out double[,] x)
244    {
245        info = 0;
246        rep = new densesolverreport();
247        x = new double[0,0];
248        densesolver.rmatrixlusolvem(lua, p, n, b, m, ref info, rep.innerobj, ref x);
249        return;
250    }
251
252    /*************************************************************************
253    Dense solver.
254
255    This  subroutine  solves  a  system  A*x=b,  where BOTH ORIGINAL A AND ITS
256    LU DECOMPOSITION ARE KNOWN. You can use it if for some  reasons  you  have
257    both A and its LU decomposition.
258
259    Algorithm features:
260    * automatic detection of degenerate cases
261    * condition number estimation
262    * iterative refinement
263    * O(N^2) complexity
264
265    INPUT PARAMETERS
266        A       -   array[0..N-1,0..N-1], system matrix
267        LUA     -   array[0..N-1,0..N-1], LU decomposition, RMatrixLU result
268        P       -   array[0..N-1], pivots array, RMatrixLU result
269        N       -   size of A
270        B       -   array[0..N-1], right part
271
272    OUTPUT PARAMETERS
273        Info    -   same as in RMatrixSolveM
274        Rep     -   same as in RMatrixSolveM
275        X       -   same as in RMatrixSolveM
276
277      -- ALGLIB --
278         Copyright 27.01.2010 by Bochkanov Sergey
279    *************************************************************************/
280    public static void rmatrixmixedsolve(double[,] a, double[,] lua, int[] p, int n, double[] b, out int info, out densesolverreport rep, out double[] x)
281    {
282        info = 0;
283        rep = new densesolverreport();
284        x = new double[0];
285        densesolver.rmatrixmixedsolve(a, lua, p, n, b, ref info, rep.innerobj, ref x);
286        return;
287    }
288
289    /*************************************************************************
290    Dense solver.
291
292    Similar to RMatrixMixedSolve() but  solves task with multiple right  parts
293    (where b and x are NxM matrices).
294
295    Algorithm features:
296    * automatic detection of degenerate cases
297    * condition number estimation
298    * iterative refinement
299    * O(M*N^2) complexity
300
301    INPUT PARAMETERS
302        A       -   array[0..N-1,0..N-1], system matrix
303        LUA     -   array[0..N-1,0..N-1], LU decomposition, RMatrixLU result
304        P       -   array[0..N-1], pivots array, RMatrixLU result
305        N       -   size of A
306        B       -   array[0..N-1,0..M-1], right part
307        M       -   right part size
308
309    OUTPUT PARAMETERS
310        Info    -   same as in RMatrixSolveM
311        Rep     -   same as in RMatrixSolveM
312        X       -   same as in RMatrixSolveM
313
314      -- ALGLIB --
315         Copyright 27.01.2010 by Bochkanov Sergey
316    *************************************************************************/
317    public static void rmatrixmixedsolvem(double[,] a, double[,] lua, int[] p, int n, double[,] b, int m, out int info, out densesolverreport rep, out double[,] x)
318    {
319        info = 0;
320        rep = new densesolverreport();
321        x = new double[0,0];
322        densesolver.rmatrixmixedsolvem(a, lua, p, n, b, m, ref info, rep.innerobj, ref x);
323        return;
324    }
325
326    /*************************************************************************
327    Dense solver. Same as RMatrixSolveM(), but for complex matrices.
328
329    Algorithm features:
330    * automatic detection of degenerate cases
331    * condition number estimation
332    * iterative refinement
333    * O(N^3+M*N^2) complexity
334
335    INPUT PARAMETERS
336        A       -   array[0..N-1,0..N-1], system matrix
337        N       -   size of A
338        B       -   array[0..N-1,0..M-1], right part
339        M       -   right part size
340        RFS     -   iterative refinement switch:
341                    * True - refinement is used.
342                      Less performance, more precision.
343                    * False - refinement is not used.
344                      More performance, less precision.
345
346    OUTPUT PARAMETERS
347        Info    -   same as in RMatrixSolve
348        Rep     -   same as in RMatrixSolve
349        X       -   same as in RMatrixSolve
350
351      -- ALGLIB --
352         Copyright 27.01.2010 by Bochkanov Sergey
353    *************************************************************************/
354    public static void cmatrixsolvem(complex[,] a, int n, complex[,] b, int m, bool rfs, out int info, out densesolverreport rep, out complex[,] x)
355    {
356        info = 0;
357        rep = new densesolverreport();
358        x = new complex[0,0];
359        densesolver.cmatrixsolvem(a, n, b, m, rfs, ref info, rep.innerobj, ref x);
360        return;
361    }
362
363    /*************************************************************************
364    Dense solver. Same as RMatrixSolve(), but for complex matrices.
365
366    Algorithm features:
367    * automatic detection of degenerate cases
368    * condition number estimation
369    * iterative refinement
370    * O(N^3) complexity
371
372    INPUT PARAMETERS
373        A       -   array[0..N-1,0..N-1], system matrix
374        N       -   size of A
375        B       -   array[0..N-1], right part
376
377    OUTPUT PARAMETERS
378        Info    -   same as in RMatrixSolve
379        Rep     -   same as in RMatrixSolve
380        X       -   same as in RMatrixSolve
381
382      -- ALGLIB --
383         Copyright 27.01.2010 by Bochkanov Sergey
384    *************************************************************************/
385    public static void cmatrixsolve(complex[,] a, int n, complex[] b, out int info, out densesolverreport rep, out complex[] x)
386    {
387        info = 0;
388        rep = new densesolverreport();
389        x = new complex[0];
390        densesolver.cmatrixsolve(a, n, b, ref info, rep.innerobj, ref x);
391        return;
392    }
393
394    /*************************************************************************
395    Dense solver. Same as RMatrixLUSolveM(), but for complex matrices.
396
397    Algorithm features:
398    * automatic detection of degenerate cases
399    * O(M*N^2) complexity
400    * condition number estimation
401
402    No iterative refinement  is provided because exact form of original matrix
403    is not known to subroutine. Use CMatrixSolve or CMatrixMixedSolve  if  you
404    need iterative refinement.
405
406    INPUT PARAMETERS
407        LUA     -   array[0..N-1,0..N-1], LU decomposition, RMatrixLU result
408        P       -   array[0..N-1], pivots array, RMatrixLU result
409        N       -   size of A
410        B       -   array[0..N-1,0..M-1], right part
411        M       -   right part size
412
413    OUTPUT PARAMETERS
414        Info    -   same as in RMatrixSolve
415        Rep     -   same as in RMatrixSolve
416        X       -   same as in RMatrixSolve
417
418      -- ALGLIB --
419         Copyright 27.01.2010 by Bochkanov Sergey
420    *************************************************************************/
421    public static void cmatrixlusolvem(complex[,] lua, int[] p, int n, complex[,] b, int m, out int info, out densesolverreport rep, out complex[,] x)
422    {
423        info = 0;
424        rep = new densesolverreport();
425        x = new complex[0,0];
426        densesolver.cmatrixlusolvem(lua, p, n, b, m, ref info, rep.innerobj, ref x);
427        return;
428    }
429
430    /*************************************************************************
431    Dense solver. Same as RMatrixLUSolve(), but for complex matrices.
432
433    Algorithm features:
434    * automatic detection of degenerate cases
435    * O(N^2) complexity
436    * condition number estimation
437
438    No iterative refinement is provided because exact form of original matrix
439    is not known to subroutine. Use CMatrixSolve or CMatrixMixedSolve  if  you
440    need iterative refinement.
441
442    INPUT PARAMETERS
443        LUA     -   array[0..N-1,0..N-1], LU decomposition, CMatrixLU result
444        P       -   array[0..N-1], pivots array, CMatrixLU result
445        N       -   size of A
446        B       -   array[0..N-1], right part
447
448    OUTPUT PARAMETERS
449        Info    -   same as in RMatrixSolve
450        Rep     -   same as in RMatrixSolve
451        X       -   same as in RMatrixSolve
452
453      -- ALGLIB --
454         Copyright 27.01.2010 by Bochkanov Sergey
455    *************************************************************************/
456    public static void cmatrixlusolve(complex[,] lua, int[] p, int n, complex[] b, out int info, out densesolverreport rep, out complex[] x)
457    {
458        info = 0;
459        rep = new densesolverreport();
460        x = new complex[0];
461        densesolver.cmatrixlusolve(lua, p, n, b, ref info, rep.innerobj, ref x);
462        return;
463    }
464
465    /*************************************************************************
466    Dense solver. Same as RMatrixMixedSolveM(), but for complex matrices.
467
468    Algorithm features:
469    * automatic detection of degenerate cases
470    * condition number estimation
471    * iterative refinement
472    * O(M*N^2) complexity
473
474    INPUT PARAMETERS
475        A       -   array[0..N-1,0..N-1], system matrix
476        LUA     -   array[0..N-1,0..N-1], LU decomposition, CMatrixLU result
477        P       -   array[0..N-1], pivots array, CMatrixLU result
478        N       -   size of A
479        B       -   array[0..N-1,0..M-1], right part
480        M       -   right part size
481
482    OUTPUT PARAMETERS
483        Info    -   same as in RMatrixSolveM
484        Rep     -   same as in RMatrixSolveM
485        X       -   same as in RMatrixSolveM
486
487      -- ALGLIB --
488         Copyright 27.01.2010 by Bochkanov Sergey
489    *************************************************************************/
490    public static void cmatrixmixedsolvem(complex[,] a, complex[,] lua, int[] p, int n, complex[,] b, int m, out int info, out densesolverreport rep, out complex[,] x)
491    {
492        info = 0;
493        rep = new densesolverreport();
494        x = new complex[0,0];
495        densesolver.cmatrixmixedsolvem(a, lua, p, n, b, m, ref info, rep.innerobj, ref x);
496        return;
497    }
498
499    /*************************************************************************
500    Dense solver. Same as RMatrixMixedSolve(), but for complex matrices.
501
502    Algorithm features:
503    * automatic detection of degenerate cases
504    * condition number estimation
505    * iterative refinement
506    * O(N^2) complexity
507
508    INPUT PARAMETERS
509        A       -   array[0..N-1,0..N-1], system matrix
510        LUA     -   array[0..N-1,0..N-1], LU decomposition, CMatrixLU result
511        P       -   array[0..N-1], pivots array, CMatrixLU result
512        N       -   size of A
513        B       -   array[0..N-1], right part
514
515    OUTPUT PARAMETERS
516        Info    -   same as in RMatrixSolveM
517        Rep     -   same as in RMatrixSolveM
518        X       -   same as in RMatrixSolveM
519
520      -- ALGLIB --
521         Copyright 27.01.2010 by Bochkanov Sergey
522    *************************************************************************/
523    public static void cmatrixmixedsolve(complex[,] a, complex[,] lua, int[] p, int n, complex[] b, out int info, out densesolverreport rep, out complex[] x)
524    {
525        info = 0;
526        rep = new densesolverreport();
527        x = new complex[0];
528        densesolver.cmatrixmixedsolve(a, lua, p, n, b, ref info, rep.innerobj, ref x);
529        return;
530    }
531
532    /*************************************************************************
533    Dense solver. Same as RMatrixSolveM(), but for symmetric positive definite
534    matrices.
535
536    Algorithm features:
537    * automatic detection of degenerate cases
538    * condition number estimation
539    * O(N^3+M*N^2) complexity
540    * matrix is represented by its upper or lower triangle
541
542    No iterative refinement is provided because such partial representation of
543    matrix does not allow efficient calculation of extra-precise  matrix-vector
544    products for large matrices. Use RMatrixSolve or RMatrixMixedSolve  if  you
545    need iterative refinement.
546
547    INPUT PARAMETERS
548        A       -   array[0..N-1,0..N-1], system matrix
549        N       -   size of A
550        IsUpper -   what half of A is provided
551        B       -   array[0..N-1,0..M-1], right part
552        M       -   right part size
553
554    OUTPUT PARAMETERS
555        Info    -   same as in RMatrixSolve.
556                    Returns -3 for non-SPD matrices.
557        Rep     -   same as in RMatrixSolve
558        X       -   same as in RMatrixSolve
559
560      -- ALGLIB --
561         Copyright 27.01.2010 by Bochkanov Sergey
562    *************************************************************************/
563    public static void spdmatrixsolvem(double[,] a, int n, bool isupper, double[,] b, int m, out int info, out densesolverreport rep, out double[,] x)
564    {
565        info = 0;
566        rep = new densesolverreport();
567        x = new double[0,0];
568        densesolver.spdmatrixsolvem(a, n, isupper, b, m, ref info, rep.innerobj, ref x);
569        return;
570    }
571
572    /*************************************************************************
573    Dense solver. Same as RMatrixSolve(), but for SPD matrices.
574
575    Algorithm features:
576    * automatic detection of degenerate cases
577    * condition number estimation
578    * O(N^3) complexity
579    * matrix is represented by its upper or lower triangle
580
581    No iterative refinement is provided because such partial representation of
582    matrix does not allow efficient calculation of extra-precise  matrix-vector
583    products for large matrices. Use RMatrixSolve or RMatrixMixedSolve  if  you
584    need iterative refinement.
585
586    INPUT PARAMETERS
587        A       -   array[0..N-1,0..N-1], system matrix
588        N       -   size of A
589        IsUpper -   what half of A is provided
590        B       -   array[0..N-1], right part
591
592    OUTPUT PARAMETERS
593        Info    -   same as in RMatrixSolve
594                    Returns -3 for non-SPD matrices.
595        Rep     -   same as in RMatrixSolve
596        X       -   same as in RMatrixSolve
597
598      -- ALGLIB --
599         Copyright 27.01.2010 by Bochkanov Sergey
600    *************************************************************************/
601    public static void spdmatrixsolve(double[,] a, int n, bool isupper, double[] b, out int info, out densesolverreport rep, out double[] x)
602    {
603        info = 0;
604        rep = new densesolverreport();
605        x = new double[0];
606        densesolver.spdmatrixsolve(a, n, isupper, b, ref info, rep.innerobj, ref x);
607        return;
608    }
609
610    /*************************************************************************
611    Dense solver. Same as RMatrixLUSolveM(), but for SPD matrices  represented
612    by their Cholesky decomposition.
613
614    Algorithm features:
615    * automatic detection of degenerate cases
616    * O(M*N^2) complexity
617    * condition number estimation
618    * matrix is represented by its upper or lower triangle
619
620    No iterative refinement is provided because such partial representation of
621    matrix does not allow efficient calculation of extra-precise  matrix-vector
622    products for large matrices. Use RMatrixSolve or RMatrixMixedSolve  if  you
623    need iterative refinement.
624
625    INPUT PARAMETERS
626        CHA     -   array[0..N-1,0..N-1], Cholesky decomposition,
627                    SPDMatrixCholesky result
628        N       -   size of CHA
629        IsUpper -   what half of CHA is provided
630        B       -   array[0..N-1,0..M-1], right part
631        M       -   right part size
632
633    OUTPUT PARAMETERS
634        Info    -   same as in RMatrixSolve
635        Rep     -   same as in RMatrixSolve
636        X       -   same as in RMatrixSolve
637
638      -- ALGLIB --
639         Copyright 27.01.2010 by Bochkanov Sergey
640    *************************************************************************/
641    public static void spdmatrixcholeskysolvem(double[,] cha, int n, bool isupper, double[,] b, int m, out int info, out densesolverreport rep, out double[,] x)
642    {
643        info = 0;
644        rep = new densesolverreport();
645        x = new double[0,0];
646        densesolver.spdmatrixcholeskysolvem(cha, n, isupper, b, m, ref info, rep.innerobj, ref x);
647        return;
648    }
649
650    /*************************************************************************
651    Dense solver. Same as RMatrixLUSolve(), but for  SPD matrices  represented
652    by their Cholesky decomposition.
653
654    Algorithm features:
655    * automatic detection of degenerate cases
656    * O(N^2) complexity
657    * condition number estimation
658    * matrix is represented by its upper or lower triangle
659
660    No iterative refinement is provided because such partial representation of
661    matrix does not allow efficient calculation of extra-precise  matrix-vector
662    products for large matrices. Use RMatrixSolve or RMatrixMixedSolve  if  you
663    need iterative refinement.
664
665    INPUT PARAMETERS
666        CHA     -   array[0..N-1,0..N-1], Cholesky decomposition,
667                    SPDMatrixCholesky result
668        N       -   size of A
669        IsUpper -   what half of CHA is provided
670        B       -   array[0..N-1], right part
671
672    OUTPUT PARAMETERS
673        Info    -   same as in RMatrixSolve
674        Rep     -   same as in RMatrixSolve
675        X       -   same as in RMatrixSolve
676
677      -- ALGLIB --
678         Copyright 27.01.2010 by Bochkanov Sergey
679    *************************************************************************/
680    public static void spdmatrixcholeskysolve(double[,] cha, int n, bool isupper, double[] b, out int info, out densesolverreport rep, out double[] x)
681    {
682        info = 0;
683        rep = new densesolverreport();
684        x = new double[0];
685        densesolver.spdmatrixcholeskysolve(cha, n, isupper, b, ref info, rep.innerobj, ref x);
686        return;
687    }
688
689    /*************************************************************************
690    Dense solver. Same as RMatrixSolveM(), but for Hermitian positive definite
691    matrices.
692
693    Algorithm features:
694    * automatic detection of degenerate cases
695    * condition number estimation
696    * O(N^3+M*N^2) complexity
697    * matrix is represented by its upper or lower triangle
698
699    No iterative refinement is provided because such partial representation of
700    matrix does not allow efficient calculation of extra-precise  matrix-vector
701    products for large matrices. Use RMatrixSolve or RMatrixMixedSolve  if  you
702    need iterative refinement.
703
704    INPUT PARAMETERS
705        A       -   array[0..N-1,0..N-1], system matrix
706        N       -   size of A
707        IsUpper -   what half of A is provided
708        B       -   array[0..N-1,0..M-1], right part
709        M       -   right part size
710
711    OUTPUT PARAMETERS
712        Info    -   same as in RMatrixSolve.
713                    Returns -3 for non-HPD matrices.
714        Rep     -   same as in RMatrixSolve
715        X       -   same as in RMatrixSolve
716
717      -- ALGLIB --
718         Copyright 27.01.2010 by Bochkanov Sergey
719    *************************************************************************/
720    public static void hpdmatrixsolvem(complex[,] a, int n, bool isupper, complex[,] b, int m, out int info, out densesolverreport rep, out complex[,] x)
721    {
722        info = 0;
723        rep = new densesolverreport();
724        x = new complex[0,0];
725        densesolver.hpdmatrixsolvem(a, n, isupper, b, m, ref info, rep.innerobj, ref x);
726        return;
727    }
728
729    /*************************************************************************
730    Dense solver. Same as RMatrixSolve(),  but for Hermitian positive definite
731    matrices.
732
733    Algorithm features:
734    * automatic detection of degenerate cases
735    * condition number estimation
736    * O(N^3) complexity
737    * matrix is represented by its upper or lower triangle
738
739    No iterative refinement is provided because such partial representation of
740    matrix does not allow efficient calculation of extra-precise  matrix-vector
741    products for large matrices. Use RMatrixSolve or RMatrixMixedSolve  if  you
742    need iterative refinement.
743
744    INPUT PARAMETERS
745        A       -   array[0..N-1,0..N-1], system matrix
746        N       -   size of A
747        IsUpper -   what half of A is provided
748        B       -   array[0..N-1], right part
749
750    OUTPUT PARAMETERS
751        Info    -   same as in RMatrixSolve
752                    Returns -3 for non-HPD matrices.
753        Rep     -   same as in RMatrixSolve
754        X       -   same as in RMatrixSolve
755
756      -- ALGLIB --
757         Copyright 27.01.2010 by Bochkanov Sergey
758    *************************************************************************/
759    public static void hpdmatrixsolve(complex[,] a, int n, bool isupper, complex[] b, out int info, out densesolverreport rep, out complex[] x)
760    {
761        info = 0;
762        rep = new densesolverreport();
763        x = new complex[0];
764        densesolver.hpdmatrixsolve(a, n, isupper, b, ref info, rep.innerobj, ref x);
765        return;
766    }
767
768    /*************************************************************************
769    Dense solver. Same as RMatrixLUSolveM(), but for HPD matrices  represented
770    by their Cholesky decomposition.
771
772    Algorithm features:
773    * automatic detection of degenerate cases
774    * O(M*N^2) complexity
775    * condition number estimation
776    * matrix is represented by its upper or lower triangle
777
778    No iterative refinement is provided because such partial representation of
779    matrix does not allow efficient calculation of extra-precise  matrix-vector
780    products for large matrices. Use RMatrixSolve or RMatrixMixedSolve  if  you
781    need iterative refinement.
782
783    INPUT PARAMETERS
784        CHA     -   array[0..N-1,0..N-1], Cholesky decomposition,
785                    HPDMatrixCholesky result
786        N       -   size of CHA
787        IsUpper -   what half of CHA is provided
788        B       -   array[0..N-1,0..M-1], right part
789        M       -   right part size
790
791    OUTPUT PARAMETERS
792        Info    -   same as in RMatrixSolve
793        Rep     -   same as in RMatrixSolve
794        X       -   same as in RMatrixSolve
795
796      -- ALGLIB --
797         Copyright 27.01.2010 by Bochkanov Sergey
798    *************************************************************************/
799    public static void hpdmatrixcholeskysolvem(complex[,] cha, int n, bool isupper, complex[,] b, int m, out int info, out densesolverreport rep, out complex[,] x)
800    {
801        info = 0;
802        rep = new densesolverreport();
803        x = new complex[0,0];
804        densesolver.hpdmatrixcholeskysolvem(cha, n, isupper, b, m, ref info, rep.innerobj, ref x);
805        return;
806    }
807
808    /*************************************************************************
809    Dense solver. Same as RMatrixLUSolve(), but for  HPD matrices  represented
810    by their Cholesky decomposition.
811
812    Algorithm features:
813    * automatic detection of degenerate cases
814    * O(N^2) complexity
815    * condition number estimation
816    * matrix is represented by its upper or lower triangle
817
818    No iterative refinement is provided because such partial representation of
819    matrix does not allow efficient calculation of extra-precise  matrix-vector
820    products for large matrices. Use RMatrixSolve or RMatrixMixedSolve  if  you
821    need iterative refinement.
822
823    INPUT PARAMETERS
824        CHA     -   array[0..N-1,0..N-1], Cholesky decomposition,
825                    SPDMatrixCholesky result
826        N       -   size of A
827        IsUpper -   what half of CHA is provided
828        B       -   array[0..N-1], right part
829
830    OUTPUT PARAMETERS
831        Info    -   same as in RMatrixSolve
832        Rep     -   same as in RMatrixSolve
833        X       -   same as in RMatrixSolve
834
835      -- ALGLIB --
836         Copyright 27.01.2010 by Bochkanov Sergey
837    *************************************************************************/
838    public static void hpdmatrixcholeskysolve(complex[,] cha, int n, bool isupper, complex[] b, out int info, out densesolverreport rep, out complex[] x)
839    {
840        info = 0;
841        rep = new densesolverreport();
842        x = new complex[0];
843        densesolver.hpdmatrixcholeskysolve(cha, n, isupper, b, ref info, rep.innerobj, ref x);
844        return;
845    }
846
847    /*************************************************************************
848    Dense solver.
849
850    This subroutine finds solution of the linear system A*X=B with non-square,
851    possibly degenerate A.  System  is  solved in the least squares sense, and
852    general least squares solution  X = X0 + CX*y  which  minimizes |A*X-B| is
853    returned. If A is non-degenerate, solution in the  usual sense is returned
854
855    Algorithm features:
856    * automatic detection of degenerate cases
857    * iterative refinement
858    * O(N^3) complexity
859
860    INPUT PARAMETERS
861        A       -   array[0..NRows-1,0..NCols-1], system matrix
862        NRows   -   vertical size of A
863        NCols   -   horizontal size of A
864        B       -   array[0..NCols-1], right part
865        Threshold-  a number in [0,1]. Singular values  beyond  Threshold  are
866                    considered  zero.  Set  it to 0.0, if you don't understand
867                    what it means, so the solver will choose good value on its
868                    own.
869
870    OUTPUT PARAMETERS
871        Info    -   return code:
872                    * -4    SVD subroutine failed
873                    * -1    if NRows<=0 or NCols<=0 or Threshold<0 was passed
874                    *  1    if task is solved
875        Rep     -   solver report, see below for more info
876        X       -   array[0..N-1,0..M-1], it contains:
877                    * solution of A*X=B if A is non-singular (well-conditioned
878                      or ill-conditioned, but not very close to singular)
879                    * zeros,  if  A  is  singular  or  VERY  close to singular
880                      (in this case Info=-3).
881
882    SOLVER REPORT
883
884    Subroutine sets following fields of the Rep structure:
885    * R2        reciprocal of condition number: 1/cond(A), 2-norm.
886    * N         = NCols
887    * K         dim(Null(A))
888    * CX        array[0..N-1,0..K-1], kernel of A.
889                Columns of CX store such vectors that A*CX[i]=0.
890
891      -- ALGLIB --
892         Copyright 24.08.2009 by Bochkanov Sergey
893    *************************************************************************/
894    public static void rmatrixsolvels(double[,] a, int nrows, int ncols, double[] b, double threshold, out int info, out densesolverlsreport rep, out double[] x)
895    {
896        info = 0;
897        rep = new densesolverlsreport();
898        x = new double[0];
899        densesolver.rmatrixsolvels(a, nrows, ncols, b, threshold, ref info, rep.innerobj, ref x);
900        return;
901    }
902
903}
904public partial class alglib
905{
906
907
908    /*************************************************************************
909    This object stores state of the LinLSQR method.
910
911    You should use ALGLIB functions to work with this object.
912    *************************************************************************/
913    public class linlsqrstate
914    {
915        //
916        // Public declarations
917        //
918
919        public linlsqrstate()
920        {
921            _innerobj = new linlsqr.linlsqrstate();
922        }
923
924        //
925        // Although some of declarations below are public, you should not use them
926        // They are intended for internal use only
927        //
928        private linlsqr.linlsqrstate _innerobj;
929        public linlsqr.linlsqrstate innerobj { get { return _innerobj; } }
930        public linlsqrstate(linlsqr.linlsqrstate obj)
931        {
932            _innerobj = obj;
933        }
934    }
935
936
937    /*************************************************************************
938
939    *************************************************************************/
940    public class linlsqrreport
941    {
942        //
943        // Public declarations
944        //
945        public int iterationscount { get { return _innerobj.iterationscount; } set { _innerobj.iterationscount = value; } }
946        public int nmv { get { return _innerobj.nmv; } set { _innerobj.nmv = value; } }
947        public int terminationtype { get { return _innerobj.terminationtype; } set { _innerobj.terminationtype = value; } }
948
949        public linlsqrreport()
950        {
951            _innerobj = new linlsqr.linlsqrreport();
952        }
953
954        //
955        // Although some of declarations below are public, you should not use them
956        // They are intended for internal use only
957        //
958        private linlsqr.linlsqrreport _innerobj;
959        public linlsqr.linlsqrreport innerobj { get { return _innerobj; } }
960        public linlsqrreport(linlsqr.linlsqrreport obj)
961        {
962            _innerobj = obj;
963        }
964    }
965
966    /*************************************************************************
967    This function initializes linear LSQR Solver. This solver is used to solve
968    non-symmetric (and, possibly, non-square) problems. Least squares solution
969    is returned for non-compatible systems.
970
971    USAGE:
972    1. User initializes algorithm state with LinLSQRCreate() call
973    2. User tunes solver parameters with  LinLSQRSetCond() and other functions
974    3. User  calls  LinLSQRSolveSparse()  function which takes algorithm state
975       and SparseMatrix object.
976    4. User calls LinLSQRResults() to get solution
977    5. Optionally, user may call LinLSQRSolveSparse() again to  solve  another
978       problem  with different matrix and/or right part without reinitializing
979       LinLSQRState structure.
980
981    INPUT PARAMETERS:
982        M       -   number of rows in A
983        N       -   number of variables, N>0
984
985    OUTPUT PARAMETERS:
986        State   -   structure which stores algorithm state
987
988      -- ALGLIB --
989         Copyright 30.11.2011 by Bochkanov Sergey
990    *************************************************************************/
991    public static void linlsqrcreate(int m, int n, out linlsqrstate state)
992    {
993        state = new linlsqrstate();
994        linlsqr.linlsqrcreate(m, n, state.innerobj);
995        return;
996    }
997
998    /*************************************************************************
999    This function sets optional Tikhonov regularization coefficient.
1000    It is zero by default.
1001
1002    INPUT PARAMETERS:
1003        LambdaI -   regularization factor, LambdaI>=0
1004
1005    OUTPUT PARAMETERS:
1006        State   -   structure which stores algorithm state
1007
1008      -- ALGLIB --
1009         Copyright 30.11.2011 by Bochkanov Sergey
1010    *************************************************************************/
1011    public static void linlsqrsetlambdai(linlsqrstate state, double lambdai)
1012    {
1013
1014        linlsqr.linlsqrsetlambdai(state.innerobj, lambdai);
1015        return;
1016    }
1017
1018    /*************************************************************************
1019    Procedure for solution of A*x=b with sparse A.
1020
1021    INPUT PARAMETERS:
1022        State   -   algorithm state
1023        A       -   sparse M*N matrix in the CRS format (you MUST contvert  it
1024                    to CRS format  by  calling  SparseConvertToCRS()  function
1025                    BEFORE you pass it to this function).
1026        B       -   right part, array[M]
1027
1028    RESULT:
1029        This function returns no result.
1030        You can get solution by calling LinCGResults()
1031
1032      -- ALGLIB --
1033         Copyright 30.11.2011 by Bochkanov Sergey
1034    *************************************************************************/
1035    public static void linlsqrsolvesparse(linlsqrstate state, sparsematrix a, double[] b)
1036    {
1037
1038        linlsqr.linlsqrsolvesparse(state.innerobj, a.innerobj, b);
1039        return;
1040    }
1041
1042    /*************************************************************************
1043    This function sets stopping criteria.
1044
1045    INPUT PARAMETERS:
1046        EpsA    -   algorithm will be stopped if ||A^T*Rk||/(||A||*||Rk||)<=EpsA.
1047        EpsB    -   algorithm will be stopped if ||Rk||<=EpsB*||B||
1048        MaxIts  -   algorithm will be stopped if number of iterations
1049                    more than MaxIts.
1050
1051    OUTPUT PARAMETERS:
1052        State   -   structure which stores algorithm state
1053
1054    NOTE: if EpsA,EpsB,EpsC and MaxIts are zero then these variables will
1055    be setted as default values.
1056
1057      -- ALGLIB --
1058         Copyright 30.11.2011 by Bochkanov Sergey
1059    *************************************************************************/
1060    public static void linlsqrsetcond(linlsqrstate state, double epsa, double epsb, int maxits)
1061    {
1062
1063        linlsqr.linlsqrsetcond(state.innerobj, epsa, epsb, maxits);
1064        return;
1065    }
1066
1067    /*************************************************************************
1068    LSQR solver: results.
1069
1070    This function must be called after LinLSQRSolve
1071
1072    INPUT PARAMETERS:
1073        State   -   algorithm state
1074
1075    OUTPUT PARAMETERS:
1076        X       -   array[N], solution
1077        Rep     -   optimization report:
1078                    * Rep.TerminationType completetion code:
1079                        *  1    ||Rk||<=EpsB*||B||
1080                        *  4    ||A^T*Rk||/(||A||*||Rk||)<=EpsA
1081                        *  5    MaxIts steps was taken
1082                        *  7    rounding errors prevent further progress,
1083                                X contains best point found so far.
1084                                (sometimes returned on singular systems)
1085                    * Rep.IterationsCount contains iterations count
1086                    * NMV countains number of matrix-vector calculations
1087
1088      -- ALGLIB --
1089         Copyright 30.11.2011 by Bochkanov Sergey
1090    *************************************************************************/
1091    public static void linlsqrresults(linlsqrstate state, out double[] x, out linlsqrreport rep)
1092    {
1093        x = new double[0];
1094        rep = new linlsqrreport();
1095        linlsqr.linlsqrresults(state.innerobj, ref x, rep.innerobj);
1096        return;
1097    }
1098
1099    /*************************************************************************
1100    This function turns on/off reporting.
1101
1102    INPUT PARAMETERS:
1103        State   -   structure which stores algorithm state
1104        NeedXRep-   whether iteration reports are needed or not
1105
1106    If NeedXRep is True, algorithm will call rep() callback function if  it is
1107    provided to MinCGOptimize().
1108
1109      -- ALGLIB --
1110         Copyright 30.11.2011 by Bochkanov Sergey
1111    *************************************************************************/
1112    public static void linlsqrsetxrep(linlsqrstate state, bool needxrep)
1113    {
1114
1115        linlsqr.linlsqrsetxrep(state.innerobj, needxrep);
1116        return;
1117    }
1118
1119}
1120public partial class alglib
1121{
1122
1123
1124    /*************************************************************************
1125    This object stores state of the linear CG method.
1126
1127    You should use ALGLIB functions to work with this object.
1128    Never try to access its fields directly!
1129    *************************************************************************/
1130    public class lincgstate
1131    {
1132        //
1133        // Public declarations
1134        //
1135
1136        public lincgstate()
1137        {
1138            _innerobj = new lincg.lincgstate();
1139        }
1140
1141        //
1142        // Although some of declarations below are public, you should not use them
1143        // They are intended for internal use only
1144        //
1145        private lincg.lincgstate _innerobj;
1146        public lincg.lincgstate innerobj { get { return _innerobj; } }
1147        public lincgstate(lincg.lincgstate obj)
1148        {
1149            _innerobj = obj;
1150        }
1151    }
1152
1153
1154    /*************************************************************************
1155
1156    *************************************************************************/
1157    public class lincgreport
1158    {
1159        //
1160        // Public declarations
1161        //
1162        public int iterationscount { get { return _innerobj.iterationscount; } set { _innerobj.iterationscount = value; } }
1163        public int nmv { get { return _innerobj.nmv; } set { _innerobj.nmv = value; } }
1164        public int terminationtype { get { return _innerobj.terminationtype; } set { _innerobj.terminationtype = value; } }
1165        public double r2 { get { return _innerobj.r2; } set { _innerobj.r2 = value; } }
1166
1167        public lincgreport()
1168        {
1169            _innerobj = new lincg.lincgreport();
1170        }
1171
1172        //
1173        // Although some of declarations below are public, you should not use them
1174        // They are intended for internal use only
1175        //
1176        private lincg.lincgreport _innerobj;
1177        public lincg.lincgreport innerobj { get { return _innerobj; } }
1178        public lincgreport(lincg.lincgreport obj)
1179        {
1180            _innerobj = obj;
1181        }
1182    }
1183
1184    /*************************************************************************
1185    This function initializes linear CG Solver. This solver is used  to  solve
1186    symmetric positive definite problems. If you want  to  solve  nonsymmetric
1187    (or non-positive definite) problem you may use LinLSQR solver provided  by
1188    ALGLIB.
1189
1190    USAGE:
1191    1. User initializes algorithm state with LinCGCreate() call
1192    2. User tunes solver parameters with  LinCGSetCond() and other functions
1193    3. Optionally, user sets starting point with LinCGSetStartingPoint()
1194    4. User  calls LinCGSolveSparse() function which takes algorithm state and
1195       SparseMatrix object.
1196    5. User calls LinCGResults() to get solution
1197    6. Optionally, user may call LinCGSolveSparse()  again  to  solve  another
1198       problem  with different matrix and/or right part without reinitializing
1199       LinCGState structure.
1200
1201    INPUT PARAMETERS:
1202        N       -   problem dimension, N>0
1203
1204    OUTPUT PARAMETERS:
1205        State   -   structure which stores algorithm state
1206
1207      -- ALGLIB --
1208         Copyright 14.11.2011 by Bochkanov Sergey
1209    *************************************************************************/
1210    public static void lincgcreate(int n, out lincgstate state)
1211    {
1212        state = new lincgstate();
1213        lincg.lincgcreate(n, state.innerobj);
1214        return;
1215    }
1216
1217    /*************************************************************************
1218    This function sets starting point.
1219    By default, zero starting point is used.
1220
1221    INPUT PARAMETERS:
1222        X       -   starting point, array[N]
1223
1224    OUTPUT PARAMETERS:
1225        State   -   structure which stores algorithm state
1226
1227      -- ALGLIB --
1228         Copyright 14.11.2011 by Bochkanov Sergey
1229    *************************************************************************/
1230    public static void lincgsetstartingpoint(lincgstate state, double[] x)
1231    {
1232
1233        lincg.lincgsetstartingpoint(state.innerobj, x);
1234        return;
1235    }
1236
1237    /*************************************************************************
1238    This function sets stopping criteria.
1239
1240    INPUT PARAMETERS:
1241        EpsF    -   algorithm will be stopped if norm of residual is less than
1242                    EpsF*||b||.
1243        MaxIts  -   algorithm will be stopped if number of iterations is  more
1244                    than MaxIts.
1245
1246    OUTPUT PARAMETERS:
1247        State   -   structure which stores algorithm state
1248
1249    NOTES:
1250    If  both  EpsF  and  MaxIts  are  zero then small EpsF will be set to small
1251    value.
1252
1253      -- ALGLIB --
1254         Copyright 14.11.2011 by Bochkanov Sergey
1255    *************************************************************************/
1256    public static void lincgsetcond(lincgstate state, double epsf, int maxits)
1257    {
1258
1259        lincg.lincgsetcond(state.innerobj, epsf, maxits);
1260        return;
1261    }
1262
1263    /*************************************************************************
1264    Procedure for solution of A*x=b with sparse A.
1265
1266    INPUT PARAMETERS:
1267        State   -   algorithm state
1268        A       -   sparse matrix in the CRS format (you MUST contvert  it  to
1269                    CRS format by calling SparseConvertToCRS() function).
1270        IsUpper -   whether upper or lower triangle of A is used:
1271                    * IsUpper=True  => only upper triangle is used and lower
1272                                       triangle is not referenced at all
1273                    * IsUpper=False => only lower triangle is used and upper
1274                                       triangle is not referenced at all
1275        B       -   right part, array[N]
1276
1277    RESULT:
1278        This function returns no result.
1279        You can get solution by calling LinCGResults()
1280
1281      -- ALGLIB --
1282         Copyright 14.11.2011 by Bochkanov Sergey
1283    *************************************************************************/
1284    public static void lincgsolvesparse(lincgstate state, sparsematrix a, bool isupper, double[] b)
1285    {
1286
1287        lincg.lincgsolvesparse(state.innerobj, a.innerobj, isupper, b);
1288        return;
1289    }
1290
1291    /*************************************************************************
1292    CG-solver: results.
1293
1294    This function must be called after LinCGSolve
1295
1296    INPUT PARAMETERS:
1297        State   -   algorithm state
1298
1299    OUTPUT PARAMETERS:
1300        X       -   array[N], solution
1301        Rep     -   optimization report:
1302                    * Rep.TerminationType completetion code:
1303                        * -5    input matrix is either not positive definite,
1304                                too large or too small
1305                        * -4    overflow/underflow during solution
1306                                (ill conditioned problem)
1307                        *  1    ||residual||<=EpsF*||b||
1308                        *  5    MaxIts steps was taken
1309                        *  7    rounding errors prevent further progress,
1310                                best point found is returned
1311                    * Rep.IterationsCount contains iterations count
1312                    * NMV countains number of matrix-vector calculations
1313
1314      -- ALGLIB --
1315         Copyright 14.11.2011 by Bochkanov Sergey
1316    *************************************************************************/
1317    public static void lincgresults(lincgstate state, out double[] x, out lincgreport rep)
1318    {
1319        x = new double[0];
1320        rep = new lincgreport();
1321        lincg.lincgresults(state.innerobj, ref x, rep.innerobj);
1322        return;
1323    }
1324
1325    /*************************************************************************
1326    This function sets restart frequency. By default, algorithm  is  restarted
1327    after N subsequent iterations.
1328
1329      -- ALGLIB --
1330         Copyright 14.11.2011 by Bochkanov Sergey
1331    *************************************************************************/
1332    public static void lincgsetrestartfreq(lincgstate state, int srf)
1333    {
1334
1335        lincg.lincgsetrestartfreq(state.innerobj, srf);
1336        return;
1337    }
1338
1339    /*************************************************************************
1340    This function sets frequency of residual recalculations.
1341
1342    Algorithm updates residual r_k using iterative formula,  but  recalculates
1343    it from scratch after each 10 iterations. It is done to avoid accumulation
1344    of numerical errors and to stop algorithm when r_k starts to grow.
1345
1346    Such low update frequence (1/10) gives very  little  overhead,  but  makes
1347    algorithm a bit more robust against numerical errors. However, you may
1348    change it
1349
1350    INPUT PARAMETERS:
1351        Freq    -   desired update frequency, Freq>=0.
1352                    Zero value means that no updates will be done.
1353
1354      -- ALGLIB --
1355         Copyright 14.11.2011 by Bochkanov Sergey
1356    *************************************************************************/
1357    public static void lincgsetrupdatefreq(lincgstate state, int freq)
1358    {
1359
1360        lincg.lincgsetrupdatefreq(state.innerobj, freq);
1361        return;
1362    }
1363
1364    /*************************************************************************
1365    This function turns on/off reporting.
1366
1367    INPUT PARAMETERS:
1368        State   -   structure which stores algorithm state
1369        NeedXRep-   whether iteration reports are needed or not
1370
1371    If NeedXRep is True, algorithm will call rep() callback function if  it is
1372    provided to MinCGOptimize().
1373
1374      -- ALGLIB --
1375         Copyright 14.11.2011 by Bochkanov Sergey
1376    *************************************************************************/
1377    public static void lincgsetxrep(lincgstate state, bool needxrep)
1378    {
1379
1380        lincg.lincgsetxrep(state.innerobj, needxrep);
1381        return;
1382    }
1383
1384}
1385public partial class alglib
1386{
1387
1388
1389    /*************************************************************************
1390
1391    *************************************************************************/
1392    public class nleqstate
1393    {
1394        //
1395        // Public declarations
1396        //
1397        public bool needf { get { return _innerobj.needf; } set { _innerobj.needf = value; } }
1398        public bool needfij { get { return _innerobj.needfij; } set { _innerobj.needfij = value; } }
1399        public bool xupdated { get { return _innerobj.xupdated; } set { _innerobj.xupdated = value; } }
1400        public double f { get { return _innerobj.f; } set { _innerobj.f = value; } }
1401        public double[] fi { get { return _innerobj.fi; } }
1402        public double[,] j { get { return _innerobj.j; } }
1403        public double[] x { get { return _innerobj.x; } }
1404
1405        public nleqstate()
1406        {
1407            _innerobj = new nleq.nleqstate();
1408        }
1409
1410        //
1411        // Although some of declarations below are public, you should not use them
1412        // They are intended for internal use only
1413        //
1414        private nleq.nleqstate _innerobj;
1415        public nleq.nleqstate innerobj { get { return _innerobj; } }
1416        public nleqstate(nleq.nleqstate obj)
1417        {
1418            _innerobj = obj;
1419        }
1420    }
1421
1422
1423    /*************************************************************************
1424
1425    *************************************************************************/
1426    public class nleqreport
1427    {
1428        //
1429        // Public declarations
1430        //
1431        public int iterationscount { get { return _innerobj.iterationscount; } set { _innerobj.iterationscount = value; } }
1432        public int nfunc { get { return _innerobj.nfunc; } set { _innerobj.nfunc = value; } }
1433        public int njac { get { return _innerobj.njac; } set { _innerobj.njac = value; } }
1434        public int terminationtype { get { return _innerobj.terminationtype; } set { _innerobj.terminationtype = value; } }
1435
1436        public nleqreport()
1437        {
1438            _innerobj = new nleq.nleqreport();
1439        }
1440
1441        //
1442        // Although some of declarations below are public, you should not use them
1443        // They are intended for internal use only
1444        //
1445        private nleq.nleqreport _innerobj;
1446        public nleq.nleqreport innerobj { get { return _innerobj; } }
1447        public nleqreport(nleq.nleqreport obj)
1448        {
1449            _innerobj = obj;
1450        }
1451    }
1452
1453    /*************************************************************************
1454                    LEVENBERG-MARQUARDT-LIKE NONLINEAR SOLVER
1455
1456    DESCRIPTION:
1457    This algorithm solves system of nonlinear equations
1458        F[0](x[0], ..., x[n-1])   = 0
1459        F[1](x[0], ..., x[n-1])   = 0
1460        ...
1461        F[M-1](x[0], ..., x[n-1]) = 0
1462    with M/N do not necessarily coincide.  Algorithm  converges  quadratically
1463    under following conditions:
1464        * the solution set XS is nonempty
1465        * for some xs in XS there exist such neighbourhood N(xs) that:
1466          * vector function F(x) and its Jacobian J(x) are continuously
1467            differentiable on N
1468          * ||F(x)|| provides local error bound on N, i.e. there  exists  such
1469            c1, that ||F(x)||>c1*distance(x,XS)
1470    Note that these conditions are much more weaker than usual non-singularity
1471    conditions. For example, algorithm will converge for any  affine  function
1472    F (whether its Jacobian singular or not).
1473
1474
1475    REQUIREMENTS:
1476    Algorithm will request following information during its operation:
1477    * function vector F[] and Jacobian matrix at given point X
1478    * value of merit function f(x)=F[0]^2(x)+...+F[M-1]^2(x) at given point X
1479
1480
1481    USAGE:
1482    1. User initializes algorithm state with NLEQCreateLM() call
1483    2. User tunes solver parameters with  NLEQSetCond(),  NLEQSetStpMax()  and
1484       other functions
1485    3. User  calls  NLEQSolve()  function  which  takes  algorithm  state  and
1486       pointers (delegates, etc.) to callback functions which calculate  merit
1487       function value and Jacobian.
1488    4. User calls NLEQResults() to get solution
1489    5. Optionally, user may call NLEQRestartFrom() to  solve  another  problem
1490       with same parameters (N/M) but another starting  point  and/or  another
1491       function vector. NLEQRestartFrom() allows to reuse already  initialized
1492       structure.
1493
1494
1495    INPUT PARAMETERS:
1496        N       -   space dimension, N>1:
1497                    * if provided, only leading N elements of X are used
1498                    * if not provided, determined automatically from size of X
1499        M       -   system size
1500        X       -   starting point
1501
1502
1503    OUTPUT PARAMETERS:
1504        State   -   structure which stores algorithm state
1505
1506
1507    NOTES:
1508    1. you may tune stopping conditions with NLEQSetCond() function
1509    2. if target function contains exp() or other fast growing functions,  and
1510       optimization algorithm makes too large steps which leads  to  overflow,
1511       use NLEQSetStpMax() function to bound algorithm's steps.
1512    3. this  algorithm  is  a  slightly  modified implementation of the method
1513       described  in  'Levenberg-Marquardt  method  for constrained  nonlinear
1514       equations with strong local convergence properties' by Christian Kanzow
1515       Nobuo Yamashita and Masao Fukushima and further  developed  in  'On the
1516       convergence of a New Levenberg-Marquardt Method'  by  Jin-yan  Fan  and
1517       Ya-Xiang Yuan.
1518
1519
1520      -- ALGLIB --
1521         Copyright 20.08.2009 by Bochkanov Sergey
1522    *************************************************************************/
1523    public static void nleqcreatelm(int n, int m, double[] x, out nleqstate state)
1524    {
1525        state = new nleqstate();
1526        nleq.nleqcreatelm(n, m, x, state.innerobj);
1527        return;
1528    }
1529    public static void nleqcreatelm(int m, double[] x, out nleqstate state)
1530    {
1531        int n;
1532
1533        state = new nleqstate();
1534        n = ap.len(x);
1535        nleq.nleqcreatelm(n, m, x, state.innerobj);
1536
1537        return;
1538    }
1539
1540    /*************************************************************************
1541    This function sets stopping conditions for the nonlinear solver
1542
1543    INPUT PARAMETERS:
1544        State   -   structure which stores algorithm state
1545        EpsF    -   >=0
1546                    The subroutine finishes  its work if on k+1-th iteration
1547                    the condition ||F||<=EpsF is satisfied
1548        MaxIts  -   maximum number of iterations. If MaxIts=0, the  number  of
1549                    iterations is unlimited.
1550
1551    Passing EpsF=0 and MaxIts=0 simultaneously will lead to  automatic
1552    stopping criterion selection (small EpsF).
1553
1554    NOTES:
1555
1556      -- ALGLIB --
1557         Copyright 20.08.2010 by Bochkanov Sergey
1558    *************************************************************************/
1559    public static void nleqsetcond(nleqstate state, double epsf, int maxits)
1560    {
1561
1562        nleq.nleqsetcond(state.innerobj, epsf, maxits);
1563        return;
1564    }
1565
1566    /*************************************************************************
1567    This function turns on/off reporting.
1568
1569    INPUT PARAMETERS:
1570        State   -   structure which stores algorithm state
1571        NeedXRep-   whether iteration reports are needed or not
1572
1573    If NeedXRep is True, algorithm will call rep() callback function if  it is
1574    provided to NLEQSolve().
1575
1576      -- ALGLIB --
1577         Copyright 20.08.2010 by Bochkanov Sergey
1578    *************************************************************************/
1579    public static void nleqsetxrep(nleqstate state, bool needxrep)
1580    {
1581
1582        nleq.nleqsetxrep(state.innerobj, needxrep);
1583        return;
1584    }
1585
1586    /*************************************************************************
1587    This function sets maximum step length
1588
1589    INPUT PARAMETERS:
1590        State   -   structure which stores algorithm state
1591        StpMax  -   maximum step length, >=0. Set StpMax to 0.0,  if you don't
1592                    want to limit step length.
1593
1594    Use this subroutine when target function  contains  exp()  or  other  fast
1595    growing functions, and algorithm makes  too  large  steps  which  lead  to
1596    overflow. This function allows us to reject steps that are too large  (and
1597    therefore expose us to the possible overflow) without actually calculating
1598    function value at the x+stp*d.
1599
1600      -- ALGLIB --
1601         Copyright 20.08.2010 by Bochkanov Sergey
1602    *************************************************************************/
1603    public static void nleqsetstpmax(nleqstate state, double stpmax)
1604    {
1605
1606        nleq.nleqsetstpmax(state.innerobj, stpmax);
1607        return;
1608    }
1609
1610    /*************************************************************************
1611    This function provides reverse communication interface
1612    Reverse communication interface is not documented or recommended to use.
1613    See below for functions which provide better documented API
1614    *************************************************************************/
1615    public static bool nleqiteration(nleqstate state)
1616    {
1617
1618        bool result = nleq.nleqiteration(state.innerobj);
1619        return result;
1620    }
1621    /*************************************************************************
1622    This family of functions is used to launcn iterations of nonlinear solver
1623
1624    These functions accept following parameters:
1625        func    -   callback which calculates function (or merit function)
1626                    value func at given point x
1627        jac     -   callback which calculates function vector fi[]
1628                    and Jacobian jac at given point x
1629        rep     -   optional callback which is called after each iteration
1630                    can be null
1631        obj     -   optional object which is passed to func/grad/hess/jac/rep
1632                    can be null
1633
1634
1635      -- ALGLIB --
1636         Copyright 20.03.2009 by Bochkanov Sergey
1637
1638    *************************************************************************/
1639    public static void nleqsolve(nleqstate state, ndimensional_func func, ndimensional_jac  jac, ndimensional_rep rep, object obj)
1640    {
1641        if( func==null )
1642            throw new alglibexception("ALGLIB: error in 'nleqsolve()' (func is null)");
1643        if( jac==null )
1644            throw new alglibexception("ALGLIB: error in 'nleqsolve()' (jac is null)");
1645        while( alglib.nleqiteration(state) )
1646        {
1647            if( state.needf )
1648            {
1649                func(state.x, ref state.innerobj.f, obj);
1650                continue;
1651            }
1652            if( state.needfij )
1653            {
1654                jac(state.x, state.innerobj.fi, state.innerobj.j, obj);
1655                continue;
1656            }
1657            if( state.innerobj.xupdated )
1658            {
1659                if( rep!=null )
1660                    rep(state.innerobj.x, state.innerobj.f, obj);
1661                continue;
1662            }
1663            throw new alglibexception("ALGLIB: error in 'nleqsolve' (some derivatives were not provided?)");
1664        }
1665    }
1666
1667
1668
1669    /*************************************************************************
1670    NLEQ solver results
1671
1672    INPUT PARAMETERS:
1673        State   -   algorithm state.
1674
1675    OUTPUT PARAMETERS:
1676        X       -   array[0..N-1], solution
1677        Rep     -   optimization report:
1678                    * Rep.TerminationType completetion code:
1679                        * -4    ERROR:  algorithm   has   converged   to   the
1680                                stationary point Xf which is local minimum  of
1681                                f=F[0]^2+...+F[m-1]^2, but is not solution  of
1682                                nonlinear system.
1683                        *  1    sqrt(f)<=EpsF.
1684                        *  5    MaxIts steps was taken
1685                        *  7    stopping conditions are too stringent,
1686                                further improvement is impossible
1687                    * Rep.IterationsCount contains iterations count
1688                    * NFEV countains number of function calculations
1689                    * ActiveConstraints contains number of active constraints
1690
1691      -- ALGLIB --
1692         Copyright 20.08.2009 by Bochkanov Sergey
1693    *************************************************************************/
1694    public static void nleqresults(nleqstate state, out double[] x, out nleqreport rep)
1695    {
1696        x = new double[0];
1697        rep = new nleqreport();
1698        nleq.nleqresults(state.innerobj, ref x, rep.innerobj);
1699        return;
1700    }
1701
1702    /*************************************************************************
1703    NLEQ solver results
1704
1705    Buffered implementation of NLEQResults(), which uses pre-allocated  buffer
1706    to store X[]. If buffer size is  too  small,  it  resizes  buffer.  It  is
1707    intended to be used in the inner cycles of performance critical algorithms
1708    where array reallocation penalty is too large to be ignored.
1709
1710      -- ALGLIB --
1711         Copyright 20.08.2009 by Bochkanov Sergey
1712    *************************************************************************/
1713    public static void nleqresultsbuf(nleqstate state, ref double[] x, nleqreport rep)
1714    {
1715
1716        nleq.nleqresultsbuf(state.innerobj, ref x, rep.innerobj);
1717        return;
1718    }
1719
1720    /*************************************************************************
1721    This  subroutine  restarts  CG  algorithm from new point. All optimization
1722    parameters are left unchanged.
1723
1724    This  function  allows  to  solve multiple  optimization  problems  (which
1725    must have same number of dimensions) without object reallocation penalty.
1726
1727    INPUT PARAMETERS:
1728        State   -   structure used for reverse communication previously
1729                    allocated with MinCGCreate call.
1730        X       -   new starting point.
1731        BndL    -   new lower bounds
1732        BndU    -   new upper bounds
1733
1734      -- ALGLIB --
1735         Copyright 30.07.2010 by Bochkanov Sergey
1736    *************************************************************************/
1737    public static void nleqrestartfrom(nleqstate state, double[] x)
1738    {
1739
1740        nleq.nleqrestartfrom(state.innerobj, x);
1741        return;
1742    }
1743
1744}
1745public partial class alglib
1746{
1747    public class densesolver
1748    {
1749        public class densesolverreport
1750        {
1751            public double r1;
1752            public double rinf;
1753        };
1754
1755
1756        public class densesolverlsreport
1757        {
1758            public double r2;
1759            public double[,] cx;
1760            public int n;
1761            public int k;
1762            public densesolverlsreport()
1763            {
1764                cx = new double[0,0];
1765            }
1766        };
1767
1768
1769
1770
1771        /*************************************************************************
1772        Dense solver.
1773
1774        This  subroutine  solves  a  system  A*x=b,  where A is NxN non-denegerate
1775        real matrix, x and b are vectors.
1776
1777        Algorithm features:
1778        * automatic detection of degenerate cases
1779        * condition number estimation
1780        * iterative refinement
1781        * O(N^3) complexity
1782
1783        INPUT PARAMETERS
1784            A       -   array[0..N-1,0..N-1], system matrix
1785            N       -   size of A
1786            B       -   array[0..N-1], right part
1787
1788        OUTPUT PARAMETERS
1789            Info    -   return code:
1790                        * -3    A is singular, or VERY close to singular.
1791                                X is filled by zeros in such cases.
1792                        * -1    N<=0 was passed
1793                        *  1    task is solved (but matrix A may be ill-conditioned,
1794                                check R1/RInf parameters for condition numbers).
1795            Rep     -   solver report, see below for more info
1796            X       -   array[0..N-1], it contains:
1797                        * solution of A*x=b if A is non-singular (well-conditioned
1798                          or ill-conditioned, but not very close to singular)
1799                        * zeros,  if  A  is  singular  or  VERY  close to singular
1800                          (in this case Info=-3).
1801
1802        SOLVER REPORT
1803
1804        Subroutine sets following fields of the Rep structure:
1805        * R1        reciprocal of condition number: 1/cond(A), 1-norm.
1806        * RInf      reciprocal of condition number: 1/cond(A), inf-norm.
1807
1808          -- ALGLIB --
1809             Copyright 27.01.2010 by Bochkanov Sergey
1810        *************************************************************************/
1811        public static void rmatrixsolve(double[,] a,
1812            int n,
1813            double[] b,
1814            ref int info,
1815            densesolverreport rep,
1816            ref double[] x)
1817        {
1818            double[,] bm = new double[0,0];
1819            double[,] xm = new double[0,0];
1820            int i_ = 0;
1821
1822            info = 0;
1823            x = new double[0];
1824
1825            if( n<=0 )
1826            {
1827                info = -1;
1828                return;
1829            }
1830            bm = new double[n, 1];
1831            for(i_=0; i_<=n-1;i_++)
1832            {
1833                bm[i_,0] = b[i_];
1834            }
1835            rmatrixsolvem(a, n, bm, 1, true, ref info, rep, ref xm);
1836            x = new double[n];
1837            for(i_=0; i_<=n-1;i_++)
1838            {
1839                x[i_] = xm[i_,0];
1840            }
1841        }
1842
1843
1844        /*************************************************************************
1845        Dense solver.
1846
1847        Similar to RMatrixSolve() but solves task with multiple right parts (where
1848        b and x are NxM matrices).
1849
1850        Algorithm features:
1851        * automatic detection of degenerate cases
1852        * condition number estimation
1853        * optional iterative refinement
1854        * O(N^3+M*N^2) complexity
1855
1856        INPUT PARAMETERS
1857            A       -   array[0..N-1,0..N-1], system matrix
1858            N       -   size of A
1859            B       -   array[0..N-1,0..M-1], right part
1860            M       -   right part size
1861            RFS     -   iterative refinement switch:
1862                        * True - refinement is used.
1863                          Less performance, more precision.
1864                        * False - refinement is not used.
1865                          More performance, less precision.
1866
1867        OUTPUT PARAMETERS
1868            Info    -   same as in RMatrixSolve
1869            Rep     -   same as in RMatrixSolve
1870            X       -   same as in RMatrixSolve
1871
1872          -- ALGLIB --
1873             Copyright 27.01.2010 by Bochkanov Sergey
1874        *************************************************************************/
1875        public static void rmatrixsolvem(double[,] a,
1876            int n,
1877            double[,] b,
1878            int m,
1879            bool rfs,
1880            ref int info,
1881            densesolverreport rep,
1882            ref double[,] x)
1883        {
1884            double[,] da = new double[0,0];
1885            double[,] emptya = new double[0,0];
1886            int[] p = new int[0];
1887            double scalea = 0;
1888            int i = 0;
1889            int j = 0;
1890            int i_ = 0;
1891
1892            info = 0;
1893            x = new double[0,0];
1894
1895           
1896            //
1897            // prepare: check inputs, allocate space...
1898            //
1899            if( n<=0 || m<=0 )
1900            {
1901                info = -1;
1902                return;
1903            }
1904            da = new double[n, n];
1905           
1906            //
1907            // 1. scale matrix, max(|A[i,j]|)
1908            // 2. factorize scaled matrix
1909            // 3. solve
1910            //
1911            scalea = 0;
1912            for(i=0; i<=n-1; i++)
1913            {
1914                for(j=0; j<=n-1; j++)
1915                {
1916                    scalea = Math.Max(scalea, Math.Abs(a[i,j]));
1917                }
1918            }
1919            if( (double)(scalea)==(double)(0) )
1920            {
1921                scalea = 1;
1922            }
1923            scalea = 1/scalea;
1924            for(i=0; i<=n-1; i++)
1925            {
1926                for(i_=0; i_<=n-1;i_++)
1927                {
1928                    da[i,i_] = a[i,i_];
1929                }
1930            }
1931            trfac.rmatrixlu(ref da, n, n, ref p);
1932            if( rfs )
1933            {
1934                rmatrixlusolveinternal(da, p, scalea, n, a, true, b, m, ref info, rep, ref x);
1935            }
1936            else
1937            {
1938                rmatrixlusolveinternal(da, p, scalea, n, emptya, false, b, m, ref info, rep, ref x);
1939            }
1940        }
1941
1942
1943        /*************************************************************************
1944        Dense solver.
1945
1946        This  subroutine  solves  a  system  A*X=B,  where A is NxN non-denegerate
1947        real matrix given by its LU decomposition, X and B are NxM real matrices.
1948
1949        Algorithm features:
1950        * automatic detection of degenerate cases
1951        * O(N^2) complexity
1952        * condition number estimation
1953
1954        No iterative refinement  is provided because exact form of original matrix
1955        is not known to subroutine. Use RMatrixSolve or RMatrixMixedSolve  if  you
1956        need iterative refinement.
1957
1958        INPUT PARAMETERS
1959            LUA     -   array[0..N-1,0..N-1], LU decomposition, RMatrixLU result
1960            P       -   array[0..N-1], pivots array, RMatrixLU result
1961            N       -   size of A
1962            B       -   array[0..N-1], right part
1963
1964        OUTPUT PARAMETERS
1965            Info    -   same as in RMatrixSolve
1966            Rep     -   same as in RMatrixSolve
1967            X       -   same as in RMatrixSolve
1968           
1969          -- ALGLIB --
1970             Copyright 27.01.2010 by Bochkanov Sergey
1971        *************************************************************************/
1972        public static void rmatrixlusolve(double[,] lua,
1973            int[] p,
1974            int n,
1975            double[] b,
1976            ref int info,
1977            densesolverreport rep,
1978            ref double[] x)
1979        {
1980            double[,] bm = new double[0,0];
1981            double[,] xm = new double[0,0];
1982            int i_ = 0;
1983
1984            info = 0;
1985            x = new double[0];
1986
1987            if( n<=0 )
1988            {
1989                info = -1;
1990                return;
1991            }
1992            bm = new double[n, 1];
1993            for(i_=0; i_<=n-1;i_++)
1994            {
1995                bm[i_,0] = b[i_];
1996            }
1997            rmatrixlusolvem(lua, p, n, bm, 1, ref info, rep, ref xm);
1998            x = new double[n];
1999            for(i_=0; i_<=n-1;i_++)
2000            {
2001                x[i_] = xm[i_,0];
2002            }
2003        }
2004
2005
2006        /*************************************************************************
2007        Dense solver.
2008
2009        Similar to RMatrixLUSolve() but solves task with multiple right parts
2010        (where b and x are NxM matrices).
2011
2012        Algorithm features:
2013        * automatic detection of degenerate cases
2014        * O(M*N^2) complexity
2015        * condition number estimation
2016
2017        No iterative refinement  is provided because exact form of original matrix
2018        is not known to subroutine. Use RMatrixSolve or RMatrixMixedSolve  if  you
2019        need iterative refinement.
2020
2021        INPUT PARAMETERS
2022            LUA     -   array[0..N-1,0..N-1], LU decomposition, RMatrixLU result
2023            P       -   array[0..N-1], pivots array, RMatrixLU result
2024            N       -   size of A
2025            B       -   array[0..N-1,0..M-1], right part
2026            M       -   right part size
2027
2028        OUTPUT PARAMETERS
2029            Info    -   same as in RMatrixSolve
2030            Rep     -   same as in RMatrixSolve
2031            X       -   same as in RMatrixSolve
2032
2033          -- ALGLIB --
2034             Copyright 27.01.2010 by Bochkanov Sergey
2035        *************************************************************************/
2036        public static void rmatrixlusolvem(double[,] lua,
2037            int[] p,
2038            int n,
2039            double[,] b,
2040            int m,
2041            ref int info,
2042            densesolverreport rep,
2043            ref double[,] x)
2044        {
2045            double[,] emptya = new double[0,0];
2046            int i = 0;
2047            int j = 0;
2048            double scalea = 0;
2049
2050            info = 0;
2051            x = new double[0,0];
2052
2053           
2054            //
2055            // prepare: check inputs, allocate space...
2056            //
2057            if( n<=0 || m<=0 )
2058            {
2059                info = -1;
2060                return;
2061            }
2062           
2063            //
2064            // 1. scale matrix, max(|U[i,j]|)
2065            //    we assume that LU is in its normal form, i.e. |L[i,j]|<=1
2066            // 2. solve
2067            //
2068            scalea = 0;
2069            for(i=0; i<=n-1; i++)
2070            {
2071                for(j=i; j<=n-1; j++)
2072                {
2073                    scalea = Math.Max(scalea, Math.Abs(lua[i,j]));
2074                }
2075            }
2076            if( (double)(scalea)==(double)(0) )
2077            {
2078                scalea = 1;
2079            }
2080            scalea = 1/scalea;
2081            rmatrixlusolveinternal(lua, p, scalea, n, emptya, false, b, m, ref info, rep, ref x);
2082        }
2083
2084
2085        /*************************************************************************
2086        Dense solver.
2087
2088        This  subroutine  solves  a  system  A*x=b,  where BOTH ORIGINAL A AND ITS
2089        LU DECOMPOSITION ARE KNOWN. You can use it if for some  reasons  you  have
2090        both A and its LU decomposition.
2091
2092        Algorithm features:
2093        * automatic detection of degenerate cases
2094        * condition number estimation
2095        * iterative refinement
2096        * O(N^2) complexity
2097
2098        INPUT PARAMETERS
2099            A       -   array[0..N-1,0..N-1], system matrix
2100            LUA     -   array[0..N-1,0..N-1], LU decomposition, RMatrixLU result
2101            P       -   array[0..N-1], pivots array, RMatrixLU result
2102            N       -   size of A
2103            B       -   array[0..N-1], right part
2104
2105        OUTPUT PARAMETERS
2106            Info    -   same as in RMatrixSolveM
2107            Rep     -   same as in RMatrixSolveM
2108            X       -   same as in RMatrixSolveM
2109
2110          -- ALGLIB --
2111             Copyright 27.01.2010 by Bochkanov Sergey
2112        *************************************************************************/
2113        public static void rmatrixmixedsolve(double[,] a,
2114            double[,] lua,
2115            int[] p,
2116            int n,
2117            double[] b,
2118            ref int info,
2119            densesolverreport rep,
2120            ref double[] x)
2121        {
2122            double[,] bm = new double[0,0];
2123            double[,] xm = new double[0,0];
2124            int i_ = 0;
2125
2126            info = 0;
2127            x = new double[0];
2128
2129            if( n<=0 )
2130            {
2131                info = -1;
2132                return;
2133            }
2134            bm = new double[n, 1];
2135            for(i_=0; i_<=n-1;i_++)
2136            {
2137                bm[i_,0] = b[i_];
2138            }
2139            rmatrixmixedsolvem(a, lua, p, n, bm, 1, ref info, rep, ref xm);
2140            x = new double[n];
2141            for(i_=0; i_<=n-1;i_++)
2142            {
2143                x[i_] = xm[i_,0];
2144            }
2145        }
2146
2147
2148        /*************************************************************************
2149        Dense solver.
2150
2151        Similar to RMatrixMixedSolve() but  solves task with multiple right  parts
2152        (where b and x are NxM matrices).
2153
2154        Algorithm features:
2155        * automatic detection of degenerate cases
2156        * condition number estimation
2157        * iterative refinement
2158        * O(M*N^2) complexity
2159
2160        INPUT PARAMETERS
2161            A       -   array[0..N-1,0..N-1], system matrix
2162            LUA     -   array[0..N-1,0..N-1], LU decomposition, RMatrixLU result
2163            P       -   array[0..N-1], pivots array, RMatrixLU result
2164            N       -   size of A
2165            B       -   array[0..N-1,0..M-1], right part
2166            M       -   right part size
2167
2168        OUTPUT PARAMETERS
2169            Info    -   same as in RMatrixSolveM
2170            Rep     -   same as in RMatrixSolveM
2171            X       -   same as in RMatrixSolveM
2172
2173          -- ALGLIB --
2174             Copyright 27.01.2010 by Bochkanov Sergey
2175        *************************************************************************/
2176        public static void rmatrixmixedsolvem(double[,] a,
2177            double[,] lua,
2178            int[] p,
2179            int n,
2180            double[,] b,
2181            int m,
2182            ref int info,
2183            densesolverreport rep,
2184            ref double[,] x)
2185        {
2186            double scalea = 0;
2187            int i = 0;
2188            int j = 0;
2189
2190            info = 0;
2191            x = new double[0,0];
2192
2193           
2194            //
2195            // prepare: check inputs, allocate space...
2196            //
2197            if( n<=0 || m<=0 )
2198            {
2199                info = -1;
2200                return;
2201            }
2202           
2203            //
2204            // 1. scale matrix, max(|A[i,j]|)
2205            // 2. factorize scaled matrix
2206            // 3. solve
2207            //
2208            scalea = 0;
2209            for(i=0; i<=n-1; i++)
2210            {
2211                for(j=0; j<=n-1; j++)
2212                {
2213                    scalea = Math.Max(scalea, Math.Abs(a[i,j]));
2214                }
2215            }
2216            if( (double)(scalea)==(double)(0) )
2217            {
2218                scalea = 1;
2219            }
2220            scalea = 1/scalea;
2221            rmatrixlusolveinternal(lua, p, scalea, n, a, true, b, m, ref info, rep, ref x);
2222        }
2223
2224
2225        /*************************************************************************
2226        Dense solver. Same as RMatrixSolveM(), but for complex matrices.
2227
2228        Algorithm features:
2229        * automatic detection of degenerate cases
2230        * condition number estimation
2231        * iterative refinement
2232        * O(N^3+M*N^2) complexity
2233
2234        INPUT PARAMETERS
2235            A       -   array[0..N-1,0..N-1], system matrix
2236            N       -   size of A
2237            B       -   array[0..N-1,0..M-1], right part
2238            M       -   right part size
2239            RFS     -   iterative refinement switch:
2240                        * True - refinement is used.
2241                          Less performance, more precision.
2242                        * False - refinement is not used.
2243                          More performance, less precision.
2244
2245        OUTPUT PARAMETERS
2246            Info    -   same as in RMatrixSolve
2247            Rep     -   same as in RMatrixSolve
2248            X       -   same as in RMatrixSolve
2249
2250          -- ALGLIB --
2251             Copyright 27.01.2010 by Bochkanov Sergey
2252        *************************************************************************/
2253        public static void cmatrixsolvem(complex[,] a,
2254            int n,
2255            complex[,] b,
2256            int m,
2257            bool rfs,
2258            ref int info,
2259            densesolverreport rep,
2260            ref complex[,] x)
2261        {
2262            complex[,] da = new complex[0,0];
2263            complex[,] emptya = new complex[0,0];
2264            int[] p = new int[0];
2265            double scalea = 0;
2266            int i = 0;
2267            int j = 0;
2268            int i_ = 0;
2269
2270            info = 0;
2271            x = new complex[0,0];
2272
2273           
2274            //
2275            // prepare: check inputs, allocate space...
2276            //
2277            if( n<=0 || m<=0 )
2278            {
2279                info = -1;
2280                return;
2281            }
2282            da = new complex[n, n];
2283           
2284            //
2285            // 1. scale matrix, max(|A[i,j]|)
2286            // 2. factorize scaled matrix
2287            // 3. solve
2288            //
2289            scalea = 0;
2290            for(i=0; i<=n-1; i++)
2291            {
2292                for(j=0; j<=n-1; j++)
2293                {
2294                    scalea = Math.Max(scalea, math.abscomplex(a[i,j]));
2295                }
2296            }
2297            if( (double)(scalea)==(double)(0) )
2298            {
2299                scalea = 1;
2300            }
2301            scalea = 1/scalea;
2302            for(i=0; i<=n-1; i++)
2303            {
2304                for(i_=0; i_<=n-1;i_++)
2305                {
2306                    da[i,i_] = a[i,i_];
2307                }
2308            }
2309            trfac.cmatrixlu(ref da, n, n, ref p);
2310            if( rfs )
2311            {
2312                cmatrixlusolveinternal(da, p, scalea, n, a, true, b, m, ref info, rep, ref x);
2313            }
2314            else
2315            {
2316                cmatrixlusolveinternal(da, p, scalea, n, emptya, false, b, m, ref info, rep, ref x);
2317            }
2318        }
2319
2320
2321        /*************************************************************************
2322        Dense solver. Same as RMatrixSolve(), but for complex matrices.
2323
2324        Algorithm features:
2325        * automatic detection of degenerate cases
2326        * condition number estimation
2327        * iterative refinement
2328        * O(N^3) complexity
2329
2330        INPUT PARAMETERS
2331            A       -   array[0..N-1,0..N-1], system matrix
2332            N       -   size of A
2333            B       -   array[0..N-1], right part
2334
2335        OUTPUT PARAMETERS
2336            Info    -   same as in RMatrixSolve
2337            Rep     -   same as in RMatrixSolve
2338            X       -   same as in RMatrixSolve
2339
2340          -- ALGLIB --
2341             Copyright 27.01.2010 by Bochkanov Sergey
2342        *************************************************************************/
2343        public static void cmatrixsolve(complex[,] a,
2344            int n,
2345            complex[] b,
2346            ref int info,
2347            densesolverreport rep,
2348            ref complex[] x)
2349        {
2350            complex[,] bm = new complex[0,0];
2351            complex[,] xm = new complex[0,0];
2352            int i_ = 0;
2353
2354            info = 0;
2355            x = new complex[0];
2356
2357            if( n<=0 )
2358            {
2359                info = -1;
2360                return;
2361            }
2362            bm = new complex[n, 1];
2363            for(i_=0; i_<=n-1;i_++)
2364            {
2365                bm[i_,0] = b[i_];
2366            }
2367            cmatrixsolvem(a, n, bm, 1, true, ref info, rep, ref xm);
2368            x = new complex[n];
2369            for(i_=0; i_<=n-1;i_++)
2370            {
2371                x[i_] = xm[i_,0];
2372            }
2373        }
2374
2375
2376        /*************************************************************************
2377        Dense solver. Same as RMatrixLUSolveM(), but for complex matrices.
2378
2379        Algorithm features:
2380        * automatic detection of degenerate cases
2381        * O(M*N^2) complexity
2382        * condition number estimation
2383
2384        No iterative refinement  is provided because exact form of original matrix
2385        is not known to subroutine. Use CMatrixSolve or CMatrixMixedSolve  if  you
2386        need iterative refinement.
2387
2388        INPUT PARAMETERS
2389            LUA     -   array[0..N-1,0..N-1], LU decomposition, RMatrixLU result
2390            P       -   array[0..N-1], pivots array, RMatrixLU result
2391            N       -   size of A
2392            B       -   array[0..N-1,0..M-1], right part
2393            M       -   right part size
2394
2395        OUTPUT PARAMETERS
2396            Info    -   same as in RMatrixSolve
2397            Rep     -   same as in RMatrixSolve
2398            X       -   same as in RMatrixSolve
2399
2400          -- ALGLIB --
2401             Copyright 27.01.2010 by Bochkanov Sergey
2402        *************************************************************************/
2403        public static void cmatrixlusolvem(complex[,] lua,
2404            int[] p,
2405            int n,
2406            complex[,] b,
2407            int m,
2408            ref int info,
2409            densesolverreport rep,
2410            ref complex[,] x)
2411        {
2412            complex[,] emptya = new complex[0,0];
2413            int i = 0;
2414            int j = 0;
2415            double scalea = 0;
2416
2417            info = 0;
2418            x = new complex[0,0];
2419
2420           
2421            //
2422            // prepare: check inputs, allocate space...
2423            //
2424            if( n<=0 || m<=0 )
2425            {
2426                info = -1;
2427                return;
2428            }
2429           
2430            //
2431            // 1. scale matrix, max(|U[i,j]|)
2432            //    we assume that LU is in its normal form, i.e. |L[i,j]|<=1
2433            // 2. solve
2434            //
2435            scalea = 0;
2436            for(i=0; i<=n-1; i++)
2437            {
2438                for(j=i; j<=n-1; j++)
2439                {
2440                    scalea = Math.Max(scalea, math.abscomplex(lua[i,j]));
2441                }
2442            }
2443            if( (double)(scalea)==(double)(0) )
2444            {
2445                scalea = 1;
2446            }
2447            scalea = 1/scalea;
2448            cmatrixlusolveinternal(lua, p, scalea, n, emptya, false, b, m, ref info, rep, ref x);
2449        }
2450
2451
2452        /*************************************************************************
2453        Dense solver. Same as RMatrixLUSolve(), but for complex matrices.
2454
2455        Algorithm features:
2456        * automatic detection of degenerate cases
2457        * O(N^2) complexity
2458        * condition number estimation
2459
2460        No iterative refinement is provided because exact form of original matrix
2461        is not known to subroutine. Use CMatrixSolve or CMatrixMixedSolve  if  you
2462        need iterative refinement.
2463
2464        INPUT PARAMETERS
2465            LUA     -   array[0..N-1,0..N-1], LU decomposition, CMatrixLU result
2466            P       -   array[0..N-1], pivots array, CMatrixLU result
2467            N       -   size of A
2468            B       -   array[0..N-1], right part
2469
2470        OUTPUT PARAMETERS
2471            Info    -   same as in RMatrixSolve
2472            Rep     -   same as in RMatrixSolve
2473            X       -   same as in RMatrixSolve
2474
2475          -- ALGLIB --
2476             Copyright 27.01.2010 by Bochkanov Sergey
2477        *************************************************************************/
2478        public static void cmatrixlusolve(complex[,] lua,
2479            int[] p,
2480            int n,
2481            complex[] b,
2482            ref int info,
2483            densesolverreport rep,
2484            ref complex[] x)
2485        {
2486            complex[,] bm = new complex[0,0];
2487            complex[,] xm = new complex[0,0];
2488            int i_ = 0;
2489
2490            info = 0;
2491            x = new complex[0];
2492
2493            if( n<=0 )
2494            {
2495                info = -1;
2496                return;
2497            }
2498            bm = new complex[n, 1];
2499            for(i_=0; i_<=n-1;i_++)
2500            {
2501                bm[i_,0] = b[i_];
2502            }
2503            cmatrixlusolvem(lua, p, n, bm, 1, ref info, rep, ref xm);
2504            x = new complex[n];
2505            for(i_=0; i_<=n-1;i_++)
2506            {
2507                x[i_] = xm[i_,0];
2508            }
2509        }
2510
2511
2512        /*************************************************************************
2513        Dense solver. Same as RMatrixMixedSolveM(), but for complex matrices.
2514
2515        Algorithm features:
2516        * automatic detection of degenerate cases
2517        * condition number estimation
2518        * iterative refinement
2519        * O(M*N^2) complexity
2520
2521        INPUT PARAMETERS
2522            A       -   array[0..N-1,0..N-1], system matrix
2523            LUA     -   array[0..N-1,0..N-1], LU decomposition, CMatrixLU result
2524            P       -   array[0..N-1], pivots array, CMatrixLU result
2525            N       -   size of A
2526            B       -   array[0..N-1,0..M-1], right part
2527            M       -   right part size
2528
2529        OUTPUT PARAMETERS
2530            Info    -   same as in RMatrixSolveM
2531            Rep     -   same as in RMatrixSolveM
2532            X       -   same as in RMatrixSolveM
2533
2534          -- ALGLIB --
2535             Copyright 27.01.2010 by Bochkanov Sergey
2536        *************************************************************************/
2537        public static void cmatrixmixedsolvem(complex[,] a,
2538            complex[,] lua,
2539            int[] p,
2540            int n,
2541            complex[,] b,
2542            int m,
2543            ref int info,
2544            densesolverreport rep,
2545            ref complex[,] x)
2546        {
2547            double scalea = 0;
2548            int i = 0;
2549            int j = 0;
2550
2551            info = 0;
2552            x = new complex[0,0];
2553
2554           
2555            //
2556            // prepare: check inputs, allocate space...
2557            //
2558            if( n<=0 || m<=0 )
2559            {
2560                info = -1;
2561                return;
2562            }
2563           
2564            //
2565            // 1. scale matrix, max(|A[i,j]|)
2566            // 2. factorize scaled matrix
2567            // 3. solve
2568            //
2569            scalea = 0;
2570            for(i=0; i<=n-1; i++)
2571            {
2572                for(j=0; j<=n-1; j++)
2573                {
2574                    scalea = Math.Max(scalea, math.abscomplex(a[i,j]));
2575                }
2576            }
2577            if( (double)(scalea)==(double)(0) )
2578            {
2579                scalea = 1;
2580            }
2581            scalea = 1/scalea;
2582            cmatrixlusolveinternal(lua, p, scalea, n, a, true, b, m, ref info, rep, ref x);
2583        }
2584
2585
2586        /*************************************************************************
2587        Dense solver. Same as RMatrixMixedSolve(), but for complex matrices.
2588
2589        Algorithm features:
2590        * automatic detection of degenerate cases
2591        * condition number estimation
2592        * iterative refinement
2593        * O(N^2) complexity
2594
2595        INPUT PARAMETERS
2596            A       -   array[0..N-1,0..N-1], system matrix
2597            LUA     -   array[0..N-1,0..N-1], LU decomposition, CMatrixLU result
2598            P       -   array[0..N-1], pivots array, CMatrixLU result
2599            N       -   size of A
2600            B       -   array[0..N-1], right part
2601
2602        OUTPUT PARAMETERS
2603            Info    -   same as in RMatrixSolveM
2604            Rep     -   same as in RMatrixSolveM
2605            X       -   same as in RMatrixSolveM
2606
2607          -- ALGLIB --
2608             Copyright 27.01.2010 by Bochkanov Sergey
2609        *************************************************************************/
2610        public static void cmatrixmixedsolve(complex[,] a,
2611            complex[,] lua,
2612            int[] p,
2613            int n,
2614            complex[] b,
2615            ref int info,
2616            densesolverreport rep,
2617            ref complex[] x)
2618        {
2619            complex[,] bm = new complex[0,0];
2620            complex[,] xm = new complex[0,0];
2621            int i_ = 0;
2622
2623            info = 0;
2624            x = new complex[0];
2625
2626            if( n<=0 )
2627            {
2628                info = -1;
2629                return;
2630            }
2631            bm = new complex[n, 1];
2632            for(i_=0; i_<=n-1;i_++)
2633            {
2634                bm[i_,0] = b[i_];
2635            }
2636            cmatrixmixedsolvem(a, lua, p, n, bm, 1, ref info, rep, ref xm);
2637            x = new complex[n];
2638            for(i_=0; i_<=n-1;i_++)
2639            {
2640                x[i_] = xm[i_,0];
2641            }
2642        }
2643
2644
2645        /*************************************************************************
2646        Dense solver. Same as RMatrixSolveM(), but for symmetric positive definite
2647        matrices.
2648
2649        Algorithm features:
2650        * automatic detection of degenerate cases
2651        * condition number estimation
2652        * O(N^3+M*N^2) complexity
2653        * matrix is represented by its upper or lower triangle
2654
2655        No iterative refinement is provided because such partial representation of
2656        matrix does not allow efficient calculation of extra-precise  matrix-vector
2657        products for large matrices. Use RMatrixSolve or RMatrixMixedSolve  if  you
2658        need iterative refinement.
2659
2660        INPUT PARAMETERS
2661            A       -   array[0..N-1,0..N-1], system matrix
2662            N       -   size of A
2663            IsUpper -   what half of A is provided
2664            B       -   array[0..N-1,0..M-1], right part
2665            M       -   right part size
2666
2667        OUTPUT PARAMETERS
2668            Info    -   same as in RMatrixSolve.
2669                        Returns -3 for non-SPD matrices.
2670            Rep     -   same as in RMatrixSolve
2671            X       -   same as in RMatrixSolve
2672
2673          -- ALGLIB --
2674             Copyright 27.01.2010 by Bochkanov Sergey
2675        *************************************************************************/
2676        public static void spdmatrixsolvem(double[,] a,
2677            int n,
2678            bool isupper,
2679            double[,] b,
2680            int m,
2681            ref int info,
2682            densesolverreport rep,
2683            ref double[,] x)
2684        {
2685            double[,] da = new double[0,0];
2686            double sqrtscalea = 0;
2687            int i = 0;
2688            int j = 0;
2689            int j1 = 0;
2690            int j2 = 0;
2691            int i_ = 0;
2692
2693            info = 0;
2694            x = new double[0,0];
2695
2696           
2697            //
2698            // prepare: check inputs, allocate space...
2699            //
2700            if( n<=0 || m<=0 )
2701            {
2702                info = -1;
2703                return;
2704            }
2705            da = new double[n, n];
2706           
2707            //
2708            // 1. scale matrix, max(|A[i,j]|)
2709            // 2. factorize scaled matrix
2710            // 3. solve
2711            //
2712            sqrtscalea = 0;
2713            for(i=0; i<=n-1; i++)
2714            {
2715                if( isupper )
2716                {
2717                    j1 = i;
2718                    j2 = n-1;
2719                }
2720                else
2721                {
2722                    j1 = 0;
2723                    j2 = i;
2724                }
2725                for(j=j1; j<=j2; j++)
2726                {
2727                    sqrtscalea = Math.Max(sqrtscalea, Math.Abs(a[i,j]));
2728                }
2729            }
2730            if( (double)(sqrtscalea)==(double)(0) )
2731            {
2732                sqrtscalea = 1;
2733            }
2734            sqrtscalea = 1/sqrtscalea;
2735            sqrtscalea = Math.Sqrt(sqrtscalea);
2736            for(i=0; i<=n-1; i++)
2737            {
2738                if( isupper )
2739                {
2740                    j1 = i;
2741                    j2 = n-1;
2742                }
2743                else
2744                {
2745                    j1 = 0;
2746                    j2 = i;
2747                }
2748                for(i_=j1; i_<=j2;i_++)
2749                {
2750                    da[i,i_] = a[i,i_];
2751                }
2752            }
2753            if( !trfac.spdmatrixcholesky(ref da, n, isupper) )
2754            {
2755                x = new double[n, m];
2756                for(i=0; i<=n-1; i++)
2757                {
2758                    for(j=0; j<=m-1; j++)
2759                    {
2760                        x[i,j] = 0;
2761                    }
2762                }
2763                rep.r1 = 0;
2764                rep.rinf = 0;
2765                info = -3;
2766                return;
2767            }
2768            info = 1;
2769            spdmatrixcholeskysolveinternal(da, sqrtscalea, n, isupper, a, true, b, m, ref info, rep, ref x);
2770        }
2771
2772
2773        /*************************************************************************
2774        Dense solver. Same as RMatrixSolve(), but for SPD matrices.
2775
2776        Algorithm features:
2777        * automatic detection of degenerate cases
2778        * condition number estimation
2779        * O(N^3) complexity
2780        * matrix is represented by its upper or lower triangle
2781
2782        No iterative refinement is provided because such partial representation of
2783        matrix does not allow efficient calculation of extra-precise  matrix-vector
2784        products for large matrices. Use RMatrixSolve or RMatrixMixedSolve  if  you
2785        need iterative refinement.
2786
2787        INPUT PARAMETERS
2788            A       -   array[0..N-1,0..N-1], system matrix
2789            N       -   size of A
2790            IsUpper -   what half of A is provided
2791            B       -   array[0..N-1], right part
2792
2793        OUTPUT PARAMETERS
2794            Info    -   same as in RMatrixSolve
2795                        Returns -3 for non-SPD matrices.
2796            Rep     -   same as in RMatrixSolve
2797            X       -   same as in RMatrixSolve
2798
2799          -- ALGLIB --
2800             Copyright 27.01.2010 by Bochkanov Sergey
2801        *************************************************************************/
2802        public static void spdmatrixsolve(double[,] a,
2803            int n,
2804            bool isupper,
2805            double[] b,
2806            ref int info,
2807            densesolverreport rep,
2808            ref double[] x)
2809        {
2810            double[,] bm = new double[0,0];
2811            double[,] xm = new double[0,0];
2812            int i_ = 0;
2813
2814            info = 0;
2815            x = new double[0];
2816
2817            if( n<=0 )
2818            {
2819                info = -1;
2820                return;
2821            }
2822            bm = new double[n, 1];
2823            for(i_=0; i_<=n-1;i_++)
2824            {
2825                bm[i_,0] = b[i_];
2826            }
2827            spdmatrixsolvem(a, n, isupper, bm, 1, ref info, rep, ref xm);
2828            x = new double[n];
2829            for(i_=0; i_<=n-1;i_++)
2830            {
2831                x[i_] = xm[i_,0];
2832            }
2833        }
2834
2835
2836        /*************************************************************************
2837        Dense solver. Same as RMatrixLUSolveM(), but for SPD matrices  represented
2838        by their Cholesky decomposition.
2839
2840        Algorithm features:
2841        * automatic detection of degenerate cases
2842        * O(M*N^2) complexity
2843        * condition number estimation
2844        * matrix is represented by its upper or lower triangle
2845
2846        No iterative refinement is provided because such partial representation of
2847        matrix does not allow efficient calculation of extra-precise  matrix-vector
2848        products for large matrices. Use RMatrixSolve or RMatrixMixedSolve  if  you
2849        need iterative refinement.
2850
2851        INPUT PARAMETERS
2852            CHA     -   array[0..N-1,0..N-1], Cholesky decomposition,
2853                        SPDMatrixCholesky result
2854            N       -   size of CHA
2855            IsUpper -   what half of CHA is provided
2856            B       -   array[0..N-1,0..M-1], right part
2857            M       -   right part size
2858
2859        OUTPUT PARAMETERS
2860            Info    -   same as in RMatrixSolve
2861            Rep     -   same as in RMatrixSolve
2862            X       -   same as in RMatrixSolve
2863
2864          -- ALGLIB --
2865             Copyright 27.01.2010 by Bochkanov Sergey
2866        *************************************************************************/
2867        public static void spdmatrixcholeskysolvem(double[,] cha,
2868            int n,
2869            bool isupper,
2870            double[,] b,
2871            int m,
2872            ref int info,
2873            densesolverreport rep,
2874            ref double[,] x)
2875        {
2876            double[,] emptya = new double[0,0];
2877            double sqrtscalea = 0;
2878            int i = 0;
2879            int j = 0;
2880            int j1 = 0;
2881            int j2 = 0;
2882
2883            info = 0;
2884            x = new double[0,0];
2885
2886           
2887            //
2888            // prepare: check inputs, allocate space...
2889            //
2890            if( n<=0 || m<=0 )
2891            {
2892                info = -1;
2893                return;
2894            }
2895           
2896            //
2897            // 1. scale matrix, max(|U[i,j]|)
2898            // 2. factorize scaled matrix
2899            // 3. solve
2900            //
2901            sqrtscalea = 0;
2902            for(i=0; i<=n-1; i++)
2903            {
2904                if( isupper )
2905                {
2906                    j1 = i;
2907                    j2 = n-1;
2908                }
2909                else
2910                {
2911                    j1 = 0;
2912                    j2 = i;
2913                }
2914                for(j=j1; j<=j2; j++)
2915                {
2916                    sqrtscalea = Math.Max(sqrtscalea, Math.Abs(cha[i,j]));
2917                }
2918            }
2919            if( (double)(sqrtscalea)==(double)(0) )
2920            {
2921                sqrtscalea = 1;
2922            }
2923            sqrtscalea = 1/sqrtscalea;
2924            spdmatrixcholeskysolveinternal(cha, sqrtscalea, n, isupper, emptya, false, b, m, ref info, rep, ref x);
2925        }
2926
2927
2928        /*************************************************************************
2929        Dense solver. Same as RMatrixLUSolve(), but for  SPD matrices  represented
2930        by their Cholesky decomposition.
2931
2932        Algorithm features:
2933        * automatic detection of degenerate cases
2934        * O(N^2) complexity
2935        * condition number estimation
2936        * matrix is represented by its upper or lower triangle
2937
2938        No iterative refinement is provided because such partial representation of
2939        matrix does not allow efficient calculation of extra-precise  matrix-vector
2940        products for large matrices. Use RMatrixSolve or RMatrixMixedSolve  if  you
2941        need iterative refinement.
2942
2943        INPUT PARAMETERS
2944            CHA     -   array[0..N-1,0..N-1], Cholesky decomposition,
2945                        SPDMatrixCholesky result
2946            N       -   size of A
2947            IsUpper -   what half of CHA is provided
2948            B       -   array[0..N-1], right part
2949
2950        OUTPUT PARAMETERS
2951            Info    -   same as in RMatrixSolve
2952            Rep     -   same as in RMatrixSolve
2953            X       -   same as in RMatrixSolve
2954
2955          -- ALGLIB --
2956             Copyright 27.01.2010 by Bochkanov Sergey
2957        *************************************************************************/
2958        public static void spdmatrixcholeskysolve(double[,] cha,
2959            int n,
2960            bool isupper,
2961            double[] b,
2962            ref int info,
2963            densesolverreport rep,
2964            ref double[] x)
2965        {
2966            double[,] bm = new double[0,0];
2967            double[,] xm = new double[0,0];
2968            int i_ = 0;
2969
2970            info = 0;
2971            x = new double[0];
2972
2973            if( n<=0 )
2974            {
2975                info = -1;
2976                return;
2977            }
2978            bm = new double[n, 1];
2979            for(i_=0; i_<=n-1;i_++)
2980            {
2981                bm[i_,0] = b[i_];
2982            }
2983            spdmatrixcholeskysolvem(cha, n, isupper, bm, 1, ref info, rep, ref xm);
2984            x = new double[n];
2985            for(i_=0; i_<=n-1;i_++)
2986            {
2987                x[i_] = xm[i_,0];
2988            }
2989        }
2990
2991
2992        /*************************************************************************
2993        Dense solver. Same as RMatrixSolveM(), but for Hermitian positive definite
2994        matrices.
2995
2996        Algorithm features:
2997        * automatic detection of degenerate cases
2998        * condition number estimation
2999        * O(N^3+M*N^2) complexity
3000        * matrix is represented by its upper or lower triangle
3001
3002        No iterative refinement is provided because such partial representation of
3003        matrix does not allow efficient calculation of extra-precise  matrix-vector
3004        products for large matrices. Use RMatrixSolve or RMatrixMixedSolve  if  you
3005        need iterative refinement.
3006
3007        INPUT PARAMETERS
3008            A       -   array[0..N-1,0..N-1], system matrix
3009            N       -   size of A
3010            IsUpper -   what half of A is provided
3011            B       -   array[0..N-1,0..M-1], right part
3012            M       -   right part size
3013
3014        OUTPUT PARAMETERS
3015            Info    -   same as in RMatrixSolve.
3016                        Returns -3 for non-HPD matrices.
3017            Rep     -   same as in RMatrixSolve
3018            X       -   same as in RMatrixSolve
3019
3020          -- ALGLIB --
3021             Copyright 27.01.2010 by Bochkanov Sergey
3022        *************************************************************************/
3023        public static void hpdmatrixsolvem(complex[,] a,
3024            int n,
3025            bool isupper,
3026            complex[,] b,
3027            int m,
3028            ref int info,
3029            densesolverreport rep,
3030            ref complex[,] x)
3031        {
3032            complex[,] da = new complex[0,0];
3033            double sqrtscalea = 0;
3034            int i = 0;
3035            int j = 0;
3036            int j1 = 0;
3037            int j2 = 0;
3038            int i_ = 0;
3039
3040            info = 0;
3041            x = new complex[0,0];
3042
3043           
3044            //
3045            // prepare: check inputs, allocate space...
3046            //
3047            if( n<=0 || m<=0 )
3048            {
3049                info = -1;
3050                return;
3051            }
3052            da = new complex[n, n];
3053           
3054            //
3055            // 1. scale matrix, max(|A[i,j]|)
3056            // 2. factorize scaled matrix
3057            // 3. solve
3058            //
3059            sqrtscalea = 0;
3060            for(i=0; i<=n-1; i++)
3061            {
3062                if( isupper )
3063                {
3064                    j1 = i;
3065                    j2 = n-1;
3066                }
3067                else
3068                {
3069                    j1 = 0;
3070                    j2 = i;
3071                }
3072                for(j=j1; j<=j2; j++)
3073                {
3074                    sqrtscalea = Math.Max(sqrtscalea, math.abscomplex(a[i,j]));
3075                }
3076            }
3077            if( (double)(sqrtscalea)==(double)(0) )
3078            {
3079                sqrtscalea = 1;
3080            }
3081            sqrtscalea = 1/sqrtscalea;
3082            sqrtscalea = Math.Sqrt(sqrtscalea);
3083            for(i=0; i<=n-1; i++)
3084            {
3085                if( isupper )
3086                {
3087                    j1 = i;
3088                    j2 = n-1;
3089                }
3090                else
3091                {
3092                    j1 = 0;
3093                    j2 = i;
3094                }
3095                for(i_=j1; i_<=j2;i_++)
3096                {
3097                    da[i,i_] = a[i,i_];
3098                }
3099            }
3100            if( !trfac.hpdmatrixcholesky(ref da, n, isupper) )
3101            {
3102                x = new complex[n, m];
3103                for(i=0; i<=n-1; i++)
3104                {
3105                    for(j=0; j<=m-1; j++)
3106                    {
3107                        x[i,j] = 0;
3108                    }
3109                }
3110                rep.r1 = 0;
3111                rep.rinf = 0;
3112                info = -3;
3113                return;
3114            }
3115            info = 1;
3116            hpdmatrixcholeskysolveinternal(da, sqrtscalea, n, isupper, a, true, b, m, ref info, rep, ref x);
3117        }
3118
3119
3120        /*************************************************************************
3121        Dense solver. Same as RMatrixSolve(),  but for Hermitian positive definite
3122        matrices.
3123
3124        Algorithm features:
3125        * automatic detection of degenerate cases
3126        * condition number estimation
3127        * O(N^3) complexity
3128        * matrix is represented by its upper or lower triangle
3129
3130        No iterative refinement is provided because such partial representation of
3131        matrix does not allow efficient calculation of extra-precise  matrix-vector
3132        products for large matrices. Use RMatrixSolve or RMatrixMixedSolve  if  you
3133        need iterative refinement.
3134
3135        INPUT PARAMETERS
3136            A       -   array[0..N-1,0..N-1], system matrix
3137            N       -   size of A
3138            IsUpper -   what half of A is provided
3139            B       -   array[0..N-1], right part
3140
3141        OUTPUT PARAMETERS
3142            Info    -   same as in RMatrixSolve
3143                        Returns -3 for non-HPD matrices.
3144            Rep     -   same as in RMatrixSolve
3145            X       -   same as in RMatrixSolve
3146
3147          -- ALGLIB --
3148             Copyright 27.01.2010 by Bochkanov Sergey
3149        *************************************************************************/
3150        public static void hpdmatrixsolve(complex[,] a,
3151            int n,
3152            bool isupper,
3153            complex[] b,
3154            ref int info,
3155            densesolverreport rep,
3156            ref complex[] x)
3157        {
3158            complex[,] bm = new complex[0,0];
3159            complex[,] xm = new complex[0,0];
3160            int i_ = 0;
3161
3162            info = 0;
3163            x = new complex[0];
3164
3165            if( n<=0 )
3166            {
3167                info = -1;
3168                return;
3169            }
3170            bm = new complex[n, 1];
3171            for(i_=0; i_<=n-1;i_++)
3172            {
3173                bm[i_,0] = b[i_];
3174            }
3175            hpdmatrixsolvem(a, n, isupper, bm, 1, ref info, rep, ref xm);
3176            x = new complex[n];
3177            for(i_=0; i_<=n-1;i_++)
3178            {
3179                x[i_] = xm[i_,0];
3180            }
3181        }
3182
3183
3184        /*************************************************************************
3185        Dense solver. Same as RMatrixLUSolveM(), but for HPD matrices  represented
3186        by their Cholesky decomposition.
3187
3188        Algorithm features:
3189        * automatic detection of degenerate cases
3190        * O(M*N^2) complexity
3191        * condition number estimation
3192        * matrix is represented by its upper or lower triangle
3193
3194        No iterative refinement is provided because such partial representation of
3195        matrix does not allow efficient calculation of extra-precise  matrix-vector
3196        products for large matrices. Use RMatrixSolve or RMatrixMixedSolve  if  you
3197        need iterative refinement.
3198
3199        INPUT PARAMETERS
3200            CHA     -   array[0..N-1,0..N-1], Cholesky decomposition,
3201                        HPDMatrixCholesky result
3202            N       -   size of CHA
3203            IsUpper -   what half of CHA is provided
3204            B       -   array[0..N-1,0..M-1], right part
3205            M       -   right part size
3206
3207        OUTPUT PARAMETERS
3208            Info    -   same as in RMatrixSolve
3209            Rep     -   same as in RMatrixSolve
3210            X       -   same as in RMatrixSolve
3211
3212          -- ALGLIB --
3213             Copyright 27.01.2010 by Bochkanov Sergey
3214        *************************************************************************/
3215        public static void hpdmatrixcholeskysolvem(complex[,] cha,
3216            int n,
3217            bool isupper,
3218            complex[,] b,
3219            int m,
3220            ref int info,
3221            densesolverreport rep,
3222            ref complex[,] x)
3223        {
3224            complex[,] emptya = new complex[0,0];
3225            double sqrtscalea = 0;
3226            int i = 0;
3227            int j = 0;
3228            int j1 = 0;
3229            int j2 = 0;
3230
3231            info = 0;
3232            x = new complex[0,0];
3233
3234           
3235            //
3236            // prepare: check inputs, allocate space...
3237            //
3238            if( n<=0 || m<=0 )
3239            {
3240                info = -1;
3241                return;
3242            }
3243           
3244            //
3245            // 1. scale matrix, max(|U[i,j]|)
3246            // 2. factorize scaled matrix
3247            // 3. solve
3248            //
3249            sqrtscalea = 0;
3250            for(i=0; i<=n-1; i++)
3251            {
3252                if( isupper )
3253                {
3254                    j1 = i;
3255                    j2 = n-1;
3256                }
3257                else
3258                {
3259                    j1 = 0;
3260                    j2 = i;
3261                }
3262                for(j=j1; j<=j2; j++)
3263                {
3264                    sqrtscalea = Math.Max(sqrtscalea, math.abscomplex(cha[i,j]));
3265                }
3266            }
3267            if( (double)(sqrtscalea)==(double)(0) )
3268            {
3269                sqrtscalea = 1;
3270            }
3271            sqrtscalea = 1/sqrtscalea;
3272            hpdmatrixcholeskysolveinternal(cha, sqrtscalea, n, isupper, emptya, false, b, m, ref info, rep, ref x);
3273        }
3274
3275
3276        /*************************************************************************
3277        Dense solver. Same as RMatrixLUSolve(), but for  HPD matrices  represented
3278        by their Cholesky decomposition.
3279
3280        Algorithm features:
3281        * automatic detection of degenerate cases
3282        * O(N^2) complexity
3283        * condition number estimation
3284        * matrix is represented by its upper or lower triangle
3285
3286        No iterative refinement is provided because such partial representation of
3287        matrix does not allow efficient calculation of extra-precise  matrix-vector
3288        products for large matrices. Use RMatrixSolve or RMatrixMixedSolve  if  you
3289        need iterative refinement.
3290
3291        INPUT PARAMETERS
3292            CHA     -   array[0..N-1,0..N-1], Cholesky decomposition,
3293                        SPDMatrixCholesky result
3294            N       -   size of A
3295            IsUpper -   what half of CHA is provided
3296            B       -   array[0..N-1], right part
3297
3298        OUTPUT PARAMETERS
3299            Info    -   same as in RMatrixSolve
3300            Rep     -   same as in RMatrixSolve
3301            X       -   same as in RMatrixSolve
3302
3303          -- ALGLIB --
3304             Copyright 27.01.2010 by Bochkanov Sergey
3305        *************************************************************************/
3306        public static void hpdmatrixcholeskysolve(complex[,] cha,
3307            int n,
3308            bool isupper,
3309            complex[] b,
3310            ref int info,
3311            densesolverreport rep,
3312            ref complex[] x)
3313        {
3314            complex[,] bm = new complex[0,0];
3315            complex[,] xm = new complex[0,0];
3316            int i_ = 0;
3317
3318            info = 0;
3319            x = new complex[0];
3320
3321            if( n<=0 )
3322            {
3323                info = -1;
3324                return;
3325            }
3326            bm = new complex[n, 1];
3327            for(i_=0; i_<=n-1;i_++)
3328            {
3329                bm[i_,0] = b[i_];
3330            }
3331            hpdmatrixcholeskysolvem(cha, n, isupper, bm, 1, ref info, rep, ref xm);
3332            x = new complex[n];
3333            for(i_=0; i_<=n-1;i_++)
3334            {
3335                x[i_] = xm[i_,0];
3336            }
3337        }
3338
3339
3340        /*************************************************************************
3341        Dense solver.
3342
3343        This subroutine finds solution of the linear system A*X=B with non-square,
3344        possibly degenerate A.  System  is  solved in the least squares sense, and
3345        general least squares solution  X = X0 + CX*y  which  minimizes |A*X-B| is
3346        returned. If A is non-degenerate, solution in the  usual sense is returned
3347
3348        Algorithm features:
3349        * automatic detection of degenerate cases
3350        * iterative refinement
3351        * O(N^3) complexity
3352
3353        INPUT PARAMETERS
3354            A       -   array[0..NRows-1,0..NCols-1], system matrix
3355            NRows   -   vertical size of A
3356            NCols   -   horizontal size of A
3357            B       -   array[0..NCols-1], right part
3358            Threshold-  a number in [0,1]. Singular values  beyond  Threshold  are
3359                        considered  zero.  Set  it to 0.0, if you don't understand
3360                        what it means, so the solver will choose good value on its
3361                        own.
3362                       
3363        OUTPUT PARAMETERS
3364            Info    -   return code:
3365                        * -4    SVD subroutine failed
3366                        * -1    if NRows<=0 or NCols<=0 or Threshold<0 was passed
3367                        *  1    if task is solved
3368            Rep     -   solver report, see below for more info
3369            X       -   array[0..N-1,0..M-1], it contains:
3370                        * solution of A*X=B if A is non-singular (well-conditioned
3371                          or ill-conditioned, but not very close to singular)
3372                        * zeros,  if  A  is  singular  or  VERY  close to singular
3373                          (in this case Info=-3).
3374
3375        SOLVER REPORT
3376
3377        Subroutine sets following fields of the Rep structure:
3378        * R2        reciprocal of condition number: 1/cond(A), 2-norm.
3379        * N         = NCols
3380        * K         dim(Null(A))
3381        * CX        array[0..N-1,0..K-1], kernel of A.
3382                    Columns of CX store such vectors that A*CX[i]=0.
3383
3384          -- ALGLIB --
3385             Copyright 24.08.2009 by Bochkanov Sergey
3386        *************************************************************************/
3387        public static void rmatrixsolvels(double[,] a,
3388            int nrows,
3389            int ncols,
3390            double[] b,
3391            double threshold,
3392            ref int info,
3393            densesolverlsreport rep,
3394            ref double[] x)
3395        {
3396            double[] sv = new double[0];
3397            double[,] u = new double[0,0];
3398            double[,] vt = new double[0,0];
3399            double[] rp = new double[0];
3400            double[] utb = new double[0];
3401            double[] sutb = new double[0];
3402            double[] tmp = new double[0];
3403            double[] ta = new double[0];
3404            double[] tx = new double[0];
3405            double[] buf = new double[0];
3406            double[] w = new double[0];
3407            int i = 0;
3408            int j = 0;
3409            int nsv = 0;
3410            int kernelidx = 0;
3411            double v = 0;
3412            double verr = 0;
3413            bool svdfailed = new bool();
3414            bool zeroa = new bool();
3415            int rfs = 0;
3416            int nrfs = 0;
3417            bool terminatenexttime = new bool();
3418            bool smallerr = new bool();
3419            int i_ = 0;
3420
3421            info = 0;
3422            x = new double[0];
3423
3424            if( (nrows<=0 || ncols<=0) || (double)(threshold)<(double)(0) )
3425            {
3426                info = -1;
3427                return;
3428            }
3429            if( (double)(threshold)==(double)(0) )
3430            {
3431                threshold = 1000*math.machineepsilon;
3432            }
3433           
3434            //
3435            // Factorize A first
3436            //
3437            svdfailed = !svd.rmatrixsvd(a, nrows, ncols, 1, 2, 2, ref sv, ref u, ref vt);
3438            zeroa = (double)(sv[0])==(double)(0);
3439            if( svdfailed || zeroa )
3440            {
3441                if( svdfailed )
3442                {
3443                    info = -4;
3444                }
3445                else
3446                {
3447                    info = 1;
3448                }
3449                x = new double[ncols];
3450                for(i=0; i<=ncols-1; i++)
3451                {
3452                    x[i] = 0;
3453                }
3454                rep.n = ncols;
3455                rep.k = ncols;
3456                rep.cx = new double[ncols, ncols];
3457                for(i=0; i<=ncols-1; i++)
3458                {
3459                    for(j=0; j<=ncols-1; j++)
3460                    {
3461                        if( i==j )
3462                        {
3463                            rep.cx[i,j] = 1;
3464                        }
3465                        else
3466                        {
3467                            rep.cx[i,j] = 0;
3468                        }
3469                    }
3470                }
3471                rep.r2 = 0;
3472                return;
3473            }
3474            nsv = Math.Min(ncols, nrows);
3475            if( nsv==ncols )
3476            {
3477                rep.r2 = sv[nsv-1]/sv[0];
3478            }
3479            else
3480            {
3481                rep.r2 = 0;
3482            }
3483            rep.n = ncols;
3484            info = 1;
3485           
3486            //
3487            // Iterative refinement of xc combined with solution:
3488            // 1. xc = 0
3489            // 2. calculate r = bc-A*xc using extra-precise dot product
3490            // 3. solve A*y = r
3491            // 4. update x:=x+r
3492            // 5. goto 2
3493            //
3494            // This cycle is executed until one of two things happens:
3495            // 1. maximum number of iterations reached
3496            // 2. last iteration decreased error to the lower limit
3497            //
3498            utb = new double[nsv];
3499            sutb = new double[nsv];
3500            x = new double[ncols];
3501            tmp = new double[ncols];
3502            ta = new double[ncols+1];
3503            tx = new double[ncols+1];
3504            buf = new double[ncols+1];
3505            for(i=0; i<=ncols-1; i++)
3506            {
3507                x[i] = 0;
3508            }
3509            kernelidx = nsv;
3510            for(i=0; i<=nsv-1; i++)
3511            {
3512                if( (double)(sv[i])<=(double)(threshold*sv[0]) )
3513                {
3514                    kernelidx = i;
3515                    break;
3516                }
3517            }
3518            rep.k = ncols-kernelidx;
3519            nrfs = densesolverrfsmaxv2(ncols, rep.r2);
3520            terminatenexttime = false;
3521            rp = new double[nrows];
3522            for(rfs=0; rfs<=nrfs; rfs++)
3523            {
3524                if( terminatenexttime )
3525                {
3526                    break;
3527                }
3528               
3529                //
3530                // calculate right part
3531                //
3532                if( rfs==0 )
3533                {
3534                    for(i_=0; i_<=nrows-1;i_++)
3535                    {
3536                        rp[i_] = b[i_];
3537                    }
3538                }
3539                else
3540                {
3541                    smallerr = true;
3542                    for(i=0; i<=nrows-1; i++)
3543                    {
3544                        for(i_=0; i_<=ncols-1;i_++)
3545                        {
3546                            ta[i_] = a[i,i_];
3547                        }
3548                        ta[ncols] = -1;
3549                        for(i_=0; i_<=ncols-1;i_++)
3550                        {
3551                            tx[i_] = x[i_];
3552                        }
3553                        tx[ncols] = b[i];
3554                        xblas.xdot(ta, tx, ncols+1, ref buf, ref v, ref verr);
3555                        rp[i] = -v;
3556                        smallerr = smallerr && (double)(Math.Abs(v))<(double)(4*verr);
3557                    }
3558                    if( smallerr )
3559                    {
3560                        terminatenexttime = true;
3561                    }
3562                }
3563               
3564                //
3565                // solve A*dx = rp
3566                //
3567                for(i=0; i<=ncols-1; i++)
3568                {
3569                    tmp[i] = 0;
3570                }
3571                for(i=0; i<=nsv-1; i++)
3572                {
3573                    utb[i] = 0;
3574                }
3575                for(i=0; i<=nrows-1; i++)
3576                {
3577                    v = rp[i];
3578                    for(i_=0; i_<=nsv-1;i_++)
3579                    {
3580                        utb[i_] = utb[i_] + v*u[i,i_];
3581                    }
3582                }
3583                for(i=0; i<=nsv-1; i++)
3584                {
3585                    if( i<kernelidx )
3586                    {
3587                        sutb[i] = utb[i]/sv[i];
3588                    }
3589                    else
3590                    {
3591                        sutb[i] = 0;
3592                    }
3593                }
3594                for(i=0; i<=nsv-1; i++)
3595                {
3596                    v = sutb[i];
3597                    for(i_=0; i_<=ncols-1;i_++)
3598                    {
3599                        tmp[i_] = tmp[i_] + v*vt[i,i_];
3600                    }
3601                }
3602               
3603                //
3604                // update x:  x:=x+dx
3605                //
3606                for(i_=0; i_<=ncols-1;i_++)
3607                {
3608                    x[i_] = x[i_] + tmp[i_];
3609                }
3610            }
3611           
3612            //
3613            // fill CX
3614            //
3615            if( rep.k>0 )
3616            {
3617                rep.cx = new double[ncols, rep.k];
3618                for(i=0; i<=rep.k-1; i++)
3619                {
3620                    for(i_=0; i_<=ncols-1;i_++)
3621                    {
3622                        rep.cx[i_,i] = vt[kernelidx+i,i_];
3623                    }
3624                }
3625            }
3626        }
3627
3628
3629        /*************************************************************************
3630        Internal LU solver
3631
3632          -- ALGLIB --
3633             Copyright 27.01.2010 by Bochkanov Sergey
3634        *************************************************************************/
3635        private static void rmatrixlusolveinternal(double[,] lua,
3636            int[] p,
3637            double scalea,
3638            int n,
3639            double[,] a,
3640            bool havea,
3641            double[,] b,
3642            int m,
3643            ref int info,
3644            densesolverreport rep,
3645            ref double[,] x)
3646        {
3647            int i = 0;
3648            int j = 0;
3649            int k = 0;
3650            int rfs = 0;
3651            int nrfs = 0;
3652            double[] xc = new double[0];
3653            double[] y = new double[0];
3654            double[] bc = new double[0];
3655            double[] xa = new double[0];
3656            double[] xb = new double[0];
3657            double[] tx = new double[0];
3658            double v = 0;
3659            double verr = 0;
3660            double mxb = 0;
3661            double scaleright = 0;
3662            bool smallerr = new bool();
3663            bool terminatenexttime = new bool();
3664            int i_ = 0;
3665
3666            info = 0;
3667            x = new double[0,0];
3668
3669            alglib.ap.assert((double)(scalea)>(double)(0));
3670           
3671            //
3672            // prepare: check inputs, allocate space...
3673            //
3674            if( n<=0 || m<=0 )
3675            {
3676                info = -1;
3677                return;
3678            }
3679            for(i=0; i<=n-1; i++)
3680            {
3681                if( p[i]>n-1 || p[i]<i )
3682                {
3683                    info = -1;
3684                    return;
3685                }
3686            }
3687            x = new double[n, m];
3688            y = new double[n];
3689            xc = new double[n];
3690            bc = new double[n];
3691            tx = new double[n+1];
3692            xa = new double[n+1];
3693            xb = new double[n+1];
3694           
3695            //
3696            // estimate condition number, test for near singularity
3697            //
3698            rep.r1 = rcond.rmatrixlurcond1(lua, n);
3699            rep.rinf = rcond.rmatrixlurcondinf(lua, n);
3700            if( (double)(rep.r1)<(double)(rcond.rcondthreshold()) || (double)(rep.rinf)<(double)(rcond.rcondthreshold()) )
3701            {
3702                for(i=0; i<=n-1; i++)
3703                {
3704                    for(j=0; j<=m-1; j++)
3705                    {
3706                        x[i,j] = 0;
3707                    }
3708                }
3709                rep.r1 = 0;
3710                rep.rinf = 0;
3711                info = -3;
3712                return;
3713            }
3714            info = 1;
3715           
3716            //
3717            // solve
3718            //
3719            for(k=0; k<=m-1; k++)
3720            {
3721               
3722                //
3723                // copy B to contiguous storage
3724                //
3725                for(i_=0; i_<=n-1;i_++)
3726                {
3727                    bc[i_] = b[i_,k];
3728                }
3729               
3730                //
3731                // Scale right part:
3732                // * MX stores max(|Bi|)
3733                // * ScaleRight stores actual scaling applied to B when solving systems
3734                //   it is chosen to make |scaleRight*b| close to 1.
3735                //
3736                mxb = 0;
3737                for(i=0; i<=n-1; i++)
3738                {
3739                    mxb = Math.Max(mxb, Math.Abs(bc[i]));
3740                }
3741                if( (double)(mxb)==(double)(0) )
3742                {
3743                    mxb = 1;
3744                }
3745                scaleright = 1/mxb;
3746               
3747                //
3748                // First, non-iterative part of solution process.
3749                // We use separate code for this task because
3750                // XDot is quite slow and we want to save time.
3751                //
3752                for(i_=0; i_<=n-1;i_++)
3753                {
3754                    xc[i_] = scaleright*bc[i_];
3755                }
3756                rbasiclusolve(lua, p, scalea, n, ref xc, ref tx);
3757               
3758                //
3759                // Iterative refinement of xc:
3760                // * calculate r = bc-A*xc using extra-precise dot product
3761                // * solve A*y = r
3762                // * update x:=x+r
3763                //
3764                // This cycle is executed until one of two things happens:
3765                // 1. maximum number of iterations reached
3766                // 2. last iteration decreased error to the lower limit
3767                //
3768                if( havea )
3769                {
3770                    nrfs = densesolverrfsmax(n, rep.r1, rep.rinf);
3771                    terminatenexttime = false;
3772                    for(rfs=0; rfs<=nrfs-1; rfs++)
3773                    {
3774                        if( terminatenexttime )
3775                        {
3776                            break;
3777                        }
3778                       
3779                        //
3780                        // generate right part
3781                        //
3782                        smallerr = true;
3783                        for(i_=0; i_<=n-1;i_++)
3784                        {
3785                            xb[i_] = xc[i_];
3786                        }
3787                        for(i=0; i<=n-1; i++)
3788                        {
3789                            for(i_=0; i_<=n-1;i_++)
3790                            {
3791                                xa[i_] = scalea*a[i,i_];
3792                            }
3793                            xa[n] = -1;
3794                            xb[n] = scaleright*bc[i];
3795                            xblas.xdot(xa, xb, n+1, ref tx, ref v, ref verr);
3796                            y[i] = -v;
3797                            smallerr = smallerr && (double)(Math.Abs(v))<(double)(4*verr);
3798                        }
3799                        if( smallerr )
3800                        {
3801                            terminatenexttime = true;
3802                        }
3803                       
3804                        //
3805                        // solve and update
3806                        //
3807                        rbasiclusolve(lua, p, scalea, n, ref y, ref tx);
3808                        for(i_=0; i_<=n-1;i_++)
3809                        {
3810                            xc[i_] = xc[i_] + y[i_];
3811                        }
3812                    }
3813                }
3814               
3815                //
3816                // Store xc.
3817                // Post-scale result.
3818                //
3819                v = scalea*mxb;
3820                for(i_=0; i_<=n-1;i_++)
3821                {
3822                    x[i_,k] = v*xc[i_];
3823                }
3824            }
3825        }
3826
3827
3828        /*************************************************************************
3829        Internal Cholesky solver
3830
3831          -- ALGLIB --
3832             Copyright 27.01.2010 by Bochkanov Sergey
3833        *************************************************************************/
3834        private static void spdmatrixcholeskysolveinternal(double[,] cha,
3835            double sqrtscalea,
3836            int n,
3837            bool isupper,
3838            double[,] a,
3839            bool havea,
3840            double[,] b,
3841            int m,
3842            ref int info,
3843            densesolverreport rep,
3844            ref double[,] x)
3845        {
3846            int i = 0;
3847            int j = 0;
3848            int k = 0;
3849            double[] xc = new double[0];
3850            double[] y = new double[0];
3851            double[] bc = new double[0];
3852            double[] xa = new double[0];
3853            double[] xb = new double[0];
3854            double[] tx = new double[0];
3855            double v = 0;
3856            double mxb = 0;
3857            double scaleright = 0;
3858            int i_ = 0;
3859
3860            info = 0;
3861            x = new double[0,0];
3862
3863            alglib.ap.assert((double)(sqrtscalea)>(double)(0));
3864           
3865            //
3866            // prepare: check inputs, allocate space...
3867            //
3868            if( n<=0 || m<=0 )
3869            {
3870                info = -1;
3871                return;
3872            }
3873            x = new double[n, m];
3874            y = new double[n];
3875            xc = new double[n];
3876            bc = new double[n];
3877            tx = new double[n+1];
3878            xa = new double[n+1];
3879            xb = new double[n+1];
3880           
3881            //
3882            // estimate condition number, test for near singularity
3883            //
3884            rep.r1 = rcond.spdmatrixcholeskyrcond(cha, n, isupper);
3885            rep.rinf = rep.r1;
3886            if( (double)(rep.r1)<(double)(rcond.rcondthreshold()) )
3887            {
3888                for(i=0; i<=n-1; i++)
3889                {
3890                    for(j=0; j<=m-1; j++)
3891                    {
3892                        x[i,j] = 0;
3893                    }
3894                }
3895                rep.r1 = 0;
3896                rep.rinf = 0;
3897                info = -3;
3898                return;
3899            }
3900            info = 1;
3901           
3902            //
3903            // solve
3904            //
3905            for(k=0; k<=m-1; k++)
3906            {
3907               
3908                //
3909                // copy B to contiguous storage
3910                //
3911                for(i_=0; i_<=n-1;i_++)
3912                {
3913                    bc[i_] = b[i_,k];
3914                }
3915               
3916                //
3917                // Scale right part:
3918                // * MX stores max(|Bi|)
3919                // * ScaleRight stores actual scaling applied to B when solving systems
3920                //   it is chosen to make |scaleRight*b| close to 1.
3921                //
3922                mxb = 0;
3923                for(i=0; i<=n-1; i++)
3924                {
3925                    mxb = Math.Max(mxb, Math.Abs(bc[i]));
3926                }
3927                if( (double)(mxb)==(double)(0) )
3928                {
3929                    mxb = 1;
3930                }
3931                scaleright = 1/mxb;
3932               
3933                //
3934                // First, non-iterative part of solution process.
3935                // We use separate code for this task because
3936                // XDot is quite slow and we want to save time.
3937                //
3938                for(i_=0; i_<=n-1;i_++)
3939                {
3940                    xc[i_] = scaleright*bc[i_];
3941                }
3942                spdbasiccholeskysolve(cha, sqrtscalea, n, isupper, ref xc, ref tx);
3943               
3944                //
3945                // Store xc.
3946                // Post-scale result.
3947                //
3948                v = math.sqr(sqrtscalea)*mxb;
3949                for(i_=0; i_<=n-1;i_++)
3950                {
3951                    x[i_,k] = v*xc[i_];
3952                }
3953            }
3954        }
3955
3956
3957        /*************************************************************************
3958        Internal LU solver
3959
3960          -- ALGLIB --
3961             Copyright 27.01.2010 by Bochkanov Sergey
3962        *************************************************************************/
3963        private static void cmatrixlusolveinternal(complex[,] lua,
3964            int[] p,
3965            double scalea,
3966            int n,
3967            complex[,] a,
3968            bool havea,
3969            complex[,] b,
3970            int m,
3971            ref int info,
3972            densesolverreport rep,
3973            ref complex[,] x)
3974        {
3975            int i = 0;
3976            int j = 0;
3977            int k = 0;
3978            int rfs = 0;
3979            int nrfs = 0;
3980            complex[] xc = new complex[0];
3981            complex[] y = new complex[0];
3982            complex[] bc = new complex[0];
3983            complex[] xa = new complex[0];
3984            complex[] xb = new complex[0];
3985            complex[] tx = new complex[0];
3986            double[] tmpbuf = new double[0];
3987            complex v = 0;
3988            double verr = 0;
3989            double mxb = 0;
3990            double scaleright = 0;
3991            bool smallerr = new bool();
3992            bool terminatenexttime = new bool();
3993            int i_ = 0;
3994
3995            info = 0;
3996            x = new complex[0,0];
3997
3998            alglib.ap.assert((double)(scalea)>(double)(0));
3999           
4000            //
4001            // prepare: check inputs, allocate space...
4002            //
4003            if( n<=0 || m<=0 )
4004            {
4005                info = -1;
4006                return;
4007            }
4008            for(i=0; i<=n-1; i++)
4009            {
4010                if( p[i]>n-1 || p[i]<i )
4011                {
4012                    info = -1;
4013                    return;
4014                }
4015            }
4016            x = new complex[n, m];
4017            y = new complex[n];
4018            xc = new complex[n];
4019            bc = new complex[n];
4020            tx = new complex[n];
4021            xa = new complex[n+1];
4022            xb = new complex[n+1];
4023            tmpbuf = new double[2*n+2];
4024           
4025            //
4026            // estimate condition number, test for near singularity
4027            //
4028            rep.r1 = rcond.cmatrixlurcond1(lua, n);
4029            rep.rinf = rcond.cmatrixlurcondinf(lua, n);
4030            if( (double)(rep.r1)<(double)(rcond.rcondthreshold()) || (double)(rep.rinf)<(double)(rcond.rcondthreshold()) )
4031            {
4032                for(i=0; i<=n-1; i++)
4033                {
4034                    for(j=0; j<=m-1; j++)
4035                    {
4036                        x[i,j] = 0;
4037                    }
4038                }
4039                rep.r1 = 0;
4040                rep.rinf = 0;
4041                info = -3;
4042                return;
4043            }
4044            info = 1;
4045           
4046            //
4047            // solve
4048            //
4049            for(k=0; k<=m-1; k++)
4050            {
4051               
4052                //
4053                // copy B to contiguous storage
4054                //
4055                for(i_=0; i_<=n-1;i_++)
4056                {
4057                    bc[i_] = b[i_,k];
4058                }
4059               
4060                //
4061                // Scale right part:
4062                // * MX stores max(|Bi|)
4063                // * ScaleRight stores actual scaling applied to B when solving systems
4064                //   it is chosen to make |scaleRight*b| close to 1.
4065                //
4066                mxb = 0;
4067                for(i=0; i<=n-1; i++)
4068                {
4069                    mxb = Math.Max(mxb, math.abscomplex(bc[i]));
4070                }
4071                if( (double)(mxb)==(double)(0) )
4072                {
4073                    mxb = 1;
4074                }
4075                scaleright = 1/mxb;
4076               
4077                //
4078                // First, non-iterative part of solution process.
4079                // We use separate code for this task because
4080                // XDot is quite slow and we want to save time.
4081                //
4082                for(i_=0; i_<=n-1;i_++)
4083                {
4084                    xc[i_] = scaleright*bc[i_];
4085                }
4086                cbasiclusolve(lua, p, scalea, n, ref xc, ref tx);
4087               
4088                //
4089                // Iterative refinement of xc:
4090                // * calculate r = bc-A*xc using extra-precise dot product
4091                // * solve A*y = r
4092                // * update x:=x+r
4093                //
4094                // This cycle is executed until one of two things happens:
4095                // 1. maximum number of iterations reached
4096                // 2. last iteration decreased error to the lower limit
4097                //
4098                if( havea )
4099                {
4100                    nrfs = densesolverrfsmax(n, rep.r1, rep.rinf);
4101                    terminatenexttime = false;
4102                    for(rfs=0; rfs<=nrfs-1; rfs++)
4103                    {
4104                        if( terminatenexttime )
4105                        {
4106                            break;
4107                        }
4108                       
4109                        //
4110                        // generate right part
4111                        //
4112                        smallerr = true;
4113                        for(i_=0; i_<=n-1;i_++)
4114                        {
4115                            xb[i_] = xc[i_];
4116                        }
4117                        for(i=0; i<=n-1; i++)
4118                        {
4119                            for(i_=0; i_<=n-1;i_++)
4120                            {
4121                                xa[i_] = scalea*a[i,i_];
4122                            }
4123                            xa[n] = -1;
4124                            xb[n] = scaleright*bc[i];
4125                            xblas.xcdot(xa, xb, n+1, ref tmpbuf, ref v, ref verr);
4126                            y[i] = -v;
4127                            smallerr = smallerr && (double)(math.abscomplex(v))<(double)(4*verr);
4128                        }
4129                        if( smallerr )
4130                        {
4131                            terminatenexttime = true;
4132                        }
4133                       
4134                        //
4135                        // solve and update
4136                        //
4137                        cbasiclusolve(lua, p, scalea, n, ref y, ref tx);
4138                        for(i_=0; i_<=n-1;i_++)
4139                        {
4140                            xc[i_] = xc[i_] + y[i_];
4141                        }
4142                    }
4143                }
4144               
4145                //
4146                // Store xc.
4147                // Post-scale result.
4148                //
4149                v = scalea*mxb;
4150                for(i_=0; i_<=n-1;i_++)
4151                {
4152                    x[i_,k] = v*xc[i_];
4153                }
4154            }
4155        }
4156
4157
4158        /*************************************************************************
4159        Internal Cholesky solver
4160
4161          -- ALGLIB --
4162             Copyright 27.01.2010 by Bochkanov Sergey
4163        *************************************************************************/
4164        private static void hpdmatrixcholeskysolveinternal(complex[,] cha,
4165            double sqrtscalea,
4166            int n,
4167            bool isupper,
4168            complex[,] a,
4169            bool havea,
4170            complex[,] b,
4171            int m,
4172            ref int info,
4173            densesolverreport rep,
4174            ref complex[,] x)
4175        {
4176            int i = 0;
4177            int j = 0;
4178            int k = 0;
4179            complex[] xc = new complex[0];
4180            complex[] y = new complex[0];
4181            complex[] bc = new complex[0];
4182            complex[] xa = new complex[0];
4183            complex[] xb = new complex[0];
4184            complex[] tx = new complex[0];
4185            double v = 0;
4186            double mxb = 0;
4187            double scaleright = 0;
4188            int i_ = 0;
4189
4190            info = 0;
4191            x = new complex[0,0];
4192
4193            alglib.ap.assert((double)(sqrtscalea)>(double)(0));
4194           
4195            //
4196            // prepare: check inputs, allocate space...
4197            //
4198            if( n<=0 || m<=0 )
4199            {
4200                info = -1;
4201                return;
4202            }
4203            x = new complex[n, m];
4204            y = new complex[n];
4205            xc = new complex[n];
4206            bc = new complex[n];
4207            tx = new complex[n+1];
4208            xa = new complex[n+1];
4209            xb = new complex[n+1];
4210           
4211            //
4212            // estimate condition number, test for near singularity
4213            //
4214            rep.r1 = rcond.hpdmatrixcholeskyrcond(cha, n, isupper);
4215            rep.rinf = rep.r1;
4216            if( (double)(rep.r1)<(double)(rcond.rcondthreshold()) )
4217            {
4218                for(i=0; i<=n-1; i++)
4219                {
4220                    for(j=0; j<=m-1; j++)
4221                    {
4222                        x[i,j] = 0;
4223                    }
4224                }
4225                rep.r1 = 0;
4226                rep.rinf = 0;
4227                info = -3;
4228                return;
4229            }
4230            info = 1;
4231           
4232            //
4233            // solve
4234            //
4235            for(k=0; k<=m-1; k++)
4236            {
4237               
4238                //
4239                // copy B to contiguous storage
4240                //
4241                for(i_=0; i_<=n-1;i_++)
4242                {
4243                    bc[i_] = b[i_,k];
4244                }
4245               
4246                //
4247                // Scale right part:
4248                // * MX stores max(|Bi|)
4249                // * ScaleRight stores actual scaling applied to B when solving systems
4250                //   it is chosen to make |scaleRight*b| close to 1.
4251                //
4252                mxb = 0;
4253                for(i=0; i<=n-1; i++)
4254                {
4255                    mxb = Math.Max(mxb, math.abscomplex(bc[i]));
4256                }
4257                if( (double)(mxb)==(double)(0) )
4258                {
4259                    mxb = 1;
4260                }
4261                scaleright = 1/mxb;
4262               
4263                //
4264                // First, non-iterative part of solution process.
4265                // We use separate code for this task because
4266                // XDot is quite slow and we want to save time.
4267                //
4268                for(i_=0; i_<=n-1;i_++)
4269                {
4270                    xc[i_] = scaleright*bc[i_];
4271                }
4272                hpdbasiccholeskysolve(cha, sqrtscalea, n, isupper, ref xc, ref tx);
4273               
4274                //
4275                // Store xc.
4276                // Post-scale result.
4277                //
4278                v = math.sqr(sqrtscalea)*mxb;
4279                for(i_=0; i_<=n-1;i_++)
4280                {
4281                    x[i_,k] = v*xc[i_];
4282                }
4283            }
4284        }
4285
4286
4287        /*************************************************************************
4288        Internal subroutine.
4289        Returns maximum count of RFS iterations as function of:
4290        1. machine epsilon
4291        2. task size.
4292        3. condition number
4293
4294          -- ALGLIB --
4295             Copyright 27.01.2010 by Bochkanov Sergey
4296        *************************************************************************/
4297        private static int densesolverrfsmax(int n,
4298            double r1,
4299            double rinf)
4300        {
4301            int result = 0;
4302
4303            result = 5;
4304            return result;
4305        }
4306
4307
4308        /*************************************************************************
4309        Internal subroutine.
4310        Returns maximum count of RFS iterations as function of:
4311        1. machine epsilon
4312        2. task size.
4313        3. norm-2 condition number
4314
4315          -- ALGLIB --
4316             Copyright 27.01.2010 by Bochkanov Sergey
4317        *************************************************************************/
4318        private static int densesolverrfsmaxv2(int n,
4319            double r2)
4320        {
4321            int result = 0;
4322
4323            result = densesolverrfsmax(n, 0, 0);
4324            return result;
4325        }
4326
4327
4328        /*************************************************************************
4329        Basic LU solver for ScaleA*PLU*x = y.
4330
4331        This subroutine assumes that:
4332        * L is well-scaled, and it is U which needs scaling by ScaleA.
4333        * A=PLU is well-conditioned, so no zero divisions or overflow may occur
4334
4335          -- ALGLIB --
4336             Copyright 27.01.2010 by Bochkanov Sergey
4337        *************************************************************************/
4338        private static void rbasiclusolve(double[,] lua,
4339            int[] p,
4340            double scalea,
4341            int n,
4342            ref double[] xb,
4343            ref double[] tmp)
4344        {
4345            int i = 0;
4346            double v = 0;
4347            int i_ = 0;
4348
4349            for(i=0; i<=n-1; i++)
4350            {
4351                if( p[i]!=i )
4352                {
4353                    v = xb[i];
4354                    xb[i] = xb[p[i]];
4355                    xb[p[i]] = v;
4356                }
4357            }
4358            for(i=1; i<=n-1; i++)
4359            {
4360                v = 0.0;
4361                for(i_=0; i_<=i-1;i_++)
4362                {
4363                    v += lua[i,i_]*xb[i_];
4364                }
4365                xb[i] = xb[i]-v;
4366            }
4367            xb[n-1] = xb[n-1]/(scalea*lua[n-1,n-1]);
4368            for(i=n-2; i>=0; i--)
4369            {
4370                for(i_=i+1; i_<=n-1;i_++)
4371                {
4372                    tmp[i_] = scalea*lua[i,i_];
4373                }
4374                v = 0.0;
4375                for(i_=i+1; i_<=n-1;i_++)
4376                {
4377                    v += tmp[i_]*xb[i_];
4378                }
4379                xb[i] = (xb[i]-v)/(scalea*lua[i,i]);
4380            }
4381        }
4382
4383
4384        /*************************************************************************
4385        Basic Cholesky solver for ScaleA*Cholesky(A)'*x = y.
4386
4387        This subroutine assumes that:
4388        * A*ScaleA is well scaled
4389        * A is well-conditioned, so no zero divisions or overflow may occur
4390
4391          -- ALGLIB --
4392             Copyright 27.01.2010 by Bochkanov Sergey
4393        *************************************************************************/
4394        private static void spdbasiccholeskysolve(double[,] cha,
4395            double sqrtscalea,
4396            int n,
4397            bool isupper,
4398            ref double[] xb,
4399            ref double[] tmp)
4400        {
4401            int i = 0;
4402            double v = 0;
4403            int i_ = 0;
4404
4405           
4406            //
4407            // A = L*L' or A=U'*U
4408            //
4409            if( isupper )
4410            {
4411               
4412                //
4413                // Solve U'*y=b first.
4414                //
4415                for(i=0; i<=n-1; i++)
4416                {
4417                    xb[i] = xb[i]/(sqrtscalea*cha[i,i]);
4418                    if( i<n-1 )
4419                    {
4420                        v = xb[i];
4421                        for(i_=i+1; i_<=n-1;i_++)
4422                        {
4423                            tmp[i_] = sqrtscalea*cha[i,i_];
4424                        }
4425                        for(i_=i+1; i_<=n-1;i_++)
4426                        {
4427                            xb[i_] = xb[i_] - v*tmp[i_];
4428                        }
4429                    }
4430                }
4431               
4432                //
4433                // Solve U*x=y then.
4434                //
4435                for(i=n-1; i>=0; i--)
4436                {
4437                    if( i<n-1 )
4438                    {
4439                        for(i_=i+1; i_<=n-1;i_++)
4440                        {
4441                            tmp[i_] = sqrtscalea*cha[i,i_];
4442                        }
4443                        v = 0.0;
4444                        for(i_=i+1; i_<=n-1;i_++)
4445                        {
4446                            v += tmp[i_]*xb[i_];
4447                        }
4448                        xb[i] = xb[i]-v;
4449                    }
4450                    xb[i] = xb[i]/(sqrtscalea*cha[i,i]);
4451                }
4452            }
4453            else
4454            {
4455               
4456                //
4457                // Solve L*y=b first
4458                //
4459                for(i=0; i<=n-1; i++)
4460                {
4461                    if( i>0 )
4462                    {
4463                        for(i_=0; i_<=i-1;i_++)
4464                        {
4465                            tmp[i_] = sqrtscalea*cha[i,i_];
4466                        }
4467                        v = 0.0;
4468                        for(i_=0; i_<=i-1;i_++)
4469                        {
4470                            v += tmp[i_]*xb[i_];
4471                        }
4472                        xb[i] = xb[i]-v;
4473                    }
4474                    xb[i] = xb[i]/(sqrtscalea*cha[i,i]);
4475                }
4476               
4477                //
4478                // Solve L'*x=y then.
4479                //
4480                for(i=n-1; i>=0; i--)
4481                {
4482                    xb[i] = xb[i]/(sqrtscalea*cha[i,i]);
4483                    if( i>0 )
4484                    {
4485                        v = xb[i];
4486                        for(i_=0; i_<=i-1;i_++)
4487                        {
4488                            tmp[i_] = sqrtscalea*cha[i,i_];
4489                        }
4490                        for(i_=0; i_<=i-1;i_++)
4491                        {
4492                            xb[i_] = xb[i_] - v*tmp[i_];
4493                        }
4494                    }
4495                }
4496            }
4497        }
4498
4499
4500        /*************************************************************************
4501        Basic LU solver for ScaleA*PLU*x = y.
4502
4503        This subroutine assumes that:
4504        * L is well-scaled, and it is U which needs scaling by ScaleA.
4505        * A=PLU is well-conditioned, so no zero divisions or overflow may occur
4506
4507          -- ALGLIB --
4508             Copyright 27.01.2010 by Bochkanov Sergey
4509        *************************************************************************/
4510        private static void cbasiclusolve(complex[,] lua,
4511            int[] p,
4512            double scalea,
4513            int n,
4514            ref complex[] xb,
4515            ref complex[] tmp)
4516        {
4517            int i = 0;
4518            complex v = 0;
4519            int i_ = 0;
4520
4521            for(i=0; i<=n-1; i++)
4522            {
4523                if( p[i]!=i )
4524                {
4525                    v = xb[i];
4526                    xb[i] = xb[p[i]];
4527                    xb[p[i]] = v;
4528                }
4529            }
4530            for(i=1; i<=n-1; i++)
4531            {
4532                v = 0.0;
4533                for(i_=0; i_<=i-1;i_++)
4534                {
4535                    v += lua[i,i_]*xb[i_];
4536                }
4537                xb[i] = xb[i]-v;
4538            }
4539            xb[n-1] = xb[n-1]/(scalea*lua[n-1,n-1]);
4540            for(i=n-2; i>=0; i--)
4541            {
4542                for(i_=i+1; i_<=n-1;i_++)
4543                {
4544                    tmp[i_] = scalea*lua[i,i_];
4545                }
4546                v = 0.0;
4547                for(i_=i+1; i_<=n-1;i_++)
4548                {
4549                    v += tmp[i_]*xb[i_];
4550                }
4551                xb[i] = (xb[i]-v)/(scalea*lua[i,i]);
4552            }
4553        }
4554
4555
4556        /*************************************************************************
4557        Basic Cholesky solver for ScaleA*Cholesky(A)'*x = y.
4558
4559        This subroutine assumes that:
4560        * A*ScaleA is well scaled
4561        * A is well-conditioned, so no zero divisions or overflow may occur
4562
4563          -- ALGLIB --
4564             Copyright 27.01.2010 by Bochkanov Sergey
4565        *************************************************************************/
4566        private static void hpdbasiccholeskysolve(complex[,] cha,
4567            double sqrtscalea,
4568            int n,
4569            bool isupper,
4570            ref complex[] xb,
4571            ref complex[] tmp)
4572        {
4573            int i = 0;
4574            complex v = 0;
4575            int i_ = 0;
4576
4577           
4578            //
4579            // A = L*L' or A=U'*U
4580            //
4581            if( isupper )
4582            {
4583               
4584                //
4585                // Solve U'*y=b first.
4586                //
4587                for(i=0; i<=n-1; i++)
4588                {
4589                    xb[i] = xb[i]/(sqrtscalea*math.conj(cha[i,i]));
4590                    if( i<n-1 )
4591                    {
4592                        v = xb[i];
4593                        for(i_=i+1; i_<=n-1;i_++)
4594                        {
4595                            tmp[i_] = sqrtscalea*math.conj(cha[i,i_]);
4596                        }
4597                        for(i_=i+1; i_<=n-1;i_++)
4598                        {
4599                            xb[i_] = xb[i_] - v*tmp[i_];
4600                        }
4601                    }
4602                }
4603               
4604                //
4605                // Solve U*x=y then.
4606                //
4607                for(i=n-1; i>=0; i--)
4608                {
4609                    if( i<n-1 )
4610                    {
4611                        for(i_=i+1; i_<=n-1;i_++)
4612                        {
4613                            tmp[i_] = sqrtscalea*cha[i,i_];
4614                        }
4615                        v = 0.0;
4616                        for(i_=i+1; i_<=n-1;i_++)
4617                        {
4618                            v += tmp[i_]*xb[i_];
4619                        }
4620                        xb[i] = xb[i]-v;
4621                    }
4622                    xb[i] = xb[i]/(sqrtscalea*cha[i,i]);
4623                }
4624            }
4625            else
4626            {
4627               
4628                //
4629                // Solve L*y=b first
4630                //
4631                for(i=0; i<=n-1; i++)
4632                {
4633                    if( i>0 )
4634                    {
4635                        for(i_=0; i_<=i-1;i_++)
4636                        {
4637                            tmp[i_] = sqrtscalea*cha[i,i_];
4638                        }
4639                        v = 0.0;
4640                        for(i_=0; i_<=i-1;i_++)
4641                        {
4642                            v += tmp[i_]*xb[i_];
4643                        }
4644                        xb[i] = xb[i]-v;
4645                    }
4646                    xb[i] = xb[i]/(sqrtscalea*cha[i,i]);
4647                }
4648               
4649                //
4650                // Solve L'*x=y then.
4651                //
4652                for(i=n-1; i>=0; i--)
4653                {
4654                    xb[i] = xb[i]/(sqrtscalea*math.conj(cha[i,i]));
4655                    if( i>0 )
4656                    {
4657                        v = xb[i];
4658                        for(i_=0; i_<=i-1;i_++)
4659                        {
4660                            tmp[i_] = sqrtscalea*math.conj(cha[i,i_]);
4661                        }
4662                        for(i_=0; i_<=i-1;i_++)
4663                        {
4664                            xb[i_] = xb[i_] - v*tmp[i_];
4665                        }
4666                    }
4667                }
4668            }
4669        }
4670
4671
4672    }
4673    public class linlsqr
4674    {
4675        /*************************************************************************
4676        This object stores state of the LinLSQR method.
4677
4678        You should use ALGLIB functions to work with this object.
4679        *************************************************************************/
4680        public class linlsqrstate
4681        {
4682            public normestimator.normestimatorstate nes;
4683            public double[] rx;
4684            public double[] b;
4685            public int n;
4686            public int m;
4687            public double[] ui;
4688            public double[] uip1;
4689            public double[] vi;
4690            public double[] vip1;
4691            public double[] omegai;
4692            public double[] omegaip1;
4693            public double alphai;
4694            public double alphaip1;
4695            public double betai;
4696            public double betaip1;
4697            public double phibari;
4698            public double phibarip1;
4699            public double phii;
4700            public double rhobari;
4701            public double rhobarip1;
4702            public double rhoi;
4703            public double ci;
4704            public double si;
4705            public double theta;
4706            public double lambdai;
4707            public double[] d;
4708            public double anorm;
4709            public double bnorm2;
4710            public double dnorm;
4711            public double r2;
4712            public double[] x;
4713            public double[] mv;
4714            public double[] mtv;
4715            public double epsa;
4716            public double epsb;
4717            public double epsc;
4718            public int maxits;
4719            public bool xrep;
4720            public bool xupdated;
4721            public bool needmv;
4722            public bool needmtv;
4723            public bool needmv2;
4724            public bool needvmv;
4725            public bool needprec;
4726            public int repiterationscount;
4727            public int repnmv;
4728            public int repterminationtype;
4729            public bool running;
4730            public rcommstate rstate;
4731            public linlsqrstate()
4732            {
4733                nes = new normestimator.normestimatorstate();
4734                rx = new double[0];
4735                b = new double[0];
4736                ui = new double[0];
4737                uip1 = new double[0];
4738                vi = new double[0];
4739                vip1 = new double[0];
4740                omegai = new double[0];
4741                omegaip1 = new double[0];
4742                d = new double[0];
4743                x = new double[0];
4744                mv = new double[0];
4745                mtv = new double[0];
4746                rstate = new rcommstate();
4747            }
4748        };
4749
4750
4751        public class linlsqrreport
4752        {
4753            public int iterationscount;
4754            public int nmv;
4755            public int terminationtype;
4756        };
4757
4758
4759
4760
4761        public const double atol = 1.0E-6;
4762        public const double btol = 1.0E-6;
4763
4764
4765        /*************************************************************************
4766        This function initializes linear LSQR Solver. This solver is used to solve
4767        non-symmetric (and, possibly, non-square) problems. Least squares solution
4768        is returned for non-compatible systems.
4769
4770        USAGE:
4771        1. User initializes algorithm state with LinLSQRCreate() call
4772        2. User tunes solver parameters with  LinLSQRSetCond() and other functions
4773        3. User  calls  LinLSQRSolveSparse()  function which takes algorithm state
4774           and SparseMatrix object.
4775        4. User calls LinLSQRResults() to get solution
4776        5. Optionally, user may call LinLSQRSolveSparse() again to  solve  another 
4777           problem  with different matrix and/or right part without reinitializing
4778           LinLSQRState structure.
4779         
4780        INPUT PARAMETERS:
4781            M       -   number of rows in A
4782            N       -   number of variables, N>0
4783
4784        OUTPUT PARAMETERS:
4785            State   -   structure which stores algorithm state
4786
4787          -- ALGLIB --
4788             Copyright 30.11.2011 by Bochkanov Sergey
4789        *************************************************************************/
4790        public static void linlsqrcreate(int m,
4791            int n,
4792            linlsqrstate state)
4793        {
4794            int i = 0;
4795
4796            alglib.ap.assert(m>0, "LinLSQRCreate: M<=0");
4797            alglib.ap.assert(n>0, "LinLSQRCreate: N<=0");
4798            state.m = m;
4799            state.n = n;
4800            state.epsa = atol;
4801            state.epsb = btol;
4802            state.epsc = 1/Math.Sqrt(math.machineepsilon);
4803            state.maxits = 0;
4804            state.lambdai = 0;
4805            state.xrep = false;
4806            state.running = false;
4807           
4808            //
4809            // * allocate arrays
4810            // * set RX to NAN (just for the case user calls Results() without
4811            //   calling SolveSparse()
4812            // * set B to zero
4813            //
4814            normestimator.normestimatorcreate(m, n, 2, 2, state.nes);
4815            state.rx = new double[state.n];
4816            state.ui = new double[state.m+state.n];
4817            state.uip1 = new double[state.m+state.n];
4818            state.vip1 = new double[state.n];
4819            state.vi = new double[state.n];
4820            state.omegai = new double[state.n];
4821            state.omegaip1 = new double[state.n];
4822            state.d = new double[state.n];
4823            state.x = new double[state.m+state.n];
4824            state.mv = new double[state.m+state.n];
4825            state.mtv = new double[state.n];
4826            state.b = new double[state.m];
4827            for(i=0; i<=n-1; i++)
4828            {
4829                state.rx[i] = Double.NaN;
4830            }
4831            for(i=0; i<=m-1; i++)
4832            {
4833                state.b[i] = 0;
4834            }
4835            state.rstate.ia = new int[1+1];
4836            state.rstate.ra = new double[0+1];
4837            state.rstate.stage = -1;
4838        }
4839
4840
4841        /*************************************************************************
4842        This function sets right part. By default, right part is zero.
4843
4844        INPUT PARAMETERS:
4845            B       -   right part, array[N].
4846
4847        OUTPUT PARAMETERS:
4848            State   -   structure which stores algorithm state
4849
4850          -- ALGLIB --
4851             Copyright 30.11.2011 by Bochkanov Sergey
4852        *************************************************************************/
4853        public static void linlsqrsetb(linlsqrstate state,
4854            double[] b)
4855        {
4856            int i = 0;
4857
4858            alglib.ap.assert(!state.running, "LinLSQRSetB: you can not change B when LinLSQRIteration is running");
4859            alglib.ap.assert(state.m<=alglib.ap.len(b), "LinLSQRSetB: Length(B)<M");
4860            alglib.ap.assert(apserv.isfinitevector(b, state.m), "LinLSQRSetB: B contains infinite or NaN values");
4861            state.bnorm2 = 0;
4862            for(i=0; i<=state.m-1; i++)
4863            {
4864                state.b[i] = b[i];
4865                state.bnorm2 = state.bnorm2+b[i]*b[i];
4866            }
4867        }
4868
4869
4870        /*************************************************************************
4871        This function sets optional Tikhonov regularization coefficient.
4872        It is zero by default.
4873
4874        INPUT PARAMETERS:
4875            LambdaI -   regularization factor, LambdaI>=0
4876
4877        OUTPUT PARAMETERS:
4878            State   -   structure which stores algorithm state
4879           
4880          -- ALGLIB --
4881             Copyright 30.11.2011 by Bochkanov Sergey
4882        *************************************************************************/
4883        public static void linlsqrsetlambdai(linlsqrstate state,
4884            double lambdai)
4885        {
4886            alglib.ap.assert(!state.running, "LinLSQRSetLambdaI: you can not set LambdaI, because function LinLSQRIteration is running");
4887            alglib.ap.assert(math.isfinite(lambdai) && (double)(lambdai)>=(double)(0), "LinLSQRSetLambdaI: LambdaI is infinite or NaN");
4888            state.lambdai = lambdai;
4889        }
4890
4891
4892        /*************************************************************************
4893
4894          -- ALGLIB --
4895             Copyright 30.11.2011 by Bochkanov Sergey
4896        *************************************************************************/
4897        public static bool linlsqriteration(linlsqrstate state)
4898        {
4899            bool result = new bool();
4900            int summn = 0;
4901            double bnorm = 0;
4902            int i = 0;
4903            int i_ = 0;
4904
4905           
4906            //
4907            // Reverse communication preparations
4908            // I know it looks ugly, but it works the same way
4909            // anywhere from C++ to Python.
4910            //
4911            // This code initializes locals by:
4912            // * random values determined during code
4913            //   generation - on first subroutine call
4914            // * values from previous call - on subsequent calls
4915            //
4916            if( state.rstate.stage>=0 )
4917            {
4918                summn = state.rstate.ia[0];
4919                i = state.rstate.ia[1];
4920                bnorm = state.rstate.ra[0];
4921            }
4922            else
4923            {
4924                summn = -983;
4925                i = -989;
4926                bnorm = -834;
4927            }
4928            if( state.rstate.stage==0 )
4929            {
4930                goto lbl_0;
4931            }
4932            if( state.rstate.stage==1 )
4933            {
4934                goto lbl_1;
4935            }
4936            if( state.rstate.stage==2 )
4937            {
4938                goto lbl_2;
4939            }
4940            if( state.rstate.stage==3 )
4941            {
4942                goto lbl_3;
4943            }
4944            if( state.rstate.stage==4 )
4945            {
4946                goto lbl_4;
4947            }
4948            if( state.rstate.stage==5 )
4949            {
4950                goto lbl_5;
4951            }
4952            if( state.rstate.stage==6 )
4953            {
4954                goto lbl_6;
4955            }
4956           
4957            //
4958            // Routine body
4959            //
4960            alglib.ap.assert(alglib.ap.len(state.b)>0, "LinLSQRIteration: using non-allocated array B");
4961            bnorm = Math.Sqrt(state.bnorm2);
4962            state.running = true;
4963            state.repnmv = 0;
4964            clearrfields(state);
4965            state.repiterationscount = 0;
4966            summn = state.m+state.n;
4967            state.r2 = state.bnorm2;
4968           
4969            //
4970            //estimate for ANorm
4971            //
4972            normestimator.normestimatorrestart(state.nes);
4973        lbl_7:
4974            if( !normestimator.normestimatoriteration(state.nes) )
4975            {
4976                goto lbl_8;
4977            }
4978            if( !state.nes.needmv )
4979            {
4980                goto lbl_9;
4981            }
4982            for(i_=0; i_<=state.n-1;i_++)
4983            {
4984                state.x[i_] = state.nes.x[i_];
4985            }
4986            state.repnmv = state.repnmv+1;
4987            clearrfields(state);
4988            state.needmv = true;
4989            state.rstate.stage = 0;
4990            goto lbl_rcomm;
4991        lbl_0:
4992            state.needmv = false;
4993            for(i_=0; i_<=state.m-1;i_++)
4994            {
4995                state.nes.mv[i_] = state.mv[i_];
4996            }
4997            goto lbl_7;
4998        lbl_9:
4999            if( !state.nes.needmtv )
5000            {
5001                goto lbl_11;
5002            }
5003            for(i_=0; i_<=state.m-1;i_++)
5004            {
5005                state.x[i_] = state.nes.x[i_];
5006            }
5007           
5008            //
5009            //matrix-vector multiplication
5010            //
5011            state.repnmv = state.repnmv+1;
5012            clearrfields(state);
5013            state.needmtv = true;
5014            state.rstate.stage = 1;
5015            goto lbl_rcomm;
5016        lbl_1:
5017            state.needmtv = false;
5018            for(i_=0; i_<=state.n-1;i_++)
5019            {
5020                state.nes.mtv[i_] = state.mtv[i_];
5021            }
5022            goto lbl_7;
5023        lbl_11:
5024            goto lbl_7;
5025        lbl_8:
5026            normestimator.normestimatorresults(state.nes, ref state.anorm);
5027           
5028            //
5029            //initialize .RX by zeros
5030            //
5031            for(i=0; i<=state.n-1; i++)
5032            {
5033                state.rx[i] = 0;
5034            }
5035           
5036            //
5037            //output first report
5038            //
5039            if( !state.xrep )
5040            {
5041                goto lbl_13;
5042            }
5043            for(i_=0; i_<=state.n-1;i_++)
5044            {
5045                state.x[i_] = state.rx[i_];
5046            }
5047            clearrfields(state);
5048            state.xupdated = true;
5049            state.rstate.stage = 2;
5050            goto lbl_rcomm;
5051        lbl_2:
5052            state.xupdated = false;
5053        lbl_13:
5054           
5055            //
5056            // LSQR, Step 0.
5057            //
5058            // Algorithm outline corresponds to one which was described at p.50 of
5059            // "LSQR - an algorithm for sparse linear equations and sparse least
5060            // squares" by C.Paige and M.Saunders with one small addition - we
5061            // explicitly extend system matrix by additional N lines in order
5062            // to handle non-zero lambda, i.e. original A is replaced by
5063            //         [ A        ]
5064            // A_mod = [          ]
5065            //         [ lambda*I ].
5066            //
5067            // Step 0:
5068            //     x[0]          = 0
5069            //     beta[1]*u[1]  = b
5070            //     alpha[1]*v[1] = A_mod'*u[1]
5071            //     w[1]          = v[1]
5072            //     phiBar[1]     = beta[1]
5073            //     rhoBar[1]     = alpha[1]
5074            //     d[0]          = 0
5075            //
5076            // NOTE:
5077            // There are three criteria for stopping:
5078            // (S0) maximum number of iterations
5079            // (S1) ||Rk||<=EpsB*||B||;
5080            // (S2) ||A^T*Rk||/(||A||*||Rk||)<=EpsA.
5081            // It is very important that S2 always checked AFTER S1. It is necessary
5082            // to avoid division by zero when Rk=0.
5083            //
5084            state.betai = bnorm;
5085            if( (double)(state.betai)==(double)(0) )
5086            {
5087               
5088                //
5089                // Zero right part
5090                //
5091                state.running = false;
5092                state.repterminationtype = 1;
5093                result = false;
5094                return result;
5095            }
5096            for(i=0; i<=summn-1; i++)
5097            {
5098                if( i<state.m )
5099                {
5100                    state.ui[i] = state.b[i]/state.betai;
5101                }
5102                else
5103                {
5104                    state.ui[i] = 0;
5105                }
5106                state.x[i] = state.ui[i];
5107            }
5108            state.repnmv = state.repnmv+1;
5109            clearrfields(state);
5110            state.needmtv = true;
5111            state.rstate.stage = 3;
5112            goto lbl_rcomm;
5113        lbl_3:
5114            state.needmtv = false;
5115            for(i=0; i<=state.n-1; i++)
5116            {
5117                state.mtv[i] = state.mtv[i]+state.lambdai*state.ui[state.m+i];
5118            }
5119            state.alphai = 0;
5120            for(i=0; i<=state.n-1; i++)
5121            {
5122                state.alphai = state.alphai+state.mtv[i]*state.mtv[i];
5123            }
5124            state.alphai = Math.Sqrt(state.alphai);
5125            if( (double)(state.alphai)==(double)(0) )
5126            {
5127               
5128                //
5129                // Orthogonality stopping criterion is met
5130                //
5131                state.running = false;
5132                state.repterminationtype = 4;
5133                result = false;
5134                return result;
5135            }
5136            for(i=0; i<=state.n-1; i++)
5137            {
5138                state.vi[i] = state.mtv[i]/state.alphai;
5139                state.omegai[i] = state.vi[i];
5140            }
5141            state.phibari = state.betai;
5142            state.rhobari = state.alphai;
5143            for(i=0; i<=state.n-1; i++)
5144            {
5145                state.d[i] = 0;
5146            }
5147            state.dnorm = 0;
5148           
5149            //
5150            // Steps I=1, 2, ...
5151            //
5152        lbl_15:
5153            if( false )
5154            {
5155                goto lbl_16;
5156            }
5157           
5158            //
5159            // At I-th step State.RepIterationsCount=I.
5160            //
5161            state.repiterationscount = state.repiterationscount+1;
5162           
5163            //
5164            // Bidiagonalization part:
5165            //     beta[i+1]*u[i+1]  = A_mod*v[i]-alpha[i]*u[i]
5166            //     alpha[i+1]*v[i+1] = A_mod'*u[i+1] - beta[i+1]*v[i]
5167            //     
5168            // NOTE:  beta[i+1]=0 or alpha[i+1]=0 will lead to successful termination
5169            //        in the end of the current iteration. In this case u/v are zero.
5170            // NOTE2: algorithm won't fail on zero alpha or beta (there will be no
5171            //        division by zero because it will be stopped BEFORE division
5172            //        occurs). However, near-zero alpha and beta won't stop algorithm
5173            //        and, although no division by zero will happen, orthogonality
5174            //        in U and V will be lost.
5175            //
5176            for(i_=0; i_<=state.n-1;i_++)
5177            {
5178                state.x[i_] = state.vi[i_];
5179            }
5180            state.repnmv = state.repnmv+1;
5181            clearrfields(state);
5182            state.needmv = true;
5183            state.rstate.stage = 4;
5184            goto lbl_rcomm;
5185        lbl_4:
5186            state.needmv = false;
5187            for(i=0; i<=state.n-1; i++)
5188            {
5189                state.mv[state.m+i] = state.lambdai*state.vi[i];
5190            }
5191            state.betaip1 = 0;
5192            for(i=0; i<=summn-1; i++)
5193            {
5194                state.uip1[i] = state.mv[i]-state.alphai*state.ui[i];
5195                state.betaip1 = state.betaip1+state.uip1[i]*state.uip1[i];
5196            }
5197            if( (double)(state.betaip1)!=(double)(0) )
5198            {
5199                state.betaip1 = Math.Sqrt(state.betaip1);
5200                for(i=0; i<=summn-1; i++)
5201                {
5202                    state.uip1[i] = state.uip1[i]/state.betaip1;
5203                }
5204            }
5205            for(i_=0; i_<=state.m-1;i_++)
5206            {
5207                state.x[i_] = state.uip1[i_];
5208            }
5209            state.repnmv = state.repnmv+1;
5210            clearrfields(state);
5211            state.needmtv = true;
5212            state.rstate.stage = 5;
5213            goto lbl_rcomm;
5214        lbl_5:
5215            state.needmtv = false;
5216            for(i=0; i<=state.n-1; i++)
5217            {
5218                state.mtv[i] = state.mtv[i]+state.lambdai*state.uip1[state.m+i];
5219            }
5220            state.alphaip1 = 0;
5221            for(i=0; i<=state.n-1; i++)
5222            {
5223                state.vip1[i] = state.mtv[i]-state.betaip1*state.vi[i];
5224                state.alphaip1 = state.alphaip1+state.vip1[i]*state.vip1[i];
5225            }
5226            if( (double)(state.alphaip1)!=(double)(0) )
5227            {
5228                state.alphaip1 = Math.Sqrt(state.alphaip1);
5229                for(i=0; i<=state.n-1; i++)
5230                {
5231                    state.vip1[i] = state.vip1[i]/state.alphaip1;
5232                }
5233            }
5234           
5235            //
5236            // Build next orthogonal transformation
5237            //
5238            state.rhoi = apserv.safepythag2(state.rhobari, state.betaip1);
5239            state.ci = state.rhobari/state.rhoi;
5240            state.si = state.betaip1/state.rhoi;
5241            state.theta = state.si*state.alphaip1;
5242            state.rhobarip1 = -(state.ci*state.alphaip1);
5243            state.phii = state.ci*state.phibari;
5244            state.phibarip1 = state.si*state.phibari;
5245           
5246            //
5247            // Update .RNorm
5248            //
5249            // This tricky  formula  is  necessary  because  simply  writing
5250            // State.R2:=State.PhiBarIP1*State.PhiBarIP1 does NOT guarantees
5251            // monotonic decrease of R2. Roundoff error combined with 80-bit
5252            // precision used internally by Intel chips allows R2 to increase
5253            // slightly in some rare, but possible cases. This property is
5254            // undesirable, so we prefer to guard against R increase.
5255            //
5256            state.r2 = Math.Min(state.r2, state.phibarip1*state.phibarip1);
5257           
5258            //
5259            // Update d and DNorm, check condition-related stopping criteria
5260            //
5261            for(i=0; i<=state.n-1; i++)
5262            {
5263                state.d[i] = 1/state.rhoi*(state.vi[i]-state.theta*state.d[i]);
5264                state.dnorm = state.dnorm+state.d[i]*state.d[i];
5265            }
5266            if( (double)(Math.Sqrt(state.dnorm)*state.anorm)>=(double)(state.epsc) )
5267            {
5268                state.running = false;
5269                state.repterminationtype = 7;
5270                result = false;
5271                return result;
5272            }
5273           
5274            //
5275            // Update x, output report
5276            //
5277            for(i=0; i<=state.n-1; i++)
5278            {
5279                state.rx[i] = state.rx[i]+state.phii/state.rhoi*state.omegai[i];
5280            }
5281            if( !state.xrep )
5282            {
5283                goto lbl_17;
5284            }
5285            for(i_=0; i_<=state.n-1;i_++)
5286            {
5287                state.x[i_] = state.rx[i_];
5288            }
5289            clearrfields(state);
5290            state.xupdated = true;
5291            state.rstate.stage = 6;
5292            goto lbl_rcomm;
5293        lbl_6:
5294            state.xupdated = false;
5295        lbl_17:
5296           
5297            //
5298            // Check stopping criteria
5299            // 1. achieved required number of iterations;
5300            // 2. ||Rk||<=EpsB*||B||;
5301            // 3. ||A^T*Rk||/(||A||*||Rk||)<=EpsA;
5302            //
5303            if( state.maxits>0 && state.repiterationscount>=state.maxits )
5304            {
5305               
5306                //
5307                // Achieved required number of iterations
5308                //
5309                state.running = false;
5310                state.repterminationtype = 5;
5311                result = false;
5312                return result;
5313            }
5314            if( (double)(state.phibarip1)<=(double)(state.epsb*bnorm) )
5315            {
5316               
5317                //
5318                // ||Rk||<=EpsB*||B||, here ||Rk||=PhiBar
5319                //
5320                state.running = false;
5321                state.repterminationtype = 1;
5322                result = false;
5323                return result;
5324            }
5325            if( (double)(state.alphaip1*Math.Abs(state.ci)/state.anorm)<=(double)(state.epsa) )
5326            {
5327               
5328                //
5329                // ||A^T*Rk||/(||A||*||Rk||)<=EpsA, here ||A^T*Rk||=PhiBar*Alpha[i+1]*|.C|
5330                //
5331                state.running = false;
5332                state.repterminationtype = 4;
5333                result = false;
5334                return result;
5335            }
5336           
5337            //
5338            // Update omega
5339            //
5340            for(i=0; i<=state.n-1; i++)
5341            {
5342                state.omegaip1[i] = state.vip1[i]-state.theta/state.rhoi*state.omegai[i];
5343            }
5344           
5345            //
5346            // Prepare for the next iteration - rename variables:
5347            // u[i]   := u[i+1]
5348            // v[i]   := v[i+1]
5349            // rho[i] := rho[i+1]
5350            // ...
5351            //
5352            for(i_=0; i_<=summn-1;i_++)
5353            {
5354                state.ui[i_] = state.uip1[i_];
5355            }
5356            for(i_=0; i_<=state.n-1;i_++)
5357            {
5358                state.vi[i_] = state.vip1[i_];
5359            }
5360            for(i_=0; i_<=state.n-1;i_++)
5361            {
5362                state.omegai[i_] = state.omegaip1[i_];
5363            }
5364            state.alphai = state.alphaip1;
5365            state.betai = state.betaip1;
5366            state.phibari = state.phibarip1;
5367            state.rhobari = state.rhobarip1;
5368            goto lbl_15;
5369        lbl_16:
5370            result = false;
5371            return result;
5372           
5373            //
5374            // Saving state
5375            //
5376        lbl_rcomm:
5377            result = true;
5378            state.rstate.ia[0] = summn;
5379            state.rstate.ia[1] = i;
5380            state.rstate.ra[0] = bnorm;
5381            return result;
5382        }
5383
5384
5385        /*************************************************************************
5386        Procedure for solution of A*x=b with sparse A.
5387
5388        INPUT PARAMETERS:
5389            State   -   algorithm state
5390            A       -   sparse M*N matrix in the CRS format (you MUST contvert  it
5391                        to CRS format  by  calling  SparseConvertToCRS()  function
5392                        BEFORE you pass it to this function).
5393            B       -   right part, array[M]
5394
5395        RESULT:
5396            This function returns no result.
5397            You can get solution by calling LinCGResults()
5398
5399          -- ALGLIB --
5400             Copyright 30.11.2011 by Bochkanov Sergey
5401        *************************************************************************/
5402        public static void linlsqrsolvesparse(linlsqrstate state,
5403            sparse.sparsematrix a,
5404            double[] b)
5405        {
5406            alglib.ap.assert(!state.running, "LinLSQRSolveSparse: you can not call this function when LinLSQRIteration is running");
5407            alglib.ap.assert(alglib.ap.len(b)>=state.m, "LinLSQRSolveSparse: Length(B)<M");
5408            alglib.ap.assert(apserv.isfinitevector(b, state.m), "LinLSQRSolveSparse: B contains infinite or NaN values");
5409            linlsqrsetb(state, b);
5410            linlsqrrestart(state);
5411            while( linlsqriteration(state) )
5412            {
5413                if( state.needmv )
5414                {
5415                    sparse.sparsemv(a, state.x, ref state.mv);
5416                }
5417                if( state.needmtv )
5418                {
5419                    sparse.sparsemtv(a, state.x, ref state.mtv);
5420                }
5421            }
5422        }
5423
5424
5425        /*************************************************************************
5426        This function sets stopping criteria.
5427
5428        INPUT PARAMETERS:
5429            EpsA    -   algorithm will be stopped if ||A^T*Rk||/(||A||*||Rk||)<=EpsA.
5430            EpsB    -   algorithm will be stopped if ||Rk||<=EpsB*||B||
5431            MaxIts  -   algorithm will be stopped if number of iterations
5432                        more than MaxIts.
5433
5434        OUTPUT PARAMETERS:
5435            State   -   structure which stores algorithm state
5436
5437        NOTE: if EpsA,EpsB,EpsC and MaxIts are zero then these variables will
5438        be setted as default values.
5439           
5440          -- ALGLIB --
5441             Copyright 30.11.2011 by Bochkanov Sergey
5442        *************************************************************************/
5443        public static void linlsqrsetcond(linlsqrstate state,
5444            double epsa,
5445            double epsb,
5446            int maxits)
5447        {
5448            alglib.ap.assert(!state.running, "LinLSQRSetCond: you can not call this function when LinLSQRIteration is running");
5449            alglib.ap.assert(math.isfinite(epsa) && (double)(epsa)>=(double)(0), "LinLSQRSetCond: EpsA is negative, INF or NAN");
5450            alglib.ap.assert(math.isfinite(epsb) && (double)(epsb)>=(double)(0), "LinLSQRSetCond: EpsB is negative, INF or NAN");
5451            alglib.ap.assert(maxits>=0, "LinLSQRSetCond: MaxIts is negative");
5452            if( ((double)(epsa)==(double)(0) && (double)(epsb)==(double)(0)) && maxits==0 )
5453            {
5454                state.epsa = atol;
5455                state.epsb = btol;
5456                state.maxits = state.n;
5457            }
5458            else
5459            {
5460                state.epsa = epsa;
5461                state.epsb = epsb;
5462                state.maxits = maxits;
5463            }
5464        }
5465
5466
5467        /*************************************************************************
5468        LSQR solver: results.
5469
5470        This function must be called after LinLSQRSolve
5471
5472        INPUT PARAMETERS:
5473            State   -   algorithm state
5474
5475        OUTPUT PARAMETERS:
5476            X       -   array[N], solution
5477            Rep     -   optimization report:
5478                        * Rep.TerminationType completetion code:
5479                            *  1    ||Rk||<=EpsB*||B||
5480                            *  4    ||A^T*Rk||/(||A||*||Rk||)<=EpsA
5481                            *  5    MaxIts steps was taken
5482                            *  7    rounding errors prevent further progress,
5483                                    X contains best point found so far.
5484                                    (sometimes returned on singular systems)
5485                        * Rep.IterationsCount contains iterations count
5486                        * NMV countains number of matrix-vector calculations
5487                       
5488          -- ALGLIB --
5489             Copyright 30.11.2011 by Bochkanov Sergey
5490        *************************************************************************/
5491        public static void linlsqrresults(linlsqrstate state,
5492            ref double[] x,
5493            linlsqrreport rep)
5494        {
5495            int i_ = 0;
5496
5497            x = new double[0];
5498
5499            alglib.ap.assert(!state.running, "LinLSQRResult: you can not call this function when LinLSQRIteration is running");
5500            if( alglib.ap.len(x)<state.n )
5501            {
5502                x = new double[state.n];
5503            }
5504            for(i_=0; i_<=state.n-1;i_++)
5505            {
5506                x[i_] = state.rx[i_];
5507            }
5508            rep.iterationscount = state.repiterationscount;
5509            rep.nmv = state.repnmv;
5510            rep.terminationtype = state.repterminationtype;
5511        }
5512
5513
5514        /*************************************************************************
5515        This function turns on/off reporting.
5516
5517        INPUT PARAMETERS:
5518            State   -   structure which stores algorithm state
5519            NeedXRep-   whether iteration reports are needed or not
5520
5521        If NeedXRep is True, algorithm will call rep() callback function if  it is
5522        provided to MinCGOptimize().
5523
5524          -- ALGLIB --
5525             Copyright 30.11.2011 by Bochkanov Sergey
5526        *************************************************************************/
5527        public static void linlsqrsetxrep(linlsqrstate state,
5528            bool needxrep)
5529        {
5530            state.xrep = needxrep;
5531        }
5532
5533
5534        /*************************************************************************
5535        This function restarts LinLSQRIteration
5536
5537          -- ALGLIB --
5538             Copyright 30.11.2011 by Bochkanov Sergey
5539        *************************************************************************/
5540        public static void linlsqrrestart(linlsqrstate state)
5541        {
5542            state.rstate.ia = new int[1+1];
5543            state.rstate.ra = new double[0+1];
5544            state.rstate.stage = -1;
5545            clearrfields(state);
5546        }
5547
5548
5549        /*************************************************************************
5550        Clears request fileds (to be sure that we don't forgot to clear something)
5551        *************************************************************************/
5552        private static void clearrfields(linlsqrstate state)
5553        {
5554            state.xupdated = false;
5555            state.needmv = false;
5556            state.needmtv = false;
5557            state.needmv2 = false;
5558            state.needvmv = false;
5559            state.needprec = false;
5560        }
5561
5562
5563    }
5564    public class lincg
5565    {
5566        /*************************************************************************
5567        This object stores state of the linear CG method.
5568
5569        You should use ALGLIB functions to work with this object.
5570        Never try to access its fields directly!
5571        *************************************************************************/
5572        public class lincgstate
5573        {
5574            public double[] rx;
5575            public double[] b;
5576            public int n;
5577            public double[] cx;
5578            public double[] cr;
5579            public double[] cz;
5580            public double[] p;
5581            public double[] r;
5582            public double[] z;
5583            public double alpha;
5584            public double beta;
5585            public double r2;
5586            public double meritfunction;
5587            public double[] x;
5588            public double[] mv;
5589            public double[] pv;
5590            public double vmv;
5591            public double[] startx;
5592            public double epsf;
5593            public int maxits;
5594            public int itsbeforerestart;
5595            public int itsbeforerupdate;
5596            public bool xrep;
5597            public bool xupdated;
5598            public bool needmv;
5599            public bool needmtv;
5600            public bool needmv2;
5601            public bool needvmv;
5602            public bool needprec;
5603            public int repiterationscount;
5604            public int repnmv;
5605            public int repterminationtype;
5606            public bool running;
5607            public rcommstate rstate;
5608            public lincgstate()
5609            {
5610                rx = new double[0];
5611                b = new double[0];
5612                cx = new double[0];
5613                cr = new double[0];
5614                cz = new double[0];
5615                p = new double[0];
5616                r = new double[0];
5617                z = new double[0];
5618                x = new double[0];
5619                mv = new double[0];
5620                pv = new double[0];
5621                startx = new double[0];
5622                rstate = new rcommstate();
5623            }
5624        };
5625
5626
5627        public class lincgreport
5628        {
5629            public int iterationscount;
5630            public int nmv;
5631            public int terminationtype;
5632            public double r2;
5633        };
5634
5635
5636
5637
5638        public const double defaultprecision = 1.0E-6;
5639
5640
5641        /*************************************************************************
5642        This function initializes linear CG Solver. This solver is used  to  solve
5643        symmetric positive definite problems. If you want  to  solve  nonsymmetric
5644        (or non-positive definite) problem you may use LinLSQR solver provided  by
5645        ALGLIB.
5646
5647        USAGE:
5648        1. User initializes algorithm state with LinCGCreate() call
5649        2. User tunes solver parameters with  LinCGSetCond() and other functions
5650        3. Optionally, user sets starting point with LinCGSetStartingPoint()
5651        4. User  calls LinCGSolveSparse() function which takes algorithm state and
5652           SparseMatrix object.
5653        5. User calls LinCGResults() to get solution
5654        6. Optionally, user may call LinCGSolveSparse()  again  to  solve  another
5655           problem  with different matrix and/or right part without reinitializing
5656           LinCGState structure.
5657         
5658        INPUT PARAMETERS:
5659            N       -   problem dimension, N>0
5660
5661        OUTPUT PARAMETERS:
5662            State   -   structure which stores algorithm state
5663
5664          -- ALGLIB --
5665             Copyright 14.11.2011 by Bochkanov Sergey
5666        *************************************************************************/
5667        public static void lincgcreate(int n,
5668            lincgstate state)
5669        {
5670            int i = 0;
5671
5672            alglib.ap.assert(n>0, "LinCGCreate: N<=0");
5673            state.n = n;
5674            state.itsbeforerestart = n;
5675            state.itsbeforerupdate = 10;
5676            state.epsf = defaultprecision;
5677            state.maxits = 0;
5678            state.xrep = false;
5679            state.running = false;
5680           
5681            //
5682            // * allocate arrays
5683            // * set RX to NAN (just for the case user calls Results() without
5684            //   calling SolveSparse()
5685            // * set starting point to zero
5686            // * we do NOT initialize B here because we assume that user should
5687            //   initializate it using LinCGSetB() function. In case he forgets
5688            //   to do so, exception will be thrown in the LinCGIteration().
5689            //
5690            state.rx = new double[state.n];
5691            state.startx = new double[state.n];
5692            state.b = new double[state.n];
5693            for(i=0; i<=state.n-1; i++)
5694            {
5695                state.rx[i] = Double.NaN;
5696                state.startx[i] = 0.0;
5697                state.b[i] = 0;
5698            }
5699            state.cx = new double[state.n];
5700            state.p = new double[state.n];
5701            state.r = new double[state.n];
5702            state.cr = new double[state.n];
5703            state.z = new double[state.n];
5704            state.cz = new double[state.n];
5705            state.x = new double[state.n];
5706            state.mv = new double[state.n];
5707            state.pv = new double[state.n];
5708            updateitersdata(state);
5709            state.rstate.ia = new int[0+1];
5710            state.rstate.ra = new double[2+1];
5711            state.rstate.stage = -1;
5712        }
5713
5714
5715        /*************************************************************************
5716        This function sets starting point.
5717        By default, zero starting point is used.
5718
5719        INPUT PARAMETERS:
5720            X       -   starting point, array[N]
5721
5722        OUTPUT PARAMETERS:
5723            State   -   structure which stores algorithm state
5724
5725          -- ALGLIB --
5726             Copyright 14.11.2011 by Bochkanov Sergey
5727        *************************************************************************/
5728        public static void lincgsetstartingpoint(lincgstate state,
5729            double[] x)
5730        {
5731            int i_ = 0;
5732
5733            alglib.ap.assert(!state.running, "LinCGSetStartingPoint: you can not change starting point because LinCGIteration() function is running");
5734            alglib.ap.assert(state.n<=alglib.ap.len(x), "LinCGSetStartingPoint: Length(X)<N");
5735            alglib.ap.assert(apserv.isfinitevector(x, state.n), "LinCGSetStartingPoint: X contains infinite or NaN values!");
5736            for(i_=0; i_<=state.n-1;i_++)
5737            {
5738                state.startx[i_] = x[i_];
5739            }
5740        }
5741
5742
5743        /*************************************************************************
5744        This function sets right part. By default, right part is zero.
5745
5746        INPUT PARAMETERS:
5747            B       -   right part, array[N].
5748
5749        OUTPUT PARAMETERS:
5750            State   -   structure which stores algorithm state
5751
5752          -- ALGLIB --
5753             Copyright 14.11.2011 by Bochkanov Sergey
5754        *************************************************************************/
5755        public static void lincgsetb(lincgstate state,
5756            double[] b)
5757        {
5758            int i_ = 0;
5759
5760            alglib.ap.assert(!state.running, "LinCGSetB: you can not set B, because function LinCGIteration is running!");
5761            alglib.ap.assert(alglib.ap.len(b)>=state.n, "LinCGSetB: Length(B)<N");
5762            alglib.ap.assert(apserv.isfinitevector(b, state.n), "LinCGSetB: B contains infinite or NaN values!");
5763            for(i_=0; i_<=state.n-1;i_++)
5764            {
5765                state.b[i_] = b[i_];
5766            }
5767        }
5768
5769
5770        /*************************************************************************
5771        This function sets stopping criteria.
5772
5773        INPUT PARAMETERS:
5774            EpsF    -   algorithm will be stopped if norm of residual is less than
5775                        EpsF*||b||.
5776            MaxIts  -   algorithm will be stopped if number of iterations is  more
5777                        than MaxIts.
5778
5779        OUTPUT PARAMETERS:
5780            State   -   structure which stores algorithm state
5781
5782        NOTES:
5783        If  both  EpsF  and  MaxIts  are  zero then small EpsF will be set to small
5784        value.
5785
5786          -- ALGLIB --
5787             Copyright 14.11.2011 by Bochkanov Sergey
5788        *************************************************************************/
5789        public static void lincgsetcond(lincgstate state,
5790            double epsf,
5791            int maxits)
5792        {
5793            alglib.ap.assert(!state.running, "LinCGSetCond: you can not change stopping criteria when LinCGIteration() is running");
5794            alglib.ap.assert(math.isfinite(epsf) && (double)(epsf)>=(double)(0), "LinCGSetCond: EpsF is negative or contains infinite or NaN values");
5795            alglib.ap.assert(maxits>=0, "LinCGSetCond: MaxIts is negative");
5796            if( (double)(epsf)==(double)(0) && maxits==0 )
5797            {
5798                state.epsf = defaultprecision;
5799                state.maxits = maxits;
5800            }
5801            else
5802            {
5803                state.epsf = epsf;
5804                state.maxits = maxits;
5805            }
5806        }
5807
5808
5809        /*************************************************************************
5810        Reverse communication version of linear CG.
5811
5812          -- ALGLIB --
5813             Copyright 14.11.2011 by Bochkanov Sergey
5814        *************************************************************************/
5815        public static bool lincgiteration(lincgstate state)
5816        {
5817            bool result = new bool();
5818            int i = 0;
5819            double uvar = 0;
5820            double bnorm = 0;
5821            double v = 0;
5822            int i_ = 0;
5823
5824           
5825            //
5826            // Reverse communication preparations
5827            // I know it looks ugly, but it works the same way
5828            // anywhere from C++ to Python.
5829            //
5830            // This code initializes locals by:
5831            // * random values determined during code
5832            //   generation - on first subroutine call
5833            // * values from previous call - on subsequent calls
5834            //
5835            if( state.rstate.stage>=0 )
5836            {
5837                i = state.rstate.ia[0];
5838                uvar = state.rstate.ra[0];
5839                bnorm = state.rstate.ra[1];
5840                v = state.rstate.ra[2];
5841            }
5842            else
5843            {
5844                i = -983;
5845                uvar = -989;
5846                bnorm = -834;
5847                v = 900;
5848            }
5849            if( state.rstate.stage==0 )
5850            {
5851                goto lbl_0;
5852            }
5853            if( state.rstate.stage==1 )
5854            {
5855                goto lbl_1;
5856            }
5857            if( state.rstate.stage==2 )
5858            {
5859                goto lbl_2;
5860            }
5861            if( state.rstate.stage==3 )
5862            {
5863                goto lbl_3;
5864            }
5865            if( state.rstate.stage==4 )
5866            {
5867                goto lbl_4;
5868            }
5869            if( state.rstate.stage==5 )
5870            {
5871                goto lbl_5;
5872            }
5873            if( state.rstate.stage==6 )
5874            {
5875                goto lbl_6;
5876            }
5877            if( state.rstate.stage==7 )
5878            {
5879                goto lbl_7;
5880            }
5881           
5882            //
5883            // Routine body
5884            //
5885            alglib.ap.assert(alglib.ap.len(state.b)>0, "LinCGIteration: B is not initialized (you must initialize B by LinCGSetB() call");
5886            state.running = true;
5887            state.repnmv = 0;
5888            clearrfields(state);
5889            updateitersdata(state);
5890           
5891            //
5892            // Start 0-th iteration
5893            //
5894            for(i_=0; i_<=state.n-1;i_++)
5895            {
5896                state.rx[i_] = state.startx[i_];
5897            }
5898            for(i_=0; i_<=state.n-1;i_++)
5899            {
5900                state.x[i_] = state.rx[i_];
5901            }
5902            state.repnmv = state.repnmv+1;
5903            clearrfields(state);
5904            state.needvmv = true;
5905            state.rstate.stage = 0;
5906            goto lbl_rcomm;
5907        lbl_0:
5908            state.needvmv = false;
5909            bnorm = 0;
5910            state.r2 = 0;
5911            state.meritfunction = 0;
5912            for(i=0; i<=state.n-1; i++)
5913            {
5914                state.r[i] = state.b[i]-state.mv[i];
5915                state.r2 = state.r2+state.r[i]*state.r[i];
5916                state.meritfunction = state.meritfunction+state.mv[i]*state.rx[i]-2*state.b[i]*state.rx[i];
5917                bnorm = bnorm+state.b[i]*state.b[i];
5918            }
5919            bnorm = Math.Sqrt(bnorm);
5920           
5921            //
5922            // Output first report
5923            //
5924            if( !state.xrep )
5925            {
5926                goto lbl_8;
5927            }
5928            for(i_=0; i_<=state.n-1;i_++)
5929            {
5930                state.x[i_] = state.rx[i_];
5931            }
5932            clearrfields(state);
5933            state.xupdated = true;
5934            state.rstate.stage = 1;
5935            goto lbl_rcomm;
5936        lbl_1:
5937            state.xupdated = false;
5938        lbl_8:
5939           
5940            //
5941            // Is x0 a solution?
5942            //
5943            if( !math.isfinite(state.r2) || (double)(Math.Sqrt(state.r2))<=(double)(state.epsf*bnorm) )
5944            {
5945                state.running = false;
5946                if( math.isfinite(state.r2) )
5947                {
5948                    state.repterminationtype = 1;
5949                }
5950                else
5951                {
5952                    state.repterminationtype = -4;
5953                }
5954                result = false;
5955                return result;
5956            }
5957           
5958            //
5959            // Calculate Z and P
5960            //
5961            for(i_=0; i_<=state.n-1;i_++)
5962            {
5963                state.x[i_] = state.r[i_];
5964            }
5965            state.repnmv = state.repnmv+1;
5966            clearrfields(state);
5967            state.needprec = true;
5968            state.rstate.stage = 2;
5969            goto lbl_rcomm;
5970        lbl_2:
5971            state.needprec = false;
5972            for(i=0; i<=state.n-1; i++)
5973            {
5974                state.z[i] = state.pv[i];
5975                state.p[i] = state.z[i];
5976            }
5977           
5978            //
5979            // Other iterations(1..N)
5980            //
5981            state.repiterationscount = 0;
5982        lbl_10:
5983            if( false )
5984            {
5985                goto lbl_11;
5986            }
5987            state.repiterationscount = state.repiterationscount+1;
5988           
5989            //
5990            // Calculate Alpha
5991            //
5992            for(i_=0; i_<=state.n-1;i_++)
5993            {
5994                state.x[i_] = state.p[i_];
5995            }
5996            state.repnmv = state.repnmv+1;
5997            clearrfields(state);
5998            state.needvmv = true;
5999            state.rstate.stage = 3;
6000            goto lbl_rcomm;
6001        lbl_3:
6002            state.needvmv = false;
6003            if( !math.isfinite(state.vmv) || (double)(state.vmv)<=(double)(0) )
6004            {
6005               
6006                //
6007                // a) Overflow when calculating VMV
6008                // b) non-positive VMV (non-SPD matrix)
6009                //
6010                state.running = false;
6011                if( math.isfinite(state.vmv) )
6012                {
6013                    state.repterminationtype = -5;
6014                }
6015                else
6016                {
6017                    state.repterminationtype = -4;
6018                }
6019                result = false;
6020                return result;
6021            }
6022            state.alpha = 0;
6023            for(i=0; i<=state.n-1; i++)
6024            {
6025                state.alpha = state.alpha+state.r[i]*state.z[i];
6026            }
6027            state.alpha = state.alpha/state.vmv;
6028            if( !math.isfinite(state.alpha) )
6029            {
6030               
6031                //
6032                // Overflow when calculating Alpha
6033                //
6034                state.running = false;
6035                state.repterminationtype = -4;
6036                result = false;
6037                return result;
6038            }
6039           
6040            //
6041            // Next step toward solution
6042            //
6043            for(i=0; i<=state.n-1; i++)
6044            {
6045                state.cx[i] = state.rx[i]+state.alpha*state.p[i];
6046            }
6047           
6048            //
6049            // Calculate R:
6050            // * use recurrent relation to update R
6051            // * at every ItsBeforeRUpdate-th iteration recalculate it from scratch, using matrix-vector product
6052            //   in case R grows instead of decreasing, algorithm is terminated with positive completion code
6053            //
6054            if( !(state.itsbeforerupdate==0 || state.repiterationscount%state.itsbeforerupdate!=0) )
6055            {
6056                goto lbl_12;
6057            }
6058           
6059            //
6060            // Calculate R using recurrent formula
6061            //
6062            for(i=0; i<=state.n-1; i++)
6063            {
6064                state.cr[i] = state.r[i]-state.alpha*state.mv[i];
6065                state.x[i] = state.cr[i];
6066            }
6067            goto lbl_13;
6068        lbl_12:
6069           
6070            //
6071            // Calculate R using matrix-vector multiplication
6072            //
6073            for(i_=0; i_<=state.n-1;i_++)
6074            {
6075                state.x[i_] = state.cx[i_];
6076            }
6077            state.repnmv = state.repnmv+1;
6078            clearrfields(state);
6079            state.needmv = true;
6080            state.rstate.stage = 4;
6081            goto lbl_rcomm;
6082        lbl_4:
6083            state.needmv = false;
6084            for(i=0; i<=state.n-1; i++)
6085            {
6086                state.cr[i] = state.b[i]-state.mv[i];
6087                state.x[i] = state.cr[i];
6088            }
6089           
6090            //
6091            // Calculating merit function
6092            // Check emergency stopping criterion
6093            //
6094            v = 0;
6095            for(i=0; i<=state.n-1; i++)
6096            {
6097                v = v+state.mv[i]*state.cx[i]-2*state.b[i]*state.cx[i];
6098            }
6099            if( (double)(v)<(double)(state.meritfunction) )
6100            {
6101                goto lbl_14;
6102            }
6103            for(i=0; i<=state.n-1; i++)
6104            {
6105                if( !math.isfinite(state.rx[i]) )
6106                {
6107                    state.running = false;
6108                    state.repterminationtype = -4;
6109                    result = false;
6110                    return result;
6111                }
6112            }
6113           
6114            //
6115            //output last report
6116            //
6117            if( !state.xrep )
6118            {
6119                goto lbl_16;
6120            }
6121            for(i_=0; i_<=state.n-1;i_++)
6122            {
6123                state.x[i_] = state.rx[i_];
6124            }
6125            clearrfields(state);
6126            state.xupdated = true;
6127            state.rstate.stage = 5;
6128            goto lbl_rcomm;
6129        lbl_5:
6130            state.xupdated = false;
6131        lbl_16:
6132            state.running = false;
6133            state.repterminationtype = 7;
6134            result = false;
6135            return result;
6136        lbl_14:
6137            state.meritfunction = v;
6138        lbl_13:
6139            for(i_=0; i_<=state.n-1;i_++)
6140            {
6141                state.rx[i_] = state.cx[i_];
6142            }
6143           
6144            //
6145            // calculating RNorm
6146            //
6147            // NOTE: monotonic decrease of R2 is not guaranteed by algorithm.
6148            //
6149            state.r2 = 0;
6150            for(i=0; i<=state.n-1; i++)
6151            {
6152                state.r2 = state.r2+state.cr[i]*state.cr[i];
6153            }
6154           
6155            //
6156            //output report
6157            //
6158            if( !state.xrep )
6159            {
6160                goto lbl_18;
6161            }
6162            for(i_=0; i_<=state.n-1;i_++)
6163            {
6164                state.x[i_] = state.rx[i_];
6165            }
6166            clearrfields(state);
6167            state.xupdated = true;
6168            state.rstate.stage = 6;
6169            goto lbl_rcomm;
6170        lbl_6:
6171            state.xupdated = false;
6172        lbl_18:
6173           
6174            //
6175            //stopping criterion
6176            //achieved the required precision
6177            //
6178            if( !math.isfinite(state.r2) || (double)(Math.Sqrt(state.r2))<=(double)(state.epsf*bnorm) )
6179            {
6180                state.running = false;
6181                if( math.isfinite(state.r2) )
6182                {
6183                    state.repterminationtype = 1;
6184                }
6185                else
6186                {
6187                    state.repterminationtype = -4;
6188                }
6189                result = false;
6190                return result;
6191            }
6192            if( state.repiterationscount>=state.maxits && state.maxits>0 )
6193            {
6194                for(i=0; i<=state.n-1; i++)
6195                {
6196                    if( !math.isfinite(state.rx[i]) )
6197                    {
6198                        state.running = false;
6199                        state.repterminationtype = -4;
6200                        result = false;
6201                        return result;
6202                    }
6203                }
6204               
6205                //
6206                //if X is finite number
6207                //
6208                state.running = false;
6209                state.repterminationtype = 5;
6210                result = false;
6211                return result;
6212            }
6213            for(i_=0; i_<=state.n-1;i_++)
6214            {
6215                state.x[i_] = state.cr[i_];
6216            }
6217           
6218            //
6219            //prepere of parameters for next iteration
6220            //
6221            state.repnmv = state.repnmv+1;
6222            clearrfields(state);
6223            state.needprec = true;
6224            state.rstate.stage = 7;
6225            goto lbl_rcomm;
6226        lbl_7:
6227            state.needprec = false;
6228            for(i_=0; i_<=state.n-1;i_++)
6229            {
6230                state.cz[i_] = state.pv[i_];
6231            }
6232            if( state.repiterationscount%state.itsbeforerestart!=0 )
6233            {
6234                state.beta = 0;
6235                uvar = 0;
6236                for(i=0; i<=state.n-1; i++)
6237                {
6238                    state.beta = state.beta+state.cz[i]*state.cr[i];
6239                    uvar = uvar+state.z[i]*state.r[i];
6240                }
6241               
6242                //
6243                //check that UVar is't INF or is't zero
6244                //
6245                if( !math.isfinite(uvar) || (double)(uvar)==(double)(0) )
6246                {
6247                    state.running = false;
6248                    state.repterminationtype = -4;
6249                    result = false;
6250                    return result;
6251                }
6252               
6253                //
6254                //calculate .BETA
6255                //
6256                state.beta = state.beta/uvar;
6257               
6258                //
6259                //check that .BETA neither INF nor NaN
6260                //
6261                if( !math.isfinite(state.beta) )
6262                {
6263                    state.running = false;
6264                    state.repterminationtype = -1;
6265                    result = false;
6266                    return result;
6267                }
6268                for(i=0; i<=state.n-1; i++)
6269                {
6270                    state.p[i] = state.cz[i]+state.beta*state.p[i];
6271                }
6272            }
6273            else
6274            {
6275                for(i_=0; i_<=state.n-1;i_++)
6276                {
6277                    state.p[i_] = state.cz[i_];
6278                }
6279            }
6280           
6281            //
6282            //prepere data for next iteration
6283            //
6284            for(i=0; i<=state.n-1; i++)
6285            {
6286               
6287                //
6288                //write (k+1)th iteration to (k )th iteration
6289                //
6290                state.r[i] = state.cr[i];
6291                state.z[i] = state.cz[i];
6292            }
6293            goto lbl_10;
6294        lbl_11:
6295            result = false;
6296            return result;
6297           
6298            //
6299            // Saving state
6300            //
6301        lbl_rcomm:
6302            result = true;
6303            state.rstate.ia[0] = i;
6304            state.rstate.ra[0] = uvar;
6305            state.rstate.ra[1] = bnorm;
6306            state.rstate.ra[2] = v;
6307            return result;
6308        }
6309
6310
6311        /*************************************************************************
6312        Procedure for solution of A*x=b with sparse A.
6313
6314        INPUT PARAMETERS:
6315            State   -   algorithm state
6316            A       -   sparse matrix in the CRS format (you MUST contvert  it  to
6317                        CRS format by calling SparseConvertToCRS() function).
6318            IsUpper -   whether upper or lower triangle of A is used:
6319                        * IsUpper=True  => only upper triangle is used and lower
6320                                           triangle is not referenced at all
6321                        * IsUpper=False => only lower triangle is used and upper
6322                                           triangle is not referenced at all
6323            B       -   right part, array[N]
6324
6325        RESULT:
6326            This function returns no result.
6327            You can get solution by calling LinCGResults()
6328
6329          -- ALGLIB --
6330             Copyright 14.11.2011 by Bochkanov Sergey
6331        *************************************************************************/
6332        public static void lincgsolvesparse(lincgstate state,
6333            sparse.sparsematrix a,
6334            bool isupper,
6335            double[] b)
6336        {
6337            double vmv = 0;
6338            int i_ = 0;
6339
6340            alglib.ap.assert(alglib.ap.len(b)>=state.n, "LinCGSetB: Length(B)<N");
6341            alglib.ap.assert(apserv.isfinitevector(b, state.n), "LinCGSetB: B contains infinite or NaN values!");
6342            lincgrestart(state);
6343            lincgsetb(state, b);
6344            while( lincgiteration(state) )
6345            {
6346                if( state.needmv )
6347                {
6348                    sparse.sparsesmv(a, isupper, state.x, ref state.mv);
6349                }
6350                if( state.needvmv )
6351                {
6352                    sparse.sparsesmv(a, isupper, state.x, ref state.mv);
6353                    vmv = 0.0;
6354                    for(i_=0; i_<=state.n-1;i_++)
6355                    {
6356                        vmv += state.x[i_]*state.mv[i_];
6357                    }
6358                    state.vmv = vmv;
6359                }
6360                if( state.needprec )
6361                {
6362                    for(i_=0; i_<=state.n-1;i_++)
6363                    {
6364                        state.pv[i_] = state.x[i_];
6365                    }
6366                }
6367            }
6368        }
6369
6370
6371        /*************************************************************************
6372        CG-solver: results.
6373
6374        This function must be called after LinCGSolve
6375
6376        INPUT PARAMETERS:
6377            State   -   algorithm state
6378
6379        OUTPUT PARAMETERS:
6380            X       -   array[N], solution
6381            Rep     -   optimization report:
6382                        * Rep.TerminationType completetion code:
6383                            * -5    input matrix is either not positive definite,
6384                                    too large or too small                           
6385                            * -4    overflow/underflow during solution
6386                                    (ill conditioned problem)
6387                            *  1    ||residual||<=EpsF*||b||
6388                            *  5    MaxIts steps was taken
6389                            *  7    rounding errors prevent further progress,
6390                                    best point found is returned
6391                        * Rep.IterationsCount contains iterations count
6392                        * NMV countains number of matrix-vector calculations
6393
6394          -- ALGLIB --
6395             Copyright 14.11.2011 by Bochkanov Sergey
6396        *************************************************************************/
6397        public static void lincgresults(lincgstate state,
6398            ref double[] x,
6399            lincgreport rep)
6400        {
6401            int i_ = 0;
6402
6403            x = new double[0];
6404
6405            alglib.ap.assert(!state.running, "LinCGResult: you can not get result, because function LinCGIteration has been launched!");
6406            if( alglib.ap.len(x)<state.n )
6407            {
6408                x = new double[state.n];
6409            }
6410            for(i_=0; i_<=state.n-1;i_++)
6411            {
6412                x[i_] = state.rx[i_];
6413            }
6414            rep.iterationscount = state.repiterationscount;
6415            rep.nmv = state.repnmv;
6416            rep.terminationtype = state.repterminationtype;
6417            rep.r2 = state.r2;
6418        }
6419
6420
6421        /*************************************************************************
6422        This function sets restart frequency. By default, algorithm  is  restarted
6423        after N subsequent iterations.
6424
6425          -- ALGLIB --
6426             Copyright 14.11.2011 by Bochkanov Sergey
6427        *************************************************************************/
6428        public static void lincgsetrestartfreq(lincgstate state,
6429            int srf)
6430        {
6431            alglib.ap.assert(!state.running, "LinCGSetRestartFreq: you can not change restart frequency when LinCGIteration() is running");
6432            alglib.ap.assert(srf>0, "LinCGSetRestartFreq: non-positive SRF");
6433            state.itsbeforerestart = srf;
6434        }
6435
6436
6437        /*************************************************************************
6438        This function sets frequency of residual recalculations.
6439
6440        Algorithm updates residual r_k using iterative formula,  but  recalculates
6441        it from scratch after each 10 iterations. It is done to avoid accumulation
6442        of numerical errors and to stop algorithm when r_k starts to grow.
6443
6444        Such low update frequence (1/10) gives very  little  overhead,  but  makes
6445        algorithm a bit more robust against numerical errors. However, you may
6446        change it
6447
6448        INPUT PARAMETERS:
6449            Freq    -   desired update frequency, Freq>=0.
6450                        Zero value means that no updates will be done.
6451
6452          -- ALGLIB --
6453             Copyright 14.11.2011 by Bochkanov Sergey
6454        *************************************************************************/
6455        public static void lincgsetrupdatefreq(lincgstate state,
6456            int freq)
6457        {
6458            alglib.ap.assert(!state.running, "LinCGSetRUpdateFreq: you can not change update frequency when LinCGIteration() is running");
6459            alglib.ap.assert(freq>=0, "LinCGSetRUpdateFreq: non-positive Freq");
6460            state.itsbeforerupdate = freq;
6461        }
6462
6463
6464        /*************************************************************************
6465        This function turns on/off reporting.
6466
6467        INPUT PARAMETERS:
6468            State   -   structure which stores algorithm state
6469            NeedXRep-   whether iteration reports are needed or not
6470
6471        If NeedXRep is True, algorithm will call rep() callback function if  it is
6472        provided to MinCGOptimize().
6473
6474          -- ALGLIB --
6475             Copyright 14.11.2011 by Bochkanov Sergey
6476        *************************************************************************/
6477        public static void lincgsetxrep(lincgstate state,
6478            bool needxrep)
6479        {
6480            state.xrep = needxrep;
6481        }
6482
6483
6484        /*************************************************************************
6485        Procedure for restart function LinCGIteration
6486
6487          -- ALGLIB --
6488             Copyright 14.11.2011 by Bochkanov Sergey
6489        *************************************************************************/
6490        public static void lincgrestart(lincgstate state)
6491        {
6492            state.rstate.ia = new int[0+1];
6493            state.rstate.ra = new double[2+1];
6494            state.rstate.stage = -1;
6495            clearrfields(state);
6496        }
6497
6498
6499        /*************************************************************************
6500        Clears request fileds (to be sure that we don't forgot to clear something)
6501        *************************************************************************/
6502        private static void clearrfields(lincgstate state)
6503        {
6504            state.xupdated = false;
6505            state.needmv = false;
6506            state.needmtv = false;
6507            state.needmv2 = false;
6508            state.needvmv = false;
6509            state.needprec = false;
6510        }
6511
6512
6513        /*************************************************************************
6514        Clears request fileds (to be sure that we don't forgot to clear something)
6515        *************************************************************************/
6516        private static void updateitersdata(lincgstate state)
6517        {
6518            state.repiterationscount = 0;
6519            state.repnmv = 0;
6520            state.repterminationtype = 0;
6521        }
6522
6523
6524    }
6525    public class nleq
6526    {
6527        public class nleqstate
6528        {
6529            public int n;
6530            public int m;
6531            public double epsf;
6532            public int maxits;
6533            public bool xrep;
6534            public double stpmax;
6535            public double[] x;
6536            public double f;
6537            public double[] fi;
6538            public double[,] j;
6539            public bool needf;
6540            public bool needfij;
6541            public bool xupdated;
6542            public rcommstate rstate;
6543            public int repiterationscount;
6544            public int repnfunc;
6545            public int repnjac;
6546            public int repterminationtype;
6547            public double[] xbase;
6548            public double fbase;
6549            public double fprev;
6550            public double[] candstep;
6551            public double[] rightpart;
6552            public double[] cgbuf;
6553            public nleqstate()
6554            {
6555                x = new double[0];
6556                fi = new double[0];
6557                j = new double[0,0];
6558                rstate = new rcommstate();
6559                xbase = new double[0];
6560                candstep = new double[0];
6561                rightpart = new double[0];
6562                cgbuf = new double[0];
6563            }
6564        };
6565
6566
6567        public class nleqreport
6568        {
6569            public int iterationscount;
6570            public int nfunc;
6571            public int njac;
6572            public int terminationtype;
6573        };
6574
6575
6576
6577
6578        public const int armijomaxfev = 20;
6579
6580
6581        /*************************************************************************
6582                        LEVENBERG-MARQUARDT-LIKE NONLINEAR SOLVER
6583
6584        DESCRIPTION:
6585        This algorithm solves system of nonlinear equations
6586            F[0](x[0], ..., x[n-1])   = 0
6587            F[1](x[0], ..., x[n-1])   = 0
6588            ...
6589            F[M-1](x[0], ..., x[n-1]) = 0
6590        with M/N do not necessarily coincide.  Algorithm  converges  quadratically
6591        under following conditions:
6592            * the solution set XS is nonempty
6593            * for some xs in XS there exist such neighbourhood N(xs) that:
6594              * vector function F(x) and its Jacobian J(x) are continuously
6595                differentiable on N
6596              * ||F(x)|| provides local error bound on N, i.e. there  exists  such
6597                c1, that ||F(x)||>c1*distance(x,XS)
6598        Note that these conditions are much more weaker than usual non-singularity
6599        conditions. For example, algorithm will converge for any  affine  function
6600        F (whether its Jacobian singular or not).
6601
6602
6603        REQUIREMENTS:
6604        Algorithm will request following information during its operation:
6605        * function vector F[] and Jacobian matrix at given point X
6606        * value of merit function f(x)=F[0]^2(x)+...+F[M-1]^2(x) at given point X
6607
6608
6609        USAGE:
6610        1. User initializes algorithm state with NLEQCreateLM() call
6611        2. User tunes solver parameters with  NLEQSetCond(),  NLEQSetStpMax()  and
6612           other functions
6613        3. User  calls  NLEQSolve()  function  which  takes  algorithm  state  and
6614           pointers (delegates, etc.) to callback functions which calculate  merit
6615           function value and Jacobian.
6616        4. User calls NLEQResults() to get solution
6617        5. Optionally, user may call NLEQRestartFrom() to  solve  another  problem
6618           with same parameters (N/M) but another starting  point  and/or  another
6619           function vector. NLEQRestartFrom() allows to reuse already  initialized
6620           structure.
6621
6622
6623        INPUT PARAMETERS:
6624            N       -   space dimension, N>1:
6625                        * if provided, only leading N elements of X are used
6626                        * if not provided, determined automatically from size of X
6627            M       -   system size
6628            X       -   starting point
6629
6630
6631        OUTPUT PARAMETERS:
6632            State   -   structure which stores algorithm state
6633
6634
6635        NOTES:
6636        1. you may tune stopping conditions with NLEQSetCond() function
6637        2. if target function contains exp() or other fast growing functions,  and
6638           optimization algorithm makes too large steps which leads  to  overflow,
6639           use NLEQSetStpMax() function to bound algorithm's steps.
6640        3. this  algorithm  is  a  slightly  modified implementation of the method
6641           described  in  'Levenberg-Marquardt  method  for constrained  nonlinear
6642           equations with strong local convergence properties' by Christian Kanzow
6643           Nobuo Yamashita and Masao Fukushima and further  developed  in  'On the
6644           convergence of a New Levenberg-Marquardt Method'  by  Jin-yan  Fan  and
6645           Ya-Xiang Yuan.
6646
6647
6648          -- ALGLIB --
6649             Copyright 20.08.2009 by Bochkanov Sergey
6650        *************************************************************************/
6651        public static void nleqcreatelm(int n,
6652            int m,
6653            double[] x,
6654            nleqstate state)
6655        {
6656            alglib.ap.assert(n>=1, "NLEQCreateLM: N<1!");
6657            alglib.ap.assert(m>=1, "NLEQCreateLM: M<1!");
6658            alglib.ap.assert(alglib.ap.len(x)>=n, "NLEQCreateLM: Length(X)<N!");
6659            alglib.ap.assert(apserv.isfinitevector(x, n), "NLEQCreateLM: X contains infinite or NaN values!");
6660           
6661            //
6662            // Initialize
6663            //
6664            state.n = n;
6665            state.m = m;
6666            nleqsetcond(state, 0, 0);
6667            nleqsetxrep(state, false);
6668            nleqsetstpmax(state, 0);
6669            state.x = new double[n];
6670            state.xbase = new double[n];
6671            state.j = new double[m, n];
6672            state.fi = new double[m];
6673            state.rightpart = new double[n];
6674            state.candstep = new double[n];
6675            nleqrestartfrom(state, x);
6676        }
6677
6678
6679        /*************************************************************************
6680        This function sets stopping conditions for the nonlinear solver
6681
6682        INPUT PARAMETERS:
6683            State   -   structure which stores algorithm state
6684            EpsF    -   >=0
6685                        The subroutine finishes  its work if on k+1-th iteration
6686                        the condition ||F||<=EpsF is satisfied
6687            MaxIts  -   maximum number of iterations. If MaxIts=0, the  number  of
6688                        iterations is unlimited.
6689
6690        Passing EpsF=0 and MaxIts=0 simultaneously will lead to  automatic
6691        stopping criterion selection (small EpsF).
6692
6693        NOTES:
6694
6695          -- ALGLIB --
6696             Copyright 20.08.2010 by Bochkanov Sergey
6697        *************************************************************************/
6698        public static void nleqsetcond(nleqstate state,
6699            double epsf,
6700            int maxits)
6701        {
6702            alglib.ap.assert(math.isfinite(epsf), "NLEQSetCond: EpsF is not finite number!");
6703            alglib.ap.assert((double)(epsf)>=(double)(0), "NLEQSetCond: negative EpsF!");
6704            alglib.ap.assert(maxits>=0, "NLEQSetCond: negative MaxIts!");
6705            if( (double)(epsf)==(double)(0) && maxits==0 )
6706            {
6707                epsf = 1.0E-6;
6708            }
6709            state.epsf = epsf;
6710            state.maxits = maxits;
6711        }
6712
6713
6714        /*************************************************************************
6715        This function turns on/off reporting.
6716
6717        INPUT PARAMETERS:
6718            State   -   structure which stores algorithm state
6719            NeedXRep-   whether iteration reports are needed or not
6720
6721        If NeedXRep is True, algorithm will call rep() callback function if  it is
6722        provided to NLEQSolve().
6723
6724          -- ALGLIB --
6725             Copyright 20.08.2010 by Bochkanov Sergey
6726        *************************************************************************/
6727        public static void nleqsetxrep(nleqstate state,
6728            bool needxrep)
6729        {
6730            state.xrep = needxrep;
6731        }
6732
6733
6734        /*************************************************************************
6735        This function sets maximum step length
6736
6737        INPUT PARAMETERS:
6738            State   -   structure which stores algorithm state
6739            StpMax  -   maximum step length, >=0. Set StpMax to 0.0,  if you don't
6740                        want to limit step length.
6741
6742        Use this subroutine when target function  contains  exp()  or  other  fast
6743        growing functions, and algorithm makes  too  large  steps  which  lead  to
6744        overflow. This function allows us to reject steps that are too large  (and
6745        therefore expose us to the possible overflow) without actually calculating
6746        function value at the x+stp*d.
6747
6748          -- ALGLIB --
6749             Copyright 20.08.2010 by Bochkanov Sergey
6750        *************************************************************************/
6751        public static void nleqsetstpmax(nleqstate state,
6752            double stpmax)
6753        {
6754            alglib.ap.assert(math.isfinite(stpmax), "NLEQSetStpMax: StpMax is not finite!");
6755            alglib.ap.assert((double)(stpmax)>=(double)(0), "NLEQSetStpMax: StpMax<0!");
6756            state.stpmax = stpmax;
6757        }
6758
6759
6760        /*************************************************************************
6761
6762          -- ALGLIB --
6763             Copyright 20.03.2009 by Bochkanov Sergey
6764        *************************************************************************/
6765        public static bool nleqiteration(nleqstate state)
6766        {
6767            bool result = new bool();
6768            int n = 0;
6769            int m = 0;
6770            int i = 0;
6771            double lambdaup = 0;
6772            double lambdadown = 0;
6773            double lambdav = 0;
6774            double rho = 0;
6775            double mu = 0;
6776            double stepnorm = 0;
6777            bool b = new bool();
6778            int i_ = 0;
6779
6780           
6781            //
6782            // Reverse communication preparations
6783            // I know it looks ugly, but it works the same way
6784            // anywhere from C++ to Python.
6785            //
6786            // This code initializes locals by:
6787            // * random values determined during code
6788            //   generation - on first subroutine call
6789            // * values from previous call - on subsequent calls
6790            //
6791            if( state.rstate.stage>=0 )
6792            {
6793                n = state.rstate.ia[0];
6794                m = state.rstate.ia[1];
6795                i = state.rstate.ia[2];
6796                b = state.rstate.ba[0];
6797                lambdaup = state.rstate.ra[0];
6798                lambdadown = state.rstate.ra[1];
6799                lambdav = state.rstate.ra[2];
6800                rho = state.rstate.ra[3];
6801                mu = state.rstate.ra[4];
6802                stepnorm = state.rstate.ra[5];
6803            }
6804            else
6805            {
6806                n = -983;
6807                m = -989;
6808                i = -834;
6809                b = false;
6810                lambdaup = -287;
6811                lambdadown = 364;
6812                lambdav = 214;
6813                rho = -338;
6814                mu = -686;
6815                stepnorm = 912;
6816            }
6817            if( state.rstate.stage==0 )
6818            {
6819                goto lbl_0;
6820            }
6821            if( state.rstate.stage==1 )
6822            {
6823                goto lbl_1;
6824            }
6825            if( state.rstate.stage==2 )
6826            {
6827                goto lbl_2;
6828            }
6829            if( state.rstate.stage==3 )
6830            {
6831                goto lbl_3;
6832            }
6833            if( state.rstate.stage==4 )
6834            {
6835                goto lbl_4;
6836            }
6837           
6838            //
6839            // Routine body
6840            //
6841           
6842            //
6843            // Prepare
6844            //
6845            n = state.n;
6846            m = state.m;
6847            state.repterminationtype = 0;
6848            state.repiterationscount = 0;
6849            state.repnfunc = 0;
6850            state.repnjac = 0;
6851           
6852            //
6853            // Calculate F/G, initialize algorithm
6854            //
6855            clearrequestfields(state);
6856            state.needf = true;
6857            state.rstate.stage = 0;
6858            goto lbl_rcomm;
6859        lbl_0:
6860            state.needf = false;
6861            state.repnfunc = state.repnfunc+1;
6862            for(i_=0; i_<=n-1;i_++)
6863            {
6864                state.xbase[i_] = state.x[i_];
6865            }
6866            state.fbase = state.f;
6867            state.fprev = math.maxrealnumber;
6868            if( !state.xrep )
6869            {
6870                goto lbl_5;
6871            }
6872           
6873            //
6874            // progress report
6875            //
6876            clearrequestfields(state);
6877            state.xupdated = true;
6878            state.rstate.stage = 1;
6879            goto lbl_rcomm;
6880        lbl_1:
6881            state.xupdated = false;
6882        lbl_5:
6883            if( (double)(state.f)<=(double)(math.sqr(state.epsf)) )
6884            {
6885                state.repterminationtype = 1;
6886                result = false;
6887                return result;
6888            }
6889           
6890            //
6891            // Main cycle
6892            //
6893            lambdaup = 10;
6894            lambdadown = 0.3;
6895            lambdav = 0.001;
6896            rho = 1;
6897        lbl_7:
6898            if( false )
6899            {
6900                goto lbl_8;
6901            }
6902           
6903            //
6904            // Get Jacobian;
6905            // before we get to this point we already have State.XBase filled
6906            // with current point and State.FBase filled with function value
6907            // at XBase
6908            //
6909            clearrequestfields(state);
6910            state.needfij = true;
6911            for(i_=0; i_<=n-1;i_++)
6912            {
6913                state.x[i_] = state.xbase[i_];
6914            }
6915            state.rstate.stage = 2;
6916            goto lbl_rcomm;
6917        lbl_2:
6918            state.needfij = false;
6919            state.repnfunc = state.repnfunc+1;
6920            state.repnjac = state.repnjac+1;
6921            ablas.rmatrixmv(n, m, state.j, 0, 0, 1, state.fi, 0, ref state.rightpart, 0);
6922            for(i_=0; i_<=n-1;i_++)
6923            {
6924                state.rightpart[i_] = -1*state.rightpart[i_];
6925            }
6926           
6927            //
6928            // Inner cycle: find good lambda
6929            //
6930        lbl_9:
6931            if( false )
6932            {
6933                goto lbl_10;
6934            }
6935           
6936            //
6937            // Solve (J^T*J + (Lambda+Mu)*I)*y = J^T*F
6938            // to get step d=-y where:
6939            // * Mu=||F|| - is damping parameter for nonlinear system
6940            // * Lambda   - is additional Levenberg-Marquardt parameter
6941            //              for better convergence when far away from minimum
6942            //
6943            for(i=0; i<=n-1; i++)
6944            {
6945                state.candstep[i] = 0;
6946            }
6947            fbls.fblssolvecgx(state.j, m, n, lambdav, state.rightpart, ref state.candstep, ref state.cgbuf);
6948           
6949            //
6950            // Normalize step (it must be no more than StpMax)
6951            //
6952            stepnorm = 0;
6953            for(i=0; i<=n-1; i++)
6954            {
6955                if( (double)(state.candstep[i])!=(double)(0) )
6956                {
6957                    stepnorm = 1;
6958                    break;
6959                }
6960            }
6961            linmin.linminnormalized(ref state.candstep, ref stepnorm, n);
6962            if( (double)(state.stpmax)!=(double)(0) )
6963            {
6964                stepnorm = Math.Min(stepnorm, state.stpmax);
6965            }
6966           
6967            //
6968            // Test new step - is it good enough?
6969            // * if not, Lambda is increased and we try again.
6970            // * if step is good, we decrease Lambda and move on.
6971            //
6972            // We can break this cycle on two occasions:
6973            // * step is so small that x+step==x (in floating point arithmetics)
6974            // * lambda is so large
6975            //
6976            for(i_=0; i_<=n-1;i_++)
6977            {
6978                state.x[i_] = state.xbase[i_];
6979            }
6980            for(i_=0; i_<=n-1;i_++)
6981            {
6982                state.x[i_] = state.x[i_] + stepnorm*state.candstep[i_];
6983            }
6984            b = true;
6985            for(i=0; i<=n-1; i++)
6986            {
6987                if( (double)(state.x[i])!=(double)(state.xbase[i]) )
6988                {
6989                    b = false;
6990                    break;
6991                }
6992            }
6993            if( b )
6994            {
6995               
6996                //
6997                // Step is too small, force zero step and break
6998                //
6999                stepnorm = 0;
7000                for(i_=0; i_<=n-1;i_++)
7001                {
7002                    state.x[i_] = state.xbase[i_];
7003                }
7004                state.f = state.fbase;
7005                goto lbl_10;
7006            }
7007            clearrequestfields(state);
7008            state.needf = true;
7009            state.rstate.stage = 3;
7010            goto lbl_rcomm;
7011        lbl_3:
7012            state.needf = false;
7013            state.repnfunc = state.repnfunc+1;
7014            if( (double)(state.f)<(double)(state.fbase) )
7015            {
7016               
7017                //
7018                // function value decreased, move on
7019                //
7020                decreaselambda(ref lambdav, ref rho, lambdadown);
7021                goto lbl_10;
7022            }
7023            if( !increaselambda(ref lambdav, ref rho, lambdaup) )
7024            {
7025               
7026                //
7027                // Lambda is too large (near overflow), force zero step and break
7028                //
7029                stepnorm = 0;
7030                for(i_=0; i_<=n-1;i_++)
7031                {
7032                    state.x[i_] = state.xbase[i_];
7033                }
7034                state.f = state.fbase;
7035                goto lbl_10;
7036            }
7037            goto lbl_9;
7038        lbl_10:
7039           
7040            //
7041            // Accept step:
7042            // * new position
7043            // * new function value
7044            //
7045            state.fbase = state.f;
7046            for(i_=0; i_<=n-1;i_++)
7047            {
7048                state.xbase[i_] = state.xbase[i_] + stepnorm*state.candstep[i_];
7049            }
7050            state.repiterationscount = state.repiterationscount+1;
7051           
7052            //
7053            // Report new iteration
7054            //
7055            if( !state.xrep )
7056            {
7057                goto lbl_11;
7058            }
7059            clearrequestfields(state);
7060            state.xupdated = true;
7061            state.f = state.fbase;
7062            for(i_=0; i_<=n-1;i_++)
7063            {
7064                state.x[i_] = state.xbase[i_];
7065            }
7066            state.rstate.stage = 4;
7067            goto lbl_rcomm;
7068        lbl_4:
7069            state.xupdated = false;
7070        lbl_11:
7071           
7072            //
7073            // Test stopping conditions on F, step (zero/non-zero) and MaxIts;
7074            // If one of the conditions is met, RepTerminationType is changed.
7075            //
7076            if( (double)(Math.Sqrt(state.f))<=(double)(state.epsf) )
7077            {
7078                state.repterminationtype = 1;
7079            }
7080            if( (double)(stepnorm)==(double)(0) && state.repterminationtype==0 )
7081            {
7082                state.repterminationtype = -4;
7083            }
7084            if( state.repiterationscount>=state.maxits && state.maxits>0 )
7085            {
7086                state.repterminationtype = 5;
7087            }
7088            if( state.repterminationtype!=0 )
7089            {
7090                goto lbl_8;
7091            }
7092           
7093            //
7094            // Now, iteration is finally over
7095            //
7096            goto lbl_7;
7097        lbl_8:
7098            result = false;
7099            return result;
7100           
7101            //
7102            // Saving state
7103            //
7104        lbl_rcomm:
7105            result = true;
7106            state.rstate.ia[0] = n;
7107            state.rstate.ia[1] = m;
7108            state.rstate.ia[2] = i;
7109            state.rstate.ba[0] = b;
7110            state.rstate.ra[0] = lambdaup;
7111            state.rstate.ra[1] = lambdadown;
7112            state.rstate.ra[2] = lambdav;
7113            state.rstate.ra[3] = rho;
7114            state.rstate.ra[4] = mu;
7115            state.rstate.ra[5] = stepnorm;
7116            return result;
7117        }
7118
7119
7120        /*************************************************************************
7121        NLEQ solver results
7122
7123        INPUT PARAMETERS:
7124            State   -   algorithm state.
7125
7126        OUTPUT PARAMETERS:
7127            X       -   array[0..N-1], solution
7128            Rep     -   optimization report:
7129                        * Rep.TerminationType completetion code:
7130                            * -4    ERROR:  algorithm   has   converged   to   the
7131                                    stationary point Xf which is local minimum  of
7132                                    f=F[0]^2+...+F[m-1]^2, but is not solution  of
7133                                    nonlinear system.
7134                            *  1    sqrt(f)<=EpsF.
7135                            *  5    MaxIts steps was taken
7136                            *  7    stopping conditions are too stringent,
7137                                    further improvement is impossible
7138                        * Rep.IterationsCount contains iterations count
7139                        * NFEV countains number of function calculations
7140                        * ActiveConstraints contains number of active constraints
7141
7142          -- ALGLIB --
7143             Copyright 20.08.2009 by Bochkanov Sergey
7144        *************************************************************************/
7145        public static void nleqresults(nleqstate state,
7146            ref double[] x,
7147            nleqreport rep)
7148        {
7149            x = new double[0];
7150
7151            nleqresultsbuf(state, ref x, rep);
7152        }
7153
7154
7155        /*************************************************************************
7156        NLEQ solver results
7157
7158        Buffered implementation of NLEQResults(), which uses pre-allocated  buffer
7159        to store X[]. If buffer size is  too  small,  it  resizes  buffer.  It  is
7160        intended to be used in the inner cycles of performance critical algorithms
7161        where array reallocation penalty is too large to be ignored.
7162
7163          -- ALGLIB --
7164             Copyright 20.08.2009 by Bochkanov Sergey
7165        *************************************************************************/
7166        public static void nleqresultsbuf(nleqstate state,
7167            ref double[] x,
7168            nleqreport rep)
7169        {
7170            int i_ = 0;
7171
7172            if( alglib.ap.len(x)<state.n )
7173            {
7174                x = new double[state.n];
7175            }
7176            for(i_=0; i_<=state.n-1;i_++)
7177            {
7178                x[i_] = state.xbase[i_];
7179            }
7180            rep.iterationscount = state.repiterationscount;
7181            rep.nfunc = state.repnfunc;
7182            rep.njac = state.repnjac;
7183            rep.terminationtype = state.repterminationtype;
7184        }
7185
7186
7187        /*************************************************************************
7188        This  subroutine  restarts  CG  algorithm from new point. All optimization
7189        parameters are left unchanged.
7190
7191        This  function  allows  to  solve multiple  optimization  problems  (which
7192        must have same number of dimensions) without object reallocation penalty.
7193
7194        INPUT PARAMETERS:
7195            State   -   structure used for reverse communication previously
7196                        allocated with MinCGCreate call.
7197            X       -   new starting point.
7198            BndL    -   new lower bounds
7199            BndU    -   new upper bounds
7200
7201          -- ALGLIB --
7202             Copyright 30.07.2010 by Bochkanov Sergey
7203        *************************************************************************/
7204        public static void nleqrestartfrom(nleqstate state,
7205            double[] x)
7206        {
7207            int i_ = 0;
7208
7209            alglib.ap.assert(alglib.ap.len(x)>=state.n, "NLEQRestartFrom: Length(X)<N!");
7210            alglib.ap.assert(apserv.isfinitevector(x, state.n), "NLEQRestartFrom: X contains infinite or NaN values!");
7211            for(i_=0; i_<=state.n-1;i_++)
7212            {
7213                state.x[i_] = x[i_];
7214            }
7215            state.rstate.ia = new int[2+1];
7216            state.rstate.ba = new bool[0+1];
7217            state.rstate.ra = new double[5+1];
7218            state.rstate.stage = -1;
7219            clearrequestfields(state);
7220        }
7221
7222
7223        /*************************************************************************
7224        Clears request fileds (to be sure that we don't forgot to clear something)
7225        *************************************************************************/
7226        private static void clearrequestfields(nleqstate state)
7227        {
7228            state.needf = false;
7229            state.needfij = false;
7230            state.xupdated = false;
7231        }
7232
7233
7234        /*************************************************************************
7235        Increases lambda, returns False when there is a danger of overflow
7236        *************************************************************************/
7237        private static bool increaselambda(ref double lambdav,
7238            ref double nu,
7239            double lambdaup)
7240        {
7241            bool result = new bool();
7242            double lnlambda = 0;
7243            double lnnu = 0;
7244            double lnlambdaup = 0;
7245            double lnmax = 0;
7246
7247            result = false;
7248            lnlambda = Math.Log(lambdav);
7249            lnlambdaup = Math.Log(lambdaup);
7250            lnnu = Math.Log(nu);
7251            lnmax = 0.5*Math.Log(math.maxrealnumber);
7252            if( (double)(lnlambda+lnlambdaup+lnnu)>(double)(lnmax) )
7253            {
7254                return result;
7255            }
7256            if( (double)(lnnu+Math.Log(2))>(double)(lnmax) )
7257            {
7258                return result;
7259            }
7260            lambdav = lambdav*lambdaup*nu;
7261            nu = nu*2;
7262            result = true;
7263            return result;
7264        }
7265
7266
7267        /*************************************************************************
7268        Decreases lambda, but leaves it unchanged when there is danger of underflow.
7269        *************************************************************************/
7270        private static void decreaselambda(ref double lambdav,
7271            ref double nu,
7272            double lambdadown)
7273        {
7274            nu = 1;
7275            if( (double)(Math.Log(lambdav)+Math.Log(lambdadown))<(double)(Math.Log(math.minrealnumber)) )
7276            {
7277                lambdav = math.minrealnumber;
7278            }
7279            else
7280            {
7281                lambdav = lambdav*lambdadown;
7282            }
7283        }
7284
7285
7286    }
7287}
7288
Note: See TracBrowser for help on using the repository browser.