Renesas GR-PEACH OpenCV Development / gr-peach-opencv-project-sd-card_update

Fork of gr-peach-opencv-project-sd-card by the do

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers matop.cpp Source File

matop.cpp

00001 /*M///////////////////////////////////////////////////////////////////////////////////////
00002 //
00003 //  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
00004 //
00005 //  By downloading, copying, installing or using the software you agree to this license.
00006 //  If you do not agree to this license, do not download, install,
00007 //  copy or use the software.
00008 //
00009 //
00010 //                           License Agreement
00011 //                For Open Source Computer Vision Library
00012 //
00013 // Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
00014 // Copyright (C) 2009-2010, Willow Garage Inc., all rights reserved.
00015 // Third party copyrights are property of their respective owners.
00016 //
00017 // Redistribution and use in source and binary forms, with or without modification,
00018 // are permitted provided that the following conditions are met:
00019 //
00020 //   * Redistribution's of source code must retain the above copyright notice,
00021 //     this list of conditions and the following disclaimer.
00022 //
00023 //   * Redistribution's in binary form must reproduce the above copyright notice,
00024 //     this list of conditions and the following disclaimer in the documentation
00025 //     and/or other materials provided with the distribution.
00026 //
00027 //   * The name of the copyright holders may not be used to endorse or promote products
00028 //     derived from this software without specific prior written permission.
00029 //
00030 // This software is provided by the copyright holders and contributors "as is" and
00031 // any express or implied warranties, including, but not limited to, the implied
00032 // warranties of merchantability and fitness for a particular purpose are disclaimed.
00033 // In no event shall the Intel Corporation or contributors be liable for any direct,
00034 // indirect, incidental, special, exemplary, or consequential damages
00035 // (including, but not limited to, procurement of substitute goods or services;
00036 // loss of use, data, or profits; or business interruption) however caused
00037 // and on any theory of liability, whether in contract, strict liability,
00038 // or tort (including negligence or otherwise) arising in any way out of
00039 // the use of this software, even if advised of the possibility of such damage.
00040 //
00041 //M*/
00042 
00043 /* ////////////////////////////////////////////////////////////////////
00044 //
00045 //  Mat basic operations: Copy, Set
00046 //
00047 // */
00048 
00049 #include "precomp.hpp"
00050 
00051 namespace cv
00052 {
00053 
00054 class MatOp_Identity : public MatOp
00055 {
00056 public:
00057     MatOp_Identity() {}
00058     virtual ~MatOp_Identity() {}
00059 
00060     bool elementWise(const MatExpr& /*expr*/) const { return true; }
00061     void assign(const MatExpr& expr, Mat& m, int type=-1) const;
00062 
00063     static void makeExpr(MatExpr& res, const Mat& m);
00064 };
00065 
00066 static MatOp_Identity g_MatOp_Identity;
00067 
00068 class MatOp_AddEx : public MatOp
00069 {
00070 public:
00071     MatOp_AddEx() {}
00072     virtual ~MatOp_AddEx() {}
00073 
00074     bool elementWise(const MatExpr& /*expr*/) const { return true; }
00075     void assign(const MatExpr& expr, Mat& m, int type=-1) const;
00076 
00077     void add(const MatExpr& e1, const Scalar& s, MatExpr& res) const;
00078     void subtract(const Scalar& s, const MatExpr& expr, MatExpr& res) const;
00079     void multiply(const MatExpr& e1, double s, MatExpr& res) const;
00080     void divide(double s, const MatExpr& e, MatExpr& res) const;
00081 
00082     void transpose(const MatExpr& e1, MatExpr& res) const;
00083     void abs(const MatExpr& expr, MatExpr& res) const;
00084 
00085     static void makeExpr(MatExpr& res, const Mat& a, const Mat& b, double alpha, double beta, const Scalar& s=Scalar());
00086 };
00087 
00088 static MatOp_AddEx g_MatOp_AddEx;
00089 
00090 class MatOp_Bin : public MatOp
00091 {
00092 public:
00093     MatOp_Bin() {}
00094     virtual ~MatOp_Bin() {}
00095 
00096     bool elementWise(const MatExpr& /*expr*/) const { return true; }
00097     void assign(const MatExpr& expr, Mat& m, int type=-1) const;
00098 
00099     void multiply(const MatExpr& e1, double s, MatExpr& res) const;
00100     void divide(double s, const MatExpr& e, MatExpr& res) const;
00101 
00102     static void makeExpr(MatExpr& res, char op, const Mat& a, const Mat& b, double scale=1);
00103     static void makeExpr(MatExpr& res, char op, const Mat& a, const Scalar& s);
00104 };
00105 
00106 static MatOp_Bin g_MatOp_Bin;
00107 
00108 class MatOp_Cmp : public MatOp
00109 {
00110 public:
00111     MatOp_Cmp() {}
00112     virtual ~MatOp_Cmp() {}
00113 
00114     bool elementWise(const MatExpr& /*expr*/) const { return true; }
00115     void assign(const MatExpr& expr, Mat& m, int type=-1) const;
00116 
00117     static void makeExpr(MatExpr& res, int cmpop, const Mat& a, const Mat& b);
00118     static void makeExpr(MatExpr& res, int cmpop, const Mat& a, double alpha);
00119 };
00120 
00121 static MatOp_Cmp g_MatOp_Cmp;
00122 
00123 class MatOp_GEMM : public MatOp
00124 {
00125 public:
00126     MatOp_GEMM() {}
00127     virtual ~MatOp_GEMM() {}
00128 
00129     bool elementWise(const MatExpr& /*expr*/) const { return false; }
00130     void assign(const MatExpr& expr, Mat& m, int type=-1) const;
00131 
00132     void add(const MatExpr& e1, const MatExpr& e2, MatExpr& res) const;
00133     void subtract(const MatExpr& e1, const MatExpr& e2, MatExpr& res) const;
00134     void multiply(const MatExpr& e, double s, MatExpr& res) const;
00135 
00136     void transpose(const MatExpr& expr, MatExpr& res) const;
00137 
00138     static void makeExpr(MatExpr& res, int flags, const Mat& a, const Mat& b,
00139                          double alpha=1, const Mat& c=Mat(), double beta=1);
00140 };
00141 
00142 static MatOp_GEMM g_MatOp_GEMM;
00143 
00144 class MatOp_Invert : public MatOp
00145 {
00146 public:
00147     MatOp_Invert() {}
00148     virtual ~MatOp_Invert() {}
00149 
00150     bool elementWise(const MatExpr& /*expr*/) const { return false; }
00151     void assign(const MatExpr& expr, Mat& m, int type=-1) const;
00152 
00153     void matmul(const MatExpr& expr1, const MatExpr& expr2, MatExpr& res) const;
00154 
00155     static void makeExpr(MatExpr& res, int method, const Mat& m);
00156 };
00157 
00158 static MatOp_Invert g_MatOp_Invert;
00159 
00160 class MatOp_T : public MatOp
00161 {
00162 public:
00163     MatOp_T() {}
00164     virtual ~MatOp_T() {}
00165 
00166     bool elementWise(const MatExpr& /*expr*/) const { return false; }
00167     void assign(const MatExpr& expr, Mat& m, int type=-1) const;
00168 
00169     void multiply(const MatExpr& e1, double s, MatExpr& res) const;
00170     void transpose(const MatExpr& expr, MatExpr& res) const;
00171 
00172     static void makeExpr(MatExpr& res, const Mat& a, double alpha=1);
00173 };
00174 
00175 static MatOp_T g_MatOp_T;
00176 
00177 class MatOp_Solve : public MatOp
00178 {
00179 public:
00180     MatOp_Solve() {}
00181     virtual ~MatOp_Solve() {}
00182 
00183     bool elementWise(const MatExpr& /*expr*/) const { return false; }
00184     void assign(const MatExpr& expr, Mat& m, int type=-1) const;
00185 
00186     static void makeExpr(MatExpr& res, int method, const Mat& a, const Mat& b);
00187 };
00188 
00189 static MatOp_Solve g_MatOp_Solve;
00190 
00191 class MatOp_Initializer : public MatOp
00192 {
00193 public:
00194     MatOp_Initializer() {}
00195     virtual ~MatOp_Initializer() {}
00196 
00197     bool elementWise(const MatExpr& /*expr*/) const { return false; }
00198     void assign(const MatExpr& expr, Mat& m, int type=-1) const;
00199 
00200     void multiply(const MatExpr& e, double s, MatExpr& res) const;
00201 
00202     static void makeExpr(MatExpr& res, int method, Size sz, int type, double alpha=1);
00203     static void makeExpr(MatExpr& res, int method, int ndims, const int* sizes, int type, double alpha=1);
00204 };
00205 
00206 static MatOp_Initializer* getGlobalMatOpInitializer()
00207 {
00208     CV_SINGLETON_LAZY_INIT(MatOp_Initializer, new MatOp_Initializer())
00209 }
00210 
00211 static inline bool isIdentity(const MatExpr& e) { return e.op == &g_MatOp_Identity; }
00212 static inline bool isAddEx(const MatExpr& e) { return e.op == &g_MatOp_AddEx; }
00213 static inline bool isScaled(const MatExpr& e) { return isAddEx(e) && (!e.b.data || e.beta == 0) && e.s == Scalar(); }
00214 static inline bool isBin(const MatExpr& e, char c) { return e.op == &g_MatOp_Bin && e.flags == c; }
00215 static inline bool isCmp(const MatExpr& e) { return e.op == &g_MatOp_Cmp; }
00216 static inline bool isReciprocal(const MatExpr& e) { return isBin(e,'/') && (!e.b.data || e.beta == 0); }
00217 static inline bool isT(const MatExpr& e) { return e.op == &g_MatOp_T; }
00218 static inline bool isInv(const MatExpr& e) { return e.op == &g_MatOp_Invert; }
00219 static inline bool isSolve(const MatExpr& e) { return e.op == &g_MatOp_Solve; }
00220 static inline bool isGEMM(const MatExpr& e) { return e.op == &g_MatOp_GEMM; }
00221 static inline bool isMatProd(const MatExpr& e) { return e.op == &g_MatOp_GEMM && (!e.c.data || e.beta == 0); }
00222 static inline bool isInitializer(const MatExpr& e) { return e.op == getGlobalMatOpInitializer(); }
00223 
00224 /////////////////////////////////////////////////////////////////////////////////////////////////////
00225 
00226 MatOp::MatOp() {}
00227 MatOp::~MatOp() {}
00228 
00229 
00230 bool MatOp::elementWise(const MatExpr& /*expr*/) const
00231 {
00232     return false;
00233 }
00234 
00235 void MatOp::roi(const MatExpr& expr, const Range& rowRange, const Range& colRange, MatExpr& e) const
00236 {
00237     if( elementWise(expr) )
00238     {
00239         e = MatExpr(expr.op, expr.flags, Mat(), Mat(), Mat(),
00240                     expr.alpha, expr.beta, expr.s);
00241         if(expr.a.data)
00242             e.a = expr.a(rowRange, colRange);
00243         if(expr.b.data)
00244             e.b = expr.b(rowRange, colRange);
00245         if(expr.c.data)
00246             e.c = expr.c(rowRange, colRange);
00247     }
00248     else
00249     {
00250         Mat m;
00251         expr.op->assign(expr, m);
00252         e = MatExpr(&g_MatOp_Identity, 0, m(rowRange, colRange), Mat(), Mat());
00253     }
00254 }
00255 
00256 void MatOp::diag(const MatExpr& expr, int d, MatExpr& e) const
00257 {
00258     if( elementWise(expr) )
00259     {
00260         e = MatExpr(expr.op, expr.flags, Mat(), Mat(), Mat(),
00261                     expr.alpha, expr.beta, expr.s);
00262         if(expr.a.data)
00263             e.a = expr.a.diag(d);
00264         if(expr.b.data)
00265             e.b = expr.b.diag(d);
00266         if(expr.c.data)
00267             e.c = expr.c.diag(d);
00268     }
00269     else
00270     {
00271         Mat m;
00272         expr.op->assign(expr, m);
00273         e = MatExpr(&g_MatOp_Identity, 0, m.diag(d), Mat(), Mat());
00274     }
00275 }
00276 
00277 
00278 void MatOp::augAssignAdd(const MatExpr& expr, Mat& m) const
00279 {
00280     Mat temp;
00281     expr.op->assign(expr, temp);
00282     m += temp;
00283 }
00284 
00285 
00286 void MatOp::augAssignSubtract(const MatExpr& expr, Mat& m) const
00287 {
00288     Mat temp;
00289     expr.op->assign(expr, temp);
00290     m -= temp;
00291 }
00292 
00293 
00294 void MatOp::augAssignMultiply(const MatExpr& expr, Mat& m) const
00295 {
00296     Mat temp;
00297     expr.op->assign(expr, temp);
00298     m *= temp;
00299 }
00300 
00301 
00302 void MatOp::augAssignDivide(const MatExpr& expr, Mat& m) const
00303 {
00304     Mat temp;
00305     expr.op->assign(expr, temp);
00306     m /= temp;
00307 }
00308 
00309 
00310 void MatOp::augAssignAnd(const MatExpr& expr, Mat& m) const
00311 {
00312     Mat temp;
00313     expr.op->assign(expr, temp);
00314     m &= temp;
00315 }
00316 
00317 
00318 void MatOp::augAssignOr(const MatExpr& expr, Mat& m) const
00319 {
00320     Mat temp;
00321     expr.op->assign(expr, temp);
00322     m |= temp;
00323 }
00324 
00325 
00326 void MatOp::augAssignXor(const MatExpr& expr, Mat& m) const
00327 {
00328     Mat temp;
00329     expr.op->assign(expr, temp);
00330     m ^= temp;
00331 }
00332 
00333 
00334 void MatOp::add(const MatExpr& e1, const MatExpr& e2, MatExpr& res) const
00335 {
00336     if( this == e2.op )
00337     {
00338         double alpha = 1, beta = 1;
00339         Scalar s;
00340         Mat m1, m2;
00341         if( isAddEx(e1) && (!e1.b.data || e1.beta == 0) )
00342         {
00343             m1 = e1.a;
00344             alpha = e1.alpha;
00345             s = e1.s;
00346         }
00347         else
00348             e1.op->assign(e1, m1);
00349 
00350         if( isAddEx(e2) && (!e2.b.data || e2.beta == 0) )
00351         {
00352             m2 = e2.a;
00353             beta = e2.alpha;
00354             s += e2.s;
00355         }
00356         else
00357             e2.op->assign(e2, m2);
00358         MatOp_AddEx::makeExpr(res, m1, m2, alpha, beta, s);
00359     }
00360     else
00361         e2.op->add(e1, e2, res);
00362 }
00363 
00364 
00365 void MatOp::add(const MatExpr& expr1, const Scalar& s, MatExpr& res) const
00366 {
00367     Mat m1;
00368     expr1.op->assign(expr1, m1);
00369     MatOp_AddEx::makeExpr(res, m1, Mat(), 1, 0, s);
00370 }
00371 
00372 
00373 void MatOp::subtract(const MatExpr& e1, const MatExpr& e2, MatExpr& res) const
00374 {
00375     if( this == e2.op )
00376     {
00377         double alpha = 1, beta = -1;
00378         Scalar s;
00379         Mat m1, m2;
00380         if( isAddEx(e1) && (!e1.b.data || e1.beta == 0) )
00381         {
00382             m1 = e1.a;
00383             alpha = e1.alpha;
00384             s = e1.s;
00385         }
00386         else
00387             e1.op->assign(e1, m1);
00388 
00389         if( isAddEx(e2) && (!e2.b.data || e2.beta == 0) )
00390         {
00391             m2 = e2.a;
00392             beta = -e2.alpha;
00393             s -= e2.s;
00394         }
00395         else
00396             e2.op->assign(e2, m2);
00397         MatOp_AddEx::makeExpr(res, m1, m2, alpha, beta, s);
00398     }
00399     else
00400         e2.op->subtract(e1, e2, res);
00401 }
00402 
00403 
00404 void MatOp::subtract(const Scalar& s, const MatExpr& expr, MatExpr& res) const
00405 {
00406     Mat m;
00407     expr.op->assign(expr, m);
00408     MatOp_AddEx::makeExpr(res, m, Mat(), -1, 0, s);
00409 }
00410 
00411 
00412 void MatOp::multiply(const MatExpr& e1, const MatExpr& e2, MatExpr& res, double scale) const
00413 {
00414     if( this == e2.op )
00415     {
00416         Mat m1, m2;
00417 
00418         if( isReciprocal(e1) )
00419         {
00420             if( isScaled(e2) )
00421             {
00422                 scale *= e2.alpha;
00423                 m2 = e2.a;
00424             }
00425             else
00426                 e2.op->assign(e2, m2);
00427 
00428             MatOp_Bin::makeExpr(res, '/', m2, e1.a, scale/e1.alpha);
00429         }
00430         else
00431         {
00432             char op = '*';
00433             if( isScaled(e1) )
00434             {
00435                 m1 = e1.a;
00436                 scale *= e1.alpha;
00437             }
00438             else
00439                 e1.op->assign(e1, m1);
00440 
00441             if( isScaled(e2) )
00442             {
00443                 m2 = e2.a;
00444                 scale *= e2.alpha;
00445             }
00446             else if( isReciprocal(e2) )
00447             {
00448                 op = '/';
00449                 m2 = e2.a;
00450                 scale /= e2.alpha;
00451             }
00452             else
00453                 e2.op->assign(e2, m2);
00454 
00455             MatOp_Bin::makeExpr(res, op, m1, m2, scale);
00456         }
00457     }
00458     else
00459         e2.op->multiply(e1, e2, res, scale);
00460 }
00461 
00462 
00463 void MatOp::multiply(const MatExpr& expr, double s, MatExpr& res) const
00464 {
00465     Mat m;
00466     expr.op->assign(expr, m);
00467     MatOp_AddEx::makeExpr(res, m, Mat(), s, 0);
00468 }
00469 
00470 
00471 void MatOp::divide(const MatExpr& e1, const MatExpr& e2, MatExpr& res, double scale) const
00472 {
00473     if( this == e2.op )
00474     {
00475         if( isReciprocal(e1) && isReciprocal(e2) )
00476             MatOp_Bin::makeExpr(res, '/', e2.a, e1.a, e1.alpha/e2.alpha);
00477         else
00478         {
00479             Mat m1, m2;
00480             char op = '/';
00481 
00482             if( isScaled(e1) )
00483             {
00484                 m1 = e1.a;
00485                 scale *= e1.alpha;
00486             }
00487             else
00488                 e1.op->assign(e1, m1);
00489 
00490             if( isScaled(e2) )
00491             {
00492                 m2 = e2.a;
00493                 scale /= e2.alpha;
00494             }
00495             else if( isReciprocal(e2) )
00496             {
00497                 m2 = e2.a;
00498                 scale /= e2.alpha;
00499                 op = '*';
00500             }
00501             else
00502                 e2.op->assign(e2, m2);
00503             MatOp_Bin::makeExpr(res, op, m1, m2, scale);
00504         }
00505     }
00506     else
00507         e2.op->divide(e1, e2, res, scale);
00508 }
00509 
00510 
00511 void MatOp::divide(double s, const MatExpr& expr, MatExpr& res) const
00512 {
00513     Mat m;
00514     expr.op->assign(expr, m);
00515     MatOp_Bin::makeExpr(res, '/', m, Mat(), s);
00516 }
00517 
00518 
00519 void MatOp::abs(const MatExpr& expr, MatExpr& res) const
00520 {
00521     Mat m;
00522     expr.op->assign(expr, m);
00523     MatOp_Bin::makeExpr(res, 'a', m, Mat());
00524 }
00525 
00526 
00527 void MatOp::transpose(const MatExpr& expr, MatExpr& res) const
00528 {
00529     Mat m;
00530     expr.op->assign(expr, m);
00531     MatOp_T::makeExpr(res, m, 1);
00532 }
00533 
00534 
00535 void MatOp::matmul(const MatExpr& e1, const MatExpr& e2, MatExpr& res) const
00536 {
00537     if( this == e2.op )
00538     {
00539         double scale = 1;
00540         int flags = 0;
00541         Mat m1, m2;
00542 
00543         if( isT(e1) )
00544         {
00545             flags = CV_GEMM_A_T;
00546             scale = e1.alpha;
00547             m1 = e1.a;
00548         }
00549         else if( isScaled(e1) )
00550         {
00551             scale = e1.alpha;
00552             m1 = e1.a;
00553         }
00554         else
00555             e1.op->assign(e1, m1);
00556 
00557         if( isT(e2) )
00558         {
00559             flags |= CV_GEMM_B_T;
00560             scale *= e2.alpha;
00561             m2 = e2.a;
00562         }
00563         else if( isScaled(e2) )
00564         {
00565             scale *= e2.alpha;
00566             m2 = e2.a;
00567         }
00568         else
00569             e2.op->assign(e2, m2);
00570 
00571         MatOp_GEMM::makeExpr(res, flags, m1, m2, scale);
00572     }
00573     else
00574         e2.op->matmul(e1, e2, res);
00575 }
00576 
00577 
00578 void MatOp::invert(const MatExpr& expr, int method, MatExpr& res) const
00579 {
00580     Mat m;
00581     expr.op->assign(expr, m);
00582     MatOp_Invert::makeExpr(res, method, m);
00583 }
00584 
00585 
00586 Size MatOp::size(const MatExpr& expr) const
00587 {
00588     return !expr.a.empty() ? expr.a.size() : expr.b.empty() ? expr.b.size() : expr.c.size();
00589 }
00590 
00591 int MatOp::type(const MatExpr& expr) const
00592 {
00593     return !expr.a.empty() ? expr.a.type() : expr.b.empty() ? expr.b.type() : expr.c.type();
00594 }
00595 
00596 //////////////////////////////////////////////////////////////////////////////////////////////////
00597 
00598 MatExpr::MatExpr(const Mat& m) : op(&g_MatOp_Identity), flags(0), a(m), b(Mat()), c(Mat()), alpha(1), beta(0), s(Scalar())
00599 {
00600 }
00601 
00602 MatExpr MatExpr::row(int y) const
00603 {
00604     MatExpr e;
00605     op->roi(*this, Range(y, y+1), Range::all(), e);
00606     return e;
00607 }
00608 
00609 MatExpr MatExpr::col(int x) const
00610 {
00611     MatExpr e;
00612     op->roi(*this, Range::all(), Range(x, x+1), e);
00613     return e;
00614 }
00615 
00616 MatExpr MatExpr::diag(int d) const
00617 {
00618     MatExpr e;
00619     op->diag(*this, d, e);
00620     return e;
00621 }
00622 
00623 MatExpr MatExpr::operator()( const Range& rowRange, const Range& colRange ) const
00624 {
00625     MatExpr e;
00626     op->roi(*this, rowRange, colRange, e);
00627     return e;
00628 }
00629 
00630 MatExpr MatExpr::operator()( const Rect& roi ) const
00631 {
00632     MatExpr e;
00633     op->roi(*this, Range(roi.y, roi.y + roi.height), Range(roi.x, roi.x + roi.width), e);
00634     return e;
00635 }
00636 
00637 Mat MatExpr::cross(const Mat& m) const
00638 {
00639     return ((Mat)*this).cross(m);
00640 }
00641 
00642 double MatExpr::dot(const Mat& m) const
00643 {
00644     return ((Mat)*this).dot(m);
00645 }
00646 
00647 MatExpr MatExpr::t() const
00648 {
00649     MatExpr e;
00650     op->transpose(*this, e);
00651     return e;
00652 }
00653 
00654 MatExpr MatExpr::inv(int method) const
00655 {
00656     MatExpr e;
00657     op->invert(*this, method, e);
00658     return e;
00659 }
00660 
00661 MatExpr MatExpr::mul(const MatExpr& e, double scale) const
00662 {
00663     MatExpr en;
00664     op->multiply(*this, e, en, scale);
00665     return en;
00666 }
00667 
00668 MatExpr MatExpr::mul(const Mat& m, double scale) const
00669 {
00670     MatExpr e;
00671     op->multiply(*this, MatExpr(m), e, scale);
00672     return e;
00673 }
00674 
00675 MatExpr operator + (const Mat& a, const Mat& b)
00676 {
00677     MatExpr e;
00678     MatOp_AddEx::makeExpr(e, a, b, 1, 1);
00679     return e;
00680 }
00681 
00682 MatExpr operator + (const Mat& a, const Scalar& s)
00683 {
00684     MatExpr e;
00685     MatOp_AddEx::makeExpr(e, a, Mat(), 1, 0, s);
00686     return e;
00687 }
00688 
00689 MatExpr operator + (const Scalar& s, const Mat& a)
00690 {
00691     MatExpr e;
00692     MatOp_AddEx::makeExpr(e, a, Mat(), 1, 0, s);
00693     return e;
00694 }
00695 
00696 MatExpr operator + (const MatExpr& e, const Mat& m)
00697 {
00698     MatExpr en;
00699     e.op->add(e, MatExpr(m), en);
00700     return en;
00701 }
00702 
00703 MatExpr operator + (const Mat& m, const MatExpr& e)
00704 {
00705     MatExpr en;
00706     e.op->add(e, MatExpr(m), en);
00707     return en;
00708 }
00709 
00710 MatExpr operator + (const MatExpr& e, const Scalar& s)
00711 {
00712     MatExpr en;
00713     e.op->add(e, s, en);
00714     return en;
00715 }
00716 
00717 MatExpr operator + (const Scalar& s, const MatExpr& e)
00718 {
00719     MatExpr en;
00720     e.op->add(e, s, en);
00721     return en;
00722 }
00723 
00724 MatExpr operator + (const MatExpr& e1, const MatExpr& e2)
00725 {
00726     MatExpr en;
00727     e1.op->add(e1, e2, en);
00728     return en;
00729 }
00730 
00731 MatExpr operator - (const Mat& a, const Mat& b)
00732 {
00733     MatExpr e;
00734     MatOp_AddEx::makeExpr(e, a, b, 1, -1);
00735     return e;
00736 }
00737 
00738 MatExpr operator - (const Mat& a, const Scalar& s)
00739 {
00740     MatExpr e;
00741     MatOp_AddEx::makeExpr(e, a, Mat(), 1, 0, -s);
00742     return e;
00743 }
00744 
00745 MatExpr operator - (const Scalar& s, const Mat& a)
00746 {
00747     MatExpr e;
00748     MatOp_AddEx::makeExpr(e, a, Mat(), -1, 0, s);
00749     return e;
00750 }
00751 
00752 MatExpr operator - (const MatExpr& e, const Mat& m)
00753 {
00754     MatExpr en;
00755     e.op->subtract(e, MatExpr(m), en);
00756     return en;
00757 }
00758 
00759 MatExpr operator - (const Mat& m, const MatExpr& e)
00760 {
00761     MatExpr en;
00762     e.op->subtract(MatExpr(m), e, en);
00763     return en;
00764 }
00765 
00766 MatExpr operator - (const MatExpr& e, const Scalar& s)
00767 {
00768     MatExpr en;
00769     e.op->add(e, -s, en);
00770     return en;
00771 }
00772 
00773 MatExpr operator - (const Scalar& s, const MatExpr& e)
00774 {
00775     MatExpr en;
00776     e.op->subtract(s, e, en);
00777     return en;
00778 }
00779 
00780 MatExpr operator - (const MatExpr& e1, const MatExpr& e2)
00781 {
00782     MatExpr en;
00783     e1.op->subtract(e1, e2, en);
00784     return en;
00785 }
00786 
00787 MatExpr operator - (const Mat& m)
00788 {
00789     MatExpr e;
00790     MatOp_AddEx::makeExpr(e, m, Mat(), -1, 0);
00791     return e;
00792 }
00793 
00794 MatExpr operator - (const MatExpr& e)
00795 {
00796     MatExpr en;
00797     e.op->subtract(Scalar(0), e, en);
00798     return en;
00799 }
00800 
00801 MatExpr operator * (const Mat& a, const Mat& b)
00802 {
00803     MatExpr e;
00804     MatOp_GEMM::makeExpr(e, 0, a, b);
00805     return e;
00806 }
00807 
00808 MatExpr operator * (const Mat& a, double s)
00809 {
00810     MatExpr e;
00811     MatOp_AddEx::makeExpr(e, a, Mat(), s, 0);
00812     return e;
00813 }
00814 
00815 MatExpr operator * (double s, const Mat& a)
00816 {
00817     MatExpr e;
00818     MatOp_AddEx::makeExpr(e, a, Mat(), s, 0);
00819     return e;
00820 }
00821 
00822 MatExpr operator * (const MatExpr& e, const Mat& m)
00823 {
00824     MatExpr en;
00825     e.op->matmul(e, MatExpr(m), en);
00826     return en;
00827 }
00828 
00829 MatExpr operator * (const Mat& m, const MatExpr& e)
00830 {
00831     MatExpr en;
00832     e.op->matmul(MatExpr(m), e, en);
00833     return en;
00834 }
00835 
00836 MatExpr operator * (const MatExpr& e, double s)
00837 {
00838     MatExpr en;
00839     e.op->multiply(e, s, en);
00840     return en;
00841 }
00842 
00843 MatExpr operator * (double s, const MatExpr& e)
00844 {
00845     MatExpr en;
00846     e.op->multiply(e, s, en);
00847     return en;
00848 }
00849 
00850 MatExpr operator * (const MatExpr& e1, const MatExpr& e2)
00851 {
00852     MatExpr en;
00853     e1.op->matmul(e1, e2, en);
00854     return en;
00855 }
00856 
00857 MatExpr operator / (const Mat& a, const Mat& b)
00858 {
00859     MatExpr e;
00860     MatOp_Bin::makeExpr(e, '/', a, b);
00861     return e;
00862 }
00863 
00864 MatExpr operator / (const Mat& a, double s)
00865 {
00866     MatExpr e;
00867     MatOp_AddEx::makeExpr(e, a, Mat(), 1./s, 0);
00868     return e;
00869 }
00870 
00871 MatExpr operator / (double s, const Mat& a)
00872 {
00873     MatExpr e;
00874     MatOp_Bin::makeExpr(e, '/', a, Mat(), s);
00875     return e;
00876 }
00877 
00878 MatExpr operator / (const MatExpr& e, const Mat& m)
00879 {
00880     MatExpr en;
00881     e.op->divide(e, MatExpr(m), en);
00882     return en;
00883 }
00884 
00885 MatExpr operator / (const Mat& m, const MatExpr& e)
00886 {
00887     MatExpr en;
00888     e.op->divide(MatExpr(m), e, en);
00889     return en;
00890 }
00891 
00892 MatExpr operator / (const MatExpr& e, double s)
00893 {
00894     MatExpr en;
00895     e.op->multiply(e, 1./s, en);
00896     return en;
00897 }
00898 
00899 MatExpr operator / (double s, const MatExpr& e)
00900 {
00901     MatExpr en;
00902     e.op->divide(s, e, en);
00903     return en;
00904 }
00905 
00906 MatExpr operator / (const MatExpr& e1, const MatExpr& e2)
00907 {
00908     MatExpr en;
00909     e1.op->divide(e1, e2, en);
00910     return en;
00911 }
00912 
00913 MatExpr operator < (const Mat& a, const Mat& b)
00914 {
00915     MatExpr e;
00916     MatOp_Cmp::makeExpr(e, CV_CMP_LT, a, b);
00917     return e;
00918 }
00919 
00920 MatExpr operator < (const Mat& a, double s)
00921 {
00922     MatExpr e;
00923     MatOp_Cmp::makeExpr(e, CV_CMP_LT, a, s);
00924     return e;
00925 }
00926 
00927 MatExpr operator < (double s, const Mat& a)
00928 {
00929     MatExpr e;
00930     MatOp_Cmp::makeExpr(e, CV_CMP_GT, a, s);
00931     return e;
00932 }
00933 
00934 MatExpr operator <= (const Mat& a, const Mat& b)
00935 {
00936     MatExpr e;
00937     MatOp_Cmp::makeExpr(e, CV_CMP_LE, a, b);
00938     return e;
00939 }
00940 
00941 MatExpr operator <= (const Mat& a, double s)
00942 {
00943     MatExpr e;
00944     MatOp_Cmp::makeExpr(e, CV_CMP_LE, a, s);
00945     return e;
00946 }
00947 
00948 MatExpr operator <= (double s, const Mat& a)
00949 {
00950     MatExpr e;
00951     MatOp_Cmp::makeExpr(e, CV_CMP_GE, a, s);
00952     return e;
00953 }
00954 
00955 MatExpr operator == (const Mat& a, const Mat& b)
00956 {
00957     MatExpr e;
00958     MatOp_Cmp::makeExpr(e, CV_CMP_EQ, a, b);
00959     return e;
00960 }
00961 
00962 MatExpr operator == (const Mat& a, double s)
00963 {
00964     MatExpr e;
00965     MatOp_Cmp::makeExpr(e, CV_CMP_EQ, a, s);
00966     return e;
00967 }
00968 
00969 MatExpr operator == (double s, const Mat& a)
00970 {
00971     MatExpr e;
00972     MatOp_Cmp::makeExpr(e, CV_CMP_EQ, a, s);
00973     return e;
00974 }
00975 
00976 MatExpr operator != (const Mat& a, const Mat& b)
00977 {
00978     MatExpr e;
00979     MatOp_Cmp::makeExpr(e, CV_CMP_NE, a, b);
00980     return e;
00981 }
00982 
00983 MatExpr operator != (const Mat& a, double s)
00984 {
00985     MatExpr e;
00986     MatOp_Cmp::makeExpr(e, CV_CMP_NE, a, s);
00987     return e;
00988 }
00989 
00990 MatExpr operator != (double s, const Mat& a)
00991 {
00992     MatExpr e;
00993     MatOp_Cmp::makeExpr(e, CV_CMP_NE, a, s);
00994     return e;
00995 }
00996 
00997 MatExpr operator >= (const Mat& a, const Mat& b)
00998 {
00999     MatExpr e;
01000     MatOp_Cmp::makeExpr(e, CV_CMP_GE, a, b);
01001     return e;
01002 }
01003 
01004 MatExpr operator >= (const Mat& a, double s)
01005 {
01006     MatExpr e;
01007     MatOp_Cmp::makeExpr(e, CV_CMP_GE, a, s);
01008     return e;
01009 }
01010 
01011 MatExpr operator >= (double s, const Mat& a)
01012 {
01013     MatExpr e;
01014     MatOp_Cmp::makeExpr(e, CV_CMP_LE, a, s);
01015     return e;
01016 }
01017 
01018 MatExpr operator > (const Mat& a, const Mat& b)
01019 {
01020     MatExpr e;
01021     MatOp_Cmp::makeExpr(e, CV_CMP_GT, a, b);
01022     return e;
01023 }
01024 
01025 MatExpr operator > (const Mat& a, double s)
01026 {
01027     MatExpr e;
01028     MatOp_Cmp::makeExpr(e, CV_CMP_GT, a, s);
01029     return e;
01030 }
01031 
01032 MatExpr operator > (double s, const Mat& a)
01033 {
01034     MatExpr e;
01035     MatOp_Cmp::makeExpr(e, CV_CMP_LT, a, s);
01036     return e;
01037 }
01038 
01039 MatExpr min(const Mat& a, const Mat& b)
01040 {
01041     MatExpr e;
01042     MatOp_Bin::makeExpr(e, 'm', a, b);
01043     return e;
01044 }
01045 
01046 MatExpr min(const Mat& a, double s)
01047 {
01048     MatExpr e;
01049     MatOp_Bin::makeExpr(e, 'n', a, s);
01050     return e;
01051 }
01052 
01053 MatExpr min(double s, const Mat& a)
01054 {
01055     MatExpr e;
01056     MatOp_Bin::makeExpr(e, 'n', a, s);
01057     return e;
01058 }
01059 
01060 MatExpr max(const Mat& a, const Mat& b)
01061 {
01062     MatExpr e;
01063     MatOp_Bin::makeExpr(e, 'M', a, b);
01064     return e;
01065 }
01066 
01067 MatExpr max(const Mat& a, double s)
01068 {
01069     MatExpr e;
01070     MatOp_Bin::makeExpr(e, 'N', a, s);
01071     return e;
01072 }
01073 
01074 MatExpr max(double s, const Mat& a)
01075 {
01076     MatExpr e;
01077     MatOp_Bin::makeExpr(e, 'N', a, s);
01078     return e;
01079 }
01080 
01081 MatExpr operator & (const Mat& a, const Mat& b)
01082 {
01083     MatExpr e;
01084     MatOp_Bin::makeExpr(e, '&', a, b);
01085     return e;
01086 }
01087 
01088 MatExpr operator & (const Mat& a, const Scalar& s)
01089 {
01090     MatExpr e;
01091     MatOp_Bin::makeExpr(e, '&', a, s);
01092     return e;
01093 }
01094 
01095 MatExpr operator & (const Scalar& s, const Mat& a)
01096 {
01097     MatExpr e;
01098     MatOp_Bin::makeExpr(e, '&', a, s);
01099     return e;
01100 }
01101 
01102 MatExpr operator | (const Mat& a, const Mat& b)
01103 {
01104     MatExpr e;
01105     MatOp_Bin::makeExpr(e, '|', a, b);
01106     return e;
01107 }
01108 
01109 MatExpr operator | (const Mat& a, const Scalar& s)
01110 {
01111     MatExpr e;
01112     MatOp_Bin::makeExpr(e, '|', a, s);
01113     return e;
01114 }
01115 
01116 MatExpr operator | (const Scalar& s, const Mat& a)
01117 {
01118     MatExpr e;
01119     MatOp_Bin::makeExpr(e, '|', a, s);
01120     return e;
01121 }
01122 
01123 MatExpr operator ^ (const Mat& a, const Mat& b)
01124 {
01125     MatExpr e;
01126     MatOp_Bin::makeExpr(e, '^', a, b);
01127     return e;
01128 }
01129 
01130 MatExpr operator ^ (const Mat& a, const Scalar& s)
01131 {
01132     MatExpr e;
01133     MatOp_Bin::makeExpr(e, '^', a, s);
01134     return e;
01135 }
01136 
01137 MatExpr operator ^ (const Scalar& s, const Mat& a)
01138 {
01139     MatExpr e;
01140     MatOp_Bin::makeExpr(e, '^', a, s);
01141     return e;
01142 }
01143 
01144 MatExpr operator ~(const Mat& a)
01145 {
01146     MatExpr e;
01147     MatOp_Bin::makeExpr(e, '~', a, Scalar());
01148     return e;
01149 }
01150 
01151 MatExpr abs(const Mat& a)
01152 {
01153     MatExpr e;
01154     MatOp_Bin::makeExpr(e, 'a', a, Scalar ());
01155     return e;
01156 }
01157 
01158 MatExpr abs(const MatExpr& e)
01159 {
01160     MatExpr en;
01161     e.op->abs(e, en);
01162     return en;
01163 }
01164 
01165 
01166 Size MatExpr::size() const
01167 {
01168     if( isT(*this) || isInv(*this) )
01169         return Size(a.rows, a.cols);
01170     if( isGEMM(*this) )
01171         return Size(b.cols, a.rows);
01172     if( isSolve(*this) )
01173         return Size(b.cols, a.cols);
01174     if( isInitializer(*this) )
01175         return a.size();
01176     return op ? op->size(*this) : Size();
01177 }
01178 
01179 
01180 int MatExpr::type() const
01181 {
01182     if( isInitializer(*this) )
01183         return a.type();
01184     if( isCmp(*this) )
01185         return CV_8U;
01186     return op ? op->type(*this) : -1;
01187 }
01188 
01189 
01190 /////////////////////////////////////////////////////////////////////////////////////////////////////
01191 
01192 void MatOp_Identity::assign(const MatExpr& e, Mat& m, int _type) const
01193 {
01194     if( _type == -1 || _type == e.a.type() )
01195         m = e.a;
01196     else
01197     {
01198         CV_Assert( CV_MAT_CN(_type) == e.a.channels() );
01199         e.a.convertTo(m, _type);
01200     }
01201 }
01202 
01203 inline void MatOp_Identity::makeExpr(MatExpr& res, const Mat& m)
01204 {
01205     res = MatExpr(&g_MatOp_Identity, 0, m, Mat(), Mat(), 1, 0);
01206 }
01207 
01208 /////////////////////////////////////////////////////////////////////////////////////////////////////
01209 
01210 void MatOp_AddEx::assign(const MatExpr& e, Mat& m, int _type) const
01211 {
01212     Mat temp, &dst = _type == -1 || e.a.type() == _type ? m : temp;
01213     if( e.b.data )
01214     {
01215         if( e.s == Scalar() || !e.s.isReal() )
01216         {
01217             if( e.alpha == 1 )
01218             {
01219                 if( e.beta == 1 )
01220                     cv::add(e.a, e.b, dst);
01221                 else if( e.beta == -1 )
01222                     cv::subtract(e.a, e.b, dst);
01223                 else
01224                     cv::scaleAdd(e.b, e.beta, e.a, dst);
01225             }
01226             else if( e.beta == 1 )
01227             {
01228                 if( e.alpha == -1 )
01229                     cv::subtract(e.b, e.a, dst);
01230                 else
01231                     cv::scaleAdd(e.a, e.alpha, e.b, dst);
01232             }
01233             else
01234                 cv::addWeighted(e.a, e.alpha, e.b, e.beta, 0, dst);
01235 
01236             if( !e.s.isReal() )
01237                 cv::add(dst, e.s, dst);
01238         }
01239         else
01240             cv::addWeighted(e.a, e.alpha, e.b, e.beta, e.s[0], dst);
01241     }
01242     else if( e.s.isReal() && (dst.data != m.data || fabs(e.alpha) != 1))
01243     {
01244         e.a.convertTo(m, _type, e.alpha, e.s[0]);
01245         return;
01246     }
01247     else if( e.alpha == 1 )
01248         cv::add(e.a, e.s, dst);
01249     else if( e.alpha == -1 )
01250         cv::subtract(e.s, e.a, dst);
01251     else
01252     {
01253         e.a.convertTo(dst, e.a.type(), e.alpha);
01254         cv::add(dst, e.s, dst);
01255     }
01256 
01257     if( dst.data != m.data )
01258         dst.convertTo(m, m.type());
01259 }
01260 
01261 
01262 void MatOp_AddEx::add(const MatExpr& e, const Scalar& s, MatExpr& res) const
01263 {
01264     res = e;
01265     res.s += s;
01266 }
01267 
01268 
01269 void MatOp_AddEx::subtract(const Scalar& s, const MatExpr& e, MatExpr& res) const
01270 {
01271     res = e;
01272     res.alpha = -res.alpha;
01273     res.beta = -res.beta;
01274     res.s = s - res.s;
01275 }
01276 
01277 void MatOp_AddEx::multiply(const MatExpr& e, double s, MatExpr& res) const
01278 {
01279     res = e;
01280     res.alpha *= s;
01281     res.beta *= s;
01282     res.s *= s;
01283 }
01284 
01285 void MatOp_AddEx::divide(double s, const MatExpr& e, MatExpr& res) const
01286 {
01287     if( isScaled(e) )
01288         MatOp_Bin::makeExpr(res, '/', e.a, Mat(), s/e.alpha);
01289     else
01290         MatOp::divide(s, e, res);
01291 }
01292 
01293 
01294 void MatOp_AddEx::transpose(const MatExpr& e, MatExpr& res) const
01295 {
01296     if( isScaled(e) )
01297         MatOp_T::makeExpr(res, e.a, e.alpha);
01298     else
01299         MatOp::transpose(e, res);
01300 }
01301 
01302 void MatOp_AddEx::abs(const MatExpr& e, MatExpr& res) const
01303 {
01304     if( (!e.b.data || e.beta == 0) && fabs(e.alpha) == 1 )
01305         MatOp_Bin::makeExpr(res, 'a', e.a, -e.s*e.alpha);
01306     else if( e.b.data && e.alpha + e.beta == 0 && e.alpha*e.beta == -1 )
01307         MatOp_Bin::makeExpr(res, 'a', e.a, e.b);
01308     else
01309         MatOp::abs(e, res);
01310 }
01311 
01312 inline void MatOp_AddEx::makeExpr(MatExpr& res, const Mat& a, const Mat& b, double alpha, double beta, const Scalar& s)
01313 {
01314     res = MatExpr(&g_MatOp_AddEx, 0, a, b, Mat(), alpha, beta, s);
01315 }
01316 
01317 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
01318 
01319 void MatOp_Bin::assign(const MatExpr& e, Mat& m, int _type) const
01320 {
01321     Mat temp, &dst = _type == -1 || e.a.type() == _type ? m : temp;
01322 
01323     if( e.flags == '*' )
01324         cv::multiply(e.a, e.b, dst, e.alpha);
01325     else if( e.flags == '/' && e.b.data )
01326         cv::divide(e.a, e.b, dst, e.alpha);
01327     else if( e.flags == '/' && !e.b.data )
01328         cv::divide(e.alpha, e.a, dst );
01329     else if( e.flags == '&' && e.b.data )
01330         bitwise_and(e.a, e.b, dst);
01331     else if( e.flags == '&' && !e.b.data )
01332         bitwise_and(e.a, e.s, dst);
01333     else if( e.flags == '|' && e.b.data )
01334         bitwise_or(e.a, e.b, dst);
01335     else if( e.flags == '|' && !e.b.data )
01336         bitwise_or(e.a, e.s, dst);
01337     else if( e.flags == '^' && e.b.data )
01338         bitwise_xor(e.a, e.b, dst);
01339     else if( e.flags == '^' && !e.b.data )
01340         bitwise_xor(e.a, e.s, dst);
01341     else if( e.flags == '~' && !e.b.data )
01342         bitwise_not(e.a, dst);
01343     else if( e.flags == 'm' )
01344         cv::min(e.a, e.b, dst);
01345     else if( e.flags == 'n' )
01346         cv::min(e.a, e.s[0], dst);
01347     else if( e.flags == 'M' )
01348         cv::max(e.a, e.b, dst);
01349     else if( e.flags == 'N' )
01350         cv::max(e.a, e.s[0], dst);
01351     else if( e.flags == 'a' && e.b.data )
01352         cv::absdiff(e.a, e.b, dst);
01353     else if( e.flags == 'a' && !e.b.data )
01354         cv::absdiff(e.a, e.s, dst);
01355     else
01356         CV_Error(CV_StsError, "Unknown operation");
01357 
01358     if( dst.data != m.data )
01359         dst.convertTo(m, _type);
01360 }
01361 
01362 void MatOp_Bin::multiply(const MatExpr& e, double s, MatExpr& res) const
01363 {
01364     if( e.flags == '*' || e.flags == '/' )
01365     {
01366         res = e;
01367         res.alpha *= s;
01368     }
01369     else
01370         MatOp::multiply(e, s, res);
01371 }
01372 
01373 void MatOp_Bin::divide(double s, const MatExpr& e, MatExpr& res) const
01374 {
01375     if( e.flags == '/' && (!e.b.data || e.beta == 0) )
01376         MatOp_AddEx::makeExpr(res, e.a, Mat(), s/e.alpha, 0);
01377     else
01378         MatOp::divide(s, e, res);
01379 }
01380 
01381 inline void MatOp_Bin::makeExpr(MatExpr& res, char op, const Mat& a, const Mat& b, double scale)
01382 {
01383     res = MatExpr(&g_MatOp_Bin, op, a, b, Mat(), scale, b.data ? 1 : 0);
01384 }
01385 
01386 inline void MatOp_Bin::makeExpr(MatExpr& res, char op, const Mat& a, const Scalar& s)
01387 {
01388     res = MatExpr(&g_MatOp_Bin, op, a, Mat(), Mat(), 1, 0, s);
01389 }
01390 
01391 ///////////////////////////////////////////////////////////////////////////////////////////////////////
01392 
01393 void MatOp_Cmp::assign(const MatExpr& e, Mat& m, int _type) const
01394 {
01395     Mat temp, &dst = _type == -1 || _type == CV_8U ? m : temp;
01396 
01397     if( e.b.data )
01398         cv::compare(e.a, e.b, dst, e.flags);
01399     else
01400         cv::compare(e.a, e.alpha, dst, e.flags);
01401 
01402     if( dst.data != m.data )
01403         dst.convertTo(m, _type);
01404 }
01405 
01406 inline void MatOp_Cmp::makeExpr(MatExpr& res, int cmpop, const Mat& a, const Mat& b)
01407 {
01408     res = MatExpr(&g_MatOp_Cmp, cmpop, a, b, Mat(), 1, 1);
01409 }
01410 
01411 inline void MatOp_Cmp::makeExpr(MatExpr& res, int cmpop, const Mat& a, double alpha)
01412 {
01413     res = MatExpr(&g_MatOp_Cmp, cmpop, a, Mat(), Mat(), alpha, 1);
01414 }
01415 
01416 /////////////////////////////////////////////////////////////////////////////////////////////////////////
01417 
01418 void MatOp_T::assign(const MatExpr& e, Mat& m, int _type) const
01419 {
01420     Mat temp, &dst = _type == -1 || _type == e.a.type() ? m : temp;
01421 
01422     cv::transpose(e.a, dst);
01423 
01424     if( dst.data != m.data || e.alpha != 1 )
01425         dst.convertTo(m, _type, e.alpha);
01426 }
01427 
01428 void MatOp_T::multiply(const MatExpr& e, double s, MatExpr& res) const
01429 {
01430     res = e;
01431     res.alpha *= s;
01432 }
01433 
01434 void MatOp_T::transpose(const MatExpr& e, MatExpr& res) const
01435 {
01436     if( e.alpha == 1 )
01437         MatOp_Identity::makeExpr(res, e.a);
01438     else
01439         MatOp_AddEx::makeExpr(res, e.a, Mat(), e.alpha, 0);
01440 }
01441 
01442 inline void MatOp_T::makeExpr(MatExpr& res, const Mat& a, double alpha)
01443 {
01444     res = MatExpr(&g_MatOp_T, 0, a, Mat(), Mat(), alpha, 0);
01445 }
01446 
01447 /////////////////////////////////////////////////////////////////////////////////////////////////////////
01448 
01449 void MatOp_GEMM::assign(const MatExpr& e, Mat& m, int _type) const
01450 {
01451     Mat temp, &dst = _type == -1 || _type == e.a.type() ? m : temp;
01452 
01453     cv::gemm(e.a, e.b, e.alpha, e.c, e.beta, dst, e.flags);
01454     if( dst.data != m.data )
01455         dst.convertTo(m, _type);
01456 }
01457 
01458 void MatOp_GEMM::add(const MatExpr& e1, const MatExpr& e2, MatExpr& res) const
01459 {
01460     bool i1 = isIdentity(e1), i2 = isIdentity(e2);
01461     double alpha1 = i1 ? 1 : e1.alpha, alpha2 = i2 ? 1 : e2.alpha;
01462 
01463     if( isMatProd(e1) && (i2 || isScaled(e2) || isT(e2)) )
01464         MatOp_GEMM::makeExpr(res, (e1.flags & ~CV_GEMM_C_T)|(isT(e2) ? CV_GEMM_C_T : 0),
01465                              e1.a, e1.b, alpha1, e2.a, alpha2);
01466     else if( isMatProd(e2) && (i1 || isScaled(e1) || isT(e1)) )
01467         MatOp_GEMM::makeExpr(res, (e2.flags & ~CV_GEMM_C_T)|(isT(e1) ? CV_GEMM_C_T : 0),
01468                              e2.a, e2.b, alpha2, e1.a, alpha1);
01469     else if( this == e2.op )
01470         MatOp::add(e1, e2, res);
01471     else
01472         e2.op->add(e1, e2, res);
01473 }
01474 
01475 void MatOp_GEMM::subtract(const MatExpr& e1, const MatExpr& e2, MatExpr& res) const
01476 {
01477     bool i1 = isIdentity(e1), i2 = isIdentity(e2);
01478     double alpha1 = i1 ? 1 : e1.alpha, alpha2 = i2 ? 1 : e2.alpha;
01479 
01480     if( isMatProd(e1) && (i2 || isScaled(e2) || isT(e2)) )
01481         MatOp_GEMM::makeExpr(res, (e1.flags & ~CV_GEMM_C_T)|(isT(e2) ? CV_GEMM_C_T : 0),
01482                              e1.a, e1.b, alpha1, e2.a, -alpha2);
01483     else if( isMatProd(e2) && (i1 || isScaled(e1) || isT(e1)) )
01484         MatOp_GEMM::makeExpr(res, (e2.flags & ~CV_GEMM_C_T)|(isT(e1) ? CV_GEMM_C_T : 0),
01485                             e2.a, e2.b, -alpha2, e1.a, alpha1);
01486     else if( this == e2.op )
01487         MatOp::subtract(e1, e2, res);
01488     else
01489         e2.op->subtract(e1, e2, res);
01490 }
01491 
01492 void MatOp_GEMM::multiply(const MatExpr& e, double s, MatExpr& res) const
01493 {
01494     res = e;
01495     res.alpha *= s;
01496     res.beta *= s;
01497 }
01498 
01499 void MatOp_GEMM::transpose(const MatExpr& e, MatExpr& res) const
01500 {
01501     res = e;
01502     res.flags = (!(e.flags & CV_GEMM_A_T) ? CV_GEMM_B_T : 0) |
01503                 (!(e.flags & CV_GEMM_B_T) ? CV_GEMM_A_T : 0) |
01504                 (!(e.flags & CV_GEMM_C_T) ? CV_GEMM_C_T : 0);
01505     swap(res.a, res.b);
01506 }
01507 
01508 inline void MatOp_GEMM::makeExpr(MatExpr& res, int flags, const Mat& a, const Mat& b,
01509                                  double alpha, const Mat& c, double beta)
01510 {
01511     res = MatExpr(&g_MatOp_GEMM, flags, a, b, c, alpha, beta);
01512 }
01513 
01514 ///////////////////////////////////////////////////////////////////////////////////////////////////////
01515 
01516 void MatOp_Invert::assign(const MatExpr& e, Mat& m, int _type) const
01517 {
01518     Mat temp, &dst = _type == -1 || _type == e.a.type() ? m : temp;
01519 
01520     cv::invert(e.a, dst, e.flags);
01521     if( dst.data != m.data )
01522         dst.convertTo(m, _type);
01523 }
01524 
01525 void MatOp_Invert::matmul(const MatExpr& e1, const MatExpr& e2, MatExpr& res) const
01526 {
01527     if( isInv(e1) && isIdentity(e2) )
01528         MatOp_Solve::makeExpr(res, e1.flags, e1.a, e2.a);
01529     else if( this == e2.op )
01530         MatOp::matmul(e1, e2, res);
01531     else
01532         e2.op->matmul(e1, e2, res);
01533 }
01534 
01535 inline void MatOp_Invert::makeExpr(MatExpr& res, int method, const Mat& m)
01536 {
01537     res = MatExpr(&g_MatOp_Invert, method, m, Mat(), Mat(), 1, 0);
01538 }
01539 
01540 /////////////////////////////////////////////////////////////////////////////////////////////////////////
01541 
01542 void MatOp_Solve::assign(const MatExpr& e, Mat& m, int _type) const
01543 {
01544     Mat temp, &dst = _type == -1 || _type == e.a.type() ? m : temp;
01545 
01546     cv::solve(e.a, e.b, dst, e.flags);
01547     if( dst.data != m.data )
01548         dst.convertTo(m, _type);
01549 }
01550 
01551 inline void MatOp_Solve::makeExpr(MatExpr& res, int method, const Mat& a, const Mat& b)
01552 {
01553     res = MatExpr(&g_MatOp_Solve, method, a, b, Mat(), 1, 1);
01554 }
01555 
01556 //////////////////////////////////////////////////////////////////////////////////////////////////////////
01557 
01558 void MatOp_Initializer::assign(const MatExpr& e, Mat& m, int _type) const
01559 {
01560     if( _type == -1 )
01561         _type = e.a.type();
01562 
01563     if( e.a.dims <= 2 )
01564         m.create(e.a.size(), _type);
01565     else
01566         m.create(e.a.dims, e.a.size, _type);
01567 
01568     if( e.flags == 'I' && e.a.dims <= 2 )
01569         setIdentity(m, Scalar(e.alpha));
01570     else if( e.flags == '0' )
01571         m = Scalar();
01572     else if( e.flags == '1' )
01573         m = Scalar(e.alpha);
01574     else
01575         CV_Error(CV_StsError, "Invalid matrix initializer type");
01576 }
01577 
01578 void MatOp_Initializer::multiply(const MatExpr& e, double s, MatExpr& res) const
01579 {
01580     res = e;
01581     res.alpha *= s;
01582 }
01583 
01584 inline void MatOp_Initializer::makeExpr(MatExpr& res, int method, Size sz, int type, double alpha)
01585 {
01586     res = MatExpr(getGlobalMatOpInitializer(), method, Mat(sz, type, (void*)(size_t)0xEEEEEEEE), Mat(), Mat(), alpha, 0);
01587 }
01588 
01589 inline void MatOp_Initializer::makeExpr(MatExpr& res, int method, int ndims, const int* sizes, int type, double alpha)
01590 {
01591     res = MatExpr(getGlobalMatOpInitializer(), method, Mat(ndims, sizes, type, (void*)(size_t)0xEEEEEEEE), Mat(), Mat(), alpha, 0);
01592 }
01593 
01594 ///////////////////////////////////////////////////////////////////////////////////////////////////////////
01595 
01596 MatExpr Mat::t() const
01597 {
01598     MatExpr e;
01599     MatOp_T::makeExpr(e, *this);
01600     return e;
01601 }
01602 
01603 MatExpr Mat::inv(int method) const
01604 {
01605     MatExpr e;
01606     MatOp_Invert::makeExpr(e, method, *this);
01607     return e;
01608 }
01609 
01610 
01611 MatExpr Mat::mul(InputArray m, double scale) const
01612 {
01613     MatExpr e;
01614     if(m.kind() == _InputArray::EXPR)
01615     {
01616         const MatExpr& me = *(const MatExpr*)m.getObj();
01617         me.op->multiply(MatExpr(*this), me, e, scale);
01618     }
01619     else
01620         MatOp_Bin::makeExpr(e, '*', *this, m.getMat(), scale);
01621     return e;
01622 }
01623 
01624 MatExpr Mat::zeros(int rows, int cols, int type)
01625 {
01626     MatExpr e;
01627     MatOp_Initializer::makeExpr(e, '0', Size(cols, rows), type);
01628     return e;
01629 }
01630 
01631 MatExpr Mat::zeros(Size size, int type)
01632 {
01633     MatExpr e;
01634     MatOp_Initializer::makeExpr(e, '0', size, type);
01635     return e;
01636 }
01637 
01638 MatExpr Mat::zeros(int ndims, const int* sizes, int type)
01639 {
01640     MatExpr e;
01641     MatOp_Initializer::makeExpr(e, '0', ndims, sizes, type);
01642     return e;
01643 }
01644 
01645 MatExpr Mat::ones(int rows, int cols, int type)
01646 {
01647     MatExpr e;
01648     MatOp_Initializer::makeExpr(e, '1', Size(cols, rows), type);
01649     return e;
01650 }
01651 
01652 MatExpr Mat::ones(Size size, int type)
01653 {
01654     MatExpr e;
01655     MatOp_Initializer::makeExpr(e, '1', size, type);
01656     return e;
01657 }
01658 
01659 MatExpr Mat::ones(int ndims, const int* sizes, int type)
01660 {
01661     MatExpr e;
01662     MatOp_Initializer::makeExpr(e, '1', ndims, sizes, type);
01663     return e;
01664 }
01665 
01666 MatExpr Mat::eye(int rows, int cols, int type)
01667 {
01668     MatExpr e;
01669     MatOp_Initializer::makeExpr(e, 'I', Size(cols, rows), type);
01670     return e;
01671 }
01672 
01673 MatExpr Mat::eye(Size size, int type)
01674 {
01675     MatExpr e;
01676     MatOp_Initializer::makeExpr(e, 'I', size, type);
01677     return e;
01678 }
01679 
01680 }
01681 
01682 /* End of file. */
01683