00001
00002
00003
00004 #ifndef vectMatr_hh
00005 #define vectMatr_hh
00006
00007 #include <iostream>
00008 #include <cmath>
00009 #include <cstring>
00010
00011 #include "functionCompiler.hh"
00012 #include "exceptions.hh"
00013 #include "typedefs.hh"
00014 #include "vectorsMatricesForward.hh"
00015 #include "debug.hh"
00016
00017
00018 #define MappingAppll_D 0
00019 #define MappingAppl_D 0
00020
00021 namespace concepts {
00022
00024 template<typename F, typename G>
00025 void memorycpy(F *dest, const G *src, size_t n) {
00026 for (size_t i = 0; i < n; ++i) *dest++ = *src++;
00027 }
00028
00029
00030
00039 template<class F, int dim>
00040 class Point {
00041 public:
00045 Point() { F* d = data_; for(uint i = dim; i--;) *d++ = 0; }
00047 template<class G>
00048 Point(const Point<G, dim>& p) {
00049 memorycpy(data_, (const G*)p, dim);
00050 }
00052 template<int dim2>
00053 Point(const Point<F, dim2>& p) {
00054 if (dim2<dim) {
00055 F* d = data_+dim2; for(uint i = dim-dim2; i--;) *d++ = 0;
00056 }
00057 memorycpy(data_, (const F*)p, ((dim < dim2) ? dim : dim2));
00058 }
00062 Point(F x) { F* d = data_; for(uint i = dim; i--;) *d++ = x; }
00064 Point(const F e0, const F e1, const F e2 = 0) {
00065 data_[0] = e0;
00066 if (dim > 1)
00067 data_[1] = e1;
00068 if (dim > 2)
00069 data_[2] = e2;
00070 }
00072 Point(const uchar *pgm, const Real x, const Real y, const Real z = 0.0);
00073
00075 template<int dim2>
00076 Point<F, dim>& operator=(const Point<F, dim2>& b) {
00077 if (this != &b)
00078 memorycpy(data_, b.data_, ((dim < dim2) ? dim : dim2));
00079 return *this;
00080 }
00081
00083 const F& operator[](const int i) const {
00084 conceptsAssert(i < dim, concepts::Assertion());
00085 return data_[i]; }
00087 F& operator[](const int i) {
00088 conceptsAssert(i < dim, concepts::Assertion());
00089 return data_[i]; }
00090
00092 operator F*() { return data_; }
00094 operator const F*() const { return data_; }
00095
00097 Point<F, dim>& operator+=(const Point<F, dim>& p) {
00098 F* d = data_; const F* dp = p.data_;
00099 for(uint i = dim; i--;) *d++ += *dp++;
00100 return *this;
00101 }
00103 Point<F, dim> operator+ (const Point<F, dim>& p) const {
00104 Point<F, dim> res(*this);
00105 return res += p;
00106 }
00108 Point<F, dim>& operator-=(const Point<F, dim>& p) {
00109 F* d = data_; const F* dp = p.data_;
00110 for(uint i = dim; i--;) *d++ -= *dp++;
00111 return *this;
00112 }
00114 Point<F, dim> operator- (const Point<F, dim>& p) const {
00115 Point<F, dim> res(*this);
00116 return res -= p;
00117 }
00118
00120 F operator*(const Point<F, dim>& b) const;
00121 F operator*(const UnitNd<dim>& b) const;
00123 F dot(const Point<F, dim>& b) const {
00124 return *this * b;
00125 }
00126
00128 template<class G>
00129 Point<F, dim>& operator*=(const G n) {
00130 F* d = data_;
00131 for(uint i = dim; i--;) *d++ *= n;
00132 return *this;
00133 }
00134 template<class G>
00135 Point<F, dim>& operator/=(const G n) {
00136 F* d = data_; for(uint i = dim; i--;) *d++ /= n;
00137 return *this;
00138 }
00140 template<class G>
00141 Point<typename Combtype<F,G>::type, dim> operator*(const G n) const {
00142 Point<typename Combtype<F,G>::type, dim> res(*this);
00143 return res *= n;
00144 }
00146 Point<F, dim>& scale(const Point<F, dim>& n) {
00147 F* d = data_; const F* e = n.data_;
00148 for(uint i = dim; i--;) *d++ *= *e++;
00149 return *this;
00150 }
00151
00153 F cross(const Point<F, dim>& b) const {
00154 return data_[0]*b[1] - data_[1]*b[0];
00155 }
00157 Point<F, dim> operator^(const Point<F, dim>& b) const;
00158
00160 Real l2() const { return std::sqrt(l2_2()); }
00162 Real l2_2() const;
00164 Real linfty() const;
00165
00167 void lincomb(const Point<F, dim>& a, const Point<F, dim>& b,
00168 const F ca = 1.0, const F cb = 1.0);
00169
00171 void max(const Point<F, dim>& a, const Point<F, dim>& b);
00172
00174 void min(const Point<F, dim>& a, const Point<F, dim>& b);
00175
00179 Point<F, dim>& ortho(const Point<F, dim>& a);
00181 Point<F, dim>& ortho();
00183 Point<F, dim> ortho() const;
00184
00185 std::ostream& info(std::ostream& os) const;
00186 private:
00187 F data_[dim];
00188 };
00189
00190 template<class F, int dim>
00191 std::ostream& operator<<(std::ostream& os, const Point<F, dim>& p) {
00192 return p.info(os);
00193 }
00194
00195
00196 template<typename F, int dim>
00197 struct Realtype<Point<F,dim> > {
00198 typedef typename Realtype<F>::type type;
00199 };
00200
00201
00202 template<typename F, int dim>
00203 struct Datatype<Point<F,dim> > {
00204
00205 typedef F type;
00206 };
00207
00208 template <class F, int dim>
00209 inline bool operator==(const Point<F,dim>& x, const Point<F,dim>& y)
00210 {
00211 const F* d = (const F*)x; const F* e = (const F*)y;
00212 for (uint i = dim; i--;)
00213 if (*d++ != *e++) return false;
00214 return true;
00215 }
00216
00217 template <class F, int dim>
00218 inline Point<typename Combtype<F,Real>::type,dim> operator*(const Real x, const Point<F,dim>& y)
00219 {
00220 return y * x;
00221 }
00222
00223 template <class F, int dim>
00224 inline Point<typename Combtype<F,Cmplx>::type,dim> operator*(const Cmplx x, const Point<F,dim>& y)
00225 {
00226 return y * x;
00227 }
00228
00229 template<int dim>
00230 Cmplx operator*(const Point<Cmplx, dim>& a, const Point<Real, dim>& b) {
00231 Cmplx res = 0.0;
00232 const Cmplx* d = (const Cmplx*)a; const Real* db = (const Real*)b;
00233 for(uint i = 2; i--;)
00234 res += (*d++) * *db++;
00235 return res;
00236 }
00237
00238 template<int dim>
00239 Cmplx operator*(const Point<Real, dim>& a, const Point<Cmplx, dim>& b) {
00240 Cmplx res = 0.0;
00241 const Real* d = (const Real*)a; const Cmplx* db = (const Cmplx*)b;
00242 for(uint i = dim; i--;)
00243 res += (*d++) * conj(*db++);
00244 return res;
00245 }
00246
00247
00248
00257 template<class F, uint dim>
00258 struct GeneralPoint {
00259 typedef typename concepts::Point<F,dim> Type;
00260 };
00261
00262 template<class F>
00263 struct GeneralPoint<F,1> {
00264 typedef F Type;
00265 };
00266
00267
00268
00269
00274 template <int dim>
00275 class UnitNd : public Point<Real, dim> {
00276 Real len_;
00277
00278 public:
00280 UnitNd() : Point<Real, dim>() {len_ = 0.0;}
00282 inline UnitNd(const Point<Real, dim>& u);
00284 inline UnitNd(Real x, Real y, Real z);
00285
00287 Real length() const {return len_;}
00288 };
00289
00290 template <int dim>
00291 inline UnitNd<dim>::UnitNd(const Point<Real, dim>& u)
00292 : Point<Real, dim>(u) {
00293 len_ = this->l2(); *this *= (1.0 / len_);
00294 }
00295
00296 template <int dim>
00297 inline UnitNd<dim>::UnitNd(Real x, Real y, Real z)
00298 : Point<Real, dim>(x, y, z) {
00299 len_ = this->l2(); *this *= (1.0 / len_);
00300 }
00301
00302
00303
00311 template<class F, int dim>
00312 class Mapping {
00313 public:
00317 Mapping() {}
00319 Mapping(const Mapping<F, dim>& m) {
00320 memorycpy(data_, m.data_, dim*dim);
00321 }
00322
00326 template <class H>
00327 Mapping(const Mapping<H, dim>& m) {
00328 for(int i=0; i < dim*dim; ++i)
00329 data_[i] = m.data_[i];
00330 }
00331
00332
00333 friend class Mapping<Cmplx, dim>;
00334 friend class Mapping<Real, dim>;
00335
00337 Mapping(const F e0, const F e1,
00338 const F e2, const F e3);
00343 Mapping(const Point<F, dim> first, const Point<F, dim> second);
00345 Mapping(const F e0, const F e1, const F e2,
00346 const F e3, const F e4, const F e5,
00347 const F e6, const F e7, const F e8);
00351 Mapping(const Point<F, dim> first,
00352 const Point<F, dim> second,
00353 const Point<F, dim> third);
00355 Mapping(const F e0, const F e1, const F e2,
00356 const F e3, const F e4, const F e5,
00357 const F e6, const F e7, const F e8,
00358 const F e9, const F e10, const F e11,
00359 const F e12, const F e13, const F e14,
00360 const F e15, const F e16, const F e17,
00361 const F e18, const F e19, const F e20,
00362 const F e21, const F e22, const F e23,
00363 const F e24, const F e25, const F e26,
00364 const F e27, const F e28, const F e29,
00365 const F e30, const F e31, const F e32,
00366 const F e33, const F e34, const F e35);
00367
00371 Mapping(const UnitNd<dim>& n);
00372
00374 const F& operator()(uint i, uint j) const {
00375 conceptsAssert(i < dim, Assertion());
00376 conceptsAssert(j < dim, Assertion());
00377 DEBUGL(MappingAppll_D, '(' << i << ", " << j << ") is " << data_[i*dim+j]
00378 << " at " << &(data_[i*dim+j]));
00379 return data_[i*dim+j];
00380 }
00381
00383 F& operator()(uint i, uint j) {
00384 conceptsAssert(i < dim, Assertion());
00385 conceptsAssert(j < dim, Assertion());
00386 DEBUGL(MappingAppll_D, '(' << i << ", " << j << ") is " << data_[i*dim+j]
00387 << " at " << &(data_[i*dim+j]));
00388 return data_[i*dim+j];
00389 }
00390
00391
00395 Mapping(F x) { F* d = data_; for(uint i = dim*dim; i--;) *d++ = x; }
00396
00398 template<class H>
00399 Point<typename Combtype<F,H>::type, dim> operator*(const Point<H, dim>& p) const;
00400
00401 template<class H>
00402 Point<H, dim> mapPoint(const Point<H, dim>& b) const {
00403 return this->operator*(b);
00404 }
00405
00407 template<class G>
00408 Mapping<typename Combtype<F,G>::type, dim>
00409 operator*(const Mapping<G, dim>& m) const;
00411 Mapping<F, dim>& operator*=(const F n);
00413 Mapping<F, dim>& operator*=(const Mapping<F, dim>& m);
00417 template<class G>
00418 Mapping<typename Combtype<F,G>::type, dim> operator*(const G n) const;
00419
00421 Mapping<F, dim>& operator+=(const Mapping<F, dim>& M);
00423 Mapping<F, dim>& scaleRows(const Point<F, dim>& s);
00425 Mapping<F, dim>& scaleCols(const Point<F, dim>& s);
00427 F determinant() const;
00429 Mapping<F, dim> inverse() const;
00433 Mapping<F, dim> adjugate() const;
00435 Mapping<F, dim> transpose() const;
00437 Mapping<F, dim> prodTranspose() const;
00439 Point<F, dim> column(const uint i) const;
00440
00445 template<class H, class J, int dimy, int dimx>
00446 void operator()(const Point<H, dimy>& y, Point<J, dimx>& x) const;
00447
00449 void zeros() { F* d = data_;
00450 for (uint i = 0; i < dim*dim; ++i) *d++ = 0; }
00451
00455 template <class H>
00456 void mapTranspose(const Point<H, dim>& y, Point<H, dim>& x) const;
00457
00459 void rank1Product(const Point<F, dim> x,
00460 const Point<F, dim> y);
00461
00462 std::ostream& info(std::ostream& os) const;
00463 private:
00464 F data_[dim*dim];
00465 };
00466
00467 template<class F, int dim>
00468 template<class H>
00469 Point<typename Combtype<F,H>::type, dim> Mapping<F, dim>::operator*(const Point<H, dim>& p) const
00470 {
00471 Point<typename Combtype<F,H>::type, dim> res;
00472 this->operator()(p, res);
00473 return res;
00474 }
00475
00476 template<class F, int dim>
00477 template<class H, class J, int dimy, int dimx>
00478 void Mapping<F, dim>::operator()(const Point<H, dimy>& y,
00479 Point<J, dimx>& x) const
00480 {
00481 DEBUGL(MappingAppl_D, *this << " * " << y << " -> " << x);
00482 if (dimx == dimy && (void*)&x == (void*)&y) {
00483
00484 J* dx = (J*)x;
00485 const F* d = data_;
00486 const H* yp = (const H*)y;
00487 H yy[dimy];
00488 for (int k = 0; k < dimy; k++) yy[k] = yp[k];
00489 const H* dy = yy;
00490 for(int i = 0; i < (dim < dimx ? dim : dimx); ++dx, ++i) {
00491 dy = yy;
00492 *dx = 0;
00493 for(int j = 0; j < (dim < dimy ? dim : dimy); ++j) {
00494 *dx += d[j] * (*dy++);
00495 }
00496 d += dim;
00497 }
00498 if (dim < dimx) {
00499 for(int j = dim; j < (dimx < dimy ? dimx : dimy); ++j)
00500 *dx++ = *dy++;
00501 for(int k = 0; k < dimx - (dim < dimy ? dimy : dim); ++k)
00502 *dx++ = 0;
00503 }
00504
00505 }
00506 else {
00507 DEBUGL(MappingAppl_D, "x != y");
00508 J* dx = (J*)x;
00509 const F* d = data_;
00510 const H* dy = (const H*)y;
00511 for(int i = 0; i < (dim < dimx ? dim : dimx); ++dx, ++i) {
00512 dy = (const H*)y;
00513 *dx = 0;
00514 for(int j = 0; j < (dim < dimy ? dim : dimy); ++j) {
00515 *dx += d[j] * (*dy++);
00516 }
00517 DEBUGL(MappingAppl_D, "x = " << x);
00518 d += dim;
00519 }
00520 if (dim < dimx) {
00521 for(int j = dim; j < (dimx < dimy ? dimx : dimy); ++j)
00522 *dx++ = *dy++;
00523 for(int k = 0; k < dimx - (dim < dimy ? dimy : dim); ++k)
00524 *dx++ = 0;
00525 }
00526
00527 }
00528 }
00529
00530 template<class F, int dim>
00531 template<class H>
00532 inline void Mapping<F, dim>::mapTranspose(const Point<H, dim>& y,
00533 Point<H, dim>& x) const
00534 {
00535 H* dr = (H*)x;
00536 for(uint i = 0; i < dim; i++, dr++) {
00537 const H* dp = (const H*)y;
00538 const F* dm = data_ + i;
00539 *dr = 0;
00540 for(uint j = dim; j--; ++dp) {
00541 *dr += (*dm) * (*dp);
00542 dm += dim;
00543 }
00544 }
00545 }
00546
00547 template<class F, int dim>
00548 std::ostream& operator<<(std::ostream& os, const Mapping<F, dim>& m) {
00549 return m.info(os);
00550 }
00551
00552
00553 template<typename F, int dim>
00554 struct Realtype<Mapping<F,dim> > {
00555 typedef typename Realtype<F>::type type;
00556 };
00557
00558
00559 template<typename F, int dim>
00560 struct Datatype<Mapping<F,dim> > {
00561 typedef typename Datatype<F>::type type;
00562 };
00563
00564
00565
00574 template<class F, uint dim>
00575 struct GeneralMapping {
00576 typedef typename concepts::Mapping<F,dim> Type;
00577 };
00578
00579 template<class F>
00580 struct GeneralMapping<F,1> {
00581 typedef F Type;
00582 };
00583
00584
00585
00586 template<>
00587 template<class F, int dim>
00588 struct number<Point<F,dim> > {
00589 static inline std::string name() {
00590 return number<F>::name() + char('0'+dim) + 'd';
00591 }
00592 };
00593
00594 template<>
00595 template<class F, int dim>
00596 struct number<Mapping<F,dim> > {
00597 static inline std::string name() {
00598 return "Map" + number<F>::name() + char('0'+dim) + 'd';
00599 }
00600 };
00601
00602 }
00603
00604 namespace std {
00605
00613 template<class F, int dim>
00614 inline const concepts::Point<F,dim> conj(const concepts::Point<F,dim>& v) {
00615 concepts::Point<F,dim> res;
00616 F* d = (F*)res; const F* e = (const F*)v;
00617 for(uint i = dim; i--;) *d++ += conj(*e++);
00618 return res;
00619 }
00620
00626 template<class F, int dim>
00627 inline const concepts::Real norm(const concepts::Point<F,dim>& v) {
00628 return v.l2_2();
00629 }
00630
00631
00632
00638 concepts::Real arg(const concepts::Point<concepts::Real,2>& p);
00639
00640 }
00641
00642 #endif // vectMatr_hh