Files
pymol-open-source/include/tnt/tnt_sparse_vector.h
2020-12-03 18:10:46 +01:00

249 lines
4.8 KiB
C++

#ifndef TNT_SPARSE_VECTOR_H
#define TNT_SPARSE_VECTOR_H
/*
*
* Template Numerical Toolkit (TNT)
*
* Mathematical and Computational Sciences Division
* National Institute of Technology,
* Gaithersburg, MD USA
*
*
* This software was developed at the National Institute of Standards and
* Technology (NIST) by employees of the Federal Government in the course
* of their official duties. Pursuant to title 17 Section 105 of the
* United States Code, this software is not subject to copyright protection
* and is in the public domain. NIST assumes no responsibility whatsoever for
* its use by other parties, and makes no guarantees, expressed or implied,
* about its quality, reliability, or any other characteristic.
*
*/
#include <vector>
#include "tnt_vector.h"
namespace TNT
{
//namespace Linear_Algebra
//{
template <class T, class Integer>
class Sparse_Vector_Element
{
private:
T val_;
Integer index_;
public:
Sparse_Vector_Element(const T& a, const Integer &i) :
val_(a), index_(i) {}
const T& value() const { return val_; }
Integer index() const { return index_; }
T& value() { return val_; }
Integer& index() { return index_; }
};
/**
Sparse Vector.
<p>
Index values begin at 0. Thus S[3] = 6.5 means that the fourth, not
the third element, is set to 6.5.
<p>
S.value(0) is the first nonzero values in S, and S.index(0) is
the index (0-based) of the first in S.
*/
template <class T>
class Sparse_Vector
{
/* sparse vector indices are 0-based internally. */
private:
// (value, index) pairs
//
std::vector< Sparse_Vector_Element<T, Subscript> > s_;
int dim_; // dimension
int num_nonzeros_; // number of nonzeros
public:
typedef typename
std::vector< Sparse_Vector_Element<T, Subscript> >::const_iterator
const_iterator;
const_iterator begin() const { return s_.begin(); }
const_iterator end() const { return s_.end(); }
inline const T& value(Subscript i) const { return s_[i].value(); }
inline Subscript index(Subscript i) const {return s_[i].index(); }
inline T dot_product(const Vector<T>& x) const
{
T sum(0);
for ( const_iterator p = begin(); p < end(); p++)
{
sum += p->value() * x[p->index()];
}
return sum;
}
Sparse_Vector() : s_(), dim_(0), num_nonzeros_(0) {}
Sparse_Vector(Subscript N): dim_(N), num_nonzeros_(0) {}
Sparse_Vector(Subscript N, Subscript nz, const T* Val, const Subscript *I):
dim_(N),
num_nonzeros_(0)
{
insert(nz, Val, I);
}
void insert(const T& val, Subscript i)
{
s_.push_back( Sparse_Vector_Element<T, Subscript>(val,i) );
num_nonzeros_++;
}
void insert(Subscript nz, const T* Val, const Subscript *I)
{
for (int count=0; count<nz; count++)
{
insert(Val[count], I[count]);
}
}
void insert_base_one(const T& val, Subscript i)
{
insert(val, i-1);
}
void insert_base_one(Subscript nz, const T* Val, const Subscript *I)
{
for (int count=0; count<nz; count++)
{
insert(Val[count], I[count]-1);
}
}
inline int dim() const {return dim_;}
int num_nonzeros() const {return num_nonzeros_;}
inline double norm() const
{
T sum(0.0);
for (const_iterator p = begin(); p < end(); p++)
{
sum += p->value() * p->value();
}
return sqrt(sum);
}
std::ostream & print(std::ostream &s) const
{
for (typename Sparse_Vector<T>::const_iterator p = begin();
p < end(); p++)
{
s << "( " << p->value() << ", " << p->index() << " ) \n";
}
return s;
}
std::ostream & print_base_one(std::ostream &s) const
{
for (typename Sparse_Vector<T>::const_iterator p = begin();
p < end(); p++)
{
s << "( " << p->value() << ", " << p->index()+1 << " ) \n";
}
return s;
}
};
template <class T>
inline T dot_product(const Sparse_Vector<T> &s, const Vector<T> &x)
{
return s.dot_product(x);
}
template <class T>
inline T dot_product(const Vector<T> &x, const Sparse_Vector<T> &s)
{
return s.dot_product(x);
}
template <class T>
inline T operator*(const Vector<T> &x, const Sparse_Vector<T> &s)
{
return dot_product(x,s);
}
template <class T>
inline T operator*(const Sparse_Vector<T> &s, const Vector<T> &x)
{
return dot_product(x,s);
}
template <class T>
inline double norm( const Sparse_Vector<T> & s)
{
return s.norm();
}
template <class T>
std::ostream& operator<<(std::ostream &s, const Sparse_Vector<T> &A)
{
return A.print(s);
}
//} /* namspace TNT::Linear_Algebra */
} /* namspace TNT */
#endif
// TNT_SPARSE_VECTOR_H