primatologist-gpl  5.1.2
matrix_d.h
Go to the documentation of this file.
1 /* Copyright (C) 2000-2013 CEA
2  *
3  * This software and supporting documentation were developed by
4  * bioPICSEL
5  * CEA/DSV/I²BM/MIRCen/LMN, Batiment 61,
6  * 18, route du Panorama
7  * 92265 Fontenay-aux-Roses
8  * France
9  */
10 
11 #ifndef PRIMATOLOGIST_MATH_MATRIX_D_H
12 #define PRIMATOLOGIST_MATH_MATRIX_D_H
13 
15 #include <aims/data/data_g.h> // AimsData
16 #include <aims/math/gausslu.h> // AimsInversionLU
17 
18 namespace aims {
19 namespace math {
20 
21  //==========================================================================
22  // BASE CLASS FOR MATRICES
23  //==========================================================================
24 
25  //--------------------------------------------------------------------------
26  // CONSTRUCTOR / DESTRUCTOR / COPY
27  //--------------------------------------------------------------------------
28 
29  template <typename T>
30  MatrixBase<T>::MatrixBase( int nrow, int ncol ):
31  carto::VolumeRef<T>( nrow, ncol )
32  {
33  this->fill(0);
34  }
35 
36  template <typename T>
37  template <typename U>
38  MatrixBase<T>::MatrixBase( const carto::VolumeRef<U> & volume ):
39  carto::VolumeRef<T>( volume.template copy<T>() )
40  {}
41 
42 
43  template <typename T>
44  template <typename U>
45  MatrixBase<T>::MatrixBase( const std::vector<U> & vector ):
46  carto::VolumeRef<T>( vector.size() )
47  {
48  for( int i = 0; i < vector.size(); ++i )
49  this->at(i) = vector[i];
50  }
51 
52  template <typename T>
54  {}
55 
56  // Utility structure to compare adresses of volumes of possibly
57  // different types
58  namespace internal {
59 
60  template <typename T, typename U>
62  {
63  static bool equal( const carto::VolumeRef<T> *,
64  const carto::VolumeRef<U> * )
65  {
66  return false;
67  }
68  };
69 
70  template <typename T>
72  {
73  static bool equal( const carto::VolumeRef<T> * a,
74  const carto::VolumeRef<T> * b )
75  {
76  return( a == b );
77  }
78  };
79 
80  } // namespace internal
81 
82  template <typename T>
83  template <typename U>
84  MatrixBase<T> & MatrixBase<T>::operator= ( const carto::VolumeRef<U> & volume )
85  {
86  if( !internal::CompareVolumeRefAdress<T, U>::equal( this, &volume ) )
87  {
88  *this = volume.copy();
89  }
90  return *this;
91  }
92 
93  template <typename T>
94  template <typename U>
95  MatrixBase<T> & MatrixBase<T>::operator= ( const std::vector<U> & vector )
96  {
97  this->reallocate( vector.size() );
98  for( int i = 0; i < vector.size(); ++i )
99  this->at(i) = vector[i];
100  return *this;
101  }
102 
103  //--------------------------------------------------------------------------
104  // PRIVATE SHARED MEMORY CONSTRUCTOR
105  //--------------------------------------------------------------------------
106 
107  template <typename T>
108  MatrixBase<T>::MatrixBase( carto::VolumeRef<T> & volume ):
109  carto::VolumeRef<T>( volume )
110  {}
111 
112  //--------------------------------------------------------------------------
113  // CONVERSIONS
114  //--------------------------------------------------------------------------
115 
116  template <typename T>
117  template <typename U>
119  {
120  return( MatrixBase<U>( *this ) );
121  }
122 
123  //--------------------------------------------------------------------------
124  // MATRIX OPERATIONS
125  //--------------------------------------------------------------------------
126 
127  template <typename T>
128  template <typename U>
130  {
131  *this = *this * m;;
132  return *this;
133  }
134 
135  template <typename T, typename U>
137  operator* ( const MatrixBase<T> & a, const MatrixBase<U> & b )
138  {
139  typedef typename carto::volumeutil::multiplies<T,U>::result_type
140  result_type;
141  if( a.ncol() != b.nrow() )
142  throw incompatible_matrix_exception( a.ncol(), b.nrow() );
143 
144  MatrixBase<result_type> result( a.nrow(), b.ncol() );
145  double value;
146  for( int i = 0; i < a.nrow(); ++i )
147  for( int j = 0; j < b.ncol(); ++j )
148  {
149  value = 0.;
150  for( int k = 0; k < a.ncol(); ++k )
151  value += a(i, k) * b(k, j);
152  result(i, j) = value;
153  }
154  return result;
155  }
156 
157  template <typename T>
159  {
160  *this = aims::math::transpose(*this);
161  return *this;
162  }
163 
164  template <typename T>
166  {
167  MatrixBase<T> result( m.ncol(), m.nrow() );
168  for( int i = 0; i < m.nrow(); ++i )
169  for( int j = 0; j < m.ncol(); ++j )
170  result( j, i ) = m( i, j );
171  return result;
172  }
173 
174  template <typename T>
176  {
177  *this = aims::math::invert(*this);
178  return *this;
179  }
180 
181  template <typename T>
183  {
184  // We use AIMS tools
185  AimsData<float> aimsFloat( matrix.template copy<float>() );
186  AimsData<float> invertedAimsFloat = AimsInversionLU( aimsFloat );
187  carto::VolumeRef<T> volume = carto::VolumeRef<float>( invertedAimsFloat.volume() ).copy<T>();
188  return asMatrix( volume );
189  }
190 
191  //==========================================================================
192  // OVERLOAD OPERATORS
193  //==========================================================================
194 
195  template <typename T, typename U>
196  bool operator== ( const MatrixBase<T> & vol, const MatrixBase<U> & other )
197  {
198  if( vol.nrow() != other.nrow() || vol.ncol() != other.ncol() )
199  return false;
200  for( int i = 0; i < vol.nrow(); ++i )
201  for( int j = 0; j < vol.ncol(); ++j )
202  if( vol(i, j) != other(i, j) )
203  return false;
204  return true;
205  }
206 
207  template <typename T, typename U>
208  bool operator!= ( const MatrixBase<T> & vol, const MatrixBase<U> & other )
209  {
210  return !( vol == other );
211  }
212 
213  template <typename T>
215  {
216  carto::VolumeRef<T> volresult = -(carto::VolumeRef<T> &)vol;
217  return asMatrix(volresult);
218  }
219 
220  template <typename T, typename U>
221  MatrixBase<typename carto::volumeutil::plus<T,U>::result_type >
222  operator+ ( const MatrixBase<T> & vol, const U & value )
223  {
224  carto::VolumeRef<typename carto::volumeutil::plus<T,U>::result_type> volresult = (carto::VolumeRef<T>&)vol + value;
225  return asMatrix(volresult);
226  }
227 
228  template <typename T, typename U>
229  MatrixBase<typename carto::volumeutil::minus<T,U>::result_type >
230  operator- ( const MatrixBase<T> & vol, const U & value )
231  {
232  carto::VolumeRef<typename carto::volumeutil::minus<T,U>::result_type> volresult = (carto::VolumeRef<T>&)vol - value;
233  return asMatrix(volresult);
234  }
235 
236  template <typename T, typename U>
237  MatrixBase<typename carto::volumeutil::multiplies<T,U>::result_type >
238  operator* ( const MatrixBase<T> & vol, const U & value )
239  {
240  carto::VolumeRef<typename carto::volumeutil::multiplies<T,U>::result_type> volresult = (carto::VolumeRef<T>&)vol * value;
241  return asMatrix(volresult);
242  }
243 
244  template <typename T, typename U>
245  MatrixBase<typename carto::volumeutil::divides<T,U>::result_type >
246  operator/ ( const MatrixBase<T> & vol, const U & value )
247  {
248  carto::VolumeRef<typename carto::volumeutil::divides<T,U>::result_type> volresult = (carto::VolumeRef<T>&)vol / value;
249  return asMatrix(volresult);
250  }
251 
252  template <typename T, typename U>
253  MatrixBase<typename carto::volumeutil::plus<U,T>::result_type >
254  operator+ ( const U & value, const MatrixBase<T> & vol )
255  {
256  carto::VolumeRef<typename carto::volumeutil::plus<T,U>::result_type> volresult = value + (carto::VolumeRef<T>&)vol;
257  return asMatrix(volresult);
258  }
259 
260  template <typename T, typename U>
261  MatrixBase<typename carto::volumeutil::minus<U,T>::result_type >
262  operator- ( const U & value, const MatrixBase<T> & vol )
263  {
264  carto::VolumeRef<typename carto::volumeutil::minus<T,U>::result_type> volresult = value - (carto::VolumeRef<T>&)vol;
265  return asMatrix(volresult);
266  }
267 
268  template <typename T, typename U>
269  MatrixBase<typename carto::volumeutil::multiplies<U,T>::result_type >
270  operator* ( const U & value, const MatrixBase<T> & vol )
271  {
272  carto::VolumeRef<typename carto::volumeutil::multiplies<T,U>::result_type> volresult = value * (carto::VolumeRef<T>&)vol;
273  return asMatrix(volresult);
274  }
275 
276  template <typename T, typename U>
277  MatrixBase<typename carto::volumeutil::divides<U,T>::result_type >
278  operator/ ( const U & value, const MatrixBase<T> & vol )
279  {
280  carto::VolumeRef<typename carto::volumeutil::divides<T,U>::result_type> volresult = value / (carto::VolumeRef<T>&)vol;
281  return asMatrix(volresult);
282  }
283 
284  template <typename T, typename U>
285  MatrixBase<typename carto::volumeutil::plus<T,U>::result_type >
286  operator+ ( const MatrixBase<T> & vol, const MatrixBase<U> & other )
287  {
288  carto::VolumeRef<typename carto::volumeutil::plus<T,U>::result_type> volresult = (carto::VolumeRef<T>&)vol + (carto::VolumeRef<U>&)other;
289  return asMatrix(volresult);
290  }
291 
292  template <typename T, typename U>
293  MatrixBase<typename carto::volumeutil::minus<T,U>::result_type >
294  operator- ( const MatrixBase<T> & vol, const MatrixBase<U> & other )
295  {
296  carto::VolumeRef<typename carto::volumeutil::minus<T,U>::result_type> volresult = (carto::VolumeRef<T>&)vol - (carto::VolumeRef<U>&)other;
297  return asMatrix(volresult);
298  }
299 
300  //--------------------------------------------------------------------------
301  // SIZE
302  //--------------------------------------------------------------------------
303 
304  template <typename T>
306  {
307  return this->getSizeX();
308  }
309 
310  template <typename T>
312  {
313  return this->getSizeY();
314  }
315 
316  template <typename T>
318  {
319  return this->getSizeX() * this->getSizeY();
320  }
321 
322  //==========================================================================
323  // STREAM / WRITE
324  //==========================================================================
325 
326  template <typename T>
327  std::ostream & operator<< ( std::ostream & out,
328  const MatrixBase<T> & matrix )
329  {
330  return out << (carto::VolumeRef<T> &)matrix;
331  }
332 
333  // template <typename T>
334  // void write( const MatrixBase<T> & matrix );
335 
336  //==========================================================================
337  // UTILITY FUNCTIONS
338  //==========================================================================
339 
340  template <typename T>
341  MatrixBase<T> asMatrix( carto::VolumeRef<T> & volume )
342  {
343  return MatrixBase<T>( volume );
344  }
345 
346 } // namespace math
347 } // namespace aims
348 
349 #endif // PRIMATOLOGIST_MATH_MATRIX_D_H
Matrix class implementing matrix operations.
Definition: matrix.h:50
MatrixBase< T > & transpose()
Matrix transposition.
Definition: matrix_d.h:158
int size() const
Number of elements.
Definition: matrix_d.h:317
MatrixBase< T > & invert()
Matrix inversion.
Definition: matrix_d.h:175
int ncol() const
Number of columns.
Definition: matrix_d.h:311
~MatrixBase()
Destructor.
Definition: matrix_d.h:53
MatrixBase< T > & operator*=(const MatrixBase< U > &)
Matrix product.
Definition: matrix_d.h:129
int nrow() const
Number of rows.
Definition: matrix_d.h:305
MatrixBase(int nrow=1, int ncol=1)
Standard constructor Allocate a matrix of size nrow x ncol.
Definition: matrix_d.h:30
MatrixBase< T > & operator=(const carto::VolumeRef< U > &matrix)
Assignment operator The content from other is entirely copied.
Definition: matrix_d.h:84
This exception is thrown when an attempt is made at multiplying two matrices with incompatible dimens...
Definition: matrix.h:215
const T & at(const carto::VolumeRef< T > &vol, long px, long py, long pz, long pt, const Point4dl &fullsize, const Point4dl &binf)
MatrixBase< T > transpose(const MatrixBase< T > &)
Matrix transposition.
Definition: matrix_d.h:165
MatrixBase< T > asMatrix(carto::VolumeRef< T > &volume)
Interprets the volume as a matrix.
Definition: matrix_d.h:341
MatrixBase< typename carto::volumeutil::multiplies< T, U >::result_type > operator*(const MatrixBase< T > &a, const MatrixBase< U > &b)
Matrix product.
Definition: matrix_d.h:137
MatrixBase< T > invert(const MatrixBase< T > &)
Matrix inversion.
Definition: matrix_d.h:182
bool operator!=(const MatrixBase< T > &vol, const MatrixBase< U > &other)
Returns false if dimensions are not the same or if any couple of elements is not equal.
Definition: matrix_d.h:208
bool operator==(const MatrixBase< T > &vol, const MatrixBase< U > &other)
Returns true if the dimensions are the same and if all elements are equal.
Definition: matrix_d.h:196
MatrixBase< T > operator-(const MatrixBase< T > &vol)
Returns a Matrix filled with opposite elements.
Definition: matrix_d.h:214
MatrixBase< typename carto::volumeutil::divides< T, U >::result_type > operator/(const MatrixBase< T > &vol, const U &value)
Matrix / Scalar.
Definition: matrix_d.h:246
std::ostream & operator<<(std::ostream &out, const MatrixBase< T > &matrix)
Print the matrix content on the standard output.
Definition: matrix_d.h:327
MatrixBase< typename carto::volumeutil::plus< T, U >::result_type > operator+(const MatrixBase< T > &vol, const U &value)
Matrix + Scalar.
Definition: matrix_d.h:222
static bool equal(const carto::VolumeRef< T > *a, const carto::VolumeRef< T > *b)
Definition: matrix_d.h:73
static bool equal(const carto::VolumeRef< T > *, const carto::VolumeRef< U > *)
Definition: matrix_d.h:63