Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.Problems.GaussianProcessTuning/ILNumerics.2.14.4735.573/Functions/builtin/qr.cs @ 11194

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

#1967: ILNumerics source for experimentation

File size: 51.3 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
48
49namespace ILNumerics {
50    public partial class ILMath {
51
52
53        /// <summary>
54        /// QR decomposition - raw Lapack output
55        /// </summary>
56        /// <param name="A">Input matrix A</param>
57        /// <returns>Orthonormal / unitary matrix Q and upper triangular
58        /// matrix R packed into single matrix. This is the output of the
59        /// lapack function ?geqrf.</returns>
60        /// <remarks><para>Input matrix A will not be altered. </para>
61        /// <para>The matrix returned is the direct output of the lapack
62        /// function [d,s,c,z]geqrf respectively. This means that it contains
63        /// the decomposition factors Q and R, but they are combined into a
64        /// single matrix for performance reasons. If you need one of the factors,
65        /// you would use the overloaded function
66        /// <see cref="ILNumerics.ILMath.qr(ILInArray{double},ILOutArray{double})"/>
67        /// instead, which returns those factors separately.</para></remarks>
68        internal static ILRetArray<double> qr( ILInArray<double> A ) {
69            using (ILScope.Enter(A)) {
70                if (!A.IsMatrix)
71                    throw new ILArgumentException("input A must be matrix");
72                int m = A.Size[0], n = A.Size[1];
73                ILArray<double> ret = A.C;
74                 double[] tau = ILMemoryPool.Pool.New<  double>((m < n) ? m : n);
75                int info = 0;
76                /*!HC:lapack_*geqrf*/
77                Lapack.dgeqrf(m, n, ret.GetArrayForWrite(), m, tau, ref info);
78                if (info < 0)
79                    throw new ILArgumentException("an unknown error occoured during decomposition");
80                return ret;
81            }
82        }
83        /// <summary>
84        /// QR decomposition, returning Q and R
85        /// </summary>
86        /// <param name="A">Input matrix A of size [m x n]</param>
87        /// <param name="outR">[Output] Upper triangular matrix R as
88        /// result of decomposition, size [m x n]</param>
89        /// <returns>Orthonormal / unitary matrix Q as result of decomposition, size [m x m]</returns>
90        /// <remarks>The function returns Q and R such that the equation
91        /// <para>A = Q * R</para> holds within roundoff errors. ('*' denotes
92        /// matrix multiplication)</remarks>
93        public static ILRetArray<double> qr(
94                                      ILInArray<double> A,
95                                      ILOutArray<double> outR ) {
96            return qr(A, outR, false);
97        }
98        /// <summary>
99        /// QR decomposition, returning Q and R, optionally economical sized
100        /// </summary>
101        /// <param name="A">Input matrix A of size [m x n]</param>
102        /// <param name="outR">[Output] Upper triangular matrix R as
103        /// result of decomposition, size [m x n]</param>
104        /// <param name="economySize">If true, the size of Q and R will
105        /// be [m x m] and [m x n] respectively. However, if m &lt; n,
106        /// the economySize parameter has no effect. </param>
107        /// <returns>Orthonormal real / unitary complex matrix Q as result
108        /// of decomposition. Size [m x m] or [m x min(m,n)], depending
109        /// on <paramref name="economySize"/> (see remarks below)</returns>
110        /// <remarks>The function returns Q and R such that the equation
111        /// <para>A = Q * R</para> holds with roundoff errors. ('*'
112        /// denotes matrix multiplication.)</remarks>
113        public static ILRetArray<double> qr( ILInArray<double> A
114            , ILOutArray<double> outR, bool economySize ) {
115            using (ILScope.Enter(A)) {
116                if (Object.Equals(outR, null)) {
117                    return qr(A);
118                }
119                int m = A.Size[0];
120                int n = A.Size[1];
121                if (m < n && economySize) return qr(A, outR, false);
122                ILArray<double> ret = empty<double>(ILSize.Empty00);
123                if (m == 0 || n == 0) {
124                    if (!object.Equals(outR,null))
125                        outR.a = empty<double>(new ILSize(m, n));
126                    return empty<double>(A.Size);
127                }
128                int minMN = (m < n) ? m : n;
129                int info = 0;
130                 double[] tau = ILMemoryPool.Pool.New<  double>(minMN);
131                if (m >= n) {
132                    ret.a = zeros<double>(m, (economySize) ? minMN : m);
133                } else {
134                    // economySize is always false ... !
135                    // a temporary array is needed for extraction of the compact lapack Q (?geqrf)
136                    ret.a = zeros<double>(m, n);
137                }
138                ret[full, r(0, n - 1)] = A[full, full];
139                 double[] QArr = ret.GetArrayForWrite();
140                /*!HC:lapack_*geqrf*/
141                Lapack.dgeqrf(m, n, QArr, m, tau, ref info);
142                if (info != 0) {
143                    throw new ILArgumentException("error inside lapack library (?geqrf). info=" + info.ToString());
144                }
145                // extract R, Q
146                if (economySize) {
147                    outR.a = copyUpperTriangle(QArr, m, n, minMN);
148                    /*!HC:lapack_*orgqr*/
149                    Lapack.dorgqr(m, minMN, minMN, QArr, m, tau, ref info);
150                } else {
151                    outR.a = copyUpperTriangle(QArr, m, n, m);
152                    /*!HC:lapack_*orgqr*/
153                    Lapack.dorgqr(m, m, minMN, QArr, m, tau, ref info);
154                    if (m < n)
155                        ret.a = ret[full,r(0,m - 1)];
156                }
157                if (info != 0)
158                    throw new ILArgumentException("error in lapack library (???gqr). info=" + info.ToString());
159                return ret;
160            }
161        }
162        /// <summary>
163        /// QR decomposition with pivoting
164        /// </summary>
165        /// <param name="A">Input matrix A of size [m x n]</param>
166        /// <param name="outR">[Output] Upper triangular matrix
167        /// R as result of decomposition. Size [m x n] or [min(m,n) x n]
168        /// (see remarks). </param>
169        /// <param name="outE">[Output] Permutation matrix from pivoting. Size [m x m]</param>
170        /// <returns>Orthonormal / unitary matrix Q as result of decomposition.
171        /// Size [m x min(m,n)]</returns>
172        /// <remarks>The function returns Q, R and E such that the equation
173        /// <para>A * E = Q * R</para> holds with roundoff errors, where '*'
174        /// denotes matrix multiplication. E reflects the pivoting done
175        /// inside LAPACK in order to give R increasingly diagonal elements.</remarks>
176        /// <seealso cref="ILNumerics.ILMath.qr(ILInArray{double}, ILOutArray{double}, ILOutArray{double},bool)"/>
177        public static  ILRetArray<double> qr(
178                                    ILInArray<double> A,
179                                    ILOutArray< double> outR,
180                                    ILOutArray< double> outE ) {
181            return qr(A, outR, outE, false);
182        }
183        /// <summary>
184        /// QR decomposition with pivoting, possibly economical sized
185        /// </summary>
186        /// <param name="A">Input matrix A of size [m x n]</param>
187        /// <param name="outR">[Output] Upper triangular matrix R as
188        /// result of decomposition. Size [m x n] or [min(m,n) x n] depending
189        /// on <paramref name="economySize"/> (see remarks).</param>
190        /// <param name="economySize"><para>If true, <list type="bullet">
191        /// <item>the size of Q and R will be [m x m] and [m x n] respectively.
192        /// However, if m &lt; n, the economySize parameter has no effect on
193        /// those sizes.</item>
194        /// <item>the output parameter E will be returned as row permutation
195        /// vector rather than as permutation matrix</item></list></para>
196        /// <para>If false, this function acts exactly as its overload
197        /// <see cref="ILNumerics.ILMath.qr(ILInArray{double}, ILOutArray{double}, ILOutArray{double})"/></para>
198        /// </param>
199        /// <param name="outE">[Output] Permutation matrix from pivoting. Size [m x m].
200        /// If this is not null, the permutation matrix/ vector E will be returned.
201        /// <para>E is of size [n x n], if <paramref name="economySize"/> is
202        /// true, a row vector of length n otherwise</para></param>
203        /// <returns>Orthonormal / unitary matrix Q as result of decomposition.
204        /// Size [m x m] or [m x min(m,n)], depending on <paramref name="economySize"/>
205        /// (see remarks below)</returns>
206        /// <remarks><para> If <paramref name="economySize"/> is false, the function
207        /// returns Q, R and E such that the equation A * E = Q * R holds within
208        /// roundoff errors. </para>
209        /// <para>If <paramref name="economySize"/> is true, E will be a permutation
210        /// vector and the equation A[":",E] == Q * R holds (except roundoff).</para>
211        /// <para>E reflects the pivoting of A done inside LAPACK in order to give R
212        /// increasingly diagonal elements.</para></remarks>
213        public static ILRetArray<double> qr(
214                        ILInArray<  double> A,
215                        ILOutArray<  double> outR,
216                        ILOutArray<  double> outE,
217                        bool economySize ) {
218            using (ILScope.Enter(A)) {
219                if (Object.Equals(outR, null)) {
220                    return qr(A);
221                }
222                int m = A.Size[0];
223                int n = A.Size[1];
224                if (m < n && economySize) return qr(A, outR, false);
225                if (m == 0 || n == 0) {
226                    if (!object.Equals(outR,null))
227                        outR.a = zeros< double>(m, n);
228                    if (!object.Equals(outE,null))
229                        outE.a = zeros< double>(1, 0);
230                    return empty<double>(A.Size);
231                }
232                // prepare IPVT
233                if (object.Equals(outE, null))
234                    return qr(A, outR, economySize);
235                if (!economySize) {
236                    outE.a = zeros< double>( n, n);
237                } else {
238                    outE.a = zeros< double>( 1, n);
239                }
240                int[] ipvt = ILMemoryPool.Pool.New<int>(n);
241                int minMN = (m < n) ? m : n;
242                int info = 0;
243                 double[] tau = ILMemoryPool.Pool.New<  double>(minMN);
244                 double[] QArr;
245                ILArray<double> ret;
246                if (m >= n) {
247                    ret = zeros<double>(m, (economySize) ? minMN : m);
248                } else {
249                    // economySize is always false ... !
250                    // a temporary array is needed for extraction of the compact lapack Q (?geqrf)
251                    ret = zeros<double>( m, n);
252                }
253                ret[full,r(0,n-1)] = A[full,full];
254                QArr = ret.GetArrayForWrite();
255                /*!HC:lapack_*geqp3*/
256                Lapack.dgeqp3(m, n, QArr, m, ipvt, tau, ref info);
257                if (info != 0) {
258                    throw new ILArgumentException("error inside lapack library (?geqrf). info=" + info.ToString());
259                }
260                // extract R, Q
261                 double[] eArr = outE.GetArrayForWrite();
262                if (economySize) {
263                    outR.a = copyUpperTriangle(QArr, m, n, minMN);
264                    /*!HC:lapack_*orgqr*/
265                    Lapack.dorgqr(m, minMN, minMN, QArr, m, tau, ref info);
266                    // transform E into out typed vector
267                    for (int i = 0; i < n; i++) {
268                        eArr[i] = ipvt[i] - 1;
269                    }
270                } else {
271                    outR.a = copyUpperTriangle(QArr, m, n, m);
272                    /*!HC:lapack_*orgqr*/
273                    Lapack.dorgqr(m, m, minMN, QArr, m, tau, ref info);
274                    if (m < n)
275                        ret.a = ret[full,r(0,m - 1)];
276                    // transform E into matrix
277                    for (int i = 0; i < n; i++) {
278                        eArr[(ipvt[i] - 1) + n * i] =  1.0;
279                    }
280                }
281                if (info != 0)
282                    throw new ILArgumentException("error in lapack library (???gqr). info=" + info.ToString());
283                return ret;
284            }
285        }
286
287
288#region HYCALPER AUTO GENERATED CODE
289
290        /// <summary>
291        /// QR decomposition - raw Lapack output
292        /// </summary>
293        /// <param name="A">Input matrix A</param>
294        /// <returns>Orthonormal / unitary matrix Q and upper triangular
295        /// matrix R packed into single matrix. This is the output of the
296        /// lapack function ?geqrf.</returns>
297        /// <remarks><para>Input matrix A will not be altered. </para>
298        /// <para>The matrix returned is the direct output of the lapack
299        /// function [d,s,c,z]geqrf respectively. This means that it contains
300        /// the decomposition factors Q and R, but they are combined into a
301        /// single matrix for performance reasons. If you need one of the factors,
302        /// you would use the overloaded function
303        /// <see cref="ILNumerics.ILMath.qr(ILInArray{double},ILOutArray{double})"/>
304        /// instead, which returns those factors separately.</para></remarks>
305        internal static ILRetArray<float> qr( ILInArray<float> A ) {
306            using (ILScope.Enter(A)) {
307                if (!A.IsMatrix)
308                    throw new ILArgumentException("input A must be matrix");
309                int m = A.Size[0], n = A.Size[1];
310                ILArray<float> ret = A.C;
311                float[] tau = ILMemoryPool.Pool.New<  float>((m < n) ? m : n);
312                int info = 0;
313               
314                Lapack.sgeqrf(m, n, ret.GetArrayForWrite(), m, tau, ref info);
315                if (info < 0)
316                    throw new ILArgumentException("an unknown error occoured during decomposition");
317                return ret;
318            }
319        }
320        /// <summary>
321        /// QR decomposition, returning Q and R
322        /// </summary>
323        /// <param name="A">Input matrix A of size [m x n]</param>
324        /// <param name="outR">[Output] Upper triangular matrix R as
325        /// result of decomposition, size [m x n]</param>
326        /// <returns>Orthonormal / unitary matrix Q as result of decomposition, size [m x m]</returns>
327        /// <remarks>The function returns Q and R such that the equation
328        /// <para>A = Q * R</para> holds within roundoff errors. ('*' denotes
329        /// matrix multiplication)</remarks>
330        public static ILRetArray<float> qr(
331                                      ILInArray<float> A,
332                                      ILOutArray<float> outR ) {
333            return qr(A, outR, false);
334        }
335        /// <summary>
336        /// QR decomposition, returning Q and R, optionally economical sized
337        /// </summary>
338        /// <param name="A">Input matrix A of size [m x n]</param>
339        /// <param name="outR">[Output] Upper triangular matrix R as
340        /// result of decomposition, size [m x n]</param>
341        /// <param name="economySize">If true, the size of Q and R will
342        /// be [m x m] and [m x n] respectively. However, if m &lt; n,
343        /// the economySize parameter has no effect. </param>
344        /// <returns>Orthonormal real / unitary complex matrix Q as result
345        /// of decomposition. Size [m x m] or [m x min(m,n)], depending
346        /// on <paramref name="economySize"/> (see remarks below)</returns>
347        /// <remarks>The function returns Q and R such that the equation
348        /// <para>A = Q * R</para> holds with roundoff errors. ('*'
349        /// denotes matrix multiplication.)</remarks>
350        public static ILRetArray<float> qr( ILInArray<float> A
351            , ILOutArray<float> outR, bool economySize ) {
352            using (ILScope.Enter(A)) {
353                if (Object.Equals(outR, null)) {
354                    return qr(A);
355                }
356                int m = A.Size[0];
357                int n = A.Size[1];
358                if (m < n && economySize) return qr(A, outR, false);
359                ILArray<float> ret = empty<float>(ILSize.Empty00);
360                if (m == 0 || n == 0) {
361                    if (!object.Equals(outR,null))
362                        outR.a = empty<float>(new ILSize(m, n));
363                    return empty<float>(A.Size);
364                }
365                int minMN = (m < n) ? m : n;
366                int info = 0;
367                float[] tau = ILMemoryPool.Pool.New<  float>(minMN);
368                if (m >= n) {
369                    ret.a = zeros<float>(m, (economySize) ? minMN : m);
370                } else {
371                    // economySize is always false ... !
372                    // a temporary array is needed for extraction of the compact lapack Q (?geqrf)
373                    ret.a = zeros<float>(m, n);
374                }
375                ret[full, r(0, n - 1)] = A[full, full];
376                float[] QArr = ret.GetArrayForWrite();
377               
378                Lapack.sgeqrf(m, n, QArr, m, tau, ref info);
379                if (info != 0) {
380                    throw new ILArgumentException("error inside lapack library (?geqrf). info=" + info.ToString());
381                }
382                // extract R, Q
383                if (economySize) {
384                    outR.a = copyUpperTriangle(QArr, m, n, minMN);
385                   
386                    Lapack.sorgqr(m, minMN, minMN, QArr, m, tau, ref info);
387                } else {
388                    outR.a = copyUpperTriangle(QArr, m, n, m);
389                   
390                    Lapack.sorgqr(m, m, minMN, QArr, m, tau, ref info);
391                    if (m < n)
392                        ret.a = ret[full,r(0,m - 1)];
393                }
394                if (info != 0)
395                    throw new ILArgumentException("error in lapack library (???gqr). info=" + info.ToString());
396                return ret;
397            }
398        }
399        /// <summary>
400        /// QR decomposition with pivoting
401        /// </summary>
402        /// <param name="A">Input matrix A of size [m x n]</param>
403        /// <param name="outR">[Output] Upper triangular matrix
404        /// R as result of decomposition. Size [m x n] or [min(m,n) x n]
405        /// (see remarks). </param>
406        /// <param name="outE">[Output] Permutation matrix from pivoting. Size [m x m]</param>
407        /// <returns>Orthonormal / unitary matrix Q as result of decomposition.
408        /// Size [m x min(m,n)]</returns>
409        /// <remarks>The function returns Q, R and E such that the equation
410        /// <para>A * E = Q * R</para> holds with roundoff errors, where '*'
411        /// denotes matrix multiplication. E reflects the pivoting done
412        /// inside LAPACK in order to give R increasingly diagonal elements.</remarks>
413        /// <seealso cref="ILNumerics.ILMath.qr(ILInArray{double}, ILOutArray{double}, ILOutArray{double},bool)"/>
414        public static  ILRetArray<float> qr(
415                                    ILInArray<float> A,
416                                    ILOutArray< float> outR,
417                                    ILOutArray< float> outE ) {
418            return qr(A, outR, outE, false);
419        }
420        /// <summary>
421        /// QR decomposition with pivoting, possibly economical sized
422        /// </summary>
423        /// <param name="A">Input matrix A of size [m x n]</param>
424        /// <param name="outR">[Output] Upper triangular matrix R as
425        /// result of decomposition. Size [m x n] or [min(m,n) x n] depending
426        /// on <paramref name="economySize"/> (see remarks).</param>
427        /// <param name="economySize"><para>If true, <list type="bullet">
428        /// <item>the size of Q and R will be [m x m] and [m x n] respectively.
429        /// However, if m &lt; n, the economySize parameter has no effect on
430        /// those sizes.</item>
431        /// <item>the output parameter E will be returned as row permutation
432        /// vector rather than as permutation matrix</item></list></para>
433        /// <para>If false, this function acts exactly as its overload
434        /// <see cref="ILNumerics.ILMath.qr(ILInArray{double}, ILOutArray{double}, ILOutArray{double})"/></para>
435        /// </param>
436        /// <param name="outE">[Output] Permutation matrix from pivoting. Size [m x m].
437        /// If this is not null, the permutation matrix/ vector E will be returned.
438        /// <para>E is of size [n x n], if <paramref name="economySize"/> is
439        /// true, a row vector of length n otherwise</para></param>
440        /// <returns>Orthonormal / unitary matrix Q as result of decomposition.
441        /// Size [m x m] or [m x min(m,n)], depending on <paramref name="economySize"/>
442        /// (see remarks below)</returns>
443        /// <remarks><para> If <paramref name="economySize"/> is false, the function
444        /// returns Q, R and E such that the equation A * E = Q * R holds within
445        /// roundoff errors. </para>
446        /// <para>If <paramref name="economySize"/> is true, E will be a permutation
447        /// vector and the equation A[":",E] == Q * R holds (except roundoff).</para>
448        /// <para>E reflects the pivoting of A done inside LAPACK in order to give R
449        /// increasingly diagonal elements.</para></remarks>
450        public static ILRetArray<float> qr(
451                        ILInArray<  float> A,
452                        ILOutArray<  float> outR,
453                        ILOutArray<  float> outE,
454                        bool economySize ) {
455            using (ILScope.Enter(A)) {
456                if (Object.Equals(outR, null)) {
457                    return qr(A);
458                }
459                int m = A.Size[0];
460                int n = A.Size[1];
461                if (m < n && economySize) return qr(A, outR, false);
462                if (m == 0 || n == 0) {
463                    if (!object.Equals(outR,null))
464                        outR.a = zeros< float>(m, n);
465                    if (!object.Equals(outE,null))
466                        outE.a = zeros< float>(1, 0);
467                    return empty<float>(A.Size);
468                }
469                // prepare IPVT
470                if (object.Equals(outE, null))
471                    return qr(A, outR, economySize);
472                if (!economySize) {
473                    outE.a = zeros< float>( n, n);
474                } else {
475                    outE.a = zeros< float>( 1, n);
476                }
477                int[] ipvt = ILMemoryPool.Pool.New<int>(n);
478                int minMN = (m < n) ? m : n;
479                int info = 0;
480                float[] tau = ILMemoryPool.Pool.New<  float>(minMN);
481                float[] QArr;
482                ILArray<float> ret;
483                if (m >= n) {
484                    ret = zeros<float>(m, (economySize) ? minMN : m);
485                } else {
486                    // economySize is always false ... !
487                    // a temporary array is needed for extraction of the compact lapack Q (?geqrf)
488                    ret = zeros<float>( m, n);
489                }
490                ret[full,r(0,n-1)] = A[full,full];
491                QArr = ret.GetArrayForWrite();
492               
493                Lapack.sgeqp3(m, n, QArr, m, ipvt, tau, ref info);
494                if (info != 0) {
495                    throw new ILArgumentException("error inside lapack library (?geqrf). info=" + info.ToString());
496                }
497                // extract R, Q
498                float[] eArr = outE.GetArrayForWrite();
499                if (economySize) {
500                    outR.a = copyUpperTriangle(QArr, m, n, minMN);
501                   
502                    Lapack.sorgqr(m, minMN, minMN, QArr, m, tau, ref info);
503                    // transform E into out typed vector
504                    for (int i = 0; i < n; i++) {
505                        eArr[i] = ipvt[i] - 1;
506                    }
507                } else {
508                    outR.a = copyUpperTriangle(QArr, m, n, m);
509                   
510                    Lapack.sorgqr(m, m, minMN, QArr, m, tau, ref info);
511                    if (m < n)
512                        ret.a = ret[full,r(0,m - 1)];
513                    // transform E into matrix
514                    for (int i = 0; i < n; i++) {
515                        eArr[(ipvt[i] - 1) + n * i] =  1.0f;
516                    }
517                }
518                if (info != 0)
519                    throw new ILArgumentException("error in lapack library (???gqr). info=" + info.ToString());
520                return ret;
521            }
522        }
523
524        /// <summary>
525        /// QR decomposition - raw Lapack output
526        /// </summary>
527        /// <param name="A">Input matrix A</param>
528        /// <returns>Orthonormal / unitary matrix Q and upper triangular
529        /// matrix R packed into single matrix. This is the output of the
530        /// lapack function ?geqrf.</returns>
531        /// <remarks><para>Input matrix A will not be altered. </para>
532        /// <para>The matrix returned is the direct output of the lapack
533        /// function [d,s,c,z]geqrf respectively. This means that it contains
534        /// the decomposition factors Q and R, but they are combined into a
535        /// single matrix for performance reasons. If you need one of the factors,
536        /// you would use the overloaded function
537        /// <see cref="ILNumerics.ILMath.qr(ILInArray{double},ILOutArray{double})"/>
538        /// instead, which returns those factors separately.</para></remarks>
539        internal static ILRetArray<fcomplex> qr( ILInArray<fcomplex> A ) {
540            using (ILScope.Enter(A)) {
541                if (!A.IsMatrix)
542                    throw new ILArgumentException("input A must be matrix");
543                int m = A.Size[0], n = A.Size[1];
544                ILArray<fcomplex> ret = A.C;
545                fcomplex[] tau = ILMemoryPool.Pool.New<  fcomplex>((m < n) ? m : n);
546                int info = 0;
547               
548                Lapack.cgeqrf(m, n, ret.GetArrayForWrite(), m, tau, ref info);
549                if (info < 0)
550                    throw new ILArgumentException("an unknown error occoured during decomposition");
551                return ret;
552            }
553        }
554        /// <summary>
555        /// QR decomposition, returning Q and R
556        /// </summary>
557        /// <param name="A">Input matrix A of size [m x n]</param>
558        /// <param name="outR">[Output] Upper triangular matrix R as
559        /// result of decomposition, size [m x n]</param>
560        /// <returns>Orthonormal / unitary matrix Q as result of decomposition, size [m x m]</returns>
561        /// <remarks>The function returns Q and R such that the equation
562        /// <para>A = Q * R</para> holds within roundoff errors. ('*' denotes
563        /// matrix multiplication)</remarks>
564        public static ILRetArray<fcomplex> qr(
565                                      ILInArray<fcomplex> A,
566                                      ILOutArray<fcomplex> outR ) {
567            return qr(A, outR, false);
568        }
569        /// <summary>
570        /// QR decomposition, returning Q and R, optionally economical sized
571        /// </summary>
572        /// <param name="A">Input matrix A of size [m x n]</param>
573        /// <param name="outR">[Output] Upper triangular matrix R as
574        /// result of decomposition, size [m x n]</param>
575        /// <param name="economySize">If true, the size of Q and R will
576        /// be [m x m] and [m x n] respectively. However, if m &lt; n,
577        /// the economySize parameter has no effect. </param>
578        /// <returns>Orthonormal real / unitary complex matrix Q as result
579        /// of decomposition. Size [m x m] or [m x min(m,n)], depending
580        /// on <paramref name="economySize"/> (see remarks below)</returns>
581        /// <remarks>The function returns Q and R such that the equation
582        /// <para>A = Q * R</para> holds with roundoff errors. ('*'
583        /// denotes matrix multiplication.)</remarks>
584        public static ILRetArray<fcomplex> qr( ILInArray<fcomplex> A
585            , ILOutArray<fcomplex> outR, bool economySize ) {
586            using (ILScope.Enter(A)) {
587                if (Object.Equals(outR, null)) {
588                    return qr(A);
589                }
590                int m = A.Size[0];
591                int n = A.Size[1];
592                if (m < n && economySize) return qr(A, outR, false);
593                ILArray<fcomplex> ret = empty<fcomplex>(ILSize.Empty00);
594                if (m == 0 || n == 0) {
595                    if (!object.Equals(outR,null))
596                        outR.a = empty<fcomplex>(new ILSize(m, n));
597                    return empty<fcomplex>(A.Size);
598                }
599                int minMN = (m < n) ? m : n;
600                int info = 0;
601                fcomplex[] tau = ILMemoryPool.Pool.New<  fcomplex>(minMN);
602                if (m >= n) {
603                    ret.a = zeros<fcomplex>(m, (economySize) ? minMN : m);
604                } else {
605                    // economySize is always false ... !
606                    // a temporary array is needed for extraction of the compact lapack Q (?geqrf)
607                    ret.a = zeros<fcomplex>(m, n);
608                }
609                ret[full, r(0, n - 1)] = A[full, full];
610                fcomplex[] QArr = ret.GetArrayForWrite();
611               
612                Lapack.cgeqrf(m, n, QArr, m, tau, ref info);
613                if (info != 0) {
614                    throw new ILArgumentException("error inside lapack library (?geqrf). info=" + info.ToString());
615                }
616                // extract R, Q
617                if (economySize) {
618                    outR.a = copyUpperTriangle(QArr, m, n, minMN);
619                   
620                    Lapack.cungqr(m, minMN, minMN, QArr, m, tau, ref info);
621                } else {
622                    outR.a = copyUpperTriangle(QArr, m, n, m);
623                   
624                    Lapack.cungqr(m, m, minMN, QArr, m, tau, ref info);
625                    if (m < n)
626                        ret.a = ret[full,r(0,m - 1)];
627                }
628                if (info != 0)
629                    throw new ILArgumentException("error in lapack library (???gqr). info=" + info.ToString());
630                return ret;
631            }
632        }
633        /// <summary>
634        /// QR decomposition with pivoting
635        /// </summary>
636        /// <param name="A">Input matrix A of size [m x n]</param>
637        /// <param name="outR">[Output] Upper triangular matrix
638        /// R as result of decomposition. Size [m x n] or [min(m,n) x n]
639        /// (see remarks). </param>
640        /// <param name="outE">[Output] Permutation matrix from pivoting. Size [m x m]</param>
641        /// <returns>Orthonormal / unitary matrix Q as result of decomposition.
642        /// Size [m x min(m,n)]</returns>
643        /// <remarks>The function returns Q, R and E such that the equation
644        /// <para>A * E = Q * R</para> holds with roundoff errors, where '*'
645        /// denotes matrix multiplication. E reflects the pivoting done
646        /// inside LAPACK in order to give R increasingly diagonal elements.</remarks>
647        /// <seealso cref="ILNumerics.ILMath.qr(ILInArray{double}, ILOutArray{double}, ILOutArray{double},bool)"/>
648        public static  ILRetArray<fcomplex> qr(
649                                    ILInArray<fcomplex> A,
650                                    ILOutArray< fcomplex> outR,
651                                    ILOutArray< fcomplex> outE ) {
652            return qr(A, outR, outE, false);
653        }
654        /// <summary>
655        /// QR decomposition with pivoting, possibly economical sized
656        /// </summary>
657        /// <param name="A">Input matrix A of size [m x n]</param>
658        /// <param name="outR">[Output] Upper triangular matrix R as
659        /// result of decomposition. Size [m x n] or [min(m,n) x n] depending
660        /// on <paramref name="economySize"/> (see remarks).</param>
661        /// <param name="economySize"><para>If true, <list type="bullet">
662        /// <item>the size of Q and R will be [m x m] and [m x n] respectively.
663        /// However, if m &lt; n, the economySize parameter has no effect on
664        /// those sizes.</item>
665        /// <item>the output parameter E will be returned as row permutation
666        /// vector rather than as permutation matrix</item></list></para>
667        /// <para>If false, this function acts exactly as its overload
668        /// <see cref="ILNumerics.ILMath.qr(ILInArray{double}, ILOutArray{double}, ILOutArray{double})"/></para>
669        /// </param>
670        /// <param name="outE">[Output] Permutation matrix from pivoting. Size [m x m].
671        /// If this is not null, the permutation matrix/ vector E will be returned.
672        /// <para>E is of size [n x n], if <paramref name="economySize"/> is
673        /// true, a row vector of length n otherwise</para></param>
674        /// <returns>Orthonormal / unitary matrix Q as result of decomposition.
675        /// Size [m x m] or [m x min(m,n)], depending on <paramref name="economySize"/>
676        /// (see remarks below)</returns>
677        /// <remarks><para> If <paramref name="economySize"/> is false, the function
678        /// returns Q, R and E such that the equation A * E = Q * R holds within
679        /// roundoff errors. </para>
680        /// <para>If <paramref name="economySize"/> is true, E will be a permutation
681        /// vector and the equation A[":",E] == Q * R holds (except roundoff).</para>
682        /// <para>E reflects the pivoting of A done inside LAPACK in order to give R
683        /// increasingly diagonal elements.</para></remarks>
684        public static ILRetArray<fcomplex> qr(
685                        ILInArray<  fcomplex> A,
686                        ILOutArray<  fcomplex> outR,
687                        ILOutArray<  fcomplex> outE,
688                        bool economySize ) {
689            using (ILScope.Enter(A)) {
690                if (Object.Equals(outR, null)) {
691                    return qr(A);
692                }
693                int m = A.Size[0];
694                int n = A.Size[1];
695                if (m < n && economySize) return qr(A, outR, false);
696                if (m == 0 || n == 0) {
697                    if (!object.Equals(outR,null))
698                        outR.a = zeros< fcomplex>(m, n);
699                    if (!object.Equals(outE,null))
700                        outE.a = zeros< fcomplex>(1, 0);
701                    return empty<fcomplex>(A.Size);
702                }
703                // prepare IPVT
704                if (object.Equals(outE, null))
705                    return qr(A, outR, economySize);
706                if (!economySize) {
707                    outE.a = zeros< fcomplex>( n, n);
708                } else {
709                    outE.a = zeros< fcomplex>( 1, n);
710                }
711                int[] ipvt = ILMemoryPool.Pool.New<int>(n);
712                int minMN = (m < n) ? m : n;
713                int info = 0;
714                fcomplex[] tau = ILMemoryPool.Pool.New<  fcomplex>(minMN);
715                fcomplex[] QArr;
716                ILArray<fcomplex> ret;
717                if (m >= n) {
718                    ret = zeros<fcomplex>(m, (economySize) ? minMN : m);
719                } else {
720                    // economySize is always false ... !
721                    // a temporary array is needed for extraction of the compact lapack Q (?geqrf)
722                    ret = zeros<fcomplex>( m, n);
723                }
724                ret[full,r(0,n-1)] = A[full,full];
725                QArr = ret.GetArrayForWrite();
726               
727                Lapack.cgeqp3(m, n, QArr, m, ipvt, tau, ref info);
728                if (info != 0) {
729                    throw new ILArgumentException("error inside lapack library (?geqrf). info=" + info.ToString());
730                }
731                // extract R, Q
732                fcomplex[] eArr = outE.GetArrayForWrite();
733                if (economySize) {
734                    outR.a = copyUpperTriangle(QArr, m, n, minMN);
735                   
736                    Lapack.cungqr(m, minMN, minMN, QArr, m, tau, ref info);
737                    // transform E into out typed vector
738                    for (int i = 0; i < n; i++) {
739                        eArr[i] = ipvt[i] - 1;
740                    }
741                } else {
742                    outR.a = copyUpperTriangle(QArr, m, n, m);
743                   
744                    Lapack.cungqr(m, m, minMN, QArr, m, tau, ref info);
745                    if (m < n)
746                        ret.a = ret[full,r(0,m - 1)];
747                    // transform E into matrix
748                    for (int i = 0; i < n; i++) {
749                        eArr[(ipvt[i] - 1) + n * i] =  1.0f;
750                    }
751                }
752                if (info != 0)
753                    throw new ILArgumentException("error in lapack library (???gqr). info=" + info.ToString());
754                return ret;
755            }
756        }
757
758        /// <summary>
759        /// QR decomposition - raw Lapack output
760        /// </summary>
761        /// <param name="A">Input matrix A</param>
762        /// <returns>Orthonormal / unitary matrix Q and upper triangular
763        /// matrix R packed into single matrix. This is the output of the
764        /// lapack function ?geqrf.</returns>
765        /// <remarks><para>Input matrix A will not be altered. </para>
766        /// <para>The matrix returned is the direct output of the lapack
767        /// function [d,s,c,z]geqrf respectively. This means that it contains
768        /// the decomposition factors Q and R, but they are combined into a
769        /// single matrix for performance reasons. If you need one of the factors,
770        /// you would use the overloaded function
771        /// <see cref="ILNumerics.ILMath.qr(ILInArray{double},ILOutArray{double})"/>
772        /// instead, which returns those factors separately.</para></remarks>
773        internal static ILRetArray<complex> qr( ILInArray<complex> A ) {
774            using (ILScope.Enter(A)) {
775                if (!A.IsMatrix)
776                    throw new ILArgumentException("input A must be matrix");
777                int m = A.Size[0], n = A.Size[1];
778                ILArray<complex> ret = A.C;
779                complex[] tau = ILMemoryPool.Pool.New<  complex>((m < n) ? m : n);
780                int info = 0;
781               
782                Lapack.zgeqrf(m, n, ret.GetArrayForWrite(), m, tau, ref info);
783                if (info < 0)
784                    throw new ILArgumentException("an unknown error occoured during decomposition");
785                return ret;
786            }
787        }
788        /// <summary>
789        /// QR decomposition, returning Q and R
790        /// </summary>
791        /// <param name="A">Input matrix A of size [m x n]</param>
792        /// <param name="outR">[Output] Upper triangular matrix R as
793        /// result of decomposition, size [m x n]</param>
794        /// <returns>Orthonormal / unitary matrix Q as result of decomposition, size [m x m]</returns>
795        /// <remarks>The function returns Q and R such that the equation
796        /// <para>A = Q * R</para> holds within roundoff errors. ('*' denotes
797        /// matrix multiplication)</remarks>
798        public static ILRetArray<complex> qr(
799                                      ILInArray<complex> A,
800                                      ILOutArray<complex> outR ) {
801            return qr(A, outR, false);
802        }
803        /// <summary>
804        /// QR decomposition, returning Q and R, optionally economical sized
805        /// </summary>
806        /// <param name="A">Input matrix A of size [m x n]</param>
807        /// <param name="outR">[Output] Upper triangular matrix R as
808        /// result of decomposition, size [m x n]</param>
809        /// <param name="economySize">If true, the size of Q and R will
810        /// be [m x m] and [m x n] respectively. However, if m &lt; n,
811        /// the economySize parameter has no effect. </param>
812        /// <returns>Orthonormal real / unitary complex matrix Q as result
813        /// of decomposition. Size [m x m] or [m x min(m,n)], depending
814        /// on <paramref name="economySize"/> (see remarks below)</returns>
815        /// <remarks>The function returns Q and R such that the equation
816        /// <para>A = Q * R</para> holds with roundoff errors. ('*'
817        /// denotes matrix multiplication.)</remarks>
818        public static ILRetArray<complex> qr( ILInArray<complex> A
819            , ILOutArray<complex> outR, bool economySize ) {
820            using (ILScope.Enter(A)) {
821                if (Object.Equals(outR, null)) {
822                    return qr(A);
823                }
824                int m = A.Size[0];
825                int n = A.Size[1];
826                if (m < n && economySize) return qr(A, outR, false);
827                ILArray<complex> ret = empty<complex>(ILSize.Empty00);
828                if (m == 0 || n == 0) {
829                    if (!object.Equals(outR,null))
830                        outR.a = empty<complex>(new ILSize(m, n));
831                    return empty<complex>(A.Size);
832                }
833                int minMN = (m < n) ? m : n;
834                int info = 0;
835                complex[] tau = ILMemoryPool.Pool.New<  complex>(minMN);
836                if (m >= n) {
837                    ret.a = zeros<complex>(m, (economySize) ? minMN : m);
838                } else {
839                    // economySize is always false ... !
840                    // a temporary array is needed for extraction of the compact lapack Q (?geqrf)
841                    ret.a = zeros<complex>(m, n);
842                }
843                ret[full, r(0, n - 1)] = A[full, full];
844                complex[] QArr = ret.GetArrayForWrite();
845               
846                Lapack.zgeqrf(m, n, QArr, m, tau, ref info);
847                if (info != 0) {
848                    throw new ILArgumentException("error inside lapack library (?geqrf). info=" + info.ToString());
849                }
850                // extract R, Q
851                if (economySize) {
852                    outR.a = copyUpperTriangle(QArr, m, n, minMN);
853                   
854                    Lapack.zungqr(m, minMN, minMN, QArr, m, tau, ref info);
855                } else {
856                    outR.a = copyUpperTriangle(QArr, m, n, m);
857                   
858                    Lapack.zungqr(m, m, minMN, QArr, m, tau, ref info);
859                    if (m < n)
860                        ret.a = ret[full,r(0,m - 1)];
861                }
862                if (info != 0)
863                    throw new ILArgumentException("error in lapack library (???gqr). info=" + info.ToString());
864                return ret;
865            }
866        }
867        /// <summary>
868        /// QR decomposition with pivoting
869        /// </summary>
870        /// <param name="A">Input matrix A of size [m x n]</param>
871        /// <param name="outR">[Output] Upper triangular matrix
872        /// R as result of decomposition. Size [m x n] or [min(m,n) x n]
873        /// (see remarks). </param>
874        /// <param name="outE">[Output] Permutation matrix from pivoting. Size [m x m]</param>
875        /// <returns>Orthonormal / unitary matrix Q as result of decomposition.
876        /// Size [m x min(m,n)]</returns>
877        /// <remarks>The function returns Q, R and E such that the equation
878        /// <para>A * E = Q * R</para> holds with roundoff errors, where '*'
879        /// denotes matrix multiplication. E reflects the pivoting done
880        /// inside LAPACK in order to give R increasingly diagonal elements.</remarks>
881        /// <seealso cref="ILNumerics.ILMath.qr(ILInArray{double}, ILOutArray{double}, ILOutArray{double},bool)"/>
882        public static  ILRetArray<complex> qr(
883                                    ILInArray<complex> A,
884                                    ILOutArray< complex> outR,
885                                    ILOutArray< complex> outE ) {
886            return qr(A, outR, outE, false);
887        }
888        /// <summary>
889        /// QR decomposition with pivoting, possibly economical sized
890        /// </summary>
891        /// <param name="A">Input matrix A of size [m x n]</param>
892        /// <param name="outR">[Output] Upper triangular matrix R as
893        /// result of decomposition. Size [m x n] or [min(m,n) x n] depending
894        /// on <paramref name="economySize"/> (see remarks).</param>
895        /// <param name="economySize"><para>If true, <list type="bullet">
896        /// <item>the size of Q and R will be [m x m] and [m x n] respectively.
897        /// However, if m &lt; n, the economySize parameter has no effect on
898        /// those sizes.</item>
899        /// <item>the output parameter E will be returned as row permutation
900        /// vector rather than as permutation matrix</item></list></para>
901        /// <para>If false, this function acts exactly as its overload
902        /// <see cref="ILNumerics.ILMath.qr(ILInArray{double}, ILOutArray{double}, ILOutArray{double})"/></para>
903        /// </param>
904        /// <param name="outE">[Output] Permutation matrix from pivoting. Size [m x m].
905        /// If this is not null, the permutation matrix/ vector E will be returned.
906        /// <para>E is of size [n x n], if <paramref name="economySize"/> is
907        /// true, a row vector of length n otherwise</para></param>
908        /// <returns>Orthonormal / unitary matrix Q as result of decomposition.
909        /// Size [m x m] or [m x min(m,n)], depending on <paramref name="economySize"/>
910        /// (see remarks below)</returns>
911        /// <remarks><para> If <paramref name="economySize"/> is false, the function
912        /// returns Q, R and E such that the equation A * E = Q * R holds within
913        /// roundoff errors. </para>
914        /// <para>If <paramref name="economySize"/> is true, E will be a permutation
915        /// vector and the equation A[":",E] == Q * R holds (except roundoff).</para>
916        /// <para>E reflects the pivoting of A done inside LAPACK in order to give R
917        /// increasingly diagonal elements.</para></remarks>
918        public static ILRetArray<complex> qr(
919                        ILInArray<  complex> A,
920                        ILOutArray<  complex> outR,
921                        ILOutArray<  complex> outE,
922                        bool economySize ) {
923            using (ILScope.Enter(A)) {
924                if (Object.Equals(outR, null)) {
925                    return qr(A);
926                }
927                int m = A.Size[0];
928                int n = A.Size[1];
929                if (m < n && economySize) return qr(A, outR, false);
930                if (m == 0 || n == 0) {
931                    if (!object.Equals(outR,null))
932                        outR.a = zeros< complex>(m, n);
933                    if (!object.Equals(outE,null))
934                        outE.a = zeros< complex>(1, 0);
935                    return empty<complex>(A.Size);
936                }
937                // prepare IPVT
938                if (object.Equals(outE, null))
939                    return qr(A, outR, economySize);
940                if (!economySize) {
941                    outE.a = zeros< complex>( n, n);
942                } else {
943                    outE.a = zeros< complex>( 1, n);
944                }
945                int[] ipvt = ILMemoryPool.Pool.New<int>(n);
946                int minMN = (m < n) ? m : n;
947                int info = 0;
948                complex[] tau = ILMemoryPool.Pool.New<  complex>(minMN);
949                complex[] QArr;
950                ILArray<complex> ret;
951                if (m >= n) {
952                    ret = zeros<complex>(m, (economySize) ? minMN : m);
953                } else {
954                    // economySize is always false ... !
955                    // a temporary array is needed for extraction of the compact lapack Q (?geqrf)
956                    ret = zeros<complex>( m, n);
957                }
958                ret[full,r(0,n-1)] = A[full,full];
959                QArr = ret.GetArrayForWrite();
960               
961                Lapack.zgeqp3(m, n, QArr, m, ipvt, tau, ref info);
962                if (info != 0) {
963                    throw new ILArgumentException("error inside lapack library (?geqrf). info=" + info.ToString());
964                }
965                // extract R, Q
966                complex[] eArr = outE.GetArrayForWrite();
967                if (economySize) {
968                    outR.a = copyUpperTriangle(QArr, m, n, minMN);
969                   
970                    Lapack.zungqr(m, minMN, minMN, QArr, m, tau, ref info);
971                    // transform E into out typed vector
972                    for (int i = 0; i < n; i++) {
973                        eArr[i] = ipvt[i] - 1;
974                    }
975                } else {
976                    outR.a = copyUpperTriangle(QArr, m, n, m);
977                   
978                    Lapack.zungqr(m, m, minMN, QArr, m, tau, ref info);
979                    if (m < n)
980                        ret.a = ret[full,r(0,m - 1)];
981                    // transform E into matrix
982                    for (int i = 0; i < n; i++) {
983                        eArr[(ipvt[i] - 1) + n * i] =  1.0;
984                    }
985                }
986                if (info != 0)
987                    throw new ILArgumentException("error in lapack library (???gqr). info=" + info.ToString());
988                return ret;
989            }
990        }
991
992
993#endregion HYCALPER AUTO GENERATED CODE
994
995    }
996}
Note: See TracBrowser for help on using the repository browser.