-
Mark Jenkinson authoredMark Jenkinson authored
sparse_matrix.cc 5.28 KiB
#include <iostream>
#include <iomanip>
#include <strstream>
#include <cmath>
#define WANT_STREAM
#define WANT_MATH
#include "sparse_matrix.h"
#include "newmatio.h"
#include "newmat.h"
#include "miscmaths.h"
#include "utils/tracer_plus.h"
using namespace std;
using namespace Utilities;
using namespace NEWMAT;
using namespace MISCMATHS;
namespace MISCMATHS {
SparseMatrix::SparseMatrix(int pnrows, int pncols) :
nrows(pnrows),
ncols(pncols),
data(pnrows)
{
}
void SparseMatrix::ReSize(int pnrows, int pncols)
{
nrows = pnrows;
ncols = pncols;
data.clear();
data.resize(nrows);
}
const SparseMatrix& SparseMatrix::operator=(const Matrix& pmatin)
{
data.clear();
data.resize(pmatin.Nrows());
nrows = pmatin.Nrows();
ncols = pmatin.Ncols();
for(int r=1; r <= pmatin.Nrows(); r++)
{
for(int c=1; c <= pmatin.Ncols(); c++)
{
if(pmatin(r,c)!=0)
insert(r,c,pmatin(r,c));
}
}
return *this;
}
void SparseMatrix::transpose(SparseMatrix& ret)
{
Tracer_Plus tr("SparseMatrix::transpose");
ret.ReSize(ncols,nrows);
for(int r=1; r <= nrows; r++)
for(map<int,double>::const_iterator it=data[r-1].begin(); it!=data[r-1].end(); it++)
ret.insert((*it).first+1, r, (*it).second);
}
int SparseMatrix::maxnonzerosinrow() const
{
int mx = 0;
for(int r=1; r <= nrows; r++)
{
int si = data[r-1].size();
if(si > mx)
mx = si;
}
return mx;
}
void SparseMatrix::permute(const ColumnVector& p, SparseMatrix& pA)
{
Tracer_Plus tr("SparseMatrix::permute");
pA.ReSize(nrows,ncols);
ColumnVector ip(p.Nrows());
for(int r=1; r <= nrows; r++)
ip(int(p(r))) = r;
for(int r=1; r <= nrows; r++)
for(map<int,double>::const_iterator it=data[r-1].begin(); it!=data[r-1].end(); it++)
{
pA.insert(int(ip(r)), int(ip((*it).first+1)), (*it).second);
}
}
ReturnMatrix SparseMatrix::AsMatrix() const
{
Matrix ret(nrows,ncols);
ret = 0;
for(int r=1; r <= nrows; r++)
for(map<int,double>::const_iterator it=data[r-1].begin(); it!=data[r-1].end(); it++)
ret(r,(*it).first+1) = (*it).second;
ret.Release();
return ret;
}
float SparseMatrix::trace() const
{
float tr = 0.0;
for(int k = 1; k<=Nrows(); k++)
{
tr += (*this)(k,k);
}
return tr;
}
ReturnMatrix SparseMatrix::RowAsColumn(int r) const
{
Tracer_Plus tr("SparseMatrix::RowAsColumn");
ColumnVector ret;
ret.ReSize(ncols);
ret = 0;
const SparseMatrix::Row& rowtmp = row(r);
for(SparseMatrix::Row::const_iterator it=rowtmp.begin();it!=rowtmp.end();it++)
{
int c = (*it).first+1;
double val = (*it).second;
ret(c) = val;
}
ret.Release();
return ret;
}
void colvectosparserow(const ColumnVector& col, SparseMatrix::Row& row)
{
Tracer_Plus tr("SparseMatrix::colvectosparserow");
for(int j = 1; j<=col.Nrows(); j++)
{
if(std::abs(col(j))>1e-4)
row[j-1] = col(j);
}
}
void SparseMatrix::multiplyby(float S)
{
Tracer_Plus tr("SparseMatrix::multiplyby");
for(int j = 1; j<=Nrows(); j++)
{
SparseMatrix::Row& row = (*this).row(j);
for(SparseMatrix::Row::iterator it=row.begin();it!=row.end();it++)
{
(*it).second *= S;
}
}
}
void multiply(const SparseMatrix& lm, const SparseMatrix& rm, SparseMatrix& ret)
{
Tracer_Plus tr("SparseMatrix::multiply");
int nrows = lm.Nrows();
int ncols = rm.Ncols();
if(lm.Ncols() != rm.Nrows()) throw Exception("Rows and cols don't match in SparseMatrix::multiply");
ret.ReSize(nrows,ncols);
for(int j = 1; j<=nrows; j++)
{
const SparseMatrix::Row& row = lm.row(j);
for(SparseMatrix::Row::const_iterator it=row.begin();it!=row.end();it++)
{
int c = (*it).first+1;
double val = (*it).second;
for(int k = 1; k<=ncols; k++)
{
ret.addto(j,k,val*rm(c,k));
}
}
}
}
void multiply(const SparseMatrix& lm, const ColumnVector& rm, ColumnVector& ret)
{
Tracer_Plus tr("SparseMatrix::multiply2");
int nrows = lm.Nrows();
if(lm.Ncols() != rm.Nrows()) throw Exception("Rows and cols don't match in SparseMatrix::multiply");
ret.ReSize(nrows);
for(int j = 1; j<=nrows; j++)
{
float sum = 0.0;
const SparseMatrix::Row& row = lm.row(j);
for(SparseMatrix::Row::const_iterator it=row.begin();it!=row.end();it++)
{
int c = (*it).first+1;
double val = (*it).second;
sum += val*rm(c);
}
ret(j) = sum;
}
}
void multiply(const SparseMatrix& lm, const SparseMatrix::Row& rm, ColumnVector& ret)
{
Tracer_Plus tr("SparseMatrix::multiply3");
int nrows = lm.Nrows();
ret.ReSize(nrows);
for(int j = 1; j<=nrows; j++)
{
float sum = 0.0;
const SparseMatrix::Row& row = lm.row(j);
SparseMatrix::Row::const_iterator it=row.begin();
SparseMatrix::Row::const_iterator itrm=rm.begin();
while(it!=row.end() && itrm!=rm.end())
{
int crm = (*itrm).first;
int c = (*it).first;
if(c==crm)
{
sum += ((*itrm).second)*((*it).second);
it++;
itrm++;
}
else if(c < crm)
{
it++;
}
else
{
itrm++;
}
}
ret(j) = sum;
}
}
}