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: Mon, 15 Jun 2009 19:44:34 +0000

CVSROOT:        /cvsroot/toon
Module name:    TooN
Changes by:     Edward Rosten <edrosten>        09/06/15 19:44:34

Modified files:
        internal       : objects.h 

Log message:
        Reverted back to version 1.17 with code duplication, instead of a 
working
        One type. One still has one byte of data since it is a struct, so GCC 
still
        copy-constructs it. This copy construction causes a violation with 
        -fmudflap. 
        
        Presumably the violation will get optimized away with -O3, but the 
debug 
        version needs to work properly.

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/TooN/internal/objects.h?cvsroot=toon&r1=1.19&r2=1.20

Patches:
Index: objects.h
===================================================================
RCS file: /cvsroot/toon/TooN/internal/objects.h,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -b -r1.19 -r1.20
--- objects.h   15 Jun 2009 19:37:05 -0000      1.19
+++ objects.h   15 Jun 2009 19:44:33 -0000      1.20
@@ -36,55 +36,16 @@
        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;        
        template<int R, int C, class P, class B, class Ps> class ScalarsMatrix; 
        template<int R, int C, class P, class B, class Ps> class AddIdentity;   
+       template<class P> class Ones;   
        template<class P> class Scalars;        
        template<class P> class SizedScalars;   
        template<class P> class RCScalars;
-
-       struct One{
-               //Generic cast to anything
-               template<class C> operator C() const
-               {
-                       return 1;
-               }
-       };
-       template<class Rhs> Rhs operator*(One, const Rhs& v){return v;}
-       template<class Lhs> Lhs operator*(const Lhs& v, One){return v;}
-       template<class Rhs> Rhs operator+(One, const Rhs& v){return 1+v;}
-       template<class Lhs> Lhs operator+(const Lhs& v, One){return v+1;}
-       template<class Rhs> Rhs operator-(One, const Rhs& v){return 1-v;}
-       template<class Lhs> Lhs operator-(const Lhs& v, One){return v-1;}
-       int operator-(const One&)
-       {
-               return -1;
-       }
-
-       template<class C> struct NegType
-       {
-               typedef C Type;
-       };
-
-       template<> struct NegType<One>
-       {
-               typedef int Type;
-       };
-
-       //One can be converted in to anything, so the resulting type is
-       //a field if the other type is a field.
-       template<class Rhs> struct Field<One, Rhs>
-       {
-               static const int is = IsField<Rhs>::value;
-       };
-
-       template<class Lhs> struct Field<Lhs, One>
-       {
-               static const int is = IsField<Lhs>::value;
-       };
-
 }
 
 ////////////////////
@@ -194,7 +155,7 @@
                                        mm[r][c] = m[r][c];
 
                for(int i=0; i < m.num_rows(); i++)
-                               mm[i][i] += (P)s;
+                               mm[i][i] += s;
        }
 
        int num_rows() const
@@ -208,9 +169,9 @@
        ///@}
 };
 
-///Object which behaves like an Identity matrix. See TooN::Identity.
+///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;
@@ -231,7 +192,7 @@
                }
                
                for(int r=0; r < m.num_rows(); r++) {
-                       m(r,r) = (P)val;
+                       m(r,r) = val;
                }
        }
        
@@ -240,7 +201,7 @@
        {
                SizeMismatch<Rows, Cols>::test(m.num_rows(), m.num_cols());
                for(int i=0; i < m.num_rows(); i++)
-                       m[i][i] += (P)val;
+                       m[i][i] += val;
        }
 
        template <int Rows, int Cols, typename P1, typename B1> 
@@ -264,29 +225,30 @@
                return 
Operator<Internal::AddIdentity<Rows,Cols,P1,B1,Precision> >(val, m, 1);
        }
 
-       template<class Pout, class Pmult> Operator<Internal::Identity<Pout> > 
scale_me(const Pmult& m) const
-       {
-               return Operator<Internal::Identity<Pout> >(val*m);
-       }
-
        ///@}
+       template<class Q> struct ScaleType
+       {
+               typedef Operator<Internal::ScaledIdentity<Q> > Type;
+       };
 
-       Operator<Internal::SizedIdentity<Precision> > operator()(int s){
-               return Operator<Internal::SizedIdentity<Precision> >(s, val);
+       template<class Pout, class Pmult> 
Operator<Internal::ScaledIdentity<Pout> > scale_me(const Pmult& m) const
+       {
+               return Operator<Internal::ScaledIdentity<Pout> >(val*m);
        }
+
 };
        
 ///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)
