27 template <
typename TYPE, 
size_t C, 
size_t R>
 
   32 template <
typename TYPE, 
size_t C, 
size_t R>
 
   35         typename TypeTraits<TYPE>::ParameterType rhs) {
 
   36     for (
size_t i=0 ; i<C ; i++)
 
   37         for (
size_t j=0 ; j<R ; j++)
 
   38             lhs[i][j] = (i==j) ? rhs : 0;
 
   42 template <
typename TYPE, 
size_t C, 
size_t R, 
size_t D>
 
   48     for (
size_t c=0 ; c<C ; c++) {
 
   49         for (
size_t r=0 ; r<R ; r++) {
 
   51             for (
size_t k=0 ; k<D ; k++) {
 
   52                 v += lhs[k][r] * rhs[c][k];
 
   60 template <
typename TYPE, 
size_t R, 
size_t D>
 
   61 vec<TYPE, R> PURE doMul(
 
   62         const mat<TYPE, D, R>& lhs,
 
   63         const vec<TYPE, D>& rhs)
 
   66     for (
size_t r=0 ; r<R ; r++) {
 
   68         for (
size_t k=0 ; k<D ; k++) {
 
   69             v += lhs[k][r] * rhs[k];
 
   76 template <
typename TYPE, 
size_t C, 
size_t R>
 
   77 mat<TYPE, C, R> PURE doMul(
 
   78         const vec<TYPE, R>& lhs,
 
   79         const mat<TYPE, C, 1>& rhs)
 
   82     for (
size_t c=0 ; c<C ; c++) {
 
   83         for (
size_t r=0 ; r<R ; r++) {
 
   84             res[c][r] = lhs[r] * rhs[c][0];
 
   90 template <
typename TYPE, 
size_t C, 
size_t R>
 
   91 mat<TYPE, C, R> PURE doMul(
 
   92         const mat<TYPE, C, R>& rhs,
 
   93         typename TypeTraits<TYPE>::ParameterType v)
 
   96     for (
size_t c=0 ; c<C ; c++) {
 
   97         for (
size_t r=0 ; r<R ; r++) {
 
   98             res[c][r] = rhs[c][r] * v;
 
  104 template <
typename TYPE, 
size_t C, 
size_t R>
 
  105 mat<TYPE, C, R> PURE doMul(
 
  106         typename TypeTraits<TYPE>::ParameterType v,
 
  107         const mat<TYPE, C, R>& rhs)
 
  110     for (
size_t c=0 ; c<C ; c++) {
 
  111         for (
size_t r=0 ; r<R ; r++) {
 
  112             res[c][r] = v * rhs[c][r];
 
  123 template <
typename TYPE, 
size_t C, 
size_t R>
 
  124 class mat : 
public vec< vec<TYPE, R>, C > {
 
  125     typedef typename TypeTraits<TYPE>::ParameterType pTYPE;
 
  126     typedef vec< vec<TYPE, R>, C > base;
 
  129     typedef TYPE value_type;
 
  130     typedef TYPE& reference;
 
  131     typedef TYPE 
const& const_reference;
 
  132     typedef size_t size_type;
 
  133     size_type size()
 const { 
return R*C; }
 
  134     enum { ROWS = R, COLS = C };
 
  141     mat(
const mat& rhs)  : base(rhs) { }
 
  142     mat(
const base& rhs) : base(rhs) { }
 
  149         helpers::doAssign(*
this, rhs);
 
  155     mat& operator=(
const mat& rhs) {
 
  156         base::operator=(rhs);
 
  160     mat& operator=(
const base& rhs) {
 
  161         base::operator=(rhs);
 
  165     mat& operator=(pTYPE rhs) {
 
  166         return helpers::doAssign(*
this, rhs);
 
  172     friend inline mat PURE operator + (
const mat& lhs, 
const mat& rhs) {
 
  173         return helpers::doAdd(
 
  174                 static_cast<const base&>(lhs),
 
  175                 static_cast<const base&>(rhs));
 
  177     friend inline mat PURE operator - (
const mat& lhs, 
const mat& rhs) {
 
  178         return helpers::doSub(
 
  179                 static_cast<const base&>(lhs),
 
  180                 static_cast<const base&>(rhs));
 
  185     friend mat PURE operator * (
 
  186             const mat<TYPE, D, R>& lhs,
 
  187             const mat<TYPE, C, D>& rhs) {
 
  188         return helpers::doMul(lhs, rhs);
 
  192     friend vec<TYPE, R> PURE operator * (
 
  193             const mat& lhs, 
const vec<TYPE, C>& rhs) {
 
  194         return helpers::doMul(lhs, rhs);
 
  198     friend mat PURE operator * (
 
  199             const vec<TYPE, R>& lhs, 
const mat<TYPE, C, 1>& rhs) {
 
  200         return helpers::doMul(lhs, rhs);
 
  204     friend inline mat PURE operator * (
const mat& lhs, pTYPE v) {
 
  205         return helpers::doMul(lhs, v);
 
  209     friend inline mat PURE operator * (pTYPE v, 
const mat& rhs) {
 
  210         return helpers::doMul(v, rhs);
 
  220     template<
size_t PREV_COLUMN>
 
  230     template<
size_t PREV_COLUMN>
 
  234         lhs.matrix[PREV_COLUMN+1] = rhs;
 
  240     friend void operator << (
 
  241             const column_builder<C-2>& lhs,
 
  243         lhs.matrix[C-1] = rhs;
 
  248     column_builder<0> operator << (const vec<TYPE, R>& rhs) {
 
  250         return column_builder<0>(*this);
 
  255 template <
typename TYPE, 
size_t R>
 
  256 class mat<TYPE, 1, R> : 
public vec<TYPE, R> {
 
  260     typedef TYPE value_type;
 
  261     typedef TYPE& reference;
 
  262     typedef TYPE 
const& const_reference;
 
  263     typedef size_t size_type;
 
  264     size_type size()
 const { 
return R; }
 
  265     enum { ROWS = R, COLS = 1 };
 
  270     mat(
const TYPE& rhs) { helpers::doAssign(*
this, rhs); }
 
  271     mat& operator=(
const mat& rhs) { base::operator=(rhs); 
return *
this; }
 
  272     mat& operator=(
const base& rhs) { base::operator=(rhs); 
return *
this; }
 
  273     mat& operator=(
const TYPE& rhs) { 
return helpers::doAssign(*
this, rhs); }
 
  275     const base& operator[](
size_t)
 const { 
return *
this; }
 
  276     base& operator[](
size_t) { 
return *
this; }
 
  277     void operator << (const vec<TYPE, R>& rhs) { base::operator[](0) = rhs; }
 
  284 inline int     PURE transpose(
int v)    { 
return v; }
 
  285 inline float   PURE transpose(
float v)  { 
return v; }
 
  286 inline double  PURE transpose(
double v) { 
return v; }
 
  289 template <
typename TYPE, 
size_t C, 
size_t R>
 
  290 mat<TYPE, R, C> PURE transpose(
const mat<TYPE, C, R>& m) {
 
  292     for (
size_t i=0 ; i<R ; i++)
 
  293         for (
size_t j=0 ; j<C ; j++)
 
  294             r[i][j] = transpose(m[j][i]);
 
  298 template <
typename TYPE, 
size_t M, 
size_t N, 
size_t P>
 
  299 mat<TYPE, M, P> PURE multiply(
const mat<TYPE, M, N>& m1, 
const mat<TYPE, N, P>& m2)
 
  302     for (
size_t i = 0; i < M; i++)
 
  303         for (
size_t k = 0; k < P; k++) {
 
  305             for (
size_t j = 0; j < N; j++)
 
  306                 r [i][k] += m1[i][j] * m2 [j][k];
 
  312 template <
typename TYPE, 
size_t C> 
static TYPE trace(
const mat<TYPE, C, C>& m) {
 
  314     for (
size_t i=0 ; i<C ; i++)
 
  320 template <
typename TYPE, 
size_t C>
 
  321 static bool isPositiveSemidefinite(
const mat<TYPE, C, C>& m, TYPE tolerance) {
 
  322     for (
size_t i=0 ; i<C ; i++)
 
  326     for (
size_t i=0 ; i<C ; i++)
 
  327       for (
size_t j=i+1 ; j<C ; j++)
 
  328           if (fabs(m[i][j] - m[j][i]) > tolerance)
 
  336     template<
typename T, 
size_t S> 
class VEC,
 
  340 mat<TYPE, SIZE, 1> PURE transpose(
const VEC<TYPE, SIZE>& v) {
 
  341     mat<TYPE, SIZE, 1> r;
 
  342     for (
size_t i=0 ; i<SIZE ; i++)
 
  343         r[i][0] = transpose(v[i]);
 
  349 template<
typename T, 
size_t N>
 
  350 mat<T, N, N> PURE invert(
const mat<T, N, N>& src) {
 
  353     mat<T, N, N> tmp(src);
 
  354     mat<T, N, N> inverse(1);
 
  356     for (
size_t i=0 ; i<N ; i++) {
 
  359         for (
size_t j=i+1 ; j<N ; j++) {
 
  360             if (fabs(tmp[j][i]) > fabs(tmp[i][i])) {
 
  367             for (
size_t k=0 ; k<N ; k++) {
 
  369                 tmp[i][k] = tmp[swap][k];
 
  373                 inverse[i][k] = inverse[swap][k];
 
  374                 inverse[swap][k] = t;
 
  379         for (
size_t k=0 ; k<N ; k++) {
 
  383         for (
size_t j=0 ; j<N ; j++) {
 
  386                 for (
size_t k=0 ; k<N ; k++) {
 
  387                     tmp[j][k] -= tmp[i][k] * t;
 
  388                     inverse[j][k] -= inverse[i][k] * t;
 
  398 typedef mat<float, 2, 2> mat22_t;
 
  399 typedef mat<float, 3, 3> mat33_t;
 
  400 typedef mat<float, 4, 4> mat44_t;