21 #include <tjutils/tjnumeric.h>
22 #include <odindata/data.h>
23 #include <odindata/linalg.h>
24 #include <odindata/utils.h>
27 #define DEFAULT_MAX_ITER 1000
28 #define DEFAULT_TOLERANCE 1e-4
56 return s << fp.
val <<
" +/- " << fp.
err;
107 static const Array<float,1> defaultArray;
142 virtual bool fit(
const Array<float,1>& yvals,
143 const Array<float,1>& ysigma=defaultArray,
144 const Array<float,1>& xvals=defaultArray,
145 unsigned int max_iterations=DEFAULT_MAX_ITER,
double tolerance=DEFAULT_TOLERANCE) = 0;
148 static const Array<float,1> defaultArray;
175 bool fit(
const Array<float,1>& yvals,
176 const Array<float,1>& ysigma=defaultArray,
177 const Array<float,1>& xvals=defaultArray,
178 unsigned int max_iterations=DEFAULT_MAX_ITER,
double tolerance=DEFAULT_TOLERANCE);
183 void print_state (
size_t iter);
185 GslData4Fit* gsldata;
294 void set_pars(
float alphaval,
float xmax,
float ymax);
317 template <
int N_rank>
332 bool fit(
const Array<float,1>& yvals,
333 const Array<float,1>& ysigma,
334 const Array<float,1>& xvals);
346 bool fit(
const Array<float,1>& yvals){
347 Array<float,1> ysigma(yvals.size());
349 return fit(yvals,ysigma);
356 Array<float,1>
get_function(
const Array<float,1>& xvals)
const;
361 template <
int N_rank>
365 for(
int i=0; i<npol; i++) a[i]=
fitpar();
367 int npts=yvals.size();
369 Array<float,1> sigma(npts);
370 if(
int(ysigma.size())==npts) sigma=ysigma;
373 Array<float,1> x(npts);
374 if(
int(xvals.size())==npts) x=xvals;
375 else for(
int ipt=0; ipt<npts; ipt++) x(ipt)=ipt;
378 Array<float,2> A(npts,npol);
379 Array<float,1> b(npts);
382 for(
int ipt=0; ipt<npts; ipt++) {
385 b(ipt)=weight*yvals(ipt);
387 for(
int ipol=0; ipol<npol; ipol++) {
388 A(ipt,ipol)=weight*pow(x(ipt),ipol);
394 for(
int ipol=0; ipol<npol; ipol++) a[ipol].val=coeff(ipol);
400 template <
int N_rank>
402 int npts=xvals.size();
403 Array<float,1> result(npts); result=0.0;
405 for(
int ipt=0; ipt<npts; ipt++) {
406 for(
int ipol=0; ipol<(N_rank+1); ipol++) {
407 result(ipt)+=a[ipol].val*pow(xvals(ipt),ipol);
441 bool fit(
const Array<float,1>& yvals,
442 const Array<float,1>& ysigma=defaultArray,
443 const Array<float,1>& xvals=defaultArray);
453 static const Array<float,1> defaultArray;
460 class GslData4DownhillSimplex;
493 GslData4DownhillSimplex* gsldata;
519 bool fit(
const Array<float,1>& yvals,
520 const Array<float,1>& ysigma=defaultArray,
521 const Array<float,1>& xvals=defaultArray,
522 unsigned int max_iterations=DEFAULT_MAX_ITER,
double tolerance=DEFAULT_TOLERANCE);
533 Array<float,1> yvals_cache;
534 Array<float,1> ysigma_cache;
535 Array<float,1> xvals_cache;
553 template <
int N_rank>
554 Array<float,N_rank>
polyniomial_fit(
const Array<float,N_rank>& value_map,
const Array<float,N_rank>& reliability_map,
555 unsigned int polynom_order,
float kernel_size,
bool only_zero_reliability=
false) {
562 ODINLOG(odinlog,errorLog) <<
"size mismatch (value_map.shape()=" << value_map.shape() <<
") != (reliability_map.shape()=" << reliability_map.shape() <<
")" << STD_endl;
566 if(min(reliability_map)<0.0) {
567 ODINLOG(odinlog,errorLog) <<
"reliability_map must be non-negative" << STD_endl;
571 int minsize=max(value_map.shape());
572 for(
int idim=0; idim<N_rank; idim++) {
573 int dimsize=value_map.shape()(idim);
574 if( (dimsize>1) && (dimsize<minsize) ) minsize=dimsize;
580 if((minsize-1)<int(polynom_order)) {
581 polynom_order=minsize-1;
582 ODINLOG(odinlog,warningLog) <<
"array size too small, restricting polynom_order to " << polynom_order << STD_endl;
585 TinyVector<int,N_rank> valshape(value_map.shape());
586 int nvals=value_map.numElements();
588 TinyVector<int,N_rank> polsize; polsize=polynom_order+1;
590 int npol=polarr.numElements();
592 if(pow(kernel_size,
float(N_rank))<
float(npol)) {
593 kernel_size=pow(
double(npol),
double(1.0/
float(N_rank)));
594 ODINLOG(odinlog,warningLog) <<
"kernel_size too small for polynome, increasing to " << kernel_size << STD_endl;
599 int neighb_pixel=int(kernel_size);
600 if(neighb_pixel<=0) neighb_pixel=1;
601 TinyVector<int,N_rank> neighbsize; neighbsize=2*neighb_pixel+1;
602 TinyVector<int,N_rank> neighboffset; neighboffset=-neighb_pixel;
604 int nneighb=neighbarr.numElements();
606 ODINLOG(odinlog,normalDebug) <<
"nvals/npol/nneighb=" << nvals <<
"/" << npol <<
"/" << nneighb << STD_endl;
609 ODINLOG(odinlog,warningLog) <<
"polynome order (" << npol <<
") larger than number of neighbours (" << nneighb <<
")" << STD_endl;
613 Array<float,2> A(npol,npol);
614 Array<float,1> c(npol);
615 Array<float,1> b(npol);
617 TinyVector<int,N_rank> valindex;
618 TinyVector<int,N_rank> neighbindex;
619 TinyVector<int,N_rank> currindex;
620 TinyVector<int,N_rank> diffindex;
621 TinyVector<int,N_rank> polindex;
622 TinyVector<int,N_rank> polindex_sum;
625 float relevant_radius=0.5*kernel_size*sqrt(
double(N_rank))+epsilon;
628 for(
int ival=0; ival<nvals; ival++) {
631 if( (!only_zero_reliability) || (reliability_map(valindex)<=0.0) ) {
636 int n_relevant_neighb_pixel=0;
640 for(
int ineighb=0; ineighb<nneighb; ineighb++) {
642 currindex=valindex+neighboffset+neighbindex;
644 bool valid_pixel=
true;
647 for(
int irank=0; irank<N_rank; irank++) {
648 if(currindex(irank)<0 || currindex(irank)>=valshape(irank)) valid_pixel=
false;
652 float reliability=0.0;
653 if(valid_pixel) reliability=reliability_map(currindex);
654 if(reliability<=0.0) valid_pixel=
false;
659 diffindex=currindex-valindex;
661 float radiussqr=sum(diffindex*diffindex);
662 float weight=reliability*exp(-2.0*radiussqr/(kernel_size*kernel_size));
665 if(sqrt(radiussqr)<=relevant_radius) n_relevant_neighb_pixel++;
668 for(
int ipol=0; ipol<npol; ipol++) {
670 float polproduct=1.0;
671 for(
int irank=0; irank<N_rank; irank++) polproduct*=pow(
float(diffindex(irank)),
float(polindex(irank)));
672 b(ipol)+=weight*value_map(currindex)*polproduct;
676 for(
int ipol=0; ipol<npol; ipol++) {
677 for(
int ipol_prime=0; ipol_prime<npol; ipol_prime++) {
679 float polproduct=1.0;
680 for(
int irank=0; irank<N_rank; irank++) polproduct*=pow(
float(diffindex(irank)),
float(polindex_sum(irank)));
681 A(ipol,ipol_prime)+=weight*polproduct;
691 if(n_relevant_neighb_pixel>=npol) {
693 result(valindex)=c(0);
696 }
else result(valindex)=value_map(valindex);
TinyVector< int, N_rank > create_index(unsigned long index) const
DownhillSimplex(MinimizationFunction &function)
bool get_minimum_parameters(fvector &result, const fvector &starting_point, const fvector &step_size, unsigned int max_iterations=DEFAULT_MAX_ITER, double tolerance=DEFAULT_TOLERANCE)
bool fit(const Array< float, 1 > &yvals, const Array< float, 1 > &ysigma=defaultArray, const Array< float, 1 > &xvals=defaultArray, unsigned int max_iterations=DEFAULT_MAX_ITER, double tolerance=DEFAULT_TOLERANCE)
bool init(ModelFunction &model_func, unsigned int nvals)
~FunctionFitDownhillSimplex()
bool fit(const Array< float, 1 > &yvals, const Array< float, 1 > &ysigma=defaultArray, const Array< float, 1 > &xvals=defaultArray, unsigned int max_iterations=DEFAULT_MAX_ITER, double tolerance=DEFAULT_TOLERANCE)
FunctionFitDownhillSimplex()
float evaluate(const fvector &pars) const
bool init(ModelFunction &model_func, unsigned int nvals)
unsigned int numof_fitpars() const
virtual bool init(ModelFunction &model_func, unsigned int nvals)=0
virtual bool fit(const Array< float, 1 > &yvals, const Array< float, 1 > &ysigma=defaultArray, const Array< float, 1 > &xvals=defaultArray, unsigned int max_iterations=DEFAULT_MAX_ITER, double tolerance=DEFAULT_TOLERANCE)=0
virtual unsigned int numof_fitpars() const =0
virtual fvector evaluate_df(float x) const =0
virtual fitpar & get_fitpar(unsigned int i)=0
virtual float evaluate_f(float x) const =0
Array< float, 1 > get_function(const Array< float, 1 > &xvals) const
Data< float, 1 > solve_linear(const Data< float, 2 > &A, const Data< float, 1 > &b, float sv_truncation=0.0)
Array< float, N_rank > polyniomial_fit(const Array< float, N_rank > &value_map, const Array< float, N_rank > &reliability_map, unsigned int polynom_order, float kernel_size, bool only_zero_reliability=false)
bool same_shape(const Array< T, N_rank > &a1, const Array< T, N_rank > &a2, const TinyVector< int, N_rank > &dimmask=1)
Array< float, 1 > get_function(const Array< float, 1 > &xvals) const
bool fit(const Array< float, 1 > &yvals, const Array< float, 1 > &ysigma, const Array< float, 1 > &xvals)
double secureInv(double denominator)
unsigned int numof_fitpars() const
fitpar & get_fitpar(unsigned int i)
float evaluate_f(float x) const
fvector evaluate_df(float x) const
float evaluate_f(float x) const
fitpar & get_fitpar(unsigned int i)
fvector evaluate_df(float x) const
unsigned int numof_fitpars() const
fitpar & get_fitpar(unsigned int i)
float evaluate_f(float x) const
void set_pars(float alphaval, float xmax, float ymax)
unsigned int numof_fitpars() const
fvector evaluate_df(float x) const
float evaluate_f(float x) const
fvector evaluate_df(float x) const
fitpar & get_fitpar(unsigned int i)
unsigned int numof_fitpars() const
bool fit(const Array< float, 1 > &yvals, const Array< float, 1 > &ysigma=defaultArray, const Array< float, 1 > &xvals=defaultArray)
Array< float, 1 > get_function(const Array< float, 1 > &xvals) const
unsigned int numof_fitpars() const
fvector evaluate_df(float x) const
fitpar & get_fitpar(unsigned int i)
float evaluate_f(float x) const
friend STD_ostream & operator<<(STD_ostream &s, const fitpar &fp)