0

I meet a serious problem when I was coding my programme. Firstly, I will state my implementation. I have a Conjugate Gradient Implementation to solve linear system. In my densematrixvector.h, I have two classes, denseMatrix and denseVector, and I put these two arrays into the function template < class M, class V > int ConjugateGradient(const M &A, const V &b, V &x, const int &maxstep, const int &eps), here, M is denseMatrix, V is denseVector.

In function ConjugateGradient, I am using a function void gemv(const double &alpha, const DenseMatrix &A, const DenseVector &x, const double &beta, DenseVector &y) to solve the linear system.

But this code did not take advantage of the sparsity of the matrix. So I want to modify the code so that it does. In particular, the matrix type passed to the ConjugateGradient function represent dense matrix. I want to modify the code to pass it sparse matrix in ccs format. this class transfers information of sparse matrix. So I modify the declaration of function gemv like this:

template <class M, class V >void gemv(const double &alpha, const M &A, const V &x, const double &beta, V &y)

And the declaration of matCCS is template < class T >class matCCS.

finally, my computer tells me that undefined reference to.

and the code I attach below.

Please help me. Thank you in advance.

mainconjugategradientmethodmatCCS.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.cc

#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]];

  }

}

densematrixvector.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

ConjugateGradient.h

#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);

...

The report error is attached below

report error

[master@localhost part3ddis]$ g++ maintestconjugategradientmatCCS.cc densematrixvector.cc mmio.cc libsuperlu_4.3.a libblas.a -lgfortran
/tmp/ccg7iPUj.o: In function `int ConjugateGradient<DenseMatrix, DenseVector>(DenseMatrix const&, DenseVector const&, DenseVector&, int const&, int const&)':
maintestconjugategradientmatCCS.cc:(.text._Z17ConjugateGradientI11DenseMatrix11DenseVectorEiRKT_RKT0_RS5_RKiSA_[_Z17ConjugateGradientI11DenseMatrix11DenseVectorEiRKT_RKT0_RS5_RKiSA_]+0xb2): undefined reference to `void gemv<DenseMatrix, DenseVector>(double const&, DenseMatrix const&, DenseVector const&, double const&, DenseVector&)'
maintestconjugategradientmatCCS.cc:(.text._Z17ConjugateGradientI11DenseMatrix11DenseVectorEiRKT_RKT0_RS5_RKiSA_[_Z17ConjugateGradientI11DenseMatrix11DenseVectorEiRKT_RKT0_RS5_RKiSA_]+0x208): undefined reference to `void gemv<DenseMatrix, DenseVector>(double const&, DenseMatrix const&, DenseVector const&, double const&, DenseVector&)'
collect2: error: ld returned 1 exit status
Yannlove
  • 35
  • 3

0 Answers0