1984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian/* 2984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian * Copyright (C) 2011 The Android Open Source Project 3984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian * 4984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian * Licensed under the Apache License, Version 2.0 (the "License"); 5984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian * you may not use this file except in compliance with the License. 6984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian * You may obtain a copy of the License at 7984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian * 8984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian * http://www.apache.org/licenses/LICENSE-2.0 9984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian * 10984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian * Unless required by applicable law or agreed to in writing, software 11984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian * distributed under the License is distributed on an "AS IS" BASIS, 12984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian * See the License for the specific language governing permissions and 14984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian * limitations under the License. 15984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian */ 16984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 17984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian#ifndef ANDROID_MAT_H 18984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian#define ANDROID_MAT_H 19984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 20984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian#include "vec.h" 21984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian#include "traits.h" 22984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 23984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian// ----------------------------------------------------------------------- 24984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 25984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopiannamespace android { 26984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 27984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopiantemplate <typename TYPE, size_t C, size_t R> 28984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopianclass mat; 29984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 30984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopiannamespace helpers { 31984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 32984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopiantemplate <typename TYPE, size_t C, size_t R> 33984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopianmat<TYPE, C, R>& doAssign( 34984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian mat<TYPE, C, R>& lhs, 35984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian typename TypeTraits<TYPE>::ParameterType rhs) { 36984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian for (size_t i=0 ; i<C ; i++) 37984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian for (size_t j=0 ; j<R ; j++) 38984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian lhs[i][j] = (i==j) ? rhs : 0; 39984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian return lhs; 40984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian} 41984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 42984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopiantemplate <typename TYPE, size_t C, size_t R, size_t D> 43984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopianmat<TYPE, C, R> PURE doMul( 44984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian const mat<TYPE, D, R>& lhs, 45984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian const mat<TYPE, C, D>& rhs) 46984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian{ 47984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian mat<TYPE, C, R> res; 48984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian for (size_t c=0 ; c<C ; c++) { 49984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian for (size_t r=0 ; r<R ; r++) { 50984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian TYPE v(0); 51984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian for (size_t k=0 ; k<D ; k++) { 52984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian v += lhs[k][r] * rhs[c][k]; 53984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian } 54984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian res[c][r] = v; 55984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian } 56984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian } 57984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian return res; 58984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian} 59984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 60984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopiantemplate <typename TYPE, size_t R, size_t D> 61984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopianvec<TYPE, R> PURE doMul( 62984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian const mat<TYPE, D, R>& lhs, 63984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian const vec<TYPE, D>& rhs) 64984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian{ 65984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian vec<TYPE, R> res; 66984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian for (size_t r=0 ; r<R ; r++) { 67984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian TYPE v(0); 68984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian for (size_t k=0 ; k<D ; k++) { 69984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian v += lhs[k][r] * rhs[k]; 70984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian } 71984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian res[r] = v; 72984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian } 73984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian return res; 74984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian} 75984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 76984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopiantemplate <typename TYPE, size_t C, size_t R> 77984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopianmat<TYPE, C, R> PURE doMul( 78984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian const vec<TYPE, R>& lhs, 79984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian const mat<TYPE, C, 1>& rhs) 80984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian{ 81984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian mat<TYPE, C, R> res; 82984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian for (size_t c=0 ; c<C ; c++) { 83984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian for (size_t r=0 ; r<R ; r++) { 84984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian res[c][r] = lhs[r] * rhs[c][0]; 85984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian } 86984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian } 87984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian return res; 88984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian} 89984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 90984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopiantemplate <typename TYPE, size_t C, size_t R> 91984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopianmat<TYPE, C, R> PURE doMul( 92984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian const mat<TYPE, C, R>& rhs, 93984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian typename TypeTraits<TYPE>::ParameterType v) 94984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian{ 95984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian mat<TYPE, C, R> res; 96984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian for (size_t c=0 ; c<C ; c++) { 97984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian for (size_t r=0 ; r<R ; r++) { 98984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian res[c][r] = rhs[c][r] * v; 99984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian } 100984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian } 101984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian return res; 102984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian} 103984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 104984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopiantemplate <typename TYPE, size_t C, size_t R> 105984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopianmat<TYPE, C, R> PURE doMul( 106984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian typename TypeTraits<TYPE>::ParameterType v, 107984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian const mat<TYPE, C, R>& rhs) 108984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian{ 109984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian mat<TYPE, C, R> res; 110984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian for (size_t c=0 ; c<C ; c++) { 111984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian for (size_t r=0 ; r<R ; r++) { 112984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian res[c][r] = v * rhs[c][r]; 113984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian } 114984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian } 115984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian return res; 116984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian} 117984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 118984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 119984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian}; // namespace helpers 120984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 121984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian// ----------------------------------------------------------------------- 122984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 123984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopiantemplate <typename TYPE, size_t C, size_t R> 124984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopianclass mat : public vec< vec<TYPE, R>, C > { 125984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian typedef typename TypeTraits<TYPE>::ParameterType pTYPE; 126984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian typedef vec< vec<TYPE, R>, C > base; 127984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopianpublic: 128984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian // STL-like interface. 129984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian typedef TYPE value_type; 130984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian typedef TYPE& reference; 131984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian typedef TYPE const& const_reference; 132984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian typedef size_t size_type; 133984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian size_type size() const { return R*C; } 134984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian enum { ROWS = R, COLS = C }; 135984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 136984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 137984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian // ----------------------------------------------------------------------- 138984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian // default constructors 139984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 140984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian mat() { } 141984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian mat(const mat& rhs) : base(rhs) { } 14238fc101331d15dde716f80f2f64b4317ea1e22f1Chih-Hung Hsieh mat(const base& rhs) : base(rhs) { } // NOLINT(implicit) 143984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 144984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian // ----------------------------------------------------------------------- 145984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian // conversion constructors 146984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 147984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian // sets the diagonal to the value, off-diagonal to zero 14838fc101331d15dde716f80f2f64b4317ea1e22f1Chih-Hung Hsieh mat(pTYPE rhs) { // NOLINT(implicit) 149984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian helpers::doAssign(*this, rhs); 150984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian } 151984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 152984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian // ----------------------------------------------------------------------- 153984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian // Assignment 154984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 155984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian mat& operator=(const mat& rhs) { 156984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian base::operator=(rhs); 157984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian return *this; 158984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian } 159984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 160984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian mat& operator=(const base& rhs) { 161984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian base::operator=(rhs); 162984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian return *this; 163984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian } 164984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 165984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian mat& operator=(pTYPE rhs) { 166984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian return helpers::doAssign(*this, rhs); 167984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian } 168984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 169984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian // ----------------------------------------------------------------------- 170984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian // non-member function declaration and definition 171984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 172984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian friend inline mat PURE operator + (const mat& lhs, const mat& rhs) { 173984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian return helpers::doAdd( 174984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian static_cast<const base&>(lhs), 175984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian static_cast<const base&>(rhs)); 176984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian } 177984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian friend inline mat PURE operator - (const mat& lhs, const mat& rhs) { 178984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian return helpers::doSub( 179984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian static_cast<const base&>(lhs), 180984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian static_cast<const base&>(rhs)); 181984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian } 182984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 183984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian // matrix*matrix 184984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian template <size_t D> 185984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian friend mat PURE operator * ( 186984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian const mat<TYPE, D, R>& lhs, 187984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian const mat<TYPE, C, D>& rhs) { 188984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian return helpers::doMul(lhs, rhs); 189984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian } 190984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 191984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian // matrix*vector 192984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian friend vec<TYPE, R> PURE operator * ( 193984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian const mat& lhs, const vec<TYPE, C>& rhs) { 194984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian return helpers::doMul(lhs, rhs); 195984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian } 196984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 197984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian // vector*matrix 198984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian friend mat PURE operator * ( 199984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian const vec<TYPE, R>& lhs, const mat<TYPE, C, 1>& rhs) { 200984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian return helpers::doMul(lhs, rhs); 201984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian } 202984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 203984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian // matrix*scalar 204984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian friend inline mat PURE operator * (const mat& lhs, pTYPE v) { 205984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian return helpers::doMul(lhs, v); 206984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian } 207984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 208984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian // scalar*matrix 209984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian friend inline mat PURE operator * (pTYPE v, const mat& rhs) { 210984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian return helpers::doMul(v, rhs); 211984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian } 212984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 213984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian // ----------------------------------------------------------------------- 214984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian // streaming operator to set the columns of the matrix: 215984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian // example: 216984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian // mat33_t m; 217984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian // m << v0 << v1 << v2; 218984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 219984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian // column_builder<> stores the matrix and knows which column to set 220984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian template<size_t PREV_COLUMN> 221984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian struct column_builder { 222984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian mat& matrix; 22338fc101331d15dde716f80f2f64b4317ea1e22f1Chih-Hung Hsieh explicit column_builder(mat& matrix) : matrix(matrix) { } 224984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian }; 225984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 226984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian // operator << is not a method of column_builder<> so we can 227984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian // overload it for unauthorized values (partial specialization 228984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian // not allowed in class-scope). 229984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian // we just set the column and return the next column_builder<> 230984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian template<size_t PREV_COLUMN> 231984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian friend column_builder<PREV_COLUMN+1> operator << ( 232984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian const column_builder<PREV_COLUMN>& lhs, 233984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian const vec<TYPE, R>& rhs) { 234984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian lhs.matrix[PREV_COLUMN+1] = rhs; 235984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian return column_builder<PREV_COLUMN+1>(lhs.matrix); 236984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian } 237984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 238984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian // we return void here so we get a compile-time error if the 239984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian // user tries to set too many columns 240984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian friend void operator << ( 241984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian const column_builder<C-2>& lhs, 242984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian const vec<TYPE, R>& rhs) { 243984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian lhs.matrix[C-1] = rhs; 244984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian } 245984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 246984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian // this is where the process starts. we set the first columns and 247984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian // return the next column_builder<> 248984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian column_builder<0> operator << (const vec<TYPE, R>& rhs) { 249984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian (*this)[0] = rhs; 250984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian return column_builder<0>(*this); 251984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian } 252984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian}; 253984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 254984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian// Specialize column matrix so they're exactly equivalent to a vector 255984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopiantemplate <typename TYPE, size_t R> 256984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopianclass mat<TYPE, 1, R> : public vec<TYPE, R> { 257984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian typedef vec<TYPE, R> base; 258984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopianpublic: 259984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian // STL-like interface. 260984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian typedef TYPE value_type; 261984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian typedef TYPE& reference; 262984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian typedef TYPE const& const_reference; 263984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian typedef size_t size_type; 264984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian size_type size() const { return R; } 265984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian enum { ROWS = R, COLS = 1 }; 266984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 267984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian mat() { } 26838fc101331d15dde716f80f2f64b4317ea1e22f1Chih-Hung Hsieh explicit mat(const base& rhs) : base(rhs) { } 269984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian mat(const mat& rhs) : base(rhs) { } 27038fc101331d15dde716f80f2f64b4317ea1e22f1Chih-Hung Hsieh explicit mat(const TYPE& rhs) { helpers::doAssign(*this, rhs); } 271984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian mat& operator=(const mat& rhs) { base::operator=(rhs); return *this; } 272984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian mat& operator=(const base& rhs) { base::operator=(rhs); return *this; } 273984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian mat& operator=(const TYPE& rhs) { return helpers::doAssign(*this, rhs); } 274984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian // we only have one column, so ignore the index 275984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian const base& operator[](size_t) const { return *this; } 276984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian base& operator[](size_t) { return *this; } 277984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian void operator << (const vec<TYPE, R>& rhs) { base::operator[](0) = rhs; } 278984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian}; 279984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 280984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian// ----------------------------------------------------------------------- 281984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian// matrix functions 282984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 283984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian// transpose. this handles matrices of matrices 284984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopianinline int PURE transpose(int v) { return v; } 285984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopianinline float PURE transpose(float v) { return v; } 286984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopianinline double PURE transpose(double v) { return v; } 287984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 288984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian// Transpose a matrix 289984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopiantemplate <typename TYPE, size_t C, size_t R> 290984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopianmat<TYPE, R, C> PURE transpose(const mat<TYPE, C, R>& m) { 291984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian mat<TYPE, R, C> r; 292984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian for (size_t i=0 ; i<R ; i++) 293984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian for (size_t j=0 ; j<C ; j++) 294984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian r[i][j] = transpose(m[j][i]); 295984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian return r; 296984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian} 297984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 298a01b4e237d57b74689576a3d486a2b2b903e74f4Max Braun// Calculate the trace of a matrix 299a01b4e237d57b74689576a3d486a2b2b903e74f4Max Brauntemplate <typename TYPE, size_t C> static TYPE trace(const mat<TYPE, C, C>& m) { 300a01b4e237d57b74689576a3d486a2b2b903e74f4Max Braun TYPE t; 301a01b4e237d57b74689576a3d486a2b2b903e74f4Max Braun for (size_t i=0 ; i<C ; i++) 302a01b4e237d57b74689576a3d486a2b2b903e74f4Max Braun t += m[i][i]; 303a01b4e237d57b74689576a3d486a2b2b903e74f4Max Braun return t; 304a01b4e237d57b74689576a3d486a2b2b903e74f4Max Braun} 305a01b4e237d57b74689576a3d486a2b2b903e74f4Max Braun 306a01b4e237d57b74689576a3d486a2b2b903e74f4Max Braun// Test positive-semidefiniteness of a matrix 307a01b4e237d57b74689576a3d486a2b2b903e74f4Max Brauntemplate <typename TYPE, size_t C> 308a01b4e237d57b74689576a3d486a2b2b903e74f4Max Braunstatic bool isPositiveSemidefinite(const mat<TYPE, C, C>& m, TYPE tolerance) { 309a01b4e237d57b74689576a3d486a2b2b903e74f4Max Braun for (size_t i=0 ; i<C ; i++) 310a01b4e237d57b74689576a3d486a2b2b903e74f4Max Braun if (m[i][i] < 0) 311a01b4e237d57b74689576a3d486a2b2b903e74f4Max Braun return false; 312a01b4e237d57b74689576a3d486a2b2b903e74f4Max Braun 313a01b4e237d57b74689576a3d486a2b2b903e74f4Max Braun for (size_t i=0 ; i<C ; i++) 314a01b4e237d57b74689576a3d486a2b2b903e74f4Max Braun for (size_t j=i+1 ; j<C ; j++) 315a01b4e237d57b74689576a3d486a2b2b903e74f4Max Braun if (fabs(m[i][j] - m[j][i]) > tolerance) 316a01b4e237d57b74689576a3d486a2b2b903e74f4Max Braun return false; 317a01b4e237d57b74689576a3d486a2b2b903e74f4Max Braun 318a01b4e237d57b74689576a3d486a2b2b903e74f4Max Braun return true; 319a01b4e237d57b74689576a3d486a2b2b903e74f4Max Braun} 320a01b4e237d57b74689576a3d486a2b2b903e74f4Max Braun 321984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian// Transpose a vector 322984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopiantemplate < 323984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian template<typename T, size_t S> class VEC, 324984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian typename TYPE, 325984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian size_t SIZE 326984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian> 327984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopianmat<TYPE, SIZE, 1> PURE transpose(const VEC<TYPE, SIZE>& v) { 328984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian mat<TYPE, SIZE, 1> r; 329984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian for (size_t i=0 ; i<SIZE ; i++) 330984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian r[i][0] = transpose(v[i]); 331984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian return r; 332984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian} 333984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 334984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian// ----------------------------------------------------------------------- 335984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian// "dumb" matrix inversion 336984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopiantemplate<typename T, size_t N> 337984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopianmat<T, N, N> PURE invert(const mat<T, N, N>& src) { 338984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian T t; 339984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian size_t swap; 340984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian mat<T, N, N> tmp(src); 341984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian mat<T, N, N> inverse(1); 342984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 343984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian for (size_t i=0 ; i<N ; i++) { 344984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian // look for largest element in column 345984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian swap = i; 346984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian for (size_t j=i+1 ; j<N ; j++) { 347984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian if (fabs(tmp[j][i]) > fabs(tmp[i][i])) { 348984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian swap = j; 349984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian } 350984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian } 351984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 352984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian if (swap != i) { 353984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian /* swap rows. */ 354984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian for (size_t k=0 ; k<N ; k++) { 355984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian t = tmp[i][k]; 356984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian tmp[i][k] = tmp[swap][k]; 357984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian tmp[swap][k] = t; 358984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 359984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian t = inverse[i][k]; 360984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian inverse[i][k] = inverse[swap][k]; 361984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian inverse[swap][k] = t; 362984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian } 363984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian } 364984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 365984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian t = 1 / tmp[i][i]; 366984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian for (size_t k=0 ; k<N ; k++) { 367984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian tmp[i][k] *= t; 368984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian inverse[i][k] *= t; 369984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian } 370984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian for (size_t j=0 ; j<N ; j++) { 371984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian if (j != i) { 372984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian t = tmp[j][i]; 373984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian for (size_t k=0 ; k<N ; k++) { 374984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian tmp[j][k] -= tmp[i][k] * t; 375984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian inverse[j][k] -= inverse[i][k] * t; 376984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian } 377984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian } 378984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian } 379984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian } 380984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian return inverse; 381984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian} 382984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 383984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian// ----------------------------------------------------------------------- 384984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 385984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopiantypedef mat<float, 2, 2> mat22_t; 386984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopiantypedef mat<float, 3, 3> mat33_t; 387984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopiantypedef mat<float, 4, 4> mat44_t; 388984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 389984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian// ----------------------------------------------------------------------- 390984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 391984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian}; // namespace android 392984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian 393984826cc158193e61e3a00359ef4f6699c7d748aMathias Agopian#endif /* ANDROID_MAT_H */ 394