#include "smat.h" #include #include #include #include #include extern "C" { extern ssize_t read(int, void *, size_t); extern ssize_t write(int, const void *, size_t); } // TODO // specialize unary minus ////////////////////////////////////////////////////////////////////////////// ////// forced instantization in the corresponding object file template class NRSMat; template class NRSMat< complex >; template class NRSMat; template class NRSMat; template class NRSMat; template class NRSMat; template class NRSMat; /* * * Templates first, specializations for BLAS next * */ //raw I/O template void NRSMat::put(int fd, bool dim, bool transp) const { errno=0; if(dim) { if(sizeof(int) != write(fd,&nn,sizeof(int))) laerror("cannot write"); if(sizeof(int) != write(fd,&nn,sizeof(int))) laerror("cannot write"); } LA_traits::multiput(NN2,fd,v,dim); } template void NRSMat::get(int fd, bool dim, bool transp) { int nn0[2]; //align at least 8-byte errno=0; if(dim) { if(2*sizeof(int) != read(fd,&nn0,2*sizeof(int))) laerror("cannot read"); resize(nn0[0]); } else copyonwrite(); LA_traits::multiget(NN2,fd,v,dim); } // conversion ctor, symmetrize general Mat into SMat template NRSMat::NRSMat(const NRMat &rhs) { nn=rhs.nrows(); #ifdef DEBUG if (nn != rhs.ncols()) laerror("attempt to convert non-square Mat to SMat"); #endif count = new int; *count = 1; v = new T[NN2]; int i, j, k=0; for (i=0; i NRSMat & NRSMat::operator=(const T &a) { copyonwrite(); memset(v,0,NN2*sizeof(T)); for (int i=0; i const T* NRSMat::diagonalof(NRVec &r, const bool divide, bool cache) const { #ifdef DEBUG if(r.size()!=nn) laerror("incompatible vector in diagonalof()"); #endif r.copyonwrite(); if (divide) for (int i=0; i const NRSMat NRSMat::operator-() const { NRSMat result(nn); for(int i=0; i const T NRSMat::trace() const { T tmp = 0; for (int i=0; i void NRSMat::fprintf(FILE *file, const char *format, const int modulo) const { lawritemat(file, (const T *)(*this) ,nn, nn, format, 2, modulo, 1); } // read matrix from the file with specific format template void NRSMat::fscanf(FILE *f, const char *format) { int n, m; if (std::fscanf(f,"%d %d",&n,&m) != 2) laerror("cannot read matrix dimensions in SMat::fscanf"); if (n != m) laerror("different dimensions of SMat"); resize(n); for (int i=0; i */ // SMat * Mat //NOTE: dsymm is not appropriate as it works on UNPACKED symmetric matrix template<> const NRMat NRSMat::operator*(const NRMat &rhs) const { #ifdef DEBUG if (nn != rhs.nrows()) laerror("incompatible dimensions in SMat*Mat"); #endif NRMat result(nn, rhs.ncols()); for (int k=0; k const NRMat< complex > NRSMat< complex >::operator*(const NRMat< complex > &rhs) const { #ifdef DEBUG if (nn != rhs.nrows()) laerror("incompatible dimensions in SMat*Mat"); #endif NRMat< complex > result(nn, rhs.ncols()); for (int k=0; k const NRMat NRSMat::operator*(const NRSMat &rhs) const { #ifdef DEBUG if (nn != rhs.nn) laerror("incompatible dimensions in SMat*SMat"); #endif NRMat result(0.0, nn, nn); double *p, *q; p = v; for (int i=0; i const NRMat< complex > NRSMat< complex >::operator*(const NRSMat< complex > &rhs) const { #ifdef DEBUG if (nn != rhs.nn) laerror("incompatible dimensions in SMat*SMat"); #endif NRMat< complex > result(0.0, nn, nn); NRMat< complex > rhsmat(rhs); result = *this * rhsmat; return result; // laerror("complex SMat*Smat not implemented"); } // S dot S template<> const double NRSMat::dot(const NRSMat &rhs) const { #ifdef DEBUG if (nn != rhs.nn) laerror("dot of incompatible SMat's"); #endif return cblas_ddot(NN2, v, 1, rhs.v, 1); } template<> const complex NRSMat< complex >::dot(const NRSMat< complex > &rhs) const { #ifdef DEBUG if (nn != rhs.nn) laerror("dot of incompatible SMat's"); #endif complex dot; cblas_zdotc_sub(NN2, (void *)v, 1, (void *)rhs.v, 1, (void *)(&dot)); return dot; } template<> const double NRSMat::dot(const NRVec &rhs) const { #ifdef DEBUG if (NN2 != rhs.nn) laerror("dot of incompatible SMat's"); #endif return cblas_ddot(NN2, v, 1, rhs.v, 1); } template<> const complex NRSMat< complex >::dot(const NRVec< complex > &rhs) const { #ifdef DEBUG if (NN2 != rhs.nn) laerror("dot of incompatible SMat's"); #endif complex dot; cblas_zdotc_sub(NN2, (void *)v, 1, (void *)rhs.v, 1, (void *)(&dot)); return dot; } // norm of the matrix template<> const double NRSMat::norm(const double scalar) const { if (!scalar) return cblas_dnrm2(NN2, v, 1); double sum = 0; int k = 0; for (int i=0; i const double NRSMat< complex >::norm(const complex scalar) const { if (!(scalar.real()) && !(scalar.imag())) return cblas_dznrm2(NN2, (void *)v, 1); double sum = 0; complex tmp; int k = 0; for (int i=0; i void NRSMat::axpy(const double alpha, const NRSMat & x) { #ifdef DEBUG if (nn != x.nn) laerror("axpy of incompatible SMats"); #endif copyonwrite(); cblas_daxpy(NN2, alpha, x.v, 1, v, 1); } template<> void NRSMat< complex >::axpy(const complex alpha, const NRSMat< complex > & x) { #ifdef DEBUG if (nn != x.nn) laerror("axpy of incompatible SMats"); #endif copyonwrite(); cblas_zaxpy(nn, (void *)(&alpha), (void *)x.v, 1, (void *)v, 1); } export template ostream& operator<<(ostream &s, const NRSMat &x) { int i,j,n; n=x.nrows(); s << n << ' ' << n << '\n'; for(i=0;i::IOtype)x(i,j) << (j==n-1 ? '\n' : ' '); } return s; } export template istream& operator>>(istream &s, NRSMat &x) { int i,j,n,m; s >> n >> m; if(n!=m) laerror("input symmetric matrix not square"); x.resize(n); typename LA_traits_io::IOtype tmp; for(i=0;i>tmp; x(i,j)=tmp;} return s; } ////////////////////////////////////////////////////////////////////////////// //// forced instantization in the corespoding object file #define INSTANTIZE(T) \ template ostream & operator<<(ostream &s, const NRSMat< T > &x); \ template istream & operator>>(istream &s, NRSMat< T > &x); \ INSTANTIZE(double) INSTANTIZE(complex) INSTANTIZE(int) INSTANTIZE(short) INSTANTIZE(char) INSTANTIZE(unsigned int) INSTANTIZE(unsigned long)