toon-members
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Toon-members] TooN internal/operators.hh internal/vector.hh t...


From: Edward Rosten
Subject: [Toon-members] TooN internal/operators.hh internal/vector.hh t...
Date: Wed, 18 Feb 2009 14:27:58 +0000

CVSROOT:        /cvsroot/toon
Module name:    TooN
Changes by:     Edward Rosten <edrosten>        09/02/18 14:27:58

Modified files:
        internal       : operators.hh vector.hh 
        test           : test2.cc 

Log message:
        Complete (?) set of operators for Vector.
        
        +,-,*,/,+=, *=, -=, /= for scalars.
        
        *,+,-,+=,-= for vectors

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/TooN/internal/operators.hh?cvsroot=toon&r1=1.5&r2=1.6
http://cvs.savannah.gnu.org/viewcvs/TooN/internal/vector.hh?cvsroot=toon&r1=1.12&r2=1.13
http://cvs.savannah.gnu.org/viewcvs/TooN/test/test2.cc?cvsroot=toon&r1=1.3&r2=1.4

Patches:
Index: internal/operators.hh
===================================================================
RCS file: /cvsroot/toon/TooN/internal/operators.hh,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -b -r1.5 -r1.6
--- internal/operators.hh       17 Feb 2009 17:11:07 -0000      1.5
+++ internal/operators.hh       18 Feb 2009 14:27:57 -0000      1.6
@@ -1,4 +1,11 @@
 //-*- c++ -*-
+// Operations:
+//  vector+vector
+//  vector-vector
+//  vector dot evctor
+//  vector * constant
+//  vector / constant
+//  vector +
 
 
//////////////////////////////////////////////////////////////////////////////////////////////
 //                                       Operators
@@ -8,56 +15,129 @@
 
 namespace Internal{
 
-       template<typename Precision> struct Add
+       //Operator classes. These are evaluated in the constructor
+       //of Vector = Vector+Vector, so make use of return value optimization.
+       template<typename Precision, typename Op> struct Pairwise
        {
                template<int S, typename B, int S1, typename P1, typename B1, 
int S2, typename P2, typename B2> 
                static void eval(Vector<S, Precision, B>& res, const Vector<S1, 
P1, B1>& v1, const Vector<S2, P2, B2>& v2)
                {
-                       SizeMismatch<S1, S2>:: test(v1.size(),v2.size());
                        for(int i=0; i < res.size(); ++i)
-                               res[i] = v1[i] + v2[i];
+                               res[i] = Op::template op<Precision,P1, 
P2>(v1[i],v2[i]);
                }
+       };
 
-               template<int S1, typename P1, typename B1, int S2, typename P2, 
typename B2> 
-               static int size(const Vector<S1, P1, B1>& v1, const Vector<S2, 
P2, B2>& v2)
+       template<typename Precision, typename Op> struct ApplyScalar 
                {
-                       SizeMismatch<S1, S2>:: test(v1.size(),v2.size());
-                       return v1.size();
+               template<int S, typename B, int S1, typename P1, typename B1, 
typename P2>
+               static void eval(Vector<S, Precision, B>& res, const Vector<S1, 
P1, B1>& v, const P2& s)
+               {
+                       for(int i=0; i < res.size(); ++i)
+                               res[i] = Op::template op<Precision,P1, 
P2>(v[i],s);
                }
        };
 
-       template<class L, class R> struct AddType
+       template<typename Precision, typename Op> struct ApplyScalarLeft
+       {
+               template<int S, typename B, int S2, typename P1, typename P2, 
typename B2>
+               static void eval(Vector<S, Precision, B>& res, const P1& s, 
const Vector<S2, P2, B2>& v)
        {
-               typedef TOON_TYPEOF((L()+R())) type;
+                       for(int i=0; i < res.size(); ++i)
+                               res[i] = Op::template op<Precision,P1, P2>(s, 
v[i]);
+               }
        };
 
+       //Mini operators for passing to Pairwise, etc
+       struct Add{ template<class A, class B, class C>      static A op(const 
B& b, const C& c){return b+c;} };
+       struct Subtract{ template<class A, class B, class C> static A op(const 
B& b, const C& c){return b-c;} };
+       struct Multiply{ template<class A, class B, class C> static A op(const 
B& b, const C& c){return b*c;} };
+       struct Divide{ template<class A, class B, class C>   static A op(const 
B& b, const C& c){return b/c;} };
+       
+       //Automatic type deduction of return types
+       template<class L, class R> struct AddType {      typedef 
TOON_TYPEOF((L()+R())) type; };
+       template<class L, class R> struct SubtractType { typedef 
TOON_TYPEOF((L()-R())) type; };
+       template<class L, class R> struct MultiplyType { typedef 
TOON_TYPEOF((L()*R())) type; };
+       template<class L, class R> struct DivideType {   typedef 
TOON_TYPEOF((L()*R())) type; };
+       
+       //Output size, given input size. Be static if possible.
+       template<int i, int j> struct Sizer{static const int size=i;};
+       template<int i> struct Sizer<-1, i>{static const int size=i;};
+       template<int i> struct Sizer<i, -1>{static const int size=i;};
+       template<> struct Sizer<-1, -1>    {static const int size=-1;};
 }
 
