我编写程序时遇到严重问题。首先,我将陈述我的实施情况。
我有一个Conjugate Gradient实现来解决线性系统。在我的densematrixvector.h中,我有两个类denseMatrix
和denseVector
,我将这两个数组放入函数template < class M, class V > int ConjugateGradient(const M &A, const V &b, V &x, const int &maxstep, const int &eps)
,这里M
是{{1} },denseMatrix
是V
。
在函数denseVector
中,我使用函数ConjugateGradient
来解决线性系统。
但是这段代码没有利用矩阵的稀疏性。所以我想修改它的代码。特别是,传递给void gemv(const double &alpha, const DenseMatrix &A, const DenseVector &x, const double &beta, DenseVector &y)
函数的矩阵类型表示密集矩阵。我想修改代码以ccs格式传递稀疏矩阵。该类传递稀疏矩阵的信息。所以我像这样修改函数ConjugateGradient
的声明:
gemv
template <class M, class V >void gemv(const double &alpha, const M &A, const V &x, const double &beta, V &y)
的声明是matCCS
。
最后,我的电脑告诉我template < class T >class matCCS
。
以及我在下面附上的代码。
请帮帮我。提前谢谢。
mainconjugategradientmethodmatCCS.cc
undefined reference to
densematrixvector.cc
#include "densematrixvector.h"
#include "ConjugateGradient.h"
#include <iostream>
#include "sparseMatrix.h"
int main(){
matCOO<double> Acoo;
readMatrixMarket("small.mtx", Acoo);
matCCS<double> A; // constuct a CCS matrix
COOtoCCS(Acoo, A); // convert the COO matrix Acoo to CCS A
int m, n;
m=A.m;
n=A.n;
DenseVector x;
DenseVector b;
int nx = 1;
double * xt = new double [m*nx];
for (int i = 0; i < m ;++i) xt[i] =1.;
x.a= xt;
x.n = n;
int nrhs = 1;
double * bt = new double [m*nrhs];
for (int i = 0; i < m ;++i) bt[i] =0.;
b.a = bt;
b.n = n;
int nstep = ConjugateGradient(A, b, x, 100, 0.001);
if (nstep > 0){
std::cout << "converged in nstep " <<nstep << std::endl;
std::cout<< " solution is " << x.a[0] << " " << x.a[1] << std::endl;
}
else {
std::cout << "CG could not converge " <<nstep << std::endl;
}
}
densematrixvector.h
#include "densematrixvector.h"
#include <algorithm>
#include <iostream>
DenseVector::DenseVector():a(0), n(0), owner(false){};
DenseVector::DenseVector(const int & _n):a(new double[_n]), n(_n), owner(true)
{
std::fill(a,a+n, 0.);
};
DenseVector::DenseVector(const DenseVector &in):a(new double[in.n] ), n(in.n), owner(true){
std::copy(in.a, in.a+n, a);
};
DenseVector::~DenseVector(){
if(owner) delete []a;
owner =false;
};
int size(const DenseVector &in){
return in.n;
}
void copy(const DenseVector &x, DenseVector &y){
const int n = size(x);
if (n!=size(y)){ std::cout << " Size error in copy " << __FILE__ <<
__LINE__ << std::endl;}
std::copy(x.a, x.a+n, y.a);
}
double dot(const DenseVector & x, const DenseVector & y){
const int n = size(x);
if (n!=size(y)){ std::cout << " Size error in dot " << __FILE__ << __LINE__ << std::endl;}
return ddot_(n, x.a, 1, y.a, 1);
}
void scal(const double& alpha, DenseVector &x){
dscal_(size(x), alpha, x.a, 1);
}
void axpy( const double &alpha, const DenseVector & x, DenseVector &y){
const int n = size(x);
if (n!=size(y)){ std::cout << " Size error in axpy " << __FILE__ <<
__LINE__ << std::endl; throw;}
daxpy_(n, alpha, x.a, 1, y.a, 1 );
}
template <class M, class V>
void gemv(const double& alpha, const M &A, const V &x, const double &beta, V &y )
int m =A.m;
int n =A.n;
int nnz=A.nnz;
if ((size(x) != n) || (size(y) != m)) { std::cout << " Size error in gemv "` `<< __FILE__ << __LINE__ << std::endl; throw;}
//dgemv_('N', m,n, alpha, A.a, m, x.a, 1, beta, y.a, 1 );
for(int i=0; i<m; i++) {
y.a[i]=A.a[i]*x.a[A.lineindex[i]];
}
}
ConjugateGradient.h
#ifndef _densematrixvector_
#define _densematrixvector_
...
int size(const DenseVector &in);
void copy(const DenseVector &x, DenseVector &y );
double dot(const DenseVector & x, const DenseVector & y);
void scal(const double& alpha, DenseVector &x);
void axpy( const double &alpha, const DenseVector & x, DenseVector &y);
//void gemv(const double& alpha, const DenseMatrix &A, const DenseVector &x,
const double &beta, DenseVector & y );
template <class M, class V>
void gemv(const double& alpha, const M &A, const V &x, const double &beta, V &y );
...
#endif
报告错误见
#include <iostream>
template <class M, class V>
int ConjugateGradient(const M & A, const V& b, V &x, const int & maxstep, const int &eps)
{
int n = size(b);
std::cout << n << std::endl;
//r = b - A x;
V r(b);
gemv(-1., A, x, 1., r);
...