00001
00005
00006
00007
00008
00009
00010 #ifndef TBCI_FS_VECTOR_H
00011 #define TBCI_FS_VECTOR_H
00012
00013 #include "basics.h"
00014 #include "bvector.h"
00015
00016
00017 #if !defined(NO_GD) && !defined(AUTO_DECL)
00018 # include "fs_vector_gd.h"
00019 #endif
00020
00021 NAMESPACE_TBCI
00022
00023 #ifdef EXCEPT
00024
00025
00027 class FSVecErr : public NumErr
00028 {
00029 public:
00030 FSVecErr()
00031 : NumErr("Error in FS_Vector library") {}
00032 FSVecErr(const char* t, const long i = 0)
00033 : NumErr(t, i) {}
00034 FSVecErr(const FSVecErr& fe)
00035 : NumErr(fe) {}
00036 virtual ~FSVecErr() throw() {}
00037 } ;
00038 #endif
00039
00040 #ifdef PRAGMA_I
00041 # pragma interface "fs_vector.h"
00042 #endif
00043
00044
00045 template <unsigned dims, typename T > class FS_Vector;
00046
00047 #if 0
00048 template <unsigned dims, typename T, unsigned dims2>
00049 inline FS_Vector<dims,T> slice (const FS_Vector<dims,T>&, const unsigned, const unsigned);
00050 #endif
00051
00061 template <unsigned dims, typename T>
00062 class FS_Vector : public Vector_Sig<T>
00063 {
00064 protected:
00065 T x[dims];
00066
00067 public:
00068 typedef T value_type;
00069 typedef T element_type;
00070 typedef T aligned_value_type TALIGN(MIN_ALIGN);
00071
00072 FS_Vector () {}
00073 FS_Vector (const T v) { fill(v); }
00074 FS_Vector (const FS_Vector <dims, T> & pc) { CSTD__ memcpy (x, pc.x, sizeof(T)*dims); }
00075
00076 FS_Vector (const BVector<T>& bv);
00077 #ifndef NO_POD
00078 FS_Vector (const vararg, ...);
00079 #endif
00080
00081 operator BVector<T> () const;
00082
00083 T& operator [] (const unsigned long i);
00084 const T& operator [] (const unsigned long i) const;
00085 T& operator () (const unsigned long i);
00086 const T& operator () (const unsigned long i) const;
00087
00088 T& operator * () { return x[0]; }
00089 const T& operator * () const { return x[0]; }
00090
00091
00092 #ifndef HAVE_PROMOTION_BUG
00093 # ifndef HAVE_GCC295_TMPLFRNDCLS_BUG
00094 template <unsigned dm, typename U> friend class FS_Vector;
00095 # endif
00096 template <typename U> explicit FS_Vector (const FS_Vector<dims, U>& fsv)
00097 { for (unsigned i = 0; i < dims; ++i) *(this)(i) = fsv(i); }
00098 #endif
00099
00100 FS_Vector <dims,T>& init_0 ()
00101 { if (dims) CSTD__ memset ((void*)x, 0, sizeof(T)*dims); return *this; }
00102 FS_Vector <dims,T>& fill (const T&);
00103
00104 FS_Vector <dims,T>& clear () { return init_0 (); }
00105
00106 inline unsigned long size () const { return dims; }
00107
00108
00109 FS_Vector<dims,T>& operator = (const T& a) { return fill (a); }
00110 FS_Vector<dims,T>& operator = (const FS_Vector<dims,T>& fv);
00111
00112
00113
00114 bool operator == (const FS_Vector<dims,T>&) const;
00115 bool operator != (const FS_Vector<dims,T>& fv) const { return !(*this == fv);
00116 }
00117
00118
00119 FS_Vector <dims,T>& operator += (const FS_Vector<dims,T>&);
00120 FS_Vector <dims,T>& operator -= (const FS_Vector<dims,T>&);
00121 FS_Vector <dims,T>& operator += (const T &);
00122 FS_Vector <dims,T>& operator -= (const T &);
00123 FS_Vector <dims,T>& operator *= (const T &);
00124 FS_Vector <dims,T>& operator /= (const T &);
00125
00126 FS_Vector <dims,T> operator + (const FS_Vector<dims,T>&) const;
00127 FS_Vector <dims,T> operator - (const FS_Vector<dims,T>&) const;
00128 FS_Vector <dims,T> operator + (const T &) const;
00129 FS_Vector <dims,T> operator - (const T &) const;
00130 FS_Vector <dims,T> operator * (const T &) const;
00131 FS_Vector <dims,T> operator / (const T &) const;
00132
00133 FS_Vector <dims,T> operator - () const;
00134
00135 FS_Vector <dims,T> incr (const unsigned long, const T = (T)1) const;
00136
00137
00138 FS_Vector<dims,T> mult (const T&) const;
00139
00140 FS_Vector<dims,T> plus (const T&) const;
00141
00142 FS_Vector<dims,T> minus (const T&) const;
00143
00144
00145
00146 friend STD__ ostream& operator << FGD (STD__ ostream&, const FS_Vector<dims,T>&);
00147 friend STD__ istream& operator >> FGD (STD__ istream&, FS_Vector<dims,T>&);
00148
00149 bool contains (const T&, unsigned long* = 0) const;
00150
00151 T min () const;
00152 T max () const;
00153 T sum () const;
00154 double fabssqr () const;
00155 double fabs () const;
00156 T abs () const;
00157
00158 #if 1
00159
00160 bool operator <= (const FS_Vector<dims,T>& fv) const
00161 { return fabssqr() <= fv.fabssqr(); }
00162 bool operator >= (const FS_Vector<dims,T>& fv) const
00163 { return fabssqr() >= fv.fabssqr(); }
00164 bool operator < (const FS_Vector<dims,T>& fv) const
00165 { return !((*this) >= fv); }
00166 bool operator > (const FS_Vector<dims,T>& fv) const
00167 { return !((*this) <= fv); }
00168 #endif
00169
00170 #if 0
00171 friend NOINST T min FGD (const FS_Vector<dims,T>&);
00172 friend NOINST T max FGD (const FS_Vector<dims,T>&);
00173 friend NOINST T sum FGD (const FS_Vector<dims,T>&);
00174
00175 friend NOINST double MATH__ fabs FGD (const FS_Vector<dims,T>&);
00176
00177 friend NOINST T CSTD__ abs FGD (const FS_Vector<dims,T>&);
00178
00179 friend NOINST double fabssqr FGD (const FS_Vector<dims,T>&);
00180 #endif
00181
00182 friend T dot FGD (const FS_Vector<dims,T>&, const FS_Vector<dims,T>&);
00183
00184 #if 0
00185 template <unsigned dims, typename T, unsigned d2>
00186 friend FS_Vector<d2,T> slice (const FS_Vector<dims,T>&, const unsigned, const unsigned = dims);
00187 #endif
00188
00189
00190 T* vecptr () const { return (T*)x; }
00191 T* get_fortran_vector () const { return vecptr (); }
00192
00193
00194 } ;
00195
00196 template <unsigned dims, typename T>
00197 inline FS_Vector<dims,T>::FS_Vector (const BVector<T> & bv)
00198 {
00199 BCHKNR (bv.size() != dims, FSVecErr, Wrong dim in FS_Vector BVector constructor, bv.size());
00200 CSTD__ memcpy (x, bv.vecptr(), sizeof(T)*dims);
00201 }
00202
00203 #ifndef NO_POD
00204 template <unsigned dims, typename T>
00205 inline FS_Vector<dims,T>::FS_Vector (const vararg va, ...)
00206 {
00207 BCHKNR ((unsigned)va != dims, FSVecErr, No. of vararg params unequals dimension, va);
00208 clear ();
00209 va_list vl; va_start (vl, va);
00210 for (unsigned long i = 0; i < MIN ((unsigned)va,dims); ++i)
00211 x[i] = va_arg (vl, T);
00212 va_end (vl);
00213 }
00214 #endif
00215
00216 template <unsigned dims, typename T>
00217 inline FS_Vector<dims,T>::operator BVector<T> () const
00218 {
00219 BVector<T> bv (dims);
00220 CSTD__ memcpy (&bv(0), x, sizeof(T) * dims);
00221 return bv;
00222 }
00223
00224 template <unsigned dims, typename T>
00225 inline const T& FS_Vector<dims,T>::operator [] (const unsigned long i) const
00226 {
00227 BCHK (i >= dims, FSVecErr, FS_Vector idx out of range, i, x[0]);
00228 return x[i];
00229 }
00230 template <unsigned dims, typename T>
00231 inline T& FS_Vector<dims,T>::operator [] (const unsigned long i)
00232 {
00233 BCHK (i >= dims, FSVecErr, FS_Vector idx out of range, i, x[0]);
00234 return x[i];
00235 }
00236 template <unsigned dims, typename T>
00237 inline const T& FS_Vector<dims,T>::operator () (const unsigned long i) const
00238 {
00239 BCHK (i >= dims, FSVecErr, FS_Vector idx out of range, i, x[0]);
00240 return x[i];
00241 }
00242 template <unsigned dims, typename T>
00243 inline T& FS_Vector<dims,T>::operator () (const unsigned long i)
00244 {
00245 BCHK (i >= dims, FSVecErr, FS_Vector idx out of range, i, x[0]);
00246 return x[i];
00247 }
00248
00249 template <unsigned dims, typename T>
00250 inline FS_Vector<dims,T>& FS_Vector<dims,T>::fill (const T& v)
00251 {
00252 for (unsigned long i = 0; i < dims; ++i)
00253 x[i] = v;
00254 return *this;
00255 }
00256
00257 template <unsigned dims, typename T>
00258 inline FS_Vector<dims,T>& FS_Vector<dims,T>::operator = (const FS_Vector <dims,T>& fv)
00259 {
00260 CSTD__ memcpy (x, fv.x, sizeof(T)*dims);
00261 return *this;
00262 }
00263
00264 template <unsigned dims, typename T>
00265 inline bool FS_Vector<dims,T>::operator == (const FS_Vector <dims,T>& fv) const
00266 {
00267 return !(CSTD__ memcmp (x, fv.x, sizeof(T)*dims));
00268 }
00269
00270 #if 0
00271 template <unsigned dims, typename T>
00272 inline bool FS_Vector<dims,T>::operator <= (const FS_Vector <dims,T>& fv) const
00273 {
00274 return (fabsqr() <= fv.fabssqr());
00275 }
00276
00277 template <unsigned dims, typename T>
00278 inline bool FS_Vector<dims,T>::operator >= (const FS_Vector <dims,T>& fv) const
00279 {
00280 return (fabsqr() >= fv.fabssqr());
00281 }
00282 #endif
00283
00284 #define FSV_ASS_FSV(op) \
00285 template <unsigned dims, typename T> \
00286 inline FS_Vector<dims,T>& FS_Vector<dims,T>::operator op (const FS_Vector <dims,T>& fv) \
00287 { \
00288 for (unsigned long i = 0; i < dims; ++i) \
00289 x[i] op fv[i]; \
00290 return *this; \
00291 }
00292
00293 FSV_ASS_FSV (+=)
00294 FSV_ASS_FSV (-=)
00295
00296 #define FSV_NOASS_FSV(op) \
00297 template <unsigned dims, typename T> \
00298 inline FS_Vector<dims,T> FS_Vector<dims,T>::operator op (const FS_Vector <dims,T>& fv) const \
00299 { \
00300 FS_Vector <dims,T> rv; \
00301 for (unsigned long i = 0; i < dims; ++i) \
00302 rv[i] = x[i] op fv[i]; \
00303 return rv; \
00304 }
00305
00306 FSV_NOASS_FSV (+)
00307 FSV_NOASS_FSV (-)
00308
00309 #define FSV_ASS_T(op) \
00310 template <unsigned dims, typename T> \
00311 inline FS_Vector<dims,T>& FS_Vector<dims,T>::operator op (const T& v) \
00312 { \
00313 for (unsigned long i = 0; i < dims; ++i) \
00314 x[i] op v; \
00315 return *this; \
00316 }
00317
00318 FSV_ASS_T (+=)
00319 FSV_ASS_T (-=)
00320 FSV_ASS_T (*=)
00321
00322
00323 #define FSV_NOASS_T(op) \
00324 template <unsigned dims, typename T> \
00325 inline FS_Vector<dims,T> FS_Vector<dims,T>::operator op (const T& v) const \
00326 { \
00327 FS_Vector<dims,T> rv; \
00328 for (unsigned long i = 0; i < dims; ++i) \
00329 rv[i] = x[i] op v; \
00330 return rv; \
00331 }
00332
00333 FSV_NOASS_T (+)
00334 FSV_NOASS_T (-)
00335 FSV_NOASS_T (*)
00336
00337
00338 template <unsigned dims, typename T>
00339 inline FS_Vector<dims,T>& FS_Vector<dims,T>::operator /= (const T& v)
00340 {
00341 BCHK (v == (T)0, FSVecErr, Division by zero, 0, *this);
00342 for (unsigned long i = 0; i < dims; ++i)
00343 x[i] /= v;
00344 return *this;
00345 }
00346
00347
00348 template <unsigned dims, typename T>
00349 inline FS_Vector<dims,T> FS_Vector<dims,T>::operator / (const T& v) const
00350 {
00351 FS_Vector<dims,T> rv;
00352 BCHK (v == (T)0, FSVecErr, Division by zero, 0, rv);
00353 for (unsigned long i = 0; i < dims; ++i)
00354 rv[i] = x[i] / v;
00355 return rv;
00356 }
00357
00358
00359 template <unsigned dims, typename T>
00360 inline FS_Vector <dims,T> FS_Vector <dims,T>::operator - () const
00361 {
00362 FS_Vector<dims,T> rv;
00363 for (unsigned long i = 0; i < dims; ++i)
00364 rv[i] = -x[i];
00365 return rv;
00366 }
00367
00368
00369 template <unsigned dims, typename T>
00370 inline FS_Vector <dims,T> FS_Vector <dims,T>::incr (const unsigned long wh, const T i) const
00371 {
00372 FS_Vector fv (*this);
00373 BCHK (wh >= dims, FSVecErr, Tried to change not-exitsting idx, wh, fv);
00374 fv.x[wh] += i;
00375 return fv;
00376 }
00377
00378
00379 template <unsigned dims, typename T>
00380 STD__ ostream& operator << (STD__ ostream& os, const FS_Vector<dims,T>& fv)
00381 {
00382 if (!dims) return os;
00383 os << fv.x[0];
00384 for (unsigned long i = 1; i < dims; ++i)
00385 os << ", " << fv.x[i];
00386 return os;
00387 }
00388
00389 #ifndef PTR
00390 template <unsigned dims, typename T>
00391 STD__ istream& operator >> (STD__ istream& in, FS_Vector<dims,T>& v)
00392 {
00393 T r ALIGN(MIN_ALIGN) = 0;
00394 char s = ',';
00395
00396 if( !( in >> s ) )
00397 return in;
00398 if (s != '(') in.putback(s);
00399 if( !( in >> r ) )
00400 return in;
00401 v[0] = r;
00402 for (unsigned long i = 1; i < dims; ++i) {
00403 in >> s;
00404 if (s != ',') in.putback(s);
00405 if( !( in >> r ) )
00406 return in;
00407 v[i] = r;
00408 }
00409 return in;
00410 }
00411 #else
00412 template <unsigned dims, typename T>
00413 STD__ istream& operator >> (STD__ istream& in, FS_Vector<dims,T>& v)
00414 {
00415 STD__ cerr << "fs_vector: Input on pointer types not possible!" << STD__ endl;
00416 abort ();
00417 return in;
00418 }
00419 #endif
00420
00421
00422 template <unsigned dims, typename T>
00423 inline bool FS_Vector<dims,T>::contains (const T& val, unsigned long *ind) const
00424 {
00425 for (register unsigned long i = 0; i < dims; ++i)
00426 if (val == x[i]) {
00427 if (ind) *ind = i;
00428 return true;
00429 }
00430 return false;
00431 }
00432
00433 template <unsigned dims, typename T>
00434 INLINE T FS_Vector<dims,T>::min () const
00435 {
00436 if (dims == 0) return 0;
00437 T min ALIGN(MIN_ALIGN) = x[0];
00438 for (register unsigned long t = 1; t < dims; ++t)
00439 if (x[t] < min)
00440 min = x[t];
00441 return min;
00442 }
00443
00444 template <unsigned dims, typename T>
00445 INLINE T FS_Vector<dims,T>::max () const
00446 {
00447 if (dims == 0) return 0;
00448 T max ALIGN(MIN_ALIGN) = x[0];
00449 for (register unsigned long t = 1; t < dims; ++t)
00450 if (x[t] > max)
00451 max = x[t];
00452 return max;
00453 }
00454
00455 template <unsigned dims, typename T>
00456 INLINE T FS_Vector<dims,T>::sum () const
00457 {
00458 T sum ALIGN(MIN_ALIGN) = 0;
00459 for (register unsigned long t = 0; t < dims; ++t)
00460 sum += x[t];
00461 return sum;
00462 }
00463
00464
00465 template <unsigned dims, typename T>
00466 inline T dot (const FS_Vector<dims,T>& fv1, const FS_Vector<dims,T>& fv2)
00467 {
00468 if (dims == 0) return 0;
00469 ALIGN3(T s, CPLX__ conj (fv1[0]) * fv2[0] ,MIN_ALIGN2);
00470 for (register unsigned long i = 1; i < dims; ++i)
00471 s += CPLX__ conj (fv1[i]) * fv2[i];
00472 return s;
00473 }
00474
00475 template <unsigned dims, typename T>
00476 inline double FS_Vector<dims,T>::fabssqr () const
00477 {
00478 return CPLX__ real(dot (*this, *this));
00479 }
00480
00481 template <unsigned dims, typename T>
00482 inline double FS_Vector<dims,T>::fabs () const
00483 {
00484 return MATH__ sqrt (fabssqr());
00485 }
00486
00487 template <unsigned dims, typename T>
00488 INLINE T FS_Vector<dims,T>::abs () const
00489 {
00490 return (T) MATH__ sqrt (fabssqr());
00491 }
00492
00493
00494 template <unsigned dims, typename T, unsigned long dims2>
00495 inline FS_Vector<dims,T> slice (const FS_Vector<dims,T>& fv, const unsigned long s, const unsigned long e)
00496 {
00497 FS_Vector<dims2,T> rv; rv.clear();
00498 BCHK (dims2 != e-s, FSVecErr, slice template param is wrong, dims2, rv);
00499 CSTD__ memcpy (rv.x, fv.vecptr()+s, sizeof(T) * (MIN((unsigned)e,dims)-s));
00500 return rv;
00501 }
00502
00503
00504 template <unsigned dims, typename T>
00505 FS_Vector<dims,T> emul (const FS_Vector<dims,T>& f1, const FS_Vector<dims,T>& f2)
00506 {
00507 FS_Vector<dims,T> res;
00508 for (unsigned long i = 0; i < dims; ++i)
00509 res(i) = f1(i) * f2(i);
00510 return res;
00511 }
00512
00513 template <unsigned dims, typename T>
00514 FS_Vector<dims,T> cemul (const FS_Vector<dims,T>& f1, const FS_Vector<dims,T>& f2)
00515 {
00516 FS_Vector<dims,T> res;
00517 for (unsigned long i = 0; i < dims; ++i)
00518 res(i) = CPLX__ conj(f1(i)) * f2(i);
00519 return res;
00520 }
00521
00522 template <unsigned dims, typename T>
00523 FS_Vector<dims,T> ediv (const FS_Vector<dims,T>& f1, const FS_Vector<dims,T>& f2)
00524 {
00525 FS_Vector<dims,T> res;
00526 for (unsigned long i = 0; i < dims; ++i)
00527 res(i) = f1(i) / f2(i);
00528 return res;
00529 }
00530
00531 template <unsigned dims, typename T>
00532 FS_Vector<dims,T> cediv (const FS_Vector<dims,T>& f1, const FS_Vector<dims,T>& f2)
00533 {
00534 FS_Vector<dims,T> res;
00535 for (unsigned long i = 0; i < dims; ++i)
00536 res(i) = CPLX__ conj(f1(i)) / f2(i);
00537 return res;
00538 }
00539
00540
00541 INST2(template <unsigned dims, typename T> class FS_Vector friend double fabssqr (const FS_Vector<dims,T>&);)
00542 template <unsigned dims, typename T>
00543 inline double fabssqr (const FS_Vector<dims,T>& fv)
00544 { return fv.fabssqr(); }
00545
00546
00547 #define FSV_MEM_FRD(nm,op) \
00548 template <unsigned dims, typename T> \
00549 INLINE FS_Vector<dims,T> FS_Vector<dims,T>:: nm (const T& v) const \
00550 { \
00551 FS_Vector<dims,T> res; \
00552 for (unsigned long i = 0; i < dims; ++i) \
00553 res.x[i] = v op x[i]; \
00554 return res; \
00555 }
00556
00557 FSV_MEM_FRD(mult,*)
00558 FSV_MEM_FRD(plus,*)
00559 FSV_MEM_FRD(minus,*)
00560
00561
00562 INST3(template <unsigned dims, typename T> class FS_Vector friend FS_Vector<dims,T> operator * (const T&, const FS_Vector<dims,T>&);)
00563 template <unsigned dims, typename T>
00564 inline FS_Vector<dims,T> operator * (const T& v, const FS_Vector<dims,T>& fv)
00565 { return fv.mult (v); }
00566
00567 INST3(template <unsigned dims, typename T> class FS_Vector friend FS_Vector<dims,T> operator + (const T&, const FS_Vector<dims,T>&);)
00568 template <unsigned dims, typename T>
00569 inline FS_Vector<dims,T> operator + (const T& v, const FS_Vector<dims,T>& fv)
00570 { return fv.plus(v); }
00571
00572 INST3(template <unsigned dims, typename T> class FS_Vector friend FS_Vector<dims,T> operator - (const T&, const FS_Vector<dims,T>&);)
00573 template <unsigned dims, typename T>
00574 inline FS_Vector<dims,T> operator - (const T& v, const FS_Vector<dims,T>& fv)
00575 { return fv.minus(v); }
00576
00577
00578
00579
00580
00581
00582 INST2(template <unsigned dims, typename T> class FS_Vector friend T min (const FS_Vector<dims,T>&);)
00583 template <unsigned dims, typename T>
00584 inline T min (const FS_Vector<dims,T>& fv)
00585 { return fv.min(); }
00586
00587 INST2(template <unsigned dims, typename T> class FS_Vector friend T max (const FS_Vector<dims,T>&);)
00588 template <unsigned dims, typename T>
00589 inline T max (const FS_Vector<dims,T>& fv)
00590 { return fv.max(); }
00591
00592 INST2(template <unsigned dims, typename T> class FS_Vector friend T sum (const FS_Vector<dims,T>&);)
00593 template <unsigned dims, typename T>
00594 inline T sum (const FS_Vector<dims,T>& fv)
00595 { return fv.sum(); }
00596
00597 NAMESPACE_END
00598
00599 NAMESPACE_CSTD
00600
00601 INST2(template <unsigned dims, typename T> class TBCI__ FS_Vector friend double fabs (const TBCI__ FS_Vector<dims,T>&);)
00602 template <unsigned dims, typename T>
00603 inline double fabs (const TBCI__ FS_Vector<dims,T>& fv)
00604 { return fv.fabs(); }
00605
00606 #if (_MSC_VER) && (_MSC_VER == 1200)
00607
00608 #else
00609 INST2(template <unsigned dims, typename T> class TBCI__ FS_Vector friend T abs (const TBCI__ FS_Vector<dims,T>&);)
00610 template <unsigned dims, typename T>
00611 inline T abs (const TBCI__ FS_Vector<dims,T>& fv)
00612 { return fv.abs(); }
00613 #endif
00614 NAMESPACE_CSTD_END
00615
00616 #endif