diff --git a/modules/core/include/opencv2/core/core.hpp b/modules/core/include/opencv2/core/core.hpp index 51dc082079..0103fc573f 100644 --- a/modules/core/include/opencv2/core/core.hpp +++ b/modules/core/include/opencv2/core/core.hpp @@ -86,23 +86,8 @@ typedef std::basic_string WString; class Mat; class MatND; -template class CV_EXPORTS MatExpr_Base_; -typedef MatExpr_Base_ MatExpr_Base; -template class MatExpr_; -template class MatExpr_Op1_; -template class MatExpr_Op2_; -template class MatExpr_Op3_; -template class MatExpr_Op4_; -template class MatExpr_Op5_; -template class CV_EXPORTS MatOp_DivRS_; -template class CV_EXPORTS MatOp_Inv_; -template class CV_EXPORTS MatOp_MulDiv_; -template class CV_EXPORTS MatOp_Repeat_; -template class CV_EXPORTS MatOp_Set_; -template class CV_EXPORTS MatOp_Scale_; -template class CV_EXPORTS MatOp_T_; +class CV_EXPORTS MatExpr; +class CV_EXPORTS MatOp_Base; template class CV_EXPORTS MatIterator_; template class CV_EXPORTS MatConstIterator_; @@ -928,7 +913,11 @@ public: //! another helper conversion method. \see cvScalarToRawData template void convertTo(T2* buf, int channels, int unroll_to=0) const; + // returns (v0, -v1, -v2, -v3) Scalar_<_Tp> conj() const; + + // returns true iff v1 == v2 == v3 == 0 + bool isReal() const; }; typedef Scalar_ Scalar; @@ -1244,9 +1233,6 @@ protected: //////////////////////////////// Mat //////////////////////////////// -typedef MatExpr_ >, Mat> MatExpr_Initializer; - enum { MAGIC_MASK=0xFFFF0000, TYPE_MASK=0x00000FFF, DEPTH_MASK=7 }; static inline size_t getElemSize(int type) { return CV_ELEM_SIZE(type); } @@ -1500,15 +1486,11 @@ public: template explicit Mat(const Point3_<_Tp>& pt); //! builds matrix from comma initializer template explicit Mat(const MatCommaInitializer_<_Tp>& commaInitializer); - //! helper constructor to compile matrix expressions - Mat(const MatExpr_Base& expr); //! destructor - calls release() ~Mat(); //! assignment operators Mat& operator = (const Mat& m); - Mat& operator = (const MatExpr_Base& expr); - - operator MatExpr_() const; + Mat& operator = (const MatExpr& expr); //! returns a new matrix header for the specified row Mat row(int y) const; @@ -1549,18 +1531,12 @@ public: Mat reshape(int _cn, int _rows=0) const; //! matrix transposition by means of matrix expressions - MatExpr_ >, Mat> - t() const; + MatExpr t() const; //! matrix inversion by means of matrix expressions - MatExpr_ >, Mat> - inv(int method=DECOMP_LU) const; - MatExpr_ >, Mat> + MatExpr inv(int method=DECOMP_LU) const; //! per-element matrix multiplication by means of matrix expressions - mul(const Mat& m, double scale=1) const; - MatExpr_ >, Mat> - mul(const MatExpr_ >, Mat>& m, double scale=1) const; - MatExpr_ >, Mat> - mul(const MatExpr_ >, Mat>& m, double scale=1) const; + MatExpr mul(const Mat& m, double scale=1) const; + MatExpr mul(const MatExpr& m, double scale=1) const; //! computes cross-product of 2 3D vectors Mat cross(const Mat& m) const; @@ -1568,12 +1544,12 @@ public: double dot(const Mat& m) const; //! Matlab-style matrix initialization - static MatExpr_Initializer zeros(int rows, int cols, int type); - static MatExpr_Initializer zeros(Size size, int type); - static MatExpr_Initializer ones(int rows, int cols, int type); - static MatExpr_Initializer ones(Size size, int type); - static MatExpr_Initializer eye(int rows, int cols, int type); - static MatExpr_Initializer eye(Size size, int type); + static MatExpr zeros(int rows, int cols, int type); + static MatExpr zeros(Size size, int type); + static MatExpr ones(int rows, int cols, int type); + static MatExpr ones(Size size, int type); + static MatExpr eye(int rows, int cols, int type); + static MatExpr eye(Size size, int type); //! allocates new matrix data unless the matrix already has specified size and type. // previous data is unreferenced if needed. @@ -2301,8 +2277,6 @@ public: Mat_(const Mat_& m, const Range& rowRange, const Range& colRange); //! selects a submatrix Mat_(const Mat_& m, const Rect& roi); - //! to support complex matrix expressions - Mat_(const MatExpr_Base& expr); //! makes a matrix out of Vec, std::vector, Point_ or Point3_. The matrix will have a single column explicit Mat_(const vector<_Tp>& vec, bool copyData=false); template explicit Mat_(const Vec<_Tp, n>& vec, bool copyData=true); @@ -2329,7 +2303,7 @@ public: //! cross-product Mat_ cross(const Mat_& m) const; //! to support complex matrix expressions - Mat_& operator = (const MatExpr_Base& expr); + Mat_& operator = (const MatExpr& expr); //! data type conversion template operator Mat_() const; //! overridden forms of Mat::row() etc. @@ -2338,19 +2312,6 @@ public: Mat_ diag(int d=0) const; Mat_ clone() const; - //! transposition, inversion, per-element multiplication - MatExpr_ >, Mat> t() const; - MatExpr_ >, Mat> inv(int method=DECOMP_LU) const; - - MatExpr_ >, Mat> - mul(const Mat_& m, double scale=1) const; - MatExpr_ >, Mat> - mul(const MatExpr_ >, Mat>& m, double scale=1) const; - MatExpr_ >, Mat> - mul(const MatExpr_ >, Mat>& m, double scale=1) const; - //! overridden forms of Mat::elemSize() etc. size_t elemSize() const; size_t elemSize1() const; @@ -2362,12 +2323,12 @@ public: size_t stepT() const; //! overridden forms of Mat::zeros() etc. Data type is omitted, of course - static MatExpr_Initializer zeros(int rows, int cols); - static MatExpr_Initializer zeros(Size size); - static MatExpr_Initializer ones(int rows, int cols); - static MatExpr_Initializer ones(Size size); - static MatExpr_Initializer eye(int rows, int cols); - static MatExpr_Initializer eye(Size size); + static MatExpr zeros(int rows, int cols); + static MatExpr zeros(Size size); + static MatExpr ones(int rows, int cols); + static MatExpr ones(Size size); + static MatExpr eye(int rows, int cols); + static MatExpr eye(Size size); //! some more overriden methods Mat_ reshape(int _rows) const; @@ -2386,9 +2347,6 @@ public: _Tp& operator ()(int i); const _Tp& operator ()(int i) const; - //! to support matrix expressions - operator MatExpr_() const; - //! conversion to vector. operator vector<_Tp>() const; //! conversion to Vec @@ -2541,8 +2499,7 @@ template class CV_EXPORTS MatOp_Iter_; Mat R = (Mat_(2,2) << a, -b, b, a); \endcode */ -template class CV_EXPORTS MatCommaInitializer_ : - public MatExpr_, Mat_<_Tp>, MatOp_Iter_<_Tp> >, Mat_<_Tp> > +template class CV_EXPORTS MatCommaInitializer_ { public: //! the constructor, created by "matrix << firstValue" operator, where matrix is cv::Mat @@ -2553,7 +2510,10 @@ public: //operator Mat_<_Tp>() const; //! another form of conversion operator Mat_<_Tp> operator *() const; - void assignTo(Mat& m, int type=-1) const; + operator Mat_<_Tp>() const; + virtual void assignTo(Mat& m, int type=-1) const; +protected: + MatIterator_<_Tp> it; }; diff --git a/modules/core/include/opencv2/core/mat.hpp b/modules/core/include/opencv2/core/mat.hpp index 1d715e0bfd..40cf91f81e 100644 --- a/modules/core/include/opencv2/core/mat.hpp +++ b/modules/core/include/opencv2/core/mat.hpp @@ -317,7 +317,7 @@ inline Mat& Mat::operator = (const Mat& m) } return *this; } - + inline Mat Mat::row(int y) const { return Mat(*this, Range(y, y+1), Range::all()); } inline Mat Mat::col(int x) const { return Mat(*this, Range::all(), Range(x, x+1)); } inline Mat Mat::rowRange(int startrow, int endrow) const @@ -943,2248 +943,469 @@ process( const Mat_& m1, const Mat_& m2, Mat_& m3, Op op ) } } -template class CV_EXPORTS MatExpr_Base_ -{ + +class CV_EXPORTS MatOp +{ public: - MatExpr_Base_() {} - virtual ~MatExpr_Base_() {} - virtual void assignTo(M& m, int type=-1) const = 0; + MatOp() {}; + virtual ~MatOp() {}; + + virtual bool elementWise(const MatExpr& expr) const; + virtual void assign(const MatExpr& expr, Mat& m, int type=-1) const = 0; + virtual void roi(const MatExpr& expr, const Range& rowRange, + const Range& colRange, MatExpr& res) const; + virtual void diag(const MatExpr& expr, int d, MatExpr& res) const; + virtual void augAssignAdd(const MatExpr& expr, Mat& m) const; + virtual void augAssignSubtract(const MatExpr& expr, Mat& m) const; + virtual void augAssignMultiply(const MatExpr& expr, Mat& m) const; + virtual void augAssignDivide(const MatExpr& expr, Mat& m) const; + virtual void augAssignAnd(const MatExpr& expr, Mat& m) const; + virtual void augAssignOr(const MatExpr& expr, Mat& m) const; + virtual void augAssignXor(const MatExpr& expr, Mat& m) const; + + virtual void add(const MatExpr& expr1, const MatExpr& expr2, MatExpr& res) const; + virtual void add(const MatExpr& expr1, const Scalar& s, MatExpr& res) const; + + virtual void subtract(const MatExpr& expr1, const MatExpr& expr2, MatExpr& res) const; + virtual void subtract(const Scalar& s, const MatExpr& expr, MatExpr& res) const; + + virtual void multiply(const MatExpr& expr1, const MatExpr& expr2, MatExpr& res, double scale=1) const; + virtual void multiply(const MatExpr& expr1, double s, MatExpr& res) const; + + virtual void divide(const MatExpr& expr1, const MatExpr& expr2, MatExpr& res, double scale=1) const; + virtual void divide(double s, const MatExpr& expr, MatExpr& res) const; + + virtual void abs(const MatExpr& expr, MatExpr& res) const; + + virtual void transpose(const MatExpr& expr, MatExpr& res) const; + virtual void matmul(const MatExpr& expr1, const MatExpr& expr2, MatExpr& res) const; + virtual void invert(const MatExpr& expr, int method, MatExpr& res) const; }; -template class CV_EXPORTS MatExpr_ : public MatExpr_Base_ + +class CV_EXPORTS MatExpr { public: - MatExpr_(const E& _e) : e(_e) {} - ~MatExpr_() {} - operator M() const { return (M)e; } - void assignTo(M& m, int type=-1) const { e.assignTo(m, type); } - - M row(int y) const { return ((M)e).row(y); } - M col(int x) const { return ((M)e).col(x); } - M diag(int d=0) const { return ((M)e).diag(d); } - - M operator()( const Range& rowRange, const Range& colRange ) const - { return ((M)e)(rowRange, colRange); } - M operator()( const Rect& roi ) const { return ((M)e)(roi); } - - M cross(const M& m) const { return ((M)e).cross(m); } - double dot(const M& m) const { return ((M)e).dot(m); } - - MatExpr_ >, M> t() const - { return ((M)e).t(); } - MatExpr_ >, M> inv(int method=DECOMP_LU) const - { return ((M)e).inv(method); } - - MatExpr_ >, M> - mul(const M& m, double scale=1) const - { return ((M)e).mul(m, scale); } - template MatExpr_ >, M > - mul(const MatExpr_& m, double scale=1) const - { return ((M)e).mul(m, scale); } - - E e; + MatExpr() : op(0), flags(0), a(Mat()), b(Mat()), c(Mat()), alpha(0), beta(0), s(Scalar()) {} + MatExpr(const MatOp* _op, int _flags, const Mat& _a=Mat(), const Mat& _b=Mat(), + const Mat& _c=Mat(), double _alpha=1, double _beta=1, const Scalar& _s=Scalar()) + : op(_op), flags(_flags), a(_a), b(_b), c(_c), alpha(_alpha), beta(_beta), s(_s) {} + explicit MatExpr(const Mat& m); + operator Mat() const + { + Mat m; + op->assign(*this, m); + return m; + } + + template operator Mat_<_Tp>() const + { + Mat_<_Tp> m; + op->assign(*this, m, DataType<_Tp>::type); + return m; + } + + MatExpr row(int y) const; + MatExpr col(int x) const; + MatExpr diag(int d=0) const; + MatExpr operator()( const Range& rowRange, const Range& colRange ) const; + MatExpr operator()( const Rect& roi ) const; + + Mat cross(const Mat& m) const; + double dot(const Mat& m) const; + + MatExpr t() const; + MatExpr inv(int method = DECOMP_LU) const; + MatExpr mul(const MatExpr& e, double scale=1) const; + MatExpr mul(const Mat& m, double scale=1) const; + + const MatOp* op; + int flags; + + Mat a, b, c; + double alpha, beta; + Scalar s; }; + + +CV_EXPORTS MatExpr operator + (const Mat& a, const Mat& b); +CV_EXPORTS MatExpr operator + (const Mat& a, const Scalar& s); +CV_EXPORTS MatExpr operator + (const Scalar& s, const Mat& a); +CV_EXPORTS MatExpr operator + (const MatExpr& e, const Mat& m); +CV_EXPORTS MatExpr operator + (const Mat& m, const MatExpr& e); +CV_EXPORTS MatExpr operator + (const MatExpr& e, const Scalar& s); +CV_EXPORTS MatExpr operator + (const Scalar& s, const MatExpr& e); +CV_EXPORTS MatExpr operator + (const MatExpr& e1, const MatExpr& e2); + +CV_EXPORTS MatExpr operator - (const Mat& a, const Mat& b); +CV_EXPORTS MatExpr operator - (const Mat& a, const Scalar& s); +CV_EXPORTS MatExpr operator - (const Scalar& s, const Mat& a); +CV_EXPORTS MatExpr operator - (const MatExpr& e, const Mat& m); +CV_EXPORTS MatExpr operator - (const Mat& m, const MatExpr& e); +CV_EXPORTS MatExpr operator - (const MatExpr& e, const Scalar& s); +CV_EXPORTS MatExpr operator - (const Scalar& s, const MatExpr& e); +CV_EXPORTS MatExpr operator - (const MatExpr& e1, const MatExpr& e2); + +CV_EXPORTS MatExpr operator - (const Mat& m); +CV_EXPORTS MatExpr operator - (const MatExpr& e); + +CV_EXPORTS MatExpr operator * (const Mat& a, const Mat& b); +CV_EXPORTS MatExpr operator * (const Mat& a, double s); +CV_EXPORTS MatExpr operator * (double s, const Mat& a); +CV_EXPORTS MatExpr operator * (const MatExpr& e, const Mat& m); +CV_EXPORTS MatExpr operator * (const Mat& m, const MatExpr& e); +CV_EXPORTS MatExpr operator * (const MatExpr& e, double s); +CV_EXPORTS MatExpr operator * (double s, const MatExpr& e); +CV_EXPORTS MatExpr operator * (const MatExpr& e1, const MatExpr& e2); + +CV_EXPORTS MatExpr operator / (const Mat& a, const Mat& b); +CV_EXPORTS MatExpr operator / (const Mat& a, double s); +CV_EXPORTS MatExpr operator / (double s, const Mat& a); +CV_EXPORTS MatExpr operator / (const MatExpr& e, const Mat& m); +CV_EXPORTS MatExpr operator / (const Mat& m, const MatExpr& e); +CV_EXPORTS MatExpr operator / (const MatExpr& e, double s); +CV_EXPORTS MatExpr operator / (double s, const MatExpr& e); +CV_EXPORTS MatExpr operator / (const MatExpr& e1, const MatExpr& e2); + +CV_EXPORTS MatExpr operator < (const Mat& a, const Mat& b); +CV_EXPORTS MatExpr operator < (const Mat& a, double s); +CV_EXPORTS MatExpr operator < (double s, const Mat& a); + +CV_EXPORTS MatExpr operator <= (const Mat& a, const Mat& b); +CV_EXPORTS MatExpr operator <= (const Mat& a, double s); +CV_EXPORTS MatExpr operator <= (double s, const Mat& a); + +CV_EXPORTS MatExpr operator == (const Mat& a, const Mat& b); +CV_EXPORTS MatExpr operator == (const Mat& a, double s); +CV_EXPORTS MatExpr operator == (double s, const Mat& a); + +CV_EXPORTS MatExpr operator != (const Mat& a, const Mat& b); +CV_EXPORTS MatExpr operator != (const Mat& a, double s); +CV_EXPORTS MatExpr operator != (double s, const Mat& a); + +CV_EXPORTS MatExpr operator >= (const Mat& a, const Mat& b); +CV_EXPORTS MatExpr operator >= (const Mat& a, double s); +CV_EXPORTS MatExpr operator >= (double s, const Mat& a); + +CV_EXPORTS MatExpr operator > (const Mat& a, const Mat& b); +CV_EXPORTS MatExpr operator > (const Mat& a, double s); +CV_EXPORTS MatExpr operator > (double s, const Mat& a); + +CV_EXPORTS MatExpr min(const Mat& a, const Mat& b); +CV_EXPORTS MatExpr min(const Mat& a, double s); +CV_EXPORTS MatExpr min(double s, const Mat& a); +CV_EXPORTS MatExpr max(const Mat& a, const Mat& b); +CV_EXPORTS MatExpr max(const Mat& a, double s); +CV_EXPORTS MatExpr max(double s, const Mat& a); -inline Mat::Mat(const MatExpr_Base& expr) - : flags(0), rows(0), cols(0), step(0), data(0), refcount(0), datastart(0), dataend(0) +template static inline MatExpr min(const Mat_<_Tp>& a, const Mat_<_Tp>& b) { - expr.assignTo(*this); + return cv::min((const Mat&)a, (const Mat&)b); } -inline Mat& Mat::operator = (const MatExpr_Base& expr) +template static inline MatExpr min(const Mat_<_Tp>& a, double s) { - expr.assignTo(*this); - return *this; + return cv::min((const Mat&)a, s); } -template inline Mat_<_Tp>::Mat_(const MatExpr_Base& e) : Mat() +template static inline MatExpr min(double s, const Mat_<_Tp>& a) { - e.assignTo(*this, DataType<_Tp>::type); -} + return cv::min((const Mat&)a, s); +} -template inline Mat_<_Tp>& Mat_<_Tp>::operator = (const MatExpr_Base& e) +template static inline MatExpr max(const Mat_<_Tp>& a, const Mat_<_Tp>& b) { - e.assignTo(*this, DataType<_Tp>::type); - return *this; + return cv::max((const Mat&)a, (const Mat&)b); } -template inline Mat_<_Tp>::operator MatExpr_() const -{ return MatExpr_(*this); } - -inline Mat::operator MatExpr_() const -{ return MatExpr_(*this); } - -template class CV_EXPORTS MatOp_Sub_ +template static inline MatExpr max(const Mat_<_Tp>& a, double s) { -public: - MatOp_Sub_() {} - - static void apply(const M& a, const M& b, M& c, int type=-1) - { - if( type == a.type() || type < 0 ) - { - subtract( a, b, c ); - } - else - { - Mat temp; - apply(a, b, temp); - temp.convertTo(c, type); - } - } -}; + return cv::max((const Mat&)a, s); +} -template class CV_EXPORTS MatOp_Scale_ +template static inline MatExpr max(double s, const Mat_<_Tp>& a) { -public: - MatOp_Scale_() {} + return cv::max((const Mat&)a, s); +} + +CV_EXPORTS MatExpr operator & (const Mat& a, const Mat& b); +CV_EXPORTS MatExpr operator & (const Mat& a, const Scalar& s); +CV_EXPORTS MatExpr operator & (const Scalar& s, const Mat& a); - static void apply(const M& a, double alpha, M& c, int type=-1) - { - a.convertTo(c, type, alpha, 0); - } -}; +CV_EXPORTS MatExpr operator | (const Mat& a, const Mat& b); +CV_EXPORTS MatExpr operator | (const Mat& a, const Scalar& s); +CV_EXPORTS MatExpr operator | (const Scalar& s, const Mat& a); -template class CV_EXPORTS MatOp_ScaleAddS_ -{ -public: - MatOp_ScaleAddS_() {} +CV_EXPORTS MatExpr operator ^ (const Mat& a, const Mat& b); +CV_EXPORTS MatExpr operator ^ (const Mat& a, const Scalar& s); +CV_EXPORTS MatExpr operator ^ (const Scalar& s, const Mat& a); - static void apply(const M& a, double alpha, double beta, M& c, int type=-1) - { - a.convertTo(c, type, alpha, beta); - } -}; +CV_EXPORTS MatExpr operator ~(const Mat& m); + +CV_EXPORTS MatExpr abs(const Mat& m); +CV_EXPORTS MatExpr abs(const MatExpr& e); + +template static inline MatExpr abs(const Mat_<_Tp>& m) +{ + return cv::abs((const Mat&)m); +} -template class CV_EXPORTS MatOp_AddS_ +////////////////////////////// Augmenting algebraic operations ////////////////////////////////// + +inline Mat& Mat::operator = (const MatExpr& e) { -public: - MatOp_AddS_() {} + e.op->assign(e, *this); + return *this; +} - static void apply(const M& a, const Scalar& s, M& c, int type=-1) - { - if( type == a.type() || type < 0 ) - { - add(a, s, c); - } - else - { - Mat temp; - apply(a, s, temp); - temp.convertTo(c, type); - } - } -}; +template Mat_<_Tp>& Mat_<_Tp>::operator = (const MatExpr& e) +{ + e.op->assign(e, *this, DataType<_Tp>::type); + return *this; +} -template class CV_EXPORTS MatOp_AddEx_ +static inline Mat& operator += (const Mat& a, const Mat& b) { -public: - MatOp_AddEx_() {} + add(a, b, (Mat&)a); + return (Mat&)a; +} - static void apply(const M& a, double alpha, const M& b, - double beta, double gamma, M& c, int type=-1) - { - if( type == a.type() || type < 0 ) - { - addWeighted(a, alpha, b, beta, gamma, c); - } - else - { - Mat temp; - apply(a, alpha, b, beta, gamma, temp); - temp.convertTo(c, type); - } - } -}; +static inline Mat& operator += (const Mat& a, const Scalar& s) +{ + add(a, s, (Mat&)a); + return (Mat&)a; +} -template class CV_EXPORTS MatOp_Bin_ +template static inline +Mat_<_Tp>& operator += (const Mat_<_Tp>& a, const Mat_<_Tp>& b) { -public: - MatOp_Bin_() {} + add(a, b, (Mat&)a); + return (Mat_<_Tp>&)a; +} - static void apply(const M& a, const M& b, int _op, M& c, int type=-1) - { - char op = (char)_op; - if( type == a.type() || type < 0 ) - { - if( op == '&' ) - bitwise_and( a, b, c ); - else if( op == '|' ) - bitwise_or( a, b, c ); - else if( op == '^' ) - bitwise_xor( a, b, c ); - else if( op == 'm' ) - min( a, b, c ); - else if( op == 'M' ) - max( a, b, c ); - else if( op == 'a' ) - absdiff( a, b, c ); - else - assert(0); - } - else - { - Mat temp; - apply(a, b, op, temp); - temp.convertTo(c, type); - } - } -}; +template static inline +Mat_<_Tp>& operator += (const Mat_<_Tp>& a, const Scalar& s) +{ + add(a, s, (Mat&)a); + return (Mat_<_Tp>&)a; +} -template class CV_EXPORTS MatOp_BinS_ +static inline Mat& operator += (const Mat& a, const MatExpr& b) { -public: - MatOp_BinS_() {} + b.op->augAssignAdd(b, (Mat&)a); + return (Mat&)a; +} - static void apply(const M& a, const Scalar& s, int _op, M& c, int type=-1) - { - char op = (char)_op; - if( type == a.type() || type < 0 ) - { - if( op == '&' ) - bitwise_and( a, s, c ); - else if( op == '|' ) - bitwise_or( a, s, c ); - else if( op == '^' ) - bitwise_xor( a, s, c ); - else if( op == 'm' ) - min( a, s[0], c ); - else if( op == 'M' ) - max( a, s[0], c ); - else if( op == 'a' ) - absdiff( a, s, c ); - else if( op == '~' ) - bitwise_not( a, c ); - else - assert(0); - } - else - { - Mat temp; - apply(a, s, op, temp); - temp.convertTo(c, type); - } - } -}; +template static inline +Mat_<_Tp>& operator += (const Mat_<_Tp>& a, const MatExpr& b) +{ + b.op->augAssignAdd(b, (Mat&)a); + return (Mat_<_Tp>&)a; +} + +static inline Mat& operator -= (const Mat& a, const Mat& b) +{ + subtract(a, b, (Mat&)a); + return (Mat&)a; +} -template class CV_EXPORTS MatOp_T_ +static inline Mat& operator -= (const Mat& a, const Scalar& s) { -public: - MatOp_T_() {} + subtract(a, s, (Mat&)a); + return (Mat&)a; +} - static void apply(const M& a, double scale, M& c, int type=-1) - { - if( type == a.type() || type < 0 ) - { - transpose(a, c); - if( fabs(scale - 1) > DBL_EPSILON ) - c.convertTo(c, -1, scale, 0); - } - else - { - Mat temp; - apply(a, scale, temp); - temp.convertTo(c, type); - } - } -}; +template static inline +Mat_<_Tp>& operator -= (const Mat_<_Tp>& a, const Mat_<_Tp>& b) +{ + subtract(a, b, (Mat&)a); + return (Mat_<_Tp>&)a; +} +template static inline +Mat_<_Tp>& operator -= (const Mat_<_Tp>& a, const Scalar& s) +{ + subtract(a, s, (Mat&)a); + return (Mat_<_Tp>&)a; +} -template class CV_EXPORTS MatOp_MatMul_ +static inline Mat& operator -= (const Mat& a, const MatExpr& b) { -public: - MatOp_MatMul_() {} + b.op->augAssignSubtract(b, (Mat&)a); + return (Mat&)a; +} - static void apply(const M& a, const M& b, double scale, int flags, M& c, int type=-1) - { - if( type == a.type() || type < 0 ) - { - gemm(a, b, scale, Mat(), 0, c, flags); - } - else - { - Mat temp; - apply(a, b, scale, flags, temp); - temp.convertTo(c, type); - } - } -}; +template static inline +Mat_<_Tp>& operator -= (const Mat_<_Tp>& a, const MatExpr& b) +{ + b.op->augAssignSubtract(b, (Mat&)a); + return (Mat_<_Tp>&)a; +} +static inline Mat& operator *= (const Mat& a, const Mat& b) +{ + gemm(a, b, 1, Mat(), 0, (Mat&)a, 0); + return (Mat&)a; +} -template class CV_EXPORTS MatOp_MatMulAdd_ +static inline Mat& operator *= (const Mat& a, double s) { -public: - MatOp_MatMulAdd_() {} + a.convertTo((Mat&)a, -1, s); + return (Mat&)a; +} - static void apply(const M& a, const M& b, double alpha, - const M& c, double beta, int flags, M& d, int type=-1) - { - if( type == a.type() || type < 0 ) - { - gemm(a, b, alpha, c, beta, d, flags); - } - else - { - Mat temp; - apply(a, b, alpha, c, beta, flags, temp); - temp.convertTo(d, type); - } - } -}; +template static inline +Mat_<_Tp>& operator *= (const Mat_<_Tp>& a, const Mat_<_Tp>& b) +{ + gemm(a, b, 1, Mat(), 0, (Mat&)a, 0); + return (Mat_<_Tp>&)a; +} +template static inline +Mat_<_Tp>& operator *= (const Mat_<_Tp>& a, double s) +{ + a.convertTo((Mat&)a, -1, s); + return (Mat_<_Tp>&)a; +} -template class CV_EXPORTS MatOp_Cmp_ +static inline Mat& operator *= (const Mat& a, const MatExpr& b) { -public: - MatOp_Cmp_() {} + b.op->augAssignMultiply(b, (Mat&)a); + return (Mat&)a; +} - static void apply(const M& a, const M& b, int op, M& c, int type=-1) - { - if( type == CV_8UC1 || type == -1 ) - { - compare(a, b, c, op); - } - else - { - Mat temp; - apply(a, b, op, temp); - temp.convertTo(c, type); - } - } -}; +template static inline +Mat_<_Tp>& operator *= (const Mat_<_Tp>& a, const MatExpr& b) +{ + b.op->augAssignMultiply(b, (Mat&)a); + return (Mat_<_Tp>&)a; +} + +static inline Mat& operator /= (const Mat& a, const Mat& b) +{ + divide(a, b, (Mat&)a); + return (Mat&)a; +} -template class CV_EXPORTS MatOp_CmpS_ +static inline Mat& operator /= (const Mat& a, double s) { -public: - MatOp_CmpS_() {} + a.convertTo((Mat&)a, -1, 1./s); + return (Mat&)a; +} - static void apply(const M& a, double alpha, int op, M& c, int type=-1) - { - if( type == CV_8UC1 || type == -1 ) - { - compare(a, alpha, c, op); - } - else - { - Mat temp; - apply(a, alpha, op, temp); - temp.convertTo(c, type); - } - } -}; +template static inline +Mat_<_Tp>& operator /= (const Mat_<_Tp>& a, const Mat_<_Tp>& b) +{ + divide(a, b, (Mat&)a); + return (Mat_<_Tp>&)a; +} -template class CV_EXPORTS MatOp_MulDiv_ +template static inline +Mat_<_Tp>& operator /= (const Mat_<_Tp>& a, double s) { -public: - MatOp_MulDiv_() {} + a.convertTo((Mat&)a, -1, 1./s); + return (Mat_<_Tp>&)a; +} - static void apply(const M& a, const M& b, double alpha, char op, M& c, int type=-1) - { - if( type == a.type() || type == -1 ) - { - if( op == '*' ) - multiply( a, b, c, alpha ); - else - divide( a, b, c, alpha ); - } - else - { - Mat temp; - apply(a, b, alpha, op, temp); - temp.convertTo(c, type); - } - } -}; +static inline Mat& operator /= (const Mat& a, const MatExpr& b) +{ + b.op->augAssignDivide(b, (Mat&)a); + return (Mat&)a; +} -template class CV_EXPORTS MatOp_DivRS_ +template static inline +Mat_<_Tp>& operator /= (const Mat_<_Tp>& a, const MatExpr& b) { -public: - MatOp_DivRS_() {} + b.op->augAssignDivide(b, (Mat&)a); + return (Mat_<_Tp>&)a; +} - static void apply(const M& a, double alpha, M& c, int type=-1) - { - if( type == a.type() || type == -1 ) - { - c.create(a.rows, a.cols, a.type()); - divide( alpha, a, c ); - } - else - { - Mat temp; - apply(a, alpha, temp); - temp.convertTo(c, type); - } - } -}; +////////////////////////////// Logical operations /////////////////////////////// +static inline Mat& operator &= (const Mat& a, const Mat& b) +{ + bitwise_and(a, b, (Mat&)a); + return (Mat&)a; +} -template class CV_EXPORTS MatOp_Inv_ +static inline Mat& operator &= (const Mat& a, const Scalar& s) { -public: - MatOp_Inv_() {} + bitwise_and(a, s, (Mat&)a); + return (Mat&)a; +} - static void apply(const M& a, int method, M& c, int type=-1) - { - if( type == a.type() || type == -1 ) - { - invert(a, c, method); - } - else - { - Mat temp; - apply(a, method, temp); - temp.convertTo(c, type); - } - } -}; - - -template class CV_EXPORTS MatOp_Solve_ -{ -public: - MatOp_Solve_() {} - - static void apply(const M& a, const M& b, int method, M& c, int type=-1) - { - if( type == a.type() || type == -1 ) - { - solve(a, b, c, method); - } - else - { - Mat temp; - apply(a, b, method, temp); - temp.convertTo(c, type); - } - } -}; - -template class CV_EXPORTS MatOp_Set_ -{ -public: - MatOp_Set_() {} - - static void apply(Size size, int type0, const Scalar& s, int mtype, M& c, int type=-1) - { - if( type < 0 ) - type = type0; - c.create(size.height, size.width, type); - if( mtype == 0 ) - c = Scalar(0); - else if( mtype == 1 ) - c = s; - else if( mtype == 2 ) - setIdentity(c, s); - } -}; - -template -class CV_EXPORTS MatExpr_Op1_ -{ -public: - MatExpr_Op1_(const A1& _a1) : a1(_a1) {} - void assignTo(Mat& m, int type=-1) const { Op::apply(a1, (M&)m, type); } - operator M() const { M result; assignTo(result); return result; } - - A1 a1; -}; - -template -class CV_EXPORTS MatExpr_Op2_ -{ -public: - MatExpr_Op2_(const A1& _a1, const A2& _a2) : a1(_a1), a2(_a2) {} - void assignTo(Mat& m, int type=-1) const { Op::apply(a1, a2, (M&)m, type); } - operator M() const { M result; assignTo(result); return result; } - - A1 a1; A2 a2; -}; - -template -class CV_EXPORTS MatExpr_Op3_ -{ -public: - MatExpr_Op3_(const A1& _a1, const A2& _a2, const A3& _a3) : a1(_a1), a2(_a2), a3(_a3) {} - void assignTo(Mat& m, int type=-1) const { Op::apply(a1, a2, a3, (M&)m, type); } - operator M() const { M result; assignTo(result); return result; } - - A1 a1; A2 a2; A3 a3; -}; - -template -class CV_EXPORTS MatExpr_Op4_ -{ -public: - MatExpr_Op4_(const A1& _a1, const A2& _a2, const A3& _a3, const A4& _a4) - : a1(_a1), a2(_a2), a3(_a3), a4(_a4) {} - void assignTo(Mat& m, int type=-1) const { Op::apply(a1, a2, a3, a4, (M&)m, type); } - operator M() const { M result; assignTo(result); return result; } - - A1 a1; A2 a2; A3 a3; A4 a4; -}; - -template -class CV_EXPORTS MatExpr_Op5_ -{ -public: - MatExpr_Op5_(const A1& _a1, const A2& _a2, const A3& _a3, const A4& _a4, const A5& _a5) - : a1(_a1), a2(_a2), a3(_a3), a4(_a4), a5(_a5) {} - void assignTo(Mat& m, int type=-1) const { Op::apply(a1, a2, a3, a4, a5, (M&)m, type); } - operator M() const { M result; assignTo(result); return result; } - - A1 a1; A2 a2; A3 a3; A4 a4; A5 a5; -}; - -template -class CV_EXPORTS MatExpr_Op6_ -{ -public: - MatExpr_Op6_(const A1& _a1, const A2& _a2, const A3& _a3, - const A4& _a4, const A5& _a5, const A6& _a6) - : a1(_a1), a2(_a2), a3(_a3), a4(_a4), a5(_a5), a6(_a6) {} - void assignTo(Mat& m, int type=-1) const { Op::apply(a1, a2, a3, a4, a5, a6, (M&)m, type); } - operator M() const { M result; assignTo(result); return result; } - - A1 a1; A2 a2; A3 a3; A4 a4; A5 a5; A6 a6; -}; - -///////////////////////////////// Arithmetical Operations /////////////////////////////////// - -// A + B -static inline MatExpr_ >, Mat> -operator + (const Mat& a, const Mat& b) -{ - typedef MatExpr_Op5_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp(a, 1, b, 1, 0)); -} - -template static inline -MatExpr_ >, Mat > -operator + (const Mat_<_Tp>& a, const Mat_<_Tp>& b) -{ - typedef MatExpr_Op5_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp(a, 1, b, 1, 0)); -} - -// E1 + E2 -template static inline -MatExpr_ >, M> -operator + (const MatExpr_& a, const MatExpr_& b ) -{ - typedef MatExpr_Op5_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp((M)a, 1, (M)b, 1, 0)); -} - -// A - B -static inline MatExpr_ >, Mat> -operator - (const Mat& a, const Mat& b) -{ - typedef MatExpr_Op2_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp(a, b)); -} - -template static inline -MatExpr_ >, Mat > -operator - (const Mat_<_Tp>& a, const Mat_<_Tp>& b) -{ - typedef MatExpr_Op2_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp(a, b)); -} - -// E1 - E2 -template static inline -MatExpr_ >, M> -operator - (const MatExpr_& a, const MatExpr_& b ) -{ - typedef MatExpr_Op2_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp((M)a, (M)b)); -} - -// -(E1 - E2) -template static inline -MatExpr_ >, M> -operator - (const MatExpr_ >, M>& a ) -{ - typedef MatExpr_Op2_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp(a.e.a2, a.e.a1)); -} - -// (A - B)*alpha -template static inline -MatExpr_ >, M> -operator * (const MatExpr_ >, M>& a, - double alpha) -{ - typedef MatExpr_Op5_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp(a.e.a1, alpha, a.e.a2, -alpha, 0)); -} - -// alpha*(A - B) -template static inline -MatExpr_ >, M> -operator * (double alpha, - const MatExpr_ >, M>& a) -{ return a*alpha; } - - -// A*alpha -static inline -MatExpr_ >, Mat> -operator * (const Mat& a, double alpha) -{ - typedef MatExpr_Op2_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp(a, alpha)); -} - -// A*alpha -template static inline -MatExpr_ >, Mat > -operator * (const Mat_<_Tp>& a, double alpha) -{ - typedef MatExpr_Op2_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp(a, alpha)); -} - -// alpha*A -static inline -MatExpr_ >, Mat> -operator * (double alpha, const Mat& a) -{ return a*alpha; } - -// alpha*A -template static inline -MatExpr_ >, Mat > -operator * (double alpha, const Mat_<_Tp>& a) -{ return a*alpha; } - -// A/alpha -static inline -MatExpr_ >, Mat> -operator / (const Mat& a, double alpha) -{ return a*(1./alpha); } - -// A/alpha -template static inline -MatExpr_ >, Mat > -operator / (const Mat_<_Tp>& a, double alpha) -{ return a*(1./alpha); } - -// -A -static inline -MatExpr_ >, Mat> -operator - (const Mat& a) -{ return a*(-1); } - -// -A -template static inline -MatExpr_ >, Mat > -operator - (const Mat_<_Tp>& a) -{ return a*(-1); } - -// E*alpha -template static inline -MatExpr_ >, M> -operator * (const MatExpr_& a, double alpha) -{ - typedef MatExpr_Op2_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp((M)a, alpha)); -} - -// alpha*E -template static inline -MatExpr_ >, M> -operator * (double alpha, const MatExpr_& a) -{ - typedef MatExpr_Op2_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp((M)a, alpha)); -} - -// E/alpha -template static inline -MatExpr_ >, M> -operator / (const MatExpr_& a, double alpha) -{ - typedef MatExpr_Op2_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp((M)a, (1./alpha))); -} - -// (E*alpha)*beta ~ E*(alpha*beta) -template static inline -MatExpr_ >, M> -operator * (const MatExpr_ >, M>& a, - double beta) -{ return a.e.a1*(a.e.a2*beta); } - -// beta*(E*alpha) ~ E*(alpha*beta) -template static inline -MatExpr_ >, M> -operator * (double beta, - const MatExpr_ >, M>& a) -{ return a.e.a1*(a.e.a2*beta); } - -// (E*alpha)/beta ~ E*(alpha/beta) -template static inline -MatExpr_ >, M> -operator / (const MatExpr_ >, M>& a, - double beta) -{ return a.e.a1*(a.e.a2/beta); } - -// -E ~ E*(-1) -template static inline -MatExpr_ >, M> -operator - (const MatExpr_& a) -{ return a*(-1.); } - -// -(E*alpha) ~ E*(-alpha) -template static inline -MatExpr_ >, M> -operator - (const MatExpr_ >, M>& a) -{ return a.e.a1*(-a.e.a2); } - -// A + alpha -template static inline -MatExpr_ >, Mat > -operator + (const Mat_<_Tp>& a, double alpha) -{ - typedef MatExpr_Op3_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp(a, 1, alpha)); -} - -// A + alpha -template static inline -MatExpr_ >, Mat > -operator + (const Mat_<_Tp>& a, const Scalar& alpha) -{ - typedef MatExpr_Op2_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp(a, alpha)); -} - -static inline -MatExpr_ >, Mat > -operator + (const Mat& a, const Scalar& alpha) -{ - typedef MatExpr_Op2_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp(a, alpha)); -} - - -// alpha + A -template static inline -MatExpr_ >, Mat > -operator + (double alpha, const Mat_<_Tp>& a) -{ return a + alpha; } - -// alpha + A -template static inline -MatExpr_ >, Mat > -operator + (const Scalar& alpha, const Mat_<_Tp>& a) -{ return a + alpha; } - -static inline -MatExpr_ >, Mat > -operator + (const Scalar& alpha, const Mat& a) -{ return a + alpha; } - -// A - alpha -template static inline -MatExpr_ >, Mat > -operator - (const Mat_<_Tp>& a, double alpha) -{ return a + (-alpha); } - -// A - alpha -template static inline -MatExpr_ >, Mat > -operator - (const Mat_<_Tp>& a, const Scalar& alpha) -{ return a + (-alpha); } - -static inline -MatExpr_ >, Mat > -operator - (const Mat& a, const Scalar& alpha) -{ return a + (-alpha); } - -// alpha - A -template static inline -MatExpr_ >, Mat > -operator - (double alpha, const Mat_<_Tp>& a) -{ - typedef MatExpr_Op3_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp(a, -1, alpha)); -} - -// E + alpha -template static inline -MatExpr_ >, M> -operator + (const MatExpr_& a, double alpha) -{ - typedef MatExpr_Op3_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp((M)a, 1, alpha)); -} - -// E + alpha -template static inline -MatExpr_ >, M> -operator + (const MatExpr_& a, const Scalar& alpha) -{ - typedef MatExpr_Op2_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp((M)a, alpha)); -} - -// alpha + E -template static inline -MatExpr_ >, M> -operator + (double alpha, const MatExpr_& a) -{ return a + alpha; } - -// alpha + E -template static inline -MatExpr_ >, M> -operator + (const Scalar& alpha, const MatExpr_& a) -{ return a + alpha; } - -// E - alpha -template static inline -MatExpr_ >, M> -operator - (const MatExpr_& a, double alpha) -{ return a + (-alpha); } - -// E - alpha -template static inline -MatExpr_ >, M> -operator - (const MatExpr_& a, const Scalar& alpha) -{ return a + (-alpha); } - -// alpha - E -template static inline -MatExpr_ >, M> -operator - (double alpha, const MatExpr_& a) -{ - typedef MatExpr_Op3_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp(a, -1, alpha)); -} - -// E*alpha + beta -template static inline -MatExpr_ >, M> -operator + (const MatExpr_ >, M>& a, - double beta) -{ - typedef MatExpr_Op3_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp(a.e.a1, a.e.a2, beta)); -} - -// beta + E*alpha -template static inline -MatExpr_ >, M> -operator + (double beta, - const MatExpr_ >, M>& a) -{ return a + beta; } - -// E*alpha - beta -template static inline -MatExpr_ >, M> -operator - (const MatExpr_ >, M>& a, - double beta) -{ return a + (-beta); } - -// beta - E*alpha -template static inline -MatExpr_ >, M> -operator - (double beta, - const MatExpr_ >, M>& a) -{ return (a.e.a1*(-a.e.a2)) + beta; } - -// (E*alpha + gamma) + beta ~ E*alpha + (gamma + beta) -template static inline -MatExpr_ >, M> -operator + (const MatExpr_ >, M>& a, - double beta) -{ return a.e.a1*a.e.a2 + (a.e.a3 + beta); } - -// beta + (E*alpha + gamma) -template static inline -MatExpr_ >, M> -operator + (double beta, const MatExpr_ >, M>& a) -{ return a + beta; } - -// (E*alpha + gamma) - beta -template static inline -MatExpr_ >, M> -operator - (const MatExpr_ >, M>& a, - double beta) -{ return a + (-beta); } - -// beta - (E*alpha + gamma) -template static inline -MatExpr_ >, M> -operator - (double beta, const MatExpr_ >, M>& a) -{ return a.e.a1*(-a.e.a2) + (beta - a.e.a3); } - -// (E*alpha + gamma)*beta -template static inline -MatExpr_ >, M> -operator * (const MatExpr_ >, M>& a, - double beta) -{ return a.e.a1*(a.e.a2*beta) + (a.e.a3*beta); } - -// beta*(E*alpha + gamma) -template static inline -MatExpr_ >, M> -operator * (double beta, const MatExpr_ >, M>& a) -{ return a*beta; } - -// -(E*alpha + beta) -template static inline -MatExpr_ >, M> -operator - (const MatExpr_ >, M>& a) -{ return a*(-1); } - -// (A*u + B*v + w) + beta -template static inline -MatExpr_ >, M> -operator + (const MatExpr_ >, M>& a, - double beta ) -{ - typedef MatExpr_Op5_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp(a.e.a1, a.e.a2, a.e.a3, a.e.a4, a.e.a5 + beta)); -} - -// beta + (A*u + B*v + w) -template static inline -MatExpr_ >, M> -operator + (double beta, - const MatExpr_ >, M>& a) -{ return a + beta; } - -// (A*u + B*v + w) - beta -template static inline -MatExpr_ >, M> -operator - (const MatExpr_ >, M>& a, - double beta) -{ return a + (-beta); } - -// beta - (A*u + B*v + w) -template static inline -MatExpr_ >, M> -operator - (double beta, - const MatExpr_ >, M>& a) -{ - typedef MatExpr_Op5_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp(a.e.a1, -a.e.a2, a.e.a3, -a.e.a4, -a.e.a5 + beta)); -} - -// (A*u + B*v + w)*beta -template static inline -MatExpr_ >, M> -operator * (const MatExpr_ >, M>& a, - double beta ) -{ - typedef MatExpr_Op5_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp(a.e.a1, - a.e.a2*beta, a.e.a3, a.e.a4*beta, a.e.a5*beta)); -} - -// beta*(A*u + B*v + w) -template static inline -MatExpr_ >, M> -operator * (double beta, - const MatExpr_ >, M>& a) -{ return a * beta; } - -// -(A*u + B*v + w) -template static inline -MatExpr_ >, M> -operator - (const MatExpr_ >, M>& a) -{ return a*(-1); } - -// A*alpha + B -template static inline -MatExpr_ >, M> -operator + (const MatExpr_ >, M>& a, - const M& b ) -{ - typedef MatExpr_Op5_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp(a.e.a1, a.e.a2, b, 1, 0)); -} - -// B + A*alpha -template static inline -MatExpr_ >, M> -operator + (const M& b, - const MatExpr_ >, M>& a) -{ return a + b; } - -// (A*alpha + beta) + B -template static inline -MatExpr_ >, M> -operator + (const MatExpr_ >, M>& a, - const M& b ) -{ - typedef MatExpr_Op5_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp(a.e.a1, a.e.a2, b, 1, a.e.a3)); -} - -// B + (A*alpha + beta) -template static inline -MatExpr_ >, M> -operator + (const M& b, - const MatExpr_ >, M>& a) -{ return a + b; } - - -// A*alpha + E -template static inline -MatExpr_ >, M> -operator + (const MatExpr_ >, M>& a, - const MatExpr_& b ) -{ return a + (M)b; } - -// E + A*alpha -template static inline -MatExpr_ >, M> -operator + (const MatExpr_& b, - const MatExpr_ >, M>& a) -{ return a + (M)b; } - -// (A*alpha + beta) + E -template static inline -MatExpr_ >, M> -operator + (const MatExpr_ >, M>& a, - const MatExpr_& b ) -{ return a + (M)b; } - -// E + (A*alpha + beta) -template static inline -MatExpr_ >, M> -operator + (const MatExpr_& b, - const MatExpr_ >, M>& a) -{ return a + b; } - -// A*alpha + B*beta -template static inline -MatExpr_ >, M> -operator + (const MatExpr_ >, M>& a, - const MatExpr_ >, M>& b ) -{ - typedef MatExpr_Op5_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp(a.e.a1, a.e.a2, b.e.a1, b.e.a2, 0)); -} - -// (A*alpha + beta) + B*gamma -template static inline -MatExpr_ >, M> -operator + (const MatExpr_ >, M>& a, - const MatExpr_ >, M>& b ) -{ - typedef MatExpr_Op5_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp(a.e.a1, a.e.a2, b.e.a1, b.e.a2, a.e.a3)); -} - -// B*gamma + (A*alpha + beta) -template static inline -MatExpr_ >, M> -operator + (const MatExpr_ >, M>& b, - const MatExpr_ >, M>& a ) -{ return a + b; } - -// (A*alpha + beta) + (B*gamma + theta) -template static inline -MatExpr_ >, M> -operator + (const MatExpr_ >, M>& a, - const MatExpr_ >, M>& b ) -{ - typedef MatExpr_Op5_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp(a.e.a1, a.e.a2, b.e.a1, b.e.a2, a.e.a3 + b.e.a3)); -} - -// A*alpha - B -template static inline -MatExpr_ >, M> -operator - (const MatExpr_ >, M>& a, - const M& b ) -{ - typedef MatExpr_Op5_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp(a.e.a1, a.e.a2, b, -1, 0)); -} - -// B - A*alpha -template static inline -MatExpr_ >, M> -operator - (const M& b, - const MatExpr_ >, M>& a) -{ - typedef MatExpr_Op5_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp(a.e.a1, -a.e.a2, b, 1, 0)); -} - -// (A*alpha + beta) - B -template static inline -MatExpr_ >, M> -operator - (const MatExpr_ >, M>& a, - const M& b ) -{ - typedef MatExpr_Op5_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp(a.e.a1, a.e.a2, b, -1, a.e.a3)); -} - -// B - (A*alpha + beta) -template static inline -MatExpr_ >, M> -operator - (const M& b, - const MatExpr_ >, M>& a) -{ - typedef MatExpr_Op5_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp(a.e.a1, -a.e.a2, b, 1, -a.e.a3)); -} - -// A*alpha - E -template static inline -MatExpr_ >, M> -operator - (const MatExpr_ >, M>& a, - const MatExpr_& b ) -{ return a - (M)b; } - -// E - A*alpha -template static inline -MatExpr_ >, M> -operator - (const MatExpr_& b, - const MatExpr_ >, M>& a) -{ return (M)b - a; } - -// (A*alpha + beta) - E -template static inline -MatExpr_ >, M> -operator - (const MatExpr_ >, M>& a, - const MatExpr_& b ) -{ return a - (M)b; } - -// E - (A*alpha + beta) -template static inline -MatExpr_ >, M> -operator - (const MatExpr_& b, - const MatExpr_ >, M>& a) -{ return (M)b - a; } - -// A*alpha - B*beta -template static inline -MatExpr_ >, M> -operator - (const MatExpr_ >, M>& a, - const MatExpr_ >, M>& b ) -{ - typedef MatExpr_Op5_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp(a.e.a1, a.e.a2, b.e.a1, -b.e.a2, 0)); -} - -// (A*alpha + beta) - B*gamma -template static inline -MatExpr_ >, M> -operator - (const MatExpr_ >, M>& a, - const MatExpr_ >, M>& b ) -{ - typedef MatExpr_Op5_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp(a.e.a1, a.e.a2, b.e.a1, -b.e.a2, a.e.a3)); -} - -// B*gamma - (A*alpha + beta) -template static inline -MatExpr_ >, M> -operator - (const MatExpr_ >, M>& b, - const MatExpr_ >, M>& a ) -{ - typedef MatExpr_Op5_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp(a.e.a1, -a.e.a2, b.e.a1, b.e.a2, -a.e.a3)); -} - -// (A*alpha + beta) - (B*gamma + theta) -template static inline -MatExpr_ >, M> -operator - (const MatExpr_ >, M>& a, - const MatExpr_ >, M>& b ) -{ - typedef MatExpr_Op5_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp(a.e.a1, a.e.a2, b.e.a1, -b.e.a2, a.e.a3 - b.e.a3)); -} - -/////////////////////////////// Mat Multiplication /////////////////////////////////// - -// A^t -inline MatExpr_ >, Mat> -Mat::t() const -{ - typedef MatExpr_Op2_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp(*this, 1)); -} - -template inline -MatExpr_ >, Mat > -Mat_<_Tp>::t() const -{ - typedef MatExpr_Op2_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp(*this, 1)); -} - -// A*B -static inline -MatExpr_ >, Mat> -operator * ( const Mat& a, const Mat& b ) -{ - typedef MatExpr_Op4_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp(a, b, 1, 0)); -} - -template static inline -MatExpr_ >, Mat > -operator * ( const Mat_<_Tp>& a, const Mat_<_Tp>& b ) -{ - typedef MatExpr_Op4_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp(a, b, 1, 0)); -} - -template static inline -MatExpr_ >, M> -operator * ( const MatExpr_& a, const MatExpr_& b ) -{ - typedef MatExpr_Op4_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp((M)a, (M)b, 1, 0)); -} - -// (A*alpha)*B -template static inline -MatExpr_ >, M> -operator * ( const MatExpr_ >, M>& a, const M& b ) -{ - typedef MatExpr_Op4_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp((M)a.e.a1, b, a.e.a2, 0)); -} - -// A*(B*alpha) -template static inline -MatExpr_ >, M> -operator * ( const M& b, const MatExpr_ >, M>& a ) -{ - typedef MatExpr_Op4_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp(b, (M)a.e.a1, a.e.a2, 0)); -} - -// A^t*B -template static inline -MatExpr_ >, M> -operator * ( const MatExpr_ >, M>& a, const M& b ) -{ - typedef MatExpr_Op4_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp((M)a.e.a1, b, a.e.a2, GEMM_1_T)); -} - -// A*B^t -template static inline -MatExpr_ >, M> -operator * ( const M& a, const MatExpr_ >, M>& b ) -{ - typedef MatExpr_Op4_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp(a, (M)b.e.a1, b.e.a2, GEMM_2_T)); -} - -// (A*alpha)*(B*beta) -template static inline -MatExpr_ >, M> -operator * ( const MatExpr_ >, M>& a, - const MatExpr_ >, M>& b ) -{ - typedef MatExpr_Op4_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp((M)a.e.a1, (M)b.e.a1, a.e.a2*b.e.a2, 0)); -} - -// A^t*(B*alpha) -template static inline -MatExpr_ >, M> -operator * ( const MatExpr_ >, M>& a, - const MatExpr_ >, M>& b ) -{ - typedef MatExpr_Op4_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp((M)a.e.a1, (M)b.e.a1, a.e.a2*b.e.a2, GEMM_1_T)); -} - -// (A*alpha)*B^t -template static inline -MatExpr_ >, M> -operator * ( const MatExpr_ >, M>& a, - const MatExpr_ >, M>& b ) -{ - typedef MatExpr_Op4_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp((M)a.e.a1, (M)b.e.a1, a.e.a2*b.e.a2, GEMM_2_T)); -} - -// A^t*B^t -template static inline -MatExpr_ >, M> -operator * ( const MatExpr_ >, M>& a, - const MatExpr_ >, M>& b ) -{ - typedef MatExpr_Op4_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp((M)a.e.a1, - (M)b.e.a1, a.e.a2*b.e.a2, GEMM_1_T+GEMM_2_T)); -} - -// (A*B)*alpha -template static inline -MatExpr_ >, M> -operator * ( const MatExpr_ >, M>& a, - double alpha ) -{ - typedef MatExpr_Op4_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp(a.e.a1, a.e.a2, a.e.a3*alpha, a.e.a4)); -} - -// alpha*(A*B) -template static inline -MatExpr_ >, M> -operator * ( double alpha, - const MatExpr_ >, M>& a ) -{ - return a*alpha; -} - -// -(A*B) -template static inline -MatExpr_ >, M> -operator - ( const MatExpr_ >, M>& a ) -{ - return a*(-1); -} - -// (A*alpha + beta)*B -template static inline -MatExpr_ >, M> -operator * ( const MatExpr_ >, M>& a, const M& b ) -{ - typedef MatExpr_Op4_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp((M)a.e.a1, b, a.e.a2, b, a.e.a3, 0)); -} - -// A*(B*alpha + beta) -template static inline -MatExpr_ >, M> -operator * ( const M& a, const MatExpr_ >, M>& b ) -{ - typedef MatExpr_Op4_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp(a, (M)b.e.a1, b.e.a2, a, b.e.a3, 0)); -} - -// (A*alpha + beta)*(B*gamma) -template static inline -MatExpr_ >, M> -operator * ( const MatExpr_ >, M>& a, - const MatExpr_ >, M>& b ) -{ - typedef MatExpr_Op4_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp((M)a.e.a1, (M)b.e.a1, - a.e.a2*b.e.a2, (M)b.e.a1, a.e.a3*b.e.a2, 0)); -} - -// (A*gamma)*(B*alpha + beta) -template static inline -MatExpr_ >, M> -operator * ( const MatExpr_ >, M>& a, - const MatExpr_ >, M>& b ) -{ - typedef MatExpr_Op4_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp((M)a.e.a1, (M)b.e.a1, - a.e.a2*b.e.a2, (M)a.e.a1, a.e.a2*b.e.a3, 0)); -} - -// (A*alpha + beta)*B^t -template static inline -MatExpr_ >, M> -operator * ( const MatExpr_ >, M>& a, - const MatExpr_ >, M>& b ) -{ - typedef MatExpr_Op4_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp((M)a.e.a1, (M)b.e.a1, - a.e.a2*b.e.a2, (M)b.e.a1, a.e.a3*b.e.a2, GEMM_2_T)); -} - -// A^t*(B*alpha + beta) -template static inline -MatExpr_ >, M> -operator * ( const MatExpr_ >, M>& a, - const MatExpr_ >, M>& b ) -{ - typedef MatExpr_Op4_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp((M)a.e.a1, (M)b.e.a1, - a.e.a2*b.e.a2, (M)a.e.a1, a.e.a2*b.e.a3, GEMM_1_T)); -} - -// (A*B + C)*alpha -template static inline -MatExpr_ >, M> -operator * ( const MatExpr_ >, M>& a, double alpha ) -{ - typedef MatExpr_Op6_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp(a.e.a1, a.e.a2, - a.e.a3*alpha, a.e.a4, a.e.a5*alpha, a.e.a6)); -} - -// alpha*(A*B + C) -template static inline -MatExpr_ >, M> -operator * ( double alpha, const MatExpr_ >, M>& a ) -{ return a*alpha; } - -// -(A*B + C) -template static inline -MatExpr_ >, M> -operator - ( const MatExpr_ >, M>& a ) -{ return a*(-1); } - - -// (A*B) + C -template static inline -MatExpr_ >, M> -operator + ( const MatExpr_ >, M>& a, - const M& b ) -{ - typedef MatExpr_Op6_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp( - (M)a.e.a1, (M)a.e.a2, a.e.a3, b, 1, a.e.a4)); -} - -// C + (A*B) -template static inline -MatExpr_ >, M> -operator + ( const M& b, - const MatExpr_ >, M>& a ) -{ return a + b; } - - -// (A*B) - C -template static inline -MatExpr_ >, M> -operator - ( const MatExpr_ >, M>& a, - const M& b ) -{ - typedef MatExpr_Op6_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp( - (M)a.e.a1, (M)a.e.a2, a.e.a3, b, -1, a.e.a4)); -} - -// C - (A*B) -template static inline -MatExpr_ >, M> -operator - ( const M& b, - const MatExpr_ >, M>& a ) -{ - typedef MatExpr_Op6_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp( - (M)a.e.a1, (M)a.e.a2, -a.e.a3, b, 1, a.e.a4)); -} - - -// (A*B) + C -template static inline -MatExpr_ >, M> -operator + ( const MatExpr_ >, M>& a, - const MatExpr_& b ) -{ - typedef MatExpr_Op6_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp( - (M)a.e.a1, (M)a.e.a2, a.e.a3, (M)b, 1, a.e.a4)); -} - -// C + (A*B) -template static inline -MatExpr_ >, M> -operator + ( const MatExpr_& b, - const MatExpr_ >, M>& a ) -{ return a + b; } - - -// (A*B) - C -template static inline -MatExpr_ >, M> -operator - ( const MatExpr_ >, M>& a, - const MatExpr_& b ) -{ - typedef MatExpr_Op6_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp( - (M)a.e.a1, (M)a.e.a2, a.e.a3, (M)b, -1, a.e.a4)); -} - -// C - (A*B) -template static inline -MatExpr_ >, M> -operator - ( const MatExpr_& b, - const MatExpr_ >, M>& a ) -{ - typedef MatExpr_Op6_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp( - (M)a.e.a1, (M)a.e.a2, -a.e.a3, (M)b, 1, a.e.a4)); -} - - -// (A*B) + C*alpha -template static inline -MatExpr_ >, M> -operator + ( const MatExpr_ >, M>& a, - const MatExpr_ >, M>& b ) -{ - typedef MatExpr_Op6_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp( - (M)a.e.a1, (M)a.e.a2, a.e.a3, (M)b.e.a1, b.e.a2, a.e.a4)); -} - -// C*alpha + (A*B) -template static inline -MatExpr_ >, M> -operator + ( const MatExpr_ >, M>& b, - const MatExpr_ >, M>& a ) -{ return a + b; } - - -// (A*B) - (C*alpha) -template static inline -MatExpr_ >, M> -operator - ( const MatExpr_ >, M>& a, - const MatExpr_ >, M>& b ) -{ - typedef MatExpr_Op6_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp( - (M)a.e.a1, (M)a.e.a2, a.e.a3, (M)b.e.a1, -b.e.a2, a.e.a4)); -} - -// (C*alpha) - (A*B) -template static inline -MatExpr_ >, M> -operator - ( const MatExpr_ >, M>& b, - const MatExpr_ >, M>& a ) -{ - typedef MatExpr_Op6_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp( - (M)a.e.a1, (M)a.e.a2, -a.e.a3, (M)b.e.a1, b.e.a2, a.e.a4)); -} - - -// (A*B) + C^t -template static inline -MatExpr_ >, M> -operator + ( const MatExpr_ >, M>& a, - const MatExpr_ >, M>& b ) -{ - typedef MatExpr_Op6_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp( - (M)a.e.a1, (M)a.e.a2, a.e.a3, (M)b.e.a1, b.e.a2, a.e.a4 + GEMM_3_T)); -} - -// C^t + (A*B) -template static inline -MatExpr_ >, M> -operator + ( const MatExpr_ >, M>& b, - const MatExpr_ >, M>& a ) -{ return a + b; } - - -// (A*B) - C^t -template static inline -MatExpr_ >, M> -operator - ( const MatExpr_ >, M>& a, - const MatExpr_ >, M>& b ) -{ - typedef MatExpr_Op6_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp( - (M)a.e.a1, (M)a.e.a2, a.e.a3, (M)b.e.a1, -b.e.a2, a.e.a4+GEMM_3_T)); -} - -// C^t - (A*B) -template static inline -MatExpr_ >, M> -operator - ( const MatExpr_ >, M>& b, - const MatExpr_ >, M>& a ) -{ - typedef MatExpr_Op6_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp( - (M)a.e.a1, (M)a.e.a2, -a.e.a3, (M)b.e.a1, b.e.a2, a.e.a4+GEMM_3_T)); -} - - -////////////////////////////// Augmenting algebraic operations ////////////////////////////////// - -static inline Mat& operator += (const Mat& a, const Mat& b) -{ - add(a, b, (Mat&)a); - return (Mat&)a; -} - -static inline Mat& operator -= (const Mat& a, const Mat& b) -{ - subtract(a, b, (Mat&)a); - return (Mat&)a; -} - -static inline Mat& operator *= (const Mat& a, const Mat& b) -{ - gemm(a, b, 1, Mat(), 0, (Mat&)a, 0); - return (Mat&)a; -} - -static inline Mat& operator *= (const Mat& a, double alpha) -{ - a.convertTo((Mat&)a, -1, alpha); - return (Mat&)a; -} - -static inline Mat& operator += (const Mat& a, const Scalar& s) -{ - add(a, s, (Mat&)a); - return (Mat&)a; -} - -static inline Mat& operator -= (const Mat& a, const Scalar& s) -{ return (a += -s); } - -template static inline -Mat_<_Tp>& operator += (const Mat_<_Tp>& a, const Mat_<_Tp>& b) -{ - (Mat&)a += (const Mat&)b; - return (Mat_<_Tp>&)a; -} - -template static inline -Mat_<_Tp>& operator -= (const Mat_<_Tp>& a, const Mat_<_Tp>& b) -{ - (Mat&)a -= (const Mat&)b; - return (Mat_<_Tp>&)a; -} - -template static inline -Mat_<_Tp>& operator *= (const Mat_<_Tp>& a, const Mat_<_Tp>& b) -{ - (Mat&)a *= (const Mat&)b; - return (Mat_<_Tp>&)a; -} - -template static inline -Mat_<_Tp>& operator += (const Mat_<_Tp>& a, const Scalar& s) -{ - (Mat&)a += s; - return (Mat_<_Tp>&)a; -} - -template static inline -Mat_<_Tp>& operator -= (const Mat_<_Tp>& a, const Scalar& s) -{ - (Mat&)a -= s; - return (Mat_<_Tp>&)a; -} - -template static inline -M& operator += (const M& a, const MatExpr_& b) -{ return (a += (M)b); } - -template static inline -M& operator -= (const M& a, const MatExpr_& b) -{ return (a -= (M)b); } - -template static inline -M& operator *= (const M& a, const MatExpr_& b) -{ return (a *= (M)b); } - -template static inline -M& operator += (const M& a, - const MatExpr_ >, M>& b) -{ - M& _a = (M&)a; - scaleAdd( b.e.a1, b.e.a2, _a, _a ); - return _a; -} - -template static inline -M& operator -= (const M& a, - const MatExpr_ >, M>& b) -{ - M& _a = (M&)a; - scaleAdd( b.e.a1, -b.e.a2, _a, _a ); - return _a; -} - -template static inline -M& operator += (const M& a, - const MatExpr_ >, M>& b) -{ - M& _a = (M&)a; - MatOp_AddEx_::apply( a, 1, (M)b.e.a1, b.e.a2, b.e.a3, _a ); - return _a; -} - -template static inline -M& operator -= (const M& a, - const MatExpr_ >, M>& b) -{ - M& _a = (M&)a; - MatOp_AddEx_::apply( a, 1, (M)b.e.a1, -b.e.a2, -b.e.a3, _a ); - return _a; -} - -template static inline -M& operator += (const M& a, - const MatExpr_ >, M>& b) -{ - M& _a = (M&)a; - MatOp_MatMulAdd_::apply( (M)b.e.a1, (M)b.e.a2, b.e.a3, a, 1, b.e.a4, _a ); - return _a; -} - -template static inline -M& operator -= (const M& a, - const MatExpr_ >, M>& b) -{ - M& _a = (M&)a; - MatOp_MatMulAdd_::apply( (M)b.e.a1, (M)b.e.a2, -b.e.a3, a, 1, b.e.a4, _a ); - return _a; -} - -template static inline -M& operator *= (const M& a, - const MatExpr_ >, M>& b) -{ - M& _a = (M&)a; - MatOp_MatMul_::apply( a, (M)b.e.a1, b.e.a2, 0, _a ); - return _a; -} - -template static inline -M& operator *= (const M& a, - const MatExpr_ >, M>& b) -{ - M& _a = (M&)a; - MatOp_MatMulAdd_::apply( a, (M)b.e.a1, b.e.a2, a, b.e.a3, 0, _a ); - return _a; -} - -template static inline -M& operator *= (const M& a, - const MatExpr_ >, M>& b) -{ - M& _a = (M&)a; - MatOp_MatMul_::apply( a, (M)b.e.a1, b.e.a2, GEMM_2_T, _a ); - return _a; -} - -////////////////////////////// Logical operations /////////////////////////////// - -static inline MatExpr_ >, Mat> -operator & (const Mat& a, const Mat& b) -{ - typedef MatExpr_Op3_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp(a, b, '&')); -} - -static inline MatExpr_ >, Mat> -operator | (const Mat& a, const Mat& b) -{ - typedef MatExpr_Op3_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp(a, b, '|')); -} - -static inline MatExpr_ >, Mat> -operator ^ (const Mat& a, const Mat& b) -{ - typedef MatExpr_Op3_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp(a, b, '^')); -} - -template static inline -MatExpr_ >, Mat > -operator & (const Mat_<_Tp>& a, const Mat_<_Tp>& b) -{ - typedef MatExpr_Op3_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp( - a, b, '&')); -} - -template static inline -MatExpr_ >, Mat > -operator | (const Mat_<_Tp>& a, const Mat_<_Tp>& b) -{ - typedef MatExpr_Op3_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp( - a, b, '|')); -} - -template static inline -MatExpr_ >, Mat > -operator ^ (const Mat_<_Tp>& a, const Mat_<_Tp>& b) -{ - typedef MatExpr_Op3_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp( - a, b, '^')); -} - -template static inline -MatExpr_ >, M> -operator & (const MatExpr_& a, const MatExpr_& b) -{ return (M)a & (M)b; } - -template static inline -MatExpr_ >, M> -operator & (const MatExpr_& a, const M& b) -{ return (M)a & b; } - -template static inline -MatExpr_ >, M> -operator & (const M& a, const MatExpr_& b) -{ return a & (M)b; } - -template static inline -MatExpr_ >, M> -operator | (const MatExpr_& a, const MatExpr_& b) -{ return (M)a | (M)b; } - -template static inline -MatExpr_ >, M> -operator | (const MatExpr_& a, const M& b) -{ return (M)a | b; } - -template static inline -MatExpr_ >, M> -operator | (const M& a, const MatExpr_& b) -{ return a | (M)b; } - -template static inline -MatExpr_ >, M> -operator ^ (const MatExpr_& a, const MatExpr_& b) -{ return (M)a ^ (M)b; } - -template static inline -MatExpr_ >, M> -operator ^ (const MatExpr_& a, const M& b) -{ return (M)a ^ b; } - -template static inline -MatExpr_ >, M> -operator ^ (const M& a, const MatExpr_& b) -{ return a ^ (M)b; } - -static inline Mat& operator &= (const Mat& a, const Mat& b) -{ - MatOp_Bin_::apply( a, b, '&', (Mat&)a ); - return (Mat&)a; -} - -static inline Mat& operator |= (const Mat& a, const Mat& b) -{ - MatOp_Bin_::apply( a, b, '|', (Mat&)a ); - return (Mat&)a; -} - -static inline Mat& operator ^= (const Mat& a, const Mat& b) -{ - MatOp_Bin_::apply( a, b, '^', (Mat&)a ); - return (Mat&)a; -} - -template static inline Mat_<_Tp>& -operator &= (const Mat_<_Tp>& a, const Mat_<_Tp>& b) -{ - (Mat&)a &= (const Mat&)b; - return (Mat_<_Tp>&)a; -} - -template static inline Mat_<_Tp>& -operator |= (const Mat_<_Tp>& a, const Mat_<_Tp>& b) -{ - (Mat&)a |= (const Mat&)b; - return (Mat_<_Tp>&)a; -} - -template static inline Mat_<_Tp>& -operator ^= (const Mat_<_Tp>& a, const Mat_<_Tp>& b) -{ - (Mat&)a ^= (const Mat&)b; - return (Mat_<_Tp>&)a; -} - -template static inline M& -operator &= (const M& a, const MatExpr_& b) -{ return (a &= (M)b); } - -template static inline M& -operator |= (const M& a, const MatExpr_& b) -{ return (a |= (M)b); } - -template static inline M& -operator ^= (const M& a, const MatExpr_& b) -{ return (a ^= (M)b); } - -static inline MatExpr_ >, Mat> -operator & (const Mat& a, const Scalar& s) -{ - typedef MatExpr_Op3_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp(a, s, '&')); -} - -static inline MatExpr_ >, Mat> -operator & (const Scalar& s, const Mat& a) -{ return a & s; } - -static inline MatExpr_ >, Mat> -operator | (const Mat& a, const Scalar& s) -{ - typedef MatExpr_Op3_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp(a, s, '|')); -} - -static inline MatExpr_ >, Mat> -operator | (const Scalar& s, const Mat& a) -{ return a | s; } - -static inline MatExpr_ >, Mat> -operator ^ (const Mat& a, const Scalar& s) -{ - typedef MatExpr_Op3_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp(a, s, '^')); -} - -static inline MatExpr_ >, Mat> -operator ^ (const Scalar& s, const Mat& a) -{ return a ^ s; } - -static inline MatExpr_ >, Mat> -operator ~ (const Mat& a) -{ - typedef MatExpr_Op3_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp(a, Scalar(), '~')); -} - -template static inline -MatExpr_ >, Mat > -operator & (const Mat_<_Tp>& a, const Scalar& s) -{ - typedef MatExpr_Op3_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp(a, s, '&')); -} - -template static inline -MatExpr_ >, Mat > -operator & (const Scalar& s, const Mat_<_Tp>& a) -{ return a & s; } - -template static inline -MatExpr_ >, Mat > -operator | (const Mat_<_Tp>& a, const Scalar& s) -{ - typedef MatExpr_Op3_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp(a, s, '|')); -} - -template static inline -MatExpr_ >, Mat > -operator | (const Scalar& s, const Mat_<_Tp>& a) -{ return a | s; } - -template static inline -MatExpr_ >, Mat > -operator ^ (const Mat_<_Tp>& a, const Scalar& s) +template static inline Mat_<_Tp>& +operator &= (const Mat_<_Tp>& a, const Mat_<_Tp>& b) { - typedef MatExpr_Op3_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp(a, s, '^')); -} - -template static inline -MatExpr_ >, Mat > -operator ^ (const Scalar& s, const Mat_<_Tp>& a) -{ return a ^ s; } + bitwise_and(a, b, (Mat&)a); + return (Mat_<_Tp>&)a; +} -template static inline -MatExpr_ >, Mat > -operator ~ (const Mat_<_Tp>& a) +template static inline Mat_<_Tp>& +operator &= (const Mat_<_Tp>& a, const Scalar& s) { - typedef MatExpr_Op3_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp(a, Scalar(), '~')); -} - -template static inline -MatExpr_ >, M > -operator & (const MatExpr_& a, const Scalar& s) -{ return (M)a & s; } - -template static inline -MatExpr_ >, M > -operator & (const Scalar& s, const MatExpr_& a) -{ return (M)a & s; } - -template static inline -MatExpr_ >, M > -operator | (const MatExpr_& a, const Scalar& s) -{ return (M)a | s; } - -template static inline -MatExpr_ >, M > -operator | (const Scalar& s, const MatExpr_& a) -{ return (M)a | s; } - -template static inline -MatExpr_ >, M > -operator ^ (const MatExpr_& a, const Scalar& s) -{ return (M)a ^ s; } - -template static inline -MatExpr_ >, M > -operator ^ (const Scalar& s, const MatExpr_& a) -{ return (M)a ^ s; } - -template static inline -MatExpr_ >, M > -operator ~ (const MatExpr_& a) -{ return ~(M)a; } - -static inline Mat& operator &= (const Mat& a, const Scalar& s) + bitwise_and(a, s, (Mat&)a); + return (Mat_<_Tp>&)a; +} + +static inline Mat& operator |= (const Mat& a, const Mat& b) { - MatOp_BinS_::apply( a, s, '&', (Mat&)a ); + bitwise_or(a, b, (Mat&)a); return (Mat&)a; } static inline Mat& operator |= (const Mat& a, const Scalar& s) { - MatOp_BinS_::apply( a, s, '|', (Mat&)a ); - return (Mat&)a; -} - -static inline Mat& operator ^= (const Mat& a, const Scalar& s) -{ - MatOp_BinS_::apply( a, s, '^', (Mat&)a ); + bitwise_or(a, s, (Mat&)a); return (Mat&)a; -} +} template static inline Mat_<_Tp>& -operator &= (const Mat_<_Tp>& a, const Scalar& s) +operator |= (const Mat_<_Tp>& a, const Mat_<_Tp>& b) { - (Mat&)a &= s; + bitwise_or(a, b, (Mat&)a); return (Mat_<_Tp>&)a; -} +} template static inline Mat_<_Tp>& operator |= (const Mat_<_Tp>& a, const Scalar& s) { - (Mat&)a |= s; - return (Mat_<_Tp>&)a; -} - -template static inline Mat_<_Tp>& -operator ^= (const Mat_<_Tp>& a, const Scalar& s) -{ - (Mat&)a ^= s; + bitwise_or(a, s, (Mat&)a); return (Mat_<_Tp>&)a; -} - -////////////////////////////// Comparison operations /////////////////////////////// - -static inline MatExpr_ >, Mat> -operator == (const Mat& a, const Mat& b) -{ - typedef MatExpr_Op3_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp(a, b, CMP_EQ)); -} - -static inline MatExpr_ >, Mat> -operator >= (const Mat& a, const Mat& b) -{ - typedef MatExpr_Op3_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp(a, b, CMP_GE)); -} - -static inline MatExpr_ >, Mat> -operator > (const Mat& a, const Mat& b) -{ - typedef MatExpr_Op3_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp(a, b, CMP_GT)); -} - -static inline MatExpr_ >, Mat> -operator <= (const Mat& a, const Mat& b) -{ return b >= a; } - -static inline MatExpr_ >, Mat> -operator < (const Mat& a, const Mat& b) -{ return b > a; } - -static inline MatExpr_ >, Mat> -operator != (const Mat& a, const Mat& b) -{ - typedef MatExpr_Op3_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp(a, b, CMP_NE)); -} - -static inline MatExpr_ >, Mat> -operator == (const Mat& a, double alpha) -{ - typedef MatExpr_Op3_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp(a, alpha, CMP_EQ)); -} - -static inline MatExpr_ >, Mat> -operator >= (const Mat& a, double alpha) -{ - typedef MatExpr_Op3_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp(a, alpha, CMP_GE)); -} - -static inline MatExpr_ >, Mat> -operator > (const Mat& a, double alpha) +} + +static inline Mat& operator ^= (const Mat& a, const Mat& b) { - typedef MatExpr_Op3_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp(a, alpha, CMP_GT)); + bitwise_xor(a, b, (Mat&)a); + return (Mat&)a; } -static inline MatExpr_ >, Mat> -operator <= (const Mat& a, double alpha) +static inline Mat& operator ^= (const Mat& a, const Scalar& s) { - typedef MatExpr_Op3_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp(a, alpha, CMP_LE)); -} + bitwise_xor(a, s, (Mat&)a); + return (Mat&)a; +} -static inline MatExpr_ >, Mat> -operator < (const Mat& a, double alpha) +template static inline Mat_<_Tp>& +operator ^= (const Mat_<_Tp>& a, const Mat_<_Tp>& b) { - typedef MatExpr_Op3_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp(a, alpha, CMP_LT)); -} + bitwise_xor(a, b, (Mat&)a); + return (Mat_<_Tp>&)a; +} -static inline MatExpr_ >, Mat> -operator != (const Mat& a, double alpha) +template static inline Mat_<_Tp>& +operator ^= (const Mat_<_Tp>& a, const Scalar& s) { - typedef MatExpr_Op3_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp(a, alpha, CMP_NE)); -} - -static inline MatExpr_ >, Mat> -operator == (double alpha, const Mat& a) -{ return a == alpha; } - -static inline MatExpr_ >, Mat> -operator >= (double alpha, const Mat& a) -{ return a <= alpha; } - -static inline MatExpr_ >, Mat> -operator > (double alpha, const Mat& a) -{ return a < alpha; } - -static inline MatExpr_ >, Mat> -operator <= (double alpha, const Mat& a) -{ return a >= alpha; } - -static inline MatExpr_ >, Mat> -operator < (double alpha, const Mat& a) -{ return a > alpha; } - -static inline MatExpr_ >, Mat> -operator != (double alpha, const Mat& a) -{ return a != alpha; } + bitwise_xor(a, s, (Mat&)a); + return (Mat_<_Tp>&)a; +} /////////////////////////////// Miscellaneous operations ////////////////////////////// -// max(A, B) -static inline MatExpr_ >, Mat> -max(const Mat& a, const Mat& b) -{ - typedef MatExpr_Op3_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp(a, b, 'M')); -} - -// min(A, B) -static inline MatExpr_ >, Mat> -min(const Mat& a, const Mat& b) -{ - typedef MatExpr_Op3_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp(a, b, 'm')); -} - -// abs(A) -static inline MatExpr_ >, Mat> -abs(const Mat& a) -{ - typedef MatExpr_Op3_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp(a, Scalar(0), 'a')); -} - -// max(A, B) -template static inline -MatExpr_ >, Mat > -max(const Mat_<_Tp>& a, const Mat_<_Tp>& b) -{ - typedef MatExpr_Op3_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp( - a, b, 'M')); -} - -// min(A, B) -template static inline -MatExpr_ >, Mat > -min(const Mat_<_Tp>& a, const Mat_<_Tp>& b) -{ - typedef MatExpr_Op3_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp( - a, b, 'm')); -} - -// abs(A) -template static inline -MatExpr_ >, Mat > -abs(const Mat_<_Tp>& a, const Mat_<_Tp>& b) -{ - typedef MatExpr_Op3_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp( - a, Scalar(0), 'a')); -} - -template static inline -MatExpr_ >, M> -max(const MatExpr_& a, const M& b) -{ return max((M)a, b); } - -template static inline -MatExpr_ >, M> -max(const M& a, const MatExpr_& b) -{ return max(a, (M)b); } - -template static inline -MatExpr_ >, M> -min(const MatExpr_& a, const M& b) -{ return min((M)a, b); } - -template static inline -MatExpr_ >, M> -min(const M& a, const MatExpr_& b) -{ return min(a, (M)b); } - -// abs(A) -template static inline -MatExpr_ >, M> -abs(const MatExpr_ >, M>& a) -{ - typedef MatExpr_Op3_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp((M)a.e.a1, (M)a.e.a2, 'a')); -} - +static inline void merge(const vector& mv, Mat& dst) +{ merge(&mv[0], mv.size(), dst); } + template void merge(const Mat_<_Tp>* mvbegin, size_t count, Mat& dst) { merge( (const Mat*)mvbegin, count, dst ); } @@ -3193,315 +1414,49 @@ static inline void split(const Mat& m, vector& mv) mv.resize(m.channels()); if(m.channels() > 0) split(m, &mv[0]); -} +} template void split(const Mat& src, vector >& mv) { split(src, (vector&)mv ); } - -static inline void merge(const vector& mv, Mat& dst) -{ merge(&mv[0], mv.size(), dst); } static inline void mixChannels(const vector& src, vector& dst, const int* fromTo, int npairs) { mixChannels(&src[0], (int)src.size(), &dst[0], (int)dst.size(), fromTo, npairs); } + +////////////////////////////////////////////////////////////// -///// Element-wise multiplication - -inline MatExpr_ >, Mat> -Mat::mul(const Mat& m, double scale) const -{ - typedef MatExpr_Op4_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp(*this, m, scale, '*')); -} - -inline MatExpr_ >, Mat> -Mat::mul(const MatExpr_ >, Mat>& m, double scale) const -{ - typedef MatExpr_Op4_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp(*this, m.e.a1, m.e.a2*scale, '*')); -} - -inline MatExpr_ >, Mat> -Mat::mul(const MatExpr_ >, Mat>& m, double scale) const -{ - typedef MatExpr_Op4_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp(*this, m.e.a1, scale/m.e.a2, '/')); -} - -template inline -MatExpr_ >, Mat > -Mat_<_Tp>::mul(const Mat_<_Tp>& m, double scale) const -{ - typedef MatExpr_Op4_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp(*this, m, scale, '*')); -} - -template inline -MatExpr_ >, Mat > -Mat_<_Tp>::mul(const MatExpr_ >, Mat >& m, double scale) const -{ - typedef MatExpr_Op4_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp(*this, m.e.a1, m.e.a2*scale, '*')); -} - -template inline -MatExpr_ >, Mat > -Mat_<_Tp>::mul(const MatExpr_ >, Mat >& m, double scale) const -{ - typedef MatExpr_Op4_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp(*this, m.e.a1, scale/m.e.a2, '/')); -} - -template static inline -MatExpr_ >, M> -operator * (const MatExpr_ >, M>& a, - double alpha) -{ - typedef MatExpr_Op4_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp((M)a.e.a1, (M)a.e.a2, a.e.a3*alpha, a.e.a4)); -} - -template static inline -MatExpr_ >, M> -operator * (double alpha, - const MatExpr_ >, M>& a) -{ return a*alpha; } - - -////// Element-wise division - -static inline MatExpr_ >, Mat> -operator / (const Mat& a, const Mat& b) -{ - typedef MatExpr_Op4_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp(a, b, 1, '/')); -} - -template static inline -MatExpr_ >, Mat > -operator / (const Mat& a, const Mat& b) -{ - typedef MatExpr_Op4_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp(a, b, 1, '/')); -} - -template static inline -MatExpr_ >, M> -operator / (const MatExpr_& a, const MatExpr_& b) -{ return (M)a/(M)b; } - -template static inline -MatExpr_ >, M> -operator / (const MatExpr_& a, const M& b) -{ return (M)a/b; } - -template static inline -MatExpr_ >, M> -operator / (const M& a, const MatExpr_& b) -{ return a/(M)b; } - -template static inline -MatExpr_ >, M> -operator / (const MatExpr_ >, M>& a, - const M& b) -{ return ((M)a.e.a1/b)*a.e.a2; } - -template static inline -MatExpr_ >, M> -operator / (const M& a, - const MatExpr_ >, M>& b) -{ return (a/(M)b.e.a1)*(1./b.e.a2); } - -template static inline -MatExpr_ >, M> -operator / (const MatExpr_ >, M>& a, - const MatExpr_ >, M>& b) -{ return ((M)a.e.a1/(M)b.e.a1)*(a.e.a2/b.e.a2); } - -template static inline -MatExpr_ >, M> -operator / (const M& a, - const MatExpr_ >, M>& b) -{ return a.mul((M)b.e.a1, 1./b.e.a2); } - -template static inline -MatExpr_ >, M> -operator / (const MatExpr_& a, - const MatExpr_ >, M>& b) -{ return ((M)a).mul((M)b.e.a1, 1./b.e.a2); } - -static inline -MatExpr_ >, Mat > -operator / (double alpha, const Mat& a) -{ - typedef MatExpr_Op2_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp(a, alpha)); -} - -static inline Mat& operator /= (const Mat& a, double alpha) -{ - MatOp_Scale_::apply( a, 1./alpha, (Mat&)a ); - return (Mat&)a; -} - -template -static inline Mat_<_Tp>& operator /= (const Mat_<_Tp>& a, double alpha) -{ - MatOp_Scale_::apply( a, 1./alpha, (Mat&)a ); - return (Mat_<_Tp>&)a; -} - -template static inline -MatExpr_ >, Mat > -operator / (double alpha, const Mat_<_Tp>& a) -{ - typedef MatExpr_Op2_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp(a, alpha)); -} - -template static inline -MatExpr_ >, M> -operator / (double alpha, const MatExpr_& a) -{ return alpha/(M)a; } - -template static inline -MatExpr_ >, M> -operator / (double alpha, - const MatExpr_ >, M>& a) -{ return (alpha/a.e.a2)/(M)a.e.a1; } - -template static inline -MatExpr_ >, M> -operator / (double alpha, - const MatExpr_ >, M>& a) -{ return (M)a.e.a1*(alpha/a.e.a2); } - -static inline Mat& operator /= (const Mat& a, const Mat& b) -{ - MatOp_MulDiv_::apply( a, b, 1, '/', (Mat&)a ); - return (Mat&)a; -} - -template -static inline M& operator /= (const M& a, const MatExpr_ >, M>& b) -{ - MatOp_MulDiv_::apply( a, (M)b.e.a1, 1./b.e.a2, '/', (M&)a ); - return (M&)a; -} - -template -static inline M& operator /= (const M& a, const MatExpr_ >, M>& b) -{ - MatOp_MulDiv_::apply( a, (M)b.e.a1, 1./b.e.a2, '*', (M&)a ); - return (M&)a; -} - -// Mat Inversion and solving linear systems - -inline MatExpr_ >, Mat> -Mat::inv(int method) const -{ - typedef MatExpr_Op2_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp(*this, method)); -} - -template inline -MatExpr_ >, Mat > -Mat_<_Tp>::inv(int method) const -{ - typedef MatExpr_Op2_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp(*this, method)); -} - -template static inline -MatExpr_ >, M> -operator * (const MatExpr_ >, M>& a, - const M& b) -{ - typedef MatExpr_Op3_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp((M)a.e.a1, b, a.e.a2)); -} - -template static inline -MatExpr_ >, M> -operator * (const MatExpr_ >, M>& a, - const MatExpr_& b) -{ return a*(M)b; } - - -/////////////////////////////// Initialization //////////////////////////////////////// - -inline MatExpr_Initializer Mat::zeros(int rows, int cols, int type) -{ - typedef MatExpr_Op4_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp(Size(cols, rows), type, 0, 0)); -} - -inline MatExpr_Initializer Mat::zeros(Size size, int type) -{ - return zeros(size.height, size.width, type); -} - -inline MatExpr_Initializer Mat::ones(int rows, int cols, int type) +template inline MatExpr Mat_<_Tp>::zeros(int rows, int cols) { - typedef MatExpr_Op4_ > MatExpr_Temp; - return MatExpr_(MatExpr_Temp(Size(cols, rows), type, 1, 1)); + return Mat::zeros(rows, cols, DataType<_Tp>::type); } - -inline MatExpr_Initializer Mat::ones(Size size, int type) + +template inline MatExpr Mat_<_Tp>::zeros(Size sz) { - return ones(size.height, size.width, type); -} - -inline MatExpr_Initializer Mat::eye(int rows, int cols, int type) + return Mat::zeros(sz, DataType<_Tp>::type); +} + +template inline MatExpr Mat_<_Tp>::ones(int rows, int cols) { - typedef MatExpr_Op4_ > MatExpr_Temp; - return MatExpr_Initializer(MatExpr_Temp(Size(cols, rows), type, 1, 2)); + return Mat::ones(rows, cols, DataType<_Tp>::type); } -inline MatExpr_Initializer Mat::eye(Size size, int type) +template inline MatExpr Mat_<_Tp>::ones(Size sz) { - return eye(size.height, size.width, type); -} - -static inline MatExpr_Initializer operator * (const MatExpr_Initializer& a, double alpha) + return Mat::ones(sz, DataType<_Tp>::type); +} + +template inline MatExpr Mat_<_Tp>::eye(int rows, int cols) { - typedef MatExpr_Op4_ > MatExpr_Temp; - return MatExpr_Initializer(MatExpr_Temp(a.e.a1, a.e.a2, a.e.a3*alpha, a.e.a4)); + return Mat::eye(rows, cols, DataType<_Tp>::type); } -static inline MatExpr_Initializer operator * (double alpha, MatExpr_Initializer& a) +template inline MatExpr Mat_<_Tp>::eye(Size sz) { - typedef MatExpr_Op4_ > MatExpr_Temp; - return MatExpr_Initializer(MatExpr_Temp(a.e.a1, a.e.a2, a.e.a3*alpha, a.e.a4)); -} - -template inline MatExpr_Initializer Mat_<_Tp>::zeros(int rows, int cols) -{ return Mat::zeros(rows, cols, DataType<_Tp>::type); } - -template inline MatExpr_Initializer Mat_<_Tp>::zeros(Size size) -{ return Mat::zeros(size, DataType<_Tp>::type); } - -template inline MatExpr_Initializer Mat_<_Tp>::ones(int rows, int cols) -{ return Mat::ones(rows, cols, DataType<_Tp>::type); } - -template inline MatExpr_Initializer Mat_<_Tp>::ones(Size size) -{ return Mat::ones(size, DataType<_Tp>::type); } - -template inline MatExpr_Initializer Mat_<_Tp>::eye(int rows, int cols) -{ return Mat::eye(rows, cols, DataType<_Tp>::type); } - -template inline MatExpr_Initializer Mat_<_Tp>::eye(Size size) -{ return Mat::eye(size, DataType<_Tp>::type); } - - + return Mat::eye(sz, DataType<_Tp>::type); +} + //////////// Iterators & Comma initializers ////////////////// template inline MatConstIterator_<_Tp>::MatConstIterator_() @@ -3796,38 +1751,28 @@ template inline MatIterator_<_Tp> Mat_<_Tp>::begin() template inline MatIterator_<_Tp> Mat_<_Tp>::end() { return Mat::end<_Tp>(); } -template class CV_EXPORTS MatOp_Iter_ -{ -public: - MatOp_Iter_() {} - - static void apply(const MatIterator_<_Tp>& a, Mat& c, int type=-1) - { - if( type < 0 ) - c = *a.m; - else - a.m->convertTo(c, type); - } -}; - -template inline MatCommaInitializer_<_Tp>::MatCommaInitializer_(Mat_<_Tp>* _m) : - MatExpr_, Mat_<_Tp>, - MatOp_Iter_<_Tp> >, Mat_<_Tp> >(MatIterator_<_Tp>(_m)) {} +template inline MatCommaInitializer_<_Tp>::MatCommaInitializer_(Mat_<_Tp>* _m) : it(_m) {} template template inline MatCommaInitializer_<_Tp>& MatCommaInitializer_<_Tp>::operator , (T2 v) { - CV_DbgAssert( this->e.a1 < this->e.a1.m->end() ); - *this->e.a1 = _Tp(v); ++this->e.a1; + CV_DbgAssert( this->it < this->it.m->end() ); + *this->it = _Tp(v); ++this->it; return *this; } template inline Mat_<_Tp> MatCommaInitializer_<_Tp>::operator *() const { - CV_DbgAssert( this->e.a1 == this->e.a1.m->end() ); - return *this->e.a1.m; + CV_DbgAssert( this->it == this->it.m->end() ); + return *this->it.m; } +template inline MatCommaInitializer_<_Tp>::operator Mat_<_Tp>() const +{ + CV_DbgAssert( this->it == this->it.m->end() ); + return *this->it.m; +} + template inline void MatCommaInitializer_<_Tp>::assignTo(Mat& m, int type) const { diff --git a/modules/core/include/opencv2/core/operations.hpp b/modules/core/include/opencv2/core/operations.hpp index 5a902bf2a3..ef530fef07 100644 --- a/modules/core/include/opencv2/core/operations.hpp +++ b/modules/core/include/opencv2/core/operations.hpp @@ -1996,6 +1996,11 @@ template inline Scalar_<_Tp> Scalar_<_Tp>::conj() const saturate_cast<_Tp>(-this->val[3])); } +template inline bool Scalar_<_Tp>::isReal() const +{ + return this->val[1] == 0 && this->val[2] == 0 && this->val[3] == 0; +} + template static inline Scalar_<_Tp> operator / (const Scalar_<_Tp>& a, _Tp alpha) { diff --git a/modules/core/src/matop.cpp b/modules/core/src/matop.cpp new file mode 100644 index 0000000000..9ec5cde78e --- /dev/null +++ b/modules/core/src/matop.cpp @@ -0,0 +1,1715 @@ +/*M/////////////////////////////////////////////////////////////////////////////////////// +// +// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. +// +// By downloading, copying, installing or using the software you agree to this license. +// If you do not agree to this license, do not download, install, +// copy or use the software. +// +// +// License Agreement +// For Open Source Computer Vision Library +// +// Copyright (C) 2000-2008, Intel Corporation, all rights reserved. +// Copyright (C) 2009-2010, Willow Garage Inc., all rights reserved. +// Third party copyrights are property of their respective owners. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// * Redistribution's of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistribution's in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * The name of the copyright holders may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// This software is provided by the copyright holders and contributors "as is" and +// any express or implied warranties, including, but not limited to, the implied +// warranties of merchantability and fitness for a particular purpose are disclaimed. +// In no event shall the Intel Corporation or contributors be liable for any direct, +// indirect, incidental, special, exemplary, or consequential damages +// (including, but not limited to, procurement of substitute goods or services; +// loss of use, data, or profits; or business interruption) however caused +// and on any theory of liability, whether in contract, strict liability, +// or tort (including negligence or otherwise) arising in any way out of +// the use of this software, even if advised of the possibility of such damage. +// +//M*/ + +/* //////////////////////////////////////////////////////////////////// +// +// Mat basic operations: Copy, Set +// +// */ + +#include "precomp.hpp" + +namespace cv +{ + +class MatOp_Identity : public MatOp +{ +public: + MatOp_Identity() {} + virtual ~MatOp_Identity() {} + + bool elementWise(const MatExpr& expr) const { return true; } + void assign(const MatExpr& expr, Mat& m, int type=-1) const; + + void add(const MatExpr& e1, const MatExpr& e2, MatExpr& res) const; + void add(const MatExpr& e1, const Scalar& s, MatExpr& res) const; + void subtract(const MatExpr& e1, const MatExpr& e2, MatExpr& res) const; + void subtract(const Scalar& s, const MatExpr& expr, MatExpr& res) const; + void multiply(const MatExpr& e1, const MatExpr& e2, MatExpr& res, double scale=1) const; + void multiply(const MatExpr& e1, double s, MatExpr& res) const; + void divide(const MatExpr& e1, const MatExpr& e2, MatExpr& res, double scale=1) const; + void divide(double s, const MatExpr& e, MatExpr& res) const; + + void matmul(const MatExpr& expr1, const MatExpr& expr2, MatExpr& res) const; + + static void makeExpr(MatExpr& res, const Mat& m); +}; + +static MatOp_Identity g_MatOp_Identity; + +class MatOp_AddEx : public MatOp +{ +public: + MatOp_AddEx() {} + virtual ~MatOp_AddEx() {} + + bool elementWise(const MatExpr& expr) const { return true; } + void assign(const MatExpr& expr, Mat& m, int type=-1) const; + + void add(const MatExpr& e1, const MatExpr& e2, MatExpr& res) const; + void add(const MatExpr& e1, const Scalar& s, MatExpr& res) const; + + void subtract(const MatExpr& e1, const MatExpr& e2, MatExpr& res) const; + void subtract(const Scalar& s, const MatExpr& expr, MatExpr& res) const; + + void multiply(const MatExpr& e1, const MatExpr& e2, MatExpr& res, double scale=1) const; + void multiply(const MatExpr& e1, double s, MatExpr& res) const; + + void divide(const MatExpr& e1, const MatExpr& e2, MatExpr& res, double scale=1) const; + void divide(double s, const MatExpr& e, MatExpr& res) const; + + void transpose(const MatExpr& e1, MatExpr& res) const; + void abs(const MatExpr& expr, MatExpr& res) const; + void matmul(const MatExpr& expr1, const MatExpr& expr2, MatExpr& res) const; + + static void makeExpr(MatExpr& res, const Mat& a, const Mat& b, double alpha, double beta, const Scalar& s=Scalar()); +}; + +static MatOp_AddEx g_MatOp_AddEx; + +class MatOp_Bin : public MatOp +{ +public: + MatOp_Bin() {} + virtual ~MatOp_Bin() {} + + bool elementWise(const MatExpr& expr) const { return true; } + void assign(const MatExpr& expr, Mat& m, int type=-1) const; + + void multiply(const MatExpr& e1, const MatExpr& e2, MatExpr& res, double scale=1) const; + void multiply(const MatExpr& e1, double s, MatExpr& res) const; + + void divide(const MatExpr& e1, const MatExpr& e2, MatExpr& res, double scale=1) const; + void divide(double s, const MatExpr& e, MatExpr& res) const; + + static void makeExpr(MatExpr& res, char op, const Mat& a, const Mat& b, double scale=1); + static void makeExpr(MatExpr& res, char op, const Mat& a, const Scalar& s); +}; + +static MatOp_Bin g_MatOp_Bin; + +class MatOp_Cmp : public MatOp +{ +public: + MatOp_Cmp() {} + virtual ~MatOp_Cmp() {} + + bool elementWise(const MatExpr& expr) const { return true; } + void assign(const MatExpr& expr, Mat& m, int type=-1) const; + + static void makeExpr(MatExpr& res, int cmpop, const Mat& a, const Mat& b); + static void makeExpr(MatExpr& res, int cmpop, const Mat& a, double alpha); +}; + +static MatOp_Cmp g_MatOp_Cmp; + +class MatOp_GEMM : public MatOp +{ +public: + MatOp_GEMM() {} + virtual ~MatOp_GEMM() {} + + bool elementWise(const MatExpr& expr) const { return false; } + void assign(const MatExpr& expr, Mat& m, int type=-1) const; + + void add(const MatExpr& e1, const MatExpr& e2, MatExpr& res) const; + void subtract(const MatExpr& e1, const MatExpr& e2, MatExpr& res) const; + void multiply(const MatExpr& e, double s, MatExpr& res) const; + + void transpose(const MatExpr& expr, MatExpr& res) const; + + static void makeExpr(MatExpr& res, int flags, const Mat& a, const Mat& b, + double alpha=1, const Mat& c=Mat(), double beta=1); +}; + +static MatOp_GEMM g_MatOp_GEMM; + +class MatOp_Invert : public MatOp +{ +public: + MatOp_Invert() {} + virtual ~MatOp_Invert() {} + + bool elementWise(const MatExpr& expr) const { return false; } + void assign(const MatExpr& expr, Mat& m, int type=-1) const; + + void matmul(const MatExpr& expr1, const MatExpr& expr2, MatExpr& res) const; + + static void makeExpr(MatExpr& res, int method, const Mat& m); +}; + +static MatOp_Invert g_MatOp_Invert; + +class MatOp_T : public MatOp +{ +public: + MatOp_T() {} + virtual ~MatOp_T() {} + + bool elementWise(const MatExpr& expr) const { return false; } + void assign(const MatExpr& expr, Mat& m, int type=-1) const; + + void multiply(const MatExpr& e1, double s, MatExpr& res) const; + void transpose(const MatExpr& expr, MatExpr& res) const; + void matmul(const MatExpr& expr1, const MatExpr& expr2, MatExpr& res) const; + + static void makeExpr(MatExpr& res, const Mat& a, double alpha=1); +}; + +static MatOp_T g_MatOp_T; + +class MatOp_Solve : public MatOp +{ +public: + MatOp_Solve() {} + virtual ~MatOp_Solve() {} + + bool elementWise(const MatExpr& expr) const { return false; } + void assign(const MatExpr& expr, Mat& m, int type=-1) const; + + static void makeExpr(MatExpr& res, int method, const Mat& a, const Mat& b); +}; + +static MatOp_Solve g_MatOp_Solve; + +class MatOp_Initializer : public MatOp +{ +public: + MatOp_Initializer() {} + virtual ~MatOp_Initializer() {} + + bool elementWise(const MatExpr& expr) const { return false; } + void assign(const MatExpr& expr, Mat& m, int type=-1) const; + + void multiply(const MatExpr& e, double s, MatExpr& res) const; + + static void makeExpr(MatExpr& res, int method, Size sz, int type, double alpha=1); +}; + +static MatOp_Initializer g_MatOp_Initializer; + +static inline bool isIdentity(const MatExpr& e) { return e.op == &g_MatOp_Identity; } +static inline bool isAddEx(const MatExpr& e) { return e.op == &g_MatOp_AddEx; } +static inline bool isScaled(const MatExpr& e) { return isAddEx(e) && (!e.b.data || e.beta == 0) && e.s == Scalar(); } +static inline bool isBin(const MatExpr& e, char c) { return e.op == &g_MatOp_Bin && e.flags == c; } +static inline bool isReciprocal(const MatExpr& e) { return isBin(e,'/') && (!e.b.data || e.beta == 0); } +static inline bool isT(const MatExpr& e) { return e.op == &g_MatOp_T; } +static inline bool isInv(const MatExpr& e) { return e.op == &g_MatOp_Invert; } +static inline bool isGEMM(const MatExpr& e) { return e.op == &g_MatOp_GEMM; } +static inline bool isMatProd(const MatExpr& e) { return e.op == &g_MatOp_GEMM && (!e.c.data || e.beta == 0); } +static inline bool isInitializer(const MatExpr& e) { return e.op == &g_MatOp_Initializer; } + +///////////////////////////////////////////////////////////////////////////////////////////////////// + +bool MatOp::elementWise(const MatExpr& expr) const +{ + return false; +} + +void MatOp::roi(const MatExpr& expr, const Range& rowRange, const Range& colRange, MatExpr& e) const +{ + if( elementWise(expr) ) + { + e = MatExpr(expr.op, expr.flags, Mat(), Mat(), Mat(), + expr.alpha, expr.beta, expr.s); + if(expr.a.data) + e.a = expr.a(rowRange, colRange); + if(expr.b.data) + e.b = expr.b(rowRange, colRange); + if(expr.c.data) + e.c = expr.c(rowRange, colRange); + } + else + { + Mat m; + expr.op->assign(expr, m); + e = MatExpr(&g_MatOp_Identity, 0, m(rowRange, colRange), Mat(), Mat()); + } +} + +void MatOp::diag(const MatExpr& expr, int d, MatExpr& e) const +{ + if( elementWise(expr) ) + { + e = MatExpr(expr.op, expr.flags, Mat(), Mat(), Mat(), + expr.alpha, expr.beta, expr.s); + if(expr.a.data) + e.a = expr.a.diag(d); + if(expr.b.data) + e.b = expr.b.diag(d); + if(expr.c.data) + e.c = expr.c.diag(d); + } + else + { + Mat m; + expr.op->assign(expr, m); + e = MatExpr(&g_MatOp_Identity, 0, m.diag(d), Mat(), Mat()); + } +} + + +void MatOp::augAssignAdd(const MatExpr& expr, Mat& m) const +{ + Mat temp; + expr.op->assign(expr, temp); + m += temp; +} + + +void MatOp::augAssignSubtract(const MatExpr& expr, Mat& m) const +{ + Mat temp; + expr.op->assign(expr, temp); + m -= temp; +} + + +void MatOp::augAssignMultiply(const MatExpr& expr, Mat& m) const +{ + Mat temp; + expr.op->assign(expr, temp); + m *= temp; +} + + +void MatOp::augAssignDivide(const MatExpr& expr, Mat& m) const +{ + Mat temp; + expr.op->assign(expr, temp); + m /= temp; +} + + +void MatOp::augAssignAnd(const MatExpr& expr, Mat& m) const +{ + Mat temp; + expr.op->assign(expr, temp); + m &= temp; +} + + +void MatOp::augAssignOr(const MatExpr& expr, Mat& m) const +{ + Mat temp; + expr.op->assign(expr, temp); + m |= temp; +} + + +void MatOp::augAssignXor(const MatExpr& expr, Mat& m) const +{ + Mat temp; + expr.op->assign(expr, temp); + m /= temp; +} + + +void MatOp::add(const MatExpr& expr1, const MatExpr& expr2, MatExpr& res) const +{ + if( this == expr2.op ) + { + Mat m1, m2; + expr1.op->assign(expr1, m1); + expr2.op->assign(expr2, m2); + MatOp_AddEx::makeExpr(res, m1, m2, 1, 1); + } + else + expr2.op->add(expr1, expr2, res); +} + + +void MatOp::add(const MatExpr& expr1, const Scalar& s, MatExpr& res) const +{ + Mat m1; + expr1.op->assign(expr1, m1); + MatOp_AddEx::makeExpr(res, m1, Mat(), 1, 0, s); +} + + +void MatOp::subtract(const MatExpr& expr1, const MatExpr& expr2, MatExpr& res) const +{ + if( this == expr2.op ) + { + Mat m1, m2; + expr1.op->assign(expr1, m1); + expr2.op->assign(expr2, m2); + MatOp_AddEx::makeExpr(res, m1, m2, 1, -1); + } + else + expr2.op->subtract(expr1, expr2, res); +} + + +void MatOp::subtract(const Scalar& s, const MatExpr& expr, MatExpr& res) const +{ + Mat m; + expr.op->assign(expr, m); + MatOp_AddEx::makeExpr(res, m, Mat(), -1, 0, s); +} + + +void MatOp::multiply(const MatExpr& expr1, const MatExpr& expr2, MatExpr& res, double scale) const +{ + if( this == expr2.op ) + { + Mat m1, m2; + expr1.op->assign(expr1, m1); + expr2.op->assign(expr2, m2); + MatOp_Bin::makeExpr(res, '*', m1, m2, scale); + } + else + expr2.op->multiply(expr1, expr2, res, scale); +} + + +void MatOp::multiply(const MatExpr& expr, double s, MatExpr& res) const +{ + Mat m; + expr.op->assign(expr, m); + MatOp_AddEx::makeExpr(res, m, Mat(), s, 0); +} + + +void MatOp::divide(const MatExpr& expr1, const MatExpr& expr2, MatExpr& res, double scale) const +{ + if( this == expr2.op ) + { + Mat m1, m2; + expr1.op->assign(expr1, m1); + expr2.op->assign(expr2, m2); + MatOp_Bin::makeExpr(res, '/', m1, m2, scale); + } + else + expr2.op->divide(expr1, expr2, res, scale); +} + + +void MatOp::divide(double s, const MatExpr& expr, MatExpr& res) const +{ + Mat m; + expr.op->assign(expr, m); + MatOp_Bin::makeExpr(res, '/', m, Mat(), s); +} + + +void MatOp::abs(const MatExpr& expr, MatExpr& res) const +{ + Mat m; + expr.op->assign(expr, m); + MatOp_Bin::makeExpr(res, 'a', m, Mat()); +} + + +void MatOp::transpose(const MatExpr& expr, MatExpr& res) const +{ + Mat m; + expr.op->assign(expr, m); + MatOp_T::makeExpr(res, m, 1); +} + + +void MatOp::matmul(const MatExpr& expr1, const MatExpr& expr2, MatExpr& res) const +{ + if( this == expr2.op ) + { + Mat m1, m2; + expr1.op->assign(expr1, m1); + expr2.op->assign(expr2, m2); + MatOp_GEMM::makeExpr(res, 0, m1, m2); + } + else + expr2.op->matmul(expr1, expr2, res); +} + + +void MatOp::invert(const MatExpr& expr, int method, MatExpr& res) const +{ + Mat m; + expr.op->assign(expr, m); + MatOp_Invert::makeExpr(res, method, m); +} + +////////////////////////////////////////////////////////////////////////////////////////////////// + +MatExpr::MatExpr(const Mat& m) : op(&g_MatOp_Identity), flags(0), a(m), b(Mat()), c(Mat()), alpha(1), beta(0), s(Scalar()) +{ +} + +MatExpr MatExpr::row(int y) const +{ + MatExpr e; + op->roi(*this, Range(y, y+1), Range::all(), e); + return e; +} + +MatExpr MatExpr::col(int x) const +{ + MatExpr e; + op->roi(*this, Range::all(), Range(x, x+1), e); + return e; +} + +MatExpr MatExpr::diag(int d) const +{ + MatExpr e; + op->diag(*this, d, e); + return e; +} + +MatExpr MatExpr::operator()( const Range& rowRange, const Range& colRange ) const +{ + MatExpr e; + op->roi(*this, rowRange, colRange, e); + return e; +} + +MatExpr MatExpr::operator()( const Rect& roi ) const +{ + MatExpr e; + op->roi(*this, Range(roi.y, roi.y + roi.height), Range(roi.x, roi.x + roi.width), e); + return e; +} + +Mat MatExpr::cross(const Mat& m) const +{ + return ((Mat)*this).cross(m); +} + +double MatExpr::dot(const Mat& m) const +{ + return ((Mat)*this).dot(m); +} + +MatExpr MatExpr::t() const +{ + MatExpr e; + op->transpose(*this, e); + return e; +} + +MatExpr MatExpr::inv(int method) const +{ + MatExpr e; + op->invert(*this, method, e); + return e; +} + +MatExpr MatExpr::mul(const MatExpr& e, double scale) const +{ + MatExpr en; + op->multiply(*this, e, en, scale); + return en; +} + +MatExpr MatExpr::mul(const Mat& m, double scale) const +{ + MatExpr e; + op->multiply(*this, MatExpr(m), e, scale); + return e; +} + +MatExpr operator + (const Mat& a, const Mat& b) +{ + MatExpr e; + MatOp_AddEx::makeExpr(e, a, b, 1, 1); + return e; +} + +MatExpr operator + (const Mat& a, const Scalar& s) +{ + MatExpr e; + MatOp_AddEx::makeExpr(e, a, Mat(), 1, 0, s); + return e; +} + +MatExpr operator + (const Scalar& s, const Mat& a) +{ + MatExpr e; + MatOp_AddEx::makeExpr(e, a, Mat(), 1, 0, s); + return e; +} + +MatExpr operator + (const MatExpr& e, const Mat& m) +{ + MatExpr en; + e.op->add(e, MatExpr(m), en); + return en; +} + +MatExpr operator + (const Mat& m, const MatExpr& e) +{ + MatExpr en; + e.op->add(e, MatExpr(m), en); + return en; +} + +MatExpr operator + (const MatExpr& e, const Scalar& s) +{ + MatExpr en; + e.op->add(e, s, en); + return en; +} + +MatExpr operator + (const Scalar& s, const MatExpr& e) +{ + MatExpr en; + e.op->add(e, s, en); + return en; +} + +MatExpr operator + (const MatExpr& e1, const MatExpr& e2) +{ + MatExpr en; + e1.op->add(e1, e2, en); + return en; +} + +MatExpr operator - (const Mat& a, const Mat& b) +{ + MatExpr e; + MatOp_AddEx::makeExpr(e, a, b, 1, -1); + return e; +} + +MatExpr operator - (const Mat& a, const Scalar& s) +{ + MatExpr e; + MatOp_AddEx::makeExpr(e, a, Mat(), 1, 0, -s); + return e; +} + +MatExpr operator - (const Scalar& s, const Mat& a) +{ + MatExpr e; + MatOp_AddEx::makeExpr(e, a, Mat(), -1, 0, s); + return e; +} + +MatExpr operator - (const MatExpr& e, const Mat& m) +{ + MatExpr en; + e.op->subtract(e, MatExpr(m), en); + return en; +} + +MatExpr operator - (const Mat& m, const MatExpr& e) +{ + MatExpr en; + e.op->subtract(MatExpr(m), e, en); + return en; +} + +MatExpr operator - (const MatExpr& e, const Scalar& s) +{ + MatExpr en; + e.op->add(e, -s, en); + return en; +} + +MatExpr operator - (const Scalar& s, const MatExpr& e) +{ + MatExpr en; + e.op->subtract(s, e, en); + return en; +} + +MatExpr operator - (const MatExpr& e1, const MatExpr& e2) +{ + MatExpr en; + e1.op->subtract(e1, e2, en); + return en; +} + +MatExpr operator - (const Mat& m) +{ + MatExpr e; + MatOp_AddEx::makeExpr(e, m, Mat(), -1, 0); + return e; +} + +MatExpr operator - (const MatExpr& e) +{ + MatExpr en; + e.op->subtract(Scalar(0), e, en); + return en; +} + +MatExpr operator * (const Mat& a, const Mat& b) +{ + MatExpr e; + MatOp_GEMM::makeExpr(e, 0, a, b); + return e; +} + +MatExpr operator * (const Mat& a, double s) +{ + MatExpr e; + MatOp_AddEx::makeExpr(e, a, Mat(), s, 0); + return e; +} + +MatExpr operator * (double s, const Mat& a) +{ + MatExpr e; + MatOp_AddEx::makeExpr(e, a, Mat(), s, 0); + return e; +} + +MatExpr operator * (const MatExpr& e, const Mat& m) +{ + MatExpr en; + e.op->matmul(e, MatExpr(m), en); + return en; +} + +MatExpr operator * (const Mat& m, const MatExpr& e) +{ + MatExpr en; + e.op->matmul(MatExpr(m), e, en); + return en; +} + +MatExpr operator * (const MatExpr& e, double s) +{ + MatExpr en; + e.op->multiply(e, s, en); + return en; +} + +MatExpr operator * (double s, const MatExpr& e) +{ + MatExpr en; + e.op->multiply(e, s, en); + return en; +} + +MatExpr operator * (const MatExpr& e1, const MatExpr& e2) +{ + MatExpr en; + e1.op->matmul(e1, e2, en); + return en; +} + +MatExpr operator / (const Mat& a, const Mat& b) +{ + MatExpr e; + MatOp_Bin::makeExpr(e, '/', a, b); + return e; +} + +MatExpr operator / (const Mat& a, double s) +{ + MatExpr e; + MatOp_AddEx::makeExpr(e, a, Mat(), 1./s, 0); + return e; +} + +MatExpr operator / (double s, const Mat& a) +{ + MatExpr e; + MatOp_Bin::makeExpr(e, '/', a, Mat(), s); + return e; +} + +MatExpr operator / (const MatExpr& e, const Mat& m) +{ + MatExpr en; + e.op->divide(e, MatExpr(m), en); + return en; +} + +MatExpr operator / (const Mat& m, const MatExpr& e) +{ + MatExpr en; + e.op->divide(MatExpr(m), e, en); + return en; +} + +MatExpr operator / (const MatExpr& e, double s) +{ + MatExpr en; + e.op->multiply(e, 1./s, en); + return en; +} + +MatExpr operator / (double s, const MatExpr& e) +{ + MatExpr en; + e.op->divide(s, e, en); + return en; +} + +MatExpr operator / (const MatExpr& e1, const MatExpr& e2) +{ + MatExpr en; + e1.op->divide(e1, e2, en); + return en; +} + +MatExpr operator < (const Mat& a, const Mat& b) +{ + MatExpr e; + MatOp_Cmp::makeExpr(e, CV_CMP_LT, a, b); + return e; +} + +MatExpr operator < (const Mat& a, double s) +{ + MatExpr e; + MatOp_Cmp::makeExpr(e, CV_CMP_LT, a, s); + return e; +} + +MatExpr operator < (double s, const Mat& a) +{ + MatExpr e; + MatOp_Cmp::makeExpr(e, CV_CMP_GT, a, s); + return e; +} + +MatExpr operator <= (const Mat& a, const Mat& b) +{ + MatExpr e; + MatOp_Cmp::makeExpr(e, CV_CMP_LE, a, b); + return e; +} + +MatExpr operator <= (const Mat& a, double s) +{ + MatExpr e; + MatOp_Cmp::makeExpr(e, CV_CMP_LE, a, s); + return e; +} + +MatExpr operator <= (double s, const Mat& a) +{ + MatExpr e; + MatOp_Cmp::makeExpr(e, CV_CMP_GE, a, s); + return e; +} + +MatExpr operator == (const Mat& a, const Mat& b) +{ + MatExpr e; + MatOp_Cmp::makeExpr(e, CV_CMP_EQ, a, b); + return e; +} + +MatExpr operator == (const Mat& a, double s) +{ + MatExpr e; + MatOp_Cmp::makeExpr(e, CV_CMP_EQ, a, s); + return e; +} + +MatExpr operator == (double s, const Mat& a) +{ + MatExpr e; + MatOp_Cmp::makeExpr(e, CV_CMP_EQ, a, s); + return e; +} + +MatExpr operator != (const Mat& a, const Mat& b) +{ + MatExpr e; + MatOp_Cmp::makeExpr(e, CV_CMP_NE, a, b); + return e; +} + +MatExpr operator != (const Mat& a, double s) +{ + MatExpr e; + MatOp_Cmp::makeExpr(e, CV_CMP_NE, a, s); + return e; +} + +MatExpr operator != (double s, const Mat& a) +{ + MatExpr e; + MatOp_Cmp::makeExpr(e, CV_CMP_NE, a, s); + return e; +} + +MatExpr operator >= (const Mat& a, const Mat& b) +{ + MatExpr e; + MatOp_Cmp::makeExpr(e, CV_CMP_GE, a, b); + return e; +} + +MatExpr operator >= (const Mat& a, double s) +{ + MatExpr e; + MatOp_Cmp::makeExpr(e, CV_CMP_GE, a, s); + return e; +} + +MatExpr operator >= (double s, const Mat& a) +{ + MatExpr e; + MatOp_Cmp::makeExpr(e, CV_CMP_LE, a, s); + return e; +} + +MatExpr operator > (const Mat& a, const Mat& b) +{ + MatExpr e; + MatOp_Cmp::makeExpr(e, CV_CMP_GT, a, b); + return e; +} + +MatExpr operator > (const Mat& a, double s) +{ + MatExpr e; + MatOp_Cmp::makeExpr(e, CV_CMP_GT, a, s); + return e; +} + +MatExpr operator > (double s, const Mat& a) +{ + MatExpr e; + MatOp_Cmp::makeExpr(e, CV_CMP_LT, a, s); + return e; +} + +MatExpr min(const Mat& a, const Mat& b) +{ + MatExpr e; + MatOp_Bin::makeExpr(e, 'm', a, b); + return e; +} + +MatExpr min(const Mat& a, double s) +{ + MatExpr e; + MatOp_Bin::makeExpr(e, 'm', a, s); + return e; +} + +MatExpr min(double s, const Mat& a) +{ + MatExpr e; + MatOp_Bin::makeExpr(e, 'm', a, s); + return e; +} + +MatExpr max(const Mat& a, const Mat& b) +{ + MatExpr e; + MatOp_Bin::makeExpr(e, 'M', a, b); + return e; +} + +MatExpr max(const Mat& a, double s) +{ + MatExpr e; + MatOp_Bin::makeExpr(e, 'M', a, s); + return e; +} + +MatExpr max(double s, const Mat& a) +{ + MatExpr e; + MatOp_Bin::makeExpr(e, 'M', a, s); + return e; +} + +MatExpr operator & (const Mat& a, const Mat& b) +{ + MatExpr e; + MatOp_Bin::makeExpr(e, '&', a, b); + return e; +} + +MatExpr operator & (const Mat& a, const Scalar& s) +{ + MatExpr e; + MatOp_Bin::makeExpr(e, '&', a, s); + return e; +} + +MatExpr operator & (const Scalar& s, const Mat& a) +{ + MatExpr e; + MatOp_Bin::makeExpr(e, '&', a, s); + return e; +} + +MatExpr operator | (const Mat& a, const Mat& b) +{ + MatExpr e; + MatOp_Bin::makeExpr(e, '|', a, b); + return e; +} + +MatExpr operator | (const Mat& a, const Scalar& s) +{ + MatExpr e; + MatOp_Bin::makeExpr(e, '|', a, s); + return e; +} + +MatExpr operator | (const Scalar& s, const Mat& a) +{ + MatExpr e; + MatOp_Bin::makeExpr(e, '|', a, s); + return e; +} + +MatExpr operator ^ (const Mat& a, const Mat& b) +{ + MatExpr e; + MatOp_Bin::makeExpr(e, '^', a, b); + return e; +} + +MatExpr operator ^ (const Mat& a, const Scalar& s) +{ + MatExpr e; + MatOp_Bin::makeExpr(e, '^', a, s); + return e; +} + +MatExpr operator ^ (const Scalar& s, const Mat& a) +{ + MatExpr e; + MatOp_Bin::makeExpr(e, '^', a, s); + return e; +} + +MatExpr operator ~(const Mat& a) +{ + MatExpr e; + MatOp_Bin::makeExpr(e, '~', a, Scalar()); + return e; +} + +MatExpr abs(const Mat& a) +{ + MatExpr e; + MatOp_Bin::makeExpr(e, 'a', a, Scalar()); + return e; +} + +MatExpr abs(const MatExpr& e) +{ + MatExpr en; + e.op->abs(e, en); + return en; +} + + +///////////////////////////////////////////////////////////////////////////////////////////////////// + +inline void MatOp_Identity::makeExpr(MatExpr& res, const Mat& m) +{ + res = MatExpr(&g_MatOp_Identity, 0, m, Mat(), Mat(), 1, 0); +} + +void MatOp_Identity::assign(const MatExpr& e, Mat& m, int type) const +{ + if( type == -1 || type == e.a.type() ) + m = e.a; + else + { + CV_Assert( CV_MAT_CN(type) == e.a.channels() ); + e.a.convertTo(m, type); + } +} + +void MatOp_Identity::add(const MatExpr& e1, const MatExpr& e2, MatExpr& res) const +{ + if( isIdentity(e2) ) + { + if( isIdentity(e1) ) + MatOp_AddEx::makeExpr(res, e1.a, e2.a, 1, 1); + else + MatOp::add(e1, e2, res); + } + else + e2.op->add(e1, e2, res); +} + +void MatOp_Identity::add(const MatExpr& e, const Scalar& s, MatExpr& res) const +{ + MatOp_AddEx::makeExpr(res, e.a, Mat(), 1, 0, s); +} + +void MatOp_Identity::subtract(const MatExpr& e1, const MatExpr& e2, MatExpr& res) const +{ + if( isIdentity(e2) ) + { + if( isIdentity(e1) ) + MatOp_AddEx::makeExpr(res, e1.a, e2.a, 1, -1); + else + MatOp::subtract(e1, e2, res); + } + else + e2.op->subtract(e1, e2, res); +} + +void MatOp_Identity::subtract(const Scalar& s, const MatExpr& e, MatExpr& res) const +{ + MatOp_AddEx::makeExpr(res, e.a, Mat(), -1, 0, s); +} + +void MatOp_Identity::multiply(const MatExpr& e1, const MatExpr& e2, MatExpr& res, double scale) const +{ + if( isIdentity(e2) ) + { + if( isIdentity(e1) ) + MatOp_Bin::makeExpr(res, '*', e1.a, e2.a, scale); + else + MatOp::multiply(e1, e2, res, scale); + } + else + e2.op->multiply(e1, e2, res, scale); +} + +void MatOp_Identity::multiply(const MatExpr& e, double s, MatExpr& res) const +{ + MatOp_AddEx::makeExpr(res, e.a, Mat(), s, 0); +} + +void MatOp_Identity::divide(const MatExpr& e1, const MatExpr& e2, MatExpr& res, double scale) const +{ + if( isIdentity(e2) ) + { + if( isIdentity(e1) ) + MatOp_Bin::makeExpr(res, '/', e1.a, e2.a, scale); + else + MatOp::divide(e1, e2, res, scale); + } + else + e2.op->divide(e1, e2, res, scale); +} + +void MatOp_Identity::divide(double s, const MatExpr& e, MatExpr& res) const +{ + MatOp_Bin::makeExpr(res, '/', e.a, Mat(), s); +} + +void MatOp_Identity::matmul(const MatExpr& e1, const MatExpr& e2, MatExpr& res) const +{ + if( isIdentity(e2) ) + { + if( isIdentity(e1) ) + MatOp_GEMM::makeExpr(res, 0, e1.a, e2.a); + else + MatOp::matmul(e1, e2, res); + } + else + e2.op->matmul(e1, e2, res); +} + +///////////////////////////////////////////////////////////////////////////////////////////////////// + +void MatOp_AddEx::assign(const MatExpr& e, Mat& m, int type) const +{ + Mat temp, &dst = type == -1 || e.a.type() == type ? m : temp; + if( e.b.data ) + { + if( e.s == Scalar() || !e.s.isReal() ) + { + if( e.alpha == 1 ) + { + if( e.beta == 1 ) + cv::add(e.a, e.b, dst); + else if( e.beta == -1 ) + cv::subtract(e.a, e.b, dst); + else + cv::scaleAdd(e.b, e.beta, e.a, dst); + } + else if( e.beta == 1 ) + { + if( e.alpha == -1 ) + cv::subtract(e.b, e.a, dst); + else + cv::scaleAdd(e.a, e.alpha, e.b, dst); + } + else + cv::addWeighted(e.a, e.alpha, e.b, e.beta, 0, dst); + + if( !e.s.isReal() ) + cv::add(dst, e.s, dst); + } + else + cv::addWeighted(e.a, e.alpha, e.b, e.beta, e.s[0], dst); + } + else if( e.s.isReal() && (dst.data != m.data || fabs(e.alpha) != 1)) + { + e.a.convertTo(m, type, e.alpha, e.s[0]); + return; + } + else if( e.alpha == 1 ) + cv::add(e.a, e.s, dst); + else if( e.alpha == -1 ) + cv::subtract(e.s, e.a, dst); + else + { + e.a.convertTo(dst, e.a.type(), e.alpha); + cv::add(dst, e.s, dst); + } + + if( dst.data != m.data ) + dst.convertTo(m, m.type()); +} + + +void MatOp_AddEx::add(const MatExpr& e1, const MatExpr& e2, MatExpr& res) const +{ + bool i1 = isIdentity(e1), i2 = isIdentity(e2); + + if( ((isAddEx(e2) && !e2.b.data) || i2) && ((isAddEx(e1) && !e1.b.data) || i1) ) + MatOp_AddEx::makeExpr(res, e1.a, e2.a, i1 ? 1 : e1.alpha, i2 ? 1 : e2.alpha, + (i1 ? Scalar() : e1.s) + (i2 ? Scalar() : e2.s)); + else if( e2.op == this ) + MatOp::add(e1, e2, res); + else + e2.op->add(e1, e2, res); +} + + +void MatOp_AddEx::add(const MatExpr& e, const Scalar& s, MatExpr& res) const +{ + res = e; + res.s += s; +} + + +void MatOp_AddEx::subtract(const MatExpr& e1, const MatExpr& e2, MatExpr& res) const +{ + bool i1 = isIdentity(e1), i2 = isIdentity(e2); + + if( ((isAddEx(e2) && !e2.b.data) || i2) && ((isAddEx(e1) && !e1.b.data) || i1) ) + MatOp_AddEx::makeExpr(res, e1.a, e2.a, i1 ? 1 : e1.alpha, i2 ? -1 : -e2.alpha, + (i1 ? Scalar() : e1.s) - (i2 ? Scalar() : e2.s)); + else if( e2.op == this ) + MatOp::subtract(e1, e2, res); + else + e2.op->subtract(e1, e2, res); +} + + +void MatOp_AddEx::subtract(const Scalar& s, const MatExpr& e, MatExpr& res) const +{ + res = e; + res.alpha = -res.alpha; + res.beta = -res.beta; + res.s = s - res.s; +} + + +void MatOp_AddEx::multiply(const MatExpr& e1, const MatExpr& e2, MatExpr& res, double scale) const +{ + bool i1 = isIdentity(e1), i2 = isIdentity(e2); + + if( (isScaled(e1) || i1) && (isScaled(e2) || i2) ) + MatOp_Bin::makeExpr(res, '*', e1.a, e2.a, scale*(i1 ? 1 : e1.alpha)*(i2 ? 1 : e2.alpha)); + else if( this == e2.op ) + MatOp::multiply(e1, e2, res, scale); + else + e2.op->multiply(e1, e2, res, scale); +} + + +void MatOp_AddEx::multiply(const MatExpr& e, double s, MatExpr& res) const +{ + res = e; + res.alpha *= s; + res.beta *= s; + res.s *= s; +} + + +void MatOp_AddEx::divide(const MatExpr& e1, const MatExpr& e2, MatExpr& res, double scale) const +{ + bool i1 = isIdentity(e1), i2 = isIdentity(e2); + + if( (isScaled(e1) || i1) && (isScaled(e2) || i2) ) + MatOp_Bin::makeExpr(res, '/', e1.a, e2.a, scale*(i1 ? 1 : e1.alpha)*(i2 ? 1 : 1./e2.alpha)); + else if( this == e2.op ) + MatOp::divide(e1, e2, res, scale); + else + e2.op->divide(e1, e2, res, scale); +} + + +void MatOp_AddEx::divide(double s, const MatExpr& e, MatExpr& res) const +{ + if( isScaled(e) ) + MatOp_Bin::makeExpr(res, '/', e.a, Mat(), s/e.alpha); + else + MatOp::divide(s, e, res); +} + + +void MatOp_AddEx::transpose(const MatExpr& e, MatExpr& res) const +{ + if( isScaled(e) ) + MatOp_T::makeExpr(res, e.a, e.alpha); + else + MatOp::transpose(e, res); +} + +void MatOp_AddEx::abs(const MatExpr& e, MatExpr& res) const +{ + if( (!e.b.data || e.beta == 0) && fabs(e.alpha) == 1 ) + MatOp_Bin::makeExpr(res, 'a', e.a, -e.s*e.alpha); + else if( e.b.data && e.alpha + e.beta == 0 && e.alpha*e.beta == -1 ) + MatOp_Bin::makeExpr(res, 'a', e.a, e.b); + else + MatOp::abs(e, res); +} + +void MatOp_AddEx::matmul(const MatExpr& e1, const MatExpr& e2, MatExpr& res) const +{ + bool i1 = isIdentity(e1), i2 = isIdentity(e2); + double alpha1 = i1 ? 1 : e1.alpha, alpha2 = i2 ? 1 : e2.alpha; + + if( (isScaled(e1) || i1) && (isScaled(e2) || i2) ) + MatOp_GEMM::makeExpr(res, 0, e1.a, e2.a, alpha1*alpha2); + else if( this == e2.op ) + MatOp::matmul(e1, e2, res); + else + e2.op->matmul(e1, e2, res); +} + + +inline void MatOp_AddEx::makeExpr(MatExpr& res, const Mat& a, const Mat& b, double alpha, double beta, const Scalar& s) +{ + res = MatExpr(&g_MatOp_AddEx, 0, a, b, Mat(), alpha, beta, s); +} + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +void MatOp_Bin::assign(const MatExpr& e, Mat& m, int type) const +{ + Mat temp, &dst = type == -1 || e.a.type() == type ? m : temp; + + if( e.flags == '*' ) + cv::multiply(e.a, e.b, dst, e.alpha); + else if( e.flags == '/' && e.b.data ) + cv::divide(e.a, e.b, dst, e.alpha); + else if( e.flags == '/' && !e.b.data ) + cv::divide(e.alpha, e.a, dst ); + else if( e.flags == '&' && e.b.data ) + bitwise_and(e.a, e.b, dst); + else if( e.flags == '&' && !e.b.data ) + bitwise_and(e.a, e.s, dst); + else if( e.flags == '|' && e.b.data ) + bitwise_or(e.a, e.b, dst); + else if( e.flags == '|' && !e.b.data ) + bitwise_or(e.a, e.s, dst); + else if( e.flags == '^' && e.b.data ) + bitwise_xor(e.a, e.b, dst); + else if( e.flags == '^' && !e.b.data ) + bitwise_xor(e.a, e.s, dst); + else if( e.flags == '~' && !e.b.data ) + bitwise_not(e.a, dst); + else if( e.flags == 'm' && e.b.data ) + cv::min(e.a, e.b, dst); + else if( e.flags == 'm' && !e.b.data ) + cv::min(e.a, e.s[0], dst); + else if( e.flags == 'M' && e.b.data ) + cv::max(e.a, e.b, dst); + else if( e.flags == 'M' && !e.b.data ) + cv::max(e.a, e.s[0], dst); + else if( e.flags == 'a' && e.b.data ) + cv::absdiff(e.a, e.b, dst); + else if( e.flags == 'a' && !e.b.data ) + cv::absdiff(e.a, e.s, dst); + else + CV_Error(CV_StsError, "Unknown operation"); + + if( dst.data != m.data ) + dst.convertTo(m, type); +} + +void MatOp_Bin::multiply(const MatExpr& e1, const MatExpr& e2, MatExpr& res, double scale) const +{ + if( isReciprocal(e1) && (isIdentity(e2) || isScaled(e2)) ) + MatOp_Bin::makeExpr(res, '/', e2.a, e1.a, e1.alpha*(isIdentity(e2) ? 1 : e2.alpha)*scale); + else if( isReciprocal(e2) && (isIdentity(e1) || isScaled(e1)) ) + MatOp_Bin::makeExpr(res, '/', e1.a, e2.a, (isIdentity(e1) ? 1 : e1.alpha)*e2.alpha*scale); + else if( e2.op == this ) + MatOp::multiply(e1, e2, res, scale); + else + e2.op->multiply(e1, e2, res, scale); +} + +void MatOp_Bin::multiply(const MatExpr& e, double s, MatExpr& res) const +{ + if( e.flags == '*' || e.flags == '/' ) + { + res = e; + res.alpha *= s; + } + else + MatOp::multiply(e, s, res); +} + +void MatOp_Bin::divide(const MatExpr& e1, const MatExpr& e2, MatExpr& res, double scale) const +{ + if( isReciprocal(e2) ) + { + if( isIdentity(e1) || isScaled(e1) ) + { + MatOp_Bin::makeExpr(res, '*', e1.a, e2.a, (isIdentity(e1) ? 1 : e1.alpha)*scale/e2.alpha); + return; + } + if( isReciprocal(e1) ) + { + MatOp_Bin::makeExpr(res, '/', e2.a, e1.a, e1.alpha*scale/e2.alpha); + return; + } + } + if( e2.op == this ) + MatOp::divide(e1, e2, res, scale); + else + e2.op->divide(e1, e2, res, scale); +} + +void MatOp_Bin::divide(double s, const MatExpr& e, MatExpr& res) const +{ + if( e.flags == '/' && !e.b.data ) + MatOp_AddEx::makeExpr(res, e.a, Mat(), s/e.alpha, 0); + else + MatOp::divide(s, e, res); +} + +inline void MatOp_Bin::makeExpr(MatExpr& res, char op, const Mat& a, const Mat& b, double scale) +{ + res = MatExpr(&g_MatOp_Bin, op, a, b, Mat(), scale, b.data ? 1 : 0); +} + +inline void MatOp_Bin::makeExpr(MatExpr& res, char op, const Mat& a, const Scalar& s) +{ + res = MatExpr(&g_MatOp_Bin, op, a, Mat(), Mat(), 1, 0, s); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////// + +void MatOp_Cmp::assign(const MatExpr& e, Mat& m, int type) const +{ + Mat temp, &dst = type == -1 || type == CV_8U ? m : temp; + + if( e.b.data ) + cv::compare(e.a, e.b, dst, e.flags); + else + cv::compare(e.a, e.alpha, dst, e.flags); + + if( dst.data != m.data ) + dst.convertTo(m, type); +} + +inline void MatOp_Cmp::makeExpr(MatExpr& res, int cmpop, const Mat& a, const Mat& b) +{ + res = MatExpr(&g_MatOp_Cmp, cmpop, a, b, Mat(), 1, 1); +} + +inline void MatOp_Cmp::makeExpr(MatExpr& res, int cmpop, const Mat& a, double alpha) +{ + res = MatExpr(&g_MatOp_Cmp, cmpop, a, Mat(), Mat(), alpha, 1); +} + +///////////////////////////////////////////////////////////////////////////////////////////////////////// + +void MatOp_T::assign(const MatExpr& e, Mat& m, int type) const +{ + Mat temp, &dst = type == -1 || type == e.a.type() ? m : temp; + + cv::transpose(e.a, dst); + + if( dst.data != m.data || e.alpha != 1 ) + dst.convertTo(m, type, e.alpha); +} + +void MatOp_T::multiply(const MatExpr& e, double s, MatExpr& res) const +{ + res = e; + res.alpha *= s; +} + +void MatOp_T::transpose(const MatExpr& e, MatExpr& res) const +{ + if( e.alpha == 1 ) + MatOp_Identity::makeExpr(res, e.a); + else + MatOp_AddEx::makeExpr(res, e.a, Mat(), e.alpha, 0); +} + +void MatOp_T::matmul(const MatExpr& e1, const MatExpr& e2, MatExpr& res) const +{ + bool i1 = isIdentity(e1), i2 = isIdentity(e2); + double alpha1 = i1 ? 1 : e1.alpha, alpha2 = i2 ? 1 : e2.alpha; + + if( isT(e1) && (isT(e2) || isScaled(e2) || i2)) + MatOp_GEMM::makeExpr(res, CV_GEMM_A_T + (isT(e2) ? CV_GEMM_B_T : 0), + e1.a, e2.a, e1.alpha*alpha2); + else if( isT(e2) && (isT(e1) || isScaled(e1) || i1)) + MatOp_GEMM::makeExpr(res, CV_GEMM_B_T + (isT(e1) ? CV_GEMM_A_T : 0), + e1.a, e2.a, e2.alpha*alpha1); + else if( this == e2.op ) + MatOp::matmul(e1, e2, res); + else + e2.op->matmul(e1, e2, res); +} + +inline void MatOp_T::makeExpr(MatExpr& res, const Mat& a, double alpha) +{ + res = MatExpr(&g_MatOp_T, 0, a, Mat(), Mat(), alpha, 0); +} + +///////////////////////////////////////////////////////////////////////////////////////////////////////// + +void MatOp_GEMM::assign(const MatExpr& e, Mat& m, int type) const +{ + Mat temp, &dst = type == -1 || type == e.a.type() ? m : temp; + + cv::gemm(e.a, e.b, e.alpha, e.c, e.beta, dst, e.flags); + if( dst.data != m.data ) + dst.convertTo(m, type); +} + +void MatOp_GEMM::add(const MatExpr& e1, const MatExpr& e2, MatExpr& res) const +{ + bool i1 = isIdentity(e1), i2 = isIdentity(e2); + double alpha1 = i1 ? 1 : e1.alpha, alpha2 = i2 ? 1 : e2.alpha; + + if( isMatProd(e1) && (i2 || isScaled(e2) || isT(e2)) ) + MatOp_GEMM::makeExpr(res, (e1.flags & ~CV_GEMM_C_T)|(isT(e2) ? CV_GEMM_C_T : 0), + e1.a, e1.b, alpha1, e2.a, alpha2); + else if( isMatProd(e2) && (i1 || isScaled(e1) || isT(e1)) ) + MatOp_GEMM::makeExpr(res, (e2.flags & ~CV_GEMM_C_T)|(isT(e1) ? CV_GEMM_C_T : 0), + e2.a, e2.b, alpha2, e1.a, alpha1); + else if( this == e2.op ) + MatOp::add(e1, e2, res); + else + e2.op->add(e1, e2, res); +} + +void MatOp_GEMM::subtract(const MatExpr& e1, const MatExpr& e2, MatExpr& res) const +{ + bool i1 = isIdentity(e1), i2 = isIdentity(e2); + double alpha1 = i1 ? 1 : e1.alpha, alpha2 = i2 ? 1 : e2.alpha; + + if( isMatProd(e1) && (i2 || isScaled(e2) || isT(e2)) ) + MatOp_GEMM::makeExpr(res, (e1.flags & ~CV_GEMM_C_T)|(isT(e2) ? CV_GEMM_C_T : 0), + e1.a, e1.b, alpha1, e2.a, -alpha2); + else if( isMatProd(e2) && (i1 || isScaled(e1) || isT(e1)) ) + MatOp_GEMM::makeExpr(res, (e2.flags & ~CV_GEMM_C_T)|(isT(e1) ? CV_GEMM_C_T : 0), + e2.a, e2.b, -alpha2, e1.a, alpha1); + else if( this == e2.op ) + MatOp::subtract(e1, e2, res); + else + e2.op->subtract(e1, e2, res); +} + +void MatOp_GEMM::multiply(const MatExpr& e, double s, MatExpr& res) const +{ + res = e; + res.alpha *= s; + res.beta *= s; +} + +void MatOp_GEMM::transpose(const MatExpr& e, MatExpr& res) const +{ + res = e; + res.flags ^= CV_GEMM_A_T | CV_GEMM_B_T | CV_GEMM_C_T; + swap(res.a, res.b); +} + +inline void MatOp_GEMM::makeExpr(MatExpr& res, int flags, const Mat& a, const Mat& b, + double alpha, const Mat& c, double beta) +{ + res = MatExpr(&g_MatOp_GEMM, flags, a, b, c, alpha, beta); +} + +/////////////////////////////////////////////////////////////////////////////////////////////////////// + +void MatOp_Invert::assign(const MatExpr& e, Mat& m, int type) const +{ + Mat temp, &dst = type == -1 || type == e.a.type() ? m : temp; + + cv::invert(e.a, dst, e.flags); + if( dst.data != m.data ) + dst.convertTo(m, type); +} + +void MatOp_Invert::matmul(const MatExpr& e1, const MatExpr& e2, MatExpr& res) const +{ + if( isInv(e1) && isIdentity(e2) ) + MatOp_Solve::makeExpr(res, e1.flags, e1.a, e2.a); + else if( this == e2.op ) + MatOp::matmul(e1, e2, res); + else + e2.op->matmul(e1, e2, res); +} + +inline void MatOp_Invert::makeExpr(MatExpr& res, int method, const Mat& m) +{ + res = MatExpr(&g_MatOp_Invert, method, m, Mat(), Mat(), 1, 0); +} + +///////////////////////////////////////////////////////////////////////////////////////////////////////// + +void MatOp_Solve::assign(const MatExpr& e, Mat& m, int type) const +{ + Mat temp, &dst = type == -1 || type == e.a.type() ? m : temp; + + cv::solve(e.a, e.b, dst, e.flags); + if( dst.data != m.data ) + dst.convertTo(m, type); +} + +inline void MatOp_Solve::makeExpr(MatExpr& res, int method, const Mat& a, const Mat& b) +{ + res = MatExpr(&g_MatOp_Solve, method, a, b, Mat(), 1, 1); +} + +////////////////////////////////////////////////////////////////////////////////////////////////////////// + +void MatOp_Initializer::assign(const MatExpr& e, Mat& m, int type) const +{ + if( type == -1 ) + type = e.a.type(); + m.create(e.a.size(), type); + if( e.flags == 'I' ) + setIdentity(m, Scalar(e.alpha)); + else if( e.flags == '0' ) + m = Scalar(); + else if( e.flags == '1' ) + m = Scalar(e.alpha); + else + CV_Error(CV_StsError, "Invalid matrix initializer type"); +} + +void MatOp_Initializer::multiply(const MatExpr& e, double s, MatExpr& res) const +{ + res = e; + res.alpha *= s; +} + +inline void MatOp_Initializer::makeExpr(MatExpr& res, int method, Size sz, int type, double alpha) +{ + res = MatExpr(&g_MatOp_Initializer, method, Mat(sz, type, (void*)0), Mat(), Mat(), alpha, 0); +} + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////// + +MatExpr Mat::t() const +{ + MatExpr e; + MatOp_T::makeExpr(e, *this); + return e; +} + +MatExpr Mat::inv(int method) const +{ + MatExpr e; + MatOp_Invert::makeExpr(e, method, *this); + return e; +} + + +MatExpr Mat::mul(const Mat& m, double scale) const +{ + MatExpr e; + MatOp_Bin::makeExpr(e, '*', *this, m, scale); + return e; +} + +MatExpr Mat::mul(const MatExpr& m, double scale) const +{ + MatExpr e; + m.op->multiply(MatExpr(*this), m, e, scale); + return e; +} + +MatExpr Mat::zeros(int rows, int cols, int type) +{ + MatExpr e; + MatOp_Initializer::makeExpr(e, '0', Size(cols, rows), type); + return e; +} + +MatExpr Mat::zeros(Size size, int type) +{ + MatExpr e; + MatOp_Initializer::makeExpr(e, '0', size, type); + return e; +} + +MatExpr Mat::ones(int rows, int cols, int type) +{ + MatExpr e; + MatOp_Initializer::makeExpr(e, '1', Size(cols, rows), type); + return e; +} + +MatExpr Mat::ones(Size size, int type) +{ + MatExpr e; + MatOp_Initializer::makeExpr(e, '1', size, type); + return e; +} + +MatExpr Mat::eye(int rows, int cols, int type) +{ + MatExpr e; + MatOp_Initializer::makeExpr(e, 'I', Size(cols, rows), type); + return e; +} + +MatExpr Mat::eye(Size size, int type) +{ + MatExpr e; + MatOp_Initializer::makeExpr(e, 'I', size, type); + return e; +} + +} + +/* End of file. */ diff --git a/tests/cv/src/operations.cpp b/tests/cv/src/operations.cpp index 82a1e6d2f9..319bf0fbc7 100644 --- a/tests/cv/src/operations.cpp +++ b/tests/cv/src/operations.cpp @@ -342,7 +342,7 @@ bool CV_OperationsTest::TestMat() m = mi.clone(); m+=(3.0 * mi * mt + d1); CHECK_DIFF_FLT(m, mi + d1 * 4); m = mi.clone(); m-=(3.0 * mi * mt + d1); CHECK_DIFF_FLT(m, mi - d1 * 4); m = mi.clone(); m*=(mt * 1.0); CHECK_DIFF_FLT(m, d1); - m = mi.clone(); m*=(mt * 1.0 + 1.0); CHECK_DIFF_FLT(m, d1 + mi); + m = mi.clone(); m*=(mt * 1.0 + Mat::eye(m.size(), m.type())); CHECK_DIFF_FLT(m, d1 + mi); m = mi.clone(); m*=mt_tr.t(); CHECK_DIFF_FLT(m, d1); CHECK_DIFF_FLT( (mi * 2) * mt, d2); @@ -611,7 +611,7 @@ bool CV_OperationsTest::TestTemplateMat() if (Mat_(1, 1).channels() != 3) throw test_excep(); if (Mat_(1, 1).channels() != 3) throw test_excep(); - Mat_ eye = Mat_::zeros(2, 2); CHECK_DIFF(Mat_::zeros(Size(2, 2)), eye); + Mat_ eye = Mat_::zeros(2, 2); CHECK_DIFF(Mat_::zeros(Size(2, 2)), eye); eye.at(Point(0,0)) = 1; eye.at(1, 1) = 1; CHECK_DIFF(Mat_::eye(2, 2), eye);