realroot_doc 0.1.1
|
00001 #ifndef realroot_tensor_eenvops_hpp 00002 #define realroot_tensor_eenvops_hpp 00003 00004 #include <realroot/texp_sup.hpp> 00005 #include <realroot/tensor_vctops.hpp> 00006 #include <realroot/binomials.hpp> 00007 00008 namespace mmx { 00009 00010 namespace tensor 00011 { 00019 template < class R, class C, class eenv, class P > 00020 void levalm (R & result, const C * data, const eenv & env, const P & p) 00021 { 00022 typedef R result_type; 00023 00024 // query for the environment information 00025 00026 const int esz = env.sz (); // number of coefficients 00027 const int nvr = env.nvr (); // number of variables 00028 const int *szs = env.szs (); // sizes in each variables 00029 const int *str = env.str (); // corresponding strides. 00030 00031 result_type tmp[env.sz ()], r; // temporary array used by the inplace evaluation loop 00032 std::copy (data, data + env.sz (), tmp); 00033 for (int v = nvr - 1; v >= 0; v--) 00034 for (int i = 0; i < esz; i += str[v - 1]) { 00035 vct::horner(r,tmp + i, szs[v], p[v], str[v]); 00036 tmp[i] = r; 00037 } 00038 // let::assign(result,tmp[0]); 00039 result= tmp[0]; 00040 }; 00041 00042 template < class R, class C, class eenv, class P > 00043 void hevalm (R & result, const C * data, const eenv & env, const P & p) 00044 { 00045 typedef R result_type; 00046 00047 // query for the environment information 00048 00049 const int esz = env.sz (); // number of coefficients 00050 const int nvr = env.nvr (); // number of variables 00051 const int *szs = env.szs (); // sizes in each variables 00052 const int *str = env.str (); // corresponding strides. 00053 00054 result_type tmp[env.sz ()],r; // temporary array used by the inplace evaluation loop 00055 std::copy (data, data + env.sz (), tmp); 00056 for (int v = nvr - 1; v >= 0; v--) 00057 for (int i = 0; i < esz; i += str[v - 1]) { 00058 vct::hhorner(r,tmp + i, szs[v], p[v+1],p[0],str[v]); 00059 tmp[i] = r; 00060 } 00061 00062 let::assign(result,tmp[0]); 00063 00064 }; 00065 00066 template<typename real_t, typename value_t> 00067 void decasteljau( real_t * r, unsigned sz, const value_t& t, int str = 1 ) 00068 { 00069 real_t *er, *p; 00070 for ( er = r + (sz-1)*str; er != r; er -= str ) 00071 for ( p = r; p != er; p += str ) 00072 *p = real_t(value_t(1)-t)* *p+t**(p+str); 00073 }; 00074 00076 template < class R, class C, class eenv, class P > 00077 void levalb (R & result, const C * data, const eenv & env, const P & p) 00078 { 00079 // typename sup<typename texp::value_type<P>::result_t, C >::T tmp[env.sz()]; 00080 //XXX typename texp::ringof_ < typename texp::value_type<P>::T,C >::T 00081 00082 R tmp[env.sz()]; 00083 00084 const int esz (env.sz ()); 00085 const int nvr (env.nvr ()); 00086 const int *szs (env.szs ()); 00087 const int *str (env.str ()); 00088 00089 std::copy (data, data + env.sz (), tmp); 00090 00091 for (int v = nvr - 1; v >= 0; v--) 00092 for (int i = 0; i < esz; i += str[v - 1]) 00093 decasteljau (tmp + i, szs[v], p[v], str[v]); 00094 00095 let::assign(result,tmp[0]); 00096 }; 00097 00098 00099 00100 template < class OutputIterator, class C, class eenv > 00101 void maxs (OutputIterator _maxs_, const C * data, const eenv & env, int v) 00102 { 00103 const int *eszs = env.szs (); 00104 const int *estr = env.str (); 00105 // const int envr = env.nvr (); 00106 int p, k, i; //, j; 00107 for (p = 0, k = 0; k < eszs[v]; k++, data += estr[v], _maxs_++) 00108 { 00109 *_maxs_ = *data; 00110 for (i = 0; i < estr[-1]; i += estr[v - 1]) 00111 for (const C * edata = data + i; edata < data + i + estr[v]; edata++) 00112 if (*edata > *_maxs_) 00113 *_maxs_ = *edata; 00114 }; 00115 }; 00116 00117 template < class OutputIterator, class C, class eenv > 00118 void mins (OutputIterator _mins_, const C * data, const eenv & env, int v) 00119 { 00120 const int *eszs = env.szs (); 00121 const int *estr = env.str (); 00122 // const int envr = env.nvr (); 00123 int p, k, i, j; 00124 for (p = 0, k = 0; k < eszs[v]; k++, p += estr[v], _mins_++) 00125 { 00126 *_mins_ = data[p]; 00127 for (i = 0; i < estr[-1]; i += estr[v - 1]) 00128 for (j = i; j < i + estr[v]; j++) 00129 if (data[j + p] < *_mins_) 00130 *_mins_ = data[j + p]; 00131 }; 00132 }; 00133 00134 00135 00136 template < class C, class eenv > 00137 void vswap( C * data, const eenv & env, int *perm, int *supp = 0, int nsupp = 0 ) 00138 { 00139 const int *szs = env.szs (); 00140 const int *str = env.str (); 00141 int ostr[env.nvr ()]; 00142 int i; 00143 for (i = env.nvr () - 2, str[env.nvr () - 1] = 1; i >= -1; 00144 ostr[i] = szs[perm[i + 1]] * str[i + 1], i--) ; 00145 if (supp == 0) 00146 { 00147 int a, o, v; 00148 for (i = 0; i < env.esz (); i++) 00149 { 00150 for (a = i, v = env.nvr () - 1; a; a /= szs[v], v--) 00151 o += (a % szs[v]) * ostr[perm[v]]; 00152 std::swap (data[i], data[o]) ; 00153 }; 00154 } 00155 else 00156 { 00157 int a, o, v; 00158 for (i = 0; i < nsupp; supp[i++] = o) 00159 { 00160 for (a = supp[i], v = env.nvr () - 1; a; a /= szs[v], v--) 00161 o += (a % szs[v]) * ostr[perm[v]]; 00162 std::swap (data[i], data[o]); 00163 }; 00164 }; 00165 env.vswap (perm); 00166 }; 00167 00168 00169 template < class C, class eenv > 00170 void binoms (C * data, const eenv & env, binomials < C > & binms) 00171 { 00172 const int *estr = env.str (); 00173 const int *eszs = env.szs (); 00174 const int envr = env.nvr (); 00175 const int esz = env.sz (); 00176 const C *bins = binms[eszs[envr - 1] - 1]; 00177 for (C * pdata = data; pdata < data + esz; pdata += estr[envr - 2]) 00178 vct::copy (pdata, bins, eszs[envr - 1]); 00179 for (int v = 0; v < envr - 1; v++) 00180 { 00181 bins = binms[eszs[v] - 1]; 00182 // int k = 0; 00183 for (int i = 0; i < esz; i += estr[v - 1]) 00184 for (int j = 0; j < estr[v]; j++) 00185 vct::pmul (data + i + j, bins, eszs[v], estr[v], 1); 00186 }; 00187 }; 00188 00189 template < class C > 00190 void ibinoms (C * data, const eenv & env, binomials < C > & binms) 00191 { 00192 binoms(data,env,binms); 00193 vct::inverses(data,data+env.sz()); 00194 }; 00195 00197 template < class C, class eenv > 00198 void scale (C * data, const eenv & env, binomials < C > &binoms) 00199 { 00200 const int *estr = env.str (); 00201 const int *eszs = env.szs (); 00202 const int envr = env.nvr (); 00203 const int esz = env.sz (); 00204 const C * bins = binoms[eszs[envr - 1] - 1]; 00205 00206 for (C * pdata = data; pdata < data + esz; vct::pmul (pdata, bins, eszs[envr - 1]), pdata += estr[envr - 2]) ; 00207 00208 for (int v = 0; v < envr - 1; v++) 00209 { 00210 bins = binoms[eszs[v] - 1]; 00211 // int k = 0; 00212 for (int i = 0; i < esz; i += estr[v - 1]) 00213 for (int j = 0; j < estr[v]; j++) 00214 vct::pmul (data + i + j, bins, eszs[v], estr[v], 1); 00215 }; 00216 }; 00217 00219 template < class C, class eenv > 00220 void uscale (C * data, const eenv & env, binomials < C > &binoms) 00221 { 00222 const int *estr = env.str (); 00223 const int *eszs = env.szs (); 00224 const int envr = env.nvr (); 00225 const int esz = env.sz (); 00226 const C *bins = binoms[eszs[envr - 1] - 1]; 00227 for (C * pdata = data; pdata < data + esz; pdata += estr[envr - 2]) 00228 vct::pdiv (pdata, bins, eszs[envr - 1]); 00229 for (int v = 0; v < envr - 1; v++) 00230 { 00231 bins = binoms[eszs[v] - 1]; 00232 // int k = 0; 00233 for (int i = 0; i < esz; i += estr[v - 1]) 00234 for (int j = 0; j < estr[v]; j++) 00235 vct::pdiv (data + i + j, bins, eszs[v], estr[v], 1); 00236 }; 00237 }; 00238 00239 template<class C> inline 00240 void convertb2m( C * bzc, unsigned sz, int st, binomials<C>& binom ) { 00241 int i,k; 00242 for ( i = st; i != st*int(sz); i += st ) 00243 for ( k = (sz-1)*st; k != i-st; k -= st ) 00244 bzc[k] -= bzc[k-st]; 00245 vct::pmul(bzc,binom[sz-1],sz,st,1); 00246 }; 00247 00248 00249 template<class C> inline 00250 void convertm2b( C * bzc, unsigned sz, int st, binomials<C>& binoms ) { 00251 C tmp[sz]; 00252 const C * bin; 00253 unsigned i,k,p,l; 00254 00255 for ( p = 0, i = 0; i < sz; i++, p += st ) 00256 { tmp[i] = bzc[p]; bzc[p] = C(0); }; 00257 for ( p = 0, i = 0; i < sz; i++, p += st ) 00258 for ( bin = binoms[sz-i-1], l = p, k = 0; k < sz-i; k++, l += st ) 00259 bzc[l] += tmp[i]*bin[k]; 00260 bin = binoms[sz-1]; 00261 for ( i = 0, l = 0; i < sz; i ++, l += st ) 00262 bzc[l] /= bin[i]; 00263 }; 00264 00268 template < class C, class eenv > 00269 void convertm2b (C * data, const eenv & e, binomials < C > &bins, int v) 00270 { 00271 const int *esz = e.szs (); 00272 const int *est = e.str (); 00273 int i, j; 00274 for (i = 0; i < e.sz (); i += est[v - 1]) 00275 for (j = i; j < i + est[v]; convertm2b (data + j, esz[v], est[v], bins), j++) ; 00276 }; 00277 00279 template < class C, class eenv > 00280 void convertm2b (C * data, const eenv & env, binomials < C > &bins) 00281 { 00282 for (int v = 0; v < env.nvr (); convertm2b (data, env, bins, v++)) ; 00283 }; 00284 00288 template < class C, class eenv > 00289 void convertb2m (C * data, const eenv & e, binomials < C > &bins, int v) 00290 { 00291 const int *esz = e.szs (); 00292 const int *est = e.str (); 00293 int i, j; 00294 for (i = 0; i < e.sz (); i += est[v - 1]) 00295 for (j = i; j < i + est[v]; 00296 convertb2m (data + j, esz[v], est[v], bins), j++) ; 00297 }; 00298 00300 template < class C, class eenv > 00301 void convertb2m (C * data, const eenv & env, binomials < C > &bins) 00302 { 00303 for (int v = 0; v < env.nvr (); convertb2m (data, env, bins, v++)) ; 00304 }; 00305 00306 00307 00308 00309 00310 template<typename C> inline 00311 void diff( C * b, const C * a, unsigned sz, int sb, int sa ) 00312 { 00313 assert(sa==sb); 00314 for ( unsigned i = 1; i < sz; i ++ ) { b[(i-1)*sb] = i*a[i]; }; 00315 // for ( unsigned i = 1, a += sa; i < sz; *b = *a*i++, b += sb, a += sa ) ; 00316 }; 00317 00318 template<typename C> inline /* differentiation */ 00319 void diff( C * b, C * e, C const * a, int s ) 00320 { 00321 unsigned i; 00322 for ( i = 1, a += s; b != e; *b = *a*i++, b += s, a += s ) ; 00323 }; 00324 00325 template<typename C> inline /* differentiation */ 00326 void diff( C * b, C * e, C const * a ) 00327 { 00328 for ( int i = 1; b != e; *b++ = *(++a)*i++ ) ; 00329 }; 00330 00331 00332 template<typename C> 00333 void m_diff( C * op, const eenv& o, C const * ap, const eenv& a, int v ) 00334 { 00335 typedef int sz_t; 00336 sz_t is = 0; 00337 for ( sz_t i = 0; i < o.sz(); i += o.st(v-1), is += a.st(v-1) ) 00338 for ( sz_t j = 0; j < a.st(v); j ++ ) 00339 diff(op+i+j, ap+is+j,a.sz(v), o.st(v), a.st(v)) ; 00340 }; 00341 00342 template<typename C> 00343 void mdiff( C * dst, const eenv& a, C const * const src, const eenv& esrc, int v ) 00344 { 00345 const int ssz = esrc.sz (); 00346 // const int * sszs = a.szs(); 00347 const int * sstr = esrc.str(); 00348 int rst = sstr[v-1]-sstr[v]; 00349 unsigned i; 00350 C * ed, * fd; 00351 const C * es, * fs; 00352 for ( ed = dst, es = src; es < src+ssz; ed += rst, es += sstr[v-1] ) 00353 for ( i = 1, fd = ed, fs = es+sstr[v]; fs != es+sstr[v-1]; fd += sstr[v], fs += sstr[v], i ++ ) 00354 vct::scmul(fd,fd+sstr[v],fs,C(i)); 00355 } 00356 00357 00358 00359 template<typename C> 00360 static void bdiff( C * dst, const eenv& a, C const * const src, int v ) 00361 { 00362 const int ssz = a.sz (); 00363 const int * sszs = a.szs(); 00364 const int * sstr = a.str(); 00365 int rst = sstr[v-1]-sstr[v]; 00366 // unsigned i; 00367 C * ed; const C * es; 00368 for ( ed = dst, es = src; es < src+ssz; ed += rst, es += sstr[v-1] ) 00369 { 00370 C * fd; const C * fs; 00371 for ( fs = es, fd = ed; fs < es + sstr[v]; fs++, fd ++ ) 00372 { 00373 C * dp; const C * p; 00374 for ( p = fs, dp = fd; p < fs+rst; p += sstr[v], dp += sstr[v] ) 00375 *dp = (*(p+sstr[v])-*p)*(sszs[v]-1); 00376 }; 00377 }; 00378 } 00379 00380 template<class C, class T> inline 00381 void bsplit_uloop( C * r, C * rlast, C * l, const T& t, int st ) 00382 { 00383 C * er, * p; 00384 for ( er = rlast - st ; er != r; er -= st, l += st ) 00385 { 00386 *l = *r; 00387 for ( p = r; p != er; p += st ) 00388 *p = (1.0-t)**p+t**(p+st); 00389 }; 00390 *l = *r; 00391 }; 00392 00393 template < class C, class eenv, class T> inline 00394 void bsplit (C * l, C * r, const eenv & env, const T & t, int v ) 00395 { 00396 // const int *sszs = env.szs (); 00397 const int *sstr = env.str (); 00398 // int i, j, k; 00399 C *er,*el; 00400 for ( el = l, er = r; el != l + sstr[-1]; el += sstr[v-1], er += sstr[v-1] ) 00401 { 00402 C *fr,*fl; 00403 for ( fl = el, fr = er; fl != el + sstr[v]; fl++, fr++ ) 00404 bsplit_uloop(fr,fr+sstr[v-1],fl,t,sstr[v]) ; 00405 }; 00406 }; 00407 00408 00409 template<class C> inline 00410 void bsplit2_uloop( C * r, C * rlast, C * l, int st ) 00411 { 00412 C * er, * p; 00413 for ( er = rlast - st ; er != r; er -= st, l += st ) 00414 { 00415 *l = *r; 00416 for ( p = r; p != er; p += st ) 00417 *p = (*p+*(p+st))/C(2); 00418 }; 00419 *l = *r; 00420 }; 00421 00422 template < class C, class eenv > 00423 void bsplit2 (C * l, C * r, const eenv & env, int v ) 00424 { 00425 // const int *sszs = env.szs (); 00426 const int *sstr = env.str (); 00427 C *er,*el; 00428 for ( el = l, er = r; el != l + sstr[-1]; el += sstr[v-1], er += sstr[v-1] ) 00429 { 00430 C *fr,*fl; 00431 for ( fl = el, fr = er; fl != el + sstr[v]; fl++, fr++ ) 00432 bsplit2_uloop(fr,fr+sstr[v-1],fl,sstr[v]); 00433 }; 00434 }; 00435 00436 00437 template<class C,class T> inline 00438 void brestrict_uloop( C * r, C * rlast, int st, const T& a, const T& b ) 00439 { 00440 C * er, * p; 00441 for ( er = rlast - st ; er != r; er -= st ) 00442 for ( p = r; p != er; p += st ) 00443 *p = (a**p+b**(p+st)); 00444 }; 00445 00446 00447 00448 template<class C, class T> inline 00449 void brestrictLR (C * s, const eenv & env, int v, const T& a, const T& b, const T& c, const T& d ) 00450 { 00451 // std::cout << a << " " << b << std::endl; 00452 // std::cout << c << " " << d << std::endl; 00453 // const int *sszs = env.szs (); 00454 const int *sstr = env.str (); 00455 // int i, j, k; 00456 for ( C * es = s; es != s + sstr[-1]; es += sstr[v-1] ) 00457 for ( C * fs = es; fs != es + sstr[v]; fs ++ ) 00458 { 00459 brestrict_uloop(fs,fs+sstr[v-1],sstr[v],a,b); 00460 brestrict_uloop(fs+sstr[v-1]-sstr[v],fs-sstr[v],-sstr[v],c,d); 00461 }; 00462 }; 00463 00464 template<class C, class T> inline 00465 void brestrictRL (C * s, const eenv & env, int v, const T& a, const T& b, const T& c, const T& d ) 00466 { 00467 // std::cout << a << " " << b << std::endl; 00468 // std::cout << c << " " << d << std::endl; 00469 00470 00471 00472 // const int *sszs = env.szs (); 00473 const int *sstr = env.str (); 00474 // int i, j, k; 00475 for ( C * es = s; es != s + sstr[-1]; es += sstr[v-1] ) 00476 for ( C * fs = es; fs != es + sstr[v]; fs ++ ) 00477 { 00478 brestrict_uloop(fs+sstr[v-1]-sstr[v],fs-sstr[v],-sstr[v],c,d); 00479 brestrict_uloop(fs,fs+sstr[v-1],sstr[v],a,b); 00480 }; 00481 }; 00482 00483 template<class C, class eenv, class T > inline 00484 void brestrict( C * src, const eenv& env, int v, const T& a, const T& b ) 00485 { 00486 brestrictLR ( src, env, v, T(1-a), a, T((b-a)/(T(1)-a)), T((T(1)-b)/(T(1)-a)) ); 00487 }; 00488 00489 00490 template<class C> 00491 void lface( C * dst, const eenv& a, const C * src, int v ) 00492 { 00493 const int ssz = a.sz (); 00494 // const int * sszs = a.szs(); 00495 const int * sstr = a.str(); 00496 00497 C * ed; const C * es; 00498 const C * fs; 00499 for ( ed = dst, es = src; es < src+ssz; es += sstr[v-1] ) 00500 for ( fs = es; fs < es + sstr[v]; *ed++ = *fs++ ) ; 00501 }; 00502 00503 template<class C> 00504 void rface( C * dst, const eenv& a, const C * src, int v ) 00505 { 00506 const int ssz = a.sz (); 00507 // const int * sszs = a.szs(); 00508 const int * sstr = a.str(); 00509 00510 C * ed; const C * es; 00511 const C * fs; 00512 es = src + sstr[v-1]-sstr[v]; 00513 for ( ed = dst; es < src+ssz; es += sstr[v-1] ) 00514 { 00515 for ( fs = es; fs < es + sstr[v]; *ed++ = *fs++ ) ; 00516 }; 00517 }; 00518 00519 template<class C> 00520 void slice( C * dst, const eenv& a, const C * src, int v, int n) 00521 { 00522 const int ssz = a.sz (); 00523 const int * sstr = a.str(); 00524 00525 C * ed; const C * es; 00526 const C * fs; 00527 es = src + sstr[v-1]-sstr[v]; 00528 for ( ed = dst; es < src+ssz; es += sstr[v-1] ) 00529 { 00530 // fs = es + sstr[v-1] - sstr[v]; 00531 for ( fs = es; fs < es + sstr[v]; *ed++ = *fs++ ) ; 00532 }; 00533 }; 00534 00535 template<class C, class X, class O, class eenv > 00536 void mpolfill( C * data, const sparse::monomial_seq<X,O>& mpol, const eenv& env ) 00537 { 00538 const int *vr = env.vrs (); 00539 const int *st = env.str (); 00540 const int nvr = env.nvr(); 00541 typename sparse::monomial_seq<X,O>::const_iterator it; 00542 C c; 00543 for (it =mpol.begin (); it != mpol.end (); it++) 00544 { 00545 int a = 0; 00546 for (int v = 0; v < nvr; a += (*it)[vr[v]] * st[v], v++) ; 00547 let::assign(c,(*it).coeff ()); 00548 data[a] += c; 00549 }; 00550 } 00551 } 00552 00553 } //namespace mmx 00554 #endif