nmpp
tmatrix.h
1
2// //
3// Header file of template of class mtr //
4// //
6#ifndef _TMATRIX_H_INCLUDED_
7#define _TMATRIX_H_INCLUDED_
8
9//#ifdef __cplusplus
10
11#include "crtdbg2.h"
12
13#include <stdio.h>
14#include "tvector.h"
15#include <string.h>
16
18//
19// Class of matrixes
20//
21
22//*****************************************************************************
57//*****************************************************************************
58
59#ifndef GetVec
60#define GetVec getvec
61#endif
62
63#ifndef GetCol
64#define GetCol getcol
65#endif
66
67#ifndef Min
68#define Min min
69#endif
70
71
72#ifndef Max
73#define Max max
74#endif
75
76
77#ifndef MinPos
78#define MinPos minpos
79#endif
80
81#ifndef MaxPos
82#define MaxPos maxpos
83#endif
84
85
86
87template<class T> class mtr
88{
89protected:
90 T* m_container;
91public:
92 int m_border;
93 int m_stride;
94 int m_height,m_width,m_size;
95 int m_x0;
96 int m_y0;
97 T *m_data;
98
99 explicit mtr()
100 {
101 m_height=0;
102 m_width=0;
103 m_size=0;
104 m_container=0;
105 m_data=0;
106 m_stride=0;
107 }
108
109 // Setting (0,0) index for element [y][x]
110 void origin(int y,int x){
111 m_x0=x;
112 m_y0=y;
113 }
114
115 // Setting value
116 inline void setval(int y, int x, const T& val)
117 {
118 ASSERTE(y>=-m_border);
119 ASSERTE(y<m_height+m_border);
120 m_data[y*m_stride+x]=val;
121 }
122
123 // extended setting value
124 inline void setvalx(int y, int x, const T& val)
125 {
126 ASSERTE(y+m_y0>=-m_border);
127 ASSERTE(y+m_y0<m_height+m_border);
128 m_data[(y+m_y0)*m_stride+x+m_x0]=val;
129 }
130 // getting value
131 inline T getval(int y,int x) const
132 {
133 ASSERTE(y>=-m_border);
134 ASSERTE(y<m_height+m_border);
135 T val=m_data[y*m_stride+x];
136 return val;
137 }
138 // extended getting value
139 inline T getvalx(int y,int x) const
140 {
141 ASSERTE(y+m_y0>=-m_border);
142 ASSERTE(y+m_y0<m_height+m_border);
143 T val=m_data[(y+m_y0)*m_stride+x+m_x0];
144 return val;
145 }
146
147 // constructor
148 explicit mtr(int nHeight, int nWidth, int nBorder=0)
149 {
150 m_border=nBorder;
151 m_height=nHeight;
152 m_width=nWidth;
153 m_stride=m_width;
154 m_size=m_width*m_height;
155 m_container=new T[m_size+2*m_stride*m_border];
156 m_data=m_container+m_border*m_stride;
157 ASSERTE(m_container!=NULL);
158 }
159
160 // resizing of matrix dimensions
161 void resize(int nHeight, int nWidth, int nBorder=0)
162 {
163 if (m_container)
164 delete m_container;
165 m_border=nBorder;
166 m_height=nHeight;
167 m_width =nWidth;
168 m_size =m_width*m_height;
169 m_stride=m_width;
170 m_container=new T[m_size+2*m_stride*m_border];
171 m_data=m_container+m_border*m_stride;
172 }
173
174 // constructor for matrix duplication
175 /*explicit*/ mtr(const mtr<T>& matr)
176 {
177 m_height=matr.m_height;
178 m_width =matr.m_width;
179 m_size =matr.m_size;
180 m_stride=m_width;
181 m_border=matr.m_border;
182 m_container =new T[m_size+2*m_stride*m_border];
183 m_data=m_container+m_border*m_stride;
184
185 for(int y=0;y<m_height;y++){
186 for(int x=0;x<m_width;x++){
187 T val=matr.getval(y,x);
188 setval(y,x,val);
189 }
190 }
191 };
192
193/*
194 ..\include\tmatrix.h(162) : error C2535: '__thiscall mtr<T2>::mtr<T2>(const class mtr<T2> &)' : member function already defined or declared
195 ..\include\tmatrix.h(143) : see declaration of 'mtr<T>::mtr<T>'
196 ..\include\tmatrix.h(692) : see reference to class template instantiation 'mtr<T>' being compiled
197 template <class T2> mtr(const mtr<T2>& matr)
198 {
199 m_height=matr.m_height;
200 m_width =matr.m_width;
201 m_size =matr.m_size;
202 m_stride=m_width;
203 m_border=matr.m_border;
204 m_container =new T[m_size+2*m_border*m_stride];
205 m_data=m_container+m_border*m_stride;
206
207 for(int y=0;y<m_height;y++){
208 for(int x=0;x<m_width;x++){
209 T val=matr.getval(y,x);
210 setval(y,x,val);
211 }
212 }
213 };
214*/
215 // constructoк of matrix over existing data
216 void assign(T* Data,int nHeight,int nWidth,int nStride=0){
217 m_height=nHeight;
218 m_width=nWidth;
219 if (nStride==0)
220 m_stride=m_width;
221 else
222 m_stride=nStride;
223 m_size =m_height*m_width;
224 m_data=Data;
225 m_container=0;
226 m_border=0;
227 }
228 explicit mtr(T* Data,int nHeight,int nWidth,int nStride=0)
229 {
230 assign(Data,nHeight,nWidth,nStride);
231 };
232
233 // destructor
234 ~mtr()
235 {
236 if (m_container)
237 delete m_container;
238 }
239
240 // assignment
241
242 mtr<T>& operator= (mtr<T>& matr)
243 {
244 ASSERTE(matr.m_height==m_height);
245 ASSERTE(matr.m_width ==m_width);
246 T* pSrcData=matr.m_data;
247 T* pDstData=m_data;
248 for(int y=0;y<m_height;y++,pSrcData+=matr.m_stride, pDstData+=m_stride)
249 for(int x=0; x<m_width; x++)
250 pDstData[x]=pSrcData[x];
251 return *this;
252 }
253
254 // filling of matrix with constant value
255 mtr<T>& operator= (T& val)
256 {
257 for(int y=0;y<m_height;y++)
258 getvec(y)=val;
259 return *this;
260 }
261
262//#ifdef _DEBUG
263// inline vec<T> operator[](int row)
264// {
265// ASSERTE(row<m_height+m_border);
266// ASSERTE(row>=-m_border);
267// return vec<T>(m_data+row*m_stride,m_width,m_border);
268// }
269 // return pointer to first element in row
270 inline T* operator[](int row) const
271 {
272 ASSERTE(row<m_height+m_border);
273 ASSERTE(row>=-m_border);
274 return m_data+row*m_stride;
275 }
276
277 // getting value by linear index
278 inline T& index(int idx)
279 {
280 ASSERTE(idx>=0);
281 ASSERTE(idx<m_size);
282 ASSERTE(m_width==m_stride);
283 return(m_data[idx]);
284 }
285
286//#else
287// inline T* operator[](int row)
288// {
289// return (m_data+row*m_stride);
290// }
291//#endif
292
293 // inplace multiplication by constant value
294 mtr<T>& operator*= (const T val)
295 {
296 for(int y=0;y<m_height;y++)
297 getvec(y)*=val;
298 return *this;
299 }
300
301 // multiplication by constant value
302 mtr<T> operator* (const T& val) const
303 {
304 mtr<T> res(*this);
305 return res*=val;
306 }
307
308 // multiplication by vector
309 vec<T> operator* (const vec<T>& vect)
310 {
311 ASSERTE(m_width==vect.m_size);
312 vec<T> res(m_height);
313 for(int y=0;y<m_height;y++)
314 res[y]=getvec(y)*vect;
315 return vec<T>(res);
316 }
317
318// mtr<T> operator* (const mtr<T>& matr)
319// {
320// ASSERTE(m_width==matr.m_height);
321// mtr<T> res(m_height,matr.m_width);
322// for(int row=0;row<res.m_height;row++)
323// for(int col=0;col<res.m_width;col++)
324// {
325// T sum(0);
326// for(int i=0;i<m_width;i++)
327// sum+=m_data[m_width*row+i]*matr.m_data[matr.m_width*i+col];
328// res.m_data[row*res.m_width+col]=sum;
329// }
330// return res;
331// }
332
333 // multiplication by matrix
334 mtr<T> operator* (const mtr<T>& matr)
335 {
336 ASSERTE(m_width==matr.m_height);
337 mtr<T> res(m_height, matr.m_width);
338 res.reset();
339 for(int y=0;y<m_height;y++)
340 {
341 vec<T>& thisvec=getvec(y);
342 vec<T>& resvec=res.getvec(y);
343 for(int x=0;x<m_width;x++)
344 resvec+=matr.getvec(x)*thisvec[x];
345 }
346 return res;
347 }
348
349 // inplace adding of value to all elements of matrix
350 mtr<T>& operator+= (const T &val)
351 {
352 for(int y=0;y<m_height;y++)
353 getvec(y)+=val;
354 return (*this);
355 }
356
357 // inplace summation of matrixes
358 mtr<T>& operator+= (const mtr<T> &matr)
359 {
360 ASSERTE (matr.m_size==m_size);
361 for(int y=0;y<m_height;y++)
362 getvec(y)+=matr.getvec(y);
363 return (*this);
364 }
365
366 // summation of matrices
367 mtr<T> operator+ (const mtr<T>& matr) const
368 {
369 ASSERTE (matr.m_size==m_size);
370 mtr<T> res(*this);
371 res+=matr;
372 return res;
373 }
374
375 //inplace substraction of matrix
376 mtr<T>& operator-= (const mtr<T> &matr)
377 {
378 ASSERTE (matr.m_size==m_size);
379 for(int y=0;y<m_height;y++)
380 getvec(y)-=matr.getvec(y);
381 return (*this);
382 }
383
384 // inplace subtraction of value from all elements of matix
385 mtr<T>& operator-= (const T &val)
386 {
387 for(int y=0;y<m_height;y++)
388 getvec(y)-=val;
389 return (*this);
390 }
391
392 // subtraction of matrixes
393 mtr<T> operator- (const mtr<T>& matr) const
394 {
395 ASSERTE (matr.m_size==m_size);
396 mtr <T> res(*this);
397 res-=matr;
398 return res;
399 }
400
401 // sign inversion
402 mtr<T> operator- () const
403 {
404 mtr<T> res(m_height,m_width);
405 for(int y=0;y<m_height;y++)
406 res.getvec(y)=-getvec(y);
407 return res;
408 }
409
410 // inplace division
411 mtr<T>& operator/=(const T val)
412 {
413 ASSERTE(val!=0);
414 for(int y=0;y<m_height;y++)
415 getvec(y)/=val;
416 return (*this);
417 }
418
419 // division
420 mtr<T> operator/ (const T val) const
421 {
422 mtr<T> res(*this);
423 res/=val;
424 return res;
425 }
426
427 // inplace shift
428 mtr<T>& operator>>=(const int shr)
429 {
430 ASSERTE(shr>=0);
431 for(int y=0;y<m_height;y++)
432 getvec(y)>>=shr;
433 return (*this);
434 }
435
436 // shift
437 mtr<T> operator>> (const int shr) const
438 {
439 ASSERTE(shr>=0);
440 mtr<T> res(*this);
441 res>>=shr;
442 return res;
443 }
444
445 // inplace left shift
446 mtr<T>& operator<<=(const int shl)
447 {
448 ASSERTE(shl>=0);
449 for(int y=0; y<m_height; y++)
450 getvec(y)<<=shl;
451 return (*this);
452 }
453
454 // left shift
455 mtr<T> operator<< (const int shl) const
456 {
457 ASSERTE(shl>=0);
458 mtr<T> res(*this);
459 res<<=shl;
460 return res;
461 }
462
463 // inplace AND with value
464 mtr<T>& operator&= (const T &val)
465 {
466 for(int y=0;y<m_height;y++)
467 getvec(y)&=val;
468 return (*this);
469 }
470
471
472 // inplace AND with matrix
473 mtr<T>& operator&= (const mtr<T> &matr)
474 {
475 ASSERTE (matr.m_size==m_size);
476 for(int y=0;y<m_height;y++)
477 getvec(y)&=matr.getvec(y);
478 return (*this);
479 }
480
481 // AND
482 mtr<T> operator& (const mtr<T>& matr) const
483 {
484 ASSERTE (matr.m_size==m_size);
485 mtr <T> res(*this);
486 res&=matr;
487 return res;
488 }
489
490 // inplace OR
491 mtr<T>& operator|= (const mtr<T> &matr)
492 {
493 ASSERTE (matr.m_size==m_size);
494 for(int y=0;y<m_height;y++)
495 getvec(y)|=matr.getvec(y);
496 return (*this);
497 }
498
499 // OR
500 mtr<T> operator| (const mtr<T>& matr) const
501 {
502 ASSERTE (matr.m_size==m_size);
503 mtr <T> res(*this);
504 res|=matr;
505 return res;
506 }
507
508 // inplace XOR
509 mtr<T>& operator^= (const mtr<T> &matr)
510 {
511 ASSERTE (matr.m_size==m_size);
512 for(int y=0;y<m_height;y++)
513 getvec(y)^=matr.getvec(y);
514 return (*this);
515 }
516
517 // inplace XOR with constant value
518 mtr<T>& operator^= (const T &val)
519 {
520 for(int y=0;y<m_height;y++)
521 getvec(y)^=val;
522 return (*this);
523 }
524
525 // XOR
526 mtr<T> operator^ (const mtr<T>& matr) const
527 {
528 ASSERTE (matr.m_size==m_size);
529 mtr <T> res(*this);
530 res^=matr;
531 return res;
532 }
533
534 // XOR
535 mtr<T> operator^ (const T& val) const
536 {
537 mtr <T> res(*this);
538 res^=val;
539 return res;
540 }
541
542 // NOT
543 mtr<T> operator ~ ()
544 {
545 mtr <T> res(*this);
546 T* r=res.m_data;
547 T* s=m_data;
548 for(int y=0;y<m_height;y++, r+=res.m_stride, s+=m_stride)
549 for(int x=0; x<m_width;x++)
550 r[x]=~s[x];
551
552 return res;
553 }
554
555
556
557 void set (const T val)
558 {
559 T* p=m_container;
560 for(int y=0; y<m_height; y++,p+=m_stride){
561 for(int x=0; x<m_width; x++){
562 p[x]=val;
563 }
564 }
565 }
566
567
568 /*
569 void SetBorder(const T val, int nBorderWidth)
570 {
571 T* p=m_container;
572 for(int y=0; y<m_border+nBorderWidth; y++,p+=m_stride){
573 for(int x=0; x<m_width; x++){
574 p[x]=val;
575 }
576 }
577
578 p=addr(nHeight-1-nBorderWidth,0);
579 for(int y=0; y<m_border+nBorderWidth; y++,p+=m_stride){
580 for(int x=0; x<m_width; x++){
581 p[x]=val;
582 }
583 }
584 }*/
585// void set(const T val, const T border)
586// {
587// T* p0;
588// T* p1;
589// for(p0=m_container,p1=m_data+m_size;p0<m_data;p0++,p1++)
590// {
591// *p0=border;
592// *p1=border;
593// }
594// for(int i=0;i<m_size;i++)
595// m_data[i]=val;
596// }
597 /*
598
599 template<class T> void SetData(T* Data)
600 {
601 for(int i=0;i<m_size;i++)
602 m_data[i]=Data[i];
603 }
604
605 template<class T> void GetData(T* Data)
606 {
607 for(int i=0;i<m_size;i++)
608 Data[i]=(T)m_data[i].value;
609 }
610
611 mtr<T>& operator*= (const mtr<T>& matr)
612 {
613 ASSERTE(m_width==m_height);
614 ASSERTE(m_width==matr.m_width);
615 ASSERTE(m_height==matr.m_height);
616 vec<T> res(m_height);
617 for(int row=0;row<m_height;row++)
618 res[row]=(*this)[row]*vec;
619 return res;
620 }
621
622
623 void InitConst(T &Value)
624 {
625 int m_size=m_height*m_width;
626 for(int i=0;i<m_size;i++)
627 m_data[i]=Value;
628 }
629*/
630// void InitConst(T &Value)
631// {
632// int m_size=m_height*m_width;
633// for(int i=0;i<m_size;i++)
634// m_data[i]=Value;
635// }
636
637//THIS FUNCTIONS WAS INSERTED FROM OLD VERSION OF THIS FILE!!!!!!!!!!!!!!!!!!!!!!!!!!
638 mtr<T> transpose()
639 {
640 mtr<T> Z(m_width,m_height);
641 for(int row=0;row<m_height;row++)
642 for(int col=0;col<m_width;col++)
643 Z[col][row]=(*this)[row][col];
644 return Z;
645 }
646
647 mtr<T>& diag(T val)
648 {
649 reset();
650 int size=(m_height<m_width)?(m_height):(m_width);
651 for(int i=0; i<size; i++)
652 (*this)[i][i]=val;
653 return (*this);
654 }
655
656
657
658
659
660// template<class T> void SetMatrix(mtr<T> &matr)
661// {
662// int m_size=m_height*m_width;
663// for(int i=0;i<m_size;i++)
664// m_data[i]=matr.m_data[i];
665// }
666
667 inline T* addr(int y,int x)
668 {
669 ASSERTE(y<m_height+m_border);
670 ASSERTE(y>=-m_border);
671 ASSERTE(x<m_width+m_border);
672 ASSERTE(x>=-m_border);
673 T* address=m_data+m_stride*y+x;
674 return address;
675 }
676
677 void reset()
678 {
679// ASSERTE(m_container);
680 if (m_container){
681 memset(m_container,0,(m_size+2*m_border*m_width)*sizeof(T));
682 }else{
683 memset(m_data,0,m_size*sizeof(T));
684 }
685 }
686
687 int sum()
688 {
689 int summ=0;
690 for(int y=0;y<m_height;y++)
691 {
692
693 summ+=getvec(y).sum();
694 }
695 return summ;
696 }
697
698
699 vec<T> getvec(int y) const
700 {
701 ASSERTE(y>=0 && y<m_height);
702 return vec<T>(m_data+y*m_stride,m_width,m_border);
703 }
704
705 vec<T> getcol(int x) const
706 {
707 ASSERTE(x>=0 && x<m_width);
708 vec<T> vect(m_height);
709 for(int i=0; i<m_height; i++)
710 vect[i]=(*this)[i][x];
711 return vect;
712
713
714 }
715/*
716 T min()
717 {
718 T m=m_data[0];
719 T* row=m_data;
720 for(int y=0; y<m_height; y++, row+=m_stride)
721 for(int x=0; x<m_width; x++)
722 if (row[x]<m)
723 m=row[x];
724 return m;
725 }
726
727 T max()
728 {
729 T m=m_data[0];
730 T* row=m_data;
731 for(int y=0; y<m_height; y++, row+=m_stride)
732 for(int x=0; x<m_width; x++)
733 if (row[x]>m)
734 m=row[x];
735 return m;
736 }
737*/
738 T minpos(int &ypos, int &xpos){
739 ypos=0;
740 xpos=0;
741 T m=m_data[0];
742 T* row=m_data;
743 for(int y=0; y<m_height; y++, row+=m_stride)
744 for(int x=0; x<m_width; x++)
745 if (row[x]<m){
746 m=row[x];
747 ypos=y;
748 xpos=x;
749 }
750 return m;
751 }
752
753 T maxpos(int &ypos, int &xpos){
754 ypos=0;
755 xpos=0;
756 T m=m_data[0];
757 T* row=m_data;
758 for(int y=0; y<m_height; y++, row+=m_stride)
759 for(int x=0; x<m_width; x++)
760 if (row[x]>m){
761 m=row[x];
762 ypos=y;
763 xpos=x;
764 }
765 return m;
766 }
767
768 void CopyTo(T* pData){
769 T* row=m_data;
770 for(int y=0; y<m_height; y++, row+=m_stride, pData+=m_width){
771 memcpy(pData, row, sizeof(T)*m_width);
772 }
773 }
774
775 void CopyFrom(T* pData){
776 T* row=m_data;
777 for(int y=0; y<m_height; y++, row+=m_stride, pData+=m_width){
778 memcpy(row, pData, sizeof(T)*m_width);
779 }
780 }
781
782 template <class T2> void ConvertTo(T2* pData){
783 T* row=m_data;
784 for(int y=0; y<m_height; y++, row+=m_stride, pData+=m_width){
785 for(int x=0; x<m_width; x++){
786 pData[x]=row[x];
787 }
788 }
789 }
790
791 template <class T2> void ConvertFrom(T2* pData){
792 T* row=m_data;
793 for(int y=0; y<m_height; y++, row+=m_stride, pData+=m_width){
794 for(int x=0; x<m_width; x++){
795 row[x]=pData[x];
796 }
797 }
798 }
799
800
801 /*
802 inline T max()
803 {
804 T Max=m_data[0];
805 T* row=m_data;
806 for(int y=0; y<m_height; y++, row+=m_stride)
807 for(int x=0; x<m_width; x++)
808 if (row[x]<min)
809 Max=row[x];
810 return Max;
811 }
812*/
813//THIS FUNCTIONS WAS INSERTED FROM OLD VERSION OF THIS FILE!!!!!!!!!!!!!!!!!!!!!!!!!!
814
815};
816
817
818/*
819template <class T1, class T2> convert(mtr<T1>& pSrcMtr1,mtr<T2>& pSrcMtr2)
820{
821 for(int i=0;i<pSrcMtr1.m_size;i++)
822 pSrcMtr2.m_data[i]=pSrcMtr1.m_data[i];
823}
824*/
825
826template<class T> mtr<T> DirectProduct(vec<T>& vSrc1,vec<T>& vSrc2)
827{
828 mtr<T> res(vSrc1.m_size, vSrc2.m_size);
829 for(int y=0; y<res.m_height; y++){
830 res.getvec(y)=vSrc2*vSrc1[y];
831 }
832 return res;
833
834}
835
836
837#ifndef __NM__
838
839 template<class T1, class T2> void DotMul(mtr<T1>& mSrcMtr1, mtr<T2>& mSrcMtr2, mtr<T2>& mDstMtr )
840 {
841 for(int y=0; y< mSrcMtr1.m_height; y++)
842 for(int x=0; x<mSrcMtr1.m_width; x++)
843 {
844 T2 res=mSrcMtr1[y][x]*mSrcMtr2[y][x];
845 mDstMtr[y][x]=res;
846 }
847 }
848
849 template<class T1, class T2> void GetSum(mtr<T1>& mSrcMtr1, T2& nResSum)
850 {
851 nResSum=0;
852 for(int y=0; y< mSrcMtr1.m_height; y++)
853 for(int x=0; x<mSrcMtr1.m_width; x++)
854 nResSum+=T2 (mSrcMtr1[y][x]);
855 }
856 template<class T1, class T2> void Convert(mtr<T1>& mSrcMtr, mtr<T2>& mDstMtr){
857 ASSERTE(mSrcMtr.m_height==mDstMtr.m_height);
858 ASSERTE(mSrcMtr.m_width ==mDstMtr.m_width);
859 for(int y=0; y<mSrcMtr.m_height; y++){
860 for(int x=0; x<mSrcMtr.m_width; x++){
861 mDstMtr[y][x]=(T2)mSrcMtr[y][x];
862 }
863 }
864 }
865#endif
866#endif
Definition: tmatrix.h:88
Definition: tvector.h:80