00001
00013 #ifndef TBCI_VECTOR_H
00014 #define TBCI_VECTOR_H
00015
00016 #include "bvector.h"
00017
00018
00019
00020 #include "vec_kern_unr_pref.h"
00021
00026 #ifndef TBCI_NO_SIMD
00027 # include "vec_kern_special.h"
00028 #endif
00029
00030
00031 #if !defined(NO_GD) && !defined(AUTO_DECL)
00032 # include "vector_gd.h"
00033 #endif
00034
00035 NAMESPACE_TBCI
00036
00037
00038
00039 template <typename T> class Vector;
00040 template <typename T> class TVector;
00041 template <typename T> class TSVector;
00042 template <typename T> class Matrix;
00043 template <typename T> class TMatrix;
00044 template <typename T> class TSMatrix;
00045 template <typename T> class F_Matrix;
00046 template <typename T> class F_TMatrix;
00047 template <typename T> class F_TSMatrix;
00048 template <typename T> class Mat_Brack;
00049 template <typename T> class CRMatrix;
00050 template <typename T> class CSCMatrix;
00051 template <typename T> class BdMatrix;
00052 template <typename T> class Symm_BdMatrix;
00053
00059 #if defined(SMP) && !defined(SMP_VECSLICE)
00060 # define SMP_VECSLICE 16384
00061 #endif
00062 #if defined(SMP) && defined(__i386__) && !defined(SMP_VECSCALAR)
00063 # define NOSMP_VECSCALAR
00064 # define NOSMP_VECFABS
00065 #endif
00066
00067 #ifdef PRAGMA_I
00068 # pragma interface "vector.h"
00069 #endif
00070
00071
00072
00080 template <typename T>
00081 class TVector : public BVector<T>, public Vector_Sig<T>
00082 {
00083 public:
00084 friend class Vector<T>;
00085 friend class TSVector<T>;
00086 friend class Matrix<T>;
00087 friend class BdMatrix<T>;
00088
00089 typedef T value_type;
00090 typedef T element_type;
00091 typedef T aligned_value_type TALIGN(MIN_ALIGN2);
00092
00093 explicit TVector (const unsigned long d = 0) : BVector<T> (d) {}
00094 TVector (const T& val, const unsigned long d) : BVector<T> (val, d) {}
00095 TVector (const BVector<T>& bv) : BVector<T> (bv) {}
00096 TVector (const Vector<T>& v) : BVector<T> ( v) {}
00097
00098 TVector (const TVector<T>& tv) HOT
00099 { this->dim = tv.dim; this->vec = tv.vec; }
00100 explicit TVector (const TSVector<T>& ts)
00101 { ts.eval (); this->vec = ts.vec; this->dim = ts.dim; }
00102 TVector (const Mat_Brack<T>&);
00103
00104 ~TVector () { this->keep = true; }
00105
00106
00107
00108
00109
00110
00111
00112
00113 unsigned long size () const { return this->dim; }
00114
00115 TVector<T>& operator = (const T& a)
00116 { this->BVector<T>::operator = (a); return *this; }
00117 TVector<T>& operator = (const Vector<T>& v)
00118 { this->BVector<T>::operator = (v); return *this; }
00120 TVector<T>& operator = (const TVector<T>& tv);
00121 TVector<T>& operator = (const TSVector<T>& ts);
00122
00123 bool operator == (const TVector<T>& tv) const
00124 { Vector<T> v(*this); if (LIKELY(this->vec == tv.vec)) return true;
00125 Vector<T> v2(tv); return (v == v2); }
00126
00127 bool operator != (const TVector<T>& tv) const { return !(*this == tv); }
00128 bool operator == (const Vector<T>& v) const
00129 { Vector<T> tv(*this); return (tv == v); }
00130 bool operator != (const Vector<T>& v) const { return !(*this == v); }
00131 bool operator == (const BVector<T>& bv) const
00132 { Vector<T> v(*this); return bv.operator == (v); }
00133 bool operator != (const BVector<T>& v) const { return !(*this == v); }
00134 bool operator == (const TSVector<T>& tsv) const { return (tsv == *this); }
00135 bool operator != (const TSVector<T>& tsv) const { return !(*this == tsv); }
00136
00137 TVector<T>& operator += (const T&);
00138 TVector<T>& operator -= (const T&);
00139 TVector<T>& operator *= (const T&);
00140 TVector<T>& operator /= (const T&);
00141
00142 TVector<T>& operator += (const Vector<T>&) HOT;
00143 TVector<T>& operator -= (const Vector<T>&) HOT;
00144
00145 TVector<T>& operator += (const TVector<T>& tv)
00146 { return this->operator += (Vector<T> (tv)); }
00147 TVector<T>& operator -= (const TVector<T>& tv)
00148 { return this->operator -= (Vector<T> (tv)); }
00149
00150 TVector<T>& operator += (const TSVector<T>& tsv) HOT;
00151 TVector<T>& operator -= (const TSVector<T>& tsv) HOT;
00152
00153
00154
00155 T min () { Vector<T> th (*this); return th.min (); }
00156 T max () { Vector<T> th (*this); return th.max (); }
00157 T sum () { Vector<T> th (*this); return th.sum (); }
00158
00159 double fabssqr () { Vector<T> th (*this); return th.fabssqr (); }
00160 double fabs () { Vector<T> th (*this); return th.fabs (); }
00161 T abs () { Vector<T> th (*this); return th.abs (); }
00162
00163
00164
00165
00166
00167 TVector<T>& operator + (const Vector<T>&) HOT;
00168 TVector<T>& operator - (const Vector<T>&) HOT;
00169 TVector<T>& operator + (const TSVector<T>& ts) HOT;
00170 TVector<T>& operator - (const TSVector<T>& ts) HOT;
00171 const TVector<T>& operator + (const TVector<T>& a) HOT;
00172 const TVector<T>& operator - (const TVector<T>& a) HOT;
00173
00174
00175 #ifdef TV_OP_FRIENDS
00176 friend NOINST const TVector<T>& operator + FGD (const T&, const TVector<T>&);
00177 friend NOINST const TVector<T>& operator - FGD (const T&, const TVector<T>&);
00178 friend NOINST TSVector<T> operator * FGD (const T&, const TVector<T>&);
00179 friend NOINST TSVector<T> operator / FGD (const T&, const TVector<T>&);
00180 friend NOINST TVector<T> operator + FGD (const T&, const Vector<T>&);
00181 friend NOINST TVector<T> operator - FGD (const T&, const Vector<T>&);
00182 friend NOINST TSVector<T> operator * FGD (const T&, const Vector<T>&);
00183
00184
00185
00186 friend NOINST TVector<T> operator + FGD (const T&, const TSVector<T>&);
00187 friend NOINST TVector<T> operator - FGD (const T&, const TSVector<T>&);
00188 #endif
00189
00190
00191 T operator () (const unsigned long i)
00192 { T val = this->vec[i]; this->destroy (); return val; }
00193
00194 T operator [] (const unsigned long i) { return this->operator() (i); }
00195
00196
00197 const T& getcref (const unsigned long i) const { return this->vec[i]; }
00198 typename tbci_traits<T>::const_refval_type
00199 get (const unsigned long i) const { return this->vec[i]; }
00200
00201 T& setval (const unsigned long i) const { return this->vec[i]; }
00202 T& setval (const T& val, const unsigned long i) const { return this->vec[i] = val; }
00203 T& set (const T& val, const unsigned long i) const { return this->vec[i] = val; }
00204
00205 TVector<T> slice (const unsigned long, const unsigned long);
00206 TVector<T>& incr (const unsigned long, const T = (T)1);
00207
00208 TVector<T>& operator + (const T&);
00209 TVector<T>& operator - (const T&);
00210 TSVector<T> operator * (const T&);
00211 TSVector<T> operator / (const T&);
00212 TSVector<T> operator - ();
00213
00214 T operator * (const Vector<T>& v)
00215 { Vector<T> th (*this); return th * v; }
00216 T operator * (TVector<T>& tv)
00217 { Vector<T> th (*this); Vector<T> v (tv); return th * v; }
00218
00219
00220 friend TVector<T> conj FGD (const Vector<T>&);
00221 friend TVector<T> real FGD (const Vector<T>&);
00222 friend TVector<T> imag FGD (const Vector<T>&);
00223
00224 friend TVector<T>& conj FGD (TVector<T>&);
00225 friend TVector<T>& real FGD (TVector<T>&);
00226 friend TVector<T>& imag FGD (TVector<T>&);
00227
00228 static const char* vec_info() { return "TVector"; }
00229
00230 friend STD__ ostream& operator << FGD (STD__ ostream&, const TVector<T>&);
00231
00232 #ifndef HAVE_PROMOTION_BUG
00233
00234
00235
00236
00237 template <typename U> explicit TVector (const BVector<U>& bv) : BVector<T> (bv) {}
00238 #endif
00239
00240 friend NOINST void FRIEND_TBCI2__ do_mat_vec_mult FGD (const unsigned start, const unsigned end, \
00241 TVector<T> * res, const Matrix<T> * mat, const Vector<T> * vec);
00242 friend NOINST void FRIEND_TBCI2__ do_mat_tsv_mult FGD (const unsigned start, const unsigned end, \
00243 TVector<T> * res, const Matrix<T> * mat, const TSVector<T> * rsv);
00244 friend NOINST void FRIEND_TBCI2__ do_mat_vec_transmult FGD (const unsigned start, const unsigned end, \
00245 TVector<T> * res, const Matrix<T> * mat, const Vector<T> * vec);
00246 } ;
00247
00248
00249
00250 template <typename T>
00251 inline TVector<T>& TVector<T>::operator = (const TVector<T>& tv)
00252 {
00253 BCHK (this->dim != tv.dim, VecErr, diff size in assignment, tv.dim, *this);
00254 if (LIKELY(this->vec != tv.vec)) {
00255 this->destroy (); this->vec = tv.vec; this->dim = tv.dim;
00256 }
00257 return *this;
00258 }
00259
00260
00261 template <typename T>
00262 inline STD__ ostream& operator << (STD__ ostream& os, const TVector<T>& tv)
00263 { Vector<T> v(tv); return os << (BVector<T>)v; }
00264
00265 template <typename T>
00266 inline TVector<T>& TVector<T>::operator = (const TSVector<T>& tsv)
00267 {
00268 BCHK (this->dim != tsv.dim, VecErr, diff size in assignment, tsv.dim, *this);
00269 if (LIKELY(tsv.mut && tsv.fac == (T)1)) {
00270 this->destroy (); this->vec = tsv.vec;
00271 }
00272 else
00273 tsv.eval (this->vec);
00274 return *this;
00275 }
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285 #if !defined(SMP) || defined(NOSMP_VECVEC)
00286
00287 #else
00288
00289 INST(template <typename T> class Vector friend void job_vec_vec_add (struct thr_ctrl *);)
00291 template <typename T>
00292 void job_vec_vec_add (struct thr_ctrl *tc)
00293 {
00294 do_vec_vec_add (tc->t_size, (T*)(tc->t_par[0]),
00295 (const T*)(tc->t_par[1]), (const T*)(tc->t_par[2]));
00296 }
00297 INST(template <typename T> class Vector friend void job_vec_vec_sub (struct thr_ctrl *);)
00299 template <typename T>
00300 void job_vec_vec_sub (struct thr_ctrl *tc)
00301 {
00302 do_vec_vec_sub (tc->t_size, (T*)(tc->t_par[0]),
00303 (const T*)(tc->t_par[1]), (const T*)(tc->t_par[2]));
00304 }
00305 INST(template <typename T> class Vector friend void job_vec_add_vec (struct thr_ctrl *);)
00307 template <typename T>
00308 void job_vec_add_vec (struct thr_ctrl *tc)
00309 {
00310 do_vec_add_vec (tc->t_size, (T*)(tc->t_par[0]),
00311 (const T*)(tc->t_par[1]));
00312 }
00313 INST(template <typename T> class Vector friend void job_vec_sub_vec (struct thr_ctrl *);)
00315 template <typename T>
00316 void job_vec_sub_vec (struct thr_ctrl *tc)
00317 {
00318 do_vec_sub_vec (tc->t_size, (T*)(tc->t_par[0]),
00319 (const T*)(tc->t_par[1]));
00320 }
00321 INST(template <typename T> class Vector friend void job_vec_sub_vec_inv (struct thr_ctrl *);)
00323 template <typename T>
00324 void job_vec_sub_vec_inv (struct thr_ctrl *tc)
00325 {
00326 do_vec_sub_vec_inv (tc->t_size, (T*)(tc->t_par[0]),
00327 (const T*)(tc->t_par[1]));
00328 }
00329 INST(template <typename T> class Vector friend void job_vec_val_add (struct thr_ctrl *);)
00331 template <typename T>
00332 void job_vec_val_add (struct thr_ctrl *tc)
00333 {
00334 do_vec_val_add (tc->t_size, (T*)(tc->t_par[0]),
00335 (const T*)(tc->t_par[1]), *(const T*)(tc->t_par[2]));
00336 }
00337 INST(template <typename T> class Vector friend void job_vec_val_sub (struct thr_ctrl *);)
00339 template <typename T>
00340 void job_vec_val_sub (struct thr_ctrl *tc)
00341 {
00342 do_vec_val_sub (tc->t_size, (T*)(tc->t_par[0]),
00343 (const T*)(tc->t_par[1]), *(const T*)(tc->t_par[2]));
00344 }
00345 INST(template <typename T> class Vector friend void job_vec_val_mul (struct thr_ctrl *);)
00347 template <typename T>
00348 void job_vec_val_mul (struct thr_ctrl *tc)
00349 {
00350 do_vec_val_mul (tc->t_size, (T*)(tc->t_par[0]),
00351 (const T*)(tc->t_par[1]), *(const T*)(tc->t_par[2]));
00352 }
00353 INST(template <typename T> class Vector friend void job_val_vec_mul (struct thr_ctrl *);)
00355 template <typename T>
00356 void job_val_vec_mul (struct thr_ctrl *tc)
00357 {
00358 do_val_vec_mul (tc->t_size, (T*)(tc->t_par[0]),
00359 (const T*)(tc->t_par[1]), *(const T*)(tc->t_par[2]));
00360 }
00361 INST(template <typename T> class Vector friend void job_val_vec_add (struct thr_ctrl *);)
00363 template <typename T>
00364 void job_val_vec_add (struct thr_ctrl *tc)
00365 {
00366 do_val_vec_add (tc->t_size, (T*)(tc->t_par[0]),
00367 (const T*)(tc->t_par[1]), *(const T*)(tc->t_par[2]));
00368 }
00369 INST(template <typename T> class Vector friend void job_val_vec_sub (struct thr_ctrl *);)
00371 template <typename T>
00372 void job_val_vec_sub (struct thr_ctrl *tc)
00373 {
00374 do_val_vec_sub (tc->t_size, (T*)(tc->t_par[0]),
00375 (const T*)(tc->t_par[1]), *(const T*)(tc->t_par[2]));
00376 }
00377 INST(template <typename T> class Vector friend void job_val_vec_div (struct thr_ctrl *);)
00379 template <typename T>
00380 void job_val_vec_div (struct thr_ctrl *tc)
00381 {
00382 do_val_vec_div (tc->t_size, (T*)(tc->t_par[0]),
00383 (const T*)(tc->t_par[1]), *(const T*)(tc->t_par[2]));
00384 }
00385 INST(template <typename T> class Vector friend void job_vec_add_val (struct thr_ctrl *);)
00387 template <typename T>
00388 void job_vec_add_val (struct thr_ctrl *tc)
00389 {
00390 do_vec_add_val (tc->t_size, (T*)(tc->t_par[0]),
00391 *(const T*)(tc->t_par[1]));
00392 }
00393 INST(template <typename T> class Vector friend void job_val_add_vec (struct thr_ctrl *);)
00395 template <typename T>
00396 void job_val_add_vec (struct thr_ctrl *tc)
00397 {
00398 do_val_add_vec(tc->t_size, (T*)(tc->t_par[0]),
00399 *(const T*)(tc->t_par[1]));
00400 }
00401 INST(template <typename T> class Vector friend void job_vec_sub_val (struct thr_ctrl *);)
00403 template <typename T>
00404 void job_vec_sub_val (struct thr_ctrl *tc)
00405 {
00406 do_vec_sub_val (tc->t_size, (T*)(tc->t_par[0]),
00407 *(const T*)(tc->t_par[1]));
00408 }
00409 INST(template <typename T> class Vector friend void job_val_sub_vec (struct thr_ctrl *);)
00411 template <typename T>
00412 void job_val_sub_vec (struct thr_ctrl *tc)
00413 {
00414 do_val_sub_vec(tc->t_size, (T*)(tc->t_par[0]),
00415 *(const T*)(tc->t_par[1]));
00416 }
00417 INST(template <typename T> class Vector friend void job_vec_mul_val (struct thr_ctrl *);)
00419 template <typename T>
00420 void job_vec_mul_val (struct thr_ctrl *tc)
00421 {
00422 do_vec_mul_val (tc->t_size, (T*)(tc->t_par[0]),
00423 *(const T*)(tc->t_par[1]));
00424 }
00425 INST(template <typename T> class Vector friend void job_vec_div_val (struct thr_ctrl *);)
00427 template <typename T>
00428 void job_vec_div_val (struct thr_ctrl *tc)
00429 {
00430 do_vec_div_val (tc->t_size, (T*)(tc->t_par[0]),
00431 *(const T*)(tc->t_par[1]));
00432 }
00433 INST(template <typename T> class Vector friend void job_val_div_vec (struct thr_ctrl *);)
00435 template <typename T>
00436 void job_val_div_vec (struct thr_ctrl *tc)
00437 {
00438 do_val_div_vec(tc->t_size, (T*)(tc->t_par[0]),
00439 *(const T*)(tc->t_par[1]));
00440 }
00441
00442
00443 INST(template <typename T> class Vector friend void job_vec_svc_add (struct thr_ctrl *);)
00445 template <typename T>
00446 void job_vec_svc_add (struct thr_ctrl *tc)
00447 {
00448 do_vec_svc_add (tc->t_size, (T*)(tc->t_par[0]),
00449 (const T*)(tc->t_par[1]), (const T*)(tc->t_par[2]),
00450 *(const T*)(tc->t_par[3]));
00451 }
00452 INST(template <typename T> class Vector friend void job_svc_vec_add (struct thr_ctrl *);)
00454 template <typename T>
00455 void job_svc_vec_add (struct thr_ctrl *tc)
00456 {
00457 do_svc_vec_add (tc->t_size, (T*)(tc->t_par[0]),
00458 (const T*)(tc->t_par[1]), (const T*)(tc->t_par[2]),
00459 *(const T*)(tc->t_par[3]));
00460 }
00461 INST(template <typename T> class Vector friend void job_svc_svc_add (struct thr_ctrl *);)
00463 template <typename T>
00464 void job_svc_svc_add (struct thr_ctrl *tc)
00465 {
00466 do_svc_svc_add (tc->t_size, (T*)(tc->t_par[0]),
00467 (const T*)(tc->t_par[1]), (const T*)(tc->t_par[2]),
00468 *(const T*)(tc->t_par[3]), *(const T*)(tc->t_par[4]));
00469 }
00471 INST(template <typename T> class Vector friend void job_vec_svc_sub (struct thr_ctrl *);)
00472 template <typename T>
00473 void job_vec_svc_sub (struct thr_ctrl *tc)
00474 {
00475 do_vec_svc_sub (tc->t_size, (T*)(tc->t_par[0]),
00476 (const T*)(tc->t_par[1]), (const T*)(tc->t_par[2]),
00477 *(const T*)(tc->t_par[3]));
00478 }
00479 INST(template <typename T> class Vector friend void job_svc_vec_sub (struct thr_ctrl *);)
00481 template <typename T>
00482 void job_svc_vec_sub (struct thr_ctrl *tc)
00483 {
00484 do_svc_vec_sub (tc->t_size, (T*)(tc->t_par[0]),
00485 (const T*)(tc->t_par[1]), (const T*)(tc->t_par[2]),
00486 *(const T*)(tc->t_par[3]));
00487 }
00488 INST(template <typename T> class Vector friend void job_svc_svc_sub (struct thr_ctrl *);)
00490 template <typename T>
00491 void job_svc_svc_sub (struct thr_ctrl *tc)
00492 {
00493 do_svc_svc_sub (tc->t_size, (T*)(tc->t_par[0]),
00494 (const T*)(tc->t_par[1]), (const T*)(tc->t_par[2]),
00495 *(const T*)(tc->t_par[3]), *(const T*)(tc->t_par[4]));
00496 }
00497 INST(template <typename T> class Vector friend void job_vec_add_svc (struct thr_ctrl *);)
00499 template <typename T>
00500 void job_vec_add_svc (struct thr_ctrl *tc)
00501 {
00502 do_vec_add_svc (tc->t_size, (T*)(tc->t_par[0]),
00503 (const T*)(tc->t_par[1]),
00504 *(const T*)(tc->t_par[2]));
00505 }
00506 INST(template <typename T> class Vector friend void job_vec_sub_svc (struct thr_ctrl *);)
00508 template <typename T>
00509 void job_vec_sub_svc (struct thr_ctrl *tc)
00510 {
00511 do_vec_sub_svc (tc->t_size, (T*)(tc->t_par[0]),
00512 (const T*)(tc->t_par[1]),
00513 *(const T*)(tc->t_par[2]));
00514 }
00515 INST(template <typename T> class Vector friend void job_vec_sub_svc_inv (struct thr_ctrl *);)
00517 template <typename T>
00518 void job_vec_sub_svc_inv (struct thr_ctrl *tc)
00519 {
00520 do_vec_sub_svc_inv (tc->t_size, (T*)(tc->t_par[0]),
00521 (const T*)(tc->t_par[1]),
00522 *(const T*)(tc->t_par[2]));
00523 }
00524
00525 INST(template <typename T> class Vector friend void job_svc_val_add (struct thr_ctrl *);)
00527 template <typename T>
00528 void job_svc_val_add (struct thr_ctrl *tc)
00529 {
00530 do_svc_val_add (tc->t_size, (T*)(tc->t_par[0]),
00531 (const T*)(tc->t_par[1]),
00532 *(const T*)(tc->t_par[2]), *(const T*)(tc->t_par[3]));
00533 }
00534 INST(template <typename T> class Vector friend void job_svc_val_sub (struct thr_ctrl *);)
00536 template <typename T>
00537 void job_svc_val_sub (struct thr_ctrl *tc)
00538 {
00539 do_svc_val_sub (tc->t_size, (T*)(tc->t_par[0]),
00540 (const T*)(tc->t_par[1]),
00541 *(const T*)(tc->t_par[2]), *(const T*)(tc->t_par[3]));
00542 }
00543 INST(template <typename T> class Vector friend void job_val_svc_add (struct thr_ctrl *);)
00545 template <typename T>
00546 void job_val_svc_add (struct thr_ctrl *tc)
00547 {
00548 do_val_svc_add (tc->t_size, (T*)(tc->t_par[0]),
00549 (const T*)(tc->t_par[1]),
00550 *(const T*)(tc->t_par[2]), *(const T*)(tc->t_par[3]));
00551 }
00552 INST(template <typename T> class Vector friend void job_val_svc_sub (struct thr_ctrl *);)
00554 template <typename T>
00555 void job_val_svc_sub (struct thr_ctrl *tc)
00556 {
00557 do_val_svc_sub (tc->t_size, (T*)(tc->t_par[0]),
00558 (const T*)(tc->t_par[1]),
00559 *(const T*)(tc->t_par[2]), *(const T*)(tc->t_par[3]));
00560 }
00561 INST(template <typename T> class Vector friend void job_val_svc_div (struct thr_ctrl *);)
00563 template <typename T>
00564 void job_val_svc_div (struct thr_ctrl *tc)
00565 {
00566 do_val_svc_div (tc->t_size, (T*)(tc->t_par[0]),
00567 (const T*)(tc->t_par[1]),
00568 *(const T*)(tc->t_par[2]), *(const T*)(tc->t_par[3]));
00569 }
00570
00571
00572
00573
00574
00575 #endif
00576
00577
00578
00579
00580
00581
00582
00583
00584 #if !defined(SMP) || defined(NOSMP_VECVEC)
00585 #define STD_SMP_TEMPLATE2V(oper, dm, a1, a2) \
00586 do_##oper <T> (dm, a1, a2)
00587 #define STD_SMP_TEMPLATE2C(oper, dm, a1, a2) \
00588 do_##oper <T> (dm, a1, a2)
00589 #define STD_SMP_TEMPLATE3VV(oper, dm, a1, a2, a3) \
00590 do_##oper <T> (dm, a1, a2, a3)
00591 #define STD_SMP_TEMPLATE3VC(oper, dm, a1, a2, a3) \
00592 do_##oper <T> (dm, a1, a2, a3)
00593 #define STD_SMP_TEMPLATE3CC(oper, dm, a1, a2, a3) \
00594 do_##oper <T> (dm, a1, a2, a3)
00595 #define STD_SMP_TEMPLATE4V(oper, dm, a1, a2, a3, a4) \
00596 do_##oper <T> (dm, a1, a2, a3, a4)
00597 #define STD_SMP_TEMPLATE4C(oper, dm, a1, a2, a3, a4) \
00598 do_##oper <T> (dm, a1, a2, a3, a4)
00599 #define STD_SMP_TEMPLATE5(oper, dm, a1, a2, a3, a4, a5) \
00600 do_##oper <T> (dm, a1, a2, a3, a4, a5)
00601
00602 #else
00603
00604 #define _SMP_TMPL2V(oper,st,en,a1,a2,a3,a4,a5) do_##oper <T> (en-st, a1+st, a2+st)
00605 #define _JOB_TMPL2V(oper,st,en,a1,a2,a3,a4,a5) job_##oper <T>, en-st, a1+st, a2+st
00606 #define _SMP_TMPL2C(oper,st,en,a1,a2,a3,a4,a5) do_##oper <T> (en-st, a1+st, a2)
00607 #define _JOB_TMPL2C(oper,st,en,a1,a2,a3,a4,a5) job_##oper <T>, en-st, a1+st, &a2
00608 #define _SMP_TMPL3VV(oper,st,en,a1,a2,a3,a4,a5) do_##oper <T> (en-st, a1+st, a2+st, a3+st)
00609 #define _JOB_TMPL3VV(oper,st,en,a1,a2,a3,a4,a5) job_##oper <T>, en-st, a1+st, a2+st, a3+st
00610 #define _SMP_TMPL3VC(oper,st,en,a1,a2,a3,a4,a5) do_##oper <T> (en-st, a1+st, a2+st, a3)
00611 #define _JOB_TMPL3VC(oper,st,en,a1,a2,a3,a4,a5) job_##oper <T>, en-st, a1+st, a2+st, &a3
00612 #define _SMP_TMPL3CC(oper,st,en,a1,a2,a3,a4,a5) do_##oper <T> (en-st, a1+st, a2, a3)
00613 #define _JOB_TMPL3CC(oper,st,en,a1,a2,a3,a4,a5) job_##oper <T>, en-st, a1+st, &a2, &a3
00614 #define _SMP_TMPL4V(oper,st,en,a1,a2,a3,a4,a5) do_##oper <T> (en-st, a1+st, a2+st, a3+st, a4)
00615 #define _JOB_TMPL4V(oper,st,en,a1,a2,a3,a4,a5) job_##oper <T>, en-st, a1+st, a2+st, a3+st, &a4
00616 #define _SMP_TMPL4C(oper,st,en,a1,a2,a3,a4,a5) do_##oper <T> (en-st, a1+st, a2+st, a3, a4)
00617 #define _JOB_TMPL4C(oper,st,en,a1,a2,a3,a4,a5) job_##oper <T>, en-st, a1+st, a2+st, &a3, &a4
00618 #define _SMP_TMPL5(oper,st,en,a1,a2,a3,a4,a5) do_##oper <T> (en-st, a1+st, a2+st, a3+st, a4, a5)
00619 #define _JOB_TMPL5(oper,st,en,a1,a2,a3,a4,a5) job_##oper <T>, en-st, a1+st, a2+st, a3+st, &a4, &a5
00620
00626 #define STD_SMP_TEMPLATE(oper, dm, a1, a2, a3, a4, a5, SMP_TMPL, JOB_TMPL) \
00627 \
00628 const unsigned n_thr = threads_avail (dm / SMP_VECSLICE); \
00629 if (LIKELY(n_thr < 2)) { \
00630 SMP_TMPL(oper, 0, dm, a1, a2, a3, a4, a5); \
00631 } else { \
00632 PREFETCH_R(a1, 3); \
00633 const unsigned long first = slice_offset(1, n_thr, dm, a1); \
00634 unsigned long st, en = first; \
00635 unsigned _t; \
00636 \
00637 \
00638 for (_t = 0; _t < n_thr-1; ++_t) { \
00639 st = en; en = slice_offset(_t+2, n_thr, dm, a1); \
00640 thread_start (_t, JOB_TMPL(oper, st, en, a1, a2, a3, a4, a5), (void*)0); \
00641 } \
00642 \
00643 SMP_TMPL(oper, 0UL, first, a1, a2, a3, a4, a5); \
00644 \
00645 \
00646 for (_t = 0; _t < n_thr-1; ++_t) \
00647 thread_wait (_t); \
00648 }
00649
00650 #define STD_SMP_TEMPLATE2V(oper, dm, a1, a2) \
00651 STD_SMP_TEMPLATE(oper, dm, a1, a2, X, X, X, _SMP_TMPL2V, _JOB_TMPL2V)
00652 #define STD_SMP_TEMPLATE2C(oper, dm, a1, a2) \
00653 STD_SMP_TEMPLATE(oper, dm, a1, a2, X, X, X, _SMP_TMPL2C, _JOB_TMPL2C)
00654 #define STD_SMP_TEMPLATE3VV(oper, dm, a1, a2, a3) \
00655 STD_SMP_TEMPLATE(oper, dm, a1, a2, a3, X, X, _SMP_TMPL3VV, _JOB_TMPL3VV)
00656 #define STD_SMP_TEMPLATE3VC(oper, dm, a1, a2, a3) \
00657 STD_SMP_TEMPLATE(oper, dm, a1, a2, a3, X, X, _SMP_TMPL3VC, _JOB_TMPL3VC)
00658 #define STD_SMP_TEMPLATE3CC(oper, dm, a1, a2, a3) \
00659 STD_SMP_TEMPLATE(oper, dm, a1, a2, a3, X, X, _SMP_TMPL3CC, _JOB_TMPL3CC)
00660 #define STD_SMP_TEMPLATE4V(oper, dm, a1, a2, a3, a4) \
00661 STD_SMP_TEMPLATE(oper, dm, a1, a2, a3, a4, X, _SMP_TMPL4V, _JOB_TMPL4V)
00662 #define STD_SMP_TEMPLATE4C(oper, dm, a1, a2, a3, a4) \
00663 STD_SMP_TEMPLATE(oper, dm, a1, a2, a3, a4, X, _SMP_TMPL4C, _JOB_TMPL4C)
00664 #define STD_SMP_TEMPLATE5(oper, dm, a1, a2, a3, a4, a5) \
00665 STD_SMP_TEMPLATE(oper, dm, a1, a2, a3, a4, a5, _SMP_TMPL5, _JOB_TMPL5)
00666
00667
00668 #endif
00669
00671 template <typename T>
00672 inline TVector<T>& TVector<T>::operator += (const T& a)
00673 {
00674 STD_SMP_TEMPLATE2C(vec_add_val, this->dim, this->vec, a);
00675 return *this;
00676 }
00678 template <typename T>
00679 inline TVector<T>& TVector<T>::operator -= (const T& a)
00680 {
00681 STD_SMP_TEMPLATE2C(vec_sub_val, this->dim, this->vec, a);
00682 return *this;
00683 }
00685 template <typename T>
00686 inline TVector<T>& TVector<T>::operator *= (const T& a)
00687 {
00688 STD_SMP_TEMPLATE2C(vec_mul_val, this->dim, this->vec, a);
00689 return *this;
00690 }
00691
00693 template <typename T>
00694 inline TVector<T>& TVector<T>::operator /= (const T& a)
00695 {
00696 BCHK (a == (T)0, VecErr, Divide by zero (TVector), 0, *this);
00697 return this->operator *= ((T)1/a);
00698 }
00699
00700
00702 template <typename T>
00703 inline TVector<T>& TVector<T>::operator += (const Vector<T>& a)
00704 {
00705 BCHK(this->dim!=a.dim,VecErr,"TV += V operator with diff. sizes", a.dim, *this);
00706 STD_SMP_TEMPLATE2V(vec_add_vec, this->dim, this->vec, a.vec);
00707 return *this;
00708 }
00710 template <typename T>
00711 inline TVector<T>& TVector<T>::operator -= (const Vector<T>& a)
00712 {
00713 BCHK(this->dim!=a.dim,VecErr,"TV -= V operator with diff. sizes", a.dim, *this);
00714 STD_SMP_TEMPLATE2V(vec_sub_vec, this->dim, this->vec, a.vec);
00715 return *this;
00716 }
00717
00719 template <typename T>
00720 inline TVector<T>& TVector<T>::operator += (const TSVector<T>& a)
00721 {
00722 BCHK(this->dim!=a.dim,VecErr,"TV += TSV operator with diff. sizes", a.dim, *this);
00723 STD_SMP_TEMPLATE3VC(vec_add_svc, this->dim, this->vec, a.vec, a.fac);
00724 if (LIKELY(this->vec != a.vec))
00725 a.destroy ();
00726 return *this;
00727 }
00729 template <typename T>
00730 inline TVector<T>& TVector<T>::operator -= (const TSVector<T>& a)
00731 {
00732 BCHK(this->dim!=a.dim,VecErr,"TV -= TSV operator with diff. sizes", a.dim, *this);
00733 STD_SMP_TEMPLATE3VC(vec_sub_svc, this->dim, this->vec, a.vec, a.fac);
00734 if (LIKELY(this->vec != a.vec))
00735 a.destroy ();
00736 return *this;
00737 }
00738
00739
00740
00741
00742 template <typename T>
00743 inline TVector<T>& TVector<T>::operator + (const Vector<T>& a)
00744 {
00745
00746 return this->operator += (a);
00747 }
00748 template <typename T>
00749 inline TVector<T>& TVector<T>::operator - (const Vector<T>& a)
00750 {
00751
00752 return this->operator -= (a);
00753 }
00754
00755
00758 template <typename T>
00759 const TVector<T>& TVector<T>::operator + (const TVector<T>& tv)
00760 {
00761 BCHK (tv.dim != this->dim, VecErr, Diff. dim in TV + TV, tv.dim, (this->destroy(), tv));
00762
00763 STD_SMP_TEMPLATE2V(vec_add_vec, this->dim, tv.vec, this->vec);
00764 this->destroy (); return tv;
00765 }
00766
00769 template <typename T>
00770 const TVector<T>& TVector<T>::operator - (const TVector<T>& tv)
00771 {
00772 BCHK (tv.dim != this->dim, VecErr, Diff. dim in TV - TV, tv.dim, (this->destroy(), tv));
00773
00774 STD_SMP_TEMPLATE2V(vec_sub_vec_inv, this->dim, tv.vec, this->vec);
00775 this->destroy (); return tv;
00776 }
00777
00778
00781 INST(template<typename T> class TVector friend const TVector<T>& operator + (const T&, const TVector<T>&);)
00782 template <typename T>
00783 inline const TVector<T>& operator + (const T& a, const TVector<T>& b)
00784 {
00785
00786 const unsigned long dim = b.size();
00787 T* vec = &b.setval(0);
00788 STD_SMP_TEMPLATE2C(val_add_vec, dim, vec, a);
00789 return b;
00790 }
00793 INST(template<typename T> class TVector friend const TVector<T>& operator - (const T&, const TVector<T>&);)
00794 template <typename T>
00795 inline const TVector<T>& operator - (const T& a, const TVector<T>& b)
00796 {
00797
00798 const unsigned long dim = b.size();
00799 T* vec = &b.setval(0);
00800 STD_SMP_TEMPLATE2C(val_sub_vec, dim, vec, a);
00801 return b;
00802 }
00803
00804
00805 INST(template <typename T> class TVector friend TSVector<T> operator * (const T&, const TVector<T>&);)
00806 template <typename T>
00807 inline TSVector<T> operator * (const T& a, const TVector<T>& b)
00808 {
00809 return TSVector<T> (b, a);
00810 }
00811
00812
00813
00814 INSTCTL(#ifndef VEC_INT_DIV_SUPPORT)
00815 INST(template <typename T> class TVector friend TSVector<T> operator / (const T&, TVector<T>);)
00816 INSTCTL(#endif)
00817 template <typename T>
00818 inline TSVector<T> operator / (const T& a, TVector<T> b)
00819 {
00820 T dv = a / b.fabssqr();
00821 BCHK(dv==(T)0, VecErr, Divide by norm 0 Vector, 0, 0);
00822 return TSVector<T> (b, dv);
00823 }
00824
00825
00826 template <typename T>
00827 inline TVector<T>& TVector<T>::operator + (const T& a)
00828 { return this->operator += (a); }
00829 template <typename T>
00830 inline TVector<T>& TVector<T>::operator - (const T& a)
00831 { return this->operator -= (a); }
00832
00833
00834 template <typename T>
00835 inline TSVector<T> TVector<T>::operator * (const T& a)
00836 {
00837 return TSVector<T> (*this, a);
00838 }
00839
00840
00841 template <typename T>
00842 inline TSVector<T> TVector<T>::operator / (const T& a)
00843 {
00844 return TSVector<T> (*this, (T)1/a);
00845 }
00846
00847 #if 0
00848 template <typename T>
00849 inline TVector<T>& TVector<T>::operator - ()
00850 {
00851 for (register unsigned long i=0; i<dim; ++i)
00852 this->vec[i] = -this->vec[i];
00853 return *this;
00854 }
00855 #else
00856 template <typename T>
00857 inline TSVector<T> TVector<T>::operator - ()
00858 {
00859 return TSVector<T> (*this, (T)-1);
00860 }
00861 #endif
00862
00863
00864
00865
00866
00867 template <typename T>
00868 inline TVector<T>& conj (TVector<T>& tv)
00869 {
00870 for (register unsigned long i=0; i<tv.size(); ++i)
00871 tv.set (CPLX__ conj (tv.get(i)), i);
00872 return tv;
00873 }
00874
00875
00876 template <typename T>
00877 inline TVector<T>& real (TVector<T>& tv)
00878 {
00879 for (register unsigned long i=0; i<tv.size(); ++i)
00880 tv.set(CPLX__ real (tv.get(i)), i);
00881
00882 return tv;
00883 }
00884
00885
00886 template <typename T>
00887 inline TVector<T>& imag (TVector<T>& tv)
00888 {
00889 for (register unsigned long i=0; i<tv.size(); ++i)
00890 tv.set(CPLX__ imag (tv.get(i)), i);
00891
00892 return tv;
00893 }
00894
00895
00896 template <typename T>
00897 inline TVector<T> conj (const Vector<T>& v)
00898 {
00899 TVector<T> tv(v.size());
00900 for (register unsigned long i=0; i<v.size(); ++i)
00901 tv.set (CPLX__ conj (v(i)), i);
00902 return tv;
00903 }
00904
00905
00906 template <typename T>
00907 inline TVector<T> real (const Vector<T>& v)
00908 {
00909 TVector<T> tv (v.size());
00910 for (register unsigned long i=0; i<v.size(); ++i)
00911 tv.set (CPLX__ real (v(i)), i);
00912
00913 return tv;
00914 }
00915
00916
00917 template <typename T>
00918 inline TVector<T> imag (const Vector<T>& v)
00919 {
00920 TVector<T> tv (v.size());
00921 for (register unsigned long i=0; i<v.size(); ++i)
00922 tv.set(CPLX__ imag (v(i)), i);
00923
00924 return tv;
00925 }
00926
00927
00928
00929
00932 template <typename T>
00933 inline TVector<T>& TVector<T>::operator + (const TSVector<T>& ts)
00934 {
00935 BCHK(this->dim!=ts.dim,VecErr,Wrong dim TV + TSV,ts.dim,*this);
00936
00937
00938 STD_SMP_TEMPLATE3VC(vec_add_svc, this->dim, this->vec, ts.vec, ts.fac);
00939
00940 if (LIKELY(this->vec != ts.vec))
00941 ts.destroy();
00942 return *this;
00943 }
00944
00947 template <typename T>
00948 inline TVector<T>& TVector<T>::operator - (const TSVector<T>& ts)
00949 {
00950 BCHK(this->dim!=ts.dim,VecErr,Wrong dim TV - TSV,ts.dim,*this);
00951
00952
00953 STD_SMP_TEMPLATE3VC(vec_sub_svc, this->dim, this->vec, ts.vec, ts.fac);
00954
00955 if (LIKELY(this->vec != ts.vec))
00956 ts.destroy();
00957 return *this;
00958 }
00959
00960
00961 template <typename T>
00962 inline TVector<T> TVector<T>::slice (const unsigned long i0, const unsigned long i1)
00963 {
00964 BCHK (i1 < i0, VecErr, Slicing needs ordered arguments, i0, *this);
00965 BCHK (i0 >= this->dim, VecErr, Slice: arg1 out of range, i0, *this);
00966 BCHK (i1 > this->dim, VecErr, Slice: arg2 out of range, i1, *this);
00967 this->dim = i1 - i0;
00968
00969
00970 if (UNLIKELY(this->dim == 0))
00971 TBCIDELETE (T, this->vec, this->dim);
00972 else
00973 this->vec += i0;
00974 return *this;
00975 }
00976
00977
00978 template <typename T>
00979 inline TVector<T>& TVector<T>::incr (const unsigned long wh, const T i)
00980 {
00981 BCHK (wh >= this->dim, VecErr, Tried to change not-exitsting idx, wh, *this);
00982 this->vec[wh] += i;
00983 return *this;
00984 }
00985
00986
00987
00988 template <typename T> inline double fabssqr(const Vector<T>& v);
00989
00990 NAMESPACE_END
00991
00992 NAMESPACE_CSTD
00993
00994 INST(template <typename T> class TBCI__ Vector friend double fabs (const TBCI__ Vector<T>&);)
00995 template <typename T>
00996 inline double fabs (const TBCI__ Vector<T>& v)
00997 {
00998 return sqrt (TBCI__ fabssqr (v));
00999 }
01000
01001 INST(template <typename T> class TBCI__ Vector friend T abs (const TBCI__ Vector<T>&);)
01002 template <typename T>
01003 inline T abs (const TBCI__ Vector<T>& v)
01004 {
01005 return v.abs();
01006 }
01007
01008 INST(template <typename T> class TBCI__ TVector friend double fabs (TBCI__ TVector<T>);)
01009 template <typename T>
01010 inline double fabs (TBCI__ TVector<T> tv)
01011 {
01012 TBCI__ Vector<T> v(tv); return fabs (v);
01013 }
01014
01015 INST(template <typename T> class TBCI__ Vector friend T abs (TBCI__ TVector<T>);)
01016 template <typename T>
01017 inline T abs (TBCI__ TVector<T> tv)
01018 {
01019 TBCI__ Vector<T> v(tv); return abs (v);
01020 }
01021
01022 NAMESPACE_CSTD_END
01023
01024 NAMESPACE_TBCI
01025
01031 template <typename T>
01032 class TSVector : public Vector_Sig<T>
01033 {
01034 protected:
01035 mutable T* vec; mutable unsigned long dim;
01036 mutable T fac ALIGN(MIN_ALIGN2);
01037
01038 void clone (const bool = false, const T* = 0) const;
01039 public:
01040 void detach (const T* = 0) const;
01041
01042 public:
01043 mutable bool mut;
01044 void destroy () const;
01045
01046 public:
01047 friend class Vector<T>;
01048 friend class TVector<T>;
01049 friend class CRMatrix<T>;
01050 friend NOINST void FRIEND_TBCI2__ do_mat_tsv_mult FGD (const unsigned start, const unsigned end, \
01051 TVector<T> * res, const Matrix<T> * mat, const TSVector<T> * rsv);
01052
01053 typedef T value_type;
01054 typedef T element_type;
01055 typedef T aligned_value_type TALIGN(MIN_ALIGN2);
01056
01057 const TSVector<T>& eval (const T* vv = 0) const;
01058
01059 TSVector () : vec((T*)0), dim(0), fac((T)1), mut(true) {}
01060 ~TSVector () { }
01061 explicit TSVector (const unsigned long d) : vec(new T[d]), dim(d), fac((T)1), mut(true) {}
01062
01063 TSVector (const TSVector<T>& ts)
01064 : vec(ts.vec), dim(ts.dim), fac(ts.fac), mut(ts.mut) {}
01065
01066 TSVector (const TVector<T>& tv, const T& f = (T)1)
01067 : vec(tv.vec), dim(tv.dim), fac(f), mut(true) {}
01068 TSVector (const Vector<T>& v, const T& f = (T)1)
01069 : vec(v.vec), dim(v.dim), fac(f), mut(false) {}
01070
01071
01072 T operator () (const unsigned long i) const
01073 { T val = vec[i] * fac; destroy (); return val; }
01074
01075 T operator [] (const unsigned long i) const { return this->operator() (i); }
01076
01077
01078 T get (const unsigned long i) const HOT { return vec[i] * fac; }
01079 const T& getfac () const { return fac; }
01080 T& getfacref () const { return fac; }
01081 const T& getcref (const unsigned long i) const HOT { return vec[i]; }
01082
01083
01084 TSVector<T>& operator = (const TSVector<T>& ts)
01085 { destroy (); vec = ts.vec; dim = ts.dim;
01086 fac = ts.fac; mut = ts.mut; return *this; }
01087 TSVector<T>& operator = (const TVector<T>& tv)
01088 { destroy (); vec = tv.vec; dim = tv.dim;
01089 fac = (T)1; mut = true; return *this; }
01090
01091
01092
01093
01094
01095
01096
01097 TSVector<T>& operator *= (const T& f) { fac *= f; return *this; }
01098 TSVector<T>& operator /= (const T& f) { fac /= f; return *this; }
01099 const TSVector<T>& operator * (const T& f) const { fac *= f; return *this; }
01100 const TSVector<T>& operator / (const T& f) const { fac /= f; return *this; }
01101
01102 const TSVector<T>& operator - () const { fac = -fac; return *this; }
01103
01104
01105 TVector<T> operator + (const Vector<T>&) const HOT;
01106 TVector<T> operator + (TVector<T>) const HOT;
01107 TVector<T> operator + (const TSVector<T>&) const HOT;
01108 TVector<T> operator + (const T&) const;
01109 TVector<T> operator - (const Vector<T>&) const HOT;
01110 TVector<T> operator - (TVector<T>) const HOT;
01111 TVector<T> operator - (const TSVector<T>&) const HOT;
01112 TVector<T> operator - (const T&) const;
01113
01114 #ifdef TSV_OP_FRIENDS
01115 friend const TSVector<T>& operator * FGD (const T& f, const TSVector<T>& ts);
01116 friend TVector<T> operator + FGD (const T&, const TSVector<T>&);
01117 friend TVector<T> operator - FGD (const T&, const TSVector<T>&);
01118
01119 #else
01120 TVector<T> add_t_tsv (const T&) const;
01121 TVector<T> sub_t_tsv (const T&) const;
01122 #endif
01123
01124 TVector<T> incr (const unsigned long, const T = (T)1) const;
01125
01126 inline unsigned long size () const { return dim; }
01127
01128 T min () { Vector<T> th(*this); return th.min (); }
01129 T max () { Vector<T> th(*this); return th.max (); }
01130 T abs () const
01131 { return ((TVector<T>)*this).abs () * GLBL__ CSTD__ abs(fac); }
01132 double fabs () const
01133 { return ((TVector<T>)*this).fabs () * GLBL__ MATH__ fabs(fac); }
01134 double fabssqr () const
01135 { return ((TVector<T>)*this).fabssqr () * GLBL2__ TBCI__ fabssqr(fac); }
01136
01137 T sum () { T val = ((TVector<T>)*this).sum () * fac; destroy (); return val; }
01138
01139
01140 #ifdef TSVEC_NEED_DOT
01141 T operator * (const TSVector<T>&);
01142 T operator * (const TVector<T>&);
01143 T operator * (const Vector<T>&);
01144 #endif
01145
01146 #if 0
01147 friend TVector<T> conj FGD (const TSVector<T>&);
01148 friend TVector<T> real FGD (const TSVector<T>&);
01149 friend TVector<T> imag FGD (const TSVector<T>&);
01150 #endif
01151
01152
01153 #ifndef HAVE_GCC295_FRIEND_BUG
01154 friend NOINST double FRIEND_TBCI__ fabssqr FGDT (const TSVector<T>&);
01155 #endif
01156 #if 0
01157 friend NOINST double MATH__ fabs FGD (const TBCI__ TSVector<T>&);
01158 friend NOINST T CSTD__ abs FGD (const TBCI__ TSVector<T>&);
01159 #endif
01160
01161 bool operator == (const Vector<T>&) const;
01162 bool operator != (const Vector<T>& v) const { return !(*this == v); }
01163 bool operator == (const TSVector<T>&) const;
01164 bool operator != (const TSVector<T>& ts) const { return !(*this == ts); }
01165 bool operator == (const TVector<T>& tv) const { Vector<T> v(tv); return (*this == v); }
01166 bool operator != (const TVector<T>& tv) const { return !(*this == tv); }
01167
01168
01169 T* const & vecptr () const { return vec; }
01170
01171 static const char* vec_info() { return "TSVector"; }
01172
01173 friend STD__ ostream& operator << FGD (STD__ ostream&, const TSVector<T>&);
01174 } ;
01175
01176
01177 template <typename T>
01178 inline void TSVector<T>::destroy () const
01179 {
01180 if (LIKELY(!mut || !dim)) return;
01181 TBCIDELETE(T, vec, dim);
01182 }
01183
01184 template <typename T>
01185 inline void TSVector<T>::detach (const T* vv) const
01186 {
01187 if (LIKELY(!dim || (mut && !vv)))
01188 return;
01189 mut = true;
01190 if (vv)
01191 vec = const_cast<T*> (vv);
01192 else {
01193 vec = NEW(T,dim);
01194 if (UNLIKELY(!vec)) {
01195 dim = 0; mut = false;
01196 }
01197 }
01198 }
01199
01200 INST(template <typename T> class TSVector<T> friend const TSVector<T>& operator * (const T&, const TSVector<T>&);)
01201 template <typename T>
01202 const TSVector<T>& operator * (const T& f, const TSVector<T>& ts)
01203 { ts.getfacref() = f * ts.getfac(); return ts; }
01204
01205 template <typename T>
01206 inline void TSVector<T>::clone (const bool evl, const T* vv) const
01207 {
01208 if (LIKELY(!dim || (mut && !vv)))
01209 return;
01210 const T* oldv = vec; bool oldm = mut; detach (vv);
01211 if (LIKELY(evl && fac != (T)1)) {
01212 #if 0 //def __i386__
01213 for (register unsigned long t = 0; t < dim; t++)
01214 vec[t] = oldv[t] * fac;
01215 #else
01216 STD_SMP_TEMPLATE3VC(vec_val_mul, dim, vec, oldv, fac);
01217 #endif
01218 fac = (T)1;
01219 }
01220 else
01221 TBCICOPY(vec, oldv, T, dim);
01222 if (UNLIKELY(vv && oldm))
01223 TBCIDELETE(T, oldv, dim);
01224 }
01225
01226 template <typename T>
01227 const TSVector<T>& TSVector<T>::eval (const T* vv) const
01228 {
01229 if (!vv && mut) {
01230 if (fac != (T)1) {
01231 #if 0 //def __i386__
01232 for (register unsigned long t = 0; t < dim; t++)
01233 vec[t] *= fac;
01234 #else
01235 STD_SMP_TEMPLATE2C(vec_mul_val, dim, vec, fac);
01236 #endif
01237 fac = (T)1;
01238 }
01239
01240 }
01241 else
01242 clone (true, vv);
01243 return *this;
01244 }
01245
01246 template <typename T>
01247 bool TSVector<T>::operator == (const Vector<T>& v) const
01248 {
01249 if (LIKELY(dim != v.dim)) {
01250 destroy (); return false;
01251 }
01252 if (LIKELY(dim == 0)) {
01253 return true;
01254 }
01255 if (LIKELY(fac == (T)1)) {
01256 if (LIKELY(vec == v.vec))
01257 return true;
01258 if (TBCICOMP(vec, v.vec, T, dim)) {
01259 destroy (); return false;
01260 }
01261 } else {
01262 if (LIKELY(vec == v.vec))
01263 return false;
01264 for (register unsigned long i = 0; i < dim; ++i)
01265 if (UNLIKELY(vec[i]*fac != v.vec[i])) {
01266 destroy (); return false;
01267 }
01268 }
01269 destroy ();
01270 return true;
01271 }
01272
01273 template <typename T>
01274 bool TSVector<T>::operator == (const TSVector<T>& ts) const
01275 {
01276 if (LIKELY(dim != ts.dim)) {
01277 ts.destroy (); destroy (); return false;
01278 }
01279 if (LIKELY(dim == 0)) {
01280 return true;
01281 }
01282 if (LIKELY(fac == ts.fac)) {
01283 if (LIKELY(vec == ts.vec)) {
01284 destroy (); return true;
01285 }
01286 if (TBCICOMP(vec, ts.vec, T, dim)) {
01287 ts.destroy (); destroy (); return false;
01288 }
01289 } else {
01290 if (LIKELY(vec == ts.vec)) {
01291 destroy (); return false;
01292 }
01293 for (register unsigned long i = 0; i < dim; ++i)
01294 if (UNLIKELY(vec[i]*fac != ts.vec[i]*ts.fac)) {
01295 ts.destroy (); destroy (); return false;
01296 }
01297 }
01298 ts.destroy (); destroy (); return true;
01299 }
01300
01303 template <typename T>
01304 inline TVector<T> TSVector<T>::operator + (TVector<T> tv) const
01305 {
01306 BCHK(dim!=tv.dim,VecErr,Wrong dims in TSV + TV,tv.dim,tv);
01307
01308
01309 STD_SMP_TEMPLATE3VC(vec_add_svc, dim, tv.vec, vec, fac);
01310 destroy (); return tv;
01311 }
01314 template <typename T>
01315 inline TVector<T> TSVector<T>::operator - (TVector<T> tv) const
01316 {
01317 BCHK(dim!=tv.dim,VecErr,Wrong dims in TSV - TV,tv.dim,tv);
01318
01319
01320 STD_SMP_TEMPLATE3VC(vec_sub_svc_inv, dim, tv.vec, vec, fac);
01321 destroy (); return tv;
01322 }
01323
01325 template <typename T>
01326 inline TVector<T> TSVector<T>::operator + (const Vector<T>& v) const
01327 {
01328 TVector<T> tv;
01329 if (LIKELY(mut)) {
01330 tv.vec = vec; tv.dim = dim;
01331 } else
01332 tv.resize (dim);
01333 BCHK(dim!=v.dim,VecErr,Wrong dims in TSV + V,v.dim,tv);
01334
01335
01336 STD_SMP_TEMPLATE4V(svc_vec_add, dim, tv.vec, vec, v.vec, fac);
01337 return (tv);
01338 }
01340 template <typename T>
01341 inline TVector<T> TSVector<T>::operator - (const Vector<T>& v) const
01342 {
01343 TVector<T> tv;
01344 if (LIKELY(mut)) {
01345 tv.vec = vec; tv.dim = dim;
01346 } else
01347 tv.resize (dim);
01348 BCHK(dim!=v.dim,VecErr,Wrong dims in TSV - V,v.dim,tv);
01349
01350
01351 STD_SMP_TEMPLATE4V(svc_vec_sub, dim, tv.vec, vec, v.vec, fac);
01352 return (tv);
01353 }
01354
01356 template <typename T>
01357 inline TVector<T> TSVector<T>::operator + (const TSVector<T>& tsv) const
01358 {
01359 TVector<T> tv;
01360 if (LIKELY(mut)) {
01361 tv.vec = vec; tv.dim = dim;
01362 } else if (LIKELY(tsv.mut)) {
01363 tv.vec = tsv.vec; tv.dim = tsv.dim;
01364 } else
01365 tv.resize (dim);
01366 BCHK(dim!=tsv.dim,VecErr,Wrong dims in TSV + TSV,tsv.dim,tv);
01367
01368
01369 STD_SMP_TEMPLATE5(svc_svc_add, dim, tv.vec, vec, tsv.vec, fac, tsv.fac);
01370 if (UNLIKELY(mut && tsv.mut))
01371 tsv.destroy ();
01372 return tv;
01373 }
01375 template <typename T>
01376 inline TVector<T> TSVector<T>::operator - (const TSVector<T>& tsv) const
01377 {
01378 TVector<T> tv;
01379 if (LIKELY(mut)) {
01380 tv.vec = vec; tv.dim = dim;
01381 } else if (LIKELY(tsv.mut)) {
01382 tv.vec = tsv.vec; tv.dim = tsv.dim;
01383 } else
01384 tv.resize (dim);
01385 BCHK(dim!=tsv.dim,VecErr,Wrong dims in TSV - TSV,tsv.dim,tv);
01386
01387
01388 STD_SMP_TEMPLATE5(svc_svc_sub, dim, tv.vec, vec, tsv.vec, fac, tsv.fac);
01389 if (UNLIKELY(mut && tsv.mut))
01390 tsv.destroy ();
01391 return tv;
01392 }
01393
01395 template <typename T>
01396 inline TVector<T> TSVector<T>::operator + (const T& v) const
01397 {
01398 TVector<T> tv;
01399 if (LIKELY(mut)) {
01400 tv.vec = vec; tv.dim = dim;
01401 } else
01402 tv.resize (dim);
01403
01404
01405 STD_SMP_TEMPLATE4C(svc_val_add, dim, tv.vec, vec, fac, v);
01406 return tv;
01407 }
01409 template <typename T>
01410 inline TVector<T> TSVector<T>::operator - (const T& v) const
01411 {
01412 TVector<T> tv;
01413 if (LIKELY(mut)) {
01414 tv.vec = vec; tv.dim = dim;
01415 } else
01416 tv.resize (dim);
01417
01418
01419 STD_SMP_TEMPLATE4C(svc_val_sub, dim, tv.vec, vec, fac, v);
01420 return tv;
01421 }
01422
01425 template <typename T>
01426 inline TVector<T> TSVector<T>::add_t_tsv (const T& v) const
01427 {
01428 TVector<T> tv;
01429 if (LIKELY(mut)) {
01430 tv.vec = vec; tv.dim = dim;
01431 }
01432 else
01433 tv.resize (size());
01434
01435
01436 STD_SMP_TEMPLATE4C(val_svc_add, dim, tv.vec, vec, v, fac);
01437 return tv;
01438 }
01439 INST(template <typename T> class TSVector<T> friend TVector<T> operator + (const T&, const TSVector<T>&);)
01440 template <typename T>
01441 inline TVector<T> operator + (const T& v, const TSVector<T>& tsv)
01442 { return tsv.add_t_tsv (v); }
01443
01445 template <typename T>
01446 inline TVector<T> TSVector<T>::sub_t_tsv (const T& v) const
01447 {
01448 TVector<T> tv;
01449 if (LIKELY(mut)) {
01450 tv.vec = vec; tv.dim = dim;
01451 }
01452 else
01453 tv.resize (size());
01454
01455
01456 STD_SMP_TEMPLATE4C(val_svc_sub, dim, tv.vec, vec, v, fac);
01457 return tv;
01458 }
01459 INST(template <typename T> class TSVector<T> friend TVector<T> operator - (const T&, const TSVector<T>&);)
01460 template <typename T>
01461 inline TVector<T> operator - (const T& v, const TSVector<T>& tsv)
01462 { return tsv.sub_t_tsv (v); }
01463
01464 template <typename T>
01465 STD__ ostream& operator << (STD__ ostream& os, const TSVector<T>& ts)
01466 {
01467 for (unsigned long i = 0; i < ts.dim; ++i)
01468 os << ts.vec[i]*ts.fac << " ";
01469 ts.destroy (); return os;
01470 }
01471
01472
01473 template <typename T>
01474 inline TVector<T> TSVector<T>::incr (const unsigned long wh, const T i) const
01475 {
01476 TVector<T> tv (*this);
01477 BCHK (wh >= dim, VecErr, Tried to change not-exitsting idx, wh, tv);
01478 tv.vec[wh] += i;
01479 return tv;
01480 }
01481
01482
01483 INST(template <typename T> class TSVector friend double fabssqr (const TSVector<T>&);)
01484 template <typename T>
01485 double fabssqr (const TSVector<T>& ts)
01486 { return ts.fabssqr (); }
01487
01488 NAMESPACE_END
01489
01490 NAMESPACE_CSTD
01491
01492 INST(template <typename T> class TBCI__ TSVector friend double fabs (const TBCI__ TSVector<T>&);)
01493 template <typename T>
01494 double inline fabs (const TBCI__ TSVector<T>& ts)
01495 { return ts.fabs(); }
01496
01497 INST(template <typename T> class TBCI__ TSVector friend T abs (const TBCI__ TSVector<T>&);)
01498 template <typename T>
01499 inline T abs (const TBCI__ TSVector<T>& ts)
01500 { return ts.abs(); }
01501
01502 NAMESPACE_CSTD_END
01503
01504 NAMESPACE_TBCI
01505
01506
01507
01531 template <typename T>
01532 class Vector : public TVector<T>
01533 {
01534 public:
01535
01536 typedef T value_type;
01537 typedef T element_type;
01538 typedef T aligned_value_type TALIGN(MIN_ALIGN2);
01539
01540 friend class TSVector<T>;
01541
01542
01543
01544
01545 explicit Vector (const unsigned long d = 0) : TVector<T> (d) {}
01546 Vector (const T& val, const unsigned long d) : TVector<T> (val, d) {}
01547 Vector (const BVector<T>& bv) : TVector<T> (bv) {}
01548 Vector (const Vector<T>& v) : TVector<T> (v) {}
01549
01550 Vector (const TSVector<T>& ts)
01551 { ts.eval (this->vec); this->vec = ts.vec; this->dim = ts.dim; }
01552 Vector (const TVector<T>& tv) : TVector<T> (tv) {}
01553 Vector (const Mat_Brack<T>&);
01554 #ifndef NO_POD
01555 Vector (const vararg va, ... );
01556 #endif
01557
01558
01559
01560
01561 #if defined(__GNUC__) && defined VEC_CPLX_CONSTR
01562 explicit Vector (const Vector<cplx<T> >& cv);
01563 #endif
01564
01565 ~Vector() { this->destroy (); }
01566
01567
01568 typename tbci_traits<T>::const_refval_type
01569 operator () (const unsigned long i) const
01570 { return BVector<T>::operator () (i); }
01571 typename tbci_traits<T>::const_refval_type
01572 operator [] (const unsigned long i) const
01573 { return this->operator() (i); }
01574
01575 T& operator () (const unsigned long i)
01576 { return BVector<T>::operator () (i); }
01577 T& operator [] (const unsigned long i)
01578 { return this->operator() (i); }
01579
01580
01581
01582
01583 Vector<T>& fill (const T& v) { BVector<T>::fill (v); return *this; }
01584 Vector<T>& clear () { return this->fill((T)0); }
01585
01586
01587 TVector<T> slice (unsigned long, unsigned long) const;
01588
01589 TVector<T> incr (const unsigned long, const T = (T)1) const;
01590
01591
01592
01593 Vector<T>& operator = (const T& a)
01594 { this->TVector<T>::operator = (a); return *this; }
01596 Vector<T>& operator = (const Vector<T>& v) HOT
01597 { this->TVector<T>::operator = (v); return *this; }
01598 Vector<T>& operator = (const TSVector<T>& ts) HOT
01599 { TVector<T>::operator = (ts); return *this; }
01600 Vector<T>& operator = (const TVector<T>& tv) HOT
01601 { this->TVector<T>::operator = (tv); return *this; }
01602 #ifdef TBCI_NEW_BRACKET
01604 Vector<T>& operator = (const T* ptr)
01605 { TBCICOPY(this->vec,ptr,T,this->dim); return *this; }
01606 #endif
01607
01608
01609 bool operator == (const Vector<T>& v) const
01610 { return BVector<T>::operator == ((BVector<T>)v); }
01611 bool operator != (const Vector<T>& v) const { return !(*this == v); }
01612 bool operator == (const TSVector<T>&) const;
01613 bool operator != (const TSVector<T>& ts) const { return !(*this == ts); }
01614 bool operator == (const TVector<T>& tv) const { return (tv == *this); }
01615 bool operator != (const TVector<T>& tv) const { return !(*this == tv); }
01616
01617
01618
01619 bool operator <= (const Vector<T>& v) const { return BVector<T>::operator <= (v); }
01620 bool operator >= (const Vector<T>& v) const { return BVector<T>::operator >= (v); }
01621 bool operator < (const Vector<T>& v) const { return !((*this) >= v); }
01622 bool operator > (const Vector<T>& v) const { return !((*this) <= v); }
01623
01624 TVector<T> operator + (const Vector<T>&) const HOT;
01625 TVector<T> operator - (const Vector<T>&) const HOT;
01626 TVector<T> operator + ( TVector<T> tv) const HOT;
01627 TVector<T> operator - ( TVector<T> tv) const HOT;
01628 TVector<T> operator + (const TSVector<T>&) const HOT;
01629 TVector<T> operator - (const TSVector<T>&) const HOT;
01630
01631 TVector<T> operator + (const T&) const;
01632 TVector<T> operator - (const T&) const;
01633 TSVector<T> operator * (const T&) const;
01634 TSVector<T> operator / (const T&) const;
01635
01636 TVector<T> operator - () const;
01637
01638
01639
01640 friend T dot FGD (const Vector<T>&, const Vector<T>&) HOT;
01641
01642 T operator * (const Vector<T>&) const;
01643 T operator * (TVector<T>& tv) const
01644 { Vector<T> v (tv); return this->operator * (v); }
01645 T operator / (const Vector<T>&) const;
01646
01647 T min () const;
01648 T max () const;
01649 T min (unsigned long& pos) const;
01650 T max (unsigned long& pos) const;
01651 T sum () const;
01652 double fabssqr () const HOT;
01653 double fabs () const { return MATH__ sqrt (this->fabssqr()); }
01654 T abs () const { return (T) MATH__ sqrt (this->fabssqr()); }
01655
01656
01657 bool contains (const T& v) const { return BVector<T>::contains (v); }
01658
01659
01660
01661
01662
01663 static const char* vec_info() { return "Vector"; }
01664
01665
01666
01667 #if 0
01668 friend STD__ ostream& operator << (STD__ ostream& os, const Vector<T>& v);
01669 #endif
01670
01671 #ifdef OLD_GCC
01672 friend STD__ istream& operator >> (STD__ istream& is, Vector<T>& v)
01673 { return is >> (BVector<T>&)v; }
01674 #endif
01675
01676 #ifndef HAVE_PROMOTION_BUG
01677
01678
01679
01680
01681 template <typename U> explicit Vector (const BVector<U>& bv) : TVector<T> (bv) {}
01682 #endif
01683
01684 } ;
01685
01686 #if 1
01687 INST(template <typename T> friend inline STD__ ostream& operator << (STD__ ostream& os, const Vector<T>& v);)
01688 template <typename T>
01689 inline STD__ ostream& operator << (STD__ ostream& os, const Vector<T>& v)
01690 { return os << (BVector<T>&)v; }
01691 #endif
01692
01693 #ifndef NO_POD
01694 template <typename T>
01695 inline Vector<T>::Vector (const vararg va, ...)
01696 {
01697 this->vec = (T*)0; this->dim = (unsigned)va; this->keep = false;
01698 if (UNLIKELY(this->dim)) {
01699 this->vec = NEW (T, this->dim);
01700 if (UNLIKELY(!this->vec))
01701 this->dim = 0;
01702 }
01703 va_list vl;
01704 va_start (vl, va);
01705 for (unsigned long i=0; i < this->dim; ++i)
01706 this->vec[i] = va_arg (vl, T);
01707 va_end (vl);
01708 }
01709 #endif
01710
01711 #if defined(__GNUC__) && defined VEC_CPLX_CONSTR
01712 template <typename T>
01713 inline Vector<T>::Vector (const Vector<cplx<T> >& vc) : TVector<T> (vc.size())
01714 {
01715 for (unsigned long i = 0; i < this->dim; ++i)
01716 this->vec[i] = CPLX__ real (vc(i));
01717 }
01718 #endif
01719
01720 template <typename T>
01721 bool Vector<T>::operator == (const TSVector<T>& tsv) const
01722 {
01723 if (LIKELY(this->dim != tsv.dim)) {
01724 tsv.destroy (); return false;
01725 }
01726 if (LIKELY(this->dim == 0)) {
01727 return true;
01728 }
01729 if (LIKELY(tsv.fac == (T)1)) {
01730 if (LIKELY(this->vec == tsv.vec))
01731 return true;
01732 if (TBCICOMP(this->vec, tsv.vec, T, this->dim)) {
01733 tsv.destroy (); return false;
01734 }
01735 } else {
01736 if (LIKELY(this->vec == tsv.vec))
01737 return false;
01738 for (register unsigned long i = 0; i < this->dim; ++i)
01739 if (UNLIKELY(tsv.vec[i]*tsv.fac != this->vec[i])) {
01740 tsv.destroy (); return false;
01741 }
01742 }
01743 tsv.destroy (); return true;
01744 }
01745
01746
01747 #if 0
01748 template <typename T>
01749 inline Vector<T>& Vector<T>::operator *= (const T& f)
01750 {
01751 for (unsigned long i = 0; i < this->dim; ++i)
01752 this->vec[i] *= f;
01753 return *this;
01754 }
01755
01756 template <typename T>
01757 inline Vector<T>& Vector<T>::operator /= (const T& f)
01758 {
01759 for (unsigned long i = 0; i < this->dim; ++i)
01760 this->vec[i] /= f;
01761 return *this;
01762 }
01763 #endif
01764
01765 #if !defined(SMP) || defined(NOSMP_VECSCALAR)
01766
01767
01768 template <typename T>
01769 inline T dot (const Vector<T>& a, const Vector<T>& b)
01770 {
01771 BCHK(a.dim != b.dim, VecErr, Scalar dot product with diff. size Vectors, b.size(), T(0));
01772 T s = T(0.0);
01773 do_vec_dot <T> (a.dim, a.vec, b.vec, s);
01774
01775 # ifdef SMPVEC_DEBUG
01776 STD__ cerr << "dot: " << STD__ setprecision (16) << s << STD__ endl;
01777 # endif
01778 return s;
01779 }
01780
01781
01782 template <typename T>
01783 inline T Vector<T>::operator * (const Vector<T>& a) const
01784 {
01785 BCHK(this->dim != a.dim, VecErr, Scalar product with diff. size Vectors, a.size(), 0);
01786 T s = T(0.0);
01787 do_vec_mult <T> (this->dim, this->vec, a.vec, s);
01788 # ifdef SMPVEC_DEBUG
01789 STD__ cerr << "op *: " << STD__ setprecision (16) << s << STD__ endl;
01790 # endif
01791 return s;
01792 }
01793
01794
01795 #else
01796
01797 INST(template <typename T> class TVector friend void job_vec_dot (struct thr_ctrl*);)
01798 template <typename T>
01799 void job_vec_dot (struct thr_ctrl *tc)
01800 {
01801 *(T*)(tc->t_par[2]) = T(0.0);
01802 do_vec_dot (tc->t_size, (const T*)(tc->t_par[0]),
01803 (const T*)(tc->t_par[1]), *(T*)(tc->t_par[2]));
01804 }
01805
01806 INST(template <typename T> class TVector friend void job_vec_mult (struct thr_ctrl*);)
01807 template <typename T>
01808 void job_vec_mult (struct thr_ctrl *tc)
01809 {
01810 *(T*)(tc->t_par[2]) = T(0.0);
01811 do_vec_mult (tc->t_size, (const T*)(tc->t_par[0]),
01812 (const T*)(tc->t_par[1]), *(T*)(tc->t_par[2]));
01813 }
01814
01815
01816 template <typename T>
01817 inline T dot (const Vector<T>& a, const Vector<T>& b)
01818 {
01819 BCHK(a.size() != b.size(), VecErr, Scalar dot product with diff. size Vectors, b.size(), 0);
01820 T res = T(0); unsigned long sz = a.size();
01821
01822 const unsigned n_thr = threads_avail (sz / SMP_VECSLICE);
01823 if (LIKELY(n_thr < 2)) {
01824 do_vec_dot<T> (sz, a.vec, b.vec, res);
01825
01826 }
01827 else
01828 {
01829 PREFETCH_R(a.vec, 3); PREFETCH_R(b.vec, 3);
01830 const unsigned long first = slice_offset(1, n_thr, sz, a.vec);
01831 unsigned long st, en = first;
01832 T* results = 0;
01833 if (sizeof (T) > THREAD_MAX_RES_LN)
01834 results = new T[n_thr];
01835
01836 for (unsigned t = 0; t < n_thr-1; ++t) {
01837 st = en; en = slice_offset(t+2, n_thr, sz, a.vec);
01838 if (sizeof (T) > THREAD_MAX_RES_LN)
01839 thread_start (t, (thr_job_t)job_vec_dot<T>, en - st,
01840 a.vec+st, b.vec+st, results+t, (void*)0);
01841 else
01842 thread_start (t, (thr_job_t)job_vec_dot<T>, en - st,
01843 a.vec+st, b.vec+st, (T*)threads[t].t_res_dummy, (void*)0);
01844 }
01845
01846 do_vec_dot<T> (first, a.vec, b.vec, res);
01847
01848
01849
01850 for (unsigned t = 0; t < n_thr-1; ++t) {
01851 thread_wait (t);
01852 if (sizeof (T) > THREAD_MAX_RES_LN)
01853 res += results[t];
01854 else {
01855 T* resptr = (T*)(threads[t].t_res_dummy);
01856 res += *resptr;
01857 }
01858 #ifdef SMPVEC_DEBUG
01859 STD__ cerr << "+"
01860 << (sizeof(T) > THREAD_MAX_RES_LN?
01861 results[t]: *((T*)(threads[t].t_res_dummy)));
01862 #endif
01863 }
01864
01865 if (sizeof (T) > CACHELINE_SZ)
01866 delete[] results;
01867 }
01868 #ifdef SMPVEC_DEBUG
01869 STD__ cerr << "dot: " << STD__ setprecision (16) << res << STD__ endl;
01870 #endif
01871 return res;
01872 }
01873
01874
01875 template <typename T>
01876 inline T Vector<T>::operator * (const Vector<T>& a) const
01877 {
01878 BCHK(this->dim != a.size(), VecErr, Scalar product with diff. size Vectors, a.size(), 0);
01879 T res = T(0); unsigned long sz = this->dim;
01880
01881 const unsigned n_thr = threads_avail (sz / SMP_VECSLICE);
01882 if (LIKELY(n_thr < 2)) {
01883 do_vec_mult<T> (sz, this->vec, a.vec, res);
01884
01885 }
01886 else
01887 {
01888 PREFETCH_R(this->vec, 3); PREFETCH_R(a.vec, 3);
01889 const unsigned long first = sz/n_thr - (sz/n_thr)%4;
01890 unsigned long st, en = first;
01891 T* results = 0;
01892 if (sizeof (T) > THREAD_MAX_RES_LN)
01893 results = new T[n_thr];
01894
01895 for (unsigned t = 0; t < n_thr-1; ++t) {
01896 st = en; en = (t+2)*sz / n_thr;
01897 if (en < n_thr-2)
01898 en -= en%4;
01899 if (sizeof (T) > THREAD_MAX_RES_LN)
01900 thread_start (t, (thr_job_t)job_vec_mult<T>, en - st,
01901 this->vec+st, a.vec+st, results+t, (void*)0);
01902 else
01903 thread_start (t, (thr_job_t)job_vec_mult<T>, en - st,
01904 this->vec+st, a.vec+st, (T*)threads[t].t_res_dummy, (void*)0);
01905 }
01906
01907 do_vec_dot<T> (first, this->vec, a.vec, res);
01908
01909
01910
01911 for (unsigned t = 0; t < n_thr-1; ++t) {
01912 thread_wait (t);
01913 if (sizeof (T) > THREAD_MAX_RES_LN)
01914 res += results[t];
01915 else {
01916 T* resptr = (T*)(threads[t].t_res_dummy);
01917 res += *resptr;
01918 }
01919 #ifdef SMPVEC_DEBUG
01920 STD__ cerr << "+"
01921 << (sizeof(T) > THREAD_MAX_RES_LN?
01922 results[t]: *((T*)(threads[t].t_res_dummy)));
01923 #endif
01924 }
01925
01926 if (sizeof (T) > CACHELINE_SZ)
01927 delete[] results;
01928 }
01929 #ifdef SMPVEC_DEBUG
01930 STD__ cerr << "mlt: " << STD__ setprecision (16) << res << STD__ endl;
01931 #endif
01932 return res;
01933 }
01934
01935
01936
01937 #endif
01938
01939
01940 #if defined(SMP) && !defined(NO_SMP_VECVEC)
01941 INST(template <typename T> class TVector friend void job_vv_comp (struct thr_ctrl*);)
01942 template <typename T>
01943 void job_vv_comp (struct thr_ctrl *tc)
01944 {
01945 tc->t_res_l = 0;
01946 do_vv_comp (tc->t_size,
01947 (const T*)(tc->t_par[0]), (const T*)(tc->t_par[1]),
01948 tc->t_res_l);
01949 }
01950
01951 HOTDECL(template <typename T>
01952 bool par_comp (const Vector<T>& v1, const Vector<T>& v2))
01953 {
01954 unsigned long dim = v1.size();
01955 if (LIKELY(dim != v2.size()))
01956 return false;
01957 if (LIKELY(!dim))
01958 return true;
01959 if (LIKELY(v1(0) != v2(0)))
01960 return false;
01961
01962 volatile long res = 0;
01963
01964 const unsigned n_thr = threads_avail (dim / SMP_VECSLICE);
01965 const T * const vec1(&v1.getcref(0)), * const vec2(&v2.getcref(0));
01966
01967
01968 if (LIKELY(n_thr < 2)) {
01969 do_vv_comp<T> (dim, vec1, vec2, res);
01970 } else {
01971 PREFETCH_R(vec1, 3); PREFETCH_R(vec2, 3);
01972 const unsigned first = slice_offset(1, n_thr, dim, vec1);
01973 unsigned long st, en = first;
01974
01975 for (unsigned t = 0; t < n_thr-1; ++t) {
01976 st = en; en = slice_offset(t+2, n_thr, dim, vec1);
01977 thread_start (t, (thr_job_t)job_vv_comp<T>, en - st,
01978 vec1+st, vec2+st, (void*)0);
01979 }
01980
01981 do_vv_comp<T> (first, vec1, vec2, res);
01982
01983
01984 for (unsigned t = 0; t < n_thr-1; ++t) {
01985 thread_wait (t);
01986 res += (long) threads[t].t_res_l;
01987 }
01988 }
01989 return (res? false: true);
01990 }
01991
01992 #else
01993 template <typename T>
01994 bool par_comp (const Vector<T>& v1, const Vector<T>& v2)
01995 {
01996 unsigned long dim = v1.size();
01997 if (LIKELY(dim != v2.size()))
01998 return false;
01999 long res = 0;
02000 if (LIKELY(!dim))
02001 return true;
02002 do_vv_comp<T> (dim, &v1.getcref(0), &v2.getcref(0), res);
02003 return (res? false: true);
02004 }
02005 #endif
02006
02007 INST(template <typename T> class TVector friend bool par_comp (const Vector<T>&, const Vector<T>&);)
02008 INST(template <typename T> class TVector friend bool par_comp (const Vector<T>&, TVector<T>);)
02009 INST(template <typename T> class TVector friend bool par_comp (TVector<T>, const Vector<T>&);)
02010 INST(template <typename T> class TVector friend bool par_comp (TVector<T>, TVector<T>);)
02011
02012 template <typename T>
02013 inline bool par_comp (const Vector<T>& v1, TVector<T> v2)
02014 {
02015 return par_comp (v1, (const Vector<T>)v2);
02016
02017 }
02018
02019 template <typename T>
02020 inline bool par_comp (TVector<T> v1, const Vector<T>& v2)
02021 {
02022 return par_comp ((const Vector<T>)v1, v2);
02023 }
02024
02025 template <typename T>
02026 inline bool par_comp (TVector<T> v1, TVector<T> v2)
02027 {
02028 return par_comp ((const Vector<T>)v1, (const Vector<T>)v2);
02029 }
02030
02031
02032
02033 template <typename T>
02034 T Vector<T>::operator / (const Vector<T>& a) const
02035 {
02036 double div ALIGN(MIN_ALIGN) = a.fabssqr();
02037 BCHK(div == 0, VecErr, Division by Vector with norm 0, 0, div);
02038 return (T)((*this * a) / div);
02039 }
02040
02041 template <typename T>
02042 T Vector<T>::min () const
02043 {
02044 if (LIKELY(this->dim == 0))
02045 return 0;
02046 T min ALIGN(MIN_ALIGN) = this->vec[0];
02047 for (register unsigned long t = 1; t < this->dim; t++)
02048 if (UNLIKELY(this->vec[t] < min))
02049 min = this->vec[t];
02050 return min;
02051 }
02052
02053 template <typename T>
02054 T Vector<T>::min (unsigned long& pos) const
02055 {
02056 if (LIKELY(this->dim == 0))
02057 return 0;
02058 BCHK (pos >= this->dim, VecErr, pos outside range, pos, 0);
02059 T min ALIGN(MIN_ALIGN) = this->vec[pos];
02060 for (register unsigned long t = pos+1; t < this->dim; t++)
02061 if (UNLIKELY(this->vec[t] < min)) {
02062 min = this->vec[t]; pos = t;
02063 }
02064 return min;
02065 }
02066
02067 template <typename T>
02068 T Vector<T>::max () const
02069 {
02070 if (LIKELY(this->dim == 0))
02071 return 0;
02072 T max ALIGN(MIN_ALIGN) = this->vec[0];
02073 for (register unsigned long t = 1; t < this->dim; t++)
02074 if (UNLIKELY(this->vec[t] > max))
02075 max = this->vec[t];
02076 return max;
02077 }
02078
02079 template <typename T>
02080 T Vector<T>::max (unsigned long& pos) const
02081 {
02082 if (LIKELY(this->dim == 0))
02083 return 0;
02084 BCHK (pos >= this->dim, VecErr, pos outside range, pos, 0);
02085 T max ALIGN(MIN_ALIGN) = this->vec[pos];
02086 for (register unsigned long t = pos+1; t < this->dim; t++)
02087 if (UNLIKELY(this->vec[t] > max)) {
02088 max = this->vec[t]; pos = t;
02089 }
02090 return max;
02091 }
02092
02093 template <typename T>
02094 T Vector<T>::sum () const
02095 {
02096 T sum ALIGN(MIN_ALIGN) = T(0);
02097 do_vec_sum<T> (this->dim, this->vec, sum);
02098 return sum;
02099 }
02100
02101 #if 0
02102 {
02103 if (!this->dim) return 0.0;
02104 double s = CPLX__ real (vec[0] * CPLX__ conj(vec[0]));
02105 for (unsigned long i = 1; i < this->dim; ++i)
02106 s += CPLX__ real ((this->vec[i] * CPLX__ conj(this->vec[i])));
02107 return (sqrt(s));
02108
02109
02110
02111 }
02112 #endif
02113
02115 template <typename T>
02116 inline TVector<T> Vector<T>::operator + (const Vector<T>& v) const
02117 {
02118 TVector<T> tv (this->dim);
02119 BCHK(this->dim!=v.dim, VecErr, Unequal size in V + V, v.dim, tv);
02120
02121 STD_SMP_TEMPLATE3VV(vec_vec_add, this->dim, tv.vec, this->vec, v.vec);
02122 return tv;
02123 }
02125 template <typename T>
02126 inline TVector<T> Vector<T>::operator - (const Vector<T>& v) const
02127 {
02128 TVector<T> tv (this->dim);
02129 BCHK(this->dim!=v.dim, VecErr, Unequal size in V - V, v.dim, tv);
02130
02131 STD_SMP_TEMPLATE3VV(vec_vec_sub, this->dim, tv.vec, this->vec, v.vec);
02132 return tv;
02133 }
02134
02137 template <typename T>
02138 inline TVector<T> Vector<T>::operator + ( TVector<T> tv) const
02139 {
02140 BCHK(this->dim!=tv.dim, VecErr, Unequal size in V + TV, tv.dim, tv);
02141
02142 STD_SMP_TEMPLATE2V(vec_add_vec, this->dim, tv.vec, this->vec);
02143 return tv;
02144 }
02147 template <typename T>
02148 inline TVector<T> Vector<T>::operator - ( TVector<T> tv) const
02149 {
02150 BCHK(this->dim!=tv.dim, VecErr, Unequal size in V - TV, tv.dim, tv);
02151
02152 STD_SMP_TEMPLATE2V(vec_sub_vec_inv, this->dim, tv.vec, this->vec);
02153 return tv;
02154 }
02155
02156
02157
02159 template <typename T>
02160 inline TVector<T> Vector<T>::operator + (const TSVector<T>& ts) const
02161 {
02162 TVector<T> tv;
02163 BCHK(this->dim!=ts.dim, VecErr, Wrong dim in V + TSV, ts.dim, tv);
02164 if (LIKELY(ts.mut)) {
02165 tv.vec = ts.vec; tv.dim = ts.dim;
02166 } else
02167 tv.resize (this->dim);
02168
02169
02170 STD_SMP_TEMPLATE4V(vec_svc_add, this->dim, tv.vec, this->vec, ts.vec, ts.fac);
02171 return tv;
02172 }
02174 template <typename T>
02175 inline TVector<T> Vector<T>::operator - (const TSVector<T>& ts) const
02176 {
02177 TVector<T> tv;
02178 BCHK(this->dim!=ts.dim, VecErr, Wrong dim in V - TSV, ts.dim, tv);
02179 if (LIKELY(ts.mut)) {
02180 tv.vec = ts.vec; tv.dim = ts.dim;
02181 } else
02182 tv.resize (this->dim);
02183
02184
02185 STD_SMP_TEMPLATE4V(vec_svc_sub, this->dim, tv.vec, this->vec, ts.vec, ts.fac);
02186 return tv;
02187 }
02188
02190 template <typename T>
02191 inline TVector<T> Vector<T>::operator + (const T& a) const
02192 {
02193 TVector<T> tv (this->dim);
02194
02195 STD_SMP_TEMPLATE3VC(vec_val_add, this->dim, tv.vec, this->vec, a);
02196 return tv;
02197 }
02199 template <typename T>
02200 inline TVector<T> Vector<T>::operator - (const T& a) const
02201 {
02202 TVector<T> tv (this->dim);
02203
02204 STD_SMP_TEMPLATE3VC(vec_val_sub, this->dim, tv.vec, this->vec, a);
02205 return tv;
02206 }
02207
02208
02209 template <typename T>
02210 inline TSVector<T> Vector<T>::operator * (const T& a) const
02211 {
02212 return TSVector<T> (*this, a);
02213 }
02214
02215 template <typename T>
02216 inline TSVector<T> Vector<T>::operator / (const T& a) const
02217 {
02218 BCHK (a==(T)0, VecErr, Division by zero in TSVec / T, 0, TSVector<T> (*this, 1));
02219 return TSVector<T> (*this, (T)1 / a);
02220 }
02221
02222
02223 INST(template <typename T> class Vector friend TVector<T> operator + (const T&, const Vector<T>&);)
02225 template <typename T>
02226 inline TVector<T> operator + (const T& a, const Vector<T>& v)
02227 {
02228 const unsigned long dim = v.size();
02229 TVector<T> tv (dim);
02230 const T* const vvec(&v.getcref(0));
02231 T* const tvvec(&tv.setval(0));
02232
02233
02234 STD_SMP_TEMPLATE3VC(val_vec_add, dim, tvvec, vvec, a);
02235 return tv;
02236 }
02238 INST(template <typename T> class Vector friend TVector<T> operator - (const T&, const Vector<T>&);)
02239 template <typename T>
02240 inline TVector<T> operator - (const T& a, const Vector<T>& v)
02241 {
02242 const unsigned long dim = v.size();
02243 TVector<T> tv (dim);
02244 const T* const vvec(&v.getcref(0));
02245 T* const tvvec(&tv.setval(0));
02246
02247
02248 STD_SMP_TEMPLATE3VC(val_vec_sub, dim, tvvec, vvec, a);
02249 return tv;
02250 }
02251
02252
02253 INST(template <typename T> class Vector friend TSVector<T> operator * (const T&, const Vector<T>&);)
02254 template <typename T>
02255 inline TSVector<T> operator * (const T& a, const Vector<T>& b)
02256 {
02257 return TSVector<T> (b, a);
02258 }
02259
02260
02261 INSTCTL(#ifndef VEC_INT_DIV_SUPPORT)
02262 INST(template <typename T> class Vector friend TSVector<T> operator / (const T&, const Vector<T>&);)
02263 INSTCTL(#endif)
02264 template <typename T>
02265 TSVector<T> operator / (const T& a, const Vector<T>& b)
02266 {
02267 T dv = a / fabssqr (b);
02268 BCHK(dv==(T)0, VecErr, Divide by norm 0 Vector, 0, 0);
02269 return TSVector<T> (b, dv);
02270 }
02271
02272 template <typename T>
02273 inline TVector<T> Vector<T>::operator - () const
02274 {
02275 TVector<T> tv (this->dim);
02276 do_vec_neg_vec<T> (this->dim, tv.vec, this->vec);
02277 return tv;
02278 }
02279
02280
02281 template <typename T>
02282 inline TVector<T> Vector<T>::slice (unsigned long i0, unsigned long i1) const
02283 {
02284 BCHK (i1 < i0, VecErr, Slicing needs ordered arguments, i0, *this);
02285 BCHK (i0 >= this->dim, VecErr, Slice: arg1 out of range, i0, *this);
02286 BCHK (i1 > this->dim, VecErr, Slice: arg2 out of range, i1, *this);
02287 TVector<T> tv (i1 - i0);
02288 if (UNLIKELY(tv.dim))
02289 TBCICOPY(tv.vec, this->vec+i0, T, tv.dim);
02290 return tv;
02291 }
02292
02293
02294 template <typename T>
02295 inline TVector<T> Vector<T>::incr (const unsigned long wh, const T i) const
02296 {
02297 TVector<T> tv (*this);
02298 BCHK (wh >= this->dim, VecErr, Tried to change not-exitsting idx, wh, tv);
02299 tv.vec[wh] += i;
02300 return tv;
02301 }
02302
02303
02304
02305 #define COST_VECFABSSQR(d) (d*(COST_UNIT_LOAD+COST_MULT+COST_ADD+COST_LOOP))
02306 #define COST_VECSCALAR(d) (d*(2*COST_UNIT_LOAD+COST_MULT+COST_ADD+COST_LOOP))
02307
02308
02309
02310 INST(template <typename T> class Vector friend double fabssqr (const Vector<T>&);)
02311 template <typename T>
02312 inline double fabssqr (const Vector<T>& v)
02313 { return v.fabssqr(); ;}
02314
02315
02316 #if !defined(SMP) || defined(NOSMP_VECFABS)
02317
02318 template <typename T>
02319 inline double Vector<T>::fabssqr () const
02320 {
02321 LONG_DOUBLE res = 0.0;
02322 do_vec_fabssqr (this->dim, this->vec, res);
02323 #ifdef SMPVEC_DEBUG
02324 STD__ cerr << "fabssqr: " << STD__ setprecision (16) << res << STD__ endl;
02325 #endif
02326 return res;
02327 }
02328
02329 #else
02330
02331 INST(template <typename T> class Vector friend void job_vec_fabssqr (struct thr_ctrl*);)
02332 template <typename T>
02333 void job_vec_fabssqr (struct thr_ctrl *tc)
02334 {
02335 tc->t_res = 0.0;
02336 do_vec_fabssqr (tc->t_size, (const T*)(tc->t_par[0]), tc->t_res);
02337 }
02338
02339 template <typename T>
02340 inline double Vector<T>::fabssqr () const
02341 {
02342 LONG_DOUBLE res = 0.0; unsigned long sz = this->dim;
02343
02344 const unsigned n_thr = threads_avail (sz / SMP_VECSLICE);
02345 if (LIKELY(n_thr < 2))
02346 do_vec_fabssqr<T> (sz, this->vec, res);
02347 else {
02348 PREFETCH_R(this->vec, 3);
02349 const unsigned long first = slice_offset(1, n_thr, sz, this->vec);
02350 unsigned long st, en = first;
02351
02352 for (unsigned t = 0; t < n_thr-1; ++t) {
02353 st = en; en = slice_offset(t+2, n_thr, sz, this->vec);
02354 thread_start (t, (thr_job_t)job_vec_fabssqr<T>, en-st,
02355 this->vec+st, (void*)0);
02356 }
02357
02358 do_vec_fabssqr<T> (first, this->vec, res);
02359
02360
02361 for (unsigned t = 0; t < n_thr-1; ++t)
02362 res += thread_wait_result (t);
02363 }
02364 #ifdef SMPVEC_DEBUG
02365 STD__ cerr << "fabssqr: " << STD__ setprecision (16) << res << STD__ endl;
02366 #endif
02367 return res;
02368 }
02369
02370 #endif
02371
02372 INST(template <typename T> class TVector friend double fabssqr (TVector<T>);)
02373 template <typename T>
02374 inline double fabssqr (TVector<T> tv)
02375 { return tv.fabssqr (); }
02376
02377
02378
02379
02380
02381
02382
02383
02384
02385
02386
02387
02388
02389 #ifdef INC_VEC_EXTRA
02390 # include "vector_extra.h"
02391 #endif
02392
02393 NAMESPACE_END
02394
02395
02396
02397
02398
02399 #ifdef VEC_INT_DIV_SUPPORT
02400
02401 NAMESPACE_TBCI
02402
02403
02404 template <>
02405 inline TSVector<int> operator / (const int& a, TVector<int> b)
02406 {
02407 double dv = (double)a / b.fabssqr ();
02408 BCHK(!dv, VecErr, Divide by norm 0 Vector, 0, b);
02409 for (unsigned long i = 0; i < b.size (); ++i)
02410 b.set((int)(b.get(i) * dv), i);
02411 return TSVector<int> (b, (int)1);
02412 }
02413
02414 template <>
02415 inline TVector<int>& TVector<int>::operator /= (const int& a)
02416 {
02417 BCHK(a==0, VecErr, Divide TVector<int> by zero, 0, *this);
02418 for (register unsigned long i = 0; i < this->dim; ++i)
02419 this->vec[i] /= a;
02420 return *this;
02421 }
02422
02423 template <>
02424 inline TSVector<int> operator / (const int& a, const Vector<int>& b)
02425 {
02426 double dv = (double)a / b.fabssqr ();
02427 TVector<int> r (b.size ());
02428 BCHK(!dv, VecErr, Divide by norm 0 Vector, 0, r);
02429 for (unsigned long i = 0; i < b.size (); ++i)
02430 r.set ((int)(dv * b.get(i)), i);
02431 return TSVector<int>(r, 1);
02432 }
02433
02434 template <>
02435 inline TSVector<int> Vector<int>::operator / (const int& a) const
02436 {
02437 TVector<int> r (this->dim);
02438 BCHK(a==0, VecErr, Divide Vector<int> by 0, 0, r);
02439 for (unsigned long i = 0; i < this->dim; ++i)
02440 r.vec[i] = this->vec[i] / a;
02441 return TSVector<int> (r, 1);
02442 }
02443
02444
02445
02446
02447
02448 template <>
02449 inline TVector<unsigned>& TVector<unsigned>::operator /= (const unsigned& a)
02450 {
02451 BCHK(a==0, VecErr, Divide TVector<unsigned> by zero, 0, *this);
02452 for (register unsigned long i = 0; i < this->dim; ++i)
02453 this->vec[i] /= a;
02454 return *this;
02455 }
02456
02457
02458 #ifndef HAVE_WIN_32
02459
02460 template <>
02461 inline TSVector<unsigned> operator / (const unsigned& a, TVector<unsigned> b)
02462 {
02463 double dv = (double)a / b.fabssqr ();
02464 BCHK(!dv, VecErr, Divide by norm 0 Vector, 0, b);
02465 for (unsigned long i = 0; i < b.size (); ++i)
02466 b.set((unsigned)(b.get(i) * dv), i);
02467 return TSVector<unsigned> (b, (unsigned)1);
02468 }
02469 #endif
02470
02471 template <>
02472 inline TSVector<unsigned> operator / (const unsigned& a, const Vector<unsigned>& b)
02473 {
02474 double dv = (double)a / b.fabssqr ();
02475 BCHK(!dv, VecErr, Divide by norm 0 Vector, 0, b);
02476 TVector<unsigned> r (b.size ());
02477 for (unsigned long i = 0; i < b.size (); ++i)
02478 r.set ((unsigned)(dv * b.get(i)), i);
02479 return TSVector<unsigned>(r, 1);
02480 }
02481
02482 template <>
02483 inline TSVector<unsigned> Vector<unsigned>::operator / (const unsigned& a) const
02484 {
02485 TVector<unsigned> r (this->dim);
02486 BCHK(a==0, VecErr, Divide Vector<unsigned> by 0, 0, r);
02487 for (unsigned long i = 0; i < this->dim; ++i)
02488 r.vec[i] = this->vec[i] / a;
02489 return TSVector<unsigned> (r, 1);
02490 }
02491
02492 NAMESPACE_END
02493
02494 #endif
02495
02496 #endif