Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Matrix 如何从QR分解输出中获得Q?_Matrix_Fortran_Linear Algebra_Lapack_Qr Decomposition - Fatal编程技术网

Matrix 如何从QR分解输出中获得Q?

Matrix 如何从QR分解输出中获得Q?,matrix,fortran,linear-algebra,lapack,qr-decomposition,Matrix,Fortran,Linear Algebra,Lapack,Qr Decomposition,从LAPACK以压缩格式返回QR因式分解的Q部分。解包似乎需要O(k^3)步骤(k个低阶产品),而且似乎不是很简单。另外,我不清楚进行k顺序乘法的数值稳定性 LAPACK是否包含用于解包Q的子例程,如果没有,我应该如何做 DORMQR(SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC, WORK, LWORK, INFO) 它计算Q*C其中Q=H(1)H(2)。H(k)从DGEQRF返回。只需使用C=I 要了解更多信息,请查看。是的,LAPACK确实提供了一个

从LAPACK以压缩格式返回QR因式分解的Q部分。解包似乎需要
O(k^3)
步骤(k个低阶产品),而且似乎不是很简单。另外,我不清楚进行
k
顺序乘法的数值稳定性

LAPACK是否包含用于解包Q的子例程,如果没有,我应该如何做

DORMQR(SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC, WORK, LWORK, INFO)
它计算
Q*C
其中
Q=H(1)H(2)。H(k)
DGEQRF
返回。只需使用
C=I


要了解更多信息,请查看。

是的,LAPACK确实提供了一个例程,用于从基本反射器(即DGEQRF返回的数据部分)检索Q,它被称为。根据描述:

*  DORGQR generates an M-by-N real matrix Q with orthonormal columns,
*  which is defined as the first N columns of a product of K elementary
*  reflectors of order M
*
*        Q  =  H(1) H(2) . . . H(k)
*  as returned by DGEQRF.
使用
C
-wrapper-LAPACKE从
A
Q
R
进行完整的计算可能如下所示(Fortran自适应应该是直接的):

void qr(双*常数Q、双*常数R、双*常数A、常数大小t、常数大小t){
//最大秩由Lapacke使用
const size\u t rank=std::min(\u m,\u n);
//用于Lapacke的Tmp阵列
const std::unique_ptr tau(新双[秩]);
//计算QR因子
拉帕克大调(拉帕克大调,(int)m,(int)n,_A,(int)n,tau.get());
//将上三角矩阵R(秩x_n)复制到位
用于(行大小=0;行<秩;++行){
memset(_R+row*_n,0,row*sizeof(double));//设置起始零
memcpy(_R+行*_n+行,_A+行*_n+行,(_n-行)*sizeof(double));//从Lapack结果复制上三角部分。
}
//创建正交矩阵Q(在tmpA中)
拉帕克·多尔格(拉帕克·罗·少校,(int)m,(int)秩,(int)秩,A,(int)n,tau.get());
//将Q(_mx秩)复制到位置
如果(_m==_n){
memcpy(_Q,_A,sizeof(double)*(_m*_n));
}否则{
用于(行大小=0;行<行+行){
memcpy(_Q+行*秩,_A+行*秩,大小(双)*(秩));
}
}
}

这是我自己的一段代码,我删除了所有检查以提高可读性。为了高效使用,您需要检查输入是否有效,并注意LAPACK调用的返回值。请注意,输入
A
已被破坏。

我试图在R中重现QR分解中Q的压缩形式的实际计算,我猜这就是QR()$QR in R返回的结果,这可能会经过DGEQRF。你能帮我吗?@AntoniParellada对不起,我想我在那里帮不了你。根本没有和R一起工作过。
void qr( double* const _Q, double* const _R, double* const _A, const size_t _m, const size_t _n) {
    // Maximal rank is used by Lapacke
    const size_t rank = std::min(_m, _n); 

    // Tmp Array for Lapacke
    const std::unique_ptr<double[]> tau(new double[rank]);

    // Calculate QR factorisations
    LAPACKE_dgeqrf(LAPACK_ROW_MAJOR, (int) _m, (int) _n, _A, (int) _n, tau.get());

    // Copy the upper triangular Matrix R (rank x _n) into position
    for(size_t row =0; row < rank; ++row) {
        memset(_R+row*_n, 0, row*sizeof(double)); // Set starting zeros
        memcpy(_R+row*_n+row, _A+row*_n+row, (_n-row)*sizeof(double)); // Copy upper triangular part from Lapack result.
    }

    // Create orthogonal matrix Q (in tmpA)
    LAPACKE_dorgqr(LAPACK_ROW_MAJOR, (int) _m, (int) rank, (int) rank, _A, (int) _n, tau.get());

    //Copy Q (_m x rank) into position
    if(_m == _n) {
        memcpy(_Q, _A, sizeof(double)*(_m*_n));
    } else {
        for(size_t row =0; row < _m; ++row) {
            memcpy(_Q+row*rank, _A+row*_n, sizeof(double)*(rank));
        }
    }
}