00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include "factor.h"
00030
00032
00034
00035 namespace pcl
00036 {
00037 namespace poisson
00038 {
00039
00040
00041 template<int Degree>
00042 template<int Degree2>
00043 StartingPolynomial<Degree+Degree2> StartingPolynomial<Degree>::operator * (const StartingPolynomial<Degree2>& p) const{
00044 StartingPolynomial<Degree+Degree2> sp;
00045 if(start>p.start){sp.start=start;}
00046 else{sp.start=p.start;}
00047 sp.p=this->p*p.p;
00048 return sp;
00049 }
00050 template<int Degree>
00051 StartingPolynomial<Degree> StartingPolynomial<Degree>::scale(double s) const{
00052 StartingPolynomial q;
00053 q.start=start*s;
00054 q.p=p.scale(s);
00055 return q;
00056 }
00057 template<int Degree>
00058 StartingPolynomial<Degree> StartingPolynomial<Degree>::shift(double s) const{
00059 StartingPolynomial q;
00060 q.start=start+s;
00061 q.p=p.shift(s);
00062 return q;
00063 }
00064
00065
00066 template<int Degree>
00067 int StartingPolynomial<Degree>::operator < (const StartingPolynomial<Degree>& sp) const{
00068 if(start<sp.start){return 1;}
00069 else{return 0;}
00070 }
00071 template<int Degree>
00072 int StartingPolynomial<Degree>::Compare(const void* v1,const void* v2){
00073 double d=((StartingPolynomial*)(v1))->start-((StartingPolynomial*)(v2))->start;
00074 if (d<0) {return -1;}
00075 else if (d>0) {return 1;}
00076 else {return 0;}
00077 }
00078
00080
00082 template<int Degree>
00083 PPolynomial<Degree>::PPolynomial(void){
00084 polyCount=0;
00085 polys=NULL;
00086 }
00087 template<int Degree>
00088 PPolynomial<Degree>::PPolynomial(const PPolynomial<Degree>& p){
00089 polyCount=0;
00090 polys=NULL;
00091 set(p.polyCount);
00092 memcpy(polys,p.polys,sizeof(StartingPolynomial<Degree>)*p.polyCount);
00093 }
00094
00095 template<int Degree>
00096 PPolynomial<Degree>::~PPolynomial(void){
00097 if(polyCount){free(polys);}
00098 polyCount=0;
00099 polys=NULL;
00100 }
00101 template<int Degree>
00102 void PPolynomial<Degree>::set(StartingPolynomial<Degree>* sps,int count){
00103 int i,c=0;
00104 set(count);
00105 qsort(sps,count,sizeof(StartingPolynomial<Degree>),StartingPolynomial<Degree>::Compare);
00106 for( i=0 ; i<count ; i++ )
00107 {
00108 if( !c || sps[i].start!=polys[c-1].start ) polys[c++] = sps[i];
00109 else{polys[c-1].p+=sps[i].p;}
00110 }
00111 reset( c );
00112 }
00113 template <int Degree>
00114 int PPolynomial<Degree>::size(void) const{return int(sizeof(StartingPolynomial<Degree>)*polyCount);}
00115
00116 template<int Degree>
00117 void PPolynomial<Degree>::set( size_t size )
00118 {
00119 if(polyCount){free(polys);}
00120 polyCount=0;
00121 polys=NULL;
00122 polyCount=size;
00123 if(size){
00124 polys=(StartingPolynomial<Degree>*)malloc(sizeof(StartingPolynomial<Degree>)*size);
00125 memset(polys,0,sizeof(StartingPolynomial<Degree>)*size);
00126 }
00127 }
00128 template<int Degree>
00129 void PPolynomial<Degree>::reset( size_t newSize )
00130 {
00131 polyCount=newSize;
00132 polys=(StartingPolynomial<Degree>*)realloc(polys,sizeof(StartingPolynomial<Degree>)*newSize);
00133 }
00134
00135 template<int Degree>
00136 PPolynomial<Degree>& PPolynomial<Degree>::operator = (const PPolynomial<Degree>& p){
00137 set(p.polyCount);
00138 memcpy(polys,p.polys,sizeof(StartingPolynomial<Degree>)*p.polyCount);
00139 return *this;
00140 }
00141
00142 template<int Degree>
00143 template<int Degree2>
00144 PPolynomial<Degree>& PPolynomial<Degree>::operator = (const PPolynomial<Degree2>& p){
00145 set(p.polyCount);
00146 for(int i=0;i<int(polyCount);i++){
00147 polys[i].start=p.polys[i].start;
00148 polys[i].p=p.polys[i].p;
00149 }
00150 return *this;
00151 }
00152
00153 template<int Degree>
00154 double PPolynomial<Degree>::operator ()( double t ) const
00155 {
00156 double v=0;
00157 for( int i=0 ; i<int(polyCount) && t>polys[i].start ; i++ ) v+=polys[i].p(t);
00158 return v;
00159 }
00160
00161 template<int Degree>
00162 double PPolynomial<Degree>::integral( double tMin , double tMax ) const
00163 {
00164 int m=1;
00165 double start,end,s,v=0;
00166 start=tMin;
00167 end=tMax;
00168 if(tMin>tMax){
00169 m=-1;
00170 start=tMax;
00171 end=tMin;
00172 }
00173 for(int i=0;i<int(polyCount) && polys[i].start<end;i++){
00174 if(start<polys[i].start){s=polys[i].start;}
00175 else{s=start;}
00176 v+=polys[i].p.integral(s,end);
00177 }
00178 return v*m;
00179 }
00180 template<int Degree>
00181 double PPolynomial<Degree>::Integral(void) const{return integral(polys[0].start,polys[polyCount-1].start);}
00182 template<int Degree>
00183 PPolynomial<Degree> PPolynomial<Degree>::operator + (const PPolynomial<Degree>& p) const{
00184 PPolynomial q;
00185 int i,j;
00186 size_t idx=0;
00187 q.set(polyCount+p.polyCount);
00188 i=j=-1;
00189
00190 while(idx<q.polyCount){
00191 if (j>=int(p.polyCount)-1) {q.polys[idx]= polys[++i];}
00192 else if (i>=int( polyCount)-1) {q.polys[idx]=p.polys[++j];}
00193 else if(polys[i+1].start<p.polys[j+1].start){q.polys[idx]= polys[++i];}
00194 else {q.polys[idx]=p.polys[++j];}
00195 idx++;
00196 }
00197 return q;
00198 }
00199 template<int Degree>
00200 PPolynomial<Degree> PPolynomial<Degree>::operator - (const PPolynomial<Degree>& p) const{
00201 PPolynomial q;
00202 int i,j;
00203 size_t idx=0;
00204 q.set(polyCount+p.polyCount);
00205 i=j=-1;
00206
00207 while(idx<q.polyCount){
00208 if (j>=int(p.polyCount)-1) {q.polys[idx]= polys[++i];}
00209 else if (i>=int( polyCount)-1) {q.polys[idx].start=p.polys[++j].start;q.polys[idx].p=p.polys[j].p*(-1.0);}
00210 else if(polys[i+1].start<p.polys[j+1].start){q.polys[idx]= polys[++i];}
00211 else {q.polys[idx].start=p.polys[++j].start;q.polys[idx].p=p.polys[j].p*(-1.0);}
00212 idx++;
00213 }
00214 return q;
00215 }
00216 template<int Degree>
00217 PPolynomial<Degree>& PPolynomial<Degree>::addScaled(const PPolynomial<Degree>& p,double scale){
00218 int i,j;
00219 StartingPolynomial<Degree>* oldPolys=polys;
00220 size_t idx=0,cnt=0,oldPolyCount=polyCount;
00221 polyCount=0;
00222 polys=NULL;
00223 set(oldPolyCount+p.polyCount);
00224 i=j=-1;
00225 while(cnt<polyCount){
00226 if (j>=int( p.polyCount)-1) {polys[idx]=oldPolys[++i];}
00227 else if (i>=int(oldPolyCount)-1) {polys[idx].start= p.polys[++j].start;polys[idx].p=p.polys[j].p*scale;}
00228 else if (oldPolys[i+1].start<p.polys[j+1].start){polys[idx]=oldPolys[++i];}
00229 else {polys[idx].start= p.polys[++j].start;polys[idx].p=p.polys[j].p*scale;}
00230 if(idx && polys[idx].start==polys[idx-1].start) {polys[idx-1].p+=polys[idx].p;}
00231 else{idx++;}
00232 cnt++;
00233 }
00234 free(oldPolys);
00235 reset(idx);
00236 return *this;
00237 }
00238 template<int Degree>
00239 template<int Degree2>
00240 PPolynomial<Degree+Degree2> PPolynomial<Degree>::operator * (const PPolynomial<Degree2>& p) const{
00241 PPolynomial<Degree+Degree2> q;
00242 StartingPolynomial<Degree+Degree2> *sp;
00243 int i,j,spCount=int(polyCount*p.polyCount);
00244
00245 sp=(StartingPolynomial<Degree+Degree2>*)malloc(sizeof(StartingPolynomial<Degree+Degree2>)*spCount);
00246 for(i=0;i<int(polyCount);i++){
00247 for(j=0;j<int(p.polyCount);j++){
00248 sp[i*p.polyCount+j]=polys[i]*p.polys[j];
00249 }
00250 }
00251 q.set(sp,spCount);
00252 free(sp);
00253 return q;
00254 }
00255 template<int Degree>
00256 template<int Degree2>
00257 PPolynomial<Degree+Degree2> PPolynomial<Degree>::operator * (const Polynomial<Degree2>& p) const{
00258 PPolynomial<Degree+Degree2> q;
00259 q.set(polyCount);
00260 for(int i=0;i<int(polyCount);i++){
00261 q.polys[i].start=polys[i].start;
00262 q.polys[i].p=polys[i].p*p;
00263 }
00264 return q;
00265 }
00266 template<int Degree>
00267 PPolynomial<Degree> PPolynomial<Degree>::scale( double s ) const
00268 {
00269 PPolynomial q;
00270 q.set(polyCount);
00271 for(size_t i=0;i<polyCount;i++){q.polys[i]=polys[i].scale(s);}
00272 return q;
00273 }
00274 template<int Degree>
00275 PPolynomial<Degree> PPolynomial<Degree>::shift( double s ) const
00276 {
00277 PPolynomial q;
00278 q.set(polyCount);
00279 for(size_t i=0;i<polyCount;i++){q.polys[i]=polys[i].shift(s);}
00280 return q;
00281 }
00282 template<int Degree>
00283 PPolynomial<Degree-1> PPolynomial<Degree>::derivative(void) const{
00284 PPolynomial<Degree-1> q;
00285 q.set(polyCount);
00286 for(size_t i=0;i<polyCount;i++){
00287 q.polys[i].start=polys[i].start;
00288 q.polys[i].p=polys[i].p.derivative();
00289 }
00290 return q;
00291 }
00292 template<int Degree>
00293 PPolynomial<Degree+1> PPolynomial<Degree>::integral(void) const{
00294 int i;
00295 PPolynomial<Degree+1> q;
00296 q.set(polyCount);
00297 for(i=0;i<int(polyCount);i++){
00298 q.polys[i].start=polys[i].start;
00299 q.polys[i].p=polys[i].p.integral();
00300 q.polys[i].p-=q.polys[i].p(q.polys[i].start);
00301 }
00302 return q;
00303 }
00304 template<int Degree>
00305 PPolynomial<Degree>& PPolynomial<Degree>::operator += ( double s ) {polys[0].p+=s;}
00306 template<int Degree>
00307 PPolynomial<Degree>& PPolynomial<Degree>::operator -= ( double s ) {polys[0].p-=s;}
00308 template<int Degree>
00309 PPolynomial<Degree>& PPolynomial<Degree>::operator *= ( double s )
00310 {
00311 for(int i=0;i<int(polyCount);i++){polys[i].p*=s;}
00312 return *this;
00313 }
00314 template<int Degree>
00315 PPolynomial<Degree>& PPolynomial<Degree>::operator /= ( double s )
00316 {
00317 for(size_t i=0;i<polyCount;i++){polys[i].p/=s;}
00318 return *this;
00319 }
00320 template<int Degree>
00321 PPolynomial<Degree> PPolynomial<Degree>::operator + ( double s ) const
00322 {
00323 PPolynomial q=*this;
00324 q+=s;
00325 return q;
00326 }
00327 template<int Degree>
00328 PPolynomial<Degree> PPolynomial<Degree>::operator - ( double s ) const
00329 {
00330 PPolynomial q=*this;
00331 q-=s;
00332 return q;
00333 }
00334 template<int Degree>
00335 PPolynomial<Degree> PPolynomial<Degree>::operator * ( double s ) const
00336 {
00337 PPolynomial q=*this;
00338 q*=s;
00339 return q;
00340 }
00341 template<int Degree>
00342 PPolynomial<Degree> PPolynomial<Degree>::operator / ( double s ) const
00343 {
00344 PPolynomial q=*this;
00345 q/=s;
00346 return q;
00347 }
00348
00349 template<int Degree>
00350 void PPolynomial<Degree>::printnl(void) const{
00351 Polynomial<Degree> p;
00352
00353 if(!polyCount){
00354 Polynomial<Degree> p;
00355 printf("[-Infinity,Infinity]\n");
00356 }
00357 else{
00358 for(size_t i=0;i<polyCount;i++){
00359 printf("[");
00360 if (polys[i ].start== DBL_MAX){printf("Infinity,");}
00361 else if (polys[i ].start==-DBL_MAX){printf("-Infinity,");}
00362 else {printf("%f,",polys[i].start);}
00363 if(i+1==polyCount) {printf("Infinity]\t");}
00364 else if (polys[i+1].start== DBL_MAX){printf("Infinity]\t");}
00365 else if (polys[i+1].start==-DBL_MAX){printf("-Infinity]\t");}
00366 else {printf("%f]\t",polys[i+1].start);}
00367 p=p+polys[i].p;
00368 p.printnl();
00369 }
00370 }
00371 printf("\n");
00372 }
00373 template< >
00374 PPolynomial< 0 > PPolynomial< 0 >::BSpline( double radius )
00375 {
00376 PPolynomial q;
00377 q.set(2);
00378
00379 q.polys[0].start=-radius;
00380 q.polys[1].start= radius;
00381
00382 q.polys[0].p.coefficients[0]= 1.0;
00383 q.polys[1].p.coefficients[0]=-1.0;
00384 return q;
00385 }
00386 template< int Degree >
00387 PPolynomial< Degree > PPolynomial<Degree>::BSpline( double radius )
00388 {
00389 return PPolynomial< Degree-1 >::BSpline().MovingAverage( radius );
00390 }
00391 template<int Degree>
00392 PPolynomial<Degree+1> PPolynomial<Degree>::MovingAverage( double radius )
00393 {
00394 PPolynomial<Degree+1> A;
00395 Polynomial<Degree+1> p;
00396 StartingPolynomial<Degree+1>* sps;
00397
00398 sps=(StartingPolynomial<Degree+1>*)malloc(sizeof(StartingPolynomial<Degree+1>)*polyCount*2);
00399
00400 for(int i=0;i<int(polyCount);i++){
00401 sps[2*i ].start=polys[i].start-radius;
00402 sps[2*i+1].start=polys[i].start+radius;
00403 p=polys[i].p.integral()-polys[i].p.integral()(polys[i].start);
00404 sps[2*i ].p=p.shift(-radius);
00405 sps[2*i+1].p=p.shift( radius)*-1;
00406 }
00407 A.set(sps,int(polyCount*2));
00408 free(sps);
00409 return A*1.0/(2*radius);
00410 }
00411 template<int Degree>
00412 void PPolynomial<Degree>::getSolutions(double c,std::vector<double>& roots,double EPS,double min,double max) const{
00413 Polynomial<Degree> p;
00414 std::vector<double> tempRoots;
00415
00416 p.setZero();
00417 for(size_t i=0;i<polyCount;i++){
00418 p+=polys[i].p;
00419 if(polys[i].start>max){break;}
00420 if(i<polyCount-1 && polys[i+1].start<min){continue;}
00421 p.getSolutions(c,tempRoots,EPS);
00422 for(size_t j=0;j<tempRoots.size();j++){
00423 if(tempRoots[j]>polys[i].start && (i+1==polyCount || tempRoots[j]<=polys[i+1].start)){
00424 if(tempRoots[j]>min && tempRoots[j]<max){roots.push_back(tempRoots[j]);}
00425 }
00426 }
00427 }
00428 }
00429
00430 template<int Degree>
00431 void PPolynomial<Degree>::write(FILE* fp,int samples,double min,double max) const{
00432 fwrite(&samples,sizeof(int),1,fp);
00433 for(int i=0;i<samples;i++){
00434 double x=min+i*(max-min)/(samples-1);
00435 float v=(*this)(x);
00436 fwrite(&v,sizeof(float),1,fp);
00437 }
00438 }
00439
00440 }
00441 }