Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/ALGLIB/hessenberg.cs @ 2567

Last change on this file since 2567 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: 12.0 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 hessenberg
32    {
33        /*************************************************************************
34        Reduction of a square matrix to  upper Hessenberg form: Q'*A*Q = H,
35        where Q is an orthogonal matrix, H - Hessenberg matrix.
36
37        Input parameters:
38            A       -   matrix A with elements [0..N-1, 0..N-1]
39            N       -   size of matrix A.
40
41        Output parameters:
42            A       -   matrices Q and P in  compact form (see below).
43            Tau     -   array of scalar factors which are used to form matrix Q.
44                        Array whose index ranges within [0..N-2]
45
46        Matrix H is located on the main diagonal, on the lower secondary  diagonal
47        and above the main diagonal of matrix A. The elements which are used to
48        form matrix Q are situated in array Tau and below the lower secondary
49        diagonal of matrix A as follows:
50
51        Matrix Q is represented as a product of elementary reflections
52
53        Q = H(0)*H(2)*...*H(n-2),
54
55        where each H(i) is given by
56
57        H(i) = 1 - tau * v * (v^T)
58
59        where tau is a scalar stored in Tau[I]; v - is a real vector,
60        so that v(0:i) = 0, v(i+1) = 1, v(i+2:n-1) stored in A(i+2:n-1,i).
61
62          -- LAPACK routine (version 3.0) --
63             Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,
64             Courant Institute, Argonne National Lab, and Rice University
65             October 31, 1992
66        *************************************************************************/
67        public static void rmatrixhessenberg(ref double[,] a,
68            int n,
69            ref double[] tau)
70        {
71            int i = 0;
72            double v = 0;
73            double[] t = new double[0];
74            double[] work = new double[0];
75            int i_ = 0;
76            int i1_ = 0;
77
78            System.Diagnostics.Debug.Assert(n>=0, "RMatrixHessenberg: incorrect N!");
79           
80            //
81            // Quick return if possible
82            //
83            if( n<=1 )
84            {
85                return;
86            }
87            tau = new double[n-2+1];
88            t = new double[n+1];
89            work = new double[n-1+1];
90            for(i=0; i<=n-2; i++)
91            {
92               
93                //
94                // Compute elementary reflector H(i) to annihilate A(i+2:ihi,i)
95                //
96                i1_ = (i+1) - (1);
97                for(i_=1; i_<=n-i-1;i_++)
98                {
99                    t[i_] = a[i_+i1_,i];
100                }
101                reflections.generatereflection(ref t, n-i-1, ref v);
102                i1_ = (1) - (i+1);
103                for(i_=i+1; i_<=n-1;i_++)
104                {
105                    a[i_,i] = t[i_+i1_];
106                }
107                tau[i] = v;
108                t[1] = 1;
109               
110                //
111                // Apply H(i) to A(1:ihi,i+1:ihi) from the right
112                //
113                reflections.applyreflectionfromtheright(ref a, v, ref t, 0, n-1, i+1, n-1, ref work);
114               
115                //
116                // Apply H(i) to A(i+1:ihi,i+1:n) from the left
117                //
118                reflections.applyreflectionfromtheleft(ref a, v, ref t, i+1, n-1, i+1, n-1, ref work);
119            }
120        }
121
122
123        /*************************************************************************
124        Unpacking matrix Q which reduces matrix A to upper Hessenberg form
125
126        Input parameters:
127            A   -   output of RMatrixHessenberg subroutine.
128            N   -   size of matrix A.
129            Tau -   scalar factors which are used to form Q.
130                    Output of RMatrixHessenberg subroutine.
131
132        Output parameters:
133            Q   -   matrix Q.
134                    Array whose indexes range within [0..N-1, 0..N-1].
135
136          -- ALGLIB --
137             Copyright 2005 by Bochkanov Sergey
138        *************************************************************************/
139        public static void rmatrixhessenbergunpackq(ref double[,] a,
140            int n,
141            ref double[] tau,
142            ref double[,] q)
143        {
144            int i = 0;
145            int j = 0;
146            double[] v = new double[0];
147            double[] work = new double[0];
148            int i_ = 0;
149            int i1_ = 0;
150
151            if( n==0 )
152            {
153                return;
154            }
155           
156            //
157            // init
158            //
159            q = new double[n-1+1, n-1+1];
160            v = new double[n-1+1];
161            work = new double[n-1+1];
162            for(i=0; i<=n-1; i++)
163            {
164                for(j=0; j<=n-1; j++)
165                {
166                    if( i==j )
167                    {
168                        q[i,j] = 1;
169                    }
170                    else
171                    {
172                        q[i,j] = 0;
173                    }
174                }
175            }
176           
177            //
178            // unpack Q
179            //
180            for(i=0; i<=n-2; i++)
181            {
182               
183                //
184                // Apply H(i)
185                //
186                i1_ = (i+1) - (1);
187                for(i_=1; i_<=n-i-1;i_++)
188                {
189                    v[i_] = a[i_+i1_,i];
190                }
191                v[1] = 1;
192                reflections.applyreflectionfromtheright(ref q, tau[i], ref v, 0, n-1, i+1, n-1, ref work);
193            }
194        }
195
196
197        /*************************************************************************
198        Unpacking matrix H (the result of matrix A reduction to upper Hessenberg form)
199
200        Input parameters:
201            A   -   output of RMatrixHessenberg subroutine.
202            N   -   size of matrix A.
203
204        Output parameters:
205            H   -   matrix H. Array whose indexes range within [0..N-1, 0..N-1].
206
207          -- ALGLIB --
208             Copyright 2005 by Bochkanov Sergey
209        *************************************************************************/
210        public static void rmatrixhessenbergunpackh(ref double[,] a,
211            int n,
212            ref double[,] h)
213        {
214            int i = 0;
215            int j = 0;
216            double[] v = new double[0];
217            double[] work = new double[0];
218            int i_ = 0;
219
220            if( n==0 )
221            {
222                return;
223            }
224            h = new double[n-1+1, n-1+1];
225            for(i=0; i<=n-1; i++)
226            {
227                for(j=0; j<=i-2; j++)
228                {
229                    h[i,j] = 0;
230                }
231                j = Math.Max(0, i-1);
232                for(i_=j; i_<=n-1;i_++)
233                {
234                    h[i,i_] = a[i,i_];
235                }
236            }
237        }
238
239
240        public static void toupperhessenberg(ref double[,] a,
241            int n,
242            ref double[] tau)
243        {
244            int i = 0;
245            int ip1 = 0;
246            int nmi = 0;
247            double v = 0;
248            double[] t = new double[0];
249            double[] work = new double[0];
250            int i_ = 0;
251            int i1_ = 0;
252
253            System.Diagnostics.Debug.Assert(n>=0, "ToUpperHessenberg: incorrect N!");
254           
255            //
256            // Quick return if possible
257            //
258            if( n<=1 )
259            {
260                return;
261            }
262            tau = new double[n-1+1];
263            t = new double[n+1];
264            work = new double[n+1];
265            for(i=1; i<=n-1; i++)
266            {
267               
268                //
269                // Compute elementary reflector H(i) to annihilate A(i+2:ihi,i)
270                //
271                ip1 = i+1;
272                nmi = n-i;
273                i1_ = (ip1) - (1);
274                for(i_=1; i_<=nmi;i_++)
275                {
276                    t[i_] = a[i_+i1_,i];
277                }
278                reflections.generatereflection(ref t, nmi, ref v);
279                i1_ = (1) - (ip1);
280                for(i_=ip1; i_<=n;i_++)
281                {
282                    a[i_,i] = t[i_+i1_];
283                }
284                tau[i] = v;
285                t[1] = 1;
286               
287                //
288                // Apply H(i) to A(1:ihi,i+1:ihi) from the right
289                //
290                reflections.applyreflectionfromtheright(ref a, v, ref t, 1, n, i+1, n, ref work);
291               
292                //
293                // Apply H(i) to A(i+1:ihi,i+1:n) from the left
294                //
295                reflections.applyreflectionfromtheleft(ref a, v, ref t, i+1, n, i+1, n, ref work);
296            }
297        }
298
299
300        public static void unpackqfromupperhessenberg(ref double[,] a,
301            int n,
302            ref double[] tau,
303            ref double[,] q)
304        {
305            int i = 0;
306            int j = 0;
307            double[] v = new double[0];
308            double[] work = new double[0];
309            int ip1 = 0;
310            int nmi = 0;
311            int i_ = 0;
312            int i1_ = 0;
313
314            if( n==0 )
315            {
316                return;
317            }
318           
319            //
320            // init
321            //
322            q = new double[n+1, n+1];
323            v = new double[n+1];
324            work = new double[n+1];
325            for(i=1; i<=n; i++)
326            {
327                for(j=1; j<=n; j++)
328                {
329                    if( i==j )
330                    {
331                        q[i,j] = 1;
332                    }
333                    else
334                    {
335                        q[i,j] = 0;
336                    }
337                }
338            }
339           
340            //
341            // unpack Q
342            //
343            for(i=1; i<=n-1; i++)
344            {
345               
346                //
347                // Apply H(i)
348                //
349                ip1 = i+1;
350                nmi = n-i;
351                i1_ = (ip1) - (1);
352                for(i_=1; i_<=nmi;i_++)
353                {
354                    v[i_] = a[i_+i1_,i];
355                }
356                v[1] = 1;
357                reflections.applyreflectionfromtheright(ref q, tau[i], ref v, 1, n, i+1, n, ref work);
358            }
359        }
360
361
362        public static void unpackhfromupperhessenberg(ref double[,] a,
363            int n,
364            ref double[] tau,
365            ref double[,] h)
366        {
367            int i = 0;
368            int j = 0;
369            double[] v = new double[0];
370            double[] work = new double[0];
371            int i_ = 0;
372
373            if( n==0 )
374            {
375                return;
376            }
377            h = new double[n+1, n+1];
378            for(i=1; i<=n; i++)
379            {
380                for(j=1; j<=i-2; j++)
381                {
382                    h[i,j] = 0;
383                }
384                j = Math.Max(1, i-1);
385                for(i_=j; i_<=n;i_++)
386                {
387                    h[i,i_] = a[i,i_];
388                }
389            }
390        }
391    }
392}
Note: See TracBrowser for help on using the repository browser.