---
milena/ChangeLog | 4 +
milena/mln/algebra/mat.hh | 265 ++++++++++++++++++++++++++++++++-------------
2 files changed, 195 insertions(+), 74 deletions(-)
diff --git a/milena/ChangeLog b/milena/ChangeLog
index 0be75ec..8ac0430 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,3 +1,7 @@
+2012-05-28 Guillaume Lazzara <z(a)lrde.epita.fr>
+
+ * mln/algebra/mat.hh: Add implementations for 4x4 matrices.
+
2012-05-25 Guillaume Lazzara <z(a)lrde.epita.fr>
New routines to get bottom left and top right sites.
diff --git a/milena/mln/algebra/mat.hh b/milena/mln/algebra/mat.hh
index 0fc08b4..e51f6e1 100644
--- a/milena/mln/algebra/mat.hh
+++ b/milena/mln/algebra/mat.hh
@@ -1,4 +1,5 @@
-// Copyright (C) 2006, 2008, 2009 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2006, 2008, 2009, 2012 EPITA Research and Development
+// Laboratory (LRDE)
//
// This file is part of Olena.
//
@@ -123,7 +124,7 @@ namespace mln
mat<m,n,T> t() const;
/// Return the inverse of the matrix.
- /// Only compile on square matrix.
+ /// Only compile on square matrix.
mat<n,m,T> _1() const;
private:
@@ -134,18 +135,6 @@ namespace mln
};
- template <typename T>
- mat<2,2,T>
- make(const T& t00, const T& t01,
- const T& t10, const T& t11);
-
- template <typename T>
- mat<3,3,T>
- make(const T& t00, const T& t01, const T& t02,
- const T& t10, const T& t11, const T& t12,
- const T& t20, const T& t21, const T& t22);
-
-
} // end of namespace algebra
@@ -225,7 +214,7 @@ namespace mln
{
typedef algebra::mat<m, m, mln_trait_op_times(T, U)> ret;
};
-
+
// mat * s
template < unsigned n, unsigned m, typename T,
@@ -245,7 +234,7 @@ namespace mln
// {
// typedef algebra::mat<n, m, mln_trait_binary(Name, T, S)> ret;
// };
-
+
// mat / s
template < unsigned n, unsigned m, typename T,
@@ -340,6 +329,7 @@ namespace mln
// Trace.
+ /// Compute the trace of a matrix \p m
template<unsigned n, typename T>
mln_sum(T)
tr(const mat<n,n,T>& m);
@@ -347,13 +337,10 @@ namespace mln
// Determinant.
- template<typename T>
- mln_sum_product(T,T)
- det(const mat<2,2,T>& m);
-
- template<typename T>
+ /// Compute the determinant of a matrix \p m
+ template<unsigned n, typename T>
mln_sum_product(T,T)
- det(const mat<3,3,T>& m);
+ det(const mat<n,n,T>& m);
@@ -548,6 +535,37 @@ namespace mln
namespace internal
{
+ // "Make" routines.
+
+ template <typename T>
+ inline
+ mat<2,2,T>
+ make(const T& t00, const T& t01,
+ const T& t10, const T& t11)
+ {
+ mat<2,2,T> tmp;
+ tmp(0, 0) = t00; tmp(0, 1) = t01;
+ tmp(1, 0) = t10; tmp(1, 1) = t11;
+ return tmp;
+ }
+
+ template <typename T>
+ inline
+ mat<3,3,T>
+ make(const T& t00, const T& t01, const T& t02,
+ const T& t10, const T& t11, const T& t12,
+ const T& t20, const T& t21, const T& t22)
+ {
+ mat<3,3,T> tmp;
+ tmp(0, 0) = t00; tmp(0, 1) = t01; tmp(0, 2) = t02;
+ tmp(1, 0) = t10; tmp(1, 1) = t11; tmp(1, 2) = t12;
+ tmp(2, 0) = t20; tmp(2, 1) = t21; tmp(2, 2) = t22;
+ return tmp;
+ }
+
+
+ // Inverse routines.
+
template <typename T>
inline
mat<2,2,float>
@@ -568,35 +586,119 @@ namespace mln
mln_precondition(d != 0);
return make<float>( det(make(m(1,1), m(1,2),
m(2,1), m(2,2))),
-
+
det(make(m(0,2), m(0,1),
m(2,2), m(2,1))),
-
+
det(make(m(0,1), m(0,2),
m(1,1), m(1,2))),
-
+
det(make(m(1,2), m(1,0),
m(2,2), m(2,0))),
-
+
det(make(m(0,0), m(0,2),
m(2,0), m(2,2))),
-
+
det(make(m(0,2), m(0,0),
m(1,2), m(1,0))),
det(make(m(1,0), m(1,1),
m(2,0), m(2,1))),
-
+
det(make(m(0,1), m(0,0),
m(2,1), m(2,0))),
-
+
det(make(m(0,0), m(0,1),
m(1,0), m(1,1)))
) / d;
}
- } // end of namespace algebra::inverse
+ template <typename T>
+ inline
+ mat<4,4,float>
+ inverse(const mat<4,4,T>& m)
+ {
+ mat<4,4,T> mo;
+
+ // Based on MESA implementation of the GLU library.
+ mo(0,0) = m(1,1) * m(2,2) * m(3,3) - m(1,1) * m(2,3) * m(3,2) -
+ m(2,1) * m(1,2) * m(3,3) + m(2,1) * m(1,3) * m(3,2) +
+ m(3,1) * m(1,2) * m(2,3) - m(3,1) * m(1,3) * m(2,2);
+
+ mo(1,0) = -m(1,0) * m(2,2) * m(3,3) + m(1,0) * m(2,3) * m(3,2) +
+ m(2,0) * m(1,2) * m(3,3) - m(2,0) * m(1,3) * m(3,2) -
+ m(3,0) * m(1,2) * m(2,3) + m(3,0) * m(1,3) * m(2,2);
+
+ mo(2,0) = m(1,0) * m(2,1) * m(3,3) - m(1,0) * m(2,3) * m(3,1) -
+ m(2,0) * m(1,1) * m(3,3) + m(2,0) * m(1,3) * m(3,1) +
+ m(3,0) * m(1,1) * m(2,3) - m(3,0) * m(1,3) * m(2,1);
+
+ mo(3,0) = -m(1,0) * m(2,1) * m(3,2) + m(1,0) * m(2,2) * m(3,1) +
+ m(2,0) * m(1,1) * m(3,2) - m(2,0) * m(1,2) * m(3,1) -
+ m(3,0) * m(1,1) * m(2,2) + m(3,0) * m(1,2) * m(2,1);
+
+ mo(0,1) = -m(0,1) * m(2,2) * m(3,3) + m(0,1) * m(2,3) * m(3,2) +
+ m(2,1) * m(0,2) * m(3,3) - m(2,1) * m(0,3) * m(3,2) -
+ m(3,1) * m(0,2) * m(2,3) + m(3,1) * m(0,3) * m(2,2);
+
+ mo(1,1) = m(0,0) * m(2,2) * m(3,3) - m(0,0) * m(2,3) * m(3,2) -
+ m(2,0) * m(0,2) * m(3,3) + m(2,0) * m(0,3) * m(3,2) +
+ m(3,0) * m(0,2) * m(2,3) - m(3,0) * m(0,3) * m(2,2);
+
+ mo(2,1) = -m(0,0) * m(2,1) * m(3,3) + m(0,0) * m(2,3) * m(3,1) +
+ m(2,0) * m(0,1) * m(3,3) - m(2,0) * m(0,3) * m(3,1) -
+ m(3,0) * m(0,1) * m(2,3) + m(3,0) * m(0,3) * m(2,1);
+
+ mo(3,1) = m(0,0) * m(2,1) * m(3,2) - m(0,0) * m(2,2) * m(3,1) -
+ m(2,0) * m(0,1) * m(3,2) + m(2,0) * m(0,2) * m(3,1) +
+ m(3,0) * m(0,1) * m(2,2) - m(3,0) * m(0,2) * m(2,1);
+
+ mo(0,2) = m(0,1) * m(1,2) * m(3,3) - m(0,1) * m(1,3) * m(3,2) -
+ m(1,1) * m(0,2) * m(3,3) + m(1,1) * m(0,3) * m(3,2) +
+ m(3,1) * m(0,2) * m(1,3) - m(3,1) * m(0,3) * m(1,2);
+
+ mo(1,2) = -m(0,0) * m(1,2) * m(3,3) + m(0,0) * m(1,3) * m(3,2) +
+ m(1,0) * m(0,2) * m(3,3) - m(1,0) * m(0,3) * m(3,2) -
+ m(3,0) * m(0,2) * m(1,3) + m(3,0) * m(0,3) * m(1,2);
+
+ mo(2,2) = m(0,0) * m(1,1) * m(3,3) - m(0,0) * m(1,3) * m(3,1) -
+ m(1,0) * m(0,1) * m(3,3) + m(1,0) * m(0,3) * m(3,1) +
+ m(3,0) * m(0,1) * m(1,3) - m(3,0) * m(0,3) * m(1,1);
+
+ mo(3,2) = -m(0,0) * m(1,1) * m(3,2) + m(0,0) * m(1,2) * m(3,1) +
+ m(1,0) * m(0,1) * m(3,2) - m(1,0) * m(0,2) * m(3,1) -
+ m(3,0) * m(0,1) * m(1,2) + m(3,0) * m(0,2) * m(1,1);
+
+ mo(0,3) = -m(0,1) * m(1,2) * m(2,3) + m(0,1) * m(1,3) * m(2,2) +
+ m(1,1) * m(0,2) * m(2,3) - m(1,1) * m(0,3) * m(2,2) -
+ m(2,1) * m(0,2) * m(1,3) + m(2,1) * m(0,3) * m(1,2);
+
+ mo(1,3) = m(0,0) * m(1,2) * m(2,3) - m(0,0) * m(1,3) * m(2,2) -
+ m(1,0) * m(0,2) * m(2,3) + m(1,0) * m(0,3) * m(2,2) +
+ m(2,0) * m(0,2) * m(1,3) - m(2,0) * m(0,3) * m(1,2);
+
+ mo(2,3) = -m(0,0) * m(1,1) * m(2,3) + m(0,0) * m(1,3) * m(2,1) +
+ m(1,0) * m(0,1) * m(2,3) - m(1,0) * m(0,3) * m(2,1) -
+ m(2,0) * m(0,1) * m(1,3) + m(2,0) * m(0,3) * m(1,1);
+
+ mo(3,3) = m(0,0) * m(1,1) * m(2,2) - m(0,0) * m(1,2) * m(2,1) -
+ m(1,0) * m(0,1) * m(2,2) + m(1,0) * m(0,2) * m(2,1) +
+ m(2,0) * m(0,1) * m(1,2) - m(2,0) * m(0,2) * m(1,1);
+
+ double det = m(0,0) * mo(0,0) + m(0,1) * mo(1,0) + m(0,2) * mo(2,0) + m(0,3) * mo(0,3);
+ mln_precondition(det != 0);
+
+ det = 1.0 / det;
+
+ for (int i = 0; i < 4; i++)
+ for (int j = 0; j < 4; j++)
+ mo(i,j) *= det;
+
+ return mo;
+ }
+
+ } // end of namespace algebra::internal
template <unsigned n, unsigned m, typename T>
inline
@@ -608,35 +710,6 @@ namespace mln
}
- // "Make" routines.
-
- template <typename T>
- inline
- mat<2,2,T>
- make(const T& t00, const T& t01,
- const T& t10, const T& t11)
- {
- mat<2,2,T> tmp;
- tmp(0, 0) = t00; tmp(0, 1) = t01;
- tmp(1, 0) = t10; tmp(1, 1) = t11;
- return tmp;
- }
-
- template <typename T>
- inline
- mat<3,3,T>
- make(const T& t00, const T& t01, const T& t02,
- const T& t10, const T& t11, const T& t12,
- const T& t20, const T& t21, const T& t22)
- {
- mat<3,3,T> tmp;
- tmp(0, 0) = t00; tmp(0, 1) = t01; tmp(0, 2) = t02;
- tmp(1, 0) = t10; tmp(1, 1) = t11; tmp(1, 2) = t12;
- tmp(2, 0) = t20; tmp(2, 1) = t21; tmp(2, 2) = t22;
- return tmp;
- }
-
-
// Operators.
@@ -827,29 +900,72 @@ namespace mln
// Determinant.
- template<typename T>
- inline
- mln_sum_product(T,T)
- det(const mat<2,2,T>& m)
+ namespace impl
{
- return m(0,0) * m(1,1) - m(0,1) * m(1,0);
- }
- template<typename T>
+ template<unsigned n, typename T>
+ mln_sum_product(T,T)
+ det(const mat<n,n,T>& m)
+ {
+ // Not implemented.
+ mlc_abort(T)::check();
+ }
+
+ template<typename T>
+ inline
+ mln_sum_product(T,T)
+ det(const mat<2,2,T>& m)
+ {
+ return m(0,0) * m(1,1) - m(0,1) * m(1,0);
+ }
+
+ template<typename T>
+ inline
+ mln_sum_product(T,T)
+ det(const mat<3,3,T>& m)
+ {
+ return
+ + m(0,0) * m(1,1) * m(2,2)
+ - m(0,0) * m(1,2) * m(2,1)
+ - m(0,1) * m(1,0) * m(2,2)
+ + m(0,1) * m(1,2) * m(2,0)
+ + m(0,2) * m(1,0) * m(2,1)
+ - m(0,2) * m(1,1) * m(2,0);
+ }
+
+ template<typename T>
+ inline
+ mln_sum_product(T,T)
+ det(const mat<4,4,T>& m)
+ {
+ return m(0,3) * m(1,2) * m(2,1) * m(3,0) - m(0,2) * m(1,3) * m(2,1) * m(3,0) -
+ m(0,3) * m(1,1) * m(2,2) * m(3,0) + m(0,1) * m(1,3) * m(2,2) * m(3,0) +
+ m(0,2) * m(1,1) * m(2,3) * m(3,0) - m(0,1) * m(1,2) * m(2,3) * m(3,0) -
+ m(0,3) * m(1,2) * m(2,0) * m(3,1) + m(0,2) * m(1,3) * m(2,0) * m(3,1) +
+ m(0,3) * m(1,0) * m(2,2) * m(3,1) - m(0,0) * m(1,3) * m(2,2) * m(3,1) -
+ m(0,2) * m(1,0) * m(2,3) * m(3,1) + m(0,0) * m(1,2) * m(2,3) * m(3,1) +
+ m(0,3) * m(1,1) * m(2,0) * m(3,2) - m(0,1) * m(1,3) * m(2,0) * m(3,2) -
+ m(0,3) * m(1,0) * m(2,1) * m(3,2) + m(0,0) * m(1,3) * m(2,1) * m(3,2) +
+ m(0,1) * m(1,0) * m(2,3) * m(3,2) - m(0,0) * m(1,1) * m(2,3) * m(3,2) -
+ m(0,2) * m(1,1) * m(2,0) * m(3,3) + m(0,1) * m(1,2) * m(2,0) * m(3,3) +
+ m(0,2) * m(1,0) * m(2,1) * m(3,3) - m(0,0) * m(1,2) * m(2,1) * m(3,3) -
+ m(0,1) * m(1,0) * m(2,2) * m(3,3) + m(0,0) * m(1,1) * m(2,2) * m(3,3);
+ }
+
+ } // end of namespace mln::algebra::impl
+
+
+ template<unsigned n, typename T>
inline
mln_sum_product(T,T)
- det(const mat<3,3,T>& m)
+ det(const mat<n,n,T>& m)
{
- return
- + m(0,0) * m(1,1) * m(2,2)
- - m(0,0) * m(1,2) * m(2,1)
- - m(0,1) * m(1,0) * m(2,2)
- + m(0,1) * m(1,2) * m(2,0)
- + m(0,2) * m(1,0) * m(2,1)
- - m(0,2) * m(1,1) * m(2,0);
+ return mln::algebra::impl::det(m);
}
+
+
// vec methods.
template <unsigned n, typename T>
@@ -863,6 +979,7 @@ namespace mln
return tmp;
}
+
# endif // ! MLN_INCLUDE_ONLY
} // end of namespace mln::algebra
--
1.7.2.5