blob: b778af0fff8c44b53204b1867dc17bcb7ddd5033 [file] [log] [blame]
Mathias Agopian595ea772013-08-21 23:10:41 -07001/*
2 * Copyright 2013 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef TMAT_IMPLEMENTATION
18#error "Don't include TMatHelpers.h directly. use ui/mat*.h instead"
19#else
20#undef TMAT_IMPLEMENTATION
21#endif
22
23
24#ifndef UI_TMAT_HELPERS_H
25#define UI_TMAT_HELPERS_H
26
27#include <stdint.h>
28#include <sys/types.h>
29#include <utils/Debug.h>
30#include <utils/String8.h>
31
32#define PURE __attribute__((pure))
33
34namespace android {
35// -------------------------------------------------------------------------------------
36
37/*
38 * No user serviceable parts here.
39 *
40 * Don't use this file directly, instead include ui/mat*.h
41 */
42
43
44/*
45 * Matrix utilities
46 */
47
48namespace matrix {
49
50inline int PURE transpose(int v) { return v; }
51inline float PURE transpose(float v) { return v; }
52inline double PURE transpose(double v) { return v; }
53
54inline int PURE trace(int v) { return v; }
55inline float PURE trace(float v) { return v; }
56inline double PURE trace(double v) { return v; }
57
58template<typename MATRIX>
59MATRIX PURE inverse(const MATRIX& src) {
60
61 COMPILE_TIME_ASSERT_FUNCTION_SCOPE( MATRIX::COL_SIZE == MATRIX::ROW_SIZE );
62
63 typename MATRIX::value_type t;
64 const size_t N = MATRIX::col_size();
65 size_t swap;
66 MATRIX tmp(src);
67 MATRIX inverse(1);
68
69 for (size_t i=0 ; i<N ; i++) {
70 // look for largest element in column
71 swap = i;
72 for (size_t j=i+1 ; j<N ; j++) {
73 if (fabs(tmp[j][i]) > fabs(tmp[i][i])) {
74 swap = j;
75 }
76 }
77
78 if (swap != i) {
79 /* swap rows. */
80 for (size_t k=0 ; k<N ; k++) {
81 t = tmp[i][k];
82 tmp[i][k] = tmp[swap][k];
83 tmp[swap][k] = t;
84
85 t = inverse[i][k];
86 inverse[i][k] = inverse[swap][k];
87 inverse[swap][k] = t;
88 }
89 }
90
91 t = 1 / tmp[i][i];
92 for (size_t k=0 ; k<N ; k++) {
93 tmp[i][k] *= t;
94 inverse[i][k] *= t;
95 }
96 for (size_t j=0 ; j<N ; j++) {
97 if (j != i) {
98 t = tmp[j][i];
99 for (size_t k=0 ; k<N ; k++) {
100 tmp[j][k] -= tmp[i][k] * t;
101 inverse[j][k] -= inverse[i][k] * t;
102 }
103 }
104 }
105 }
106 return inverse;
107}
108
109template<typename MATRIX_R, typename MATRIX_A, typename MATRIX_B>
110MATRIX_R PURE multiply(const MATRIX_A& lhs, const MATRIX_B& rhs) {
111 // pre-requisite:
112 // lhs : D columns, R rows
113 // rhs : C columns, D rows
114 // res : C columns, R rows
115
116 COMPILE_TIME_ASSERT_FUNCTION_SCOPE( MATRIX_A::ROW_SIZE == MATRIX_B::COL_SIZE );
117 COMPILE_TIME_ASSERT_FUNCTION_SCOPE( MATRIX_R::ROW_SIZE == MATRIX_B::ROW_SIZE );
118 COMPILE_TIME_ASSERT_FUNCTION_SCOPE( MATRIX_R::COL_SIZE == MATRIX_A::COL_SIZE );
119
120 MATRIX_R res(MATRIX_R::NO_INIT);
121 for (size_t r=0 ; r<MATRIX_R::row_size() ; r++) {
122 res[r] = lhs * rhs[r];
123 }
124 return res;
125}
126
127// transpose. this handles matrices of matrices
128template <typename MATRIX>
129MATRIX PURE transpose(const MATRIX& m) {
130 // for now we only handle square matrix transpose
131 COMPILE_TIME_ASSERT_FUNCTION_SCOPE( MATRIX::ROW_SIZE == MATRIX::COL_SIZE );
132 MATRIX result(MATRIX::NO_INIT);
133 for (size_t r=0 ; r<MATRIX::row_size() ; r++)
134 for (size_t c=0 ; c<MATRIX::col_size() ; c++)
135 result[c][r] = transpose(m[r][c]);
136 return result;
137}
138
139// trace. this handles matrices of matrices
140template <typename MATRIX>
141typename MATRIX::value_type PURE trace(const MATRIX& m) {
142 COMPILE_TIME_ASSERT_FUNCTION_SCOPE( MATRIX::ROW_SIZE == MATRIX::COL_SIZE );
143 typename MATRIX::value_type result(0);
144 for (size_t r=0 ; r<MATRIX::row_size() ; r++)
145 result += trace(m[r][r]);
146 return result;
147}
148
149// trace. this handles matrices of matrices
150template <typename MATRIX>
151typename MATRIX::col_type PURE diag(const MATRIX& m) {
152 COMPILE_TIME_ASSERT_FUNCTION_SCOPE( MATRIX::ROW_SIZE == MATRIX::COL_SIZE );
153 typename MATRIX::col_type result(MATRIX::col_type::NO_INIT);
154 for (size_t r=0 ; r<MATRIX::row_size() ; r++)
155 result[r] = m[r][r];
156 return result;
157}
158
159template <typename MATRIX>
160String8 asString(const MATRIX& m) {
161 String8 s;
162 for (size_t c=0 ; c<MATRIX::col_size() ; c++) {
163 s.append("| ");
164 for (size_t r=0 ; r<MATRIX::row_size() ; r++) {
165 s.appendFormat("%7.2f ", m[r][c]);
166 }
167 s.append("|\n");
168 }
169 return s;
170}
171
172}; // namespace matrix
173
174// -------------------------------------------------------------------------------------
175}; // namespace android
176
177#undef PURE
178
179#endif /* UI_TMAT_HELPERS_H */