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>
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//======================================================================
41//======================================================================
42// declaration of class *Slice_iter*
43//======================================================================
48template<class T>
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()]; }
56public:
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//======================================================================
120template<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()]; }
129public:
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//======================================================================
192template <class T>
194 std::valarray<T>* v;
195 size_t size_x;
196 size_t size_y;
197public:
198 MatrixTemplate(size_t x, size_t y);
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
212 Cslice_iter<T> row(size_t i) const;
213
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//======================================================================
248template <class T, size_t SIZE_X, size_t SIZE_Y>
250{
251 public:
254};
255
256
257
258
259
260
261//=======================================================================
262// Implementation of MatrixTemplate - functions
263//=======================================================================
264
266template <class T>
268{
269 return Slice_iter<T>(v,std::slice(i,size_x,size_y));
270}
271
273template <class T>
275{
276 return Cslice_iter<T>(v,std::slice(i,size_x,size_y));
277}
278
280template <class T>
282{
283 return Slice_iter<T>(v,std::slice(i*size_y,size_y,1));
284}
285
287template <class T>
289{
290 return Cslice_iter<T>(v,std::slice(i*size_y,size_y,1));
291}
292
294template <class T>
296{
297 size_x = x;
298 size_y = y;
299 v = new std::valarray<T>(size_x*size_y);
300}
301
303template <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
317template <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
330template <class T>
332{
333 delete v;
334}
335
339template <class T>
340void 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
350template <class T>
351void 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
361template <class T>
363{
364 size_x = 0;
365 size_y = 0;
366 v->free();
367}
368
370template <class T>
372{
373 return column(x)[y];
374}
375
376
377
378//---------------------------------------------------------------------------------
380//---------------------------------------------------------------------------------
383template <class T>
384T 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
393template <class T>
394std::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)
410template <class T>
411std::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
431template <class T>
432std::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
450template <class T>
452{
453 (*v) *= d;
454 return *this;
455}
456
458template <class T>
459std::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
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
const T & operator()(size_t i) const
Fortran-style subscript.
Cslice_iter< T > & operator++()
standard itterator incrementation
const T & operator*() const
current element
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
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
Cslice_iter< T > operator++(int)
standard itterator incrementation
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 ...
Slice_iter< T > operator[](size_t i)
slice of column(i)
Cslice_iter< T > operator[](size_t i) const
const slice of column(i)
size_t sizeX() const
return number of columns
void overrideMatrix(size_t x, size_t y, const T &c=T())
resize matrix if necessary, set all elements on value c
Cslice_iter< T > row(size_t i) const
const itterator access to i-te row slice
Cslice_iter< T > operator()(size_t i) const
const slice of first argument (i.e column(i))
T & operator()(size_t x, size_t y)
reference of element x,y
void freeMatrix()
free allocated memory
size_t sizeY() const
return number of rows
void resizeMatrix(size_t x, size_t y, const T &c=T())
resize matrix, set new allocated elements to value c
MatrixTemplate(size_t x, size_t y)
constructor initialising memory block for requested matrix size
Cslice_iter< T > column(size_t i) const
const itterator access to i-te column slice
Slice_iter< T > column(size_t i)
itterator access to i-te column slice
MatrixTemplate< T > & operator=(const MatrixTemplate< T > &)
assignment operator ATTENTION: implies resizing of matrix
size_t size() const
return total number of matrix elements
~MatrixTemplate()
destructor: free allocated memory
T operator()(size_t x, size_t y) const
element x,y
Slice_iter< T > operator()(size_t i)
slice of first argument (i.e column(i))
Slice_iter< T > row(size_t i)
itterator access to i-te row slice
MatrixTemplate(const MatrixTemplate< T > &)
copy constructor
std::valarray< T > & array()
reference to internal valarray
MatrixTemplate< T > & operator*=(T)
multiplication of all matrix elements with element-type multiplicator
Templated support class for class MatrixTemplate to allow fast element access organisation by slicing...
Slice_iter< T > & operator++()
standard itterator incrementation
Slice_iter(std::valarray< T > *vv, std::slice ss)
constructor: initialising slice-itterator for val-array
T & operator[](size_t i)
C style subscript.
Slice_iter< T > end() const
returns itterator positioned on last-plus-one element
T & operator()(size_t i)
Fortran-style subscript.
Slice_iter< T > operator++(int)
standard itterator incrementation
T & operator*()
current element
#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:823
Target mlrange_cast(Source arg)
Generic version of checked ML casts.
std::ostream & operator<<(std::ostream &out, const ml::Variant &variant)
Definition mlVariant.h:210
void ML_UTILS_EXPORT printTemplateError(const char *location, MLErrorCode reason, const std::string_view &handling)
T operator*(const FloatingPointVector< T, size, DataContainer > &a, const FloatingPointVector< T, size, DataContainer > &b)
Dot product, returns a.dot(b).
T mul(const Cslice_iter< T > &v1, const std::valarray< T > &v2)
implementation of (global) operator functions to assist MatrixTemplate class
std::valarray< T > mul_mv(const MatrixTemplate< T > &m, std::valarray< T > &v)
alternative definition of m*v