basix_doc 0.1
|
00001 00002 /****************************************************************************** 00003 * MODULE : vector.hpp 00004 * DESCRIPTION: Dense univariate vectors 00005 * COPYRIGHT : (C) 2004 Joris van der Hoeven 00006 ******************************************************************************* 00007 * This software falls under the GNU general public license and comes WITHOUT 00008 * ANY WARRANTY WHATSOEVER. See the file $TEXMACS_PATH/LICENSE for more details. 00009 * If you don't have this file, write to the Free Software Foundation, Inc., 00010 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00011 ******************************************************************************/ 00012 00013 #ifndef __MMX_VECTOR_HPP 00014 #define __MMX_VECTOR_HPP 00015 #include <basix/iterator.hpp> 00016 #include <basix/vector_naive.hpp> 00017 00019 00020 namespace mmx { 00021 #define Vector_variant(C) vector_variant_helper<C>::VV 00022 #define TMPL_DEF template<typename C, typename V> 00023 // NOTE: default argument vector_variant_helper<C>::VV specified in basix.hpp 00024 #define TMPL template<typename C, typename V> 00025 #define TMPLK template<typename C, typename V, typename K> 00026 #define Format format<C> 00027 #define Vector vector<C,V> 00028 #define Vector_int vector<int,V> 00029 #define Vector_rep vector_rep<C,V> 00030 #define Abs_vector vector<Abs_type(C),V> 00031 #define Real_vector vector<Real_type(C),V> 00032 #define Center_vector vector<Center_type(C),V> 00033 #define Radius_vector vector<Radius_type(C),V> 00034 TMPL class vector; 00035 TMPL inline nat N (const Vector& v); 00036 TMPL inline C* seg (Vector& v); 00037 TMPL inline const C* seg (const Vector& v); 00038 TMPL inline bool is_a_scalar (const Vector& v); 00039 TMPL inline bool is_non_scalar (const Vector& v); 00040 00041 /****************************************************************************** 00042 * Dense vectors of arbitrary sizes 00043 ******************************************************************************/ 00044 00045 TMPL_DEF 00046 class vector_rep REP_STRUCT_1(C) { 00047 public: 00048 typedef implementation<vector_linear,V> Vec; 00049 private: 00050 C* a; // entries of vector 00051 nat n; // dimension of vector 00052 nat l; // allocated number of entries 00053 bool scalar_flag; // is the vector a scalar value? 00054 public: 00055 inline vector_rep (C* a2, nat n2, bool flag, const Format& fm): 00056 Format (fm), a (a2), n (n2), l (n2), scalar_flag (flag) {} 00057 inline vector_rep (C* a2, nat n2, nat l2, bool flag, const Format& fm): 00058 Format (fm), a (a2), n (n2), l (l2), scalar_flag (flag) {} 00059 inline ~vector_rep () { mmx_delete<C> (a, l); } 00060 void resize (nat n2) { 00061 nat l2; 00062 if (n2 > l) l2= aligned_size<C,V> (max (n2, l<<1)); 00063 else if (n2 < (l >> 1)) l2= aligned_size<C,V> (n2); 00064 else { n= n2; return; } 00065 C* b= mmx_new<C> (l2); 00066 Vec::copy (b, a, min (n, n2)); 00067 mmx_delete<C> (a, l); 00068 a= b; 00069 n= n2; 00070 l= l2; 00071 } 00072 friend class Vector; 00073 friend nat N LESSGTR (const Vector& v); 00074 friend C* seg LESSGTR (Vector& v); 00075 friend const C* seg LESSGTR (const Vector& v); 00076 friend bool is_a_scalar LESSGTR (const Vector& v); 00077 friend bool is_non_scalar LESSGTR (const Vector& v); 00078 }; 00079 00080 TMPL_DEF 00081 class vector { 00082 INDIRECT_PROTO_2 (vector, vector_rep, C, V) 00083 public: 00084 typedef implementation<vector_linear,V> Vec; 00085 public: 00086 vector () { 00087 nat n= Vec::def_len; 00088 nat l= aligned_size<C,V> (n); 00089 C* a= mmx_formatted_new<C> (l, Format (no_format ())); 00090 rep= new Vector_rep (a, n, l, false, Format (no_format ())); 00091 } 00092 vector (const Format& fm) { 00093 nat n= Vec::def_len; 00094 nat l= aligned_size<C,V> (n); 00095 C* a= mmx_formatted_new<C> (l, fm); 00096 rep= new Vector_rep (a, n, l, false, fm); 00097 } 00098 template<typename T> 00099 vector (const T& c) { 00100 Format fm= as<Format > (get_format (c)); 00101 nat n= Vec::init_len; 00102 nat l= aligned_size<C,V> (n); 00103 C* a= mmx_formatted_new<C> (l, fm); 00104 Vec::set (a, as<C> (c), n); 00105 rep= new Vector_rep (a, n, l, true, fm); 00106 } 00107 template<typename T> 00108 vector (const T& c, const Format& fm) { 00109 nat n= Vec::init_len; 00110 nat l= aligned_size<C,V> (n); 00111 C* a= mmx_formatted_new<C> (l, fm); 00112 Vec::set_as (a, c, n); 00113 rep= new Vector_rep (a, n, l, true, fm); 00114 } 00115 vector (const C& x) { 00116 Format fm= as<Format > (get_format (x)); 00117 nat n= Vec::init_len; 00118 nat l= aligned_size<C,V> (n); 00119 C* a= mmx_formatted_new<C> (l, fm); 00120 Vec::set (a, x, n); 00121 rep= new Vector_rep (a, n, l, true, fm); 00122 } 00123 template<typename T, typename W> 00124 vector (const vector<T,W>& v) { 00125 Format fm= as<Format > (CF(v)); 00126 nat l= aligned_size<C,V> (N(v)); 00127 C* a= mmx_formatted_new<C> (l, fm); 00128 Vec::cast (a, seg (v), N(v)); 00129 rep= new Vector_rep (a, N(v), l, is_a_scalar (v), fm); 00130 } 00131 template<typename T, typename W> 00132 vector (const vector<T,W>& v, const Format& fm) { 00133 nat l= aligned_size<C,V> (N(v)); 00134 C* a= mmx_formatted_new<C> (l, fm); 00135 Vec::cast (a, seg (v), N(v)); 00136 rep= new Vector_rep (a, N(v), l, is_a_scalar (v), fm); 00137 } 00138 template<typename T> 00139 vector (const T& c, nat n) { 00140 Format fm= as<Format > (get_format (c)); 00141 nat l= aligned_size<C,V> (n); 00142 C* a= mmx_formatted_new<C> (l, fm); 00143 Vec::set (a, as<C> (c), n); 00144 rep= new Vector_rep (a, n, l, true, fm); 00145 } 00146 vector (const C& x, nat n) { 00147 nat l= aligned_size<C,V> (n); 00148 C* a= mmx_formatted_new<C> (l, get_format (x)); 00149 Vec::set (a, x, n); 00150 rep= new Vector_rep (a, n, l, false, get_format (x)); 00151 } 00152 inline vector (C* a, nat n, const Format& fm) { 00153 rep= new Vector_rep (a, n, false, fm); 00154 } 00155 inline vector (C* a, nat n, nat l, const Format& fm) { 00156 rep= new Vector_rep (a, n, l, false, fm); 00157 } 00158 inline vector (C* a, nat n, nat l, bool flag, const Format& fm) { 00159 rep= new Vector_rep (a, n, l, flag, fm); 00160 } 00161 vector (const iterator<C>& it) { 00162 Format fm= CF(it); 00163 nat i, l= Vec::def_len; 00164 if (l==0) l= aligned_size<C,V> ((nat) 1); 00165 C* a= mmx_formatted_new<C> (l, fm); 00166 for (i=0; busy (it); i++, ++it) { 00167 if (i >= l) { 00168 C* b= mmx_formatted_new<C> (aligned_size<C,V> (l<<1), fm); 00169 Vec::copy (b, a, l); 00170 mmx_delete (a, l); 00171 a= b; 00172 l= l<<1; 00173 } 00174 a[i]= *it; 00175 } 00176 rep= new Vector_rep (a, i, l, false, fm); 00177 } 00178 00179 inline const C& operator [] (nat i) const { 00180 VERIFY (is_non_scalar (*this), "non-scalar vector expected"); 00181 VERIFY (i<N(*this), "index out of range"); 00182 return rep->a[i]; } 00183 inline C& operator [] (nat i) { 00184 VERIFY (is_non_scalar (*this), "non-scalar vector expected"); 00185 VERIFY (i<N(*this), "index out of range"); 00186 secure(); return rep->a[i]; } 00187 inline C scalar () const { 00188 VERIFY (is_a_scalar (*this), "scalar vector expected"); 00189 return rep->a[0]; } 00190 inline C& scalar () { 00191 VERIFY (is_a_scalar (*this), "scalar vector expected"); 00192 return rep->a[0]; } 00193 inline nat size() const { 00194 return rep->n; } 00195 00196 Vector& operator << (const C& append); 00197 Vector& operator << (const Vector& w); 00198 }; 00199 INDIRECT_IMPL_2 (vector, vector_rep, typename C, C, typename V, V) 00200 DEFINE_UNARY_FORMAT_2 (vector) 00201 00202 TMPL inline nat N (const Vector& v) { return v->n; } 00203 TMPL inline Format CF (const Vector& v) { return v->tfm (); } 00204 TMPL inline bool is_a_scalar (const Vector& v) { return v->scalar_flag; } 00205 TMPL inline bool is_non_scalar (const Vector& v) { return !v->scalar_flag; } 00206 TMPL inline const C& read (const Vector& v, nat i) { return v[i]; } 00207 TMPL inline const C* seg (const Vector& v) { return v->a; } 00208 TMPL inline C* seg (Vector& v) { 00209 VERIFY (is_non_scalar (v), "non-scalar vector expected"); 00210 v.secure(); return v->a; } 00211 template<typename C, typename V, typename C2, typename V2> inline Vector 00212 extend (const Vector& v, const vector<C2,V2>& w) { 00213 VERIFY (is_a_scalar (v), "scalar vector expected"); 00214 VERIFY (is_non_scalar (w), "non-scalar vector expected"); 00215 return Vector (v.scalar(), N(w)); } 00216 TMPL inline bool is_nil (const Vector& v) { 00217 return N(v) == 0; } 00218 TMPL inline bool is_atom (const Vector& v) { 00219 return is_non_scalar (v) && N(v) == 1; } 00220 00221 STYPE_TO_TYPE(TMPL,scalar_type,Vector,C); 00222 UNARY_RETURN_TYPE(TMPL,abs_op,Vector,Abs_vector); 00223 UNARY_RETURN_TYPE(TMPL,Re_op,Vector,Real_vector); 00224 UNARY_RETURN_TYPE(TMPL,center_op,Vector,Center_vector); 00225 UNARY_RETURN_TYPE(TMPL,radius_op,Vector,Radius_vector); 00226 TMPL struct rounding_helper<Vector >: public rounding_helper<C> {}; 00227 TMPL struct species_type_information<Vector > { 00228 static const nat id= SPECIES_VECTOR; }; 00229 00230 TMPL 00231 struct fast_helper<Vector > { 00232 typedef Fast_type(C) FC; 00233 typedef vector<FC> fast_type; 00234 typedef typename Vector_variant(FC) FV; 00235 static inline fast_type dd (const Vector& v) { 00236 format<FC> fm= fast (CF(v)); 00237 nat l= aligned_size<FC, FV> (N(v)); 00238 FC* r= mmx_formatted_new<FC> (l, fm); 00239 for (nat i=0; i<N(v); i++) r[i]= fast (v[i]); 00240 return fast_type (r, N(v), l, is_a_scalar (v), fm); } 00241 static inline Vector uu (const fast_type& v) { 00242 Format fm= slow<C> (CF(v)); 00243 nat l= aligned_size<C,V> ((N(v))); 00244 C* r= mmx_formatted_new<C> (l, fm); 00245 for (nat i=0; i<N(v); i++) r[i]= slow<C> (v[i]); 00246 return Vector (r, N(v), l, is_a_scalar (v), fm); } 00247 }; 00248 00249 template<typename T, typename F, typename TV, typename FV> 00250 struct as_helper<vector<T,TV>, vector<F,FV> > { 00251 static inline vector<T,TV> 00252 cv (const vector<F,FV>& v) { 00253 format<T> fm= as<format<T> > (CF(v)); 00254 nat l= aligned_size<T,TV> (N(v)); 00255 T* c= mmx_formatted_new<T> (l, fm); 00256 for (nat i=0; i<N(v); i++) c[i]= as<T> (v[i]); 00257 return vector<T,TV> (c, N(v), l, is_a_scalar (v), fm); } 00258 }; 00259 00260 template<typename T, typename F, typename TV, typename FV> inline void 00261 set_as (vector<T,TV>& r, const vector<F,FV>& v) { 00262 r= vector<T,TV> (v, CF(r)); 00263 } 00264 00265 template<typename C, typename V, typename T> inline void 00266 set_as (Vector& r, const T& x) { 00267 r= Vector (x, CF(r)); 00268 } 00269 00270 /****************************************************************************** 00271 * Abstract vectors 00272 ******************************************************************************/ 00273 00274 TMPL 00275 struct vector_as_helper<Vector > { 00276 static inline generic abstract (const Vector& x) { 00277 return as<generic> (as<vector<generic> > (x)); } 00278 static inline Vector concrete (const generic& x) { 00279 return as<Vector > (as<vector<generic> > (x)); } 00280 }; 00281 00282 inline vector<generic> 00283 abstract_vector (const generic& conc) { 00284 return as<vector<generic> > (conc->make_abstract_vector ()); 00285 } 00286 00287 inline generic 00288 concrete_vector (const vector<generic>& abst, const generic& conc) { 00289 return conc->make_concrete_vector (as<generic> (abst)); 00290 } 00291 00292 /****************************************************************************** 00293 * Fixed size dense vectors 00294 ******************************************************************************/ 00295 00296 template<typename V, typename S> 00297 struct vector_fixed: public V { 00298 typedef typename V::Naive Naive; 00299 typedef vector_fixed<typename V::Aligned,S> Aligned; 00300 typedef vector_fixed<typename V::No_simd,S> No_simd; 00301 typedef vector_fixed<typename V::No_thread,S> No_thread; 00302 }; 00303 00304 template<typename V, typename W, typename S> 00305 struct implementation<vector_defaults,V,vector_fixed<W,S> > { 00306 static const nat def_len = S::val; 00307 static const nat init_len= S::val; 00308 }; // implementation<vector_defaults,V,vector_fixed<W,S> > 00309 00310 template<typename F, typename V, typename W, typename S> 00311 struct implementation<F,V,vector_fixed<W,S> >: 00312 public implementation<F,V,W> {}; 00313 00314 #define FVector vector <C,vector_fixed<V,S> > 00315 #define FVector_rep vector_rep<C,vector_fixed<V,S> > 00316 00317 template<typename C, typename V, typename S> 00318 class FVector_rep REP_STRUCT_1(C) { 00319 C* a; 00320 public: 00321 /* 00322 inline vector_rep (C* a2, nat n, bool dummy): 00323 a (a2) { 00324 VERIFY (n == S::val, "wrong size"); 00325 (void) n; (void) dummy; } 00326 inline vector_rep (C* a2, nat n, nat l, bool dummy): 00327 a (a2) { 00328 VERIFY (n == S::val, "wrong size"); 00329 VERIFY ((l == aligned_size<C,V> (S::val)), "wrong allocated size"); 00330 (void) n; (void) l; (void) dummy; } 00331 */ 00332 inline vector_rep (C* a2, nat n, bool dummy, const Format& fm): 00333 Format (fm), a (a2) { 00334 VERIFY (n == S::val, "wrong size"); 00335 (void) n; (void) dummy; } 00336 inline vector_rep (C* a2, nat n, nat l, bool dummy, const Format& fm): 00337 Format (fm), a (a2) { 00338 VERIFY (n == S::val, "wrong size"); 00339 VERIFY ((l == aligned_size<C,V> (S::val)), "wrong allocated size"); 00340 (void) n; (void) l; (void) dummy; } 00341 inline virtual ~vector_rep () { 00342 mmx_delete<C> (a, aligned_size<C,V> (S::val)); } 00343 friend class FVector; 00344 friend nat N LESSGTR (const FVector& v); 00345 friend C* seg LESSGTR (FVector& v); 00346 friend const C* seg LESSGTR (const FVector& v); 00347 friend bool is_a_scalar LESSGTR (const Vector& v); 00348 friend bool is_non_scalar LESSGTR (const Vector& v); 00349 }; 00350 00351 template<typename C, typename V, typename S> inline nat 00352 N (const FVector& v) { return S::val; } 00353 template<typename C, typename V, typename S> inline bool 00354 is_a_scalar (const FVector& v) { (void) v; return false; } 00355 template<typename C, typename V, typename S> inline bool 00356 is_non_scalar (const FVector& v) { (void) v; return true; } 00357 00358 #undef FVector 00359 #undef FVector_rep 00360 00361 /****************************************************************************** 00362 * Explicit dense vectors 00363 ******************************************************************************/ 00364 00365 template<typename C> vector<C> 00366 vec () { 00367 Format fm; 00368 nat l= default_aligned_size<C> ((nat) 0); 00369 C* a= mmx_formatted_new<C> (l, fm); 00370 return vector<C> (a, 0, l, fm); 00371 } 00372 00373 template<typename C> vector<C> 00374 vec (const Format& fm) { 00375 nat l= default_aligned_size<C> ((nat) 0); 00376 C* a= mmx_formatted_new<C> (l, fm); 00377 return vector<C> (a, 0, l, fm); 00378 } 00379 00380 template<typename C> vector<C> 00381 vec (const C& c1) { 00382 Format fm= get_format (c1); 00383 nat l= default_aligned_size<C> ((nat) 1); 00384 C* a= mmx_formatted_new<C> (l, fm); 00385 a[0]= c1; 00386 return vector<C> (a, 1, l, fm); 00387 } 00388 00389 template<typename C> vector<C> 00390 vec (const C& c1, const C& c2) { 00391 Format fm= get_format (c1); 00392 nat l= default_aligned_size<C> ((nat) 2); 00393 C* a= mmx_formatted_new<C> (l, fm); 00394 a[0]= c1; a[1]= c2; 00395 return vector<C> (a, 2, l, fm); 00396 } 00397 00398 template<typename C> vector<C> 00399 vec (const C& c1, const C& c2, const C& c3) { 00400 Format fm= get_format (c1); 00401 nat l= default_aligned_size<C> ((nat) 3); 00402 C* a= mmx_formatted_new<C> (l, fm); 00403 a[0]= c1; a[1]= c2; a[2]= c3; 00404 return vector<C> (a, 3, l, fm); 00405 } 00406 00407 template<typename C> vector<C> 00408 vec (const C& c1, const C& c2, const C& c3, const C& c4) { 00409 Format fm= get_format (c1); 00410 nat l= default_aligned_size<C> ((nat) 4); 00411 C* a= mmx_formatted_new<C> (l, fm); 00412 a[0]= c1; a[1]= c2; a[2]= c3; a[3]= c4; 00413 return vector<C> (a, 4, l, fm); 00414 } 00415 00416 template<typename C> vector<C> 00417 vec (const C& c1, const C& c2, const C& c3, const C& c4, const C& c5) { 00418 Format fm= get_format (c1); 00419 nat l= default_aligned_size<C> ((nat) 5); 00420 C* a= mmx_formatted_new<C> (l, fm); 00421 a[0]= c1; a[1]= c2; a[2]= c3; a[3]= c4; a[4]= c5; 00422 return vector<C> (a, 5, l, fm); 00423 } 00424 00425 template<typename C> vector<C> 00426 vec (const C& c1, const C& c2, const C& c3, 00427 const C& c4, const C& c5, const C& c6) { 00428 Format fm= get_format (c1); 00429 nat l= default_aligned_size<C> ((nat) 6); 00430 C* a= mmx_formatted_new<C> (l, fm); 00431 a[0]= c1; a[1]= c2; a[2]= c3; a[3]= c4; a[4]= c5; a[5]= c6; 00432 return vector<C> (a, 6, l, fm); 00433 } 00434 00435 template<typename C> vector<C> 00436 vec (const C& c1, const C& c2, const C& c3, const C& c4, 00437 const C& c5, const C& c6, const C& c7) { 00438 Format fm= get_format (c1); 00439 nat l= default_aligned_size<C> ((nat) 7); 00440 C* a= mmx_formatted_new<C> (l, fm); 00441 a[0]= c1; a[1]= c2; a[2]= c3; a[3]= c4; a[4]= c5; a[5]= c6; a[6]= c7; 00442 return vector<C> (a, 7, l, fm); 00443 } 00444 00445 template<typename C> vector<C> 00446 vec (const C& c1, const C& c2, const C& c3, const C& c4, 00447 const C& c5, const C& c6, const C& c7, const C& c8) { 00448 Format fm= get_format (c1); 00449 nat l= default_aligned_size<C> ((nat) 8); 00450 C* a= mmx_formatted_new<C> (l, fm); 00451 a[0]= c1; a[1]= c2; a[2]= c3; a[3]= c4; 00452 a[4]= c5; a[5]= c6; a[6]= c7; a[7]= c8; 00453 return vector<C> (a, 8, l, fm); 00454 } 00455 00456 template<typename C> inline vector<C> 00457 fill (nat n) { 00458 Format fm; 00459 nat l= default_aligned_size<C> (n); 00460 C* a= mmx_formatted_new<C> (l, fm); 00461 return vector<C> (a, n, l, fm); 00462 } 00463 00464 template<typename C> inline vector<C> 00465 fill (nat n, const Format& fm) { 00466 nat l= default_aligned_size<C> (n); 00467 C* a= mmx_formatted_new<C> (l, fm); 00468 return vector<C> (a, n, l, fm); 00469 } 00470 00471 template<typename C> inline vector<C> 00472 fill (const C& c, nat n) { 00473 Format fm= get_format (c); 00474 nat l= default_aligned_size<C> (n); 00475 C* a= mmx_formatted_new<C> (l, fm); 00476 for (nat i=0; i<n; i++) a[i]= c; 00477 return vector<C> (a, n, l, fm); 00478 } 00479 00480 /****************************************************************************** 00481 * Vector iteration 00482 ******************************************************************************/ 00483 00484 TMPL_DEF 00485 class vector_iterator_rep: public iterator_rep<C> { 00486 const Vector v; // the vector to traverse 00487 nat i; // current position 00488 public: 00489 vector_iterator_rep (const Vector& v2, nat i2= 0): 00490 iterator_rep<C> (CF (v2)), v (v2), i (0) { (void) i2; } 00491 protected: 00492 bool is_busy () { return i < N(v); } 00493 void advance () { i++; } 00494 C current () { return v[i]; } 00495 iterator_rep<C>* clone () { return new vector_iterator_rep (v, i); } 00496 }; 00497 00498 TMPL iterator<C> 00499 iterate (const Vector& v) { 00500 return iterator<C> (new vector_iterator_rep<C,V> (v)); 00501 } 00502 00503 /****************************************************************************** 00504 * Hashing and generic output routines for iterators and vectors 00505 ******************************************************************************/ 00506 00507 TMPL syntactic 00508 flatten (const Vector& v) { 00509 if (is_a_scalar (v)) return flatten (v.scalar()); 00510 nat i, n= N(v); 00511 vector<syntactic> r= fill <syntactic> (n); 00512 for (i=0; i<n; i++) 00513 r[i]= flatten (v[i]); 00514 return apply (GEN_SQTUPLE, r); 00515 } 00516 00517 TMPL 00518 struct binary_helper<Vector > { 00519 static inline string short_type_name () { 00520 return "V" * Short_type_name (C); } 00521 static inline generic full_type_name () { 00522 return gen ("Vector", Full_type_name (C)); } 00523 static nat size (const Vector& v) { 00524 if (is_a_scalar (v)) return 0; 00525 else return N(v); } 00526 static generic access (const Vector& v, nat i) { 00527 ASSERT (!is_a_scalar (v), "non-scalar vector expected"); 00528 return as<generic> (v[i]); } 00529 static generic disassemble (const Vector& v) { 00530 if (is_a_scalar (v)) return as<generic> (v.scalar ()); 00531 return as<generic> (as<vector<generic> > (v)); } 00532 static Vector assemble (const generic& v) { 00533 // FIXME: what to do with the format? 00534 if (!is<vector<generic> > (v)) return Vector (as<C> (v)); 00535 else return as<Vector > (as<vector<generic> > (v)); } 00536 static void write (const port& out, const Vector& v) { 00537 binary_write<Format > (out, CF (v)); 00538 binary_write<bool> (out, is_a_scalar (v)); 00539 if (is_a_scalar (v)) binary_write<C> (out, v.scalar ()); 00540 else { 00541 binary_write<nat> (out, N(v)); 00542 for (nat i=0; i<N(v); i++) 00543 binary_write<C> (out, v[i]); } } 00544 static Vector read (const port& in) { 00545 Format fm= binary_read<Format > (in); 00546 bool sc= binary_read<bool> (in); 00547 if (sc) return Vector (binary_read<C> (in)); 00548 else { 00549 nat n= binary_read<nat> (in); 00550 nat l= aligned_size<C,V> (n); 00551 C* r= mmx_new<C> (l); 00552 for (nat i=0; i<n; i++) 00553 r[i]= binary_read<C> (in); 00554 return Vector (r, n, l, fm); } } 00555 }; 00556 00557 /****************************************************************************** 00558 * Extracting ranges of elements and appending new elements 00559 ******************************************************************************/ 00560 00561 TMPL Vector 00562 range (const Vector& v, nat start, nat end) { 00563 typedef implementation<vector_linear,V> Vec; 00564 VERIFY(end >= start, "bad range"); 00565 nat n= end - start; 00566 if (is_a_scalar (v)) return Vector (v.scalar(), n); 00567 nat l= aligned_size<C,V> (n); 00568 C* a= mmx_formatted_new<C> (l, CF(v)); 00569 Vec::copy (a, seg (v) + start, n); 00570 return Vector (a, n, l, CF(v)); 00571 } 00572 00573 TMPL Vector 00574 extract_mod (const Vector& v, nat k, nat p) { 00575 nat n= (N(v) - k + p - 1) / p; 00576 nat l= aligned_size<C,V> (n); 00577 C* r= mmx_formatted_new<C> (l, CF(v)); 00578 for (nat i=0; i<n; i++) r[i]= v[i*p+k]; 00579 return Vector (r, n, l, CF(v)); 00580 } 00581 00582 TMPL Vector 00583 extract (const Vector& v, vector<nat> e) { 00584 nat l= aligned_size<C,V> (N(e)); 00585 C* r= mmx_formatted_new<C> (l, CF(v)); 00586 for (nat i=0; i<N(e); i++) 00587 if (e[i] < N(v)) r[i]= v[e[i]]; 00588 return Vector (r, N(e), l, CF(v)); 00589 } 00590 00591 TMPL Vector 00592 remove (const Vector& v, vector<nat> e) { 00593 nat n= N(v); 00594 vector<nat> f ((nat) 0, n); 00595 for (nat i= 0; i < n; i++) f[i]= i; 00596 for (nat i= 0; i < N(e); i++) if (e[i] < n) f[e[i]]= n; 00597 Vector r; 00598 for (nat i= 0; i < n; i++) { 00599 if (f[i] == n) continue; 00600 r << v[i]; 00601 } 00602 return r; 00603 } 00604 00605 TMPL inline C car (const Vector& v) { return v[0]; } 00606 TMPL inline Vector cdr (const Vector& v) { return range (v, 1, N(v)); } 00607 00608 TMPL Vector 00609 append (const Vector& v, const C& c) { 00610 typedef implementation<vector_linear,V> Vec; 00611 ASSERT (is_non_scalar (v), "non-scalar vector expected"); 00612 nat n= N(v); 00613 nat l= aligned_size<C,V> (n+1); 00614 C* a= mmx_formatted_new<C> (l, CF(v)); 00615 a[n]= c; 00616 Vec::copy (a, seg (v), n); 00617 return Vector (a, n+1, l, CF(v)); 00618 } 00619 00620 TMPL Vector 00621 append (const Vector& v, const Vector& w) { 00622 typedef implementation<vector_linear,V> Vec; 00623 ASSERT (is_non_scalar (v) && is_non_scalar (w), 00624 "non-scalar vectors expected"); 00625 nat n= N(v), p= N(w); 00626 nat l= aligned_size<C,V> (n+p); 00627 C* a= mmx_formatted_new<C> (l, CF(v)); 00628 Vec::copy (a, seg (v), n); 00629 Vec::copy (a+n, seg (w), p); 00630 return Vector (a, n+p, l, CF(v)); 00631 } 00632 00633 TMPL Vector 00634 cons (const C& c, const Vector& v) { 00635 typedef implementation<vector_linear,V> Vec; 00636 ASSERT (is_non_scalar (v), "non-scalar vector expected"); 00637 nat n= N(v); 00638 nat l= aligned_size<C,V> (n+1); 00639 C* a= mmx_formatted_new<C> (l, CF(v)); 00640 a[0]= c; 00641 Vec::copy (a+1, seg (v), n); 00642 return Vector (a, n+1, l, CF(v)); 00643 } 00644 00645 TMPL Vector& 00646 Vector::operator << (const C& append) { 00647 ASSERT (is_non_scalar (*this), "non-scalar vector expected"); 00648 secure (); 00649 nat n= rep->n; 00650 rep->resize (n+1); 00651 rep->a[n]= append; 00652 return *this; 00653 } 00654 00655 TMPL Vector& 00656 Vector::operator << (const Vector& w) { 00657 typedef implementation<vector_linear,V> Vec; 00658 ASSERT (is_non_scalar (*this) && is_non_scalar (w), 00659 "non-scalar vectors expected"); 00660 secure (); 00661 nat n= rep->n, p= N(w); 00662 rep->resize (n + p); 00663 Vec::copy (rep->a + n, seg (w), p); 00664 return *this; 00665 } 00666 00667 TMPL void 00668 inside_append (const Vector& v, const Vector& w) { 00669 typedef implementation<vector_linear,V> Vec; 00670 ASSERT (is_non_scalar (v) && is_non_scalar (w), 00671 "non-scalar vectors expected"); 00672 nat n= N(v), p= N(w); 00673 inside (v)->resize (n + p); 00674 Vec::copy (const_cast<C*> (seg (v)) + n, seg (w), p); 00675 } 00676 00677 TMPL Vector 00678 reverse (const Vector& v) { 00679 typedef implementation<vector_linear,V> Vec; 00680 if (is_a_scalar (v)) return v; 00681 nat n= N(v); 00682 nat l= aligned_size<C,V> (n); 00683 C* a= mmx_formatted_new<C> (l, CF(v)); 00684 Vec::vec_reverse (a, seg (v), n); 00685 return Vector (a, n, l, CF(v)); 00686 } 00687 00688 TMPL int 00689 find (const Vector& v, const C& x) { 00690 nat i, n=N(v); 00691 for (i=0; i<n; i++) 00692 if (v[i] == x) return (int) i; 00693 return (int) i; 00694 } 00695 00696 TMPL bool 00697 contains (const Vector& v, const C& x) { 00698 return find (v, x) < ((int) N(v)); 00699 } 00700 00701 TMPL Vector 00702 insert (const Vector& v, const C& x) { 00703 if (contains (v, x)) return v; 00704 else return append (v, x); 00705 } 00706 00707 TMPL Vector 00708 insert (const Vector& v, const C& x, nat pos) { 00709 // insert x at 'pos' in v 00710 ASSERT (pos <= N(v), "position out of range"); 00711 nat n= N(v) + 1, i; nat l= aligned_size<C,V> (n); 00712 C* a= mmx_formatted_new<C> (l, CF(v)); 00713 const C* p= seg (v); 00714 for (i= 0; i < pos; i++, p++) a[i]= *p; 00715 a[pos]= x; i++; 00716 for (;i < n; i++, p++) a[i]= *p; 00717 return Vector (a, n, l, CF(v)); 00718 } 00719 00720 template<typename C,typename V,typename W> Vector 00721 insert (const Vector& v, const Vector& x, const vector<nat,W>& pos) { 00722 // insert x[0] at pos[0] in v, then x[1] at pos[1], etc 00723 ASSERT (N(x) == N(pos), "wrong sizes"); 00724 nat n= N(v) + N(x), i= 0; nat l= aligned_size<C,V> (n); 00725 C* a= mmx_formatted_new<C> (l, CF(v)); 00726 const C* p= seg (v); 00727 for (nat k= 0; k < N(pos); k++) { 00728 ASSERT (pos[k] < n, "position out of range"); 00729 for (; i < pos[k]; i++, p++) a[i]= *p; 00730 a[pos[k]]= x[k]; i++; 00731 } 00732 for (;i < n; i++, p++) a[i]= *p; 00733 return Vector (a, n, l, CF(v)); 00734 } 00735 00736 /****************************************************************************** 00737 * Routines on dense vectors 00738 ******************************************************************************/ 00739 00740 template<typename Op, typename C, typename V> nat 00741 unary_hash (const vector<C,V>& v) { 00742 register nat i, h= 12345, n= N(v); 00743 for (i=0; i<n; i++) 00744 h= (h<<1) ^ (h<<5) ^ (h>>27) ^ Op::op (v[i]); 00745 return h; 00746 } 00747 00748 template<typename Op, typename C, typename V> 00749 vector<Unary_return_type(Op,C),V> 00750 unary_map (const vector<C,V>& v) { 00751 typedef implementation<vector_linear,V> Vec; 00752 typedef Unary_return_type(Op,C) T; 00753 format<T> fm= unary_map<Op> (CF(v)); 00754 if (is_a_scalar (v)) return vector<T,V> (Op::op (v.scalar())); 00755 nat n= N(v); 00756 nat l= aligned_size<T,V> (n); 00757 T* r= mmx_formatted_new<T> (l, fm); 00758 Vec::template vec_unary<Op> (r, seg (v), n); 00759 return vector<T,V> (r, n, l, fm); 00760 } 00761 00762 template<typename Op, typename C1, typename C2, typename V> 00763 vector<Binary_return_type(Op,C1,C2),V> 00764 binary_map (const vector<C1,V>& v, const vector<C2,V>& w) { 00765 typedef implementation<vector_linear,V> Vec; 00766 typedef Binary_return_type(Op,C1,C2) T; 00767 format<T> fm= binary_map<Op> (CF(v), CF(w)); 00768 if (is_a_scalar (v) || is_a_scalar (w)) { 00769 if (is_non_scalar (v)) return binary_map<Op> (v, extend (w, v)); 00770 if (is_non_scalar (w)) return binary_map<Op> (extend (v, w), w); 00771 return vector<T,V> (Op::op (v.scalar(), w.scalar())); 00772 } 00773 nat n= N(v); 00774 ASSERT (N(w) == n, "lengths don't match"); 00775 nat l= aligned_size<T,V> (n); 00776 T* r= mmx_formatted_new<T> (l, fm); 00777 Vec::template vec_binary<Op> (r, seg (v), seg (w), n); 00778 return vector<T,V> (r, n, l, fm); 00779 } 00780 00781 template<typename Op, typename C, typename V, typename X> 00782 vector<Binary_return_type(Op,C,X),V> 00783 binary_map_scalar (const vector<C,V>& v, const X& x) { 00784 typedef implementation<vector_linear,V> Vec; 00785 typedef Binary_return_type(Op,C,X) T; 00786 format<T> fm= binary_map_scalar<C> (CF(v), x); 00787 if (is_a_scalar (v)) return vector<T,V> (Op::op (v.scalar(), x)); 00788 nat n= N(v); 00789 nat l= aligned_size<T,V> (n); 00790 T* r= mmx_formatted_new<T> (l, fm); 00791 Vec::template vec_binary_scalar<Op> (r, seg (v), x, n); 00792 return vector<T,V> (r, n, l, fm); 00793 } 00794 00795 template<typename Op, typename C, typename V> vector<C,V>& 00796 nullary_set (vector<C,V>& v) { 00797 typedef implementation<vector_linear,V> Vec; 00798 nat n= N(v); 00799 Vec::template vec_nullary<Op> (seg (v), n); 00800 return v; 00801 } 00802 00803 template<typename Op, typename T, typename C, typename V> vector<T,V>& 00804 unary_set (vector<T,V>& v, const vector<C,V>& w) { 00805 typedef implementation<vector_linear,V> Vec; 00806 if (is_a_scalar (v) || is_a_scalar (w)) { 00807 if (is_non_scalar (v)) 00808 return unary_set<Op> (v, extend (w, v)); 00809 else if (is_non_scalar (w)) 00810 v= extend (v, w); 00811 else { 00812 Op::set_op (v.scalar(), w.scalar()); 00813 return v; 00814 } 00815 } 00816 nat n= N(v); 00817 ASSERT (N(w) == n, "lengths don't match"); 00818 Vec::template vec_unary<Op> (seg (v), seg (w), n); 00819 return v; 00820 } 00821 00822 template<typename Op, typename T, typename V, typename X> vector<T,V>& 00823 unary_set_scalar (vector<T,V>& v, const X& x) { 00824 typedef implementation<vector_linear,V> Vec; 00825 if (is_a_scalar (v)) { 00826 Op::set_op (v.scalar(), x); 00827 return v; 00828 } 00829 nat n= N(v); 00830 Vec::template vec_unary_scalar<Op> (seg (v), x, n); 00831 return v; 00832 } 00833 00834 template<typename Op, typename C1, typename C2, typename V> bool 00835 binary_test (const vector<C1,V>& v, const vector<C2,V>& w) { 00836 typedef implementation<vector_linear,V> Vec; 00837 if (is_a_scalar (v) || is_a_scalar (w)) { 00838 if (is_non_scalar (v)) return binary_test<Op> (v, extend (w, v)); 00839 if (is_non_scalar (w)) return binary_test<Op> (extend (v, w), w); 00840 return Op::op (v.scalar(), w.scalar()); 00841 } 00842 nat n= N(v); 00843 if (N(w) != n) return false; 00844 return Vec::template vec_binary_test<Op> (seg (v), seg (w), n); 00845 } 00846 00847 template<typename Op, typename C, typename V, typename X> bool 00848 binary_test_scalar (const vector<C,V>& v, const X& c) { 00849 typedef implementation<vector_linear,V> Vec; 00850 if (is_a_scalar (v)) return Op::op (v.scalar(), c); 00851 return Vec::template vec_binary_test_scalar<Op> (seg (v), c, N(v)); 00852 } 00853 00854 template<typename Op, typename C, typename V> Unary_return_type(Op,C) 00855 big (const vector<C,V>& v) { 00856 typedef implementation<vector_linear,V> Vec; 00857 ASSERT (is_non_scalar (v), "non scalar vector expected"); 00858 return Vec::template vec_unary_big<Op> (seg (v), N(v), CF(v)); 00859 } 00860 00861 template<typename Op, typename C, typename V> Unary_return_type(Op,C) 00862 big_dicho (const vector<C,V>& v) { 00863 typedef implementation<vector_linear,V> Vec; 00864 ASSERT (is_non_scalar (v), "non scalar vector expected"); 00865 return Vec::template vec_unary_big_dicho<Op> (seg (v), N(v), CF(v)); 00866 } 00867 00868 /****************************************************************************** 00869 * Dynamic mappers 00870 ******************************************************************************/ 00871 00872 template<typename S1, typename D> vector<D> 00873 map (const function_1<D,Argument(S1) >& fun, const vector<S1>& v1) { 00874 format<D> fm= map (fun, CF(v1)); 00875 ASSERT (is_non_scalar (v1), "non-scalar vector expected"); 00876 nat n= N(v1); 00877 nat l= default_aligned_size<D> (n); 00878 D* r= mmx_formatted_new<D> (l, fm); 00879 for (nat i=0; i<n; i++) r[i]= fun (v1[i]); 00880 return vector<D> (r, n, l, fm); 00881 } 00882 00883 template<typename S1, typename D> vector<D> 00884 map (D (*fun) (const S1&), const vector<S1>& v1) { 00885 format<D> fm= map (fun, CF(v1)); 00886 ASSERT (is_non_scalar (v1), "non-scalar vector expected"); 00887 nat n= N(v1); 00888 nat l= default_aligned_size<D> (n); 00889 D* r= mmx_formatted_new<D> (l, fm); 00890 for (nat i=0; i<n; i++) r[i]= fun (v1[i]); 00891 return vector<D> (r, n, l, fm); 00892 } 00893 00894 template<typename S1, typename D> vector<D> 00895 map (const function_1<D,Argument(S1) >& fun, 00896 const vector<S1>& v1, const format<D>& fm) 00897 { 00898 ASSERT (is_non_scalar (v1), "non-scalar vector expected"); 00899 nat n= N(v1); 00900 nat l= default_aligned_size<D> (n); 00901 D* r= mmx_formatted_new<D> (l, fm); 00902 for (nat i=0; i<n; i++) r[i]= fun (v1[i]); 00903 return vector<D> (r, n, l, fm); 00904 } 00905 00906 template<typename S1, typename D> vector<D> 00907 map (D (*fun) (const S1&), 00908 const vector<S1>& v1, const format<D>& fm) { 00909 ASSERT (is_non_scalar (v1), "non-scalar vector expected"); 00910 nat n= N(v1); 00911 nat l= default_aligned_size<D> (n); 00912 D* r= mmx_formatted_new<D> (l, fm); 00913 for (nat i=0; i<n; i++) r[i]= fun (v1[i]); 00914 return vector<D> (r, n, l, fm); 00915 } 00916 00917 template<typename S1, typename S2, typename D> vector<D> 00918 map (const function_2<D,Argument(S1),Argument(S2) >& fun, 00919 const vector<S1>& v1, const vector<S2>& v2) 00920 { 00921 format<D> fm; //= map (fun, CF(v1), CF(v2)); 00922 ASSERT (is_non_scalar (v1), "non-scalar vector expected"); 00923 ASSERT (is_non_scalar (v2), "non-scalar vector expected"); 00924 ASSERT (N(v1) == N(v2), "lengths don't match"); 00925 nat n= N(v1); 00926 nat l= default_aligned_size<D> (n); 00927 D* r= mmx_formatted_new<D> (l, fm); 00928 for (nat i=0; i<n; i++) r[i]= fun (v1[i], v2[i]); 00929 return vector<D> (r, n, l, fm); 00930 } 00931 00932 template<typename S1, typename S2, typename S3, typename D> vector<D> 00933 map (const function_3<D,Argument(S1),Argument(S2),Argument(S3) >& fun, 00934 const vector<S1>& v1, const vector<S2>& v2, const vector<S3>& v3) 00935 { 00936 format<D> fm; //= map (fun, CF(v1), CF(v2), CF(v3)); 00937 ASSERT (is_non_scalar (v1), "non-scalar vector expected"); 00938 ASSERT (is_non_scalar (v2), "non-scalar vector expected"); 00939 ASSERT (is_non_scalar (v3), "non-scalar vector expected"); 00940 ASSERT (N(v1) == N(v2) && N(v2) == N(v3), "lengths don't match"); 00941 nat n= N(v1); 00942 nat l= default_aligned_size<D> (n); 00943 D* r= mmx_formatted_new<D> (l, fm); 00944 for (nat i=0; i<n; i++) r[i]= fun (v1[i], v2[i], v3[i]); 00945 return vector<D> (r, n, l, fm); 00946 } 00947 00948 /****************************************************************************** 00949 * Constants 00950 ******************************************************************************/ 00951 00952 TMPL void set_pi (Vector& v) { nullary_set<pi_as_op> (v); } 00953 TMPL void set_log2 (Vector& v) { nullary_set<log2_as_op> (v); } 00954 TMPL void set_euler (Vector& v) { nullary_set<euler_as_op> (v); } 00955 TMPL void set_catalan (Vector& v) { nullary_set<catalan_as_op> (v); } 00956 TMPL void set_imaginary (Vector& v) { nullary_set<imaginary_as_op> (v); } 00957 TMPL void set_nan (Vector& v) { nullary_set<nan_as_op> (v); } 00958 TMPL void set_fuzz (Vector& v) { nullary_set<fuzz_as_op> (v); } 00959 TMPL void set_smallest (Vector& v) { nullary_set<smallest_as_op> (v); } 00960 TMPL void set_largest (Vector& v) { nullary_set<largest_as_op> (v); } 00961 TMPL void set_accuracy (Vector& v) { nullary_set<accuracy_as_op> (v); } 00962 TMPL void set_infinity (Vector& v) { nullary_set<infinity_as_op> (v); } 00963 TMPL void set_maximal (Vector& v) { nullary_set<maximal_as_op> (v); } 00964 TMPL void set_minimal (Vector& v) { nullary_set<minimal_as_op> (v); } 00965 00966 /****************************************************************************** 00967 * Instantiations of the abstract routines 00968 ******************************************************************************/ 00969 00970 TMPL Vector copy (const Vector& v) { 00971 return unary_map<id_op> (v); } 00972 TMPL Vector duplicate (const Vector& v) { 00973 return unary_map<duplicate_op> (v); } 00974 00975 TMPL Vector operator - (const Vector& v) { 00976 return unary_map<neg_op> (v); } 00977 TMPL Vector operator + (const Vector& v, const Vector& w) { 00978 return binary_map<add_op> (v, w); } 00979 TMPL Vector operator + (const C& v, const Vector& w) { 00980 return binary_map<add_op> (Vector (v), w); } 00981 template<typename V> Vector_int 00982 operator + (const int& v, const Vector_int& w) { 00983 return binary_map<add_op> (Vector_int (v), w); } 00984 TMPL Vector operator + (const Vector& w, const C& v) { 00985 return binary_map<add_op> (w, Vector (v)); } 00986 template<typename V> Vector_int 00987 operator + (const Vector_int& w, const int& v) { 00988 return binary_map<add_op> (w, Vector_int (v)); } 00989 TMPL Vector operator - (const Vector& v, const Vector& w) { 00990 return binary_map<sub_op> (v, w); } 00991 TMPL Vector operator - (const Vector& v, const C& w) { 00992 return binary_map<sub_op> (v, Vector (w)); } 00993 template<typename V> Vector_int 00994 operator - (const Vector_int& v, const int& w) { 00995 return binary_map<sub_op> (v, Vector_int (w)); } 00996 TMPL Vector operator - (const C& v, const Vector& w) { 00997 return binary_map<sub_op> (Vector (v), w); } 00998 template<typename V> Vector_int 00999 operator - (const int& v, const Vector_int& w) { 01000 return binary_map<sub_op> (Vector_int (v), w); } 01001 TMPL Vector operator * (const Vector& v, const Vector& w) { 01002 return binary_map<mul_op> (v, w); } 01003 TMPL Vector operator / (const Vector& v, const Vector& w) { 01004 return binary_map<div_op> (v, w); } 01005 TMPL Vector quo (const Vector& v, const Vector& w) { 01006 return binary_map<quo_op> (v, w); } 01007 TMPL Vector rem (const Vector& v, const Vector& w) { 01008 return binary_map<rem_op> (v, w); } 01009 TMPL Vector operator * (const Vector& v, const C& c) { 01010 return binary_map_scalar<rmul_op> (v, c); } 01011 template<typename V> Vector_int 01012 operator * (const Vector_int& v, const int& c) { 01013 return binary_map_scalar<rmul_op> (v, c); } 01014 TMPL Vector operator * (const C& c, const Vector& v) { 01015 return binary_map_scalar<lmul_op> (v, c); } 01016 template<typename V> Vector_int 01017 operator * (const int& c, const Vector_int& v) { 01018 return binary_map_scalar<lmul_op> (v, c); } 01019 TMPL Vector operator / (const Vector& v, const C& c) { 01020 return binary_map_scalar<rdiv_op> (v, c); } 01021 template<typename V> Vector_int 01022 operator / (const Vector_int& v, const int& c) { 01023 return binary_map_scalar<rdiv_op> (v, c); } 01024 TMPL Vector operator / (const C& c, const Vector& v) { 01025 return binary_map_scalar<ldiv_op> (v, c); } 01026 template<typename V> Vector_int 01027 operator / (const int& c, const Vector_int& v) { 01028 return binary_map_scalar<ldiv_op> (v, c); } 01029 TMPL Vector quo (const Vector& v, const C& c) { 01030 return binary_map_scalar<rquo_op> (v, c); } 01031 TMPL Vector rem (const Vector& v, const C& c) { 01032 return binary_map_scalar<rrem_op> (v, c); } 01033 TMPL Vector operator | (const Vector& v, const Vector& w) { 01034 return binary_map<or_op> (v, w); } 01035 TMPL Vector operator & (const Vector& v, const Vector& w) { 01036 return binary_map<and_op> (v, w); } 01037 01038 TMPL Vector& operator += (Vector& v, const Vector& w) { 01039 return unary_set<add_op> (v, w); } 01040 TMPL Vector& operator -= (Vector& v, const Vector& w) { 01041 return unary_set<sub_op> (v, w); } 01042 TMPL Vector& operator *= (Vector& v, const Vector& w) { 01043 return unary_set<mul_op> (v, w); } 01044 TMPL Vector& operator /= (Vector& v, const Vector& w) { 01045 return unary_set<div_op> (v, w); } 01046 TMPL Vector& operator *= (Vector& v, const C& c) { 01047 return unary_set_scalar<rmul_op> (v, c); } 01048 TMPL Vector& operator /= (Vector& v, const C& c) { 01049 return unary_set_scalar<rdiv_op> (v, c); } 01050 01051 TMPL Vector inf (const Vector& v, const Vector& w) { 01052 return binary_map<inf_op> (v, w); } 01053 TMPL Vector sup (const Vector& v, const Vector& w) { 01054 return binary_map<sup_op> (v, w); } 01055 TMPL bool operator <= (const Vector& v, const Vector& w) { 01056 return binary_test<lesseq_op> (v, w); } 01057 TMPL bool operator >= (const Vector& v, const Vector& w) { 01058 return binary_test<gtreq_op> (v, w); } 01059 TMPL bool operator == (const Vector& v, const C& c) { 01060 return binary_test_scalar<equal_op> (v, c); } 01061 template<typename V> bool 01062 operator == (const Vector_int& v, const int& c) { 01063 return binary_test_scalar<equal_op> (v, c); } 01064 TMPL bool operator <= (const Vector& v, const C& c) { 01065 return binary_test_scalar<lesseq_op> (v, c); } 01066 template<typename V> bool 01067 operator <= (const Vector_int& v, const int& c) { 01068 return binary_test_scalar<lesseq_op> (v, c); } 01069 TMPL bool operator >= (const Vector& v, const C& c) { 01070 return binary_test_scalar<gtreq_op> (v, c); } 01071 template<typename V> bool 01072 operator >= (const Vector_int& v, const int& c) { 01073 return binary_test_scalar<gtreq_op> (v, c); } 01074 01075 TRUE_IDENTITY_OP_SUGAR(TMPL,Vector) 01076 EXACT_IDENTITY_OP_SUGAR(TMPL,Vector) 01077 STRICT_COMPARE_SUGAR(TMPL,Vector) 01078 ARITH_SCALAR_INT_SUGAR(TMPL,Vector); 01079 EQUAL_INT_SUGAR(TMPL,Vector); 01080 COMPARE_INT_SUGAR(TMPL,Vector); 01081 01082 TMPL Vector sqrt (const Vector& v) { return unary_map<sqrt_op> (v); } 01083 TMPL Vector exp (const Vector& v) { return unary_map<exp_op> (v); } 01084 TMPL Vector log (const Vector& v) { return unary_map<log_op> (v); } 01085 TMPL Vector cos (const Vector& v) { return unary_map<cos_op> (v); } 01086 TMPL Vector sin (const Vector& v) { return unary_map<sin_op> (v); } 01087 TMPL Vector tan (const Vector& v) { return unary_map<tan_op> (v); } 01088 TMPL Vector acos (const Vector& v) { return unary_map<acos_op> (v); } 01089 TMPL Vector asin (const Vector& v) { return unary_map<asin_op> (v); } 01090 TMPL Vector atan (const Vector& v) { return unary_map<atan_op> (v); } 01091 01092 TMPL Vector pow (const Vector& v, const Vector& w) { 01093 return binary_map<pow_op> (v, w); } 01094 TMPL Vector pow (const Vector& v, const int& w) { 01095 return binary_map_scalar<rpow_op> (v, w); } 01096 TMPL Vector pow (const int& w, const Vector& v) { 01097 return binary_map_scalar<lpow_op> (v, w); } 01098 01099 TMPL Vector derive (const Vector& v) { 01100 return unary_map<derive_op> (v); } 01101 TMPL Vector integrate (const Vector& v) { 01102 return unary_map<integrate_op> (v); } 01103 template<typename C,typename V,typename X> Vector 01104 derive (const Vector& v, const X& x) { 01105 return binary_map_scalar<derive_op> (v, x); } 01106 template<typename C,typename V,typename X> Vector 01107 integrate (const Vector& v, const X& x) { 01108 return binary_map_scalar<integrate_op> (v, x); } 01109 01110 TMPL inline C big_add (const Vector& v) { return big<add_op> (v); } 01111 TMPL inline C big_mul (const Vector& v) { return big<mul_op> (v); } 01112 TMPL inline C big_or (const Vector& v) { return big< or_op> (v); } 01113 TMPL inline C big_and (const Vector& v) { return big<and_op> (v); } 01114 TMPL inline C big_min (const Vector& v) { return big<min_op> (v); } 01115 TMPL inline C big_max (const Vector& v) { return big<max_op> (v); } 01116 TMPL inline C big_inf (const Vector& v) { return big<inf_op> (v); } 01117 TMPL inline C big_sup (const Vector& v) { return big<sup_op> (v); } 01118 01119 /****************************************************************************** 01120 * Floating point related functions 01121 ******************************************************************************/ 01122 01123 TMPL inline bool is_finite (const Vector& v) { 01124 if (is_a_scalar (v)) return is_finite (v.scalar()); 01125 return big<and_is_finite_op> (v); } 01126 TMPL inline bool is_nan (const Vector& v) { 01127 if (is_a_scalar (v)) return is_nan (v.scalar()); 01128 return big<or_is_nan_op> (v); } 01129 TMPL inline bool is_infinite (const Vector& v) { 01130 if (is_a_scalar (v)) return is_infinite (v.scalar()); 01131 return !is_nan (v) && big<or_is_infinite_op> (v); } 01132 TMPL inline bool is_fuzz (const Vector& v) { 01133 if (is_a_scalar (v)) return is_fuzz (v.scalar()); 01134 return !is_nan (v) && big<or_is_fuzz_op> (v); } 01135 TMPL inline bool is_reliable (const Vector& v) { 01136 if (is_a_scalar (v)) return is_reliable (v.scalar()); 01137 return is_reliable (C (0)); } 01138 01139 TMPL inline Vector change_precision (const Vector& v, xnat p) { 01140 return binary_map_scalar<change_precision_op> (v, p); } 01141 TMPL inline xnat precision (const Vector& v) { 01142 return big<min_precision_op> (v); } 01143 01144 TMPL inline xint exponent (const Vector& v) { 01145 return big<max_exponent_op> (v); } 01146 TMPL inline double magnitude (const Vector& v) { 01147 return big<max_magnitude_op> (v); } 01148 01149 /****************************************************************************** 01150 * Complex and ball vectors 01151 ******************************************************************************/ 01152 01153 TMPL Abs_vector abs (const Vector& v) { return unary_map<abs_op> (v); } 01154 TMPL Real_vector Re (const Vector& v) { return unary_map<Re_op> (v); } 01155 TMPL Real_vector Im (const Vector& v) { return unary_map<Im_op> (v); } 01156 TMPL Vector conj (const Vector& v) { return unary_map<conj_op> (v); } 01157 01158 TMPL Center_vector center (const Vector& v) { 01159 return unary_map<center_op> (v); } 01160 TMPL Radius_vector radius (const Vector& v) { 01161 return unary_map<radius_op> (v); } 01162 TMPL Center_vector lower (const Vector& v) { 01163 return unary_map<lower_op> (v); } 01164 TMPL Center_vector upper (const Vector& v) { 01165 return unary_map<upper_op> (v); } 01166 TMPL inline Vector sharpen (const Vector& v) { 01167 return unary_map<sharpen_op> (v); } 01168 TMPLK inline Vector blur (const Vector& v, const K& x) { 01169 return binary_map_scalar<blur_op> (v, x); } 01170 template<typename C, typename V, typename C2, typename V2> inline Vector 01171 blur (const Vector& v, const vector<C2,V2>& w) { 01172 return binary_map<blur_op> (v, w); } 01173 01174 /****************************************************************************** 01175 * Implementation of some routines on operators 01176 ******************************************************************************/ 01177 01178 template<typename C> inline C 01179 trig_op::diff_op (const C& me, const C& x) { 01180 return from_vector (vec (-derive (access (x, 0)) * access (me, 1), 01181 derive (access (x, 0)) * access (me, 0))); 01182 } 01183 01184 template<typename C> inline C 01185 tan_op::def (const C& me, const C& f) { 01186 (void) me; const vector<C> v= cos_sin (f); return v[1] / v[0]; 01187 } 01188 01189 template<typename C> inline C 01190 solve_vector_lde_op::diff_op (const C& me, const C& x) { 01191 typedef As_vector_type (C) V; 01192 typedef Scalar_type (V) K; 01193 const V w= as_vector (me); 01194 const V v= as_vector (x); 01195 nat i, n= N(v); 01196 K sum (0); 01197 V d (K (0), n); 01198 for (i=0; i<n; i++) { 01199 if (i==0) sum= v[i] * w[i]; 01200 else sum= sum + v[i] * w[i]; 01201 if (i<n-1) d[i]= w[i+1]; 01202 else d[i]= sum; 01203 } 01204 return from_vector (d); 01205 } 01206 01207 /****************************************************************************** 01208 * Further operations 01209 ******************************************************************************/ 01210 01211 TMPL C dot (const Vector& v, const Vector& w) { 01212 typedef implementation<vector_linear,V> Vec; 01213 ASSERT (is_non_scalar (v) && is_non_scalar (w), 01214 "non-scalar vectors expected"); 01215 ASSERT (N(v) == N(w), "lengths don't match"); 01216 return Vec::inn_prod (seg (v), seg (w), N(v), CF (v)); } 01217 01218 template<typename C> vector<C> cos_sin (const C& x) { 01219 return vec (cos (x), sin (x)); } 01220 template<typename C> vector<C> trig (const vector<C>& v) { 01221 return vec (cos (v[0]), sin (v[0])); } 01222 01223 #undef TMPL_DEF 01224 #undef TMPL 01225 #undef TMPLK 01226 #undef Format 01227 #undef Vector 01228 #undef Vector_int 01229 #undef Vector_rep 01230 #undef Abs_vector 01231 #undef Real_vector 01232 #undef Center_vector 01233 #undef Radius_vector 01234 } // namespace mmx 01235 #endif // __MMX_VECTOR_HPP