basix_doc 0.1
/Users/mourrain/Devel/mmx/basix/include/basix/vector.hpp
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines