Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.ExtLibs/HeuristicLab.ALGLIB/2.5.0/ALGLIB-2.5.0/creflections.cs @ 3932

Last change on this file since 3932 was 3839, checked in by mkommend, 15 years ago

implemented first version of LR (ticket #1012)

File size: 11.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 creflections
32    {
33        /*************************************************************************
34        Generation of an elementary complex reflection transformation
35
36        The subroutine generates elementary complex reflection H of  order  N,  so
37        that, for a given X, the following equality holds true:
38
39             ( X(1) )   ( Beta )
40        H' * (  ..  ) = (  0   ),   H'*H = I,   Beta is a real number
41             ( X(n) )   (  0   )
42
43        where
44
45                      ( V(1) )
46        H = 1 - Tau * (  ..  ) * ( conj(V(1)), ..., conj(V(n)) )
47                      ( V(n) )
48
49        where the first component of vector V equals 1.
50
51        Input parameters:
52            X   -   vector. Array with elements [1..N].
53            N   -   reflection order.
54
55        Output parameters:
56            X   -   components from 2 to N are replaced by vector V.
57                    The first component is replaced with parameter Beta.
58            Tau -   scalar value Tau.
59
60        This subroutine is the modification of CLARFG subroutines  from the LAPACK
61        library. It has similar functionality except for the fact that it  doesn’t
62        handle errors when intermediate results cause an overflow.
63
64          -- LAPACK auxiliary routine (version 3.0) --
65             Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,
66             Courant Institute, Argonne National Lab, and Rice University
67             September 30, 1994
68        *************************************************************************/
69        public static void complexgeneratereflection(ref AP.Complex[] x,
70            int n,
71            ref AP.Complex tau)
72        {
73            int j = 0;
74            AP.Complex alpha = 0;
75            double alphi = 0;
76            double alphr = 0;
77            double beta = 0;
78            double xnorm = 0;
79            double mx = 0;
80            AP.Complex t = 0;
81            double s = 0;
82            AP.Complex v = 0;
83            int i_ = 0;
84
85            if( n<=0 )
86            {
87                tau = 0;
88                return;
89            }
90           
91            //
92            // Scale if needed (to avoid overflow/underflow during intermediate
93            // calculations).
94            //
95            mx = 0;
96            for(j=1; j<=n; j++)
97            {
98                mx = Math.Max(AP.Math.AbsComplex(x[j]), mx);
99            }
100            s = 1;
101            if( (double)(mx)!=(double)(0) )
102            {
103                if( (double)(mx)<(double)(1) )
104                {
105                    s = Math.Sqrt(AP.Math.MinRealNumber);
106                    v = 1/s;
107                    for(i_=1; i_<=n;i_++)
108                    {
109                        x[i_] = v*x[i_];
110                    }
111                }
112                else
113                {
114                    s = Math.Sqrt(AP.Math.MaxRealNumber);
115                    v = 1/s;
116                    for(i_=1; i_<=n;i_++)
117                    {
118                        x[i_] = v*x[i_];
119                    }
120                }
121            }
122           
123            //
124            // calculate
125            //
126            alpha = x[1];
127            mx = 0;
128            for(j=2; j<=n; j++)
129            {
130                mx = Math.Max(AP.Math.AbsComplex(x[j]), mx);
131            }
132            xnorm = 0;
133            if( (double)(mx)!=(double)(0) )
134            {
135                for(j=2; j<=n; j++)
136                {
137                    t = x[j]/mx;
138                    xnorm = xnorm+(t*AP.Math.Conj(t)).x;
139                }
140                xnorm = Math.Sqrt(xnorm)*mx;
141            }
142            alphr = alpha.x;
143            alphi = alpha.y;
144            if( (double)(xnorm)==(double)(0) & (double)(alphi)==(double)(0) )
145            {
146                tau = 0;
147                x[1] = x[1]*s;
148                return;
149            }
150            mx = Math.Max(Math.Abs(alphr), Math.Abs(alphi));
151            mx = Math.Max(mx, Math.Abs(xnorm));
152            beta = -(mx*Math.Sqrt(AP.Math.Sqr(alphr/mx)+AP.Math.Sqr(alphi/mx)+AP.Math.Sqr(xnorm/mx)));
153            if( (double)(alphr)<(double)(0) )
154            {
155                beta = -beta;
156            }
157            tau.x = (beta-alphr)/beta;
158            tau.y = -(alphi/beta);
159            alpha = 1/(alpha-beta);
160            if( n>1 )
161            {
162                for(i_=2; i_<=n;i_++)
163                {
164                    x[i_] = alpha*x[i_];
165                }
166            }
167            alpha = beta;
168            x[1] = alpha;
169           
170            //
171            // Scale back
172            //
173            x[1] = x[1]*s;
174        }
175
176
177        /*************************************************************************
178        Application of an elementary reflection to a rectangular matrix of size MxN
179
180        The  algorithm  pre-multiplies  the  matrix  by  an  elementary reflection
181        transformation  which  is  given  by  column  V  and  scalar  Tau (see the
182        description of the GenerateReflection). Not the whole matrix  but  only  a
183        part of it is transformed (rows from M1 to M2, columns from N1 to N2). Only
184        the elements of this submatrix are changed.
185
186        Note: the matrix is multiplied by H, not by H'.   If  it  is  required  to
187        multiply the matrix by H', it is necessary to pass Conj(Tau) instead of Tau.
188
189        Input parameters:
190            C       -   matrix to be transformed.
191            Tau     -   scalar defining transformation.
192            V       -   column defining transformation.
193                        Array whose index ranges within [1..M2-M1+1]
194            M1, M2  -   range of rows to be transformed.
195            N1, N2  -   range of columns to be transformed.
196            WORK    -   working array whose index goes from N1 to N2.
197
198        Output parameters:
199            C       -   the result of multiplying the input matrix C by the
200                        transformation matrix which is given by Tau and V.
201                        If N1>N2 or M1>M2, C is not modified.
202
203          -- LAPACK auxiliary routine (version 3.0) --
204             Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,
205             Courant Institute, Argonne National Lab, and Rice University
206             September 30, 1994
207        *************************************************************************/
208        public static void complexapplyreflectionfromtheleft(ref AP.Complex[,] c,
209            AP.Complex tau,
210            ref AP.Complex[] v,
211            int m1,
212            int m2,
213            int n1,
214            int n2,
215            ref AP.Complex[] work)
216        {
217            AP.Complex t = 0;
218            int i = 0;
219            int vm = 0;
220            int i_ = 0;
221
222            if( tau==0 | n1>n2 | m1>m2 )
223            {
224                return;
225            }
226           
227            //
228            // w := C^T * conj(v)
229            //
230            vm = m2-m1+1;
231            for(i=n1; i<=n2; i++)
232            {
233                work[i] = 0;
234            }
235            for(i=m1; i<=m2; i++)
236            {
237                t = AP.Math.Conj(v[i+1-m1]);
238                for(i_=n1; i_<=n2;i_++)
239                {
240                    work[i_] = work[i_] + t*c[i,i_];
241                }
242            }
243           
244            //
245            // C := C - tau * v * w^T
246            //
247            for(i=m1; i<=m2; i++)
248            {
249                t = v[i-m1+1]*tau;
250                for(i_=n1; i_<=n2;i_++)
251                {
252                    c[i,i_] = c[i,i_] - t*work[i_];
253                }
254            }
255        }
256
257
258        /*************************************************************************
259        Application of an elementary reflection to a rectangular matrix of size MxN
260
261        The  algorithm  post-multiplies  the  matrix  by  an elementary reflection
262        transformation  which  is  given  by  column  V  and  scalar  Tau (see the
263        description  of  the  GenerateReflection). Not the whole matrix but only a
264        part  of  it  is  transformed (rows from M1 to M2, columns from N1 to N2).
265        Only the elements of this submatrix are changed.
266
267        Input parameters:
268            C       -   matrix to be transformed.
269            Tau     -   scalar defining transformation.
270            V       -   column defining transformation.
271                        Array whose index ranges within [1..N2-N1+1]
272            M1, M2  -   range of rows to be transformed.
273            N1, N2  -   range of columns to be transformed.
274            WORK    -   working array whose index goes from M1 to M2.
275
276        Output parameters:
277            C       -   the result of multiplying the input matrix C by the
278                        transformation matrix which is given by Tau and V.
279                        If N1>N2 or M1>M2, C is not modified.
280
281          -- LAPACK auxiliary routine (version 3.0) --
282             Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,
283             Courant Institute, Argonne National Lab, and Rice University
284             September 30, 1994
285        *************************************************************************/
286        public static void complexapplyreflectionfromtheright(ref AP.Complex[,] c,
287            AP.Complex tau,
288            ref AP.Complex[] v,
289            int m1,
290            int m2,
291            int n1,
292            int n2,
293            ref AP.Complex[] work)
294        {
295            AP.Complex t = 0;
296            int i = 0;
297            int vm = 0;
298            int i_ = 0;
299            int i1_ = 0;
300
301            if( tau==0 | n1>n2 | m1>m2 )
302            {
303                return;
304            }
305           
306            //
307            // w := C * v
308            //
309            vm = n2-n1+1;
310            for(i=m1; i<=m2; i++)
311            {
312                i1_ = (1)-(n1);
313                t = 0.0;
314                for(i_=n1; i_<=n2;i_++)
315                {
316                    t += c[i,i_]*v[i_+i1_];
317                }
318                work[i] = t;
319            }
320           
321            //
322            // C := C - w * conj(v^T)
323            //
324            for(i_=1; i_<=vm;i_++)
325            {
326                v[i_] = AP.Math.Conj(v[i_]);
327            }
328            for(i=m1; i<=m2; i++)
329            {
330                t = work[i]*tau;
331                i1_ = (1) - (n1);
332                for(i_=n1; i_<=n2;i_++)
333                {
334                    c[i,i_] = c[i,i_] - t*v[i_+i1_];
335                }
336            }
337            for(i_=1; i_<=vm;i_++)
338            {
339                v[i_] = AP.Math.Conj(v[i_]);
340            }
341        }
342    }
343}
Note: See TracBrowser for help on using the repository browser.