Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.ExtLibs/HeuristicLab.ALGLIB/2.3.0/ALGLIB-2.3.0/creflections.cs @ 2806

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

Added plugin for new version of ALGLIB. #875 (Update ALGLIB sources)

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