#include "matrix.h"
template <class Type>
matrix<Type>::matrix()
{
m= 1;
n= 1;
data= new Type[1];
data[0]= 0;
}
template <class Type>
matrix<Type>::matrix(int zsz, int ssz)
{
m= zsz;
n= ssz;
data= new Type[m*n];
for(int i= 0; i < m; i++)
{
for(int j= 0; j < n; j++)
{
data[i*n+j]= 0;
}
}
}
template <class Type>
matrix<Type>::matrix(matrix<Type>& a)
{
m= a.zdim();
n= a.sdim();
data= new Type[m*n];
for(int i= 0; i < m; i++)
{
for(int j= 0; j < n; j++)
{
data[i*n+j]= a[i][j];
}
}
}
template <class Type>
matrix<Type>::matrix(int zsz, int ssz, Type *a)
{
m= zsz;
n= ssz;
data= new Type[m*n];
for(int i= 0; i < m; i++)
{
for(int j= 0; j < n; j++)
{
data[i*n+j]= a[i*n+j];
}
}
}
template <class Type>
matrix<Type>::~matrix()
{
delete[] data;
}
template <class Type>
void matrix<Type>::resize(int zsz, int ssz)
{
m= zsz;
n= ssz;
delete[] data;
data= new Type[m*n];
for(int i= 0; i < m; i++)
{
for(int j= 0; j < n; j++)
{
data[i*n+j]= 0;
}
}
}
template <class Type>
int matrix<Type>::zdim()
{
return m;
}
template <class Type>
int matrix<Type>::sdim()
{
return n;
}
template <class Type>
void matrix<Type>::set(int i, int j, Type dat)
{
assert(i < m);
assert(j < n);
data[i*n+j]= dat;
}
template <class Type>
void matrix<Type>::swap_lines(int i, int k)
{
assert(i < m);
assert(k < m);
Type buf= 0;
for(int j= 0; j < n; j++)
{
buf= data[i*n+j];
data[i*n+j]= data[k*n+j];
data[k*n+j]= buf;
}
}
template <class Type>
void matrix<Type>::swap_cols(int j, int k)
{
assert(j < n);
assert(k < n);
Type buf= 0;
for(int i= 0; i < m; i++)
{
buf= data[i*n+j];
data[i*n+j]= data[i*n+k];
data[i*n+k]= buf;
}
}
template <class Type>
int matrix<Type>::invert(matrix<Type>& b)
{
Type fac;
assert(m == n);
matrix<Type> a(*this);
for(int i= 0; i < m; i++)
{
for(int j= 0; j < n; j++)
{
if (i == j)
{
b.set(i,j,1);
}
else
{
b.set(i,j,0);
}
}
}
for(int i= 0; i < m; i++)
{
if (fabs(a[i][i]) < epsilon)
{
int l= i;
while((l < m) && (fabs(a[l][i]) < epsilon))
{
l++;
}
if (l == m)
{
return 0;
}
else
{
a.swap_lines(i,l);
b.swap_lines(i,l);
}
}
for(int k= i; k < m; k++)
{
if (fabs(a[k][i]) > epsilon)
{
fac= 1/a[k][i];
for(int j= 0; j < n; j++)
{
a.set(k,j,a[k][j]*fac);
b.set(k,j,b[k][j]*fac);
}
}
}
for(int k= i+1; k < m; k++)
{
if (fabs(a[k][i]) > epsilon)
{
for(int j= 0; j < n; j++)
{
a.set(k,j,a[k][j]-a[i][j]);
b.set(k,j,b[k][j]-b[i][j]);
}
}
}
}
for(int i= m-1; i > 0; i--)
{
for(int k= 0; k < i; k++)
{
if (fabs(a[k][i]) > epsilon)
{
fac= a[k][i];
for(int j= 0; j < n; j++)
{
a.set(k,j,a[k][j]-a[i][j]*fac);
b.set(k,j,b[k][j]-b[i][j]*fac);
}
}
}
}
return 1;
}
template <class Type>
const matrix<Type>& matrix<Type>::operator=(const matrix<Type>& a)
{
if ((m != a.m) || (n != a.n))
{
m= a.m;
n= a.n;
delete[] data;
data= new Type[m*n];
}
for(int i= 0; i < m; i++)
{
for(int j= 0; j < n; j++)
{
data[i*n+j]= a.data[i*n+j];
}
}
return *this;
}
template <class Type>
const matrix<Type>& matrix<Type>::operator+=(const matrix<Type>& a)
{
for(int i= 0; i < m; i++)
{
for(int j= 0; j < n; j++)
{
data[i*n+j]+= a.data[i*n+j];
}
}
return *this;
}
template <class Type>
const matrix<Type>& matrix<Type>::operator-=(const matrix<Type>& a)
{
for(int i= 0; i < m; i++)
{
for(int j= 0; j < n; j++)
{
data[i*n+j]-= a.data[i*n+j];
}
}
return *this;
}
template <class Type>
tnvector<Type> matrix<Type>::operator[](int i)
{
if (i < m)
{
tnvector<Type> vec(n,&data[i*n]);
return vec;
}
else
{
tnvector<Type> vec(n);
return vec;
}
}
template <class Type>
int matrix<Type>::operator==(const matrix<Type>& b)
{
if ((m != b.m) || (n != b.n))
{
return 0;
}
for(int i= 0; i < m; i++)
{
for(int j= 0; j < n; j++)
{
if (data[i*n+j] != b.data[i*n+j])
{
return 0;
}
}
}
return 1;
}
template <class Type>
int matrix<Type>::operator!=(const matrix<Type>& b)
{
return (!(*this == b));
}
template <class Type>
matrix<Type> operator+(const matrix<Type>& a, const matrix<Type>& b)
{
assert((a.m == b.m) && (a.n == b.n));
matrix<Type> c(a);
c+= b;
return c;
}
template <class Type>
matrix<Type> operator-(const matrix<Type>& a, const matrix<Type>& b)
{
assert((a.m == b.m) && (a.n == b.n));
matrix<Type> c(a);
c-= b;
return c;
}
template <class Type>
matrix<Type> operator*(const matrix<Type>& a, const matrix<Type>& b)
{
assert(a.n == b.m);
matrix<Type> c(a.m, b.n);
Type buf;
for (int i= 0; i < a.m; i++)
{
for (int j= 0; j < b.n; j++)
{
buf= 0;
for (int k= 0; k < a.n; k++)
{
buf+= a.data[i*a.n+k]*b.data[k*b.n+j];
}
c.data[i*c.n+j]= buf;
}
}
return c;
}
template <class Type>
tnvector<Type> operator*(const matrix<Type>& a, const tnvector<Type>& b)
{
assert(a.n == b.n);
tnvector<Type> c(a.m);
Type buf;
for(int i= 0; i < a.m; i++)
{
buf= 0;
for(int j= 0; j < a.n; j++)
{
buf+= a.data[i*a.n+j]*b.data[j];
}
c.data[i]= buf;
}
return c;
}
template <class Type>
matrix<Type> operator*(Type a, const matrix<Type>& b)
{
matrix<Type> c(b);
for (int i= 0; i < b.m; i++)
{
for (int j= 0; j < b.n; j++)
{
c.data[i*c.n+j]*= a;
}
}
return c;
}
template <class Type>
istream& operator>>(istream& is, matrix<Type>& a)
{
Type dat;
for(int i= 0; i < a.zdim(); i++)
{
for(int j= 0; j < a.sdim(); j++)
{
is >> dat;
a.set(i, j, dat);
}
}
return is;
}
template <class Type>
ostream& operator<<(ostream& os, matrix<Type> a)
{
for(int i= 0; i < a.zdim(); i++)
{
for(int j= 0; j < a.sdim(); j++)
{
os << a[i][j] << " ";
}
os << endl;
}
return os;
}