-               :Operator<Internal::Identity<Precision> > (v), my_size(s)
+               :Operator<Internal::ScaledIdentity<Precision> > (v), my_size(s)
        {}
 
        ///@name Operator members
@@ -295,11 +257,94 @@
        int num_cols() const {return my_size;}
        ///@}
 
+       template<class Q> struct ScaleType
+       {
+               typedef Operator<Internal::SizedIdentity<Q> > Type;
+       };
+
        template<class Pout, class Pmult> 
Operator<Internal::SizedIdentity<Pout> > scale_me(const Pmult& m) const
        {
                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
@@ -366,6 +411,141 @@
        ///@}
 };
 
+///This is different from Scalars 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 P> struct Operator<Internal::Ones<P> >
+{
+       typedef P Precision;
+       //Default argument in constructor, otherwise Doxygen mis-parses
+       //a static object with a constructor as a function.
+       Operator()
+       {}
+
+       ////////////////////////////////////////
+       //
+       // All applications for vector
+       //
+       ///@name Operator members
+       ///@{
+
+       template <int Size, typename P1, typename B1> 
+       void eval(Vector<Size, P1, B1>& v) const
+       {
+               for(int i=0; i < v.size(); i++)
+                       v[i] = 1;
+       }
+
+       template <int Size, typename P1, typename B1> 
+       void plusequals(Vector<Size, P1, B1>& v) const
+       {
+               for(int i=0; i < v.size(); i++)
+                       v[i] += 1;
+       }
+
+       template <int Size, typename P1, typename B1>
+       void minusequals(Vector<Size, P1, B1>& v) const
+       {
+               for(int i=0; i < v.size(); ++i)
+                       v[i] -= 1;
+       }
+
+       template <int Size, typename P1, typename B1> 
+       Operator<Internal::ScalarsVector<Size,P1,B1,Precision> > add(const 
Vector<Size, P1, B1>& v) const
+       {
+               return Operator<Internal::ScalarsVector<Size,P1,B1,Precision> 
>(1, v, 0);
+       }
+
+       template <int Size, typename P1, typename B1> 
+       Operator<Internal::ScalarsVector<Size,P1,B1,Precision> > 
rsubtract(const Vector<Size, P1, B1>& v) const
+       {
+               return Operator<Internal::ScalarsVector<Size,P1,B1,Precision> 
>(-1, v, 0);
+       }
+
+       template <int Size, typename P1, typename B1> 
+       Operator<Internal::ScalarsVector<Size,P1,B1,Precision> > 
lsubtract(const Vector<Size, P1, B1>& v) const
+       {
+               return Operator<Internal::ScalarsVector<Size,P1,B1,Precision> 
>(1, v, 1);
+       }
+
+       ////////////////////////////////////////
+       //
+       // All applications for matrix
+       //
+
+       template <int Rows, int Cols, typename P1, typename B1> 
+       void eval(Matrix<Rows,Cols, P1, B1>& m) const
+       {
+               for(int r=0; r < m.num_rows(); r++)
+                       for(int c=0; c < m.num_cols(); c++)
+                               m[r][c] = 1;
+       }
+
+       template <int Rows, int Cols, typename P1, typename B1> 
+       void plusequals(Matrix<Rows,Cols, P1, B1>& m) const
+       {
+               for(int r=0; r < m.num_rows(); r++)
+                       for(int c=0; c < m.num_cols(); c++)
+                               m[r][c] += 1;
+       }
+
+       template <int Rows, int Cols, typename P1, typename B1> 
+       void minusequals(Matrix<Rows,Cols, P1, B1>& m) const
+       {
+               for(int r=0; r < m.num_rows(); r++)
+                       for(int c=0; c < m.num_cols(); c++)
+                               m[r][c] -= 1;
+       }
+
+       template <int Rows, int Cols, typename P1, typename B1> 
+       Operator<Internal::ScalarsMatrix<Rows,Cols,P1,B1,Precision> > add(const 
Matrix<Rows,Cols, P1, B1>& v) const
+       {
+               return 
Operator<Internal::ScalarsMatrix<Rows,Cols,P1,B1,Precision> >(1, v, 0);
+       }
+
+
+       template <int Rows, int Cols, typename P1, typename B1> 
+       Operator<Internal::ScalarsMatrix<Rows,Cols,P1,B1,Precision> > 
rsubtract(const Matrix<Rows,Cols, P1, B1>& v) const
+       {
+               return 
Operator<Internal::ScalarsMatrix<Rows,Cols,P1,B1,Precision> >(-1, v, 0);
+       }
+
+       template <int Rows, int Cols, typename P1, typename B1> 
+       Operator<Internal::ScalarsMatrix<Rows,Cols,P1,B1,Precision> > 
lsubtract(const Matrix<Rows,Cols, P1, B1>& v) const
+       {
+               return 
Operator<Internal::ScalarsMatrix<Rows,Cols,P1,B1,Precision> >(1, v, 1);
+       }
+       ///@}
+       ////////////////////////////////////////
+       //
+       // Create sized versions for initialization
+       //
+
+       Operator<Internal::SizedScalars<Precision> > operator()(int size) const
+       {
+               return Operator<Internal::SizedScalars<Precision> > (1,size);
+       }
+
+       Operator<Internal::RCScalars<Precision> > operator()(int r, int c) const
+       {
+               return Operator<Internal::RCScalars<Precision> > (1,r,c);
+       }
+
+       template<class Q> struct ScaleType
+       {
+               typedef Operator<Internal::Scalars<Q> > Type;
+       };
+
+       template<class Pout, class Pmult> Operator<Internal::Scalars<Pout> > 
scale_me(const Pmult& m) const
+       {
+               return Operator<Internal::Scalars<Pout> >(m);
+       }
+};
+
 ///Generic scalars object. Knows how to be added, knows how to deal with += 
