1 | #pragma once |
---|---|
2 | #ifndef __CVTT_COVARIANCEMATRIX_H__ |
3 | #define __CVTT_COVARIANCEMATRIX_H__ |
4 | |
5 | namespace cvtt |
6 | { |
7 | namespace Internal |
8 | { |
9 | |
10 | template<int TMatrixSize> |
11 | class PackedCovarianceMatrix |
12 | { |
13 | public: |
14 | // 0: xx, |
15 | // 1: xy, yy |
16 | // 3: xz, yz, zz |
17 | // 6: xw, yw, zw, ww |
18 | // ... etc. |
19 | static const int PyramidSize = (TMatrixSize * (TMatrixSize + 1)) / 2; |
20 | |
21 | typedef ParallelMath::Float MFloat; |
22 | |
23 | PackedCovarianceMatrix() |
24 | { |
25 | for (int i = 0; i < PyramidSize; i++) |
26 | m_values[i] = ParallelMath::MakeFloatZero(); |
27 | } |
28 | |
29 | void Add(const ParallelMath::Float *vec, const ParallelMath::Float &weight) |
30 | { |
31 | int index = 0; |
32 | for (int row = 0; row < TMatrixSize; row++) |
33 | { |
34 | for (int col = 0; col <= row; col++) |
35 | { |
36 | m_values[index] = m_values[index] + vec[row] * vec[col] * weight; |
37 | index++; |
38 | } |
39 | } |
40 | } |
41 | |
42 | void Product(MFloat *outVec, const MFloat *inVec) |
43 | { |
44 | for (int row = 0; row < TMatrixSize; row++) |
45 | { |
46 | MFloat sum = ParallelMath::MakeFloatZero(); |
47 | |
48 | int index = (row * (row + 1)) >> 1; |
49 | for (int col = 0; col < TMatrixSize; col++) |
50 | { |
51 | sum = sum + inVec[col] * m_values[index]; |
52 | if (col >= row) |
53 | index += col + 1; |
54 | else |
55 | index++; |
56 | } |
57 | |
58 | outVec[row] = sum; |
59 | } |
60 | } |
61 | |
62 | private: |
63 | ParallelMath::Float m_values[PyramidSize]; |
64 | }; |
65 | } |
66 | } |
67 | |
68 | #endif |
69 |