Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.ExtLibs/HeuristicLab.ALGLIB/2.1.2.2591/ALGLIB-2.1.2.2591/spdsolve.cs @ 3031

Last change on this file since 3031 was 2645, checked in by mkommend, 15 years ago

extracted external libraries and adapted dependent plugins (ticket #837)

File size: 10.9 KB
Line 
1/*************************************************************************
2This file is a part of 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
18>>> END OF LICENSE >>>
19*************************************************************************/
20
21using System;
22
23namespace alglib
24{
25    public class spdsolve
26    {
27        /*************************************************************************
28        Solving a system of linear equations with a system  matrix  given  by  its
29        Cholesky decomposition.
30
31        The algorithm solves systems with a square matrix only.
32
33        Input parameters:
34            A       -   Cholesky decomposition of a system matrix (the result of
35                        the SMatrixCholesky subroutine).
36            B       -   right side of a system.
37                        Array whose index ranges within [0..N-1].
38            N       -   size of matrix A.
39            IsUpper -   points to the triangle of matrix A in which the Cholesky
40                        decomposition is stored. If IsUpper=True,  the  Cholesky
41                        decomposition has the form of U'*U, and the upper triangle
42                        of matrix A stores matrix U (in  that  case,  the  lower
43                        triangle isn’t used and isn’t changed by the subroutine)
44                        Similarly, if IsUpper = False, the Cholesky decomposition
45                        has the form of L*L',  and  the  lower  triangle  stores
46                        matrix L.
47
48        Output parameters:
49            X       -   solution of a system.
50                        Array whose index ranges within [0..N-1].
51
52        Result:
53            True, if the system is not singular. X contains the solution.
54            False, if the system is singular (there is a zero element on the main
55        diagonal). In this case, X doesn't contain a solution.
56
57          -- ALGLIB --
58             Copyright 2005-2008 by Bochkanov Sergey
59        *************************************************************************/
60        public static bool spdmatrixcholeskysolve(ref double[,] a,
61            double[] b,
62            int n,
63            bool isupper,
64            ref double[] x)
65        {
66            bool result = new bool();
67            int i = 0;
68            double v = 0;
69            int i_ = 0;
70
71            b = (double[])b.Clone();
72
73            System.Diagnostics.Debug.Assert(n>0, "Error: N<=0 in SolveSystemCholesky");
74           
75            //
76            // det(A)=0?
77            //
78            result = true;
79            for(i=0; i<=n-1; i++)
80            {
81                if( (double)(a[i,i])==(double)(0) )
82                {
83                    result = false;
84                    return result;
85                }
86            }
87           
88            //
89            // det(A)<>0
90            //
91            x = new double[n-1+1];
92            if( isupper )
93            {
94               
95                //
96                // A = U'*U, solve U'*y = b first
97                //
98                b[0] = b[0]/a[0,0];
99                for(i=1; i<=n-1; i++)
100                {
101                    v = 0.0;
102                    for(i_=0; i_<=i-1;i_++)
103                    {
104                        v += a[i_,i]*b[i_];
105                    }
106                    b[i] = (b[i]-v)/a[i,i];
107                }
108               
109                //
110                // Solve U*x = y
111                //
112                b[n-1] = b[n-1]/a[n-1,n-1];
113                for(i=n-2; i>=0; i--)
114                {
115                    v = 0.0;
116                    for(i_=i+1; i_<=n-1;i_++)
117                    {
118                        v += a[i,i_]*b[i_];
119                    }
120                    b[i] = (b[i]-v)/a[i,i];
121                }
122                for(i_=0; i_<=n-1;i_++)
123                {
124                    x[i_] = b[i_];
125                }
126            }
127            else
128            {
129               
130                //
131                // A = L*L', solve L'*y = b first
132                //
133                b[0] = b[0]/a[0,0];
134                for(i=1; i<=n-1; i++)
135                {
136                    v = 0.0;
137                    for(i_=0; i_<=i-1;i_++)
138                    {
139                        v += a[i,i_]*b[i_];
140                    }
141                    b[i] = (b[i]-v)/a[i,i];
142                }
143               
144                //
145                // Solve L'*x = y
146                //
147                b[n-1] = b[n-1]/a[n-1,n-1];
148                for(i=n-2; i>=0; i--)
149                {
150                    v = 0.0;
151                    for(i_=i+1; i_<=n-1;i_++)
152                    {
153                        v += a[i_,i]*b[i_];
154                    }
155                    b[i] = (b[i]-v)/a[i,i];
156                }
157                for(i_=0; i_<=n-1;i_++)
158                {
159                    x[i_] = b[i_];
160                }
161            }
162            return result;
163        }
164
165
166        /*************************************************************************
167        Solving a system of linear equations with  a  symmetric  positive-definite
168        matrix by using the Cholesky decomposition.
169
170        The algorithm solves a system of linear equations whose matrix is symmetric
171        and positive-definite.
172
173        Input parameters:
174            A       -   upper or lower triangle part of a symmetric system matrix.
175                        Array whose indexes range within [0..N-1, 0..N-1].
176            B       -   right side of a system.
177                        Array whose index ranges within [0..N-1].
178            N       -   size of matrix A.
179            IsUpper -   points to the triangle of matrix A in which the matrix is stored.
180
181        Output parameters:
182            X       -   solution of a system.
183                        Array whose index ranges within [0..N-1].
184
185        Result:
186            True, if the system is not singular.
187            False, if the system is singular. In this case, X doesn't contain a
188        solution.
189
190          -- ALGLIB --
191             Copyright 2005-2008 by Bochkanov Sergey
192        *************************************************************************/
193        public static bool spdmatrixsolve(double[,] a,
194            double[] b,
195            int n,
196            bool isupper,
197            ref double[] x)
198        {
199            bool result = new bool();
200
201            a = (double[,])a.Clone();
202            b = (double[])b.Clone();
203
204            result = cholesky.spdmatrixcholesky(ref a, n, isupper);
205            if( !result )
206            {
207                return result;
208            }
209            result = spdmatrixcholeskysolve(ref a, b, n, isupper, ref x);
210            return result;
211        }
212
213
214        public static bool solvesystemcholesky(ref double[,] a,
215            double[] b,
216            int n,
217            bool isupper,
218            ref double[] x)
219        {
220            bool result = new bool();
221            int i = 0;
222            int im1 = 0;
223            int ip1 = 0;
224            double v = 0;
225            int i_ = 0;
226
227            b = (double[])b.Clone();
228
229            System.Diagnostics.Debug.Assert(n>0, "Error: N<=0 in SolveSystemCholesky");
230           
231            //
232            // det(A)=0?
233            //
234            result = true;
235            for(i=1; i<=n; i++)
236            {
237                if( (double)(a[i,i])==(double)(0) )
238                {
239                    result = false;
240                    return result;
241                }
242            }
243           
244            //
245            // det(A)<>0
246            //
247            x = new double[n+1];
248            if( isupper )
249            {
250               
251                //
252                // A = U'*U, solve U'*y = b first
253                //
254                b[1] = b[1]/a[1,1];
255                for(i=2; i<=n; i++)
256                {
257                    im1 = i-1;
258                    v = 0.0;
259                    for(i_=1; i_<=im1;i_++)
260                    {
261                        v += a[i_,i]*b[i_];
262                    }
263                    b[i] = (b[i]-v)/a[i,i];
264                }
265               
266                //
267                // Solve U*x = y
268                //
269                b[n] = b[n]/a[n,n];
270                for(i=n-1; i>=1; i--)
271                {
272                    ip1 = i+1;
273                    v = 0.0;
274                    for(i_=ip1; i_<=n;i_++)
275                    {
276                        v += a[i,i_]*b[i_];
277                    }
278                    b[i] = (b[i]-v)/a[i,i];
279                }
280                for(i_=1; i_<=n;i_++)
281                {
282                    x[i_] = b[i_];
283                }
284            }
285            else
286            {
287               
288                //
289                // A = L*L', solve L'*y = b first
290                //
291                b[1] = b[1]/a[1,1];
292                for(i=2; i<=n; i++)
293                {
294                    im1 = i-1;
295                    v = 0.0;
296                    for(i_=1; i_<=im1;i_++)
297                    {
298                        v += a[i,i_]*b[i_];
299                    }
300                    b[i] = (b[i]-v)/a[i,i];
301                }
302               
303                //
304                // Solve L'*x = y
305                //
306                b[n] = b[n]/a[n,n];
307                for(i=n-1; i>=1; i--)
308                {
309                    ip1 = i+1;
310                    v = 0.0;
311                    for(i_=ip1; i_<=n;i_++)
312                    {
313                        v += a[i_,i]*b[i_];
314                    }
315                    b[i] = (b[i]-v)/a[i,i];
316                }
317                for(i_=1; i_<=n;i_++)
318                {
319                    x[i_] = b[i_];
320                }
321            }
322            return result;
323        }
324
325
326        public static bool solvespdsystem(double[,] a,
327            double[] b,
328            int n,
329            bool isupper,
330            ref double[] x)
331        {
332            bool result = new bool();
333
334            a = (double[,])a.Clone();
335            b = (double[])b.Clone();
336
337            result = cholesky.choleskydecomposition(ref a, n, isupper);
338            if( !result )
339            {
340                return result;
341            }
342            result = solvesystemcholesky(ref a, b, n, isupper, ref x);
343            return result;
344        }
345    }
346}
Note: See TracBrowser for help on using the repository browser.