1 /*M///////////////////////////////////////////////////////////////////////////////////////
3 // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
5 // By downloading, copying, installing or using the software you agree to this license.
6 // If you do not agree to this license, do not download, install,
7 // copy or use the software.
11 // For Open Source Computer Vision Library
13 // Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
14 // Copyright (C) 2009, Willow Garage Inc., all rights reserved.
15 // Third party copyrights are property of their respective owners.
17 // Redistribution and use in source and binary forms, with or without modification,
18 // are permitted provided that the following conditions are met:
20 // * Redistribution's of source code must retain the above copyright notice,
21 // this list of conditions and the following disclaimer.
23 // * Redistribution's in binary form must reproduce the above copyright notice,
24 // this list of conditions and the following disclaimer in the documentation
25 // and/or other materials provided with the distribution.
27 // * The name of the copyright holders may not be used to endorse or promote products
28 // derived from this software without specific prior written permission.
30 // This software is provided by the copyright holders and contributors "as is" and
31 // any express or implied warranties, including, but not limited to, the implied
32 // warranties of merchantability and fitness for a particular purpose are disclaimed.
33 // In no event shall the Intel Corporation or contributors be liable for any direct,
34 // indirect, incidental, special, exemplary, or consequential damages
35 // (including, but not limited to, procurement of substitute goods or services;
36 // loss of use, data, or profits; or business interruption) however caused
37 // and on any theory of liability, whether in contract, strict liability,
38 // or tort (including negligence or otherwise) arising in any way out of
39 // the use of this software, even if advised of the possibility of such damage.
43 #ifndef _OPENCV_CORE_MAT_OPERATIONS_H_
44 #define _OPENCV_CORE_MAT_OPERATIONS_H_
48 #endif // SKIP_INCLUDES
55 //////////////////////////////// Mat ////////////////////////////////
58 : flags(0), rows(0), cols(0), step(0), data(0), refcount(0), datastart(0), dataend(0) {}
60 inline Mat::Mat(int _rows, int _cols, int _type)
61 : flags(0), rows(0), cols(0), step(0), data(0), refcount(0), datastart(0), dataend(0)
63 if( _rows > 0 && _cols > 0 )
64 create( _rows, _cols, _type );
67 inline Mat::Mat(int _rows, int _cols, int _type, const Scalar& _s)
68 : flags(0), rows(0), cols(0), step(0), data(0), refcount(0),
69 datastart(0), dataend(0)
71 if(_rows > 0 && _cols > 0)
73 create(_rows, _cols, _type);
78 inline Mat::Mat(Size _size, int _type)
79 : flags(0), rows(0), cols(0), step(0), data(0), refcount(0),
80 datastart(0), dataend(0)
82 if( _size.height > 0 && _size.width > 0 )
83 create( _size.height, _size.width, _type );
86 inline Mat::Mat(Size _size, int _type, const Scalar& _s)
87 : flags(0), rows(0), cols(0), step(0), data(0), refcount(0),
88 datastart(0), dataend(0)
90 if( _size.height > 0 && _size.width > 0 )
92 create( _size.height, _size.width, _type );
97 inline Mat::Mat(const Mat& m)
98 : flags(m.flags), rows(m.rows), cols(m.cols), step(m.step), data(m.data),
99 refcount(m.refcount), datastart(m.datastart), dataend(m.dataend)
102 CV_XADD(refcount, 1);
105 inline Mat::Mat(int _rows, int _cols, int _type, void* _data, size_t _step)
106 : flags(MAGIC_VAL + (_type & TYPE_MASK)), rows(_rows), cols(_cols),
107 step(_step), data((uchar*)_data), refcount(0),
108 datastart((uchar*)_data), dataend((uchar*)_data)
110 size_t minstep = cols*elemSize();
111 if( step == AUTO_STEP )
114 flags |= CONTINUOUS_FLAG;
118 if( rows == 1 ) step = minstep;
119 CV_DbgAssert( step >= minstep );
120 flags |= step == minstep ? CONTINUOUS_FLAG : 0;
122 dataend += step*(rows-1) + minstep;
125 inline Mat::Mat(Size _size, int _type, void* _data, size_t _step)
126 : flags(MAGIC_VAL + (_type & TYPE_MASK)), rows(_size.height), cols(_size.width),
127 step(_step), data((uchar*)_data), refcount(0),
128 datastart((uchar*)_data), dataend((uchar*)_data)
130 size_t minstep = cols*elemSize();
131 if( step == AUTO_STEP )
134 flags |= CONTINUOUS_FLAG;
138 if( rows == 1 ) step = minstep;
139 CV_DbgAssert( step >= minstep );
140 flags |= step == minstep ? CONTINUOUS_FLAG : 0;
142 dataend += step*(rows-1) + minstep;
145 inline Mat::Mat(const Mat& m, const Range& rowRange, const Range& colRange)
148 step = m.step; refcount = m.refcount;
149 data = m.data; datastart = m.datastart; dataend = m.dataend;
151 if( rowRange == Range::all() )
155 CV_Assert( 0 <= rowRange.start && rowRange.start <= rowRange.end && rowRange.end <= m.rows );
156 rows = rowRange.size();
157 data += step*rowRange.start;
160 if( colRange == Range::all() )
164 CV_Assert( 0 <= colRange.start && colRange.start <= colRange.end && colRange.end <= m.cols );
165 cols = colRange.size();
166 data += colRange.start*elemSize();
167 flags &= cols < m.cols ? ~CONTINUOUS_FLAG : -1;
171 flags |= CONTINUOUS_FLAG;
174 CV_XADD(refcount, 1);
175 if( rows <= 0 || cols <= 0 )
179 inline Mat::Mat(const Mat& m, const Rect& roi)
180 : flags(m.flags), rows(roi.height), cols(roi.width),
181 step(m.step), data(m.data + roi.y*step), refcount(m.refcount),
182 datastart(m.datastart), dataend(m.dataend)
184 flags &= roi.width < m.cols ? ~CONTINUOUS_FLAG : -1;
185 data += roi.x*elemSize();
186 CV_Assert( 0 <= roi.x && 0 <= roi.width && roi.x + roi.width <= m.cols &&
187 0 <= roi.y && 0 <= roi.height && roi.y + roi.height <= m.rows );
189 CV_XADD(refcount, 1);
190 if( rows <= 0 || cols <= 0 )
194 inline Mat::Mat(const CvMat* m, bool copyData)
195 : flags(MAGIC_VAL + (m->type & (CV_MAT_TYPE_MASK|CV_MAT_CONT_FLAG))),
196 rows(m->rows), cols(m->cols), step(m->step), data(m->data.ptr), refcount(0),
197 datastart(m->data.ptr), dataend(m->data.ptr)
200 step = cols*elemSize();
201 size_t minstep = cols*elemSize();
202 dataend += step*(rows-1) + minstep;
205 data = datastart = dataend = 0;
206 Mat(m->rows, m->cols, m->type, m->data.ptr, m->step).copyTo(*this);
210 template<typename _Tp> inline Mat::Mat(const vector<_Tp>& vec, bool copyData)
211 : flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG),
212 rows(0), cols(0), step(0), data(0), refcount(0),
213 datastart(0), dataend(0)
219 rows = (int)vec.size();
222 data = datastart = (uchar*)&vec[0];
223 dataend = datastart + rows*step;
226 Mat((int)vec.size(), 1, DataType<_Tp>::type, (uchar*)&vec[0]).copyTo(*this);
234 inline Mat& Mat::operator = (const Mat& m)
239 CV_XADD(m.refcount, 1);
242 rows = m.rows; cols = m.cols;
243 step = m.step; data = m.data;
244 datastart = m.datastart; dataend = m.dataend;
245 refcount = m.refcount;
250 inline Mat Mat::row(int y) const { return Mat(*this, Range(y, y+1), Range::all()); }
251 inline Mat Mat::col(int x) const { return Mat(*this, Range::all(), Range(x, x+1)); }
252 inline Mat Mat::rowRange(int startrow, int endrow) const
253 { return Mat(*this, Range(startrow, endrow), Range::all()); }
254 inline Mat Mat::rowRange(const Range& r) const
255 { return Mat(*this, r, Range::all()); }
256 inline Mat Mat::colRange(int startcol, int endcol) const
257 { return Mat(*this, Range::all(), Range(startcol, endcol)); }
258 inline Mat Mat::colRange(const Range& r) const
259 { return Mat(*this, Range::all(), r); }
261 inline Mat Mat::diag(int d) const
264 size_t esz = elemSize();
269 len = std::min(cols - d, rows);
274 len = std::min(rows + d, cols);
277 CV_DbgAssert( len > 0 );
282 m.flags &= ~CONTINUOUS_FLAG;
284 m.flags |= CONTINUOUS_FLAG;
288 inline Mat Mat::diag(const Mat& d)
290 Mat m(d.rows, d.rows, d.type(), Scalar(0)), md = m.diag();
295 inline Mat Mat::clone() const
302 inline void Mat::assignTo( Mat& m, int type ) const
310 inline void Mat::create(int _rows, int _cols, int _type)
313 if( rows == _rows && cols == _cols && type() == _type && data )
317 CV_DbgAssert( _rows >= 0 && _cols >= 0 );
318 if( _rows > 0 && _cols > 0 )
320 flags = MAGIC_VAL + CONTINUOUS_FLAG + _type;
323 step = elemSize()*cols;
324 int64 _nettosize = (int64)step*rows;
325 size_t nettosize = (size_t)_nettosize;
326 if( _nettosize != (int64)nettosize )
327 CV_Error(CV_StsNoMem, "Too big buffer is allocated");
328 size_t datasize = alignSize(nettosize, (int)sizeof(*refcount));
329 datastart = data = (uchar*)fastMalloc(datasize + sizeof(*refcount));
330 dataend = data + nettosize;
331 refcount = (int*)(data + datasize);
336 inline void Mat::create(Size _size, int _type)
338 create(_size.height, _size.width, _type);
341 inline void Mat::addref()
342 { if( refcount ) CV_XADD(refcount, 1); }
344 inline void Mat::release()
346 if( refcount && CV_XADD(refcount, -1) == 1 )
348 data = datastart = dataend = 0;
349 step = rows = cols = 0;
353 inline void Mat::locateROI( Size& wholeSize, Point& ofs ) const
355 size_t esz = elemSize(), minstep;
356 ptrdiff_t delta1 = data - datastart, delta2 = dataend - datastart;
357 CV_DbgAssert( step > 0 );
362 ofs.y = (int)(delta1/step);
363 ofs.x = (int)((delta1 - step*ofs.y)/esz);
364 CV_DbgAssert( data == datastart + ofs.y*step + ofs.x*esz );
366 minstep = (ofs.x + cols)*esz;
367 wholeSize.height = (int)((delta2 - minstep)/step + 1);
368 wholeSize.height = std::max(wholeSize.height, ofs.y + rows);
369 wholeSize.width = (int)((delta2 - step*(wholeSize.height-1))/esz);
370 wholeSize.width = std::max(wholeSize.width, ofs.x + cols);
373 inline Mat& Mat::adjustROI( int dtop, int dbottom, int dleft, int dright )
375 Size wholeSize; Point ofs;
376 size_t esz = elemSize();
377 locateROI( wholeSize, ofs );
378 int row1 = std::max(ofs.y - dtop, 0), row2 = std::min(ofs.y + rows + dbottom, wholeSize.height);
379 int col1 = std::max(ofs.x - dleft, 0), col2 = std::min(ofs.x + cols + dright, wholeSize.width);
380 data += (row1 - ofs.y)*step + (col1 - ofs.x)*esz;
381 rows = row2 - row1; cols = col2 - col1;
382 if( esz*cols == step || rows == 1 )
383 flags |= CONTINUOUS_FLAG;
385 flags &= ~CONTINUOUS_FLAG;
389 inline Mat Mat::operator()( Range rowRange, Range colRange ) const
391 return Mat(*this, rowRange, colRange);
394 inline Mat Mat::operator()( const Rect& roi ) const
395 { return Mat(*this, roi); }
397 inline Mat::operator CvMat() const
399 CvMat m = cvMat(rows, cols, type(), data);
401 m.type = (m.type & ~CONTINUOUS_FLAG) | (flags & CONTINUOUS_FLAG);
405 inline Mat::operator IplImage() const
408 cvInitImageHeader(&img, size(), cvIplDepth(flags), channels());
409 cvSetData(&img, data, (int)step);
413 inline bool Mat::isContinuous() const { return (flags & CONTINUOUS_FLAG) != 0; }
414 inline size_t Mat::elemSize() const { return CV_ELEM_SIZE(flags); }
415 inline size_t Mat::elemSize1() const { return CV_ELEM_SIZE1(flags); }
416 inline int Mat::type() const { return CV_MAT_TYPE(flags); }
417 inline int Mat::depth() const { return CV_MAT_DEPTH(flags); }
418 inline int Mat::channels() const { return CV_MAT_CN(flags); }
419 inline size_t Mat::step1() const { return step/elemSize1(); }
420 inline Size Mat::size() const { return Size(cols, rows); }
421 inline bool Mat::empty() const { return data == 0; }
423 inline uchar* Mat::ptr(int y)
425 CV_DbgAssert( (unsigned)y < (unsigned)rows );
426 return data + step*y;
429 inline const uchar* Mat::ptr(int y) const
431 CV_DbgAssert( (unsigned)y < (unsigned)rows );
432 return data + step*y;
435 template<typename _Tp> inline _Tp* Mat::ptr(int y)
437 CV_DbgAssert( (unsigned)y < (unsigned)rows );
438 return (_Tp*)(data + step*y);
441 template<typename _Tp> inline const _Tp* Mat::ptr(int y) const
443 CV_DbgAssert( (unsigned)y < (unsigned)rows );
444 return (const _Tp*)(data + step*y);
447 template<typename _Tp> inline _Tp& Mat::at(int y, int x)
449 CV_DbgAssert( (unsigned)y < (unsigned)rows && (unsigned)x < (unsigned)cols &&
450 sizeof(_Tp) == elemSize() );
451 return ((_Tp*)(data + step*y))[x];
454 template<typename _Tp> inline const _Tp& Mat::at(int y, int x) const
456 CV_DbgAssert( (unsigned)y < (unsigned)rows && (unsigned)x < (unsigned)cols &&
457 sizeof(_Tp) == elemSize() );
458 return ((const _Tp*)(data + step*y))[x];
461 template<typename _Tp> inline _Tp& Mat::at(Point pt)
463 CV_DbgAssert( (unsigned)pt.y < (unsigned)rows && (unsigned)pt.x < (unsigned)cols &&
464 sizeof(_Tp) == elemSize() );
465 return ((_Tp*)(data + step*pt.y))[pt.x];
468 template<typename _Tp> inline const _Tp& Mat::at(Point pt) const
470 CV_DbgAssert( (unsigned)pt.y < (unsigned)rows && (unsigned)pt.x < (unsigned)cols &&
471 sizeof(_Tp) == elemSize() );
472 return ((const _Tp*)(data + step*pt.y))[pt.x];
475 template<typename _Tp> inline MatConstIterator_<_Tp> Mat::begin() const
477 CV_DbgAssert( elemSize() == sizeof(_Tp) );
478 return MatConstIterator_<_Tp>((const Mat_<_Tp>*)this);
481 template<typename _Tp> inline MatConstIterator_<_Tp> Mat::end() const
483 CV_DbgAssert( elemSize() == sizeof(_Tp) );
484 MatConstIterator_<_Tp> it((const Mat_<_Tp>*)this);
485 it.ptr = it.sliceEnd = (_Tp*)(data + step*(rows-1)) + cols;
489 template<typename _Tp> inline MatIterator_<_Tp> Mat::begin()
491 CV_DbgAssert( elemSize() == sizeof(_Tp) );
492 return MatIterator_<_Tp>((Mat_<_Tp>*)this);
495 template<typename _Tp> inline MatIterator_<_Tp> Mat::end()
497 CV_DbgAssert( elemSize() == sizeof(_Tp) );
498 MatIterator_<_Tp> it((Mat_<_Tp>*)this);
499 it.ptr = it.sliceEnd = (_Tp*)(data + step*(rows-1)) + cols;
504 static inline void swap( Mat& a, Mat& b )
506 std::swap( a.flags, b.flags );
507 std::swap( a.rows, b.rows ); std::swap( a.cols, b.cols );
508 std::swap( a.step, b.step ); std::swap( a.data, b.data );
509 std::swap( a.datastart, b.datastart );
510 std::swap( a.dataend, b.dataend );
511 std::swap( a.refcount, b.refcount );
515 inline SVD::SVD( const Mat& m, int flags ) { operator ()(m, flags); }
516 inline void SVD::solveZ( const Mat& m, Mat& dst )
519 svd.vt.row(svd.vt.rows-1).reshape(1,svd.vt.cols).copyTo(dst);
522 ///////////////////////////////// Mat_<_Tp> ////////////////////////////////////
524 template<typename _Tp> inline Mat_<_Tp>::Mat_() :
525 Mat() { flags = (flags & ~CV_MAT_TYPE_MASK) | DataType<_Tp>::type; }
527 template<typename _Tp> inline Mat_<_Tp>::Mat_(int _rows, int _cols) :
528 Mat(_rows, _cols, DataType<_Tp>::type) {}
530 template<typename _Tp> inline Mat_<_Tp>::Mat_(int _rows, int _cols, const _Tp& value) :
531 Mat(_rows, _cols, DataType<_Tp>::type) { *this = value; }
533 template<typename _Tp> inline Mat_<_Tp>::Mat_(Size _size) :
534 Mat(_size.height, _size.width, DataType<_Tp>::type) {}
536 template<typename _Tp> inline Mat_<_Tp>::Mat_(Size _size, const _Tp& value) :
537 Mat(_size.height, _size.width, DataType<_Tp>::type) { *this = value; }
539 template<typename _Tp> inline Mat_<_Tp>::Mat_(const Mat& m) : Mat()
540 { flags = (flags & ~CV_MAT_TYPE_MASK) | DataType<_Tp>::type; *this = m; }
542 template<typename _Tp> inline Mat_<_Tp>::Mat_(const Mat_& m) : Mat(m) {}
544 template<typename _Tp> inline Mat_<_Tp>::Mat_(int _rows, int _cols, _Tp* _data, size_t _step)
545 : Mat(_rows, _cols, DataType<_Tp>::type, _data, _step) {}
547 template<typename _Tp> inline Mat_<_Tp>::Mat_(const Mat_& m, const Range& rowRange, const Range& colRange)
548 : Mat(m, rowRange, colRange) {}
550 template<typename _Tp> inline Mat_<_Tp>::Mat_(const Mat_& m, const Rect& roi)
553 template<typename _Tp> template<int n> inline Mat_<_Tp>::Mat_(const Vec<_Tp, n>& vec)
554 : Mat(n, 1, DataType<_Tp>::type)
557 for( int i = 0; i < n; i++ )
561 template<typename _Tp> inline Mat_<_Tp>::Mat_(const vector<_Tp>& vec, bool copyData)
565 template<typename _Tp> inline Mat_<_Tp>& Mat_<_Tp>::operator = (const Mat& m)
567 if( DataType<_Tp>::type == m.type() )
572 if( DataType<_Tp>::depth == m.depth() )
574 return (*this = m.reshape(DataType<_Tp>::channels));
576 CV_DbgAssert(DataType<_Tp>::channels == m.channels());
577 m.convertTo(*this, type());
581 template<typename _Tp> inline Mat_<_Tp>& Mat_<_Tp>::operator = (const Mat_& m)
587 template<typename _Tp> inline Mat_<_Tp>& Mat_<_Tp>::operator = (const _Tp& s)
589 Mat::operator=(Scalar(s));
593 template<typename _Tp> inline void Mat_<_Tp>::create(int _rows, int _cols)
595 Mat::create(_rows, _cols, DataType<_Tp>::type);
598 template<typename _Tp> inline void Mat_<_Tp>::create(Size _size)
600 Mat::create(_size, DataType<_Tp>::type);
603 template<typename _Tp> inline Mat_<_Tp> Mat_<_Tp>::cross(const Mat_& m) const
604 { return Mat_<_Tp>(Mat::cross(m)); }
606 template<typename _Tp> template<typename T2> inline Mat_<_Tp>::operator Mat_<T2>() const
607 { return Mat_<T2>(*this); }
609 template<typename _Tp> inline Mat_<_Tp> Mat_<_Tp>::row(int y) const
610 { return Mat_(*this, Range(y, y+1), Range::all()); }
611 template<typename _Tp> inline Mat_<_Tp> Mat_<_Tp>::col(int x) const
612 { return Mat_(*this, Range::all(), Range(x, x+1)); }
613 template<typename _Tp> inline Mat_<_Tp> Mat_<_Tp>::diag(int d) const
614 { return Mat_(Mat::diag(d)); }
615 template<typename _Tp> inline Mat_<_Tp> Mat_<_Tp>::clone() const
616 { return Mat_(Mat::clone()); }
618 template<typename _Tp> inline size_t Mat_<_Tp>::elemSize() const
620 CV_DbgAssert( Mat::elemSize() == sizeof(_Tp) );
624 template<typename _Tp> inline size_t Mat_<_Tp>::elemSize1() const
626 CV_DbgAssert( Mat::elemSize1() == sizeof(_Tp)/DataType<_Tp>::channels );
627 return sizeof(_Tp)/DataType<_Tp>::channels;
629 template<typename _Tp> inline int Mat_<_Tp>::type() const
631 CV_DbgAssert( Mat::type() == DataType<_Tp>::type );
632 return DataType<_Tp>::type;
634 template<typename _Tp> inline int Mat_<_Tp>::depth() const
636 CV_DbgAssert( Mat::depth() == DataType<_Tp>::depth );
637 return DataType<_Tp>::depth;
639 template<typename _Tp> inline int Mat_<_Tp>::channels() const
641 CV_DbgAssert( Mat::channels() == DataType<_Tp>::channels );
642 return DataType<_Tp>::channels;
644 template<typename _Tp> inline size_t Mat_<_Tp>::stepT() const { return step/elemSize(); }
645 template<typename _Tp> inline size_t Mat_<_Tp>::step1() const { return step/elemSize1(); }
647 template<typename _Tp> inline Mat_<_Tp> Mat_<_Tp>::reshape(int _rows) const
648 { return Mat_<_Tp>(Mat::reshape(0,_rows)); }
650 template<typename _Tp> inline Mat_<_Tp>& Mat_<_Tp>::adjustROI( int dtop, int dbottom, int dleft, int dright )
651 { return (Mat_<_Tp>&)(Mat::adjustROI(dtop, dbottom, dleft, dright)); }
653 template<typename _Tp> inline Mat_<_Tp> Mat_<_Tp>::operator()( const Range& rowRange, const Range& colRange ) const
654 { return Mat_<_Tp>(*this, rowRange, colRange); }
656 template<typename _Tp> inline Mat_<_Tp> Mat_<_Tp>::operator()( const Rect& roi ) const
657 { return Mat_<_Tp>(roi); }
659 template<typename _Tp> inline _Tp* Mat_<_Tp>::operator [](int y)
660 { return (_Tp*)ptr(y); }
661 template<typename _Tp> inline const _Tp* Mat_<_Tp>::operator [](int y) const
662 { return (const _Tp*)ptr(y); }
664 template<typename _Tp> inline _Tp& Mat_<_Tp>::operator ()(int row, int col)
666 CV_DbgAssert( (unsigned)row < (unsigned)rows && (unsigned)col < (unsigned)cols );
667 return ((_Tp*)(data + step*row))[col];
670 template<typename _Tp> inline const _Tp& Mat_<_Tp>::operator ()(int row, int col) const
672 CV_DbgAssert( (unsigned)row < (unsigned)rows && (unsigned)col < (unsigned)cols );
673 return ((const _Tp*)(data + step*row))[col];
676 template<typename _Tp> inline _Tp& Mat_<_Tp>::operator ()(Point pt)
678 CV_DbgAssert( (unsigned)pt.y < (unsigned)rows && (unsigned)pt.x < (unsigned)cols );
679 return ((_Tp*)(data + step*pt.y))[pt.x];
682 template<typename _Tp> inline const _Tp& Mat_<_Tp>::operator ()(Point pt) const
684 CV_DbgAssert( (unsigned)pt.y < (unsigned)rows && (unsigned)pt.x < (unsigned)cols );
685 return ((const _Tp*)(data + step*pt.y))[pt.x];
688 template<typename _Tp> inline Mat_<_Tp>::operator vector<_Tp>() const
690 CV_Assert( rows == 1 || cols == 1 );
691 return isContinuous() ? vector<_Tp>((size_t)(rows + cols - 1), (_Tp*)data) :
692 (vector<_Tp>)((Mat_<_Tp>)this->t());
695 template<typename T1, typename T2, typename Op> inline void
696 process( const Mat_<T1>& m1, Mat_<T2>& m2, Op op )
698 int y, x, rows = m1.rows, cols = m1.cols;
699 int c1 = m1.channels(), c2 = m2.channels();
701 CV_DbgAssert( m1.size() == m2.size() );
703 for( y = 0; y < rows; y++ )
705 const T1* src = m1[y];
708 for( x = 0; x < cols; x++ )
713 template<typename T1, typename T2, typename T3, typename Op> inline void
714 process( const Mat_<T1>& m1, const Mat_<T2>& m2, Mat_<T3>& m3, Op op )
716 int y, x, rows = m1.rows, cols = m1.cols;
718 CV_DbgAssert( m1.size() == m2.size() );
720 for( y = 0; y < rows; y++ )
722 const T1* src1 = m1[y];
723 const T2* src2 = m2[y];
726 for( x = 0; x < cols; x++ )
727 dst[x] = op( src1[x], src2[x] );
731 template<typename M> class CV_EXPORTS MatExpr_Base_
735 virtual ~MatExpr_Base_() {}
736 virtual void assignTo(M& m, int type=-1) const = 0;
739 template<typename E, typename M> class CV_EXPORTS MatExpr_ : public MatExpr_Base_<M>
742 MatExpr_(const E& _e) : e(_e) {}
744 operator M() const { return (M)e; }
745 void assignTo(M& m, int type=-1) const { e.assignTo(m, type); }
747 M row(int y) const { return ((M)e).row(y); }
748 M col(int x) const { return ((M)e).col(x); }
749 M diag(int d=0) const { return ((M)e).diag(d); }
751 M operator()( const Range& rowRange, const Range& colRange ) const
752 { return ((M)e)(rowRange, colRange); }
753 M operator()( const Rect& roi ) const { return ((M)e)(roi); }
755 M cross(const M& m) const { return ((M)e).cross(m); }
756 double dot(const M& m) const { return ((M)e).dot(m); }
758 MatExpr_<MatExpr_Op2_<M, double, M, MatOp_T_<Mat> >, M> t() const
759 { return ((M)e).t(); }
760 MatExpr_<MatExpr_Op2_<M, int, M, MatOp_Inv_<Mat> >, M> inv(int method=DECOMP_LU) const
761 { return ((M)e).inv(method); }
763 MatExpr_<MatExpr_Op4_<M, M, double, char, M, MatOp_MulDiv_<Mat> >, M>
764 mul(const M& m, double scale=1) const
765 { return ((M)e).mul(m, scale); }
766 template<typename A> MatExpr_<MatExpr_Op4_<M, M, double, char, M, MatOp_MulDiv_<Mat> >, M >
767 mul(const MatExpr_<A, M>& m, double scale=1) const
768 { return ((M)e).mul(m, scale); }
774 inline Mat::Mat(const MatExpr_Base& expr)
775 : flags(0), rows(0), cols(0), step(0), data(0), refcount(0), datastart(0), dataend(0)
777 expr.assignTo(*this);
780 inline Mat& Mat::operator = (const MatExpr_Base& expr)
782 expr.assignTo(*this);
786 template<typename _Tp> inline Mat_<_Tp>::Mat_(const MatExpr_Base& e) : Mat()
788 e.assignTo(*this, DataType<_Tp>::type);
791 template<typename _Tp> inline Mat_<_Tp>& Mat_<_Tp>::operator = (const MatExpr_Base& e)
793 e.assignTo(*this, DataType<_Tp>::type);
797 template<typename _Tp> inline Mat_<_Tp>::operator MatExpr_<Mat_<_Tp>, Mat_<_Tp> >() const
798 { return MatExpr_<Mat_<_Tp>, Mat_<_Tp> >(*this); }
800 inline Mat::operator MatExpr_<Mat, Mat>() const
801 { return MatExpr_<Mat, Mat>(*this); }
803 template<typename M> class CV_EXPORTS MatOp_Sub_
808 static void apply(const M& a, const M& b, M& c, int type=-1)
810 if( type == a.type() || type < 0 )
818 temp.convertTo(c, type);
823 template<typename M> class CV_EXPORTS MatOp_Scale_
828 static void apply(const M& a, double alpha, M& c, int type=-1)
830 a.convertTo(c, type, alpha, 0);
834 template<typename M> class CV_EXPORTS MatOp_ScaleAddS_
837 MatOp_ScaleAddS_() {}
839 static void apply(const M& a, double alpha, double beta, M& c, int type=-1)
841 a.convertTo(c, type, alpha, beta);
845 template<typename M> class CV_EXPORTS MatOp_AddS_
850 static void apply(const M& a, const Scalar& s, M& c, int type=-1)
852 if( type == a.type() || type < 0 )
860 temp.convertTo(c, type);
865 template<typename M> class CV_EXPORTS MatOp_AddEx_
870 static void apply(const M& a, double alpha, const M& b,
871 double beta, double gamma, M& c, int type=-1)
873 if( type == a.type() || type < 0 )
875 addWeighted(a, alpha, b, beta, gamma, c);
880 apply(a, alpha, b, beta, gamma, temp);
881 temp.convertTo(c, type);
886 template<typename M> class CV_EXPORTS MatOp_Bin_
891 static void apply(const M& a, const M& b, int _op, M& c, int type=-1)
894 if( type == a.type() || type < 0 )
897 bitwise_and( a, b, c );
899 bitwise_or( a, b, c );
901 bitwise_xor( a, b, c );
914 apply(a, b, op, temp);
915 temp.convertTo(c, type);
920 template<typename M> class CV_EXPORTS MatOp_BinS_
925 static void apply(const M& a, const Scalar& s, int _op, M& c, int type=-1)
928 if( type == a.type() || type < 0 )
931 bitwise_and( a, s, c );
933 bitwise_or( a, s, c );
935 bitwise_xor( a, s, c );
950 apply(a, s, op, temp);
951 temp.convertTo(c, type);
956 template<typename M> class CV_EXPORTS MatOp_T_
961 static void apply(const M& a, double scale, M& c, int type=-1)
963 if( type == a.type() || type < 0 )
966 if( fabs(scale - 1) > DBL_EPSILON )
967 c.convertTo(c, -1, scale, 0);
972 apply(a, scale, temp);
973 temp.convertTo(c, type);
979 template<typename M> class CV_EXPORTS MatOp_MatMul_
984 static void apply(const M& a, const M& b, double scale, int flags, M& c, int type=-1)
986 if( type == a.type() || type < 0 )
988 gemm(a, b, scale, Mat(), 0, c, flags);
993 apply(a, b, scale, flags, temp);
994 temp.convertTo(c, type);
1000 template<typename M> class CV_EXPORTS MatOp_MatMulAdd_
1003 MatOp_MatMulAdd_() {}
1005 static void apply(const M& a, const M& b, double alpha,
1006 const M& c, double beta, int flags, M& d, int type=-1)
1008 if( type == a.type() || type < 0 )
1010 gemm(a, b, alpha, c, beta, d, flags);
1015 apply(a, b, alpha, c, beta, flags, temp);
1016 temp.convertTo(d, type);
1022 template<typename M> class CV_EXPORTS MatOp_Cmp_
1027 static void apply(const M& a, const M& b, int op, M& c, int type=-1)
1029 if( type == CV_8UC1 || type == -1 )
1031 compare(a, b, c, op);
1036 apply(a, b, op, temp);
1037 temp.convertTo(c, type);
1042 template<typename M> class CV_EXPORTS MatOp_CmpS_
1047 static void apply(const M& a, double alpha, int op, M& c, int type=-1)
1049 if( type == CV_8UC1 || type == -1 )
1051 compare(a, alpha, c, op);
1056 apply(a, alpha, op, temp);
1057 temp.convertTo(c, type);
1062 template<typename M> class CV_EXPORTS MatOp_MulDiv_
1067 static void apply(const M& a, const M& b, double alpha, char op, M& c, int type=-1)
1069 if( type == a.type() || type == -1 )
1072 multiply( a, b, c, alpha );
1074 divide( a, b, c, alpha );
1079 apply(a, b, alpha, op, temp);
1080 temp.convertTo(c, type);
1085 template<typename M> class CV_EXPORTS MatOp_DivRS_
1090 static void apply(const M& a, double alpha, M& c, int type=-1)
1092 if( type == a.type() || type == -1 )
1094 c.create(a.rows, a.cols, a.type());
1095 divide( alpha, a, c );
1100 apply(a, alpha, temp);
1101 temp.convertTo(c, type);
1107 template<typename M> class CV_EXPORTS MatOp_Inv_
1112 static void apply(const M& a, int method, M& c, int type=-1)
1114 if( type == a.type() || type == -1 )
1116 invert(a, c, method);
1121 apply(a, method, temp);
1122 temp.convertTo(c, type);
1128 template<typename M> class CV_EXPORTS MatOp_Solve_
1133 static void apply(const M& a, const M& b, int method, M& c, int type=-1)
1135 if( type == a.type() || type == -1 )
1137 solve(a, b, c, method);
1142 apply(a, b, method, temp);
1143 temp.convertTo(c, type);
1148 template<typename M> class CV_EXPORTS MatOp_Set_
1153 static void apply(Size size, int type0, const Scalar& s, int mtype, M& c, int type=-1)
1157 c.create(size.height, size.width, type);
1160 else if( mtype == 1 )
1162 else if( mtype == 2 )
1167 template<typename A1, typename M, typename Op>
1168 class CV_EXPORTS MatExpr_Op1_
1171 MatExpr_Op1_(const A1& _a1) : a1(_a1) {}
1172 void assignTo(Mat& m, int type=-1) const { Op::apply(a1, (M&)m, type); }
1173 operator M() const { M result; assignTo(result); return result; }
1178 template<typename A1, typename A2, typename M, typename Op>
1179 class CV_EXPORTS MatExpr_Op2_
1182 MatExpr_Op2_(const A1& _a1, const A2& _a2) : a1(_a1), a2(_a2) {}
1183 void assignTo(Mat& m, int type=-1) const { Op::apply(a1, a2, (M&)m, type); }
1184 operator M() const { M result; assignTo(result); return result; }
1189 template<typename A1, typename A2, typename A3, typename M, typename Op>
1190 class CV_EXPORTS MatExpr_Op3_
1193 MatExpr_Op3_(const A1& _a1, const A2& _a2, const A3& _a3) : a1(_a1), a2(_a2), a3(_a3) {}
1194 void assignTo(Mat& m, int type=-1) const { Op::apply(a1, a2, a3, (M&)m, type); }
1195 operator M() const { M result; assignTo(result); return result; }
1197 A1 a1; A2 a2; A3 a3;
1200 template<typename A1, typename A2, typename A3, typename A4, typename M, typename Op>
1201 class CV_EXPORTS MatExpr_Op4_
1204 MatExpr_Op4_(const A1& _a1, const A2& _a2, const A3& _a3, const A4& _a4)
1205 : a1(_a1), a2(_a2), a3(_a3), a4(_a4) {}
1206 void assignTo(Mat& m, int type=-1) const { Op::apply(a1, a2, a3, a4, (M&)m, type); }
1207 operator M() const { M result; assignTo(result); return result; }
1209 A1 a1; A2 a2; A3 a3; A4 a4;
1212 template<typename A1, typename A2, typename A3, typename A4, typename A5, typename M, typename Op>
1213 class CV_EXPORTS MatExpr_Op5_
1216 MatExpr_Op5_(const A1& _a1, const A2& _a2, const A3& _a3, const A4& _a4, const A5& _a5)
1217 : a1(_a1), a2(_a2), a3(_a3), a4(_a4), a5(_a5) {}
1218 void assignTo(Mat& m, int type=-1) const { Op::apply(a1, a2, a3, a4, a5, (M&)m, type); }
1219 operator M() const { M result; assignTo(result); return result; }
1221 A1 a1; A2 a2; A3 a3; A4 a4; A5 a5;
1224 template<typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename M, typename Op>
1225 class CV_EXPORTS MatExpr_Op6_
1228 MatExpr_Op6_(const A1& _a1, const A2& _a2, const A3& _a3,
1229 const A4& _a4, const A5& _a5, const A6& _a6)
1230 : a1(_a1), a2(_a2), a3(_a3), a4(_a4), a5(_a5), a6(_a6) {}
1231 void assignTo(Mat& m, int type=-1) const { Op::apply(a1, a2, a3, a4, a5, a6, (M&)m, type); }
1232 operator M() const { M result; assignTo(result); return result; }
1234 A1 a1; A2 a2; A3 a3; A4 a4; A5 a5; A6 a6;
1237 ///////////////////////////////// Arithmetical Operations ///////////////////////////////////
1240 static inline MatExpr_<MatExpr_Op5_<Mat, double, Mat, double, double, Mat, MatOp_AddEx_<Mat> >, Mat>
1241 operator + (const Mat& a, const Mat& b)
1243 typedef MatExpr_Op5_<Mat, double, Mat, double, double, Mat, MatOp_AddEx_<Mat> > MatExpr_Temp;
1244 return MatExpr_<MatExpr_Temp, Mat>(MatExpr_Temp(a, 1, b, 1, 0));
1247 template<typename _Tp> static inline
1248 MatExpr_<MatExpr_Op5_<Mat_<_Tp>, double, Mat_<_Tp>,
1249 double, double, Mat_<_Tp>, MatOp_AddEx_<Mat> >, Mat_<_Tp> >
1250 operator + (const Mat_<_Tp>& a, const Mat_<_Tp>& b)
1252 typedef MatExpr_Op5_<Mat_<_Tp>, double, Mat_<_Tp>, double, double, Mat_<_Tp>, MatOp_AddEx_<Mat> > MatExpr_Temp;
1253 return MatExpr_<MatExpr_Temp, Mat_<_Tp> >(MatExpr_Temp(a, 1, b, 1, 0));
1257 template<typename A, typename B, typename M> static inline
1258 MatExpr_<MatExpr_Op5_<M, double, M, double, double, M, MatOp_AddEx_<Mat> >, M>
1259 operator + (const MatExpr_<A, M>& a, const MatExpr_<B, M>& b )
1261 typedef MatExpr_Op5_<M, double, M, double, double, M, MatOp_AddEx_<Mat> > MatExpr_Temp;
1262 return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp((M)a, 1, (M)b, 1, 0));
1266 static inline MatExpr_<MatExpr_Op2_<Mat, Mat, Mat, MatOp_Sub_<Mat> >, Mat>
1267 operator - (const Mat& a, const Mat& b)
1269 typedef MatExpr_Op2_<Mat, Mat, Mat, MatOp_Sub_<Mat> > MatExpr_Temp;
1270 return MatExpr_<MatExpr_Temp, Mat>(MatExpr_Temp(a, b));
1273 template<typename _Tp> static inline
1274 MatExpr_<MatExpr_Op2_<Mat_<_Tp>, Mat_<_Tp>, Mat_<_Tp>, MatOp_Sub_<Mat> >, Mat_<_Tp> >
1275 operator - (const Mat_<_Tp>& a, const Mat_<_Tp>& b)
1277 typedef MatExpr_Op2_<Mat_<_Tp>, Mat_<_Tp>, Mat_<_Tp>, MatOp_Sub_<Mat> > MatExpr_Temp;
1278 return MatExpr_<MatExpr_Temp, Mat_<_Tp> >(MatExpr_Temp(a, b));
1282 template<typename A, typename B, typename M> static inline
1283 MatExpr_<MatExpr_Op2_<M, M, M, MatOp_Sub_<Mat> >, M>
1284 operator - (const MatExpr_<A, M>& a, const MatExpr_<B, M>& b )
1286 typedef MatExpr_Op2_<M, M, M, MatOp_Sub_<Mat> > MatExpr_Temp;
1287 return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp((M)a, (M)b));
1291 template<typename A, typename B, typename M> static inline
1292 MatExpr_<MatExpr_Op2_<B, A, M, MatOp_Sub_<Mat> >, M>
1293 operator - (const MatExpr_<MatExpr_Op2_<A, B, M, MatOp_Sub_<Mat> >, M>& a )
1295 typedef MatExpr_Op2_<B, A, M, MatOp_Sub_<Mat> > MatExpr_Temp;
1296 return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(a.e.a2, a.e.a1));
1300 template<typename A, typename B, typename M> static inline
1301 MatExpr_<MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> >, M>
1302 operator * (const MatExpr_<MatExpr_Op2_<A, B, M, MatOp_Sub_<Mat> >, M>& a,
1305 typedef MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> > MatExpr_Temp;
1306 return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(a.e.a1, alpha, a.e.a2, -alpha, 0));
1310 template<typename A, typename B, typename M> static inline
1311 MatExpr_<MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> >, M>
1312 operator * (double alpha,
1313 const MatExpr_<MatExpr_Op2_<A, B, M, MatOp_Sub_<Mat> >, M>& a)
1319 MatExpr_<MatExpr_Op2_<Mat, double, Mat, MatOp_Scale_<Mat> >, Mat>
1320 operator * (const Mat& a, double alpha)
1322 typedef MatExpr_Op2_<Mat, double, Mat, MatOp_Scale_<Mat> > MatExpr_Temp;
1323 return MatExpr_<MatExpr_Temp, Mat>(MatExpr_Temp(a, alpha));
1327 template<typename _Tp> static inline
1328 MatExpr_<MatExpr_Op2_<Mat_<_Tp>, double, Mat_<_Tp>, MatOp_Scale_<Mat> >, Mat_<_Tp> >
1329 operator * (const Mat_<_Tp>& a, double alpha)
1331 typedef MatExpr_Op2_<Mat_<_Tp>, double, Mat_<_Tp>, MatOp_Scale_<Mat> > MatExpr_Temp;
1332 return MatExpr_<MatExpr_Temp, Mat_<_Tp> >(MatExpr_Temp(a, alpha));
1337 MatExpr_<MatExpr_Op2_<Mat, double, Mat, MatOp_Scale_<Mat> >, Mat>
1338 operator * (double alpha, const Mat& a)
1342 template<typename _Tp> static inline
1343 MatExpr_<MatExpr_Op2_<Mat_<_Tp>, double, Mat_<_Tp>, MatOp_Scale_<Mat> >, Mat_<_Tp> >
1344 operator * (double alpha, const Mat_<_Tp>& a)
1349 MatExpr_<MatExpr_Op2_<Mat, double, Mat, MatOp_Scale_<Mat> >, Mat>
1350 operator / (const Mat& a, double alpha)
1351 { return a*(1./alpha); }
1354 template<typename _Tp> static inline
1355 MatExpr_<MatExpr_Op2_<Mat_<_Tp>, double, Mat_<_Tp>, MatOp_Scale_<Mat> >, Mat_<_Tp> >
1356 operator / (const Mat_<_Tp>& a, double alpha)
1357 { return a*(1./alpha); }
1361 MatExpr_<MatExpr_Op2_<Mat, double, Mat, MatOp_Scale_<Mat> >, Mat>
1362 operator - (const Mat& a)
1366 template<typename _Tp> static inline
1367 MatExpr_<MatExpr_Op2_<Mat_<_Tp>, double, Mat_<_Tp>, MatOp_Scale_<Mat> >, Mat_<_Tp> >
1368 operator - (const Mat_<_Tp>& a)
1372 template<typename A, typename M> static inline
1373 MatExpr_<MatExpr_Op2_<M, double, M, MatOp_Scale_<Mat> >, M>
1374 operator * (const MatExpr_<A, M>& a, double alpha)
1376 typedef MatExpr_Op2_<M, double, M, MatOp_Scale_<Mat> > MatExpr_Temp;
1377 return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp((M)a, alpha));
1381 template<typename A, typename M> static inline
1382 MatExpr_<MatExpr_Op2_<M, double, M, MatOp_Scale_<Mat> >, M>
1383 operator * (double alpha, const MatExpr_<A, M>& a)
1387 template<typename A, typename M> static inline
1388 MatExpr_<MatExpr_Op2_<M, double, M, MatOp_Scale_<Mat> >, M>
1389 operator / (const MatExpr_<A, M>& a, double alpha)
1390 { return a*(1./alpha); }
1392 // (E*alpha)*beta ~ E*(alpha*beta)
1393 template<typename A, typename M> static inline
1394 MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>
1395 operator * (const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& a,
1397 { return a.e.a1*(a.e.a2*beta); }
1399 // beta*(E*alpha) ~ E*(alpha*beta)
1400 template<typename A, typename M> static inline
1401 MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>
1402 operator * (double beta,
1403 const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& a)
1404 { return a.e.a1*(a.e.a2*beta); }
1406 // (E*alpha)/beta ~ E*(alpha/beta)
1407 template<typename A, typename M> static inline
1408 MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>
1409 operator / (const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& a,
1411 { return a.e.a1*(a.e.a2/beta); }
1414 template<typename A, typename M> static inline
1415 MatExpr_<MatExpr_Op2_<MatExpr_<A, M>, double, M, MatOp_Scale_<Mat> >, M>
1416 operator - (const MatExpr_<A, M>& a)
1419 // -(E*alpha) ~ E*(-alpha)
1420 template<typename A, typename M> static inline
1421 MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>
1422 operator - (const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& a)
1423 { return a.e.a1*(-a.e.a2); }
1426 template<typename _Tp> static inline
1427 MatExpr_<MatExpr_Op3_<Mat_<_Tp>, double, double, Mat_<_Tp>, MatOp_ScaleAddS_<Mat> >, Mat_<_Tp> >
1428 operator + (const Mat_<_Tp>& a, double alpha)
1430 typedef MatExpr_Op3_<Mat_<_Tp>, double, double, Mat_<_Tp>,
1431 MatOp_ScaleAddS_<Mat> > MatExpr_Temp;
1432 return MatExpr_<MatExpr_Temp, Mat_<_Tp> >(MatExpr_Temp(a, 1, alpha));
1436 template<typename _Tp> static inline
1437 MatExpr_<MatExpr_Op2_<Mat_<_Tp>, Scalar, Mat_<_Tp>, MatOp_AddS_<Mat> >, Mat_<_Tp> >
1438 operator + (const Mat_<_Tp>& a, const Scalar& alpha)
1440 typedef MatExpr_Op2_<Mat_<_Tp>, Scalar, Mat_<_Tp>,
1441 MatOp_AddS_<Mat> > MatExpr_Temp;
1442 return MatExpr_<MatExpr_Temp, Mat_<_Tp> >(MatExpr_Temp(a, alpha));
1446 template<typename _Tp> static inline
1447 MatExpr_<MatExpr_Op3_<Mat_<_Tp>, double, double, Mat_<_Tp>, MatOp_ScaleAddS_<Mat> >, Mat_<_Tp> >
1448 operator + (double alpha, const Mat_<_Tp>& a)
1449 { return a + alpha; }
1452 template<typename _Tp> static inline
1453 MatExpr_<MatExpr_Op2_<Mat_<_Tp>, Scalar, Mat_<_Tp>, MatOp_AddS_<Mat> >, Mat_<_Tp> >
1454 operator + (const Scalar& alpha, const Mat_<_Tp>& a)
1455 { return a + alpha; }
1458 template<typename _Tp> static inline
1459 MatExpr_<MatExpr_Op3_<Mat_<_Tp>, double, double, Mat_<_Tp>, MatOp_ScaleAddS_<Mat> >, Mat_<_Tp> >
1460 operator - (const Mat_<_Tp>& a, double alpha)
1461 { return a + (-alpha); }
1464 template<typename _Tp> static inline
1465 MatExpr_<MatExpr_Op2_<Mat_<_Tp>, Scalar, Mat_<_Tp>, MatOp_AddS_<Mat> >, Mat_<_Tp> >
1466 operator - (const Mat_<_Tp>& a, const Scalar& alpha)
1467 { return a + (-alpha); }
1470 template<typename _Tp> static inline
1471 MatExpr_<MatExpr_Op3_<Mat_<_Tp>, double, double, Mat_<_Tp>, MatOp_ScaleAddS_<Mat> >, Mat_<_Tp> >
1472 operator - (double alpha, const Mat_<_Tp>& a)
1474 typedef MatExpr_Op3_<Mat_<_Tp>, double, double, Mat_<_Tp>,
1475 MatOp_ScaleAddS_<Mat> > MatExpr_Temp;
1476 return MatExpr_<MatExpr_Temp, Mat_<_Tp> >(MatExpr_Temp(a, -1, alpha));
1480 template<typename A, typename M> static inline
1481 MatExpr_<MatExpr_Op3_<M, double, double, M, MatOp_ScaleAddS_<Mat> >, M>
1482 operator + (const MatExpr_<A, M>& a, double alpha)
1484 typedef MatExpr_Op3_<M, double, double, M, MatOp_ScaleAddS_<Mat> > MatExpr_Temp;
1485 return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp((M)a, 1, alpha));
1489 template<typename A, typename M> static inline
1490 MatExpr_<MatExpr_Op2_<M, Scalar, M, MatOp_AddS_<Mat> >, M>
1491 operator + (const MatExpr_<A, M>& a, const Scalar& alpha)
1493 typedef MatExpr_Op2_<M, Scalar, M, MatOp_AddS_<Mat> > MatExpr_Temp;
1494 return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp((M)a, alpha));
1498 template<typename A, typename M> static inline
1499 MatExpr_<MatExpr_Op3_<M, double, double, M, MatOp_ScaleAddS_<Mat> >, M>
1500 operator + (double alpha, const MatExpr_<A, M>& a)
1501 { return a + alpha; }
1504 template<typename A, typename M> static inline
1505 MatExpr_<MatExpr_Op2_<M, Scalar, M, MatOp_AddS_<Mat> >, M>
1506 operator + (const Scalar& alpha, const MatExpr_<A, M>& a)
1507 { return a + alpha; }
1510 template<typename A, typename M> static inline
1511 MatExpr_<MatExpr_Op3_<M, double, double, M, MatOp_ScaleAddS_<Mat> >, M>
1512 operator - (const MatExpr_<A, M>& a, double alpha)
1513 { return a + (-alpha); }
1516 template<typename A, typename M> static inline
1517 MatExpr_<MatExpr_Op2_<M, Scalar, M, MatOp_AddS_<Mat> >, M>
1518 operator - (const MatExpr_<A, M>& a, const Scalar& alpha)
1519 { return a + (-alpha); }
1522 template<typename A, typename M> static inline
1523 MatExpr_<MatExpr_Op3_<M, double, double, M, MatOp_ScaleAddS_<Mat> >, M>
1524 operator - (double alpha, const MatExpr_<A, M>& a)
1526 typedef MatExpr_Op3_<M, double, double, M, MatOp_ScaleAddS_<Mat> > MatExpr_Temp;
1527 return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(a, -1, alpha));
1531 template<typename A, typename M> static inline
1532 MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>
1533 operator + (const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& a,
1536 typedef MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> > MatExpr_Temp;
1537 return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(a.e.a1, a.e.a2, beta));
1541 template<typename A, typename M> static inline
1542 MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>
1543 operator + (double beta,
1544 const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& a)
1545 { return a + beta; }
1548 template<typename A, typename M> static inline
1549 MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>
1550 operator - (const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& a,
1552 { return a + (-beta); }
1555 template<typename A, typename M> static inline
1556 MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>
1557 operator - (double beta,
1558 const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& a)
1559 { return (a.e.a1*(-a.e.a2)) + beta; }
1561 // (E*alpha + gamma) + beta ~ E*alpha + (gamma + beta)
1562 template<typename A, typename M> static inline
1563 MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>
1564 operator + (const MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>& a,
1566 { return a.e.a1*a.e.a2 + (a.e.a3 + beta); }
1568 // beta + (E*alpha + gamma)
1569 template<typename A, typename M> static inline
1570 MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>
1571 operator + (double beta, const MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>& a)
1572 { return a + beta; }
1574 // (E*alpha + gamma) - beta
1575 template<typename A, typename M> static inline
1576 MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>
1577 operator - (const MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>& a,
1579 { return a + (-beta); }
1581 // beta - (E*alpha + gamma)
1582 template<typename A, typename M> static inline
1583 MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>
1584 operator - (double beta, const MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>& a)
1585 { return a.e.a1*(-a.e.a2) + (beta - a.e.a3); }
1587 // (E*alpha + gamma)*beta
1588 template<typename A, typename M> static inline
1589 MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>
1590 operator * (const MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>& a,
1592 { return a.e.a1*(a.e.a2*beta) + (a.e.a3*beta); }
1594 // beta*(E*alpha + gamma)
1595 template<typename A, typename M> static inline
1596 MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>
1597 operator * (double beta, const MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>& a)
1600 // -(E*alpha + beta)
1601 template<typename A, typename M> static inline
1602 MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>
1603 operator - (const MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>& a)
1606 // (A*u + B*v + w) + beta
1607 template<typename A, typename B, typename M> static inline
1608 MatExpr_<MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> >, M>
1609 operator + (const MatExpr_<MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> >, M>& a,
1612 typedef MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> > MatExpr_Temp;
1613 return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(a.e.a1, a.e.a2, a.e.a3, a.e.a4, a.e.a5 + beta));
1616 // beta + (A*u + B*v + w)
1617 template<typename A, typename B, typename M> static inline
1618 MatExpr_<MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> >, M>
1619 operator + (double beta,
1620 const MatExpr_<MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> >, M>& a)
1621 { return a + beta; }
1623 // (A*u + B*v + w) - beta
1624 template<typename A, typename B, typename M> static inline
1625 MatExpr_<MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> >, M>
1626 operator - (const MatExpr_<MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> >, M>& a,
1628 { return a + (-beta); }
1630 // beta - (A*u + B*v + w)
1631 template<typename A, typename B, typename M> static inline
1632 MatExpr_<MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> >, M>
1633 operator - (double beta,
1634 const MatExpr_<MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> >, M>& a)
1636 typedef MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> > MatExpr_Temp;
1637 return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(a.e.a1, -a.e.a2, a.e.a3, -a.e.a4, -a.e.a5 + beta));
1640 // (A*u + B*v + w)*beta
1641 template<typename A, typename B, typename M> static inline
1642 MatExpr_<MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> >, M>
1643 operator * (const MatExpr_<MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> >, M>& a,
1646 typedef MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> > MatExpr_Temp;
1647 return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(a.e.a1,
1648 a.e.a2*beta, a.e.a3, a.e.a4*beta, a.e.a5*beta));
1651 // beta*(A*u + B*v + w)
1652 template<typename A, typename B, typename M> static inline
1653 MatExpr_<MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> >, M>
1654 operator * (double beta,
1655 const MatExpr_<MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> >, M>& a)
1656 { return a * beta; }
1659 template<typename A, typename B, typename M> static inline
1660 MatExpr_<MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> >, M>
1661 operator - (const MatExpr_<MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> >, M>& a)
1665 template<typename A, typename M> static inline
1666 MatExpr_<MatExpr_Op5_<A, double, M, double, double, M, MatOp_AddEx_<Mat> >, M>
1667 operator + (const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& a,
1670 typedef MatExpr_Op5_<A, double, M, double, double, M, MatOp_AddEx_<Mat> > MatExpr_Temp;
1671 return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(a.e.a1, a.e.a2, b, 1, 0));
1675 template<typename A, typename M> static inline
1676 MatExpr_<MatExpr_Op5_<A, double, M, double, double, M, MatOp_AddEx_<Mat> >, M>
1677 operator + (const M& b,
1678 const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& a)
1681 // (A*alpha + beta) + B
1682 template<typename A, typename M> static inline
1683 MatExpr_<MatExpr_Op5_<A, double, M, double, double, M, MatOp_AddEx_<Mat> >, M>
1684 operator + (const MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>& a,
1687 typedef MatExpr_Op5_<A, double, M, double, double, M, MatOp_AddEx_<Mat> > MatExpr_Temp;
1688 return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(a.e.a1, a.e.a2, b, 1, a.e.a3));
1691 // B + (A*alpha + beta)
1692 template<typename A, typename M> static inline
1693 MatExpr_<MatExpr_Op5_<A, double, M, double, double, M, MatOp_AddEx_<Mat> >, M>
1694 operator + (const M& b,
1695 const MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>& a)
1700 template<typename A, typename B, typename M> static inline
1701 MatExpr_<MatExpr_Op5_<A, double, M, double, double, M, MatOp_AddEx_<Mat> >, M>
1702 operator + (const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& a,
1703 const MatExpr_<B, M>& b )
1704 { return a + (M)b; }
1707 template<typename A, typename B, typename M> static inline
1708 MatExpr_<MatExpr_Op5_<A, double, M, double, double, M, MatOp_AddEx_<Mat> >, M>
1709 operator + (const MatExpr_<B, M>& b,
1710 const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& a)
1711 { return a + (M)b; }
1713 // (A*alpha + beta) + E
1714 template<typename A, typename B, typename M> static inline
1715 MatExpr_<MatExpr_Op5_<A, double, M, double, double, M, MatOp_AddEx_<Mat> >, M>
1716 operator + (const MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>& a,
1717 const MatExpr_<B, M>& b )
1718 { return a + (M)b; }
1720 // E + (A*alpha + beta)
1721 template<typename A, typename B, typename M> static inline
1722 MatExpr_<MatExpr_Op5_<A, double, M, double, double, M, MatOp_AddEx_<Mat> >, M>
1723 operator + (const MatExpr_<B, M>& b,
1724 const MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>& a)
1728 template<typename A, typename B, typename M> static inline
1729 MatExpr_<MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> >, M>
1730 operator + (const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& a,
1731 const MatExpr_<MatExpr_Op2_<B, double, M, MatOp_Scale_<Mat> >, M>& b )
1733 typedef MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> > MatExpr_Temp;
1734 return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(a.e.a1, a.e.a2, b.e.a1, b.e.a2, 0));
1737 // (A*alpha + beta) + B*gamma
1738 template<typename A, typename B, typename M> static inline
1739 MatExpr_<MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> >, M>
1740 operator + (const MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>& a,
1741 const MatExpr_<MatExpr_Op2_<B, double, M, MatOp_Scale_<Mat> >, M>& b )
1743 typedef MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> > MatExpr_Temp;
1744 return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(a.e.a1, a.e.a2, b.e.a1, b.e.a2, a.e.a3));
1747 // B*gamma + (A*alpha + beta)
1748 template<typename A, typename B, typename M> static inline
1749 MatExpr_<MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> >, M>
1750 operator + (const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& b,
1751 const MatExpr_<MatExpr_Op3_<B, double, double, M, MatOp_ScaleAddS_<Mat> >, M>& a )
1754 // (A*alpha + beta) + (B*gamma + theta)
1755 template<typename A, typename B, typename M> static inline
1756 MatExpr_<MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> >, M>
1757 operator + (const MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>& a,
1758 const MatExpr_<MatExpr_Op3_<B, double, double, M, MatOp_ScaleAddS_<Mat> >, M>& b )
1760 typedef MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> > MatExpr_Temp;
1761 return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(a.e.a1, a.e.a2, b.e.a1, b.e.a2, a.e.a3 + b.e.a3));
1765 template<typename A, typename M> static inline
1766 MatExpr_<MatExpr_Op5_<A, double, M, double, double, M, MatOp_AddEx_<Mat> >, M>
1767 operator - (const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& a,
1770 typedef MatExpr_Op5_<A, double, M, double, double, M, MatOp_AddEx_<Mat> > MatExpr_Temp;
1771 return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(a.e.a1, a.e.a2, b, -1, 0));
1775 template<typename A, typename M> static inline
1776 MatExpr_<MatExpr_Op5_<A, double, M, double, double, M, MatOp_AddEx_<Mat> >, M>
1777 operator - (const M& b,
1778 const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& a)
1780 typedef MatExpr_Op5_<A, double, M, double, double, M, MatOp_AddEx_<Mat> > MatExpr_Temp;
1781 return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(a.e.a1, -a.e.a2, b, 1, 0));
1784 // (A*alpha + beta) - B
1785 template<typename A, typename M> static inline
1786 MatExpr_<MatExpr_Op5_<A, double, M, double, double, M, MatOp_AddEx_<Mat> >, M>
1787 operator - (const MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>& a,
1790 typedef MatExpr_Op5_<A, double, M, double, double, M, MatOp_AddEx_<Mat> > MatExpr_Temp;
1791 return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(a.e.a1, a.e.a2, b, -1, a.e.a3));
1794 // B - (A*alpha + beta)
1795 template<typename A, typename M> static inline
1796 MatExpr_<MatExpr_Op5_<A, double, M, double, double, M, MatOp_AddEx_<Mat> >, M>
1797 operator - (const M& b,
1798 const MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>& a)
1800 typedef MatExpr_Op5_<A, double, M, double, double, M, MatOp_AddEx_<Mat> > MatExpr_Temp;
1801 return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(a.e.a1, a.e.a2, b, -1, a.e.a3));
1805 template<typename A, typename B, typename M> static inline
1806 MatExpr_<MatExpr_Op5_<A, double, M, double, double, M, MatOp_AddEx_<Mat> >, M>
1807 operator - (const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& a,
1808 const MatExpr_<B, M>& b )
1809 { return a - (M)b; }
1812 template<typename A, typename B, typename M> static inline
1813 MatExpr_<MatExpr_Op5_<A, double, M, double, double, M, MatOp_AddEx_<Mat> >, M>
1814 operator - (const MatExpr_<B, M>& b,
1815 const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& a)
1816 { return (M)b - a; }
1818 // (A*alpha + beta) - E
1819 template<typename A, typename B, typename M> static inline
1820 MatExpr_<MatExpr_Op5_<A, double, M, double, double, M, MatOp_AddEx_<Mat> >, M>
1821 operator - (const MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>& a,
1822 const MatExpr_<B, M>& b )
1823 { return a - (M)b; }
1825 // E - (A*alpha + beta)
1826 template<typename A, typename B, typename M> static inline
1827 MatExpr_<MatExpr_Op5_<A, double, M, double, double, M, MatOp_AddEx_<Mat> >, M>
1828 operator - (const MatExpr_<B, M>& b,
1829 const MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>& a)
1830 { return (M)b - a; }
1833 template<typename A, typename B, typename M> static inline
1834 MatExpr_<MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> >, M>
1835 operator - (const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& a,
1836 const MatExpr_<MatExpr_Op2_<B, double, M, MatOp_Scale_<Mat> >, M>& b )
1838 typedef MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> > MatExpr_Temp;
1839 return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(a.e.a1, a.e.a2, b.e.a1, -b.e.a2, 0));
1842 // (A*alpha + beta) - B*gamma
1843 template<typename A, typename B, typename M> static inline
1844 MatExpr_<MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> >, M>
1845 operator - (const MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>& a,
1846 const MatExpr_<MatExpr_Op2_<B, double, M, MatOp_Scale_<Mat> >, M>& b )
1848 typedef MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> > MatExpr_Temp;
1849 return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(a.e.a1, a.e.a2, b.e.a1, -b.e.a2, a.e.a3));
1852 // B*gamma - (A*alpha + beta)
1853 template<typename A, typename B, typename M> static inline
1854 MatExpr_<MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> >, M>
1855 operator - (const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& b,
1856 const MatExpr_<MatExpr_Op3_<B, double, double, M, MatOp_ScaleAddS_<Mat> >, M>& a )
1858 typedef MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> > MatExpr_Temp;
1859 return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(a.e.a1, -a.e.a2, b.e.a1, b.e.a2, -a.e.a3));
1862 // (A*alpha + beta) - (B*gamma + theta)
1863 template<typename A, typename B, typename M> static inline
1864 MatExpr_<MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> >, M>
1865 operator - (const MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>& a,
1866 const MatExpr_<MatExpr_Op3_<B, double, double, M, MatOp_ScaleAddS_<Mat> >, M>& b )
1868 typedef MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> > MatExpr_Temp;
1869 return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(a.e.a1, a.e.a2, b.e.a1, -b.e.a2, a.e.a3 - b.e.a3));
1872 /////////////////////////////// Mat Multiplication ///////////////////////////////////
1875 inline MatExpr_<MatExpr_Op2_<Mat, double, Mat, MatOp_T_<Mat> >, Mat>
1878 typedef MatExpr_Op2_<Mat, double, Mat, MatOp_T_<Mat> > MatExpr_Temp;
1879 return MatExpr_<MatExpr_Temp, Mat>(MatExpr_Temp(*this, 1));
1882 template<typename _Tp> inline
1883 MatExpr_<MatExpr_Op2_<Mat_<_Tp>, double, Mat_<_Tp>, MatOp_T_<Mat> >, Mat_<_Tp> >
1884 Mat_<_Tp>::t() const
1886 typedef MatExpr_Op2_<Mat_<_Tp>, double, Mat_<_Tp>, MatOp_T_<Mat> > MatExpr_Temp;
1887 return MatExpr_<MatExpr_Temp, Mat_<_Tp> >(MatExpr_Temp(*this, 1));
1892 MatExpr_<MatExpr_Op4_<Mat, Mat, double, int, Mat, MatOp_MatMul_<Mat> >, Mat>
1893 operator * ( const Mat& a, const Mat& b )
1895 typedef MatExpr_Op4_<Mat, Mat, double, int, Mat, MatOp_MatMul_<Mat> > MatExpr_Temp;
1896 return MatExpr_<MatExpr_Temp, Mat>(MatExpr_Temp(a, b, 1, 0));
1899 template<typename _Tp> static inline
1900 MatExpr_<MatExpr_Op4_<Mat_<_Tp>, Mat_<_Tp>, double, int, Mat_<_Tp>,
1901 MatOp_MatMul_<Mat> >, Mat_<_Tp> >
1902 operator * ( const Mat_<_Tp>& a, const Mat_<_Tp>& b )
1904 typedef MatExpr_Op4_<Mat_<_Tp>, Mat_<_Tp>, double, int, Mat_<_Tp>,
1905 MatOp_MatMul_<Mat> > MatExpr_Temp;
1906 return MatExpr_<MatExpr_Temp, Mat_<_Tp> >(MatExpr_Temp(a, b, 1, 0));
1909 template<typename A, typename B, typename M> static inline
1910 MatExpr_<MatExpr_Op4_<M, M, double, int, M, MatOp_MatMul_<Mat> >, M>
1911 operator * ( const MatExpr_<A, M>& a, const MatExpr_<B, M>& b )
1913 typedef MatExpr_Op4_<M, M, double, int, M, MatOp_MatMul_<Mat> > MatExpr_Temp;
1914 return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp((M)a, (M)b, 1, 0));
1918 template<typename A, typename M> static inline
1919 MatExpr_<MatExpr_Op4_<M, M, double, int, M, MatOp_MatMul_<Mat> >, M>
1920 operator * ( const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& a, const M& b )
1922 typedef MatExpr_Op4_<M, M, double, int, M, MatOp_MatMul_<Mat> > MatExpr_Temp;
1923 return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp((M)a.e.a1, b, a.e.a2, 0));
1927 template<typename A, typename M> static inline
1928 MatExpr_<MatExpr_Op4_<M, M, double, int, M, MatOp_MatMul_<Mat> >, M>
1929 operator * ( const M& b, const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& a )
1931 typedef MatExpr_Op4_<M, M, double, int, M, MatOp_MatMul_<Mat> > MatExpr_Temp;
1932 return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(b, (M)a.e.a1, a.e.a2, 0));
1936 template<typename A, typename M> static inline
1937 MatExpr_<MatExpr_Op4_<M, M, double, int, M, MatOp_MatMul_<Mat> >, M>
1938 operator * ( const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_T_<Mat> >, M>& a, const M& b )
1940 typedef MatExpr_Op4_<M, M, double, int, M, MatOp_MatMul_<Mat> > MatExpr_Temp;
1941 return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp((M)a.e.a1, b, a.e.a2, GEMM_1_T));
1945 template<typename A, typename M> static inline
1946 MatExpr_<MatExpr_Op4_<M, M, double, int, M, MatOp_MatMul_<Mat> >, M>
1947 operator * ( const M& a, const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_T_<Mat> >, M>& b )
1949 typedef MatExpr_Op4_<M, M, double, int, M, MatOp_MatMul_<Mat> > MatExpr_Temp;
1950 return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(a, (M)b.e.a1, b.e.a2, GEMM_2_T));
1953 // (A*alpha)*(B*beta)
1954 template<typename A, typename B, typename M> static inline
1955 MatExpr_<MatExpr_Op4_<M, M, double, int, M, MatOp_MatMul_<Mat> >, M>
1956 operator * ( const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& a,
1957 const MatExpr_<MatExpr_Op2_<B, double, M, MatOp_Scale_<Mat> >, M>& b )
1959 typedef MatExpr_Op4_<M, M, double, int, M, MatOp_MatMul_<Mat> > MatExpr_Temp;
1960 return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp((M)a.e.a1, (M)b.e.a1, a.e.a2*b.e.a2, 0));
1964 template<typename A, typename B, typename M> static inline
1965 MatExpr_<MatExpr_Op4_<M, M, double, int, M, MatOp_MatMul_<Mat> >, M>
1966 operator * ( const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_T_<Mat> >, M>& a,
1967 const MatExpr_<MatExpr_Op2_<B, double, M, MatOp_Scale_<Mat> >, M>& b )
1969 typedef MatExpr_Op4_<M, M, double, int, M, MatOp_MatMul_<Mat> > MatExpr_Temp;
1970 return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp((M)a.e.a1, (M)b.e.a1, a.e.a2*b.e.a2, GEMM_1_T));
1974 template<typename A, typename B, typename M> static inline
1975 MatExpr_<MatExpr_Op4_<M, M, double, int, M, MatOp_MatMul_<Mat> >, M>
1976 operator * ( const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& a,
1977 const MatExpr_<MatExpr_Op2_<B, double, M, MatOp_T_<Mat> >, M>& b )
1979 typedef MatExpr_Op4_<M, M, double, int, M, MatOp_MatMul_<Mat> > MatExpr_Temp;
1980 return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp((M)a.e.a1, (M)b.e.a1, a.e.a2*b.e.a2, GEMM_2_T));
1984 template<typename A, typename B, typename M> static inline
1985 MatExpr_<MatExpr_Op4_<M, M, double, int, M, MatOp_MatMul_<Mat> >, M>
1986 operator * ( const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_T_<Mat> >, M>& a,
1987 const MatExpr_<MatExpr_Op2_<B, double, M, MatOp_T_<Mat> >, M>& b )
1989 typedef MatExpr_Op4_<M, M, double, int, M, MatOp_MatMul_<Mat> > MatExpr_Temp;
1990 return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp((M)a.e.a1,
1991 (M)b.e.a1, a.e.a2*b.e.a2, GEMM_1_T+GEMM_2_T));
1995 template<typename A, typename B, typename M> static inline
1996 MatExpr_<MatExpr_Op4_<A, B, double, int, M, MatOp_MatMul_<Mat> >, M>
1997 operator * ( const MatExpr_<MatExpr_Op4_<A, B, double, int, M, MatOp_MatMul_<Mat> >, M>& a,
2000 typedef MatExpr_Op4_<A, B, double, int, M, MatOp_MatMul_<Mat> > MatExpr_Temp;
2001 return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(a.e.a1, a.e.a2, a.e.a3*alpha, a.e.a4));
2005 template<typename A, typename B, typename M> static inline
2006 MatExpr_<MatExpr_Op4_<M, M, double, int, M, MatOp_MatMul_<Mat> >, M>
2007 operator * ( double alpha,
2008 const MatExpr_<MatExpr_Op4_<A, B, double, int, M, MatOp_MatMul_<Mat> >, M>& a )
2014 template<typename A, typename B, typename M> static inline
2015 MatExpr_<MatExpr_Op4_<A, B, double, int, M, MatOp_MatMul_<Mat> >, M>
2016 operator - ( const MatExpr_<MatExpr_Op4_<A, B, double, int, M, MatOp_MatMul_<Mat> >, M>& a )
2021 // (A*alpha + beta)*B
2022 template<typename A, typename M> static inline
2023 MatExpr_<MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> >, M>
2024 operator * ( const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_ScaleAddS_<Mat> >, M>& a, const M& b )
2026 typedef MatExpr_Op4_<M, M, double, int, M, MatOp_MatMul_<Mat> > MatExpr_Temp;
2027 return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp((M)a.e.a1, b, a.e.a2, b, a.e.a3, 0));
2030 // A*(B*alpha + beta)
2031 template<typename A, typename M> static inline
2032 MatExpr_<MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> >, M>
2033 operator * ( const M& a, const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_ScaleAddS_<Mat> >, M>& b )
2035 typedef MatExpr_Op4_<M, M, double, int, M, MatOp_MatMul_<Mat> > MatExpr_Temp;
2036 return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(a, (M)b.e.a1, b.e.a2, a, b.e.a3, 0));
2039 // (A*alpha + beta)*(B*gamma)
2040 template<typename A, typename B, typename M> static inline
2041 MatExpr_<MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> >, M>
2042 operator * ( const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_ScaleAddS_<Mat> >, M>& a,
2043 const MatExpr_<MatExpr_Op2_<B, double, M, MatOp_Scale_<Mat> >, M>& b )
2045 typedef MatExpr_Op4_<M, M, double, int, M, MatOp_MatMul_<Mat> > MatExpr_Temp;
2046 return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp((M)a.e.a1, (M)b.e.a1,
2047 a.e.a2*b.e.a2, (M)b.e.a1, a.e.a3*b.e.a2, 0));
2050 // (A*gamma)*(B*alpha + beta)
2051 template<typename A, typename B, typename M> static inline
2052 MatExpr_<MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> >, M>
2053 operator * ( const MatExpr_<MatExpr_Op2_<B, double, M, MatOp_Scale_<Mat> >, M>& a,
2054 const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_ScaleAddS_<Mat> >, M>& b )
2056 typedef MatExpr_Op4_<M, M, double, int, M, MatOp_MatMul_<Mat> > MatExpr_Temp;
2057 return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp((M)a.e.a1, (M)b.e.a1,
2058 a.e.a2*b.e.a2, (M)a.e.a1, a.e.a2*b.e.a3, 0));
2061 // (A*alpha + beta)*B^t
2062 template<typename A, typename B, typename M> static inline
2063 MatExpr_<MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> >, M>
2064 operator * ( const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_ScaleAddS_<Mat> >, M>& a,
2065 const MatExpr_<MatExpr_Op2_<B, double, M, MatOp_T_<Mat> >, M>& b )
2067 typedef MatExpr_Op4_<M, M, double, int, M, MatOp_MatMul_<Mat> > MatExpr_Temp;
2068 return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp((M)a.e.a1, (M)b.e.a1,
2069 a.e.a2*b.e.a2, (M)b.e.a1, a.e.a3*b.e.a2, GEMM_2_T));
2072 // A^t*(B*alpha + beta)
2073 template<typename A, typename B, typename M> static inline
2074 MatExpr_<MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> >, M>
2075 operator * ( const MatExpr_<MatExpr_Op2_<B, double, M, MatOp_T_<Mat> >, M>& a,
2076 const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_ScaleAddS_<Mat> >, M>& b )
2078 typedef MatExpr_Op4_<M, M, double, int, M, MatOp_MatMul_<Mat> > MatExpr_Temp;
2079 return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp((M)a.e.a1, (M)b.e.a1,
2080 a.e.a2*b.e.a2, (M)a.e.a1, a.e.a2*b.e.a3, GEMM_1_T));
2084 template<typename A, typename B, typename C, typename M> static inline
2085 MatExpr_<MatExpr_Op6_<A, B, double, C, double, int, M, MatOp_MatMulAdd_<Mat> >, M>
2086 operator * ( const MatExpr_<MatExpr_Op6_<A, B, double, C,
2087 double, int, M, MatOp_MatMulAdd_<Mat> >, M>& a, double alpha )
2089 typedef MatExpr_Op6_<A, B, double, C, double, int, M, MatOp_MatMulAdd_<Mat> > MatExpr_Temp;
2090 return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(a.e.a1, a.e.a2,
2091 a.e.a3*alpha, a.e.a4, a.e.a5*alpha, a.e.a6));
2095 template<typename A, typename B, typename C, typename M> static inline
2096 MatExpr_<MatExpr_Op6_<A, B, double, C, double, int, M, MatOp_MatMulAdd_<Mat> >, M>
2097 operator * ( double alpha, const MatExpr_<MatExpr_Op6_<A, B, double, C,
2098 double, int, M, MatOp_MatMulAdd_<Mat> >, M>& a )
2102 template<typename A, typename B, typename C, typename M> static inline
2103 MatExpr_<MatExpr_Op6_<A, B, double, C, double, int, M, MatOp_MatMulAdd_<Mat> >, M>
2104 operator - ( const MatExpr_<MatExpr_Op6_<A, B, double, C,
2105 double, int, M, MatOp_MatMulAdd_<Mat> >, M>& a )
2110 template<typename A, typename B, typename M> static inline
2111 MatExpr_<MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> >, M>
2112 operator + ( const MatExpr_<MatExpr_Op4_<A, B, double, int, M, MatOp_MatMul_<Mat> >, M>& a,
2115 typedef MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> > MatExpr_Temp;
2116 return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(
2117 (M)a.e.a1, (M)a.e.a2, a.e.a3, b, 1, a.e.a4));
2121 template<typename A, typename B, typename M> static inline
2122 MatExpr_<MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> >, M>
2123 operator + ( const M& b,
2124 const MatExpr_<MatExpr_Op4_<A, B, double, int, M, MatOp_MatMul_<Mat> >, M>& a )
2129 template<typename A, typename B, typename M> static inline
2130 MatExpr_<MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> >, M>
2131 operator - ( const MatExpr_<MatExpr_Op4_<A, B, double, int, M, MatOp_MatMul_<Mat> >, M>& a,
2134 typedef MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> > MatExpr_Temp;
2135 return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(
2136 (M)a.e.a1, (M)a.e.a2, a.e.a3, b, -1, a.e.a4));
2140 template<typename A, typename B, typename M> static inline
2141 MatExpr_<MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> >, M>
2142 operator - ( const M& b,
2143 const MatExpr_<MatExpr_Op4_<A, B, double, int, M, MatOp_MatMul_<Mat> >, M>& a )
2145 typedef MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> > MatExpr_Temp;
2146 return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(
2147 (M)a.e.a1, (M)a.e.a2, -a.e.a3, b, 1, a.e.a4));
2152 template<typename A, typename B, typename C, typename M> static inline
2153 MatExpr_<MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> >, M>
2154 operator + ( const MatExpr_<MatExpr_Op4_<A, B, double, int, M, MatOp_MatMul_<Mat> >, M>& a,
2155 const MatExpr_<C, M>& b )
2157 typedef MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> > MatExpr_Temp;
2158 return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(
2159 (M)a.e.a1, (M)a.e.a2, a.e.a3, (M)b, 1, a.e.a4));
2163 template<typename A, typename B, typename C, typename M> static inline
2164 MatExpr_<MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> >, M>
2165 operator + ( const MatExpr_<C, M>& b,
2166 const MatExpr_<MatExpr_Op4_<A, B, double, int, M, MatOp_MatMul_<Mat> >, M>& a )
2171 template<typename A, typename B, typename C, typename M> static inline
2172 MatExpr_<MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> >, M>
2173 operator - ( const MatExpr_<MatExpr_Op4_<A, B, double, int, M, MatOp_MatMul_<Mat> >, M>& a,
2174 const MatExpr_<C, M>& b )
2176 typedef MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> > MatExpr_Temp;
2177 return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(
2178 (M)a.e.a1, (M)a.e.a2, a.e.a3, (M)b, -1, a.e.a4));
2182 template<typename A, typename B, typename C, typename M> static inline
2183 MatExpr_<MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> >, M>
2184 operator - ( const MatExpr_<C, M>& b,
2185 const MatExpr_<MatExpr_Op4_<A, B, double, int, M, MatOp_MatMul_<Mat> >, M>& a )
2187 typedef MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> > MatExpr_Temp;
2188 return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(
2189 (M)a.e.a1, (M)a.e.a2, -a.e.a3, (M)b, 1, a.e.a4));
2194 template<typename A, typename B, typename C, typename M> static inline
2195 MatExpr_<MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> >, M>
2196 operator + ( const MatExpr_<MatExpr_Op4_<A, B, double, int, M, MatOp_MatMul_<Mat> >, M>& a,
2197 const MatExpr_<MatExpr_Op2_<C, double, M, MatOp_Scale_<Mat> >, M>& b )
2199 typedef MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> > MatExpr_Temp;
2200 return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(
2201 (M)a.e.a1, (M)a.e.a2, a.e.a3, (M)b.e.a1, b.e.a2, a.e.a4));
2205 template<typename A, typename B, typename C, typename M> static inline
2206 MatExpr_<MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> >, M>
2207 operator + ( const MatExpr_<MatExpr_Op2_<C, double, M, MatOp_Scale_<Mat> >, M>& b,
2208 const MatExpr_<MatExpr_Op4_<A, B, double, int, M, MatOp_MatMul_<Mat> >, M>& a )
2212 // (A*B) - (C*alpha)
2213 template<typename A, typename B, typename C, typename M> static inline
2214 MatExpr_<MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> >, M>
2215 operator - ( const MatExpr_<MatExpr_Op4_<A, B, double, int, M, MatOp_MatMul_<Mat> >, M>& a,
2216 const MatExpr_<MatExpr_Op2_<C, double, M, MatOp_Scale_<Mat> >, M>& b )
2218 typedef MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> > MatExpr_Temp;
2219 return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(
2220 (M)a.e.a1, (M)a.e.a2, a.e.a3, (M)b.e.a1, -b.e.a2, a.e.a4));
2223 // (C*alpha) - (A*B)
2224 template<typename A, typename B, typename C, typename M> static inline
2225 MatExpr_<MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> >, M>
2226 operator - ( const MatExpr_<MatExpr_Op2_<C, double, M, MatOp_Scale_<Mat> >, M>& b,
2227 const MatExpr_<MatExpr_Op4_<A, B, double, int, M, MatOp_MatMul_<Mat> >, M>& a )
2229 typedef MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> > MatExpr_Temp;
2230 return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(
2231 (M)a.e.a1, (M)a.e.a2, -a.e.a3, (M)b.e.a1, b.e.a2, a.e.a4));
2236 template<typename A, typename B, typename C, typename M> static inline
2237 MatExpr_<MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> >, M>
2238 operator + ( const MatExpr_<MatExpr_Op4_<A, B, double, int, M, MatOp_MatMul_<Mat> >, M>& a,
2239 const MatExpr_<MatExpr_Op2_<C, double, M, MatOp_T_<Mat> >, M>& b )
2241 typedef MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> > MatExpr_Temp;
2242 return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(
2243 (M)a.e.a1, (M)a.e.a2, a.e.a3, (M)b.e.a1, b.e.a2, a.e.a4 + GEMM_3_T));
2247 template<typename A, typename B, typename C, typename M> static inline
2248 MatExpr_<MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> >, M>
2249 operator + ( const MatExpr_<MatExpr_Op2_<C, double, M, MatOp_T_<Mat> >, M>& b,
2250 const MatExpr_<MatExpr_Op4_<A, B, double, int, M, MatOp_MatMul_<Mat> >, M>& a )
2255 template<typename A, typename B, typename C, typename M> static inline
2256 MatExpr_<MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> >, M>
2257 operator - ( const MatExpr_<MatExpr_Op4_<A, B, double, int, M, MatOp_MatMul_<Mat> >, M>& a,
2258 const MatExpr_<MatExpr_Op2_<C, double, M, MatOp_T_<Mat> >, M>& b )
2260 typedef MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> > MatExpr_Temp;
2261 return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(
2262 (M)a.e.a1, (M)a.e.a2, a.e.a3, (M)b.e.a1, -b.e.a2, a.e.a4+GEMM_3_T));
2266 template<typename A, typename B, typename C, typename M> static inline
2267 MatExpr_<MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> >, M>
2268 operator - ( const MatExpr_<MatExpr_Op2_<C, double, M, MatOp_T_<Mat> >, M>& b,
2269 const MatExpr_<MatExpr_Op4_<A, B, double, int, M, MatOp_MatMul_<Mat> >, M>& a )
2271 typedef MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> > MatExpr_Temp;
2272 return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(
2273 (M)a.e.a1, (M)a.e.a2, -a.e.a3, (M)b.e.a1, b.e.a2, a.e.a4+GEMM_3_T));
2277 ////////////////////////////// Augmenting algebraic operations //////////////////////////////////
2279 static inline Mat& operator += (const Mat& a, const Mat& b)
2285 static inline Mat& operator -= (const Mat& a, const Mat& b)
2287 subtract(a, b, (Mat&)a);
2291 static inline Mat& operator *= (const Mat& a, const Mat& b)
2293 gemm(a, b, 1, Mat(), 0, (Mat&)a, 0);
2297 static inline Mat& operator *= (const Mat& a, double alpha)
2299 a.convertTo((Mat&)a, -1, alpha);
2303 static inline Mat& operator += (const Mat& a, const Scalar& s)
2309 static inline Mat& operator -= (const Mat& a, const Scalar& s)
2310 { return (a += -s); }
2312 template<typename _Tp> static inline
2313 Mat_<_Tp>& operator += (const Mat_<_Tp>& a, const Mat_<_Tp>& b)
2315 (Mat&)a += (const Mat&)b;
2316 return (Mat_<_Tp>&)a;
2319 template<typename _Tp> static inline
2320 Mat_<_Tp>& operator -= (const Mat_<_Tp>& a, const Mat_<_Tp>& b)
2322 (Mat&)a -= (const Mat&)b;
2323 return (Mat_<_Tp>&)a;
2326 template<typename _Tp> static inline
2327 Mat_<_Tp>& operator *= (const Mat_<_Tp>& a, const Mat_<_Tp>& b)
2329 (Mat&)a *= (const Mat&)b;
2330 return (Mat_<_Tp>&)a;
2333 template<typename _Tp> static inline
2334 Mat_<_Tp>& operator += (const Mat_<_Tp>& a, const Scalar& s)
2337 return (Mat_<_Tp>&)a;
2340 template<typename _Tp> static inline
2341 Mat_<_Tp>& operator -= (const Mat_<_Tp>& a, const Scalar& s)
2344 return (Mat_<_Tp>&)a;
2347 template<typename A, typename M> static inline
2348 M& operator += (const M& a, const MatExpr_<A, M>& b)
2349 { return (a += (M)b); }
2351 template<typename A, typename M> static inline
2352 M& operator -= (const M& a, const MatExpr_<A, M>& b)
2353 { return (a -= (M)b); }
2355 template<typename A, typename M> static inline
2356 M& operator *= (const M& a, const MatExpr_<A, M>& b)
2357 { return (a *= (M)b); }
2359 template<typename A, typename M> static inline
2360 M& operator += (const M& a,
2361 const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& b)
2364 scaleAdd( b.e.a1, Scalar(b.e.a2), _a, _a );
2368 template<typename A, typename M> static inline
2369 M& operator -= (const M& a,
2370 const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& b)
2373 scaleAdd( b.e.a1, -Scalar(b.e.a2), _a, _a );
2377 template<typename A, typename M> static inline
2378 M& operator += (const M& a,
2379 const MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>& b)
2382 MatOp_AddEx_<Mat>::apply( a, 1, (M)b.e.a1, b.e.a2, b.e.a3, _a );
2386 template<typename A, typename M> static inline
2387 M& operator -= (const M& a,
2388 const MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>& b)
2391 MatOp_AddEx_<Mat>::apply( a, 1, (M)b.e.a1, -b.e.a2, -b.e.a3, _a );
2395 template<typename A, typename B, typename M> static inline
2396 M& operator += (const M& a,
2397 const MatExpr_<MatExpr_Op4_<A, B, double, int, M, MatOp_MatMul_<Mat> >, M>& b)
2400 MatOp_MatMulAdd_<Mat>::apply( (M)b.e.a1, (M)b.e.a2, b.e.a3, a, 1, b.e.a4, _a );
2404 template<typename A, typename B, typename M> static inline
2405 M& operator -= (const M& a,
2406 const MatExpr_<MatExpr_Op4_<A, B, double, int, M, MatOp_MatMul_<Mat> >, M>& b)
2409 MatOp_MatMulAdd_<Mat>::apply( (M)b.e.a1, (M)b.e.a2, -b.e.a3, a, 1, b.e.a4, _a );
2413 template<typename A, typename M> static inline
2414 M& operator *= (const M& a,
2415 const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& b)
2418 MatOp_MatMul_<Mat>::apply( a, (M)b.e.a1, b.e.a2, 0, _a );
2422 template<typename A, typename M> static inline
2423 M& operator *= (const M& a,
2424 const MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>& b)
2427 MatOp_MatMulAdd_<Mat>::apply( a, (M)b.e.a1, b.e.a2, a, b.e.a3, 0, _a );
2431 template<typename A, typename M> static inline
2432 M& operator *= (const M& a,
2433 const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_T_<Mat> >, M>& b)
2436 MatOp_MatMul_<Mat>::apply( a, (M)b.e.a1, b.e.a2, GEMM_2_T, _a );
2440 ////////////////////////////// Logical operations ///////////////////////////////
2442 static inline MatExpr_<MatExpr_Op3_<Mat, Mat, int, Mat, MatOp_Bin_<Mat> >, Mat>
2443 operator & (const Mat& a, const Mat& b)
2445 typedef MatExpr_Op3_<Mat, Mat, int, Mat, MatOp_Bin_<Mat> > MatExpr_Temp;
2446 return MatExpr_<MatExpr_Temp, Mat>(MatExpr_Temp(a, b, '&'));
2449 static inline MatExpr_<MatExpr_Op3_<Mat, Mat, int, Mat, MatOp_Bin_<Mat> >, Mat>
2450 operator | (const Mat& a, const Mat& b)
2452 typedef MatExpr_Op3_<Mat, Mat, int, Mat, MatOp_Bin_<Mat> > MatExpr_Temp;
2453 return MatExpr_<MatExpr_Temp, Mat>(MatExpr_Temp(a, b, '|'));
2456 static inline MatExpr_<MatExpr_Op3_<Mat, Mat, int, Mat, MatOp_Bin_<Mat> >, Mat>
2457 operator ^ (const Mat& a, const Mat& b)
2459 typedef MatExpr_Op3_<Mat, Mat, int, Mat, MatOp_Bin_<Mat> > MatExpr_Temp;
2460 return MatExpr_<MatExpr_Temp, Mat>(MatExpr_Temp(a, b, '^'));
2463 template<typename _Tp> static inline
2464 MatExpr_<MatExpr_Op3_<Mat_<_Tp>, Mat_<_Tp>, int, Mat_<_Tp>,
2465 MatOp_Bin_<Mat> >, Mat_<_Tp> >
2466 operator & (const Mat_<_Tp>& a, const Mat_<_Tp>& b)
2468 typedef MatExpr_Op3_<Mat_<_Tp>, Mat_<_Tp>, int, Mat_<_Tp>,
2469 MatOp_Bin_<Mat> > MatExpr_Temp;
2470 return MatExpr_<MatExpr_Temp, Mat_<_Tp> >(MatExpr_Temp(
2474 template<typename _Tp> static inline
2475 MatExpr_<MatExpr_Op3_<Mat_<_Tp>, Mat_<_Tp>, int, Mat_<_Tp>,
2476 MatOp_Bin_<Mat> >, Mat_<_Tp> >
2477 operator | (const Mat_<_Tp>& a, const Mat_<_Tp>& b)
2479 typedef MatExpr_Op3_<Mat_<_Tp>, Mat_<_Tp>, int, Mat_<_Tp>,
2480 MatOp_Bin_<Mat> > MatExpr_Temp;
2481 return MatExpr_<MatExpr_Temp, Mat_<_Tp> >(MatExpr_Temp(
2485 template<typename _Tp> static inline
2486 MatExpr_<MatExpr_Op3_<Mat_<_Tp>, Mat_<_Tp>, int, Mat_<_Tp>,
2487 MatOp_Bin_<Mat> >, Mat_<_Tp> >
2488 operator ^ (const Mat_<_Tp>& a, const Mat_<_Tp>& b)
2490 typedef MatExpr_Op3_<Mat_<_Tp>, Mat_<_Tp>, int, Mat_<_Tp>,
2491 MatOp_Bin_<Mat> > MatExpr_Temp;
2492 return MatExpr_<MatExpr_Temp, Mat_<_Tp> >(MatExpr_Temp(
2496 template<typename A, typename B, typename M> static inline
2497 MatExpr_<MatExpr_Op3_<M, M, int, M, MatOp_Bin_<Mat> >, M>
2498 operator & (const MatExpr_<A, M>& a, const MatExpr_<B, M>& b)
2499 { return (M)a & (M)b; }
2501 template<typename A, typename M> static inline
2502 MatExpr_<MatExpr_Op3_<M, M, int, M, MatOp_Bin_<Mat> >, M>
2503 operator & (const MatExpr_<A, M>& a, const M& b)
2504 { return (M)a & b; }
2506 template<typename A, typename M> static inline
2507 MatExpr_<MatExpr_Op3_<M, M, int, M, MatOp_Bin_<Mat> >, M>
2508 operator & (const M& a, const MatExpr_<A, M>& b)
2509 { return a & (M)b; }
2511 template<typename A, typename B, typename M> static inline
2512 MatExpr_<MatExpr_Op3_<M, M, int, M, MatOp_Bin_<Mat> >, M>
2513 operator | (const MatExpr_<A, M>& a, const MatExpr_<B, M>& b)
2514 { return (M)a | (M)b; }
2516 template<typename A, typename M> static inline
2517 MatExpr_<MatExpr_Op3_<M, M, int, M, MatOp_Bin_<Mat> >, M>
2518 operator | (const MatExpr_<A, M>& a, const M& b)
2519 { return (M)a | b; }
2521 template<typename A, typename M> static inline
2522 MatExpr_<MatExpr_Op3_<M, M, int, M, MatOp_Bin_<Mat> >, M>
2523 operator | (const M& a, const MatExpr_<A, M>& b)
2524 { return a | (M)b; }
2526 template<typename A, typename B, typename M> static inline
2527 MatExpr_<MatExpr_Op3_<M, M, int, M, MatOp_Bin_<Mat> >, M>
2528 operator ^ (const MatExpr_<A, M>& a, const MatExpr_<B, M>& b)
2529 { return (M)a ^ (M)b; }
2531 template<typename A, typename M> static inline
2532 MatExpr_<MatExpr_Op3_<M, M, int, M, MatOp_Bin_<Mat> >, M>
2533 operator ^ (const MatExpr_<A, M>& a, const M& b)
2534 { return (M)a ^ b; }
2536 template<typename A, typename M> static inline
2537 MatExpr_<MatExpr_Op3_<M, M, int, M, MatOp_Bin_<Mat> >, M>
2538 operator ^ (const M& a, const MatExpr_<A, M>& b)
2539 { return a ^ (M)b; }
2541 static inline Mat& operator &= (const Mat& a, const Mat& b)
2543 MatOp_Bin_<Mat>::apply( a, b, '&', (Mat&)a );
2547 static inline Mat& operator |= (const Mat& a, const Mat& b)
2549 MatOp_Bin_<Mat>::apply( a, b, '|', (Mat&)a );
2553 static inline Mat& operator ^= (const Mat& a, const Mat& b)
2555 MatOp_Bin_<Mat>::apply( a, b, '^', (Mat&)a );
2559 template<typename _Tp> static inline Mat_<_Tp>&
2560 operator &= (const Mat_<_Tp>& a, const Mat_<_Tp>& b)
2562 (Mat&)a &= (const Mat&)b;
2563 return (Mat_<_Tp>&)a;
2566 template<typename _Tp> static inline Mat_<_Tp>&
2567 operator |= (const Mat_<_Tp>& a, const Mat_<_Tp>& b)
2569 (Mat&)a |= (const Mat&)b;
2570 return (Mat_<_Tp>&)a;
2573 template<typename _Tp> static inline Mat_<_Tp>&
2574 operator ^= (const Mat_<_Tp>& a, const Mat_<_Tp>& b)
2576 (Mat&)a ^= (const Mat&)b;
2577 return (Mat_<_Tp>&)a;
2580 template<typename A, typename M> static inline M&
2581 operator &= (const M& a, const MatExpr_<A, M>& b)
2582 { return (a &= (M)b); }
2584 template<typename A, typename M> static inline M&
2585 operator |= (const M& a, const MatExpr_<A, M>& b)
2586 { return (a |= (M)b); }
2588 template<typename A, typename M> static inline M&
2589 operator ^= (const M& a, const MatExpr_<A, M>& b)
2590 { return (a ^= (M)b); }
2592 static inline MatExpr_<MatExpr_Op3_<Mat, Scalar, int, Mat, MatOp_BinS_<Mat> >, Mat>
2593 operator & (const Mat& a, const Scalar& s)
2595 typedef MatExpr_Op3_<Mat, Scalar, int, Mat, MatOp_BinS_<Mat> > MatExpr_Temp;
2596 return MatExpr_<MatExpr_Temp, Mat>(MatExpr_Temp(a, s, '&'));
2599 static inline MatExpr_<MatExpr_Op3_<Mat, Scalar, int, Mat, MatOp_BinS_<Mat> >, Mat>
2600 operator & (const Scalar& s, const Mat& a)
2603 static inline MatExpr_<MatExpr_Op3_<Mat, Scalar, int, Mat, MatOp_BinS_<Mat> >, Mat>
2604 operator | (const Mat& a, const Scalar& s)
2606 typedef MatExpr_Op3_<Mat, Scalar, int, Mat, MatOp_BinS_<Mat> > MatExpr_Temp;
2607 return MatExpr_<MatExpr_Temp, Mat>(MatExpr_Temp(a, s, '|'));
2610 static inline MatExpr_<MatExpr_Op3_<Mat, Scalar, int, Mat, MatOp_BinS_<Mat> >, Mat>
2611 operator | (const Scalar& s, const Mat& a)
2614 static inline MatExpr_<MatExpr_Op3_<Mat, Scalar, int, Mat, MatOp_BinS_<Mat> >, Mat>
2615 operator ^ (const Mat& a, const Scalar& s)
2617 typedef MatExpr_Op3_<Mat, Scalar, int, Mat, MatOp_BinS_<Mat> > MatExpr_Temp;
2618 return MatExpr_<MatExpr_Temp, Mat>(MatExpr_Temp(a, s, '^'));
2621 static inline MatExpr_<MatExpr_Op3_<Mat, Scalar, int, Mat, MatOp_BinS_<Mat> >, Mat>
2622 operator ^ (const Scalar& s, const Mat& a)
2625 static inline MatExpr_<MatExpr_Op3_<Mat, Scalar, int, Mat, MatOp_BinS_<Mat> >, Mat>
2626 operator ~ (const Mat& a)
2628 typedef MatExpr_Op3_<Mat, Scalar, int, Mat, MatOp_BinS_<Mat> > MatExpr_Temp;
2629 return MatExpr_<MatExpr_Temp, Mat>(MatExpr_Temp(a, Scalar(), '~'));
2632 template<typename _Tp> static inline
2633 MatExpr_<MatExpr_Op3_<Mat_<_Tp>, Scalar, int, Mat_<_Tp>, MatOp_BinS_<Mat> >, Mat_<_Tp> >
2634 operator & (const Mat_<_Tp>& a, const Scalar& s)
2636 typedef MatExpr_Op3_<Mat_<_Tp>, Scalar, int, Mat_<_Tp>, MatOp_BinS_<Mat> > MatExpr_Temp;
2637 return MatExpr_<MatExpr_Temp, Mat_<_Tp> >(MatExpr_Temp(a, s, '&'));
2640 template<typename _Tp> static inline
2641 MatExpr_<MatExpr_Op3_<Mat_<_Tp>, Scalar, int, Mat_<_Tp>, MatOp_BinS_<Mat> >, Mat_<_Tp> >
2642 operator & (const Scalar& s, const Mat_<_Tp>& a)
2645 template<typename _Tp> static inline
2646 MatExpr_<MatExpr_Op3_<Mat_<_Tp>, Scalar, int, Mat_<_Tp>, MatOp_BinS_<Mat> >, Mat_<_Tp> >
2647 operator | (const Mat_<_Tp>& a, const Scalar& s)
2649 typedef MatExpr_Op3_<Mat_<_Tp>, Scalar, int, Mat_<_Tp>, MatOp_BinS_<Mat> > MatExpr_Temp;
2650 return MatExpr_<MatExpr_Temp, Mat_<_Tp> >(MatExpr_Temp(a, s, '|'));
2653 template<typename _Tp> static inline
2654 MatExpr_<MatExpr_Op3_<Mat_<_Tp>, Scalar, int, Mat_<_Tp>, MatOp_BinS_<Mat> >, Mat_<_Tp> >
2655 operator | (const Scalar& s, const Mat_<_Tp>& a)
2658 template<typename _Tp> static inline
2659 MatExpr_<MatExpr_Op3_<Mat_<_Tp>, Scalar, int, Mat_<_Tp>, MatOp_BinS_<Mat> >, Mat_<_Tp> >
2660 operator ^ (const Mat_<_Tp>& a, const Scalar& s)
2662 typedef MatExpr_Op3_<Mat_<_Tp>, Scalar, int, Mat_<_Tp>, MatOp_BinS_<Mat> > MatExpr_Temp;
2663 return MatExpr_<MatExpr_Temp, Mat_<_Tp> >(MatExpr_Temp(a, s, '^'));
2666 template<typename _Tp> static inline
2667 MatExpr_<MatExpr_Op3_<Mat_<_Tp>, Scalar, int, Mat_<_Tp>, MatOp_BinS_<Mat> >, Mat_<_Tp> >
2668 operator ^ (const Scalar& s, const Mat_<_Tp>& a)
2671 template<typename _Tp> static inline
2672 MatExpr_<MatExpr_Op3_<Mat_<_Tp>, Scalar, int, Mat_<_Tp>, MatOp_BinS_<Mat> >, Mat_<_Tp> >
2673 operator ~ (const Mat_<_Tp>& a)
2675 typedef MatExpr_Op3_<Mat_<_Tp>, Scalar, int, Mat_<_Tp>, MatOp_BinS_<Mat> > MatExpr_Temp;
2676 return MatExpr_<MatExpr_Temp, Mat_<_Tp> >(MatExpr_Temp(a, Scalar(), '~'));
2679 template<typename A, typename M> static inline
2680 MatExpr_<MatExpr_Op3_<M, Scalar, int, M, MatOp_BinS_<Mat> >, M >
2681 operator & (const MatExpr_<A, M>& a, const Scalar& s)
2682 { return (M)a & s; }
2684 template<typename A, typename M> static inline
2685 MatExpr_<MatExpr_Op3_<M, Scalar, int, M, MatOp_BinS_<Mat> >, M >
2686 operator & (const Scalar& s, const MatExpr_<A, M>& a)
2687 { return (M)a & s; }
2689 template<typename A, typename M> static inline
2690 MatExpr_<MatExpr_Op3_<M, Scalar, int, M, MatOp_BinS_<Mat> >, M >
2691 operator | (const MatExpr_<A, M>& a, const Scalar& s)
2692 { return (M)a | s; }
2694 template<typename A, typename M> static inline
2695 MatExpr_<MatExpr_Op3_<M, Scalar, int, M, MatOp_BinS_<Mat> >, M >
2696 operator | (const Scalar& s, const MatExpr_<A, M>& a)
2697 { return (M)a | s; }
2699 template<typename A, typename M> static inline
2700 MatExpr_<MatExpr_Op3_<M, Scalar, int, M, MatOp_BinS_<Mat> >, M >
2701 operator ^ (const MatExpr_<A, M>& a, const Scalar& s)
2702 { return (M)a ^ s; }
2704 template<typename A, typename M> static inline
2705 MatExpr_<MatExpr_Op3_<M, Scalar, int, M, MatOp_BinS_<Mat> >, M >
2706 operator ^ (const Scalar& s, const MatExpr_<A, M>& a)
2707 { return (M)a ^ s; }
2709 template<typename A, typename M> static inline
2710 MatExpr_<MatExpr_Op3_<M, Scalar, int, M, MatOp_BinS_<Mat> >, M >
2711 operator ~ (const MatExpr_<A, M>& a)
2714 static inline Mat& operator &= (const Mat& a, const Scalar& s)
2716 MatOp_BinS_<Mat>::apply( a, s, '&', (Mat&)a );
2720 static inline Mat& operator |= (const Mat& a, const Scalar& s)
2722 MatOp_BinS_<Mat>::apply( a, s, '|', (Mat&)a );
2726 static inline Mat& operator ^= (const Mat& a, const Scalar& s)
2728 MatOp_BinS_<Mat>::apply( a, s, '^', (Mat&)a );
2732 template<typename _Tp> static inline Mat_<_Tp>&
2733 operator &= (const Mat_<_Tp>& a, const Scalar& s)
2736 return (Mat_<_Tp>&)a;
2739 template<typename _Tp> static inline Mat_<_Tp>&
2740 operator |= (const Mat_<_Tp>& a, const Scalar& s)
2743 return (Mat_<_Tp>&)a;
2746 template<typename _Tp> static inline Mat_<_Tp>&
2747 operator ^= (const Mat_<_Tp>& a, const Scalar& s)
2750 return (Mat_<_Tp>&)a;
2753 ////////////////////////////// Comparison operations ///////////////////////////////
2755 static inline MatExpr_<MatExpr_Op3_<Mat, Mat, int, Mat, MatOp_Cmp_<Mat> >, Mat>
2756 operator == (const Mat& a, const Mat& b)
2758 typedef MatExpr_Op3_<Mat, Mat, int, Mat, MatOp_Cmp_<Mat> > MatExpr_Temp;
2759 return MatExpr_<MatExpr_Temp, Mat>(MatExpr_Temp(a, b, CMP_EQ));
2762 static inline MatExpr_<MatExpr_Op3_<Mat, Mat, int, Mat, MatOp_Cmp_<Mat> >, Mat>
2763 operator >= (const Mat& a, const Mat& b)
2765 typedef MatExpr_Op3_<Mat, Mat, int, Mat, MatOp_Cmp_<Mat> > MatExpr_Temp;
2766 return MatExpr_<MatExpr_Temp, Mat>(MatExpr_Temp(a, b, CMP_GE));
2769 static inline MatExpr_<MatExpr_Op3_<Mat, Mat, int, Mat, MatOp_Cmp_<Mat> >, Mat>
2770 operator > (const Mat& a, const Mat& b)
2772 typedef MatExpr_Op3_<Mat, Mat, int, Mat, MatOp_Cmp_<Mat> > MatExpr_Temp;
2773 return MatExpr_<MatExpr_Temp, Mat>(MatExpr_Temp(a, b, CMP_GT));
2776 static inline MatExpr_<MatExpr_Op3_<Mat, Mat, int, Mat, MatOp_Cmp_<Mat> >, Mat>
2777 operator <= (const Mat& a, const Mat& b)
2780 static inline MatExpr_<MatExpr_Op3_<Mat, Mat, int, Mat, MatOp_Cmp_<Mat> >, Mat>
2781 operator < (const Mat& a, const Mat& b)
2784 static inline MatExpr_<MatExpr_Op3_<Mat, Mat, int, Mat, MatOp_Cmp_<Mat> >, Mat>
2785 operator != (const Mat& a, const Mat& b)
2787 typedef MatExpr_Op3_<Mat, Mat, int, Mat, MatOp_Cmp_<Mat> > MatExpr_Temp;
2788 return MatExpr_<MatExpr_Temp, Mat>(MatExpr_Temp(a, b, CMP_NE));
2791 static inline MatExpr_<MatExpr_Op3_<Mat, double, int, Mat, MatOp_CmpS_<Mat> >, Mat>
2792 operator == (const Mat& a, double alpha)
2794 typedef MatExpr_Op3_<Mat, double, int, Mat, MatOp_CmpS_<Mat> > MatExpr_Temp;
2795 return MatExpr_<MatExpr_Temp, Mat>(MatExpr_Temp(a, alpha, CMP_EQ));
2798 static inline MatExpr_<MatExpr_Op3_<Mat, double, int, Mat, MatOp_CmpS_<Mat> >, Mat>
2799 operator >= (const Mat& a, double alpha)
2801 typedef MatExpr_Op3_<Mat, double, int, Mat, MatOp_CmpS_<Mat> > MatExpr_Temp;
2802 return MatExpr_<MatExpr_Temp, Mat>(MatExpr_Temp(a, alpha, CMP_GE));
2805 static inline MatExpr_<MatExpr_Op3_<Mat, double, int, Mat, MatOp_CmpS_<Mat> >, Mat>
2806 operator > (const Mat& a, double alpha)
2808 typedef MatExpr_Op3_<Mat, double, int, Mat, MatOp_CmpS_<Mat> > MatExpr_Temp;
2809 return MatExpr_<MatExpr_Temp, Mat>(MatExpr_Temp(a, alpha, CMP_GT));
2812 static inline MatExpr_<MatExpr_Op3_<Mat, double, int, Mat, MatOp_CmpS_<Mat> >, Mat>
2813 operator <= (const Mat& a, double alpha)
2815 typedef MatExpr_Op3_<Mat, double, int, Mat, MatOp_CmpS_<Mat> > MatExpr_Temp;
2816 return MatExpr_<MatExpr_Temp, Mat>(MatExpr_Temp(a, alpha, CMP_LE));
2819 static inline MatExpr_<MatExpr_Op3_<Mat, double, int, Mat, MatOp_CmpS_<Mat> >, Mat>
2820 operator < (const Mat& a, double alpha)
2822 typedef MatExpr_Op3_<Mat, double, int, Mat, MatOp_CmpS_<Mat> > MatExpr_Temp;
2823 return MatExpr_<MatExpr_Temp, Mat>(MatExpr_Temp(a, alpha, CMP_LT));
2826 static inline MatExpr_<MatExpr_Op3_<Mat, double, int, Mat, MatOp_CmpS_<Mat> >, Mat>
2827 operator != (const Mat& a, double alpha)
2829 typedef MatExpr_Op3_<Mat, double, int, Mat, MatOp_CmpS_<Mat> > MatExpr_Temp;
2830 return MatExpr_<MatExpr_Temp, Mat>(MatExpr_Temp(a, alpha, CMP_NE));
2833 static inline MatExpr_<MatExpr_Op3_<Mat, double, int, Mat, MatOp_CmpS_<Mat> >, Mat>
2834 operator == (double alpha, const Mat& a)
2835 { return a == alpha; }
2837 static inline MatExpr_<MatExpr_Op3_<Mat, double, int, Mat, MatOp_CmpS_<Mat> >, Mat>
2838 operator >= (double alpha, const Mat& a)
2839 { return a <= alpha; }
2841 static inline MatExpr_<MatExpr_Op3_<Mat, double, int, Mat, MatOp_CmpS_<Mat> >, Mat>
2842 operator > (double alpha, const Mat& a)
2843 { return a < alpha; }
2845 static inline MatExpr_<MatExpr_Op3_<Mat, double, int, Mat, MatOp_CmpS_<Mat> >, Mat>
2846 operator <= (double alpha, const Mat& a)
2847 { return a >= alpha; }
2849 static inline MatExpr_<MatExpr_Op3_<Mat, double, int, Mat, MatOp_CmpS_<Mat> >, Mat>
2850 operator < (double alpha, const Mat& a)
2851 { return a > alpha; }
2853 static inline MatExpr_<MatExpr_Op3_<Mat, double, int, Mat, MatOp_CmpS_<Mat> >, Mat>
2854 operator != (double alpha, const Mat& a)
2855 { return a != alpha; }
2857 /////////////////////////////// Miscellaneous operations //////////////////////////////
2860 static inline MatExpr_<MatExpr_Op3_<Mat, Mat, int, Mat, MatOp_Bin_<Mat> >, Mat>
2861 max(const Mat& a, const Mat& b)
2863 typedef MatExpr_Op3_<Mat, Mat, int, Mat, MatOp_Bin_<Mat> > MatExpr_Temp;
2864 return MatExpr_<MatExpr_Temp, Mat>(MatExpr_Temp(a, b, 'M'));
2868 static inline MatExpr_<MatExpr_Op3_<Mat, Mat, int, Mat, MatOp_Bin_<Mat> >, Mat>
2869 min(const Mat& a, const Mat& b)
2871 typedef MatExpr_Op3_<Mat, Mat, int, Mat, MatOp_Bin_<Mat> > MatExpr_Temp;
2872 return MatExpr_<MatExpr_Temp, Mat>(MatExpr_Temp(a, b, 'm'));
2876 static inline MatExpr_<MatExpr_Op3_<Mat, Scalar, int, Mat, MatOp_BinS_<Mat> >, Mat>
2879 typedef MatExpr_Op3_<Mat, Scalar, int, Mat, MatOp_BinS_<Mat> > MatExpr_Temp;
2880 return MatExpr_<MatExpr_Temp, Mat>(MatExpr_Temp(a, Scalar(0), 'a'));
2884 template<typename _Tp> static inline
2885 MatExpr_<MatExpr_Op3_<Mat_<_Tp>, Mat_<_Tp>, int, Mat_<_Tp>,
2886 MatOp_Bin_<Mat> >, Mat_<_Tp> >
2887 max(const Mat_<_Tp>& a, const Mat_<_Tp>& b)
2889 typedef MatExpr_Op3_<Mat_<_Tp>, Mat_<_Tp>, int, Mat_<_Tp>,
2890 MatOp_Bin_<Mat> > MatExpr_Temp;
2891 return MatExpr_<MatExpr_Temp, Mat_<_Tp> >(MatExpr_Temp(
2896 template<typename _Tp> static inline
2897 MatExpr_<MatExpr_Op3_<Mat_<_Tp>, Mat_<_Tp>, int, Mat_<_Tp>,
2898 MatOp_Bin_<Mat> >, Mat_<_Tp> >
2899 min(const Mat_<_Tp>& a, const Mat_<_Tp>& b)
2901 typedef MatExpr_Op3_<Mat_<_Tp>, Mat_<_Tp>, int, Mat_<_Tp>,
2902 MatOp_Bin_<Mat> > MatExpr_Temp;
2903 return MatExpr_<MatExpr_Temp, Mat_<_Tp> >(MatExpr_Temp(
2908 template<typename _Tp> static inline
2909 MatExpr_<MatExpr_Op3_<Mat_<_Tp>, Scalar, int, Mat_<_Tp>,
2910 MatOp_BinS_<Mat> >, Mat_<_Tp> >
2911 abs(const Mat_<_Tp>& a, const Mat_<_Tp>& b)
2913 typedef MatExpr_Op3_<Mat_<_Tp>, Scalar, int, Mat_<_Tp>,
2914 MatOp_Bin_<Mat> > MatExpr_Temp;
2915 return MatExpr_<MatExpr_Temp, Mat_<_Tp> >(MatExpr_Temp(
2916 a, Scalar(0), 'a'));
2920 template<typename A, typename B, typename M> static inline
2921 MatExpr_<MatExpr_Op3_<M, M, int, M, MatOp_Bin_<Mat> >, M>
2922 max(const MatExpr_<A, M>& a, const MatExpr_<B, M>& b)
2923 { return max((M)a, (M)b); }
2925 template<typename A, typename M> static inline
2926 MatExpr_<MatExpr_Op3_<M, M, int, M, MatOp_Bin_<Mat> >, M>
2927 max(const MatExpr_<A, M>& a, const M& b)
2928 { return max((M)a, b); }
2930 template<typename A, typename M> static inline
2931 MatExpr_<MatExpr_Op3_<M, M, int, M, MatOp_Bin_<Mat> >, M>
2932 max(const M& a, const MatExpr_<A, M>& b)
2933 { return max(a, (M)b); }
2936 template<typename A, typename B, typename M> static inline
2937 MatExpr_<MatExpr_Op3_<M, M, int, M, MatOp_Bin_<Mat> >, M>
2938 min(const MatExpr_<A, M>& a, const MatExpr_<B, M>& b)
2939 { return min((M)a, (M)b); }
2941 template<typename A, typename M> static inline
2942 MatExpr_<MatExpr_Op3_<M, M, int, M, MatOp_Bin_<Mat> >, M>
2943 min(const MatExpr_<A, M>& a, const M& b)
2944 { return min((M)a, b); }
2946 template<typename A, typename M> static inline
2947 MatExpr_<MatExpr_Op3_<M, M, int, M, MatOp_Bin_<Mat> >, M>
2948 min(const M& a, const MatExpr_<A, M>& b)
2949 { return min(a, (M)b); }
2952 template<typename A, typename B, typename M> static inline
2953 MatExpr_<MatExpr_Op3_<M, M, int, M, MatOp_Bin_<Mat> >, M>
2954 abs(const MatExpr_<MatExpr_Op2_<A, B, M, MatOp_Sub_<Mat> >, M>& a)
2956 typedef MatExpr_Op3_<M, M, int, M, MatOp_Bin_<Mat> > MatExpr_Temp;
2957 return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp((M)a.e.a1, (M)a.e.a2, 'a'));
2960 template<typename _Tp> void merge(const Mat_<_Tp>* mvbegin, size_t count, Mat& dst)
2961 { merge( (const Mat*)mvbegin, count, dst ); }
2963 static inline void split(const Mat& m, vector<Mat>& mv)
2965 mv.resize(m.channels());
2966 if(m.channels() > 0)
2970 template<typename _Tp> void split(const Mat& src, vector<Mat_<_Tp> >& mv)
2971 { split(src, (vector<Mat>&)mv ); }
2973 static inline void merge(const vector<Mat>& mv, Mat& dst)
2974 { merge(&mv[0], mv.size(), dst); }
2976 static inline void mixChannels(const vector<Mat>& src, vector<Mat>& dst,
2977 const int* fromTo, int npairs)
2979 mixChannels(&src[0], (int)src.size(), &dst[0], (int)dst.size(), fromTo, npairs);
2982 ///// Element-wise multiplication
2984 inline MatExpr_<MatExpr_Op4_<Mat, Mat, double, char, Mat, MatOp_MulDiv_<Mat> >, Mat>
2985 Mat::mul(const Mat& m, double scale) const
2987 typedef MatExpr_Op4_<Mat, Mat, double, char, Mat, MatOp_MulDiv_<Mat> > MatExpr_Temp;
2988 return MatExpr_<MatExpr_Temp, Mat>(MatExpr_Temp(*this, m, scale, '*'));
2991 inline MatExpr_<MatExpr_Op4_<Mat, Mat, double, char, Mat, MatOp_MulDiv_<Mat> >, Mat>
2992 Mat::mul(const MatExpr_<MatExpr_Op2_<Mat, double, Mat, MatOp_Scale_<Mat> >, Mat>& m, double scale) const
2994 typedef MatExpr_Op4_<Mat, Mat, double, char, Mat, MatOp_MulDiv_<Mat> > MatExpr_Temp;
2995 return MatExpr_<MatExpr_Temp, Mat>(MatExpr_Temp(*this, m.e.a1, m.e.a2*scale, '*'));
2998 inline MatExpr_<MatExpr_Op4_<Mat, Mat, double, char, Mat, MatOp_MulDiv_<Mat> >, Mat>
2999 Mat::mul(const MatExpr_<MatExpr_Op2_<Mat, double, Mat, MatOp_DivRS_<Mat> >, Mat>& m, double scale) const
3001 typedef MatExpr_Op4_<Mat, Mat, double, char, Mat, MatOp_MulDiv_<Mat> > MatExpr_Temp;
3002 return MatExpr_<MatExpr_Temp, Mat>(MatExpr_Temp(*this, m.e.a1, scale/m.e.a2, '/'));
3005 template<typename _Tp> inline
3006 MatExpr_<MatExpr_Op4_<Mat_<_Tp>, Mat_<_Tp>, double, char, Mat_<_Tp>, MatOp_MulDiv_<Mat> >, Mat_<_Tp> >
3007 Mat_<_Tp>::mul(const Mat_<_Tp>& m, double scale) const
3009 typedef MatExpr_Op4_<Mat_<_Tp>, Mat_<_Tp>, double, char, Mat_<_Tp>, MatOp_MulDiv_<Mat> > MatExpr_Temp;
3010 return MatExpr_<MatExpr_Temp, Mat_<_Tp> >(MatExpr_Temp(*this, m, scale, '*'));
3013 template<typename _Tp> inline
3014 MatExpr_<MatExpr_Op4_<Mat_<_Tp>, Mat_<_Tp>, double, char, Mat_<_Tp>, MatOp_MulDiv_<Mat> >, Mat_<_Tp> >
3015 Mat_<_Tp>::mul(const MatExpr_<MatExpr_Op2_<Mat_<_Tp>, double, Mat_<_Tp>, MatOp_Scale_<Mat> >, Mat_<_Tp> >& m, double scale) const
3017 typedef MatExpr_Op4_<Mat_<_Tp>, Mat_<_Tp>, double, char, Mat_<_Tp>, MatOp_MulDiv_<Mat> > MatExpr_Temp;
3018 return MatExpr_<MatExpr_Temp, Mat_<_Tp> >(MatExpr_Temp(*this, m.e.a1, m.e.a2*scale, '*'));
3021 template<typename _Tp> inline
3022 MatExpr_<MatExpr_Op4_<Mat_<_Tp>, Mat_<_Tp>, double, char, Mat_<_Tp>, MatOp_MulDiv_<Mat> >, Mat_<_Tp> >
3023 Mat_<_Tp>::mul(const MatExpr_<MatExpr_Op2_<Mat_<_Tp>, double, Mat_<_Tp>, MatOp_DivRS_<Mat> >, Mat_<_Tp> >& m, double scale) const
3025 typedef MatExpr_Op4_<Mat_<_Tp>, Mat_<_Tp>, double, char, Mat_<_Tp>, MatOp_MulDiv_<Mat> > MatExpr_Temp;
3026 return MatExpr_<MatExpr_Temp, Mat_<_Tp> >(MatExpr_Temp(*this, m.e.a1, scale/m.e.a2, '/'));
3029 template<typename A, typename B, typename M> static inline
3030 MatExpr_<MatExpr_Op4_<M, M, double, char, M, MatOp_MulDiv_<Mat> >, M>
3031 operator * (const MatExpr_<MatExpr_Op4_<A, B, double, char, M, MatOp_MulDiv_<Mat> >, M>& a,
3034 typedef MatExpr_Op4_<M, M, double, char, M, MatOp_MulDiv_<Mat> > MatExpr_Temp;
3035 return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp((M)a.e.a1, (M)a.e.a2, a.e.a3*alpha, a.e.a4));
3038 template<typename A, typename B, typename M> static inline
3039 MatExpr_<MatExpr_Op4_<M, M, double, char, M, MatOp_MulDiv_<Mat> >, M>
3040 operator * (double alpha,
3041 const MatExpr_<MatExpr_Op4_<A, B, double, char, M, MatOp_MulDiv_<Mat> >, M>& a)
3045 ////// Element-wise division
3047 static inline MatExpr_<MatExpr_Op4_<Mat, Mat, double, char, Mat, MatOp_MulDiv_<Mat> >, Mat>
3048 operator / (const Mat& a, const Mat& b)
3050 typedef MatExpr_Op4_<Mat, Mat, double, char, Mat, MatOp_MulDiv_<Mat> > MatExpr_Temp;
3051 return MatExpr_<MatExpr_Temp, Mat>(MatExpr_Temp(a, b, 1, '/'));
3054 template<typename _Tp> static inline
3055 MatExpr_<MatExpr_Op4_<Mat_<_Tp>, Mat_<_Tp>, double,
3056 char, Mat_<_Tp>, MatOp_MulDiv_<Mat> >, Mat_<_Tp> >
3057 operator / (const Mat_<_Tp>& a, const Mat_<_Tp>& b)
3059 typedef MatExpr_Op4_<Mat_<_Tp>, Mat_<_Tp>, double,
3060 char, Mat_<_Tp>, MatOp_MulDiv_<Mat> > MatExpr_Temp;
3061 return MatExpr_<MatExpr_Temp, Mat_<_Tp> >(MatExpr_Temp(a, b, 1, '/'));
3064 template<typename A, typename B, typename M> static inline
3065 MatExpr_<MatExpr_Op4_<M, M, double, char, M, MatOp_MulDiv_<Mat> >, M>
3066 operator / (const MatExpr_<A, M>& a, const MatExpr_<B, M>& b)
3067 { return (M)a/(M)b; }
3069 template<typename A, typename M> static inline
3070 MatExpr_<MatExpr_Op4_<M, M, double, char, M, MatOp_MulDiv_<Mat> >, M>
3071 operator / (const MatExpr_<A, M>& a, const M& b)
3074 template<typename A, typename M> static inline
3075 MatExpr_<MatExpr_Op4_<M, M, double, char, M, MatOp_MulDiv_<Mat> >, M>
3076 operator / (const M& a, const MatExpr_<A, M>& b)
3079 template<typename A, typename M> static inline
3080 MatExpr_<MatExpr_Op4_<M, M, double, char, M, MatOp_MulDiv_<Mat> >, M>
3081 operator / (const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& a,
3083 { return ((M)a.e.a1/b)*a.e.a2; }
3085 template<typename A, typename M> static inline
3086 MatExpr_<MatExpr_Op4_<M, M, double, char, M, MatOp_MulDiv_<Mat> >, M>
3087 operator / (const M& a,
3088 const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& b)
3089 { return (a/(M)b.e.a1)*(1./b.e.a2); }
3091 template<typename A, typename B, typename M> static inline
3092 MatExpr_<MatExpr_Op4_<M, M, double, char, M, MatOp_MulDiv_<Mat> >, M>
3093 operator / (const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& a,
3094 const MatExpr_<MatExpr_Op2_<B, double, M, MatOp_Scale_<Mat> >, M>& b)
3095 { return ((M)a.e.a1/(M)b.e.a1)*(a.e.a2/b.e.a2); }
3097 template<typename A, typename M> static inline
3098 MatExpr_<MatExpr_Op4_<M, M, double, char, M, MatOp_MulDiv_<Mat> >, M>
3099 operator / (const M& a,
3100 const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_DivRS_<Mat> >, M>& b)
3101 { return a.mul((M)b.e.a1, 1./b.e.a2); }
3103 template<typename A, typename B, typename M> static inline
3104 MatExpr_<MatExpr_Op4_<M, M, double, char, M, MatOp_MulDiv_<Mat> >, M>
3105 operator / (const MatExpr_<A, M>& a,
3106 const MatExpr_<MatExpr_Op2_<B, double, M, MatOp_DivRS_<Mat> >, M>& b)
3107 { return ((M)a).mul((M)b.e.a1, 1./b.e.a2); }
3110 MatExpr_<MatExpr_Op2_<Mat, double, Mat, MatOp_DivRS_<Mat> >, Mat >
3111 operator / (double alpha, const Mat& a)
3113 typedef MatExpr_Op2_<Mat, double, Mat, MatOp_DivRS_<Mat> > MatExpr_Temp;
3114 return MatExpr_<MatExpr_Temp, Mat>(MatExpr_Temp(a, alpha));
3117 static inline Mat& operator /= (const Mat& a, double alpha)
3119 MatOp_Scale_<Mat>::apply( a, 1./alpha, (Mat&)a );
3123 template<typename _Tp>
3124 static inline Mat_<_Tp>& operator /= (const Mat_<_Tp>& a, double alpha)
3126 MatOp_Scale_<Mat>::apply( a, 1./alpha, (Mat&)a );
3127 return (Mat_<_Tp>&)a;
3130 template<typename _Tp> static inline
3131 MatExpr_<MatExpr_Op2_<Mat_<_Tp>, double, Mat_<_Tp>, MatOp_DivRS_<Mat> >, Mat_<_Tp> >
3132 operator / (double alpha, const Mat_<_Tp>& a)
3134 typedef MatExpr_Op2_<Mat_<_Tp>, double, Mat_<_Tp>,
3135 MatOp_DivRS_<Mat> > MatExpr_Temp;
3136 return MatExpr_<MatExpr_Temp, Mat_<_Tp> >(MatExpr_Temp(a, alpha));
3139 template<typename A, typename M> static inline
3140 MatExpr_<MatExpr_Op2_<M, double, M, MatOp_DivRS_<Mat> >, M>
3141 operator / (double alpha, const MatExpr_<A, M>& a)
3142 { return alpha/(M)a; }
3144 template<typename A, typename M> static inline
3145 MatExpr_<MatExpr_Op2_<M, double, M, MatOp_DivRS_<Mat> >, M>
3146 operator / (double alpha,
3147 const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& a)
3148 { return (alpha/a.e.a2)/(M)a.e.a1; }
3150 template<typename A, typename M> static inline
3151 MatExpr_<MatExpr_Op2_<M, double, M, MatOp_Scale_<Mat> >, M>
3152 operator / (double alpha,
3153 const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_DivRS_<Mat> >, M>& a)
3154 { return (M)a.e.a1*(alpha/a.e.a2); }
3156 static inline Mat& operator /= (const Mat& a, const Mat& b)
3158 MatOp_MulDiv_<Mat>::apply( a, b, 1, '/', (Mat&)a );
3162 template<typename A, typename M>
3163 static inline M& operator /= (const M& a, const MatExpr_<MatExpr_Op2_<A, double,
3164 M, MatOp_Scale_<Mat> >, M>& b)
3166 MatOp_MulDiv_<Mat>::apply( a, (M)b.e.a1, 1./b.e.a2, '/', (M&)a );
3170 template<typename A, typename M>
3171 static inline M& operator /= (const M& a, const MatExpr_<MatExpr_Op2_<A, double,
3172 M, MatOp_DivRS_<Mat> >, M>& b)
3174 MatOp_MulDiv_<Mat>::apply( a, (M)b.e.a1, 1./b.e.a2, '*', (M&)a );
3178 // Mat Inversion and solving linear systems
3180 inline MatExpr_<MatExpr_Op2_<Mat, int, Mat, MatOp_Inv_<Mat> >, Mat>
3181 Mat::inv(int method) const
3183 typedef MatExpr_Op2_<Mat, int, Mat, MatOp_Inv_<Mat> > MatExpr_Temp;
3184 return MatExpr_<MatExpr_Temp, Mat>(MatExpr_Temp(*this, method));
3187 template<typename _Tp> inline
3188 MatExpr_<MatExpr_Op2_<Mat_<_Tp>, int, Mat_<_Tp>, MatOp_Inv_<Mat> >, Mat_<_Tp> >
3189 Mat_<_Tp>::inv(int method) const
3191 typedef MatExpr_Op2_<Mat_<_Tp>, int, Mat_<_Tp>, MatOp_Inv_<Mat> > MatExpr_Temp;
3192 return MatExpr_<MatExpr_Temp, Mat_<_Tp> >(MatExpr_Temp(*this, method));
3195 template<typename A, typename M> static inline
3196 MatExpr_<MatExpr_Op3_<M, M, int, M, MatOp_Solve_<Mat> >, M>
3197 operator * (const MatExpr_<MatExpr_Op2_<A, int, M, MatOp_Inv_<Mat> >, M>& a,
3200 typedef MatExpr_Op3_<M, M, int, M, MatOp_Solve_<Mat> > MatExpr_Temp;
3201 return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp((M)a.e.a1, b, a.e.a2));
3204 template<typename A, typename B, typename M> static inline
3205 MatExpr_<MatExpr_Op3_<M, M, int, M, MatOp_Solve_<Mat> >, M>
3206 operator * (const MatExpr_<MatExpr_Op2_<A, int, M, MatOp_Inv_<Mat> >, M>& a,
3207 const MatExpr_<B, M>& b)
3211 /////////////////////////////// Initialization ////////////////////////////////////////
3213 inline MatExpr_Initializer Mat::zeros(int rows, int cols, int type)
3215 typedef MatExpr_Op4_<Size, int, Scalar, int, Mat, MatOp_Set_<Mat> > MatExpr_Temp;
3216 return MatExpr_<MatExpr_Temp, Mat>(MatExpr_Temp(Size(cols, rows), type, 0, 0));
3219 inline MatExpr_Initializer Mat::zeros(Size size, int type)
3221 return zeros(size.height, size.width, type);
3224 inline MatExpr_Initializer Mat::ones(int rows, int cols, int type)
3226 typedef MatExpr_Op4_<Size, int, Scalar, int, Mat, MatOp_Set_<Mat> > MatExpr_Temp;
3227 return MatExpr_<MatExpr_Temp, Mat>(MatExpr_Temp(Size(cols, rows), type, 1, 1));
3230 inline MatExpr_Initializer Mat::ones(Size size, int type)
3232 return ones(size.height, size.width, type);
3235 inline MatExpr_Initializer Mat::eye(int rows, int cols, int type)
3237 typedef MatExpr_Op4_<Size, int, Scalar, int, Mat, MatOp_Set_<Mat> > MatExpr_Temp;
3238 return MatExpr_Initializer(MatExpr_Temp(Size(cols, rows), type, 1, 2));
3241 inline MatExpr_Initializer Mat::eye(Size size, int type)
3243 return eye(size.height, size.width, type);
3246 static inline MatExpr_Initializer operator * (const MatExpr_Initializer& a, double alpha)
3248 typedef MatExpr_Op4_<Size, int, Scalar, int, Mat, MatOp_Set_<Mat> > MatExpr_Temp;
3249 return MatExpr_Initializer(MatExpr_Temp(a.e.a1, a.e.a2, a.e.a3*alpha, a.e.a4));
3252 static inline MatExpr_Initializer operator * (double alpha, MatExpr_Initializer& a)
3254 typedef MatExpr_Op4_<Size, int, Scalar, int, Mat, MatOp_Set_<Mat> > MatExpr_Temp;
3255 return MatExpr_Initializer(MatExpr_Temp(a.e.a1, a.e.a2, a.e.a3*alpha, a.e.a4));
3258 template<typename _Tp> inline MatExpr_Initializer Mat_<_Tp>::zeros(int rows, int cols)
3259 { return Mat::zeros(rows, cols, DataType<_Tp>::type); }
3261 template<typename _Tp> inline MatExpr_Initializer Mat_<_Tp>::zeros(Size size)
3262 { return Mat::zeros(size, DataType<_Tp>::type); }
3264 template<typename _Tp> inline MatExpr_Initializer Mat_<_Tp>::ones(int rows, int cols)
3265 { return Mat::ones(rows, cols, DataType<_Tp>::type); }
3267 template<typename _Tp> inline MatExpr_Initializer Mat_<_Tp>::ones(Size size)
3268 { return Mat::ones(size, DataType<_Tp>::type); }
3270 template<typename _Tp> inline MatExpr_Initializer Mat_<_Tp>::eye(int rows, int cols)
3271 { return Mat::eye(rows, cols, DataType<_Tp>::type); }
3273 template<typename _Tp> inline MatExpr_Initializer Mat_<_Tp>::eye(Size size)
3274 { return Mat::eye(size, DataType<_Tp>::type); }
3277 //////////// Iterators & Comma initializers //////////////////
3279 template<typename _Tp> inline MatConstIterator_<_Tp>::MatConstIterator_()
3280 : m(0), ptr(0), sliceEnd(0) {}
3282 template<typename _Tp> inline MatConstIterator_<_Tp>::MatConstIterator_(const Mat_<_Tp>* _m) : m(_m)
3288 ptr = (_Tp*)_m->data;
3289 sliceEnd = ptr + (_m->isContinuous() ? _m->rows*_m->cols : _m->cols);
3293 template<typename _Tp> inline MatConstIterator_<_Tp>::
3294 MatConstIterator_(const Mat_<_Tp>* _m, int _row, int _col) : m(_m)
3300 CV_DbgAssert( (unsigned)_row < _m->rows && (unsigned)_col < _m->cols );
3301 ptr = (_Tp*)(_m->data + _m->step*_row);
3302 sliceEnd = _m->isContinuous() ? (_Tp*)_m->data + _m->rows*_m->cols : ptr + _m->cols;
3307 template<typename _Tp> inline MatConstIterator_<_Tp>::
3308 MatConstIterator_(const Mat_<_Tp>* _m, Point _pt) : m(_m)
3314 CV_DbgAssert( (unsigned)_pt.y < (unsigned)_m->rows && (unsigned)_pt.x < (unsigned)_m->cols );
3315 ptr = (_Tp*)(_m->data + _m->step*_pt.y);
3316 sliceEnd = _m->isContinuous() ? (_Tp*)_m->data + _m->rows*_m->cols : ptr + _m->cols;
3321 template<typename _Tp> inline MatConstIterator_<_Tp>::
3322 MatConstIterator_(const MatConstIterator_& it)
3323 : m(it.m), ptr(it.ptr), sliceEnd(it.sliceEnd) {}
3325 template<typename _Tp> inline MatConstIterator_<_Tp>&
3326 MatConstIterator_<_Tp>::operator = (const MatConstIterator_& it )
3328 m = it.m; ptr = it.ptr; sliceEnd = it.sliceEnd;
3332 template<typename _Tp> inline _Tp MatConstIterator_<_Tp>::operator *() const { return *ptr; }
3334 template<typename _Tp> inline MatConstIterator_<_Tp>& MatConstIterator_<_Tp>::operator += (int ofs)
3336 if( !m || ofs == 0 )
3339 if( m->isContinuous() )
3341 if( ptr > sliceEnd )
3343 else if( ptr < (_Tp*)m->data )
3344 ptr = (_Tp*)m->data;
3346 else if( ptr >= sliceEnd || ptr < sliceEnd - m->cols )
3351 ofs += pt.y*cols + pt.x;
3352 if( ofs > cols*m->rows )
3357 pt.x = ofs - pt.y*cols;
3358 ptr = (_Tp*)(m->data + m->step*pt.y);
3359 sliceEnd = ptr + cols;
3365 template<typename _Tp> inline MatConstIterator_<_Tp>& MatConstIterator_<_Tp>::operator -= (int ofs)
3366 { return (*this += -ofs); }
3368 template<typename _Tp> inline MatConstIterator_<_Tp>& MatConstIterator_<_Tp>::operator --()
3369 { return (*this += -1); }
3371 template<typename _Tp> inline MatConstIterator_<_Tp> MatConstIterator_<_Tp>::operator --(int)
3373 MatConstIterator_ b = *this;
3378 template<typename _Tp> inline MatConstIterator_<_Tp>& MatConstIterator_<_Tp>::operator ++()
3380 if( m && ++ptr >= sliceEnd )
3388 template<typename _Tp> inline MatConstIterator_<_Tp> MatConstIterator_<_Tp>::operator ++(int)
3390 MatConstIterator_ b = *this;
3391 if( m && ++ptr >= sliceEnd )
3399 template<typename _Tp> inline Point MatConstIterator_<_Tp>::pos() const
3403 if( m->isContinuous() )
3405 int ofs = ptr - (_Tp*)m->data, y = ofs / m->cols, x = ofs - y*m->cols;
3410 int stepT = m->stepT(), y = (ptr - (_Tp*)m->data)/stepT, x = (ptr - (_Tp*)m->data) - y*stepT;
3415 template<typename _Tp> inline MatIterator_<_Tp>::MatIterator_() : MatConstIterator_<_Tp>() {}
3417 template<typename _Tp> inline MatIterator_<_Tp>::MatIterator_(Mat_<_Tp>* _m)
3418 : MatConstIterator_<_Tp>(_m) {}
3420 template<typename _Tp> inline MatIterator_<_Tp>::MatIterator_(Mat_<_Tp>* _m, int _row, int _col)
3421 : MatConstIterator_<_Tp>(_m, _row, _col) {}
3423 template<typename _Tp> inline MatIterator_<_Tp>::MatIterator_(const Mat_<_Tp>* _m, Point _pt)
3424 : MatConstIterator_<_Tp>(_m, _pt) {}
3426 template<typename _Tp> inline MatIterator_<_Tp>::MatIterator_(const MatIterator_& it)
3427 : MatConstIterator_<_Tp>(it) {}
3429 template<typename _Tp> inline MatIterator_<_Tp>& MatIterator_<_Tp>::operator = (const MatIterator_<_Tp>& it )
3431 this->m = it.m; this->ptr = it.ptr; this->sliceEnd = it.sliceEnd;
3435 template<typename _Tp> inline _Tp& MatIterator_<_Tp>::operator *() const { return *(this->ptr); }
3437 template<typename _Tp> inline MatIterator_<_Tp>& MatIterator_<_Tp>::operator += (int ofs)
3439 MatConstIterator_<_Tp>::operator += (ofs);
3443 template<typename _Tp> inline MatIterator_<_Tp>& MatIterator_<_Tp>::operator -= (int ofs)
3445 MatConstIterator_<_Tp>::operator += (-ofs);
3449 template<typename _Tp> inline MatIterator_<_Tp>& MatIterator_<_Tp>::operator --()
3451 MatConstIterator_<_Tp>::operator += (-1);
3455 template<typename _Tp> inline MatIterator_<_Tp> MatIterator_<_Tp>::operator --(int)
3457 MatIterator_ b = *this;
3458 MatConstIterator_<_Tp>::operator += (-1);
3462 template<typename _Tp> inline MatIterator_<_Tp>& MatIterator_<_Tp>::operator ++()
3464 if( this->m && ++this->ptr >= this->sliceEnd )
3467 MatConstIterator_<_Tp>::operator += (1);
3472 template<typename _Tp> inline MatIterator_<_Tp> MatIterator_<_Tp>::operator ++(int)
3474 MatIterator_ b = *this;
3475 if( this->m && ++this->ptr >= this->sliceEnd )
3478 MatConstIterator_<_Tp>::operator += (1);
3483 template<typename _Tp> static inline bool
3484 operator == (const MatConstIterator_<_Tp>& a, const MatConstIterator_<_Tp>& b)
3485 { return a.m == b.m && a.ptr == b.ptr; }
3487 template<typename _Tp> static inline bool
3488 operator != (const MatConstIterator_<_Tp>& a, const MatConstIterator_<_Tp>& b)
3489 { return !(a == b); }
3491 template<typename _Tp> static inline bool
3492 operator < (const MatConstIterator_<_Tp>& a, const MatConstIterator_<_Tp>& b)
3493 { return a.ptr < b.ptr; }
3495 template<typename _Tp> static inline bool
3496 operator > (const MatConstIterator_<_Tp>& a, const MatConstIterator_<_Tp>& b)
3497 { return a.ptr > b.ptr; }
3499 template<typename _Tp> static inline bool
3500 operator <= (const MatConstIterator_<_Tp>& a, const MatConstIterator_<_Tp>& b)
3501 { return a.ptr <= b.ptr; }
3503 template<typename _Tp> static inline bool
3504 operator >= (const MatConstIterator_<_Tp>& a, const MatConstIterator_<_Tp>& b)
3505 { return a.ptr >= b.ptr; }
3507 template<typename _Tp> static inline int
3508 operator - (const MatConstIterator_<_Tp>& b, const MatConstIterator_<_Tp>& a)
3512 if( a.sliceEnd == b.sliceEnd )
3513 return b.ptr - a.ptr;
3515 Point ap = a.pos(), bp = b.pos();
3517 return (bp.y - ap.y - 1)*a.m->cols + (a.m->cols - ap.x) + bp.x;
3519 return -((ap.y - bp.y - 1)*a.m->cols + (a.m->cols - bp.x) + ap.x);
3524 template<typename _Tp> static inline MatConstIterator_<_Tp>
3525 operator + (const MatConstIterator_<_Tp>& a, int ofs)
3526 { MatConstIterator_<_Tp> b = a; return b += ofs; }
3528 template<typename _Tp> static inline MatConstIterator_<_Tp>
3529 operator + (int ofs, const MatConstIterator_<_Tp>& a)
3530 { MatConstIterator_<_Tp> b = a; return b += ofs; }
3532 template<typename _Tp> static inline MatConstIterator_<_Tp>
3533 operator - (const MatConstIterator_<_Tp>& a, int ofs)
3534 { MatConstIterator_<_Tp> b = a; return b += -ofs; }
3536 template<typename _Tp> inline _Tp MatConstIterator_<_Tp>::operator [](int i) const
3537 { return *(*this + i); }
3539 template<typename _Tp> static inline MatIterator_<_Tp>
3540 operator + (const MatIterator_<_Tp>& a, int ofs)
3541 { MatIterator_<_Tp> b = a; return b += ofs; }
3543 template<typename _Tp> static inline MatIterator_<_Tp>
3544 operator + (int ofs, const MatIterator_<_Tp>& a)
3545 { MatIterator_<_Tp> b = a; return b += ofs; }
3547 template<typename _Tp> static inline MatIterator_<_Tp>
3548 operator - (const MatIterator_<_Tp>& a, int ofs)
3549 { MatIterator_<_Tp> b = a; return b += -ofs; }
3551 template<typename _Tp> inline _Tp& MatIterator_<_Tp>::operator [](int i) const
3552 { return *(*this + i); }
3554 template<typename _Tp> inline MatConstIterator_<_Tp> Mat_<_Tp>::begin() const
3555 { return Mat::begin<_Tp>(); }
3557 template<typename _Tp> inline MatConstIterator_<_Tp> Mat_<_Tp>::end() const
3558 { return Mat::end<_Tp>(); }
3560 template<typename _Tp> inline MatIterator_<_Tp> Mat_<_Tp>::begin()
3561 { return Mat::begin<_Tp>(); }
3563 template<typename _Tp> inline MatIterator_<_Tp> Mat_<_Tp>::end()
3564 { return Mat::end<_Tp>(); }
3566 template<typename _Tp> class CV_EXPORTS MatOp_Iter_
3571 static void apply(const MatIterator_<_Tp>& a, Mat& c, int type=-1)
3576 a.m->convertTo(c, type);
3580 template<typename _Tp> inline MatCommaInitializer_<_Tp>::MatCommaInitializer_(Mat_<_Tp>* _m) :
3581 MatExpr_<MatExpr_Op1_<MatIterator_<_Tp>, Mat_<_Tp>,
3582 MatOp_Iter_<_Tp> >, Mat_<_Tp> >(MatIterator_<_Tp>(_m)) {}
3584 template<typename _Tp> template<typename T2> inline MatCommaInitializer_<_Tp>&
3585 MatCommaInitializer_<_Tp>::operator , (T2 v)
3587 CV_DbgAssert( this->e.a1 < this->e.a1.m->end() );
3588 *this->e.a1 = _Tp(v); ++this->e.a1;
3592 template<typename _Tp> inline MatCommaInitializer_<_Tp>::operator Mat_<_Tp>() const
3594 CV_DbgAssert( this->e.a1 == this->e.a1.m->end() );
3595 return *this->e.a1.m;
3598 template<typename _Tp> inline Mat_<_Tp> MatCommaInitializer_<_Tp>::operator *() const
3600 CV_DbgAssert( this->e.a1 == this->e.a1.m->end() );
3601 return *this->e.a1.m;
3604 template<typename _Tp> inline void
3605 MatCommaInitializer_<_Tp>::assignTo(Mat& m, int type) const
3607 Mat_<_Tp>(*this).assignTo(m, type);
3610 template<typename _Tp, typename T2> static inline MatCommaInitializer_<_Tp>
3611 operator << (const Mat_<_Tp>& m, T2 val)
3613 MatCommaInitializer_<_Tp> commaInitializer((Mat_<_Tp>*)&m);
3614 return (commaInitializer, val);
3617 //////////////////////////////// MatND ////////////////////////////////
3619 inline MatND::MatND()
3620 : flags(MAGIC_VAL), dims(0), refcount(0), data(0), datastart(0), dataend(0)
3624 inline MatND::MatND(int _dims, const int* _sizes, int _type)
3625 : flags(MAGIC_VAL), dims(0), refcount(0), data(0), datastart(0), dataend(0)
3627 create(_dims, _sizes, _type);
3630 inline MatND::MatND(int _dims, const int* _sizes, int _type, const Scalar& _s)
3631 : flags(MAGIC_VAL), dims(0), refcount(0), data(0), datastart(0), dataend(0)
3633 create(_dims, _sizes, _type);
3637 inline MatND::MatND(const MatND& m)
3638 : flags(m.flags), dims(m.dims), refcount(m.refcount),
3639 data(m.data), datastart(m.datastart), dataend(m.dataend)
3642 for( i = 0; i < d; i++ )
3644 size[i] = m.size[i];
3645 step[i] = m.step[i];
3648 CV_XADD(refcount, 1);
3651 inline MatND::MatND(const CvMatND* m, bool copyData)
3652 : flags(MAGIC_VAL|(m->type & (CV_MAT_TYPE_MASK|CV_MAT_CONT_FLAG))),
3653 dims(m->dims), refcount(0), data(m->data.ptr)
3656 for( i = 0; i < d; i++ )
3658 size[i] = m->dim[i].size;
3659 step[i] = m->dim[i].step;
3662 dataend = datastart + size[0]*step[0];
3670 inline MatND::~MatND() { release(); }
3672 inline MatND& MatND::operator = (const MatND& m)
3677 CV_XADD(m.refcount, 1);
3682 datastart = m.datastart;
3683 dataend = m.dataend;
3684 refcount = m.refcount;
3686 for( i = 0; i < d; i++ )
3688 size[i] = m.size[i];
3689 step[i] = m.step[i];
3695 inline MatND MatND::clone() const
3702 inline MatND MatND::operator()(const Range* ranges) const
3704 return MatND(*this, ranges);
3707 inline void MatND::assignTo( MatND& m, int type ) const
3715 inline void MatND::addref()
3717 if( refcount ) CV_XADD(refcount, 1);
3720 inline void MatND::release()
3722 if( refcount && CV_XADD(refcount, -1) == 1 )
3723 fastFree(datastart);
3725 data = datastart = dataend = 0;
3729 inline bool MatND::isContinuous() const { return (flags & CONTINUOUS_FLAG) != 0; }
3730 inline size_t MatND::elemSize() const { return getElemSize(flags); }
3731 inline size_t MatND::elemSize1() const { return CV_ELEM_SIZE1(flags); }
3732 inline int MatND::type() const { return CV_MAT_TYPE(flags); }
3733 inline int MatND::depth() const { return CV_MAT_DEPTH(flags); }
3734 inline int MatND::channels() const { return CV_MAT_CN(flags); }
3736 inline size_t MatND::step1(int i) const
3737 { CV_DbgAssert((unsigned)i < (unsigned)dims); return step[i]/elemSize1(); }
3739 inline uchar* MatND::ptr(int i0)
3741 CV_DbgAssert( dims == 1 && data &&
3742 (unsigned)i0 < (unsigned)size[0] );
3743 return data + i0*step[0];
3746 inline const uchar* MatND::ptr(int i0) const
3748 CV_DbgAssert( dims == 1 && data &&
3749 (unsigned)i0 < (unsigned)size[0] );
3750 return data + i0*step[0];
3753 inline uchar* MatND::ptr(int i0, int i1)
3755 CV_DbgAssert( dims == 2 && data &&
3756 (unsigned)i0 < (unsigned)size[0] &&
3757 (unsigned)i1 < (unsigned)size[1] );
3758 return data + i0*step[0] + i1*step[1];
3761 inline const uchar* MatND::ptr(int i0, int i1) const
3763 CV_DbgAssert( dims == 2 && data &&
3764 (unsigned)i0 < (unsigned)size[0] &&
3765 (unsigned)i1 < (unsigned)size[1] );
3766 return data + i0*step[0] + i1*step[1];
3769 inline uchar* MatND::ptr(int i0, int i1, int i2)
3771 CV_DbgAssert( dims == 3 && data &&
3772 (unsigned)i0 < (unsigned)size[0] &&
3773 (unsigned)i1 < (unsigned)size[1] &&
3774 (unsigned)i2 < (unsigned)size[2] );
3775 return data + i0*step[0] + i1*step[1] + i2*step[2];
3778 inline const uchar* MatND::ptr(int i0, int i1, int i2) const
3780 CV_DbgAssert( dims == 3 && data &&
3781 (unsigned)i0 < (unsigned)size[0] &&
3782 (unsigned)i1 < (unsigned)size[1] &&
3783 (unsigned)i2 < (unsigned)size[2] );
3784 return data + i0*step[0] + i1*step[1] + i2*step[2];
3787 inline uchar* MatND::ptr(const int* idx)
3791 CV_DbgAssert( data );
3792 for( i = 0; i < d; i++ )
3794 CV_DbgAssert( (unsigned)idx[i] < (unsigned)size[i] );
3795 p += idx[i]*step[i];
3800 inline const uchar* MatND::ptr(const int* idx) const
3804 CV_DbgAssert( data );
3805 for( i = 0; i < d; i++ )
3807 CV_DbgAssert( (unsigned)idx[i] < (unsigned)size[i] );
3808 p += idx[i]*step[i];
3813 template<typename _Tp> inline _Tp& MatND::at(int i0)
3814 { return *(_Tp*)ptr(i0); }
3815 template<typename _Tp> inline const _Tp& MatND::at(int i0) const
3816 { return *(const _Tp*)ptr(i0); }
3817 template<typename _Tp> inline _Tp& MatND::at(int i0, int i1)
3818 { return *(_Tp*)ptr(i0, i1); }
3819 template<typename _Tp> inline const _Tp& MatND::at(int i0, int i1) const
3820 { return *(const _Tp*)ptr(i0, i1); }
3821 template<typename _Tp> inline _Tp& MatND::at(int i0, int i1, int i2)
3822 { return *(_Tp*)ptr(i0, i1, i2); }
3823 template<typename _Tp> inline const _Tp& MatND::at(int i0, int i1, int i2) const
3824 { return *(const _Tp*)ptr(i0, i1, i2); }
3825 template<typename _Tp> inline _Tp& MatND::at(const int* idx)
3826 { return *(_Tp*)ptr(idx); }
3827 template<typename _Tp> inline const _Tp& MatND::at(const int* idx) const
3828 { return *(const _Tp*)ptr(idx); }
3830 inline NAryMatNDIterator::NAryMatNDIterator()
3834 inline void subtract(const MatND& a, const Scalar& s, MatND& c, const MatND& mask=MatND())
3836 add(a, -s, c, mask);
3840 template<typename _Tp> inline MatND_<_Tp>::MatND_()
3842 flags = MAGIC_VAL | DataType<_Tp>::type;
3845 template<typename _Tp> inline MatND_<_Tp>::MatND_(int _dims, const int* _sizes)
3846 : MatND(_dims, _sizes, DataType<_Tp>::type)
3850 template<typename _Tp> inline MatND_<_Tp>::MatND_(int _dims, const int* _sizes, const _Tp& _s)
3851 : MatND(_dims, _sizes, DataType<_Tp>::type, Scalar(_s))
3855 template<typename _Tp> inline MatND_<_Tp>::MatND_(const MatND& m)
3857 if( m.type() == DataType<_Tp>::type )
3858 *this = (const MatND_<_Tp>&)m;
3860 m.convertTo(this, DataType<_Tp>::type);
3863 template<typename _Tp> inline MatND_<_Tp>::MatND_(const MatND_<_Tp>& m) : MatND(m)
3867 template<typename _Tp> inline MatND_<_Tp>::MatND_(const MatND_<_Tp>& m, const Range* ranges)
3872 template<typename _Tp> inline MatND_<_Tp>::MatND_(const CvMatND* m, bool copyData)
3874 *this = MatND(m, copyData || CV_MAT_TYPE(m->type) != DataType<_Tp>::type);
3877 template<typename _Tp> inline MatND_<_Tp>& MatND_<_Tp>::operator = (const MatND& m)
3879 if( DataType<_Tp>::type == m.type() )
3881 Mat::operator = (m);
3884 if( DataType<_Tp>::depth == m.depth() )
3886 return (*this = m.reshape(DataType<_Tp>::channels));
3888 CV_DbgAssert(DataType<_Tp>::channels == m.channels());
3889 m.convertTo(*this, DataType<_Tp>::type);
3893 template<typename _Tp> inline MatND_<_Tp>& MatND_<_Tp>::operator = (const MatND_<_Tp>& m)
3895 return ((MatND&)*this = m);
3898 template<typename _Tp> inline MatND_<_Tp>& MatND_<_Tp>::operator = (const _Tp& s)
3900 return (MatND&)*this = Scalar(s);
3903 template<typename _Tp> inline void MatND_<_Tp>::create(int _dims, const int* _sizes)
3905 MatND::create(_dims, _sizes, DataType<_Tp>::type);
3908 template<typename _Tp> template<typename _Tp2> inline MatND_<_Tp>::operator MatND_<_Tp2>() const
3910 return MatND_<_Tp2>((const MatND&)*this);
3913 template<typename _Tp> inline MatND_<_Tp> MatND_<_Tp>::clone() const
3920 template<typename _Tp> inline MatND_<_Tp>
3921 MatND_<_Tp>::operator()(const Range* ranges) const
3922 { return MatND_<_Tp>(*this, ranges); }
3924 template<typename _Tp> inline size_t MatND_<_Tp>::elemSize() const
3925 { return CV_ELEM_SIZE(DataType<_Tp>::type); }
3927 template<typename _Tp> inline size_t MatND_<_Tp>::elemSize1() const
3928 { return CV_ELEM_SIZE1(DataType<_Tp>::type); }
3930 template<typename _Tp> inline int MatND_<_Tp>::type() const
3931 { return DataType<_Tp>::type; }
3933 template<typename _Tp> inline int MatND_<_Tp>::depth() const
3934 { return DataType<_Tp>::depth; }
3936 template<typename _Tp> inline int MatND_<_Tp>::channels() const
3937 { return DataType<_Tp>::channels; }
3939 template<typename _Tp> inline size_t MatND_<_Tp>::stepT(int i) const
3941 CV_DbgAssert( (unsigned)i < (unsigned)dims );
3942 return step[i]/elemSize();
3945 template<typename _Tp> inline size_t MatND_<_Tp>::step1(int i) const
3947 CV_DbgAssert( (unsigned)i < (unsigned)dims );
3948 return step[i]/elemSize1();
3951 template<typename _Tp> inline _Tp& MatND_<_Tp>::operator ()(const int* idx)
3955 for( i = 0; i < d; i++ )
3958 CV_DbgAssert( (unsigned)ii < (unsigned)size[i] );
3964 template<typename _Tp> inline const _Tp& MatND_<_Tp>::operator ()(const int* idx) const
3966 const uchar* ptr = data;
3968 for( i = 0; i < d; i++ )
3971 CV_DbgAssert( (unsigned)ii < (unsigned)size[i] );
3974 return *(const _Tp*)ptr;
3977 template<typename _Tp> inline _Tp& MatND_<_Tp>::operator ()(int i0)
3979 CV_DbgAssert( dims == 1 &&
3980 (unsigned)i0 < (unsigned)size[0] );
3982 return *(_Tp*)(data + i0*step[0]);
3985 template<typename _Tp> inline const _Tp& MatND_<_Tp>::operator ()(int i0) const
3987 CV_DbgAssert( dims == 1 &&
3988 (unsigned)i0 < (unsigned)size[0] );
3990 return *(const _Tp*)(data + i0*step[0]);
3994 template<typename _Tp> inline _Tp& MatND_<_Tp>::operator ()(int i0, int i1)
3996 CV_DbgAssert( dims == 2 &&
3997 (unsigned)i0 < (unsigned)size[0] &&
3998 (unsigned)i1 < (unsigned)size[1] );
4000 return *(_Tp*)(data + i0*step[0] + i1*step[1]);
4003 template<typename _Tp> inline const _Tp& MatND_<_Tp>::operator ()(int i0, int i1) const
4005 CV_DbgAssert( dims == 2 &&
4006 (unsigned)i0 < (unsigned)size[0] &&
4007 (unsigned)i1 < (unsigned)size[1] );
4009 return *(const _Tp*)(data + i0*step[0] + i1*step[1]);
4013 template<typename _Tp> inline _Tp& MatND_<_Tp>::operator ()(int i0, int i1, int i2)
4015 CV_DbgAssert( dims == 3 &&
4016 (unsigned)i0 < (unsigned)size[0] &&
4017 (unsigned)i1 < (unsigned)size[1] &&
4018 (unsigned)i2 < (unsigned)size[2] );
4020 return *(_Tp*)(data + i0*step[0] + i1*step[1] + i2*step[2]);
4023 template<typename _Tp> inline const _Tp& MatND_<_Tp>::operator ()(int i0, int i1, int i2) const
4025 CV_DbgAssert( dims == 3 &&
4026 (unsigned)i0 < (unsigned)size[0] &&
4027 (unsigned)i1 < (unsigned)size[1] &&
4028 (unsigned)i2 < (unsigned)size[2] );
4030 return *(const _Tp*)(data + i0*step[0] + i1*step[1] + i2*step[2]);
4034 static inline void merge(const vector<MatND>& mv, MatND& dst)
4036 merge(&mv[0], mv.size(), dst);
4039 static inline void split(const MatND& m, vector<MatND>& mv)
4041 mv.resize(m.channels());
4042 if(m.channels() > 0)
4046 static inline void mixChannels(const vector<MatND>& src, vector<MatND>& dst,
4047 const int* fromTo, int npairs)
4049 mixChannels(&src[0], (int)src.size(), &dst[0], (int)dst.size(), fromTo, npairs);
4052 //////////////////////////////// SparseMat ////////////////////////////////
4054 inline SparseMat::SparseMat()
4055 : flags(MAGIC_VAL), hdr(0)
4059 inline SparseMat::SparseMat(int _dims, const int* _sizes, int _type)
4060 : flags(MAGIC_VAL), hdr(0)
4062 create(_dims, _sizes, _type);
4065 inline SparseMat::SparseMat(const SparseMat& m)
4066 : flags(m.flags), hdr(m.hdr)
4071 inline SparseMat::~SparseMat()
4076 inline SparseMat& SparseMat::operator = (const SparseMat& m)
4081 CV_XADD(&m.hdr->refcount, 1);
4089 inline SparseMat& SparseMat::operator = (const Mat& m)
4090 { return (*this = SparseMat(m)); }
4092 inline SparseMat& SparseMat::operator = (const MatND& m)
4093 { return (*this = SparseMat(m)); }
4095 inline SparseMat SparseMat::clone() const
4103 inline void SparseMat::assignTo( SparseMat& m, int type ) const
4111 inline void SparseMat::addref()
4112 { if( hdr ) CV_XADD(&hdr->refcount, 1); }
4114 inline void SparseMat::release()
4116 if( hdr && CV_XADD(&hdr->refcount, -1) == 1 )
4121 inline size_t SparseMat::elemSize() const
4122 { return CV_ELEM_SIZE(flags); }
4124 inline size_t SparseMat::elemSize1() const
4125 { return CV_ELEM_SIZE1(flags); }
4127 inline int SparseMat::type() const
4128 { return CV_MAT_TYPE(flags); }
4130 inline int SparseMat::depth() const
4131 { return CV_MAT_DEPTH(flags); }
4133 inline int SparseMat::channels() const
4134 { return CV_MAT_CN(flags); }
4136 inline const int* SparseMat::size() const
4138 return hdr ? hdr->size : 0;
4141 inline int SparseMat::size(int i) const
4145 CV_DbgAssert((unsigned)i < (unsigned)hdr->dims);
4146 return hdr->size[i];
4151 inline int SparseMat::dims() const
4153 return hdr ? hdr->dims : 0;
4156 inline size_t SparseMat::nzcount() const
4158 return hdr ? hdr->nodeCount : 0;
4161 inline size_t SparseMat::hash(int i0) const
4166 inline size_t SparseMat::hash(int i0, int i1) const
4168 return (size_t)(unsigned)i0*HASH_SCALE + (unsigned)i1;
4171 inline size_t SparseMat::hash(int i0, int i1, int i2) const
4173 return ((size_t)(unsigned)i0*HASH_SCALE + (unsigned)i1)*HASH_SCALE + (unsigned)i2;
4176 inline size_t SparseMat::hash(const int* idx) const
4178 size_t h = (unsigned)idx[0];
4181 int i, d = hdr->dims;
4182 for( i = 1; i < d; i++ )
4183 h = h*HASH_SCALE + (unsigned)idx[i];
4187 template<typename _Tp> inline _Tp& SparseMat::ref(int i0, size_t* hashval)
4188 { return *(_Tp*)((SparseMat*)this)->ptr(i0, true, hashval); }
4190 template<typename _Tp> inline _Tp& SparseMat::ref(int i0, int i1, size_t* hashval)
4191 { return *(_Tp*)((SparseMat*)this)->ptr(i0, i1, true, hashval); }
4193 template<typename _Tp> inline _Tp& SparseMat::ref(int i0, int i1, int i2, size_t* hashval)
4194 { return *(_Tp*)((SparseMat*)this)->ptr(i0, i1, i2, true, hashval); }
4196 template<typename _Tp> inline _Tp& SparseMat::ref(const int* idx, size_t* hashval)
4197 { return *(_Tp*)((SparseMat*)this)->ptr(idx, true, hashval); }
4199 template<typename _Tp> inline _Tp SparseMat::value(int i0, size_t* hashval) const
4201 const _Tp* p = (const _Tp*)((SparseMat*)this)->ptr(i0, false, hashval);
4202 return p ? *p : _Tp();
4205 template<typename _Tp> inline _Tp SparseMat::value(int i0, int i1, size_t* hashval) const
4207 const _Tp* p = (const _Tp*)((SparseMat*)this)->ptr(i0, i1, false, hashval);
4208 return p ? *p : _Tp();
4211 template<typename _Tp> inline _Tp SparseMat::value(int i0, int i1, int i2, size_t* hashval) const
4213 const _Tp* p = (const _Tp*)((SparseMat*)this)->ptr(i0, i1, i2, false, hashval);
4214 return p ? *p : _Tp();
4217 template<typename _Tp> inline _Tp SparseMat::value(const int* idx, size_t* hashval) const
4219 const _Tp* p = (const _Tp*)((SparseMat*)this)->ptr(idx, false, hashval);
4220 return p ? *p : _Tp();
4223 template<typename _Tp> inline const _Tp* SparseMat::find(int i0, size_t* hashval) const
4224 { return (const _Tp*)((SparseMat*)this)->ptr(i0, true, hashval); }
4226 template<typename _Tp> inline const _Tp* SparseMat::find(int i0, int i1, size_t* hashval) const
4227 { return (const _Tp*)((SparseMat*)this)->ptr(i0, i1, true, hashval); }
4229 template<typename _Tp> inline const _Tp* SparseMat::find(int i0, int i1, int i2, size_t* hashval) const
4230 { return (const _Tp*)((SparseMat*)this)->ptr(i0, i1, i2, true, hashval); }
4232 template<typename _Tp> inline const _Tp* SparseMat::find(const int* idx, size_t* hashval) const
4233 { return (const _Tp*)((SparseMat*)this)->ptr(idx, true, hashval); }
4235 template<typename _Tp> inline _Tp& SparseMat::value(Node* n)
4236 { return *(_Tp*)((uchar*)n + hdr->valueOffset); }
4238 template<typename _Tp> inline const _Tp& SparseMat::value(const Node* n) const
4239 { return *(const _Tp*)((const uchar*)n + hdr->valueOffset); }
4241 inline SparseMat::Node* SparseMat::node(size_t nidx)
4242 { return (Node*)&hdr->pool[nidx]; }
4244 inline const SparseMat::Node* SparseMat::node(size_t nidx) const
4245 { return (const Node*)&hdr->pool[nidx]; }
4247 inline SparseMatIterator SparseMat::begin()
4248 { return SparseMatIterator(this); }
4250 inline SparseMatConstIterator SparseMat::begin() const
4251 { return SparseMatConstIterator(this); }
4253 inline SparseMatIterator SparseMat::end()
4254 { SparseMatIterator it(this); it.seekEnd(); return it; }
4256 inline SparseMatConstIterator SparseMat::end() const
4257 { SparseMatConstIterator it(this); it.seekEnd(); return it; }
4259 template<typename _Tp> inline SparseMatIterator_<_Tp> SparseMat::begin()
4260 { return SparseMatIterator_<_Tp>(this); }
4262 template<typename _Tp> inline SparseMatConstIterator_<_Tp> SparseMat::begin() const
4263 { return SparseMatConstIterator_<_Tp>(this); }
4265 template<typename _Tp> inline SparseMatIterator_<_Tp> SparseMat::end()
4266 { SparseMatIterator_<_Tp> it(this); it.seekEnd(); return it; }
4268 template<typename _Tp> inline SparseMatConstIterator_<_Tp> SparseMat::end() const
4269 { SparseMatConstIterator_<_Tp> it(this); it.seekEnd(); return it; }
4272 inline SparseMatConstIterator::SparseMatConstIterator()
4273 : m(0), hashidx(0), ptr(0)
4277 inline SparseMatConstIterator::SparseMatConstIterator(const SparseMatConstIterator& it)
4278 : m(it.m), hashidx(it.hashidx), ptr(it.ptr)
4282 static inline bool operator == (const SparseMatConstIterator& it1, const SparseMatConstIterator& it2)
4283 { return it1.m == it2.m && it1.hashidx == it2.hashidx && it1.ptr == it2.ptr; }
4285 static inline bool operator != (const SparseMatConstIterator& it1, const SparseMatConstIterator& it2)
4286 { return !(it1 == it2); }
4289 inline SparseMatConstIterator& SparseMatConstIterator::operator = (const SparseMatConstIterator& it)
4294 hashidx = it.hashidx;
4300 template<typename _Tp> inline const _Tp& SparseMatConstIterator::value() const
4301 { return *(_Tp*)ptr; }
4303 inline const SparseMat::Node* SparseMatConstIterator::node() const
4305 return ptr && m && m->hdr ?
4306 (const SparseMat::Node*)(ptr - m->hdr->valueOffset) : 0;
4309 inline SparseMatConstIterator SparseMatConstIterator::operator ++(int)
4311 SparseMatConstIterator it = *this;
4317 inline void SparseMatConstIterator::seekEnd()
4321 hashidx = m->hdr->hashtab.size();
4326 inline SparseMatIterator::SparseMatIterator()
4329 inline SparseMatIterator::SparseMatIterator(SparseMat* _m)
4330 : SparseMatConstIterator(_m)
4333 inline SparseMatIterator::SparseMatIterator(const SparseMatIterator& it)
4334 : SparseMatConstIterator(it)
4338 inline SparseMatIterator& SparseMatIterator::operator = (const SparseMatIterator& it)
4340 (SparseMatConstIterator&)*this = it;
4344 template<typename _Tp> inline _Tp& SparseMatIterator::value() const
4345 { return *(_Tp*)ptr; }
4347 inline SparseMat::Node* SparseMatIterator::node() const
4349 return (SparseMat::Node*)SparseMatConstIterator::node();
4352 inline SparseMatIterator& SparseMatIterator::operator ++()
4354 SparseMatConstIterator::operator ++();
4358 inline SparseMatIterator SparseMatIterator::operator ++(int)
4360 SparseMatIterator it = *this;
4366 template<typename _Tp> inline SparseMat_<_Tp>::SparseMat_()
4367 { flags = MAGIC_VAL | DataType<_Tp>::type; }
4369 template<typename _Tp> inline SparseMat_<_Tp>::SparseMat_(int _dims, const int* _sizes)
4370 : SparseMat(_dims, _sizes, DataType<_Tp>::type)
4373 template<typename _Tp> inline SparseMat_<_Tp>::SparseMat_(const SparseMat& m)
4375 if( m.type() == DataType<_Tp>::type )
4376 *this = (const SparseMat_<_Tp>&)m;
4378 m.convertTo(this, DataType<_Tp>::type);
4381 template<typename _Tp> inline SparseMat_<_Tp>::SparseMat_(const SparseMat_<_Tp>& m)
4383 this->flags = m.flags;
4386 CV_XADD(&this->hdr->refcount, 1);
4389 template<typename _Tp> inline SparseMat_<_Tp>::SparseMat_(const Mat& m)
4395 template<typename _Tp> inline SparseMat_<_Tp>::SparseMat_(const MatND& m)
4401 template<typename _Tp> inline SparseMat_<_Tp>::SparseMat_(const CvSparseMat* m)
4407 template<typename _Tp> inline SparseMat_<_Tp>&
4408 SparseMat_<_Tp>::operator = (const SparseMat_<_Tp>& m)
4412 if( m.hdr ) CV_XADD(&m.hdr->refcount, 1);
4420 template<typename _Tp> inline SparseMat_<_Tp>&
4421 SparseMat_<_Tp>::operator = (const SparseMat& m)
4423 if( m.type() == DataType<_Tp>::type )
4424 return (*this = (const SparseMat_<_Tp>&)m);
4425 m.convertTo(*this, DataType<_Tp>::type);
4429 template<typename _Tp> inline SparseMat_<_Tp>&
4430 SparseMat_<_Tp>::operator = (const Mat& m)
4431 { return (*this = SparseMat(m)); }
4433 template<typename _Tp> inline SparseMat_<_Tp>&
4434 SparseMat_<_Tp>::operator = (const MatND& m)
4435 { return (*this = SparseMat(m)); }
4437 template<typename _Tp> inline SparseMat_<_Tp>
4438 SparseMat_<_Tp>::clone() const
4445 template<typename _Tp> inline void
4446 SparseMat_<_Tp>::create(int _dims, const int* _sizes)
4448 SparseMat::create(_dims, _sizes, DataType<_Tp>::type);
4451 template<typename _Tp> inline
4452 SparseMat_<_Tp>::operator CvSparseMat*() const
4454 return SparseMat::operator CvSparseMat*();
4457 template<typename _Tp> inline int SparseMat_<_Tp>::type() const
4458 { return DataType<_Tp>::type; }
4460 template<typename _Tp> inline int SparseMat_<_Tp>::depth() const
4461 { return DataType<_Tp>::depth; }
4463 template<typename _Tp> inline int SparseMat_<_Tp>::channels() const
4464 { return DataType<_Tp>::channels; }
4466 template<typename _Tp> inline _Tp&
4467 SparseMat_<_Tp>::ref(int i0, size_t* hashval)
4468 { return SparseMat::ref<_Tp>(i0, hashval); }
4470 template<typename _Tp> inline _Tp
4471 SparseMat_<_Tp>::operator()(int i0, size_t* hashval) const
4472 { return SparseMat::value<_Tp>(i0, hashval); }
4474 template<typename _Tp> inline _Tp&
4475 SparseMat_<_Tp>::ref(int i0, int i1, size_t* hashval)
4476 { return SparseMat::ref<_Tp>(i0, i1, hashval); }
4478 template<typename _Tp> inline _Tp
4479 SparseMat_<_Tp>::operator()(int i0, int i1, size_t* hashval) const
4480 { return SparseMat::value<_Tp>(i0, i1, hashval); }
4482 template<typename _Tp> inline _Tp&
4483 SparseMat_<_Tp>::ref(int i0, int i1, int i2, size_t* hashval)
4484 { return SparseMat::ref<_Tp>(i0, i1, i2, hashval); }
4486 template<typename _Tp> inline _Tp
4487 SparseMat_<_Tp>::operator()(int i0, int i1, int i2, size_t* hashval) const
4488 { return SparseMat::value<_Tp>(i0, i1, i2, hashval); }
4490 template<typename _Tp> inline _Tp&
4491 SparseMat_<_Tp>::ref(const int* idx, size_t* hashval)
4492 { return SparseMat::ref<_Tp>(idx, hashval); }
4494 template<typename _Tp> inline _Tp
4495 SparseMat_<_Tp>::operator()(const int* idx, size_t* hashval) const
4496 { return SparseMat::value<_Tp>(idx, hashval); }
4498 template<typename _Tp> inline SparseMatIterator_<_Tp> SparseMat_<_Tp>::begin()
4499 { return SparseMatIterator_<_Tp>(this); }
4501 template<typename _Tp> inline SparseMatConstIterator_<_Tp> SparseMat_<_Tp>::begin() const
4502 { return SparseMatConstIterator_<_Tp>(this); }
4504 template<typename _Tp> inline SparseMatIterator_<_Tp> SparseMat_<_Tp>::end()
4505 { SparseMatIterator_<_Tp> it(this); it.seekEnd(); return it; }
4507 template<typename _Tp> inline SparseMatConstIterator_<_Tp> SparseMat_<_Tp>::end() const
4508 { SparseMatConstIterator_<_Tp> it(this); it.seekEnd(); return it; }
4510 template<typename _Tp> inline
4511 SparseMatConstIterator_<_Tp>::SparseMatConstIterator_()
4514 template<typename _Tp> inline
4515 SparseMatConstIterator_<_Tp>::SparseMatConstIterator_(const SparseMat_<_Tp>* _m)
4516 : SparseMatConstIterator(_m)
4519 template<typename _Tp> inline
4520 SparseMatConstIterator_<_Tp>::SparseMatConstIterator_(const SparseMatConstIterator_<_Tp>& it)
4521 : SparseMatConstIterator(it)
4524 template<typename _Tp> inline SparseMatConstIterator_<_Tp>&
4525 SparseMatConstIterator_<_Tp>::operator = (const SparseMatConstIterator_<_Tp>& it)
4526 { return ((SparseMatConstIterator&)*this = it); }
4528 template<typename _Tp> inline const _Tp&
4529 SparseMatConstIterator_<_Tp>::operator *() const
4530 { return *(const _Tp*)this->ptr; }
4532 template<typename _Tp> inline SparseMatConstIterator_<_Tp>&
4533 SparseMatConstIterator_<_Tp>::operator ++()
4535 SparseMatConstIterator::operator ++();
4539 template<typename _Tp> inline SparseMatConstIterator_<_Tp>
4540 SparseMatConstIterator_<_Tp>::operator ++(int)
4542 SparseMatConstIterator it = *this;
4543 SparseMatConstIterator::operator ++();
4547 template<typename _Tp> inline
4548 SparseMatIterator_<_Tp>::SparseMatIterator_()
4551 template<typename _Tp> inline
4552 SparseMatIterator_<_Tp>::SparseMatIterator_(SparseMat_<_Tp>* _m)
4553 : SparseMatConstIterator_<_Tp>(_m)
4556 template<typename _Tp> inline
4557 SparseMatIterator_<_Tp>::SparseMatIterator_(const SparseMatIterator_<_Tp>& it)
4558 : SparseMatConstIterator_<_Tp>(it)
4561 template<typename _Tp> inline SparseMatIterator_<_Tp>&
4562 SparseMatIterator_<_Tp>::operator = (const SparseMatIterator_<_Tp>& it)
4563 { return ((SparseMatIterator&)*this = it); }
4565 template<typename _Tp> inline _Tp&
4566 SparseMatIterator_<_Tp>::operator *() const
4567 { return *(_Tp*)this->ptr; }
4569 template<typename _Tp> inline SparseMatIterator_<_Tp>&
4570 SparseMatIterator_<_Tp>::operator ++()
4572 SparseMatConstIterator::operator ++();
4576 template<typename _Tp> inline SparseMatIterator_<_Tp>
4577 SparseMatIterator_<_Tp>::operator ++(int)
4579 SparseMatIterator it = *this;
4580 SparseMatConstIterator::operator ++();