00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
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
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
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_basix_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 }