Cinder

  • Main Page
  • Related Pages
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

include/OpenCV/cxmat.hpp

Go to the documentation of this file.
00001 /*M///////////////////////////////////////////////////////////////////////////////////////
00002 //
00003 //  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
00004 //
00005 //  By downloading, copying, installing or using the software you agree to this license.
00006 //  If you do not agree to this license, do not download, install,
00007 //  copy or use the software.
00008 //
00009 //
00010 //                           License Agreement
00011 //                For Open Source Computer Vision Library
00012 //
00013 // Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
00014 // Copyright (C) 2009, Willow Garage Inc., all rights reserved.
00015 // Third party copyrights are property of their respective owners.
00016 //
00017 // Redistribution and use in source and binary forms, with or without modification,
00018 // are permitted provided that the following conditions are met:
00019 //
00020 //   * Redistribution's of source code must retain the above copyright notice,
00021 //     this list of conditions and the following disclaimer.
00022 //
00023 //   * Redistribution's in binary form must reproduce the above copyright notice,
00024 //     this list of conditions and the following disclaimer in the documentation
00025 //     and/or other materials provided with the distribution.
00026 //
00027 //   * The name of the copyright holders may not be used to endorse or promote products
00028 //     derived from this software without specific prior written permission.
00029 //
00030 // This software is provided by the copyright holders and contributors "as is" and
00031 // any express or implied warranties, including, but not limited to, the implied
00032 // warranties of merchantability and fitness for a particular purpose are disclaimed.
00033 // In no event shall the Intel Corporation or contributors be liable for any direct,
00034 // indirect, incidental, special, exemplary, or consequential damages
00035 // (including, but not limited to, procurement of substitute goods or services;
00036 // loss of use, data, or profits; or business interruption) however caused
00037 // and on any theory of liability, whether in contract, strict liability,
00038 // or tort (including negligence or otherwise) arising in any way out of
00039 // the use of this software, even if advised of the possibility of such damage.
00040 //
00041 //M*/
00042 
00043 #ifndef __OPENCV_MATRIX_OPERATIONS_H__
00044 #define __OPENCV_MATRIX_OPERATIONS_H__
00045 
00046 #ifndef SKIP_INCLUDES
00047 #include <limits.h>
00048 #endif // SKIP_INCLUDES
00049 
00050 #ifdef __cplusplus
00051 
00052 namespace cv
00053 {
00054 
00056 
00057 inline Mat::Mat()
00058     : flags(0), rows(0), cols(0), step(0), data(0), refcount(0), datastart(0), dataend(0) {}
00059 
00060 inline Mat::Mat(int _rows, int _cols, int _type)
00061     : flags(0), rows(0), cols(0), step(0), data(0), refcount(0), datastart(0), dataend(0)
00062 {
00063     if( _rows > 0 && _cols > 0 )
00064         create( _rows, _cols, _type );
00065 }
00066 
00067 inline Mat::Mat(int _rows, int _cols, int _type, const Scalar& _s)
00068     : flags(0), rows(0), cols(0), step(0), data(0), refcount(0),
00069     datastart(0), dataend(0)
00070 {
00071     if(_rows > 0 && _cols > 0)
00072     {
00073         create(_rows, _cols, _type);
00074         *this = _s;
00075     }
00076 }
00077 
00078 inline Mat::Mat(Size _size, int _type)
00079     : flags(0), rows(0), cols(0), step(0), data(0), refcount(0),
00080     datastart(0), dataend(0)
00081 {
00082     if( _size.height > 0 && _size.width > 0 )
00083         create( _size.height, _size.width, _type );
00084 }
00085     
00086 inline Mat::Mat(Size _size, int _type, const Scalar& _s)
00087 : flags(0), rows(0), cols(0), step(0), data(0), refcount(0),
00088 datastart(0), dataend(0)
00089 {
00090     if( _size.height > 0 && _size.width > 0 )
00091     {
00092         create( _size.height, _size.width, _type );
00093         *this = _s;
00094     }
00095 }    
00096 
00097 inline Mat::Mat(const Mat& m)
00098     : flags(m.flags), rows(m.rows), cols(m.cols), step(m.step), data(m.data),
00099     refcount(m.refcount), datastart(m.datastart), dataend(m.dataend)
00100 {
00101     if( refcount )
00102         CV_XADD(refcount, 1);
00103 }
00104 
00105 inline Mat::Mat(int _rows, int _cols, int _type, void* _data, size_t _step)
00106     : flags(MAGIC_VAL + (_type & TYPE_MASK)), rows(_rows), cols(_cols),
00107     step(_step), data((uchar*)_data), refcount(0),
00108     datastart((uchar*)_data), dataend((uchar*)_data)
00109 {
00110     size_t minstep = cols*elemSize();
00111     if( step == AUTO_STEP )
00112     {
00113         step = minstep;
00114         flags |= CONTINUOUS_FLAG;
00115     }
00116     else
00117     {
00118         if( rows == 1 ) step = minstep;
00119         CV_DbgAssert( step >= minstep );
00120         flags |= step == minstep ? CONTINUOUS_FLAG : 0;
00121     }
00122     dataend += step*(rows-1) + minstep;
00123 }
00124 
00125 inline Mat::Mat(Size _size, int _type, void* _data, size_t _step)
00126     : flags(MAGIC_VAL + (_type & TYPE_MASK)), rows(_size.height), cols(_size.width),
00127     step(_step), data((uchar*)_data), refcount(0),
00128     datastart((uchar*)_data), dataend((uchar*)_data)
00129 {
00130     size_t minstep = cols*elemSize();
00131     if( step == AUTO_STEP )
00132     {
00133         step = minstep;
00134         flags |= CONTINUOUS_FLAG;
00135     }
00136     else
00137     {
00138         if( rows == 1 ) step = minstep;
00139         CV_DbgAssert( step >= minstep );
00140         flags |= step == minstep ? CONTINUOUS_FLAG : 0;
00141     }
00142     dataend += step*(rows-1) + minstep;
00143 }
00144 
00145 inline Mat::Mat(const Mat& m, const Range& rowRange, const Range& colRange)
00146 {
00147     flags = m.flags;
00148     step = m.step; refcount = m.refcount;
00149     data = m.data; datastart = m.datastart; dataend = m.dataend;
00150 
00151     if( rowRange == Range::all() )
00152         rows = m.rows;
00153     else
00154     {
00155         CV_Assert( 0 <= rowRange.start && rowRange.start <= rowRange.end && rowRange.end <= m.rows );
00156         rows = rowRange.size();
00157         data += step*rowRange.start;
00158     }
00159 
00160     if( colRange == Range::all() )
00161         cols = m.cols;
00162     else
00163     {
00164         CV_Assert( 0 <= colRange.start && colRange.start <= colRange.end && colRange.end <= m.cols );
00165         cols = colRange.size();
00166         data += colRange.start*elemSize();
00167         flags &= cols < m.cols ? ~CONTINUOUS_FLAG : -1;
00168     }
00169 
00170     if( rows == 1 )
00171         flags |= CONTINUOUS_FLAG;
00172 
00173     if( refcount )
00174         CV_XADD(refcount, 1);
00175     if( rows <= 0 || cols <= 0 )
00176         rows = cols = 0;
00177 }
00178 
00179 inline Mat::Mat(const Mat& m, const Rect& roi)
00180     : flags(m.flags), rows(roi.height), cols(roi.width),
00181     step(m.step), data(m.data + roi.y*step), refcount(m.refcount),
00182     datastart(m.datastart), dataend(m.dataend)
00183 {
00184     flags &= roi.width < m.cols ? ~CONTINUOUS_FLAG : -1;
00185     data += roi.x*elemSize();
00186     CV_Assert( 0 <= roi.x && 0 <= roi.width && roi.x + roi.width <= m.cols &&
00187         0 <= roi.y && 0 <= roi.height && roi.y + roi.height <= m.rows );
00188     if( refcount )
00189         CV_XADD(refcount, 1);
00190     if( rows <= 0 || cols <= 0 )
00191         rows = cols = 0;
00192 }
00193 
00194 inline Mat::Mat(const CvMat* m, bool copyData)
00195     : flags(MAGIC_VAL + (m->type & (CV_MAT_TYPE_MASK|CV_MAT_CONT_FLAG))),
00196     rows(m->rows), cols(m->cols), step(m->step), data(m->data.ptr), refcount(0),
00197     datastart(m->data.ptr), dataend(m->data.ptr)
00198 {
00199     if( step == 0 )
00200         step = cols*elemSize();
00201     size_t minstep = cols*elemSize();
00202     dataend += step*(rows-1) + minstep;
00203     if( copyData )
00204     {
00205         data = datastart = dataend = 0;
00206         Mat(m->rows, m->cols, m->type, m->data.ptr, m->step).copyTo(*this);
00207     }
00208 }
00209 
00210 static inline Mat cvarrToMat(const CvArr* arr, bool copyData=false,
00211                              bool allowND=true, int coiMode=0)
00212 {
00213     if( CV_IS_MAT(arr) )
00214         return Mat((const CvMat*)arr, copyData );
00215     else if( CV_IS_IMAGE(arr) )
00216     {
00217         const IplImage* iplimg = (const IplImage*)arr;
00218         if( coiMode == 0 && iplimg->roi && iplimg->roi->coi > 0 )
00219             CV_Error(CV_BadCOI, "COI is not supported by the function");
00220         return Mat(iplimg, copyData);
00221     }
00222     else if( CV_IS_SEQ(arr) )
00223     {
00224         CvSeq* seq = (CvSeq*)arr;
00225         CV_Assert(seq->total > 0 && CV_ELEM_SIZE(seq->flags) == seq->elem_size);
00226         if(!copyData && seq->first->next == seq->first)
00227             return Mat(seq->total, 1, CV_MAT_TYPE(seq->flags), seq->first->data);
00228         Mat buf(seq->total, 1, CV_MAT_TYPE(seq->flags));
00229         cvCvtSeqToArray(seq, buf.data, CV_WHOLE_SEQ);
00230         return buf;
00231     }
00232     else
00233     {
00234         CvMat hdr, *cvmat = cvGetMat( arr, &hdr, 0, allowND ? 1 : 0 );
00235         if( cvmat )
00236             return Mat(cvmat, copyData);
00237     }
00238     return Mat();
00239 }
00240 
00241 template<typename _Tp> inline Mat::Mat(const vector<_Tp>& vec, bool copyData)
00242     : flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG),
00243     rows(0), cols(0), step(0), data(0), refcount(0),
00244     datastart(0), dataend(0)
00245 {
00246     if(vec.empty())
00247         return;
00248     if( !copyData )
00249     {
00250         rows = (int)vec.size();
00251         cols = 1;
00252         step = sizeof(_Tp);
00253         data = datastart = (uchar*)&vec[0];
00254         dataend = datastart + rows*step;
00255     }
00256     else
00257         Mat((int)vec.size(), 1, DataType<_Tp>::type, (uchar*)&vec[0]).copyTo(*this);
00258 }
00259     
00260 inline Mat::~Mat()
00261 {
00262     release();
00263 }
00264 
00265 inline Mat& Mat::operator = (const Mat& m)
00266 {
00267     if( this != &m )
00268     {
00269         if( m.refcount )
00270             CV_XADD(m.refcount, 1);
00271         release();
00272         flags = m.flags;
00273         rows = m.rows; cols = m.cols;
00274         step = m.step; data = m.data;
00275         datastart = m.datastart; dataend = m.dataend;
00276         refcount = m.refcount;
00277     }
00278     return *this;
00279 }
00280 
00281 inline Mat Mat::row(int y) const { return Mat(*this, Range(y, y+1), Range::all()); }
00282 inline Mat Mat::col(int x) const { return Mat(*this, Range::all(), Range(x, x+1)); }
00283 inline Mat Mat::rowRange(int startrow, int endrow) const
00284     { return Mat(*this, Range(startrow, endrow), Range::all()); }
00285 inline Mat Mat::rowRange(const Range& r) const
00286     { return Mat(*this, r, Range::all()); }
00287 inline Mat Mat::colRange(int startcol, int endcol) const
00288     { return Mat(*this, Range::all(), Range(startcol, endcol)); }
00289 inline Mat Mat::colRange(const Range& r) const
00290     { return Mat(*this, Range::all(), r); }
00291 
00292 inline Mat Mat::diag(int d) const
00293 {
00294     Mat m = *this;
00295     size_t esz = elemSize();
00296     int len;
00297 
00298     if( d >= 0 )
00299     {
00300         len = std::min(cols - d, rows);
00301         m.data += esz*d;
00302     }
00303     else
00304     {
00305         len = std::min(rows + d, cols);
00306         m.data -= step*d;
00307     }
00308     CV_DbgAssert( len > 0 );
00309     m.rows = len;
00310     m.cols = 1;
00311     m.step += esz;
00312     if( m.rows > 1 )
00313         m.flags &= ~CONTINUOUS_FLAG;
00314     else
00315         m.flags |= CONTINUOUS_FLAG;
00316     return m;
00317 }
00318 
00319 inline Mat Mat::diag(const Mat& d)
00320 {
00321     Mat m(d.rows, d.rows, d.type(), Scalar(0)), md = m.diag();
00322     d.copyTo(md);
00323     return m;
00324 }
00325 
00326 inline Mat Mat::clone() const
00327 {
00328     Mat m;
00329     copyTo(m);
00330     return m;
00331 }
00332 
00333 inline void Mat::assignTo( Mat& m, int type ) const
00334 {
00335     if( type < 0 )
00336         m = *this;
00337     else
00338         convertTo(m, type);
00339 }
00340 
00341 inline void Mat::create(int _rows, int _cols, int _type)
00342 {
00343     _type &= TYPE_MASK;
00344     if( rows == _rows && cols == _cols && type() == _type && data )
00345         return;
00346     if( data )
00347         release();
00348     CV_DbgAssert( _rows >= 0 && _cols >= 0 );
00349     if( _rows > 0 && _cols > 0 )
00350     {
00351         flags = MAGIC_VAL + CONTINUOUS_FLAG + _type;
00352         rows = _rows;
00353         cols = _cols;
00354         step = elemSize()*cols;
00355         int64 _nettosize = (int64)step*rows;
00356         size_t nettosize = (size_t)_nettosize;
00357         if( _nettosize != (int64)nettosize )
00358             CV_Error(CV_StsNoMem, "Too big buffer is allocated");
00359         size_t datasize = alignSize(nettosize, (int)sizeof(*refcount));
00360         datastart = data = (uchar*)fastMalloc(datasize + sizeof(*refcount));
00361         dataend = data + nettosize;
00362         refcount = (int*)(data + datasize);
00363         *refcount = 1;
00364     }
00365 }
00366 
00367 inline void Mat::create(Size _size, int _type)
00368 {
00369     create(_size.height, _size.width, _type);
00370 }
00371 
00372 inline void Mat::addref()
00373 { if( refcount ) CV_XADD(refcount, 1); }
00374 
00375 inline void Mat::release()
00376 {
00377     if( refcount && CV_XADD(refcount, -1) == 1 )
00378         fastFree(datastart);
00379     data = datastart = dataend = 0;
00380     step = rows = cols = 0;
00381     refcount = 0;
00382 }
00383 
00384 inline void Mat::locateROI( Size& wholeSize, Point& ofs ) const
00385 {
00386     size_t esz = elemSize(), minstep;
00387     ptrdiff_t delta1 = data - datastart, delta2 = dataend - datastart;
00388     CV_DbgAssert( step > 0 );
00389     if( delta1 == 0 )
00390         ofs.x = ofs.y = 0;
00391     else
00392     {
00393         ofs.y = (int)(delta1/step);
00394         ofs.x = (int)((delta1 - step*ofs.y)/esz);
00395         CV_DbgAssert( data == datastart + ofs.y*step + ofs.x*esz );
00396     }
00397     minstep = (ofs.x + cols)*esz;
00398     wholeSize.height = (int)((delta2 - minstep)/step + 1);
00399     wholeSize.height = std::max(wholeSize.height, ofs.y + rows);
00400     wholeSize.width = (int)((delta2 - step*(wholeSize.height-1))/esz);
00401     wholeSize.width = std::max(wholeSize.width, ofs.x + cols);
00402 }
00403 
00404 inline Mat& Mat::adjustROI( int dtop, int dbottom, int dleft, int dright )
00405 {
00406     Size wholeSize; Point ofs;
00407     size_t esz = elemSize();
00408     locateROI( wholeSize, ofs );
00409     int row1 = std::max(ofs.y - dtop, 0), row2 = std::min(ofs.y + rows + dbottom, wholeSize.height);
00410     int col1 = std::max(ofs.x - dleft, 0), col2 = std::min(ofs.x + cols + dright, wholeSize.width);
00411     data += (row1 - ofs.y)*step + (col1 - ofs.x)*esz;
00412     rows = row2 - row1; cols = col2 - col1;
00413     if( esz*cols == step || rows == 1 )
00414         flags |= CONTINUOUS_FLAG;
00415     else
00416         flags &= ~CONTINUOUS_FLAG;
00417     return *this;
00418 }
00419 
00420 inline Mat Mat::operator()( Range rowRange, Range colRange ) const
00421 {
00422     return Mat(*this, rowRange, colRange);
00423 }
00424 
00425 inline Mat Mat::operator()( const Rect& roi ) const
00426 { return Mat(*this, roi); }
00427 
00428 inline Mat::operator CvMat() const
00429 {
00430     CvMat m = cvMat(rows, cols, type(), data);
00431     m.step = (int)step;
00432     m.type = (m.type & ~CONTINUOUS_FLAG) | (flags & CONTINUOUS_FLAG);
00433     return m;
00434 }
00435 
00436 inline Mat::operator IplImage() const
00437 {
00438     IplImage img;
00439     cvInitImageHeader(&img, size(), cvIplDepth(flags), channels());
00440     cvSetData(&img, data, (int)step);
00441     return img;
00442 }
00443 
00444 inline bool Mat::isContinuous() const { return (flags & CONTINUOUS_FLAG) != 0; }
00445 inline size_t Mat::elemSize() const { return CV_ELEM_SIZE(flags); }
00446 inline size_t Mat::elemSize1() const { return CV_ELEM_SIZE1(flags); }
00447 inline int Mat::type() const { return CV_MAT_TYPE(flags); }
00448 inline int Mat::depth() const { return CV_MAT_DEPTH(flags); }
00449 inline int Mat::channels() const { return CV_MAT_CN(flags); }
00450 inline size_t Mat::step1() const { return step/elemSize1(); }
00451 inline Size Mat::size() const { return Size(cols, rows); }
00452 inline bool Mat::empty() const { return data == 0; }
00453 
00454 inline uchar* Mat::ptr(int y)
00455 {
00456     CV_DbgAssert( (unsigned)y < (unsigned)rows );
00457     return data + step*y;
00458 }
00459 
00460 inline const uchar* Mat::ptr(int y) const
00461 {
00462     CV_DbgAssert( (unsigned)y < (unsigned)rows );
00463     return data + step*y;
00464 }
00465 
00466 template<typename _Tp> inline _Tp* Mat::ptr(int y)
00467 {
00468     CV_DbgAssert( (unsigned)y < (unsigned)rows );
00469     return (_Tp*)(data + step*y);
00470 }
00471 
00472 template<typename _Tp> inline const _Tp* Mat::ptr(int y) const
00473 {
00474     CV_DbgAssert( (unsigned)y < (unsigned)rows );
00475     return (const _Tp*)(data + step*y);
00476 }
00477 
00478 template<typename _Tp> inline _Tp& Mat::at(int y, int x)
00479 {
00480     CV_DbgAssert( (unsigned)y < (unsigned)rows &&
00481         (unsigned)(x*DataType<_Tp>::channels) < (unsigned)(cols*channels()) &&
00482         CV_ELEM_SIZE1(DataType<_Tp>::depth) == elemSize1());
00483     return ((_Tp*)(data + step*y))[x];
00484 }
00485 
00486 template<typename _Tp> inline const _Tp& Mat::at(int y, int x) const
00487 {
00488     CV_DbgAssert( (unsigned)y < (unsigned)rows &&
00489         (unsigned)(x*DataType<_Tp>::channels) < (unsigned)(cols*channels()) &&
00490         CV_ELEM_SIZE1(DataType<_Tp>::depth) == elemSize1());
00491     return ((const _Tp*)(data + step*y))[x];
00492 }
00493 
00494 template<typename _Tp> inline _Tp& Mat::at(Point pt)
00495 {
00496     CV_DbgAssert( (unsigned)pt.y < (unsigned)rows &&
00497         (unsigned)(pt.x*DataType<_Tp>::channels) < (unsigned)(cols*channels()) &&
00498         CV_ELEM_SIZE1(DataType<_Tp>::depth) == elemSize1());
00499     return ((_Tp*)(data + step*pt.y))[pt.x];
00500 }
00501 
00502 template<typename _Tp> inline const _Tp& Mat::at(Point pt) const
00503 {
00504     CV_DbgAssert( (unsigned)pt.y < (unsigned)rows &&
00505         (unsigned)(pt.x*DataType<_Tp>::channels) < (unsigned)(cols*channels()) &&
00506         CV_ELEM_SIZE1(DataType<_Tp>::depth) == elemSize1());
00507     return ((const _Tp*)(data + step*pt.y))[pt.x];
00508 }
00509     
00510 template<typename _Tp> inline MatConstIterator_<_Tp> Mat::begin() const
00511 {
00512     CV_DbgAssert( elemSize() == sizeof(_Tp) );
00513     return MatConstIterator_<_Tp>((const Mat_<_Tp>*)this);
00514 }
00515 
00516 template<typename _Tp> inline MatConstIterator_<_Tp> Mat::end() const
00517 {
00518     CV_DbgAssert( elemSize() == sizeof(_Tp) );
00519     MatConstIterator_<_Tp> it((const Mat_<_Tp>*)this);
00520     it.ptr = it.sliceEnd = (_Tp*)(data + step*(rows-1)) + cols;
00521     return it;
00522 }
00523 
00524 template<typename _Tp> inline MatIterator_<_Tp> Mat::begin()
00525 {
00526     CV_DbgAssert( elemSize() == sizeof(_Tp) );
00527     return MatIterator_<_Tp>((Mat_<_Tp>*)this);
00528 }
00529 
00530 template<typename _Tp> inline MatIterator_<_Tp> Mat::end()
00531 {
00532     CV_DbgAssert( elemSize() == sizeof(_Tp) );
00533     MatIterator_<_Tp> it((Mat_<_Tp>*)this);
00534     it.ptr = it.sliceEnd = (_Tp*)(data + step*(rows-1)) + cols;
00535     return it;
00536 }
00537     
00538     
00539 static inline void swap( Mat& a, Mat& b )
00540 {
00541     std::swap( a.flags, b.flags );
00542     std::swap( a.rows, b.rows ); std::swap( a.cols, b.cols );
00543     std::swap( a.step, b.step ); std::swap( a.data, b.data );
00544     std::swap( a.datastart, b.datastart );
00545     std::swap( a.dataend, b.dataend );
00546     std::swap( a.refcount, b.refcount );
00547 }
00548 
00549 inline SVD::SVD() {}
00550 inline SVD::SVD( const Mat& m, int flags ) { operator ()(m, flags); }
00551 inline void SVD::solveZ( const Mat& m, Mat& dst )
00552 {
00553     SVD svd(m);
00554     svd.vt.row(svd.vt.rows-1).reshape(1,svd.vt.cols).copyTo(dst);
00555 }
00556 
00558 
00559 template<typename _Tp> inline Mat_<_Tp>::Mat_() :
00560     Mat() { flags = (flags & ~CV_MAT_TYPE_MASK) | DataType<_Tp>::type; }
00561     
00562 template<typename _Tp> inline Mat_<_Tp>::Mat_(int _rows, int _cols) :
00563     Mat(_rows, _cols, DataType<_Tp>::type) {}
00564 
00565 template<typename _Tp> inline Mat_<_Tp>::Mat_(int _rows, int _cols, const _Tp& value) :
00566     Mat(_rows, _cols, DataType<_Tp>::type) { *this = value; }
00567 
00568 template<typename _Tp> inline Mat_<_Tp>::Mat_(Size _size) :
00569     Mat(_size.height, _size.width, DataType<_Tp>::type) {}
00570     
00571 template<typename _Tp> inline Mat_<_Tp>::Mat_(Size _size, const _Tp& value) :
00572     Mat(_size.height, _size.width, DataType<_Tp>::type) { *this = value; }
00573     
00574 template<typename _Tp> inline Mat_<_Tp>::Mat_(const Mat& m) : Mat()
00575 { flags = (flags & ~CV_MAT_TYPE_MASK) | DataType<_Tp>::type; *this = m; }
00576 
00577 template<typename _Tp> inline Mat_<_Tp>::Mat_(const Mat_& m) : Mat(m) {}
00578 
00579 template<typename _Tp> inline Mat_<_Tp>::Mat_(int _rows, int _cols, _Tp* _data, size_t _step)
00580     : Mat(_rows, _cols, DataType<_Tp>::type, _data, _step) {}
00581 
00582 template<typename _Tp> inline Mat_<_Tp>::Mat_(const Mat_& m, const Range& rowRange, const Range& colRange)
00583     : Mat(m, rowRange, colRange) {}
00584 
00585 template<typename _Tp> inline Mat_<_Tp>::Mat_(const Mat_& m, const Rect& roi)
00586     : Mat(m, roi) {}
00587 
00588 template<typename _Tp> template<int n> inline Mat_<_Tp>::Mat_(const Vec<_Tp, n>& vec)
00589     : Mat(n, 1, DataType<_Tp>::type)
00590 {
00591     _Tp* d = (_Tp*)data;
00592     for( int i = 0; i < n; i++ )
00593         d[i] = vec[i];
00594 }
00595 
00596 template<typename _Tp> inline Mat_<_Tp>::Mat_(const vector<_Tp>& vec, bool copyData)
00597     : Mat(vec, copyData)
00598 {}
00599 
00600 template<typename _Tp> inline Mat_<_Tp>& Mat_<_Tp>::operator = (const Mat& m)
00601 {
00602     if( DataType<_Tp>::type == m.type() )
00603     {
00604         Mat::operator = (m);
00605         return *this;
00606     }
00607     if( DataType<_Tp>::depth == m.depth() )
00608     {
00609         return (*this = m.reshape(DataType<_Tp>::channels));
00610     }
00611     CV_DbgAssert(DataType<_Tp>::channels == m.channels());
00612     m.convertTo(*this, type());
00613     return *this;
00614 }
00615 
00616 template<typename _Tp> inline Mat_<_Tp>& Mat_<_Tp>::operator = (const Mat_& m)
00617 {
00618     Mat::operator=(m);
00619     return *this;
00620 }
00621 
00622 template<typename _Tp> inline Mat_<_Tp>& Mat_<_Tp>::operator = (const _Tp& s)
00623 {
00624     typedef typename DataType<_Tp>::vec_type VT;
00625     Mat::operator=(Scalar((const VT&)s));
00626     return *this;
00627 }
00628     
00629 
00630 template<typename _Tp> inline void Mat_<_Tp>::create(int _rows, int _cols)
00631 {
00632     Mat::create(_rows, _cols, DataType<_Tp>::type);
00633 }
00634 
00635 template<typename _Tp> inline void Mat_<_Tp>::create(Size _size)
00636 {
00637     Mat::create(_size, DataType<_Tp>::type);
00638 }
00639 
00640 template<typename _Tp> inline Mat_<_Tp> Mat_<_Tp>::cross(const Mat_& m) const
00641 { return Mat_<_Tp>(Mat::cross(m)); }
00642 
00643 template<typename _Tp> template<typename T2> inline Mat_<_Tp>::operator Mat_<T2>() const
00644 { return Mat_<T2>(*this); }
00645 
00646 template<typename _Tp> inline Mat_<_Tp> Mat_<_Tp>::row(int y) const
00647 { return Mat_(*this, Range(y, y+1), Range::all()); }
00648 template<typename _Tp> inline Mat_<_Tp> Mat_<_Tp>::col(int x) const
00649 { return Mat_(*this, Range::all(), Range(x, x+1)); }
00650 template<typename _Tp> inline Mat_<_Tp> Mat_<_Tp>::diag(int d) const
00651 { return Mat_(Mat::diag(d)); }
00652 template<typename _Tp> inline Mat_<_Tp> Mat_<_Tp>::clone() const
00653 { return Mat_(Mat::clone()); }
00654 
00655 template<typename _Tp> inline size_t Mat_<_Tp>::elemSize() const
00656 {
00657     CV_DbgAssert( Mat::elemSize() == sizeof(_Tp) );
00658     return sizeof(_Tp);
00659 }
00660 
00661 template<typename _Tp> inline size_t Mat_<_Tp>::elemSize1() const
00662 {
00663     CV_DbgAssert( Mat::elemSize1() == sizeof(_Tp)/DataType<_Tp>::channels );
00664     return sizeof(_Tp)/DataType<_Tp>::channels;
00665 }
00666 template<typename _Tp> inline int Mat_<_Tp>::type() const
00667 {
00668     CV_DbgAssert( Mat::type() == DataType<_Tp>::type );
00669     return DataType<_Tp>::type;
00670 }
00671 template<typename _Tp> inline int Mat_<_Tp>::depth() const
00672 {
00673     CV_DbgAssert( Mat::depth() == DataType<_Tp>::depth );
00674     return DataType<_Tp>::depth;
00675 }
00676 template<typename _Tp> inline int Mat_<_Tp>::channels() const
00677 {
00678     CV_DbgAssert( Mat::channels() == DataType<_Tp>::channels );
00679     return DataType<_Tp>::channels;
00680 }
00681 template<typename _Tp> inline size_t Mat_<_Tp>::stepT() const { return step/elemSize(); }
00682 template<typename _Tp> inline size_t Mat_<_Tp>::step1() const { return step/elemSize1(); }
00683 
00684 template<typename _Tp> inline Mat_<_Tp> Mat_<_Tp>::reshape(int _rows) const
00685 { return Mat_<_Tp>(Mat::reshape(0,_rows)); }
00686 
00687 template<typename _Tp> inline Mat_<_Tp>& Mat_<_Tp>::adjustROI( int dtop, int dbottom, int dleft, int dright )
00688 { return (Mat_<_Tp>&)(Mat::adjustROI(dtop, dbottom, dleft, dright));  }
00689 
00690 template<typename _Tp> inline Mat_<_Tp> Mat_<_Tp>::operator()( const Range& rowRange, const Range& colRange ) const
00691 { return Mat_<_Tp>(*this, rowRange, colRange); }
00692 
00693 template<typename _Tp> inline Mat_<_Tp> Mat_<_Tp>::operator()( const Rect& roi ) const
00694 { return Mat_<_Tp>(*this, roi); }
00695 
00696 template<typename _Tp> inline _Tp* Mat_<_Tp>::operator [](int y)
00697 { return (_Tp*)ptr(y); }
00698 template<typename _Tp> inline const _Tp* Mat_<_Tp>::operator [](int y) const
00699 { return (const _Tp*)ptr(y); }
00700 
00701 template<typename _Tp> inline _Tp& Mat_<_Tp>::operator ()(int row, int col)
00702 {
00703     CV_DbgAssert( (unsigned)row < (unsigned)rows && (unsigned)col < (unsigned)cols );
00704     return ((_Tp*)(data + step*row))[col];
00705 }
00706 
00707 template<typename _Tp> inline const _Tp& Mat_<_Tp>::operator ()(int row, int col) const
00708 {
00709     CV_DbgAssert( (unsigned)row < (unsigned)rows && (unsigned)col < (unsigned)cols );
00710     return ((const _Tp*)(data + step*row))[col];
00711 }
00712 
00713 template<typename _Tp> inline _Tp& Mat_<_Tp>::operator ()(Point pt)
00714 {
00715     CV_DbgAssert( (unsigned)pt.y < (unsigned)rows && (unsigned)pt.x < (unsigned)cols );
00716     return ((_Tp*)(data + step*pt.y))[pt.x];
00717 }
00718 
00719 template<typename _Tp> inline const _Tp& Mat_<_Tp>::operator ()(Point pt) const
00720 {
00721     CV_DbgAssert( (unsigned)pt.y < (unsigned)rows && (unsigned)pt.x < (unsigned)cols );
00722     return ((const _Tp*)(data + step*pt.y))[pt.x];
00723 }
00724 
00725 template<typename _Tp> inline Mat_<_Tp>::operator vector<_Tp>() const
00726 {
00727     CV_Assert( rows == 1 || cols == 1 );
00728     return isContinuous() ?
00729         vector<_Tp>((_Tp*)data,(_Tp*)data + (rows + cols - 1)) :
00730         (vector<_Tp>)((Mat_<_Tp>)this->t());
00731 }
00732 
00733 template<typename T1, typename T2, typename Op> inline void
00734 process( const Mat_<T1>& m1, Mat_<T2>& m2, Op op )
00735 {
00736     int y, x, rows = m1.rows, cols = m1.cols;
00737     int c1 = m1.channels(), c2 = m2.channels();
00738 
00739     CV_DbgAssert( m1.size() == m2.size() );
00740 
00741     for( y = 0; y < rows; y++ )
00742     {
00743         const T1* src = m1[y];
00744         T2* dst = m2[y];
00745 
00746         for( x = 0; x < cols; x++ )
00747             dst[x] = op(src[x]);
00748     }
00749 }
00750 
00751 template<typename T1, typename T2, typename T3, typename Op> inline void
00752 process( const Mat_<T1>& m1, const Mat_<T2>& m2, Mat_<T3>& m3, Op op )
00753 {
00754     int y, x, rows = m1.rows, cols = m1.cols;
00755 
00756     CV_DbgAssert( m1.size() == m2.size() );
00757 
00758     for( y = 0; y < rows; y++ )
00759     {
00760         const T1* src1 = m1[y];
00761         const T2* src2 = m2[y];
00762         T3* dst = m3[y];
00763 
00764         for( x = 0; x < cols; x++ )
00765             dst[x] = op( src1[x], src2[x] );
00766     }
00767 }
00768 
00769 template<typename M> class CV_EXPORTS MatExpr_Base_
00770 {
00771 public:
00772     MatExpr_Base_() {}
00773     virtual ~MatExpr_Base_() {}
00774     virtual void assignTo(M& m, int type=-1) const = 0;
00775 };
00776 
00777 template<typename E, typename M> class CV_EXPORTS MatExpr_ : public MatExpr_Base_<M>
00778 {
00779 public:
00780     MatExpr_(const E& _e) : e(_e) {}
00781     ~MatExpr_() {}
00782     operator M() const { return (M)e; }
00783     void assignTo(M& m, int type=-1) const { e.assignTo(m, type); }
00784 
00785     M row(int y) const { return ((M)e).row(y); }
00786     M col(int x) const { return ((M)e).col(x); }
00787     M diag(int d=0) const { return ((M)e).diag(d); }
00788 
00789     M operator()( const Range& rowRange, const Range& colRange ) const
00790     { return ((M)e)(rowRange, colRange); }
00791     M operator()( const Rect& roi ) const { return ((M)e)(roi); }
00792 
00793     M cross(const M& m) const { return ((M)e).cross(m); }
00794     double dot(const M& m) const { return ((M)e).dot(m); }
00795 
00796     MatExpr_<MatExpr_Op2_<M, double, M, MatOp_T_<Mat> >, M> t() const
00797     { return ((M)e).t(); }
00798     MatExpr_<MatExpr_Op2_<M, int, M, MatOp_Inv_<Mat> >, M> inv(int method=DECOMP_LU) const
00799     { return ((M)e).inv(method); }
00800 
00801     MatExpr_<MatExpr_Op4_<M, M, double, char, M, MatOp_MulDiv_<Mat> >, M>
00802     mul(const M& m, double scale=1) const
00803     { return ((M)e).mul(m, scale); }
00804     template<typename A> MatExpr_<MatExpr_Op4_<M, M, double, char, M, MatOp_MulDiv_<Mat> >, M >
00805     mul(const MatExpr_<A, M>& m, double scale=1) const
00806     { return ((M)e).mul(m, scale); }
00807 
00808     E e;
00809 };
00810 
00811 
00812 inline Mat::Mat(const MatExpr_Base& expr)
00813  : flags(0), rows(0), cols(0), step(0), data(0), refcount(0), datastart(0), dataend(0)
00814 {
00815     expr.assignTo(*this);
00816 }
00817 
00818 inline Mat& Mat::operator = (const MatExpr_Base& expr)
00819 {
00820     expr.assignTo(*this);
00821     return *this;
00822 }
00823 
00824 template<typename _Tp> inline Mat_<_Tp>::Mat_(const MatExpr_Base& e) : Mat()
00825 {
00826     e.assignTo(*this, DataType<_Tp>::type);
00827 }
00828 
00829 template<typename _Tp> inline Mat_<_Tp>& Mat_<_Tp>::operator = (const MatExpr_Base& e)
00830 {
00831     e.assignTo(*this, DataType<_Tp>::type);
00832     return *this;
00833 }
00834 
00835 template<typename _Tp> inline Mat_<_Tp>::operator MatExpr_<Mat, Mat>() const
00836 { return MatExpr_<Mat, Mat>(*this); }
00837 
00838 inline Mat::operator MatExpr_<Mat, Mat>() const
00839 { return MatExpr_<Mat, Mat>(*this); }
00840 
00841 template<typename M> class CV_EXPORTS MatOp_Sub_
00842 {
00843 public:
00844     MatOp_Sub_() {}
00845 
00846     static void apply(const M& a, const M& b, M& c, int type=-1)
00847     {
00848         if( type == a.type() || type < 0 )
00849         {
00850             subtract( a, b, c );
00851         }
00852         else
00853         {
00854             Mat temp;
00855             apply(a, b, temp);
00856             temp.convertTo(c, type);
00857         }
00858     }
00859 };
00860 
00861 template<typename M> class CV_EXPORTS MatOp_Scale_
00862 {
00863 public:
00864     MatOp_Scale_() {}
00865 
00866     static void apply(const M& a, double alpha, M& c, int type=-1)
00867     {
00868         a.convertTo(c, type, alpha, 0);
00869     }
00870 };
00871 
00872 template<typename M> class CV_EXPORTS MatOp_ScaleAddS_
00873 {
00874 public:
00875     MatOp_ScaleAddS_() {}
00876 
00877     static void apply(const M& a, double alpha, double beta, M& c, int type=-1)
00878     {
00879         a.convertTo(c, type, alpha, beta);
00880     }
00881 };
00882 
00883 template<typename M> class CV_EXPORTS MatOp_AddS_
00884 {
00885 public:
00886     MatOp_AddS_() {}
00887 
00888     static void apply(const M& a, const Scalar& s, M& c, int type=-1)
00889     {
00890         if( type == a.type() || type < 0 )
00891         {
00892             add(a, s, c);
00893         }
00894         else
00895         {
00896             Mat temp;
00897             apply(a, s, temp);
00898             temp.convertTo(c, type);
00899         }
00900     }
00901 };
00902 
00903 template<typename M> class CV_EXPORTS MatOp_AddEx_
00904 {
00905 public:
00906     MatOp_AddEx_() {}
00907 
00908     static void apply(const M& a, double alpha, const M& b,
00909                       double beta, double gamma, M& c, int type=-1)
00910     {
00911         if( type == a.type() || type < 0 )
00912         {
00913             addWeighted(a, alpha, b, beta, gamma, c);
00914         }
00915         else
00916         {
00917             Mat temp;
00918             apply(a, alpha, b, beta, gamma, temp);
00919             temp.convertTo(c, type);
00920         }
00921     }
00922 };
00923 
00924 template<typename M> class CV_EXPORTS MatOp_Bin_
00925 {
00926 public:
00927     MatOp_Bin_() {}
00928 
00929     static void apply(const M& a, const M& b, int _op, M& c, int type=-1)
00930     {
00931         char op = (char)_op;
00932         if( type == a.type() || type < 0 )
00933         {
00934             if( op == '&' )
00935                 bitwise_and( a, b, c );
00936             else if( op == '|' )
00937                 bitwise_or( a, b, c );
00938             else if( op == '^' )
00939                 bitwise_xor( a, b, c );
00940             else if( op == 'm' )
00941                 min( a, b, c );
00942             else if( op == 'M' )
00943                 max( a, b, c );
00944             else if( op == 'a' )
00945                 absdiff( a, b, c );
00946             else
00947                 assert(0);
00948         }
00949         else
00950         {
00951             Mat temp;
00952             apply(a, b, op, temp);
00953             temp.convertTo(c, type);
00954         }
00955     }
00956 };
00957 
00958 template<typename M> class CV_EXPORTS MatOp_BinS_
00959 {
00960 public:
00961     MatOp_BinS_() {}
00962 
00963     static void apply(const M& a, const Scalar& s, int _op, M& c, int type=-1)
00964     {
00965         char op = (char)_op;
00966         if( type == a.type() || type < 0 )
00967         {
00968             if( op == '&' )
00969                 bitwise_and( a, s, c );
00970             else if( op == '|' )
00971                 bitwise_or( a, s, c );
00972             else if( op == '^' )
00973                 bitwise_xor( a, s, c );
00974             else if( op == 'm' )
00975                 min( a, s[0], c );
00976             else if( op == 'M' )
00977                 max( a, s[0], c );
00978             else if( op == 'a' )
00979                 absdiff( a, s, c );
00980             else if( op == '~' )
00981                 bitwise_not( a, c );
00982             else
00983                 assert(0);
00984         }
00985         else
00986         {
00987             Mat temp;
00988             apply(a, s, op, temp);
00989             temp.convertTo(c, type);
00990         }
00991     }
00992 };
00993 
00994 template<typename M> class CV_EXPORTS MatOp_T_
00995 {
00996 public:
00997     MatOp_T_() {}
00998 
00999     static void apply(const M& a, double scale, M& c, int type=-1)
01000     {
01001         if( type == a.type() || type < 0 )
01002         {
01003             transpose(a, c);
01004             if( fabs(scale - 1) > DBL_EPSILON )
01005                 c.convertTo(c, -1, scale, 0);
01006         }
01007         else
01008         {
01009             Mat temp;
01010             apply(a, scale, temp);
01011             temp.convertTo(c, type);
01012         }
01013     }
01014 };
01015 
01016 
01017 template<typename M> class CV_EXPORTS MatOp_MatMul_
01018 {
01019 public:
01020     MatOp_MatMul_() {}
01021 
01022     static void apply(const M& a, const M& b, double scale, int flags, M& c, int type=-1)
01023     {
01024         if( type == a.type() || type < 0 )
01025         {
01026             gemm(a, b, scale, Mat(), 0, c, flags);
01027         }
01028         else
01029         {
01030             Mat temp;
01031             apply(a, b, scale, flags, temp);
01032             temp.convertTo(c, type);
01033         }
01034     }
01035 };
01036 
01037 
01038 template<typename M> class CV_EXPORTS MatOp_MatMulAdd_
01039 {
01040 public:
01041     MatOp_MatMulAdd_() {}
01042 
01043     static void apply(const M& a, const M& b, double alpha,
01044         const M& c, double beta, int flags, M& d, int type=-1)
01045     {
01046         if( type == a.type() || type < 0 )
01047         {
01048             gemm(a, b, alpha, c, beta, d, flags);
01049         }
01050         else
01051         {
01052             Mat temp;
01053             apply(a, b, alpha, c, beta, flags, temp);
01054             temp.convertTo(d, type);
01055         }
01056     }
01057 };
01058 
01059 
01060 template<typename M> class CV_EXPORTS MatOp_Cmp_
01061 {
01062 public:
01063     MatOp_Cmp_() {}
01064 
01065     static void apply(const M& a, const M& b, int op, M& c, int type=-1)
01066     {
01067         if( type == CV_8UC1 || type == -1 )
01068         {
01069             compare(a, b, c, op);
01070         }
01071         else
01072         {
01073             Mat temp;
01074             apply(a, b, op, temp);
01075             temp.convertTo(c, type);
01076         }
01077     }
01078 };
01079 
01080 template<typename M> class CV_EXPORTS MatOp_CmpS_
01081 {
01082 public:
01083     MatOp_CmpS_() {}
01084 
01085     static void apply(const M& a, double alpha, int op, M& c, int type=-1)
01086     {
01087         if( type == CV_8UC1 || type == -1 )
01088         {
01089             compare(a, alpha, c, op);
01090         }
01091         else
01092         {
01093             Mat temp;
01094             apply(a, alpha, op, temp);
01095             temp.convertTo(c, type);
01096         }
01097     }
01098 };
01099 
01100 template<typename M> class CV_EXPORTS MatOp_MulDiv_
01101 {
01102 public:
01103     MatOp_MulDiv_() {}
01104 
01105     static void apply(const M& a, const M& b, double alpha, char op, M& c, int type=-1)
01106     {
01107         if( type == a.type() || type == -1 )
01108         {
01109             if( op == '*' )
01110                 multiply( a, b, c, alpha );
01111             else
01112                 divide( a, b, c, alpha );
01113         }
01114         else
01115         {
01116             Mat temp;
01117             apply(a, b, alpha, op, temp);
01118             temp.convertTo(c, type);
01119         }
01120     }
01121 };
01122 
01123 template<typename M> class CV_EXPORTS MatOp_DivRS_
01124 {
01125 public:
01126     MatOp_DivRS_() {}
01127 
01128     static void apply(const M& a, double alpha, M& c, int type=-1)
01129     {
01130         if( type == a.type() || type == -1 )
01131         {
01132             c.create(a.rows, a.cols, a.type());
01133             divide( alpha, a, c );
01134         }
01135         else
01136         {
01137             Mat temp;
01138             apply(a, alpha, temp);
01139             temp.convertTo(c, type);
01140         }
01141     }
01142 };
01143 
01144 
01145 template<typename M> class CV_EXPORTS MatOp_Inv_
01146 {
01147 public:
01148     MatOp_Inv_() {}
01149 
01150     static void apply(const M& a, int method, M& c, int type=-1)
01151     {
01152         if( type == a.type() || type == -1 )
01153         {
01154             invert(a, c, method);
01155         }
01156         else
01157         {
01158             Mat temp;
01159             apply(a, method, temp);
01160             temp.convertTo(c, type);
01161         }
01162     }
01163 };
01164 
01165 
01166 template<typename M> class CV_EXPORTS MatOp_Solve_
01167 {
01168 public:
01169     MatOp_Solve_() {}
01170 
01171     static void apply(const M& a, const M& b, int method, M& c, int type=-1)
01172     {
01173         if( type == a.type() || type == -1 )
01174         {
01175             solve(a, b, c, method);
01176         }
01177         else
01178         {
01179             Mat temp;
01180             apply(a, b, method, temp);
01181             temp.convertTo(c, type);
01182         }
01183     }
01184 };
01185 
01186 template<typename M> class CV_EXPORTS MatOp_Set_
01187 {
01188 public:
01189     MatOp_Set_() {}
01190 
01191     static void apply(Size size, int type0, const Scalar& s, int mtype, M& c, int type=-1)
01192     {
01193         if( type < 0 )
01194             type = type0;
01195         c.create(size.height, size.width, type);
01196         if( mtype == 0 )
01197             c = Scalar(0);
01198         else if( mtype == 1 )
01199             c = s;
01200         else if( mtype == 2 )
01201             setIdentity(c, s);
01202     }
01203 };
01204 
01205 template<typename A1, typename M, typename Op>
01206 class CV_EXPORTS MatExpr_Op1_
01207 {
01208 public:
01209     MatExpr_Op1_(const A1& _a1) : a1(_a1) {}
01210     void assignTo(Mat& m, int type=-1) const { Op::apply(a1, (M&)m, type); }
01211     operator M() const { M result; assignTo(result); return result; }
01212 
01213     A1 a1;
01214 };
01215 
01216 template<typename A1, typename A2, typename M, typename Op>
01217 class CV_EXPORTS MatExpr_Op2_
01218 {
01219 public:
01220     MatExpr_Op2_(const A1& _a1, const A2& _a2) : a1(_a1), a2(_a2) {}
01221     void assignTo(Mat& m, int type=-1) const { Op::apply(a1, a2, (M&)m, type); }
01222     operator M() const { M result; assignTo(result); return result; }
01223 
01224     A1 a1; A2 a2;
01225 };
01226 
01227 template<typename A1, typename A2, typename A3, typename M, typename Op>
01228 class CV_EXPORTS MatExpr_Op3_
01229 {
01230 public:
01231     MatExpr_Op3_(const A1& _a1, const A2& _a2, const A3& _a3) : a1(_a1), a2(_a2), a3(_a3) {}
01232     void assignTo(Mat& m, int type=-1) const { Op::apply(a1, a2, a3, (M&)m, type); }
01233     operator M() const { M result; assignTo(result); return result; }
01234 
01235     A1 a1; A2 a2; A3 a3;
01236 };
01237 
01238 template<typename A1, typename A2, typename A3, typename A4, typename M, typename Op>
01239 class CV_EXPORTS MatExpr_Op4_
01240 {
01241 public:
01242     MatExpr_Op4_(const A1& _a1, const A2& _a2, const A3& _a3, const A4& _a4)
01243         : a1(_a1), a2(_a2), a3(_a3), a4(_a4) {}
01244     void assignTo(Mat& m, int type=-1) const { Op::apply(a1, a2, a3, a4, (M&)m, type); }
01245     operator M() const { M result; assignTo(result); return result; }
01246 
01247     A1 a1; A2 a2; A3 a3; A4 a4;
01248 };
01249 
01250 template<typename A1, typename A2, typename A3, typename A4, typename A5, typename M, typename Op>
01251 class CV_EXPORTS MatExpr_Op5_
01252 {
01253 public:
01254     MatExpr_Op5_(const A1& _a1, const A2& _a2, const A3& _a3, const A4& _a4, const A5& _a5)
01255         : a1(_a1), a2(_a2), a3(_a3), a4(_a4), a5(_a5) {}
01256     void assignTo(Mat& m, int type=-1) const { Op::apply(a1, a2, a3, a4, a5, (M&)m, type); }
01257     operator M() const { M result; assignTo(result); return result; }
01258 
01259     A1 a1; A2 a2; A3 a3; A4 a4; A5 a5;
01260 };
01261 
01262 template<typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename M, typename Op>
01263 class CV_EXPORTS MatExpr_Op6_
01264 {
01265 public:
01266     MatExpr_Op6_(const A1& _a1, const A2& _a2, const A3& _a3,
01267                     const A4& _a4, const A5& _a5, const A6& _a6)
01268         : a1(_a1), a2(_a2), a3(_a3), a4(_a4), a5(_a5), a6(_a6) {}
01269     void assignTo(Mat& m, int type=-1) const { Op::apply(a1, a2, a3, a4, a5, a6, (M&)m, type); }
01270     operator M() const { M result; assignTo(result); return result; }
01271 
01272     A1 a1; A2 a2; A3 a3; A4 a4; A5 a5; A6 a6;
01273 };
01274 
01276 
01277 // A + B
01278 static inline MatExpr_<MatExpr_Op5_<Mat, double, Mat, double, double, Mat, MatOp_AddEx_<Mat> >, Mat>
01279 operator + (const Mat& a, const Mat& b)
01280 {
01281     typedef MatExpr_Op5_<Mat, double, Mat, double, double, Mat, MatOp_AddEx_<Mat> > MatExpr_Temp;
01282     return MatExpr_<MatExpr_Temp, Mat>(MatExpr_Temp(a, 1, b, 1, 0));
01283 }
01284 
01285 template<typename _Tp> static inline
01286 MatExpr_<MatExpr_Op5_<Mat, double, Mat,
01287 double, double, Mat, MatOp_AddEx_<Mat> >, Mat >
01288 operator + (const Mat_<_Tp>& a, const Mat_<_Tp>& b)
01289 {
01290     typedef MatExpr_Op5_<Mat, double, Mat, double, double, Mat, MatOp_AddEx_<Mat> > MatExpr_Temp;
01291     return MatExpr_<MatExpr_Temp, Mat >(MatExpr_Temp(a, 1, b, 1, 0));
01292 }
01293 
01294 // E1 + E2
01295 template<typename A, typename B, typename M> static inline
01296 MatExpr_<MatExpr_Op5_<M, double, M, double, double, M, MatOp_AddEx_<Mat> >, M>
01297 operator + (const MatExpr_<A, M>& a, const MatExpr_<B, M>& b )
01298 {
01299     typedef MatExpr_Op5_<M, double, M, double, double, M, MatOp_AddEx_<Mat> > MatExpr_Temp;
01300     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp((M)a, 1, (M)b, 1, 0));
01301 }
01302 
01303 // A - B
01304 static inline MatExpr_<MatExpr_Op2_<Mat, Mat, Mat, MatOp_Sub_<Mat> >, Mat>
01305 operator - (const Mat& a, const Mat& b)
01306 {
01307     typedef MatExpr_Op2_<Mat, Mat, Mat, MatOp_Sub_<Mat> > MatExpr_Temp;
01308     return MatExpr_<MatExpr_Temp, Mat>(MatExpr_Temp(a, b));
01309 }
01310 
01311 template<typename _Tp> static inline
01312 MatExpr_<MatExpr_Op2_<Mat, Mat, Mat, MatOp_Sub_<Mat> >, Mat >
01313 operator - (const Mat_<_Tp>& a, const Mat_<_Tp>& b)
01314 {
01315     typedef MatExpr_Op2_<Mat, Mat, Mat, MatOp_Sub_<Mat> > MatExpr_Temp;
01316     return MatExpr_<MatExpr_Temp, Mat >(MatExpr_Temp(a, b));
01317 }
01318 
01319 // E1 - E2
01320 template<typename A, typename B, typename M> static inline
01321 MatExpr_<MatExpr_Op2_<M, M, M, MatOp_Sub_<Mat> >, M>
01322 operator - (const MatExpr_<A, M>& a, const MatExpr_<B, M>& b )
01323 {
01324     typedef MatExpr_Op2_<M, M, M, MatOp_Sub_<Mat> > MatExpr_Temp;
01325     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp((M)a, (M)b));
01326 }
01327 
01328 // -(E1 - E2)
01329 template<typename A, typename B, typename M> static inline
01330 MatExpr_<MatExpr_Op2_<B, A, M, MatOp_Sub_<Mat> >, M>
01331 operator - (const MatExpr_<MatExpr_Op2_<A, B, M, MatOp_Sub_<Mat> >, M>& a )
01332 {
01333     typedef MatExpr_Op2_<B, A, M, MatOp_Sub_<Mat> > MatExpr_Temp;
01334     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(a.e.a2, a.e.a1));
01335 }
01336 
01337 // (A - B)*alpha
01338 template<typename A, typename B, typename M> static inline
01339 MatExpr_<MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> >, M>
01340 operator * (const MatExpr_<MatExpr_Op2_<A, B, M, MatOp_Sub_<Mat> >, M>& a,
01341             double alpha)
01342 {
01343     typedef MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> > MatExpr_Temp;
01344     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(a.e.a1, alpha, a.e.a2, -alpha, 0));
01345 }
01346 
01347 // alpha*(A - B)
01348 template<typename A, typename B, typename M> static inline
01349 MatExpr_<MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> >, M>
01350 operator * (double alpha,
01351             const MatExpr_<MatExpr_Op2_<A, B, M, MatOp_Sub_<Mat> >, M>& a)
01352 { return a*alpha; }
01353 
01354 
01355 // A*alpha
01356 static inline
01357 MatExpr_<MatExpr_Op2_<Mat, double, Mat, MatOp_Scale_<Mat> >, Mat>
01358 operator * (const Mat& a, double alpha)
01359 {
01360     typedef MatExpr_Op2_<Mat, double, Mat, MatOp_Scale_<Mat> > MatExpr_Temp;
01361     return MatExpr_<MatExpr_Temp, Mat>(MatExpr_Temp(a, alpha));
01362 }
01363 
01364 // A*alpha
01365 template<typename _Tp> static inline
01366 MatExpr_<MatExpr_Op2_<Mat, double, Mat, MatOp_Scale_<Mat> >, Mat >
01367 operator * (const Mat_<_Tp>& a, double alpha)
01368 {
01369     typedef MatExpr_Op2_<Mat, double, Mat, MatOp_Scale_<Mat> > MatExpr_Temp;
01370     return MatExpr_<MatExpr_Temp, Mat >(MatExpr_Temp(a, alpha));
01371 }
01372 
01373 // alpha*A
01374 static inline
01375 MatExpr_<MatExpr_Op2_<Mat, double, Mat, MatOp_Scale_<Mat> >, Mat>
01376 operator * (double alpha, const Mat& a)
01377 { return a*alpha; }
01378 
01379 // alpha*A
01380 template<typename _Tp> static inline
01381 MatExpr_<MatExpr_Op2_<Mat, double, Mat, MatOp_Scale_<Mat> >, Mat >
01382 operator * (double alpha, const Mat_<_Tp>& a)
01383 { return a*alpha; }
01384 
01385 // A/alpha
01386 static inline
01387 MatExpr_<MatExpr_Op2_<Mat, double, Mat, MatOp_Scale_<Mat> >, Mat>
01388 operator / (const Mat& a, double alpha)
01389 { return a*(1./alpha); }
01390 
01391 // A/alpha
01392 template<typename _Tp> static inline
01393 MatExpr_<MatExpr_Op2_<Mat, double, Mat, MatOp_Scale_<Mat> >, Mat >
01394 operator / (const Mat_<_Tp>& a, double alpha)
01395 { return a*(1./alpha); }
01396 
01397 // -A
01398 static inline
01399 MatExpr_<MatExpr_Op2_<Mat, double, Mat, MatOp_Scale_<Mat> >, Mat>
01400 operator - (const Mat& a)
01401 { return a*(-1); }
01402 
01403 // -A
01404 template<typename _Tp> static inline
01405 MatExpr_<MatExpr_Op2_<Mat, double, Mat, MatOp_Scale_<Mat> >, Mat >
01406 operator - (const Mat_<_Tp>& a)
01407 { return a*(-1); }
01408 
01409 // E*alpha
01410 template<typename A, typename M> static inline
01411 MatExpr_<MatExpr_Op2_<M, double, M, MatOp_Scale_<Mat> >, M>
01412 operator * (const MatExpr_<A, M>& a, double alpha)
01413 {
01414     typedef MatExpr_Op2_<M, double, M, MatOp_Scale_<Mat> > MatExpr_Temp;
01415     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp((M)a, alpha));
01416 }
01417 
01418 // alpha*E
01419 template<typename A, typename M> static inline
01420 MatExpr_<MatExpr_Op2_<M, double, M, MatOp_Scale_<Mat> >, M>
01421 operator * (double alpha, const MatExpr_<A, M>& a)
01422 {
01423     typedef MatExpr_Op2_<M, double, M, MatOp_Scale_<Mat> > MatExpr_Temp;
01424     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp((M)a, alpha));
01425 }
01426 
01427 // E/alpha
01428 template<typename A, typename M> static inline
01429 MatExpr_<MatExpr_Op2_<M, double, M, MatOp_Scale_<Mat> >, M>
01430 operator / (const MatExpr_<A, M>& a, double alpha)
01431 {
01432     typedef MatExpr_Op2_<M, double, M, MatOp_Scale_<Mat> > MatExpr_Temp;
01433     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp((M)a, (1./alpha)));
01434 }
01435 
01436 // (E*alpha)*beta ~ E*(alpha*beta)
01437 template<typename A, typename M> static inline
01438 MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>
01439 operator * (const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& a,
01440             double beta)
01441 { return a.e.a1*(a.e.a2*beta); }
01442 
01443 // beta*(E*alpha) ~ E*(alpha*beta)
01444 template<typename A, typename M> static inline
01445 MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>
01446 operator * (double beta,
01447             const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& a)
01448 { return a.e.a1*(a.e.a2*beta); }
01449 
01450 // (E*alpha)/beta ~ E*(alpha/beta)
01451 template<typename A, typename M> static inline
01452 MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>
01453 operator / (const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& a,
01454             double beta)
01455 { return a.e.a1*(a.e.a2/beta); }
01456 
01457 // -E ~ E*(-1)
01458 template<typename A, typename M> static inline
01459 MatExpr_<MatExpr_Op2_<M, double, M, MatOp_Scale_<Mat> >, M>
01460 operator - (const MatExpr_<A, M>& a)
01461 { return a*(-1.); }
01462 
01463 // -(E*alpha) ~ E*(-alpha)
01464 template<typename A, typename M> static inline
01465 MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>
01466 operator - (const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& a)
01467 { return a.e.a1*(-a.e.a2); }
01468 
01469 // A + alpha
01470 template<typename _Tp> static inline
01471 MatExpr_<MatExpr_Op3_<Mat, double, double, Mat, MatOp_ScaleAddS_<Mat> >, Mat >
01472 operator + (const Mat_<_Tp>& a, double alpha)
01473 {
01474     typedef MatExpr_Op3_<Mat, double, double, Mat,
01475         MatOp_ScaleAddS_<Mat> > MatExpr_Temp;
01476     return MatExpr_<MatExpr_Temp, Mat >(MatExpr_Temp(a, 1, alpha));
01477 }
01478 
01479 // A + alpha
01480 template<typename _Tp> static inline
01481 MatExpr_<MatExpr_Op2_<Mat, Scalar, Mat, MatOp_AddS_<Mat> >, Mat >
01482 operator + (const Mat_<_Tp>& a, const Scalar& alpha)
01483 {
01484     typedef MatExpr_Op2_<Mat, Scalar, Mat,
01485         MatOp_AddS_<Mat> > MatExpr_Temp;
01486     return MatExpr_<MatExpr_Temp, Mat >(MatExpr_Temp(a, alpha));
01487 }
01488 
01489 static inline
01490 MatExpr_<MatExpr_Op2_<Mat, Scalar, Mat, MatOp_AddS_<Mat> >, Mat >
01491 operator + (const Mat& a, const Scalar& alpha)
01492 {
01493     typedef MatExpr_Op2_<Mat, Scalar, Mat, MatOp_AddS_<Mat> > MatExpr_Temp;
01494     return MatExpr_<MatExpr_Temp, Mat>(MatExpr_Temp(a, alpha));
01495 }
01496 
01497 
01498 // alpha + A
01499 template<typename _Tp> static inline
01500 MatExpr_<MatExpr_Op3_<Mat, double, double, Mat, MatOp_ScaleAddS_<Mat> >, Mat >
01501 operator + (double alpha, const Mat_<_Tp>& a)
01502 { return a + alpha; }
01503 
01504 // alpha + A
01505 template<typename _Tp> static inline
01506 MatExpr_<MatExpr_Op2_<Mat, Scalar, Mat, MatOp_AddS_<Mat> >, Mat >
01507 operator + (const Scalar& alpha, const Mat_<_Tp>& a)
01508 { return a + alpha; }
01509 
01510 static inline
01511 MatExpr_<MatExpr_Op2_<Mat, Scalar, Mat, MatOp_AddS_<Mat> >, Mat >
01512 operator + (const Scalar& alpha, const Mat& a)
01513 { return a + alpha; }
01514 
01515 // A - alpha
01516 template<typename _Tp> static inline
01517 MatExpr_<MatExpr_Op3_<Mat, double, double, Mat, MatOp_ScaleAddS_<Mat> >, Mat >
01518 operator - (const Mat_<_Tp>& a, double alpha)
01519 { return a + (-alpha); }
01520 
01521 // A - alpha
01522 template<typename _Tp> static inline
01523 MatExpr_<MatExpr_Op2_<Mat, Scalar, Mat, MatOp_AddS_<Mat> >, Mat >
01524 operator - (const Mat_<_Tp>& a, const Scalar& alpha)
01525 { return a + (-alpha); }
01526 
01527 static inline
01528 MatExpr_<MatExpr_Op2_<Mat, Scalar, Mat, MatOp_AddS_<Mat> >, Mat >
01529 operator - (const Mat& a, const Scalar& alpha)
01530 { return a + (-alpha); }
01531 
01532 // alpha - A
01533 template<typename _Tp> static inline
01534 MatExpr_<MatExpr_Op3_<Mat, double, double, Mat, MatOp_ScaleAddS_<Mat> >, Mat >
01535 operator - (double alpha, const Mat_<_Tp>& a)
01536 {
01537     typedef MatExpr_Op3_<Mat, double, double, Mat,
01538         MatOp_ScaleAddS_<Mat> > MatExpr_Temp;
01539     return MatExpr_<MatExpr_Temp, Mat >(MatExpr_Temp(a, -1, alpha));
01540 }
01541 
01542 // E + alpha
01543 template<typename A, typename M> static inline
01544 MatExpr_<MatExpr_Op3_<M, double, double, M, MatOp_ScaleAddS_<Mat> >, M>
01545 operator + (const MatExpr_<A, M>& a, double alpha)
01546 {
01547     typedef MatExpr_Op3_<M, double, double, M, MatOp_ScaleAddS_<Mat> > MatExpr_Temp;
01548     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp((M)a, 1, alpha));
01549 }
01550 
01551 // E + alpha
01552 template<typename A, typename M> static inline
01553 MatExpr_<MatExpr_Op2_<M, Scalar, M, MatOp_AddS_<Mat> >, M>
01554 operator + (const MatExpr_<A, M>& a, const Scalar& alpha)
01555 {
01556     typedef MatExpr_Op2_<M, Scalar, M, MatOp_AddS_<Mat> > MatExpr_Temp;
01557     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp((M)a, alpha));
01558 }
01559 
01560 // alpha + E
01561 template<typename A, typename M> static inline
01562 MatExpr_<MatExpr_Op3_<M, double, double, M, MatOp_ScaleAddS_<Mat> >, M>
01563 operator + (double alpha, const MatExpr_<A, M>& a)
01564 { return a + alpha; }
01565 
01566 // alpha + E
01567 template<typename A, typename M> static inline
01568 MatExpr_<MatExpr_Op2_<M, Scalar, M, MatOp_AddS_<Mat> >, M>
01569 operator + (const Scalar& alpha, const MatExpr_<A, M>& a)
01570 { return a + alpha; }
01571 
01572 // E - alpha
01573 template<typename A, typename M> static inline
01574 MatExpr_<MatExpr_Op3_<M, double, double, M, MatOp_ScaleAddS_<Mat> >, M>
01575 operator - (const MatExpr_<A, M>& a, double alpha)
01576 { return a + (-alpha); }
01577 
01578 // E - alpha
01579 template<typename A, typename M> static inline
01580 MatExpr_<MatExpr_Op2_<M, Scalar, M, MatOp_AddS_<Mat> >, M>
01581 operator - (const MatExpr_<A, M>& a, const Scalar& alpha)
01582 { return a + (-alpha); }
01583 
01584 // alpha - E
01585 template<typename A, typename M> static inline
01586 MatExpr_<MatExpr_Op3_<M, double, double, M, MatOp_ScaleAddS_<Mat> >, M>
01587 operator - (double alpha, const MatExpr_<A, M>& a)
01588 {
01589     typedef MatExpr_Op3_<M, double, double, M, MatOp_ScaleAddS_<Mat> > MatExpr_Temp;
01590     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(a, -1, alpha));
01591 }
01592 
01593 // E*alpha + beta
01594 template<typename A, typename M> static inline
01595 MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>
01596 operator + (const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& a,
01597             double beta)
01598 {
01599     typedef MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> > MatExpr_Temp;
01600     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(a.e.a1, a.e.a2, beta));
01601 }
01602 
01603 // beta + E*alpha
01604 template<typename A, typename M> static inline
01605 MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>
01606 operator + (double beta,
01607             const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& a)
01608 { return a + beta; }
01609 
01610 // E*alpha - beta
01611 template<typename A, typename M> static inline
01612 MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>
01613 operator - (const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& a,
01614             double beta)
01615 { return a + (-beta); }
01616 
01617 // beta - E*alpha
01618 template<typename A, typename M> static inline
01619 MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>
01620 operator - (double beta,
01621             const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& a)
01622 { return (a.e.a1*(-a.e.a2)) + beta; }
01623 
01624 // (E*alpha + gamma) + beta ~ E*alpha + (gamma + beta)
01625 template<typename A, typename M> static inline
01626 MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>
01627 operator + (const MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>& a,
01628             double beta)
01629 { return a.e.a1*a.e.a2 + (a.e.a3 + beta); }
01630 
01631 // beta + (E*alpha + gamma)
01632 template<typename A, typename M> static inline
01633 MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>
01634 operator + (double beta, const MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>& a)
01635 { return a + beta; }
01636 
01637 // (E*alpha + gamma) - beta
01638 template<typename A, typename M> static inline
01639 MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>
01640 operator - (const MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>& a,
01641             double beta)
01642 { return a + (-beta); }
01643 
01644 // beta - (E*alpha + gamma)
01645 template<typename A, typename M> static inline
01646 MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>
01647 operator - (double beta, const MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>& a)
01648 { return a.e.a1*(-a.e.a2) + (beta - a.e.a3); }
01649 
01650 // (E*alpha + gamma)*beta
01651 template<typename A, typename M> static inline
01652 MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>
01653 operator * (const MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>& a,
01654             double beta)
01655 { return a.e.a1*(a.e.a2*beta) + (a.e.a3*beta); }
01656 
01657 // beta*(E*alpha + gamma)
01658 template<typename A, typename M> static inline
01659 MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>
01660 operator * (double beta, const MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>& a)
01661 { return a*beta; }
01662 
01663 // -(E*alpha + beta)
01664 template<typename A, typename M> static inline
01665 MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>
01666 operator - (const MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>& a)
01667 { return a*(-1); }
01668 
01669 // (A*u + B*v + w) + beta
01670 template<typename A, typename B, typename M> static inline
01671 MatExpr_<MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> >, M>
01672 operator + (const MatExpr_<MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> >, M>& a,
01673             double beta )
01674 {
01675     typedef MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> > MatExpr_Temp;
01676     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(a.e.a1, a.e.a2, a.e.a3, a.e.a4, a.e.a5 + beta));
01677 }
01678 
01679 // beta + (A*u + B*v + w)
01680 template<typename A, typename B, typename M> static inline
01681 MatExpr_<MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> >, M>
01682 operator + (double beta,
01683             const MatExpr_<MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> >, M>& a)
01684 { return a + beta; }
01685 
01686 // (A*u + B*v + w) - beta
01687 template<typename A, typename B, typename M> static inline
01688 MatExpr_<MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> >, M>
01689 operator - (const MatExpr_<MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> >, M>& a,
01690             double beta)
01691 { return a + (-beta); }
01692 
01693 // beta - (A*u + B*v + w)
01694 template<typename A, typename B, typename M> static inline
01695 MatExpr_<MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> >, M>
01696 operator - (double beta,
01697             const MatExpr_<MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> >, M>& a)
01698 {
01699     typedef MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> > MatExpr_Temp;
01700     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(a.e.a1, -a.e.a2, a.e.a3, -a.e.a4, -a.e.a5 + beta));
01701 }
01702 
01703 // (A*u + B*v + w)*beta
01704 template<typename A, typename B, typename M> static inline
01705 MatExpr_<MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> >, M>
01706 operator * (const MatExpr_<MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> >, M>& a,
01707             double beta )
01708 {
01709     typedef MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> > MatExpr_Temp;
01710     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(a.e.a1,
01711         a.e.a2*beta, a.e.a3, a.e.a4*beta, a.e.a5*beta));
01712 }
01713 
01714 // beta*(A*u + B*v + w)
01715 template<typename A, typename B, typename M> static inline
01716 MatExpr_<MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> >, M>
01717 operator * (double beta,
01718             const MatExpr_<MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> >, M>& a)
01719 { return a * beta; }
01720 
01721 // -(A*u + B*v + w)
01722 template<typename A, typename B, typename M> static inline
01723 MatExpr_<MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> >, M>
01724 operator - (const MatExpr_<MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> >, M>& a)
01725 { return a*(-1); }
01726 
01727 // A*alpha + B
01728 template<typename A, typename M> static inline
01729 MatExpr_<MatExpr_Op5_<A, double, M, double, double, M, MatOp_AddEx_<Mat> >, M>
01730 operator + (const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& a,
01731             const M& b )
01732 {
01733     typedef MatExpr_Op5_<A, double, M, double, double, M, MatOp_AddEx_<Mat> > MatExpr_Temp;
01734     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(a.e.a1, a.e.a2, b, 1, 0));
01735 }
01736 
01737 // B + A*alpha
01738 template<typename A, typename M> static inline
01739 MatExpr_<MatExpr_Op5_<A, double, M, double, double, M, MatOp_AddEx_<Mat> >, M>
01740 operator + (const M& b,
01741             const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& a)
01742 { return a + b; }
01743 
01744 // (A*alpha + beta) + B
01745 template<typename A, typename M> static inline
01746 MatExpr_<MatExpr_Op5_<A, double, M, double, double, M, MatOp_AddEx_<Mat> >, M>
01747 operator + (const MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>& a,
01748             const M& b )
01749 {
01750     typedef MatExpr_Op5_<A, double, M, double, double, M, MatOp_AddEx_<Mat> > MatExpr_Temp;
01751     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(a.e.a1, a.e.a2, b, 1, a.e.a3));
01752 }
01753 
01754 // B + (A*alpha + beta)
01755 template<typename A, typename M> static inline
01756 MatExpr_<MatExpr_Op5_<A, double, M, double, double, M, MatOp_AddEx_<Mat> >, M>
01757 operator + (const M& b,
01758             const MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>& a)
01759 { return a + b; }
01760 
01761 
01762 // A*alpha + E
01763 template<typename A, typename B, typename M> static inline
01764 MatExpr_<MatExpr_Op5_<A, double, M, double, double, M, MatOp_AddEx_<Mat> >, M>
01765 operator + (const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& a,
01766             const MatExpr_<B, M>& b )
01767 { return a + (M)b; }
01768 
01769 // E + A*alpha
01770 template<typename A, typename B, typename M> static inline
01771 MatExpr_<MatExpr_Op5_<A, double, M, double, double, M, MatOp_AddEx_<Mat> >, M>
01772 operator + (const MatExpr_<B, M>& b,
01773             const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& a)
01774 { return a + (M)b; }
01775 
01776 // (A*alpha + beta) + E
01777 template<typename A, typename B, typename M> static inline
01778 MatExpr_<MatExpr_Op5_<A, double, M, double, double, M, MatOp_AddEx_<Mat> >, M>
01779 operator + (const MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>& a,
01780             const MatExpr_<B, M>& b )
01781 { return a + (M)b; }
01782 
01783 // E + (A*alpha + beta)
01784 template<typename A, typename B, typename M> static inline
01785 MatExpr_<MatExpr_Op5_<A, double, M, double, double, M, MatOp_AddEx_<Mat> >, M>
01786 operator + (const MatExpr_<B, M>& b,
01787             const MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>& a)
01788 { return a + b; }
01789 
01790 // A*alpha + B*beta
01791 template<typename A, typename B, typename M> static inline
01792 MatExpr_<MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> >, M>
01793 operator + (const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& a,
01794             const MatExpr_<MatExpr_Op2_<B, double, M, MatOp_Scale_<Mat> >, M>& b )
01795 {
01796     typedef MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> > MatExpr_Temp;
01797     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(a.e.a1, a.e.a2, b.e.a1, b.e.a2, 0));
01798 }
01799 
01800 // (A*alpha + beta) + B*gamma
01801 template<typename A, typename B, typename M> static inline
01802 MatExpr_<MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> >, M>
01803 operator + (const MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>& a,
01804             const MatExpr_<MatExpr_Op2_<B, double, M, MatOp_Scale_<Mat> >, M>& b )
01805 {
01806     typedef MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> > MatExpr_Temp;
01807     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(a.e.a1, a.e.a2, b.e.a1, b.e.a2, a.e.a3));
01808 }
01809 
01810 // B*gamma + (A*alpha + beta)
01811 template<typename A, typename B, typename M> static inline
01812 MatExpr_<MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> >, M>
01813 operator + (const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& b,
01814             const MatExpr_<MatExpr_Op3_<B, double, double, M, MatOp_ScaleAddS_<Mat> >, M>& a )
01815 { return a + b; }
01816 
01817 // (A*alpha + beta) + (B*gamma + theta)
01818 template<typename A, typename B, typename M> static inline
01819 MatExpr_<MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> >, M>
01820 operator + (const MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>& a,
01821             const MatExpr_<MatExpr_Op3_<B, double, double, M, MatOp_ScaleAddS_<Mat> >, M>& b )
01822 {
01823     typedef MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> > MatExpr_Temp;
01824     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));
01825 }
01826 
01827 // A*alpha - B
01828 template<typename A, typename M> static inline
01829 MatExpr_<MatExpr_Op5_<A, double, M, double, double, M, MatOp_AddEx_<Mat> >, M>
01830 operator - (const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& a,
01831             const M& b )
01832 {
01833     typedef MatExpr_Op5_<A, double, M, double, double, M, MatOp_AddEx_<Mat> > MatExpr_Temp;
01834     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(a.e.a1, a.e.a2, b, -1, 0));
01835 }
01836 
01837 // B - A*alpha
01838 template<typename A, typename M> static inline
01839 MatExpr_<MatExpr_Op5_<A, double, M, double, double, M, MatOp_AddEx_<Mat> >, M>
01840 operator - (const M& b,
01841             const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& a)
01842 {
01843     typedef MatExpr_Op5_<A, double, M, double, double, M, MatOp_AddEx_<Mat> > MatExpr_Temp;
01844     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(a.e.a1, -a.e.a2, b, 1, 0));
01845 }
01846 
01847 // (A*alpha + beta) - B
01848 template<typename A, typename M> static inline
01849 MatExpr_<MatExpr_Op5_<A, double, M, double, double, M, MatOp_AddEx_<Mat> >, M>
01850 operator - (const MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>& a,
01851             const M& b )
01852 {
01853     typedef MatExpr_Op5_<A, double, M, double, double, M, MatOp_AddEx_<Mat> > MatExpr_Temp;
01854     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(a.e.a1, a.e.a2, b, -1, a.e.a3));
01855 }
01856 
01857 // B - (A*alpha + beta)
01858 template<typename A, typename M> static inline
01859 MatExpr_<MatExpr_Op5_<A, double, M, double, double, M, MatOp_AddEx_<Mat> >, M>
01860 operator - (const M& b,
01861             const MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>& a)
01862 {
01863     typedef MatExpr_Op5_<A, double, M, double, double, M, MatOp_AddEx_<Mat> > MatExpr_Temp;
01864     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(a.e.a1, -a.e.a2, b, 1, -a.e.a3));
01865 }
01866 
01867 // A*alpha - E
01868 template<typename A, typename B, typename M> static inline
01869 MatExpr_<MatExpr_Op5_<A, double, M, double, double, M, MatOp_AddEx_<Mat> >, M>
01870 operator - (const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& a,
01871             const MatExpr_<B, M>& b )
01872 { return a - (M)b; }
01873 
01874 // E - A*alpha
01875 template<typename A, typename B, typename M> static inline
01876 MatExpr_<MatExpr_Op5_<A, double, M, double, double, M, MatOp_AddEx_<Mat> >, M>
01877 operator - (const MatExpr_<B, M>& b,
01878             const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& a)
01879 { return (M)b - a; }
01880 
01881 // (A*alpha + beta) - E
01882 template<typename A, typename B, typename M> static inline
01883 MatExpr_<MatExpr_Op5_<A, double, M, double, double, M, MatOp_AddEx_<Mat> >, M>
01884 operator - (const MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>& a,
01885             const MatExpr_<B, M>& b )
01886 { return a - (M)b; }
01887 
01888 // E - (A*alpha + beta)
01889 template<typename A, typename B, typename M> static inline
01890 MatExpr_<MatExpr_Op5_<A, double, M, double, double, M, MatOp_AddEx_<Mat> >, M>
01891 operator - (const MatExpr_<B, M>& b,
01892             const MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>& a)
01893 { return (M)b - a; }
01894 
01895 // A*alpha - B*beta
01896 template<typename A, typename B, typename M> static inline
01897 MatExpr_<MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> >, M>
01898 operator - (const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& a,
01899             const MatExpr_<MatExpr_Op2_<B, double, M, MatOp_Scale_<Mat> >, M>& b )
01900 {
01901     typedef MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> > MatExpr_Temp;
01902     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(a.e.a1, a.e.a2, b.e.a1, -b.e.a2, 0));
01903 }
01904 
01905 // (A*alpha + beta) - B*gamma
01906 template<typename A, typename B, typename M> static inline
01907 MatExpr_<MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> >, M>
01908 operator - (const MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>& a,
01909             const MatExpr_<MatExpr_Op2_<B, double, M, MatOp_Scale_<Mat> >, M>& b )
01910 {
01911     typedef MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> > MatExpr_Temp;
01912     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(a.e.a1, a.e.a2, b.e.a1, -b.e.a2, a.e.a3));
01913 }
01914 
01915 // B*gamma - (A*alpha + beta)
01916 template<typename A, typename B, typename M> static inline
01917 MatExpr_<MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> >, M>
01918 operator - (const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& b,
01919             const MatExpr_<MatExpr_Op3_<B, double, double, M, MatOp_ScaleAddS_<Mat> >, M>& a )
01920 {
01921     typedef MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> > MatExpr_Temp;
01922     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(a.e.a1, -a.e.a2, b.e.a1, b.e.a2, -a.e.a3));
01923 }
01924 
01925 // (A*alpha + beta) - (B*gamma + theta)
01926 template<typename A, typename B, typename M> static inline
01927 MatExpr_<MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> >, M>
01928 operator - (const MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>& a,
01929             const MatExpr_<MatExpr_Op3_<B, double, double, M, MatOp_ScaleAddS_<Mat> >, M>& b )
01930 {
01931     typedef MatExpr_Op5_<A, double, B, double, double, M, MatOp_AddEx_<Mat> > MatExpr_Temp;
01932     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));
01933 }
01934 
01936 
01937 // A^t
01938 inline MatExpr_<MatExpr_Op2_<Mat, double, Mat, MatOp_T_<Mat> >, Mat>
01939 Mat::t() const
01940 {
01941     typedef MatExpr_Op2_<Mat, double, Mat, MatOp_T_<Mat> > MatExpr_Temp;
01942     return MatExpr_<MatExpr_Temp, Mat>(MatExpr_Temp(*this, 1));
01943 }
01944 
01945 template<typename _Tp> inline
01946 MatExpr_<MatExpr_Op2_<Mat, double, Mat, MatOp_T_<Mat> >, Mat >
01947 Mat_<_Tp>::t() const
01948 {
01949     typedef MatExpr_Op2_<Mat, double, Mat, MatOp_T_<Mat> > MatExpr_Temp;
01950     return MatExpr_<MatExpr_Temp, Mat>(MatExpr_Temp(*this, 1));
01951 }
01952 
01953 // A*B
01954 static inline
01955 MatExpr_<MatExpr_Op4_<Mat, Mat, double, int, Mat, MatOp_MatMul_<Mat> >, Mat>
01956 operator * ( const Mat& a, const Mat& b )
01957 {
01958     typedef MatExpr_Op4_<Mat, Mat, double, int, Mat, MatOp_MatMul_<Mat> > MatExpr_Temp;
01959     return MatExpr_<MatExpr_Temp, Mat>(MatExpr_Temp(a, b, 1, 0));
01960 }
01961 
01962 template<typename _Tp> static inline
01963 MatExpr_<MatExpr_Op4_<Mat, Mat, double, int, Mat,
01964 MatOp_MatMul_<Mat> >, Mat >
01965 operator * ( const Mat_<_Tp>& a, const Mat_<_Tp>& b )
01966 {
01967     typedef MatExpr_Op4_<Mat, Mat, double, int, Mat,
01968         MatOp_MatMul_<Mat> > MatExpr_Temp;
01969     return MatExpr_<MatExpr_Temp, Mat >(MatExpr_Temp(a, b, 1, 0));
01970 }
01971 
01972 template<typename A, typename B, typename M> static inline
01973 MatExpr_<MatExpr_Op4_<M, M, double, int, M, MatOp_MatMul_<Mat> >, M>
01974 operator * ( const MatExpr_<A, M>& a, const MatExpr_<B, M>& b )
01975 {
01976     typedef MatExpr_Op4_<M, M, double, int, M, MatOp_MatMul_<Mat> > MatExpr_Temp;
01977     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp((M)a, (M)b, 1, 0));
01978 }
01979 
01980 // (A*alpha)*B
01981 template<typename A, typename M> static inline
01982 MatExpr_<MatExpr_Op4_<M, M, double, int, M, MatOp_MatMul_<Mat> >, M>
01983 operator * ( const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& a, const M& b )
01984 {
01985     typedef MatExpr_Op4_<M, M, double, int, M, MatOp_MatMul_<Mat> > MatExpr_Temp;
01986     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp((M)a.e.a1, b, a.e.a2, 0));
01987 }
01988 
01989 // A*(B*alpha)
01990 template<typename A, typename M> static inline
01991 MatExpr_<MatExpr_Op4_<M, M, double, int, M, MatOp_MatMul_<Mat> >, M>
01992 operator * ( const M& b, const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& a )
01993 {
01994     typedef MatExpr_Op4_<M, M, double, int, M, MatOp_MatMul_<Mat> > MatExpr_Temp;
01995     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(b, (M)a.e.a1, a.e.a2, 0));
01996 }
01997 
01998 // A^t*B
01999 template<typename A, typename M> static inline
02000 MatExpr_<MatExpr_Op4_<M, M, double, int, M, MatOp_MatMul_<Mat> >, M>
02001 operator * ( const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_T_<Mat> >, M>& a, const M& b )
02002 {
02003     typedef MatExpr_Op4_<M, M, double, int, M, MatOp_MatMul_<Mat> > MatExpr_Temp;
02004     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp((M)a.e.a1, b, a.e.a2, GEMM_1_T));
02005 }
02006 
02007 // A*B^t
02008 template<typename A, typename M> static inline
02009 MatExpr_<MatExpr_Op4_<M, M, double, int, M, MatOp_MatMul_<Mat> >, M>
02010 operator * ( const M& a, const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_T_<Mat> >, M>& b )
02011 {
02012     typedef MatExpr_Op4_<M, M, double, int, M, MatOp_MatMul_<Mat> > MatExpr_Temp;
02013     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(a, (M)b.e.a1, b.e.a2, GEMM_2_T));
02014 }
02015 
02016 // (A*alpha)*(B*beta)
02017 template<typename A, typename B, typename M> static inline
02018 MatExpr_<MatExpr_Op4_<M, M, double, int, M, MatOp_MatMul_<Mat> >, M>
02019 operator * ( const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& a,
02020              const MatExpr_<MatExpr_Op2_<B, double, M, MatOp_Scale_<Mat> >, M>& b )
02021 {
02022     typedef MatExpr_Op4_<M, M, double, int, M, MatOp_MatMul_<Mat> > MatExpr_Temp;
02023     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp((M)a.e.a1, (M)b.e.a1, a.e.a2*b.e.a2, 0));
02024 }
02025 
02026 // A^t*(B*alpha)
02027 template<typename A, typename B, typename M> static inline
02028 MatExpr_<MatExpr_Op4_<M, M, double, int, M, MatOp_MatMul_<Mat> >, M>
02029 operator * ( const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_T_<Mat> >, M>& a,
02030              const MatExpr_<MatExpr_Op2_<B, double, M, MatOp_Scale_<Mat> >, M>& b )
02031 {
02032     typedef MatExpr_Op4_<M, M, double, int, M, MatOp_MatMul_<Mat> > MatExpr_Temp;
02033     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp((M)a.e.a1, (M)b.e.a1, a.e.a2*b.e.a2, GEMM_1_T));
02034 }
02035 
02036 // (A*alpha)*B^t
02037 template<typename A, typename B, typename M> static inline
02038 MatExpr_<MatExpr_Op4_<M, M, double, int, M, MatOp_MatMul_<Mat> >, M>
02039 operator * ( const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& a,
02040              const MatExpr_<MatExpr_Op2_<B, double, M, MatOp_T_<Mat> >, M>& b )
02041 {
02042     typedef MatExpr_Op4_<M, M, double, int, M, MatOp_MatMul_<Mat> > MatExpr_Temp;
02043     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp((M)a.e.a1, (M)b.e.a1, a.e.a2*b.e.a2, GEMM_2_T));
02044 }
02045 
02046 // A^t*B^t
02047 template<typename A, typename B, typename M> static inline
02048 MatExpr_<MatExpr_Op4_<M, M, double, int, M, MatOp_MatMul_<Mat> >, M>
02049 operator * ( const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_T_<Mat> >, M>& a,
02050              const MatExpr_<MatExpr_Op2_<B, double, M, MatOp_T_<Mat> >, M>& b )
02051 {
02052     typedef MatExpr_Op4_<M, M, double, int, M, MatOp_MatMul_<Mat> > MatExpr_Temp;
02053     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp((M)a.e.a1,
02054         (M)b.e.a1, a.e.a2*b.e.a2, GEMM_1_T+GEMM_2_T));
02055 }
02056 
02057 // (A*B)*alpha
02058 template<typename A, typename B, typename M> static inline
02059 MatExpr_<MatExpr_Op4_<A, B, double, int, M, MatOp_MatMul_<Mat> >, M>
02060 operator * ( const MatExpr_<MatExpr_Op4_<A, B, double, int, M, MatOp_MatMul_<Mat> >, M>& a,
02061              double alpha )
02062 {
02063     typedef MatExpr_Op4_<A, B, double, int, M, MatOp_MatMul_<Mat> > MatExpr_Temp;
02064     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(a.e.a1, a.e.a2, a.e.a3*alpha, a.e.a4));
02065 }
02066 
02067 // alpha*(A*B)
02068 template<typename A, typename B, typename M> static inline
02069 MatExpr_<MatExpr_Op4_<M, M, double, int, M, MatOp_MatMul_<Mat> >, M>
02070 operator * ( double alpha,
02071              const MatExpr_<MatExpr_Op4_<A, B, double, int, M, MatOp_MatMul_<Mat> >, M>& a )
02072 {
02073     return a*alpha;
02074 }
02075 
02076 // -(A*B)
02077 template<typename A, typename B, typename M> static inline
02078 MatExpr_<MatExpr_Op4_<A, B, double, int, M, MatOp_MatMul_<Mat> >, M>
02079 operator - ( const MatExpr_<MatExpr_Op4_<A, B, double, int, M, MatOp_MatMul_<Mat> >, M>& a )
02080 {
02081     return a*(-1);
02082 }
02083 
02084 // (A*alpha + beta)*B
02085 template<typename A, typename M> static inline
02086 MatExpr_<MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> >, M>
02087 operator * ( const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_ScaleAddS_<Mat> >, M>& a, const M& b )
02088 {
02089     typedef MatExpr_Op4_<M, M, double, int, M, MatOp_MatMul_<Mat> > MatExpr_Temp;
02090     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp((M)a.e.a1, b, a.e.a2, b, a.e.a3, 0));
02091 }
02092 
02093 // A*(B*alpha + beta)
02094 template<typename A, typename M> static inline
02095 MatExpr_<MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> >, M>
02096 operator * ( const M& a, const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_ScaleAddS_<Mat> >, M>& b )
02097 {
02098     typedef MatExpr_Op4_<M, M, double, int, M, MatOp_MatMul_<Mat> > MatExpr_Temp;
02099     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(a, (M)b.e.a1, b.e.a2, a, b.e.a3, 0));
02100 }
02101 
02102 // (A*alpha + beta)*(B*gamma)
02103 template<typename A, typename B, typename M> static inline
02104 MatExpr_<MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> >, M>
02105 operator * ( const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_ScaleAddS_<Mat> >, M>& a,
02106              const MatExpr_<MatExpr_Op2_<B, double, M, MatOp_Scale_<Mat> >, M>& b )
02107 {
02108     typedef MatExpr_Op4_<M, M, double, int, M, MatOp_MatMul_<Mat> > MatExpr_Temp;
02109     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp((M)a.e.a1, (M)b.e.a1,
02110         a.e.a2*b.e.a2, (M)b.e.a1, a.e.a3*b.e.a2, 0));
02111 }
02112 
02113 // (A*gamma)*(B*alpha + beta)
02114 template<typename A, typename B, typename M> static inline
02115 MatExpr_<MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> >, M>
02116 operator * ( const MatExpr_<MatExpr_Op2_<B, double, M, MatOp_Scale_<Mat> >, M>& a,
02117              const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_ScaleAddS_<Mat> >, M>& b )
02118 {
02119     typedef MatExpr_Op4_<M, M, double, int, M, MatOp_MatMul_<Mat> > MatExpr_Temp;
02120     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp((M)a.e.a1, (M)b.e.a1,
02121         a.e.a2*b.e.a2, (M)a.e.a1, a.e.a2*b.e.a3, 0));
02122 }
02123 
02124 // (A*alpha + beta)*B^t
02125 template<typename A, typename B, typename M> static inline
02126 MatExpr_<MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> >, M>
02127 operator * ( const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_ScaleAddS_<Mat> >, M>& a,
02128              const MatExpr_<MatExpr_Op2_<B, double, M, MatOp_T_<Mat> >, M>& b )
02129 {
02130     typedef MatExpr_Op4_<M, M, double, int, M, MatOp_MatMul_<Mat> > MatExpr_Temp;
02131     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp((M)a.e.a1, (M)b.e.a1,
02132         a.e.a2*b.e.a2, (M)b.e.a1, a.e.a3*b.e.a2, GEMM_2_T));
02133 }
02134 
02135 // A^t*(B*alpha + beta)
02136 template<typename A, typename B, typename M> static inline
02137 MatExpr_<MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> >, M>
02138 operator * ( const MatExpr_<MatExpr_Op2_<B, double, M, MatOp_T_<Mat> >, M>& a,
02139              const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_ScaleAddS_<Mat> >, M>& b )
02140 {
02141     typedef MatExpr_Op4_<M, M, double, int, M, MatOp_MatMul_<Mat> > MatExpr_Temp;
02142     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp((M)a.e.a1, (M)b.e.a1,
02143         a.e.a2*b.e.a2, (M)a.e.a1, a.e.a2*b.e.a3, GEMM_1_T));
02144 }
02145 
02146 // (A*B + C)*alpha
02147 template<typename A, typename B, typename C, typename M> static inline
02148 MatExpr_<MatExpr_Op6_<A, B, double, C, double, int, M, MatOp_MatMulAdd_<Mat> >, M>
02149 operator * ( const MatExpr_<MatExpr_Op6_<A, B, double, C,
02150              double, int, M, MatOp_MatMulAdd_<Mat> >, M>& a, double alpha )
02151 {
02152     typedef MatExpr_Op6_<A, B, double, C, double, int, M, MatOp_MatMulAdd_<Mat> > MatExpr_Temp;
02153     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(a.e.a1, a.e.a2,
02154         a.e.a3*alpha, a.e.a4, a.e.a5*alpha, a.e.a6));
02155 }
02156 
02157 // alpha*(A*B + C)
02158 template<typename A, typename B, typename C, typename M> static inline
02159 MatExpr_<MatExpr_Op6_<A, B, double, C, double, int, M, MatOp_MatMulAdd_<Mat> >, M>
02160 operator * ( double alpha, const MatExpr_<MatExpr_Op6_<A, B, double, C,
02161              double, int, M, MatOp_MatMulAdd_<Mat> >, M>& a )
02162 { return a*alpha; }
02163 
02164 // -(A*B + C)
02165 template<typename A, typename B, typename C, typename M> static inline
02166 MatExpr_<MatExpr_Op6_<A, B, double, C, double, int, M, MatOp_MatMulAdd_<Mat> >, M>
02167 operator - ( const MatExpr_<MatExpr_Op6_<A, B, double, C,
02168              double, int, M, MatOp_MatMulAdd_<Mat> >, M>& a )
02169 { return a*(-1); }
02170 
02171 
02172 // (A*B) + C
02173 template<typename A, typename B, typename M> static inline
02174 MatExpr_<MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> >, M>
02175 operator + ( const MatExpr_<MatExpr_Op4_<A, B, double, int, M, MatOp_MatMul_<Mat> >, M>& a,
02176              const M& b )
02177 {
02178     typedef MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> > MatExpr_Temp;
02179     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(
02180         (M)a.e.a1, (M)a.e.a2, a.e.a3, b, 1, a.e.a4));
02181 }
02182 
02183 // C + (A*B)
02184 template<typename A, typename B, typename M> static inline
02185 MatExpr_<MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> >, M>
02186 operator + ( const M& b,
02187              const MatExpr_<MatExpr_Op4_<A, B, double, int, M, MatOp_MatMul_<Mat> >, M>& a )
02188 { return a + b; }
02189 
02190 
02191 // (A*B) - C
02192 template<typename A, typename B, typename M> static inline
02193 MatExpr_<MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> >, M>
02194 operator - ( const MatExpr_<MatExpr_Op4_<A, B, double, int, M, MatOp_MatMul_<Mat> >, M>& a,
02195              const M& b )
02196 {
02197     typedef MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> > MatExpr_Temp;
02198     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(
02199         (M)a.e.a1, (M)a.e.a2, a.e.a3, b, -1, a.e.a4));
02200 }
02201 
02202 // C - (A*B)
02203 template<typename A, typename B, typename M> static inline
02204 MatExpr_<MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> >, M>
02205 operator - ( const M& b,
02206              const MatExpr_<MatExpr_Op4_<A, B, double, int, M, MatOp_MatMul_<Mat> >, M>& a )
02207 {
02208     typedef MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> > MatExpr_Temp;
02209     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(
02210         (M)a.e.a1, (M)a.e.a2, -a.e.a3, b, 1, a.e.a4));
02211 }
02212 
02213 
02214 // (A*B) + C
02215 template<typename A, typename B, typename C, typename M> static inline
02216 MatExpr_<MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> >, M>
02217 operator + ( const MatExpr_<MatExpr_Op4_<A, B, double, int, M, MatOp_MatMul_<Mat> >, M>& a,
02218              const MatExpr_<C, M>& b )
02219 {
02220     typedef MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> > MatExpr_Temp;
02221     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(
02222         (M)a.e.a1, (M)a.e.a2, a.e.a3, (M)b, 1, a.e.a4));
02223 }
02224 
02225 // C + (A*B)
02226 template<typename A, typename B, typename C, typename M> static inline
02227 MatExpr_<MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> >, M>
02228 operator + ( const MatExpr_<C, M>& b,
02229              const MatExpr_<MatExpr_Op4_<A, B, double, int, M, MatOp_MatMul_<Mat> >, M>& a )
02230 { return a + b; }
02231 
02232 
02233 // (A*B) - C
02234 template<typename A, typename B, typename C, typename M> static inline
02235 MatExpr_<MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> >, M>
02236 operator - ( const MatExpr_<MatExpr_Op4_<A, B, double, int, M, MatOp_MatMul_<Mat> >, M>& a,
02237              const MatExpr_<C, M>& b )
02238 {
02239     typedef MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> > MatExpr_Temp;
02240     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(
02241         (M)a.e.a1, (M)a.e.a2, a.e.a3, (M)b, -1, a.e.a4));
02242 }
02243 
02244 // C - (A*B)
02245 template<typename A, typename B, typename C, typename M> static inline
02246 MatExpr_<MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> >, M>
02247 operator - ( const MatExpr_<C, M>& b,
02248              const MatExpr_<MatExpr_Op4_<A, B, double, int, M, MatOp_MatMul_<Mat> >, M>& a )
02249 {
02250     typedef MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> > MatExpr_Temp;
02251     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(
02252         (M)a.e.a1, (M)a.e.a2, -a.e.a3, (M)b, 1, a.e.a4));
02253 }
02254 
02255 
02256 // (A*B) + C*alpha
02257 template<typename A, typename B, typename C, typename M> static inline
02258 MatExpr_<MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> >, M>
02259 operator + ( const MatExpr_<MatExpr_Op4_<A, B, double, int, M, MatOp_MatMul_<Mat> >, M>& a,
02260              const MatExpr_<MatExpr_Op2_<C, double, M, MatOp_Scale_<Mat> >, M>& b )
02261 {
02262     typedef MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> > MatExpr_Temp;
02263     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(
02264         (M)a.e.a1, (M)a.e.a2, a.e.a3, (M)b.e.a1, b.e.a2, a.e.a4));
02265 }
02266 
02267 // C*alpha + (A*B)
02268 template<typename A, typename B, typename C, typename M> static inline
02269 MatExpr_<MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> >, M>
02270 operator + ( const MatExpr_<MatExpr_Op2_<C, double, M, MatOp_Scale_<Mat> >, M>& b,
02271              const MatExpr_<MatExpr_Op4_<A, B, double, int, M, MatOp_MatMul_<Mat> >, M>& a )
02272 { return a + b; }
02273 
02274 
02275 // (A*B) - (C*alpha)
02276 template<typename A, typename B, typename C, typename M> static inline
02277 MatExpr_<MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> >, M>
02278 operator - ( const MatExpr_<MatExpr_Op4_<A, B, double, int, M, MatOp_MatMul_<Mat> >, M>& a,
02279              const MatExpr_<MatExpr_Op2_<C, double, M, MatOp_Scale_<Mat> >, M>& b )
02280 {
02281     typedef MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> > MatExpr_Temp;
02282     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(
02283         (M)a.e.a1, (M)a.e.a2, a.e.a3, (M)b.e.a1, -b.e.a2, a.e.a4));
02284 }
02285 
02286 // (C*alpha) - (A*B)
02287 template<typename A, typename B, typename C, typename M> static inline
02288 MatExpr_<MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> >, M>
02289 operator - ( const MatExpr_<MatExpr_Op2_<C, double, M, MatOp_Scale_<Mat> >, M>& b,
02290              const MatExpr_<MatExpr_Op4_<A, B, double, int, M, MatOp_MatMul_<Mat> >, M>& a )
02291 {
02292     typedef MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> > MatExpr_Temp;
02293     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(
02294         (M)a.e.a1, (M)a.e.a2, -a.e.a3, (M)b.e.a1, b.e.a2, a.e.a4));
02295 }
02296 
02297 
02298 // (A*B) + C^t
02299 template<typename A, typename B, typename C, typename M> static inline
02300 MatExpr_<MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> >, M>
02301 operator + ( const MatExpr_<MatExpr_Op4_<A, B, double, int, M, MatOp_MatMul_<Mat> >, M>& a,
02302              const MatExpr_<MatExpr_Op2_<C, double, M, MatOp_T_<Mat> >, M>& b )
02303 {
02304     typedef MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> > MatExpr_Temp;
02305     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(
02306         (M)a.e.a1, (M)a.e.a2, a.e.a3, (M)b.e.a1, b.e.a2, a.e.a4 + GEMM_3_T));
02307 }
02308 
02309 // C^t + (A*B)
02310 template<typename A, typename B, typename C, typename M> static inline
02311 MatExpr_<MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> >, M>
02312 operator + ( const MatExpr_<MatExpr_Op2_<C, double, M, MatOp_T_<Mat> >, M>& b,
02313              const MatExpr_<MatExpr_Op4_<A, B, double, int, M, MatOp_MatMul_<Mat> >, M>& a )
02314 { return a + b; }
02315 
02316 
02317 // (A*B) - C^t
02318 template<typename A, typename B, typename C, typename M> static inline
02319 MatExpr_<MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> >, M>
02320 operator - ( const MatExpr_<MatExpr_Op4_<A, B, double, int, M, MatOp_MatMul_<Mat> >, M>& a,
02321              const MatExpr_<MatExpr_Op2_<C, double, M, MatOp_T_<Mat> >, M>& b )
02322 {
02323     typedef MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> > MatExpr_Temp;
02324     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(
02325         (M)a.e.a1, (M)a.e.a2, a.e.a3, (M)b.e.a1, -b.e.a2, a.e.a4+GEMM_3_T));
02326 }
02327 
02328 // C^t - (A*B)
02329 template<typename A, typename B, typename C, typename M> static inline
02330 MatExpr_<MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> >, M>
02331 operator - ( const MatExpr_<MatExpr_Op2_<C, double, M, MatOp_T_<Mat> >, M>& b,
02332              const MatExpr_<MatExpr_Op4_<A, B, double, int, M, MatOp_MatMul_<Mat> >, M>& a )
02333 {
02334     typedef MatExpr_Op6_<M, M, double, M, double, int, M, MatOp_MatMulAdd_<Mat> > MatExpr_Temp;
02335     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp(
02336         (M)a.e.a1, (M)a.e.a2, -a.e.a3, (M)b.e.a1, b.e.a2, a.e.a4+GEMM_3_T));
02337 }
02338 
02339 
02341 
02342 static inline Mat& operator += (const Mat& a, const Mat& b)
02343 {
02344     add(a, b, (Mat&)a);
02345     return (Mat&)a;
02346 }
02347 
02348 static inline Mat& operator -= (const Mat& a, const Mat& b)
02349 {
02350     subtract(a, b, (Mat&)a);
02351     return (Mat&)a;
02352 }
02353 
02354 static inline Mat& operator *= (const Mat& a, const Mat& b)
02355 {
02356     gemm(a, b, 1, Mat(), 0, (Mat&)a, 0);
02357     return (Mat&)a;
02358 }
02359 
02360 static inline Mat& operator *= (const Mat& a, double alpha)
02361 {
02362     a.convertTo((Mat&)a, -1, alpha);
02363     return (Mat&)a;
02364 }
02365 
02366 static inline Mat& operator += (const Mat& a, const Scalar& s)
02367 {
02368     add(a, s, (Mat&)a);
02369     return (Mat&)a;
02370 }
02371 
02372 static inline Mat& operator -= (const Mat& a, const Scalar& s)
02373 { return (a += -s); }
02374 
02375 template<typename _Tp> static inline
02376 Mat_<_Tp>& operator += (const Mat_<_Tp>& a, const Mat_<_Tp>& b)
02377 {
02378     (Mat&)a += (const Mat&)b;
02379     return (Mat_<_Tp>&)a;
02380 }
02381 
02382 template<typename _Tp> static inline
02383 Mat_<_Tp>& operator -= (const Mat_<_Tp>& a, const Mat_<_Tp>& b)
02384 {
02385     (Mat&)a -= (const Mat&)b;
02386     return (Mat_<_Tp>&)a;
02387 }
02388 
02389 template<typename _Tp> static inline
02390 Mat_<_Tp>& operator *= (const Mat_<_Tp>& a, const Mat_<_Tp>& b)
02391 {
02392     (Mat&)a *= (const Mat&)b;
02393     return (Mat_<_Tp>&)a;
02394 }
02395 
02396 template<typename _Tp> static inline
02397 Mat_<_Tp>& operator += (const Mat_<_Tp>& a, const Scalar& s)
02398 {
02399     (Mat&)a += s;
02400     return (Mat_<_Tp>&)a;
02401 }
02402 
02403 template<typename _Tp> static inline
02404 Mat_<_Tp>& operator -= (const Mat_<_Tp>& a, const Scalar& s)
02405 {
02406     (Mat&)a -= s;
02407     return (Mat_<_Tp>&)a;
02408 }
02409 
02410 template<typename A, typename M> static inline
02411 M& operator += (const M& a, const MatExpr_<A, M>& b)
02412 { return (a += (M)b); }
02413 
02414 template<typename A, typename M> static inline
02415 M& operator -= (const M& a, const MatExpr_<A, M>& b)
02416 { return (a -= (M)b); }
02417 
02418 template<typename A, typename M> static inline
02419 M& operator *= (const M& a, const MatExpr_<A, M>& b)
02420 { return (a *= (M)b); }
02421 
02422 template<typename A, typename M> static inline
02423 M& operator += (const M& a,
02424                 const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& b)
02425 {
02426     M& _a = (M&)a;
02427     scaleAdd( b.e.a1, b.e.a2, _a, _a );
02428     return _a;
02429 }
02430 
02431 template<typename A, typename M> static inline
02432 M& operator -= (const M& a,
02433                 const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& b)
02434 {
02435     M& _a = (M&)a;
02436     scaleAdd( b.e.a1, -b.e.a2, _a, _a );
02437     return _a;
02438 }
02439 
02440 template<typename A, typename M> static inline
02441 M& operator += (const M& a,
02442                 const MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>& b)
02443 {
02444     M& _a = (M&)a;
02445     MatOp_AddEx_<Mat>::apply( a, 1, (M)b.e.a1, b.e.a2, b.e.a3, _a );
02446     return _a;
02447 }
02448 
02449 template<typename A, typename M> static inline
02450 M& operator -= (const M& a,
02451                 const MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>& b)
02452 {
02453     M& _a = (M&)a;
02454     MatOp_AddEx_<Mat>::apply( a, 1, (M)b.e.a1, -b.e.a2, -b.e.a3, _a );
02455     return _a;
02456 }
02457 
02458 template<typename A, typename B, typename M> static inline
02459 M& operator += (const M& a,
02460                 const MatExpr_<MatExpr_Op4_<A, B, double, int, M, MatOp_MatMul_<Mat> >, M>& b)
02461 {
02462     M& _a = (M&)a;
02463     MatOp_MatMulAdd_<Mat>::apply( (M)b.e.a1, (M)b.e.a2, b.e.a3, a, 1, b.e.a4, _a );
02464     return _a;
02465 }
02466 
02467 template<typename A, typename B, typename M> static inline
02468 M& operator -= (const M& a,
02469                 const MatExpr_<MatExpr_Op4_<A, B, double, int, M, MatOp_MatMul_<Mat> >, M>& b)
02470 {
02471     M& _a = (M&)a;
02472     MatOp_MatMulAdd_<Mat>::apply( (M)b.e.a1, (M)b.e.a2, -b.e.a3, a, 1, b.e.a4, _a );
02473     return _a;
02474 }
02475 
02476 template<typename A, typename M> static inline
02477 M& operator *= (const M& a,
02478                 const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& b)
02479 {
02480     M& _a = (M&)a;
02481     MatOp_MatMul_<Mat>::apply( a, (M)b.e.a1, b.e.a2, 0, _a );
02482     return _a;
02483 }
02484 
02485 template<typename A, typename M> static inline
02486 M& operator *= (const M& a,
02487                 const MatExpr_<MatExpr_Op3_<A, double, double, M, MatOp_ScaleAddS_<Mat> >, M>& b)
02488 {
02489     M& _a = (M&)a;
02490     MatOp_MatMulAdd_<Mat>::apply( a, (M)b.e.a1, b.e.a2, a, b.e.a3, 0, _a );
02491     return _a;
02492 }
02493 
02494 template<typename A, typename M> static inline
02495 M& operator *= (const M& a,
02496                 const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_T_<Mat> >, M>& b)
02497 {
02498     M& _a = (M&)a;
02499     MatOp_MatMul_<Mat>::apply( a, (M)b.e.a1, b.e.a2, GEMM_2_T, _a );
02500     return _a;
02501 }
02502 
02504 
02505 static inline MatExpr_<MatExpr_Op3_<Mat, Mat, int, Mat, MatOp_Bin_<Mat> >, Mat>
02506 operator & (const Mat& a, const Mat& b)
02507 {
02508     typedef MatExpr_Op3_<Mat, Mat, int, Mat, MatOp_Bin_<Mat> > MatExpr_Temp;
02509     return MatExpr_<MatExpr_Temp, Mat>(MatExpr_Temp(a, b, '&'));
02510 }
02511 
02512 static inline MatExpr_<MatExpr_Op3_<Mat, Mat, int, Mat, MatOp_Bin_<Mat> >, Mat>
02513 operator | (const Mat& a, const Mat& b)
02514 {
02515     typedef MatExpr_Op3_<Mat, Mat, int, Mat, MatOp_Bin_<Mat> > MatExpr_Temp;
02516     return MatExpr_<MatExpr_Temp, Mat>(MatExpr_Temp(a, b, '|'));
02517 }
02518 
02519 static inline MatExpr_<MatExpr_Op3_<Mat, Mat, int, Mat, MatOp_Bin_<Mat> >, Mat>
02520 operator ^ (const Mat& a, const Mat& b)
02521 {
02522     typedef MatExpr_Op3_<Mat, Mat, int, Mat, MatOp_Bin_<Mat> > MatExpr_Temp;
02523     return MatExpr_<MatExpr_Temp, Mat>(MatExpr_Temp(a, b, '^'));
02524 }
02525 
02526 template<typename _Tp> static inline
02527 MatExpr_<MatExpr_Op3_<Mat, Mat, int, Mat,
02528             MatOp_Bin_<Mat> >, Mat >
02529 operator & (const Mat_<_Tp>& a, const Mat_<_Tp>& b)
02530 {
02531     typedef MatExpr_Op3_<Mat, Mat, int, Mat,
02532         MatOp_Bin_<Mat> > MatExpr_Temp;
02533     return MatExpr_<MatExpr_Temp, Mat >(MatExpr_Temp(
02534         a, b, '&'));
02535 }
02536 
02537 template<typename _Tp> static inline
02538 MatExpr_<MatExpr_Op3_<Mat, Mat, int, Mat,
02539             MatOp_Bin_<Mat> >, Mat >
02540 operator | (const Mat_<_Tp>& a, const Mat_<_Tp>& b)
02541 {
02542     typedef MatExpr_Op3_<Mat, Mat, int, Mat,
02543         MatOp_Bin_<Mat> > MatExpr_Temp;
02544     return MatExpr_<MatExpr_Temp, Mat >(MatExpr_Temp(
02545         a, b, '|'));
02546 }
02547 
02548 template<typename _Tp> static inline
02549 MatExpr_<MatExpr_Op3_<Mat, Mat, int, Mat,
02550             MatOp_Bin_<Mat> >, Mat >
02551 operator ^ (const Mat_<_Tp>& a, const Mat_<_Tp>& b)
02552 {
02553     typedef MatExpr_Op3_<Mat, Mat, int, Mat,
02554         MatOp_Bin_<Mat> > MatExpr_Temp;
02555     return MatExpr_<MatExpr_Temp, Mat >(MatExpr_Temp(
02556         a, b, '^'));
02557 }
02558 
02559 template<typename A, typename B, typename M> static inline
02560 MatExpr_<MatExpr_Op3_<M, M, int, M, MatOp_Bin_<Mat> >, M>
02561 operator & (const MatExpr_<A, M>& a, const MatExpr_<B, M>& b)
02562 { return (M)a & (M)b; }
02563 
02564 template<typename A, typename M> static inline
02565 MatExpr_<MatExpr_Op3_<M, M, int, M, MatOp_Bin_<Mat> >, M>
02566 operator & (const MatExpr_<A, M>& a, const M& b)
02567 { return (M)a & b; }
02568 
02569 template<typename A, typename M> static inline
02570 MatExpr_<MatExpr_Op3_<M, M, int, M, MatOp_Bin_<Mat> >, M>
02571 operator & (const M& a, const MatExpr_<A, M>& b)
02572 { return a & (M)b; }
02573 
02574 template<typename A, typename B, typename M> static inline
02575 MatExpr_<MatExpr_Op3_<M, M, int, M, MatOp_Bin_<Mat> >, M>
02576 operator | (const MatExpr_<A, M>& a, const MatExpr_<B, M>& b)
02577 { return (M)a | (M)b; }
02578 
02579 template<typename A, typename M> static inline
02580 MatExpr_<MatExpr_Op3_<M, M, int, M, MatOp_Bin_<Mat> >, M>
02581 operator | (const MatExpr_<A, M>& a, const M& b)
02582 { return (M)a | b; }
02583 
02584 template<typename A, typename M> static inline
02585 MatExpr_<MatExpr_Op3_<M, M, int, M, MatOp_Bin_<Mat> >, M>
02586 operator | (const M& a, const MatExpr_<A, M>& b)
02587 { return a | (M)b; }
02588 
02589 template<typename A, typename B, typename M> static inline
02590 MatExpr_<MatExpr_Op3_<M, M, int, M, MatOp_Bin_<Mat> >, M>
02591 operator ^ (const MatExpr_<A, M>& a, const MatExpr_<B, M>& b)
02592 { return (M)a ^ (M)b; }
02593 
02594 template<typename A, typename M> static inline
02595 MatExpr_<MatExpr_Op3_<M, M, int, M, MatOp_Bin_<Mat> >, M>
02596 operator ^ (const MatExpr_<A, M>& a, const M& b)
02597 { return (M)a ^ b; }
02598 
02599 template<typename A, typename M> static inline
02600 MatExpr_<MatExpr_Op3_<M, M, int, M, MatOp_Bin_<Mat> >, M>
02601 operator ^ (const M& a, const MatExpr_<A, M>& b)
02602 { return a ^ (M)b; }
02603 
02604 static inline Mat& operator &= (const Mat& a, const Mat& b)
02605 {
02606     MatOp_Bin_<Mat>::apply( a, b, '&', (Mat&)a );
02607     return (Mat&)a;
02608 }
02609 
02610 static inline Mat& operator |= (const Mat& a, const Mat& b)
02611 {
02612     MatOp_Bin_<Mat>::apply( a, b, '|', (Mat&)a );
02613     return (Mat&)a;
02614 }
02615 
02616 static inline Mat& operator ^= (const Mat& a, const Mat& b)
02617 {
02618     MatOp_Bin_<Mat>::apply( a, b, '^', (Mat&)a );
02619     return (Mat&)a;
02620 }
02621 
02622 template<typename _Tp> static inline Mat_<_Tp>&
02623 operator &= (const Mat_<_Tp>& a, const Mat_<_Tp>& b)
02624 {
02625     (Mat&)a &= (const Mat&)b;
02626     return (Mat_<_Tp>&)a;
02627 }
02628 
02629 template<typename _Tp> static inline Mat_<_Tp>&
02630 operator |= (const Mat_<_Tp>& a, const Mat_<_Tp>& b)
02631 {
02632     (Mat&)a |= (const Mat&)b;
02633     return (Mat_<_Tp>&)a;
02634 }
02635 
02636 template<typename _Tp> static inline Mat_<_Tp>&
02637 operator ^= (const Mat_<_Tp>& a, const Mat_<_Tp>& b)
02638 {
02639     (Mat&)a ^= (const Mat&)b;
02640     return (Mat_<_Tp>&)a;
02641 }
02642 
02643 template<typename A, typename M> static inline M&
02644 operator &= (const M& a, const MatExpr_<A, M>& b)
02645 { return (a &= (M)b); }
02646 
02647 template<typename A, typename M> static inline M&
02648 operator |= (const M& a, const MatExpr_<A, M>& b)
02649 { return (a |= (M)b); }
02650 
02651 template<typename A, typename M> static inline M&
02652 operator ^= (const M& a, const MatExpr_<A, M>& b)
02653 { return (a ^= (M)b); }
02654 
02655 static inline MatExpr_<MatExpr_Op3_<Mat, Scalar, int, Mat, MatOp_BinS_<Mat> >, Mat>
02656 operator & (const Mat& a, const Scalar& s)
02657 {
02658     typedef MatExpr_Op3_<Mat, Scalar, int, Mat, MatOp_BinS_<Mat> > MatExpr_Temp;
02659     return MatExpr_<MatExpr_Temp, Mat>(MatExpr_Temp(a, s, '&'));
02660 }
02661 
02662 static inline MatExpr_<MatExpr_Op3_<Mat, Scalar, int, Mat, MatOp_BinS_<Mat> >, Mat>
02663 operator & (const Scalar& s, const Mat& a)
02664 { return a & s; }
02665 
02666 static inline MatExpr_<MatExpr_Op3_<Mat, Scalar, int, Mat, MatOp_BinS_<Mat> >, Mat>
02667 operator | (const Mat& a, const Scalar& s)
02668 {
02669     typedef MatExpr_Op3_<Mat, Scalar, int, Mat, MatOp_BinS_<Mat> > MatExpr_Temp;
02670     return MatExpr_<MatExpr_Temp, Mat>(MatExpr_Temp(a, s, '|'));
02671 }
02672 
02673 static inline MatExpr_<MatExpr_Op3_<Mat, Scalar, int, Mat, MatOp_BinS_<Mat> >, Mat>
02674 operator | (const Scalar& s, const Mat& a)
02675 { return a | s; }
02676 
02677 static inline MatExpr_<MatExpr_Op3_<Mat, Scalar, int, Mat, MatOp_BinS_<Mat> >, Mat>
02678 operator ^ (const Mat& a, const Scalar& s)
02679 {
02680     typedef MatExpr_Op3_<Mat, Scalar, int, Mat, MatOp_BinS_<Mat> > MatExpr_Temp;
02681     return MatExpr_<MatExpr_Temp, Mat>(MatExpr_Temp(a, s, '^'));
02682 }
02683 
02684 static inline MatExpr_<MatExpr_Op3_<Mat, Scalar, int, Mat, MatOp_BinS_<Mat> >, Mat>
02685 operator ^ (const Scalar& s, const Mat& a)
02686 { return a ^ s; }
02687 
02688 static inline MatExpr_<MatExpr_Op3_<Mat, Scalar, int, Mat, MatOp_BinS_<Mat> >, Mat>
02689 operator ~ (const Mat& a)
02690 {
02691     typedef MatExpr_Op3_<Mat, Scalar, int, Mat, MatOp_BinS_<Mat> > MatExpr_Temp;
02692     return MatExpr_<MatExpr_Temp, Mat>(MatExpr_Temp(a, Scalar(), '~'));
02693 }
02694 
02695 template<typename _Tp> static inline
02696 MatExpr_<MatExpr_Op3_<Mat, Scalar, int, Mat, MatOp_BinS_<Mat> >, Mat >
02697 operator & (const Mat_<_Tp>& a, const Scalar& s)
02698 {
02699     typedef MatExpr_Op3_<Mat, Scalar, int, Mat, MatOp_BinS_<Mat> > MatExpr_Temp;
02700     return MatExpr_<MatExpr_Temp, Mat >(MatExpr_Temp(a, s, '&'));
02701 }
02702 
02703 template<typename _Tp> static inline
02704 MatExpr_<MatExpr_Op3_<Mat, Scalar, int, Mat, MatOp_BinS_<Mat> >, Mat >
02705 operator & (const Scalar& s, const Mat_<_Tp>& a)
02706 { return a & s; }
02707 
02708 template<typename _Tp> static inline
02709 MatExpr_<MatExpr_Op3_<Mat, Scalar, int, Mat, MatOp_BinS_<Mat> >, Mat >
02710 operator | (const Mat_<_Tp>& a, const Scalar& s)
02711 {
02712     typedef MatExpr_Op3_<Mat, Scalar, int, Mat, MatOp_BinS_<Mat> > MatExpr_Temp;
02713     return MatExpr_<MatExpr_Temp, Mat >(MatExpr_Temp(a, s, '|'));
02714 }
02715 
02716 template<typename _Tp> static inline
02717 MatExpr_<MatExpr_Op3_<Mat, Scalar, int, Mat, MatOp_BinS_<Mat> >, Mat >
02718 operator | (const Scalar& s, const Mat_<_Tp>& a)
02719 { return a | s; }
02720 
02721 template<typename _Tp> static inline
02722 MatExpr_<MatExpr_Op3_<Mat, Scalar, int, Mat, MatOp_BinS_<Mat> >, Mat >
02723 operator ^ (const Mat_<_Tp>& a, const Scalar& s)
02724 {
02725     typedef MatExpr_Op3_<Mat, Scalar, int, Mat, MatOp_BinS_<Mat> > MatExpr_Temp;
02726     return MatExpr_<MatExpr_Temp, Mat >(MatExpr_Temp(a, s, '^'));
02727 }
02728 
02729 template<typename _Tp> static inline
02730 MatExpr_<MatExpr_Op3_<Mat, Scalar, int, Mat, MatOp_BinS_<Mat> >, Mat >
02731 operator ^ (const Scalar& s, const Mat_<_Tp>& a)
02732 { return a ^ s; }
02733 
02734 template<typename _Tp> static inline
02735 MatExpr_<MatExpr_Op3_<Mat, Scalar, int, Mat, MatOp_BinS_<Mat> >, Mat >
02736 operator ~ (const Mat_<_Tp>& a)
02737 {
02738     typedef MatExpr_Op3_<Mat, Scalar, int, Mat, MatOp_BinS_<Mat> > MatExpr_Temp;
02739     return MatExpr_<MatExpr_Temp, Mat >(MatExpr_Temp(a, Scalar(), '~'));
02740 }
02741 
02742 template<typename A, typename M> static inline
02743 MatExpr_<MatExpr_Op3_<M, Scalar, int, M, MatOp_BinS_<Mat> >, M >
02744 operator & (const MatExpr_<A, M>& a, const Scalar& s)
02745 { return (M)a & s; }
02746 
02747 template<typename A, typename M> static inline
02748 MatExpr_<MatExpr_Op3_<M, Scalar, int, M, MatOp_BinS_<Mat> >, M >
02749 operator & (const Scalar& s, const MatExpr_<A, M>& a)
02750 { return (M)a & s; }
02751 
02752 template<typename A, typename M> static inline
02753 MatExpr_<MatExpr_Op3_<M, Scalar, int, M, MatOp_BinS_<Mat> >, M >
02754 operator | (const MatExpr_<A, M>& a, const Scalar& s)
02755 { return (M)a | s; }
02756 
02757 template<typename A, typename M> static inline
02758 MatExpr_<MatExpr_Op3_<M, Scalar, int, M, MatOp_BinS_<Mat> >, M >
02759 operator | (const Scalar& s, const MatExpr_<A, M>& a)
02760 { return (M)a | s; }
02761 
02762 template<typename A, typename M> static inline
02763 MatExpr_<MatExpr_Op3_<M, Scalar, int, M, MatOp_BinS_<Mat> >, M >
02764 operator ^ (const MatExpr_<A, M>& a, const Scalar& s)
02765 { return (M)a ^ s; }
02766 
02767 template<typename A, typename M> static inline
02768 MatExpr_<MatExpr_Op3_<M, Scalar, int, M, MatOp_BinS_<Mat> >, M >
02769 operator ^ (const Scalar& s, const MatExpr_<A, M>& a)
02770 { return (M)a ^ s; }
02771 
02772 template<typename A, typename M> static inline
02773 MatExpr_<MatExpr_Op3_<M, Scalar, int, M, MatOp_BinS_<Mat> >, M >
02774 operator ~ (const MatExpr_<A, M>& a)
02775 { return ~(M)a; }
02776 
02777 static inline Mat& operator &= (const Mat& a, const Scalar& s)
02778 {
02779     MatOp_BinS_<Mat>::apply( a, s, '&', (Mat&)a );
02780     return (Mat&)a;
02781 }
02782 
02783 static inline Mat& operator |= (const Mat& a, const Scalar& s)
02784 {
02785     MatOp_BinS_<Mat>::apply( a, s, '|', (Mat&)a );
02786     return (Mat&)a;
02787 }
02788 
02789 static inline Mat& operator ^= (const Mat& a, const Scalar& s)
02790 {
02791     MatOp_BinS_<Mat>::apply( a, s, '^', (Mat&)a );
02792     return (Mat&)a;
02793 }
02794 
02795 template<typename _Tp> static inline Mat_<_Tp>&
02796 operator &= (const Mat_<_Tp>& a, const Scalar& s)
02797 {
02798     (Mat&)a &= s;
02799     return (Mat_<_Tp>&)a;
02800 }
02801 
02802 template<typename _Tp> static inline Mat_<_Tp>&
02803 operator |= (const Mat_<_Tp>& a, const Scalar& s)
02804 {
02805     (Mat&)a |= s;
02806     return (Mat_<_Tp>&)a;
02807 }
02808 
02809 template<typename _Tp> static inline Mat_<_Tp>&
02810 operator ^= (const Mat_<_Tp>& a, const Scalar& s)
02811 {
02812     (Mat&)a ^= s;
02813     return (Mat_<_Tp>&)a;
02814 }
02815 
02817 
02818 static inline MatExpr_<MatExpr_Op3_<Mat, Mat, int, Mat, MatOp_Cmp_<Mat> >, Mat>
02819 operator == (const Mat& a, const Mat& b)
02820 {
02821     typedef MatExpr_Op3_<Mat, Mat, int, Mat, MatOp_Cmp_<Mat> > MatExpr_Temp;
02822     return MatExpr_<MatExpr_Temp, Mat>(MatExpr_Temp(a, b, CMP_EQ));
02823 }
02824 
02825 static inline MatExpr_<MatExpr_Op3_<Mat, Mat, int, Mat, MatOp_Cmp_<Mat> >, Mat>
02826 operator >= (const Mat& a, const Mat& b)
02827 {
02828     typedef MatExpr_Op3_<Mat, Mat, int, Mat, MatOp_Cmp_<Mat> > MatExpr_Temp;
02829     return MatExpr_<MatExpr_Temp, Mat>(MatExpr_Temp(a, b, CMP_GE));
02830 }
02831 
02832 static inline MatExpr_<MatExpr_Op3_<Mat, Mat, int, Mat, MatOp_Cmp_<Mat> >, Mat>
02833 operator > (const Mat& a, const Mat& b)
02834 {
02835     typedef MatExpr_Op3_<Mat, Mat, int, Mat, MatOp_Cmp_<Mat> > MatExpr_Temp;
02836     return MatExpr_<MatExpr_Temp, Mat>(MatExpr_Temp(a, b, CMP_GT));
02837 }
02838 
02839 static inline MatExpr_<MatExpr_Op3_<Mat, Mat, int, Mat, MatOp_Cmp_<Mat> >, Mat>
02840 operator <= (const Mat& a, const Mat& b)
02841 { return b >= a; }
02842 
02843 static inline MatExpr_<MatExpr_Op3_<Mat, Mat, int, Mat, MatOp_Cmp_<Mat> >, Mat>
02844 operator < (const Mat& a, const Mat& b)
02845 { return b > a; }
02846 
02847 static inline MatExpr_<MatExpr_Op3_<Mat, Mat, int, Mat, MatOp_Cmp_<Mat> >, Mat>
02848 operator != (const Mat& a, const Mat& b)
02849 {
02850     typedef MatExpr_Op3_<Mat, Mat, int, Mat, MatOp_Cmp_<Mat> > MatExpr_Temp;
02851     return MatExpr_<MatExpr_Temp, Mat>(MatExpr_Temp(a, b, CMP_NE));
02852 }
02853 
02854 static inline MatExpr_<MatExpr_Op3_<Mat, double, int, Mat, MatOp_CmpS_<Mat> >, Mat>
02855 operator == (const Mat& a, double alpha)
02856 {
02857     typedef MatExpr_Op3_<Mat, double, int, Mat, MatOp_CmpS_<Mat> > MatExpr_Temp;
02858     return MatExpr_<MatExpr_Temp, Mat>(MatExpr_Temp(a, alpha, CMP_EQ));
02859 }
02860 
02861 static inline MatExpr_<MatExpr_Op3_<Mat, double, int, Mat, MatOp_CmpS_<Mat> >, Mat>
02862 operator >= (const Mat& a, double alpha)
02863 {
02864     typedef MatExpr_Op3_<Mat, double, int, Mat, MatOp_CmpS_<Mat> > MatExpr_Temp;
02865     return MatExpr_<MatExpr_Temp, Mat>(MatExpr_Temp(a, alpha, CMP_GE));
02866 }
02867 
02868 static inline MatExpr_<MatExpr_Op3_<Mat, double, int, Mat, MatOp_CmpS_<Mat> >, Mat>
02869 operator > (const Mat& a, double alpha)
02870 {
02871     typedef MatExpr_Op3_<Mat, double, int, Mat, MatOp_CmpS_<Mat> > MatExpr_Temp;
02872     return MatExpr_<MatExpr_Temp, Mat>(MatExpr_Temp(a, alpha, CMP_GT));
02873 }
02874 
02875 static inline MatExpr_<MatExpr_Op3_<Mat, double, int, Mat, MatOp_CmpS_<Mat> >, Mat>
02876 operator <= (const Mat& a, double alpha)
02877 {
02878     typedef MatExpr_Op3_<Mat, double, int, Mat, MatOp_CmpS_<Mat> > MatExpr_Temp;
02879     return MatExpr_<MatExpr_Temp, Mat>(MatExpr_Temp(a, alpha, CMP_LE));
02880 }
02881 
02882 static inline MatExpr_<MatExpr_Op3_<Mat, double, int, Mat, MatOp_CmpS_<Mat> >, Mat>
02883 operator < (const Mat& a, double alpha)
02884 {
02885     typedef MatExpr_Op3_<Mat, double, int, Mat, MatOp_CmpS_<Mat> > MatExpr_Temp;
02886     return MatExpr_<MatExpr_Temp, Mat>(MatExpr_Temp(a, alpha, CMP_LT));
02887 }
02888 
02889 static inline MatExpr_<MatExpr_Op3_<Mat, double, int, Mat, MatOp_CmpS_<Mat> >, Mat>
02890 operator != (const Mat& a, double alpha)
02891 {
02892     typedef MatExpr_Op3_<Mat, double, int, Mat, MatOp_CmpS_<Mat> > MatExpr_Temp;
02893     return MatExpr_<MatExpr_Temp, Mat>(MatExpr_Temp(a, alpha, CMP_NE));
02894 }
02895 
02896 static inline MatExpr_<MatExpr_Op3_<Mat, double, int, Mat, MatOp_CmpS_<Mat> >, Mat>
02897 operator == (double alpha, const Mat& a)
02898 { return a == alpha; }
02899 
02900 static inline MatExpr_<MatExpr_Op3_<Mat, double, int, Mat, MatOp_CmpS_<Mat> >, Mat>
02901 operator >= (double alpha, const Mat& a)
02902 { return a <= alpha; }
02903 
02904 static inline MatExpr_<MatExpr_Op3_<Mat, double, int, Mat, MatOp_CmpS_<Mat> >, Mat>
02905 operator > (double alpha, const Mat& a)
02906 { return a < alpha; }
02907 
02908 static inline MatExpr_<MatExpr_Op3_<Mat, double, int, Mat, MatOp_CmpS_<Mat> >, Mat>
02909 operator <= (double alpha, const Mat& a)
02910 { return a >= alpha; }
02911 
02912 static inline MatExpr_<MatExpr_Op3_<Mat, double, int, Mat, MatOp_CmpS_<Mat> >, Mat>
02913 operator < (double alpha, const Mat& a)
02914 { return a > alpha; }
02915 
02916 static inline MatExpr_<MatExpr_Op3_<Mat, double, int, Mat, MatOp_CmpS_<Mat> >, Mat>
02917 operator != (double alpha, const Mat& a)
02918 { return a != alpha; }
02919 
02921 
02922 // max(A, B)
02923 static inline MatExpr_<MatExpr_Op3_<Mat, Mat, int, Mat, MatOp_Bin_<Mat> >, Mat>
02924 max(const Mat& a, const Mat& b)
02925 {
02926     typedef MatExpr_Op3_<Mat, Mat, int, Mat, MatOp_Bin_<Mat> > MatExpr_Temp;
02927     return MatExpr_<MatExpr_Temp, Mat>(MatExpr_Temp(a, b, 'M'));
02928 }
02929 
02930 // min(A, B)
02931 static inline MatExpr_<MatExpr_Op3_<Mat, Mat, int, Mat, MatOp_Bin_<Mat> >, Mat>
02932 min(const Mat& a, const Mat& b)
02933 {
02934     typedef MatExpr_Op3_<Mat, Mat, int, Mat, MatOp_Bin_<Mat> > MatExpr_Temp;
02935     return MatExpr_<MatExpr_Temp, Mat>(MatExpr_Temp(a, b, 'm'));
02936 }
02937 
02938 // abs(A)
02939 static inline MatExpr_<MatExpr_Op3_<Mat, Scalar, int, Mat, MatOp_BinS_<Mat> >, Mat>
02940 abs(const Mat& a)
02941 {
02942     typedef MatExpr_Op3_<Mat, Scalar, int, Mat, MatOp_BinS_<Mat> > MatExpr_Temp;
02943     return MatExpr_<MatExpr_Temp, Mat>(MatExpr_Temp(a, Scalar(0), 'a'));
02944 }
02945 
02946 // max(A, B)
02947 template<typename _Tp> static inline
02948 MatExpr_<MatExpr_Op3_<Mat, Mat, int, Mat,
02949             MatOp_Bin_<Mat> >, Mat >
02950 max(const Mat_<_Tp>& a, const Mat_<_Tp>& b)
02951 {
02952     typedef MatExpr_Op3_<Mat, Mat, int, Mat,
02953         MatOp_Bin_<Mat> > MatExpr_Temp;
02954     return MatExpr_<MatExpr_Temp, Mat >(MatExpr_Temp(
02955         a, b, 'M'));
02956 }
02957 
02958 // min(A, B)
02959 template<typename _Tp> static inline
02960 MatExpr_<MatExpr_Op3_<Mat, Mat, int, Mat,
02961             MatOp_Bin_<Mat> >, Mat >
02962 min(const Mat_<_Tp>& a, const Mat_<_Tp>& b)
02963 {
02964     typedef MatExpr_Op3_<Mat, Mat, int, Mat,
02965         MatOp_Bin_<Mat> > MatExpr_Temp;
02966     return MatExpr_<MatExpr_Temp, Mat >(MatExpr_Temp(
02967         a, b, 'm'));
02968 }
02969 
02970 // abs(A)
02971 template<typename _Tp> static inline
02972 MatExpr_<MatExpr_Op3_<Mat, Scalar, int, Mat,
02973             MatOp_BinS_<Mat> >, Mat >
02974 abs(const Mat_<_Tp>& a, const Mat_<_Tp>& b)
02975 {
02976     typedef MatExpr_Op3_<Mat, Scalar, int, Mat,
02977         MatOp_Bin_<Mat> > MatExpr_Temp;
02978     return MatExpr_<MatExpr_Temp, Mat >(MatExpr_Temp(
02979         a, Scalar(0), 'a'));
02980 }
02981 
02982 template<typename A, typename M> static inline
02983 MatExpr_<MatExpr_Op3_<M, M, int, M, MatOp_Bin_<Mat> >, M>
02984 max(const MatExpr_<A, M>& a, const M& b)
02985 { return max((M)a, b); }
02986 
02987 template<typename A, typename M> static inline
02988 MatExpr_<MatExpr_Op3_<M, M, int, M, MatOp_Bin_<Mat> >, M>
02989 max(const M& a, const MatExpr_<A, M>& b)
02990 { return max(a, (M)b); }
02991 
02992 template<typename A, typename M> static inline
02993 MatExpr_<MatExpr_Op3_<M, M, int, M, MatOp_Bin_<Mat> >, M>
02994 min(const MatExpr_<A, M>& a, const M& b)
02995 { return min((M)a, b); }
02996 
02997 template<typename A, typename M> static inline
02998 MatExpr_<MatExpr_Op3_<M, M, int, M, MatOp_Bin_<Mat> >, M>
02999 min(const M& a, const MatExpr_<A, M>& b)
03000 { return min(a, (M)b); }
03001 
03002 // abs(A)
03003 template<typename A, typename B, typename M> static inline
03004 MatExpr_<MatExpr_Op3_<M, M, int, M, MatOp_Bin_<Mat> >, M>
03005 abs(const MatExpr_<MatExpr_Op2_<A, B, M, MatOp_Sub_<Mat> >, M>& a)
03006 {
03007     typedef MatExpr_Op3_<M, M, int, M, MatOp_Bin_<Mat> > MatExpr_Temp;
03008     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp((M)a.e.a1, (M)a.e.a2, 'a'));
03009 }
03010 
03011 template<typename _Tp> void merge(const Mat_<_Tp>* mvbegin, size_t count, Mat& dst)
03012 { merge( (const Mat*)mvbegin, count, dst ); }
03013 
03014 static inline void split(const Mat& m, vector<Mat>& mv)
03015 {
03016     mv.resize(m.channels());
03017     if(m.channels() > 0)
03018         split(m, &mv[0]);
03019 }
03020     
03021 template<typename _Tp> void split(const Mat& src, vector<Mat_<_Tp> >& mv)
03022 { split(src, (vector<Mat>&)mv ); }
03023     
03024 static inline void merge(const vector<Mat>& mv, Mat& dst)
03025 { merge(&mv[0], mv.size(), dst); }
03026 
03027 static inline void mixChannels(const vector<Mat>& src, vector<Mat>& dst,
03028                                const int* fromTo, int npairs)
03029 {
03030     mixChannels(&src[0], (int)src.size(), &dst[0], (int)dst.size(), fromTo, npairs);
03031 }
03032     
03034 
03035 inline MatExpr_<MatExpr_Op4_<Mat, Mat, double, char, Mat, MatOp_MulDiv_<Mat> >, Mat>
03036 Mat::mul(const Mat& m, double scale) const
03037 {
03038     typedef MatExpr_Op4_<Mat, Mat, double, char, Mat, MatOp_MulDiv_<Mat> > MatExpr_Temp;
03039     return MatExpr_<MatExpr_Temp, Mat>(MatExpr_Temp(*this, m, scale, '*'));
03040 }
03041 
03042 inline MatExpr_<MatExpr_Op4_<Mat, Mat, double, char, Mat, MatOp_MulDiv_<Mat> >, Mat>
03043 Mat::mul(const MatExpr_<MatExpr_Op2_<Mat, double, Mat, MatOp_Scale_<Mat> >, Mat>& m, double scale) const
03044 {
03045     typedef MatExpr_Op4_<Mat, Mat, double, char, Mat, MatOp_MulDiv_<Mat> > MatExpr_Temp;
03046     return MatExpr_<MatExpr_Temp, Mat>(MatExpr_Temp(*this, m.e.a1, m.e.a2*scale, '*'));
03047 }
03048 
03049 inline MatExpr_<MatExpr_Op4_<Mat, Mat, double, char, Mat, MatOp_MulDiv_<Mat> >, Mat>
03050 Mat::mul(const MatExpr_<MatExpr_Op2_<Mat, double, Mat, MatOp_DivRS_<Mat> >, Mat>& m, double scale) const
03051 {
03052     typedef MatExpr_Op4_<Mat, Mat, double, char, Mat, MatOp_MulDiv_<Mat> > MatExpr_Temp;
03053     return MatExpr_<MatExpr_Temp, Mat>(MatExpr_Temp(*this, m.e.a1, scale/m.e.a2, '/'));
03054 }
03055 
03056 template<typename _Tp> inline
03057 MatExpr_<MatExpr_Op4_<Mat, Mat, double, char, Mat, MatOp_MulDiv_<Mat> >, Mat >
03058 Mat_<_Tp>::mul(const Mat_<_Tp>& m, double scale) const
03059 {
03060     typedef MatExpr_Op4_<Mat, Mat, double, char, Mat, MatOp_MulDiv_<Mat> > MatExpr_Temp;
03061     return MatExpr_<MatExpr_Temp, Mat >(MatExpr_Temp(*this, m, scale, '*'));
03062 }
03063 
03064 template<typename _Tp> inline
03065 MatExpr_<MatExpr_Op4_<Mat, Mat, double, char, Mat, MatOp_MulDiv_<Mat> >, Mat >
03066 Mat_<_Tp>::mul(const MatExpr_<MatExpr_Op2_<Mat, double, Mat, MatOp_Scale_<Mat> >, Mat >& m, double scale) const
03067 {
03068     typedef MatExpr_Op4_<Mat, Mat, double, char, Mat, MatOp_MulDiv_<Mat> > MatExpr_Temp;
03069     return MatExpr_<MatExpr_Temp, Mat >(MatExpr_Temp(*this, m.e.a1, m.e.a2*scale, '*'));
03070 }
03071 
03072 template<typename _Tp> inline
03073 MatExpr_<MatExpr_Op4_<Mat, Mat, double, char, Mat, MatOp_MulDiv_<Mat> >, Mat >
03074 Mat_<_Tp>::mul(const MatExpr_<MatExpr_Op2_<Mat, double, Mat, MatOp_DivRS_<Mat> >, Mat >& m, double scale) const
03075 {
03076     typedef MatExpr_Op4_<Mat, Mat, double, char, Mat, MatOp_MulDiv_<Mat> > MatExpr_Temp;
03077     return MatExpr_<MatExpr_Temp, Mat >(MatExpr_Temp(*this, m.e.a1, scale/m.e.a2, '/'));
03078 }
03079 
03080 template<typename A, typename B, typename M> static inline
03081 MatExpr_<MatExpr_Op4_<M, M, double, char, M, MatOp_MulDiv_<Mat> >, M>
03082 operator * (const MatExpr_<MatExpr_Op4_<A, B, double, char, M, MatOp_MulDiv_<Mat> >, M>& a,
03083             double alpha)
03084 {
03085     typedef MatExpr_Op4_<M, M, double, char, M, MatOp_MulDiv_<Mat> > MatExpr_Temp;
03086     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp((M)a.e.a1, (M)a.e.a2, a.e.a3*alpha, a.e.a4));
03087 }
03088 
03089 template<typename A, typename B, typename M> static inline
03090 MatExpr_<MatExpr_Op4_<M, M, double, char, M, MatOp_MulDiv_<Mat> >, M>
03091 operator * (double alpha,
03092             const MatExpr_<MatExpr_Op4_<A, B, double, char, M, MatOp_MulDiv_<Mat> >, M>& a)
03093 { return a*alpha; }
03094 
03095 
03097 
03098 static inline MatExpr_<MatExpr_Op4_<Mat, Mat, double, char, Mat, MatOp_MulDiv_<Mat> >, Mat>
03099 operator / (const Mat& a, const Mat& b)
03100 {
03101     typedef MatExpr_Op4_<Mat, Mat, double, char, Mat, MatOp_MulDiv_<Mat> > MatExpr_Temp;
03102     return MatExpr_<MatExpr_Temp, Mat>(MatExpr_Temp(a, b, 1, '/'));
03103 }
03104 
03105 template<typename _Tp> static inline
03106 MatExpr_<MatExpr_Op4_<Mat, Mat, double,
03107 char, Mat, MatOp_MulDiv_<Mat> >, Mat >
03108 operator / (const Mat& a, const Mat& b)
03109 {
03110     typedef MatExpr_Op4_<Mat, Mat, double,
03111         char, Mat, MatOp_MulDiv_<Mat> > MatExpr_Temp;
03112     return MatExpr_<MatExpr_Temp, Mat>(MatExpr_Temp(a, b, 1, '/'));
03113 }
03114 
03115 template<typename A, typename B, typename M> static inline
03116 MatExpr_<MatExpr_Op4_<M, M, double, char, M, MatOp_MulDiv_<Mat> >, M>
03117 operator / (const MatExpr_<A, M>& a, const MatExpr_<B, M>& b)
03118 { return (M)a/(M)b; }
03119 
03120 template<typename A, typename M> static inline
03121 MatExpr_<MatExpr_Op4_<M, M, double, char, M, MatOp_MulDiv_<Mat> >, M>
03122 operator / (const MatExpr_<A, M>& a, const M& b)
03123 { return (M)a/b; }
03124 
03125 template<typename A, typename M> static inline
03126 MatExpr_<MatExpr_Op4_<M, M, double, char, M, MatOp_MulDiv_<Mat> >, M>
03127 operator / (const M& a, const MatExpr_<A, M>& b)
03128 { return a/(M)b; }
03129 
03130 template<typename A, typename M> static inline
03131 MatExpr_<MatExpr_Op4_<M, M, double, char, M, MatOp_MulDiv_<Mat> >, M>
03132 operator / (const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& a,
03133             const M& b)
03134 { return ((M)a.e.a1/b)*a.e.a2; }
03135 
03136 template<typename A, typename M> static inline
03137 MatExpr_<MatExpr_Op4_<M, M, double, char, M, MatOp_MulDiv_<Mat> >, M>
03138 operator / (const M& a,
03139             const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& b)
03140 { return (a/(M)b.e.a1)*(1./b.e.a2); }
03141 
03142 template<typename A, typename B, typename M> static inline
03143 MatExpr_<MatExpr_Op4_<M, M, double, char, M, MatOp_MulDiv_<Mat> >, M>
03144 operator / (const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& a,
03145             const MatExpr_<MatExpr_Op2_<B, double, M, MatOp_Scale_<Mat> >, M>& b)
03146 { return ((M)a.e.a1/(M)b.e.a1)*(a.e.a2/b.e.a2); }
03147 
03148 template<typename A, typename M> static inline
03149 MatExpr_<MatExpr_Op4_<M, M, double, char, M, MatOp_MulDiv_<Mat> >, M>
03150 operator / (const M& a,
03151             const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_DivRS_<Mat> >, M>& b)
03152 { return a.mul((M)b.e.a1, 1./b.e.a2); }
03153 
03154 template<typename A, typename B, typename M> static inline
03155 MatExpr_<MatExpr_Op4_<M, M, double, char, M, MatOp_MulDiv_<Mat> >, M>
03156 operator / (const MatExpr_<A, M>& a,
03157             const MatExpr_<MatExpr_Op2_<B, double, M, MatOp_DivRS_<Mat> >, M>& b)
03158 { return ((M)a).mul((M)b.e.a1, 1./b.e.a2); }
03159 
03160 static inline
03161 MatExpr_<MatExpr_Op2_<Mat, double, Mat, MatOp_DivRS_<Mat> >, Mat >
03162 operator / (double alpha, const Mat& a)
03163 {
03164     typedef MatExpr_Op2_<Mat, double, Mat, MatOp_DivRS_<Mat> > MatExpr_Temp;
03165     return MatExpr_<MatExpr_Temp, Mat>(MatExpr_Temp(a, alpha));
03166 }
03167 
03168 static inline Mat& operator /= (const Mat& a, double alpha)
03169 {
03170     MatOp_Scale_<Mat>::apply( a, 1./alpha, (Mat&)a );
03171     return (Mat&)a;
03172 }
03173 
03174 template<typename _Tp>
03175 static inline Mat_<_Tp>& operator /= (const Mat_<_Tp>& a, double alpha)
03176 {
03177     MatOp_Scale_<Mat>::apply( a, 1./alpha, (Mat&)a );
03178     return (Mat_<_Tp>&)a;
03179 }
03180 
03181 template<typename _Tp> static inline
03182 MatExpr_<MatExpr_Op2_<Mat, double, Mat, MatOp_DivRS_<Mat> >, Mat >
03183 operator / (double alpha, const Mat_<_Tp>& a)
03184 {
03185     typedef MatExpr_Op2_<Mat, double, Mat,
03186         MatOp_DivRS_<Mat> > MatExpr_Temp;
03187     return MatExpr_<MatExpr_Temp, Mat >(MatExpr_Temp(a, alpha));
03188 }
03189 
03190 template<typename A, typename M> static inline
03191 MatExpr_<MatExpr_Op2_<M, double, M, MatOp_DivRS_<Mat> >, M>
03192 operator / (double alpha, const MatExpr_<A, M>& a)
03193 { return alpha/(M)a; }
03194 
03195 template<typename A, typename M> static inline
03196 MatExpr_<MatExpr_Op2_<M, double, M, MatOp_DivRS_<Mat> >, M>
03197 operator / (double alpha,
03198             const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_Scale_<Mat> >, M>& a)
03199 { return (alpha/a.e.a2)/(M)a.e.a1; }
03200 
03201 template<typename A, typename M> static inline
03202 MatExpr_<MatExpr_Op2_<M, double, M, MatOp_Scale_<Mat> >, M>
03203 operator / (double alpha,
03204             const MatExpr_<MatExpr_Op2_<A, double, M, MatOp_DivRS_<Mat> >, M>& a)
03205 { return (M)a.e.a1*(alpha/a.e.a2); }
03206 
03207 static inline Mat& operator /= (const Mat& a, const Mat& b)
03208 {
03209     MatOp_MulDiv_<Mat>::apply( a, b, 1, '/', (Mat&)a );
03210     return (Mat&)a;
03211 }
03212 
03213 template<typename A, typename M>
03214 static inline M& operator /= (const M& a, const MatExpr_<MatExpr_Op2_<A, double,
03215                               M, MatOp_Scale_<Mat> >, M>& b)
03216 {
03217     MatOp_MulDiv_<Mat>::apply( a, (M)b.e.a1, 1./b.e.a2, '/', (M&)a );
03218     return (M&)a;
03219 }
03220 
03221 template<typename A, typename M>
03222 static inline M& operator /= (const M& a, const MatExpr_<MatExpr_Op2_<A, double,
03223                               M, MatOp_DivRS_<Mat> >, M>& b)
03224 {
03225     MatOp_MulDiv_<Mat>::apply( a, (M)b.e.a1, 1./b.e.a2, '*', (M&)a );
03226     return (M&)a;
03227 }
03228 
03229 // Mat Inversion and solving linear systems
03230 
03231 inline MatExpr_<MatExpr_Op2_<Mat, int, Mat, MatOp_Inv_<Mat> >, Mat>
03232 Mat::inv(int method) const
03233 {
03234     typedef MatExpr_Op2_<Mat, int, Mat, MatOp_Inv_<Mat> > MatExpr_Temp;
03235     return MatExpr_<MatExpr_Temp, Mat>(MatExpr_Temp(*this, method));
03236 }
03237 
03238 template<typename _Tp> inline
03239 MatExpr_<MatExpr_Op2_<Mat, int, Mat, MatOp_Inv_<Mat> >, Mat >
03240 Mat_<_Tp>::inv(int method) const
03241 {
03242     typedef MatExpr_Op2_<Mat, int, Mat, MatOp_Inv_<Mat> > MatExpr_Temp;
03243     return MatExpr_<MatExpr_Temp, Mat >(MatExpr_Temp(*this, method));
03244 }
03245 
03246 template<typename A, typename M> static inline
03247 MatExpr_<MatExpr_Op3_<M, M, int, M, MatOp_Solve_<Mat> >, M>
03248 operator * (const MatExpr_<MatExpr_Op2_<A, int, M, MatOp_Inv_<Mat> >, M>& a,
03249             const M& b)
03250 {
03251     typedef MatExpr_Op3_<M, M, int, M, MatOp_Solve_<Mat> > MatExpr_Temp;
03252     return MatExpr_<MatExpr_Temp, M>(MatExpr_Temp((M)a.e.a1, b, a.e.a2));
03253 }
03254 
03255 template<typename A, typename B, typename M> static inline
03256 MatExpr_<MatExpr_Op3_<M, M, int, M, MatOp_Solve_<Mat> >, M>
03257 operator * (const MatExpr_<MatExpr_Op2_<A, int, M, MatOp_Inv_<Mat> >, M>& a,
03258             const MatExpr_<B, M>& b)
03259 { return a*(M)b; }
03260 
03261 
03263 
03264 inline MatExpr_Initializer Mat::zeros(int rows, int cols, int type)
03265 {
03266     typedef MatExpr_Op4_<Size, int, Scalar, int, Mat, MatOp_Set_<Mat> > MatExpr_Temp;
03267     return MatExpr_<MatExpr_Temp, Mat>(MatExpr_Temp(Size(cols, rows), type, 0, 0));
03268 }
03269 
03270 inline MatExpr_Initializer Mat::zeros(Size size, int type)
03271 {
03272     return zeros(size.height, size.width, type);
03273 }
03274 
03275 inline MatExpr_Initializer Mat::ones(int rows, int cols, int type)
03276 {
03277     typedef MatExpr_Op4_<Size, int, Scalar, int, Mat, MatOp_Set_<Mat> > MatExpr_Temp;
03278     return MatExpr_<MatExpr_Temp, Mat>(MatExpr_Temp(Size(cols, rows), type, 1, 1));
03279 }
03280 
03281 inline MatExpr_Initializer Mat::ones(Size size, int type)
03282 {
03283     return ones(size.height, size.width, type);
03284 }
03285 
03286 inline MatExpr_Initializer Mat::eye(int rows, int cols, int type)
03287 {
03288     typedef MatExpr_Op4_<Size, int, Scalar, int, Mat, MatOp_Set_<Mat> > MatExpr_Temp;
03289     return MatExpr_Initializer(MatExpr_Temp(Size(cols, rows), type, 1, 2));
03290 }
03291 
03292 inline MatExpr_Initializer Mat::eye(Size size, int type)
03293 {
03294     return eye(size.height, size.width, type);
03295 }
03296 
03297 static inline MatExpr_Initializer operator * (const MatExpr_Initializer& a, double alpha)
03298 {
03299     typedef MatExpr_Op4_<Size, int, Scalar, int, Mat, MatOp_Set_<Mat> > MatExpr_Temp;
03300     return MatExpr_Initializer(MatExpr_Temp(a.e.a1, a.e.a2, a.e.a3*alpha, a.e.a4));
03301 }
03302 
03303 static inline MatExpr_Initializer operator * (double alpha, MatExpr_Initializer& a)
03304 {
03305     typedef MatExpr_Op4_<Size, int, Scalar, int, Mat, MatOp_Set_<Mat> > MatExpr_Temp;
03306     return MatExpr_Initializer(MatExpr_Temp(a.e.a1, a.e.a2, a.e.a3*alpha, a.e.a4));
03307 }
03308 
03309 template<typename _Tp> inline MatExpr_Initializer Mat_<_Tp>::zeros(int rows, int cols)
03310 { return Mat::zeros(rows, cols, DataType<_Tp>::type); }
03311 
03312 template<typename _Tp> inline MatExpr_Initializer Mat_<_Tp>::zeros(Size size)
03313 { return Mat::zeros(size, DataType<_Tp>::type); }
03314 
03315 template<typename _Tp> inline MatExpr_Initializer Mat_<_Tp>::ones(int rows, int cols)
03316 { return Mat::ones(rows, cols, DataType<_Tp>::type); }
03317 
03318 template<typename _Tp> inline MatExpr_Initializer Mat_<_Tp>::ones(Size size)
03319 { return Mat::ones(size, DataType<_Tp>::type); }
03320 
03321 template<typename _Tp> inline MatExpr_Initializer Mat_<_Tp>::eye(int rows, int cols)
03322 { return Mat::eye(rows, cols, DataType<_Tp>::type); }
03323 
03324 template<typename _Tp> inline MatExpr_Initializer Mat_<_Tp>::eye(Size size)
03325 { return Mat::eye(size, DataType<_Tp>::type); }
03326 
03327 
03329 
03330 template<typename _Tp> inline MatConstIterator_<_Tp>::MatConstIterator_()
03331     : m(0), ptr(0), sliceEnd(0) {}
03332 
03333 template<typename _Tp> inline MatConstIterator_<_Tp>::MatConstIterator_(const Mat_<_Tp>* _m) : m(_m)
03334 {
03335     if( !_m )
03336         ptr = sliceEnd = 0;
03337     else
03338     {
03339         ptr = (_Tp*)_m->data;
03340         sliceEnd = ptr + (_m->isContinuous() ? _m->rows*_m->cols : _m->cols);
03341     }
03342 }
03343 
03344 template<typename _Tp> inline MatConstIterator_<_Tp>::
03345     MatConstIterator_(const Mat_<_Tp>* _m, int _row, int _col) : m(_m)
03346 {
03347     if( !_m )
03348         ptr = sliceEnd = 0;
03349     else
03350     {
03351         CV_DbgAssert( (unsigned)_row < _m->rows && (unsigned)_col < _m->cols );
03352         ptr = (_Tp*)(_m->data + _m->step*_row);
03353         sliceEnd = _m->isContinuous() ? (_Tp*)_m->data + _m->rows*_m->cols : ptr + _m->cols;
03354         ptr += _col;
03355     }
03356 }
03357 
03358 template<typename _Tp> inline MatConstIterator_<_Tp>::
03359     MatConstIterator_(const Mat_<_Tp>* _m, Point _pt) : m(_m)
03360 {
03361     if( !_m )
03362         ptr = sliceEnd = 0;
03363     else
03364     {
03365         CV_DbgAssert( (unsigned)_pt.y < (unsigned)_m->rows && (unsigned)_pt.x < (unsigned)_m->cols );
03366         ptr = (_Tp*)(_m->data + _m->step*_pt.y);
03367         sliceEnd = _m->isContinuous() ? (_Tp*)_m->data + _m->rows*_m->cols : ptr + _m->cols;
03368         ptr += _pt.x;
03369     }
03370 }
03371 
03372 template<typename _Tp> inline MatConstIterator_<_Tp>::
03373     MatConstIterator_(const MatConstIterator_& it)
03374     : m(it.m), ptr(it.ptr), sliceEnd(it.sliceEnd) {}
03375 
03376 template<typename _Tp> inline MatConstIterator_<_Tp>&
03377     MatConstIterator_<_Tp>::operator = (const MatConstIterator_& it )
03378 {
03379     m = it.m; ptr = it.ptr; sliceEnd = it.sliceEnd;
03380     return *this;
03381 }
03382 
03383 template<typename _Tp> inline _Tp MatConstIterator_<_Tp>::operator *() const { return *ptr; }
03384 
03385 template<typename _Tp> inline MatConstIterator_<_Tp>& MatConstIterator_<_Tp>::operator += (int ofs)
03386 {
03387     if( !m || ofs == 0 )
03388         return *this;
03389     ptr += ofs;
03390     if( m->isContinuous() )
03391     {
03392         if( ptr > sliceEnd )
03393             ptr = sliceEnd;
03394         else if( ptr < (_Tp*)m->data )
03395             ptr = (_Tp*)m->data;
03396     }
03397     else if( ptr >= sliceEnd || ptr < sliceEnd - m->cols )
03398     {
03399         ptr -= ofs;
03400         Point pt = pos();
03401         int cols = m->cols;
03402         ofs += pt.y*cols + pt.x;
03403         if( ofs >= cols*m->rows )
03404         {
03405             ptr = sliceEnd = (_Tp*)(m->data + m->step*(m->rows-1)) + cols; 
03406             return *this; 
03407         }
03408         else if( ofs < 0 )
03409             ofs = 0;
03410         pt.y = ofs/cols;
03411         pt.x = ofs - pt.y*cols;
03412         ptr = (_Tp*)(m->data + m->step*pt.y);
03413         sliceEnd = ptr + cols;
03414         ptr += pt.x;
03415     }
03416     return *this;
03417 }
03418 
03419 template<typename _Tp> inline MatConstIterator_<_Tp>& MatConstIterator_<_Tp>::operator -= (int ofs)
03420 { return (*this += -ofs); }
03421 
03422 template<typename _Tp> inline MatConstIterator_<_Tp>& MatConstIterator_<_Tp>::operator --()
03423 { return (*this += -1); }
03424 
03425 template<typename _Tp> inline MatConstIterator_<_Tp> MatConstIterator_<_Tp>::operator --(int)
03426 {
03427     MatConstIterator_ b = *this;
03428     *this += -1;
03429     return b;
03430 }
03431 
03432 template<typename _Tp> inline MatConstIterator_<_Tp>& MatConstIterator_<_Tp>::operator ++()
03433 {
03434     if( m && ++ptr >= sliceEnd )
03435     {
03436         --ptr;
03437         *this += 1;
03438     }
03439     return *this;
03440 }
03441 
03442 template<typename _Tp> inline MatConstIterator_<_Tp> MatConstIterator_<_Tp>::operator ++(int)
03443 {
03444     MatConstIterator_ b = *this;
03445     if( m && ++ptr >= sliceEnd )
03446     {
03447         --ptr;
03448         *this += 1;
03449     }
03450     return b;
03451 }
03452 
03453 template<typename _Tp> inline Point MatConstIterator_<_Tp>::pos() const
03454 {
03455     if( !m )
03456         return Point();
03457     if( m->isContinuous() )
03458     {
03459         ptrdiff_t ofs = ptr - (_Tp*)m->data;
03460         int y = (int)(ofs / m->cols), x = (int)(ofs - (ptrdiff_t)y*m->cols);
03461         return Point(x, y);
03462     }
03463     else
03464     {
03465         ptrdiff_t ofs = (uchar*)ptr - m->data;
03466         int y = (int)(ofs / m->step), x = (int)((ofs - y*m->step)/sizeof(_Tp));
03467         return Point(x, y);
03468     }
03469 }
03470 
03471 template<typename _Tp> inline MatIterator_<_Tp>::MatIterator_() : MatConstIterator_<_Tp>() {}
03472 
03473 template<typename _Tp> inline MatIterator_<_Tp>::MatIterator_(Mat_<_Tp>* _m)
03474     : MatConstIterator_<_Tp>(_m) {}
03475 
03476 template<typename _Tp> inline MatIterator_<_Tp>::MatIterator_(Mat_<_Tp>* _m, int _row, int _col)
03477     : MatConstIterator_<_Tp>(_m, _row, _col) {}
03478 
03479 template<typename _Tp> inline MatIterator_<_Tp>::MatIterator_(const Mat_<_Tp>* _m, Point _pt)
03480     : MatConstIterator_<_Tp>(_m, _pt) {}
03481 
03482 template<typename _Tp> inline MatIterator_<_Tp>::MatIterator_(const MatIterator_& it)
03483     : MatConstIterator_<_Tp>(it) {}
03484 
03485 template<typename _Tp> inline MatIterator_<_Tp>& MatIterator_<_Tp>::operator = (const MatIterator_<_Tp>& it )
03486 {
03487     this->m = it.m; this->ptr = it.ptr; this->sliceEnd = it.sliceEnd;
03488     return *this;
03489 }
03490 
03491 template<typename _Tp> inline _Tp& MatIterator_<_Tp>::operator *() const { return *(this->ptr); }
03492 
03493 template<typename _Tp> inline MatIterator_<_Tp>& MatIterator_<_Tp>::operator += (int ofs)
03494 {
03495     MatConstIterator_<_Tp>::operator += (ofs);
03496     return *this;
03497 }
03498 
03499 template<typename _Tp> inline MatIterator_<_Tp>& MatIterator_<_Tp>::operator -= (int ofs)
03500 {
03501     MatConstIterator_<_Tp>::operator += (-ofs);
03502     return *this;
03503 }
03504 
03505 template<typename _Tp> inline MatIterator_<_Tp>& MatIterator_<_Tp>::operator --()
03506 {
03507     MatConstIterator_<_Tp>::operator += (-1);
03508     return *this;
03509 }
03510 
03511 template<typename _Tp> inline MatIterator_<_Tp> MatIterator_<_Tp>::operator --(int)
03512 {
03513     MatIterator_ b = *this;
03514     MatConstIterator_<_Tp>::operator += (-1);
03515     return b;
03516 }
03517 
03518 template<typename _Tp> inline MatIterator_<_Tp>& MatIterator_<_Tp>::operator ++()
03519 {
03520     if( this->m && ++this->ptr >= this->sliceEnd )
03521     {
03522         --this->ptr;
03523         MatConstIterator_<_Tp>::operator += (1);
03524     }
03525     return *this;
03526 }
03527 
03528 template<typename _Tp> inline MatIterator_<_Tp> MatIterator_<_Tp>::operator ++(int)
03529 {
03530     MatIterator_ b = *this;
03531     if( this->m && ++this->ptr >= this->sliceEnd )
03532     {
03533         --this->ptr;
03534         MatConstIterator_<_Tp>::operator += (1);
03535     }
03536     return b;
03537 }
03538 
03539 template<typename _Tp> static inline bool
03540 operator == (const MatConstIterator_<_Tp>& a, const MatConstIterator_<_Tp>& b)
03541 { return a.m == b.m && a.ptr == b.ptr; }
03542 
03543 template<typename _Tp> static inline bool
03544 operator != (const MatConstIterator_<_Tp>& a, const MatConstIterator_<_Tp>& b)
03545 { return !(a == b); }
03546 
03547 template<typename _Tp> static inline bool
03548 operator < (const MatConstIterator_<_Tp>& a, const MatConstIterator_<_Tp>& b)
03549 { return a.ptr < b.ptr; }
03550 
03551 template<typename _Tp> static inline bool
03552 operator > (const MatConstIterator_<_Tp>& a, const MatConstIterator_<_Tp>& b)
03553 { return a.ptr > b.ptr; }
03554 
03555 template<typename _Tp> static inline bool
03556 operator <= (const MatConstIterator_<_Tp>& a, const MatConstIterator_<_Tp>& b)
03557 { return a.ptr <= b.ptr; }
03558 
03559 template<typename _Tp> static inline bool
03560 operator >= (const MatConstIterator_<_Tp>& a, const MatConstIterator_<_Tp>& b)
03561 { return a.ptr >= b.ptr; }
03562 
03563 template<typename _Tp> static inline int
03564 operator - (const MatConstIterator_<_Tp>& b, const MatConstIterator_<_Tp>& a)
03565 {
03566     if( a.m != b.m )
03567         return INT_MAX;
03568     if( a.sliceEnd == b.sliceEnd )
03569         return b.ptr - a.ptr;
03570     {
03571         Point ap = a.pos(), bp = b.pos();
03572         if( bp.y > ap.y )
03573             return (bp.y - ap.y - 1)*a.m->cols + (a.m->cols - ap.x) + bp.x;
03574         if( bp.y < ap.y )
03575             return -((ap.y - bp.y - 1)*a.m->cols + (a.m->cols - bp.x) + ap.x);
03576         return bp.x - ap.x;
03577     }
03578 }
03579 
03580 template<typename _Tp> static inline MatConstIterator_<_Tp>
03581 operator + (const MatConstIterator_<_Tp>& a, int ofs)
03582 { MatConstIterator_<_Tp> b = a; return b += ofs; }
03583 
03584 template<typename _Tp> static inline MatConstIterator_<_Tp>
03585 operator + (int ofs, const MatConstIterator_<_Tp>& a)
03586 { MatConstIterator_<_Tp> b = a; return b += ofs; }
03587 
03588 template<typename _Tp> static inline MatConstIterator_<_Tp>
03589 operator - (const MatConstIterator_<_Tp>& a, int ofs)
03590 { MatConstIterator_<_Tp> b = a; return b += -ofs; }
03591 
03592 template<typename _Tp> inline _Tp MatConstIterator_<_Tp>::operator [](int i) const
03593 { return *(*this + i); }
03594 
03595 template<typename _Tp> static inline MatIterator_<_Tp>
03596 operator + (const MatIterator_<_Tp>& a, int ofs)
03597 { MatIterator_<_Tp> b = a; return b += ofs; }
03598 
03599 template<typename _Tp> static inline MatIterator_<_Tp>
03600 operator + (int ofs, const MatIterator_<_Tp>& a)
03601 { MatIterator_<_Tp> b = a; return b += ofs; }
03602 
03603 template<typename _Tp> static inline MatIterator_<_Tp>
03604 operator - (const MatIterator_<_Tp>& a, int ofs)
03605 { MatIterator_<_Tp> b = a; return b += -ofs; }
03606 
03607 template<typename _Tp> inline _Tp& MatIterator_<_Tp>::operator [](int i) const
03608 { return *(*this + i); }
03609 
03610 template<typename _Tp> inline MatConstIterator_<_Tp> Mat_<_Tp>::begin() const
03611 { return Mat::begin<_Tp>(); }
03612 
03613 template<typename _Tp> inline MatConstIterator_<_Tp> Mat_<_Tp>::end() const
03614 { return Mat::end<_Tp>(); }
03615 
03616 template<typename _Tp> inline MatIterator_<_Tp> Mat_<_Tp>::begin()
03617 { return Mat::begin<_Tp>(); }
03618 
03619 template<typename _Tp> inline MatIterator_<_Tp> Mat_<_Tp>::end()
03620 { return Mat::end<_Tp>(); }
03621 
03622 template<typename _Tp> class CV_EXPORTS MatOp_Iter_
03623 {
03624 public:    
03625     MatOp_Iter_() {}
03626 
03627     static void apply(const MatIterator_<_Tp>& a, Mat& c, int type=-1)
03628     {
03629         if( type < 0 )
03630             c = *a.m;
03631         else
03632             a.m->convertTo(c, type);
03633     }
03634 };
03635 
03636 template<typename _Tp> inline MatCommaInitializer_<_Tp>::MatCommaInitializer_(Mat_<_Tp>* _m) :
03637     MatExpr_<MatExpr_Op1_<MatIterator_<_Tp>, Mat_<_Tp>,
03638         MatOp_Iter_<_Tp> >, Mat_<_Tp> >(MatIterator_<_Tp>(_m)) {}
03639 
03640 template<typename _Tp> template<typename T2> inline MatCommaInitializer_<_Tp>&
03641 MatCommaInitializer_<_Tp>::operator , (T2 v)
03642 {
03643     CV_DbgAssert( this->e.a1 < this->e.a1.m->end() );
03644     *this->e.a1 = _Tp(v); ++this->e.a1;
03645     return *this;
03646 }
03647 
03648 template<typename _Tp> inline MatCommaInitializer_<_Tp>::operator Mat_<_Tp>() const
03649 {
03650     CV_DbgAssert( this->e.a1 == this->e.a1.m->end() );
03651     return *this->e.a1.m;
03652 }
03653 
03654 template<typename _Tp> inline Mat_<_Tp> MatCommaInitializer_<_Tp>::operator *() const
03655 {
03656     CV_DbgAssert( this->e.a1 == this->e.a1.m->end() );
03657     return *this->e.a1.m;
03658 }
03659 
03660 template<typename _Tp> inline void
03661 MatCommaInitializer_<_Tp>::assignTo(Mat& m, int type) const
03662 {
03663     Mat_<_Tp>(*this).assignTo(m, type);
03664 }
03665 
03666 template<typename _Tp, typename T2> static inline MatCommaInitializer_<_Tp>
03667 operator << (const Mat_<_Tp>& m, T2 val)
03668 {
03669     MatCommaInitializer_<_Tp> commaInitializer((Mat_<_Tp>*)&m);
03670     return (commaInitializer, val);
03671 }
03672 
03674 
03675 inline MatND::MatND()
03676  : flags(MAGIC_VAL), dims(0), refcount(0), data(0), datastart(0), dataend(0)
03677 {
03678 }
03679 
03680 inline MatND::MatND(int _dims, const int* _sizes, int _type)
03681  : flags(MAGIC_VAL), dims(0), refcount(0), data(0), datastart(0), dataend(0)
03682 {
03683     create(_dims, _sizes, _type);
03684 }
03685 
03686 inline MatND::MatND(int _dims, const int* _sizes, int _type, const Scalar& _s)
03687  : flags(MAGIC_VAL), dims(0), refcount(0), data(0), datastart(0), dataend(0)
03688 {
03689     create(_dims, _sizes, _type);
03690     *this = _s;
03691 }
03692 
03693 inline MatND::MatND(const MatND& m)
03694  : flags(m.flags), dims(m.dims), refcount(m.refcount),
03695  data(m.data), datastart(m.datastart), dataend(m.dataend)
03696 {
03697     int i, d = dims;
03698     for( i = 0; i < d; i++ )
03699     {
03700         size[i] = m.size[i];
03701         step[i] = m.step[i];
03702     }
03703     if( refcount )
03704         CV_XADD(refcount, 1);
03705 }
03706 
03707 inline MatND::MatND(const Mat& m)
03708  : flags(m.flags), dims(2), refcount(m.refcount),
03709    data(m.data), datastart(m.datastart), dataend(m.dataend)
03710 {
03711     size[0] = m.rows; size[1] = m.cols;
03712     step[0] = m.step; step[1] = m.elemSize();
03713     if( refcount )
03714         CV_XADD(refcount, 1);
03715 }
03716 
03717 static inline MatND cvarrToMatND(const CvArr* arr, bool copyData=false, int coiMode=0)
03718 {
03719     if( CV_IS_MAT(arr) || CV_IS_IMAGE(arr))
03720         return MatND(cvarrToMat(arr, copyData, true, coiMode));
03721     else if( CV_IS_MATND(arr) )
03722         return MatND((const CvMatND*)arr, copyData);
03723     return MatND();
03724 }
03725 
03726 inline MatND::MatND(const CvMatND* m, bool copyData)
03727   : flags(MAGIC_VAL|(m->type & (CV_MAT_TYPE_MASK|CV_MAT_CONT_FLAG))),
03728   dims(m->dims), refcount(0), data(m->data.ptr)
03729 {
03730     int i, d = dims;
03731     for( i = 0; i < d; i++ )
03732     {
03733         size[i] = m->dim[i].size;
03734         step[i] = m->dim[i].step;
03735     }
03736     datastart = data;
03737     dataend = datastart + size[0]*step[0];
03738     if( copyData )
03739     {
03740         MatND temp(*this);
03741         temp.copyTo(*this);
03742     }
03743 }
03744 
03745 inline MatND::~MatND() { release(); }
03746 
03747 inline MatND& MatND::operator = (const MatND& m)
03748 {
03749     if( this != &m )
03750     {
03751         if( m.refcount )
03752             CV_XADD(m.refcount, 1);
03753         release();
03754         flags = m.flags;
03755         dims = m.dims;
03756         data = m.data;
03757         datastart = m.datastart;
03758         dataend = m.dataend;
03759         refcount = m.refcount;
03760         int i, d = dims;
03761         for( i = 0; i < d; i++ )
03762         {
03763             size[i] = m.size[i];
03764             step[i] = m.step[i];
03765         }
03766     }
03767     return *this;
03768 }
03769 
03770 inline MatND MatND::clone() const
03771 {
03772     MatND temp;
03773     this->copyTo(temp);
03774     return temp;
03775 }
03776 
03777 inline MatND MatND::operator()(const Range* ranges) const
03778 {
03779     return MatND(*this, ranges);
03780 }
03781 
03782 inline void MatND::assignTo( MatND& m, int type ) const
03783 {
03784     if( type < 0 )
03785         m = *this;
03786     else
03787         convertTo(m, type);
03788 }
03789 
03790 inline void MatND::addref()
03791 {
03792     if( refcount ) CV_XADD(refcount, 1);
03793 }
03794 
03795 inline void MatND::release()
03796 {
03797     if( refcount && CV_XADD(refcount, -1) == 1 )
03798         fastFree(datastart);
03799     dims = 0;
03800     data = datastart = dataend = 0;
03801     refcount = 0;
03802 }
03803 
03804 inline bool MatND::isContinuous() const { return (flags & CONTINUOUS_FLAG) != 0; }
03805 inline size_t MatND::elemSize() const { return getElemSize(flags); }
03806 inline size_t MatND::elemSize1() const { return CV_ELEM_SIZE1(flags); }
03807 inline int MatND::type() const { return CV_MAT_TYPE(flags); }
03808 inline int MatND::depth() const { return CV_MAT_DEPTH(flags); }
03809 inline int MatND::channels() const { return CV_MAT_CN(flags); }
03810 
03811 inline size_t MatND::step1(int i) const
03812 { CV_DbgAssert((unsigned)i < (unsigned)dims); return step[i]/elemSize1(); }
03813 
03814 inline uchar* MatND::ptr(int i0)
03815 {
03816     CV_DbgAssert( dims == 1 && data &&
03817         (unsigned)i0 < (unsigned)size[0] );
03818     return data + i0*step[0];
03819 }
03820 
03821 inline const uchar* MatND::ptr(int i0) const
03822 {
03823     CV_DbgAssert( dims == 1 && data &&
03824         (unsigned)i0 < (unsigned)size[0] );
03825     return data + i0*step[0];
03826 }
03827 
03828 inline uchar* MatND::ptr(int i0, int i1)
03829 {
03830     CV_DbgAssert( dims == 2 && data &&
03831         (unsigned)i0 < (unsigned)size[0] &&
03832         (unsigned)i1 < (unsigned)size[1] );
03833     return data + i0*step[0] + i1*step[1];
03834 }
03835 
03836 inline const uchar* MatND::ptr(int i0, int i1) const
03837 {
03838     CV_DbgAssert( dims == 2 && data &&
03839         (unsigned)i0 < (unsigned)size[0] &&
03840         (unsigned)i1 < (unsigned)size[1] );
03841     return data + i0*step[0] + i1*step[1];
03842 }
03843 
03844 inline uchar* MatND::ptr(int i0, int i1, int i2)
03845 {
03846     CV_DbgAssert( dims == 3 && data &&
03847         (unsigned)i0 < (unsigned)size[0] &&
03848         (unsigned)i1 < (unsigned)size[1] &&
03849         (unsigned)i2 < (unsigned)size[2] );
03850     return data + i0*step[0] + i1*step[1] + i2*step[2];
03851 }
03852 
03853 inline const uchar* MatND::ptr(int i0, int i1, int i2) const
03854 {
03855     CV_DbgAssert( dims == 3 && data &&
03856         (unsigned)i0 < (unsigned)size[0] &&
03857         (unsigned)i1 < (unsigned)size[1] &&
03858         (unsigned)i2 < (unsigned)size[2] );
03859     return data + i0*step[0] + i1*step[1] + i2*step[2];
03860 }
03861 
03862 inline uchar* MatND::ptr(const int* idx)
03863 {
03864     int i, d = dims;
03865     uchar* p = data;
03866     CV_DbgAssert( data );
03867     for( i = 0; i < d; i++ )
03868     {
03869         CV_DbgAssert( (unsigned)idx[i] < (unsigned)size[i] );
03870         p += idx[i]*step[i];
03871     }
03872     return p;
03873 }
03874 
03875 inline const uchar* MatND::ptr(const int* idx) const
03876 {
03877     int i, d = dims;
03878     uchar* p = data;
03879     CV_DbgAssert( data );
03880     for( i = 0; i < d; i++ )
03881     {
03882         CV_DbgAssert( (unsigned)idx[i] < (unsigned)size[i] );
03883         p += idx[i]*step[i];
03884     }
03885     return p;
03886 }
03887 
03888 template<typename _Tp> inline _Tp& MatND::at(int i0)
03889 { return *(_Tp*)ptr(i0); }
03890 template<typename _Tp> inline const _Tp& MatND::at(int i0) const
03891 { return *(const _Tp*)ptr(i0); }
03892 template<typename _Tp> inline _Tp& MatND::at(int i0, int i1)
03893 { return *(_Tp*)ptr(i0, i1); }
03894 template<typename _Tp> inline const _Tp& MatND::at(int i0, int i1) const
03895 { return *(const _Tp*)ptr(i0, i1); }
03896 template<typename _Tp> inline _Tp& MatND::at(int i0, int i1, int i2)
03897 { return *(_Tp*)ptr(i0, i1, i2); }
03898 template<typename _Tp> inline const _Tp& MatND::at(int i0, int i1, int i2) const
03899 { return *(const _Tp*)ptr(i0, i1, i2); }
03900 template<typename _Tp> inline _Tp& MatND::at(const int* idx)
03901 { return *(_Tp*)ptr(idx); }
03902 template<typename _Tp> inline const _Tp& MatND::at(const int* idx) const
03903 { return *(const _Tp*)ptr(idx); }
03904 
03905 inline NAryMatNDIterator::NAryMatNDIterator()
03906 {
03907 }
03908 
03909 inline void subtract(const MatND& a, const Scalar& s, MatND& c, const MatND& mask=MatND())
03910 {
03911     add(a, -s, c, mask);
03912 }
03913 
03914 
03915 template<typename _Tp> inline MatND_<_Tp>::MatND_()
03916 {
03917     flags = MAGIC_VAL | DataType<_Tp>::type;
03918 }
03919 
03920 template<typename _Tp> inline MatND_<_Tp>::MatND_(int _dims, const int* _sizes)
03921 : MatND(_dims, _sizes, DataType<_Tp>::type)
03922 {
03923 }
03924 
03925 template<typename _Tp> inline MatND_<_Tp>::MatND_(int _dims, const int* _sizes, const _Tp& _s)
03926 : MatND(_dims, _sizes, DataType<_Tp>::type, Scalar(_s))
03927 {
03928 }
03929 
03930 template<typename _Tp> inline MatND_<_Tp>::MatND_(const MatND& m)
03931 {
03932     if( m.type() == DataType<_Tp>::type )
03933         *this = (const MatND_<_Tp>&)m;
03934     else
03935         m.convertTo(this, DataType<_Tp>::type);
03936 }
03937 
03938 template<typename _Tp> inline MatND_<_Tp>::MatND_(const MatND_<_Tp>& m) : MatND(m)
03939 {
03940 }
03941 
03942 template<typename _Tp> inline MatND_<_Tp>::MatND_(const MatND_<_Tp>& m, const Range* ranges)
03943 : MatND(m, ranges)
03944 {
03945 }
03946 
03947 template<typename _Tp> inline MatND_<_Tp>::MatND_(const CvMatND* m, bool copyData)
03948 {
03949     *this = MatND(m, copyData || CV_MAT_TYPE(m->type) != DataType<_Tp>::type);
03950 }
03951 
03952 template<typename _Tp> inline MatND_<_Tp>& MatND_<_Tp>::operator = (const MatND& m)
03953 {
03954     if( DataType<_Tp>::type == m.type() )
03955     {
03956         Mat::operator = (m);
03957         return *this;
03958     }
03959     if( DataType<_Tp>::depth == m.depth() )
03960     {
03961         return (*this = m.reshape(DataType<_Tp>::channels));
03962     }
03963     CV_DbgAssert(DataType<_Tp>::channels == m.channels());
03964     m.convertTo(*this, DataType<_Tp>::type);
03965     return *this;
03966 }
03967 
03968 template<typename _Tp> inline MatND_<_Tp>& MatND_<_Tp>::operator = (const MatND_<_Tp>& m)
03969 {
03970     return ((MatND&)*this = m);
03971 }
03972 
03973 template<typename _Tp> inline MatND_<_Tp>& MatND_<_Tp>::operator = (const _Tp& s)
03974 {
03975     return (MatND&)*this = Scalar(s);
03976 }
03977 
03978 template<typename _Tp> inline void MatND_<_Tp>::create(int _dims, const int* _sizes)
03979 {
03980     MatND::create(_dims, _sizes, DataType<_Tp>::type);
03981 }
03982 
03983 template<typename _Tp> template<typename _Tp2> inline MatND_<_Tp>::operator MatND_<_Tp2>() const
03984 {
03985     return MatND_<_Tp2>((const MatND&)*this);
03986 }
03987 
03988 template<typename _Tp> inline MatND_<_Tp> MatND_<_Tp>::clone() const
03989 {
03990     MatND_<_Tp> temp;
03991     this->copyTo(temp);
03992     return temp;
03993 }
03994 
03995 template<typename _Tp> inline MatND_<_Tp>
03996 MatND_<_Tp>::operator()(const Range* ranges) const
03997 { return MatND_<_Tp>(*this, ranges); }
03998 
03999 template<typename _Tp> inline size_t MatND_<_Tp>::elemSize() const
04000 { return CV_ELEM_SIZE(DataType<_Tp>::type); }
04001 
04002 template<typename _Tp> inline size_t MatND_<_Tp>::elemSize1() const
04003 { return CV_ELEM_SIZE1(DataType<_Tp>::type); }
04004 
04005 template<typename _Tp> inline int MatND_<_Tp>::type() const
04006 { return DataType<_Tp>::type; }
04007 
04008 template<typename _Tp> inline int MatND_<_Tp>::depth() const
04009 { return DataType<_Tp>::depth; }
04010 
04011 template<typename _Tp> inline int MatND_<_Tp>::channels() const
04012 { return DataType<_Tp>::channels; }
04013 
04014 template<typename _Tp> inline size_t MatND_<_Tp>::stepT(int i) const
04015 {
04016     CV_DbgAssert( (unsigned)i < (unsigned)dims );
04017     return step[i]/elemSize();
04018 }
04019 
04020 template<typename _Tp> inline size_t MatND_<_Tp>::step1(int i) const
04021 {
04022     CV_DbgAssert( (unsigned)i < (unsigned)dims );
04023     return step[i]/elemSize1();
04024 }
04025 
04026 template<typename _Tp> inline _Tp& MatND_<_Tp>::operator ()(const int* idx)
04027 {
04028     uchar* ptr = data;
04029     int i, d = dims;
04030     for( i = 0; i < d; i++ )
04031     {
04032         int ii = idx[i];
04033         CV_DbgAssert( (unsigned)ii < (unsigned)size[i] );
04034         ptr += ii*step[i];
04035     }
04036     return *(_Tp*)ptr;
04037 }
04038 
04039 template<typename _Tp> inline const _Tp& MatND_<_Tp>::operator ()(const int* idx) const
04040 {
04041     const uchar* ptr = data;
04042     int i, d = dims;
04043     for( i = 0; i < d; i++ )
04044     {
04045         int ii = idx[i];
04046         CV_DbgAssert( (unsigned)ii < (unsigned)size[i] );
04047         ptr += ii*step[i];
04048     }
04049     return *(const _Tp*)ptr;
04050 }
04051 
04052 template<typename _Tp> inline _Tp& MatND_<_Tp>::operator ()(int i0)
04053 {
04054     CV_DbgAssert( dims == 1 &&
04055                  (unsigned)i0 < (unsigned)size[0] );
04056     
04057     return *(_Tp*)(data + i0*step[0]);
04058 }
04059 
04060 template<typename _Tp> inline const _Tp& MatND_<_Tp>::operator ()(int i0) const
04061 {
04062     CV_DbgAssert( dims == 1 &&
04063                  (unsigned)i0 < (unsigned)size[0] );
04064     
04065     return *(const _Tp*)(data + i0*step[0]);
04066 }
04067     
04068     
04069 template<typename _Tp> inline _Tp& MatND_<_Tp>::operator ()(int i0, int i1)
04070 {
04071     CV_DbgAssert( dims == 2 &&
04072                  (unsigned)i0 < (unsigned)size[0] &&
04073                  (unsigned)i1 < (unsigned)size[1] );
04074     
04075     return *(_Tp*)(data + i0*step[0] + i1*step[1]);
04076 }
04077 
04078 template<typename _Tp> inline const _Tp& MatND_<_Tp>::operator ()(int i0, int i1) const
04079 {
04080     CV_DbgAssert( dims == 2 &&
04081                  (unsigned)i0 < (unsigned)size[0] &&
04082                  (unsigned)i1 < (unsigned)size[1] );
04083     
04084     return *(const _Tp*)(data + i0*step[0] + i1*step[1]);
04085 }
04086     
04087     
04088 template<typename _Tp> inline _Tp& MatND_<_Tp>::operator ()(int i0, int i1, int i2)
04089 {
04090     CV_DbgAssert( dims == 3 &&
04091         (unsigned)i0 < (unsigned)size[0] &&
04092         (unsigned)i1 < (unsigned)size[1] &&
04093         (unsigned)i2 < (unsigned)size[2] );
04094 
04095     return *(_Tp*)(data + i0*step[0] + i1*step[1] + i2*step[2]);
04096 }
04097 
04098 template<typename _Tp> inline const _Tp& MatND_<_Tp>::operator ()(int i0, int i1, int i2) const
04099 {
04100     CV_DbgAssert( dims == 3 &&
04101         (unsigned)i0 < (unsigned)size[0] &&
04102         (unsigned)i1 < (unsigned)size[1] &&
04103         (unsigned)i2 < (unsigned)size[2] );
04104 
04105     return *(const _Tp*)(data + i0*step[0] + i1*step[1] + i2*step[2]);
04106 }
04107 
04108     
04109 static inline void merge(const vector<MatND>& mv, MatND& dst)
04110 {
04111     merge(&mv[0], mv.size(), dst);
04112 }
04113     
04114 static inline void split(const MatND& m, vector<MatND>& mv)
04115 {
04116     mv.resize(m.channels());
04117     if(m.channels() > 0)
04118         split(m, &mv[0]);
04119 }
04120 
04121 static inline void mixChannels(const vector<MatND>& src, vector<MatND>& dst,
04122                                const int* fromTo, int npairs)
04123 {
04124     mixChannels(&src[0], (int)src.size(), &dst[0], (int)dst.size(), fromTo, npairs);
04125 }   
04126 
04128 
04129 inline SparseMat::SparseMat()
04130 : flags(MAGIC_VAL), hdr(0)
04131 {
04132 }
04133 
04134 inline SparseMat::SparseMat(int _dims, const int* _sizes, int _type)
04135 : flags(MAGIC_VAL), hdr(0)
04136 {
04137     create(_dims, _sizes, _type);
04138 }
04139 
04140 inline SparseMat::SparseMat(const SparseMat& m)
04141 : flags(m.flags), hdr(m.hdr)
04142 {
04143     addref();
04144 }
04145 
04146 inline SparseMat::~SparseMat()
04147 {
04148     release();
04149 }
04150 
04151 inline SparseMat& SparseMat::operator = (const SparseMat& m)
04152 {
04153     if( this != &m )
04154     {
04155         if( m.hdr )
04156             CV_XADD(&m.hdr->refcount, 1);
04157         release();
04158         flags = m.flags;
04159         hdr = m.hdr;
04160     }
04161     return *this;
04162 }
04163 
04164 inline SparseMat& SparseMat::operator = (const Mat& m)
04165 { return (*this = SparseMat(m)); }
04166 
04167 inline SparseMat& SparseMat::operator = (const MatND& m)
04168 { return (*this = SparseMat(m)); }
04169 
04170 inline SparseMat SparseMat::clone() const
04171 {
04172     SparseMat temp;
04173     this->copyTo(temp);
04174     return temp;
04175 }
04176 
04177 
04178 inline void SparseMat::assignTo( SparseMat& m, int type ) const
04179 {
04180     if( type < 0 )
04181         m = *this;
04182     else
04183         convertTo(m, type);
04184 }
04185 
04186 inline void SparseMat::addref()
04187 { if( hdr ) CV_XADD(&hdr->refcount, 1); }
04188 
04189 inline void SparseMat::release()
04190 {
04191     if( hdr && CV_XADD(&hdr->refcount, -1) == 1 )
04192         delete hdr;
04193     hdr = 0;
04194 }
04195 
04196 inline size_t SparseMat::elemSize() const
04197 { return CV_ELEM_SIZE(flags); }
04198 
04199 inline size_t SparseMat::elemSize1() const
04200 { return CV_ELEM_SIZE1(flags); }
04201 
04202 inline int SparseMat::type() const
04203 { return CV_MAT_TYPE(flags); }
04204 
04205 inline int SparseMat::depth() const
04206 { return CV_MAT_DEPTH(flags); }
04207 
04208 inline int SparseMat::channels() const
04209 { return CV_MAT_CN(flags); }
04210 
04211 inline const int* SparseMat::size() const
04212 {
04213     return hdr ? hdr->size : 0;
04214 }
04215 
04216 inline int SparseMat::size(int i) const
04217 {
04218     if( hdr )
04219     {
04220         CV_DbgAssert((unsigned)i < (unsigned)hdr->dims);
04221         return hdr->size[i];
04222     }
04223     return 0;
04224 }
04225 
04226 inline int SparseMat::dims() const
04227 {
04228     return hdr ? hdr->dims : 0;
04229 }
04230 
04231 inline size_t SparseMat::nzcount() const
04232 {
04233     return hdr ? hdr->nodeCount : 0;
04234 }
04235 
04236 inline size_t SparseMat::hash(int i0) const
04237 {
04238     return (size_t)i0;
04239 }
04240 
04241 inline size_t SparseMat::hash(int i0, int i1) const
04242 {
04243     return (size_t)(unsigned)i0*HASH_SCALE + (unsigned)i1;
04244 }
04245 
04246 inline size_t SparseMat::hash(int i0, int i1, int i2) const
04247 {
04248     return ((size_t)(unsigned)i0*HASH_SCALE + (unsigned)i1)*HASH_SCALE + (unsigned)i2;
04249 }
04250 
04251 inline size_t SparseMat::hash(const int* idx) const
04252 {
04253     size_t h = (unsigned)idx[0];
04254     if( !hdr )
04255         return 0;
04256     int i, d = hdr->dims;
04257     for( i = 1; i < d; i++ )
04258         h = h*HASH_SCALE + (unsigned)idx[i];
04259     return h;
04260 }
04261 
04262 template<typename _Tp> inline _Tp& SparseMat::ref(int i0, size_t* hashval)
04263 { return *(_Tp*)((SparseMat*)this)->ptr(i0, true, hashval); }
04264     
04265 template<typename _Tp> inline _Tp& SparseMat::ref(int i0, int i1, size_t* hashval)
04266 { return *(_Tp*)((SparseMat*)this)->ptr(i0, i1, true, hashval); }
04267 
04268 template<typename _Tp> inline _Tp& SparseMat::ref(int i0, int i1, int i2, size_t* hashval)
04269 { return *(_Tp*)((SparseMat*)this)->ptr(i0, i1, i2, true, hashval); }
04270 
04271 template<typename _Tp> inline _Tp& SparseMat::ref(const int* idx, size_t* hashval)
04272 { return *(_Tp*)((SparseMat*)this)->ptr(idx, true, hashval); }
04273 
04274 template<typename _Tp> inline _Tp SparseMat::value(int i0, size_t* hashval) const
04275 {
04276     const _Tp* p = (const _Tp*)((SparseMat*)this)->ptr(i0, false, hashval);
04277     return p ? *p : _Tp();
04278 }    
04279     
04280 template<typename _Tp> inline _Tp SparseMat::value(int i0, int i1, size_t* hashval) const
04281 {
04282     const _Tp* p = (const _Tp*)((SparseMat*)this)->ptr(i0, i1, false, hashval);
04283     return p ? *p : _Tp();
04284 }
04285 
04286 template<typename _Tp> inline _Tp SparseMat::value(int i0, int i1, int i2, size_t* hashval) const
04287 {
04288     const _Tp* p = (const _Tp*)((SparseMat*)this)->ptr(i0, i1, i2, false, hashval);
04289     return p ? *p : _Tp();
04290 }
04291 
04292 template<typename _Tp> inline _Tp SparseMat::value(const int* idx, size_t* hashval) const
04293 {
04294     const _Tp* p = (const _Tp*)((SparseMat*)this)->ptr(idx, false, hashval);
04295     return p ? *p : _Tp();
04296 }
04297 
04298 template<typename _Tp> inline const _Tp* SparseMat::find(int i0, size_t* hashval) const
04299 { return (const _Tp*)((SparseMat*)this)->ptr(i0, false, hashval); }
04300     
04301 template<typename _Tp> inline const _Tp* SparseMat::find(int i0, int i1, size_t* hashval) const
04302 { return (const _Tp*)((SparseMat*)this)->ptr(i0, i1, false, hashval); }
04303 
04304 template<typename _Tp> inline const _Tp* SparseMat::find(int i0, int i1, int i2, size_t* hashval) const
04305 { return (const _Tp*)((SparseMat*)this)->ptr(i0, i1, i2, false, hashval); }
04306 
04307 template<typename _Tp> inline const _Tp* SparseMat::find(const int* idx, size_t* hashval) const
04308 { return (const _Tp*)((SparseMat*)this)->ptr(idx, false, hashval); }
04309 
04310 template<typename _Tp> inline _Tp& SparseMat::value(Node* n)
04311 { return *(_Tp*)((uchar*)n + hdr->valueOffset); }
04312 
04313 template<typename _Tp> inline const _Tp& SparseMat::value(const Node* n) const
04314 { return *(const _Tp*)((const uchar*)n + hdr->valueOffset); }
04315 
04316 inline SparseMat::Node* SparseMat::node(size_t nidx)
04317 { return (Node*)&hdr->pool[nidx]; }
04318 
04319 inline const SparseMat::Node* SparseMat::node(size_t nidx) const
04320 { return (const Node*)&hdr->pool[nidx]; }
04321 
04322 inline SparseMatIterator SparseMat::begin()
04323 { return SparseMatIterator(this); }
04324 
04325 inline SparseMatConstIterator SparseMat::begin() const
04326 { return SparseMatConstIterator(this); }
04327 
04328 inline SparseMatIterator SparseMat::end()
04329 { SparseMatIterator it(this); it.seekEnd(); return it; }
04330     
04331 inline SparseMatConstIterator SparseMat::end() const
04332 { SparseMatConstIterator it(this); it.seekEnd(); return it; }
04333     
04334 template<typename _Tp> inline SparseMatIterator_<_Tp> SparseMat::begin()
04335 { return SparseMatIterator_<_Tp>(this); }
04336     
04337 template<typename _Tp> inline SparseMatConstIterator_<_Tp> SparseMat::begin() const
04338 { return SparseMatConstIterator_<_Tp>(this); }
04339     
04340 template<typename _Tp> inline SparseMatIterator_<_Tp> SparseMat::end()
04341 { SparseMatIterator_<_Tp> it(this); it.seekEnd(); return it; }
04342 
04343 template<typename _Tp> inline SparseMatConstIterator_<_Tp> SparseMat::end() const
04344 { SparseMatConstIterator_<_Tp> it(this); it.seekEnd(); return it; }
04345     
04346     
04347 inline SparseMatConstIterator::SparseMatConstIterator()
04348 : m(0), hashidx(0), ptr(0)
04349 {
04350 }
04351 
04352 inline SparseMatConstIterator::SparseMatConstIterator(const SparseMatConstIterator& it)
04353 : m(it.m), hashidx(it.hashidx), ptr(it.ptr)
04354 {
04355 }
04356 
04357 static inline bool operator == (const SparseMatConstIterator& it1, const SparseMatConstIterator& it2)
04358 { return it1.m == it2.m && it1.hashidx == it2.hashidx && it1.ptr == it2.ptr; }
04359 
04360 static inline bool operator != (const SparseMatConstIterator& it1, const SparseMatConstIterator& it2)
04361 { return !(it1 == it2); }
04362 
04363 
04364 inline SparseMatConstIterator& SparseMatConstIterator::operator = (const SparseMatConstIterator& it)
04365 {
04366     if( this != &it )
04367     {
04368         m = it.m;
04369         hashidx = it.hashidx;
04370         ptr = it.ptr;
04371     }
04372     return *this;
04373 }
04374 
04375 template<typename _Tp> inline const _Tp& SparseMatConstIterator::value() const
04376 { return *(_Tp*)ptr; }
04377 
04378 inline const SparseMat::Node* SparseMatConstIterator::node() const
04379 {
04380     return ptr && m && m->hdr ?
04381         (const SparseMat::Node*)(ptr - m->hdr->valueOffset) : 0;
04382 }
04383 
04384 inline SparseMatConstIterator SparseMatConstIterator::operator ++(int)
04385 {
04386     SparseMatConstIterator it = *this;
04387     ++*this;
04388     return it;
04389 }
04390 
04391     
04392 inline void SparseMatConstIterator::seekEnd()
04393 {
04394     if( m && m->hdr )
04395     {
04396         hashidx = m->hdr->hashtab.size();
04397         ptr = 0;
04398     }
04399 }
04400     
04401 inline SparseMatIterator::SparseMatIterator()
04402 {}
04403 
04404 inline SparseMatIterator::SparseMatIterator(SparseMat* _m)
04405 : SparseMatConstIterator(_m)
04406 {}
04407 
04408 inline SparseMatIterator::SparseMatIterator(const SparseMatIterator& it)
04409 : SparseMatConstIterator(it)
04410 {
04411 }
04412 
04413 inline SparseMatIterator& SparseMatIterator::operator = (const SparseMatIterator& it)
04414 {
04415     (SparseMatConstIterator&)*this = it;
04416     return *this;
04417 }
04418 
04419 template<typename _Tp> inline _Tp& SparseMatIterator::value() const
04420 { return *(_Tp*)ptr; }
04421 
04422 inline SparseMat::Node* SparseMatIterator::node() const
04423 {
04424     return (SparseMat::Node*)SparseMatConstIterator::node();
04425 }
04426 
04427 inline SparseMatIterator& SparseMatIterator::operator ++()
04428 {
04429     SparseMatConstIterator::operator ++();
04430     return *this;
04431 }
04432 
04433 inline SparseMatIterator SparseMatIterator::operator ++(int)
04434 {
04435     SparseMatIterator it = *this;
04436     ++*this;
04437     return it;
04438 }
04439 
04440 
04441 template<typename _Tp> inline SparseMat_<_Tp>::SparseMat_()
04442 { flags = MAGIC_VAL | DataType<_Tp>::type; }
04443 
04444 template<typename _Tp> inline SparseMat_<_Tp>::SparseMat_(int _dims, const int* _sizes)
04445 : SparseMat(_dims, _sizes, DataType<_Tp>::type)
04446 {}
04447 
04448 template<typename _Tp> inline SparseMat_<_Tp>::SparseMat_(const SparseMat& m)
04449 {
04450     if( m.type() == DataType<_Tp>::type )
04451         *this = (const SparseMat_<_Tp>&)m;
04452     else
04453         m.convertTo(this, DataType<_Tp>::type);
04454 }
04455 
04456 template<typename _Tp> inline SparseMat_<_Tp>::SparseMat_(const SparseMat_<_Tp>& m)
04457 {
04458     this->flags = m.flags;
04459     this->hdr = m.hdr;
04460     if( this->hdr )
04461         CV_XADD(&this->hdr->refcount, 1);
04462 }
04463 
04464 template<typename _Tp> inline SparseMat_<_Tp>::SparseMat_(const Mat& m)
04465 {
04466     SparseMat sm(m);
04467     *this = sm;
04468 }
04469 
04470 template<typename _Tp> inline SparseMat_<_Tp>::SparseMat_(const MatND& m)
04471 {
04472     SparseMat sm(m);
04473     *this = sm;
04474 }
04475 
04476 template<typename _Tp> inline SparseMat_<_Tp>::SparseMat_(const CvSparseMat* m)
04477 {
04478     SparseMat sm(m);
04479     *this = sm;
04480 }
04481 
04482 template<typename _Tp> inline SparseMat_<_Tp>&
04483 SparseMat_<_Tp>::operator = (const SparseMat_<_Tp>& m)
04484 {
04485     if( this != &m )
04486     {
04487         if( m.hdr ) CV_XADD(&m.hdr->refcount, 1);
04488         release();
04489         flags = m.flags;
04490         hdr = m.hdr;
04491     }
04492     return *this;
04493 }
04494 
04495 template<typename _Tp> inline SparseMat_<_Tp>&
04496 SparseMat_<_Tp>::operator = (const SparseMat& m)
04497 {
04498     if( m.type() == DataType<_Tp>::type )
04499         return (*this = (const SparseMat_<_Tp>&)m);
04500     m.convertTo(*this, DataType<_Tp>::type);
04501     return *this;
04502 }
04503 
04504 template<typename _Tp> inline SparseMat_<_Tp>&
04505 SparseMat_<_Tp>::operator = (const Mat& m)
04506 { return (*this = SparseMat(m)); }
04507 
04508 template<typename _Tp> inline SparseMat_<_Tp>&
04509 SparseMat_<_Tp>::operator = (const MatND& m)
04510 { return (*this = SparseMat(m)); }
04511 
04512 template<typename _Tp> inline SparseMat_<_Tp>
04513 SparseMat_<_Tp>::clone() const
04514 {
04515     SparseMat_<_Tp> m;
04516     this->copyTo(m);
04517     return m;
04518 }
04519 
04520 template<typename _Tp> inline void
04521 SparseMat_<_Tp>::create(int _dims, const int* _sizes)
04522 {
04523     SparseMat::create(_dims, _sizes, DataType<_Tp>::type);
04524 }
04525 
04526 template<typename _Tp> inline
04527 SparseMat_<_Tp>::operator CvSparseMat*() const
04528 {
04529     return SparseMat::operator CvSparseMat*();
04530 }
04531 
04532 template<typename _Tp> inline int SparseMat_<_Tp>::type() const
04533 { return DataType<_Tp>::type; }
04534 
04535 template<typename _Tp> inline int SparseMat_<_Tp>::depth() const
04536 { return DataType<_Tp>::depth; }
04537 
04538 template<typename _Tp> inline int SparseMat_<_Tp>::channels() const
04539 { return DataType<_Tp>::channels; }
04540 
04541 template<typename _Tp> inline _Tp&
04542 SparseMat_<_Tp>::ref(int i0, size_t* hashval)
04543 { return SparseMat::ref<_Tp>(i0, hashval); }
04544 
04545 template<typename _Tp> inline _Tp
04546 SparseMat_<_Tp>::operator()(int i0, size_t* hashval) const
04547 { return SparseMat::value<_Tp>(i0, hashval); }    
04548     
04549 template<typename _Tp> inline _Tp&
04550 SparseMat_<_Tp>::ref(int i0, int i1, size_t* hashval)
04551 { return SparseMat::ref<_Tp>(i0, i1, hashval); }
04552 
04553 template<typename _Tp> inline _Tp
04554 SparseMat_<_Tp>::operator()(int i0, int i1, size_t* hashval) const
04555 { return SparseMat::value<_Tp>(i0, i1, hashval); }
04556 
04557 template<typename _Tp> inline _Tp&
04558 SparseMat_<_Tp>::ref(int i0, int i1, int i2, size_t* hashval)
04559 { return SparseMat::ref<_Tp>(i0, i1, i2, hashval); }
04560 
04561 template<typename _Tp> inline _Tp
04562 SparseMat_<_Tp>::operator()(int i0, int i1, int i2, size_t* hashval) const
04563 { return SparseMat::value<_Tp>(i0, i1, i2, hashval); }
04564 
04565 template<typename _Tp> inline _Tp&
04566 SparseMat_<_Tp>::ref(const int* idx, size_t* hashval)
04567 { return SparseMat::ref<_Tp>(idx, hashval); }
04568 
04569 template<typename _Tp> inline _Tp
04570 SparseMat_<_Tp>::operator()(const int* idx, size_t* hashval) const
04571 { return SparseMat::value<_Tp>(idx, hashval); }
04572 
04573 template<typename _Tp> inline SparseMatIterator_<_Tp> SparseMat_<_Tp>::begin()
04574 { return SparseMatIterator_<_Tp>(this); }
04575 
04576 template<typename _Tp> inline SparseMatConstIterator_<_Tp> SparseMat_<_Tp>::begin() const
04577 { return SparseMatConstIterator_<_Tp>(this); }
04578 
04579 template<typename _Tp> inline SparseMatIterator_<_Tp> SparseMat_<_Tp>::end()
04580 { SparseMatIterator_<_Tp> it(this); it.seekEnd(); return it; }
04581     
04582 template<typename _Tp> inline SparseMatConstIterator_<_Tp> SparseMat_<_Tp>::end() const
04583 { SparseMatConstIterator_<_Tp> it(this); it.seekEnd(); return it; }
04584 
04585 template<typename _Tp> inline
04586 SparseMatConstIterator_<_Tp>::SparseMatConstIterator_()
04587 {}
04588 
04589 template<typename _Tp> inline
04590 SparseMatConstIterator_<_Tp>::SparseMatConstIterator_(const SparseMat_<_Tp>* _m)
04591 : SparseMatConstIterator(_m)
04592 {}
04593 
04594 template<typename _Tp> inline
04595 SparseMatConstIterator_<_Tp>::SparseMatConstIterator_(const SparseMatConstIterator_<_Tp>& it)
04596 : SparseMatConstIterator(it)
04597 {}
04598 
04599 template<typename _Tp> inline SparseMatConstIterator_<_Tp>&
04600 SparseMatConstIterator_<_Tp>::operator = (const SparseMatConstIterator_<_Tp>& it)
04601 { return ((SparseMatConstIterator&)*this = it); }
04602 
04603 template<typename _Tp> inline const _Tp&
04604 SparseMatConstIterator_<_Tp>::operator *() const
04605 { return *(const _Tp*)this->ptr; }
04606 
04607 template<typename _Tp> inline SparseMatConstIterator_<_Tp>&
04608 SparseMatConstIterator_<_Tp>::operator ++()
04609 {
04610     SparseMatConstIterator::operator ++();
04611     return *this;
04612 }
04613 
04614 template<typename _Tp> inline SparseMatConstIterator_<_Tp>
04615 SparseMatConstIterator_<_Tp>::operator ++(int)
04616 {
04617     SparseMatConstIterator it = *this;
04618     SparseMatConstIterator::operator ++();
04619     return it;
04620 }
04621 
04622 template<typename _Tp> inline
04623 SparseMatIterator_<_Tp>::SparseMatIterator_()
04624 {}
04625 
04626 template<typename _Tp> inline
04627 SparseMatIterator_<_Tp>::SparseMatIterator_(SparseMat_<_Tp>* _m)
04628 : SparseMatConstIterator_<_Tp>(_m)
04629 {}
04630 
04631 template<typename _Tp> inline
04632 SparseMatIterator_<_Tp>::SparseMatIterator_(const SparseMatIterator_<_Tp>& it)
04633 : SparseMatConstIterator_<_Tp>(it)
04634 {}
04635 
04636 template<typename _Tp> inline SparseMatIterator_<_Tp>&
04637 SparseMatIterator_<_Tp>::operator = (const SparseMatIterator_<_Tp>& it)
04638 { return ((SparseMatIterator&)*this = it); }
04639 
04640 template<typename _Tp> inline _Tp&
04641 SparseMatIterator_<_Tp>::operator *() const
04642 { return *(_Tp*)this->ptr; }
04643 
04644 template<typename _Tp> inline SparseMatIterator_<_Tp>&
04645 SparseMatIterator_<_Tp>::operator ++()
04646 {
04647     SparseMatConstIterator::operator ++();
04648     return *this;
04649 }
04650 
04651 template<typename _Tp> inline SparseMatIterator_<_Tp>
04652 SparseMatIterator_<_Tp>::operator ++(int)
04653 {
04654     SparseMatIterator it = *this;
04655     SparseMatConstIterator::operator ++();
04656     return it;
04657 }
04658     
04659 }
04660 
04661 #endif
04662 #endif