00001
00002
00003
00004
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
00198
00199
00200 template< typename real_t >
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 >
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
00212 template< typename real_t >
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 >
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
00224
00225
00226
00227
00228
00229
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
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
00314
00315 for ( sz_t v = 0; v < m_nvr; v ++ )
00316 if ( m_vrs[v] == gv ) return v;
00317 return -1;
00318 };
00319
00320
00321
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 }
00435
00436 #endif //