realroot_doc 0.1.1
/Users/mourrain/Devel/mmx/realroot/include/realroot/loops_brnops.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: brnops.hpp,v 1.1 2005/07/11 10:03:56 jppavone Exp $
00005  ********************************************************************/
00006 #ifndef realroot_SOLVE_SBDSLV_LOOPS_BRNOPS_H
00007 #define realroot_SOLVE_SBDSLV_LOOPS_BRNOPS_H
00008 //--------------------------------------------------------------------
00009 #include<algorithm>
00010 //--------------------------------------------------------------------
00011 namespace mmx {
00012 //--------------------------------------------------------------------
00013 
00014 /* boucle unidimensionelle de base pour la representation de bernstein */
00015 namespace brnops
00016 {
00017   /* algorithme de de Casteljau sur place
00018    * ------------------------------------
00019    *     r[i] = (1-t)*r[i] + t*r[i+1]
00020    */
00021   
00022   template<typename real_t>
00023   void decasteljau( real_t * r, unsigned sz, const real_t& t, int str = 1 )
00024   {
00025     real_t *er, *p;
00026       for ( er = r + (sz-1)*str; er != r; er -= str )
00027         for ( p = r; p != er; p += str )
00028           *p = (1.0-t)**p+t**(p+str);
00029   };
00030   
00031   /* algorithme de de Casteljau pour les bissections, t = 1/2 
00032    * --------------------------------------------------------
00033    *       r[i] = (r[i]+r[i+1])/2
00034    */
00035   
00036   template<typename real_t>
00037   void decasteljau( real_t * r, unsigned sz, int str = 1 )
00038   {
00039     real_t *er, *p;
00040     for ( er = r + (sz-1)*str; er != r; er -= str )
00041       for ( p = r; p != er; p += str )
00042         *p = (*p+*(p+str))/2.0;
00043   };
00044   
00045   /* évaluation en t    */
00046   template<typename real_t>
00047   real_t eval( real_t const * const src, unsigned sz, const real_t& t, int st = 1 )
00048   {
00049     real_t tmp[sz];
00050     std::copy( src, src + sz, tmp );
00051     decasteljau( tmp, sz, t );
00052     return tmp[0];
00053   };
00054     
00055   /* évaluation en (1/2) */
00056   template<typename real_t>
00057   real_t eval( real_t const * const src, unsigned sz, int st = 1 )
00058   {
00059     real_t tmp[sz];
00060     std::copy( src, src + sz, tmp );
00061     decasteljau( tmp, sz  );
00062     return tmp[0];
00063   };
00064   
00065   
00066   /* algorithme de de Casteljau, version subdivision
00067    * -----------------------------------------------
00068    * entrée:
00069    * ------
00070    * r = coefficients du polynome
00071    *
00072    * sortie:
00073    * ------
00074    * r = partie droite [t, 1]
00075    * l = partie gauche [0, t]
00076    */
00077   
00078   template<typename real_t>
00079   void decasteljau( real_t * r, real_t * l, unsigned sz, const real_t& t, int str = 1, int stl = 1 )
00080   {
00081     real_t * er, * p;
00082     for ( er = r + (sz-1)*str; er != r; er -= str, l += stl )
00083       {
00084         *l = *r;
00085         for ( p = r; p != er; p += str )
00086           *p = (1.0-t)**p+t**(p+str);
00087       };
00088     *l = *r;
00089   };
00090   
00091   /* algorithme de de Casteljau, version subdivision (1/2)
00092    * -----------------------------------------------
00093    * entrée:
00094    * ------
00095    * r = coefficients du polynome
00096    *
00097    * sortie:
00098    * ------
00099    * r = partie droite [t, 1]
00100    * l = partie gauche [0, t]
00101    */
00102   
00103   template<typename real_t>
00104   void decasteljau( real_t * r, real_t * l, unsigned sz, int str = 1, int stl = 1 )
00105   {
00106     real_t * er, * p;
00107     er = r + (sz-1)*str;
00108     for ( er = r + (sz-1)*str; er != r; er -= str, l += stl )
00109       {
00110         *l = *r;
00111         for ( p = r; p != er; p += str )
00112           *p = (*p+*(p+str))/2.0;
00113         };
00114     *l = *r;
00115     };
00116   
00117   /* restriction à gauche
00118    * --------------------
00119    * calcul de la representation pour [t,1]
00120    */
00121   
00122   template<typename real_t>
00123   void lrestrict( real_t * data, int sz, const real_t& t, int st ) 
00124   { decasteljau(data,sz,t,st); };
00125   
00126   /* restriction à droite
00127    * --------------------
00128    * calcul de la representation pour [0,t]
00129    */
00130   
00131   template<typename real_t>
00132   void rrestrict( real_t * data, int sz,  const real_t& t, int st ) 
00133   { decasteljau( data + (sz-1)*st, sz, (real_t)(real_t(1)-t), -st ); };
00134   
00135     
00136     
00137   template<typename real_t>
00138   void hodograph( real_t * dst, real_t const * const src, unsigned sz, int st)
00139   {
00140       int p = 0;
00141       for ( unsigned i = 0; i < sz-1; i ++, p += st ) dst[p] = src[p+st]-src[p];
00142     };
00143   
00144   template<typename real_t>
00145     void diff( real_t * dst, real_t const * const src, unsigned sz, int sta = 1, int stout = 1)
00146     {
00147       int pa = 0;
00148       int po = 0;
00149       for ( unsigned i = 0; i < sz-1; i ++, pa += sta, po += stout )
00150         dst[po] = (sz-1)*(src[pa+sta]-src[pa]);
00151     }; 
00152     
00153     
00154     template<typename real_t>
00155     bool rockwood_cut( real_t& t, real_t const * b, unsigned sz, int st = 1 )
00156     {
00157       for ( unsigned i = 0; i < sz-1; i ++ )
00158         {
00159           if ( b[i*st]*b[(i+1)*st] <= 0 )
00160             {
00161               real_t d = b[i*st]-b[(i+1)*st];
00162               t = (i*d+b[i])/(sz*d);
00163             return true;
00164             };
00165         };
00166       return false;
00167     };
00168   };
00169 //--------------------------------------------------------------------
00170 } //namespace mmx
00171 /********************************************************************/
00172 #endif //