and so on.
 ///See TooN::Ones
 ///@ingroup gInternal
@@ -389,21 +569,21 @@
        void eval(Vector<Size, P1, B1>& v) const
        {
                for(int i=0; i < v.size(); i++)
-                       v[i] = (P1)s;
+                       v[i] = s;
        }
 
        template <int Size, typename P1, typename B1> 
        void plusequals(Vector<Size, P1, B1>& v) const
        {
                for(int i=0; i < v.size(); i++)
-                       v[i] += (P1)s;
+                       v[i] += s;
        }
 
        template <int Size, typename P1, typename B1>
        void minusequals(Vector<Size, P1, B1>& v) const
        {
                for(int i=0; i < v.size(); ++i)
-                       v[i] -= (P1)s;
+                       v[i] -= s;
        }
 
        template <int Size, typename P1, typename B1> 
@@ -442,7 +622,7 @@
        {
                for(int r=0; r < m.num_rows(); r++)
                        for(int c=0; c < m.num_cols(); c++)
-                               m[r][c] += (P1)s;
+                               m[r][c] += s;
        }
 
        template <int Rows, int Cols, typename P1, typename B1> 
@@ -450,7 +630,7 @@
        {
                for(int r=0; r < m.num_rows(); r++)
                        for(int c=0; c < m.num_cols(); c++)
-                               m[r][c] -= (P1)s;
+                               m[r][c] -= s;
        }
 
        template <int Rows, int Cols, typename P1, typename B1> 
@@ -461,9 +641,9 @@
 
 
        template <int Rows, int Cols, typename P1, typename B1> 
-       Operator<Internal::ScalarsMatrix<Rows,Cols,P1,B1,typename 
Internal::NegType<P>::Type> > rsubtract(const Matrix<Rows,Cols, P1, B1>& v) 
const
+       Operator<Internal::ScalarsMatrix<Rows,Cols,P1,B1,Precision> > 
rsubtract(const Matrix<Rows,Cols, P1, B1>& v) const
        {
-               return 
Operator<Internal::ScalarsMatrix<Rows,Cols,P1,B1,typename 
Internal::NegType<P>::Type > >(-s, v, 0);
+               return 
Operator<Internal::ScalarsMatrix<Rows,Cols,P1,B1,Precision> >(-s, v, 0);
        }
 
        template <int Rows, int Cols, typename P1, typename B1> 
@@ -487,6 +667,11 @@
                return Operator<Internal::RCScalars<Precision> > (s,r,c);
        }
 
+       template<class Q> struct ScaleType
+       {
+               typedef Operator<Internal::Scalars<Q> > Type;
+       };
+
        template<class Pout, class Pmult> Operator<Internal::Scalars<Pout> > 
