[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Toon-members] TooN/internal objects.h
From: |
Edward Rosten |
Subject: |
[Toon-members] TooN/internal objects.h |
Date: |
Thu, 11 Jun 2009 20:10:26 +0000 |
CVSROOT: /cvsroot/toon
Module name: TooN
Changes by: Edward Rosten <edrosten> 09/06/11 20:10:26
Modified files:
internal : objects.h
Log message:
Added a "pure" unscaled identity object, which carries no data.
This is VERY important, since there is a global identity object.
Previously
the global Identity carried data and so had to be constructed. This
caused
nasty bugs due to the unspecified order of initialization of global
objects.
The bug can be observed with the following:
g++ identity_test.cc -fmudflap -lmudflap -g -ggdb
MUDFLAP_OPTIONS=-viol-gdb ./a.out
CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/TooN/internal/objects.h?cvsroot=toon&r1=1.14&r2=1.15
Patches:
Index: objects.h
===================================================================
RCS file: /cvsroot/toon/TooN/internal/objects.h,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -b -r1.14 -r1.15
--- objects.h 11 Jun 2009 20:00:58 -0000 1.14
+++ objects.h 11 Jun 2009 20:10:25 -0000 1.15
@@ -36,6 +36,7 @@
struct SizedZero;
struct RCZero;
template<class P> struct Identity;
+ template<class P> struct ScaledIdentity;
template<class P> struct SizedIdentity;
template<int S, class P, class B, class Ps> class ScalarsVector;
@@ -169,11 +170,11 @@
///Object whioch behaves like an Identity matrix. See TooN::Identity.
///@ingroup gInternal
-template<class Pr> struct Operator<Internal::Identity<Pr> > {
+template<class Pr> struct Operator<Internal::ScaledIdentity<Pr> > {
typedef Pr Precision;
const Precision val;
- Operator(const Precision& v=1)
+ Operator(const Precision& v)
:val(v)
{}
///@name Operator members
@@ -226,30 +227,27 @@
///@}
template<class Q> struct ScaleType
{
- typedef Operator<Internal::Identity<Q> > Type;
+ typedef Operator<Internal::ScaledIdentity<Q> > Type;
};
- template<class Pout, class Pmult> Operator<Internal::Identity<Pout> >
scale_me(const Pmult& m) const
+ template<class Pout, class Pmult>
Operator<Internal::ScaledIdentity<Pout> > scale_me(const Pmult& m) const
{
- return Operator<Internal::Identity<Pout> >(val*m);
+ return Operator<Internal::ScaledIdentity<Pout> >(val*m);
}
- Operator<Internal::SizedIdentity<Precision> > operator()(int s){
- return Operator<Internal::SizedIdentity<Precision> >(s);
- }
};
///A variant of Identity which holds a size, allowing
///dynamic matrices to be constructed
///@ingroup gInternal
template<class Precision> struct Operator<Internal::SizedIdentity<Precision> >
- : public Operator<Internal::Identity<Precision> > {
+ : public Operator<Internal::ScaledIdentity<Precision> > {
- using Operator<Internal::Identity<Precision> >::val;
+ using Operator<Internal::ScaledIdentity<Precision> >::val;
const int my_size;
- Operator(int s, const Precision& v=1)
- :Operator<Internal::Identity<Precision> > (v), my_size(s)
+ Operator(int s, const Precision& v)
+ :Operator<Internal::ScaledIdentity<Precision> > (v), my_size(s)
{}
///@name Operator members
@@ -268,6 +266,84 @@
return Operator<Internal::SizedIdentity<Pout> >(my_size, val*m);
}
};
+
+///Object whioch behaves like an Identity matrix. See TooN::Identity.
+///This is different from ScaledIdentity primarily because it is a
+///trivial struct. This is very important since there is a global instance.
+///If it was non trivial, then you get nasty bugs which are hard to find due
+///to the random order of initialization of non-trivial global structs.
+//
+//A precision is required to make it behave like all other scalable operators.
+//
+///@ingroup gInternal
+template<class Pr> struct Operator<Internal::Identity<Pr> > {
+
+ typedef Pr Precision;
+ Operator()
+ {}
+ ///@name Operator members
+ ///@{
+
+ template<int R, int C, class P, class B>
+ void eval(Matrix<R,C,P,B>& m) const {
+ SizeMismatch<R, C>::test(m.num_rows(), m.num_cols());
+
+ for(int r=0; r<m.num_rows(); r++){
+ for(int c=0; c<m.num_cols(); c++){
+ m(r,c)=0;
+ }
+ }
+
+ for(int r=0; r < m.num_rows(); r++) {
+ m(r,r) = 1;
+ }
+ }
+
+ template<int Rows, int Cols, typename P, typename B>
+ void plusequals(Matrix<Rows, Cols, P, B>& m) const
+ {
+ SizeMismatch<Rows, Cols>::test(m.num_rows(), m.num_cols());
+ for(int i=0; i < m.num_rows(); i++)
+ m[i][i] += 1;
+ }
+
+ template <int Rows, int Cols, typename P1, typename B1>
+ Operator<Internal::AddIdentity<Rows,Cols,P1,B1,Precision> > add(const
Matrix<Rows,Cols, P1, B1>& m) const
+ {
+ SizeMismatch<Rows, Cols>::test(m.num_rows(), m.num_cols());
+ return
Operator<Internal::AddIdentity<Rows,Cols,P1,B1,Precision> >(1, m, 0);
+ }
+
+ template <int Rows, int Cols, typename P1, typename B1>
+ Operator<Internal::AddIdentity<Rows,Cols,P1,B1,Precision> >
rsubtract(const Matrix<Rows,Cols, P1, B1>& m) const
+ {
+ SizeMismatch<Rows, Cols>::test(m.num_rows(), m.num_cols());
+ return
Operator<Internal::AddIdentity<Rows,Cols,P1,B1,Precision> >(-1, m, 0);
+ }
+
+ template <int Rows, int Cols, typename P1, typename B1>
+ Operator<Internal::AddIdentity<Rows,Cols,P1,B1,Precision> >
lsubtract(const Matrix<Rows,Cols, P1, B1>& m) const
+ {
+ SizeMismatch<Rows, Cols>::test(m.num_rows(), m.num_cols());
+ return
Operator<Internal::AddIdentity<Rows,Cols,P1,B1,Precision> >(1, m, 1);
+ }
+
+ ///@}
+ template<class Q> struct ScaleType
+ {
+ typedef Operator<Internal::ScaledIdentity<Q> > Type;
+ };
+
+ template<class Pout, class Pmult>
Operator<Internal::ScaledIdentity<Pout> > scale_me(const Pmult& m) const
+ {
+ return Operator<Internal::ScaledIdentity<Pout> >(m);
+ }
+
+ Operator<Internal::SizedIdentity<Precision> > operator()(int s){
+ return Operator<Internal::SizedIdentity<Precision> >(s, 1);
+ }
+};
+
////////////////////////////////////////////////////////////////////////////////
//
// Addition of scalars to vectors and matrices