/* LA: linear algebra C++ interface library Copyright (C) 2008 Jiri Pittner or complex versions written by Roman Curik This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #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 namespace LA { /* * * 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::randomize(const double &x) { for(int i=0; i void NRSMat >::randomize(const double &x) { 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, v, 1, rhs.v, 1, &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, v, 1, rhs.v, 1, &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, 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, &alpha, x.v, 1, v, 1); } //complex from real template<> NRSMat >::NRSMat(const NRSMat &rhs, bool imagpart) : nn(rhs.nrows()), v(new complex[rhs.nrows()*(rhs.nrows()+1)/2]), count(new int(1)) { memset(v,0,nn*(nn+1)/2*sizeof(complex)); cblas_dcopy(nn*(nn+1)/2,&rhs(0,0),1,((double *)v) + (imagpart?1:0),2); } ////////////////////////////////////////////////////////////////////////////// ////// 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; template class NRSMat; template class NRSMat; template class NRSMat; template class NRSMat; template class NRSMat; }//namespace