scale_me(const Pmult& m) const
        {
                return Operator<Internal::Scalars<Pout> >(s*m);
@@ -515,6 +700,10 @@
        }
        ///@}
 
+       template<class Q> struct ScaleType
+       {
+               typedef Operator<Internal::SizedScalars<Q> > Type;
+       };
 private:
        void operator()(int);
        void operator()(int,int);
@@ -542,6 +731,11 @@
                :Operator<Internal::Scalars<P> >(s),my_rows(r),my_cols(c)
        {}
                
+       template<class Q> struct ScaleType
+       {
+               typedef Operator<Internal::RCScalars<Q> > Type;
+       };
+
        template<class Pout, class Pmult> Operator<Internal::RCScalars<Pout> > 
scale_me(const Pmult& m) const
        {
                return Operator<Internal::RCScalars<Pout> >(s*m, my_rows, 
my_cols);
@@ -559,40 +753,42 @@
 // How to scale scalable operators
 //
        
+template<class OpIn, class Pl, class Pr, class Binary>
+struct ScaleMapper
+{
+       typedef typename Binary::template Return<Pl,Pr>::Type Res;
+       typedef typename Operator<OpIn>::template ScaleType<Res>::Type Op;
+};
+       
 template<template<class> class Op, class Pl, class Pr> 
-Operator<Op<typename Internal::MultiplyType<Pl, Pr>::type > >
+typename ScaleMapper<Op<Pr>, Pl, Pr, Internal::Multiply>::Op
 operator*(const Pl& l, const Operator<Op<Pr> >& r)
 {
        return r.template scale_me<typename Internal::MultiplyType<Pl, 
Pr>::type, Pl>(l); 
 }
 
 template<template<class> class Op, class Pl, class Pr> 
-Operator<Op<typename Internal::MultiplyType<Pl, Pr>::type > >
+typename ScaleMapper<Op<Pl>, Pl, Pr, Internal::Multiply>::Op
 operator*(const Operator<Op<Pl> >& l, const Pr&  r)
 {
-       return l.template scale_me<typename Internal::MultiplyType<Pl, 
Pr>::type>(r); 
+       return l.template scale_me<typename Internal::MultiplyType<Pl, 
Pr>::type, Pl>(r); 
 }
 
 template<template<class> class Op, class Pl, class Pr> 
-Operator<Op<typename Internal::DivideType<Pl, Pr>::type > >
+typename ScaleMapper<Op<Pl>, Pl, Pr, Internal::Divide>::Op
 operator/(const Operator<Op<Pl> >& l, const Pr&  r)
 {
-       return l.template scale_me<typename Internal::MultiplyType<Pl, 
Pr>::type, Pl>(static_cast<typename Internal::DivideType<Pl,Pr>::type>(1)/r); 
+       return l.template scale_me<typename Internal::DivideType<Pl, Pr>::type, 
Pl>(static_cast<typename Internal::DivideType<Pl,Pr>::type>(1)/r); 
 }
 
 
-template<class Op>
-Operator<Op> operator-(const Operator<Op>& o)
+template<template<class> class Op, class P>
+typename Operator<Op<P> >::template ScaleType<P>::Type
+operator-(const Operator<Op<P> >& o)
 {
-       return o.template scale_me<typename Operator<Op>::Precision>(-1);
+       return o.template scale_me<P>(-1);
 }
 
-//Special case for negating One
-template<template<class>class Op>
-Operator<Op<DefaultPrecision> > operator-(const Operator<Op<Internal::One> >& 
o)
-{
-       return o.template scale_me<DefaultPrecision>(-1);
-}
 
 /**This function is used to add a scalar to every element of a vector or
    matrix. For example:
@@ -613,7 +809,7 @@
    @endcode
    @ingroup gLinAlg
 */
-static const Operator<Internal::Scalars<Internal::One> > Ones = 
Internal::One();
+static const Operator<Internal::Ones<DefaultPrecision> > Ones;
 
 
 /**This function is used to initialize vectors and matrices to zero.
@@ -648,6 +844,6 @@
    @ingroup gLinAlg
 */
 
-static Operator<Internal::Identity<Internal::One> > Identity = Internal::One();
+static Operator<Internal::Identity<DefaultPrecision> > Identity;
 
 }




reply via email to

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