MeVisLab Toolbox Reference
mlMatrixTemplate.h
Go to the documentation of this file.
1 /*************************************************************************************
2 **
3 ** Copyright 2012, MeVis Medical Solutions AG
4 **
5 ** The user may use this file in accordance with the license agreement provided with
6 ** the Software or, alternatively, in accordance with the terms contained in a
7 ** written agreement between the user and MeVis Medical Solutions AG.
8 **
9 ** For further information use the contact form at https://www.mevislab.de/contact
10 **
11 **************************************************************************************/
12 
13 #ifndef ML_MATRIX_TEMPLATE_H
14 #define ML_MATRIX_TEMPLATE_H
15 
16 
22 
23 #include <mlInitSystemML.h>
24 #include <mlPrintTemplateErrors.h>
25 
26 #ifdef UNIX
27 #include "mlDebug.h"
28 #endif
29 
30 #include <ThirdPartyWarningsDisable.h>
31 #include <iostream>
32 #include <valarray>
33 #include <numeric>
34 #include <iterator>
35 #include <ThirdPartyWarningsRestore.h>
36 
37 //======================================================================
38 // namespaces
39 //======================================================================
40 ML_START_NAMESPACE
41 //======================================================================
42 // declaration of class *Slice_iter*
43 //======================================================================
48 template<class T>
49 class Slice_iter {
50  std::valarray<T>* v;
51  std::slice s;
52  size_t curr;
53 
55  T& ref(size_t i) const { return (*v)[s.start()+i*s.stride()]; }
56 public:
58  Slice_iter(std::valarray<T>* vv, std::slice ss) :v(vv), s(ss), curr(0) { }
59 
62  {
63  Slice_iter<T> t = *this;
64  t.curr = s.size(); // index of one plus last element
65  return t;
66  }
67 
70  Slice_iter<T>& operator++() { curr++; return *this; }
71  Slice_iter<T> operator++(int) { Slice_iter<T> t = *this; curr++; return t; }
73 
76  T& operator[](size_t i) { return ref(i); }
77  T& operator()(size_t i) { return ref(i); }
78  T& operator*() { return ref(curr); }
80 
83  // caution: friend function has to be implemented here inplace to support
84  // explicit template specification according to ansi standart in gcc, i.e to
85  // let the compiler know, that the friend functions are realy templated overloads
86  // (note: the gcc conform syntax (friend bool operator== <> (...)) is not supported
87  // on other compiler)
89  friend bool operator== (const Slice_iter<T>& p, const Slice_iter<T>& q)
90  {
91  return p.curr==q.curr
92  && p.s.stride()==q.s.stride()
93  && p.s.start()==q.s.start();
94  }
95 
97  friend bool operator!= (const Slice_iter<T>& p, const Slice_iter<T>& q)
98  {
99  return !(p==q);
100  }
101 
103  friend bool operator< (const Slice_iter<T>& p, const Slice_iter<T>& q)
104  {
105  return p.curr<q.curr
106  && p.s.stride()==q.s.stride()
107  && p.s.start()==q.s.start();
108  }
110 };
111 
112 
113 //======================================================================
114 // declaration of class *Cslice_iter*
115 //======================================================================
120 template<class T>
122 {
123  std::valarray<T>* v;
124  std::slice s;
125  size_t curr;
126 
128  const T& ref(size_t i) const { return (*v)[s.start()+i*s.stride()]; }
129 public:
131  Cslice_iter(std::valarray<T>* vv, std::slice ss): v(vv), s(ss), curr(0){}
132 
135  {
136  Cslice_iter<T> t = *this;
137  t.curr = s.size(); // index of one plus last element
138  return t;
139  }
140 
143  Cslice_iter<T>& operator++() { curr++; return *this; }
144  Cslice_iter<T> operator++(int) { Cslice_iter<T> t = *this; curr++; return t; }
146 
149  const T& operator[](size_t i) const { return ref(i); }
150  const T& operator()(size_t i) const { return ref(i); }
151  const T& operator*() const { return ref(curr); }
153 
156  // caution: friend function has to be implemented here inplace to support
157  // explicit template specification according to ansi standart in gcc, i.e to
158  // let the compiler know, that the friend functions are realy templated overloads
159  // (note: the gcc conform syntax (friend bool operator== <> (...)) is not supported
160  // on other compiler)
162  friend bool operator==(const Cslice_iter<T>& p, const Cslice_iter<T>& q)
163  {
164  return p.curr==q.curr
165  && p.s.stride()==q.s.stride()
166  && p.s.start()==q.s.start();
167  }
168 
170  friend bool operator!=(const Cslice_iter<T>& p, const Cslice_iter<T>& q)
171  {
172  return !(p==q);
173  }
174 
176  friend bool operator< (const Cslice_iter<T>& p, const Cslice_iter<T>& q)
177  {
178  return p.curr<q.curr
179  && p.s.stride()==q.s.stride()
180  && p.s.start()==q.s.start();
181  }
183 
184 };
185 
186 //======================================================================
187 // declaration of class *MatrixTemplate*
188 //======================================================================
192 template <class T>
194  std::valarray<T>* v;
195  size_t size_x;
196  size_t size_y;
197 public:
198  MatrixTemplate(size_t x, size_t y);
200  MatrixTemplate<T>& operator=(const MatrixTemplate<T>&);
201  ~MatrixTemplate();
202 
203  void freeMatrix();
204  void resizeMatrix(size_t x, size_t y, const T& c = T());
205  void overrideMatrix(size_t x, size_t y, const T& c = T());
206 
207  size_t size() const { return size_x*size_y; }
208  size_t sizeX() const { return size_x; }
209  size_t sizeY() const { return size_y; }
210 
211  Slice_iter<T> row(size_t i);
212  Cslice_iter<T> row(size_t i) const;
213 
214  Slice_iter<T> column(size_t i);
215  Cslice_iter<T> column(size_t i) const;
216 
219  T& operator()(size_t x, size_t y);
220  T operator()(size_t x, size_t y) const;
221 
222  Slice_iter<T> operator()(size_t i) { return column(i); }
223  Cslice_iter<T> operator()(size_t i) const { return column(i); }
225 
228  Slice_iter<T> operator[](size_t i) { return column(i); }
229  Cslice_iter<T> operator[](size_t i) const { return column(i); }
231 
233 
234  std::valarray<T>& array() { return *v; }
235 
236  operator T * () { return reinterpret_cast<T*>(&v); }
237 };
238 
239 
240 //======================================================================
241 // declaration of class *MatrixSizedTemplate*
242 //======================================================================
248 template <class T, size_t SIZE_X, size_t SIZE_Y>
250 {
251  public:
253  MatrixSizedTemplate () : MatrixTemplate<T>(SIZE_X, SIZE_Y) {;}
254 };
255 
256 
257 
258 
259 
260 
261 //=======================================================================
262 // Implementation of MatrixTemplate - functions
263 //=======================================================================
264 
266 template <class T>
268 {
269  return Slice_iter<T>(v,std::slice(i,size_x,size_y));
270 }
271 
273 template <class T>
275 {
276  return Cslice_iter<T>(v,std::slice(i,size_x,size_y));
277 }
278 
280 template <class T>
282 {
283  return Slice_iter<T>(v,std::slice(i*size_y,size_y,1));
284 }
285 
287 template <class T>
289 {
290  return Cslice_iter<T>(v,std::slice(i*size_y,size_y,1));
291 }
292 
294 template <class T>
296 {
297  size_x = x;
298  size_y = y;
299  v = new std::valarray<T>(size_x*size_y);
300 }
301 
303 template <class T>
305 {
306  // set size according to transfered object
307  size_x = mt.size_x;
308  size_y = mt.size_y;
309  // assign new valarray of appropriate size
310  v = new std::valarray<T>(size_x*size_y);
311 
312  // copy memory content
313  *v = *(mt.v);
314 }
315 
317 template <class T>
319 {
320  if(this != &mt){
321  // resize matrixTemplate
322  this->resizeMatrix(mt.size_x, mt.size_y);
323  // copy memory content
324  *v = *(mt.v);
325  }
326  return *this;
327 }
328 
330 template <class T>
332 {
333  delete v;
334 }
335 
339 template <class T>
340 void MatrixTemplate<T>::resizeMatrix(size_t x, size_t y, const T& c)
341 {
342  size_x = x;
343  size_y = y;
344  v->resize(size_x*size_y, c);
345 }
346 
350 template <class T>
351 void MatrixTemplate<T>::overrideMatrix(size_t x, size_t y, const T& c)
352 {
353  size_x = x;
354  size_y = y;
355  *v = c;
356  v->resize(size_x*size_y, c);
357 }
358 
359 
361 template <class T>
363 {
364  size_x = 0;
365  size_y = 0;
366  v->free();
367 }
368 
370 template <class T>
371 T& MatrixTemplate<T>::operator()(size_t x, size_t y)
372 {
373  return column(x)[y];
374 }
375 
376 
377 
378 //---------------------------------------------------------------------------------
380 //---------------------------------------------------------------------------------
383 template <class T>
384 T mul(const Cslice_iter<T>& v1, const std::valarray<T>& v2)
385 {
386  T res = 0;
387  for (size_t i = 0; i<v2.size(); i++) res+= v1[i]*v2[i];
388  return res;
389 }
390 
391 
393 template <class T>
394 std::valarray<T> operator*(const MatrixTemplate<T>& m, const std::valarray<T>& v)
395 {
396  if (m.sizeX()!=v.size()){
397  printTemplateError("mlMatrixTemplate.h, operator*() # 1",
399  "Wrong number of elements in m*v\n, ignoring problem");
400  }
401 
402  std::valarray<T> res(m.sizeY());
403  for (size_t i = 0; i<m.sizeY(); i++) res[i] = mul(m.row(i),v);
404  return res;
405 }
406 
407 
409 //std::valarray<T> operator*(const MatrixTemplate<T>& m, std::valarray<T>& v)
410 template <class T>
411 std::valarray<T> mul_mv(const MatrixTemplate<T>& m, std::valarray<T>& v)
412 {
413  if (m.sizeX()!=v.size()){
414  printTemplateError("mlMatrixTemplate.h, mul_mv()",
416  "Wrong number of elements in m*v\n, ignoring problem");
417  }
418 
419  std::valarray<T> res(m.sizeY());
420 
421  for (size_t i = 0; i<m.sizeY(); i++) {
422  const Cslice_iter<T>& ri = m.row(i);
423  res[i] = inner_product(ri,ri.end(),&v[0],T(0));
424  }
425  return res;
426 }
427 
428 
429 
431 template <class T>
432 std::valarray<T> operator*(std::valarray<T>& v, const MatrixTemplate<T>& m)
433 {
434  if (v.size()!=m.sizeY()){
435  printTemplateError("mlMatrixTemplate.h, operator*() # 2",
437  "Wrong number of elements in v*m\n, ignoring problem");
438  }
439 
440  std::valarray<T> res(m.sizeX());
441 
442  for (size_t i = 0; i<m.sizeX(); i++) {
443  const Cslice_iter<T>& ci = m.column(i);
444  res[i] = inner_product(ci,ci.end(),&v[0],T(0));
445  }
446  return res;
447 }
448 
450 template <class T>
452 {
453  (*v) *= d;
454  return *this;
455 }
456 
458 template <class T>
459 std::ostream& operator<<(std::ostream& os, MatrixTemplate<T>& m)
460 {
461  for(int y=0; y<m.sizeY(); y++)
462  {
463  for(int x=0; x<m.sizeX(); x++)
464  os<<m[x][y]<<"\t";
465  os << "\n";
466  }
467  return os;
468 }
469 
471 
472 
473 
474 
475 } // namespace ml
476 
477 #endif //__MatrixTemplate_h__
478 
479 
@ T
Definition: SoKeyGrabber.h:71
Templated support class for class MatrixTemplate to allow fast element access organisation by slicing...
friend bool operator==(const Cslice_iter< T > &p, const Cslice_iter< T > &q)
overload operator==(.,.) for Cslice_iter objects
Cslice_iter< T > & operator++()
standard itterator incrementation
Cslice_iter< T > operator++(int)
standard itterator incrementation
const T & operator[](size_t i) const
C style subscript.
friend bool operator!=(const Cslice_iter< T > &p, const Cslice_iter< T > &q)
overload operator!=(.,.) for Cslice_iter objects
const T & operator*() const
current element
const T & operator()(size_t i) const
Fortran-style subscript.
Cslice_iter< T > end() const
returns itterator positioned on last-plus-one element
Cslice_iter(std::valarray< T > *vv, std::slice ss)
constructor: initialising slice-itterator for val-array
T operator*(const FloatingPointVector< T, size, DataContainer > &a, const FloatingPointVector< T, size, DataContainer > &b)
Dot product, returns a.dot(b).
general Matrix class based on MatrixTemplate<T> to allow fixed size setting with object declaration.
MatrixSizedTemplate()
ctor: initialise size at object creation with desired value
MatricTemplate implements general Matrix class based on valarray of objects with Template class type ...
size_t sizeX() const
return number of columns
Slice_iter< T > operator[](size_t i)
slice of column(i)
std::valarray< T > & array()
reference to internal valarray
size_t sizeY() const
return number of rows
Cslice_iter< T > operator()(size_t i) const
const slice of first argument (i.e column(i))
Slice_iter< T > column(size_t i)
itterator access to i-te column slice
Slice_iter< T > operator()(size_t i)
slice of first argument (i.e column(i))
size_t size() const
return total number of matrix elements
T operator()(size_t x, size_t y) const
element x,y
Slice_iter< T > row(size_t i)
itterator access to i-te row slice
Cslice_iter< T > operator[](size_t i) const
const slice of column(i)
Templated support class for class MatrixTemplate to allow fast element access organisation by slicing...
T & operator()(size_t i)
Fortran-style subscript.
T & operator[](size_t i)
C style subscript.
Slice_iter< T > operator++(int)
standard itterator incrementation
Slice_iter(std::valarray< T > *vv, std::slice ss)
constructor: initialising slice-itterator for val-array
Slice_iter< T > end() const
returns itterator positioned on last-plus-one element
T & operator*()
current element
Slice_iter< T > & operator++()
standard itterator incrementation
#define ML_BAD_PARAMETER
A bad/invalid parameter (or even an inappropriate image) has been passed to a module or an algorithm;...
Definition: mlTypeDefs.h:925
void ML_UTILS_EXPORT printTemplateError(const char *location, MLErrorCode reason, const std::string_view &handling)
bool operator==(const Tmat2< DT > &a, const Tmat2< DT > &b)
a == b ? Return true if yes.
Definition: mlMatrix2.h:425
std::valarray< T > mul_mv(const MatrixTemplate< T > &m, std::valarray< T > &v)
alternative definition of m*v
bool operator!=(const Tmat2< DT > &a, const Tmat2< DT > &b)
a != b ? Return true if yes.
Definition: mlMatrix2.h:433
std::ostream & operator<<(std::ostream &os, MatrixTemplate< T > &m)
override operator<<(.,.) for class MatrixTemplate<T>
T mul(const Cslice_iter< T > &v1, const std::valarray< T > &v2)
implementation of (global) operator functions to assist MatrixTemplate class
FloatingPointVector< T, size, DataContainer > & operator*=(FloatingPointVector< T, size, DataContainer > &op1, MLdouble value)
Arithmetic assignment: Component wise multiplication *this with specialized MLdouble scalar value.