basix_doc 0.1
/Users/mourrain/Devel/mmx/basix/glue/glue_vector_map.cpp
Go to the documentation of this file.
00001 
00002 /******************************************************************************
00003 * MODULE     : glue_vector_generic_extra.cpp
00004 * DESCRIPTION: Extra glue for vectors
00005 * COPYRIGHT  : (C) 2006  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 #include <basix/vector.hpp>
00014 #include <basix/vector_sort.hpp>
00015 #include <basix/glue.hpp>
00016 #include <basix/routine.hpp>
00017 namespace mmx {
00018 
00019 static generic
00020 rebuild (const vector<generic>& v) {
00021   if (is_a_scalar (v)) {
00022     generic make_vector= eval ("scalar_vector");
00023     return as<routine> (make_vector) -> apply (vec<generic> (v.scalar()));
00024   }
00025   else {
00026     generic make_vector= eval ("vector");
00027     return as<routine> (make_vector) -> apply (v);
00028   }
00029 }
00030 
00031 vector<generic>
00032 vector_map_1 (const routine& fun, const vector<generic>& v) {
00033   if (is_a_scalar (v)) mmout << fun << ", " << v << "\n";
00034   //mmout << fun << ", " << v << ", " << is_a_scalar (v) << "\n";
00035   if (is_a_scalar (v)) return vector<generic> (fun->apply (v.scalar()));
00036   nat n= N(v);
00037   generic* r= mmx_new<generic> (n);
00038   for (nat i=0; i<n; i++)
00039     r[i]= fun->apply (v[i]);
00040   //mmout << "  -> " << vector<generic> (r, n) << "\n";
00041   return vector<generic> (r, n, format<generic> ());
00042 }
00043 
00044 vector<generic>
00045 vector_map_2 (const routine& fun,
00046               const vector<generic>& v1, const vector<generic>& v2)
00047 {
00048   if (is_a_scalar (v1) || is_a_scalar (v2)) {
00049     if (is_non_scalar (v1)) return vector_map_2 (fun, v1, extend (v2, v1));
00050     if (is_non_scalar (v2)) return vector_map_2 (fun, extend (v1, v2), v2);
00051     return vector<generic> (fun->apply (v1.scalar(), v2.scalar()));
00052   }
00053   ASSERT (N (v1) == N (v2), "vectors of unequal lengths");
00054   nat n= N(v1);
00055   generic* r= mmx_new<generic> (n);
00056   for (nat i=0; i<n; i++)
00057     r[i]= fun->apply (v1[i], v2[i]);
00058   return vector<generic> (r, n, format<generic> ());
00059 }
00060 
00061 vector<generic>
00062 vector_map_n (const routine& fun, const vector<vector<generic> >& a) {
00063   bool all_scalar= true, one_scalar= false;
00064   nat i, n= N(a), l= 0;
00065   for (i=0; i<n; i++)
00066     if (is_a_scalar (a[i])) one_scalar= true;
00067     else {
00068       if (all_scalar) l= N(a[i]);
00069       else ASSERT (N(a[i]) == l, "vectors of unequal lengths");
00070       all_scalar= false;
00071     }
00072 
00073   if (all_scalar) {
00074     vector<generic> arg= fill<generic> (n);
00075     for (i=0; i<n; i++)
00076       arg[i]= a[i].scalar();
00077     return vector<generic> (fun->apply (arg));
00078   }
00079 
00080   if (one_scalar) {
00081     vector<vector<generic> > b= fill<vector<generic> > (n);
00082     for (i=0; i<n; i++)
00083       if (is_a_scalar (a[i])) b[i]= vector<generic> (a[i].scalar(), l);
00084       else b[i]= a[i];
00085     return vector_map_n (fun, b);
00086   }
00087 
00088   generic* r= mmx_new<generic> (l);
00089   for (nat j=0; j<l; j++) {
00090     vector<generic> arg= fill<generic> (n);
00091     for (i=0; i<n; i++)
00092       arg[i]= a[i][j];
00093     r[j]= fun->apply (arg);
00094   }
00095   return vector<generic> (r, l, format<generic> ());
00096 }
00097 
00098 generic
00099 vector_map (const generic& f, const tuple<vector<generic> >& t) {
00100   routine fun= is<routine> (f)? as<routine> (f): default_routine (f);
00101   switch (N(t)) {
00102   case 0: ASSERT (N(t)>0, "wrong number of arguments");
00103   case 1: return rebuild (vector_map_1 (fun, t[0]));
00104   case 2: return rebuild (vector_map_2 (fun, t[0], t[1]));
00105   default:
00106     {
00107       const vector<generic> a= compound_to_vector (*t);
00108       nat i, n= N(a)-1;
00109       vector<vector<generic> > b= fill<vector<generic> > (n);
00110       for (i=0; i<n; i++) b[i]= as<vector<generic> > (a[i+1]);
00111       return rebuild (vector_map_n (fun, b));
00112     }
00113   }
00114 }
00115 
00116 generic
00117 vector_foreach (const generic& f, const tuple<vector<generic> >& t) {
00118   generic r= vector_map (f, t);
00119   return as<generic> (tuple<generic> (gen (GEN_TUPLE)));
00120 }
00121 
00122 generic
00123 vector_append_several (const tuple<vector<generic> >& t) {
00124   vector<generic> r;
00125   for (nat i=0; i<N(t); i++)
00126     r << t[i];
00127   return rebuild (r);
00128 }
00129 
00130 generic
00131 vector_apply (const generic& f, const vector<generic>& a) {
00132   routine fun= is<routine> (f)? as<routine> (f): default_routine (f);
00133   return fun->apply (a);
00134 }
00135 
00136 static routine current_comparison;
00137 
00138 vector<generic>
00139 vector_sort (const vector<generic>& v) {
00140   vector<generic> r= copy (v);
00141   sort (r);
00142   return r;
00143 }
00144 
00145 struct vector_sort_leq_op {
00146   static bool
00147   op (const generic& x, const generic& y) {
00148     return as<bool> (current_comparison->apply (x, y));
00149   }
00150 };
00151 
00152 vector<generic>
00153 vector_sort_leq (const vector<generic>& v, const generic& f) {
00154   routine old_comparison= current_comparison;
00155   current_comparison= is<routine> (f)? as<routine> (f): default_routine (f);
00156   vector<generic> r= copy (v);
00157   sort_leq<vector_sort_leq_op> (r);
00158   current_comparison= old_comparison;
00159   return r;
00160 }
00161 
00162 void
00163 glue_vector_map () {
00164   static bool done = false;
00165   if (done) return;
00166   done = true;
00167   register_glue ("glue_vector_map", &glue_vector_map);
00168   call_glue ("glue_vector_generic");
00169   define ("map", vector_map);
00170   define ("foreach", vector_foreach);
00171   define ("append", vector_append_several);
00172   define ("apply", vector_apply);
00173   define ("sort", vector_sort);
00174   define ("sort", vector_sort_leq);
00175 }
00176 
00177 } // namespace mmx
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines