///
/// This file is part of ILNumerics Community Edition.
///
/// ILNumerics Community Edition - high performance computing for applications.
/// Copyright (C) 2006 - 2012 Haymo Kutschbach, http://ilnumerics.net
///
/// ILNumerics Community Edition is free software: you can redistribute it and/or modify
/// it under the terms of the GNU General Public License version 3 as published by
/// the Free Software Foundation.
///
/// ILNumerics Community Edition is distributed in the hope that it will be useful,
/// but WITHOUT ANY WARRANTY; without even the implied warranty of
/// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
/// GNU General Public License for more details.
///
/// You should have received a copy of the GNU General Public License
/// along with ILNumerics Community Edition. See the file License.txt in the root
/// of your distribution package. If not, see .
///
/// In addition this software uses the following components and/or licenses:
///
/// =================================================================================
/// The Open Toolkit Library License
///
/// Copyright (c) 2006 - 2009 the Open Toolkit library.
///
/// Permission is hereby granted, free of charge, to any person obtaining a copy
/// of this software and associated documentation files (the "Software"), to deal
/// in the Software without restriction, including without limitation the rights to
/// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
/// the Software, and to permit persons to whom the Software is furnished to do
/// so, subject to the following conditions:
///
/// The above copyright notice and this permission notice shall be included in all
/// copies or substantial portions of the Software.
///
/// =================================================================================
///
using System;
using System.Collections.Generic;
using System.Text;
using ILNumerics.Storage;
using ILNumerics.Misc;
using ILNumerics.Exceptions;
namespace ILNumerics {
public partial class ILMath {
///
/// QR decomposition - raw Lapack output
///
/// Input matrix A
/// Orthonormal / unitary matrix Q and upper triangular
/// matrix R packed into single matrix. This is the output of the
/// lapack function ?geqrf.
/// Input matrix A will not be altered.
/// The matrix returned is the direct output of the lapack
/// function [d,s,c,z]geqrf respectively. This means that it contains
/// the decomposition factors Q and R, but they are combined into a
/// single matrix for performance reasons. If you need one of the factors,
/// you would use the overloaded function
///
/// instead, which returns those factors separately.
internal static ILRetArray qr( ILInArray A ) {
using (ILScope.Enter(A)) {
if (!A.IsMatrix)
throw new ILArgumentException("input A must be matrix");
int m = A.Size[0], n = A.Size[1];
ILArray ret = A.C;
double[] tau = ILMemoryPool.Pool.New< double>((m < n) ? m : n);
int info = 0;
/*!HC:lapack_*geqrf*/
Lapack.dgeqrf(m, n, ret.GetArrayForWrite(), m, tau, ref info);
if (info < 0)
throw new ILArgumentException("an unknown error occoured during decomposition");
return ret;
}
}
///
/// QR decomposition, returning Q and R
///
/// Input matrix A of size [m x n]
/// [Output] Upper triangular matrix R as
/// result of decomposition, size [m x n]
/// Orthonormal / unitary matrix Q as result of decomposition, size [m x m]
/// The function returns Q and R such that the equation
/// A = Q * R holds within roundoff errors. ('*' denotes
/// matrix multiplication)
public static ILRetArray qr(
ILInArray A,
ILOutArray outR ) {
return qr(A, outR, false);
}
///
/// QR decomposition, returning Q and R, optionally economical sized
///
/// Input matrix A of size [m x n]
/// [Output] Upper triangular matrix R as
/// result of decomposition, size [m x n]
/// If true, the size of Q and R will
/// be [m x m] and [m x n] respectively. However, if m < n,
/// the economySize parameter has no effect.
/// Orthonormal real / unitary complex matrix Q as result
/// of decomposition. Size [m x m] or [m x min(m,n)], depending
/// on (see remarks below)
/// The function returns Q and R such that the equation
/// A = Q * R holds with roundoff errors. ('*'
/// denotes matrix multiplication.)
public static ILRetArray qr( ILInArray A
, ILOutArray outR, bool economySize ) {
using (ILScope.Enter(A)) {
if (Object.Equals(outR, null)) {
return qr(A);
}
int m = A.Size[0];
int n = A.Size[1];
if (m < n && economySize) return qr(A, outR, false);
ILArray ret = empty(ILSize.Empty00);
if (m == 0 || n == 0) {
if (!object.Equals(outR,null))
outR.a = empty(new ILSize(m, n));
return empty(A.Size);
}
int minMN = (m < n) ? m : n;
int info = 0;
double[] tau = ILMemoryPool.Pool.New< double>(minMN);
if (m >= n) {
ret.a = zeros(m, (economySize) ? minMN : m);
} else {
// economySize is always false ... !
// a temporary array is needed for extraction of the compact lapack Q (?geqrf)
ret.a = zeros(m, n);
}
ret[full, r(0, n - 1)] = A[full, full];
double[] QArr = ret.GetArrayForWrite();
/*!HC:lapack_*geqrf*/
Lapack.dgeqrf(m, n, QArr, m, tau, ref info);
if (info != 0) {
throw new ILArgumentException("error inside lapack library (?geqrf). info=" + info.ToString());
}
// extract R, Q
if (economySize) {
outR.a = copyUpperTriangle(QArr, m, n, minMN);
/*!HC:lapack_*orgqr*/
Lapack.dorgqr(m, minMN, minMN, QArr, m, tau, ref info);
} else {
outR.a = copyUpperTriangle(QArr, m, n, m);
/*!HC:lapack_*orgqr*/
Lapack.dorgqr(m, m, minMN, QArr, m, tau, ref info);
if (m < n)
ret.a = ret[full,r(0,m - 1)];
}
if (info != 0)
throw new ILArgumentException("error in lapack library (???gqr). info=" + info.ToString());
return ret;
}
}
///
/// QR decomposition with pivoting
///
/// Input matrix A of size [m x n]
/// [Output] Upper triangular matrix
/// R as result of decomposition. Size [m x n] or [min(m,n) x n]
/// (see remarks).
/// [Output] Permutation matrix from pivoting. Size [m x m]
/// Orthonormal / unitary matrix Q as result of decomposition.
/// Size [m x min(m,n)]
/// The function returns Q, R and E such that the equation
/// A * E = Q * R holds with roundoff errors, where '*'
/// denotes matrix multiplication. E reflects the pivoting done
/// inside LAPACK in order to give R increasingly diagonal elements.
///
public static ILRetArray qr(
ILInArray A,
ILOutArray< double> outR,
ILOutArray< double> outE ) {
return qr(A, outR, outE, false);
}
///
/// QR decomposition with pivoting, possibly economical sized
///
/// Input matrix A of size [m x n]
/// [Output] Upper triangular matrix R as
/// result of decomposition. Size [m x n] or [min(m,n) x n] depending
/// on (see remarks).
/// If true,
/// - the size of Q and R will be [m x m] and [m x n] respectively.
/// However, if m < n, the economySize parameter has no effect on
/// those sizes.
/// - the output parameter E will be returned as row permutation
/// vector rather than as permutation matrix
/// If false, this function acts exactly as its overload
///
///
/// [Output] Permutation matrix from pivoting. Size [m x m].
/// If this is not null, the permutation matrix/ vector E will be returned.
/// E is of size [n x n], if is
/// true, a row vector of length n otherwise
/// Orthonormal / unitary matrix Q as result of decomposition.
/// Size [m x m] or [m x min(m,n)], depending on
/// (see remarks below)
/// If is false, the function
/// returns Q, R and E such that the equation A * E = Q * R holds within
/// roundoff errors.
/// If is true, E will be a permutation
/// vector and the equation A[":",E] == Q * R holds (except roundoff).
/// E reflects the pivoting of A done inside LAPACK in order to give R
/// increasingly diagonal elements.
public static ILRetArray qr(
ILInArray< double> A,
ILOutArray< double> outR,
ILOutArray< double> outE,
bool economySize ) {
using (ILScope.Enter(A)) {
if (Object.Equals(outR, null)) {
return qr(A);
}
int m = A.Size[0];
int n = A.Size[1];
if (m < n && economySize) return qr(A, outR, false);
if (m == 0 || n == 0) {
if (!object.Equals(outR,null))
outR.a = zeros< double>(m, n);
if (!object.Equals(outE,null))
outE.a = zeros< double>(1, 0);
return empty(A.Size);
}
// prepare IPVT
if (object.Equals(outE, null))
return qr(A, outR, economySize);
if (!economySize) {
outE.a = zeros< double>( n, n);
} else {
outE.a = zeros< double>( 1, n);
}
int[] ipvt = ILMemoryPool.Pool.New(n);
int minMN = (m < n) ? m : n;
int info = 0;
double[] tau = ILMemoryPool.Pool.New< double>(minMN);
double[] QArr;
ILArray ret;
if (m >= n) {
ret = zeros(m, (economySize) ? minMN : m);
} else {
// economySize is always false ... !
// a temporary array is needed for extraction of the compact lapack Q (?geqrf)
ret = zeros( m, n);
}
ret[full,r(0,n-1)] = A[full,full];
QArr = ret.GetArrayForWrite();
/*!HC:lapack_*geqp3*/
Lapack.dgeqp3(m, n, QArr, m, ipvt, tau, ref info);
if (info != 0) {
throw new ILArgumentException("error inside lapack library (?geqrf). info=" + info.ToString());
}
// extract R, Q
double[] eArr = outE.GetArrayForWrite();
if (economySize) {
outR.a = copyUpperTriangle(QArr, m, n, minMN);
/*!HC:lapack_*orgqr*/
Lapack.dorgqr(m, minMN, minMN, QArr, m, tau, ref info);
// transform E into out typed vector
for (int i = 0; i < n; i++) {
eArr[i] = ipvt[i] - 1;
}
} else {
outR.a = copyUpperTriangle(QArr, m, n, m);
/*!HC:lapack_*orgqr*/
Lapack.dorgqr(m, m, minMN, QArr, m, tau, ref info);
if (m < n)
ret.a = ret[full,r(0,m - 1)];
// transform E into matrix
for (int i = 0; i < n; i++) {
eArr[(ipvt[i] - 1) + n * i] = 1.0;
}
}
if (info != 0)
throw new ILArgumentException("error in lapack library (???gqr). info=" + info.ToString());
return ret;
}
}
#region HYCALPER AUTO GENERATED CODE
///
/// QR decomposition - raw Lapack output
///
/// Input matrix A
/// Orthonormal / unitary matrix Q and upper triangular
/// matrix R packed into single matrix. This is the output of the
/// lapack function ?geqrf.
/// Input matrix A will not be altered.
/// The matrix returned is the direct output of the lapack
/// function [d,s,c,z]geqrf respectively. This means that it contains
/// the decomposition factors Q and R, but they are combined into a
/// single matrix for performance reasons. If you need one of the factors,
/// you would use the overloaded function
///
/// instead, which returns those factors separately.
internal static ILRetArray qr( ILInArray A ) {
using (ILScope.Enter(A)) {
if (!A.IsMatrix)
throw new ILArgumentException("input A must be matrix");
int m = A.Size[0], n = A.Size[1];
ILArray ret = A.C;
float[] tau = ILMemoryPool.Pool.New< float>((m < n) ? m : n);
int info = 0;
Lapack.sgeqrf(m, n, ret.GetArrayForWrite(), m, tau, ref info);
if (info < 0)
throw new ILArgumentException("an unknown error occoured during decomposition");
return ret;
}
}
///
/// QR decomposition, returning Q and R
///
/// Input matrix A of size [m x n]
/// [Output] Upper triangular matrix R as
/// result of decomposition, size [m x n]
/// Orthonormal / unitary matrix Q as result of decomposition, size [m x m]
/// The function returns Q and R such that the equation
/// A = Q * R holds within roundoff errors. ('*' denotes
/// matrix multiplication)
public static ILRetArray qr(
ILInArray A,
ILOutArray outR ) {
return qr(A, outR, false);
}
///
/// QR decomposition, returning Q and R, optionally economical sized
///
/// Input matrix A of size [m x n]
/// [Output] Upper triangular matrix R as
/// result of decomposition, size [m x n]
/// If true, the size of Q and R will
/// be [m x m] and [m x n] respectively. However, if m < n,
/// the economySize parameter has no effect.
/// Orthonormal real / unitary complex matrix Q as result
/// of decomposition. Size [m x m] or [m x min(m,n)], depending
/// on (see remarks below)
/// The function returns Q and R such that the equation
/// A = Q * R holds with roundoff errors. ('*'
/// denotes matrix multiplication.)
public static ILRetArray qr( ILInArray A
, ILOutArray outR, bool economySize ) {
using (ILScope.Enter(A)) {
if (Object.Equals(outR, null)) {
return qr(A);
}
int m = A.Size[0];
int n = A.Size[1];
if (m < n && economySize) return qr(A, outR, false);
ILArray ret = empty(ILSize.Empty00);
if (m == 0 || n == 0) {
if (!object.Equals(outR,null))
outR.a = empty(new ILSize(m, n));
return empty(A.Size);
}
int minMN = (m < n) ? m : n;
int info = 0;
float[] tau = ILMemoryPool.Pool.New< float>(minMN);
if (m >= n) {
ret.a = zeros(m, (economySize) ? minMN : m);
} else {
// economySize is always false ... !
// a temporary array is needed for extraction of the compact lapack Q (?geqrf)
ret.a = zeros(m, n);
}
ret[full, r(0, n - 1)] = A[full, full];
float[] QArr = ret.GetArrayForWrite();
Lapack.sgeqrf(m, n, QArr, m, tau, ref info);
if (info != 0) {
throw new ILArgumentException("error inside lapack library (?geqrf). info=" + info.ToString());
}
// extract R, Q
if (economySize) {
outR.a = copyUpperTriangle(QArr, m, n, minMN);
Lapack.sorgqr(m, minMN, minMN, QArr, m, tau, ref info);
} else {
outR.a = copyUpperTriangle(QArr, m, n, m);
Lapack.sorgqr(m, m, minMN, QArr, m, tau, ref info);
if (m < n)
ret.a = ret[full,r(0,m - 1)];
}
if (info != 0)
throw new ILArgumentException("error in lapack library (???gqr). info=" + info.ToString());
return ret;
}
}
///
/// QR decomposition with pivoting
///
/// Input matrix A of size [m x n]
/// [Output] Upper triangular matrix
/// R as result of decomposition. Size [m x n] or [min(m,n) x n]
/// (see remarks).
/// [Output] Permutation matrix from pivoting. Size [m x m]
/// Orthonormal / unitary matrix Q as result of decomposition.
/// Size [m x min(m,n)]
/// The function returns Q, R and E such that the equation
/// A * E = Q * R holds with roundoff errors, where '*'
/// denotes matrix multiplication. E reflects the pivoting done
/// inside LAPACK in order to give R increasingly diagonal elements.
///
public static ILRetArray qr(
ILInArray A,
ILOutArray< float> outR,
ILOutArray< float> outE ) {
return qr(A, outR, outE, false);
}
///
/// QR decomposition with pivoting, possibly economical sized
///
/// Input matrix A of size [m x n]
/// [Output] Upper triangular matrix R as
/// result of decomposition. Size [m x n] or [min(m,n) x n] depending
/// on (see remarks).
/// If true,
/// - the size of Q and R will be [m x m] and [m x n] respectively.
/// However, if m < n, the economySize parameter has no effect on
/// those sizes.
/// - the output parameter E will be returned as row permutation
/// vector rather than as permutation matrix
/// If false, this function acts exactly as its overload
///
///
/// [Output] Permutation matrix from pivoting. Size [m x m].
/// If this is not null, the permutation matrix/ vector E will be returned.
/// E is of size [n x n], if is
/// true, a row vector of length n otherwise
/// Orthonormal / unitary matrix Q as result of decomposition.
/// Size [m x m] or [m x min(m,n)], depending on
/// (see remarks below)
/// If is false, the function
/// returns Q, R and E such that the equation A * E = Q * R holds within
/// roundoff errors.
/// If is true, E will be a permutation
/// vector and the equation A[":",E] == Q * R holds (except roundoff).
/// E reflects the pivoting of A done inside LAPACK in order to give R
/// increasingly diagonal elements.
public static ILRetArray qr(
ILInArray< float> A,
ILOutArray< float> outR,
ILOutArray< float> outE,
bool economySize ) {
using (ILScope.Enter(A)) {
if (Object.Equals(outR, null)) {
return qr(A);
}
int m = A.Size[0];
int n = A.Size[1];
if (m < n && economySize) return qr(A, outR, false);
if (m == 0 || n == 0) {
if (!object.Equals(outR,null))
outR.a = zeros< float>(m, n);
if (!object.Equals(outE,null))
outE.a = zeros< float>(1, 0);
return empty(A.Size);
}
// prepare IPVT
if (object.Equals(outE, null))
return qr(A, outR, economySize);
if (!economySize) {
outE.a = zeros< float>( n, n);
} else {
outE.a = zeros< float>( 1, n);
}
int[] ipvt = ILMemoryPool.Pool.New(n);
int minMN = (m < n) ? m : n;
int info = 0;
float[] tau = ILMemoryPool.Pool.New< float>(minMN);
float[] QArr;
ILArray ret;
if (m >= n) {
ret = zeros(m, (economySize) ? minMN : m);
} else {
// economySize is always false ... !
// a temporary array is needed for extraction of the compact lapack Q (?geqrf)
ret = zeros( m, n);
}
ret[full,r(0,n-1)] = A[full,full];
QArr = ret.GetArrayForWrite();
Lapack.sgeqp3(m, n, QArr, m, ipvt, tau, ref info);
if (info != 0) {
throw new ILArgumentException("error inside lapack library (?geqrf). info=" + info.ToString());
}
// extract R, Q
float[] eArr = outE.GetArrayForWrite();
if (economySize) {
outR.a = copyUpperTriangle(QArr, m, n, minMN);
Lapack.sorgqr(m, minMN, minMN, QArr, m, tau, ref info);
// transform E into out typed vector
for (int i = 0; i < n; i++) {
eArr[i] = ipvt[i] - 1;
}
} else {
outR.a = copyUpperTriangle(QArr, m, n, m);
Lapack.sorgqr(m, m, minMN, QArr, m, tau, ref info);
if (m < n)
ret.a = ret[full,r(0,m - 1)];
// transform E into matrix
for (int i = 0; i < n; i++) {
eArr[(ipvt[i] - 1) + n * i] = 1.0f;
}
}
if (info != 0)
throw new ILArgumentException("error in lapack library (???gqr). info=" + info.ToString());
return ret;
}
}
///
/// QR decomposition - raw Lapack output
///
/// Input matrix A
/// Orthonormal / unitary matrix Q and upper triangular
/// matrix R packed into single matrix. This is the output of the
/// lapack function ?geqrf.
/// Input matrix A will not be altered.
/// The matrix returned is the direct output of the lapack
/// function [d,s,c,z]geqrf respectively. This means that it contains
/// the decomposition factors Q and R, but they are combined into a
/// single matrix for performance reasons. If you need one of the factors,
/// you would use the overloaded function
///
/// instead, which returns those factors separately.
internal static ILRetArray qr( ILInArray A ) {
using (ILScope.Enter(A)) {
if (!A.IsMatrix)
throw new ILArgumentException("input A must be matrix");
int m = A.Size[0], n = A.Size[1];
ILArray ret = A.C;
fcomplex[] tau = ILMemoryPool.Pool.New< fcomplex>((m < n) ? m : n);
int info = 0;
Lapack.cgeqrf(m, n, ret.GetArrayForWrite(), m, tau, ref info);
if (info < 0)
throw new ILArgumentException("an unknown error occoured during decomposition");
return ret;
}
}
///
/// QR decomposition, returning Q and R
///
/// Input matrix A of size [m x n]
/// [Output] Upper triangular matrix R as
/// result of decomposition, size [m x n]
/// Orthonormal / unitary matrix Q as result of decomposition, size [m x m]
/// The function returns Q and R such that the equation
/// A = Q * R holds within roundoff errors. ('*' denotes
/// matrix multiplication)
public static ILRetArray qr(
ILInArray A,
ILOutArray outR ) {
return qr(A, outR, false);
}
///
/// QR decomposition, returning Q and R, optionally economical sized
///
/// Input matrix A of size [m x n]
/// [Output] Upper triangular matrix R as
/// result of decomposition, size [m x n]
/// If true, the size of Q and R will
/// be [m x m] and [m x n] respectively. However, if m < n,
/// the economySize parameter has no effect.
/// Orthonormal real / unitary complex matrix Q as result
/// of decomposition. Size [m x m] or [m x min(m,n)], depending
/// on (see remarks below)
/// The function returns Q and R such that the equation
/// A = Q * R holds with roundoff errors. ('*'
/// denotes matrix multiplication.)
public static ILRetArray qr( ILInArray A
, ILOutArray outR, bool economySize ) {
using (ILScope.Enter(A)) {
if (Object.Equals(outR, null)) {
return qr(A);
}
int m = A.Size[0];
int n = A.Size[1];
if (m < n && economySize) return qr(A, outR, false);
ILArray ret = empty(ILSize.Empty00);
if (m == 0 || n == 0) {
if (!object.Equals(outR,null))
outR.a = empty(new ILSize(m, n));
return empty(A.Size);
}
int minMN = (m < n) ? m : n;
int info = 0;
fcomplex[] tau = ILMemoryPool.Pool.New< fcomplex>(minMN);
if (m >= n) {
ret.a = zeros(m, (economySize) ? minMN : m);
} else {
// economySize is always false ... !
// a temporary array is needed for extraction of the compact lapack Q (?geqrf)
ret.a = zeros(m, n);
}
ret[full, r(0, n - 1)] = A[full, full];
fcomplex[] QArr = ret.GetArrayForWrite();
Lapack.cgeqrf(m, n, QArr, m, tau, ref info);
if (info != 0) {
throw new ILArgumentException("error inside lapack library (?geqrf). info=" + info.ToString());
}
// extract R, Q
if (economySize) {
outR.a = copyUpperTriangle(QArr, m, n, minMN);
Lapack.cungqr(m, minMN, minMN, QArr, m, tau, ref info);
} else {
outR.a = copyUpperTriangle(QArr, m, n, m);
Lapack.cungqr(m, m, minMN, QArr, m, tau, ref info);
if (m < n)
ret.a = ret[full,r(0,m - 1)];
}
if (info != 0)
throw new ILArgumentException("error in lapack library (???gqr). info=" + info.ToString());
return ret;
}
}
///
/// QR decomposition with pivoting
///
/// Input matrix A of size [m x n]
/// [Output] Upper triangular matrix
/// R as result of decomposition. Size [m x n] or [min(m,n) x n]
/// (see remarks).
/// [Output] Permutation matrix from pivoting. Size [m x m]
/// Orthonormal / unitary matrix Q as result of decomposition.
/// Size [m x min(m,n)]
/// The function returns Q, R and E such that the equation
/// A * E = Q * R holds with roundoff errors, where '*'
/// denotes matrix multiplication. E reflects the pivoting done
/// inside LAPACK in order to give R increasingly diagonal elements.
///
public static ILRetArray qr(
ILInArray A,
ILOutArray< fcomplex> outR,
ILOutArray< fcomplex> outE ) {
return qr(A, outR, outE, false);
}
///
/// QR decomposition with pivoting, possibly economical sized
///
/// Input matrix A of size [m x n]
/// [Output] Upper triangular matrix R as
/// result of decomposition. Size [m x n] or [min(m,n) x n] depending
/// on (see remarks).
/// If true,
/// - the size of Q and R will be [m x m] and [m x n] respectively.
/// However, if m < n, the economySize parameter has no effect on
/// those sizes.
/// - the output parameter E will be returned as row permutation
/// vector rather than as permutation matrix
/// If false, this function acts exactly as its overload
///
///
/// [Output] Permutation matrix from pivoting. Size [m x m].
/// If this is not null, the permutation matrix/ vector E will be returned.
/// E is of size [n x n], if is
/// true, a row vector of length n otherwise
/// Orthonormal / unitary matrix Q as result of decomposition.
/// Size [m x m] or [m x min(m,n)], depending on
/// (see remarks below)
/// If is false, the function
/// returns Q, R and E such that the equation A * E = Q * R holds within
/// roundoff errors.
/// If is true, E will be a permutation
/// vector and the equation A[":",E] == Q * R holds (except roundoff).
/// E reflects the pivoting of A done inside LAPACK in order to give R
/// increasingly diagonal elements.
public static ILRetArray qr(
ILInArray< fcomplex> A,
ILOutArray< fcomplex> outR,
ILOutArray< fcomplex> outE,
bool economySize ) {
using (ILScope.Enter(A)) {
if (Object.Equals(outR, null)) {
return qr(A);
}
int m = A.Size[0];
int n = A.Size[1];
if (m < n && economySize) return qr(A, outR, false);
if (m == 0 || n == 0) {
if (!object.Equals(outR,null))
outR.a = zeros< fcomplex>(m, n);
if (!object.Equals(outE,null))
outE.a = zeros< fcomplex>(1, 0);
return empty(A.Size);
}
// prepare IPVT
if (object.Equals(outE, null))
return qr(A, outR, economySize);
if (!economySize) {
outE.a = zeros< fcomplex>( n, n);
} else {
outE.a = zeros< fcomplex>( 1, n);
}
int[] ipvt = ILMemoryPool.Pool.New(n);
int minMN = (m < n) ? m : n;
int info = 0;
fcomplex[] tau = ILMemoryPool.Pool.New< fcomplex>(minMN);
fcomplex[] QArr;
ILArray ret;
if (m >= n) {
ret = zeros(m, (economySize) ? minMN : m);
} else {
// economySize is always false ... !
// a temporary array is needed for extraction of the compact lapack Q (?geqrf)
ret = zeros( m, n);
}
ret[full,r(0,n-1)] = A[full,full];
QArr = ret.GetArrayForWrite();
Lapack.cgeqp3(m, n, QArr, m, ipvt, tau, ref info);
if (info != 0) {
throw new ILArgumentException("error inside lapack library (?geqrf). info=" + info.ToString());
}
// extract R, Q
fcomplex[] eArr = outE.GetArrayForWrite();
if (economySize) {
outR.a = copyUpperTriangle(QArr, m, n, minMN);
Lapack.cungqr(m, minMN, minMN, QArr, m, tau, ref info);
// transform E into out typed vector
for (int i = 0; i < n; i++) {
eArr[i] = ipvt[i] - 1;
}
} else {
outR.a = copyUpperTriangle(QArr, m, n, m);
Lapack.cungqr(m, m, minMN, QArr, m, tau, ref info);
if (m < n)
ret.a = ret[full,r(0,m - 1)];
// transform E into matrix
for (int i = 0; i < n; i++) {
eArr[(ipvt[i] - 1) + n * i] = 1.0f;
}
}
if (info != 0)
throw new ILArgumentException("error in lapack library (???gqr). info=" + info.ToString());
return ret;
}
}
///
/// QR decomposition - raw Lapack output
///
/// Input matrix A
/// Orthonormal / unitary matrix Q and upper triangular
/// matrix R packed into single matrix. This is the output of the
/// lapack function ?geqrf.
/// Input matrix A will not be altered.
/// The matrix returned is the direct output of the lapack
/// function [d,s,c,z]geqrf respectively. This means that it contains
/// the decomposition factors Q and R, but they are combined into a
/// single matrix for performance reasons. If you need one of the factors,
/// you would use the overloaded function
///
/// instead, which returns those factors separately.
internal static ILRetArray qr( ILInArray A ) {
using (ILScope.Enter(A)) {
if (!A.IsMatrix)
throw new ILArgumentException("input A must be matrix");
int m = A.Size[0], n = A.Size[1];
ILArray ret = A.C;
complex[] tau = ILMemoryPool.Pool.New< complex>((m < n) ? m : n);
int info = 0;
Lapack.zgeqrf(m, n, ret.GetArrayForWrite(), m, tau, ref info);
if (info < 0)
throw new ILArgumentException("an unknown error occoured during decomposition");
return ret;
}
}
///
/// QR decomposition, returning Q and R
///
/// Input matrix A of size [m x n]
/// [Output] Upper triangular matrix R as
/// result of decomposition, size [m x n]
/// Orthonormal / unitary matrix Q as result of decomposition, size [m x m]
/// The function returns Q and R such that the equation
/// A = Q * R holds within roundoff errors. ('*' denotes
/// matrix multiplication)
public static ILRetArray qr(
ILInArray A,
ILOutArray outR ) {
return qr(A, outR, false);
}
///
/// QR decomposition, returning Q and R, optionally economical sized
///
/// Input matrix A of size [m x n]
/// [Output] Upper triangular matrix R as
/// result of decomposition, size [m x n]
/// If true, the size of Q and R will
/// be [m x m] and [m x n] respectively. However, if m < n,
/// the economySize parameter has no effect.
/// Orthonormal real / unitary complex matrix Q as result
/// of decomposition. Size [m x m] or [m x min(m,n)], depending
/// on (see remarks below)
/// The function returns Q and R such that the equation
/// A = Q * R holds with roundoff errors. ('*'
/// denotes matrix multiplication.)
public static ILRetArray qr( ILInArray A
, ILOutArray outR, bool economySize ) {
using (ILScope.Enter(A)) {
if (Object.Equals(outR, null)) {
return qr(A);
}
int m = A.Size[0];
int n = A.Size[1];
if (m < n && economySize) return qr(A, outR, false);
ILArray ret = empty(ILSize.Empty00);
if (m == 0 || n == 0) {
if (!object.Equals(outR,null))
outR.a = empty(new ILSize(m, n));
return empty(A.Size);
}
int minMN = (m < n) ? m : n;
int info = 0;
complex[] tau = ILMemoryPool.Pool.New< complex>(minMN);
if (m >= n) {
ret.a = zeros(m, (economySize) ? minMN : m);
} else {
// economySize is always false ... !
// a temporary array is needed for extraction of the compact lapack Q (?geqrf)
ret.a = zeros(m, n);
}
ret[full, r(0, n - 1)] = A[full, full];
complex[] QArr = ret.GetArrayForWrite();
Lapack.zgeqrf(m, n, QArr, m, tau, ref info);
if (info != 0) {
throw new ILArgumentException("error inside lapack library (?geqrf). info=" + info.ToString());
}
// extract R, Q
if (economySize) {
outR.a = copyUpperTriangle(QArr, m, n, minMN);
Lapack.zungqr(m, minMN, minMN, QArr, m, tau, ref info);
} else {
outR.a = copyUpperTriangle(QArr, m, n, m);
Lapack.zungqr(m, m, minMN, QArr, m, tau, ref info);
if (m < n)
ret.a = ret[full,r(0,m - 1)];
}
if (info != 0)
throw new ILArgumentException("error in lapack library (???gqr). info=" + info.ToString());
return ret;
}
}
///
/// QR decomposition with pivoting
///
/// Input matrix A of size [m x n]
/// [Output] Upper triangular matrix
/// R as result of decomposition. Size [m x n] or [min(m,n) x n]
/// (see remarks).
/// [Output] Permutation matrix from pivoting. Size [m x m]
/// Orthonormal / unitary matrix Q as result of decomposition.
/// Size [m x min(m,n)]
/// The function returns Q, R and E such that the equation
/// A * E = Q * R holds with roundoff errors, where '*'
/// denotes matrix multiplication. E reflects the pivoting done
/// inside LAPACK in order to give R increasingly diagonal elements.
///
public static ILRetArray qr(
ILInArray A,
ILOutArray< complex> outR,
ILOutArray< complex> outE ) {
return qr(A, outR, outE, false);
}
///
/// QR decomposition with pivoting, possibly economical sized
///
/// Input matrix A of size [m x n]
/// [Output] Upper triangular matrix R as
/// result of decomposition. Size [m x n] or [min(m,n) x n] depending
/// on (see remarks).
/// If true,
/// - the size of Q and R will be [m x m] and [m x n] respectively.
/// However, if m < n, the economySize parameter has no effect on
/// those sizes.
/// - the output parameter E will be returned as row permutation
/// vector rather than as permutation matrix
/// If false, this function acts exactly as its overload
///
///
/// [Output] Permutation matrix from pivoting. Size [m x m].
/// If this is not null, the permutation matrix/ vector E will be returned.
/// E is of size [n x n], if is
/// true, a row vector of length n otherwise
/// Orthonormal / unitary matrix Q as result of decomposition.
/// Size [m x m] or [m x min(m,n)], depending on
/// (see remarks below)
/// If is false, the function
/// returns Q, R and E such that the equation A * E = Q * R holds within
/// roundoff errors.
/// If is true, E will be a permutation
/// vector and the equation A[":",E] == Q * R holds (except roundoff).
/// E reflects the pivoting of A done inside LAPACK in order to give R
/// increasingly diagonal elements.
public static ILRetArray qr(
ILInArray< complex> A,
ILOutArray< complex> outR,
ILOutArray< complex> outE,
bool economySize ) {
using (ILScope.Enter(A)) {
if (Object.Equals(outR, null)) {
return qr(A);
}
int m = A.Size[0];
int n = A.Size[1];
if (m < n && economySize) return qr(A, outR, false);
if (m == 0 || n == 0) {
if (!object.Equals(outR,null))
outR.a = zeros< complex>(m, n);
if (!object.Equals(outE,null))
outE.a = zeros< complex>(1, 0);
return empty(A.Size);
}
// prepare IPVT
if (object.Equals(outE, null))
return qr(A, outR, economySize);
if (!economySize) {
outE.a = zeros< complex>( n, n);
} else {
outE.a = zeros< complex>( 1, n);
}
int[] ipvt = ILMemoryPool.Pool.New(n);
int minMN = (m < n) ? m : n;
int info = 0;
complex[] tau = ILMemoryPool.Pool.New< complex>(minMN);
complex[] QArr;
ILArray ret;
if (m >= n) {
ret = zeros(m, (economySize) ? minMN : m);
} else {
// economySize is always false ... !
// a temporary array is needed for extraction of the compact lapack Q (?geqrf)
ret = zeros( m, n);
}
ret[full,r(0,n-1)] = A[full,full];
QArr = ret.GetArrayForWrite();
Lapack.zgeqp3(m, n, QArr, m, ipvt, tau, ref info);
if (info != 0) {
throw new ILArgumentException("error inside lapack library (?geqrf). info=" + info.ToString());
}
// extract R, Q
complex[] eArr = outE.GetArrayForWrite();
if (economySize) {
outR.a = copyUpperTriangle(QArr, m, n, minMN);
Lapack.zungqr(m, minMN, minMN, QArr, m, tau, ref info);
// transform E into out typed vector
for (int i = 0; i < n; i++) {
eArr[i] = ipvt[i] - 1;
}
} else {
outR.a = copyUpperTriangle(QArr, m, n, m);
Lapack.zungqr(m, m, minMN, QArr, m, tau, ref info);
if (m < n)
ret.a = ret[full,r(0,m - 1)];
// transform E into matrix
for (int i = 0; i < n; i++) {
eArr[(ipvt[i] - 1) + n * i] = 1.0;
}
}
if (info != 0)
throw new ILArgumentException("error in lapack library (???gqr). info=" + info.ToString());
return ret;
}
}
#endregion HYCALPER AUTO GENERATED CODE
}
}