Использование Lapack с C++ дает мне небольшую головную боль. Я нашел функции, определенные для fortran немного эксцентричным, поэтому я попытался сделать несколько функций на C++, чтобы облегчить мне чтение того, что происходит.Матрица-векторный продукт с dgemm/dgemv
Во всяком случае, я не получаю продукт матрицы-вектора, работающий по своему усмотрению. Вот небольшой пример программы.
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;
}
компилирование:
г ++ -c smallmatlib.cpp
г ++ smallmatlab.cpp smallm atlib.o -L/usr/local/lib -lclapack -lcblas
Теперь проблема с функцией matvecprod. С примером матрицы А и пример вектора V, он должен производить вывод, как
12.4.. 26.8..
, но вместо этого он печатает
2.00.. 0.00..
Я пытался произвести правильный результат как с DGEMM и dgemv, но не смог. У меня есть подозрение, что мои переменные incx и incy не имеют правильных значений, но трудно найти объяснение для них, которое я бы понял.
Меньшая проблема заключается в том, что в данный момент я не могу использовать их как vecmatprod (v, A, v, SIZE) - то есть, я всегда должен определить вектор и, который будет содержать результат, отдельно, и вызовите vecmatprod (v, A, u, SIZE). Любая помощь будет оценена по достоинству.
Как примечание, я также начинаю на C++, поэтому я ценю любую критику/предложение, которое может иметь о моем коде.
'delete tmp;' Неверная форма 'delete'. Это должно быть: 'delete [] tmp;' Но зачем проходить все это, когда вы могли просто передать 'u' вашей функции? – PaulMcKenzie
Отредактировал эту часть, однако, не помог ни с одной из проблем. Скажем, если я делаю трансформацию для вектора, я заметил, что иногда было бы удобнее просто назначить v = Av – swirld