00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00020 #include<ImLib3D/Normalization.hpp>
00021 #include<ImLib3D/Arithmetic.hpp>
00022 #include<ImLib3D/ImageStats.hpp>
00023 #include<ImLib3D/Signal1D.hpp>
00024
00025
00026 #include<ImLib3D/Display.hpp>
00027 Signal1Df
00028 JointHistogram::ConfidenceWeights() const
00029 {
00030 Signal1Df res(nbSrcBins,SrcVal(0),SrcVal(nbSrcBins));
00031 for(int i=0;i<nbSrcBins;i++){res[i]=GetSrcBinTotalProba(i);}
00032 return res;
00033 }
00034
00035 Signal1Df
00036 JointHistogram::SmoothAndExtend(const Signal1Df &src,const Signal1Df &weights,double smoothSigma,double outlierSigma)
00037 {
00038 Signal1Df res=src;
00039
00040
00041 for(int iter=0;iter<2;iter++)
00042 {
00043 double sigma;
00044 if(iter==0){sigma=smoothSigma*5;}
00045 if(iter==1){sigma=smoothSigma;}
00046
00047
00048
00049 for(int x=0;x<res.Size();x++)
00050 {
00051 double s=0;
00052 double totcoef=0;
00053 for(int x0=0;x0<res.Size()-1;x0++)
00054 {
00055 int x1=x0+1;
00056 if(x0<0 || x1>=res.Size()){continue;}
00057
00058 double dx=(x-.5*(x0+x1));
00059 double dy=src[x1]-src[x0];
00060 if(dy<0){continue;}
00061
00062 double w=min(weights[x0],weights[x1]);
00063
00064 double coef=exp(-dx*dx/(2*sigma*sigma));
00065 double predictedValue=dy*(float)(x-x0)/(float)(x1-x0) + src[x0];
00066
00067 double reweight=1;
00068 if(iter>0)
00069 {
00070 double error=predictedValue-res[x];
00071 reweight=exp(-error*error/(2*outlierSigma*outlierSigma));
00072 }
00073 double finalCoef=w*reweight*coef;
00074
00075 s+=finalCoef*predictedValue;
00076 totcoef+=finalCoef;
00077 }
00078
00079 res[x]=(totcoef>0 ? s/totcoef : 0);
00080 }
00081
00082 }
00083
00084
00085 float wmax=-1;
00086 int wxmax=-1;
00087 for(int x=0;x<weights.Size();x++){if(weights[x]>wmax){wmax=weights[x];wxmax=x;}}
00088
00089 for(int x=wxmax+1;x<weights.Size();x++){res[x]=max(res[x],res[x-1]);}
00090 for(int x=wxmax-1;x>=0 ;x--){res[x]=min(res[x],res[x+1]);}
00091
00092
00093 res.Smooth(2);
00094 res.Smooth(1);
00095
00096 return res;
00097 }
00098
00099 void
00100 IP3D::NormalizeAverage(const Image3Df& src,const Image3Df& ref,Image3Df& res)
00101 {
00102 double avRef,varRef;
00103 IP3D::AverageAndVariance(ref,avRef,varRef);
00104 double avSrc,varSrc;
00105 IP3D::AverageAndVariance(src,avSrc,varSrc);
00106 printf("src:%f\n",avSrc);
00107 res=src;
00108 res+=(avRef-avSrc);
00109 }
00110
00111 void
00112 IP3D::NormalizeAverageAndVariance(const Image3Df& src,const Image3Df& ref,Image3Df& res)
00113 {
00114 double avRef,varRef;
00115 IP3D::AverageAndVariance(ref,avRef,varRef);
00116 double avSrc,varSrc;
00117
00118 IP3D::AverageAndVariance(src,avSrc,varSrc);
00119 printf("src:%f %f\n",avSrc,varSrc);
00120 if(varSrc==0){fprintf(stderr,"WARNING: NormalizeAverageAndVariance: sourceimage variance is 0 (image is constant), just normalizing averge\n");varSrc=1;}
00121 res=src;
00122 res-=avSrc;
00123 res*=sqrt(varRef/varSrc);
00124 res+=avRef;
00125
00126 }
00127
00128
00129
00130
00131
00132 void
00133 JointHistogram::AddDisplayGrid()
00134 {
00135
00136 if(!histogramImage.HasMask()){histogramImage.AddMask();}
00137 histogramImage.Mask().Fill(0);
00138 double ddSrc=pow(10.0,floor(log10(srcMax-srcMin)));
00139 double ddRef=pow(10.0,floor(log10(refMax-refMin)));
00140 for(Mask3D::iteratorXYZ p=histogramImage.Mask().begin();p!=histogramImage.Mask().end();++p)
00141 {
00142 double xx=srcMin+p.x*(srcMax-srcMin)/(double)nbSrcBins;
00143 double yy=refMin+p.y*(refMax-refMin)/(double)nbRefBins;
00144 double xx1=srcMin+(p.x+1)*(srcMax-srcMin)/(double)nbSrcBins;
00145 double yy1=refMin+(p.y+1)*(refMax-refMin)/(double)nbRefBins;
00146 if(floor(xx/ddSrc)!=floor(xx1/ddSrc))
00147 {
00148 if(p.y==0){mprintf("grid x:%f\n",xx);}
00149 *p=1;
00150 }
00151 if(floor(yy/ddRef)!=floor(yy1/ddRef))
00152 {
00153 if(p.x==0){mprintf("grid y:%f\n",yy);}
00154 *p=1;
00155 }
00156 }
00157 }
00158
00159 float
00160 JointHistogram::GetSrcBinTotalProba(int x) const
00161 {
00162 float res=0;
00163 for(int y=0;y<nbRefBins;y++){res+=histogramImage(x,y,0);}
00164 return res;
00165 }
00167 Signal1Df
00168 JointHistogram::MedianTransferFct() const
00169 {
00170 Signal1Df res(nbSrcBins,SrcVal(0),SrcVal(nbSrcBins));
00171 for(int x=0;x<nbSrcBins;x++)
00172 {
00173 double tot=0;
00174 int y;
00175 double avg=0;
00176 for(y=0;y<nbRefBins;y++)
00177 {
00178 tot+=histogramImage(x,y,0);
00179 avg+=y*histogramImage(x,y,0);
00180 }
00181 printf("tot %d:%f\n",x,tot);
00182 avg/=tot;
00183 double sum=0;
00184 int ly=0;
00185 for(y=0;y<nbRefBins;y++)
00186 {
00187 sum+=histogramImage(x,y,0);
00188 if(sum>tot/1.9999999)
00189 {
00190 if(ly==y-1)
00191 {
00192 double ls=sum-histogramImage(x,y,0);
00193 double ymiddle=(y-ly)*(0.5-ls/tot)/(sum/tot-ls/tot)+ly;
00194 printf("tot:%f sum:%f y:%d ly:%d ls:%f ymiddle:%f(%f) avg:%f(%f)\n",tot,sum,y,ly,ls,ymiddle,RefVal(ymiddle),avg,RefVal(avg));
00195 res[x]=RefVal(ymiddle);
00196 }
00197 else
00198 {
00199 double ymiddle=(y+ly)/2.0;
00200 printf("tot:%f sum:%f y:%d ly:%d ymiddle:%f\n",tot,sum,y,ly,ymiddle);
00201 res[x]=RefVal(ymiddle);
00202 }
00203 break;
00204 }
00205 if(histogramImage(x,y,0)){ly=y;}
00206 }
00207 }
00208 return res;
00209 }
00210
00212 Signal1Df
00213 JointHistogram::MaximumProbabilityTransferFct() const
00214 {
00215 Signal1Df res(nbSrcBins,SrcVal(0),SrcVal(nbSrcBins));
00216 for(int x=0;x<nbSrcBins;x++)
00217 {
00218 Signal1Df proba0(nbRefBins,RefVal(0),RefVal(nbRefBins));
00219 for(int y=0;y<nbRefBins;y++)
00220 {
00221 proba0[y]=histogramImage(x,y,0);
00222 }
00223 int supersample=10;
00224 Signal1Df proba(nbRefBins*supersample,RefVal(0),RefVal(nbRefBins));
00225 for(int y=0;y<proba.Size();y++)
00226 {
00227 proba[y]=proba0(proba.ISampleToX(y));
00228 }
00229 proba.Smooth(2*supersample);
00230 proba.Smooth(2*supersample);
00231 proba.Smooth(2*supersample);
00232 double maxv=-1;
00233 int ymax=-1;
00234 for(int y=0;y<proba.Size();y++)
00235 {
00236 if(proba[y]>maxv){ymax=y;maxv=proba[y];}
00237 }
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249 {
00250 res[x]=proba.ISampleToX(ymax);
00251 }
00252 }
00253 return res;
00254 }
00255
00256
00257 void
00258 JointHistogram::ComputeFromIndependentSamples(const Image3Df &src,const Image3Df &ref)
00259 {
00260
00261 for(Image3Df::const_iteratorXYZ p=src.begin();p!=src.end();++p)
00262 {
00263 if(src.HasMask() && !src.Mask(p.Pos())){continue;}
00264 if(ref.HasMask() && !ref.Mask(p.Pos())){continue;}
00265 histogramImage(SSrcBin(*p),SRefBin(ref(p.Pos())),0)+=1;
00266 }
00267 }
00268 void
00269 JointHistogram::ComputeFromDirectionalLinearInterpolation(const Image3Df &src,const Image3Df &ref,int dir)
00270 {
00271
00272 Vect3Di srcSize=src.SizeV();
00273 int d0=(dir+1)%3;
00274 int d1=(dir+2)%3;
00275 int d2=dir;
00276
00277
00278 Vect3Di dpos(0,0,0);dpos(d2)=1;
00279 Vect3Di pos(0,0,0);
00280 for(int x0=0;x0<srcSize(d0);x0++)
00281 {
00282 pos(d0)=x0;
00283 for(int x1=0;x1<srcSize(d1);x1++)
00284 {
00285 pos(d1)=x1;
00286 for(int x2=0;x2<srcSize(d2)-1;x2++)
00287 {
00288 pos(d2)=x2;
00289 Vect3Di pos0=pos;
00290 Vect3Di pos1=pos+dpos;
00291
00292
00293
00294
00295 if( (src.HasMask() && ( !src.Mask(pos0) || !src.Mask(pos1))) ||
00296 (ref.HasMask() && ( !ref.Mask(pos0) || !ref.Mask(pos1))) ) {continue;}
00297 float src0=src(pos0);
00298 float ref0=ref(pos0);
00299 float src1=src(pos1);
00300 float ref1=ref(pos1);
00301
00302
00303
00304
00305 {
00306 Vect3Df p0(SrcBinF(src0),RefBinF(ref0),0);
00307 Vect3Df p1(SrcBinF(src1),RefBinF(ref1),0);
00308 Vect3Df dP=p1-p0;
00309 int dir=dP.MaxAbsCoord();
00310 bool incr=dP(dir)>0;
00311 dP/=fabs(dP(dir));
00312 int linesize=0;
00313 for(Vect3Df p=p0;(incr? p(dir)<p1(dir) : p(dir)>p1(dir));p+=dP)
00314 {
00315 linesize++;
00316 }
00317 for(Vect3Df p=p0;(incr? p(dir)<p1(dir) : p(dir)>p1(dir));p+=dP)
00318 {
00319 if(histogramImage.IsInside(rint(p))){histogramImage(rint(p))+=1.0/linesize;}
00320 }
00321 }
00322 }
00323 }
00324 }
00325 }
00326
00327 JointHistogram::JointHistogram(const string &filename):
00328 histogramImage(filename)
00329 {
00330 nbSrcBins=histogramImage.Property<int>("nbSrcBins");
00331 nbRefBins=histogramImage.Property<int>("nbRefBins");
00332 srcMin=histogramImage.Property<double>("srcMin");
00333 srcMax=histogramImage.Property<double>("srcMax");
00334 refMin=histogramImage.Property<double>("refMin");
00335 refMax=histogramImage.Property<double>("refMax");
00336 printf("nbSrcBins:%d nbRefBins:%d srcMin:%f srcMax:%f refMin:%f refMax:%f\n",
00337 nbSrcBins, nbRefBins, srcMin, srcMax, refMin, refMax);
00338 }
00339 JointHistogram::JointHistogram(const Image3Df &src,const Image3Df &ref,int _nbSrcBins,int _nbRefBins):
00340 nbSrcBins(_nbSrcBins),nbRefBins(_nbRefBins),histogramImage(_nbSrcBins,_nbRefBins,1)
00341 {
00342 histogramImage.Fill(0);
00343
00344 FindRanges(src,ref);
00345
00346
00347 ComputeFromDirectionalLinearInterpolation(src,ref,0);
00348 ComputeFromDirectionalLinearInterpolation(src,ref,1);
00349 ComputeFromDirectionalLinearInterpolation(src,ref,2);
00350 histogramImage*=1/3.0;
00351 }
00352
00353 void
00354 JointHistogram::FindRanges(const Image3Df& src, const Image3Df &ref)
00355 {
00356 vector<float> srcValues;
00357 vector<float> refValues;
00358 srcValues.reserve(src.GetNVoxels());
00359 refValues.reserve(ref.GetNVoxels());
00360 for(Image3Df::const_iteratorXYZ p=src.begin();p!=src.end();++p)
00361 {
00362 if(src.HasMask() && !src.Mask(p.Pos())){continue;}
00363 if(ref.HasMask() && !ref.Mask(p.Pos())){continue;}
00364 srcValues.push_back(*p);
00365 refValues.push_back(ref(p.Pos()));
00366 }
00367
00368
00369
00370
00371 vector<float>::iterator pnth;
00372 pnth=srcValues.begin()+(size_t)floor(.005*srcValues.size());
00373 nth_element(srcValues.begin(),pnth,srcValues.end());
00374 srcMin=*pnth;
00375 pnth=srcValues.begin()+min(srcValues.size()-1,(size_t)ceil(.995*srcValues.size()));
00376 nth_element(srcValues.begin(),pnth,srcValues.end());
00377 srcMax=*pnth;
00378 float d=srcMax-srcMin;
00379 srcMin-=d*.3;
00380 srcMax+=d*.3;
00381
00382 pnth=refValues.begin()+(size_t)floor(.005*refValues.size());
00383 nth_element(refValues.begin(),pnth,refValues.end());
00384 refMin=*pnth;
00385 pnth=refValues.begin()+min(refValues.size()-1,(size_t)ceil(.995*refValues.size()));
00386 nth_element(refValues.begin(),pnth,refValues.end());
00387 refMax=*pnth;
00388 d=refMax-refMin;
00389 refMin-=d*.6;
00390 refMax+=d*.6;
00391
00392 histogramImage.AddProperty("srcMin",srcMin);
00393 histogramImage.AddProperty("srcMax",srcMax);
00394 histogramImage.AddProperty("refMin",refMin);
00395 histogramImage.AddProperty("refMax",refMax);
00396 histogramImage.AddProperty("nbSrcBins",nbSrcBins);
00397 histogramImage.AddProperty("nbRefBins",nbRefBins);
00398
00399 histogramImage.AddSupport(Vect3Df(srcMin,refMin,0),Vect3Df(srcMax,refMax,1));
00400 mprintf("JointHistogram srcMin:%f srcMax:%f refMin:%f refMax:%f\n",srcMin,srcMax,refMin,refMax);
00401 }
00402
00403
00404
00405 void
00406 IP3D::NormalizeJointHistogram(const Image3Df& src0,const Image3Df& ref,Image3Df& res,int nbSrcBins,int nbRefBins)
00407 {
00408 Image3Df src;
00409 IP3D::NormalizeAverageAndVariance(src0,ref,src);
00410
00411 JointHistogram joint(src,ref,nbSrcBins,nbRefBins);
00412
00413 Signal1Df transferFct=JointHistogram::SmoothAndExtend(joint.MaximumProbabilityTransferFct(),
00414 joint.ConfidenceWeights(),
00415 joint.nbSrcBins/50.0,
00416 (joint.refMax-joint.refMin)/25);
00417
00418
00419
00420 res=src;
00421 for(Image3Df::iteratorFast p=res.begin();p!=res.end();++p)
00422 {
00423 *p=transferFct(*p);
00424 }
00425 }
00426
00427
00428
00429
00430 void
00431 IP3D::ComputeJointHistogramImage(const Image3Df& src0,const Image3Df& ref,Image3Df& res,int drawTransferFunction,int nbSrcBins,int nbRefBins)
00432 {
00433 Image3Df src;
00434 IP3D::NormalizeAverageAndVariance(src0,ref,src);
00435 JointHistogram joint(src,ref,nbSrcBins,nbRefBins);
00436
00437 Signal1Df transferFct;
00438 if(drawTransferFunction==1)
00439 {
00440 transferFct=joint.BestFitTransferFct();
00441 }
00442 if(drawTransferFunction==2)
00443 {
00444 transferFct=JointHistogram::SmoothAndExtend(joint.MaximumProbabilityTransferFct(),
00445 joint.ConfidenceWeights(),
00446 joint.nbSrcBins/50.0,
00447 (joint.refMax-joint.refMin)/25);
00448 }
00449 if(drawTransferFunction>0)
00450 {
00451 for(int x=0;x<joint.histogramImage.Width();x++)
00452 {
00453 joint.histogramImage(x,joint.SRefBin(transferFct(joint.SrcVal(x))),0)=-10;
00454 }
00455 }
00456 res=joint.histogramImage;
00457 }
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472 #include<gsl/gsl_multimin.h>
00473
00474 class IntensityTransferFctFitter
00475 {
00476 const JointHistogram &joint;
00477 double smoothingCoef,decreasingCoef;
00478 Signal1Df central;
00479 Signal1Df confidenceWeights;
00480 double totalWeight;
00481 double refImageVariance;
00482 public:
00483 void SetDecreasingCoef(double _decreasingCoef){decreasingCoef=_decreasingCoef;}
00484
00485 float TransferFctValue(const vector<double> &values,int xpos)
00486 {
00487
00488 float pos=values.size()*xpos/(float)joint.nbSrcBins;
00489 int p0=min((int)values.size()-2,max(0,(int)floor(pos)));
00490 int p1=p0+1;
00491 return (pos-p0)*values[p1]+(p1-pos)*values[p0];
00492 }
00493 void Filter(const vector<double> &src,const vector<double> &filter,vector<double> &res)
00494 {
00495 if((filter.size()%2)==0){ThrowError("filter size must bue unpair");}
00496 res.resize(src.size());
00497 for(uint i=0;i<src.size();i++)
00498 {
00499 int center=(filter.size()-1)/2;
00500
00501 int jmin=max(center-(int)i,0);
00502
00503 int jmax=min(((int)src.size())-1+center-(int)i,(int)filter.size()-1);
00504 double total=0;
00505 double totalc=0;
00506 for(int j=jmin;j<=jmax;j++)
00507 {
00508 total+=filter[j]*src[i+j-center];
00509 totalc+=filter[j];
00510 }
00511 res[i]=total/totalc;
00512 }
00513 }
00514
00515 double TotalError(const vector<double> &values)
00516 {
00517 bool talk=false;
00518
00519 vector<double> splineYPos(joint.nbSrcBins);
00520 for(int x=0;x<joint.nbSrcBins;x++)
00521 {
00522 splineYPos[x]=TransferFctValue(values,x);
00523 }
00524
00525 double errorJointHistogram=0;
00526 vector<float> debugDisplayImageError;
00527 for(int x=0;x<joint.nbSrcBins;x++)
00528 {
00529 double d=joint.RefVal(splineYPos[x])-central[x];
00530 errorJointHistogram+=confidenceWeights[x]*(d*d);
00531 if(talk){debugDisplayImageError.push_back(confidenceWeights[x]*(d*d));}
00532 }
00533 if(talk){GnuPlot(debugDisplayImageError,"image error");}
00534 errorJointHistogram/=refImageVariance*totalWeight;
00535
00536 double errorSmoothness=0;
00537 {
00538
00539
00540 vector<double> secondDeriv(values.size()-2);
00541 for(uint i=1;i<values.size()-1;i++)
00542 {
00543 secondDeriv[i-1]=values[i+1]-2*values[i]+values[i-1];
00544 }
00545
00546 vector<double> smoothed0;
00547 {
00548 double filter00[] = {1,3,4,3,1};
00549 vector<double> filter0(filter00, filter00+sizeof(filter00)/sizeof(double));
00550 Filter(secondDeriv,filter0,smoothed0);
00551 }
00552
00553 vector<double> smoothed1;
00554 {
00555 double filter10[] = {1,2,3,4,5,6,5,4,3,2,1};
00556 vector<double> filter1(filter10, filter10+sizeof(filter10)/sizeof(double));
00557 Filter(secondDeriv,filter1,smoothed1);
00558 }
00559
00560 if(talk)
00561 {
00562 GnuPlot(values,"transfer function values");
00563 GnuPlot(secondDeriv,"secondDeriv");
00564 GnuPlot(smoothed0,"smoothed0");
00565 GnuPlot(smoothed1,"smoothed1");
00566 printf("print\n");
00567 }
00568
00569
00570
00571 for(uint i=0;i<secondDeriv.size();i++)
00572 {
00573 errorSmoothness+=
00574
00575 smoothed0 [i]*smoothed0[i]+
00576 smoothed1 [i]*smoothed1[i]*.2;
00577
00578 }
00579 }
00580 errorSmoothness*=40.0/(double)(joint.nbRefBins*joint.nbRefBins*values.size());
00581
00582 double errorDecreasing=0;
00583 for(uint i=0;i<values.size()-1;i++)
00584 {
00585 errorDecreasing+=max(0.0,-(values[i+1]-values[i]));
00586 }
00587 errorDecreasing*=.0001;
00588 return errorJointHistogram+smoothingCoef*errorSmoothness+decreasingCoef*errorDecreasing;
00589 }
00590
00591 IntensityTransferFctFitter(const JointHistogram &_joint,double _smoothingCoef=1,double _decreasingCoef=0):
00592 joint(_joint),
00593 smoothingCoef(_smoothingCoef),
00594 decreasingCoef(_decreasingCoef)
00595 {
00596 central=joint.MaximumProbabilityTransferFct();
00597 confidenceWeights=joint.ConfidenceWeights();
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610 refImageVariance=0;
00611 totalWeight=0;
00612 double refImageAverage=0;
00613 for(Image3Df::const_iteratorXYZ p=joint.histogramImage.begin();p!=joint.histogramImage.end();++p)
00614 {
00615 totalWeight+=*p;
00616 refImageVariance+=(*p)*joint.RefVal(p.y)*joint.RefVal(p.y);
00617 refImageAverage+=(*p)*joint.RefVal(p.y);
00618 }
00619 refImageAverage/=totalWeight;
00620 refImageVariance=(refImageVariance/totalWeight)-refImageAverage;
00621 printf("refImageAverage:%f refImageVariance:%f stddev:%f\n",refImageAverage,refImageVariance,sqrt(refImageVariance));
00622 }
00623
00624 };
00625 vector<double>
00626 MakeSTLVector(const gsl_vector *v)
00627 {
00628 vector<double> values(v->size);
00629 for(uint i=0;i<values.size();i++){values[i]=gsl_vector_get(v, i);}
00630 return values;
00631 }
00632 gsl_vector *
00633 MakeGSLVector(const vector<double> &src)
00634 {
00635 gsl_vector *res = gsl_vector_alloc (src.size());
00636 for(uint i=0;i<src.size();i++)
00637 {
00638 gsl_vector_set (res, i, src[i]);
00639 }
00640 return res;
00641 }
00642
00643 double
00644 GSLMinimizationFunction (const gsl_vector *v, void *params)
00645 {
00646 return ((IntensityTransferFctFitter *)params)->TotalError(MakeSTLVector(v));
00647 }
00648
00649 int
00650 FitIntensityTransferFctUsingGSLMinimization(IntensityTransferFctFitter &intensityTransferFctFitter,vector<double> &values0)
00651 {
00652 gsl_vector *values=MakeGSLVector(values0);
00653
00654
00655 gsl_vector *ss;
00656 ss = gsl_vector_alloc (values->size);
00657 gsl_vector_set_all (ss, 1.0);
00658
00659
00660
00661 gsl_multimin_function minex_func;
00662 {
00663 minex_func.f = &GSLMinimizationFunction;
00664 minex_func.n = values->size;
00665 minex_func.params = (void *)&intensityTransferFctFitter;
00666 }
00667
00668
00669 gsl_multimin_fminimizer *minimizer =
00670 minimizer = gsl_multimin_fminimizer_alloc (gsl_multimin_fminimizer_nmsimplex, values->size);
00671 gsl_multimin_fminimizer_set (minimizer, &minex_func, values, ss);
00672
00673
00674
00675 int rval = GSL_CONTINUE;
00676 int status = GSL_SUCCESS;
00677 double ssval;
00678 size_t iter = 0;
00679 while (rval == GSL_CONTINUE)
00680 {
00681 iter++;
00682 status = gsl_multimin_fminimizer_iterate(minimizer);
00683
00684 if (status)
00685 break;
00686
00687 rval = gsl_multimin_test_size (gsl_multimin_fminimizer_size (minimizer),
00688 1e-2);
00689 ssval = gsl_multimin_fminimizer_size (minimizer);
00690
00691 if (rval == GSL_SUCCESS)
00692 {
00693 printf ("converged to minimum at\n");
00694
00695 printf("iter %4d : ", iter);
00696 for (uint i = 0; i < values->size; i++)
00697 {
00698 printf ("%5.2f ", gsl_vector_get (minimizer->x, i));
00699 }
00700 printf("f() = %-10.10f ssize = %.3f\n", minimizer->fval, ssval);
00701 }
00702 }
00703
00704 values0=MakeSTLVector(minimizer->x);
00705 gsl_vector_free(values);
00706 gsl_vector_free(ss);
00707 gsl_multimin_fminimizer_free (minimizer);
00708 return status;
00709 }
00710
00711 Signal1Df
00712 JointHistogram::BestFitTransferFct(double smoothingCoef,bool allowDecreasing) const
00713 {
00714 IntensityTransferFctFitter intensityTransferFctFitter(*this);
00715
00716
00717 vector<double> values(40);
00718 for(uint i=0;i<values.size();i++)
00719 {
00720 values[i]=(nbRefBins*i)/(float)values.size();
00721 }
00722
00723
00724 for(double decreasingCoef=.0001;decreasingCoef<1000000;decreasingCoef*=4)
00725 {
00726 if(!allowDecreasing){intensityTransferFctFitter.SetDecreasingCoef(decreasingCoef);}
00727 FitIntensityTransferFctUsingGSLMinimization(intensityTransferFctFitter,values);
00728
00729 bool decreasing=false;
00730 for(uint i=0;i<values.size()-1;i++)
00731 {
00732 if(values[i+1]<values[i]){decreasing=true;break;}
00733 }
00734 if(allowDecreasing || !decreasing){break;}
00735 }
00736
00737 Signal1Df res(nbSrcBins,SrcVal(0),SrcVal(nbSrcBins));
00738 for(int i=0;i<res.Size();i++)
00739 {
00740 res[i]=RefVal(intensityTransferFctFitter.TransferFctValue(values,i));
00741 }
00742 return res;
00743 }