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/creflections.cs @ 2645

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

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

File size: 10.4 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            int knt = 0;
75            AP.Complex alpha = 0;
76            double alphi = 0;
77            double alphr = 0;
78            double beta = 0;
79            double xnorm = 0;
80            double mx = 0;
81            AP.Complex t = 0;
82            int i_ = 0;
83
84            if( n<=0 )
85            {
86                tau = 0;
87                return;
88            }
89            alpha = x[1];
90            mx = 0;
91            for(j=2; j<=n; j++)
92            {
93                mx = Math.Max(AP.Math.AbsComplex(x[j]), mx);
94            }
95            xnorm = 0;
96            if( (double)(mx)!=(double)(0) )
97            {
98                for(j=2; j<=n; j++)
99                {
100                    t = x[j]/mx;
101                    xnorm = xnorm+(t*AP.Math.Conj(t)).x;
102                }
103                xnorm = Math.Sqrt(xnorm)*mx;
104            }
105            alphr = alpha.x;
106            alphi = alpha.y;
107            if( (double)(xnorm)==(double)(0) & (double)(alphi)==(double)(0) )
108            {
109                tau = 0;
110                return;
111            }
112            mx = Math.Max(Math.Abs(alphr), Math.Abs(alphi));
113            mx = Math.Max(mx, Math.Abs(xnorm));
114            beta = -(mx*Math.Sqrt(AP.Math.Sqr(alphr/mx)+AP.Math.Sqr(alphi/mx)+AP.Math.Sqr(xnorm/mx)));
115            if( (double)(alphr)<(double)(0) )
116            {
117                beta = -beta;
118            }
119            tau.x = (beta-alphr)/beta;
120            tau.y = -(alphi/beta);
121            alpha = 1/(alpha-beta);
122            if( n>1 )
123            {
124                for(i_=2; i_<=n;i_++)
125                {
126                    x[i_] = alpha*x[i_];
127                }
128            }
129            alpha = beta;
130            x[1] = alpha;
131        }
132
133
134        /*************************************************************************
135        Application of an elementary reflection to a rectangular matrix of size MxN
136
137        The  algorithm  pre-multiplies  the  matrix  by  an  elementary reflection
138        transformation  which  is  given  by  column  V  and  scalar  Tau (see the
139        description of the GenerateReflection). Not the whole matrix  but  only  a
140        part of it is transformed (rows from M1 to M2, columns from N1 to N2). Only
141        the elements of this submatrix are changed.
142
143        Note: the matrix is multiplied by H, not by H'.   If  it  is  required  to
144        multiply the matrix by H', it is necessary to pass Conj(Tau) instead of Tau.
145
146        Input parameters:
147            C       -   matrix to be transformed.
148            Tau     -   scalar defining transformation.
149            V       -   column defining transformation.
150                        Array whose index ranges within [1..M2-M1+1]
151            M1, M2  -   range of rows to be transformed.
152            N1, N2  -   range of columns to be transformed.
153            WORK    -   working array whose index goes from N1 to N2.
154
155        Output parameters:
156            C       -   the result of multiplying the input matrix C by the
157                        transformation matrix which is given by Tau and V.
158                        If N1>N2 or M1>M2, C is not modified.
159
160          -- LAPACK auxiliary routine (version 3.0) --
161             Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,
162             Courant Institute, Argonne National Lab, and Rice University
163             September 30, 1994
164        *************************************************************************/
165        public static void complexapplyreflectionfromtheleft(ref AP.Complex[,] c,
166            AP.Complex tau,
167            ref AP.Complex[] v,
168            int m1,
169            int m2,
170            int n1,
171            int n2,
172            ref AP.Complex[] work)
173        {
174            AP.Complex t = 0;
175            int i = 0;
176            int vm = 0;
177            int i_ = 0;
178
179            if( tau==0 | n1>n2 | m1>m2 )
180            {
181                return;
182            }
183           
184            //
185            // w := C^T * conj(v)
186            //
187            vm = m2-m1+1;
188            for(i=n1; i<=n2; i++)
189            {
190                work[i] = 0;
191            }
192            for(i=m1; i<=m2; i++)
193            {
194                t = AP.Math.Conj(v[i+1-m1]);
195                for(i_=n1; i_<=n2;i_++)
196                {
197                    work[i_] = work[i_] + t*c[i,i_];
198                }
199            }
200           
201            //
202            // C := C - tau * v * w^T
203            //
204            for(i=m1; i<=m2; i++)
205            {
206                t = v[i-m1+1]*tau;
207                for(i_=n1; i_<=n2;i_++)
208                {
209                    c[i,i_] = c[i,i_] - t*work[i_];
210                }
211            }
212        }
213
214
215        /*************************************************************************
216        Application of an elementary reflection to a rectangular matrix of size MxN
217
218        The  algorithm  post-multiplies  the  matrix  by  an elementary reflection
219        transformation  which  is  given  by  column  V  and  scalar  Tau (see the
220        description  of  the  GenerateReflection). Not the whole matrix but only a
221        part  of  it  is  transformed (rows from M1 to M2, columns from N1 to N2).
222        Only the elements of this submatrix are changed.
223
224        Input parameters:
225            C       -   matrix to be transformed.
226            Tau     -   scalar defining transformation.
227            V       -   column defining transformation.
228                        Array whose index ranges within [1..N2-N1+1]
229            M1, M2  -   range of rows to be transformed.
230            N1, N2  -   range of columns to be transformed.
231            WORK    -   working array whose index goes from M1 to M2.
232
233        Output parameters:
234            C       -   the result of multiplying the input matrix C by the
235                        transformation matrix which is given by Tau and V.
236                        If N1>N2 or M1>M2, C is not modified.
237
238          -- LAPACK auxiliary routine (version 3.0) --
239             Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd.,
240             Courant Institute, Argonne National Lab, and Rice University
241             September 30, 1994
242        *************************************************************************/
243        public static void complexapplyreflectionfromtheright(ref AP.Complex[,] c,
244            AP.Complex tau,
245            ref AP.Complex[] v,
246            int m1,
247            int m2,
248            int n1,
249            int n2,
250            ref AP.Complex[] work)
251        {
252            AP.Complex t = 0;
253            int i = 0;
254            int vm = 0;
255            int i_ = 0;
256            int i1_ = 0;
257
258            if( tau==0 | n1>n2 | m1>m2 )
259            {
260                return;
261            }
262           
263            //
264            // w := C * v
265            //
266            vm = n2-n1+1;
267            for(i=m1; i<=m2; i++)
268            {
269                i1_ = (1)-(n1);
270                t = 0.0;
271                for(i_=n1; i_<=n2;i_++)
272                {
273                    t += c[i,i_]*v[i_+i1_];
274                }
275                work[i] = t;
276            }
277           
278            //
279            // C := C - w * conj(v^T)
280            //
281            for(i_=1; i_<=vm;i_++)
282            {
283                v[i_] = AP.Math.Conj(v[i_]);
284            }
285            for(i=m1; i<=m2; i++)
286            {
287                t = work[i]*tau;
288                i1_ = (1) - (n1);
289                for(i_=n1; i_<=n2;i_++)
290                {
291                    c[i,i_] = c[i,i_] - t*v[i_+i1_];
292                }
293            }
294            for(i_=1; i_<=vm;i_++)
295            {
296                v[i_] = AP.Math.Conj(v[i_]);
297            }
298        }
299    }
300}
Note: See TracBrowser for help on using the repository browser.