forked from lijiext/lammps
235 lines
7.5 KiB
C++
235 lines
7.5 KiB
C++
#ifndef VECTOR_H
|
|
#define VECTOR_H
|
|
|
|
#include "Matrix.h"
|
|
|
|
namespace ATC_matrix {
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// forward declarations ///////////////////////////////////////////////////////
|
|
|
|
//* Matrix-vector product
|
|
//template<typename T>
|
|
//void MultMv(const Matrix<T> &A, const Vector<T> &v, DenseVector<T> &c,
|
|
// const bool At=0, T a=1, T b=0);
|
|
|
|
/******************************************************************************
|
|
* abstract class Vector
|
|
******************************************************************************/
|
|
|
|
|
|
template<typename T>
|
|
class Vector : public Matrix<T>
|
|
{
|
|
public:
|
|
Vector() {}
|
|
Vector(const Vector<T> &c); // do not implement!
|
|
virtual ~Vector() {}
|
|
|
|
std::string to_string() const;
|
|
|
|
// pure virtual functions
|
|
virtual T operator()(INDEX i, INDEX j=0) const=0;
|
|
virtual T& operator()(INDEX i, INDEX j=0) =0;
|
|
virtual T operator[](INDEX i) const=0;
|
|
virtual T& operator[](INDEX i) =0;
|
|
virtual INDEX nRows() const=0;
|
|
virtual T* ptr() const=0;
|
|
virtual void resize(INDEX nRows, INDEX nCols=1, bool copy=0)=0;
|
|
virtual void reset(INDEX nRows, INDEX nCols=1, bool zero=0)=0;
|
|
virtual void copy(const T * ptr, INDEX nRows, INDEX nCols=1)=0;
|
|
void write_restart(FILE *f) const; // will be virtual
|
|
|
|
|
|
// output to matlab
|
|
using Matrix<T>::matlab;
|
|
void matlab(std::ostream &o, const std::string &s="v") const;
|
|
|
|
using Matrix<T>::operator=;
|
|
INDEX nCols() const;
|
|
bool in_range(INDEX i) const;
|
|
bool same_size(const Vector &m) const;
|
|
static bool same_size(const Vector &a, const Vector &b);
|
|
|
|
protected:
|
|
void _set_equal(const Matrix<T> &r);
|
|
//* don't allow this
|
|
Vector& operator=(const Vector &r);
|
|
};
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
//* performs a matrix-vector multiply with default naive implementation
|
|
template<typename T>
|
|
void MultMv(const Matrix<T> &A, const Vector<T> &v, DenseVector<T> &c,
|
|
const bool At, T /* a */, T b)
|
|
{
|
|
const INDEX sA[2] = {A.nRows(), A.nCols()}; // m is sA[At] k is sA[!At]
|
|
const INDEX M=sA[At], K=sA[!At];
|
|
GCK(A, v, v.size()!=K, "MultAb<T>: matrix-vector multiply");
|
|
if (c.size() != M)
|
|
{
|
|
c.resize(M); // set size of C
|
|
c.zero(); // do not add result to C
|
|
}
|
|
else c *= b;
|
|
for (INDEX p=0; p<M; p++)
|
|
for (INDEX r=0; r<K; r++)
|
|
c[p] += A(p*!At+r*At, p*At+r*!At) * v[r];
|
|
}
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
//* Operator for Matrix-vector product
|
|
template<typename T>
|
|
DenseVector<T> operator*(const Matrix<T> &A, const Vector<T> &b)
|
|
{
|
|
DenseVector<T> c;
|
|
MultMv(A, b, c, 0, 1.0, 0.0);
|
|
return c;
|
|
}
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
//* Operator for Vector-matrix product
|
|
template<typename T>
|
|
DenseVector<T> operator*(const Vector<T> &a, const Matrix<T> &B)
|
|
{
|
|
DenseVector<T> c;
|
|
MultMv(B, a, c, 1, 1.0, 0.0);
|
|
return c;
|
|
}
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
//* Multiply a vector by a scalar
|
|
template<typename T>
|
|
DenseVector<T> operator*(const Vector<T> &v, const T s)
|
|
{
|
|
DenseVector<T> r(v);
|
|
r*=s;
|
|
return r;
|
|
}
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
//* Multiply a vector by a scalar - communitive
|
|
template<typename T>
|
|
DenseVector<T> operator*(const T s, const Vector<T> &v)
|
|
{
|
|
DenseVector<T> r(v);
|
|
r*=s;
|
|
return r;
|
|
}
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
//* inverse scaling operator - must always create memory
|
|
template<typename T>
|
|
DenseVector<T> operator/(const Vector<T> &v, const T s)
|
|
{
|
|
DenseVector<T> r(v);
|
|
r*=(1.0/s); // for integer types this may be worthless
|
|
return r;
|
|
}
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
//* Operator for Vector-Vector sum
|
|
template<typename T>
|
|
DenseVector<T> operator+(const Vector<T> &a, const Vector<T> &b)
|
|
{
|
|
DenseVector<T> c(a);
|
|
c+=b;
|
|
return c;
|
|
}
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
//* Operator for Vector-Vector subtraction
|
|
template<typename T>
|
|
DenseVector<T> operator-(const Vector<T> &a, const Vector<T> &b)
|
|
{
|
|
DenseVector<T> c(a);
|
|
c-=b;
|
|
return c;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// Template definitions ///////////////////////////////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
//* output operator
|
|
template<typename T>
|
|
std::string Vector<T>::to_string() const
|
|
{
|
|
std::string s;
|
|
int sz = this->size();
|
|
for (INDEX i = 0; i < sz; i++)
|
|
s += std::string(i?"\t":"") + ATC_Utility::to_string((*this)[i],myPrecision);
|
|
return s;
|
|
}
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
//* Writes a matlab script defining the vector to the stream
|
|
template<typename T>
|
|
void Vector<T>::matlab(std::ostream &o, const std::string &s) const
|
|
{
|
|
o << s <<"=zeros(" << this->size() << ",1);\n";
|
|
int sz = this->size();
|
|
for (INDEX i = 0; i < sz; i++)
|
|
o << s << "("<<i+1<<") = " << (*this)[i] << ";\n";
|
|
}
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
//* writes the vector data to a file
|
|
template <typename T>
|
|
void Vector<T>::write_restart(FILE *f) const
|
|
{
|
|
INDEX size = this->size();
|
|
fwrite(&size, sizeof(INDEX),1,f);
|
|
if (size) fwrite(this->ptr(), sizeof(T), this->size(), f);
|
|
}
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
//* returns the number of columns; always 1
|
|
template<typename T>
|
|
inline INDEX Vector<T>::nCols() const
|
|
{
|
|
return 1;
|
|
}
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
//* returns true if INDEX i is within the range of the vector
|
|
template<typename T>
|
|
bool Vector<T>::in_range(INDEX i) const
|
|
{
|
|
return i<this->size();
|
|
}
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
//* returns true if m has the same number of elements this vector
|
|
template<typename T>
|
|
bool Vector<T>::same_size(const Vector &m) const
|
|
{
|
|
return this->size() == m.size();
|
|
}
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
//* returns true if a and b have the same number of elements
|
|
template<typename T>
|
|
inline bool Vector<T>::same_size(const Vector &a, const Vector &b)
|
|
{
|
|
return a.same_size(b);
|
|
}
|
|
//----------------------------------------------------------------------------
|
|
// general matrix assignment (for densely packed matrices)
|
|
//----------------------------------------------------------------------------
|
|
template<typename T>
|
|
void Vector<T>::_set_equal(const Matrix<T> &r)
|
|
{
|
|
this->resize(r.nRows(), r.nCols());
|
|
const Matrix<T> *pr = &r;
|
|
#ifdef OBSOLETE
|
|
if (const SparseMatrix<T> *ps = dynamic_cast<const SparseMatrix<T>*>(pr))//sparse_cast(pr))
|
|
copy_sparse_to_matrix(ps, *this);
|
|
|
|
else if (dynamic_cast<const DiagonalMatrix<T>*>(pr))//diag_cast(pr)) // r is Diagonal?
|
|
{
|
|
this->zero();
|
|
for (INDEX i=0; i<r.size(); i++) (*this)(i,i) = r[i];
|
|
}
|
|
else memcpy(this->ptr(), r.ptr(), r.size()*sizeof(T));
|
|
#else
|
|
const Vector<T> *pv = dynamic_cast<const Vector<T>*> (pr);
|
|
if (pv) this->copy(pv->ptr(),pv->nRows());
|
|
else
|
|
{
|
|
std::cout <<"Error in general vector assignment\n";
|
|
exit(1);
|
|
}
|
|
#endif
|
|
}
|
|
} // end namespace
|
|
|
|
|
|
#endif
|