2017-06-13 164 views
1

在使用Lapack中的BLAS lvl 2函数时,我成功实现了矩阵向量乘法,但是当我尝试转置时,我得到了错误的答案。你能指导我解决我的错误吗? (实际上,我使用C包装,不FORTRAN)BLAS矩阵矢量乘法与矢量矩阵乘法。一个工作;另一个失败

我试图

| 4+i 3 | | 3+2i |   | 4+i 3 |^T | 3+2i | 
| 14+3i 2 | * | 2 | (AND) | 14+3i 2 | * | 2 | 

需要明确的是,第一个成功。第二个输出不正确。

/* config variables */ 
char normal = 'N'; 
char transpose = 'T'; 
integer m = 2; 
complex alpha = {r:1,i:0}; 
complex beta = {r:0,i:0}; 
integer one = 1; 
/* data buffers */ 
complex a[4] = {(complex){r:4, i:1},(complex){r:14, i:3},(complex){r:3, i:0},(complex){r:6, i:0}}; 
complex x[2] = {(complex){r:3, i:2},(complex){r:2, i:0}}; 
complex y[2]; 
/* execution */ 
cgemv_(&normal, &m, &m, &alpha, &a[0], &m, &x[0], &one, &beta, &y[0], &one); 
cgemv_(&transpose, &m, &m, &alpha, &a[0], &m, &x[0], &one, &beta, &y[0], &one); 

第一cgemv_电话后,y持有16.0000+11.0000i 48.0000+37.0000i,其中MATLAB证实是正确的。

但第二个cgemv_调用后,y保存38.0000+17.0000i 21.0000+6.0000i,而MATLAB说它应该是42.0000-1.0000i 21.0000+6.0000i。我不知道可能会出现什么问题。

+0

'a'的最后一个元素被设置为“(复杂){r:6,i:0}”,但与问题中的第一个等式不同。 – roygvib

回答

1

由于2向量乘以2x2矩阵,因此使用penpaper执行操作并不太复杂。如果转置矩阵被用于:

(4 + I)*(3 + 2I)+(14 + 3I)* 2 = 38 + 17I

奇怪:

(4-I)* (3 + 2i)+(14-3i)* 2 = 42 -i

因此,MATLAB的输出可能是使用complex conjugate transpose获得的输出。如果参数的TRANS设置为'C',则BLAS可以产生相同的输出。

这里是一个基于我们的示例代码,显示了BLAS真正为TRANS的不同值计算的代码。它可以通过gcc main.c -o main -lblas -Wall来计算。

#include <stdlib.h> 
#include <stdio.h> 

#include <complex.h> 


extern int cgemv_(char* trans, int * m, int * n, float complex* alpha, float complex* A, int * lda,float complex * x, int* incx, float complex * beta, float complex * y,int* incy); 

int main(void) { 

    /* config variables */ 
    char normal = 'N'; 
    char transpose = 'T'; 
    char ctranspose = 'C'; 
    int m = 2; 
    float complex alpha = 1.0+0.*I; 
    float complex beta = 0.0+0.*I; 
    int one = 1; 
    /* data buffers */ 
    float complex a[4]= {4+1.*I,14+3.*I,3.+0.*I,6.+0.*I}; 
    float complex x[2] = {3.+2.*I,2+0.*I}; 
    float complex y[2]; 
    /* execution */ 

    float complex ye[2]; 
    ye[0]=a[0]*x[0]+a[2]*x[1]; 
    ye[1]=a[1]*x[0]+a[3]*x[1]; 

    cgemv_(&normal, &m, &m, &alpha, &a[0], &m, &x[0], &one, &beta, &y[0], &one); 

    printf("N\n"); 
    printf("y[0]=%2.6f + %2.6f I expected %6f + %6f I\n",creal(y[0]),cimag(y[0]),creal(ye[0]),cimag(ye[0])); 
    printf("y[1]=%2.6f + %2.6f I expected %6f + %6f I\n",creal(y[1]),cimag(y[1]),creal(ye[1]),cimag(ye[1])); 

    //float complex ye[2]; 
    ye[0]=a[0]*x[0]+a[1]*x[1]; 
    ye[1]=a[2]*x[0]+a[3]*x[1]; 

    cgemv_(&transpose, &m, &m, &alpha, &a[0], &m, &x[0], &one, &beta, &y[0], &one); 

    printf("T\n"); 
    printf("y[0]=%2.6f + %2.6f I expected %6f + %6f I\n",creal(y[0]),cimag(y[0]),creal(ye[0]),cimag(ye[0])); 
    printf("y[1]=%2.6f + %2.6f I expected %6f + %6f I\n",creal(y[1]),cimag(y[1]),creal(ye[1]),cimag(ye[1])); 

    ye[0]=conj(a[0])*x[0]+conj(a[1])*x[1]; 
    ye[1]=conj(a[2])*x[0]+conj(a[3])*x[1]; 

    cgemv_(&ctranspose, &m, &m, &alpha, &a[0], &m, &x[0], &one, &beta, &y[0], &one); 

    printf("C\n"); 
    printf("y[0]=%2.6f + %2.6f I expected %6f + %6f I\n",creal(y[0]),cimag(y[0]),creal(ye[0]),cimag(ye[0])); 
    printf("y[1]=%2.6f + %2.6f I expected %6f + %6f I\n",creal(y[1]),cimag(y[1]),creal(ye[1]),cimag(ye[1])); 


    return 0; 
}