matrix — Перегрузка оператора умножения в переполнении стека

Я написал C ++ интерфейс для LAPACK, но столкнулся с некоторыми проблемами с памятью, которые заставили меня пересмотреть некоторые из перегрузок операторов.

Прямо сейчас я перегружен оператором * вне определения класса (но как друг класса Matrix), который принимает два объекта Matrix, выделяет третий с соответствующими измерениями, использует D (GE / SY) MM для вычисления product (сохранение во внутреннем хранилище вновь выделенной матрицы) и затем возвращает указатель на эту новую матрицу. И.Е.

class Matrix {
...
friend Matrix* operator*(const Matrix&, const Matrix&);
...
}

Matrix* operator*(const Matrix& m1, const Matrix& m2) {
Matrix *prod = new Matrix(m1.rows_, m2.cols_);
if(m1.cols_!=m2.rows_) {
throw 3008;
} else {
double alpha = 1.0;
double beta = 0.0;
if(m1.symm_=='G' && m2.symm_=='G'){
dgemm_(&m1.trans_,&m2.trans_,&m1.rows_,&m2.cols_,&m1.cols_,&alpha,m1.data_,
&m1.rows_,m2.data_,&m1.cols_,&beta,prod->data_,&m2.cols_);
} else if(m1.symm_=='S'){
char SIDE = 'L';
char UPLO = 'L';
dsymm_(&SIDE,&UPLO,&m1.rows_,&m2.cols_,&alpha,m1.data_,&m1.rows_,m2.data_,
&m2.cols_,&beta,prod->data_,&m2.cols_);
} else if(m2.symm_=='S'){
char SIDE = 'R';
char UPLO = 'L';
dsymm_(&SIDE,&UPLO,&m2.rows_,&m1.cols_,&alpha,m2.data_,&m2.rows_,m1.data_,
&m1.cols_,&beta,prod->data_,&m1.cols_);
};
}
return prod;
};

Тогда я использую

Matrix *A, *B, *C;
// def of A and B
C = (*A)*(*B);

И это работает просто отлично. У меня проблема в том, что я должен выделять новую матрицу каждый раз, когда я делаю это. То, что я хотел бы сделать, это выделить C матрицу один раз и поместить произведение A а также B во внутреннее хранилище C (C->data_). Из того, что я смог найти при перегрузке операторов, я не могу найти хороший способ сделать это. Я знаю, что могу использовать функцию-член для этого, (т.е. C->mult(A,B)) но я бы хотел этого избежать, если это вообще возможно (я пишу это для простоты разработки для не-CSE типов). Любые идеи очень приветствуются.

1

Решение

class Matrix
{

struct Product
{
const Matrix* a;
const Matrix* b;
};

Matrix& operator = (const Product& p)
{
// if this matrix dims differ from required by product of p.a and p.b
// reallocate it first and set dims
// {
// rows = ....; cols = ....;
// delete [] data;
// data = new [rows*cols];
// }// then calculate product
// data[0] = ...;
// ...

return *this;

}

Product operator * (const Matrix& op) const
{
Product p;
p.a = this;
p.b = &op;
return p;
}

int rows,cols;
double* data;

/// your Matrix stuff
// ...
};

void test()
{
Matrix a(4,2),b(2,4),c;

c = a * b; // (note a*b returns Product without calculating its result
// result is calculated inside = operator

c = a * b; // note that this time c is initialized to correct size so no
// additional reallocations will occur

}
2

Другие решения


По вопросам рекламы [email protected]