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 #ifndef MECHSYS_LINALG_LAEXPR_H
00027 #define MECHSYS_LINALG_LAEXPR_H
00028
00029 #include <iostream>
00030 #include <sstream>
00031 #include "linalg/matrix.h"
00032 #include "linalg/vector.h"
00033 #include "linalg/lawrap.h"
00034
00035 #include "tensors/tensors.h"
00036
00037 using namespace std;
00038
00039 namespace LinAlg
00040 {
00041
00042
00043
00044
00045 template <typename type>
00046 inline
00047 void _scale(size_t n,
00048 type a,
00049 type const * ptrX,
00050 type * ptrY)
00051 {
00052 size_t ll = n % 4;
00053 for (size_t i = 0; i<ll; ++i) ptrY[i] = a*ptrX[i];
00054 for (size_t i = ll; i<n; i += 4)
00055 {
00056 ptrY[i] = a*ptrX[i ];
00057 ptrY[i+1] = a*ptrX[i+1];
00058 ptrY[i+2] = a*ptrX[i+2];
00059 ptrY[i+3] = a*ptrX[i+3];
00060 }
00061 }
00062
00063
00064 template <typename type>
00065 inline
00066 void _scale(size_t n,
00067 type a,
00068 type const * ptrX,
00069 type b,
00070 type const * ptrW,
00071 type * ptrY)
00072 {
00073 size_t ll = n % 4;
00074 for (size_t i = 0; i<ll; ++i) ptrY[i] = a*ptrX[i] + b*ptrW[i];
00075 for (size_t i = ll; i<n; i += 4)
00076 {
00077 ptrY[i] = a*ptrX[i ] + b*ptrW[i ];
00078 ptrY[i+1] = a*ptrX[i+1] + b*ptrW[i+1];
00079 ptrY[i+2] = a*ptrX[i+2] + b*ptrW[i+2];
00080 ptrY[i+3] = a*ptrX[i+3] + b*ptrW[i+3];
00081 }
00082 }
00083
00084
00085
00086
00087
00088
00089 template <typename type>
00090 inline
00091 void scale(type a,
00092 Vector<type> const & X,
00093 Vector<type> & Y)
00094 {
00095 size_t n = X.Size();
00096 Y.Resize(n);
00097 type const * ptrX = X.GetPtr();
00098 type * ptrY = Y.GetPtr();
00099 _scale(n, a, ptrX, ptrY);
00100 }
00101
00102
00103 template <typename type>
00104 inline
00105 void scale(type a,
00106 Vector<type> const & X,
00107 type b,
00108 Vector<type> const & W,
00109 Vector<type> & Y)
00110 {
00111 int n = X.Size();
00112 assert(W.Size() == n);
00113 Y.Resize(n);
00114 type const * ptrX = X.GetPtr();
00115 type const * ptrW = W.GetPtr();
00116 type * ptrY = Y.GetPtr();
00117 _scale(n, a, ptrX, b, ptrW, ptrY);
00118 }
00119
00120
00121 template <typename type>
00122 inline
00123 void scale(type a,
00124 Matrix<type> const & X,
00125 Matrix<type> & Y)
00126 {
00127 size_t n = X.Rows()*X.Cols();
00128 Y.Resize(X.Rows(), X.Cols());
00129 type const * ptrX = X.GetPtr();
00130 type * ptrY = Y.GetPtr();
00131 _scale(n, a, ptrX, ptrY);
00132 }
00133
00134
00135 template <typename type>
00136 inline
00137 void scale(type a,
00138 Matrix<type> const & X,
00139 type b,
00140 Matrix<type> const & W,
00141 Matrix<type> & Y)
00142 {
00143 assert(X.Rows() == W.Rows() && X.Cols() == W.Cols());
00144 size_t n = X.Rows()*X.Cols();
00145 Y.Resize(X.Rows(), X.Cols());
00146 type const * ptrX = X.GetPtr();
00147 type const * ptrW = W.GetPtr();
00148 type * ptrY = Y.GetPtr();
00149 _scale(n, a, ptrX, b, ptrW, ptrY);
00150 }
00151
00152
00153
00154 template <typename type>
00155 inline
00156 void scalet(type a,
00157 Vector<type> const & A,
00158 Matrix<type> & B)
00159 {
00160 size_t n = A.Size();
00161 B.Resize(1, n);
00162 type const * ptrA = A.GetPtr();
00163 type * ptrB = B.GetPtr();
00164 _scale(n, a, ptrA, ptrB);
00165 }
00166
00167
00168 template <typename type>
00169 inline
00170 void scalet(type a,
00171 Matrix<type> const & A,
00172 Matrix<type> & B)
00173 {
00174 size_t m = A.Rows();
00175 size_t n = A.Cols();
00176 type const * ptrA;
00177 ptrA = A.GetPtr();
00178
00179 B.Resize(n, m);
00180 type * ptrB = B.GetPtr();
00181
00182 type rowA[n];
00183 for (size_t i=0; i<m; ++i)
00184 {
00185 for (size_t k = 0; k<n; k++)
00186 rowA[k] = ptrA[i + k*m];
00187 type * colB = &ptrB[i*n];
00188 _scale(n, a, rowA, colB);
00189 }
00190 }
00191
00192
00193 template <typename type>
00194 inline
00195 void scalei(type a,
00196 Matrix<type> const & A,
00197 Matrix<type> & B)
00198 {
00199 size_t m = A.Rows();
00200 size_t n = A.Cols();
00201 assert(m==n);
00202 type const * ptrA;
00203 ptrA = A.GetPtr();
00204 B.Resize(n, m);
00205
00206 Matrix<type> extended(n, n*2);
00207
00208
00209 for (size_t r = 0; r < n; r++)
00210 for (size_t c = 0; c < n; c++)
00211 {
00212 extended(r,c) = A(r,c);
00213 if (r == c) extended(r,c+n) = 1;
00214 else extended(r,c+n) = 0;
00215 }
00216
00217 for (size_t p = 0; p < n; p++)
00218 {
00219 for (size_t r = p + 1; r < n; r++)
00220 {
00221
00222 if (fabs(extended(p,p))<1.e-10)
00223 {
00224
00225 size_t rr;
00226 for (rr = p; rr < n; rr++) if (fabs(extended(rr,p)) >= 1.e-10) break;
00227 if (rr== n) { std::cout << "Matrix::Inv: Error calculating inverse matrix: singular matrix" << std::endl; throw ""; }
00228 for (size_t c = p; c < n*2; c++){
00229 type temp = extended(p,c);
00230 extended(p,c) = extended(rr,c);
00231 extended(rr,c) = temp;
00232 }
00233 }
00234 type coef = extended(r,p) / extended(p,p);
00235 for (size_t c = p; c < n*2; c++)
00236 extended(r,c) -= coef * extended(p,c);
00237 }
00238 }
00239
00240
00241 for (size_t p = n-1; p > 0; p--)
00242 {
00243 for (int r = p-1; r >= 0; r--)
00244 {
00245 if (extended(p,p) == 0) { std::cout << "Matrix::Inv: Error calculating inverse matrix: singular matrix" << std::endl; throw ""; }
00246 type coef = extended(r,p) / extended(p,p);
00247 for (size_t c = n*2-1; c >= p; c--)
00248 extended(r,c) -= coef * extended(p,c);
00249 }
00250 }
00251
00252
00253 for (size_t r = 0; r < n; r++)
00254 for (size_t c = 0; c < n; c++)
00255 B(r,c) = a*extended(r,c+ n) / extended(r,r);
00256 }
00257
00258
00259 template<typename type>
00260 inline
00261 type determinat(Matrix<type> const & A)
00262 {
00263 type R;
00264 size_t m = A.Rows();
00265 size_t n = A.Cols();
00266 if (m==1)
00267 {
00268 R = 0;
00269 for (size_t i=0; i<n; i++) R += pow(A(0,i),2);
00270 R = pow(R, 0.5);
00271 }
00272 else if (m==3 && n==3)
00273 {
00274 R = A(0,0)*(A(1,1)*A(2,2) - A(1,2)*A(2,1)) \
00275 - A(0,1)*(A(1,0)*A(2,2) - A(1,2)*A(2,0)) \
00276 + A(0,2)*(A(1,0)*A(2,1) - A(1,1)*A(2,0));
00277 }
00278 else if (m==2 && n==3)
00279 {
00280 type d1 = A(0,0)*A(1,1) - A(0,1)*A(1,0);
00281 type d2 = A(0,1)*A(1,2) - A(0,2)*A(1,1);
00282 type d3 = A(0,2)*A(1,0) - A(0,0)*A(1,2);
00283 R = sqrt(d1*d1 + d2*d2 + d3*d3);
00284 }
00285 else
00286 {
00287 std::cout << "Matrix::Det: Determinant for a (" << m << " x " << n << ") matrix is not available" << std::endl;
00288 throw "";
00289 }
00290 return R;
00291 }
00292
00293
00294
00295
00296
00297
00298
00299
00300 template <typename type>
00301 inline
00302 Vector<type> & _add(Vector<type> const & A, Vector<type> const & B, Vector<type> & R)
00303 {
00304 scale(static_cast<type>(1), A, static_cast<type>(1), B, R);
00305 return R;
00306 }
00307
00308
00309 template <typename type>
00310 inline
00311 Vector<type> & _minus(Vector<type> const & A, Vector<type> const & B, Vector<type> & R)
00312 {
00313 scale(static_cast<type>(1), A, static_cast<type>(-1), B, R);
00314 return R;
00315 }
00316
00317
00318 template <class type, class t_num1>
00319 inline
00320 Vector<type> & _prod(t_num1 const & a, Vector<type> const & A, Vector<type> & R)
00321 {
00322
00323 R.Resize(A.Size());
00324 _scale(A.Size(), static_cast<type>(a), A.GetPtr(), R.GetPtr());
00325 return R;
00326 }
00327
00328
00329 template <typename type>
00330 inline
00331 Matrix<type> & _trn(Vector<type> const & A, Matrix<type> & R)
00332 {
00333 scalet(static_cast<type>(1), A, R);
00334 return R;
00335 }
00336
00337
00338 template <typename type>
00339 inline
00340 Matrix<type> & _add(Matrix<type> const & A, Matrix<type> const & B, Matrix<type> & R)
00341 {
00342 scale(static_cast<type>(1), A, static_cast<type>(1), B, R);
00343 return R;
00344 }
00345
00346
00347 template <typename type>
00348 inline
00349 Matrix<type> & _minus(Matrix<type> const & A, Matrix<type> const & B, Matrix<type> & R)
00350 {
00351 scale(static_cast<type>(1), A, static_cast<type>(-1), B, R);
00352 return R;
00353 }
00354
00355
00356 template <class type>
00357 inline
00358 Vector<type> & _prod(Matrix<type> const & A, Vector<type> const & B, Vector<type> & R)
00359 {
00360 R.Resize(A.Rows());
00361 assert(A.Cols() == B.Size());
00362 Gemv(static_cast<type>(1), A, B, static_cast<type>(0), R);
00363 return R;
00364 }
00365
00366
00367 template <class type>
00368 inline
00369 Matrix<type> & _prod(Vector<type> const & A, Matrix<type> const & B, Matrix<type> & R)
00370 {
00371
00372 size_t m = A.Size();
00373 size_t n = B.Cols();
00374 assert(B.Rows() == 1);
00375 R.Resize(m, n);
00376 type const * ptrA = A.GetPtr();
00377 type const * ptrB = B.GetPtr();
00378 type * ptrR = R.GetPtr();
00379
00380 for (size_t i=0; i<m; i++)
00381 for (size_t j=0; j<n; j++)
00382 ptrR[i+j*m] = ptrA[i]*ptrB[j];
00383
00384 return R;
00385 }
00386
00387
00388 template <class type>
00389 inline
00390 Matrix<type> & _prod(Matrix<type> const & A, Matrix<type> const & B, Matrix<type> & R)
00391 {
00392 R.Resize(A.Rows(), B.Cols());
00393 Gemm(static_cast<type>(1), A, B, static_cast<type>(0), R);
00394 return R;
00395 }
00396
00397
00398 template <class type, class t_scalar>
00399 inline
00400 Matrix<type> & _prod(t_scalar const & A, Matrix<type> const & B, Matrix<type> & R)
00401 {
00402 scale(static_cast<type const &>(A), B, R);
00403 return R;
00404 }
00405
00406
00407 template <typename type>
00408 inline
00409 Matrix<type> & _trn(Matrix<type> const & A, Matrix<type> & R)
00410 {
00411 scalet(static_cast<type>(1), A, R);
00412 return R;
00413 }
00414
00415
00416 template <typename type>
00417 inline
00418 Matrix<type> & _inv(Matrix<type> const & A, Matrix<type> & R)
00419 {
00420 scalei(static_cast<type>(1), A, R);
00421 return R;
00422 }
00423
00424
00425 template <class type>
00426 inline
00427 Matrix<type> & _prodt(Matrix<type> const & A, Matrix<type> const & B, Matrix<type> & R)
00428 {
00429 R.Resize(A.Cols(), B.Cols());
00430 Gemtm(static_cast<type>(1), A, B, static_cast<type>(0), R);
00431 return R;
00432 }
00433
00434
00435 template <class type>
00436 inline
00437 Matrix<type> & _prod_t(Matrix<type> const & A, Matrix<type> const & B, Matrix<type> & R)
00438 {
00439 R.Resize(A.Rows(), B.Rows());
00440 Gemmt(static_cast<type>(1), A, B, static_cast<type>(0), R);
00441 return R;
00442 }
00443
00444
00445 template <class type>
00446 inline
00447 Matrix<type> & _prod_t(Vector<type> const & A, Vector<type> const & B, Matrix<type> & R)
00448 {
00449 size_t m = A.Size();
00450 size_t n = B.Size();
00451 R.Resize(m, n);
00452 type const * ptrA = A.GetPtr();
00453 type const * ptrB = B.GetPtr();
00454 type * ptrR = R.GetPtr();
00455 for (size_t i=0; i<m; ++i)
00456 for (size_t j=0; j<n; ++j)
00457 ptrR[i+j*m] = ptrA[i]*ptrB[j];
00458 return R;
00459 }
00460
00461
00462 template <class type>
00463 inline
00464 type & _prodt(Vector<type> const & A, Vector<type> const & B, type & R)
00465 {
00466 assert(A.Size() == B.Size());
00467 R = Dot(A, B);
00468 return R;
00469 }
00470
00471
00472 template <class type>
00473 inline
00474 Matrix<type> & _prodtt(Matrix<type> const & A, Matrix<type> const & B, Matrix<type> & R)
00475 {
00476 R.Resize(A.Cols(), B.Rows());
00477 Gemtmt(static_cast<type>(1), A, B, static_cast<type>(0), R);
00478 return R;
00479 }
00480
00482
00483
00484
00485
00486 template <class t_exp, class t_res>
00487 class expression
00488 {
00489 public:
00490 operator t_res () const { return static_cast<t_exp const &>(*this).operator t_res(); }
00491
00492 void Apply (t_res & result) const { static_cast<t_exp const &>(*this).Apply (result); }
00493 void Apply_pe(t_res & result) const { static_cast<t_exp const &>(*this).Apply_pe(result); }
00494 void Apply_me(t_res & result) const { static_cast<t_exp const &>(*this).Apply_me(result); }
00495 protected:
00496 expression(){ };
00497 };
00498
00499
00500 template <class t_exp, class t_res>
00501 std::ostream & operator << (std::ostream & os, expression<t_exp, t_res> const & expr)
00502 {
00503 os << expr.operator t_res();
00504 return os;
00505 }
00506
00507
00508 template <class t_exp1, class t_op, class t_res>
00509 class exp_un:public expression<exp_un<t_exp1, t_op, t_res>, t_res>
00510 {
00511 public:
00512 typedef t_exp1 T_exp1;
00513 typedef t_op T_op;
00514 typedef t_res T_res;
00515 explicit exp_un(t_exp1 const & A):Arg(A){ }
00516 operator t_res () const { t_res result; return t_op::template Apply(Arg, result); }
00517 void Apply(t_res & result) const
00518 {
00519 void const * ptr_arg = static_cast<void const*>(&Arg);
00520 void const * ptr_result = static_cast<void const*>(&result);
00521 if (ptr_arg != ptr_result) t_op::template Apply(Arg, result);
00522 else result = operator t_res();
00523 }
00524 void Apply_pe(t_res & result) const { result = result + *this; }
00525 void Apply_me(t_res & result) const { result = result - *this; }
00526 t_exp1 const & Arg;
00527 private:
00528 exp_un() { };
00529 };
00530
00531
00532 template <class t_exp1, class t_exp2, class t_op, class t_res>
00533 class exp_bin:public expression<exp_bin<t_exp1, t_exp2, t_op, t_res>, t_res>
00534 {
00535 public:
00536 typedef t_exp1 T_exp1;
00537 typedef t_exp2 T_exp2;
00538 typedef t_op T_op;
00539 typedef t_res T_res;
00540 exp_bin(t_exp1 const & A, t_exp2 const & B):Arg1(A),Arg2(B){}
00541 operator t_res () const { t_res result; return t_op::template Apply(Arg1, Arg2, result); }
00542 void Apply(t_res & result) const
00543 {
00544 void const * ptr_arg1 = static_cast<void const*>(&Arg1);
00545 void const * ptr_arg2 = static_cast<void const*>(&Arg2);
00546 void const * ptr_result = static_cast<void const*>(&result);
00547 if (ptr_arg1 != ptr_result && ptr_arg2 != ptr_result)
00548 t_op::template Apply(Arg1, Arg2, result);
00549 else
00550 result = operator t_res ();
00551 }
00552 void Apply_pe(t_res & result) const { result = result + *this; }
00553 void Apply_me(t_res & result) const { result = result - *this; }
00554 t_exp1 const & Arg1;
00555 t_exp2 const & Arg2;
00556 private:
00557 exp_bin() { };
00558 };
00559
00560
00561 template <class t_exp1, class t_exp2, class t_exp3, class t_op, class t_res>
00562 class exp_ter:public expression<exp_ter<t_exp1, t_exp2, t_exp3, t_op, t_res>, t_res>
00563 {
00564 public:
00565 typedef t_exp1 T_exp1;
00566 typedef t_exp2 T_exp2;
00567 typedef t_exp3 T_exp3;
00568 typedef t_op T_op;
00569 typedef t_res T_res;
00570 exp_ter(t_exp1 const & A, t_exp2 const & B):Arg1(A),Arg2(B) { }
00571 operator t_res () const { t_res result; return t_op::template Apply(Arg1, Arg2, Arg3, result); }
00572 void Apply(t_res & result) const
00573 {
00574 void const * ptr_arg1 = static_cast<void const*>(&Arg1);
00575 void const * ptr_arg2 = static_cast<void const*>(&Arg2);
00576 void const * ptr_arg3 = static_cast<void const*>(&Arg3);
00577 void const * ptr_result = static_cast<void const*>(&result);
00578 if (ptr_arg1 != ptr_result && ptr_arg2 != ptr_result && ptr_arg3 != ptr_result)
00579 t_op::template Apply(Arg1, Arg2, Arg3, result);
00580 else
00581 result = operator t_res ();
00582 }
00583 void Apply_pe(t_res & result) const { result = result + *this; }
00584 void Apply_me(t_res & result) const { result = result - *this; }
00585 t_exp1 const & Arg1;
00586 t_exp2 const & Arg2;
00587 t_exp3 const & Arg3;
00588 private:
00589 exp_ter() { };
00590 };
00591
00592
00593
00594
00595
00596 template<class t_exp, class t_exp_again = t_exp>
00597 struct res_type
00598 {
00599 typedef t_exp T_res;
00600 };
00601
00602
00603 template<class t_exp>
00604 struct res_type<t_exp, exp_un< typename t_exp::T_exp1, typename t_exp::T_op, typename t_exp::T_res> >
00605 {
00606 typedef typename t_exp::T_res T_res;
00607 };
00608
00609
00610 template<class t_exp>
00611 struct res_type<t_exp, exp_bin< typename t_exp::T_exp1, typename t_exp::T_exp2, typename t_exp::T_op, typename t_exp::T_res> >
00612 {
00613 typedef typename t_exp::T_res T_res;
00614 };
00616
00617
00618
00619
00620 class op_add
00621 {
00622 public:
00623 template <class t_exp1, class t_exp2, class t_res>
00624 static t_res & Apply(t_exp1 const & A, t_exp2 const & B, t_res & R)
00625 {
00626 typedef typename res_type<t_exp1>::T_res t_res1;
00627 typedef typename res_type<t_exp2>::T_res t_res2;
00628 return _add( static_cast<t_res1 const &>(A), static_cast<t_res2 const &>(B), R);
00629 }
00630 };
00631
00632
00633 class op_minus
00634 {
00635 public:
00636 template <class t_exp1, class t_exp2, class t_res>
00637 static t_res & Apply(t_exp1 const & A, t_exp2 const & B, t_res & R)
00638 {
00639 typedef typename res_type<t_exp1>::T_res t_res1;
00640 typedef typename res_type<t_exp2>::T_res t_res2;
00641 return _minus(static_cast<t_res1 const &>(A), static_cast<t_res2 const &>(B), R);
00642 }
00643 };
00644
00645
00646 class op_minus_un
00647 {
00648 public:
00649 template <class t_exp1, class t_res>
00650 static t_res & Apply(t_exp1 const & A, t_res & R)
00651 {
00652 return _prod(-1.0, static_cast<t_res const &>(A), R);
00653 }
00654 };
00655
00656
00657 class op_prod
00658 {
00659 public:
00660 template <class t_exp1, class t_exp2, class t_res>
00661 static t_res & Apply(t_exp1 const & A, t_exp2 const & B, t_res & R)
00662 {
00663 typedef typename res_type<t_exp1>::T_res t_res1;
00664 typedef typename res_type<t_exp2>::T_res t_res2;
00665 return _prod( static_cast<t_res1 const &>(A), static_cast<t_res2 const &>(B), R);
00666 }
00667 };
00668
00669 class op_div_sc;
00670
00671
00672 class op_prod_sc
00673 {
00674 public:
00675 template <class t_sc, class t_exp, class t_res>
00676 static t_res & Apply(t_sc const & A, t_exp const & B, t_res & R)
00677 {
00678 return _prod(A, static_cast<t_res const &>(B), R);
00679 }
00680
00681
00682
00683
00684 template <class t_sc1, class t_sc2, class t_exp, class t_res>
00685 static t_res & Apply(t_sc1 const & A, exp_bin<t_sc2, t_exp, op_prod_sc, t_res > const & B, t_res & R)
00686 {
00687 return _prod(A*B.Arg1, static_cast<t_res const &>(B.Arg2), R);
00688 }
00689
00690
00691 template <class t_sc1, class t_sc2, class t_exp, class t_res>
00692 static t_res & Apply(t_sc1 const & A, exp_bin<t_sc2, t_exp, op_div_sc, t_res > const & B, t_res & R)
00693 {
00694 return _prod(A/B.Arg1, static_cast<t_res const &>(B.Arg2), R);
00695 }
00696 };
00697
00698
00699 class op_div_sc
00700 {
00701 public:
00702 template <class t_sc, class t_exp, class t_res>
00703 static t_res & Apply(t_sc const & A, t_exp const & B, t_res & R)
00704 {
00705 return _prod(1.0/A, static_cast<t_res const &>(B), R);
00706 }
00707
00708
00709
00710
00711 template <class t_sc1, class t_sc2, class t_exp, class t_res>
00712 static t_res & Apply(t_sc1 const & A, exp_bin<t_sc2, t_exp, op_prod_sc, t_res > const & B, t_res & R)
00713 {
00714 return _prod(B.Arg1/A, static_cast<t_res const &>(B.Arg2), R);
00715 }
00716
00717
00718 template <class t_sc1, class t_sc2, class t_exp, class t_res>
00719 static t_res & Apply(t_sc1 const & A, exp_bin<t_sc2, t_exp, op_div_sc, t_res > const & B, t_res & R)
00720 {
00721 return _prod(1.0/(A*B.Arg1), static_cast<t_res const &>(B.Arg2), R);
00722 }
00723 };
00724
00725
00726 class op_trn
00727 {
00728 public:
00729 template <class t_exp1, class t_res>
00730 static t_res & Apply(t_exp1 const & A, t_res & R)
00731 {
00732 typedef typename res_type<t_exp1>::T_res t_res1;
00733 return _trn(static_cast<t_res1 const &>(A), R);
00734 }
00735 };
00736
00737
00738 class op_inv
00739 {
00740 public:
00741 template <class t_exp1, class t_res>
00742 static t_res & Apply(t_exp1 const & A, t_res & R)
00743 {
00744 typedef typename res_type<t_exp1>::T_res t_res1;
00745 return _inv(static_cast<t_res1 const &>(A), R);
00746 }
00747 };
00748
00749 class op_oto
00750 {
00751 public:
00752 template <class t_exp1, class t_exp2, class t_res>
00753 static t_res & Apply(t_exp1 const & A, t_exp2 const & B, t_res & R)
00754 {
00755 typedef typename res_type<t_exp1>::T_res t_res1;
00756 typedef typename res_type<t_exp2>::T_res t_res2;
00757 _prodt(A, B, R);
00758 return R;
00759 }
00760 };
00761
00762 class op_oot
00763 {
00764 public:
00765 template <class t_exp1, class t_exp2, class t_res>
00766 static t_res & Apply(t_exp1 const & A, t_exp2 const & B, t_res & R)
00767 {
00768 typedef typename res_type<t_exp1>::T_res t_res1;
00769 typedef typename res_type<t_exp2>::T_res t_res2;
00770 _prod_t(A, B, R);
00771 return R;
00772 }
00773 };
00774
00775 class op_otot
00776 {
00777 public:
00778 template <class t_exp1, class t_exp2, class t_res>
00779 static t_res & Apply(t_exp1 const & A, t_exp2 const & B, t_res & R)
00780 {
00781 typedef typename res_type<t_exp1>::T_res t_res1;
00782 typedef typename res_type<t_exp2>::T_res t_res2;
00783 _prodtt(A, B, R);
00784 return R;
00785 }
00786 };
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806
00807 #define DECLARE_OP_WITH_SCALAR(MACRO) \
00808 MACRO(short); \
00809 MACRO(int); \
00810 MACRO(long int); \
00811 MACRO(size_t); \
00812 MACRO(float); \
00813 MACRO(double); \
00814 MACRO(long double);
00815
00816
00817
00818
00819
00820 template <class t_exp, class t_res>
00821 inline
00822 exp_un< t_exp, op_minus_un, t_res >
00823 operator-(expression<t_exp, t_res> const & A)
00824 {
00825 return exp_un< t_exp, op_minus_un, t_res >(static_cast<t_exp const &>(A));
00826 }
00827
00828
00829 template <class t_exp, class t_res>
00830 inline
00831 expression<t_exp, t_res>
00832 operator+(expression<t_exp, t_res> const & A)
00833 {
00834 return A;
00835 }
00836
00837
00838 template <class t_obj, class t_exp1>
00839 inline
00840 exp_bin< t_exp1, t_obj, op_add, t_obj >
00841 operator+(expression<t_exp1, t_obj> const & A, t_obj const & B)
00842 {
00843 return exp_bin< t_exp1 , t_obj, op_add, t_obj >(static_cast<t_exp1 const &>(A),B);
00844 }
00845
00846
00847 template <class t_obj, class t_exp1 >
00848 inline
00849 exp_bin< t_obj, t_exp1, op_add, t_obj >
00850 operator+(t_obj const & A, expression<t_exp1,t_obj> const & B)
00851 {
00852 return exp_bin<t_obj, t_exp1, op_add, t_obj >(A,static_cast<t_exp1 const &>(B));
00853 }
00854
00855
00856 template <class t_obj, class t_exp1, class t_exp2>
00857 inline
00858 exp_bin< t_exp1, t_exp2, op_add, t_obj >
00859 operator+(expression<t_exp1, t_obj > const & A, expression<t_exp2, t_obj > const & B)
00860 {
00861 return exp_bin<t_exp1 ,t_exp2, op_add, t_obj >(static_cast<t_exp1 const &>(A), static_cast<t_exp2 const &>(B));
00862 }
00863
00864
00865 template <class t_obj, class t_exp1, class t_exp2>
00866 inline
00867 exp_bin< t_exp1, t_exp2, op_minus, t_obj >
00868 operator-(expression<t_exp1, t_obj > const & A, expression<t_exp2, t_obj > const & B)
00869 {
00870 return exp_bin<t_exp1 ,t_exp2, op_minus, t_obj >(static_cast<t_exp1 const &>(A), static_cast<t_exp2 const &>(B));
00871 }
00872
00873
00874 template <class t_obj, class t_exp1>
00875 inline
00876 exp_bin< t_exp1, t_obj, op_minus, t_obj >
00877 operator-(expression<t_exp1, t_obj> const & A, t_obj const & B)
00878 {
00879 return exp_bin< t_exp1 , t_obj, op_minus, t_obj >(static_cast<t_exp1 const &>(A),B);
00880 }
00881
00882
00883 template <class t_obj, class t_exp1 >
00884 inline
00885 exp_bin< t_obj, t_exp1, op_minus, t_obj >
00886 operator-(t_obj const & A, expression<t_exp1,t_obj> const & B)
00887 {
00888 return exp_bin<t_obj, t_exp1, op_minus, t_obj >(A,static_cast<t_exp1 const &>(B));
00889 }
00890
00891
00892 #define EXPR_MULT_SCALAR(T) \
00893 template <class t_obj, class t_exp1> \
00894 inline exp_bin<T, t_exp1, op_prod_sc, t_obj > \
00895 operator*(T const & A, expression<t_exp1, t_obj > const & B) \
00896 { \
00897 return exp_bin<T, t_exp1, op_prod_sc, t_obj >(A, static_cast<t_exp1 const &>(B)); \
00898 } \
00899 template <class t_obj, class t_exp1> \
00900 inline exp_bin<T, t_exp1, op_prod_sc, t_obj > \
00901 operator*(expression<t_exp1, t_obj > const & A, T const & B) \
00902 { \
00903 return exp_bin<T, t_exp1, op_prod_sc, t_obj >(B, static_cast<t_exp1 const &>(A)); \
00904 }
00905
00906 DECLARE_OP_WITH_SCALAR(EXPR_MULT_SCALAR);
00907
00908
00909 #define EXPR_DIV_SCALAR(T) \
00910 template <class t_obj, class t_exp1> \
00911 inline exp_bin<T, t_exp1, op_div_sc, t_obj > \
00912 operator/(expression<t_exp1, t_obj > const & A, T const & B) \
00913 { \
00914 return exp_bin<T, t_exp1, op_div_sc, t_obj >(B, static_cast<t_exp1 const &>(A)); \
00915 }
00916
00917 DECLARE_OP_WITH_SCALAR(EXPR_DIV_SCALAR);
00918
00919
00920
00921
00922
00923
00924 template <class type>
00925 inline
00926 exp_un< Vector<type>, op_minus_un, Vector<type> >
00927 operator-(Vector<type> const & A)
00928 {
00929 return exp_un< Vector<type>, op_minus_un, Vector<type> > (A);
00930 }
00931
00932
00933 template <class type>
00934 inline
00935 Vector<type>
00936 operator+(Vector<type> const & A)
00937 {
00938 return A;
00939 }
00940
00941
00942 template <typename type>
00943 inline
00944 exp_bin<Vector<type>, Vector<type>, op_add, Vector<type> >
00945 operator + (Vector<type> const & A, Vector<type> const & B)
00946 {
00947 return exp_bin<Vector<type>, Vector<type>, op_add, Vector<type> >(A,B);
00948 }
00949
00950
00951 template <typename type>
00952 inline
00953 exp_bin<Vector<type>, Vector<type>, op_minus, Vector<type> >
00954 operator - (Vector<type> const & A, Vector<type> const & B)
00955 {
00956 return exp_bin<Vector<type>, Vector<type>, op_minus, Vector<type> >(A,B);
00957 }
00958
00959
00960 template <typename type>
00961 inline
00962 exp_un<Vector<type>, op_trn, Matrix<type> >
00963 trn (Vector<type> const & A)
00964 {
00965 return exp_un<Vector<type>, op_trn, Matrix<type> >(A);
00966 }
00967
00968
00969 template <class type, class t_exp1>
00970 inline
00971 exp_un< t_exp1, op_trn, Matrix<type> >
00972 trn (expression<t_exp1, Vector<type> > const & A)
00973 {
00974 return exp_un<t_exp1, op_trn, Matrix<type> >(static_cast<t_exp1 const &>(A));
00975 }
00976
00977
00978 #define VECTOR_MULT_SCALAR(T) \
00979 template <class type> \
00980 inline \
00981 exp_bin< T, Vector<type>, op_prod_sc, Vector<type> > \
00982 operator * ( T const & A, Vector<type> const & B) \
00983 { \
00984 return exp_bin< T, Vector<type>, op_prod_sc, Vector<type> >(A,B); \
00985 } \
00986 template <class type> \
00987 inline \
00988 exp_bin<T, Vector<type>, op_prod_sc, Vector<type> > \
00989 operator * (Vector<type> const & A, T const & B) \
00990 { \
00991 return exp_bin<T, Vector<type>, op_prod_sc, Vector<type> >(B,A); \
00992 }
00993
00994 DECLARE_OP_WITH_SCALAR(VECTOR_MULT_SCALAR);
00995
00996
00997 #define VECTOR_DIV_SCALAR(T) \
00998 template <class type> \
00999 inline \
01000 exp_bin<T, Vector<type>, op_div_sc, Vector<type> > \
01001 operator / (Vector<type> const & A, T const & B) \
01002 { \
01003 return exp_bin<T, Vector<type>, op_div_sc, Vector<type> >(B,A); \
01004 }
01005
01006 DECLARE_OP_WITH_SCALAR(VECTOR_DIV_SCALAR);
01007
01008
01009
01010
01011
01012
01013 template <class type>
01014 inline
01015 exp_un< Matrix<type>, op_minus_un, Matrix<type> >
01016 operator-(Matrix<type> const & A)
01017 {
01018 return exp_un< Matrix<type>, op_minus_un, Matrix<type> > (A);
01019 }
01020
01021
01022 template <class type>
01023 inline
01024 Matrix<type>
01025 operator+(Matrix<type> const & A)
01026 {
01027 return A;
01028 }
01029
01030
01031 template <typename type>
01032 inline
01033 exp_bin<Matrix<type>, Matrix<type>, op_add, Matrix<type> >
01034 operator + (Matrix<type> const & A, Matrix<type> const & B)
01035 {
01036 return exp_bin<Matrix<type>, Matrix<type>, op_add, Matrix<type> >(A,B);
01037 }
01038
01039
01040 template <typename type>
01041 inline
01042 exp_bin<Matrix<type>, Matrix<type>, op_minus, Matrix<type> >
01043 operator - (Matrix<type> const & A, Matrix<type> const & B)
01044 {
01045 return exp_bin<Matrix<type>, Matrix<type>, op_minus, Matrix<type> >(A,B);
01046 }
01047
01048
01049 template <typename type>
01050 inline
01051 exp_bin<Matrix<type>, Matrix<type>, op_prod, Matrix<type> >
01052 operator * (Matrix<type> const & A, Matrix<type> const & B)
01053 {
01054 return exp_bin<Matrix<type>, Matrix<type>, op_prod, Matrix<type> >(A,B);
01055 }
01056
01057
01058 template <typename type>
01059 inline
01060 exp_un<Matrix<type>, op_trn, Matrix<type> >
01061 trn (Matrix<type> const & A)
01062 {
01063 return exp_un<Matrix<type>, op_trn, Matrix<type> >(A);
01064 }
01065
01066
01067 template <class type, class t_exp1>
01068 inline
01069 exp_un< t_exp1, op_trn, Matrix<type> >
01070 trn (expression<t_exp1, Matrix<type> > const & A)
01071 {
01072 return exp_un<t_exp1, op_trn, Matrix<type> >(static_cast<t_exp1 const &>(A));
01073 }
01074
01075
01076 #define MATRIX_MULT_SCALAR(T) \
01077 template <class type> \
01078 inline exp_bin< T ,Matrix <type>, op_prod_sc,Matrix <type> > \
01079 operator * (T const & A, Matrix <type> const & B) \
01080 { \
01081 return exp_bin< T,Matrix <type>, op_prod_sc,Matrix <type> >(A,B); \
01082 } \
01083 template <class type> \
01084 inline exp_bin<T, Matrix <type>, op_prod_sc,Matrix <type> > \
01085 operator * (Matrix <type> const & A, T const & B) \
01086 { \
01087 return exp_bin<T, Matrix <type>, op_prod_sc,Matrix <type> >(B,A); \
01088 }
01089
01090 DECLARE_OP_WITH_SCALAR(MATRIX_MULT_SCALAR);
01091
01092
01093 #define MATRIX_DIV_SCALAR(T) \
01094 template <class type> \
01095 inline exp_bin<T, Matrix <type>, op_div_sc,Matrix <type> > \
01096 operator / (Matrix <type> const & A, T const & B) \
01097 { \
01098 return exp_bin<T, Matrix <type>, op_div_sc,Matrix <type> >(B,A); \
01099 }
01100
01101 DECLARE_OP_WITH_SCALAR(MATRIX_DIV_SCALAR);
01102
01103
01104 template <typename type>
01105 inline
01106 exp_un<Matrix<type>, op_inv, Matrix<type> >
01107 inv (Matrix<type> const & A)
01108 {
01109 return exp_un<Matrix<type>, op_inv, Matrix<type> >(A);
01110 }
01111
01112
01113 template <class type, class t_exp1>
01114 inline
01115 exp_un< t_exp1, op_inv, Matrix<type> >
01116 inv (expression<t_exp1, Matrix<type> > const & A)
01117 {
01118 return exp_un<t_exp1, op_inv, Matrix<type> >(static_cast<t_exp1 const &>(A));
01119 }
01120
01121
01122 template <typename type>
01123 inline
01124 type
01125 det (Matrix<type> const & A)
01126 {
01127 return determinat(A);
01128 }
01129
01130
01131 template <class type, class t_exp1>
01132 inline
01133 type
01134 det (expression<t_exp1, Matrix<type> > const & A)
01135 {
01136 return determinat(static_cast<typename t_exp1::T_res const &>(static_cast<t_exp1 const &>(A)));
01137 }
01138
01139
01140
01141
01142
01143
01144 template <class type>
01145 inline
01146 exp_bin<Vector<type>, Matrix<type>, op_prod, Matrix<type> >
01147 operator * (Vector<type> const & A, Matrix<type> const & B)
01148 {
01149 return exp_bin<Vector<type>, Matrix<type>, op_prod, Matrix<type> >(A,B);
01150 }
01151
01152
01153 template <typename type>
01154 inline
01155 exp_bin<Matrix<type>, Vector<type>, op_prod, Vector<type> >
01156 operator * (Matrix<type> const & A, Vector<type> const & B)
01157 {
01158 return exp_bin<Matrix<type>, Vector<type>, op_prod, Vector<type> >(A,B);
01159 }
01160
01161
01162 template <class type, class t_exp1>
01163 inline
01164 exp_bin< t_exp1, Vector<type>, op_prod, Vector<type> >
01165 operator*(expression<t_exp1, Matrix<type> > const & A, Vector<type> const & B)
01166 {
01167 return exp_bin< t_exp1 , Vector<type>, op_prod, Vector<type> >(static_cast<t_exp1 const &>(A),B);
01168 }
01169
01170
01171 template <class type, class t_exp1>
01172 inline
01173 exp_bin< t_exp1, Matrix<type>, op_prod, Matrix<type> >
01174 operator*(expression<t_exp1, Matrix<type> > const & A, Matrix<type> const & B)
01175 {
01176 return exp_bin< t_exp1, Matrix<type>, op_prod, Matrix<type> >(static_cast<t_exp1 const &>(A),B);
01177 }
01178
01179
01180 template <class type, class t_exp1>
01181 inline
01182 exp_bin<Matrix<type>, t_exp1, op_prod, Matrix<type> >
01183 operator*(Matrix<type> const & A, expression<t_exp1, Matrix<type> > const & B)
01184 {
01185 return exp_bin< Matrix<type>, t_exp1, op_prod, Matrix<type> >(A,static_cast<t_exp1 const &>(B));
01186 }
01187
01188
01189 template <class type, class t_exp1, class t_exp2>
01190 inline
01191 exp_bin< t_exp1, t_exp2, op_prod, Matrix<type> >
01192 operator*(expression<t_exp1, Matrix<type> > const & A, expression<t_exp2, Matrix<type> > const & B)
01193 {
01194 return exp_bin< t_exp1, t_exp2, op_prod, Matrix<type> >(static_cast<t_exp1 const &>(A),static_cast<t_exp2 const &>(B));
01195 }
01196
01197
01198 template <class type, class t_exp1, class t_exp2>
01199 inline
01200 exp_bin< t_exp1, t_exp2, op_prod, Vector<type> >
01201 operator*(expression<t_exp1, Matrix<type> > const & A, expression<t_exp2, Vector<type> > const & B)
01202 {
01203 return exp_bin< t_exp1, t_exp2, op_prod, Vector<type> >(static_cast<t_exp1 const &>(A),static_cast<t_exp2 const &>(B));
01204 }
01205
01206
01207 template <class type, class t_exp1, class t_exp2>
01208 inline
01209 exp_bin< t_exp1, t_exp2, op_prod, Matrix<type> >
01210 operator*(expression<t_exp1, Vector<type> > const & A, expression<t_exp2, Matrix<type> > const & B)
01211 {
01212 return exp_bin< t_exp1, t_exp2, op_prod, Matrix<type> >(static_cast<t_exp1 const &>(A),static_cast<t_exp2 const &>(B));
01213 }
01214
01215
01216
01217
01218
01219
01220 template <class type>
01221 inline
01222 exp_bin<Vector<type>, Vector<type>, op_oto, type >
01223 operator * (exp_un< Vector<type>, op_trn, Matrix<type> > const & A, Vector<type> const & B)
01224 {
01225 return exp_bin<Vector<type>, Vector<type>, op_oto, type >(A.Arg, B);
01226 }
01227
01228
01229 template <class type>
01230 inline
01231 exp_bin<Vector<type>,Vector<type>, op_oot, Matrix<type> >
01232 operator * (Vector<type> const & A, exp_un< Vector<type>, op_trn, Matrix<type> > const & B)
01233 {
01234 return exp_bin<Vector<type>,Vector<type>, op_oot, Matrix<type> >(A, B.Arg);
01235 }
01236
01237
01238 template <class type>
01239 inline
01240 exp_bin<Matrix<type>, Matrix<type>, op_oto, Matrix<type> >
01241 operator * (exp_un<Matrix<type>, op_trn, Matrix<type> > const & A, Matrix<type> const & B)
01242 {
01243 return exp_bin<Matrix<type>, Matrix<type>, op_oto, Matrix<type> >(A.Arg, B);
01244 }
01245
01246
01247 template <class type>
01248 inline
01249 exp_bin<Matrix<type>, Matrix<type>, op_oot, Matrix<type> >
01250 operator * (Matrix<type> const & A, exp_un<Matrix<type>, op_trn, Matrix<type> > const & B)
01251 {
01252 return exp_bin<Matrix<type>, Matrix<type>, op_oot, Matrix<type> >(A, B.Arg);
01253 }
01254
01255
01256 template <class type>
01257 inline
01258 exp_bin<Matrix<type>, Matrix<type>, op_otot, Matrix<type> >
01259 operator * (exp_un<Matrix<type>, op_trn, Matrix<type> > const & A, exp_un<Matrix<type>, op_trn, Matrix<type> > const & B)
01260 {
01261 return exp_bin<Matrix<type>, Matrix<type>, op_otot, Matrix<type> >(A.Arg, B.Arg);
01262 }
01263
01264
01265
01266
01267
01268 template <class type>
01269 inline
01270 void Copy(Tensors::Tensor4 const & T, Matrix<type> & M)
01271 {
01272 M.Resize(6,6);
01273 for (int i=0; i<M.Rows(); ++i)
01274 for (int j=0; j<M.Cols(); ++j)
01275 M(i,j) = T(i,j);
01276 }
01277
01278 template <class type>
01279 inline
01280 void Copy(Matrix<type> const & M, Tensors::Tensor4 & T)
01281 {
01282 assert(M.Rows() == 6 && M.Cols() == 6);
01283 for (int i=0; i<M.Rows(); ++i)
01284 for (int j=0; j<M.Cols(); ++j)
01285 T(i,j) = M(i,j);
01286 }
01287
01288 template <class type>
01289 inline
01290 void Copy(Tensors::Tensor2 const & T, Matrix<type> & M)
01291 {
01292 M.Resize(3,3);
01293 M(0,0) = T(0); M(0,1) = T(3); M(0,2) = T(5);
01294 M(1,0) = T(3); M(1,1) = T(1); M(1,2) = T(4);
01295 M(2,0) = T(5); M(2,1) = T(4); M(2,2) = T(2);
01296 }
01297
01298 template <class type>
01299 inline
01300 void Copy(Tensors::Tensor2 const & T, Vector<type> & V)
01301 {
01302 V.Resize(6);
01303 V(0) = T(0); V(1) = T(1); V(2) = T(2);
01304 V(3) = T(3); V(4) = T(4); V(5) = T(5);
01305 }
01306
01307 template <class type>
01308 inline
01309 void Copy(Vector<type> const & V, Tensors::Tensor2 & T)
01310 {
01311 assert(V.Size() == 6);
01312 T(0) = V(0); T(1) = V(1); T(2) = V(2);
01313 T(3) = V(3); T(4) = V(4); T(5) = V(5);
01314 }
01315
01316 template <class type>
01317 inline
01318 void Copy(Tensors::Tensor1 const & T, Vector<type> & V)
01319 {
01320 V.Resize(3);
01321 V(0) = T(0); V(1) = T(1); V(2) = T(2);
01322 }
01323
01324 template <class type>
01325 inline
01326 void Copy(Vector<type> const & V, Tensors::Tensor1 & T)
01327 {
01328 assert(V.Size() == 3);
01329 T(0) = V(0); T(1) = V(1); T(2) = V(2);
01330 }
01331
01332
01333 }
01334
01335 #endif //#define MECHSYS_LINALG_LAEXPR_H
01336
01337