aimsdata  5.0.5
Neuroimaging data handling
sparseordensematrix.h
Go to the documentation of this file.
1 /* This software and supporting documentation are distributed by
2  * Institut Federatif de Recherche 49
3  * CEA/NeuroSpin, Batiment 145,
4  * 91191 Gif-sur-Yvette cedex
5  * France
6  *
7  * This software is governed by the CeCILL-B license under
8  * French law and abiding by the rules of distribution of free software.
9  * You can use, modify and/or redistribute the software under the
10  * terms of the CeCILL-B license as circulated by CEA, CNRS
11  * and INRIA at the following URL "http://www.cecill.info".
12  *
13  * As a counterpart to the access to the source code and rights to copy,
14  * modify and redistribute granted by the license, users are provided only
15  * with a limited warranty and the software's author, the holder of the
16  * economic rights, and the successive licensors have only limited
17  * liability.
18  *
19  * In this respect, the user's attention is drawn to the risks associated
20  * with loading, using, modifying and/or developing or reproducing the
21  * software by the user in light of its specific status of free software,
22  * that may mean that it is complicated to manipulate, and that also
23  * therefore means that it is reserved for developers and experienced
24  * professionals having in-depth computer knowledge. Users are therefore
25  * encouraged to load and test the software's suitability as regards their
26  * requirements in conditions enabling the security of their systems and/or
27  * data to be ensured and, more generally, to use and operate it in the
28  * same conditions as regards security.
29  *
30  * The fact that you are presently reading this means that you have had
31  * knowledge of the CeCILL-B license and that you accept its terms.
32  */
33 
34 #ifndef AIMS_SPARSEMATRIX_SPARSEORDENSEMATRIX_H
35 #define AIMS_SPARSEMATRIX_SPARSEORDENSEMATRIX_H
36 
37 #include <aims/data/pheader.h>
40 
41 namespace aims
42 {
43 
44 
45  class SparseOrDenseMatrix : public virtual carto::RCObject
46  {
47 
48  public:
49 
56  {
57  public:
59  virtual ~MatrixLazyReader() {}
63  virtual bool hasRow( int32_t /* s1 */ ) const { return true; }
67  virtual bool hasColumn( int32_t /* s2 */ ) const { return true; }
68  virtual std::vector<double> *readRow( int32_t /* s1 */, bool store = true )
69  { (void)(store); return new std::vector<double>; }
70  virtual std::vector<double> *readColumn( int32_t /* s2 */,
71  bool store = true )
72  { (void)(store); return new std::vector<double>; }
73  virtual void freeRow( int32_t /* s1 */ ) {}
74  virtual void freeColumn( int32_t /* s2 */ ) {}
75  virtual void selectDimension( const std::vector<int32_t> & /* dims */ ) {}
76  void setInfFiltering( bool keep_inf, bool keep_nan )
77  { _keep_inf = keep_inf; _keep_nan = keep_nan; }
78  bool keepsInf() const { return _keep_inf; }
79  bool keepsNan() const { return _keep_nan; }
80 
81  private:
82  bool _keep_inf;
83  bool _keep_nan;
84  };
85 
88 
89  SparseOrDenseMatrix( int32_t size1 = 1, int32_t size2 = 1 );
91  virtual ~SparseOrDenseMatrix();
92 
94 
95  void reallocate( int32_t size1, int32_t size2 );
96 
97  int32_t getSize1() const;
98  int32_t getSize2() const;
99  int32_t getNonZeroElementCount() const;
100  std::vector<int32_t> getSize() const;
101 
102  bool hasElement( int32_t i, int32_t j ) const;
103 
104  double operator()( int32_t i, int32_t j ) const;
105  void erase_element( int32_t i, int32_t j );
106  void set_element( int32_t i, int32_t j, double x );
107 
108  void setRow( int32_t s1, const std::vector<double>& row );
109  void setColumn( int32_t s2, const std::vector<double>& column );
110 
111  std::vector<double> getRow( int32_t i ) const;
112  std::vector<double> getColumn( int32_t j ) const;
113 
122  void readRow( int32_t i );
131  void readColumn( int32_t i );
136  std::vector<double> *getReadRow( int32_t i, bool store = true );
141  std::vector<double> *getReadColumn( int32_t i, bool store = true );
145  void readAll();
146  void freeRow( int32_t i );
147  void freeColumn( int32_t i );
148 
149  template <typename VectorType>
150  VectorType getSparseRow( int32_t i ) const;
151  template <typename VectorType>
152  VectorType getSparseColumn( int32_t i ) const;
153 
154  void read( const std::string& filename );
155  void write( const std::string& filename,
156  carto::Object options=carto::none() ) const;
157 
158  bool isDense() const { return !_densematrix.isNull(); }
159 
160  SparseMatrixType sparseMatrix() { return _sparsematrix; }
161  const SparseMatrixType sparseMatrix() const { return _sparsematrix; }
162  DenseMatrixType denseMatrix() { return _densematrix; }
163  const DenseMatrixType denseMatrix() const { return _densematrix; }
164 
165  void setMatrix( SparseMatrixType matrix );
166  void setMatrix( DenseMatrixType matrix );
167 
169  const carto::Object header() const;
170  void setHeader( carto::Object ph );
171 
173  SparseMatrixType asSparse( bool copy=false ) const;
175  DenseMatrixType asDense( bool copy=false ) const;
176  void muteToDense();
177  void muteToSparse();
179  void muteToOptimalShape();
180  bool isOptimalShape() const;
182  unsigned long optimalShapeThreshold() const;
183 
185  operator += ( const SparseOrDenseMatrix& thing );
187  operator -= ( const SparseOrDenseMatrix& thing );
189  operator *= ( double x );
191  operator /= ( double x );
192 
194  {
195  delete _lazyreader;
196  _lazyreader = reader;
197  }
199  { return _lazyreader; }
200 
201  SparseOrDenseMatrix* subMatrix( const std::vector<int32_t> & start,
202  const std::vector<int32_t> & size );
204  const std::vector<std::vector<int32_t> > & indices_along_dims );
205 
206  protected:
207 
208  SparseMatrixType _sparsematrix;
209  DenseMatrixType _densematrix;
212 
213  };
214 
215 
216  template <typename VectorType>
217  inline
218  VectorType SparseOrDenseMatrix::getSparseRow( int32_t i ) const
219  {
220  if( !isDense() )
221  return sparseMatrix()->getSparseRow<VectorType>( i );
222 
223  // dense case
224  VectorType row( denseMatrix()->getSizeX() );
225  const double *buf = &denseMatrix().at( 0, i ), *end = &denseMatrix().at( denseMatrix()->getSizeX(), i );
226  long inc = &denseMatrix().at( 1, i ) - buf;
227  int x;
228  for( x=0; buf != end; buf += inc, ++x )
229  if( *buf != 0 )
230  row[x] = *buf;
231  return row;
232  }
233 
234 
235  template <typename VectorType>
236  inline
237  VectorType SparseOrDenseMatrix::getSparseColumn( int32_t i ) const
238  {
239  if( !isDense() )
240  return sparseMatrix()->getSparseColumn<VectorType>( i );
241 
242  // dense case
243  VectorType column( denseMatrix()->getSizeY() );
244  const double *buf = &denseMatrix().at( i, 0 ), *end = &denseMatrix().at( i, denseMatrix()->getSizeY() );
245  long inc = &denseMatrix().at( i, 1 ) - buf;
246  int x;
247  for( x=0; buf != end; buf += inc, ++x )
248  if( *buf != 0 )
249  column[x] = *buf;
250  return column;
251  }
252 
254  operator - ( const aims::SparseOrDenseMatrix & thing );
255 
257  operator + ( const aims::SparseOrDenseMatrix & thing1,
258  const aims::SparseOrDenseMatrix & thing2 );
259 
261  operator - ( const aims::SparseOrDenseMatrix & thing1,
262  const aims::SparseOrDenseMatrix & thing2 );
263 
265  operator * ( const aims::SparseOrDenseMatrix& thing1,
266  const double& thing2 );
267 
269  operator / ( const aims::SparseOrDenseMatrix & thing1,
270  const double& thing2 );
271 
272 }
273 
274 
275 #ifndef DOXYGEN_HIDE_INTERNAL_CLASSES
276 
277 namespace carto
278 {
279 
281  {
282  public:
283  static std::string objectType()
284  { return "SparseOrDenseMatrix"; }
285  static std::string dataType()
286  { return "DOUBLE"; }
287  static std::string name()
288  {
289  return std::string("SparseOrDenseMatrix_") + dataType();
290  }
291  };
292 
294 
295 }
296 
297 #endif // DOXYGEN_HIDE_INTERNAL_CLASSES
298 
299 
300 #endif
#define DECLARE_GENERIC_OBJECT_TYPE(T)
const DenseMatrixType denseMatrix() const
void write(const std::string &filename, carto::Object options=carto::none()) const
void reallocate(int32_t size1, int32_t size2)
std::vector< int32_t > getSize() const
int32_t getSize1() const
void setColumn(int32_t s2, const std::vector< double > &column)
void muteToOptimalShape()
mute to sparse or dense according to the less memory consuming
void readAll()
read all rows using lazy reading, using the MatrixLazyReader.
std::vector< double > * getReadColumn(int32_t i, bool store=true)
Get column, read it if it is not in memory, and optionally store it for later access.
std::vector< double > getRow(int32_t i) const
virtual std::vector< double > * readRow(int32_t, bool store=true)
void erase_element(int32_t i, int32_t j)
SparseOrDenseMatrix & operator*=(double x)
The class for EcatSino data write operation.
Definition: border.h:44
SparseOrDenseMatrix & operator/=(double x)
VectorType getSparseColumn(int32_t i) const
void setInfFiltering(bool keep_inf, bool keep_nan)
bool isNull() const
DenseMatrixType asDense(bool copy=false) const
get a shallow or deep copy in dense shape
SparseOrDenseMatrix & operator+=(const SparseOrDenseMatrix &thing)
virtual bool hasRow(int32_t) const
tells if row s1 has already been read.
const T & at(long x, long y=0, long z=0, long t=0) const
void setRow(int32_t s1, const std::vector< double > &row)
VectorType getSparseRow(int32_t i) const
virtual bool hasColumn(int32_t) const
tells if column s2 has already been read.
double operator()(int32_t i, int32_t j) const
int32_t getSize2() const
SparseOrDenseMatrix & operator-=(const SparseOrDenseMatrix &thing)
MatrixLazyReader * _lazyreader
Volume< T > copy(const Volume< T > &src)
void set_element(int32_t i, int32_t j, double x)
void setHeader(carto::Object ph)
SparseMatrixType asSparse(bool copy=false) const
get a shallow or deep copy in sparse shape
aims::SparseMatrix operator/(const aims::SparseMatrix &thing1, const double &thing2)
const SparseMatrixType sparseMatrix() const
carto::VolumeRef< double > DenseMatrixType
std::vector< double > * getReadRow(int32_t i, bool store=true)
Get row, read it if it is not in memory, and optionally store it for later access.
carto::Object header()
unsigned long optimalShapeThreshold() const
below this number of non-nul elements, the optimal shape is sparse
int32_t getNonZeroElementCount() const
aims::SparseMatrix operator+(const aims::SparseMatrix &thing)
aims::SparseMatrix operator-(const aims::SparseMatrix &thing)
SparseOrDenseMatrix(int32_t size1=1, int32_t size2=1)
virtual std::vector< double > * readColumn(int32_t, bool store=true)
MatrixLazyReader * lazyReader() const
void read(const std::string &filename)
void setLazyReader(MatrixLazyReader *reader)
Object none()
Pointer to an empty aims::StructuringElement.
bool hasElement(int32_t i, int32_t j) const
MatrixLazyReader allows to read a row or a column from file, on demand.
virtual void selectDimension(const std::vector< int32_t > &)
std::vector< double > getColumn(int32_t j) const
SparseOrDenseMatrix * subMatrix(const std::vector< int32_t > &start, const std::vector< int32_t > &size)
Quaternion operator*(const Quaternion &a, const Quaternion &b)
SparseOrDenseMatrix & operator=(const SparseOrDenseMatrix &other)
carto::rc_ptr< SparseMatrix > SparseMatrixType
SparseMatrixType sparseMatrix()
void setMatrix(SparseMatrixType matrix)