replicant-frameworks_native/include/ui/TMatHelpers.h

180 lines
5.1 KiB
C
Raw Normal View History

/*
* Copyright 2013 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef TMAT_IMPLEMENTATION
#error "Don't include TMatHelpers.h directly. use ui/mat*.h instead"
#else
#undef TMAT_IMPLEMENTATION
#endif
#ifndef UI_TMAT_HELPERS_H
#define UI_TMAT_HELPERS_H
#include <stdint.h>
#include <sys/types.h>
#include <utils/Debug.h>
#include <utils/String8.h>
#define PURE __attribute__((pure))
namespace android {
// -------------------------------------------------------------------------------------
/*
* No user serviceable parts here.
*
* Don't use this file directly, instead include ui/mat*.h
*/
/*
* Matrix utilities
*/
namespace matrix {
inline int PURE transpose(int v) { return v; }
inline float PURE transpose(float v) { return v; }
inline double PURE transpose(double v) { return v; }
inline int PURE trace(int v) { return v; }
inline float PURE trace(float v) { return v; }
inline double PURE trace(double v) { return v; }
template<typename MATRIX>
MATRIX PURE inverse(const MATRIX& src) {
COMPILE_TIME_ASSERT_FUNCTION_SCOPE( MATRIX::COL_SIZE == MATRIX::ROW_SIZE );
typename MATRIX::value_type t;
const size_t N = MATRIX::col_size();
size_t swap;
MATRIX tmp(src);
MATRIX inverse(1);
for (size_t i=0 ; i<N ; i++) {
// look for largest element in column
swap = i;
for (size_t j=i+1 ; j<N ; j++) {
if (fabs(tmp[j][i]) > fabs(tmp[i][i])) {
swap = j;
}
}
if (swap != i) {
/* swap rows. */
for (size_t k=0 ; k<N ; k++) {
t = tmp[i][k];
tmp[i][k] = tmp[swap][k];
tmp[swap][k] = t;
t = inverse[i][k];
inverse[i][k] = inverse[swap][k];
inverse[swap][k] = t;
}
}
t = 1 / tmp[i][i];
for (size_t k=0 ; k<N ; k++) {
tmp[i][k] *= t;
inverse[i][k] *= t;
}
for (size_t j=0 ; j<N ; j++) {
if (j != i) {
t = tmp[j][i];
for (size_t k=0 ; k<N ; k++) {
tmp[j][k] -= tmp[i][k] * t;
inverse[j][k] -= inverse[i][k] * t;
}
}
}
}
return inverse;
}
template<typename MATRIX_R, typename MATRIX_A, typename MATRIX_B>
MATRIX_R PURE multiply(const MATRIX_A& lhs, const MATRIX_B& rhs) {
// pre-requisite:
// lhs : D columns, R rows
// rhs : C columns, D rows
// res : C columns, R rows
COMPILE_TIME_ASSERT_FUNCTION_SCOPE( MATRIX_A::ROW_SIZE == MATRIX_B::COL_SIZE );
COMPILE_TIME_ASSERT_FUNCTION_SCOPE( MATRIX_R::ROW_SIZE == MATRIX_B::ROW_SIZE );
COMPILE_TIME_ASSERT_FUNCTION_SCOPE( MATRIX_R::COL_SIZE == MATRIX_A::COL_SIZE );
MATRIX_R res(MATRIX_R::NO_INIT);
for (size_t r=0 ; r<MATRIX_R::row_size() ; r++) {
res[r] = lhs * rhs[r];
}
return res;
}
// transpose. this handles matrices of matrices
template <typename MATRIX>
MATRIX PURE transpose(const MATRIX& m) {
// for now we only handle square matrix transpose
COMPILE_TIME_ASSERT_FUNCTION_SCOPE( MATRIX::ROW_SIZE == MATRIX::COL_SIZE );
MATRIX result(MATRIX::NO_INIT);
for (size_t r=0 ; r<MATRIX::row_size() ; r++)
for (size_t c=0 ; c<MATRIX::col_size() ; c++)
result[c][r] = transpose(m[r][c]);
return result;
}
// trace. this handles matrices of matrices
template <typename MATRIX>
typename MATRIX::value_type PURE trace(const MATRIX& m) {
COMPILE_TIME_ASSERT_FUNCTION_SCOPE( MATRIX::ROW_SIZE == MATRIX::COL_SIZE );
typename MATRIX::value_type result(0);
for (size_t r=0 ; r<MATRIX::row_size() ; r++)
result += trace(m[r][r]);
return result;
}
// trace. this handles matrices of matrices
template <typename MATRIX>
typename MATRIX::col_type PURE diag(const MATRIX& m) {
COMPILE_TIME_ASSERT_FUNCTION_SCOPE( MATRIX::ROW_SIZE == MATRIX::COL_SIZE );
typename MATRIX::col_type result(MATRIX::col_type::NO_INIT);
for (size_t r=0 ; r<MATRIX::row_size() ; r++)
result[r] = m[r][r];
return result;
}
template <typename MATRIX>
String8 asString(const MATRIX& m) {
String8 s;
for (size_t c=0 ; c<MATRIX::col_size() ; c++) {
s.append("| ");
for (size_t r=0 ; r<MATRIX::row_size() ; r++) {
s.appendFormat("%7.2f ", m[r][c]);
}
s.append("|\n");
}
return s;
}
}; // namespace matrix
// -------------------------------------------------------------------------------------
}; // namespace android
#undef PURE
#endif /* UI_TMAT_HELPERS_H */