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.hpp,v 1.1 2005/07/11 10:03:55 jppavone Exp $ 00005 ********************************************************************/ 00006 #ifndef realroot_SOLVE_SBDSLV_BERNSTEIN_EENV_H 00007 #define realroot_SOLVE_SBDSLV_BERNSTEIN_EENV_H 00008 //-------------------------------------------------------------------- 00009 #include <cstddef> 00010 #include <iostream> 00011 #include <realroot/loops_vctops.hpp> 00012 #include <realroot/loops_brnops.hpp> 00013 #include <realroot/loops_upoldse.hpp> 00014 #include <realroot/bernstein_bzenv.hpp> 00015 //-------------------------------------------------------------------- 00016 namespace mmx { 00017 //-------------------------------------------------------------------- 00018 #ifndef _valueof_ 00019 #define _valueof_(x) std::cout << #x" = " << (x) << std::endl; 00020 #endif 00021 00022 namespace bernstein 00023 { 00024 struct eenv_base 00025 { 00026 typedef int sz_t; 00027 sz_t m_nvr, * m_szs, * m_str; 00028 protected: 00029 inline void compute_strides() 00030 { 00031 m_str[m_nvr-1] = 1; 00032 for ( int i = m_nvr-2; i >= -1; i-- ) m_str[i] = m_szs[i+1]*m_str[i+1]; 00033 }; 00034 public: 00035 eenv_base( sz_t nvr = 0 ) { m_nvr = nvr; }; 00036 inline void set_szs( sz_t * szs ) { m_szs = szs; compute_strides(); }; 00037 inline sz_t sz( sz_t v ) const { return m_szs[v]; }; 00038 inline sz_t nvars() const { return m_nvr; }; 00039 inline sz_t data_size() const { return m_str[-1]; }; 00040 00041 template<typename real_t> 00042 void hodograph( real_t * dst, real_t * src, int v ) 00043 { 00044 int i,j; 00045 int k; 00046 int kstr = (m_szs[v]-1)*m_str[v]; 00047 for ( k = i = 0; i < data_size(); i += m_str[v-1], k += kstr ) 00048 for ( j = 0; j < m_str[v]; j++ ) 00049 brnops::hodograph(dst+k+j,src+i+j,m_szs[v],m_str[v]); 00050 }; 00051 00052 template<typename X, typename real_t> 00053 void copy( X * dst, real_t const * const src ) { std::copy(src, src + data_size(), dst ); }; 00054 00055 template<typename real_t> 00056 real_t eval( real_t * data, const real_t * prm, real_t * chunk = 0 ) 00057 { 00058 sz_t i,j; 00059 real_t * tmp; 00060 if ( chunk ) tmp = chunk; 00061 else tmp = new real_t[ data_size() ]; 00062 std::copy(data,data+data_size(), tmp ); 00063 for ( int v = nvars()-1; v >= 0 ; v -- ) 00064 for ( i = 0; i <data_size(); i += m_str[v-1] ) 00065 brnops::decasteljau(tmp+i,m_szs[v],prm[v],m_str[v]); 00066 real_t val = tmp[0]; 00067 if ( !chunk ) delete[] tmp; 00068 return val; 00069 }; 00070 00071 template<typename real_t, typename X> 00072 void spmeval( X& res, real_t* src, X * prm, unsigned * supp, unsigned nsupp ) const 00073 { 00074 sz_t v, lg, d; 00075 unsigned i,add,o; 00076 lg = 0; 00077 for ( v = 0; v < m_nvr; v ++ ) if ( m_szs[v] > m_szs[lg] ) lg = v; 00078 X powers [m_nvr][m_szs[lg]]; 00079 X acc; 00080 for ( v = 0; v < m_nvr; v ++ ) 00081 for ( powers[v][0] = 1.0, d = 1; d < m_szs[v]; powers[v][d] = prm[v]*powers[v][d-1], d ++ ); 00082 res = 0; 00083 for ( i = 0; i < nsupp; res += acc, i ++ ) 00084 for ( add = supp[i], acc = src[add], v = m_nvr-1; add; add /= m_szs[v], v -- ) 00085 acc *= powers[v][add%m_szs[v]]; 00086 }; 00087 00088 00089 template<typename real_t,typename X> 00090 void meval( X& res, real_t * data, const X * prm ) const 00091 { 00092 sz_t i; 00093 X * tmp = new X[ data_size() ]; 00094 std::copy(data,data+data_size(),tmp); 00095 for ( int v = nvars()-1; v >= 0 ; v -- ) 00096 for ( i = 0; i < data_size(); i += m_str[v-1] ) 00097 *(tmp+i) = univariate::horner(tmp+i,m_szs[v],prm[v],m_str[v]); 00098 res = tmp[0]; 00099 delete[] tmp; 00100 }; 00101 00102 template<typename real_t> 00103 real_t monoms_eval( real_t * data, const real_t * prm ) const 00104 { 00105 sz_t i; 00106 real_t * tmp = new real_t[ data_size() ]; 00107 std::copy(data,data+data_size(), tmp ); 00108 for ( int v = nvars()-1; v >= 0 ; v -- ) 00109 for ( i = 0; i < data_size(); i += m_str[v-1] ) 00110 *(tmp+i) = upoldse::horner(tmp+i,m_szs[v],prm[v],m_str[v]); 00111 real_t val = tmp[0]; 00112 delete[] tmp; 00113 return val; 00114 }; 00115 00116 00117 template<typename real_t> 00118 void mins( real_t * _mins_, real_t const * const data, sz_t v ) const 00119 { 00120 sz_t p,k,i,j; 00121 for ( p = 0, k = 0; k < m_szs[v]; k++, p += m_str[v] ) 00122 { 00123 _mins_[k] = data[p]; 00124 for ( i = 0; i < data_size(); i += m_str[v-1] ) 00125 for ( j = i; j < i + m_str[v]; j ++ ) 00126 if ( data[j+p] < _mins_[k] ) _mins_[k] = data[j+p]; 00127 }; 00128 }; 00129 00130 template<typename real_t> 00131 void maxs( real_t * _maxs_, real_t const * const data, sz_t v ) const 00132 { 00133 sz_t p,k,i,j; 00134 00135 for ( p = 0, k = 0; k < m_szs[v]; k++, p += m_str[v] ) 00136 { 00137 _maxs_[k] = data[p]; 00138 for ( i = 0; i < data_size(); i += m_str[v-1] ) 00139 for ( j = i; j < i + m_str[v]; j ++ ) 00140 if ( data[j+p] > _maxs_[k] ) _maxs_[k] = data[j+p]; 00141 }; 00142 }; 00143 00144 template<typename real_t> 00145 inline void maxs( real_t * _maxs_, real_t const * const data ) const 00146 { for ( sz_t v = 0; v < m_nvr; v ++ ) { maxs(_maxs_,data,v); _maxs_ += m_szs[v];}; }; 00147 00148 template<typename real_t> 00149 inline void mins( real_t * _mins_, real_t const * const data ) const 00150 { for ( sz_t v = 0; v < m_nvr; v ++ ) { mins(_mins_,data,v); _mins_ += m_szs[v];}; }; 00151 00154 template<typename real_t> 00155 void split( real_t * left, real_t * right, int v, const real_t& t ) 00156 { 00157 int i,j,k; 00158 for ( i = 0; i < data_size(); i += m_str[v-1] ) 00159 for ( j = i; j < i + m_str[v]; j++ ) 00160 split(left+j,right+j,m_szs[v],m_str[v],t); 00161 }; 00162 00163 template<typename real_t> 00164 void split2( real_t * left, real_t * right, int v ) 00165 { 00166 int i,j; 00167 for ( i = 0; i < data_size(); i += m_str[v-1] ) 00168 for ( j = i; j < i + m_str[v]; j++ ) 00169 split2(left+j,right+j,m_szs[v],m_str[v]); 00170 }; 00171 00172 template<typename real_t> 00173 void lrestrict( real_t * data, int v, const real_t& mn ) 00174 { 00175 sz_t i,j; 00176 for ( i = 0; i < data_size(); i += m_str[v-1] ) 00177 for ( j = i; j < i + m_str[v]; j++ ) 00178 brnops::lrestrict(data+j,m_szs[v],mn,m_str[v]); 00179 }; 00180 00181 template<typename real_t> 00182 void rrestrict( real_t * data, int v, const real_t& mx ) 00183 { 00184 int i,j; 00185 for ( i = 0; i < data_size(); i += m_str[v-1] ) 00186 for ( j = i; j < i + m_str[v]; j++ ) 00187 brnops::rrestrict(data+j,m_szs[v],mx,m_str[v]); 00188 }; 00189 00190 template<typename real_t> 00191 bool sgnchg( real_t * data ) { return vctops::sgnchg(data,data_size()); }; 00192 00193 template<typename real_t> 00194 inline void scale( real_t * data ) { vctops::scale(data,data_size()); }; 00195 00196 00197 /* conversion sur [0,1]^n */ 00198 00199 /* monomiale -> bernstein */ 00200 template< typename real_t > /* conversion partielle */ 00201 void fromMonoms( real_t * data, sz_t v, bzenv<real_t> * env = bzenv<real_t>::_default_ ) 00202 { 00203 sz_t i,j; 00204 for ( i = 0; i < data_size(); i += m_str[v-1] ) 00205 for ( j = i; j < i + m_str[v]; j++ ) 00206 env->fromMonoms(data+j,m_szs[v],m_str[v]); 00207 }; 00208 template< typename real_t > /* conversion complete */ 00209 inline void fromMonoms( real_t * data, bzenv<real_t> * env = bzenv<real_t>::_default_ ) { for ( sz_t v = 0; v < m_nvr; fromMonoms(data,v,env), v++ ); }; 00210 00211 /* bernstein -> monomiale */ 00212 template< typename real_t > /* conversion partielle */ 00213 void toMonoms( real_t * data, sz_t v, bzenv<real_t> * env = bzenv<real_t>::_default_ ) 00214 { 00215 sz_t i,j; 00216 for ( i = 0; i < data_size(); i += m_str[v-1] ) 00217 for ( j = i; j < i + m_str[v]; j++ ) 00218 env->toMonoms(data+j,m_szs[v],m_str[v]); 00219 }; 00220 template< typename real_t > /* conversion complete */ 00221 inline void toMonoms( real_t * data, bzenv<real_t> * env = bzenv<real_t>::_default_ ) { for ( sz_t v = 0; v < m_nvr; toMonoms(data,v,env), v ++ ); }; 00222 00223 // template< typename real_t > 00224 // void mshift( real_t * data, real_t * prm ) 00225 // { 00226 // sz_t i,j; 00227 // for ( i = 0; i < data_size(); i += m_str[v-1] ) 00228 // for ( j = i; j < i + m_str[v]; j++ ) 00229 // upoldse::shift(data+j,m_szs[v],m_str[v],prm[v]); 00230 // }; 00231 00232 template< typename real_t > 00233 real_t flatness( real_t * data, int v ) 00234 { 00235 real_t m = 10; 00236 sz_t i,j; 00237 for ( i = 0; i < data_size(); i += m_str[v-1] ) 00238 for ( j = i; j < i + m_str[v]; j++ ) 00239 std::max(m,flatness(data+j,m_szs[v],m_str[v]) ); 00240 return m; 00241 }; 00242 }; 00243 00244 00245 // eenv_base + dictionnaire local/global pour les variables 00246 struct eenv : public eenv_base 00247 { 00248 typedef eenv_base::sz_t sz_t; 00249 struct add 00250 { 00251 00252 }; 00253 sz_t * m_vrs; 00254 sz_t * m_pszs; 00255 sz_t m_mxvr; 00256 void _alloc_( sz_t nvr ) 00257 { 00258 m_nvr = nvr; 00259 m_szs = new sz_t[4*m_nvr+2]; 00260 m_vrs = m_szs + m_nvr; 00261 m_str = m_vrs + m_nvr + 1; 00262 m_pszs = m_str + m_nvr + 1; 00263 }; 00264 eenv(){}; 00265 eenv( sz_t szu, sz_t szv ) 00266 { 00267 _alloc_(2); 00268 m_szs[0] = szu; m_szs[1] = szv; 00269 m_vrs[0] = 0; m_vrs[1] = 1; 00270 m_mxvr = 1; 00271 compute_strides(); 00272 m_pszs[-1] = 0; 00273 for ( sz_t v = 0; v < m_nvr; v ++ ) 00274 m_pszs[v] = m_pszs[v-1] + m_szs[v]; 00275 }; 00276 00277 eenv( sz_t nvr, sz_t const * szs, sz_t const * vrs ) 00278 { 00279 _alloc_(nvr); 00280 std::copy(szs,szs+m_nvr,m_szs); 00281 std::copy(vrs,vrs+m_nvr,m_vrs); 00282 compute_strides(); 00283 m_pszs[-1] = 0; 00284 m_mxvr = m_vrs[0]; 00285 for (sz_t v = 0; v < m_nvr; v ++ ) if ( m_vrs[v] > m_mxvr ) m_mxvr = m_vrs[v]; 00286 for ( sz_t v = 0; v < m_nvr; v ++ ) 00287 m_pszs[v] = m_pszs[v-1] + m_szs[v]; 00288 }; 00289 00290 void swap( eenv& e ) 00291 { 00292 std::swap(m_nvr,e_m.hpp_nvr); 00293 std::swap(m_szs,e_m.hpp_szs); 00294 std::swap(m_vrs,e_m.hpp_vrs); 00295 std::swap(m_pszs,e_m.hpp_pszs); 00296 std::swap(m_mxvr,e_m.hpp_mxvr); 00297 }; 00298 00299 sz_t psz(){ return m_pszs[m_nvr-1]; }; 00300 sz_t psft( sz_t v ) { return m_pszs[v-1];} 00301 00302 ~eenv() 00303 { 00304 if ( nvars() ) delete[] m_szs; 00305 m_nvr = 0; 00306 }; 00307 00308 sz_t stride( sz_t v ) const { return m_str[v]; }; 00309 sz_t var ( sz_t v ) const { return m_vrs[v]; }; 00310 00311 int indexofvar( sz_t gv ) const 00312 { 00313 // if ( gv < m_vrs[0] || gv > m_vrs[m_nvr-1] ) return -1; 00314 // remplacer par dichotomie ? 00315 for ( sz_t v = 0; v < m_nvr; v ++ ) 00316 if ( m_vrs[v] == gv ) return v; 00317 return -1; 00318 }; 00319 00320 /* operations */ 00321 /* environement de diff(e,v), v est local a e */ 00322 void diff( eenv * e, sz_t v ) 00323 { 00324 if ( nvars () ) this->~eenv(); 00325 _alloc_( e->nvars() ); 00326 std::copy( e->m_vrs, e->m_vrs+e->nvars(), m_vrs ); 00327 m_mxvr = e->m_mxvr; 00328 for ( sz_t i = 0; i < m_nvr; m_szs[i] = e->sz(i), i ++ ); 00329 m_szs[v]--; 00330 compute_strides(); 00331 }; 00332 00333 template<typename real_t> 00334 static void mdiff( eenv * res, eenv * a, real_t * dst, real_t const * const src, int v ) 00335 { 00336 sz_t is = 0; 00337 for ( sz_t i = 0; i < res->data_size(); i += res->m_str[v-1], is += a->m_str[v-1] ) 00338 for ( sz_t j = 0; j < a->m_str[v]; j ++ ) 00339 upoldse::diff(dst+i+j,src+is+j,a->sz(v),a->m_str[v]); 00340 }; 00341 00342 template<typename real_t> 00343 static void monoms_derivative(eenv * res, eenv * a, real_t ** dst, real_t ** src, int v, int n = 1 ) 00344 { 00345 res->diff(a,v); 00346 for ( int c = 0; c < n; c ++ ) 00347 { 00348 dst[c] = new real_t[ res->data_size() ]; 00349 mdiff( res, a, dst[c], src[c], v ); 00350 }; 00351 }; 00352 00353 #include "bernstein_eenv_multiply.hpp" 00354 #include "bernstein_eenv_simplify.hpp" 00355 00356 template<typename real_t> 00357 bool print_monom( std::ostream& o, const real_t& c, sz_t * add, bool first ) 00358 { 00359 if ( c ) 00360 { 00361 if ( c < 0 ) o << "-"; 00362 else 00363 if ( ! first ) o << "+"; 00364 o << std::abs(c); 00365 for ( sz_t v = 0; v < nvars(); v ++ ) 00366 if ( add[var(v)] ) o << "*x" << var(v) << "^" << add[var(v)]; 00367 return true; 00368 }; 00369 return false; 00370 }; 00371 00372 template<typename real_t> 00373 void monoms_print( std::ostream& o, real_t * src ) 00374 { 00375 unsigned i; 00376 unsigned mcount = 0; 00377 int c; 00378 sz_t add[m_mxvr+1]; 00379 std::fill(add,add+m_mxvr+1,0); 00380 bool first = true; 00381 for ( i = 0; i < data_size(); i ++ ) 00382 { 00383 bool b = print_monom(o,src[i],add,first); 00384 if ( first && b ) first = false; 00385 mcount += b; 00386 c = nvars()-1; 00387 add[var(c)]++; 00388 while ( c >0 && (add[var(c)] == m_szs[c])) 00389 { 00390 add[var(c)] = 0; 00391 c--; 00392 add[var(c)]++; 00393 }; 00394 } 00395 if ( mcount == 0 ) o << "0"; 00396 }; 00397 00398 00399 00400 00401 template<typename real_t> 00402 static void elevation( eenv * out, eenv * in ) 00403 { 00404 00405 }; 00406 template<typename real_t> 00407 static void elevation( eenv * out, eenv * in, real_t * dst, real_t * src, bzenv< real_t > * bznv = bzenv<real_t>::_default_ ) 00408 { 00409 sz_t io = 0; 00410 sz_t v = 0; 00411 for ( sz_t i = 0; i < in->data_size(); i += in->m_str[v-1], io += out->m_str[v-1] ) 00412 for ( sz_t j = 0; j < in->m_str[v]; j ++ ) 00413 bznv->elevate( dst + io + j, src + i + j , in->m_szs[v], in->m_str[v], out->m_str[v], out->m_szs[v]-in->m_szs[v] ); 00414 }; 00415 00416 #include "bernstein_eenv_vrestrict.hpp" 00417 00418 }; 00419 00420 00421 inline std::ostream& operator<<( std::ostream& out, const eenv& env ) 00422 { 00423 out << "eenv:"; 00424 out << "\n\tszs = "; 00425 vctops::print(env_m.hpp_szs,env_m.hpp_nvr,1,out); 00426 out << "\n\tvrs = "; 00427 vctops::print(env_m.hpp_vrs,env_m.hpp_nvr,1,out); 00428 out << "\n"; 00429 out << "\n\ttsz = " << env.data_size() << std::endl; 00430 return out; 00431 }; 00432 }; 00433 //-------------------------------------------------------------------- 00434 } //namespace mmx 00435 /********************************************************************/ 00436 #endif //