Free cookie consent management tool by TermsFeed Policy Generator

source: branches/CEDMA-Exporter-715/sources/HeuristicLab.LinearRegression/3.2/alglib/svd.cs @ 3494

Last change on this file since 3494 was 2154, checked in by gkronber, 16 years ago

Added linear regression plugin. #697

File size: 25.0 KB
Line 
1/*************************************************************************
2Copyright (c) 2005-2007, Sergey Bochkanov (ALGLIB project).
3
4Redistribution and use in source and binary forms, with or without
5modification, are permitted provided that the following conditions are
6met:
7
8- Redistributions of source code must retain the above copyright
9  notice, this list of conditions and the following disclaimer.
10
11- Redistributions in binary form must reproduce the above copyright
12  notice, this list of conditions and the following disclaimer listed
13  in this license in the documentation and/or other materials
14  provided with the distribution.
15
16- Neither the name of the copyright holders nor the names of its
17  contributors may be used to endorse or promote products derived from
18  this software without specific prior written permission.
19
20THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31*************************************************************************/
32
33using System;
34
35class svd
36{
37    /*************************************************************************
38    Singular value decomposition of a rectangular matrix.
39
40    The algorithm calculates the singular value decomposition of a matrix of
41    size MxN: A = U * S * V^T
42
43    The algorithm finds the singular values and, optionally, matrices U and V^T.
44    The algorithm can find both first min(M,N) columns of matrix U and rows of
45    matrix V^T (singular vectors), and matrices U and V^T wholly (of sizes MxM
46    and NxN respectively).
47
48    Take into account that the subroutine does not return matrix V but V^T.
49
50    Input parameters:
51        A           -   matrix to be decomposed.
52                        Array whose indexes range within [0..M-1, 0..N-1].
53        M           -   number of rows in matrix A.
54        N           -   number of columns in matrix A.
55        UNeeded     -   0, 1 or 2. See the description of the parameter U.
56        VTNeeded    -   0, 1 or 2. See the description of the parameter VT.
57        AdditionalMemory -
58                        If the parameter:
59                         * equals 0, the algorithm doesn’t use additional
60                           memory (lower requirements, lower performance).
61                         * equals 1, the algorithm uses additional
62                           memory of size min(M,N)*min(M,N) of real numbers.
63                           It often speeds up the algorithm.
64                         * equals 2, the algorithm uses additional
65                           memory of size M*min(M,N) of real numbers.
66                           It allows to get a maximum performance.
67                        The recommended value of the parameter is 2.
68
69    Output parameters:
70        W           -   contains singular values in descending order.
71        U           -   if UNeeded=0, U isn't changed, the left singular vectors
72                        are not calculated.
73                        if Uneeded=1, U contains left singular vectors (first
74                        min(M,N) columns of matrix U). Array whose indexes range
75                        within [0..M-1, 0..Min(M,N)-1].
76                        if UNeeded=2, U contains matrix U wholly. Array whose
77                        indexes range within [0..M-1, 0..M-1].
78        VT          -   if VTNeeded=0, VT isn’t changed, the right singular vectors
79                        are not calculated.
80                        if VTNeeded=1, VT contains right singular vectors (first
81                        min(M,N) rows of matrix V^T). Array whose indexes range
82                        within [0..min(M,N)-1, 0..N-1].
83                        if VTNeeded=2, VT contains matrix V^T wholly. Array whose
84                        indexes range within [0..N-1, 0..N-1].
85
86      -- ALGLIB --
87         Copyright 2005 by Bochkanov Sergey
88    *************************************************************************/
89    public static bool rmatrixsvd(double[,] a,
90        int m,
91        int n,
92        int uneeded,
93        int vtneeded,
94        int additionalmemory,
95        ref double[] w,
96        ref double[,] u,
97        ref double[,] vt)
98    {
99        bool result = new bool();
100        double[] tauq = new double[0];
101        double[] taup = new double[0];
102        double[] tau = new double[0];
103        double[] e = new double[0];
104        double[] work = new double[0];
105        double[,] t2 = new double[0,0];
106        bool isupper = new bool();
107        int minmn = 0;
108        int ncu = 0;
109        int nrvt = 0;
110        int nru = 0;
111        int ncvt = 0;
112        int i = 0;
113        int j = 0;
114        int im1 = 0;
115        double sm = 0;
116
117        a = (double[,])a.Clone();
118
119        result = true;
120        if( m==0 | n==0 )
121        {
122            return result;
123        }
124        System.Diagnostics.Debug.Assert(uneeded>=0 & uneeded<=2, "SVDDecomposition: wrong parameters!");
125        System.Diagnostics.Debug.Assert(vtneeded>=0 & vtneeded<=2, "SVDDecomposition: wrong parameters!");
126        System.Diagnostics.Debug.Assert(additionalmemory>=0 & additionalmemory<=2, "SVDDecomposition: wrong parameters!");
127       
128        //
129        // initialize
130        //
131        minmn = Math.Min(m, n);
132        w = new double[minmn+1];
133        ncu = 0;
134        nru = 0;
135        if( uneeded==1 )
136        {
137            nru = m;
138            ncu = minmn;
139            u = new double[nru-1+1, ncu-1+1];
140        }
141        if( uneeded==2 )
142        {
143            nru = m;
144            ncu = m;
145            u = new double[nru-1+1, ncu-1+1];
146        }
147        nrvt = 0;
148        ncvt = 0;
149        if( vtneeded==1 )
150        {
151            nrvt = minmn;
152            ncvt = n;
153            vt = new double[nrvt-1+1, ncvt-1+1];
154        }
155        if( vtneeded==2 )
156        {
157            nrvt = n;
158            ncvt = n;
159            vt = new double[nrvt-1+1, ncvt-1+1];
160        }
161       
162        //
163        // M much larger than N
164        // Use bidiagonal reduction with QR-decomposition
165        //
166        if( m>1.6*n )
167        {
168            if( uneeded==0 )
169            {
170               
171                //
172                // No left singular vectors to be computed
173                //
174                qr.rmatrixqr(ref a, m, n, ref tau);
175                for(i=0; i<=n-1; i++)
176                {
177                    for(j=0; j<=i-1; j++)
178                    {
179                        a[i,j] = 0;
180                    }
181                }
182                bidiagonal.rmatrixbd(ref a, n, n, ref tauq, ref taup);
183                bidiagonal.rmatrixbdunpackpt(ref a, n, n, ref taup, nrvt, ref vt);
184                bidiagonal.rmatrixbdunpackdiagonals(ref a, n, n, ref isupper, ref w, ref e);
185                result = bdsvd.rmatrixbdsvd(ref w, e, n, isupper, false, ref u, 0, ref a, 0, ref vt, ncvt);
186                return result;
187            }
188            else
189            {
190               
191                //
192                // Left singular vectors (may be full matrix U) to be computed
193                //
194                qr.rmatrixqr(ref a, m, n, ref tau);
195                qr.rmatrixqrunpackq(ref a, m, n, ref tau, ncu, ref u);
196                for(i=0; i<=n-1; i++)
197                {
198                    for(j=0; j<=i-1; j++)
199                    {
200                        a[i,j] = 0;
201                    }
202                }
203                bidiagonal.rmatrixbd(ref a, n, n, ref tauq, ref taup);
204                bidiagonal.rmatrixbdunpackpt(ref a, n, n, ref taup, nrvt, ref vt);
205                bidiagonal.rmatrixbdunpackdiagonals(ref a, n, n, ref isupper, ref w, ref e);
206                if( additionalmemory<1 )
207                {
208                   
209                    //
210                    // No additional memory can be used
211                    //
212                    bidiagonal.rmatrixbdmultiplybyq(ref a, n, n, ref tauq, ref u, m, n, true, false);
213                    result = bdsvd.rmatrixbdsvd(ref w, e, n, isupper, false, ref u, m, ref a, 0, ref vt, ncvt);
214                }
215                else
216                {
217                   
218                    //
219                    // Large U. Transforming intermediate matrix T2
220                    //
221                    work = new double[Math.Max(m, n)+1];
222                    bidiagonal.rmatrixbdunpackq(ref a, n, n, ref tauq, n, ref t2);
223                    blas.copymatrix(ref u, 0, m-1, 0, n-1, ref a, 0, m-1, 0, n-1);
224                    blas.inplacetranspose(ref t2, 0, n-1, 0, n-1, ref work);
225                    result = bdsvd.rmatrixbdsvd(ref w, e, n, isupper, false, ref u, 0, ref t2, n, ref vt, ncvt);
226                    blas.matrixmatrixmultiply(ref a, 0, m-1, 0, n-1, false, ref t2, 0, n-1, 0, n-1, true, 1.0, ref u, 0, m-1, 0, n-1, 0.0, ref work);
227                }
228                return result;
229            }
230        }
231       
232        //
233        // N much larger than M
234        // Use bidiagonal reduction with LQ-decomposition
235        //
236        if( n>1.6*m )
237        {
238            if( vtneeded==0 )
239            {
240               
241                //
242                // No right singular vectors to be computed
243                //
244                lq.rmatrixlq(ref a, m, n, ref tau);
245                for(i=0; i<=m-1; i++)
246                {
247                    for(j=i+1; j<=m-1; j++)
248                    {
249                        a[i,j] = 0;
250                    }
251                }
252                bidiagonal.rmatrixbd(ref a, m, m, ref tauq, ref taup);
253                bidiagonal.rmatrixbdunpackq(ref a, m, m, ref tauq, ncu, ref u);
254                bidiagonal.rmatrixbdunpackdiagonals(ref a, m, m, ref isupper, ref w, ref e);
255                work = new double[m+1];
256                blas.inplacetranspose(ref u, 0, nru-1, 0, ncu-1, ref work);
257                result = bdsvd.rmatrixbdsvd(ref w, e, m, isupper, false, ref a, 0, ref u, nru, ref vt, 0);
258                blas.inplacetranspose(ref u, 0, nru-1, 0, ncu-1, ref work);
259                return result;
260            }
261            else
262            {
263               
264                //
265                // Right singular vectors (may be full matrix VT) to be computed
266                //
267                lq.rmatrixlq(ref a, m, n, ref tau);
268                lq.rmatrixlqunpackq(ref a, m, n, ref tau, nrvt, ref vt);
269                for(i=0; i<=m-1; i++)
270                {
271                    for(j=i+1; j<=m-1; j++)
272                    {
273                        a[i,j] = 0;
274                    }
275                }
276                bidiagonal.rmatrixbd(ref a, m, m, ref tauq, ref taup);
277                bidiagonal.rmatrixbdunpackq(ref a, m, m, ref tauq, ncu, ref u);
278                bidiagonal.rmatrixbdunpackdiagonals(ref a, m, m, ref isupper, ref w, ref e);
279                work = new double[Math.Max(m, n)+1];
280                blas.inplacetranspose(ref u, 0, nru-1, 0, ncu-1, ref work);
281                if( additionalmemory<1 )
282                {
283                   
284                    //
285                    // No additional memory available
286                    //
287                    bidiagonal.rmatrixbdmultiplybyp(ref a, m, m, ref taup, ref vt, m, n, false, true);
288                    result = bdsvd.rmatrixbdsvd(ref w, e, m, isupper, false, ref a, 0, ref u, nru, ref vt, n);
289                }
290                else
291                {
292                   
293                    //
294                    // Large VT. Transforming intermediate matrix T2
295                    //
296                    bidiagonal.rmatrixbdunpackpt(ref a, m, m, ref taup, m, ref t2);
297                    result = bdsvd.rmatrixbdsvd(ref w, e, m, isupper, false, ref a, 0, ref u, nru, ref t2, m);
298                    blas.copymatrix(ref vt, 0, m-1, 0, n-1, ref a, 0, m-1, 0, n-1);
299                    blas.matrixmatrixmultiply(ref t2, 0, m-1, 0, m-1, false, ref a, 0, m-1, 0, n-1, false, 1.0, ref vt, 0, m-1, 0, n-1, 0.0, ref work);
300                }
301                blas.inplacetranspose(ref u, 0, nru-1, 0, ncu-1, ref work);
302                return result;
303            }
304        }
305       
306        //
307        // M<=N
308        // We can use inplace transposition of U to get rid of columnwise operations
309        //
310        if( m<=n )
311        {
312            bidiagonal.rmatrixbd(ref a, m, n, ref tauq, ref taup);
313            bidiagonal.rmatrixbdunpackq(ref a, m, n, ref tauq, ncu, ref u);
314            bidiagonal.rmatrixbdunpackpt(ref a, m, n, ref taup, nrvt, ref vt);
315            bidiagonal.rmatrixbdunpackdiagonals(ref a, m, n, ref isupper, ref w, ref e);
316            work = new double[m+1];
317            blas.inplacetranspose(ref u, 0, nru-1, 0, ncu-1, ref work);
318            result = bdsvd.rmatrixbdsvd(ref w, e, minmn, isupper, false, ref a, 0, ref u, nru, ref vt, ncvt);
319            blas.inplacetranspose(ref u, 0, nru-1, 0, ncu-1, ref work);
320            return result;
321        }
322       
323        //
324        // Simple bidiagonal reduction
325        //
326        bidiagonal.rmatrixbd(ref a, m, n, ref tauq, ref taup);
327        bidiagonal.rmatrixbdunpackq(ref a, m, n, ref tauq, ncu, ref u);
328        bidiagonal.rmatrixbdunpackpt(ref a, m, n, ref taup, nrvt, ref vt);
329        bidiagonal.rmatrixbdunpackdiagonals(ref a, m, n, ref isupper, ref w, ref e);
330        if( additionalmemory<2 | uneeded==0 )
331        {
332           
333            //
334            // We cant use additional memory or there is no need in such operations
335            //
336            result = bdsvd.rmatrixbdsvd(ref w, e, minmn, isupper, false, ref u, nru, ref a, 0, ref vt, ncvt);
337        }
338        else
339        {
340           
341            //
342            // We can use additional memory
343            //
344            t2 = new double[minmn-1+1, m-1+1];
345            blas.copyandtranspose(ref u, 0, m-1, 0, minmn-1, ref t2, 0, minmn-1, 0, m-1);
346            result = bdsvd.rmatrixbdsvd(ref w, e, minmn, isupper, false, ref u, 0, ref t2, m, ref vt, ncvt);
347            blas.copyandtranspose(ref t2, 0, minmn-1, 0, m-1, ref u, 0, m-1, 0, minmn-1);
348        }
349        return result;
350    }
351
352
353    /*************************************************************************
354    Obsolete 1-based subroutine.
355    See RMatrixSVD for 0-based replacement.
356    *************************************************************************/
357    public static bool svddecomposition(double[,] a,
358        int m,
359        int n,
360        int uneeded,
361        int vtneeded,
362        int additionalmemory,
363        ref double[] w,
364        ref double[,] u,
365        ref double[,] vt)
366    {
367        bool result = new bool();
368        double[] tauq = new double[0];
369        double[] taup = new double[0];
370        double[] tau = new double[0];
371        double[] e = new double[0];
372        double[] work = new double[0];
373        double[,] t2 = new double[0,0];
374        bool isupper = new bool();
375        int minmn = 0;
376        int ncu = 0;
377        int nrvt = 0;
378        int nru = 0;
379        int ncvt = 0;
380        int i = 0;
381        int j = 0;
382        int im1 = 0;
383        double sm = 0;
384
385        a = (double[,])a.Clone();
386
387        result = true;
388        if( m==0 | n==0 )
389        {
390            return result;
391        }
392        System.Diagnostics.Debug.Assert(uneeded>=0 & uneeded<=2, "SVDDecomposition: wrong parameters!");
393        System.Diagnostics.Debug.Assert(vtneeded>=0 & vtneeded<=2, "SVDDecomposition: wrong parameters!");
394        System.Diagnostics.Debug.Assert(additionalmemory>=0 & additionalmemory<=2, "SVDDecomposition: wrong parameters!");
395       
396        //
397        // initialize
398        //
399        minmn = Math.Min(m, n);
400        w = new double[minmn+1];
401        ncu = 0;
402        nru = 0;
403        if( uneeded==1 )
404        {
405            nru = m;
406            ncu = minmn;
407            u = new double[nru+1, ncu+1];
408        }
409        if( uneeded==2 )
410        {
411            nru = m;
412            ncu = m;
413            u = new double[nru+1, ncu+1];
414        }
415        nrvt = 0;
416        ncvt = 0;
417        if( vtneeded==1 )
418        {
419            nrvt = minmn;
420            ncvt = n;
421            vt = new double[nrvt+1, ncvt+1];
422        }
423        if( vtneeded==2 )
424        {
425            nrvt = n;
426            ncvt = n;
427            vt = new double[nrvt+1, ncvt+1];
428        }
429       
430        //
431        // M much larger than N
432        // Use bidiagonal reduction with QR-decomposition
433        //
434        if( m>1.6*n )
435        {
436            if( uneeded==0 )
437            {
438               
439                //
440                // No left singular vectors to be computed
441                //
442                qr.qrdecomposition(ref a, m, n, ref tau);
443                for(i=2; i<=n; i++)
444                {
445                    for(j=1; j<=i-1; j++)
446                    {
447                        a[i,j] = 0;
448                    }
449                }
450                bidiagonal.tobidiagonal(ref a, n, n, ref tauq, ref taup);
451                bidiagonal.unpackptfrombidiagonal(ref a, n, n, ref taup, nrvt, ref vt);
452                bidiagonal.unpackdiagonalsfrombidiagonal(ref a, n, n, ref isupper, ref w, ref e);
453                result = bdsvd.bidiagonalsvddecomposition(ref w, e, n, isupper, false, ref u, 0, ref a, 0, ref vt, ncvt);
454                return result;
455            }
456            else
457            {
458               
459                //
460                // Left singular vectors (may be full matrix U) to be computed
461                //
462                qr.qrdecomposition(ref a, m, n, ref tau);
463                qr.unpackqfromqr(ref a, m, n, ref tau, ncu, ref u);
464                for(i=2; i<=n; i++)
465                {
466                    for(j=1; j<=i-1; j++)
467                    {
468                        a[i,j] = 0;
469                    }
470                }
471                bidiagonal.tobidiagonal(ref a, n, n, ref tauq, ref taup);
472                bidiagonal.unpackptfrombidiagonal(ref a, n, n, ref taup, nrvt, ref vt);
473                bidiagonal.unpackdiagonalsfrombidiagonal(ref a, n, n, ref isupper, ref w, ref e);
474                if( additionalmemory<1 )
475                {
476                   
477                    //
478                    // No additional memory can be used
479                    //
480                    bidiagonal.multiplybyqfrombidiagonal(ref a, n, n, ref tauq, ref u, m, n, true, false);
481                    result = bdsvd.bidiagonalsvddecomposition(ref w, e, n, isupper, false, ref u, m, ref a, 0, ref vt, ncvt);
482                }
483                else
484                {
485                   
486                    //
487                    // Large U. Transforming intermediate matrix T2
488                    //
489                    work = new double[Math.Max(m, n)+1];
490                    bidiagonal.unpackqfrombidiagonal(ref a, n, n, ref tauq, n, ref t2);
491                    blas.copymatrix(ref u, 1, m, 1, n, ref a, 1, m, 1, n);
492                    blas.inplacetranspose(ref t2, 1, n, 1, n, ref work);
493                    result = bdsvd.bidiagonalsvddecomposition(ref w, e, n, isupper, false, ref u, 0, ref t2, n, ref vt, ncvt);
494                    blas.matrixmatrixmultiply(ref a, 1, m, 1, n, false, ref t2, 1, n, 1, n, true, 1.0, ref u, 1, m, 1, n, 0.0, ref work);
495                }
496                return result;
497            }
498        }
499       
500        //
501        // N much larger than M
502        // Use bidiagonal reduction with LQ-decomposition
503        //
504        if( n>1.6*m )
505        {
506            if( vtneeded==0 )
507            {
508               
509                //
510                // No right singular vectors to be computed
511                //
512                lq.lqdecomposition(ref a, m, n, ref tau);
513                for(i=1; i<=m-1; i++)
514                {
515                    for(j=i+1; j<=m; j++)
516                    {
517                        a[i,j] = 0;
518                    }
519                }
520                bidiagonal.tobidiagonal(ref a, m, m, ref tauq, ref taup);
521                bidiagonal.unpackqfrombidiagonal(ref a, m, m, ref tauq, ncu, ref u);
522                bidiagonal.unpackdiagonalsfrombidiagonal(ref a, m, m, ref isupper, ref w, ref e);
523                work = new double[m+1];
524                blas.inplacetranspose(ref u, 1, nru, 1, ncu, ref work);
525                result = bdsvd.bidiagonalsvddecomposition(ref w, e, m, isupper, false, ref a, 0, ref u, nru, ref vt, 0);
526                blas.inplacetranspose(ref u, 1, nru, 1, ncu, ref work);
527                return result;
528            }
529            else
530            {
531               
532                //
533                // Right singular vectors (may be full matrix VT) to be computed
534                //
535                lq.lqdecomposition(ref a, m, n, ref tau);
536                lq.unpackqfromlq(ref a, m, n, ref tau, nrvt, ref vt);
537                for(i=1; i<=m-1; i++)
538                {
539                    for(j=i+1; j<=m; j++)
540                    {
541                        a[i,j] = 0;
542                    }
543                }
544                bidiagonal.tobidiagonal(ref a, m, m, ref tauq, ref taup);
545                bidiagonal.unpackqfrombidiagonal(ref a, m, m, ref tauq, ncu, ref u);
546                bidiagonal.unpackdiagonalsfrombidiagonal(ref a, m, m, ref isupper, ref w, ref e);
547                work = new double[Math.Max(m, n)+1];
548                blas.inplacetranspose(ref u, 1, nru, 1, ncu, ref work);
549                if( additionalmemory<1 )
550                {
551                   
552                    //
553                    // No additional memory available
554                    //
555                    bidiagonal.multiplybypfrombidiagonal(ref a, m, m, ref taup, ref vt, m, n, false, true);
556                    result = bdsvd.bidiagonalsvddecomposition(ref w, e, m, isupper, false, ref a, 0, ref u, nru, ref vt, n);
557                }
558                else
559                {
560                   
561                    //
562                    // Large VT. Transforming intermediate matrix T2
563                    //
564                    bidiagonal.unpackptfrombidiagonal(ref a, m, m, ref taup, m, ref t2);
565                    result = bdsvd.bidiagonalsvddecomposition(ref w, e, m, isupper, false, ref a, 0, ref u, nru, ref t2, m);
566                    blas.copymatrix(ref vt, 1, m, 1, n, ref a, 1, m, 1, n);
567                    blas.matrixmatrixmultiply(ref t2, 1, m, 1, m, false, ref a, 1, m, 1, n, false, 1.0, ref vt, 1, m, 1, n, 0.0, ref work);
568                }
569                blas.inplacetranspose(ref u, 1, nru, 1, ncu, ref work);
570                return result;
571            }
572        }
573       
574        //
575        // M<=N
576        // We can use inplace transposition of U to get rid of columnwise operations
577        //
578        if( m<=n )
579        {
580            bidiagonal.tobidiagonal(ref a, m, n, ref tauq, ref taup);
581            bidiagonal.unpackqfrombidiagonal(ref a, m, n, ref tauq, ncu, ref u);
582            bidiagonal.unpackptfrombidiagonal(ref a, m, n, ref taup, nrvt, ref vt);
583            bidiagonal.unpackdiagonalsfrombidiagonal(ref a, m, n, ref isupper, ref w, ref e);
584            work = new double[m+1];
585            blas.inplacetranspose(ref u, 1, nru, 1, ncu, ref work);
586            result = bdsvd.bidiagonalsvddecomposition(ref w, e, minmn, isupper, false, ref a, 0, ref u, nru, ref vt, ncvt);
587            blas.inplacetranspose(ref u, 1, nru, 1, ncu, ref work);
588            return result;
589        }
590       
591        //
592        // Simple bidiagonal reduction
593        //
594        bidiagonal.tobidiagonal(ref a, m, n, ref tauq, ref taup);
595        bidiagonal.unpackqfrombidiagonal(ref a, m, n, ref tauq, ncu, ref u);
596        bidiagonal.unpackptfrombidiagonal(ref a, m, n, ref taup, nrvt, ref vt);
597        bidiagonal.unpackdiagonalsfrombidiagonal(ref a, m, n, ref isupper, ref w, ref e);
598        if( additionalmemory<2 | uneeded==0 )
599        {
600           
601            //
602            // We cant use additional memory or there is no need in such operations
603            //
604            result = bdsvd.bidiagonalsvddecomposition(ref w, e, minmn, isupper, false, ref u, nru, ref a, 0, ref vt, ncvt);
605        }
606        else
607        {
608           
609            //
610            // We can use additional memory
611            //
612            t2 = new double[minmn+1, m+1];
613            blas.copyandtranspose(ref u, 1, m, 1, minmn, ref t2, 1, minmn, 1, m);
614            result = bdsvd.bidiagonalsvddecomposition(ref w, e, minmn, isupper, false, ref u, 0, ref t2, m, ref vt, ncvt);
615            blas.copyandtranspose(ref t2, 1, minmn, 1, m, ref u, 1, m, 1, minmn);
616        }
617        return result;
618    }
619}
Note: See TracBrowser for help on using the repository browser.