00001
00002
00003
00004
00005
00006
00007 template< typename real_t >
00008 real_t density( real_t * src, const real_t prec = 1e-12, unsigned nsmp = 0 )
00009 {
00010 unsigned c = 0;
00011 if ( nsmp == 0 )
00012 {
00013 nsmp = data_size();
00014 for ( unsigned i = 0; i < nsmp; i ++ )
00015 if ( std::abs(src[i]) > prec ) c++;
00016 }
00017 else
00018 {
00019 for ( unsigned i = 0; i < nsmp; i ++ )
00020 if ( std::abs(src[rand()%data_size()] > prec) ) c++;
00021 };
00022 return ((real_t)c)/nsmp;
00023 };
00024
00025
00026 template<class real_t>
00027 unsigned support( unsigned * supp, real_t * src, const real_t& prec = 1e-6 )
00028 {
00029
00030 unsigned c = 0;
00031 for ( unsigned i = 0; i < data_size(); i ++ )
00032 if ( std::abs(src[i]) > prec ) supp[c++] = i;
00033 return c;
00034 };
00035
00036
00037 void op_mul( eenv * a, eenv * b )
00038 {
00039 if ( nvars() ) this->~eenv();
00040 _alloc_( a->nvars()+b->nvars() );
00041 std::copy( a->m_vrs, a->m_vrs+a->nvars(), m_vrs );
00042 std::copy( b->m_vrs, b->m_vrs+b->nvars(), m_vrs + a->nvars() );
00043 m_nvr = vctops::set_conversion( m_vrs, m_nvr );
00044 for ( sz_t v = 0; v < m_nvr; v ++ )
00045 {
00046 int av = a->indexofvar(var(v));
00047 int bv = b->indexofvar(var(v));
00048 m_szs[ v ] = ((av!=-1)?(a->sz(av)-1):0) + ((bv!=-1)?(b->sz(bv)-1):0) + 1;
00049 };
00050 m_mxvr = std::max(a->m_mxvr,b->m_mxvr);
00051 compute_strides();
00052 };
00053
00054
00055 static void vmap( sz_t * vmap, bernstein::eenv * o, bernstein::eenv * i )
00056 {
00057 for ( sz_t v = 0; v < i->m_nvr; v ++ )
00058 {
00059 vmap[v] = -1;
00060 for ( sz_t k = 0; k < o->m_nvr; k ++ )
00061 if ( o->m_vrs[k] == i->m_vrs[v] ) vmap[v] = k;
00062 assert(vmap[v]!=-1);
00063 };
00064 };
00065
00066 static void oaddress( bernstein::eenv * oenv, unsigned * osupp,
00067 bernstein::eenv * ienv, unsigned * isupp = 0, unsigned nsp = 0 )
00068 {
00069 int v;
00070 unsigned c;
00071 sz_t vmap_[ ienv->m_nvr ];
00072 unsigned addi,addo;
00073 vmap( vmap_, oenv, ienv );
00074 if ( isupp )
00075 for ( c = 0; c < nsp; osupp[c] = addo, c ++ )
00076 for ( addi = isupp[c], addo = 0, v = ienv->m_nvr-1; addi; addi /= ienv->m_szs[v], v-- )
00077 addo += (addi%ienv->m_szs[v])*oenv->m_str[vmap_[v]];
00078 else
00079 {
00080 nsp = ienv->data_size();
00081 for ( c = 0; c < nsp; osupp[c] = addo, c ++ )
00082 for ( addi = c, addo = 0, v = ienv->m_nvr-1; addi; addi /= ienv->m_szs[v], v -- )
00083 addo += (addi%ienv->m_szs[v])*oenv->m_str[vmap_[v]];
00084 };
00085 };
00086
00089 template< class real_t, char op >
00090 inline static void _mvrcvloop_( bernstein::eenv * oenv, real_t * dst,
00091 bernstein::eenv * aenv, real_t * sra,
00092 bernstein::eenv * benv, real_t * srb,
00093 unsigned * asupp = 0, unsigned nas = 0,
00094 unsigned * oasup = 0,
00095 unsigned * bsupp = 0, unsigned nbs = 0,
00096 unsigned * obsup = 0 )
00097 {
00098
00099 unsigned * loasup, * lobsup; loasup = lobsup = 0;
00100
00101 if ( !oasup ) { if ( !asupp ) nas = aenv->data_size(); loasup = new unsigned[ nas ]; oasup = loasup; oaddress( oenv, oasup, aenv, asupp, nas ); };
00102
00103 if ( !obsup ) { if ( !bsupp ) nbs = benv->data_size(); lobsup = new unsigned[ nbs ]; obsup = lobsup; oaddress( oenv, obsup, benv, bsupp, nas ); };
00104
00105 unsigned ia, ib, out; real_t ca;
00106 switch( (asupp!=0)<<1|(bsupp!=0) )
00107 {
00108 case 0:
00109 assert(nas==aenv->data_size() && nbs == benv->data_size());
00110 if ( op == '+' )
00111 {
00112 for ( ia = 0; ia < nas; ia ++ )
00113 for ( ib = 0; ib < nbs; ib ++ )
00114 dst[oasup[ia]+obsup[ib]] += sra[ia]*srb[ib];
00115 break;
00116 }
00117 if ( op == '-' )
00118 {
00119 for ( ia = 0; ia < nas; ia ++ )
00120 for ( ib = 0; ib < nbs; out += obsup[ib], ib ++ )
00121 dst[oasup[ia]+obsup[ib]] -= sra[ia]*srb[ib];
00122 break;
00123 };
00124 break;
00125 case 1:
00126 assert(nas == aenv->data_size() && bsupp != 0);
00127 if ( op == '+' )
00128 {
00129 assert(nas==aenv->data_size() && nbs == benv->data_size());
00130 for ( ia = 0; ia < nas; ia ++ )
00131 for ( ib = 0; ib < nbs; ib ++ )
00132 dst[oasup[ia]+obsup[ib]] += sra[ia]*srb[bsupp[ib]];
00133 break;
00134 }
00135 if ( op == '-' )
00136 {
00137 for ( ia = 0; ia < nas; ia ++ )
00138 for ( ib = 0; ib < nbs; ib ++ )
00139 dst[oasup[ia]+obsup[ib]] -= sra[ia]*srb[bsupp[ib]];
00140 break;
00141 };
00142 break;
00143 case 2:
00144 assert(nbs == benv->data_size() && asupp != 0);
00145 if ( op == '+' )
00146 {
00147 for ( ia = 0; ia < nas; ia ++ )
00148 for ( ib = 0; ib < nbs; ib ++ )
00149 dst[oasup[ia]+obsup[ib]] += sra[asupp[ia]]*srb[ib];
00150 break;
00151 }
00152 if ( op == '-' )
00153 {
00154 for ( ia = 0; ia < nas; ia ++ )
00155 for ( ib = 0; ib < nbs; ib ++ )
00156 dst[oasup[ia]+obsup[ib]] -= sra[asupp[ia]]*srb[ib];
00157 break;
00158 };
00159 break;
00160 case 3:
00161 assert(asupp != 0 && bsupp != 0);
00162 if ( op == '+' )
00163 {
00164 for ( ia = 0; ia < nas; ia ++ )
00165 for ( ib = 0; ib < nbs; ib ++ )
00166 dst[oasup[ia]+obsup[ib]] += sra[asupp[ia]]*srb[bsupp[ib]];
00167 break;
00168 }
00169 if ( op == '-' )
00170 {
00171 assert(nas==aenv->data_size() && nbs == benv->data_size());
00172 for ( ia = 0; ia < nas; ia ++ )
00173 for ( ib = 0; ib < nbs; ib ++ )
00174 dst[oasup[ia]+obsup[ib]] -= sra[asupp[ia]]*srb[asupp[ib]];
00175 break;
00176 };
00177 break;
00178 };
00179
00180 if ( loasup ) delete[] loasup; if ( lobsup ) delete[] lobsup;
00181 };
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201 template<typename real_t>
00202 static void monoms_multiply_loop( eenv * o, eenv * a, eenv * b, real_t * dst, real_t * src_a, real_t * src_b )
00203 { _mvrcvloop_<real_t,'+'>( o, dst, a, src_a, b, src_b ); };
00204
00205 template<typename real_t>
00206 static void monoms_multiply( bernstein::eenv * res, bernstein::eenv * a, bernstein::eenv *b,
00207 real_t * dst, real_t * src_a, real_t * src_b )
00208 { res->op_mul(a,b); monoms_multiply_loop( res, a, b, dst, src_a, src_b ); };
00209
00210
00211 template< typename real_t >
00212 static void pmmul( eenv * oenv, real_t ** dst, eenv * aenv, real_t ** src_a, eenv * benv, real_t ** src_b, int n,
00213 bool clear = true,
00214 unsigned * asupp = 0, unsigned nas = 0,
00215 unsigned * oasup = 0,
00216 unsigned * bsupp = 0, unsigned nbs = 0,
00217 unsigned * obsup = 0 )
00218 {
00219 if ( clear ) for (int d=0;d<n;std::fill(dst[d],dst[d]+oenv->data_size(),(real_t)0.0),d++);
00220 unsigned * loasup, * lobsup; loasup = lobsup = 0;
00221
00222 if ( !oasup ) { if ( !asupp ) nas = aenv->data_size(); loasup = new unsigned[ nas ]; oasup = loasup; oaddress( oenv, oasup, aenv, asupp, nas ); };
00223
00224 if ( !obsup ) { if ( !bsupp ) nbs = benv->data_size(); lobsup = new unsigned[ nbs ]; obsup = lobsup; oaddress( oenv, obsup, benv, bsupp, nbs ); };
00225 for ( unsigned i = 0; i < n; i ++ )
00226 _mvrcvloop_<real_t,'+'>(oenv,dst[i],aenv,src_a[i],benv,src_b[i],asupp,nas,oasup,bsupp,nbs,obsup);
00227 if ( loasup ) delete[] loasup; if ( lobsup ) delete[] lobsup;
00228 };
00229
00230 template< typename real_t >
00231 static inline void mmul( eenv * oenv, real_t * dst, eenv * aenv, real_t * src_a, eenv * benv, real_t * src_b,
00232 bool clear = true,
00233 unsigned * asupp = 0, unsigned nas = 0,
00234 unsigned * oasupp = 0,
00235 unsigned * bsupp = 0, unsigned nbs = 0,
00236 unsigned * obsupp = 0 )
00237 { pmmul( oenv, &dst, aenv, &src_a, benv, &src_b, 1, clear, asupp, nas, oasupp, bsupp, nbs, obsupp ); };
00238
00239 template< typename real_t >
00240 static void spmmul( eenv * oenv, real_t ** dst, eenv * aenv, real_t ** src_a, eenv * benv, real_t ** src_b, int n,
00241 bool clear = true, bool stats = false )
00242 {
00243 unsigned nas,nbs;
00244 unsigned * assup = new unsigned[ aenv->data_size() ];
00245 unsigned * bssup = new unsigned[ benv->data_size() ];
00246 assert( assup && bssup );
00247 for ( int i = 0; i < n; i ++ )
00248 {
00249 nas = aenv->support(assup,src_a[i]);
00250 nbs = benv->support(bssup,src_b[i]);
00251 mmul( oenv, dst[i], aenv, src_a[i], benv, src_b[i], true, assup, nas, 0, bssup, nbs, 0 );
00252 };
00253 delete[] assup;
00254 delete[] bssup;
00255 };
00256
00257 template< typename real_t >
00258 static void spmmul( eenv * oenv, real_t * dst, eenv * aenv, real_t * src_a, eenv * benv, real_t * src_b,
00259 bool clear = true, bool stats = false )
00260 {
00261 spmmul( oenv, &dst, aenv, &src_a, benv, &src_b, 1, clear, stats );
00262 };
00263
00264 template<typename real_t>
00265 static void mcrossp( eenv * oenv, real_t ** dst, eenv * aenv, real_t ** src_a, eenv * benv, real_t ** src_b,
00266 bool clear = true,
00267 unsigned * asupp = 0, unsigned nas = 0,
00268 unsigned * oasup = 0,
00269 unsigned * bsupp = 0, unsigned nbs = 0,
00270 unsigned * obsup = 0 )
00271
00272
00273 {
00274 if ( clear ) for (int d=0;d<3;std::fill(dst[d],dst[d]+oenv->data_size(),(real_t)0.0),d++);
00275 unsigned * loasup, * lobsup; loasup = lobsup = 0;
00276
00277 if ( !oasup ) { if ( !asupp ) nas = aenv->data_size(); loasup = new unsigned[ nas ]; oasup = loasup; oaddress( oenv, oasup, aenv, asupp, nas ); };
00278
00279 if ( !obsup ) { if ( !bsupp ) nbs = benv->data_size(); lobsup = new unsigned[ nbs ]; obsup = lobsup; oaddress( oenv, obsup, benv, bsupp, nbs ); };
00280 _mvrcvloop_<real_t,'+'>(oenv,dst[2],aenv,src_a[0],benv,src_b[1],asupp,nas,oasup,bsupp,nbs,obsup);
00281 _mvrcvloop_<real_t,'-'>(oenv,dst[2],aenv,src_a[1],benv,src_b[0],asupp,nas,oasup,bsupp,nbs,obsup);
00282 _mvrcvloop_<real_t,'+'>(oenv,dst[0],aenv,src_a[1],benv,src_b[2],asupp,nas,oasup,bsupp,nbs,obsup);
00283 _mvrcvloop_<real_t,'-'>(oenv,dst[0],aenv,src_a[2],benv,src_b[1],asupp,nas,oasup,bsupp,nbs,obsup);
00284 _mvrcvloop_<real_t,'+'>(oenv,dst[1],aenv,src_a[2],benv,src_b[0],asupp,nas,oasup,bsupp,nbs,obsup);
00285 _mvrcvloop_<real_t,'-'>(oenv,dst[1],aenv,src_a[0],benv,src_b[2],asupp,nas,oasup,bsupp,nbs,obsup);
00286 if ( loasup ) delete[] loasup; if ( lobsup ) delete[] lobsup;
00287 };
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312 template<typename real_t>
00313 static void mcrossp( eenv * res, eenv * a, eenv * b, real_t ** dst, real_t ** src_a, real_t ** src_b )
00314 { mcrossp( res, dst, a, src_a, b, src_b ); };
00315
00316 template<typename real_t>
00317 static void monoms_crossprod( eenv * res, eenv * a, eenv * b,
00318 real_t ** dst,
00319 real_t ** src_a, real_t ** src_b )
00320 {
00321 res->op_mul(a,b);
00322 for ( int d = 0; d < 3; d ++ ) dst[d] = new real_t[ res->data_size() ];
00323 mcrossp( res, dst, a, src_a, b, src_b );
00324 };
00325
00326
00327 template<typename real_t>
00328 static void mdotp( eenv * oenv, real_t * dst, eenv * aenv, real_t ** src_a, eenv * benv, real_t ** src_b, int n,
00329 bool clear = true,
00330 unsigned * asupp = 0, unsigned nas = 0,
00331 unsigned * oasup = 0,
00332 unsigned * bsupp = 0, unsigned nbs = 0,
00333 unsigned * obsup = 0 )
00334
00335
00336 {
00337 if ( clear ) std::fill(dst,dst+oenv->data_size(),(real_t)0.0);
00338 unsigned * loasup, * lobsup; loasup = lobsup = 0;
00339
00340 if ( !oasup ) { if ( !asupp ) nas = aenv->data_size(); loasup = new unsigned[ nas ]; oasup = loasup; oaddress( oenv, oasup, aenv, asupp, nas ); };
00341
00342 if ( !obsup ) { if ( !bsupp ) nbs = benv->data_size(); lobsup = new unsigned[ nbs ]; obsup = lobsup; oaddress( oenv, obsup, benv, bsupp, nas ); };
00343 for ( int i = 0; i < n; i ++ )
00344 _mvrcvloop_<real_t,'+'>(oenv,dst,aenv,src_a[i],benv,src_b[i],asupp,nas,oasup,bsupp,nbs,obsup);
00345 if ( loasup ) delete[] loasup; if ( lobsup ) delete[] lobsup;
00346 };
00347
00348 template<typename real_t>
00349 static void monoms_dotprod( eenv * res, eenv * a, eenv * b, real_t *& dst, real_t ** src_a, real_t ** src_b, int n )
00350 {
00351 res->op_mul(a,b);
00352 dst = new real_t[res->data_size()];
00353 mdotp( res, dst, a, src_a, b, src_b, n );
00354 };
00355
00356
00359 template< class real_t >
00360 static void rvbinoms( bernstein::eenv * ienv, real_t * bcff,
00361 unsigned * isupp = 0, unsigned nsp = 0, bernstein::bzenv<real_t> * bznv = bzenv<real_t>::_default_ )
00362 {
00363 real_t cff;
00364 unsigned c,addi;
00365 int v;
00366 if ( isupp )
00367 for ( c = 0; c < nsp; bcff[c] = cff, c ++ )
00368 for ( cff = (real_t)1.0, addi = isupp[c], v = ienv->m_nvr-1; addi; addi /= ienv->m_szs[v], v-- )
00369 cff /= bznv->binomial(ienv->m_szs[v]-1,addi % ienv->m_szs[v]);
00370 else
00371 for ( c = 0; c < ienv->data_size(); bcff[c] = cff, c ++ )
00372 for ( addi = c, v = ienv->m_nvr-1; addi; addi /= ienv->m_szs[v], v -- )
00373 cff /= bznv->binomial(ienv->m_szs[v]-1,addi % ienv->m_szs[v]);
00374 };
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524