Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.Problems.GaussianProcessTuning/ILNumerics.2.14.4735.573/Functions/builtin/Svd.cs @ 10355

Last change on this file since 10355 was 9102, checked in by gkronber, 12 years ago

#1967: ILNumerics source for experimentation

File size: 34.8 KB
Line 
1///
2///    This file is part of ILNumerics Community Edition.
3///
4///    ILNumerics Community Edition - high performance computing for applications.
5///    Copyright (C) 2006 - 2012 Haymo Kutschbach, http://ilnumerics.net
6///
7///    ILNumerics Community Edition is free software: you can redistribute it and/or modify
8///    it under the terms of the GNU General Public License version 3 as published by
9///    the Free Software Foundation.
10///
11///    ILNumerics Community Edition is distributed in the hope that it will be useful,
12///    but WITHOUT ANY WARRANTY; without even the implied warranty of
13///    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14///    GNU General Public License for more details.
15///
16///    You should have received a copy of the GNU General Public License
17///    along with ILNumerics Community Edition. See the file License.txt in the root
18///    of your distribution package. If not, see <http://www.gnu.org/licenses/>.
19///
20///    In addition this software uses the following components and/or licenses:
21///
22///    =================================================================================
23///    The Open Toolkit Library License
24///   
25///    Copyright (c) 2006 - 2009 the Open Toolkit library.
26///   
27///    Permission is hereby granted, free of charge, to any person obtaining a copy
28///    of this software and associated documentation files (the "Software"), to deal
29///    in the Software without restriction, including without limitation the rights to
30///    use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
31///    the Software, and to permit persons to whom the Software is furnished to do
32///    so, subject to the following conditions:
33///
34///    The above copyright notice and this permission notice shall be included in all
35///    copies or substantial portions of the Software.
36///
37///    =================================================================================
38///   
39
40using System;
41using System.Collections.Generic;
42using System.Text;
43using ILNumerics.Storage;
44using ILNumerics.Misc;
45using ILNumerics.Exceptions;
46
47
48namespace ILNumerics {
49    public partial class ILMath {
50
51        /// <summary>
52        /// Singular value decomposition
53        /// </summary>
54        /// <param name="A">Input matrix A</param>
55        /// <returns>Vector with min(M,N) singular values of A as column vector</returns>
56        public static ILRetArray< double > svd(ILInArray< double > A) {
57            return svd(A,null, null, false, false);
58        }
59
60#region HYCALPER AUTO GENERATED CODE
61
62        /// <summary>
63        /// Singular value decomposition
64        /// </summary>
65        /// <param name="A">Input matrix A</param>
66        /// <returns>Vector with min(M,N) singular values of A as column vector</returns>
67        public static ILRetArray< float > svd(ILInArray< float > A) {
68            return svd(A,null, null, false, false);
69        }
70        /// <summary>
71        /// Singular value decomposition
72        /// </summary>
73        /// <param name="A">Input matrix A</param>
74        /// <returns>Vector with min(M,N) singular values of A as column vector</returns>
75        public static ILRetArray< float > svd(ILInArray< fcomplex > A) {
76            return svd(A,null, null, false, false);
77        }
78        /// <summary>
79        /// Singular value decomposition
80        /// </summary>
81        /// <param name="A">Input matrix A</param>
82        /// <returns>Vector with min(M,N) singular values of A as column vector</returns>
83        public static ILRetArray< double > svd(ILInArray< complex > A) {
84            return svd(A,null, null, false, false);
85        }
86
87#endregion HYCALPER AUTO GENERATED CODE
88
89
90        /// <summary>
91        /// Singular value decomposition
92        /// </summary>
93        /// <param name="A">Input matrix</param>
94        /// <param name="U">[Output] Left singular vectors of A as columns of matrix U.
95        /// Setting this parameter to a non-null value signals the need of returning those values.</param>
96        /// <returns>Singluar values as diagonal matrix of same size and type as A</returns>
97        public static ILRetArray< double > svd(ILInArray< double > A, ILOutArray< double > U) {
98            return svd(A, U, null , false,false);
99        }
100
101#region HYCALPER AUTO GENERATED CODE
102
103        /// <summary>
104        /// Singular value decomposition
105        /// </summary>
106        /// <param name="A">Input matrix</param>
107        /// <param name="U">[Output] Left singular vectors of A as columns of matrix U.
108        /// Setting this parameter to a non-null value signals the need of returning those values.</param>
109        /// <returns>Singluar values as diagonal matrix of same size and type as A</returns>
110        public static ILRetArray< float > svd(ILInArray< float > A, ILOutArray< float > U) {
111            return svd(A, U, null , false,false);
112        }
113        /// <summary>
114        /// Singular value decomposition
115        /// </summary>
116        /// <param name="A">Input matrix</param>
117        /// <param name="U">[Output] Left singular vectors of A as columns of matrix U.
118        /// Setting this parameter to a non-null value signals the need of returning those values.</param>
119        /// <returns>Singluar values as diagonal matrix of same size and type as A</returns>
120        public static ILRetArray< float > svd(ILInArray< fcomplex > A, ILOutArray< fcomplex > U) {
121            return svd(A, U, null , false,false);
122        }
123        /// <summary>
124        /// Singular value decomposition
125        /// </summary>
126        /// <param name="A">Input matrix</param>
127        /// <param name="U">[Output] Left singular vectors of A as columns of matrix U.
128        /// Setting this parameter to a non-null value signals the need of returning those values.</param>
129        /// <returns>Singluar values as diagonal matrix of same size and type as A</returns>
130        public static ILRetArray< double > svd(ILInArray< complex > A, ILOutArray< complex > U) {
131            return svd(A, U, null , false,false);
132        }
133
134#endregion HYCALPER AUTO GENERATED CODE
135
136
137        /// <summary>
138        /// Singular value decomposition
139        /// </summary>
140        /// <param name="A">Input matrix</param>
141        /// <param name="outU">[Output] Left singular vectors of A as columns of matrix outU.
142        /// Setting this parameter to a non-null value (e.g. 'empty') signals the need of returning those values.</param>
143        /// <param name="small">If true: return only first min(M,N) columns of outU will be
144        /// of size [min(M,N),min(M,N)]</param>
145        /// <returns>Singluar values as diagonal matrix of same size and type as A</returns>
146        public static ILRetArray< double > svd(ILInArray< double > A, ILOutArray< double > outU, bool small) {
147            return svd(A, outU, null, small,false);
148        }
149
150#region HYCALPER AUTO GENERATED CODE
151
152        /// <summary>
153        /// Singular value decomposition
154        /// </summary>
155        /// <param name="A">Input matrix</param>
156        /// <param name="outU">[Output] Left singular vectors of A as columns of matrix outU.
157        /// Setting this parameter to a non-null value (e.g. 'empty') signals the need of returning those values.</param>
158        /// <param name="small">If true: return only first min(M,N) columns of outU will be
159        /// of size [min(M,N),min(M,N)]</param>
160        /// <returns>Singluar values as diagonal matrix of same size and type as A</returns>
161        public static ILRetArray< float > svd(ILInArray< float > A, ILOutArray< float > outU, bool small) {
162            return svd(A, outU, null, small,false);
163        }
164        /// <summary>
165        /// Singular value decomposition
166        /// </summary>
167        /// <param name="A">Input matrix</param>
168        /// <param name="outU">[Output] Left singular vectors of A as columns of matrix outU.
169        /// Setting this parameter to a non-null value (e.g. 'empty') signals the need of returning those values.</param>
170        /// <param name="small">If true: return only first min(M,N) columns of outU will be
171        /// of size [min(M,N),min(M,N)]</param>
172        /// <returns>Singluar values as diagonal matrix of same size and type as A</returns>
173        public static ILRetArray< float > svd(ILInArray< fcomplex > A, ILOutArray< fcomplex > outU, bool small) {
174            return svd(A, outU, null, small,false);
175        }
176        /// <summary>
177        /// Singular value decomposition
178        /// </summary>
179        /// <param name="A">Input matrix</param>
180        /// <param name="outU">[Output] Left singular vectors of A as columns of matrix outU.
181        /// Setting this parameter to a non-null value (e.g. 'empty') signals the need of returning those values.</param>
182        /// <param name="small">If true: return only first min(M,N) columns of outU will be
183        /// of size [min(M,N),min(M,N)]</param>
184        /// <returns>Singluar values as diagonal matrix of same size and type as A</returns>
185        public static ILRetArray< double > svd(ILInArray< complex > A, ILOutArray< complex > outU, bool small) {
186            return svd(A, outU, null, small,false);
187        }
188
189#endregion HYCALPER AUTO GENERATED CODE
190       
191
192        /// <summary>
193        /// Singular value decomposition
194        /// </summary>
195        /// <param name="A">Input matrix</param>
196        /// <param name="outU">[Output] Left singular vectors of A as columns of matrix U.
197        /// Setting this parameter to a non-null value signals the need of returning those values.</param>
198        /// <param name="outV">[Output] Right singular vectors of X as rows of matrix V.
199        /// This parameter must not be null. It might be an empty array on input.</param>
200        /// <returns>Singluar values as diagonal matrix of same size and type as A</returns>
201        public static ILRetArray< double > svd(ILInArray< double > A, ILOutArray< double > outU, ILOutArray< double > outV) {
202            return svd(A, outU, outV, false,false);
203        }
204
205#region HYCALPER AUTO GENERATED CODE
206
207        /// <summary>
208        /// Singular value decomposition
209        /// </summary>
210        /// <param name="A">Input matrix</param>
211        /// <param name="outU">[Output] Left singular vectors of A as columns of matrix U.
212        /// Setting this parameter to a non-null value signals the need of returning those values.</param>
213        /// <param name="outV">[Output] Right singular vectors of X as rows of matrix V.
214        /// This parameter must not be null. It might be an empty array on input.</param>
215        /// <returns>Singluar values as diagonal matrix of same size and type as A</returns>
216        public static ILRetArray< float > svd(ILInArray< float > A, ILOutArray< float > outU, ILOutArray< float > outV) {
217            return svd(A, outU, outV, false,false);
218        }
219        /// <summary>
220        /// Singular value decomposition
221        /// </summary>
222        /// <param name="A">Input matrix</param>
223        /// <param name="outU">[Output] Left singular vectors of A as columns of matrix U.
224        /// Setting this parameter to a non-null value signals the need of returning those values.</param>
225        /// <param name="outV">[Output] Right singular vectors of X as rows of matrix V.
226        /// This parameter must not be null. It might be an empty array on input.</param>
227        /// <returns>Singluar values as diagonal matrix of same size and type as A</returns>
228        public static ILRetArray< float > svd(ILInArray< fcomplex > A, ILOutArray< fcomplex > outU, ILOutArray< fcomplex > outV) {
229            return svd(A, outU, outV, false,false);
230        }
231        /// <summary>
232        /// Singular value decomposition
233        /// </summary>
234        /// <param name="A">Input matrix</param>
235        /// <param name="outU">[Output] Left singular vectors of A as columns of matrix U.
236        /// Setting this parameter to a non-null value signals the need of returning those values.</param>
237        /// <param name="outV">[Output] Right singular vectors of X as rows of matrix V.
238        /// This parameter must not be null. It might be an empty array on input.</param>
239        /// <returns>Singluar values as diagonal matrix of same size and type as A</returns>
240        public static ILRetArray< double > svd(ILInArray< complex > A, ILOutArray< complex > outU, ILOutArray< complex > outV) {
241            return svd(A, outU, outV, false,false);
242        }
243
244#endregion HYCALPER AUTO GENERATED CODE
245
246
247        /// <summary>
248        /// singular value decomposition
249        /// </summary>
250        /// <param name="A">Input matrix</param>
251        /// <param name="outU">[Output] Left singular vectors of A as columns of matrix outU.
252        /// Setting this parameter to a non-null value signals the need of returning those values.</param>
253        /// <param name="outV">[Output] Right singular vectors of X as rows of matrix outV.
254        /// This parameter must not be null. It might be an empty array on input.</param>
255        /// <param name="small">If true: return only first min(M,N) columns of outU and S (returned) will be
256        /// of size [min(M,N),min(M,N)]</param>
257        /// <param name="discardFiniteTest">If true: the matrix given will not be checked for infinte or NaN values. If such elements
258        /// exist nevertheless, this may result in failing convergence or error. In worst case
259        /// the function may hang inside the Lapack lib! Use with care! </param>
260        /// <returns>Singular values as diagonal matrix of same size and type as A</returns>
261        public static ILRetArray< double> svd( ILInArray< double> A, ILOutArray< double> outU,
262                                                                ILOutArray< double> outV, bool small, bool discardFiniteTest ) {
263            if (object.Equals(A,null))
264                throw new ILArgumentException("input matrix X must not be null");
265            using (ILScope.Enter(A)) {
266               
267                if (!A.IsMatrix)
268                    throw new ILArgumentSizeException("svd is defined for matrices only");
269                // early exit for small matrices
270                if (A.Size[1] < 4 && A.Size[0] == A.Size[1]) {
271                    switch (A.Size[0]) {
272                        case 1:
273                            if (!Object.Equals(outU, null))
274                                outU.a = ( double)1.0;
275                            if (!Object.Equals(outV, null))
276                                outV.a = ( double)1.0;
277                            return abs(A);
278                        //case 2:
279                        //    return -1;
280                        //case 3:
281                        //    return -1;
282                    }
283                }
284                if (!discardFiniteTest && !allall(isfinite(A)))
285                    throw new ILArgumentException("svd: input must have only finite elements");
286                if (Lapack == null)
287                    throw new ILMathException("no Lapack package available");
288                // parameter evaluation
289                int M = A.Size[0]; int N = A.Size[1];
290                int minMN = (M < N) ? M : N;
291                int LDU = M; int LDVT = N;
292                int LDA = M, lenDU = 0, lenVT = 0;
293               
294                double[] dS = ILMemoryPool.Pool.New<  double>(minMN);
295                char jobz = (small) ? 'S' : 'A';
296               
297                double[] dU = null;
298               
299                double[] dVT = null;
300                int info = 0;
301                if (!Object.Equals(outU, null) || !Object.Equals(outV, null)) {
302                    // need to return U and VT
303                    if (small) {
304                        lenDU = M * minMN;
305                        dU = ILMemoryPool.Pool.New<  double>(lenDU);
306                        lenVT = N * minMN;
307                        dVT = ILMemoryPool.Pool.New<  double>(lenVT);
308                    } else {
309                        lenDU = M * M;
310                        dU = ILMemoryPool.Pool.New<  double>(lenDU);
311                        lenVT = N * N;
312                        dVT = ILMemoryPool.Pool.New<  double>(lenVT);
313                    }
314                } else {
315                    jobz = 'N';
316                }
317
318                // must create copy of input !
319               
320                double[] dInput = A.C.GetArrayForWrite();
321                /*!HC:lapack_dgesdd*/
322                Lapack.dgesdd(jobz, M, N, dInput, LDA, dS, dU, LDU, dVT, LDVT, ref info);
323                if (info < 0)
324                    throw new ILArgumentException("the " + (-info).ToString() + "th argument to SVD was invalid");
325                if (info > 0)
326                    throw new ILArgumentException("svd was not converging");
327                ILArray< double> ret = empty<double>(ILSize.Empty00);
328                if (info == 0) {
329                    // success
330                    if (!Object.Equals(outU, null) || !Object.Equals(outV, null)) {
331                        if (small) {
332                            ret.a = zeros< double>(new ILSize(minMN, minMN));
333                        } else {
334                            ret.a = zeros< double>(new ILSize(M, N));
335                        }
336                        for (int i = 0; i < minMN; i++) {
337                            ret.SetValue(dS[i], i, i);
338                        }
339                        ILMemoryPool.Pool.Free(dS);
340                        if (!Object.Equals(outU, null)) {
341                            outU.a = array< double>(dU, M, lenDU / M);
342                        } else {
343                            ILMemoryPool.Pool.Free(dU);
344                        }
345                        if (!Object.Equals(outV, null)) {
346                           
347                            outV.a = array< double>(dVT, N, lenVT / N).T;
348                        } else {
349                            ILMemoryPool.Pool.Free(dVT);
350                        }
351                    } else {
352                        ret.a = array< double>(dS,minMN, 1);
353                    }
354                }
355                return ret;
356            }
357        }
358
359#region HYCALPER AUTO GENERATED CODE
360
361        /// <summary>
362        /// singular value decomposition
363        /// </summary>
364        /// <param name="A">Input matrix</param>
365        /// <param name="outU">[Output] Left singular vectors of A as columns of matrix outU.
366        /// Setting this parameter to a non-null value signals the need of returning those values.</param>
367        /// <param name="outV">[Output] Right singular vectors of X as rows of matrix outV.
368        /// This parameter must not be null. It might be an empty array on input.</param>
369        /// <param name="small">If true: return only first min(M,N) columns of outU and S (returned) will be
370        /// of size [min(M,N),min(M,N)]</param>
371        /// <param name="discardFiniteTest">If true: the matrix given will not be checked for infinte or NaN values. If such elements
372        /// exist nevertheless, this may result in failing convergence or error. In worst case
373        /// the function may hang inside the Lapack lib! Use with care! </param>
374        /// <returns>Singular values as diagonal matrix of same size and type as A</returns>
375        public static ILRetArray< float> svd( ILInArray< float> A, ILOutArray< float> outU,
376                                                                ILOutArray< float> outV, bool small, bool discardFiniteTest ) {
377            if (object.Equals(A,null))
378                throw new ILArgumentException("input matrix X must not be null");
379            using (ILScope.Enter(A)) {
380               
381                if (!A.IsMatrix)
382                    throw new ILArgumentSizeException("svd is defined for matrices only");
383                // early exit for small matrices
384                if (A.Size[1] < 4 && A.Size[0] == A.Size[1]) {
385                    switch (A.Size[0]) {
386                        case 1:
387                            if (!Object.Equals(outU, null))
388                                outU.a = ( float)1.0;
389                            if (!Object.Equals(outV, null))
390                                outV.a = ( float)1.0;
391                            return abs(A);
392                        //case 2:
393                        //    return -1;
394                        //case 3:
395                        //    return -1;
396                    }
397                }
398                if (!discardFiniteTest && !allall(isfinite(A)))
399                    throw new ILArgumentException("svd: input must have only finite elements");
400                if (Lapack == null)
401                    throw new ILMathException("no Lapack package available");
402                // parameter evaluation
403                int M = A.Size[0]; int N = A.Size[1];
404                int minMN = (M < N) ? M : N;
405                int LDU = M; int LDVT = N;
406                int LDA = M, lenDU = 0, lenVT = 0;
407               
408                float[] dS = ILMemoryPool.Pool.New<  float>(minMN);
409                char jobz = (small) ? 'S' : 'A';
410               
411                float[] dU = null;
412               
413                float[] dVT = null;
414                int info = 0;
415                if (!Object.Equals(outU, null) || !Object.Equals(outV, null)) {
416                    // need to return U and VT
417                    if (small) {
418                        lenDU = M * minMN;
419                        dU = ILMemoryPool.Pool.New<  float>(lenDU);
420                        lenVT = N * minMN;
421                        dVT = ILMemoryPool.Pool.New<  float>(lenVT);
422                    } else {
423                        lenDU = M * M;
424                        dU = ILMemoryPool.Pool.New<  float>(lenDU);
425                        lenVT = N * N;
426                        dVT = ILMemoryPool.Pool.New<  float>(lenVT);
427                    }
428                } else {
429                    jobz = 'N';
430                }
431
432                // must create copy of input !
433               
434                float[] dInput = A.C.GetArrayForWrite();
435                Lapack.sgesdd(jobz, M, N, dInput, LDA, dS, dU, LDU, dVT, LDVT, ref info);
436                if (info < 0)
437                    throw new ILArgumentException("the " + (-info).ToString() + "th argument to SVD was invalid");
438                if (info > 0)
439                    throw new ILArgumentException("svd was not converging");
440                ILArray< float> ret = empty<float>(ILSize.Empty00);
441                if (info == 0) {
442                    // success
443                    if (!Object.Equals(outU, null) || !Object.Equals(outV, null)) {
444                        if (small) {
445                            ret.a = zeros< float>(new ILSize(minMN, minMN));
446                        } else {
447                            ret.a = zeros< float>(new ILSize(M, N));
448                        }
449                        for (int i = 0; i < minMN; i++) {
450                            ret.SetValue(dS[i], i, i);
451                        }
452                        ILMemoryPool.Pool.Free(dS);
453                        if (!Object.Equals(outU, null)) {
454                            outU.a = array< float>(dU, M, lenDU / M);
455                        } else {
456                            ILMemoryPool.Pool.Free(dU);
457                        }
458                        if (!Object.Equals(outV, null)) {
459                            outV.a = new  ILRetArray<float> (dVT,N,lenVT / N).T;
460                        } else {
461                            ILMemoryPool.Pool.Free(dVT);
462                        }
463                    } else {
464                        ret.a = array< float>(dS,minMN, 1);
465                    }
466                }
467                return ret;
468            }
469        }
470        /// <summary>
471        /// singular value decomposition
472        /// </summary>
473        /// <param name="A">Input matrix</param>
474        /// <param name="outU">[Output] Left singular vectors of A as columns of matrix outU.
475        /// Setting this parameter to a non-null value signals the need of returning those values.</param>
476        /// <param name="outV">[Output] Right singular vectors of X as rows of matrix outV.
477        /// This parameter must not be null. It might be an empty array on input.</param>
478        /// <param name="small">If true: return only first min(M,N) columns of outU and S (returned) will be
479        /// of size [min(M,N),min(M,N)]</param>
480        /// <param name="discardFiniteTest">If true: the matrix given will not be checked for infinte or NaN values. If such elements
481        /// exist nevertheless, this may result in failing convergence or error. In worst case
482        /// the function may hang inside the Lapack lib! Use with care! </param>
483        /// <returns>Singular values as diagonal matrix of same size and type as A</returns>
484        public static ILRetArray< float> svd( ILInArray< fcomplex> A, ILOutArray< fcomplex> outU,
485                                                                ILOutArray< fcomplex> outV, bool small, bool discardFiniteTest ) {
486            if (object.Equals(A,null))
487                throw new ILArgumentException("input matrix X must not be null");
488            using (ILScope.Enter(A)) {
489               
490                if (!A.IsMatrix)
491                    throw new ILArgumentSizeException("svd is defined for matrices only");
492                // early exit for small matrices
493                if (A.Size[1] < 4 && A.Size[0] == A.Size[1]) {
494                    switch (A.Size[0]) {
495                        case 1:
496                            if (!Object.Equals(outU, null))
497                                outU.a = ( fcomplex)1.0;
498                            if (!Object.Equals(outV, null))
499                                outV.a = ( fcomplex)1.0;
500                            return abs(A);
501                        //case 2:
502                        //    return -1;
503                        //case 3:
504                        //    return -1;
505                    }
506                }
507                if (!discardFiniteTest && !allall(isfinite(A)))
508                    throw new ILArgumentException("svd: input must have only finite elements");
509                if (Lapack == null)
510                    throw new ILMathException("no Lapack package available");
511                // parameter evaluation
512                int M = A.Size[0]; int N = A.Size[1];
513                int minMN = (M < N) ? M : N;
514                int LDU = M; int LDVT = N;
515                int LDA = M, lenDU = 0, lenVT = 0;
516               
517                float[] dS = ILMemoryPool.Pool.New<  float>(minMN);
518                char jobz = (small) ? 'S' : 'A';
519               
520                fcomplex[] dU = null;
521               
522                fcomplex[] dVT = null;
523                int info = 0;
524                if (!Object.Equals(outU, null) || !Object.Equals(outV, null)) {
525                    // need to return U and VT
526                    if (small) {
527                        lenDU = M * minMN;
528                        dU = ILMemoryPool.Pool.New<  fcomplex>(lenDU);
529                        lenVT = N * minMN;
530                        dVT = ILMemoryPool.Pool.New<  fcomplex>(lenVT);
531                    } else {
532                        lenDU = M * M;
533                        dU = ILMemoryPool.Pool.New<  fcomplex>(lenDU);
534                        lenVT = N * N;
535                        dVT = ILMemoryPool.Pool.New<  fcomplex>(lenVT);
536                    }
537                } else {
538                    jobz = 'N';
539                }
540
541                // must create copy of input !
542               
543                fcomplex[] dInput = A.C.GetArrayForWrite();
544                Lapack.cgesdd(jobz, M, N, dInput, LDA, dS, dU, LDU, dVT, LDVT, ref info);
545                if (info < 0)
546                    throw new ILArgumentException("the " + (-info).ToString() + "th argument to SVD was invalid");
547                if (info > 0)
548                    throw new ILArgumentException("svd was not converging");
549                ILArray< float> ret = empty<float>(ILSize.Empty00);
550                if (info == 0) {
551                    // success
552                    if (!Object.Equals(outU, null) || !Object.Equals(outV, null)) {
553                        if (small) {
554                            ret.a = zeros< float>(new ILSize(minMN, minMN));
555                        } else {
556                            ret.a = zeros< float>(new ILSize(M, N));
557                        }
558                        for (int i = 0; i < minMN; i++) {
559                            ret.SetValue(dS[i], i, i);
560                        }
561                        ILMemoryPool.Pool.Free(dS);
562                        if (!Object.Equals(outU, null)) {
563                            outU.a = array< fcomplex>(dU, M, lenDU / M);
564                        } else {
565                            ILMemoryPool.Pool.Free(dU);
566                        }
567                        if (!Object.Equals(outV, null)) {
568                            outV.a = conj(new  ILRetArray<fcomplex> (dVT,N,lenVT / N).T);
569                        } else {
570                            ILMemoryPool.Pool.Free(dVT);
571                        }
572                    } else {
573                        ret.a = array< float>(dS,minMN, 1);
574                    }
575                }
576                return ret;
577            }
578        }
579        /// <summary>
580        /// singular value decomposition
581        /// </summary>
582        /// <param name="A">Input matrix</param>
583        /// <param name="outU">[Output] Left singular vectors of A as columns of matrix outU.
584        /// Setting this parameter to a non-null value signals the need of returning those values.</param>
585        /// <param name="outV">[Output] Right singular vectors of X as rows of matrix outV.
586        /// This parameter must not be null. It might be an empty array on input.</param>
587        /// <param name="small">If true: return only first min(M,N) columns of outU and S (returned) will be
588        /// of size [min(M,N),min(M,N)]</param>
589        /// <param name="discardFiniteTest">If true: the matrix given will not be checked for infinte or NaN values. If such elements
590        /// exist nevertheless, this may result in failing convergence or error. In worst case
591        /// the function may hang inside the Lapack lib! Use with care! </param>
592        /// <returns>Singular values as diagonal matrix of same size and type as A</returns>
593        public static ILRetArray< double> svd( ILInArray< complex> A, ILOutArray< complex> outU,
594                                                                ILOutArray< complex> outV, bool small, bool discardFiniteTest ) {
595            if (object.Equals(A,null))
596                throw new ILArgumentException("input matrix X must not be null");
597            using (ILScope.Enter(A)) {
598               
599                if (!A.IsMatrix)
600                    throw new ILArgumentSizeException("svd is defined for matrices only");
601                // early exit for small matrices
602                if (A.Size[1] < 4 && A.Size[0] == A.Size[1]) {
603                    switch (A.Size[0]) {
604                        case 1:
605                            if (!Object.Equals(outU, null))
606                                outU.a = ( complex)1.0;
607                            if (!Object.Equals(outV, null))
608                                outV.a = ( complex)1.0;
609                            return abs(A);
610                        //case 2:
611                        //    return -1;
612                        //case 3:
613                        //    return -1;
614                    }
615                }
616                if (!discardFiniteTest && !allall(isfinite(A)))
617                    throw new ILArgumentException("svd: input must have only finite elements");
618                if (Lapack == null)
619                    throw new ILMathException("no Lapack package available");
620                // parameter evaluation
621                int M = A.Size[0]; int N = A.Size[1];
622                int minMN = (M < N) ? M : N;
623                int LDU = M; int LDVT = N;
624                int LDA = M, lenDU = 0, lenVT = 0;
625               
626                double[] dS = ILMemoryPool.Pool.New<  double>(minMN);
627                char jobz = (small) ? 'S' : 'A';
628               
629                complex[] dU = null;
630               
631                complex[] dVT = null;
632                int info = 0;
633                if (!Object.Equals(outU, null) || !Object.Equals(outV, null)) {
634                    // need to return U and VT
635                    if (small) {
636                        lenDU = M * minMN;
637                        dU = ILMemoryPool.Pool.New<  complex>(lenDU);
638                        lenVT = N * minMN;
639                        dVT = ILMemoryPool.Pool.New<  complex>(lenVT);
640                    } else {
641                        lenDU = M * M;
642                        dU = ILMemoryPool.Pool.New<  complex>(lenDU);
643                        lenVT = N * N;
644                        dVT = ILMemoryPool.Pool.New<  complex>(lenVT);
645                    }
646                } else {
647                    jobz = 'N';
648                }
649
650                // must create copy of input !
651               
652                complex[] dInput = A.C.GetArrayForWrite();
653                Lapack.zgesdd(jobz, M, N, dInput, LDA, dS, dU, LDU, dVT, LDVT, ref info);
654                if (info < 0)
655                    throw new ILArgumentException("the " + (-info).ToString() + "th argument to SVD was invalid");
656                if (info > 0)
657                    throw new ILArgumentException("svd was not converging");
658                ILArray< double> ret = empty<double>(ILSize.Empty00);
659                if (info == 0) {
660                    // success
661                    if (!Object.Equals(outU, null) || !Object.Equals(outV, null)) {
662                        if (small) {
663                            ret.a = zeros< double>(new ILSize(minMN, minMN));
664                        } else {
665                            ret.a = zeros< double>(new ILSize(M, N));
666                        }
667                        for (int i = 0; i < minMN; i++) {
668                            ret.SetValue(dS[i], i, i);
669                        }
670                        ILMemoryPool.Pool.Free(dS);
671                        if (!Object.Equals(outU, null)) {
672                            outU.a = array< complex>(dU, M, lenDU / M);
673                        } else {
674                            ILMemoryPool.Pool.Free(dU);
675                        }
676                        if (!Object.Equals(outV, null)) {
677                            outV.a = conj(new  ILRetArray<complex> (dVT,N,lenVT / N).T);
678                        } else {
679                            ILMemoryPool.Pool.Free(dVT);
680                        }
681                    } else {
682                        ret.a = array< double>(dS,minMN, 1);
683                    }
684                }
685                return ret;
686            }
687        }
688
689#endregion HYCALPER AUTO GENERATED CODE
690   }
691}
Note: See TracBrowser for help on using the repository browser.