2 * Copyright 2013 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 #ifndef TMAT_IMPLEMENTATION
18 #error "Don't include TMatHelpers.h directly. use ui/mat*.h instead"
20 #undef TMAT_IMPLEMENTATION
24 #ifndef UI_TMAT_HELPERS_H
25 #define UI_TMAT_HELPERS_H
28 #include <sys/types.h>
30 #include <utils/Debug.h>
31 #include <utils/String8.h>
33 #define PURE __attribute__((pure))
36 // -------------------------------------------------------------------------------------
39 * No user serviceable parts here.
41 * Don't use this file directly, instead include ui/mat*.h
51 inline int PURE transpose(int v) { return v; }
52 inline float PURE transpose(float v) { return v; }
53 inline double PURE transpose(double v) { return v; }
55 inline int PURE trace(int v) { return v; }
56 inline float PURE trace(float v) { return v; }
57 inline double PURE trace(double v) { return v; }
59 template<typename MATRIX>
60 MATRIX PURE inverse(const MATRIX& src) {
62 COMPILE_TIME_ASSERT_FUNCTION_SCOPE( MATRIX::COL_SIZE == MATRIX::ROW_SIZE );
64 typename MATRIX::value_type t;
65 const size_t N = MATRIX::col_size();
70 for (size_t i=0 ; i<N ; i++) {
71 // look for largest element in column
73 for (size_t j=i+1 ; j<N ; j++) {
74 if (fabs(tmp[j][i]) > fabs(tmp[i][i])) {
81 for (size_t k=0 ; k<N ; k++) {
83 tmp[i][k] = tmp[swap][k];
87 inverse[i][k] = inverse[swap][k];
93 for (size_t k=0 ; k<N ; k++) {
97 for (size_t j=0 ; j<N ; j++) {
100 for (size_t k=0 ; k<N ; k++) {
101 tmp[j][k] -= tmp[i][k] * t;
102 inverse[j][k] -= inverse[i][k] * t;
110 template<typename MATRIX_R, typename MATRIX_A, typename MATRIX_B>
111 MATRIX_R PURE multiply(const MATRIX_A& lhs, const MATRIX_B& rhs) {
113 // lhs : D columns, R rows
114 // rhs : C columns, D rows
115 // res : C columns, R rows
117 COMPILE_TIME_ASSERT_FUNCTION_SCOPE( MATRIX_A::ROW_SIZE == MATRIX_B::COL_SIZE );
118 COMPILE_TIME_ASSERT_FUNCTION_SCOPE( MATRIX_R::ROW_SIZE == MATRIX_B::ROW_SIZE );
119 COMPILE_TIME_ASSERT_FUNCTION_SCOPE( MATRIX_R::COL_SIZE == MATRIX_A::COL_SIZE );
121 MATRIX_R res(MATRIX_R::NO_INIT);
122 for (size_t r=0 ; r<MATRIX_R::row_size() ; r++) {
123 res[r] = lhs * rhs[r];
128 // transpose. this handles matrices of matrices
129 template <typename MATRIX>
130 MATRIX PURE transpose(const MATRIX& m) {
131 // for now we only handle square matrix transpose
132 COMPILE_TIME_ASSERT_FUNCTION_SCOPE( MATRIX::ROW_SIZE == MATRIX::COL_SIZE );
133 MATRIX result(MATRIX::NO_INIT);
134 for (size_t r=0 ; r<MATRIX::row_size() ; r++)
135 for (size_t c=0 ; c<MATRIX::col_size() ; c++)
136 result[c][r] = transpose(m[r][c]);
140 // trace. this handles matrices of matrices
141 template <typename MATRIX>
142 typename MATRIX::value_type PURE trace(const MATRIX& m) {
143 COMPILE_TIME_ASSERT_FUNCTION_SCOPE( MATRIX::ROW_SIZE == MATRIX::COL_SIZE );
144 typename MATRIX::value_type result(0);
145 for (size_t r=0 ; r<MATRIX::row_size() ; r++)
146 result += trace(m[r][r]);
150 // trace. this handles matrices of matrices
151 template <typename MATRIX>
152 typename MATRIX::col_type PURE diag(const MATRIX& m) {
153 COMPILE_TIME_ASSERT_FUNCTION_SCOPE( MATRIX::ROW_SIZE == MATRIX::COL_SIZE );
154 typename MATRIX::col_type result(MATRIX::col_type::NO_INIT);
155 for (size_t r=0 ; r<MATRIX::row_size() ; r++)
160 template <typename MATRIX>
161 String8 asString(const MATRIX& m) {
163 for (size_t c=0 ; c<MATRIX::col_size() ; c++) {
165 for (size_t r=0 ; r<MATRIX::row_size() ; r++) {
166 s.appendFormat("%7.2f ", m[r][c]);
173 }; // namespace matrix
175 // -------------------------------------------------------------------------------------
178 * TMatProductOperators implements basic arithmetic and basic compound assignments
179 * operators on a vector of type BASE<T>.
181 * BASE only needs to implement operator[] and size().
182 * By simply inheriting from TMatProductOperators<BASE, T> BASE will automatically
183 * get all the functionality here.
186 template <template<typename T> class BASE, typename T>
187 class TMatProductOperators {
189 // multiply by a scalar
190 BASE<T>& operator *= (T v) {
191 BASE<T>& lhs(static_cast< BASE<T>& >(*this));
192 for (size_t r=0 ; r<lhs.row_size() ; r++) {
198 // divide by a scalar
199 BASE<T>& operator /= (T v) {
200 BASE<T>& lhs(static_cast< BASE<T>& >(*this));
201 for (size_t r=0 ; r<lhs.row_size() ; r++) {
207 // matrix * matrix, result is a matrix of the same type than the lhs matrix
209 friend BASE<T> PURE operator *(const BASE<T>& lhs, const BASE<U>& rhs) {
210 return matrix::multiply<BASE<T> >(lhs, rhs);
216 * TMatSquareFunctions implements functions on a matrix of type BASE<T>.
218 * BASE only needs to implement:
225 * By simply inheriting from TMatSquareFunctions<BASE, T> BASE will automatically
226 * get all the functionality here.
229 template<template<typename U> class BASE, typename T>
230 class TMatSquareFunctions {
233 * NOTE: the functions below ARE NOT member methods. They are friend functions
234 * with they definition inlined with their declaration. This makes these
235 * template functions available to the compiler when (and only when) this class
236 * is instantiated, at which point they're only templated on the 2nd parameter
237 * (the first one, BASE<T> being known).
239 friend BASE<T> PURE inverse(const BASE<T>& m) { return matrix::inverse(m); }
240 friend BASE<T> PURE transpose(const BASE<T>& m) { return matrix::transpose(m); }
241 friend T PURE trace(const BASE<T>& m) { return matrix::trace(m); }
244 template <template<typename T> class BASE, typename T>
247 String8 asString() const {
248 return matrix::asString( static_cast< const BASE<T>& >(*this) );
252 // -------------------------------------------------------------------------------------
253 }; // namespace android
257 #endif /* UI_TMAT_HELPERS_H */