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