Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/ALGLIB/cholesky.cs @ 2575

Last change on this file since 2575 was 2563, checked in by gkronber, 15 years ago

Updated ALGLIB to latest version. #751 (Plugin for for data-modeling with ANN (integrated into CEDMA))

File size: 10.6 KB
Line 
1/*************************************************************************
2Copyright (c) 1992-2007 The University of Tennessee.  All rights reserved.
3
4Contributors:
5    * Sergey Bochkanov (ALGLIB project). Translation from FORTRAN to
6      pseudocode.
7
8See subroutines comments for additional copyrights.
9
10>>> SOURCE LICENSE >>>
11This program is free software; you can redistribute it and/or modify
12it under the terms of the GNU General Public License as published by
13the Free Software Foundation (www.fsf.org); either version 2 of the
14License, or (at your option) any later version.
15
16This program is distributed in the hope that it will be useful,
17but WITHOUT ANY WARRANTY; without even the implied warranty of
18MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19GNU General Public License for more details.
20
21A copy of the GNU General Public License is available at
22http://www.fsf.org/licensing/licenses
23
24>>> END OF LICENSE >>>
25*************************************************************************/
26
27using System;
28
29namespace alglib
30{
31    public class cholesky
32    {
33        /*************************************************************************
34        Cholesky decomposition
35
36        The algorithm computes Cholesky decomposition of a symmetric
37        positive-definite matrix.
38
39        The result of an algorithm is a representation of matrix A as A = U'*U or
40        A = L*L'.
41
42        Input parameters:
43            A       -   upper or lower triangle of a factorized matrix.
44                        array with elements [0..N-1, 0..N-1].
45            N       -   size of matrix A.
46            IsUpper -   if IsUpper=True, then A contains an upper triangle of
47                        a symmetric matrix, otherwise A contains a lower one.
48
49        Output parameters:
50            A       -   the result of factorization. If IsUpper=True, then
51                        the upper triangle contains matrix U, so that A = U'*U,
52                        and the elements below the main diagonal are not modified.
53                        Similarly, if IsUpper = False.
54
55        Result:
56            If the matrix is positive-definite, the function returns True.
57            Otherwise, the function returns False. This means that the
58            factorization could not be carried out.
59
60          -- LAPACK routine (version 3.0) --
61             Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,
62             Courant Institute, Argonne National Lab, and Rice University
63             February 29, 1992
64        *************************************************************************/
65        public static bool spdmatrixcholesky(ref double[,] a,
66            int n,
67            bool isupper)
68        {
69            bool result = new bool();
70            int i = 0;
71            int j = 0;
72            double ajj = 0;
73            double v = 0;
74            int i_ = 0;
75
76           
77            //
78            //     Test the input parameters.
79            //
80            System.Diagnostics.Debug.Assert(n>=0, "Error in SMatrixCholesky: incorrect function arguments");
81           
82            //
83            //     Quick return if possible
84            //
85            result = true;
86            if( n<=0 )
87            {
88                return result;
89            }
90            if( isupper )
91            {
92               
93                //
94                // Compute the Cholesky factorization A = U'*U.
95                //
96                for(j=0; j<=n-1; j++)
97                {
98                   
99                    //
100                    // Compute U(J,J) and test for non-positive-definiteness.
101                    //
102                    v = 0.0;
103                    for(i_=0; i_<=j-1;i_++)
104                    {
105                        v += a[i_,j]*a[i_,j];
106                    }
107                    ajj = a[j,j]-v;
108                    if( (double)(ajj)<=(double)(0) )
109                    {
110                        result = false;
111                        return result;
112                    }
113                    ajj = Math.Sqrt(ajj);
114                    a[j,j] = ajj;
115                   
116                    //
117                    // Compute elements J+1:N of row J.
118                    //
119                    if( j<n-1 )
120                    {
121                        for(i=0; i<=j-1; i++)
122                        {
123                            v = a[i,j];
124                            for(i_=j+1; i_<=n-1;i_++)
125                            {
126                                a[j,i_] = a[j,i_] - v*a[i,i_];
127                            }
128                        }
129                        v = 1/ajj;
130                        for(i_=j+1; i_<=n-1;i_++)
131                        {
132                            a[j,i_] = v*a[j,i_];
133                        }
134                    }
135                }
136            }
137            else
138            {
139               
140                //
141                // Compute the Cholesky factorization A = L*L'.
142                //
143                for(j=0; j<=n-1; j++)
144                {
145                   
146                    //
147                    // Compute L(J,J) and test for non-positive-definiteness.
148                    //
149                    v = 0.0;
150                    for(i_=0; i_<=j-1;i_++)
151                    {
152                        v += a[j,i_]*a[j,i_];
153                    }
154                    ajj = a[j,j]-v;
155                    if( (double)(ajj)<=(double)(0) )
156                    {
157                        result = false;
158                        return result;
159                    }
160                    ajj = Math.Sqrt(ajj);
161                    a[j,j] = ajj;
162                   
163                    //
164                    // Compute elements J+1:N of column J.
165                    //
166                    if( j<n-1 )
167                    {
168                        for(i=j+1; i<=n-1; i++)
169                        {
170                            v = 0.0;
171                            for(i_=0; i_<=j-1;i_++)
172                            {
173                                v += a[i,i_]*a[j,i_];
174                            }
175                            a[i,j] = a[i,j]-v;
176                        }
177                        v = 1/ajj;
178                        for(i_=j+1; i_<=n-1;i_++)
179                        {
180                            a[i_,j] = v*a[i_,j];
181                        }
182                    }
183                }
184            }
185            return result;
186        }
187
188
189        public static bool choleskydecomposition(ref double[,] a,
190            int n,
191            bool isupper)
192        {
193            bool result = new bool();
194            int i = 0;
195            int j = 0;
196            double ajj = 0;
197            double v = 0;
198            int jm1 = 0;
199            int jp1 = 0;
200            int i_ = 0;
201
202           
203            //
204            //     Test the input parameters.
205            //
206            System.Diagnostics.Debug.Assert(n>=0, "Error in CholeskyDecomposition: incorrect function arguments");
207           
208            //
209            //     Quick return if possible
210            //
211            result = true;
212            if( n==0 )
213            {
214                return result;
215            }
216            if( isupper )
217            {
218               
219                //
220                // Compute the Cholesky factorization A = U'*U.
221                //
222                for(j=1; j<=n; j++)
223                {
224                   
225                    //
226                    // Compute U(J,J) and test for non-positive-definiteness.
227                    //
228                    jm1 = j-1;
229                    v = 0.0;
230                    for(i_=1; i_<=jm1;i_++)
231                    {
232                        v += a[i_,j]*a[i_,j];
233                    }
234                    ajj = a[j,j]-v;
235                    if( (double)(ajj)<=(double)(0) )
236                    {
237                        result = false;
238                        return result;
239                    }
240                    ajj = Math.Sqrt(ajj);
241                    a[j,j] = ajj;
242                   
243                    //
244                    // Compute elements J+1:N of row J.
245                    //
246                    if( j<n )
247                    {
248                        for(i=j+1; i<=n; i++)
249                        {
250                            jm1 = j-1;
251                            v = 0.0;
252                            for(i_=1; i_<=jm1;i_++)
253                            {
254                                v += a[i_,i]*a[i_,j];
255                            }
256                            a[j,i] = a[j,i]-v;
257                        }
258                        v = 1/ajj;
259                        jp1 = j+1;
260                        for(i_=jp1; i_<=n;i_++)
261                        {
262                            a[j,i_] = v*a[j,i_];
263                        }
264                    }
265                }
266            }
267            else
268            {
269               
270                //
271                // Compute the Cholesky factorization A = L*L'.
272                //
273                for(j=1; j<=n; j++)
274                {
275                   
276                    //
277                    // Compute L(J,J) and test for non-positive-definiteness.
278                    //
279                    jm1 = j-1;
280                    v = 0.0;
281                    for(i_=1; i_<=jm1;i_++)
282                    {
283                        v += a[j,i_]*a[j,i_];
284                    }
285                    ajj = a[j,j]-v;
286                    if( (double)(ajj)<=(double)(0) )
287                    {
288                        result = false;
289                        return result;
290                    }
291                    ajj = Math.Sqrt(ajj);
292                    a[j,j] = ajj;
293                   
294                    //
295                    // Compute elements J+1:N of column J.
296                    //
297                    if( j<n )
298                    {
299                        for(i=j+1; i<=n; i++)
300                        {
301                            jm1 = j-1;
302                            v = 0.0;
303                            for(i_=1; i_<=jm1;i_++)
304                            {
305                                v += a[i,i_]*a[j,i_];
306                            }
307                            a[i,j] = a[i,j]-v;
308                        }
309                        v = 1/ajj;
310                        jp1 = j+1;
311                        for(i_=jp1; i_<=n;i_++)
312                        {
313                            a[i_,j] = v*a[i_,j];
314                        }
315                    }
316                }
317            }
318            return result;
319        }
320    }
321}
Note: See TracBrowser for help on using the repository browser.