toon-members
[Top][All Lists]
Advanced

[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




reply via email to

[Prev in Thread] Current Thread [Next in Thread]