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