basix_doc 0.1
|
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