e4d72f7ed73ad16df2d49d0c307b05860e100694
[platform/upstream/opencv.git] / modules / core / include / opencv2 / core / matx.hpp
1 /*M///////////////////////////////////////////////////////////////////////////////////////
2 //
3 //  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
4 //
5 //  By downloading, copying, installing or using the software you agree to this license.
6 //  If you do not agree to this license, do not download, install,
7 //  copy or use the software.
8 //
9 //
10 //                          License Agreement
11 //                For Open Source Computer Vision Library
12 //
13 // Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
14 // Copyright (C) 2009, Willow Garage Inc., all rights reserved.
15 // Copyright (C) 2013, OpenCV Foundation, all rights reserved.
16 // Third party copyrights are property of their respective owners.
17 //
18 // Redistribution and use in source and binary forms, with or without modification,
19 // are permitted provided that the following conditions are met:
20 //
21 //   * Redistribution's of source code must retain the above copyright notice,
22 //     this list of conditions and the following disclaimer.
23 //
24 //   * Redistribution's in binary form must reproduce the above copyright notice,
25 //     this list of conditions and the following disclaimer in the documentation
26 //     and/or other materials provided with the distribution.
27 //
28 //   * The name of the copyright holders may not be used to endorse or promote products
29 //     derived from this software without specific prior written permission.
30 //
31 // This software is provided by the copyright holders and contributors "as is" and
32 // any express or implied warranties, including, but not limited to, the implied
33 // warranties of merchantability and fitness for a particular purpose are disclaimed.
34 // In no event shall the Intel Corporation or contributors be liable for any direct,
35 // indirect, incidental, special, exemplary, or consequential damages
36 // (including, but not limited to, procurement of substitute goods or services;
37 // loss of use, data, or profits; or business interruption) however caused
38 // and on any theory of liability, whether in contract, strict liability,
39 // or tort (including negligence or otherwise) arising in any way out of
40 // the use of this software, even if advised of the possibility of such damage.
41 //
42 //M*/
43
44 #ifndef __OPENCV_CORE_MATX_HPP__
45 #define __OPENCV_CORE_MATX_HPP__
46
47 #ifndef __cplusplus
48 #  error matx.hpp header must be compiled as C++
49 #endif
50
51 #include "opencv2/core/cvdef.h"
52 #include "opencv2/core/base.hpp"
53 #include "opencv2/core/traits.hpp"
54 #include "opencv2/core/saturate.hpp"
55
56 namespace cv
57 {
58
59 //! @addtogroup core_basic
60 //! @{
61
62 ////////////////////////////// Small Matrix ///////////////////////////
63
64 //! @cond IGNORED
65 struct CV_EXPORTS Matx_AddOp {};
66 struct CV_EXPORTS Matx_SubOp {};
67 struct CV_EXPORTS Matx_ScaleOp {};
68 struct CV_EXPORTS Matx_MulOp {};
69 struct CV_EXPORTS Matx_DivOp {};
70 struct CV_EXPORTS Matx_MatMulOp {};
71 struct CV_EXPORTS Matx_TOp {};
72 //! @endcond
73
74 /** @brief Template class for small matrices whose type and size are known at compilation time
75
76 If you need a more flexible type, use Mat . The elements of the matrix M are accessible using the
77 M(i,j) notation. Most of the common matrix operations (see also @ref MatrixExpressions ) are
78 available. To do an operation on Matx that is not implemented, you can easily convert the matrix to
79 Mat and backwards:
80 @code
81     Matx33f m(1, 2, 3,
82               4, 5, 6,
83               7, 8, 9);
84     cout << sum(Mat(m*m.t())) << endl;
85  @endcode
86  */
87 template<typename _Tp, int m, int n> class Matx
88 {
89 public:
90     enum { depth    = DataType<_Tp>::depth,
91            rows     = m,
92            cols     = n,
93            channels = rows*cols,
94            type     = CV_MAKETYPE(depth, channels),
95            shortdim = (m < n ? m : n)
96          };
97
98     typedef _Tp                           value_type;
99     typedef Matx<_Tp, m, n>               mat_type;
100     typedef Matx<_Tp, shortdim, 1> diag_type;
101
102     //! default constructor
103     Matx();
104
105     Matx(_Tp v0); //!< 1x1 matrix
106     Matx(_Tp v0, _Tp v1); //!< 1x2 or 2x1 matrix
107     Matx(_Tp v0, _Tp v1, _Tp v2); //!< 1x3 or 3x1 matrix
108     Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3); //!< 1x4, 2x2 or 4x1 matrix
109     Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4); //!< 1x5 or 5x1 matrix
110     Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5); //!< 1x6, 2x3, 3x2 or 6x1 matrix
111     Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6); //!< 1x7 or 7x1 matrix
112     Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7); //!< 1x8, 2x4, 4x2 or 8x1 matrix
113     Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8); //!< 1x9, 3x3 or 9x1 matrix
114     Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8, _Tp v9); //!< 1x10, 2x5 or 5x2 or 10x1 matrix
115     Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3,
116          _Tp v4, _Tp v5, _Tp v6, _Tp v7,
117          _Tp v8, _Tp v9, _Tp v10, _Tp v11); //!< 1x12, 2x6, 3x4, 4x3, 6x2 or 12x1 matrix
118     Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3,
119          _Tp v4, _Tp v5, _Tp v6, _Tp v7,
120          _Tp v8, _Tp v9, _Tp v10, _Tp v11,
121          _Tp v12, _Tp v13); //!< 1x14, 2x7, 7x2 or 14x1 matrix
122     Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3,
123          _Tp v4, _Tp v5, _Tp v6, _Tp v7,
124          _Tp v8, _Tp v9, _Tp v10, _Tp v11,
125          _Tp v12, _Tp v13, _Tp v14, _Tp v15); //!< 1x16, 4x4 or 16x1 matrix
126     explicit Matx(const _Tp* vals); //!< initialize from a plain array
127
128     static Matx all(_Tp alpha);
129     static Matx zeros();
130     static Matx ones();
131     static Matx eye();
132     static Matx diag(const diag_type& d);
133     static Matx randu(_Tp a, _Tp b);
134     static Matx randn(_Tp a, _Tp b);
135
136     //! dot product computed with the default precision
137     _Tp dot(const Matx<_Tp, m, n>& v) const;
138
139     //! dot product computed in double-precision arithmetics
140     double ddot(const Matx<_Tp, m, n>& v) const;
141
142     //! conversion to another data type
143     template<typename T2> operator Matx<T2, m, n>() const;
144
145     //! change the matrix shape
146     template<int m1, int n1> Matx<_Tp, m1, n1> reshape() const;
147
148     //! extract part of the matrix
149     template<int m1, int n1> Matx<_Tp, m1, n1> get_minor(int i, int j) const;
150
151     //! extract the matrix row
152     Matx<_Tp, 1, n> row(int i) const;
153
154     //! extract the matrix column
155     Matx<_Tp, m, 1> col(int i) const;
156
157     //! extract the matrix diagonal
158     diag_type diag() const;
159
160     //! transpose the matrix
161     Matx<_Tp, n, m> t() const;
162
163     //! invert the matrix
164     Matx<_Tp, n, m> inv(int method=DECOMP_LU, bool *p_is_ok = NULL) const;
165
166     //! solve linear system
167     template<int l> Matx<_Tp, n, l> solve(const Matx<_Tp, m, l>& rhs, int flags=DECOMP_LU) const;
168     Vec<_Tp, n> solve(const Vec<_Tp, m>& rhs, int method) const;
169
170     //! multiply two matrices element-wise
171     Matx<_Tp, m, n> mul(const Matx<_Tp, m, n>& a) const;
172
173     //! divide two matrices element-wise
174     Matx<_Tp, m, n> div(const Matx<_Tp, m, n>& a) const;
175
176     //! element access
177     const _Tp& operator ()(int i, int j) const;
178     _Tp& operator ()(int i, int j);
179
180     //! 1D element access
181     const _Tp& operator ()(int i) const;
182     _Tp& operator ()(int i);
183
184     Matx(const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b, Matx_AddOp);
185     Matx(const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b, Matx_SubOp);
186     template<typename _T2> Matx(const Matx<_Tp, m, n>& a, _T2 alpha, Matx_ScaleOp);
187     Matx(const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b, Matx_MulOp);
188     Matx(const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b, Matx_DivOp);
189     template<int l> Matx(const Matx<_Tp, m, l>& a, const Matx<_Tp, l, n>& b, Matx_MatMulOp);
190     Matx(const Matx<_Tp, n, m>& a, Matx_TOp);
191
192     _Tp val[m*n]; //< matrix elements
193 };
194
195 typedef Matx<float, 1, 2> Matx12f;
196 typedef Matx<double, 1, 2> Matx12d;
197 typedef Matx<float, 1, 3> Matx13f;
198 typedef Matx<double, 1, 3> Matx13d;
199 typedef Matx<float, 1, 4> Matx14f;
200 typedef Matx<double, 1, 4> Matx14d;
201 typedef Matx<float, 1, 6> Matx16f;
202 typedef Matx<double, 1, 6> Matx16d;
203
204 typedef Matx<float, 2, 1> Matx21f;
205 typedef Matx<double, 2, 1> Matx21d;
206 typedef Matx<float, 3, 1> Matx31f;
207 typedef Matx<double, 3, 1> Matx31d;
208 typedef Matx<float, 4, 1> Matx41f;
209 typedef Matx<double, 4, 1> Matx41d;
210 typedef Matx<float, 6, 1> Matx61f;
211 typedef Matx<double, 6, 1> Matx61d;
212
213 typedef Matx<float, 2, 2> Matx22f;
214 typedef Matx<double, 2, 2> Matx22d;
215 typedef Matx<float, 2, 3> Matx23f;
216 typedef Matx<double, 2, 3> Matx23d;
217 typedef Matx<float, 3, 2> Matx32f;
218 typedef Matx<double, 3, 2> Matx32d;
219
220 typedef Matx<float, 3, 3> Matx33f;
221 typedef Matx<double, 3, 3> Matx33d;
222
223 typedef Matx<float, 3, 4> Matx34f;
224 typedef Matx<double, 3, 4> Matx34d;
225 typedef Matx<float, 4, 3> Matx43f;
226 typedef Matx<double, 4, 3> Matx43d;
227
228 typedef Matx<float, 4, 4> Matx44f;
229 typedef Matx<double, 4, 4> Matx44d;
230 typedef Matx<float, 6, 6> Matx66f;
231 typedef Matx<double, 6, 6> Matx66d;
232
233 /*!
234   traits
235 */
236 template<typename _Tp, int m, int n> class DataType< Matx<_Tp, m, n> >
237 {
238 public:
239     typedef Matx<_Tp, m, n>                               value_type;
240     typedef Matx<typename DataType<_Tp>::work_type, m, n> work_type;
241     typedef _Tp                                           channel_type;
242     typedef value_type                                    vec_type;
243
244     enum { generic_type = 0,
245            depth        = DataType<channel_type>::depth,
246            channels     = m * n,
247            fmt          = DataType<channel_type>::fmt + ((channels - 1) << 8),
248            type         = CV_MAKETYPE(depth, channels)
249          };
250 };
251
252 /** @brief  Comma-separated Matrix Initializer
253 */
254 template<typename _Tp, int m, int n> class MatxCommaInitializer
255 {
256 public:
257     MatxCommaInitializer(Matx<_Tp, m, n>* _mtx);
258     template<typename T2> MatxCommaInitializer<_Tp, m, n>& operator , (T2 val);
259     Matx<_Tp, m, n> operator *() const;
260
261     Matx<_Tp, m, n>* dst;
262     int idx;
263 };
264
265 /*
266  Utility methods
267 */
268 template<typename _Tp, int m> static double determinant(const Matx<_Tp, m, m>& a);
269 template<typename _Tp, int m, int n> static double trace(const Matx<_Tp, m, n>& a);
270 template<typename _Tp, int m, int n> static double norm(const Matx<_Tp, m, n>& M);
271 template<typename _Tp, int m, int n> static double norm(const Matx<_Tp, m, n>& M, int normType);
272
273
274
275 /////////////////////// Vec (used as element of multi-channel images /////////////////////
276
277 /** @brief Template class for short numerical vectors, a partial case of Matx
278
279 This template class represents short numerical vectors (of 1, 2, 3, 4 ... elements) on which you
280 can perform basic arithmetical operations, access individual elements using [] operator etc. The
281 vectors are allocated on stack, as opposite to std::valarray, std::vector, cv::Mat etc., which
282 elements are dynamically allocated in the heap.
283
284 The template takes 2 parameters:
285 @tparam _Tp element type
286 @tparam cn the number of elements
287
288 In addition to the universal notation like Vec<float, 3>, you can use shorter aliases
289 for the most popular specialized variants of Vec, e.g. Vec3f ~ Vec<float, 3>.
290
291 It is possible to convert Vec\<T,2\> to/from Point_, Vec\<T,3\> to/from Point3_ , and Vec\<T,4\>
292 to CvScalar or Scalar_. Use operator[] to access the elements of Vec.
293
294 All the expected vector operations are also implemented:
295 -   v1 = v2 + v3
296 -   v1 = v2 - v3
297 -   v1 = v2 \* scale
298 -   v1 = scale \* v2
299 -   v1 = -v2
300 -   v1 += v2 and other augmenting operations
301 -   v1 == v2, v1 != v2
302 -   norm(v1) (euclidean norm)
303 The Vec class is commonly used to describe pixel types of multi-channel arrays. See Mat for details.
304 */
305 template<typename _Tp, int cn> class Vec : public Matx<_Tp, cn, 1>
306 {
307 public:
308     typedef _Tp value_type;
309     enum { depth    = Matx<_Tp, cn, 1>::depth,
310            channels = cn,
311            type     = CV_MAKETYPE(depth, channels)
312          };
313
314     //! default constructor
315     Vec();
316
317     Vec(_Tp v0); //!< 1-element vector constructor
318     Vec(_Tp v0, _Tp v1); //!< 2-element vector constructor
319     Vec(_Tp v0, _Tp v1, _Tp v2); //!< 3-element vector constructor
320     Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3); //!< 4-element vector constructor
321     Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4); //!< 5-element vector constructor
322     Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5); //!< 6-element vector constructor
323     Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6); //!< 7-element vector constructor
324     Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7); //!< 8-element vector constructor
325     Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8); //!< 9-element vector constructor
326     Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8, _Tp v9); //!< 10-element vector constructor
327     Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8, _Tp v9, _Tp v10, _Tp v11, _Tp v12, _Tp v13); //!< 14-element vector constructor
328     explicit Vec(const _Tp* values);
329
330     Vec(const Vec<_Tp, cn>& v);
331
332     static Vec all(_Tp alpha);
333
334     //! per-element multiplication
335     Vec mul(const Vec<_Tp, cn>& v) const;
336
337     //! conjugation (makes sense for complex numbers and quaternions)
338     Vec conj() const;
339
340     /*!
341       cross product of the two 3D vectors.
342
343       For other dimensionalities the exception is raised
344     */
345     Vec cross(const Vec& v) const;
346     //! conversion to another data type
347     template<typename T2> operator Vec<T2, cn>() const;
348
349     /*! element access */
350     const _Tp& operator [](int i) const;
351     _Tp& operator[](int i);
352     const _Tp& operator ()(int i) const;
353     _Tp& operator ()(int i);
354
355     Vec(const Matx<_Tp, cn, 1>& a, const Matx<_Tp, cn, 1>& b, Matx_AddOp);
356     Vec(const Matx<_Tp, cn, 1>& a, const Matx<_Tp, cn, 1>& b, Matx_SubOp);
357     template<typename _T2> Vec(const Matx<_Tp, cn, 1>& a, _T2 alpha, Matx_ScaleOp);
358 };
359
360 /** @name Shorter aliases for the most popular specializations of Vec<T,n>
361   @{
362 */
363 typedef Vec<uchar, 2> Vec2b;
364 typedef Vec<uchar, 3> Vec3b;
365 typedef Vec<uchar, 4> Vec4b;
366
367 typedef Vec<short, 2> Vec2s;
368 typedef Vec<short, 3> Vec3s;
369 typedef Vec<short, 4> Vec4s;
370
371 typedef Vec<ushort, 2> Vec2w;
372 typedef Vec<ushort, 3> Vec3w;
373 typedef Vec<ushort, 4> Vec4w;
374
375 typedef Vec<int, 2> Vec2i;
376 typedef Vec<int, 3> Vec3i;
377 typedef Vec<int, 4> Vec4i;
378 typedef Vec<int, 6> Vec6i;
379 typedef Vec<int, 8> Vec8i;
380
381 typedef Vec<float, 2> Vec2f;
382 typedef Vec<float, 3> Vec3f;
383 typedef Vec<float, 4> Vec4f;
384 typedef Vec<float, 6> Vec6f;
385
386 typedef Vec<double, 2> Vec2d;
387 typedef Vec<double, 3> Vec3d;
388 typedef Vec<double, 4> Vec4d;
389 typedef Vec<double, 6> Vec6d;
390 /** @} */
391
392 /*!
393   traits
394 */
395 template<typename _Tp, int cn> class DataType< Vec<_Tp, cn> >
396 {
397 public:
398     typedef Vec<_Tp, cn>                               value_type;
399     typedef Vec<typename DataType<_Tp>::work_type, cn> work_type;
400     typedef _Tp                                        channel_type;
401     typedef value_type                                 vec_type;
402
403     enum { generic_type = 0,
404            depth        = DataType<channel_type>::depth,
405            channels     = cn,
406            fmt          = DataType<channel_type>::fmt + ((channels - 1) << 8),
407            type         = CV_MAKETYPE(depth, channels)
408          };
409 };
410
411 /** @brief  Comma-separated Vec Initializer
412 */
413 template<typename _Tp, int m> class VecCommaInitializer : public MatxCommaInitializer<_Tp, m, 1>
414 {
415 public:
416     VecCommaInitializer(Vec<_Tp, m>* _vec);
417     template<typename T2> VecCommaInitializer<_Tp, m>& operator , (T2 val);
418     Vec<_Tp, m> operator *() const;
419 };
420
421 template<typename _Tp, int cn> static Vec<_Tp, cn> normalize(const Vec<_Tp, cn>& v);
422
423 //! @} core_basic
424
425 //! @cond IGNORED
426
427 ///////////////////////////////////// helper classes /////////////////////////////////////
428 namespace internal
429 {
430
431 template<typename _Tp, int m> struct Matx_DetOp
432 {
433     double operator ()(const Matx<_Tp, m, m>& a) const
434     {
435         Matx<_Tp, m, m> temp = a;
436         double p = LU(temp.val, m*sizeof(_Tp), m, 0, 0, 0);
437         if( p == 0 )
438             return p;
439         for( int i = 0; i < m; i++ )
440             p *= temp(i, i);
441         return 1./p;
442     }
443 };
444
445 template<typename _Tp> struct Matx_DetOp<_Tp, 1>
446 {
447     double operator ()(const Matx<_Tp, 1, 1>& a) const
448     {
449         return a(0,0);
450     }
451 };
452
453 template<typename _Tp> struct Matx_DetOp<_Tp, 2>
454 {
455     double operator ()(const Matx<_Tp, 2, 2>& a) const
456     {
457         return a(0,0)*a(1,1) - a(0,1)*a(1,0);
458     }
459 };
460
461 template<typename _Tp> struct Matx_DetOp<_Tp, 3>
462 {
463     double operator ()(const Matx<_Tp, 3, 3>& a) const
464     {
465         return a(0,0)*(a(1,1)*a(2,2) - a(2,1)*a(1,2)) -
466             a(0,1)*(a(1,0)*a(2,2) - a(2,0)*a(1,2)) +
467             a(0,2)*(a(1,0)*a(2,1) - a(2,0)*a(1,1));
468     }
469 };
470
471 template<typename _Tp> Vec<_Tp, 2> inline conjugate(const Vec<_Tp, 2>& v)
472 {
473     return Vec<_Tp, 2>(v[0], -v[1]);
474 }
475
476 template<typename _Tp> Vec<_Tp, 4> inline conjugate(const Vec<_Tp, 4>& v)
477 {
478     return Vec<_Tp, 4>(v[0], -v[1], -v[2], -v[3]);
479 }
480
481 } // internal
482
483
484
485 ////////////////////////////////// Matx Implementation ///////////////////////////////////
486
487 template<typename _Tp, int m, int n> inline
488 Matx<_Tp, m, n>::Matx()
489 {
490     for(int i = 0; i < channels; i++) val[i] = _Tp(0);
491 }
492
493 template<typename _Tp, int m, int n> inline
494 Matx<_Tp, m, n>::Matx(_Tp v0)
495 {
496     val[0] = v0;
497     for(int i = 1; i < channels; i++) val[i] = _Tp(0);
498 }
499
500 template<typename _Tp, int m, int n> inline
501 Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1)
502 {
503     CV_StaticAssert(channels >= 2, "Matx should have at least 2 elements.");
504     val[0] = v0; val[1] = v1;
505     for(int i = 2; i < channels; i++) val[i] = _Tp(0);
506 }
507
508 template<typename _Tp, int m, int n> inline
509 Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2)
510 {
511     CV_StaticAssert(channels >= 3, "Matx should have at least 3 elements.");
512     val[0] = v0; val[1] = v1; val[2] = v2;
513     for(int i = 3; i < channels; i++) val[i] = _Tp(0);
514 }
515
516 template<typename _Tp, int m, int n> inline
517 Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3)
518 {
519     CV_StaticAssert(channels >= 4, "Matx should have at least 4 elements.");
520     val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3;
521     for(int i = 4; i < channels; i++) val[i] = _Tp(0);
522 }
523
524 template<typename _Tp, int m, int n> inline
525 Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4)
526 {
527     CV_StaticAssert(channels >= 5, "Matx should have at least 5 elements.");
528     val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3; val[4] = v4;
529     for(int i = 5; i < channels; i++) val[i] = _Tp(0);
530 }
531
532 template<typename _Tp, int m, int n> inline
533 Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5)
534 {
535     CV_StaticAssert(channels >= 6, "Matx should have at least 6 elements.");
536     val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3;
537     val[4] = v4; val[5] = v5;
538     for(int i = 6; i < channels; i++) val[i] = _Tp(0);
539 }
540
541 template<typename _Tp, int m, int n> inline
542 Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6)
543 {
544     CV_StaticAssert(channels >= 7, "Matx should have at least 7 elements.");
545     val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3;
546     val[4] = v4; val[5] = v5; val[6] = v6;
547     for(int i = 7; i < channels; i++) val[i] = _Tp(0);
548 }
549
550 template<typename _Tp, int m, int n> inline
551 Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7)
552 {
553     CV_StaticAssert(channels >= 8, "Matx should have at least 8 elements.");
554     val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3;
555     val[4] = v4; val[5] = v5; val[6] = v6; val[7] = v7;
556     for(int i = 8; i < channels; i++) val[i] = _Tp(0);
557 }
558
559 template<typename _Tp, int m, int n> inline
560 Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8)
561 {
562     CV_StaticAssert(channels >= 9, "Matx should have at least 9 elements.");
563     val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3;
564     val[4] = v4; val[5] = v5; val[6] = v6; val[7] = v7;
565     val[8] = v8;
566     for(int i = 9; i < channels; i++) val[i] = _Tp(0);
567 }
568
569 template<typename _Tp, int m, int n> inline
570 Matx<_Tp, m, n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8, _Tp v9)
571 {
572     CV_StaticAssert(channels >= 10, "Matx should have at least 10 elements.");
573     val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3;
574     val[4] = v4; val[5] = v5; val[6] = v6; val[7] = v7;
575     val[8] = v8; val[9] = v9;
576     for(int i = 10; i < channels; i++) val[i] = _Tp(0);
577 }
578
579
580 template<typename _Tp, int m, int n> inline
581 Matx<_Tp,m,n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8, _Tp v9, _Tp v10, _Tp v11)
582 {
583     CV_StaticAssert(channels >= 12, "Matx should have at least 12 elements.");
584     val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3;
585     val[4] = v4; val[5] = v5; val[6] = v6; val[7] = v7;
586     val[8] = v8; val[9] = v9; val[10] = v10; val[11] = v11;
587     for(int i = 12; i < channels; i++) val[i] = _Tp(0);
588 }
589
590 template<typename _Tp, int m, int n> inline
591 Matx<_Tp,m,n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8, _Tp v9, _Tp v10, _Tp v11, _Tp v12, _Tp v13)
592 {
593     CV_StaticAssert(channels == 14, "Matx should have at least 14 elements.");
594     val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3;
595     val[4] = v4; val[5] = v5; val[6] = v6; val[7] = v7;
596     val[8] = v8; val[9] = v9; val[10] = v10; val[11] = v11;
597     val[12] = v12; val[13] = v13;
598 }
599
600
601 template<typename _Tp, int m, int n> inline
602 Matx<_Tp,m,n>::Matx(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8, _Tp v9, _Tp v10, _Tp v11, _Tp v12, _Tp v13, _Tp v14, _Tp v15)
603 {
604     CV_StaticAssert(channels >= 16, "Matx should have at least 16 elements.");
605     val[0] = v0; val[1] = v1; val[2] = v2; val[3] = v3;
606     val[4] = v4; val[5] = v5; val[6] = v6; val[7] = v7;
607     val[8] = v8; val[9] = v9; val[10] = v10; val[11] = v11;
608     val[12] = v12; val[13] = v13; val[14] = v14; val[15] = v15;
609     for(int i = 16; i < channels; i++) val[i] = _Tp(0);
610 }
611
612 template<typename _Tp, int m, int n> inline
613 Matx<_Tp, m, n>::Matx(const _Tp* values)
614 {
615     for( int i = 0; i < channels; i++ ) val[i] = values[i];
616 }
617
618 template<typename _Tp, int m, int n> inline
619 Matx<_Tp, m, n> Matx<_Tp, m, n>::all(_Tp alpha)
620 {
621     Matx<_Tp, m, n> M;
622     for( int i = 0; i < m*n; i++ ) M.val[i] = alpha;
623     return M;
624 }
625
626 template<typename _Tp, int m, int n> inline
627 Matx<_Tp,m,n> Matx<_Tp,m,n>::zeros()
628 {
629     return all(0);
630 }
631
632 template<typename _Tp, int m, int n> inline
633 Matx<_Tp,m,n> Matx<_Tp,m,n>::ones()
634 {
635     return all(1);
636 }
637
638 template<typename _Tp, int m, int n> inline
639 Matx<_Tp,m,n> Matx<_Tp,m,n>::eye()
640 {
641     Matx<_Tp,m,n> M;
642     for(int i = 0; i < shortdim; i++)
643         M(i,i) = 1;
644     return M;
645 }
646
647 template<typename _Tp, int m, int n> inline
648 _Tp Matx<_Tp, m, n>::dot(const Matx<_Tp, m, n>& M) const
649 {
650     _Tp s = 0;
651     for( int i = 0; i < channels; i++ ) s += val[i]*M.val[i];
652     return s;
653 }
654
655 template<typename _Tp, int m, int n> inline
656 double Matx<_Tp, m, n>::ddot(const Matx<_Tp, m, n>& M) const
657 {
658     double s = 0;
659     for( int i = 0; i < channels; i++ ) s += (double)val[i]*M.val[i];
660     return s;
661 }
662
663 template<typename _Tp, int m, int n> inline
664 Matx<_Tp,m,n> Matx<_Tp,m,n>::diag(const typename Matx<_Tp,m,n>::diag_type& d)
665 {
666     Matx<_Tp,m,n> M;
667     for(int i = 0; i < shortdim; i++)
668         M(i,i) = d(i, 0);
669     return M;
670 }
671
672 template<typename _Tp, int m, int n> template<typename T2>
673 inline Matx<_Tp, m, n>::operator Matx<T2, m, n>() const
674 {
675     Matx<T2, m, n> M;
676     for( int i = 0; i < m*n; i++ ) M.val[i] = saturate_cast<T2>(val[i]);
677     return M;
678 }
679
680 template<typename _Tp, int m, int n> template<int m1, int n1> inline
681 Matx<_Tp, m1, n1> Matx<_Tp, m, n>::reshape() const
682 {
683     CV_StaticAssert(m1*n1 == m*n, "Input and destnarion matrices must have the same number of elements");
684     return (const Matx<_Tp, m1, n1>&)*this;
685 }
686
687 template<typename _Tp, int m, int n>
688 template<int m1, int n1> inline
689 Matx<_Tp, m1, n1> Matx<_Tp, m, n>::get_minor(int i, int j) const
690 {
691     CV_DbgAssert(0 <= i && i+m1 <= m && 0 <= j && j+n1 <= n);
692     Matx<_Tp, m1, n1> s;
693     for( int di = 0; di < m1; di++ )
694         for( int dj = 0; dj < n1; dj++ )
695             s(di, dj) = (*this)(i+di, j+dj);
696     return s;
697 }
698
699 template<typename _Tp, int m, int n> inline
700 Matx<_Tp, 1, n> Matx<_Tp, m, n>::row(int i) const
701 {
702     CV_DbgAssert((unsigned)i < (unsigned)m);
703     return Matx<_Tp, 1, n>(&val[i*n]);
704 }
705
706 template<typename _Tp, int m, int n> inline
707 Matx<_Tp, m, 1> Matx<_Tp, m, n>::col(int j) const
708 {
709     CV_DbgAssert((unsigned)j < (unsigned)n);
710     Matx<_Tp, m, 1> v;
711     for( int i = 0; i < m; i++ )
712         v.val[i] = val[i*n + j];
713     return v;
714 }
715
716 template<typename _Tp, int m, int n> inline
717 typename Matx<_Tp, m, n>::diag_type Matx<_Tp, m, n>::diag() const
718 {
719     diag_type d;
720     for( int i = 0; i < shortdim; i++ )
721         d.val[i] = val[i*n + i];
722     return d;
723 }
724
725 template<typename _Tp, int m, int n> inline
726 const _Tp& Matx<_Tp, m, n>::operator()(int i, int j) const
727 {
728     CV_DbgAssert( (unsigned)i < (unsigned)m && (unsigned)j < (unsigned)n );
729     return this->val[i*n + j];
730 }
731
732 template<typename _Tp, int m, int n> inline
733 _Tp& Matx<_Tp, m, n>::operator ()(int i, int j)
734 {
735     CV_DbgAssert( (unsigned)i < (unsigned)m && (unsigned)j < (unsigned)n );
736     return val[i*n + j];
737 }
738
739 template<typename _Tp, int m, int n> inline
740 const _Tp& Matx<_Tp, m, n>::operator ()(int i) const
741 {
742     CV_StaticAssert(m == 1 || n == 1, "Single index indexation requires matrix to be a column or a row");
743     CV_DbgAssert( (unsigned)i < (unsigned)(m+n-1) );
744     return val[i];
745 }
746
747 template<typename _Tp, int m, int n> inline
748 _Tp& Matx<_Tp, m, n>::operator ()(int i)
749 {
750     CV_StaticAssert(m == 1 || n == 1, "Single index indexation requires matrix to be a column or a row");
751     CV_DbgAssert( (unsigned)i < (unsigned)(m+n-1) );
752     return val[i];
753 }
754
755 template<typename _Tp, int m, int n> inline
756 Matx<_Tp,m,n>::Matx(const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b, Matx_AddOp)
757 {
758     for( int i = 0; i < channels; i++ )
759         val[i] = saturate_cast<_Tp>(a.val[i] + b.val[i]);
760 }
761
762 template<typename _Tp, int m, int n> inline
763 Matx<_Tp,m,n>::Matx(const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b, Matx_SubOp)
764 {
765     for( int i = 0; i < channels; i++ )
766         val[i] = saturate_cast<_Tp>(a.val[i] - b.val[i]);
767 }
768
769 template<typename _Tp, int m, int n> template<typename _T2> inline
770 Matx<_Tp,m,n>::Matx(const Matx<_Tp, m, n>& a, _T2 alpha, Matx_ScaleOp)
771 {
772     for( int i = 0; i < channels; i++ )
773         val[i] = saturate_cast<_Tp>(a.val[i] * alpha);
774 }
775
776 template<typename _Tp, int m, int n> inline
777 Matx<_Tp,m,n>::Matx(const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b, Matx_MulOp)
778 {
779     for( int i = 0; i < channels; i++ )
780         val[i] = saturate_cast<_Tp>(a.val[i] * b.val[i]);
781 }
782
783 template<typename _Tp, int m, int n> inline
784 Matx<_Tp,m,n>::Matx(const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b, Matx_DivOp)
785 {
786     for( int i = 0; i < channels; i++ )
787         val[i] = saturate_cast<_Tp>(a.val[i] / b.val[i]);
788 }
789
790 template<typename _Tp, int m, int n> template<int l> inline
791 Matx<_Tp,m,n>::Matx(const Matx<_Tp, m, l>& a, const Matx<_Tp, l, n>& b, Matx_MatMulOp)
792 {
793     for( int i = 0; i < m; i++ )
794         for( int j = 0; j < n; j++ )
795         {
796             _Tp s = 0;
797             for( int k = 0; k < l; k++ )
798                 s += a(i, k) * b(k, j);
799             val[i*n + j] = s;
800         }
801 }
802
803 template<typename _Tp, int m, int n> inline
804 Matx<_Tp,m,n>::Matx(const Matx<_Tp, n, m>& a, Matx_TOp)
805 {
806     for( int i = 0; i < m; i++ )
807         for( int j = 0; j < n; j++ )
808             val[i*n + j] = a(j, i);
809 }
810
811 template<typename _Tp, int m, int n> inline
812 Matx<_Tp, m, n> Matx<_Tp, m, n>::mul(const Matx<_Tp, m, n>& a) const
813 {
814     return Matx<_Tp, m, n>(*this, a, Matx_MulOp());
815 }
816
817 template<typename _Tp, int m, int n> inline
818 Matx<_Tp, m, n> Matx<_Tp, m, n>::div(const Matx<_Tp, m, n>& a) const
819 {
820     return Matx<_Tp, m, n>(*this, a, Matx_DivOp());
821 }
822
823 template<typename _Tp, int m, int n> inline
824 Matx<_Tp, n, m> Matx<_Tp, m, n>::t() const
825 {
826     return Matx<_Tp, n, m>(*this, Matx_TOp());
827 }
828
829 template<typename _Tp, int m, int n> inline
830 Vec<_Tp, n> Matx<_Tp, m, n>::solve(const Vec<_Tp, m>& rhs, int method) const
831 {
832     Matx<_Tp, n, 1> x = solve((const Matx<_Tp, m, 1>&)(rhs), method);
833     return (Vec<_Tp, n>&)(x);
834 }
835
836 template<typename _Tp, int m> static inline
837 double determinant(const Matx<_Tp, m, m>& a)
838 {
839     return cv::internal::Matx_DetOp<_Tp, m>()(a);
840 }
841
842 template<typename _Tp, int m, int n> static inline
843 double trace(const Matx<_Tp, m, n>& a)
844 {
845     _Tp s = 0;
846     for( int i = 0; i < std::min(m, n); i++ )
847         s += a(i,i);
848     return s;
849 }
850
851 template<typename _Tp, int m, int n> static inline
852 double norm(const Matx<_Tp, m, n>& M)
853 {
854     return std::sqrt(normL2Sqr<_Tp, double>(M.val, m*n));
855 }
856
857 template<typename _Tp, int m, int n> static inline
858 double norm(const Matx<_Tp, m, n>& M, int normType)
859 {
860     switch(normType) {
861     case NORM_INF:
862         return (double)normInf<_Tp, typename DataType<_Tp>::work_type>(M.val, m*n);
863     case NORM_L1:
864         return (double)normL1<_Tp, typename DataType<_Tp>::work_type>(M.val, m*n);
865     case NORM_L2SQR:
866         return (double)normL2Sqr<_Tp, typename DataType<_Tp>::work_type>(M.val, m*n);
867     default:
868     case NORM_L2:
869         return std::sqrt((double)normL2Sqr<_Tp, typename DataType<_Tp>::work_type>(M.val, m*n));
870     }
871 }
872
873
874
875 //////////////////////////////// matx comma initializer //////////////////////////////////
876
877 template<typename _Tp, typename _T2, int m, int n> static inline
878 MatxCommaInitializer<_Tp, m, n> operator << (const Matx<_Tp, m, n>& mtx, _T2 val)
879 {
880     MatxCommaInitializer<_Tp, m, n> commaInitializer((Matx<_Tp, m, n>*)&mtx);
881     return (commaInitializer, val);
882 }
883
884 template<typename _Tp, int m, int n> inline
885 MatxCommaInitializer<_Tp, m, n>::MatxCommaInitializer(Matx<_Tp, m, n>* _mtx)
886     : dst(_mtx), idx(0)
887 {}
888
889 template<typename _Tp, int m, int n> template<typename _T2> inline
890 MatxCommaInitializer<_Tp, m, n>& MatxCommaInitializer<_Tp, m, n>::operator , (_T2 value)
891 {
892     CV_DbgAssert( idx < m*n );
893     dst->val[idx++] = saturate_cast<_Tp>(value);
894     return *this;
895 }
896
897 template<typename _Tp, int m, int n> inline
898 Matx<_Tp, m, n> MatxCommaInitializer<_Tp, m, n>::operator *() const
899 {
900     CV_DbgAssert( idx == n*m );
901     return *dst;
902 }
903
904
905
906 /////////////////////////////////// Vec Implementation ///////////////////////////////////
907
908 template<typename _Tp, int cn> inline
909 Vec<_Tp, cn>::Vec() {}
910
911 template<typename _Tp, int cn> inline
912 Vec<_Tp, cn>::Vec(_Tp v0)
913     : Matx<_Tp, cn, 1>(v0) {}
914
915 template<typename _Tp, int cn> inline
916 Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1)
917     : Matx<_Tp, cn, 1>(v0, v1) {}
918
919 template<typename _Tp, int cn> inline
920 Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2)
921     : Matx<_Tp, cn, 1>(v0, v1, v2) {}
922
923 template<typename _Tp, int cn> inline
924 Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3)
925     : Matx<_Tp, cn, 1>(v0, v1, v2, v3) {}
926
927 template<typename _Tp, int cn> inline
928 Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4)
929     : Matx<_Tp, cn, 1>(v0, v1, v2, v3, v4) {}
930
931 template<typename _Tp, int cn> inline
932 Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5)
933     : Matx<_Tp, cn, 1>(v0, v1, v2, v3, v4, v5) {}
934
935 template<typename _Tp, int cn> inline
936 Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6)
937     : Matx<_Tp, cn, 1>(v0, v1, v2, v3, v4, v5, v6) {}
938
939 template<typename _Tp, int cn> inline
940 Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7)
941     : Matx<_Tp, cn, 1>(v0, v1, v2, v3, v4, v5, v6, v7) {}
942
943 template<typename _Tp, int cn> inline
944 Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8)
945     : Matx<_Tp, cn, 1>(v0, v1, v2, v3, v4, v5, v6, v7, v8) {}
946
947 template<typename _Tp, int cn> inline
948 Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8, _Tp v9)
949     : Matx<_Tp, cn, 1>(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9) {}
950
951 template<typename _Tp, int cn> inline
952 Vec<_Tp, cn>::Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8, _Tp v9, _Tp v10, _Tp v11, _Tp v12, _Tp v13)
953     : Matx<_Tp, cn, 1>(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13) {}
954
955 template<typename _Tp, int cn> inline
956 Vec<_Tp, cn>::Vec(const _Tp* values)
957     : Matx<_Tp, cn, 1>(values) {}
958
959 template<typename _Tp, int cn> inline
960 Vec<_Tp, cn>::Vec(const Vec<_Tp, cn>& m)
961     : Matx<_Tp, cn, 1>(m.val) {}
962
963 template<typename _Tp, int cn> inline
964 Vec<_Tp, cn>::Vec(const Matx<_Tp, cn, 1>& a, const Matx<_Tp, cn, 1>& b, Matx_AddOp op)
965     : Matx<_Tp, cn, 1>(a, b, op) {}
966
967 template<typename _Tp, int cn> inline
968 Vec<_Tp, cn>::Vec(const Matx<_Tp, cn, 1>& a, const Matx<_Tp, cn, 1>& b, Matx_SubOp op)
969     : Matx<_Tp, cn, 1>(a, b, op) {}
970
971 template<typename _Tp, int cn> template<typename _T2> inline
972 Vec<_Tp, cn>::Vec(const Matx<_Tp, cn, 1>& a, _T2 alpha, Matx_ScaleOp op)
973     : Matx<_Tp, cn, 1>(a, alpha, op) {}
974
975 template<typename _Tp, int cn> inline
976 Vec<_Tp, cn> Vec<_Tp, cn>::all(_Tp alpha)
977 {
978     Vec v;
979     for( int i = 0; i < cn; i++ ) v.val[i] = alpha;
980     return v;
981 }
982
983 template<typename _Tp, int cn> inline
984 Vec<_Tp, cn> Vec<_Tp, cn>::mul(const Vec<_Tp, cn>& v) const
985 {
986     Vec<_Tp, cn> w;
987     for( int i = 0; i < cn; i++ ) w.val[i] = saturate_cast<_Tp>(this->val[i]*v.val[i]);
988     return w;
989 }
990
991 template<> inline
992 Vec<float, 2> Vec<float, 2>::conj() const
993 {
994     return cv::internal::conjugate(*this);
995 }
996
997 template<> inline
998 Vec<double, 2> Vec<double, 2>::conj() const
999 {
1000     return cv::internal::conjugate(*this);
1001 }
1002
1003 template<> inline
1004 Vec<float, 4> Vec<float, 4>::conj() const
1005 {
1006     return cv::internal::conjugate(*this);
1007 }
1008
1009 template<> inline
1010 Vec<double, 4> Vec<double, 4>::conj() const
1011 {
1012     return cv::internal::conjugate(*this);
1013 }
1014
1015 template<typename _Tp, int cn> inline
1016 Vec<_Tp, cn> Vec<_Tp, cn>::cross(const Vec<_Tp, cn>&) const
1017 {
1018     CV_StaticAssert(cn == 3, "for arbitrary-size vector there is no cross-product defined");
1019     return Vec<_Tp, cn>();
1020 }
1021
1022 template<> inline
1023 Vec<float, 3> Vec<float, 3>::cross(const Vec<float, 3>& v) const
1024 {
1025     return Vec<float,3>(this->val[1]*v.val[2] - this->val[2]*v.val[1],
1026                      this->val[2]*v.val[0] - this->val[0]*v.val[2],
1027                      this->val[0]*v.val[1] - this->val[1]*v.val[0]);
1028 }
1029
1030 template<> inline
1031 Vec<double, 3> Vec<double, 3>::cross(const Vec<double, 3>& v) const
1032 {
1033     return Vec<double,3>(this->val[1]*v.val[2] - this->val[2]*v.val[1],
1034                      this->val[2]*v.val[0] - this->val[0]*v.val[2],
1035                      this->val[0]*v.val[1] - this->val[1]*v.val[0]);
1036 }
1037
1038 template<typename _Tp, int cn> template<typename T2> inline
1039 Vec<_Tp, cn>::operator Vec<T2, cn>() const
1040 {
1041     Vec<T2, cn> v;
1042     for( int i = 0; i < cn; i++ ) v.val[i] = saturate_cast<T2>(this->val[i]);
1043     return v;
1044 }
1045
1046 template<typename _Tp, int cn> inline
1047 const _Tp& Vec<_Tp, cn>::operator [](int i) const
1048 {
1049     CV_DbgAssert( (unsigned)i < (unsigned)cn );
1050     return this->val[i];
1051 }
1052
1053 template<typename _Tp, int cn> inline
1054 _Tp& Vec<_Tp, cn>::operator [](int i)
1055 {
1056     CV_DbgAssert( (unsigned)i < (unsigned)cn );
1057     return this->val[i];
1058 }
1059
1060 template<typename _Tp, int cn> inline
1061 const _Tp& Vec<_Tp, cn>::operator ()(int i) const
1062 {
1063     CV_DbgAssert( (unsigned)i < (unsigned)cn );
1064     return this->val[i];
1065 }
1066
1067 template<typename _Tp, int cn> inline
1068 _Tp& Vec<_Tp, cn>::operator ()(int i)
1069 {
1070     CV_DbgAssert( (unsigned)i < (unsigned)cn );
1071     return this->val[i];
1072 }
1073
1074 template<typename _Tp, int cn> inline
1075 Vec<_Tp, cn> normalize(const Vec<_Tp, cn>& v)
1076 {
1077     double nv = norm(v);
1078     return v * (nv ? 1./nv : 0.);
1079 }
1080
1081
1082
1083 //////////////////////////////// matx comma initializer //////////////////////////////////
1084
1085
1086 template<typename _Tp, typename _T2, int cn> static inline
1087 VecCommaInitializer<_Tp, cn> operator << (const Vec<_Tp, cn>& vec, _T2 val)
1088 {
1089     VecCommaInitializer<_Tp, cn> commaInitializer((Vec<_Tp, cn>*)&vec);
1090     return (commaInitializer, val);
1091 }
1092
1093 template<typename _Tp, int cn> inline
1094 VecCommaInitializer<_Tp, cn>::VecCommaInitializer(Vec<_Tp, cn>* _vec)
1095     : MatxCommaInitializer<_Tp, cn, 1>(_vec)
1096 {}
1097
1098 template<typename _Tp, int cn> template<typename _T2> inline
1099 VecCommaInitializer<_Tp, cn>& VecCommaInitializer<_Tp, cn>::operator , (_T2 value)
1100 {
1101     CV_DbgAssert( this->idx < cn );
1102     this->dst->val[this->idx++] = saturate_cast<_Tp>(value);
1103     return *this;
1104 }
1105
1106 template<typename _Tp, int cn> inline
1107 Vec<_Tp, cn> VecCommaInitializer<_Tp, cn>::operator *() const
1108 {
1109     CV_DbgAssert( this->idx == cn );
1110     return *this->dst;
1111 }
1112
1113 //! @endcond
1114
1115 ///////////////////////////// Matx out-of-class operators ////////////////////////////////
1116
1117 //! @relates cv::Matx
1118 //! @{
1119
1120 template<typename _Tp1, typename _Tp2, int m, int n> static inline
1121 Matx<_Tp1, m, n>& operator += (Matx<_Tp1, m, n>& a, const Matx<_Tp2, m, n>& b)
1122 {
1123     for( int i = 0; i < m*n; i++ )
1124         a.val[i] = saturate_cast<_Tp1>(a.val[i] + b.val[i]);
1125     return a;
1126 }
1127
1128 template<typename _Tp1, typename _Tp2, int m, int n> static inline
1129 Matx<_Tp1, m, n>& operator -= (Matx<_Tp1, m, n>& a, const Matx<_Tp2, m, n>& b)
1130 {
1131     for( int i = 0; i < m*n; i++ )
1132         a.val[i] = saturate_cast<_Tp1>(a.val[i] - b.val[i]);
1133     return a;
1134 }
1135
1136 template<typename _Tp, int m, int n> static inline
1137 Matx<_Tp, m, n> operator + (const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b)
1138 {
1139     return Matx<_Tp, m, n>(a, b, Matx_AddOp());
1140 }
1141
1142 template<typename _Tp, int m, int n> static inline
1143 Matx<_Tp, m, n> operator - (const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b)
1144 {
1145     return Matx<_Tp, m, n>(a, b, Matx_SubOp());
1146 }
1147
1148 template<typename _Tp, int m, int n> static inline
1149 Matx<_Tp, m, n>& operator *= (Matx<_Tp, m, n>& a, int alpha)
1150 {
1151     for( int i = 0; i < m*n; i++ )
1152         a.val[i] = saturate_cast<_Tp>(a.val[i] * alpha);
1153     return a;
1154 }
1155
1156 template<typename _Tp, int m, int n> static inline
1157 Matx<_Tp, m, n>& operator *= (Matx<_Tp, m, n>& a, float alpha)
1158 {
1159     for( int i = 0; i < m*n; i++ )
1160         a.val[i] = saturate_cast<_Tp>(a.val[i] * alpha);
1161     return a;
1162 }
1163
1164 template<typename _Tp, int m, int n> static inline
1165 Matx<_Tp, m, n>& operator *= (Matx<_Tp, m, n>& a, double alpha)
1166 {
1167     for( int i = 0; i < m*n; i++ )
1168         a.val[i] = saturate_cast<_Tp>(a.val[i] * alpha);
1169     return a;
1170 }
1171
1172 template<typename _Tp, int m, int n> static inline
1173 Matx<_Tp, m, n> operator * (const Matx<_Tp, m, n>& a, int alpha)
1174 {
1175     return Matx<_Tp, m, n>(a, alpha, Matx_ScaleOp());
1176 }
1177
1178 template<typename _Tp, int m, int n> static inline
1179 Matx<_Tp, m, n> operator * (const Matx<_Tp, m, n>& a, float alpha)
1180 {
1181     return Matx<_Tp, m, n>(a, alpha, Matx_ScaleOp());
1182 }
1183
1184 template<typename _Tp, int m, int n> static inline
1185 Matx<_Tp, m, n> operator * (const Matx<_Tp, m, n>& a, double alpha)
1186 {
1187     return Matx<_Tp, m, n>(a, alpha, Matx_ScaleOp());
1188 }
1189
1190 template<typename _Tp, int m, int n> static inline
1191 Matx<_Tp, m, n> operator * (int alpha, const Matx<_Tp, m, n>& a)
1192 {
1193     return Matx<_Tp, m, n>(a, alpha, Matx_ScaleOp());
1194 }
1195
1196 template<typename _Tp, int m, int n> static inline
1197 Matx<_Tp, m, n> operator * (float alpha, const Matx<_Tp, m, n>& a)
1198 {
1199     return Matx<_Tp, m, n>(a, alpha, Matx_ScaleOp());
1200 }
1201
1202 template<typename _Tp, int m, int n> static inline
1203 Matx<_Tp, m, n> operator * (double alpha, const Matx<_Tp, m, n>& a)
1204 {
1205     return Matx<_Tp, m, n>(a, alpha, Matx_ScaleOp());
1206 }
1207
1208 template<typename _Tp, int m, int n> static inline
1209 Matx<_Tp, m, n> operator - (const Matx<_Tp, m, n>& a)
1210 {
1211     return Matx<_Tp, m, n>(a, -1, Matx_ScaleOp());
1212 }
1213
1214 template<typename _Tp, int m, int n, int l> static inline
1215 Matx<_Tp, m, n> operator * (const Matx<_Tp, m, l>& a, const Matx<_Tp, l, n>& b)
1216 {
1217     return Matx<_Tp, m, n>(a, b, Matx_MatMulOp());
1218 }
1219
1220 template<typename _Tp, int m, int n> static inline
1221 Vec<_Tp, m> operator * (const Matx<_Tp, m, n>& a, const Vec<_Tp, n>& b)
1222 {
1223     Matx<_Tp, m, 1> c(a, b, Matx_MatMulOp());
1224     return (const Vec<_Tp, m>&)(c);
1225 }
1226
1227 template<typename _Tp, int m, int n> static inline
1228 bool operator == (const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b)
1229 {
1230     for( int i = 0; i < m*n; i++ )
1231         if( a.val[i] != b.val[i] ) return false;
1232     return true;
1233 }
1234
1235 template<typename _Tp, int m, int n> static inline
1236 bool operator != (const Matx<_Tp, m, n>& a, const Matx<_Tp, m, n>& b)
1237 {
1238     return !(a == b);
1239 }
1240
1241 //! @}
1242
1243 ////////////////////////////// Vec out-of-class operators ////////////////////////////////
1244
1245 //! @relates cv::Vec
1246 //! @{
1247
1248 template<typename _Tp1, typename _Tp2, int cn> static inline
1249 Vec<_Tp1, cn>& operator += (Vec<_Tp1, cn>& a, const Vec<_Tp2, cn>& b)
1250 {
1251     for( int i = 0; i < cn; i++ )
1252         a.val[i] = saturate_cast<_Tp1>(a.val[i] + b.val[i]);
1253     return a;
1254 }
1255
1256 template<typename _Tp1, typename _Tp2, int cn> static inline
1257 Vec<_Tp1, cn>& operator -= (Vec<_Tp1, cn>& a, const Vec<_Tp2, cn>& b)
1258 {
1259     for( int i = 0; i < cn; i++ )
1260         a.val[i] = saturate_cast<_Tp1>(a.val[i] - b.val[i]);
1261     return a;
1262 }
1263
1264 template<typename _Tp, int cn> static inline
1265 Vec<_Tp, cn> operator + (const Vec<_Tp, cn>& a, const Vec<_Tp, cn>& b)
1266 {
1267     return Vec<_Tp, cn>(a, b, Matx_AddOp());
1268 }
1269
1270 template<typename _Tp, int cn> static inline
1271 Vec<_Tp, cn> operator - (const Vec<_Tp, cn>& a, const Vec<_Tp, cn>& b)
1272 {
1273     return Vec<_Tp, cn>(a, b, Matx_SubOp());
1274 }
1275
1276 template<typename _Tp, int cn> static inline
1277 Vec<_Tp, cn>& operator *= (Vec<_Tp, cn>& a, int alpha)
1278 {
1279     for( int i = 0; i < cn; i++ )
1280         a[i] = saturate_cast<_Tp>(a[i]*alpha);
1281     return a;
1282 }
1283
1284 template<typename _Tp, int cn> static inline
1285 Vec<_Tp, cn>& operator *= (Vec<_Tp, cn>& a, float alpha)
1286 {
1287     for( int i = 0; i < cn; i++ )
1288         a[i] = saturate_cast<_Tp>(a[i]*alpha);
1289     return a;
1290 }
1291
1292 template<typename _Tp, int cn> static inline
1293 Vec<_Tp, cn>& operator *= (Vec<_Tp, cn>& a, double alpha)
1294 {
1295     for( int i = 0; i < cn; i++ )
1296         a[i] = saturate_cast<_Tp>(a[i]*alpha);
1297     return a;
1298 }
1299
1300 template<typename _Tp, int cn> static inline
1301 Vec<_Tp, cn>& operator /= (Vec<_Tp, cn>& a, int alpha)
1302 {
1303     double ialpha = 1./alpha;
1304     for( int i = 0; i < cn; i++ )
1305         a[i] = saturate_cast<_Tp>(a[i]*ialpha);
1306     return a;
1307 }
1308
1309 template<typename _Tp, int cn> static inline
1310 Vec<_Tp, cn>& operator /= (Vec<_Tp, cn>& a, float alpha)
1311 {
1312     float ialpha = 1.f/alpha;
1313     for( int i = 0; i < cn; i++ )
1314         a[i] = saturate_cast<_Tp>(a[i]*ialpha);
1315     return a;
1316 }
1317
1318 template<typename _Tp, int cn> static inline
1319 Vec<_Tp, cn>& operator /= (Vec<_Tp, cn>& a, double alpha)
1320 {
1321     double ialpha = 1./alpha;
1322     for( int i = 0; i < cn; i++ )
1323         a[i] = saturate_cast<_Tp>(a[i]*ialpha);
1324     return a;
1325 }
1326
1327 template<typename _Tp, int cn> static inline
1328 Vec<_Tp, cn> operator * (const Vec<_Tp, cn>& a, int alpha)
1329 {
1330     return Vec<_Tp, cn>(a, alpha, Matx_ScaleOp());
1331 }
1332
1333 template<typename _Tp, int cn> static inline
1334 Vec<_Tp, cn> operator * (int alpha, const Vec<_Tp, cn>& a)
1335 {
1336     return Vec<_Tp, cn>(a, alpha, Matx_ScaleOp());
1337 }
1338
1339 template<typename _Tp, int cn> static inline
1340 Vec<_Tp, cn> operator * (const Vec<_Tp, cn>& a, float alpha)
1341 {
1342     return Vec<_Tp, cn>(a, alpha, Matx_ScaleOp());
1343 }
1344
1345 template<typename _Tp, int cn> static inline
1346 Vec<_Tp, cn> operator * (float alpha, const Vec<_Tp, cn>& a)
1347 {
1348     return Vec<_Tp, cn>(a, alpha, Matx_ScaleOp());
1349 }
1350
1351 template<typename _Tp, int cn> static inline
1352 Vec<_Tp, cn> operator * (const Vec<_Tp, cn>& a, double alpha)
1353 {
1354     return Vec<_Tp, cn>(a, alpha, Matx_ScaleOp());
1355 }
1356
1357 template<typename _Tp, int cn> static inline
1358 Vec<_Tp, cn> operator * (double alpha, const Vec<_Tp, cn>& a)
1359 {
1360     return Vec<_Tp, cn>(a, alpha, Matx_ScaleOp());
1361 }
1362
1363 template<typename _Tp, int cn> static inline
1364 Vec<_Tp, cn> operator / (const Vec<_Tp, cn>& a, int alpha)
1365 {
1366     return Vec<_Tp, cn>(a, 1./alpha, Matx_ScaleOp());
1367 }
1368
1369 template<typename _Tp, int cn> static inline
1370 Vec<_Tp, cn> operator / (const Vec<_Tp, cn>& a, float alpha)
1371 {
1372     return Vec<_Tp, cn>(a, 1.f/alpha, Matx_ScaleOp());
1373 }
1374
1375 template<typename _Tp, int cn> static inline
1376 Vec<_Tp, cn> operator / (const Vec<_Tp, cn>& a, double alpha)
1377 {
1378     return Vec<_Tp, cn>(a, 1./alpha, Matx_ScaleOp());
1379 }
1380
1381 template<typename _Tp, int cn> static inline
1382 Vec<_Tp, cn> operator - (const Vec<_Tp, cn>& a)
1383 {
1384     Vec<_Tp,cn> t;
1385     for( int i = 0; i < cn; i++ ) t.val[i] = saturate_cast<_Tp>(-a.val[i]);
1386     return t;
1387 }
1388
1389 template<typename _Tp> inline Vec<_Tp, 4> operator * (const Vec<_Tp, 4>& v1, const Vec<_Tp, 4>& v2)
1390 {
1391     return Vec<_Tp, 4>(saturate_cast<_Tp>(v1[0]*v2[0] - v1[1]*v2[1] - v1[2]*v2[2] - v1[3]*v2[3]),
1392                        saturate_cast<_Tp>(v1[0]*v2[1] + v1[1]*v2[0] + v1[2]*v2[3] - v1[3]*v2[2]),
1393                        saturate_cast<_Tp>(v1[0]*v2[2] - v1[1]*v2[3] + v1[2]*v2[0] + v1[3]*v2[1]),
1394                        saturate_cast<_Tp>(v1[0]*v2[3] + v1[1]*v2[2] - v1[2]*v2[1] + v1[3]*v2[0]));
1395 }
1396
1397 template<typename _Tp> inline Vec<_Tp, 4>& operator *= (Vec<_Tp, 4>& v1, const Vec<_Tp, 4>& v2)
1398 {
1399     v1 = v1 * v2;
1400     return v1;
1401 }
1402
1403 //! @}
1404
1405 } // cv
1406
1407 #endif // __OPENCV_CORE_MATX_HPP__