00001
00002
00003
00004
00005
00006 #ifndef realroot_SOLVE_SBDSLV_PARALLEL_HPP
00007 #define realroot_SOLVE_SBDSLV_PARALLEL_HPP
00008
00009
00010
00011 namespace mmx {
00012
00013 namespace realroot
00014 {
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 namespace rdslv
00027 {
00028 template< class system >
00029 struct parallel : system::vstack_t
00030 {
00031 typedef typename system::creal_t creal_t;
00032 typedef typename system::interval_t interval_t;
00033 typedef typename system::vstack_t vstack_t;
00034 typedef typename vstack_t::sz_t sz_t;
00035
00036
00037 sz_t pinc ( sz_t iptr )
00038 {
00039 assert(iptr%4 == 0);
00040 sz_t i,s;
00041 for ( s = i = 0; i < 4*this->nbp(); s += this->pmsz(iptr+i)+this->pMsz(iptr+i), i += 4 ) ;
00042 s = this->allocc(s+2)+2;
00043 sz_t inext = this->alloci(this->nbp()*4);
00044 for ( i = 0; i < 4*this->nbp(); s += this->pmsz(iptr+i)+this->pMsz(iptr+i), i += 4 )
00045 {
00046 this->pmsz(inext+i) = this->pmsz(iptr+i);
00047 this->pmad(inext+i) = s;
00048 this->pMad(inext+i) = s + this->pmsz(iptr+i);
00049 this->pMsz(inext+i) = this->pMsz(iptr+i);
00050 };
00051 return inext;
00052 };
00053
00054 sz_t pdec( sz_t iptr )
00055 {
00056 sz_t s,i;
00057 for ( s = i = 0; i < 4*this->m_nbp; s += this->pmsz(iptr+i)+this->pMsz(iptr+i), i += 4 ) ;
00058 this->m_cpchnk.dec( s + 2 );
00059 this->m_ipchnk.dec(4*this->nbp());
00060 iptr = iptr - 4*this->nbp();
00061 return iptr;
00062 };
00063
00064
00065 bool process( std::vector<interval_t>& reductions, const vstack_t& vp, const creal_t& eps = 1e-3, int k = 12 )
00066 {
00067 this->copy(vp);
00068 sz_t iptr, inext, mxsgn, sgn, i, nmult;
00069 int itk = 0;
00070 nmult = iptr = 0;
00071
00072 for ( ; itk >= 0; )
00073 {
00074 sgn = mxsgn = 0;
00075
00076
00077 for ( mxsgn = i = 0; i < 4*this->nbp(); i += 4 )
00078 {
00079 if ( this->pmsz(iptr+i) && !(sgn = vctops::sgnchg( this->pmdata(iptr+i),this->pmsz(iptr+i))) )
00080 {
00081 this->pmsz(iptr+i) = 0;
00082 if ( * this->pmdata(iptr+i) > 0.0 ) break;
00083 };
00084 if ( mxsgn < sgn ) mxsgn = sgn;
00085 };
00086 if ( i < 4*this->nbp() ) { iptr = pdec(iptr); itk --; continue; };
00087
00088
00089 for ( i = 0; i < 4*this->nbp(); i += 4 )
00090 {
00091 if ( this->pMsz(iptr+i) && !(sgn = vctops::sgnchg( this->pMdata(iptr+i), this->pMsz(iptr+i))) )
00092 {
00093 this->pMsz(iptr+i) = 0;
00094 if ( * this->pMdata(iptr+i) < 0.0 ) break;
00095 };
00096 if ( mxsgn < sgn ) mxsgn = sgn;
00097 };
00098 if ( i < 4*this->nbp() ) { iptr = pdec(iptr); itk --; continue; };
00099
00100
00101 if ( !mxsgn || (this->pupper(iptr)-this->plower(iptr)) < eps )
00102 {
00103 if ( reductions.size() == 0 || reductions.back().upper() != this->plower(iptr) )
00104 reductions.push_back(interval_t(this->plower(iptr),this->pupper(iptr)));
00105 else
00106 reductions.back().define(reductions.back().lower(),this->pupper( iptr ));
00107 iptr = pdec( iptr ); itk --;
00108 continue;
00109 };
00110
00111
00112 inext = pinc(iptr);
00113
00114
00115
00116 {
00117 numerics::rounding<creal_t> rnd( numerics::rnd_dw() );
00118 for ( i = 0; i < 4*this->nbp(); i += 4 )
00119 if ( this->pmsz(iptr+i) )
00120 {
00121 nmult += this->pmsz(iptr+i)*(this->pmsz(iptr+i)-1);
00122 brnops::decasteljau(this->pmdata(iptr+i),this->pmdata(inext+i),this->pmsz(iptr+i));
00123
00124 };
00125 };
00126
00127
00128 {
00129 numerics::rounding<creal_t> rnd( numerics::rnd_up() );
00130 for ( i = 0; i < 4*this->nbp(); i += 4 )
00131 if ( this->pMsz(iptr+i) )
00132 {
00133 nmult += this->pMsz(iptr+i)*(this->pMsz(iptr+i)-1);
00134 brnops::decasteljau(this->pMdata(iptr+i),this->pMdata(inext+i),this->pMsz(iptr+i) );
00135
00136 };
00137 };
00138
00139
00140
00141
00142
00143
00144
00145 this->plower(inext) = this->plower(iptr);
00146 this->pupper(inext) = (this->plower(iptr)+this->pupper(iptr))/2;
00147 this->plower(iptr) = this->pupper(inext);
00148 iptr = inext;
00149 itk ++;
00150 };
00151
00152 return reductions.size() != 0;
00153 assert(k>0);
00154 }
00155
00156 };
00157 }
00158 }
00159
00160 }
00161
00162 #endif //