realroot_doc 0.1.1
|
00001 /******************************************************************** 00002 * This file is part of the source code of the realroot library. 00003 * Author(s): J.P. Pavone, GALAAD, INRIA 00004 * $Id: eenv-multiply.hpp,v 1.1 2005/07/11 10:03:55 jppavone Exp $ 00005 ********************************************************************/ 00006 /* densite exacte / statistique des coefficients non-nuls */ 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 /* calcul le support des coefficients non-nuls dans src */ 00026 template<class real_t> 00027 unsigned support( unsigned * supp, real_t * src, const real_t& prec = 1e-6 ) 00028 { 00029 // supp = new unsigned[ data_size() ]; 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 /* transforme l'environement en l'environement de a*b */ 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 /* mapping des noms i->o */ 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 > // multiplication multivariee dans la base monomiale 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 /* calcul des addresses de sorties */ 00099 unsigned * loasup, * lobsup; loasup = lobsup = 0; 00100 /* calcul des addresses de sorties de a sur o */ 00101 if ( !oasup ) { if ( !asupp ) nas = aenv->data_size(); loasup = new unsigned[ nas ]; oasup = loasup; oaddress( oenv, oasup, aenv, asupp, nas ); }; 00102 /* calcul des addresses de sorties de b sur o */ 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 /* liberation des addresses de sorties */ 00180 if ( loasup ) delete[] loasup; if ( lobsup ) delete[] lobsup; 00181 }; 00182 00183 00184 // template< typename real_t > 00185 // static void sparse_multiply( bernstein::eenv * renv, real_t * rdata, 00186 // bernstein::eenv * aenv, unsigned nasupp, unsigned * asupp, real_t * adata, 00187 // bernstein::eenv * benv, unsigned nbsupp, unsigned * bsupp, real_t * bdata ) 00188 // { 00189 00190 // unsigned * osuppa = new unsigned[ nasupp ]; 00191 // unsigned * osuppb = new unsigned[ nbsupp ]; 00192 // this-osupp( renv, osuppa, aenv, asupp, nasupp ); 00193 // this->osupp( renv, osuppb, benv, bsupp, nbsupp ); 00194 // for ( unsigned i = 0; i < nasupp; i ++ ) 00195 // for ( unsigned j = 0; j < nbsupp; j ++ ) 00196 // rdata[osuppa[i]+osuppb[j]] += adata[asupp[i]] * bdata[bsupp[j]]; 00197 // delete[] osuppa; 00198 // delete[] osuppb; 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 > // multiplication vectorielle 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 /* calcul des addresses de sorties de a sur o */ 00222 if ( !oasup ) { if ( !asupp ) nas = aenv->data_size(); loasup = new unsigned[ nas ]; oasup = loasup; oaddress( oenv, oasup, aenv, asupp, nas ); }; 00223 /* calcul des addresses de sorties de b sur o */ 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 > // multiplication simple 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 > // multiplication vectorielle creuse (calcul du support + multiplication) 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 > // multiplication simple creuse (calcul du support + multiplication) 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 /* calcul des addresses de sorties de a sur o */ 00277 if ( !oasup ) { if ( !asupp ) nas = aenv->data_size(); loasup = new unsigned[ nas ]; oasup = loasup; oaddress( oenv, oasup, aenv, asupp, nas ); }; 00278 /* calcul des addresses de sorties de b sur o */ 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 // template<typename real_t> 00291 // static void spmcrossp( eenv * oenv, real_t ** dst, eenv * aenv, real_t ** src_a, eenv * benv, real_t ** src_b, 00292 // bool clear = true, bool stats = false ) 00293 // { 00294 // if ( clear ) for (int d=0;d<3;std::fill(dst[d],dst[d]+oenv->data_size(),(real_t)0.0),d++); 00295 // unsigned * asupp = new unsigned[ a->data_size() ]; 00296 // unsigned * bsupp = new unsigned [b->data_size()]; 00297 // unsigned * loasup, * lobsup; loasup = lobsup = 0; 00298 // /* calcul des addresses de sorties de a sur o */ 00299 // if ( !oasup ) { if ( !asupp ) nas = aenv->data_size(); loasup = new unsigned[ nas ]; oasup = loasup; oaddress( oenv, oasup, aenv, asupp, nas ); }; 00300 // /* calcul des addresses de sorties de b sur o */ 00301 // if ( !obsup ) { if ( !bsupp ) nbs = benv->data_size(); lobsup = new unsigned[ nbs ]; obsup = lobsup; oaddress( oenv, obsup, benv, bsupp, nbs ); }; 00302 // _mvrcvloop_<real_t,'+'>(oenv,dst[2],aenv,src_a[0],benv,src_b[1],asupp,nas,oasup,bsupp,nbs,obsup); 00303 // _mvrcvloop_<real_t,'-'>(oenv,dst[1],aenv,src_a[0],benv,src_b[2],asupp,nas,oasup,bsupp,nbs,obsup); 00304 // _mvrcvloop_<real_t,'-'>(oenv,dst[2],aenv,src_a[1],benv,src_b[0],asupp,nas,oasup,bsupp,nbs,obsup); 00305 // _mvrcvloop_<real_t,'+'>(oenv,dst[0],aenv,src_a[1],benv,src_b[2],asupp,nas,oasup,bsupp,nbs,obsup); 00306 // _mvrcvloop_<real_t,'-'>(oenv,dst[0],aenv,src_a[2],benv,src_b[1],asupp,nas,oasup,bsupp,nbs,obsup); 00307 // _mvrcvloop_<real_t,'+'>(oenv,dst[1],aenv,src_a[2],benv,src_b[0],asupp,nas,oasup,bsupp,nbs,obsup); 00308 // if ( loasup ) delete[] loasup; if ( lobsup ) delete[] lobsup; 00309 // }; 00310 00311 00312 template<typename real_t> // compatibilite ancien code 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>// compatibilite ancien code 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 /* calcul des addresses de sorties de a sur o */ 00340 if ( !oasup ) { if ( !asupp ) nas = aenv->data_size(); loasup = new unsigned[ nas ]; oasup = loasup; oaddress( oenv, oasup, aenv, asupp, nas ); }; 00341 /* calcul des addresses de sorties de b sur o */ 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> // compatibilite ancien code 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 // template< class real_t, char op > // multiplication multivariee dans la base de bernstein 00377 // inline static void _bvrcvloop_( bernstein::eenv * oenv, real_t * dst, 00378 // bernstein::eenv * aenv, real_t * sra, 00379 // bernstein::eenv * benv, real_t * srb, 00380 // bernstein::bzenv< real_t > * bznv = bernstein::bzenv<real_t>::_default_, 00381 // unsigned * asupp = 0, unsigned nas = 0, 00382 // unsigned * oasup = 0, 00383 // unsigned * bsupp = 0, unsigned nbs = 0, 00384 // unsigned * obsup = 0, 00385 // real_t * ibzco = 0, 00386 // real_t * ibzca = 0, real_t * ibzcb = 0 ) 00387 // { 00388 // /* calcul des addresses de sorties */ 00389 // unsigned * loasup, * lobsup; loasup = lobsup = 0; 00390 // /* calcul des addresses de sorties de a sur o */ 00391 // if ( !oasup ) { if ( !asupp ) nas = aenv->data_size(); loasup = new unsigned[ nas ]; oasup = loasup; oaddress( oenv, oasup, aenv, asupp, nas ); }; 00392 // /* calcul des addresses de sorties de b sur o */ 00393 // if ( !obsup ) { if ( !bsupp ) nbs = benv->data_size(); lobsup = new unsigned[ nbs ]; obsup = lobsup; oaddress( oenv, obsup, benv, bsupp, nas ); }; 00394 00395 // /* calcul des coefficients binomiaux (inverses) */ 00396 // real_t * libzca, * libzcb, * libzco; libzca = libzcb = libzco = 0; 00397 // /* calcul des coefficients binomiaux pour aenv */ 00398 // if ( !ibzca ) { libzca = new real_t[ nas ]; ibzca = libzca; rvbinoms( aenv, ibzca, asupp, nas, bznv ); }; 00399 // /* calcul des coefficients binomiaux pour benv */ 00400 // if ( !ibzcb ) { libzcb = new real_t[ nbs ]; ibzcb = libzcb; rvbinoms( benv, ibzcb, bsupp, nbs, bznv ); }; 00401 // /* calcul des coefficients binomiaux pour oenv */ 00402 // if ( !ibzco ) { libzco = new real_t[ renv->data_size() ]; ibzco = libzcb; rvbinoms( renv, ibzco, 0, 0, bznv ); }; 00403 // unsigned ia, ib, oa; real_t ca; 00404 // switch( (asupp!=0)<<1|(bsupp!=0) ) 00405 // { 00406 // case 0: 00407 // assert(nas==aenv->data_size() && nbs == benv->data_size()); 00408 // if ( op == '+' ) 00409 // { 00410 // for ( ia = 0; ia < nas; ia ++ ) 00411 // for ( oa = oasup[ia], ca = ibzca[ia], ib = 0; ib < nbs; ib ++ ) 00412 // dst[oa+obsup[ib]] += (ibzco[oa+obsup[ib]]/(ca*ibzcb[ib]))*sra[ia]*srb[ib]; 00413 // break; 00414 // } 00415 // if ( op == '-' ) 00416 // { 00417 // for ( ia = 0; ia < nas; ia ++ ) 00418 // for ( oa = oasup[ia], ca = ibzca[ia], ib = 0; ib < nbs; ib ++ ) 00419 // dst[oa+obsup[ib]] -= (ibzco[oa+obsup[ib]]/(ca*ibzcb[ib]))*sra[ia]*srb[ib]; 00420 // break; 00421 // }; 00422 // break; 00423 // case 1: 00424 // assert(nas == aenv->data_size() && bsupp != 0); 00425 // if ( op == '+' ) 00426 // { 00427 // assert(nas==aenv->data_size() && nbs == benv->data_size()); 00428 // for ( ia = 0; ia < nas; ia ++ ) 00429 // for ( oa = oasup[ia], ca = ibzca[ia], ib = 0; ib < nbs; ib ++ ) 00430 // dst[oa+obsup[ib]] += (ibzco[oa+obsup[ib]]/(ca*ibzcb[ib]))*sra[ia]*srb[bsupp[ib]]; 00431 // break; 00432 // } 00433 // if ( op == '-' ) 00434 // { 00435 // for ( ia = 0; ia < nas; ia ++ ) 00436 // for ( oa = oasup[ia], ca = ibzca[ia], ib = 0; ib < nbs; ib ++ ) 00437 // dst[oa+obsup[ib]] -= (ibzco[oa+obsup[ib]]/(ca*ibzcb[ib]))*sra[ia]*srb[bsupp[ib]]; 00438 // break; 00439 // }; 00440 // break; 00441 // case 2: 00442 // assert(nbs == benv->data_size() && asupp != 0); 00443 // if ( op == '+' ) 00444 // { 00445 // for ( ia = 0; ia < nas; ia ++ ) 00446 // for ( oa = oasup[ia], ca = ibzca[ia], ib = 0; ib < nbs; ib ++ ) 00447 // dst[oa+obsup[ib]] += (ibzco[oa+obsup[ib]]/(ca*ibzcb[ib]))*sra[asupp[ia]]*srb[ib]; 00448 // break; 00449 // } 00450 // if ( op == '-' ) 00451 // { 00452 // for ( ia = 0; ia < nas; ia ++ ) 00453 // for ( oa = oasup[ia], ca = ibzca[ia], ib = 0; ib < nbs; ib ++ ) 00454 // dst[oa+obsup[ib]] -= (ibzco[oa+obsup[ib]]/(ca*ibzcb[ib]))*sra[asupp[ia]]*srb[ib]; 00455 // break; 00456 // }; 00457 // break; 00458 // case 3: 00459 // assert(asupp != 0 && bsupp != 0); 00460 // if ( op == '+' ) 00461 // { 00462 // for ( ia = 0; ia < nas; ia ++ ) 00463 // for ( oa = oasup[ia], ca = ibzca[ia], ib = 0; ib < nbs; ib ++ ) 00464 // dst[oa+obsup[ib]] += (ibzco[oa+obsup[ib]]/(ca*ibzcb[ib]))*sra[asupp[ia]]*srb[bsupp[ib]]; 00465 // break; 00466 // } 00467 // if ( op == '-' ) 00468 // { 00469 // assert(nas==aenv->data_size() && nbs == benv->data_size()); 00470 // for ( ia = 0; ia < nas; ia ++ ) 00471 // for ( oa = oasup[ia], ca = ibzca[ia], ib = 0; ib < nbs; ib ++ ) 00472 // dst[oa+obsup[ib]] -= (ibzco[oa+obsup[ib]]/(ca*ibzcb[ib]))*sra[asupp[ia]]*srb[bsupp[ib]]; 00473 // break; 00474 // }; 00475 // break; 00476 // }; 00477 00478 // /* liberation des addresses de sorties */ 00479 // if ( loasup ) delete[] loasup; if ( lobsup ) delete[] lobsup; 00480 // /* liberation des coefficients binomiaux */ 00481 // if ( libzca ) delete[] libzca; if ( libzcb ) delete[] libzcb; if ( libzco ) delete[] libzco; 00482 // }; 00483 00484 // template<typename real_t> 00485 // static void bernstein_multiply_loop( eenv * o, eenv * a, eenv * b, real_t * dst, real_t * src_a, real_t * src_b ) 00486 // { _bvrcvloop_<real_t,'+'>( o, dst, a, src_a, b, src_b ); }; 00487 00488 // template<typename real_t> 00489 // static void bcrossp( eenv * oenv, real_t ** dst, eenv * aenv, real_t ** src_a, eenv * benv, real_t ** src_b, 00490 // bernstein::bzenv< real_t > * bznv = bernstein::bzenv<real_t>::_default_, 00491 // bool clear = true, 00492 // unsigned * asupp = 0, unsigned nas = 0, 00493 // unsigned * oasup = 0, 00494 // unsigned * bsupp = 0, unsigned nbs = 0, 00495 // unsigned * obsup = 0 ) 00496 // { 00497 // if ( clear ) for (int d=0;d<3;std::fill(dst[d],dst[d]+oenv->data_size(),(real_t)0.0),d++); 00498 // unsigned * loasup, * lobsup; loasup = lobsup = 0; 00499 // /* calcul des addresses de sorties de a sur o */ 00500 // if ( !oasup ) { if ( !asupp ) nas = aenv->data_size(); loasup = new unsigned[ nas ]; oasup = loasup; oaddress( oenv, oasup, aenv, asupp, nas ); }; 00501 // /* calcul des addresses de sorties de b sur o */ 00502 // if ( !obsup ) { if ( !bsupp ) nbs = benv->data_size(); lobsup = new unsigned[ nbs ]; obsup = lobsup; oaddress( oenv, obsup, benv, bsupp, nas ); }; 00503 // /* calcul des coefficients binomiaux (inverses) */ 00504 // real_t * libzca, * libzcb, * libzco; libzca = libzcb = libzco = 0; 00505 // /* calcul des coefficients binomiaux pour aenv */ 00506 // if ( !ibzca ) { libzca = new real_t[ nas ]; ibzca = libzca; rvbinoms( aenv, ibzca, asupp, nas, bznv ); }; 00507 // /* calcul des coefficients binomiaux pour benv */ 00508 // if ( !ibzcb ) { libzcb = new real_t[ nbs ]; ibzcb = libzcb; rvbinoms( benv, ibzcb, bsupp, nbs, bznv ); }; 00509 // /* calcul des coefficients binomiaux pour oenv */ 00510 // if ( !ibzco ) { libzco = new real_t[ renv->data_size() ]; ibzco = libzcb; rvbinoms( renv, ibzco, 0, 0, bznv ); }; 00511 00512 // _bvrcvloop_<real_t,'-'>(oenv,dst[2],aenv,src_a[1],benv,src_b[0],asupp,nas,obsup,bsupp,nbs,obsup); 00513 // _bvrcvloop_<real_t,'+'>(oenv,dst[2],aenv,src_a[0],benv,src_b[1],asupp,nas,obsup,bsupp,nbs,obsup); 00514 // _bvrcvloop_<real_t,'-'>(oenv,dst[0],aenv,src_a[2],benv,src_b[1],asupp,nas,obsup,bsupp,nbs,obsup); 00515 // _bvrcvloop_<real_t,'+'>(oenv,dst[0],aenv,src_a[1],benv,src_b[2],asupp,nas,obsup,bsupp,nbs,obsup); 00516 // _bvrcvloop_<real_t,'-'>(oenv,dst[1],aenv,src_a[0],benv,src_b[2],asupp,nas,obsup,bsupp,nbs,obsup); 00517 // _bvrcvloop_<real_t,'+'>(oenv,dst[1],aenv,src_a[2],benv,src_b[0],asupp,nas,obsup,bsupp,nbs,obsup); 00518 00519 // /* liberation des addresses de sorties */ 00520 // if ( loasup ) delete[] loasup; if ( lobsup ) delete[] lobsup; 00521 // /* liberation des coefficients binomiaux */ 00522 // if ( libzca ) delete[] libzca; if ( libzcb ) delete[] libzcb; if ( libzco ) delete[] libzco; 00523 // }; 00524 /********************************************************************/