【发布时间】:2015-04-23 15:14:02
【问题描述】:
在 C++ 中使用 Lapack 让我有点头疼。 我发现为 fortran 定义的函数有点古怪,所以我尝试在 C++ 上创建一些函数,以使我更容易阅读正在发生的事情。
无论如何,我没有让矩阵向量产品按我的意愿工作。 这是该程序的一个小示例。
smallmatlib.cpp:
#include <cstdio>
#include <stdlib.h>
extern "C"{
// product C= alphaA.B + betaC
void dgemm_(char* TRANSA, char* TRANSB, const int* M,
const int* N, const int* K, double* alpha, double* A,
const int* LDA, double* B, const int* LDB, double* beta,
double* C, const int* LDC);
// product Y= alphaA.X + betaY
void dgemv_(char* TRANS, const int* M, const int* N,
double* alpha, double* A, const int* LDA, double* X,
const int* INCX, double* beta, double* C, const int* INCY);
}
void initvec(double* v, int N){
for(int i= 0; i<N; ++i){
v[i]= 0.0;
}
}
void matvecprod(double* A, double* v, double* u, int N){
double alpha= 1.0, beta= 0.0;
char no= 'N', tr= 'T';
int m= N, n= N, lda= N, incx= N, incy= N;
double* tmp= new double[N];
initvec(tmp, N);
dgemv_(&no,&m,&n,&alpha,A,&lda,v,&incx,&beta,tmp,&incy);
for(int i= 0; i<N; ++i){
u[i]= tmp[i];
}
delete [] tmp;
}
void vecmatprod(double* v, double* A, double* u, int N){
double alpha= 1.0, beta= 0.0;
char no= 'N', tr= 'T';
int m= N, n= 1, k= N, lda= N, ldb= N, ldc= N;
double* tmp= new double[N];
initvec(tmp, N);
dgemm_(&no,&no,&m,&n,&k,&alpha,A,&lda,v,&ldb,&beta,tmp,&ldc);
for(int i= 0; i<N; ++i){
u[i]= tmp[i];
}
delete [] tmp;
}
smallmatlib.h:
#ifndef SMALLMATLIB_H
#define SMALLMATLIB_H
void initvec(double* v, int N);
void matvecprod(double* A, double* v, double* u, int N);
void vecmatprod(double* v, double* A, double* u, int N);
#endif
smallmatlab.cpp:
#include "smallmatlib.h"
#include <cstdio>
#include <stdlib.h>
#define SIZE 2
int main(){
double A[SIZE*SIZE]=
{ 1,2,
3,4 };
double v[SIZE]= {2,5.2};
double u[SIZE]= {0,0};
matvecprod(A,v,u,SIZE);
printf("%f %f\n",u[0],u[1]);
vecmatprod(v,A,u,SIZE);
printf("%f %f\n",u[0],u[1]);
return 0;
}
编译:
g++ -c smallmatlib.cpp
g++ smallmatlab.cpp smallmatlib.o -L/usr/local/lib -lclapack -lcblas
现在函数 matvecprod 是问题所在。 使用示例矩阵 A 和示例向量 v,它应该产生类似的输出
12.4.. 26.8..
但它会打印出来
2.00.. 0.00..
我尝试使用 dgemm 和 dgemv 生成正确的结果,但未能成功。我有一种预感,我的变量 incx 和 incy 没有正确的值,但很难找到我能理解的解释。
一个较小的问题是,目前我不能像这样使用它们 vecmatprod(v,A,v,SIZE) - 也就是说,我总是必须定义向量 u,它将分别保存结果,并调用 vecmatprod(v,A,u,SIZE)。 任何帮助将不胜感激。
顺便说一句,我也是 C++ 的初学者,因此我很感激您对我的代码提出的任何批评/建议。
【问题讨论】:
-
delete tmp;delete的格式错误。应该是:delete [] tmp;但是,当您可以简单地将u传递给您的函数时,为什么还要经历这一切呢? -
编辑了该部分,但没有解决任何问题。比如说,如果我正在对向量进行转换,我注意到有时只分配 v= Av 会更方便
标签: c++ matrix vector lapack blas