-
+////////////////////////////////////////////////////////////////////////////////
+//
+// vector <op> vector
+//
 
 // Addition Vector + Vector
-template<int Size, typename P1, typename P2, typename B1, typename B2> 
-Vector<Size, typename Internal::AddType<P1, P2>::type> operator+(const 
Vector<Size, P1, B1>& v1, const Vector<Size, P2, B2>& v2)
+template<int S1, int S2, typename P1, typename P2, typename B1, typename B2> 
+Vector<Internal::Sizer<S1,S2>::size, typename Internal::AddType<P1, P2>::type> 
operator+(const Vector<S1, P1, B1>& v1, const Vector<S2, P2, B2>& v2)
 {
        typedef typename Internal::AddType<P1, P2>::type restype;
-       return Vector<Size,restype>(v1, v2, Operator<Internal::Add<restype> 
>());
+       SizeMismatch<S1, S2>:: test(v1.size(),v2.size());
+       return Vector<Internal::Sizer<S1,S2>::size,restype>(v1, v2, 
Operator<Internal::Pairwise<restype, Internal::Add> >(), v1.size());
 }
 
+// Addition Vector - Vector
+template<int S1, int S2, typename P1, typename P2, typename B1, typename B2> 
+Vector<Internal::Sizer<S1,S2>::size, typename Internal::SubtractType<P1, 
P2>::type> operator-(const Vector<S1, P1, B1>& v1, const Vector<S2, P2, B2>& v2)
+{
+       typedef typename Internal::SubtractType<P1, P2>::type restype;
+       SizeMismatch<S1, S2>:: test(v1.size(),v2.size());
+       return Vector<Internal::Sizer<S1,S2>::size,restype>(v1, v2, 
Operator<Internal::Pairwise<restype, Internal::Subtract> >(), v1.size());
+}
 
 // Dot product Vector * Vector
