1595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian/* 2595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian * Copyright 2013 The Android Open Source Project 3595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian * 4595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian * Licensed under the Apache License, Version 2.0 (the "License"); 5595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian * you may not use this file except in compliance with the License. 6595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian * You may obtain a copy of the License at 7595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian * 8595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian * http://www.apache.org/licenses/LICENSE-2.0 9595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian * 10595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian * Unless required by applicable law or agreed to in writing, software 11595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian * distributed under the License is distributed on an "AS IS" BASIS, 12595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian * See the License for the specific language governing permissions and 14595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian * limitations under the License. 15595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian */ 16595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian 17595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian#ifndef TMAT_IMPLEMENTATION 18595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian#error "Don't include TMatHelpers.h directly. use ui/mat*.h instead" 19595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian#else 20595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian#undef TMAT_IMPLEMENTATION 21595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian#endif 22595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian 23595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian 24595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian#ifndef UI_TMAT_HELPERS_H 25595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian#define UI_TMAT_HELPERS_H 26595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian 27595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian#include <stdint.h> 28595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian#include <sys/types.h> 291d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian#include <math.h> 30595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian#include <utils/Debug.h> 31595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian#include <utils/String8.h> 32595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian 33595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian#define PURE __attribute__((pure)) 34595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian 35595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopiannamespace android { 36595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian// ------------------------------------------------------------------------------------- 37595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian 38595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian/* 39595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian * No user serviceable parts here. 40595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian * 41595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian * Don't use this file directly, instead include ui/mat*.h 42595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian */ 43595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian 44595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian 45595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian/* 46595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian * Matrix utilities 47595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian */ 48595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian 49595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopiannamespace matrix { 50595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian 51595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopianinline int PURE transpose(int v) { return v; } 52595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopianinline float PURE transpose(float v) { return v; } 53595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopianinline double PURE transpose(double v) { return v; } 54595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian 55595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopianinline int PURE trace(int v) { return v; } 56595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopianinline float PURE trace(float v) { return v; } 57595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopianinline double PURE trace(double v) { return v; } 58595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian 59595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopiantemplate<typename MATRIX> 60595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias AgopianMATRIX PURE inverse(const MATRIX& src) { 61595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian 62595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian COMPILE_TIME_ASSERT_FUNCTION_SCOPE( MATRIX::COL_SIZE == MATRIX::ROW_SIZE ); 63595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian 64595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian typename MATRIX::value_type t; 65595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian const size_t N = MATRIX::col_size(); 66595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian size_t swap; 67595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian MATRIX tmp(src); 68595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian MATRIX inverse(1); 69595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian 70595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian for (size_t i=0 ; i<N ; i++) { 71595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian // look for largest element in column 72595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian swap = i; 73595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian for (size_t j=i+1 ; j<N ; j++) { 74595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian if (fabs(tmp[j][i]) > fabs(tmp[i][i])) { 75595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian swap = j; 76595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian } 77595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian } 78595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian 79595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian if (swap != i) { 80595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian /* swap rows. */ 81595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian for (size_t k=0 ; k<N ; k++) { 82595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian t = tmp[i][k]; 83595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian tmp[i][k] = tmp[swap][k]; 84595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian tmp[swap][k] = t; 85595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian 86595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian t = inverse[i][k]; 87595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian inverse[i][k] = inverse[swap][k]; 88595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian inverse[swap][k] = t; 89595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian } 90595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian } 91595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian 92595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian t = 1 / tmp[i][i]; 93595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian for (size_t k=0 ; k<N ; k++) { 94595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian tmp[i][k] *= t; 95595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian inverse[i][k] *= t; 96595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian } 97595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian for (size_t j=0 ; j<N ; j++) { 98595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian if (j != i) { 99595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian t = tmp[j][i]; 100595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian for (size_t k=0 ; k<N ; k++) { 101595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian tmp[j][k] -= tmp[i][k] * t; 102595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian inverse[j][k] -= inverse[i][k] * t; 103595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian } 104595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian } 105595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian } 106595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian } 107595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian return inverse; 108595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian} 109595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian 110595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopiantemplate<typename MATRIX_R, typename MATRIX_A, typename MATRIX_B> 111595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias AgopianMATRIX_R PURE multiply(const MATRIX_A& lhs, const MATRIX_B& rhs) { 112595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian // pre-requisite: 113595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian // lhs : D columns, R rows 114595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian // rhs : C columns, D rows 115595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian // res : C columns, R rows 116595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian 117595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian COMPILE_TIME_ASSERT_FUNCTION_SCOPE( MATRIX_A::ROW_SIZE == MATRIX_B::COL_SIZE ); 118595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian COMPILE_TIME_ASSERT_FUNCTION_SCOPE( MATRIX_R::ROW_SIZE == MATRIX_B::ROW_SIZE ); 119595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian COMPILE_TIME_ASSERT_FUNCTION_SCOPE( MATRIX_R::COL_SIZE == MATRIX_A::COL_SIZE ); 120595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian 121595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian MATRIX_R res(MATRIX_R::NO_INIT); 122595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian for (size_t r=0 ; r<MATRIX_R::row_size() ; r++) { 123595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian res[r] = lhs * rhs[r]; 124595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian } 125595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian return res; 126595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian} 127595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian 128595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian// transpose. this handles matrices of matrices 129595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopiantemplate <typename MATRIX> 130595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias AgopianMATRIX PURE transpose(const MATRIX& m) { 131595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian // for now we only handle square matrix transpose 132595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian COMPILE_TIME_ASSERT_FUNCTION_SCOPE( MATRIX::ROW_SIZE == MATRIX::COL_SIZE ); 133595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian MATRIX result(MATRIX::NO_INIT); 134595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian for (size_t r=0 ; r<MATRIX::row_size() ; r++) 135595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian for (size_t c=0 ; c<MATRIX::col_size() ; c++) 136595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian result[c][r] = transpose(m[r][c]); 137595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian return result; 138595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian} 139595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian 140595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian// trace. this handles matrices of matrices 141595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopiantemplate <typename MATRIX> 142595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopiantypename MATRIX::value_type PURE trace(const MATRIX& m) { 143595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian COMPILE_TIME_ASSERT_FUNCTION_SCOPE( MATRIX::ROW_SIZE == MATRIX::COL_SIZE ); 144595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian typename MATRIX::value_type result(0); 145595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian for (size_t r=0 ; r<MATRIX::row_size() ; r++) 146595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian result += trace(m[r][r]); 147595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian return result; 148595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian} 149595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian 150595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian// trace. this handles matrices of matrices 151595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopiantemplate <typename MATRIX> 152595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopiantypename MATRIX::col_type PURE diag(const MATRIX& m) { 153595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian COMPILE_TIME_ASSERT_FUNCTION_SCOPE( MATRIX::ROW_SIZE == MATRIX::COL_SIZE ); 154595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian typename MATRIX::col_type result(MATRIX::col_type::NO_INIT); 155595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian for (size_t r=0 ; r<MATRIX::row_size() ; r++) 156595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian result[r] = m[r][r]; 157595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian return result; 158595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian} 159595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian 160595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopiantemplate <typename MATRIX> 161595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias AgopianString8 asString(const MATRIX& m) { 162595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian String8 s; 163595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian for (size_t c=0 ; c<MATRIX::col_size() ; c++) { 164595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian s.append("| "); 165595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian for (size_t r=0 ; r<MATRIX::row_size() ; r++) { 166595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian s.appendFormat("%7.2f ", m[r][c]); 167595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian } 168595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian s.append("|\n"); 169595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian } 170595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian return s; 171595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian} 172595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian 173595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian}; // namespace matrix 174595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian 175595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian// ------------------------------------------------------------------------------------- 1761d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian 1771d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian/* 1781d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian * TMatProductOperators implements basic arithmetic and basic compound assignments 1791d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian * operators on a vector of type BASE<T>. 1801d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian * 1811d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian * BASE only needs to implement operator[] and size(). 1821d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian * By simply inheriting from TMatProductOperators<BASE, T> BASE will automatically 1831d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian * get all the functionality here. 1841d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian */ 1851d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian 1861d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopiantemplate <template<typename T> class BASE, typename T> 1871d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopianclass TMatProductOperators { 1881d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopianpublic: 1891d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian // multiply by a scalar 1901d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian BASE<T>& operator *= (T v) { 1911d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian BASE<T>& lhs(static_cast< BASE<T>& >(*this)); 1921d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian for (size_t r=0 ; r<lhs.row_size() ; r++) { 1931d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian lhs[r] *= v; 1941d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian } 1951d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian return lhs; 1961d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian } 1971d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian 1981d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian // divide by a scalar 1991d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian BASE<T>& operator /= (T v) { 2001d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian BASE<T>& lhs(static_cast< BASE<T>& >(*this)); 2011d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian for (size_t r=0 ; r<lhs.row_size() ; r++) { 2021d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian lhs[r] /= v; 2031d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian } 2041d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian return lhs; 2051d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian } 2061d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian 2071d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian // matrix * matrix, result is a matrix of the same type than the lhs matrix 2081d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian template<typename U> 2091d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian friend BASE<T> PURE operator *(const BASE<T>& lhs, const BASE<U>& rhs) { 2101d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian return matrix::multiply<BASE<T> >(lhs, rhs); 2111d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian } 2121d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian}; 2131d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian 2141d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian 2151d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian/* 2161d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian * TMatSquareFunctions implements functions on a matrix of type BASE<T>. 2171d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian * 2181d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian * BASE only needs to implement: 2191d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian * - operator[] 2201d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian * - col_type 2211d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian * - row_type 2221d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian * - COL_SIZE 2231d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian * - ROW_SIZE 2241d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian * 2251d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian * By simply inheriting from TMatSquareFunctions<BASE, T> BASE will automatically 2261d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian * get all the functionality here. 2271d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian */ 2281d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian 2291d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopiantemplate<template<typename U> class BASE, typename T> 2301d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopianclass TMatSquareFunctions { 2311d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopianpublic: 2321d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian /* 2331d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian * NOTE: the functions below ARE NOT member methods. They are friend functions 2341d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian * with they definition inlined with their declaration. This makes these 2351d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian * template functions available to the compiler when (and only when) this class 2361d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian * is instantiated, at which point they're only templated on the 2nd parameter 2371d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian * (the first one, BASE<T> being known). 2381d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian */ 2391d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian friend BASE<T> PURE inverse(const BASE<T>& m) { return matrix::inverse(m); } 2401d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian friend BASE<T> PURE transpose(const BASE<T>& m) { return matrix::transpose(m); } 2411d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian friend T PURE trace(const BASE<T>& m) { return matrix::trace(m); } 2421d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian}; 2431d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian 2441d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopiantemplate <template<typename T> class BASE, typename T> 2451d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopianclass TMatDebug { 2461d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopianpublic: 2471d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian String8 asString() const { 248c1c05de415854eb7a13a16b7e22a22de8515123aMathias Agopian return matrix::asString( static_cast< const BASE<T>& >(*this) ); 2491d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian } 2501d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian}; 2511d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian 2521d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian// ------------------------------------------------------------------------------------- 253595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian}; // namespace android 254595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian 255595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian#undef PURE 256595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian 257595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian#endif /* UI_TMAT_HELPERS_H */ 258