Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/ALGLIB/cqr.cs @ 2625

Last change on this file since 2625 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: 13.5 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 cqr
32    {
33        /*************************************************************************
34        QR decomposition of a rectangular complex matrix of size MxN
35
36        Input parameters:
37            A   -   matrix A whose indexes range within [0..M-1, 0..N-1]
38            M   -   number of rows in matrix A.
39            N   -   number of columns in matrix A.
40
41        Output parameters:
42            A   -   matrices Q and R in compact form
43            Tau -   array of scalar factors which are used to form matrix Q. Array
44                    whose indexes range within [0.. Min(M,N)-1]
45
46        Matrix A is represented as A = QR, where Q is an orthogonal matrix of size
47        MxM, R - upper triangular (or upper trapezoid) matrix of size MxN.
48
49          -- LAPACK routine (version 3.0) --
50             Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,
51             Courant Institute, Argonne National Lab, and Rice University
52             September 30, 1994
53        *************************************************************************/
54        public static void cmatrixqr(ref AP.Complex[,] a,
55            int m,
56            int n,
57            ref AP.Complex[] tau)
58        {
59            AP.Complex[] work = new AP.Complex[0];
60            AP.Complex[] t = new AP.Complex[0];
61            int i = 0;
62            int k = 0;
63            int mmi = 0;
64            int minmn = 0;
65            AP.Complex tmp = 0;
66            int i_ = 0;
67            int i1_ = 0;
68
69            minmn = Math.Min(m, n);
70            if( minmn<=0 )
71            {
72                return;
73            }
74            work = new AP.Complex[n-1+1];
75            t = new AP.Complex[m+1];
76            tau = new AP.Complex[minmn-1+1];
77           
78            //
79            // Test the input arguments
80            //
81            k = Math.Min(m, n);
82            for(i=0; i<=k-1; i++)
83            {
84               
85                //
86                // Generate elementary reflector H(i) to annihilate A(i+1:m,i)
87                //
88                mmi = m-i;
89                i1_ = (i) - (1);
90                for(i_=1; i_<=mmi;i_++)
91                {
92                    t[i_] = a[i_+i1_,i];
93                }
94                creflections.complexgeneratereflection(ref t, mmi, ref tmp);
95                tau[i] = tmp;
96                i1_ = (1) - (i);
97                for(i_=i; i_<=m-1;i_++)
98                {
99                    a[i_,i] = t[i_+i1_];
100                }
101                t[1] = 1;
102                if( i<n-1 )
103                {
104                   
105                    //
106                    // Apply H'(i) to A(i:m,i+1:n) from the left
107                    //
108                    creflections.complexapplyreflectionfromtheleft(ref a, AP.Math.Conj(tau[i]), ref t, i, m-1, i+1, n-1, ref work);
109                }
110            }
111        }
112
113
114        /*************************************************************************
115        Partial unpacking of matrix Q from QR decomposition of a complex matrix A.
116
117        Input parameters:
118            QR          -   matrices Q and R in compact form.
119                            Output of CMatrixQR subroutine .
120            M           -   number of rows in matrix A. M>=0.
121            N           -   number of rows in matrix A. N>=0.
122            Tau         -   scalar factors which are used to form Q.
123                            Output of CMatrixQR subroutine .
124            QColumns    -   required number of columns in matrix Q. M>=QColumns>=0.
125
126        Output parameters:
127            Q           -   first QColumns columns of matrix Q.
128                            Array whose index ranges within [0..M-1, 0..QColumns-1].
129                            If QColumns=0, array isn't changed.
130
131          -- ALGLIB --
132             Copyright 2005 by Bochkanov Sergey
133        *************************************************************************/
134        public static void cmatrixqrunpackq(ref AP.Complex[,] qr,
135            int m,
136            int n,
137            ref AP.Complex[] tau,
138            int qcolumns,
139            ref AP.Complex[,] q)
140        {
141            int i = 0;
142            int j = 0;
143            int k = 0;
144            int minmn = 0;
145            AP.Complex[] v = new AP.Complex[0];
146            AP.Complex[] work = new AP.Complex[0];
147            int vm = 0;
148            int i_ = 0;
149            int i1_ = 0;
150
151            System.Diagnostics.Debug.Assert(qcolumns<=m, "UnpackQFromQR: QColumns>M!");
152            if( m<=0 | n<=0 | qcolumns<=0 )
153            {
154                return;
155            }
156           
157            //
158            // init
159            //
160            minmn = Math.Min(m, n);
161            k = Math.Min(minmn, qcolumns);
162            q = new AP.Complex[m-1+1, qcolumns-1+1];
163            v = new AP.Complex[m+1];
164            work = new AP.Complex[qcolumns-1+1];
165            for(i=0; i<=m-1; i++)
166            {
167                for(j=0; j<=qcolumns-1; j++)
168                {
169                    if( i==j )
170                    {
171                        q[i,j] = 1;
172                    }
173                    else
174                    {
175                        q[i,j] = 0;
176                    }
177                }
178            }
179           
180            //
181            // unpack Q
182            //
183            for(i=k-1; i>=0; i--)
184            {
185               
186                //
187                // Apply H(i)
188                //
189                vm = m-i;
190                i1_ = (i) - (1);
191                for(i_=1; i_<=vm;i_++)
192                {
193                    v[i_] = qr[i_+i1_,i];
194                }
195                v[1] = 1;
196                creflections.complexapplyreflectionfromtheleft(ref q, tau[i], ref v, i, m-1, 0, qcolumns-1, ref work);
197            }
198        }
199
200
201        /*************************************************************************
202        Unpacking of matrix R from the QR decomposition of a matrix A
203
204        Input parameters:
205            A       -   matrices Q and R in compact form.
206                        Output of CMatrixQR subroutine.
207            M       -   number of rows in given matrix A. M>=0.
208            N       -   number of columns in given matrix A. N>=0.
209
210        Output parameters:
211            R       -   matrix R, array[0..M-1, 0..N-1].
212
213          -- ALGLIB --
214             Copyright 2005 by Bochkanov Sergey
215        *************************************************************************/
216        public static void cmatrixqrunpackr(ref AP.Complex[,] a,
217            int m,
218            int n,
219            ref AP.Complex[,] r)
220        {
221            int i = 0;
222            int k = 0;
223            int i_ = 0;
224
225            if( m<=0 | n<=0 )
226            {
227                return;
228            }
229            k = Math.Min(m, n);
230            r = new AP.Complex[m-1+1, n-1+1];
231            for(i=0; i<=n-1; i++)
232            {
233                r[0,i] = 0;
234            }
235            for(i=1; i<=m-1; i++)
236            {
237                for(i_=0; i_<=n-1;i_++)
238                {
239                    r[i,i_] = r[0,i_];
240                }
241            }
242            for(i=0; i<=k-1; i++)
243            {
244                for(i_=i; i_<=n-1;i_++)
245                {
246                    r[i,i_] = a[i,i_];
247                }
248            }
249        }
250
251
252        public static void complexqrdecomposition(ref AP.Complex[,] a,
253            int m,
254            int n,
255            ref AP.Complex[] tau)
256        {
257            AP.Complex[] work = new AP.Complex[0];
258            AP.Complex[] t = new AP.Complex[0];
259            int i = 0;
260            int k = 0;
261            int mmip1 = 0;
262            int minmn = 0;
263            AP.Complex tmp = 0;
264            int i_ = 0;
265            int i1_ = 0;
266
267            minmn = Math.Min(m, n);
268            work = new AP.Complex[n+1];
269            t = new AP.Complex[m+1];
270            tau = new AP.Complex[minmn+1];
271           
272            //
273            // Test the input arguments
274            //
275            k = Math.Min(m, n);
276            for(i=1; i<=k; i++)
277            {
278               
279                //
280                // Generate elementary reflector H(i) to annihilate A(i+1:m,i)
281                //
282                mmip1 = m-i+1;
283                i1_ = (i) - (1);
284                for(i_=1; i_<=mmip1;i_++)
285                {
286                    t[i_] = a[i_+i1_,i];
287                }
288                creflections.complexgeneratereflection(ref t, mmip1, ref tmp);
289                tau[i] = tmp;
290                i1_ = (1) - (i);
291                for(i_=i; i_<=m;i_++)
292                {
293                    a[i_,i] = t[i_+i1_];
294                }
295                t[1] = 1;
296                if( i<n )
297                {
298                   
299                    //
300                    // Apply H'(i) to A(i:m,i+1:n) from the left
301                    //
302                    creflections.complexapplyreflectionfromtheleft(ref a, AP.Math.Conj(tau[i]), ref t, i, m, i+1, n, ref work);
303                }
304            }
305        }
306
307
308        public static void complexunpackqfromqr(ref AP.Complex[,] qr,
309            int m,
310            int n,
311            ref AP.Complex[] tau,
312            int qcolumns,
313            ref AP.Complex[,] q)
314        {
315            int i = 0;
316            int j = 0;
317            int k = 0;
318            int minmn = 0;
319            AP.Complex[] v = new AP.Complex[0];
320            AP.Complex[] work = new AP.Complex[0];
321            int vm = 0;
322            int i_ = 0;
323            int i1_ = 0;
324
325            System.Diagnostics.Debug.Assert(qcolumns<=m, "UnpackQFromQR: QColumns>M!");
326            if( m==0 | n==0 | qcolumns==0 )
327            {
328                return;
329            }
330           
331            //
332            // init
333            //
334            minmn = Math.Min(m, n);
335            k = Math.Min(minmn, qcolumns);
336            q = new AP.Complex[m+1, qcolumns+1];
337            v = new AP.Complex[m+1];
338            work = new AP.Complex[qcolumns+1];
339            for(i=1; i<=m; i++)
340            {
341                for(j=1; j<=qcolumns; j++)
342                {
343                    if( i==j )
344                    {
345                        q[i,j] = 1;
346                    }
347                    else
348                    {
349                        q[i,j] = 0;
350                    }
351                }
352            }
353           
354            //
355            // unpack Q
356            //
357            for(i=k; i>=1; i--)
358            {
359               
360                //
361                // Apply H(i)
362                //
363                vm = m-i+1;
364                i1_ = (i) - (1);
365                for(i_=1; i_<=vm;i_++)
366                {
367                    v[i_] = qr[i_+i1_,i];
368                }
369                v[1] = 1;
370                creflections.complexapplyreflectionfromtheleft(ref q, tau[i], ref v, i, m, 1, qcolumns, ref work);
371            }
372        }
373
374
375        public static void complexqrdecompositionunpacked(AP.Complex[,] a,
376            int m,
377            int n,
378            ref AP.Complex[,] q,
379            ref AP.Complex[,] r)
380        {
381            int i = 0;
382            int j = 0;
383            int k = 0;
384            int l = 0;
385            int vm = 0;
386            AP.Complex[] tau = new AP.Complex[0];
387            AP.Complex[] work = new AP.Complex[0];
388            AP.Complex[] v = new AP.Complex[0];
389            double tmp = 0;
390            int i_ = 0;
391
392            a = (AP.Complex[,])a.Clone();
393
394            k = Math.Min(m, n);
395            if( n<=0 )
396            {
397                return;
398            }
399            work = new AP.Complex[m+1];
400            v = new AP.Complex[m+1];
401            q = new AP.Complex[m+1, m+1];
402            r = new AP.Complex[m+1, n+1];
403           
404            //
405            // QRDecomposition
406            //
407            complexqrdecomposition(ref a, m, n, ref tau);
408           
409            //
410            // R
411            //
412            for(i=1; i<=n; i++)
413            {
414                r[1,i] = 0;
415            }
416            for(i=2; i<=m; i++)
417            {
418                for(i_=1; i_<=n;i_++)
419                {
420                    r[i,i_] = r[1,i_];
421                }
422            }
423            for(i=1; i<=k; i++)
424            {
425                for(i_=i; i_<=n;i_++)
426                {
427                    r[i,i_] = a[i,i_];
428                }
429            }
430           
431            //
432            // Q
433            //
434            complexunpackqfromqr(ref a, m, n, ref tau, m, ref q);
435        }
436    }
437}
Note: See TracBrowser for help on using the repository browser.