primatologist-gpl 6.0.4
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
18namespace aims {
19namespace math {
20
21 //==========================================================================
22 // BASE CLASS FOR MATRICES
23 //==========================================================================
24
25 //--------------------------------------------------------------------------
26 // CONSTRUCTOR / DESTRUCTOR / COPY
27 //--------------------------------------------------------------------------
28
29 template <typename T>
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>
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 {
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 }
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>
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
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