cxmat.hpp
上传用户:soukeisyuu
上传日期:2022-07-03
资源大小:5943k
文件大小:148k
源码类别:

波变换

开发平台:

Visual C++

  1. /*M///////////////////////////////////////////////////////////////////////////////////////
  2. //
  3. //  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
  4. //
  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.
  8. //
  9. //
  10. //                           License Agreement
  11. //                For Open Source Computer Vision Library
  12. //
  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.
  16. //
  17. // Redistribution and use in source and binary forms, with or without modification,
  18. // are permitted provided that the following conditions are met:
  19. //
  20. //   * Redistribution's of source code must retain the above copyright notice,
  21. //     this list of conditions and the following disclaimer.
  22. //
  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.
  26. //
  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.
  29. //
  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.
  40. //
  41. //M*/
  42. #ifndef _OPENCV_CORE_MAT_OPERATIONS_H_
  43. #define _OPENCV_CORE_MAT_OPERATIONS_H_
  44. #ifndef SKIP_INCLUDES
  45. #include <limits.h>
  46. #endif // SKIP_INCLUDES
  47. #ifdef __cplusplus
  48. namespace cv
  49. {
  50. //////////////////////////////// Mat ////////////////////////////////
  51. inline Mat::Mat()
  52.     : flags(0), rows(0), cols(0), step(0), data(0), refcount(0), datastart(0), dataend(0) {}
  53. inline Mat::Mat(int _rows, int _cols, int _type)
  54.     : flags(0), rows(0), cols(0), step(0), data(0), refcount(0), datastart(0), dataend(0)
  55. {
  56.     if( _rows > 0 && _cols > 0 )
  57.         create( _rows, _cols, _type );
  58. }
  59. inline Mat::Mat(int _rows, int _cols, int _type, const Scalar& _s)
  60.     : flags(0), rows(0), cols(0), step(0), data(0), refcount(0),
  61.     datastart(0), dataend(0)
  62. {
  63.     if(_rows > 0 && _cols > 0)
  64.     {
  65.         create(_rows, _cols, _type);
  66.         *this = _s;
  67.     }
  68. }
  69. inline Mat::Mat(Size _size, int _type)
  70.     : flags(0), rows(0), cols(0), step(0), data(0), refcount(0),
  71.     datastart(0), dataend(0)
  72. {
  73.     if( _size.height > 0 && _size.width > 0 )
  74.         create( _size.height, _size.width, _type );
  75. }
  76.     
  77. inline Mat::Mat(Size _size, int _type, const Scalar& _s)
  78. : flags(0), rows(0), cols(0), step(0), data(0), refcount(0),
  79. datastart(0), dataend(0)
  80. {
  81.     if( _size.height > 0 && _size.width > 0 )
  82.     {
  83.         create( _size.height, _size.width, _type );
  84.         *this = _s;
  85.     }
  86. }    
  87. inline Mat::Mat(const Mat& m)
  88.     : flags(m.flags), rows(m.rows), cols(m.cols), step(m.step), data(m.data),
  89.     refcount(m.refcount), datastart(m.datastart), dataend(m.dataend)
  90. {
  91.     if( refcount )
  92.         CV_XADD(refcount, 1);
  93. }
  94. inline Mat::Mat(int _rows, int _cols, int _type, void* _data, size_t _step)
  95.     : flags(MAGIC_VAL + (_type & TYPE_MASK)), rows(_rows), cols(_cols),
  96.     step(_step), data((uchar*)_data), refcount(0),
  97.     datastart((uchar*)_data), dataend((uchar*)_data)
  98. {
  99.     size_t minstep = cols*elemSize();
  100.     if( step == AUTO_STEP )
  101.     {
  102.         step = minstep;
  103.         flags |= CONTINUOUS_FLAG;
  104.     }
  105.     else
  106.     {
  107.         if( rows == 1 ) step = minstep;
  108.         CV_DbgAssert( step >= minstep );
  109.         flags |= step == minstep ? CONTINUOUS_FLAG : 0;
  110.     }
  111.     dataend += step*(rows-1) + minstep;
  112. }
  113. inline Mat::Mat(Size _size, int _type, void* _data, size_t _step)
  114.     : flags(MAGIC_VAL + (_type & TYPE_MASK)), rows(_size.height), cols(_size.width),
  115.     step(_step), data((uchar*)_data), refcount(0),
  116.     datastart((uchar*)_data), dataend((uchar*)_data)
  117. {
  118.     size_t minstep = cols*elemSize();
  119.     if( step == AUTO_STEP )
  120.     {
  121.         step = minstep;
  122.         flags |= CONTINUOUS_FLAG;
  123.     }
  124.     else
  125.     {
  126.         if( rows == 1 ) step = minstep;
  127.         CV_DbgAssert( step >= minstep );
  128.         flags |= step == minstep ? CONTINUOUS_FLAG : 0;
  129.     }
  130.     dataend += step*(rows-1) + minstep;
  131. }
  132. inline Mat::Mat(const Mat& m, const Range& rowRange, const Range& colRange)
  133. {
  134.     flags = m.flags;
  135.     step = m.step; refcount = m.refcount;
  136.     data = m.data; datastart = m.datastart; dataend = m.dataend;
  137.     if( rowRange == Range::all() )
  138.         rows = m.rows;
  139.     else
  140.     {
  141.         CV_Assert( 0 <= rowRange.start && rowRange.start <= rowRange.end && rowRange.end <= m.rows );
  142.         rows = rowRange.size();
  143.         data += step*rowRange.start;
  144.     }
  145.     if( colRange == Range::all() )
  146.         cols = m.cols;
  147.     else
  148.     {
  149.         CV_Assert( 0 <= colRange.start && colRange.start <= colRange.end && colRange.end <= m.cols );
  150.         cols = colRange.size();
  151.         data += colRange.start*elemSize();
  152.         flags &= cols < m.cols ? ~CONTINUOUS_FLAG : -1;
  153.     }
  154.     if( rows == 1 )
  155.         flags |= CONTINUOUS_FLAG;
  156.     if( refcount )
  157.         CV_XADD(refcount, 1);
  158.     if( rows <= 0 || cols <= 0 )
  159.         rows = cols = 0;
  160. }
  161. inline Mat::Mat(const Mat& m, const Rect& roi)
  162.     : flags(m.flags), rows(roi.height), cols(roi.width),
  163.     step(m.step), data(m.data + roi.y*step), refcount(m.refcount),
  164.     datastart(m.datastart), dataend(m.dataend)
  165. {
  166.     flags &= roi.width < m.cols ? ~CONTINUOUS_FLAG : -1;
  167.     data += roi.x*elemSize();
  168.     CV_Assert( 0 <= roi.x && 0 <= roi.width && roi.x + roi.width <= m.cols &&
  169.         0 <= roi.y && 0 <= roi.height && roi.y + roi.height <= m.rows );
  170.     if( refcount )
  171.         CV_XADD(refcount, 1);
  172.     if( rows <= 0 || cols <= 0 )
  173.         rows = cols = 0;
  174. }
  175. inline Mat::Mat(const CvMat* m, bool copyData)
  176.     : flags(MAGIC_VAL + (m->type & (CV_MAT_TYPE_MASK|CV_MAT_CONT_FLAG))),
  177.     rows(m->rows), cols(m->cols), step(m->step), data(m->data.ptr), refcount(0),
  178.     datastart(m->data.ptr), dataend(m->data.ptr)
  179. {
  180.     if( step == 0 )
  181.         step = cols*elemSize();
  182.     size_t minstep = cols*elemSize();
  183.     dataend += step*(rows-1) + minstep;
  184.     if( copyData )
  185.     {
  186.         data = datastart = dataend = 0;
  187.         Mat(m->rows, m->cols, m->type, m->data.ptr, m->step).copyTo(*this);
  188.     }
  189. }
  190. template<typename _Tp> inline Mat::Mat(const vector<_Tp>& vec, bool copyData)
  191.     : flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG),
  192.     rows(0), cols(0), step(0), data(0), refcount(0),
  193.     datastart(0), dataend(0)
  194. {
  195.     if(vec.empty())
  196.         return;
  197.     if( !copyData )
  198.     {
  199.         rows = (int)vec.size();
  200.         cols = 1;
  201.         step = sizeof(_Tp);
  202.         data = datastart = (uchar*)&vec[0];
  203.         dataend = datastart + rows*step;
  204.     }
  205.     else
  206.         Mat((int)vec.size(), 1, DataType<_Tp>::type, (uchar*)&vec[0]).copyTo(*this);
  207. }
  208.     
  209. inline Mat::~Mat()
  210. {
  211.     release();
  212. }
  213. inline Mat& Mat::operator = (const Mat& m)
  214. {
  215.     if( this != &m )
  216.     {
  217.         if( m.refcount )
  218.             CV_XADD(m.refcount, 1);
  219.         release();
  220.         flags = m.flags;
  221.         rows = m.rows; cols = m.cols;
  222.         step = m.step; data = m.data;
  223.         datastart = m.datastart; dataend = m.dataend;
  224.         refcount = m.refcount;
  225.     }
  226.     return *this;
  227. }
  228. inline Mat Mat::row(int y) const { return Mat(*this, Range(y, y+1), Range::all()); }
  229. inline Mat Mat::col(int x) const { return Mat(*this, Range::all(), Range(x, x+1)); }
  230. inline Mat Mat::rowRange(int startrow, int endrow) const
  231.     { return Mat(*this, Range(startrow, endrow), Range::all()); }
  232. inline Mat Mat::rowRange(const Range& r) const
  233.     { return Mat(*this, r, Range::all()); }
  234. inline Mat Mat::colRange(int startcol, int endcol) const
  235.     { return Mat(*this, Range::all(), Range(startcol, endcol)); }
  236. inline Mat Mat::colRange(const Range& r) const
  237.     { return Mat(*this, Range::all(), r); }
  238. inline Mat Mat::diag(int d) const
  239. {
  240.     Mat m = *this;
  241.     size_t esz = elemSize();
  242.     int len;
  243.     if( d >= 0 )
  244.     {
  245.         len = std::min(cols - d, rows);
  246.         m.data += esz*d;
  247.     }
  248.     else
  249.     {
  250.         len = std::min(rows + d, cols);
  251.         m.data -= step*d;
  252.     }
  253.     CV_DbgAssert( len > 0 );
  254.     m.rows = len;
  255.     m.cols = 1;
  256.     m.step += esz;
  257.     if( m.rows > 1 )
  258.         m.flags &= ~CONTINUOUS_FLAG;
  259.     else
  260.         m.flags |= CONTINUOUS_FLAG;
  261.     return m;
  262. }
  263. inline Mat Mat::diag(const Mat& d)
  264. {
  265.     Mat m(d.rows, d.rows, d.type(), Scalar(0)), md = m.diag();
  266.     d.copyTo(md);
  267.     return m;
  268. }
  269. inline Mat Mat::clone() const
  270. {
  271.     Mat m;
  272.     copyTo(m);
  273.     return m;
  274. }
  275. inline void Mat::assignTo( Mat& m, int type ) const
  276. {
  277.     if( type < 0 )
  278.         m = *this;
  279.     else
  280.         convertTo(m, type);
  281. }
  282. inline void Mat::create(int _rows, int _cols, int _type)
  283. {
  284.     _type &= TYPE_MASK;
  285.     if( rows == _rows && cols == _cols && type() == _type && data )
  286.         return;
  287.     if( data )
  288.         release();
  289.     CV_DbgAssert( _rows >= 0 && _cols >= 0 );
  290.     if( _rows > 0 && _cols > 0 )
  291.     {
  292.         flags = MAGIC_VAL + CONTINUOUS_FLAG + _type;
  293.         rows = _rows;
  294.         cols = _cols;
  295.         step = elemSize()*cols;
  296.         int64 _nettosize = (int64)step*rows;
  297.         size_t nettosize = (size_t)_nettosize;
  298.         if( _nettosize != (int64)nettosize )
  299.             CV_Error(CV_StsNoMem, "Too big buffer is allocated");
  300.         size_t datasize = alignSize(nettosize, (int)sizeof(*refcount));
  301.         datastart = data = (uchar*)fastMalloc(datasize + sizeof(*refcount));
  302.         dataend = data + nettosize;
  303.         refcount = (int*)(data + datasize);
  304.         *refcount = 1;
  305.     }
  306. }
  307. inline void Mat::create(Size _size, int _type)
  308. {
  309.     create(_size.height, _size.width, _type);
  310. }
  311. inline void Mat::addref()
  312. { if( refcount ) CV_XADD(refcount, 1); }
  313. inline void Mat::release()
  314. {
  315.     if( refcount && CV_XADD(refcount, -1) == 1 )
  316.         fastFree(datastart);
  317.     data = datastart = dataend = 0;
  318.     step = rows = cols = 0;
  319.     refcount = 0;
  320. }
  321. inline void Mat::locateROI( Size& wholeSize, Point& ofs ) const
  322. {
  323.     size_t esz = elemSize(), minstep;
  324.     ptrdiff_t delta1 = data - datastart, delta2 = dataend - datastart;
  325.     CV_DbgAssert( step > 0 );
  326.     if( delta1 == 0 )
  327.         ofs.x = ofs.y = 0;
  328.     else
  329.     {
  330.         ofs.y = (int)(delta1/step);
  331.         ofs.x = (int)((delta1 - step*ofs.y)/esz);
  332.         CV_DbgAssert( data == datastart + ofs.y*step + ofs.x*esz );
  333.     }
  334.     minstep = (ofs.x + cols)*esz;
  335.     wholeSize.height = (int)((delta2 - minstep)/step + 1);
  336.     wholeSize.height = std::max(wholeSize.height, ofs.y + rows);
  337.     wholeSize.width = (int)((delta2 - step*(wholeSize.height-1))/esz);
  338.     wholeSize.width = std::max(wholeSize.width, ofs.x + cols);
  339. }
  340. inline Mat& Mat::adjustROI( int dtop, int dbottom, int dleft, int dright )
  341. {
  342.     Size wholeSize; Point ofs;
  343.     size_t esz = elemSize();
  344.     locateROI( wholeSize, ofs );
  345.     int row1 = std::max(ofs.y - dtop, 0), row2 = std::min(ofs.y + rows + dbottom, wholeSize.height);
  346.     int col1 = std::max(ofs.x - dleft, 0), col2 = std::min(ofs.x + cols + dright, wholeSize.width);
  347.     data += (row1 - ofs.y)*step + (col1 - ofs.x)*esz;
  348.     rows = row2 - row1; cols = col2 - col1;
  349.     if( esz*cols == step || rows == 1 )
  350.         flags |= CONTINUOUS_FLAG;
  351.     else
  352.         flags &= ~CONTINUOUS_FLAG;
  353.     return *this;
  354. }
  355. inline Mat Mat::operator()( Range rowRange, Range colRange ) const
  356. {
  357.     return Mat(*this, rowRange, colRange);
  358. }
  359. inline Mat Mat::operator()( const Rect& roi ) const
  360. { return Mat(*this, roi); }
  361. inline Mat::operator CvMat() const
  362. {
  363.     CvMat m = cvMat(rows, cols, type(), data);
  364.     m.step = (int)step;
  365.     m.type = (m.type & ~CONTINUOUS_FLAG) | (flags & CONTINUOUS_FLAG);
  366.     return m;
  367. }
  368. inline Mat::operator IplImage() const
  369. {
  370.     IplImage img;
  371.     cvInitImageHeader(&img, size(), cvIplDepth(flags), channels());
  372.     cvSetData(&img, data, (int)step);
  373.     return img;
  374. }
  375. inline bool Mat::isContinuous() const { return (flags & CONTINUOUS_FLAG) != 0; }
  376. inline size_t Mat::elemSize() const { return CV_ELEM_SIZE(flags); }
  377. inline size_t Mat::elemSize1() const { return CV_ELEM_SIZE1(flags); }
  378. inline int Mat::type() const { return CV_MAT_TYPE(flags); }
  379. inline int Mat::depth() const { return CV_MAT_DEPTH(flags); }
  380. inline int Mat::channels() const { return CV_MAT_CN(flags); }
  381. inline size_t Mat::step1() const { return step/elemSize1(); }
  382. inline Size Mat::size() const { return Size(cols, rows); }
  383. inline bool Mat::empty() const { return data == 0; }
  384. inline uchar* Mat::ptr(int y)
  385. {
  386.     CV_DbgAssert( (unsigned)y < (unsigned)rows );
  387.     return data + step*y;
  388. }
  389. inline const uchar* Mat::ptr(int y) const
  390. {
  391.     CV_DbgAssert( (unsigned)y < (unsigned)rows );
  392.     return data + step*y;
  393. }
  394. template<typename _Tp> inline _Tp* Mat::ptr(int y)
  395. {
  396.     CV_DbgAssert( (unsigned)y < (unsigned)rows );
  397.     return (_Tp*)(data + step*y);
  398. }
  399. template<typename _Tp> inline const _Tp* Mat::ptr(int y) const
  400. {
  401.     CV_DbgAssert( (unsigned)y < (unsigned)rows );
  402.     return (const _Tp*)(data + step*y);
  403. }
  404. template<typename _Tp> inline _Tp& Mat::at(int y, int x)
  405. {
  406.     CV_DbgAssert( (unsigned)y < (unsigned)rows && (unsigned)x < (unsigned)cols &&
  407.         sizeof(_Tp) == elemSize() );
  408.     return ((_Tp*)(data + step*y))[x];
  409. }
  410. template<typename _Tp> inline const _Tp& Mat::at(int y, int x) const
  411. {
  412.     CV_DbgAssert( (unsigned)y < (unsigned)rows && (unsigned)x < (unsigned)cols &&
  413.         sizeof(_Tp) == elemSize() );
  414.     return ((const _Tp*)(data + step*y))[x];
  415. }
  416. template<typename _Tp> inline _Tp& Mat::at(Point pt)
  417. {
  418.     CV_DbgAssert( (unsigned)pt.y < (unsigned)rows && (unsigned)pt.x < (unsigned)cols &&
  419.         sizeof(_Tp) == elemSize() );
  420.     return ((_Tp*)(data + step*pt.y))[pt.x];
  421. }
  422. template<typename _Tp> inline const _Tp& Mat::at(Point pt) const
  423. {
  424.     CV_DbgAssert( (unsigned)pt.y < (unsigned)rows && (unsigned)pt.x < (unsigned)cols &&
  425.         sizeof(_Tp) == elemSize() );
  426.     return ((const _Tp*)(data + step*pt.y))[pt.x];
  427. }
  428.     
  429. template<typename _Tp> inline MatConstIterator_<_Tp> Mat::begin() const
  430. {
  431.     CV_DbgAssert( elemSize() == sizeof(_Tp) );
  432.     return MatConstIterator_<_Tp>((const Mat_<_Tp>*)this);
  433. }
  434. template<typename _Tp> inline MatConstIterator_<_Tp> Mat::end() const
  435. {
  436.     CV_DbgAssert( elemSize() == sizeof(_Tp) );
  437.     MatConstIterator_<_Tp> it((const Mat_<_Tp>*)this);
  438.     it.ptr = it.sliceEnd = (_Tp*)(data + step*(rows-1)) + cols;
  439.     return it;
  440. }
  441. template<typename _Tp> inline MatIterator_<_Tp> Mat::begin()
  442. {
  443.     CV_DbgAssert( elemSize() == sizeof(_Tp) );
  444.     return MatIterator_<_Tp>((Mat_<_Tp>*)this);
  445. }
  446. template<typename _Tp> inline MatIterator_<_Tp> Mat::end()
  447. {
  448.     CV_DbgAssert( elemSize() == sizeof(_Tp) );
  449.     MatIterator_<_Tp> it((Mat_<_Tp>*)this);
  450.     it.ptr = it.sliceEnd = (_Tp*)(data + step*(rows-1)) + cols;
  451.     return it;
  452. }
  453.     
  454.     
  455. static inline void swap( Mat& a, Mat& b )
  456. {
  457.     std::swap( a.flags, b.flags );
  458.     std::swap( a.rows, b.rows ); std::swap( a.cols, b.cols );
  459.     std::swap( a.step, b.step ); std::swap( a.data, b.data );
  460.     std::swap( a.datastart, b.datastart );
  461.     std::swap( a.dataend, b.dataend );
  462.     std::swap( a.refcount, b.refcount );
  463. }
  464. inline SVD::SVD() {}
  465. inline SVD::SVD( const Mat& m, int flags ) { operator ()(m, flags); }
  466. inline void SVD::solveZ( const Mat& m, Mat& dst )
  467. {
  468.     SVD svd(m);
  469.     svd.vt.row(svd.vt.rows-1).reshape(1,svd.vt.cols).copyTo(dst);
  470. }
  471. ///////////////////////////////// Mat_<_Tp> ////////////////////////////////////
  472. template<typename _Tp> inline Mat_<_Tp>::Mat_() :
  473.     Mat() { flags = (flags & ~CV_MAT_TYPE_MASK) | DataType<_Tp>::type; }
  474.     
  475. template<typename _Tp> inline Mat_<_Tp>::Mat_(int _rows, int _cols) :
  476.     Mat(_rows, _cols, DataType<_Tp>::type) {}
  477. template<typename _Tp> inline Mat_<_Tp>::Mat_(int _rows, int _cols, const _Tp& value) :
  478.     Mat(_rows, _cols, DataType<_Tp>::type) { *this = value; }
  479. template<typename _Tp> inline Mat_<_Tp>::Mat_(Size _size) :
  480.     Mat(_size.height, _size.width, DataType<_Tp>::type) {}
  481.     
  482. template<typename _Tp> inline Mat_<_Tp>::Mat_(Size _size, const _Tp& value) :
  483.     Mat(_size.height, _size.width, DataType<_Tp>::type) { *this = value; }
  484.     
  485. template<typename _Tp> inline Mat_<_Tp>::Mat_(const Mat& m) : Mat()
  486. { flags = (flags & ~CV_MAT_TYPE_MASK) | DataType<_Tp>::type; *this = m; }
  487. template<typename _Tp> inline Mat_<_Tp>::Mat_(const Mat_& m) : Mat(m) {}
  488. template<typename _Tp> inline Mat_<_Tp>::Mat_(int _rows, int _cols, _Tp* _data, size_t _step)
  489.     : Mat(_rows, _cols, DataType<_Tp>::type, _data, _step) {}
  490. template<typename _Tp> inline Mat_<_Tp>::Mat_(const Mat_& m, const Range& rowRange, const Range& colRange)
  491.     : Mat(m, rowRange, colRange) {}
  492. template<typename _Tp> inline Mat_<_Tp>::Mat_(const Mat_& m, const Rect& roi)
  493.     : Mat(m, roi) {}
  494. template<typename _Tp> template<int n> inline Mat_<_Tp>::Mat_(const Vec<_Tp, n>& vec)
  495.     : Mat(n, 1, DataType<_Tp>::type)
  496. {
  497.     _Tp* d = (_Tp*)data;
  498.     for( int i = 0; i < n; i++ )
  499.         d[i] = vec[i];
  500. }
  501. template<typename _Tp> inline Mat_<_Tp>::Mat_(const vector<_Tp>& vec, bool copyData)
  502.     : Mat(vec, copyData)
  503. {}
  504. template<typename _Tp> inline Mat_<_Tp>& Mat_<_Tp>::operator = (const Mat& m)
  505. {
  506.     if( DataType<_Tp>::type == m.type() )
  507.     {
  508.         Mat::operator = (m);
  509.         return *this;
  510.     }
  511.     if( DataType<_Tp>::depth == m.depth() )
  512.     {
  513.         return (*this = m.reshape(DataType<_Tp>::channels));
  514.     }
  515.     CV_DbgAssert(DataType<_Tp>::channels == m.channels());
  516.     m.convertTo(*this, type());
  517.     return *this;
  518. }
  519. template<typename _Tp> inline Mat_<_Tp>& Mat_<_Tp>::operator = (const Mat_& m)
  520. {
  521.     Mat::operator=(m);
  522.     return *this;
  523. }
  524. template<typename _Tp> inline Mat_<_Tp>& Mat_<_Tp>::operator = (const _Tp& s)
  525. {
  526.     Mat::operator=(Scalar(s));
  527.     return *this;
  528. }
  529. template<typename _Tp> inline void Mat_<_Tp>::create(int _rows, int _cols)
  530. {
  531.     Mat::create(_rows, _cols, DataType<_Tp>::type);
  532. }
  533. template<typename _Tp> inline void Mat_<_Tp>::create(Size _size)
  534. {
  535.     Mat::create(_size, DataType<_Tp>::type);
  536. }
  537. template<typename _Tp> inline Mat_<_Tp> Mat_<_Tp>::cross(const Mat_& m) const
  538. { return Mat_<_Tp>(Mat::cross(m)); }
  539. template<typename _Tp> template<typename T2> inline Mat_<_Tp>::operator Mat_<T2>() const
  540. { return Mat_<T2>(*this); }
  541. template<typename _Tp> inline Mat_<_Tp> Mat_<_Tp>::row(int y) const
  542. { return Mat_(*this, Range(y, y+1), Range::all()); }
  543. template<typename _Tp> inline Mat_<_Tp> Mat_<_Tp>::col(int x) const
  544. { return Mat_(*this, Range::all(), Range(x, x+1)); }
  545. template<typename _Tp> inline Mat_<_Tp> Mat_<_Tp>::diag(int d) const
  546. { return Mat_(Mat::diag(d)); }
  547. template<typename _Tp> inline Mat_<_Tp> Mat_<_Tp>::clone() const
  548. { return Mat_(Mat::clone()); }
  549. template<typename _Tp> inline size_t Mat_<_Tp>::elemSize() const
  550. {
  551.     CV_DbgAssert( Mat::elemSize() == sizeof(_Tp) );
  552.     return sizeof(_Tp);
  553. }
  554. template<typename _Tp> inline size_t Mat_<_Tp>::elemSize1() const
  555. {
  556.     CV_DbgAssert( Mat::elemSize1() == sizeof(_Tp)/DataType<_Tp>::channels );
  557.     return sizeof(_Tp)/DataType<_Tp>::channels;
  558. }
  559. template<typename _Tp> inline int Mat_<_Tp>::type() const
  560. {
  561.     CV_DbgAssert( Mat::type() == DataType<_Tp>::type );
  562.     return DataType<_Tp>::type;
  563. }
  564. template<typename _Tp> inline int Mat_<_Tp>::depth() const
  565. {
  566.     CV_DbgAssert( Mat::depth() == DataType<_Tp>::depth );
  567.     return DataType<_Tp>::depth;
  568. }
  569. template<typename _Tp> inline int Mat_<_Tp>::channels() const
  570. {
  571.     CV_DbgAssert( Mat::channels() == DataType<_Tp>::channels );
  572.     return DataType<_Tp>::channels;
  573. }
  574. template<typename _Tp> inline size_t Mat_<_Tp>::stepT() const { return step/elemSize(); }
  575. template<typename _Tp> inline size_t Mat_<_Tp>::step1() const { return step/elemSize1(); }
  576. template<typename _Tp> inline Mat_<_Tp> Mat_<_Tp>::reshape(int _rows) const
  577. { return Mat_<_Tp>(Mat::reshape(0,_rows)); }
  578. template<typename _Tp> inline Mat_<_Tp>& Mat_<_Tp>::adjustROI( int dtop, int dbottom, int dleft, int dright )
  579. { return (Mat_<_Tp>&)(Mat::adjustROI(dtop, dbottom, dleft, dright));  }
  580. template<typename _Tp> inline Mat_<_Tp> Mat_<_Tp>::operator()( const Range& rowRange, const Range& colRange ) const
  581. { return Mat_<_Tp>(*this, rowRange, colRange); }
  582. template<typename _Tp> inline Mat_<_Tp> Mat_<_Tp>::operator()( const Rect& roi ) const
  583. { return Mat_<_Tp>(roi); }
  584. template<typename _Tp> inline _Tp* Mat_<_Tp>::operator [](int y)
  585. { return (_Tp*)ptr(y); }
  586. template<typename _Tp> inline const _Tp* Mat_<_Tp>::operator [](int y) const
  587. { return (const _Tp*)ptr(y); }
  588. template<typename _Tp> inline _Tp& Mat_<_Tp>::operator ()(int row, int col)
  589. {
  590.     CV_DbgAssert( (unsigned)row < (unsigned)rows && (unsigned)col < (unsigned)cols );
  591.     return ((_Tp*)(data + step*row))[col];
  592. }
  593. template<typename _Tp> inline const _Tp& Mat_<_Tp>::operator ()(int row, int col) const
  594. {
  595.     CV_DbgAssert( (unsigned)row < (unsigned)rows && (unsigned)col < (unsigned)cols );
  596.     return ((const _Tp*)(data + step*row))[col];
  597. }
  598. template<typename _Tp> inline _Tp& Mat_<_Tp>::operator ()(Point pt)
  599. {
  600.     CV_DbgAssert( (unsigned)pt.y < (unsigned)rows && (unsigned)pt.x < (unsigned)cols );
  601.     return ((_Tp*)(data + step*pt.y))[pt.x];
  602. }
  603. template<typename _Tp> inline const _Tp& Mat_<_Tp>::operator ()(Point pt) const
  604. {
  605.     CV_DbgAssert( (unsigned)pt.y < (unsigned)rows && (unsigned)pt.x < (unsigned)cols );
  606.     return ((const _Tp*)(data + step*pt.y))[pt.x];
  607. }
  608. template<typename _Tp> inline Mat_<_Tp>::operator vector<_Tp>() const
  609. {
  610.     CV_Assert( rows == 1 || cols == 1 );
  611.     return isContinuous() ? vector<_Tp>((size_t)(rows + cols - 1), (_Tp*)data) :
  612.         (vector<_Tp>)((Mat_<_Tp>)this->t());
  613. }
  614. template<typename T1, typename T2, typename Op> inline void
  615. process( const Mat_<T1>& m1, Mat_<T2>& m2, Op op )
  616. {
  617.     int y, x, rows = m1.rows, cols = m1.cols;
  618.     int c1 = m1.channels(), c2 = m2.channels();
  619.     CV_DbgAssert( m1.size() == m2.size() );
  620.     for( y = 0; y < rows; y++ )
  621.     {
  622.         const T1* src = m1[y];
  623.         T2* dst = m2[y];
  624.         for( x = 0; x < cols; x++ )
  625.             dst[x] = op(src[x]);
  626.     }
  627. }
  628. template<typename T1, typename T2, typename T3, typename Op> inline void
  629. process( const Mat_<T1>& m1, const Mat_<T2>& m2, Mat_<T3>& m3, Op op )
  630. {
  631.     int y, x, rows = m1.rows, cols = m1.cols;
  632.     CV_DbgAssert( m1.size() == m2.size() );
  633.     for( y = 0; y < rows; y++ )
  634.     {
  635.         const T1* src1 = m1[y];
  636.         const T2* src2 = m2[y];
  637.         T3* dst = m3[y];
  638.         for( x = 0; x < cols; x++ )
  639.             dst[x] = op( src1[x], src2[x] );
  640.     }
  641. }
  642. template<typename M> class CV_EXPORTS MatExpr_Base_
  643. {
  644. public:
  645.     MatExpr_Base_() {}
  646.     virtual ~MatExpr_Base_() {}
  647.     virtual void assignTo(M& m, int type=-1) const = 0;
  648. };
  649. template<typename E, typename M> class CV_EXPORTS MatExpr_ : public MatExpr_Base_<M>
  650. {
  651. public:
  652.     MatExpr_(const E& _e) : e(_e) {}
  653.     ~MatExpr_() {}
  654.     operator M() const { return (M)e; }
  655.     void assignTo(M& m, int type=-1) const { e.assignTo(m, type); }
  656.     M row(int y) const { return ((M)e).row(y); }
  657.     M col(int x) const { return ((M)e).col(x); }
  658.     M diag(int d=0) const { return ((M)e).diag(d); }
  659.     M operator()( const Range& rowRange, const Range& colRange ) const
  660.     { return ((M)e)(rowRange, colRange); }
  661.     M operator()( const Rect& roi ) const { return ((M)e)(roi); }
  662.     M cross(const M& m) const { return ((M)e).cross(m); }
  663.     double dot(const M& m) const { return ((M)e).dot(m); }
  664.     MatExpr_<MatExpr_Op2_<M, double, M, MatOp_T_<Mat> >, M> t() const
  665.     { return ((M)e).t(); }
  666.     MatExpr_<MatExpr_Op2_<M, int, M, MatOp_Inv_<Mat> >, M> inv(int method=DECOMP_LU) const
  667.     { return ((M)e).inv(method); }
  668.     MatExpr_<MatExpr_Op4_<M, M, double, char, M, MatOp_MulDiv_<Mat> >, M>
  669.     mul(const M& m, double scale=1) const
  670.     { return ((M)e).mul(m, scale); }
  671.     template<typename A> MatExpr_<MatExpr_Op4_<M, M, double, char, M, MatOp_MulDiv_<Mat> >, M >
  672.     mul(const MatExpr_<A, M>& m, double scale=1) const
  673.     { return ((M)e).mul(m, scale); }
  674.     E e;
  675. };
  676. inline Mat::Mat(const MatExpr_Base& expr)
  677.  : flags(0), rows(0), cols(0), step(0), data(0), refcount(0), datastart(0), dataend(0)
  678. {
  679.     expr.assignTo(*this);
  680. }
  681. inline Mat& Mat::operator = (const MatExpr_Base& expr)
  682. {
  683.     expr.assignTo(*this);
  684.     return *this;
  685. }
  686. template<typename _Tp> inline Mat_<_Tp>::Mat_(const MatExpr_Base& e) : Mat()
  687. {
  688.     e.assignTo(*this, DataType<_Tp>::type);
  689. }
  690. template<typename _Tp> inline Mat_<_Tp>& Mat_<_Tp>::operator = (const MatExpr_Base& e)
  691. {
  692.     e.assignTo(*this, DataType<_Tp>::type);
  693.     return *this;
  694. }
  695. template<typename _Tp> inline Mat_<_Tp>::operator MatExpr_<Mat_<_Tp>, Mat_<_Tp> >() const
  696. { return MatExpr_<Mat_<_Tp>, Mat_<_Tp> >(*this); }
  697. inline Mat::operator MatExpr_<Mat, Mat>() const
  698. { return MatExpr_<Mat, Mat>(*this); }
  699. template<typename M> class CV_EXPORTS MatOp_Sub_
  700. {
  701. public:
  702.     MatOp_Sub_() {}
  703.     static void apply(const M& a, const M& b, M& c, int type=-1)
  704.     {
  705.         if( type == a.type() || type < 0 )
  706.         {
  707.             subtract( a, b, c );
  708.         }
  709.         else
  710.         {
  711.             Mat temp;
  712.             apply(a, b, temp);
  713.             temp.convertTo(c, type);
  714.         }
  715.     }
  716. };
  717. template<typename M> class CV_EXPORTS MatOp_Scale_
  718. {
  719. public:
  720.     MatOp_Scale_() {}
  721.     static void apply(const M& a, double alpha, M& c, int type=-1)
  722.     {
  723.         a.convertTo(c, type, alpha, 0);
  724.     }
  725. };
  726. template<typename M> class CV_EXPORTS MatOp_ScaleAddS_
  727. {
  728. public:
  729.     MatOp_ScaleAddS_() {}
  730.     static void apply(const M& a, double alpha, double beta, M& c, int type=-1)
  731.     {
  732.         a.convertTo(c, type, alpha, beta);
  733.     }
  734. };
  735. template<typename M> class CV_EXPORTS MatOp_AddS_
  736. {
  737. public:
  738.     MatOp_AddS_() {}
  739.     static void apply(const M& a, const Scalar& s, M& c, int type=-1)
  740.     {
  741.         if( type == a.type() || type < 0 )
  742.         {
  743.             add(a, s, c);
  744.         }
  745.         else
  746.         {
  747.             Mat temp;
  748.             apply(a, s, temp);
  749.             temp.convertTo(c, type);
  750.         }
  751.     }
  752. };
  753. template<typename M> class CV_EXPORTS MatOp_AddEx_
  754. {
  755. public:
  756.     MatOp_AddEx_() {}
  757.     static void apply(const M& a, double alpha, const M& b,
  758.                       double beta, double gamma, M& c, int type=-1)
  759.     {
  760.         if( type == a.type() || type < 0 )
  761.         {
  762.             addWeighted(a, alpha, b, beta, gamma, c);
  763.         }
  764.         else
  765.         {
  766.             Mat temp;
  767.             apply(a, alpha, b, beta, gamma, temp);
  768.             temp.convertTo(c, type);
  769.         }
  770.     }
  771. };
  772. template<typename M> class CV_EXPORTS MatOp_Bin_
  773. {
  774. public:
  775.     MatOp_Bin_() {}
  776.     static void apply(const M& a, const M& b, int _op, M& c, int type=-1)
  777.     {
  778.         char op = (char)_op;
  779.         if( type == a.type() || type < 0 )
  780.         {
  781.             if( op == '&' )
  782.                 bitwise_and( a, b, c );
  783.             else if( op == '|' )
  784.                 bitwise_or( a, b, c );
  785.             else if( op == '^' )
  786.                 bitwise_xor( a, b, c );
  787.             else if( op == 'm' )
  788.                 min( a, b, c );
  789.             else if( op == 'M' )
  790.                 max( a, b, c );
  791.             else if( op == 'a' )
  792.                 absdiff( a, b, c );
  793.             else
  794.                 assert(0);
  795.         }
  796.         else
  797.         {
  798.             Mat temp;
  799.             apply(a, b, op, temp);
  800.             temp.convertTo(c, type);
  801.         }
  802.     }
  803. };
  804. template<typename M> class CV_EXPORTS MatOp_BinS_
  805. {
  806. public:
  807.     MatOp_BinS_() {}
  808.     static void apply(const M& a, const Scalar& s, int _op, M& c, int type=-1)
  809.     {
  810.         char op = (char)_op;
  811.         if( type == a.type() || type < 0 )
  812.         {
  813.             if( op == '&' )
  814.                 bitwise_and( a, s, c );
  815.             else if( op == '|' )
  816.                 bitwise_or( a, s, c );
  817.             else if( op == '^' )
  818.                 bitwise_xor( a, s, c );
  819.             else if( op == 'm' )
  820.                 min( a, s[0], c );
  821.             else if( op == 'M' )
  822.                 max( a, s[0], c );
  823.             else if( op == 'a' )
  824.                 absdiff( a, s, c );
  825.             else if( op == '~' )
  826.                 bitwise_not( a, c );
  827.             else
  828.                 assert(0);
  829.         }
  830.         else
  831.         {
  832.             Mat temp;
  833.             apply(a, s, op, temp);
  834.             temp.convertTo(c, type);
  835.         }
  836.     }
  837. };
  838. template<typename M> class CV_EXPORTS MatOp_T_
  839. {
  840. public:
  841.     MatOp_T_() {}
  842.     static void apply(const M& a, double scale, M& c, int type=-1)
  843.     {
  844.         if( type == a.type() || type < 0 )
  845.         {
  846.             transpose(a, c);
  847.             if( fabs(scale - 1) > DBL_EPSILON )
  848.                 c.convertTo(c, -1, scale, 0);
  849.         }
  850.         else
  851.         {
  852.             Mat temp;
  853.             apply(a, scale, temp);
  854.             temp.convertTo(c, type);
  855.         }
  856.     }
  857. };
  858. template<typename M> class CV_EXPORTS MatOp_MatMul_
  859. {
  860. public:
  861.     MatOp_MatMul_() {}
  862.     static void apply(const M& a, const M& b, double scale, int flags, M& c, int type=-1)
  863.     {
  864.         if( type == a.type() || type < 0 )
  865.         {
  866.             gemm(a, b, scale, Mat(), 0, c, flags);
  867.         }
  868.         else
  869.         {
  870.             Mat temp;
  871.             apply(a, b, scale, flags, temp);
  872.             temp.convertTo(c, type);
  873.         }
  874.     }
  875. };
  876. template<typename M> class CV_EXPORTS MatOp_MatMulAdd_
  877. {
  878. public:
  879.     MatOp_MatMulAdd_() {}
  880.     static void apply(const M& a, const M& b, double alpha,
  881.         const M& c, double beta, int flags, M& d, int type=-1)
  882.     {
  883.         if( type == a.type() || type < 0 )
  884.         {
  885.             gemm(a, b, alpha, c, beta, d, flags);
  886.         }
  887.         else
  888.         {
  889.             Mat temp;
  890.             apply(a, b, alpha, c, beta, flags, temp);
  891.             temp.convertTo(d, type);
  892.         }
  893.     }
  894. };
  895. template<typename M> class CV_EXPORTS MatOp_Cmp_
  896. {
  897. public:
  898.     MatOp_Cmp_() {}
  899.     static void apply(const M& a, const M& b, int op, M& c, int type=-1)
  900.     {
  901.         if( type == CV_8UC1 || type == -1 )
  902.         {
  903.             compare(a, b, c, op);
  904.         }
  905.         else
  906.         {
  907.             Mat temp;
  908.             apply(a, b, op, temp);
  909.             temp.convertTo(c, type);
  910.         }
  911.     }
  912. };
  913. template<typename M> class CV_EXPORTS MatOp_CmpS_
  914. {
  915. public:
  916.     MatOp_CmpS_() {}
  917.     static void apply(const M& a, double alpha, int op, M& c, int type=-1)
  918.     {
  919.         if( type == CV_8UC1 || type == -1 )
  920.         {
  921.             compare(a, alpha, c, op);
  922.         }
  923.         else
  924.         {
  925.             Mat temp;
  926.             apply(a, alpha, op, temp);
  927.             temp.convertTo(c, type);
  928.         }
  929.     }
  930. };
  931. template<typename M> class CV_EXPORTS MatOp_MulDiv_
  932. {
  933. public:
  934.     MatOp_MulDiv_() {}
  935.     static void apply(const M& a, const M& b, double alpha, char op, M& c, int type=-1)
  936.     {
  937.         if( type == a.type() || type == -1 )
  938.         {
  939.             if( op == '*' )
  940.                 multiply( a, b, c, alpha );
  941.             else
  942.                 divide( a, b, c, alpha );
  943.         }
  944.         else
  945.         {
  946.             Mat temp;
  947.             apply(a, b, alpha, op, temp);
  948.             temp.convertTo(c, type);
  949.         }
  950.     }
  951. };
  952. template<typename M> class CV_EXPORTS MatOp_DivRS_
  953. {
  954. public:
  955.     MatOp_DivRS_() {}
  956.     static void apply(const M& a, double alpha, M& c, int type=-1)
  957.     {
  958.         if( type == a.type() || type == -1 )
  959.         {
  960.             c.create(a.rows, a.cols, a.type());
  961.             divide( alpha, a, c );
  962.         }
  963.         else
  964.         {
  965.             Mat temp;
  966.             apply(a, alpha, temp);
  967.             temp.convertTo(c, type);
  968.         }
  969.     }
  970. };
  971. template<typename M> class CV_EXPORTS MatOp_Inv_
  972. {
  973. public:
  974.     MatOp_Inv_() {}
  975.     static void apply(const M& a, int method, M& c, int type=-1)
  976.     {
  977.         if( type == a.type() || type == -1 )
  978.         {
  979.             invert(a, c, method);
  980.         }
  981.         else
  982.         {
  983.             Mat temp;
  984.             apply(a, method, temp);
  985.             temp.convertTo(c, type);
  986.         }
  987.     }
  988. };
  989. template<typename M> class CV_EXPORTS MatOp_Solve_
  990. {
  991. public:
  992.     MatOp_Solve_() {}
  993.     static void apply(const M& a, const M& b, int method, M& c, int type=-1)
  994.     {
  995.         if( type == a.type() || type == -1 )
  996.         {
  997.             solve(a, b, c, method);
  998.         }
  999.         else
  1000.         {
  1001.             Mat temp;
  1002.             apply(a, b, method, temp);
  1003.             temp.convertTo(c, type);
  1004.         }
  1005.     }
  1006. };
  1007. template<typename M> class CV_EXPORTS MatOp_Set_
  1008. {
  1009. public:
  1010.     MatOp_Set_() {}
  1011.     static void apply(Size size, int type0, const Scalar& s, int mtype, M& c, int type=-1)
  1012.     {
  1013.         if( type < 0 )
  1014.             type = type0;
  1015.         c.create(size.height, size.width, type);
  1016.         if( mtype == 0 )
  1017.             c = Scalar(0);
  1018.         else if( mtype == 1 )
  1019.             c = s;
  1020.         else if( mtype == 2 )
  1021.             setIdentity(c, s);
  1022.     }
  1023. };
  1024. template<typename A1, typename M, typename Op>
  1025. class CV_EXPORTS MatExpr_Op1_
  1026. {
  1027. public:
  1028.     MatExpr_Op1_(const A1& _a1) : a1(_a1) {}
  1029.     void assignTo(Mat& m, int type=-1) const { Op::apply(a1, (M&)m, type); }
  1030.     operator M() const { M result; assignTo(result); return result; }
  1031.     A1 a1;
  1032. };
  1033. template<typename A1, typename A2, typename M, typename Op>
  1034. class CV_EXPORTS MatExpr_Op2_
  1035. {
  1036. public:
  1037.     MatExpr_Op2_(const A1& _a1, const A2& _a2) : a1(_a1), a2(_a2) {}
  1038.     void assignTo(Mat& m, int type=-1) const { Op::apply(a1, a2, (M&)m, type); }
  1039.     operator M() const { M result; assignTo(result); return result; }
  1040.     A1 a1; A2 a2;
  1041. };
  1042. template<typename A1, typename A2, typename A3, typename M, typename Op>
  1043. class CV_EXPORTS MatExpr_Op3_
  1044. {
  1045. public:
  1046.     MatExpr_Op3_(const A1& _a1, const A2& _a2, const A3& _a3) : a1(_a1), a2(_a2), a3(_a3) {}
  1047.     void assignTo(Mat& m, int type=-1) const { Op::apply(a1, a2, a3, (M&)m, type); }
  1048.     operator M() const { M result; assignTo(result); return result; }
  1049.     A1 a1; A2 a2; A3 a3;
  1050. };
  1051. template<typename A1, typename A2, typename A3, typename A4, typename M, typename Op>
  1052. class CV_EXPORTS MatExpr_Op4_
  1053. {
  1054. public:
  1055.     MatExpr_Op4_(const A1& _a1, const A2& _a2, const A3& _a3, const A4& _a4)
  1056.         : a1(_a1), a2(_a2), a3(_a3), a4(_a4) {}
  1057.     void assignTo(Mat& m, int type=-1) const { Op::apply(a1, a2, a3, a4, (M&)m, type); }
  1058.     operator M() const { M result; assignTo(result); return result; }
  1059.     A1 a1; A2 a2; A3 a3; A4 a4;
  1060. };
  1061. template<typename A1, typename A2, typename A3, typename A4, typename A5, typename M, typename Op>
  1062. class CV_EXPORTS MatExpr_Op5_
  1063. {
  1064. public:
  1065.     MatExpr_Op5_(const A1& _a1, const A2& _a2, const A3& _a3, const A4& _a4, const A5& _a5)
  1066.         : a1(_a1), a2(_a2), a3(_a3), a4(_a4), a5(_a5) {}
  1067.     void assignTo(Mat& m, int type=-1) const { Op::apply(a1, a2, a3, a4, a5, (M&)m, type); }
  1068.     operator M() const { M result; assignTo(result); return result; }
  1069.     A1 a1; A2 a2; A3 a3; A4 a4; A5 a5;
  1070. };
  1071. template<typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename M, typename Op>
  1072. class CV_EXPORTS MatExpr_Op6_
  1073. {
  1074. public:
  1075.     MatExpr_Op6_(const A1& _a1, const A2& _a2, const A3& _a3,
  1076.                     const A4& _a4, const A5& _a5, const A6& _a6)
  1077.         : a1(_a1), a2(_a2), a3(_a3), a4(_a4), a5(_a5), a6(_a6) {}
  1078.     void assignTo(Mat& m, int type=-1) const { Op::apply(a1, a2, a3, a4, a5, a6, (M&)m, type); }
  1079.     operator M() const { M result; assignTo(result); return result; }
  1080.     A1 a1; A2 a2; A3 a3; A4 a4; A5 a5; A6 a6;
  1081. };
  1082. ///////////////////////////////// Arithmetical Operations ///////////////////////////////////
  1083. // A + B
  1084. static inline MatExpr_<MatExpr_Op5_<Mat, double, Mat, double, double, Mat, MatOp_AddEx_<Mat> >, Mat>
  1085. operator + (const Mat& a, const Mat& b)
  1086. {
  1087.     typedef MatExpr_Op5_<Mat, double, Mat, double, double, Mat, MatOp_AddEx_<Mat> > MatExpr_Temp;
  1088.     return MatExpr_<MatExpr_Temp, Mat>(MatExpr_Temp(a, 1, b, 1, 0));
  1089. }
  1090. template<typename _Tp> static inline
  1091. MatExpr_<MatExpr_Op5_<Mat_<_Tp>, double, Mat_<_Tp>,
  1092. double, double, Mat_<_Tp>, MatOp_AddEx_<Mat> >, Mat_<_Tp> >
  1093. operator + (const Mat_<_Tp>& a, const Mat_<_Tp>& b)
  1094. {
  1095.     typedef MatExpr_Op5_<Mat_<_Tp>, double, Mat_<_Tp>, double, double, Mat_<_Tp>, MatOp_AddEx_<Mat> > MatExpr_Temp;
  1096.     return MatExpr_<MatExpr_Temp, Mat_<_Tp> >(MatExpr_Temp(a, 1, b, 1, 0));
  1097. }
  1098. // E1 + E2
  1099. template<typename A, typename B, typename M> static inline
  1100. MatExpr_<MatExpr_Op5_<M, double, M, double, double, M, MatOp_AddEx_<Mat> >, M>
  1101. operator + (const MatExpr_<A, M>& a, const MatExpr_<B, M>& b )
  1102. {
  1103.     typedef MatExpr_Op5_<M, double, M, double, double, M, MatOp_AddEx_<Mat> > MatExpr_Temp;
  1104.     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp((M)a, 1, (M)b, 1, 0));
  1105. }
  1106. // A - B
  1107. static inline MatExpr_<MatExpr_Op2_<Mat, Mat, Mat, MatOp_Sub_<Mat> >, Mat>
  1108. operator - (const Mat& a, const Mat& b)
  1109. {
  1110.     typedef MatExpr_Op2_<Mat, Mat, Mat, MatOp_Sub_<Mat> > MatExpr_Temp;
  1111.     return MatExpr_<MatExpr_Temp, Mat>(MatExpr_Temp(a, b));
  1112. }
  1113. template<typename _Tp> static inline
  1114. MatExpr_<MatExpr_Op2_<Mat_<_Tp>, Mat_<_Tp>, Mat_<_Tp>, MatOp_Sub_<Mat> >, Mat_<_Tp> >
  1115. operator - (const Mat_<_Tp>& a, const Mat_<_Tp>& b)
  1116. {
  1117.     typedef MatExpr_Op2_<Mat_<_Tp>, Mat_<_Tp>, Mat_<_Tp>, MatOp_Sub_<Mat> > MatExpr_Temp;
  1118.     return MatExpr_<MatExpr_Temp, Mat_<_Tp> >(MatExpr_Temp(a, b));
  1119. }
  1120. // E1 - E2
  1121. template<typename A, typename B, typename M> static inline
  1122. MatExpr_<MatExpr_Op2_<M, M, M, MatOp_Sub_<Mat> >, M>
  1123. operator - (const MatExpr_<A, M>& a, const MatExpr_<B, M>& b )
  1124. {
  1125.     typedef MatExpr_Op2_<M, M, M, MatOp_Sub_<Mat> > MatExpr_Temp;
  1126.     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp((M)a, (M)b));
  1127. }
  1128. // -(E1 - E2)
  1129. template<typename A, typename B, typename M> static inline
  1130. MatExpr_<MatExpr_Op2_<B, A, M, MatOp_Sub_<Mat> >, M>
  1131. operator - (const MatExpr_<MatExpr_Op2_<A, B, M, MatOp_Sub_<Mat> >, M>& a )
  1132. {
  1133.     typedef MatExpr_Op2_<B, A, M, MatOp_Sub_<Mat> > MatExpr_Temp;
  1134.     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(a.e.a2, a.e.a1));
  1135. }
  1136. // (A - B)*alpha
  1137. template<typename A, typename B, typename M> static inline
  1138. MatExpr_<MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> >, M>
  1139. operator * (const MatExpr_<MatExpr_Op2_<A, B, M, MatOp_Sub_<Mat> >, M>& a,
  1140.             double alpha)
  1141. {
  1142.     typedef MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> > MatExpr_Temp;
  1143.     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(a.e.a1, alpha, a.e.a2, -alpha, 0));
  1144. }
  1145. // alpha*(A - B)
  1146. template<typename A, typename B, typename M> static inline
  1147. MatExpr_<MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> >, M>
  1148. operator * (double alpha,
  1149.             const MatExpr_<MatExpr_Op2_<A, B, M, MatOp_Sub_<Mat> >, M>& a)
  1150. { return a*alpha; }
  1151. // A*alpha
  1152. static inline
  1153. MatExpr_<MatExpr_Op2_<Mat, double, Mat, MatOp_Scale_<Mat> >, Mat>
  1154. operator * (const Mat& a, double alpha)
  1155. {
  1156.     typedef MatExpr_Op2_<Mat, double, Mat, MatOp_Scale_<Mat> > MatExpr_Temp;
  1157.     return MatExpr_<MatExpr_Temp, Mat>(MatExpr_Temp(a, alpha));
  1158. }
  1159. // A*alpha
  1160. template<typename _Tp> static inline
  1161. MatExpr_<MatExpr_Op2_<Mat_<_Tp>, double, Mat_<_Tp>, MatOp_Scale_<Mat> >, Mat_<_Tp> >
  1162. operator * (const Mat_<_Tp>& a, double alpha)
  1163. {
  1164.     typedef MatExpr_Op2_<Mat_<_Tp>, double, Mat_<_Tp>, MatOp_Scale_<Mat> > MatExpr_Temp;
  1165.     return MatExpr_<MatExpr_Temp, Mat_<_Tp> >(MatExpr_Temp(a, alpha));
  1166. }
  1167. // alpha*A
  1168. static inline
  1169. MatExpr_<MatExpr_Op2_<Mat, double, Mat, MatOp_Scale_<Mat> >, Mat>
  1170. operator * (double alpha, const Mat& a)
  1171. { return a*alpha; }
  1172. // alpha*A
  1173. template<typename _Tp> static inline
  1174. MatExpr_<MatExpr_Op2_<Mat_<_Tp>, double, Mat_<_Tp>, MatOp_Scale_<Mat> >, Mat_<_Tp> >
  1175. operator * (double alpha, const Mat_<_Tp>& a)
  1176. { return a*alpha; }
  1177. // A/alpha
  1178. static inline
  1179. MatExpr_<MatExpr_Op2_<Mat, double, Mat, MatOp_Scale_<Mat> >, Mat>
  1180. operator / (const Mat& a, double alpha)
  1181. { return a*(1./alpha); }
  1182. // A/alpha
  1183. template<typename _Tp> static inline
  1184. MatExpr_<MatExpr_Op2_<Mat_<_Tp>, double, Mat_<_Tp>, MatOp_Scale_<Mat> >, Mat_<_Tp> >
  1185. operator / (const Mat_<_Tp>& a, double alpha)
  1186. { return a*(1./alpha); }
  1187. // -A
  1188. static inline
  1189. MatExpr_<MatExpr_Op2_<Mat, double, Mat, MatOp_Scale_<Mat> >, Mat>
  1190. operator - (const Mat& a)
  1191. { return a*(-1); }
  1192. // -A
  1193. template<typename _Tp> static inline
  1194. MatExpr_<MatExpr_Op2_<Mat_<_Tp>, double, Mat_<_Tp>, MatOp_Scale_<Mat> >, Mat_<_Tp> >
  1195. operator - (const Mat_<_Tp>& a)
  1196. { return a*(-1); }
  1197. // E*alpha
  1198. template<typename A, typename M> static inline
  1199. MatExpr_<MatExpr_Op2_<M, double, M, MatOp_Scale_<Mat> >, M>
  1200. operator * (const MatExpr_<A, M>& a, double alpha)
  1201. {
  1202.     typedef MatExpr_Op2_<M, double, M, MatOp_Scale_<Mat> > MatExpr_Temp;
  1203.     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp((M)a, alpha));
  1204. }
  1205. // alpha*E
  1206. template<typename A, typename M> static inline
  1207. MatExpr_<MatExpr_Op2_<M, double, M, MatOp_Scale_<Mat> >, M>
  1208. operator * (double alpha, const MatExpr_<A, M>& a)
  1209. { return a*alpha; }
  1210. // E/alpha
  1211. template<typename A, typename M> static inline
  1212. MatExpr_<MatExpr_Op2_<M, double, M, MatOp_Scale_<Mat> >, M>
  1213. operator / (const MatExpr_<A, M>& a, double alpha)
  1214. { return a*(1./alpha); }
  1215. // (E*alpha)*beta ~ E*(alpha*beta)
  1216. template<typename A, typename M> static inline
  1217. MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>
  1218. operator * (const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& a,
  1219.             double beta)
  1220. { return a.e.a1*(a.e.a2*beta); }
  1221. // beta*(E*alpha) ~ E*(alpha*beta)
  1222. template<typename A, typename M> static inline
  1223. MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>
  1224. operator * (double beta,
  1225.             const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& a)
  1226. { return a.e.a1*(a.e.a2*beta); }
  1227. // (E*alpha)/beta ~ E*(alpha/beta)
  1228. template<typename A, typename M> static inline
  1229. MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>
  1230. operator / (const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& a,
  1231.             double beta)
  1232. { return a.e.a1*(a.e.a2/beta); }
  1233. // -E ~ E*(-1)
  1234. template<typename A, typename M> static inline
  1235. MatExpr_<MatExpr_Op2_<MatExpr_<A, M>, double, M, MatOp_Scale_<Mat> >, M>
  1236. operator - (const MatExpr_<A, M>& a)
  1237. { return a*(-1); }
  1238. // -(E*alpha) ~ E*(-alpha)
  1239. template<typename A, typename M> static inline
  1240. MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>
  1241. operator - (const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& a)
  1242. { return a.e.a1*(-a.e.a2); }
  1243. // A + alpha
  1244. template<typename _Tp> static inline
  1245. MatExpr_<MatExpr_Op3_<Mat_<_Tp>, double, double, Mat_<_Tp>, MatOp_ScaleAddS_<Mat> >, Mat_<_Tp> >
  1246. operator + (const Mat_<_Tp>& a, double alpha)
  1247. {
  1248.     typedef MatExpr_Op3_<Mat_<_Tp>, double, double, Mat_<_Tp>,
  1249.         MatOp_ScaleAddS_<Mat> > MatExpr_Temp;
  1250.     return MatExpr_<MatExpr_Temp, Mat_<_Tp> >(MatExpr_Temp(a, 1, alpha));
  1251. }
  1252. // A + alpha
  1253. template<typename _Tp> static inline
  1254. MatExpr_<MatExpr_Op2_<Mat_<_Tp>, Scalar, Mat_<_Tp>, MatOp_AddS_<Mat> >, Mat_<_Tp> >
  1255. operator + (const Mat_<_Tp>& a, const Scalar& alpha)
  1256. {
  1257.     typedef MatExpr_Op2_<Mat_<_Tp>, Scalar, Mat_<_Tp>,
  1258.         MatOp_AddS_<Mat> > MatExpr_Temp;
  1259.     return MatExpr_<MatExpr_Temp, Mat_<_Tp> >(MatExpr_Temp(a, alpha));
  1260. }
  1261. // alpha + A
  1262. template<typename _Tp> static inline
  1263. MatExpr_<MatExpr_Op3_<Mat_<_Tp>, double, double, Mat_<_Tp>, MatOp_ScaleAddS_<Mat> >, Mat_<_Tp> >
  1264. operator + (double alpha, const Mat_<_Tp>& a)
  1265. { return a + alpha; }
  1266. // alpha + A
  1267. template<typename _Tp> static inline
  1268. MatExpr_<MatExpr_Op2_<Mat_<_Tp>, Scalar, Mat_<_Tp>, MatOp_AddS_<Mat> >, Mat_<_Tp> >
  1269. operator + (const Scalar& alpha, const Mat_<_Tp>& a)
  1270. { return a + alpha; }
  1271. // A - alpha
  1272. template<typename _Tp> static inline
  1273. MatExpr_<MatExpr_Op3_<Mat_<_Tp>, double, double, Mat_<_Tp>, MatOp_ScaleAddS_<Mat> >, Mat_<_Tp> >
  1274. operator - (const Mat_<_Tp>& a, double alpha)
  1275. { return a + (-alpha); }
  1276. // A - alpha
  1277. template<typename _Tp> static inline
  1278. MatExpr_<MatExpr_Op2_<Mat_<_Tp>, Scalar, Mat_<_Tp>, MatOp_AddS_<Mat> >, Mat_<_Tp> >
  1279. operator - (const Mat_<_Tp>& a, const Scalar& alpha)
  1280. { return a + (-alpha); }
  1281. // alpha - A
  1282. template<typename _Tp> static inline
  1283. MatExpr_<MatExpr_Op3_<Mat_<_Tp>, double, double, Mat_<_Tp>, MatOp_ScaleAddS_<Mat> >, Mat_<_Tp> >
  1284. operator - (double alpha, const Mat_<_Tp>& a)
  1285. {
  1286.     typedef MatExpr_Op3_<Mat_<_Tp>, double, double, Mat_<_Tp>,
  1287.         MatOp_ScaleAddS_<Mat> > MatExpr_Temp;
  1288.     return MatExpr_<MatExpr_Temp, Mat_<_Tp> >(MatExpr_Temp(a, -1, alpha));
  1289. }
  1290. // E + alpha
  1291. template<typename A, typename M> static inline
  1292. MatExpr_<MatExpr_Op3_<M, double, double, M, MatOp_ScaleAddS_<Mat> >, M>
  1293. operator + (const MatExpr_<A, M>& a, double alpha)
  1294. {
  1295.     typedef MatExpr_Op3_<M, double, double, M, MatOp_ScaleAddS_<Mat> > MatExpr_Temp;
  1296.     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp((M)a, 1, alpha));
  1297. }
  1298. // E + alpha
  1299. template<typename A, typename M> static inline
  1300. MatExpr_<MatExpr_Op2_<M, Scalar, M, MatOp_AddS_<Mat> >, M>
  1301. operator + (const MatExpr_<A, M>& a, const Scalar& alpha)
  1302. {
  1303.     typedef MatExpr_Op2_<M, Scalar, M, MatOp_AddS_<Mat> > MatExpr_Temp;
  1304.     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp((M)a, alpha));
  1305. }
  1306. // alpha + E
  1307. template<typename A, typename M> static inline
  1308. MatExpr_<MatExpr_Op3_<M, double, double, M, MatOp_ScaleAddS_<Mat> >, M>
  1309. operator + (double alpha, const MatExpr_<A, M>& a)
  1310. { return a + alpha; }
  1311. // alpha + E
  1312. template<typename A, typename M> static inline
  1313. MatExpr_<MatExpr_Op2_<M, Scalar, M, MatOp_AddS_<Mat> >, M>
  1314. operator + (const Scalar& alpha, const MatExpr_<A, M>& a)
  1315. { return a + alpha; }
  1316. // E - alpha
  1317. template<typename A, typename M> static inline
  1318. MatExpr_<MatExpr_Op3_<M, double, double, M, MatOp_ScaleAddS_<Mat> >, M>
  1319. operator - (const MatExpr_<A, M>& a, double alpha)
  1320. { return a + (-alpha); }
  1321. // E - alpha
  1322. template<typename A, typename M> static inline
  1323. MatExpr_<MatExpr_Op2_<M, Scalar, M, MatOp_AddS_<Mat> >, M>
  1324. operator - (const MatExpr_<A, M>& a, const Scalar& alpha)
  1325. { return a + (-alpha); }
  1326. // alpha - E
  1327. template<typename A, typename M> static inline
  1328. MatExpr_<MatExpr_Op3_<M, double, double, M, MatOp_ScaleAddS_<Mat> >, M>
  1329. operator - (double alpha, const MatExpr_<A, M>& a)
  1330. {
  1331.     typedef MatExpr_Op3_<M, double, double, M, MatOp_ScaleAddS_<Mat> > MatExpr_Temp;
  1332.     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(a, -1, alpha));
  1333. }
  1334. // E*alpha + beta
  1335. template<typename A, typename M> static inline
  1336. MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>
  1337. operator + (const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& a,
  1338.             double beta)
  1339. {
  1340.     typedef MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> > MatExpr_Temp;
  1341.     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(a.e.a1, a.e.a2, beta));
  1342. }
  1343. // beta + E*alpha
  1344. template<typename A, typename M> static inline
  1345. MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>
  1346. operator + (double beta,
  1347.             const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& a)
  1348. { return a + beta; }
  1349. // E*alpha - beta
  1350. template<typename A, typename M> static inline
  1351. MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>
  1352. operator - (const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& a,
  1353.             double beta)
  1354. { return a + (-beta); }
  1355. // beta - E*alpha
  1356. template<typename A, typename M> static inline
  1357. MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>
  1358. operator - (double beta,
  1359.             const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& a)
  1360. { return (a.e.a1*(-a.e.a2)) + beta; }
  1361. // (E*alpha + gamma) + beta ~ E*alpha + (gamma + beta)
  1362. template<typename A, typename M> static inline
  1363. MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>
  1364. operator + (const MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>& a,
  1365.             double beta)
  1366. { return a.e.a1*a.e.a2 + (a.e.a3 + beta); }
  1367. // beta + (E*alpha + gamma)
  1368. template<typename A, typename M> static inline
  1369. MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>
  1370. operator + (double beta, const MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>& a)
  1371. { return a + beta; }
  1372. // (E*alpha + gamma) - beta
  1373. template<typename A, typename M> static inline
  1374. MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>
  1375. operator - (const MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>& a,
  1376.             double beta)
  1377. { return a + (-beta); }
  1378. // beta - (E*alpha + gamma)
  1379. template<typename A, typename M> static inline
  1380. MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>
  1381. operator - (double beta, const MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>& a)
  1382. { return a.e.a1*(-a.e.a2) + (beta - a.e.a3); }
  1383. // (E*alpha + gamma)*beta
  1384. template<typename A, typename M> static inline
  1385. MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>
  1386. operator * (const MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>& a,
  1387.             double beta)
  1388. { return a.e.a1*(a.e.a2*beta) + (a.e.a3*beta); }
  1389. // beta*(E*alpha + gamma)
  1390. template<typename A, typename M> static inline
  1391. MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>
  1392. operator * (double beta, const MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>& a)
  1393. { return a*beta; }
  1394. // -(E*alpha + beta)
  1395. template<typename A, typename M> static inline
  1396. MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>
  1397. operator - (const MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>& a)
  1398. { return a*(-1); }
  1399. // (A*u + B*v + w) + beta
  1400. template<typename A, typename B, typename M> static inline
  1401. MatExpr_<MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> >, M>
  1402. operator + (const MatExpr_<MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> >, M>& a,
  1403.             double beta )
  1404. {
  1405.     typedef MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> > MatExpr_Temp;
  1406.     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(a.e.a1, a.e.a2, a.e.a3, a.e.a4, a.e.a5 + beta));
  1407. }
  1408. // beta + (A*u + B*v + w)
  1409. template<typename A, typename B, typename M> static inline
  1410. MatExpr_<MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> >, M>
  1411. operator + (double beta,
  1412.             const MatExpr_<MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> >, M>& a)
  1413. { return a + beta; }
  1414. // (A*u + B*v + w) - beta
  1415. template<typename A, typename B, typename M> static inline
  1416. MatExpr_<MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> >, M>
  1417. operator - (const MatExpr_<MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> >, M>& a,
  1418.             double beta)
  1419. { return a + (-beta); }
  1420. // beta - (A*u + B*v + w)
  1421. template<typename A, typename B, typename M> static inline
  1422. MatExpr_<MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> >, M>
  1423. operator - (double beta,
  1424.             const MatExpr_<MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> >, M>& a)
  1425. {
  1426.     typedef MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> > MatExpr_Temp;
  1427.     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(a.e.a1, -a.e.a2, a.e.a3, -a.e.a4, -a.e.a5 + beta));
  1428. }
  1429. // (A*u + B*v + w)*beta
  1430. template<typename A, typename B, typename M> static inline
  1431. MatExpr_<MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> >, M>
  1432. operator * (const MatExpr_<MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> >, M>& a,
  1433.             double beta )
  1434. {
  1435.     typedef MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> > MatExpr_Temp;
  1436.     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(a.e.a1,
  1437.         a.e.a2*beta, a.e.a3, a.e.a4*beta, a.e.a5*beta));
  1438. }
  1439. // beta*(A*u + B*v + w)
  1440. template<typename A, typename B, typename M> static inline
  1441. MatExpr_<MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> >, M>
  1442. operator * (double beta,
  1443.             const MatExpr_<MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> >, M>& a)
  1444. { return a * beta; }
  1445. // -(A*u + B*v + w)
  1446. template<typename A, typename B, typename M> static inline
  1447. MatExpr_<MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> >, M>
  1448. operator - (const MatExpr_<MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> >, M>& a)
  1449. { return a*(-1); }
  1450. // A*alpha + B
  1451. template<typename A, typename M> static inline
  1452. MatExpr_<MatExpr_Op5_<A, double, M, double, double, M, MatOp_AddEx_<Mat> >, M>
  1453. operator + (const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& a,
  1454.             const M& b )
  1455. {
  1456.     typedef MatExpr_Op5_<A, double, M, double, double, M, MatOp_AddEx_<Mat> > MatExpr_Temp;
  1457.     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(a.e.a1, a.e.a2, b, 1, 0));
  1458. }
  1459. // B + A*alpha
  1460. template<typename A, typename M> static inline
  1461. MatExpr_<MatExpr_Op5_<A, double, M, double, double, M, MatOp_AddEx_<Mat> >, M>
  1462. operator + (const M& b,
  1463.             const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& a)
  1464. { return a + b; }
  1465. // (A*alpha + beta) + B
  1466. template<typename A, typename M> static inline
  1467. MatExpr_<MatExpr_Op5_<A, double, M, double, double, M, MatOp_AddEx_<Mat> >, M>
  1468. operator + (const MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>& a,
  1469.             const M& b )
  1470. {
  1471.     typedef MatExpr_Op5_<A, double, M, double, double, M, MatOp_AddEx_<Mat> > MatExpr_Temp;
  1472.     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(a.e.a1, a.e.a2, b, 1, a.e.a3));
  1473. }
  1474. // B + (A*alpha + beta)
  1475. template<typename A, typename M> static inline
  1476. MatExpr_<MatExpr_Op5_<A, double, M, double, double, M, MatOp_AddEx_<Mat> >, M>
  1477. operator + (const M& b,
  1478.             const MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>& a)
  1479. { return a + b; }
  1480. // A*alpha + E
  1481. template<typename A, typename B, typename M> static inline
  1482. MatExpr_<MatExpr_Op5_<A, double, M, double, double, M, MatOp_AddEx_<Mat> >, M>
  1483. operator + (const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& a,
  1484.             const MatExpr_<B, M>& b )
  1485. { return a + (M)b; }
  1486. // E + A*alpha
  1487. template<typename A, typename B, typename M> static inline
  1488. MatExpr_<MatExpr_Op5_<A, double, M, double, double, M, MatOp_AddEx_<Mat> >, M>
  1489. operator + (const MatExpr_<B, M>& b,
  1490.             const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& a)
  1491. { return a + (M)b; }
  1492. // (A*alpha + beta) + E
  1493. template<typename A, typename B, typename M> static inline
  1494. MatExpr_<MatExpr_Op5_<A, double, M, double, double, M, MatOp_AddEx_<Mat> >, M>
  1495. operator + (const MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>& a,
  1496.             const MatExpr_<B, M>& b )
  1497. { return a + (M)b; }
  1498. // E + (A*alpha + beta)
  1499. template<typename A, typename B, typename M> static inline
  1500. MatExpr_<MatExpr_Op5_<A, double, M, double, double, M, MatOp_AddEx_<Mat> >, M>
  1501. operator + (const MatExpr_<B, M>& b,
  1502.             const MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>& a)
  1503. { return a + b; }
  1504. // A*alpha + B*beta
  1505. template<typename A, typename B, typename M> static inline
  1506. MatExpr_<MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> >, M>
  1507. operator + (const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& a,
  1508.             const MatExpr_<MatExpr_Op2_<B, double, M, MatOp_Scale_<Mat> >, M>& b )
  1509. {
  1510.     typedef MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> > MatExpr_Temp;
  1511.     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(a.e.a1, a.e.a2, b.e.a1, b.e.a2, 0));
  1512. }
  1513. // (A*alpha + beta) + B*gamma
  1514. template<typename A, typename B, typename M> static inline
  1515. MatExpr_<MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> >, M>
  1516. operator + (const MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>& a,
  1517.             const MatExpr_<MatExpr_Op2_<B, double, M, MatOp_Scale_<Mat> >, M>& b )
  1518. {
  1519.     typedef MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> > MatExpr_Temp;
  1520.     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(a.e.a1, a.e.a2, b.e.a1, b.e.a2, a.e.a3));
  1521. }
  1522. // B*gamma + (A*alpha + beta)
  1523. template<typename A, typename B, typename M> static inline
  1524. MatExpr_<MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> >, M>
  1525. operator + (const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& b,
  1526.             const MatExpr_<MatExpr_Op3_<B, double, double, M, MatOp_ScaleAddS_<Mat> >, M>& a )
  1527. { return a + b; }
  1528. // (A*alpha + beta) + (B*gamma + theta)
  1529. template<typename A, typename B, typename M> static inline
  1530. MatExpr_<MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> >, M>
  1531. operator + (const MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>& a,
  1532.             const MatExpr_<MatExpr_Op3_<B, double, double, M, MatOp_ScaleAddS_<Mat> >, M>& b )
  1533. {
  1534.     typedef MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> > MatExpr_Temp;
  1535.     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));
  1536. }
  1537. // A*alpha - B
  1538. template<typename A, typename M> static inline
  1539. MatExpr_<MatExpr_Op5_<A, double, M, double, double, M, MatOp_AddEx_<Mat> >, M>
  1540. operator - (const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& a,
  1541.             const M& b )
  1542. {
  1543.     typedef MatExpr_Op5_<A, double, M, double, double, M, MatOp_AddEx_<Mat> > MatExpr_Temp;
  1544.     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(a.e.a1, a.e.a2, b, -1, 0));
  1545. }
  1546. // B - A*alpha
  1547. template<typename A, typename M> static inline
  1548. MatExpr_<MatExpr_Op5_<A, double, M, double, double, M, MatOp_AddEx_<Mat> >, M>
  1549. operator - (const M& b,
  1550.             const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& a)
  1551. {
  1552.     typedef MatExpr_Op5_<A, double, M, double, double, M, MatOp_AddEx_<Mat> > MatExpr_Temp;
  1553.     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(a.e.a1, -a.e.a2, b, 1, 0));
  1554. }
  1555. // (A*alpha + beta) - B
  1556. template<typename A, typename M> static inline
  1557. MatExpr_<MatExpr_Op5_<A, double, M, double, double, M, MatOp_AddEx_<Mat> >, M>
  1558. operator - (const MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>& a,
  1559.             const M& b )
  1560. {
  1561.     typedef MatExpr_Op5_<A, double, M, double, double, M, MatOp_AddEx_<Mat> > MatExpr_Temp;
  1562.     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(a.e.a1, a.e.a2, b, -1, a.e.a3));
  1563. }
  1564. // B - (A*alpha + beta)
  1565. template<typename A, typename M> static inline
  1566. MatExpr_<MatExpr_Op5_<A, double, M, double, double, M, MatOp_AddEx_<Mat> >, M>
  1567. operator - (const M& b,
  1568.             const MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>& a)
  1569. {
  1570.     typedef MatExpr_Op5_<A, double, M, double, double, M, MatOp_AddEx_<Mat> > MatExpr_Temp;
  1571.     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(a.e.a1, a.e.a2, b, -1, a.e.a3));
  1572. }
  1573. // A*alpha - E
  1574. template<typename A, typename B, typename M> static inline
  1575. MatExpr_<MatExpr_Op5_<A, double, M, double, double, M, MatOp_AddEx_<Mat> >, M>
  1576. operator - (const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& a,
  1577.             const MatExpr_<B, M>& b )
  1578. { return a - (M)b; }
  1579. // E - A*alpha
  1580. template<typename A, typename B, typename M> static inline
  1581. MatExpr_<MatExpr_Op5_<A, double, M, double, double, M, MatOp_AddEx_<Mat> >, M>
  1582. operator - (const MatExpr_<B, M>& b,
  1583.             const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& a)
  1584. { return (M)b - a; }
  1585. // (A*alpha + beta) - E
  1586. template<typename A, typename B, typename M> static inline
  1587. MatExpr_<MatExpr_Op5_<A, double, M, double, double, M, MatOp_AddEx_<Mat> >, M>
  1588. operator - (const MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>& a,
  1589.             const MatExpr_<B, M>& b )
  1590. { return a - (M)b; }
  1591. // E - (A*alpha + beta)
  1592. template<typename A, typename B, typename M> static inline
  1593. MatExpr_<MatExpr_Op5_<A, double, M, double, double, M, MatOp_AddEx_<Mat> >, M>
  1594. operator - (const MatExpr_<B, M>& b,
  1595.             const MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>& a)
  1596. { return (M)b - a; }
  1597. // A*alpha - B*beta
  1598. template<typename A, typename B, typename M> static inline
  1599. MatExpr_<MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> >, M>
  1600. operator - (const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& a,
  1601.             const MatExpr_<MatExpr_Op2_<B, double, M, MatOp_Scale_<Mat> >, M>& b )
  1602. {
  1603.     typedef MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> > MatExpr_Temp;
  1604.     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(a.e.a1, a.e.a2, b.e.a1, -b.e.a2, 0));
  1605. }
  1606. // (A*alpha + beta) - B*gamma
  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_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>& a,
  1610.             const MatExpr_<MatExpr_Op2_<B, double, M, MatOp_Scale_<Mat> >, M>& b )
  1611. {
  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, b.e.a1, -b.e.a2, a.e.a3));
  1614. }
  1615. // B*gamma - (A*alpha + beta)
  1616. template<typename A, typename B, typename M> static inline
  1617. MatExpr_<MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> >, M>
  1618. operator - (const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& b,
  1619.             const MatExpr_<MatExpr_Op3_<B, double, double, M, MatOp_ScaleAddS_<Mat> >, M>& a )
  1620. {
  1621.     typedef MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> > MatExpr_Temp;
  1622.     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(a.e.a1, -a.e.a2, b.e.a1, b.e.a2, -a.e.a3));
  1623. }
  1624. // (A*alpha + beta) - (B*gamma + theta)
  1625. template<typename A, typename B, typename M> static inline
  1626. MatExpr_<MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> >, M>
  1627. operator - (const MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>& a,
  1628.             const MatExpr_<MatExpr_Op3_<B, double, double, M, MatOp_ScaleAddS_<Mat> >, M>& b )
  1629. {
  1630.     typedef MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> > MatExpr_Temp;
  1631.     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));
  1632. }
  1633. /////////////////////////////// Mat Multiplication ///////////////////////////////////
  1634. // A^t
  1635. inline MatExpr_<MatExpr_Op2_<Mat, double, Mat, MatOp_T_<Mat> >, Mat>
  1636. Mat::t() const
  1637. {
  1638.     typedef MatExpr_Op2_<Mat, double, Mat, MatOp_T_<Mat> > MatExpr_Temp;
  1639.     return MatExpr_<MatExpr_Temp, Mat>(MatExpr_Temp(*this, 1));
  1640. }
  1641. template<typename _Tp> inline
  1642. MatExpr_<MatExpr_Op2_<Mat_<_Tp>, double, Mat_<_Tp>, MatOp_T_<Mat> >, Mat_<_Tp> >
  1643. Mat_<_Tp>::t() const
  1644. {
  1645.     typedef MatExpr_Op2_<Mat_<_Tp>, double, Mat_<_Tp>, MatOp_T_<Mat> > MatExpr_Temp;
  1646.     return MatExpr_<MatExpr_Temp, Mat_<_Tp> >(MatExpr_Temp(*this, 1));
  1647. }
  1648. // A*B
  1649. static inline
  1650. MatExpr_<MatExpr_Op4_<Mat, Mat, double, int, Mat, MatOp_MatMul_<Mat> >, Mat>
  1651. operator * ( const Mat& a, const Mat& b )
  1652. {
  1653.     typedef MatExpr_Op4_<Mat, Mat, double, int, Mat, MatOp_MatMul_<Mat> > MatExpr_Temp;
  1654.     return MatExpr_<MatExpr_Temp, Mat>(MatExpr_Temp(a, b, 1, 0));
  1655. }
  1656. template<typename _Tp> static inline
  1657. MatExpr_<MatExpr_Op4_<Mat_<_Tp>, Mat_<_Tp>, double, int, Mat_<_Tp>,
  1658. MatOp_MatMul_<Mat> >, Mat_<_Tp> >
  1659. operator * ( const Mat_<_Tp>& a, const Mat_<_Tp>& b )
  1660. {
  1661.     typedef MatExpr_Op4_<Mat_<_Tp>, Mat_<_Tp>, double, int, Mat_<_Tp>,
  1662.         MatOp_MatMul_<Mat> > MatExpr_Temp;
  1663.     return MatExpr_<MatExpr_Temp, Mat_<_Tp> >(MatExpr_Temp(a, b, 1, 0));
  1664. }
  1665. template<typename A, typename B, typename M> static inline
  1666. MatExpr_<MatExpr_Op4_<M, M, double, int, M, MatOp_MatMul_<Mat> >, M>
  1667. operator * ( const MatExpr_<A, M>& a, const MatExpr_<B, M>& b )
  1668. {
  1669.     typedef MatExpr_Op4_<M, M, double, int, M, MatOp_MatMul_<Mat> > MatExpr_Temp;
  1670.     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp((M)a, (M)b, 1, 0));
  1671. }
  1672. // (A*alpha)*B
  1673. template<typename A, typename M> static inline
  1674. MatExpr_<MatExpr_Op4_<M, M, double, int, M, MatOp_MatMul_<Mat> >, M>
  1675. operator * ( const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& a, const M& b )
  1676. {
  1677.     typedef MatExpr_Op4_<M, M, double, int, M, MatOp_MatMul_<Mat> > MatExpr_Temp;
  1678.     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp((M)a.e.a1, b, a.e.a2, 0));
  1679. }
  1680. // A*(B*alpha)
  1681. template<typename A, typename M> static inline
  1682. MatExpr_<MatExpr_Op4_<M, M, double, int, M, MatOp_MatMul_<Mat> >, M>
  1683. operator * ( const M& b, const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& a )
  1684. {
  1685.     typedef MatExpr_Op4_<M, M, double, int, M, MatOp_MatMul_<Mat> > MatExpr_Temp;
  1686.     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(b, (M)a.e.a1, a.e.a2, 0));
  1687. }
  1688. // A^t*B
  1689. template<typename A, typename M> static inline
  1690. MatExpr_<MatExpr_Op4_<M, M, double, int, M, MatOp_MatMul_<Mat> >, M>
  1691. operator * ( const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_T_<Mat> >, M>& a, const M& b )
  1692. {
  1693.     typedef MatExpr_Op4_<M, M, double, int, M, MatOp_MatMul_<Mat> > MatExpr_Temp;
  1694.     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp((M)a.e.a1, b, a.e.a2, GEMM_1_T));
  1695. }
  1696. // A*B^t
  1697. template<typename A, typename M> static inline
  1698. MatExpr_<MatExpr_Op4_<M, M, double, int, M, MatOp_MatMul_<Mat> >, M>
  1699. operator * ( const M& a, const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_T_<Mat> >, M>& b )
  1700. {
  1701.     typedef MatExpr_Op4_<M, M, double, int, M, MatOp_MatMul_<Mat> > MatExpr_Temp;
  1702.     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(a, (M)b.e.a1, b.e.a2, GEMM_2_T));
  1703. }
  1704. // (A*alpha)*(B*beta)
  1705. template<typename A, typename B, typename M> static inline
  1706. MatExpr_<MatExpr_Op4_<M, M, double, int, M, MatOp_MatMul_<Mat> >, M>
  1707. operator * ( const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& a,
  1708.              const MatExpr_<MatExpr_Op2_<B, double, M, MatOp_Scale_<Mat> >, M>& b )
  1709. {
  1710.     typedef MatExpr_Op4_<M, M, double, int, M, MatOp_MatMul_<Mat> > MatExpr_Temp;
  1711.     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp((M)a.e.a1, (M)b.e.a1, a.e.a2*b.e.a2, 0));
  1712. }
  1713. // A^t*(B*alpha)
  1714. template<typename A, typename B, typename M> static inline
  1715. MatExpr_<MatExpr_Op4_<M, M, double, int, M, MatOp_MatMul_<Mat> >, M>
  1716. operator * ( const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_T_<Mat> >, M>& a,
  1717.              const MatExpr_<MatExpr_Op2_<B, double, M, MatOp_Scale_<Mat> >, M>& b )
  1718. {
  1719.     typedef MatExpr_Op4_<M, M, double, int, M, MatOp_MatMul_<Mat> > MatExpr_Temp;
  1720.     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp((M)a.e.a1, (M)b.e.a1, a.e.a2*b.e.a2, GEMM_1_T));
  1721. }
  1722. // (A*alpha)*B^t
  1723. template<typename A, typename B, typename M> static inline
  1724. MatExpr_<MatExpr_Op4_<M, M, double, int, M, MatOp_MatMul_<Mat> >, M>
  1725. operator * ( const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& a,
  1726.              const MatExpr_<MatExpr_Op2_<B, double, M, MatOp_T_<Mat> >, M>& b )
  1727. {
  1728.     typedef MatExpr_Op4_<M, M, double, int, M, MatOp_MatMul_<Mat> > MatExpr_Temp;
  1729.     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp((M)a.e.a1, (M)b.e.a1, a.e.a2*b.e.a2, GEMM_2_T));
  1730. }
  1731. // A^t*B^t
  1732. template<typename A, typename B, typename M> static inline
  1733. MatExpr_<MatExpr_Op4_<M, M, double, int, M, MatOp_MatMul_<Mat> >, M>
  1734. operator * ( const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_T_<Mat> >, M>& a,
  1735.              const MatExpr_<MatExpr_Op2_<B, double, M, MatOp_T_<Mat> >, M>& b )
  1736. {
  1737.     typedef MatExpr_Op4_<M, M, double, int, M, MatOp_MatMul_<Mat> > MatExpr_Temp;
  1738.     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp((M)a.e.a1,
  1739.         (M)b.e.a1, a.e.a2*b.e.a2, GEMM_1_T+GEMM_2_T));
  1740. }
  1741. // (A*B)*alpha
  1742. template<typename A, typename B, typename M> static inline
  1743. MatExpr_<MatExpr_Op4_<A, B, double, int, M, MatOp_MatMul_<Mat> >, M>
  1744. operator * ( const MatExpr_<MatExpr_Op4_<A, B, double, int, M, MatOp_MatMul_<Mat> >, M>& a,
  1745.              double alpha )
  1746. {
  1747.     typedef MatExpr_Op4_<A, B, double, int, M, MatOp_MatMul_<Mat> > MatExpr_Temp;
  1748.     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(a.e.a1, a.e.a2, a.e.a3*alpha, a.e.a4));
  1749. }
  1750. // alpha*(A*B)
  1751. template<typename A, typename B, typename M> static inline
  1752. MatExpr_<MatExpr_Op4_<M, M, double, int, M, MatOp_MatMul_<Mat> >, M>
  1753. operator * ( double alpha,
  1754.              const MatExpr_<MatExpr_Op4_<A, B, double, int, M, MatOp_MatMul_<Mat> >, M>& a )
  1755. {
  1756.     return a*alpha;
  1757. }
  1758. // -(A*B)
  1759. template<typename A, typename B, typename M> static inline
  1760. MatExpr_<MatExpr_Op4_<A, B, double, int, M, MatOp_MatMul_<Mat> >, M>
  1761. operator - ( const MatExpr_<MatExpr_Op4_<A, B, double, int, M, MatOp_MatMul_<Mat> >, M>& a )
  1762. {
  1763.     return a*(-1);
  1764. }
  1765. // (A*alpha + beta)*B
  1766. template<typename A, typename M> static inline
  1767. MatExpr_<MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> >, M>
  1768. operator * ( const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_ScaleAddS_<Mat> >, M>& a, const M& b )
  1769. {
  1770.     typedef MatExpr_Op4_<M, M, double, int, M, MatOp_MatMul_<Mat> > MatExpr_Temp;
  1771.     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp((M)a.e.a1, b, a.e.a2, b, a.e.a3, 0));
  1772. }
  1773. // A*(B*alpha + beta)
  1774. template<typename A, typename M> static inline
  1775. MatExpr_<MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> >, M>
  1776. operator * ( const M& a, const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_ScaleAddS_<Mat> >, M>& b )
  1777. {
  1778.     typedef MatExpr_Op4_<M, M, double, int, M, MatOp_MatMul_<Mat> > MatExpr_Temp;
  1779.     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(a, (M)b.e.a1, b.e.a2, a, b.e.a3, 0));
  1780. }
  1781. // (A*alpha + beta)*(B*gamma)
  1782. template<typename A, typename B, typename M> static inline
  1783. MatExpr_<MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> >, M>
  1784. operator * ( const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_ScaleAddS_<Mat> >, M>& a,
  1785.              const MatExpr_<MatExpr_Op2_<B, double, M, MatOp_Scale_<Mat> >, M>& b )
  1786. {
  1787.     typedef MatExpr_Op4_<M, M, double, int, M, MatOp_MatMul_<Mat> > MatExpr_Temp;
  1788.     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp((M)a.e.a1, (M)b.e.a1,
  1789.         a.e.a2*b.e.a2, (M)b.e.a1, a.e.a3*b.e.a2, 0));
  1790. }
  1791. // (A*gamma)*(B*alpha + beta)
  1792. template<typename A, typename B, typename M> static inline
  1793. MatExpr_<MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> >, M>
  1794. operator * ( const MatExpr_<MatExpr_Op2_<B, double, M, MatOp_Scale_<Mat> >, M>& a,
  1795.              const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_ScaleAddS_<Mat> >, M>& b )
  1796. {
  1797.     typedef MatExpr_Op4_<M, M, double, int, M, MatOp_MatMul_<Mat> > MatExpr_Temp;
  1798.     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp((M)a.e.a1, (M)b.e.a1,
  1799.         a.e.a2*b.e.a2, (M)a.e.a1, a.e.a2*b.e.a3, 0));
  1800. }
  1801. // (A*alpha + beta)*B^t
  1802. template<typename A, typename B, typename M> static inline
  1803. MatExpr_<MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> >, M>
  1804. operator * ( const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_ScaleAddS_<Mat> >, M>& a,
  1805.              const MatExpr_<MatExpr_Op2_<B, double, M, MatOp_T_<Mat> >, M>& b )
  1806. {
  1807.     typedef MatExpr_Op4_<M, M, double, int, M, MatOp_MatMul_<Mat> > MatExpr_Temp;
  1808.     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp((M)a.e.a1, (M)b.e.a1,
  1809.         a.e.a2*b.e.a2, (M)b.e.a1, a.e.a3*b.e.a2, GEMM_2_T));
  1810. }
  1811. // A^t*(B*alpha + beta)
  1812. template<typename A, typename B, typename M> static inline
  1813. MatExpr_<MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> >, M>
  1814. operator * ( const MatExpr_<MatExpr_Op2_<B, double, M, MatOp_T_<Mat> >, M>& a,
  1815.              const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_ScaleAddS_<Mat> >, M>& b )
  1816. {
  1817.     typedef MatExpr_Op4_<M, M, double, int, M, MatOp_MatMul_<Mat> > MatExpr_Temp;
  1818.     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp((M)a.e.a1, (M)b.e.a1,
  1819.         a.e.a2*b.e.a2, (M)a.e.a1, a.e.a2*b.e.a3, GEMM_1_T));
  1820. }
  1821. // (A*B + C)*alpha
  1822. template<typename A, typename B, typename C, typename M> static inline
  1823. MatExpr_<MatExpr_Op6_<A, B, double, C, double, int, M, MatOp_MatMulAdd_<Mat> >, M>
  1824. operator * ( const MatExpr_<MatExpr_Op6_<A, B, double, C,
  1825.              double, int, M, MatOp_MatMulAdd_<Mat> >, M>& a, double alpha )
  1826. {
  1827.     typedef MatExpr_Op6_<A, B, double, C, double, int, M, MatOp_MatMulAdd_<Mat> > MatExpr_Temp;
  1828.     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(a.e.a1, a.e.a2,
  1829.         a.e.a3*alpha, a.e.a4, a.e.a5*alpha, a.e.a6));
  1830. }
  1831. // alpha*(A*B + C)
  1832. template<typename A, typename B, typename C, typename M> static inline
  1833. MatExpr_<MatExpr_Op6_<A, B, double, C, double, int, M, MatOp_MatMulAdd_<Mat> >, M>
  1834. operator * ( double alpha, const MatExpr_<MatExpr_Op6_<A, B, double, C,
  1835.              double, int, M, MatOp_MatMulAdd_<Mat> >, M>& a )
  1836. { return a*alpha; }
  1837. // -(A*B + C)
  1838. template<typename A, typename B, typename C, typename M> static inline
  1839. MatExpr_<MatExpr_Op6_<A, B, double, C, double, int, M, MatOp_MatMulAdd_<Mat> >, M>
  1840. operator - ( const MatExpr_<MatExpr_Op6_<A, B, double, C,
  1841.              double, int, M, MatOp_MatMulAdd_<Mat> >, M>& a )
  1842. { return a*(-1); }
  1843. // (A*B) + C
  1844. template<typename A, typename B, typename M> static inline
  1845. MatExpr_<MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> >, M>
  1846. operator + ( const MatExpr_<MatExpr_Op4_<A, B, double, int, M, MatOp_MatMul_<Mat> >, M>& a,
  1847.              const M& b )
  1848. {
  1849.     typedef MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> > MatExpr_Temp;
  1850.     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(
  1851.         (M)a.e.a1, (M)a.e.a2, a.e.a3, b, 1, a.e.a4));
  1852. }
  1853. // C + (A*B)
  1854. template<typename A, typename B, typename M> static inline
  1855. MatExpr_<MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> >, M>
  1856. operator + ( const M& b,
  1857.              const MatExpr_<MatExpr_Op4_<A, B, double, int, M, MatOp_MatMul_<Mat> >, M>& a )
  1858. { return a + b; }
  1859. // (A*B) - C
  1860. template<typename A, typename B, typename M> static inline
  1861. MatExpr_<MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> >, M>
  1862. operator - ( const MatExpr_<MatExpr_Op4_<A, B, double, int, M, MatOp_MatMul_<Mat> >, M>& a,
  1863.              const M& b )
  1864. {
  1865.     typedef MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> > MatExpr_Temp;
  1866.     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(
  1867.         (M)a.e.a1, (M)a.e.a2, a.e.a3, b, -1, a.e.a4));
  1868. }
  1869. // C - (A*B)
  1870. template<typename A, typename B, typename M> static inline
  1871. MatExpr_<MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> >, M>
  1872. operator - ( const M& b,
  1873.              const MatExpr_<MatExpr_Op4_<A, B, double, int, M, MatOp_MatMul_<Mat> >, M>& a )
  1874. {
  1875.     typedef MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> > MatExpr_Temp;
  1876.     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(
  1877.         (M)a.e.a1, (M)a.e.a2, -a.e.a3, b, 1, a.e.a4));
  1878. }
  1879. // (A*B) + C
  1880. template<typename A, typename B, typename C, typename M> static inline
  1881. MatExpr_<MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> >, M>
  1882. operator + ( const MatExpr_<MatExpr_Op4_<A, B, double, int, M, MatOp_MatMul_<Mat> >, M>& a,
  1883.              const MatExpr_<C, M>& b )
  1884. {
  1885.     typedef MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> > MatExpr_Temp;
  1886.     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(
  1887.         (M)a.e.a1, (M)a.e.a2, a.e.a3, (M)b, 1, a.e.a4));
  1888. }
  1889. // C + (A*B)
  1890. template<typename A, typename B, typename C, typename M> static inline
  1891. MatExpr_<MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> >, M>
  1892. operator + ( const MatExpr_<C, M>& b,
  1893.              const MatExpr_<MatExpr_Op4_<A, B, double, int, M, MatOp_MatMul_<Mat> >, M>& a )
  1894. { return a + b; }
  1895. // (A*B) - C
  1896. template<typename A, typename B, typename C, typename M> static inline
  1897. MatExpr_<MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> >, M>
  1898. operator - ( const MatExpr_<MatExpr_Op4_<A, B, double, int, M, MatOp_MatMul_<Mat> >, M>& a,
  1899.              const MatExpr_<C, M>& b )
  1900. {
  1901.     typedef MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> > MatExpr_Temp;
  1902.     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(
  1903.         (M)a.e.a1, (M)a.e.a2, a.e.a3, (M)b, -1, a.e.a4));
  1904. }
  1905. // C - (A*B)
  1906. template<typename A, typename B, typename C, typename M> static inline
  1907. MatExpr_<MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> >, M>
  1908. operator - ( const MatExpr_<C, M>& b,
  1909.              const MatExpr_<MatExpr_Op4_<A, B, double, int, M, MatOp_MatMul_<Mat> >, M>& a )
  1910. {
  1911.     typedef MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> > MatExpr_Temp;
  1912.     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(
  1913.         (M)a.e.a1, (M)a.e.a2, -a.e.a3, (M)b, 1, a.e.a4));
  1914. }
  1915. // (A*B) + C*alpha
  1916. template<typename A, typename B, typename C, typename M> static inline
  1917. MatExpr_<MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> >, M>
  1918. operator + ( const MatExpr_<MatExpr_Op4_<A, B, double, int, M, MatOp_MatMul_<Mat> >, M>& a,
  1919.              const MatExpr_<MatExpr_Op2_<C, double, M, MatOp_Scale_<Mat> >, M>& b )
  1920. {
  1921.     typedef MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> > MatExpr_Temp;
  1922.     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(
  1923.         (M)a.e.a1, (M)a.e.a2, a.e.a3, (M)b.e.a1, b.e.a2, a.e.a4));
  1924. }
  1925. // C*alpha + (A*B)
  1926. template<typename A, typename B, typename C, typename M> static inline
  1927. MatExpr_<MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> >, M>
  1928. operator + ( const MatExpr_<MatExpr_Op2_<C, double, M, MatOp_Scale_<Mat> >, M>& b,
  1929.              const MatExpr_<MatExpr_Op4_<A, B, double, int, M, MatOp_MatMul_<Mat> >, M>& a )
  1930. { return a + b; }
  1931. // (A*B) - (C*alpha)
  1932. template<typename A, typename B, typename C, typename M> static inline
  1933. MatExpr_<MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> >, M>
  1934. operator - ( const MatExpr_<MatExpr_Op4_<A, B, double, int, M, MatOp_MatMul_<Mat> >, M>& a,
  1935.              const MatExpr_<MatExpr_Op2_<C, double, M, MatOp_Scale_<Mat> >, M>& b )
  1936. {
  1937.     typedef MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> > MatExpr_Temp;
  1938.     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(
  1939.         (M)a.e.a1, (M)a.e.a2, a.e.a3, (M)b.e.a1, -b.e.a2, a.e.a4));
  1940. }
  1941. // (C*alpha) - (A*B)
  1942. template<typename A, typename B, typename C, typename M> static inline
  1943. MatExpr_<MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> >, M>
  1944. operator - ( const MatExpr_<MatExpr_Op2_<C, double, M, MatOp_Scale_<Mat> >, M>& b,
  1945.              const MatExpr_<MatExpr_Op4_<A, B, double, int, M, MatOp_MatMul_<Mat> >, M>& a )
  1946. {
  1947.     typedef MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> > MatExpr_Temp;
  1948.     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(
  1949.         (M)a.e.a1, (M)a.e.a2, -a.e.a3, (M)b.e.a1, b.e.a2, a.e.a4));
  1950. }
  1951. // (A*B) + C^t
  1952. template<typename A, typename B, typename C, typename M> static inline
  1953. MatExpr_<MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> >, M>
  1954. operator + ( const MatExpr_<MatExpr_Op4_<A, B, double, int, M, MatOp_MatMul_<Mat> >, M>& a,
  1955.              const MatExpr_<MatExpr_Op2_<C, double, M, MatOp_T_<Mat> >, M>& b )
  1956. {
  1957.     typedef MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> > MatExpr_Temp;
  1958.     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(
  1959.         (M)a.e.a1, (M)a.e.a2, a.e.a3, (M)b.e.a1, b.e.a2, a.e.a4 + GEMM_3_T));
  1960. }
  1961. // C^t + (A*B)
  1962. template<typename A, typename B, typename C, typename M> static inline
  1963. MatExpr_<MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> >, M>
  1964. operator + ( const MatExpr_<MatExpr_Op2_<C, double, M, MatOp_T_<Mat> >, M>& b,
  1965.              const MatExpr_<MatExpr_Op4_<A, B, double, int, M, MatOp_MatMul_<Mat> >, M>& a )
  1966. { return a + b; }
  1967. // (A*B) - C^t
  1968. template<typename A, typename B, typename C, typename M> static inline
  1969. MatExpr_<MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> >, M>
  1970. operator - ( const MatExpr_<MatExpr_Op4_<A, B, double, int, M, MatOp_MatMul_<Mat> >, M>& a,
  1971.              const MatExpr_<MatExpr_Op2_<C, double, M, MatOp_T_<Mat> >, M>& b )
  1972. {
  1973.     typedef MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> > MatExpr_Temp;
  1974.     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(
  1975.         (M)a.e.a1, (M)a.e.a2, a.e.a3, (M)b.e.a1, -b.e.a2, a.e.a4+GEMM_3_T));
  1976. }
  1977. // C^t - (A*B)
  1978. template<typename A, typename B, typename C, typename M> static inline
  1979. MatExpr_<MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> >, M>
  1980. operator - ( const MatExpr_<MatExpr_Op2_<C, double, M, MatOp_T_<Mat> >, M>& b,
  1981.              const MatExpr_<MatExpr_Op4_<A, B, double, int, M, MatOp_MatMul_<Mat> >, M>& a )
  1982. {
  1983.     typedef MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> > MatExpr_Temp;
  1984.     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(
  1985.         (M)a.e.a1, (M)a.e.a2, -a.e.a3, (M)b.e.a1, b.e.a2, a.e.a4+GEMM_3_T));
  1986. }
  1987. ////////////////////////////// Augmenting algebraic operations //////////////////////////////////
  1988. static inline Mat& operator += (const Mat& a, const Mat& b)
  1989. {
  1990.     add(a, b, (Mat&)a);
  1991.     return (Mat&)a;
  1992. }
  1993. static inline Mat& operator -= (const Mat& a, const Mat& b)
  1994. {
  1995.     subtract(a, b, (Mat&)a);
  1996.     return (Mat&)a;
  1997. }
  1998. static inline Mat& operator *= (const Mat& a, const Mat& b)
  1999. {
  2000.     gemm(a, b, 1, Mat(), 0, (Mat&)a, 0);
  2001.     return (Mat&)a;