[Top][All Lists]
[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;