00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 namespace TooN {
00032
00034
00036
00037 namespace Internal {
00038
00039
00040 template<class C> C gettype();
00041
00042 template<class L, class R> struct Field
00043 {
00044 static const int is = IsField<L>::value && IsField<R>::value;
00045 };
00046
00047
00048
00049
00050
00051
00052 template<class L, class R, int F = Field<L,R>::is> struct AddType { typedef TOON_TYPEOF(gettype<L>()+gettype<R>()) type;};
00053 template<class L, class R, int F = Field<L,R>::is> struct SubtractType { typedef TOON_TYPEOF(gettype<L>()-gettype<R>()) type;};
00054 template<class L, class R, int F = Field<L,R>::is> struct MultiplyType { typedef TOON_TYPEOF(gettype<L>()*gettype<R>()) type;};
00055 template<class L, class R, int F = Field<L,R>::is> struct DivideType { typedef TOON_TYPEOF(gettype<L>()/gettype<R>()) type;};
00056
00057 template<class L, class R> struct AddType<L, R, 0> { typedef void type;};
00058 template<class L, class R> struct SubtractType<L, R, 0> { typedef void type;};
00059 template<class L, class R> struct MultiplyType<L, R, 0> { typedef void type;};
00060 template<class L, class R> struct DivideType<L, R, 0> { typedef void type;};
00061
00062
00063
00064 struct Add{
00065 template<class A, class B, class C> static A op(const B& b, const C& c){return b+c;}
00066 template<class P1, class P2> struct Return { typedef typename AddType<P1,P2>::type Type;};
00067 };
00068 struct Subtract{
00069 template<class A, class B, class C> static A op(const B& b, const C& c){return b-c;}
00070 template<class P1, class P2> struct Return { typedef typename SubtractType<P1,P2>::type Type;};
00071 };
00072 struct Multiply{
00073 template<class A, class B, class C> static A op(const B& b, const C& c){return b*c;}
00074 template<class P1, class P2> struct Return { typedef typename MultiplyType<P1,P2>::type Type;};
00075 };
00076 struct Divide{
00077 template<class A, class B, class C> static A op(const B& b, const C& c){return b/c;}
00078 template<class P1, class P2> struct Return { typedef typename DivideType<P1,P2>::type Type;};
00079 };
00080
00081
00082
00083 template<int i, int j> struct Sizer{static const int size=i;};
00084 template<int i> struct Sizer<-1, i>{static const int size=i;};
00085 template<int i> struct Sizer<i, -1>{static const int size=i;};
00086 template<> struct Sizer<-1, -1> {static const int size=-1;};
00087 };
00088
00090
00092
00093 template<class Op> struct Operator{};
00094
00095
00097
00099
00100 namespace Internal {
00101 template<typename Op,
00102 int S1, typename P1, typename B1,
00103 int S2, typename P2, typename B2>
00104 struct VPairwise;
00105
00106 template <int S, typename P, typename A>
00107 struct VNegate;
00108 };
00109
00110 template<typename Op,
00111 int S1, typename P1, typename B1,
00112 int S2, typename P2, typename B2>
00113 struct Operator<Internal::VPairwise<Op, S1, P1, B1, S2, P2, B2> > {
00114 const Vector<S1, P1, B1> & lhs;
00115 const Vector<S2, P2, B2> & rhs;
00116
00117 Operator(const Vector<S1, P1, B1> & lhs_in, const Vector<S2, P2, B2> & rhs_in) : lhs(lhs_in), rhs(rhs_in) {}
00118
00119 template<int S0, typename P0, typename B0>
00120 void eval(Vector<S0, P0, B0>& res) const
00121 {
00122 for(int i=0; i < res.size(); ++i)
00123 res[i] = Op::template op<P0,P1, P2>(lhs[i],rhs[i]);
00124 }
00125 int size() const {return lhs.size();}
00126 };
00127
00128
00129 template<int S1, int S2, typename P1, typename P2, typename B1, typename B2>
00130 Vector<Internal::Sizer<S1,S2>::size, typename Internal::AddType<P1, P2>::type>
00131 operator+(const Vector<S1, P1, B1>& v1, const Vector<S2, P2, B2>& v2)
00132 {
00133 SizeMismatch<S1, S2>:: test(v1.size(),v2.size());
00134 return Operator<Internal::VPairwise<Internal::Add,S1,P1,B1,S2,P2,B2> >(v1,v2);
00135 }
00136
00137
00138 template<int S1, int S2, typename P1, typename P2, typename B1, typename B2>
00139 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)
00140 {
00141 SizeMismatch<S1, S2>:: test(v1.size(),v2.size());
00142 return Operator<Internal::VPairwise<Internal::Subtract,S1,P1,B1,S2,P2,B2> >(v1,v2);
00143 }
00144
00145
00146 template <int S1, int S2, typename P1, typename P2, typename B1, typename B2>
00147 Vector<Internal::Sizer<S1,S2>::size, typename Internal::MultiplyType<P1,P2>::type> diagmult(const Vector<S1,P1,B1>& v1, const Vector<S2,P2,B2>& v2)
00148 {
00149 SizeMismatch<S1,S2>::test(v1.size(),v2.size());
00150 return Operator<Internal::VPairwise<Internal::Multiply,S1,P1,B1,S2,P2,B2> >(v1,v2);
00151 }
00152
00153 template<int S, typename P, typename A>
00154 struct Operator<Internal::VNegate<S, P, A> > {
00155 const Vector<S, P, A> & input;
00156 Operator( const Vector<S, P, A> & in ) : input(in) {}
00157
00158 template<int S0, typename P0, typename A0>
00159 void eval(Vector<S0, P0, A0> & res) const
00160 {
00161 res = input * -1;
00162 }
00163 int size() const { return input.size(); }
00164 };
00165
00166
00167 template <int S, typename P, typename A>
00168 Vector<S, P> operator-(const Vector<S,P,A> & v){
00169 return Operator<Internal::VNegate<S,P,A> >(v);
00170 }
00171
00172
00173 template<int Size1, typename Precision1, typename Base1, int Size2, typename Precision2, typename Base2>
00174 typename Internal::MultiplyType<Precision1, Precision2>::type operator*(const Vector<Size1, Precision1, Base1>& v1, const Vector<Size2, Precision2, Base2>& v2){
00175 SizeMismatch<Size1, Size2>:: test(v1.size(),v2.size());
00176 const int s=v1.size();
00177 typename Internal::MultiplyType<Precision1, Precision2>::type result=0;
00178 for(int i=0; i<s; i++){
00179 result+=v1[i]*v2[i];
00180 }
00181 return result;
00182 }
00183
00184 template <typename P1, typename P2, typename B1, typename B2>
00185 Vector<3, typename Internal::MultiplyType<P1,P2>::type> operator^(const Vector<3,P1,B1>& v1, const Vector<3,P2,B2>& v2){
00186
00187 typedef typename Internal::MultiplyType<P1,P2>::type restype;
00188
00189 Vector<3, restype> result;
00190
00191 result[0] = v1[1]*v2[2] - v1[2]*v2[1];
00192 result[1] = v1[2]*v2[0] - v1[0]*v2[2];
00193 result[2] = v1[0]*v2[1] - v1[1]*v2[0];
00194
00195 return result;
00196 }
00197
00198
00199
00200
00202
00204
00205 namespace Internal {
00206 template<typename Op,
00207 int R1, int C1, typename P1, typename B1,
00208 int R2, int C2, typename P2, typename B2>
00209 struct MPairwise;
00210
00211 template<int R1, int C1, typename P1, typename B1,
00212 int R2, int C2, typename P2, typename B2>
00213 struct MatrixMultiply;
00214
00215 template<int R, int C, typename P, typename A>
00216 struct MNegate;
00217 };
00218
00219 template<typename Op,
00220 int R1, int C1, typename P1, typename B1,
00221 int R2, int C2, typename P2, typename B2>
00222 struct Operator<Internal::MPairwise<Op, R1, C1, P1, B1, R2, C2, P2, B2> > {
00223 const Matrix<R1, C1, P1, B1> & lhs;
00224 const Matrix<R2, C2, P2, B2> & rhs;
00225
00226 Operator(const Matrix<R1, C1, P1, B1> & lhs_in, const Matrix<R2, C2, P2, B2> & rhs_in) : lhs(lhs_in), rhs(rhs_in) {}
00227
00228 template<int R0, int C0, typename P0, typename B0>
00229 void eval(Matrix<R0, C0, P0, B0>& res) const
00230 {
00231 for(int r=0; r < res.num_rows(); ++r){
00232 for(int c=0; c < res.num_cols(); ++c){
00233 res(r,c) = Op::template op<P0,P1, P2>(lhs(r,c),rhs(r,c));
00234 }
00235 }
00236 }
00237 int num_rows() const {return lhs.num_rows();}
00238 int num_cols() const {return lhs.num_cols();}
00239 };
00240
00241
00242 template<int R1, int R2, int C1, int C2, typename P1, typename P2, typename B1, typename B2>
00243 Matrix<Internal::Sizer<R1,R2>::size, Internal::Sizer<C1,C2>::size, typename Internal::AddType<P1, P2>::type>
00244 operator+(const Matrix<R1, C1, P1, B1>& m1, const Matrix<R2, C2, P2, B2>& m2)
00245 {
00246 SizeMismatch<R1, R2>:: test(m1.num_rows(),m2.num_rows());
00247 SizeMismatch<C1, C2>:: test(m1.num_cols(),m2.num_cols());
00248 return Operator<Internal::MPairwise<Internal::Add,R1,C1,P1,B1,R2,C2,P2,B2> >(m1,m2);
00249 }
00250
00251
00252 template<int R1, int R2, int C1, int C2, typename P1, typename P2, typename B1, typename B2>
00253 Matrix<Internal::Sizer<R1,R2>::size, Internal::Sizer<C1,C2>::size, typename Internal::SubtractType<P1, P2>::type>
00254 operator-(const Matrix<R1, C1, P1, B1>& m1, const Matrix<R2, C2, P2, B2>& m2)
00255 {
00256 SizeMismatch<R1, R2>:: test(m1.num_rows(),m2.num_rows());
00257 SizeMismatch<C1, C2>:: test(m1.num_cols(),m2.num_cols());
00258 return Operator<Internal::MPairwise<Internal::Subtract,R1,C1,P1,B1,R2,C2,P2,B2> >(m1,m2);
00259 }
00260
00261 template<int R, int C, typename P, typename A>
00262 struct Operator<Internal::MNegate<R,C, P, A> > {
00263 const Matrix<R,C,P,A> & input;
00264 Operator( const Matrix<R,C,P,A> & in ) : input(in) {}
00265
00266 template<int R0, int C0, typename P0, typename A0>
00267 void eval(Matrix<R0,C0,P0,A0> & res) const
00268 {
00269 res = input * -1;
00270 }
00271 int num_rows() const { return input.num_rows(); }
00272 int num_cols() const { return input.num_cols(); }
00273 };
00274
00275
00276 template <int R, int C, typename P, typename A>
00277 Matrix<R, C, P> operator-(const Matrix<R,C,P,A> & v){
00278 return Operator<Internal::MNegate<R,C,P,A> >(v);
00279 }
00280
00281 template<int R1, int C1, typename P1, typename B1,
00282 int R2, int C2, typename P2, typename B2>
00283 struct Operator<Internal::MatrixMultiply<R1, C1, P1, B1, R2, C2, P2, B2> > {
00284 const Matrix<R1, C1, P1, B1> & lhs;
00285 const Matrix<R2, C2, P2, B2> & rhs;
00286
00287 Operator(const Matrix<R1, C1, P1, B1> & lhs_in, const Matrix<R2, C2, P2, B2> & rhs_in) : lhs(lhs_in), rhs(rhs_in) {}
00288
00289 template<int R0, int C0, typename P0, typename B0>
00290 void eval(Matrix<R0, C0, P0, B0>& res) const
00291 {
00292
00293 for(int r=0; r < res.num_rows(); ++r) {
00294 for(int c=0; c < res.num_cols(); ++c) {
00295 res(r,c) = lhs[r] * (rhs.T()[c]);
00296 }
00297 }
00298 }
00299 int num_rows() const {return lhs.num_rows();}
00300 int num_cols() const {return rhs.num_cols();}
00301 };
00302
00303
00304
00305
00306
00307
00308 template<int R1, int C1, int R2, int C2, typename P1, typename P2, typename B1, typename B2>
00309 Matrix<R1, C2, typename Internal::MultiplyType<P1, P2>::type> operator*(const Matrix<R1, C1, P1, B1>& m1, const Matrix<R2, C2, P2, B2>& m2)
00310 {
00311 SizeMismatch<C1, R2>:: test(m1.num_cols(),m2.num_rows());
00312 return Operator<Internal::MatrixMultiply<R1,C1,P1,B1,R2,C2,P2,B2> >(m1,m2);
00313 }
00314
00316
00318
00319
00320 namespace Internal {
00321
00322 template<int R, int C, typename P1, typename B1, int Size, typename P2, typename B2>
00323 struct MatrixVectorMultiply;
00324
00325
00326 template<int Size, typename P1, typename B1, int R, int C, typename P2, typename B2>
00327 struct VectorMatrixMultiply;
00328
00329
00330 template<int R, int C, typename P1, typename B1, int Size, typename P2, typename B2>
00331 struct MatrixVectorDiagMultiply;
00332
00333
00334 template<int Size, typename P1, typename B1, int R, int C, typename P2, typename B2>
00335 struct VectorMatrixDiagMultiply;
00336
00337 };
00338
00339
00340 template<int R, int C, typename P1, typename B1, int Size, typename P2, typename B2>
00341 struct Operator<Internal::MatrixVectorMultiply<R,C,P1,B1,Size,P2,B2> > {
00342 const Matrix<R,C,P1,B1>& lhs;
00343 const Vector<Size,P2,B2>& rhs;
00344
00345 Operator(const Matrix<R,C,P1,B1>& lhs_in, const Vector<Size,P2,B2>& rhs_in) : lhs(lhs_in), rhs(rhs_in) {}
00346
00347 int size() const {return lhs.num_rows();}
00348
00349 template<int Sout, typename Pout, typename Bout>
00350 void eval(Vector<Sout, Pout, Bout>& res) const {
00351 for(int i=0; i < res.size(); ++i){
00352 res[i] = lhs[i] * rhs;
00353 }
00354 }
00355 };
00356
00357 template<int R, int C, int Size, typename P1, typename P2, typename B1, typename B2>
00358 Vector<R, typename Internal::MultiplyType<P1,P2>::type> operator*(const Matrix<R, C, P1, B1>& m, const Vector<Size, P2, B2>& v)
00359 {
00360 SizeMismatch<C,Size>::test(m.num_cols(), v.size());
00361 return Operator<Internal::MatrixVectorMultiply<R,C,P1,B1,Size,P2,B2> >(m,v);
00362 }
00363
00364
00365 template<int R, int C, typename P1, typename B1, int Size, typename P2, typename B2>
00366 struct Operator<Internal::VectorMatrixMultiply<Size,P1,B1,R,C,P2,B2> > {
00367 const Vector<Size,P1,B1>& lhs;
00368 const Matrix<R,C,P2,B2>& rhs;
00369
00370 Operator(const Vector<Size,P1,B1>& lhs_in, const Matrix<R,C,P2,B2>& rhs_in) : lhs(lhs_in), rhs(rhs_in) {}
00371
00372 int size() const {return rhs.num_cols();}
00373
00374 template<int Sout, typename Pout, typename Bout>
00375 void eval(Vector<Sout, Pout, Bout>& res) const {
00376 for(int i=0; i < res.size(); ++i){
00377 res[i] = lhs * rhs.T()[i];
00378 }
00379 }
00380 };
00381
00382 template<int R, int C, typename P1, typename B1, int Size, typename P2, typename B2>
00383 Vector<R, typename Internal::MultiplyType<P1,P2>::type> operator*(const Vector<Size,P1,B1>& v,
00384 const Matrix<R,C,P2,B2>& m)
00385 {
00386 SizeMismatch<C,Size>::test(m.num_rows(), v.size());
00387 return Operator<Internal::VectorMatrixMultiply<Size,P1,B1,R,C,P2,B2> >(v,m);
00388 }
00389
00390
00391
00392 template<int R, int C, typename P1, typename B1, int Size, typename P2, typename B2>
00393 struct Operator<Internal::MatrixVectorDiagMultiply<R,C,P1,B1,Size,P2,B2> > {
00394 const Matrix<R,C,P1,B1>& lhs;
00395 const Vector<Size,P2,B2>& rhs;
00396
00397 Operator(const Matrix<R,C,P1,B1>& lhs_in, const Vector<Size,P2,B2>& rhs_in) : lhs(lhs_in), rhs(rhs_in) {}
00398
00399 int num_rows() const {return lhs.num_rows();}
00400 int num_cols() const {return lhs.num_cols();}
00401
00402 template<int Rout, int Cout, typename Pout, typename Bout>
00403 void eval(Matrix<Rout, Cout, Pout, Bout>& res) const {
00404 for(int c=0; c < res.num_cols(); ++c) {
00405 P2 temp = rhs[c];
00406 for(int r=0; r < res.num_rows(); ++r) {
00407 res(r,c) = lhs(r,c)*temp;
00408 }
00409 }
00410 }
00411 };
00412
00413 template<int R, int C, int Size, typename P1, typename P2, typename B1, typename B2>
00414 Matrix<R, C, typename Internal::MultiplyType<P1,P2>::type> diagmult(const Matrix<R, C, P1, B1>& m, const Vector<Size, P2, B2>& v)
00415 {
00416 SizeMismatch<C,Size>::test(m.num_cols(), v.size());
00417 return Operator<Internal::MatrixVectorDiagMultiply<R,C,P1,B1,Size,P2,B2> >(m,v);
00418 }
00419
00420
00421 template<int R, int C, typename P1, typename B1, int Size, typename P2, typename B2>
00422 struct Operator<Internal::VectorMatrixDiagMultiply<Size,P1,B1,R,C,P2,B2> > {
00423 const Vector<Size,P1,B1>& lhs;
00424 const Matrix<R,C,P2,B2>& rhs;
00425
00426 Operator(const Vector<Size,P1,B1>& lhs_in, const Matrix<R,C,P2,B2>& rhs_in) : lhs(lhs_in), rhs(rhs_in) {}
00427
00428 int num_rows() const {return rhs.num_rows();}
00429 int num_cols() const {return rhs.num_cols();}
00430
00431 template<int Rout, int Cout, typename Pout, typename Bout>
00432 void eval(Matrix<Rout, Cout, Pout, Bout>& res) const {
00433 for(int r=0; r < res.num_rows(); ++r){
00434 const P1 temp = lhs[r];
00435 for(int c=0; c<res.num_cols(); ++c){
00436 res(r,c) = temp * rhs(r,c);
00437 }
00438 }
00439 }
00440 };
00441
00442 template<int R, int C, typename P1, typename B1, int Size, typename P2, typename B2>
00443 Matrix<R, C, typename Internal::MultiplyType<P1,P2>::type> diagmult(const Vector<Size,P1,B1>& v,
00444 const Matrix<R,C,P2,B2>& m)
00445 {
00446 SizeMismatch<R,Size>::test(m.num_rows(), v.size());
00447 return Operator<Internal::VectorMatrixDiagMultiply<Size,P1,B1,R,C,P2,B2> >(v,m);
00448 }
00449
00450
00452
00453
00454
00455
00456
00457
00458
00459
00460 namespace Internal {
00461 template<int Size, typename P1, typename B1, typename P2, typename Op>
00462 struct ApplyScalarV;
00463
00464 template<int Size, typename P1, typename B1, typename P2, typename Op>
00465 struct ApplyScalarVL;
00466
00467 template<int R, int C, typename P1, typename B1, typename P2, typename Op>
00468 struct ApplyScalarM;
00469
00470 template<int R, int C, typename P1, typename B1, typename P2, typename Op>
00471 struct ApplyScalarML;
00472 };
00473
00474 template<int Size, typename P1, typename B1, typename P2, typename Op>
00475 struct Operator<Internal::ApplyScalarV<Size,P1,B1,P2,Op> > {
00476 const Vector<Size,P1,B1>& lhs;
00477 const P2& rhs;
00478
00479 Operator(const Vector<Size,P1,B1>& v, const P2& s) : lhs(v), rhs(s) {}
00480
00481 template<int S0, typename P0, typename B0>
00482 void eval(Vector<S0,P0,B0>& v) const {
00483 for(int i=0; i<v.size(); i++){
00484 v[i]= Op::template op<P0,P1,P2> (lhs[i],rhs);
00485 }
00486 }
00487
00488 int size() const {
00489 return lhs.size();
00490 }
00491 };
00492
00493 template <int Size, typename P1, typename B1, typename P2>
00494 Vector<Size, typename Internal::Multiply::Return<P1,P2>::Type> operator*(const Vector<Size, P1, B1>& v, const P2& s){
00495 return Operator<Internal::ApplyScalarV<Size,P1,B1,P2,Internal::Multiply> > (v,s);
00496 }
00497 template <int Size, typename P1, typename B1, typename P2>
00498 Vector<Size, typename Internal::Divide::Return<P1,P2>::Type> operator/(const Vector<Size, P1, B1>& v, const P2& s){
00499 return Operator<Internal::ApplyScalarV<Size,P1,B1,P2,Internal::Divide> > (v,s);
00500 }
00501
00502 template<int Size, typename P1, typename B1, typename P2, typename Op>
00503 struct Operator<Internal::ApplyScalarVL<Size,P1,B1,P2,Op> > {
00504 const P2& lhs;
00505 const Vector<Size,P1,B1>& rhs;
00506
00507 Operator(const P2& s, const Vector<Size,P1,B1>& v) : lhs(s), rhs(v) {}
00508
00509 template<int S0, typename P0, typename B0>
00510 void eval(Vector<S0,P0,B0>& v) const {
00511 for(int i=0; i<v.size(); i++){
00512 v[i]= Op::template op<P0,P2,P1> (lhs,rhs[i]);
00513 }
00514 }
00515
00516 int size() const {
00517 return rhs.size();
00518 }
00519 };
00520 template <int Size, typename P1, typename B1, typename P2>
00521 Vector<Size, typename Internal::Multiply::Return<P2,P1>::Type> operator*(const P2& s, const Vector<Size, P1, B1>& v){
00522 return Operator<Internal::ApplyScalarVL<Size,P1,B1,P2,Internal::Multiply> > (s,v);
00523 }
00524
00525
00526
00528
00529 template<int R, int C, typename P1, typename B1, typename P2, typename Op>
00530 struct Operator<Internal::ApplyScalarM<R,C,P1,B1,P2,Op> > {
00531 const Matrix<R,C,P1,B1>& lhs;
00532 const P2& rhs;
00533
00534 Operator(const Matrix<R,C,P1,B1>& m, const P2& s) : lhs(m), rhs(s) {}
00535
00536 template<int R0, int C0, typename P0, typename B0>
00537 void eval(Matrix<R0,C0,P0,B0>& m) const {
00538 for(int r=0; r<m.num_rows(); r++){
00539 for(int c=0; c<m.num_cols(); c++){
00540 m(r,c)= Op::template op<P0,P1,P2> (lhs(r,c),rhs);
00541 }
00542 }
00543 }
00544
00545 int num_rows() const {
00546 return lhs.num_rows();
00547 }
00548 int num_cols() const {
00549 return lhs.num_cols();
00550 }
00551 };
00552
00553 template <int R, int C, typename P1, typename B1, typename P2>
00554 Matrix<R,C, typename Internal::Multiply::Return<P1,P2>::Type> operator*(const Matrix<R,C, P1, B1>& m, const P2& s){
00555 return Operator<Internal::ApplyScalarM<R,C,P1,B1,P2,Internal::Multiply> > (m,s);
00556 }
00557 template <int R, int C, typename P1, typename B1, typename P2>
00558 Matrix<R,C, typename Internal::Divide::Return<P1,P2>::Type> operator/(const Matrix<R,C, P1, B1>& m, const P2& s){
00559 return Operator<Internal::ApplyScalarM<R,C,P1,B1,P2,Internal::Divide> > (m,s);
00560 }
00561
00562 template<int R, int C, typename P1, typename B1, typename P2, typename Op>
00563 struct Operator<Internal::ApplyScalarML<R,C,P1,B1,P2,Op> > {
00564 const P2& lhs;
00565 const Matrix<R,C,P1,B1>& rhs;
00566
00567 Operator( const P2& s,const Matrix<R,C,P1,B1>& m) : lhs(s), rhs(m) {}
00568
00569 template<int R0, int C0, typename P0, typename B0>
00570 void eval(Matrix<R0,C0,P0,B0>& m) const {
00571 for(int r=0; r<m.num_rows(); r++){
00572 for(int c=0; c<m.num_cols(); c++){
00573 m(r,c)= Op::template op<P0,P1,P2> (lhs,rhs(r,c));
00574 }
00575 }
00576 }
00577
00578 int num_rows() const {
00579 return rhs.num_rows();
00580 }
00581 int num_cols() const {
00582 return rhs.num_cols();
00583 }
00584 };
00585
00586 template <int R, int C, typename P1, typename B1, typename P2>
00587 Matrix<R,C, typename Internal::Multiply::Return<P2,P1>::Type> operator*(const P2& s, const Matrix<R,C, P1, B1>& m){
00588 return Operator<Internal::ApplyScalarML<R,C,P1,B1,P2,Internal::Multiply> > (s,m);
00589 }
00590
00592
00593
00594
00595 template <int Size, typename P1, typename B1, typename Op>
00596 Vector<Size, typename Internal::Add::Return<P1,typename Operator<Op>::Precision>::Type> operator+(const Vector<Size, P1, B1>& v, const Operator<Op>& op){
00597 return op.add(v);
00598 }
00599
00600 template <int Size, typename P1, typename B1, typename Op>
00601 Vector<Size, typename Internal::Add::Return<typename Operator<Op>::Precision, P1>::Type> operator+(const Operator<Op>& op, const Vector<Size, P1, B1>& v){
00602 return op.add(v);
00603 }
00604
00605 template <int Rows, int Cols, typename P1, typename B1, typename Op>
00606 Matrix<Rows, Cols, typename Internal::Add::Return<P1,typename Operator<Op>::Precision>::Type> operator+(const Matrix<Rows, Cols, P1, B1>& m, const Operator<Op>& op){
00607 return op.add(m);
00608 }
00609
00610 template <int Rows, int Cols, typename P1, typename B1, typename Op>
00611 Matrix<Rows, Cols, typename Internal::Add::Return<typename Operator<Op>::Precision,P1>::Type> operator+(const Operator<Op>& op, const Matrix<Rows, Cols, P1, B1>& m){
00612 return op.add(m);
00613 }
00614
00615
00616
00617
00618 template <int Size, typename P1, typename B1, typename Op>
00619 Vector<Size, typename Internal::Subtract::Return<P1,typename Operator<Op>::Precision>::Type> operator-(const Vector<Size, P1, B1>& v, const Operator<Op>& op){
00620 return op.rsubtract(v);
00621 }
00622
00623 template <int Size, typename P1, typename B1, typename Op>
00624 Vector<Size, typename Internal::Subtract::Return<typename Operator<Op>::Precision, P1>::Type> operator-(const Operator<Op>& op, const Vector<Size, P1, B1>& v){
00625 return op.lsubtract(v);
00626 }
00627
00628 template <int Rows, int Cols, typename P1, typename B1, typename Op>
00629 Matrix<Rows, Cols, typename Internal::Subtract::Return<P1,typename Operator<Op>::Precision>::Type> operator-(const Matrix<Rows, Cols, P1, B1>& m, const Operator<Op>& op){
00630 return op.rsubtract(m);
00631 }
00632
00633 template <int Rows, int Cols, typename P1, typename B1, typename Op>
00634 Matrix<Rows, Cols, typename Internal::Subtract::Return<typename Operator<Op>::Precision,P1>::Type> operator-(const Operator<Op>& op, const Matrix<Rows, Cols, P1, B1>& m){
00635 return op.lsubtract(m);
00636 }
00638
00639
00640
00641
00642
00643 template <int Size, typename Precision, typename Base>
00644 inline std::ostream& operator<< (std::ostream& os, const Vector<Size,Precision,Base>& v){
00645 for(int i=0; i<v.size(); i++){
00646 os << v[i] << " ";
00647 }
00648 return os;
00649 }
00650
00651
00652 template <int Size, typename Precision, typename Base>
00653 std::istream& operator >> (std::istream& is, Vector<Size, Precision, Base>& v){
00654 for (int i=0; i<v.size(); i++){
00655 is >> v[i];
00656 }
00657 return is;
00658 }
00659
00660 template<int Rows, int Cols, typename Precision, class Base>
00661 inline std::ostream& operator<< (std::ostream& os, const Matrix<Rows, Cols, Precision, Base>& m){
00662 for(int i=0; i < m.num_rows(); i++)
00663 {
00664 for(int j=0; j < m.num_cols(); j++)
00665 {
00666 if(j != 0)
00667 os << " ";
00668 os << m(i,j);
00669 }
00670 os << std::endl;
00671 }
00672 return os;
00673 }
00674
00675
00676 template <int Rows, int Cols, typename Precision, typename Base>
00677 std::istream& operator >> (std::istream& is, Matrix<Rows, Cols, Precision, Base>& m){
00678 for(int r=0; r<m.num_rows(); r++){
00679 for(int c=0; c < m.num_cols(); c++){
00680 is >> m(r,c);
00681 }
00682 }
00683 return is;
00684 }
00685
00686 }