-template<int Size1, typename Precision1, typename Base1,
-        int Size2, typename Precision2, typename Base2>
-double operator*(const Vector<Size1, Precision1, Base1>& v1,
-                const Vector<Size2, Precision2, Base2>& v2){
+template<int Size1, typename Precision1, typename Base1, int Size2, typename 
Precision2, typename Base2>
+typename Internal::MultiplyType<Precision1, Precision2>::type operator*(const 
Vector<Size1, Precision1, Base1>& v1, const Vector<Size2, Precision2, Base2>& 
v2){
   SizeMismatch<Size1, Size2>:: test(v1.size(),v2.size());
   const int s=v1.size();
-  double result=0;
+  typename Internal::MultiplyType<Precision1, Precision2>::type result=0;
   for(int i=0; i<s; i++){
     result+=v1[i]*v2[i];
   }
   return result;
 }
 
+
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// vector <op> scalar
+//
+
+#define TOON_MAKE_SCALAR_OP_PAIR(OPNAME, OP) \
+template<int S, typename P1, typename B1, typename P2> \
+Vector<S, typename Internal::OPNAME##Type<P1, P2>::type> operator OP (const 
Vector<S, P1, B1>& v, const P2& s)\
+{      \
+       typedef typename Internal::OPNAME##Type<P1, P2>::type restype;\
+       return Vector<S,restype>(v, s, Operator<Internal::ApplyScalar<restype, 
Internal::OPNAME> >(), v.size());\
+}\
+\
+template<int S, typename P1, typename P2, typename B2> \
+Vector<S, typename Internal::OPNAME##Type<P1, P2>::type> operator OP (const 
P1& s, const Vector<S, P2, B2>& v)\
+{      \
+       typedef typename Internal::OPNAME##Type<P1, P2>::type restype;\
+       return Vector<S,restype>(s, v, 
Operator<Internal::ApplyScalarLeft<restype, Internal::OPNAME> >(), v.size());\
+}
+
+TOON_MAKE_SCALAR_OP_PAIR(Add, +)
+TOON_MAKE_SCALAR_OP_PAIR(Add, -)
+TOON_MAKE_SCALAR_OP_PAIR(Add, *)
+TOON_MAKE_SCALAR_OP_PAIR(Add, /)
+
+#undef TOON_MAKE_SCALAR_OP_PAIR
+
+
+
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// Stream I/O operators
+//
+
 // output operator <<
 template <int Size, typename Precision, typename Base>
 inline std::ostream& operator<< (std::ostream& os, const 
Vector<Size,Precision,Base>& v){

Index: internal/vector.hh
===================================================================
RCS file: /cvsroot/toon/TooN/internal/vector.hh,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -b -r1.12 -r1.13
--- internal/vector.hh  17 Feb 2009 13:53:07 -0000      1.12
+++ internal/vector.hh  18 Feb 2009 14:27:57 -0000      1.13
@@ -15,14 +15,14 @@
   // constructors to allow return value optimisations
   // construction from 1-ary operator
   template <class T, class Op>
-  inline Vector(const T& arg, const Operator<Op>&) : Base(Op::size(arg)) {
+  inline Vector(const T& arg, const Operator<Op>&, int size) : Base(size) {
     Op::eval(*this,arg);
   }
 
   // constructor from 2-ary operator
   template <class LHS, class RHS, class Op>
-  inline Vector(const LHS& lhs, const RHS& rhs, const Operator<Op>&)
-    : Base(Op::size(lhs, rhs)) {
+  inline Vector(const LHS& lhs, const RHS& rhs, const Operator<Op>&, int size)
+    : Base(size) {
     Op::eval(*this,lhs,rhs);
   }
 
@@ -61,6 +61,19 @@
   }
 
 
+  Vector& operator+=(const Precision& rhs) {
+    for(int i=0; i<Base::size(); i++)
+      (*this)[i]+=rhs;
+       return *this;
+  }
+
+
+  Vector& operator-=(const Precision& rhs) {
+    for(int i=0; i<Base::size(); i++)
+      (*this)[i]-=rhs;
+       return *this;
+  }
+
   Vector& operator/=(const Precision& rhs) {
     for(int i=0; i<Base::size(); i++)
       (*this)[i]/=rhs;

Index: test/test2.cc
===================================================================
RCS file: /cvsroot/toon/TooN/test/test2.cc,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -b -r1.3 -r1.4
--- test/test2.cc       17 Feb 2009 17:11:08 -0000      1.3
+++ test/test2.cc       18 Feb 2009 14:27:58 -0000      1.4
@@ -13,7 +13,7 @@
        Vector<4> v1 = makeVector(1, 2, 3, 4);
        Vector<4> v2 = makeVector(5, 6, 7, 8);
 
-       cout << v1 + v2 << endl;
+       cout << 1+(v1 + v2)+2 << endl;
 
        v1.slice<0, 2>() /= 2;
        cout << v1 << endl;




reply via email to

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