Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.ALGLIB-2.5.0/ALGLIB-2.5.0/rotations.cs @ 5229

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

implemented first version of LR (ticket #1012)

File size: 15.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 rotations
32    {
33        /*************************************************************************
34        Application of a sequence of  elementary rotations to a matrix
35
36        The algorithm pre-multiplies the matrix by a sequence of rotation
37        transformations which is given by arrays C and S. Depending on the value
38        of the IsForward parameter either 1 and 2, 3 and 4 and so on (if IsForward=true)
39        rows are rotated, or the rows N and N-1, N-2 and N-3 and so on, are rotated.
40
41        Not the whole matrix but only a part of it is transformed (rows from M1 to
42        M2, columns from N1 to N2). Only the elements of this submatrix are changed.
43
44        Input parameters:
45            IsForward   -   the sequence of the rotation application.
46            M1,M2       -   the range of rows to be transformed.
47            N1, N2      -   the range of columns to be transformed.
48            C,S         -   transformation coefficients.
49                            Array whose index ranges within [1..M2-M1].
50            A           -   processed matrix.
51            WORK        -   working array whose index ranges within [N1..N2].
52
53        Output parameters:
54            A           -   transformed matrix.
55
56        Utility subroutine.
57        *************************************************************************/
58        public static void applyrotationsfromtheleft(bool isforward,
59            int m1,
60            int m2,
61            int n1,
62            int n2,
63            ref double[] c,
64            ref double[] s,
65            ref double[,] a,
66            ref double[] work)
67        {
68            int j = 0;
69            int jp1 = 0;
70            double ctemp = 0;
71            double stemp = 0;
72            double temp = 0;
73            int i_ = 0;
74
75            if( m1>m2 | n1>n2 )
76            {
77                return;
78            }
79           
80            //
81            // Form  P * A
82            //
83            if( isforward )
84            {
85                if( n1!=n2 )
86                {
87                   
88                    //
89                    // Common case: N1<>N2
90                    //
91                    for(j=m1; j<=m2-1; j++)
92                    {
93                        ctemp = c[j-m1+1];
94                        stemp = s[j-m1+1];
95                        if( (double)(ctemp)!=(double)(1) | (double)(stemp)!=(double)(0) )
96                        {
97                            jp1 = j+1;
98                            for(i_=n1; i_<=n2;i_++)
99                            {
100                                work[i_] = ctemp*a[jp1,i_];
101                            }
102                            for(i_=n1; i_<=n2;i_++)
103                            {
104                                work[i_] = work[i_] - stemp*a[j,i_];
105                            }
106                            for(i_=n1; i_<=n2;i_++)
107                            {
108                                a[j,i_] = ctemp*a[j,i_];
109                            }
110                            for(i_=n1; i_<=n2;i_++)
111                            {
112                                a[j,i_] = a[j,i_] + stemp*a[jp1,i_];
113                            }
114                            for(i_=n1; i_<=n2;i_++)
115                            {
116                                a[jp1,i_] = work[i_];
117                            }
118                        }
119                    }
120                }
121                else
122                {
123                   
124                    //
125                    // Special case: N1=N2
126                    //
127                    for(j=m1; j<=m2-1; j++)
128                    {
129                        ctemp = c[j-m1+1];
130                        stemp = s[j-m1+1];
131                        if( (double)(ctemp)!=(double)(1) | (double)(stemp)!=(double)(0) )
132                        {
133                            temp = a[j+1,n1];
134                            a[j+1,n1] = ctemp*temp-stemp*a[j,n1];
135                            a[j,n1] = stemp*temp+ctemp*a[j,n1];
136                        }
137                    }
138                }
139            }
140            else
141            {
142                if( n1!=n2 )
143                {
144                   
145                    //
146                    // Common case: N1<>N2
147                    //
148                    for(j=m2-1; j>=m1; j--)
149                    {
150                        ctemp = c[j-m1+1];
151                        stemp = s[j-m1+1];
152                        if( (double)(ctemp)!=(double)(1) | (double)(stemp)!=(double)(0) )
153                        {
154                            jp1 = j+1;
155                            for(i_=n1; i_<=n2;i_++)
156                            {
157                                work[i_] = ctemp*a[jp1,i_];
158                            }
159                            for(i_=n1; i_<=n2;i_++)
160                            {
161                                work[i_] = work[i_] - stemp*a[j,i_];
162                            }
163                            for(i_=n1; i_<=n2;i_++)
164                            {
165                                a[j,i_] = ctemp*a[j,i_];
166                            }
167                            for(i_=n1; i_<=n2;i_++)
168                            {
169                                a[j,i_] = a[j,i_] + stemp*a[jp1,i_];
170                            }
171                            for(i_=n1; i_<=n2;i_++)
172                            {
173                                a[jp1,i_] = work[i_];
174                            }
175                        }
176                    }
177                }
178                else
179                {
180                   
181                    //
182                    // Special case: N1=N2
183                    //
184                    for(j=m2-1; j>=m1; j--)
185                    {
186                        ctemp = c[j-m1+1];
187                        stemp = s[j-m1+1];
188                        if( (double)(ctemp)!=(double)(1) | (double)(stemp)!=(double)(0) )
189                        {
190                            temp = a[j+1,n1];
191                            a[j+1,n1] = ctemp*temp-stemp*a[j,n1];
192                            a[j,n1] = stemp*temp+ctemp*a[j,n1];
193                        }
194                    }
195                }
196            }
197        }
198
199
200        /*************************************************************************
201        Application of a sequence of  elementary rotations to a matrix
202
203        The algorithm post-multiplies the matrix by a sequence of rotation
204        transformations which is given by arrays C and S. Depending on the value
205        of the IsForward parameter either 1 and 2, 3 and 4 and so on (if IsForward=true)
206        rows are rotated, or the rows N and N-1, N-2 and N-3 and so on are rotated.
207
208        Not the whole matrix but only a part of it is transformed (rows from M1
209        to M2, columns from N1 to N2). Only the elements of this submatrix are changed.
210
211        Input parameters:
212            IsForward   -   the sequence of the rotation application.
213            M1,M2       -   the range of rows to be transformed.
214            N1, N2      -   the range of columns to be transformed.
215            C,S         -   transformation coefficients.
216                            Array whose index ranges within [1..N2-N1].
217            A           -   processed matrix.
218            WORK        -   working array whose index ranges within [M1..M2].
219
220        Output parameters:
221            A           -   transformed matrix.
222
223        Utility subroutine.
224        *************************************************************************/
225        public static void applyrotationsfromtheright(bool isforward,
226            int m1,
227            int m2,
228            int n1,
229            int n2,
230            ref double[] c,
231            ref double[] s,
232            ref double[,] a,
233            ref double[] work)
234        {
235            int j = 0;
236            int jp1 = 0;
237            double ctemp = 0;
238            double stemp = 0;
239            double temp = 0;
240            int i_ = 0;
241
242           
243            //
244            // Form A * P'
245            //
246            if( isforward )
247            {
248                if( m1!=m2 )
249                {
250                   
251                    //
252                    // Common case: M1<>M2
253                    //
254                    for(j=n1; j<=n2-1; j++)
255                    {
256                        ctemp = c[j-n1+1];
257                        stemp = s[j-n1+1];
258                        if( (double)(ctemp)!=(double)(1) | (double)(stemp)!=(double)(0) )
259                        {
260                            jp1 = j+1;
261                            for(i_=m1; i_<=m2;i_++)
262                            {
263                                work[i_] = ctemp*a[i_,jp1];
264                            }
265                            for(i_=m1; i_<=m2;i_++)
266                            {
267                                work[i_] = work[i_] - stemp*a[i_,j];
268                            }
269                            for(i_=m1; i_<=m2;i_++)
270                            {
271                                a[i_,j] = ctemp*a[i_,j];
272                            }
273                            for(i_=m1; i_<=m2;i_++)
274                            {
275                                a[i_,j] = a[i_,j] + stemp*a[i_,jp1];
276                            }
277                            for(i_=m1; i_<=m2;i_++)
278                            {
279                                a[i_,jp1] = work[i_];
280                            }
281                        }
282                    }
283                }
284                else
285                {
286                   
287                    //
288                    // Special case: M1=M2
289                    //
290                    for(j=n1; j<=n2-1; j++)
291                    {
292                        ctemp = c[j-n1+1];
293                        stemp = s[j-n1+1];
294                        if( (double)(ctemp)!=(double)(1) | (double)(stemp)!=(double)(0) )
295                        {
296                            temp = a[m1,j+1];
297                            a[m1,j+1] = ctemp*temp-stemp*a[m1,j];
298                            a[m1,j] = stemp*temp+ctemp*a[m1,j];
299                        }
300                    }
301                }
302            }
303            else
304            {
305                if( m1!=m2 )
306                {
307                   
308                    //
309                    // Common case: M1<>M2
310                    //
311                    for(j=n2-1; j>=n1; j--)
312                    {
313                        ctemp = c[j-n1+1];
314                        stemp = s[j-n1+1];
315                        if( (double)(ctemp)!=(double)(1) | (double)(stemp)!=(double)(0) )
316                        {
317                            jp1 = j+1;
318                            for(i_=m1; i_<=m2;i_++)
319                            {
320                                work[i_] = ctemp*a[i_,jp1];
321                            }
322                            for(i_=m1; i_<=m2;i_++)
323                            {
324                                work[i_] = work[i_] - stemp*a[i_,j];
325                            }
326                            for(i_=m1; i_<=m2;i_++)
327                            {
328                                a[i_,j] = ctemp*a[i_,j];
329                            }
330                            for(i_=m1; i_<=m2;i_++)
331                            {
332                                a[i_,j] = a[i_,j] + stemp*a[i_,jp1];
333                            }
334                            for(i_=m1; i_<=m2;i_++)
335                            {
336                                a[i_,jp1] = work[i_];
337                            }
338                        }
339                    }
340                }
341                else
342                {
343                   
344                    //
345                    // Special case: M1=M2
346                    //
347                    for(j=n2-1; j>=n1; j--)
348                    {
349                        ctemp = c[j-n1+1];
350                        stemp = s[j-n1+1];
351                        if( (double)(ctemp)!=(double)(1) | (double)(stemp)!=(double)(0) )
352                        {
353                            temp = a[m1,j+1];
354                            a[m1,j+1] = ctemp*temp-stemp*a[m1,j];
355                            a[m1,j] = stemp*temp+ctemp*a[m1,j];
356                        }
357                    }
358                }
359            }
360        }
361
362
363        /*************************************************************************
364        The subroutine generates the elementary rotation, so that:
365
366        [  CS  SN  ]  .  [ F ]  =  [ R ]
367        [ -SN  CS  ]     [ G ]     [ 0 ]
368
369        CS**2 + SN**2 = 1
370        *************************************************************************/
371        public static void generaterotation(double f,
372            double g,
373            ref double cs,
374            ref double sn,
375            ref double r)
376        {
377            double f1 = 0;
378            double g1 = 0;
379
380            if( (double)(g)==(double)(0) )
381            {
382                cs = 1;
383                sn = 0;
384                r = f;
385            }
386            else
387            {
388                if( (double)(f)==(double)(0) )
389                {
390                    cs = 0;
391                    sn = 1;
392                    r = g;
393                }
394                else
395                {
396                    f1 = f;
397                    g1 = g;
398                    if( (double)(Math.Abs(f1))>(double)(Math.Abs(g1)) )
399                    {
400                        r = Math.Abs(f1)*Math.Sqrt(1+AP.Math.Sqr(g1/f1));
401                    }
402                    else
403                    {
404                        r = Math.Abs(g1)*Math.Sqrt(1+AP.Math.Sqr(f1/g1));
405                    }
406                    cs = f1/r;
407                    sn = g1/r;
408                    if( (double)(Math.Abs(f))>(double)(Math.Abs(g)) & (double)(cs)<(double)(0) )
409                    {
410                        cs = -cs;
411                        sn = -sn;
412                        r = -r;
413                    }
414                }
415            }
416        }
417    }
418}
Note: See TracBrowser for help on using the repository browser.