realroot_doc 0.1.1
/Users/mourrain/Devel/mmx/realroot/include/realroot/bernstein_eenv_multiply.hpp
Go to the documentation of this file.
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 /********************************************************************/