50 #include <visp/vpDebug.h>
51 #include <visp/vpColVector.h>
52 #include <visp/vpMath.h>
54 #include <visp/vpRobust.h>
74 vpCDEBUG(2) <<
"vpRobust constructor reached" << std::endl;
78 sorted_normres.
resize(n_data);
79 sorted_residues.
resize(n_data);
81 NoiseThreshold=0.0017;
94 sorted_normres.
resize(n_data);
95 sorted_residues.
resize(n_data);
148 unsigned int n_data = residues.
getRows();
151 sorted_residues = residues;
153 unsigned int ind_med = (
unsigned int)(ceil(n_data/2.0))-1;
156 med = select(sorted_residues, 0, n_data-1, ind_med);
160 for(
unsigned int i=0; i<n_data; i++)
162 normres[i] = (fabs(residues[i]- med));
163 sorted_normres[i] = (fabs(sorted_residues[i]- med));
168 normmedian = select(sorted_normres, 0, n_data-1, ind_med);
171 sigma = 1.4826*normmedian;
175 if(sigma < NoiseThreshold)
177 sigma= NoiseThreshold;
184 psiTukey(sigma, normres,weights);
186 vpCDEBUG(2) <<
"Tukey's function computed" << std::endl;
192 psiCauchy(sigma, normres,weights);
202 psiHuber(sigma, normres,weights);
220 unsigned int n_all_data = all_residues.
getRows();
224 normmedian = computeNormalizedMedian(all_normres,residues,all_residues,weights);
228 sigma = 1.4826*normmedian;
232 if(sigma < NoiseThreshold)
234 sigma= NoiseThreshold;
242 psiTukey(sigma, all_normres,weights);
244 vpCDEBUG(2) <<
"Tukey's function computed" << std::endl;
250 psiCauchy(sigma, all_normres,weights);
260 psiHuber(sigma, all_normres,weights);
270 double vpRobust::computeNormalizedMedian(
vpColVector &all_normres,
279 unsigned int n_all_data = all_residues.
getRows();
280 unsigned int n_data = residues.
getRows();
285 sorted_residues = residues;
287 no_null_weight_residues.
resize(n_data);
295 unsigned int index =0;
296 for(
unsigned int j=0;j<n_data;j++)
299 if(std::fabs(weights[j]) > std::numeric_limits<double>::epsilon())
301 no_null_weight_residues[index]=residues[j];
305 sorted_residues.
resize(index);
306 memcpy(sorted_residues.
data,no_null_weight_residues.
data,index*
sizeof(
double));
309 vpCDEBUG(2) <<
"vpRobust MEstimator reached. No. data = " << n_data
316 unsigned int ind_med = (
unsigned int)(ceil(n_data/2.0))-1;
317 med = select(sorted_residues, 0, n_data-1, ind_med);
321 for(i=0; i<n_all_data; i++)
323 all_normres[i] = (fabs(all_residues[i]- med));
326 for(i=0; i<n_data; i++)
328 sorted_normres[i] = (fabs(sorted_residues[i]- med));
334 normmedian = select(sorted_normres, 0, n_data-1, ind_med);
356 unsigned int n_data = residues.
getRows();
360 vpCDEBUG(2) <<
"vpRobust MEstimator reached. No. data = " << n_data
364 unsigned int ind_med = (
unsigned int)(ceil(n_data/2.0))-1;
365 med = select(residues, 0, n_data-1, ind_med);
368 for(
unsigned int i=0; i<n_data; i++)
369 normres[i] = (fabs(residues[i]- med));
376 normmedian = select(normres, 0, n_data-1, ind_med);
378 sigma = 1.4826*normmedian;
383 sigma = simultscale(residues);
388 if(sigma < NoiseThreshold)
390 sigma= NoiseThreshold;
394 vpCDEBUG(2) <<
"MAD and C computed" << std::endl;
396 psiHuber(sigma, normres,w);
404 vpRobust::scale(vpRobustEstimatorType method,
vpColVector &x)
409 double Expectation=0;
413 for(
unsigned int i=0; i<n; i++)
416 chiTmp = constrainedChi(method, x[i]);
417 Expectation += chiTmp*(1-erf(chiTmp));
421 #if VP_DEBUG_MODE == 3
423 std::cout <<
"erf = " << 1-erf(chiTmp) << std::endl;
424 std::cout <<
"x[i] = " << x[i] <<std::endl;
425 std::cout <<
"chi = " << chiTmp << std::endl;
426 std::cout <<
"Sum chi = " << chiTmp*
vpMath::sqr(sig_prev) << std::endl;
427 std::cout <<
"Expectation = " << chiTmp*(1-erf(chiTmp)) << std::endl;
435 sigma2 = Sum_chi*
vpMath::sqr(sig_prev)/((n-p)*Expectation);
438 #if VP_DEBUG_MODE == 3
440 std::cout <<
"Expectation = " << Expectation << std::endl;
441 std::cout <<
"Sum chi = " << Sum_chi << std::endl;
442 std::cout <<
"sig_prev" << sig_prev << std::endl;
443 std::cout <<
"sig_out" << sqrt(fabs(sigma2)) << std::endl;
448 return sqrt(fabs(sigma2));
459 double Expectation=0;
463 for(
unsigned int i=0; i<n; i++)
466 chiTmp = simult_chi_huber(x[i]);
467 Expectation += chiTmp*(1-erf(chiTmp));
471 #if VP_DEBUG_MODE == 3
473 std::cout <<
"erf = " << 1-erf(chiTmp) << std::endl;
474 std::cout <<
"x[i] = " << x[i] <<std::endl;
475 std::cout <<
"chi = " << chiTmp << std::endl;
476 std::cout <<
"Sum chi = " << chiTmp*
vpMath::sqr(sig_prev) << std::endl;
477 std::cout <<
"Expectation = " << chiTmp*(1-erf(chiTmp)) << std::endl;
485 sigma2 = Sum_chi*
vpMath::sqr(sig_prev)/((n-p)*Expectation);
488 #if VP_DEBUG_MODE == 3
490 std::cout <<
"Expectation = " << Expectation << std::endl;
491 std::cout <<
"Sum chi = " << Sum_chi << std::endl;
492 std::cout <<
"sig_prev" << sig_prev << std::endl;
493 std::cout <<
"sig_out" << sqrt(fabs(sigma2)) << std::endl;
498 return sqrt(fabs(sigma2));
503 vpRobust::constrainedChi(vpRobustEstimatorType method,
double x)
508 return constrainedChiTukey(x);
510 return constrainedChiCauchy(x);
512 return constrainedChiHuber(x);
521 vpRobust::constrainedChiTukey(
double x)
528 if(fabs(x) <= 4.7*sig_prev)
541 vpRobust::constrainedChiCauchy(
double x)
554 vpRobust::constrainedChiHuber(
double x)
557 double u = x/sig_prev;
569 vpRobust::simult_chi_huber(
double x)
572 double u = x/sig_prev;
600 unsigned int n_data = x.
getRows();
601 double cst_const = vpCST*4.6851;
603 for(
unsigned int i=0; i<n_data; i++)
606 if(std::fabs(sig) <= std::numeric_limits<double>::epsilon() && std::fabs(weights[i]) > std::numeric_limits<double>::epsilon())
612 double xi_sig = x[i]/sig;
615 if((std::fabs(xi_sig)<=(cst_const)) && std::fabs(weights[i]) > std::numeric_limits<double>::epsilon())
638 unsigned int n_data = x.
getRows();
640 for(
unsigned int i=0; i<n_data; i++)
643 if(std::fabs(weights[i]) > std::numeric_limits<double>::epsilon())
645 double xi_sig = x[i]/sig;
649 weights[i] = c/fabs(xi_sig);
664 unsigned int n_data = x.
getRows();
665 double const_sig = 2.3849*sig;
668 for(
unsigned int i=0; i<n_data; i++)
697 unsigned int n_data = r.
getRows();
700 for(
unsigned int i=0; i<n_data; i++)
728 vpRobust::partition(
vpColVector &a,
unsigned int l,
unsigned int r)
730 unsigned int i = l-1;
737 while (v < a[--j])
if (j == l)
break;
753 vpRobust::select(
vpColVector &a,
unsigned int l,
unsigned int r,
unsigned int k)
757 unsigned int i = partition(a, l, r);
766 vpRobust::erf(
double x)
768 return x < 0.0 ? -gammp(0.5,x*x) : gammp(0.5,x*x);
772 vpRobust::gammp(
double a,
double x)
774 double gamser=0.,gammcf=0.,gln;
776 if (x < 0.0 || a <= 0.0)
777 std::cout <<
"Invalid arguments in routine GAMMP";
780 gser(&gamser,a,x,&gln);
785 gcf(&gammcf,a,x,&gln);
791 vpRobust::gser(
double *gamser,
double a,
double x,
double *gln)
799 std::cout <<
"x less than 0 in routine GSER";
807 for (
int n=1; n<=vpITMAX; n++)
812 if (fabs(del) < fabs(sum)*vpEPS)
814 *gamser=sum*exp(-x+a*log(x)-(*gln));
818 std::cout <<
"a too large, vpITMAX too small in routine GSER";
824 vpRobust::gcf(
double *gammcf,
double a,
double x,
double *gln)
826 double gold=0.0,g,fac=1.0,b1=1.0;
827 double b0=0.0,anf,ana,an,a1,a0=1.0;
831 for (
int n=1; n<=vpITMAX; n++)
841 if (std::fabs(a1) > std::numeric_limits<double>::epsilon())
845 if (fabs((g-gold)/g) < vpEPS)
847 *gammcf=exp(-x+a*log(x)-(*gln))*g;
853 std::cout <<
"a too large, vpITMAX too small in routine GCF";
857 vpRobust::gammln(
double xx)
860 static double cof[6]={76.18009173,-86.50532033,24.01409822,
861 -1.231739516,0.120858003e-2,-0.536382e-5};
865 tmp -= (x+0.5)*log(tmp);
867 for (
int j=0; j<=5; j++)
872 return -tmp+log(2.50662827465*ser);
void MEstimator(const vpRobustEstimatorType method, const vpColVector &residues, vpColVector &weights)
Compute the weights according a residue vector and a PsiFunction.
double * data
address of the first element of the data array
vpColVector simultMEstimator(vpColVector &residues)
Simult Mestimator.
static double sqr(double x)
vpRobust(unsigned int n_data)
Default Constructor.
Class that provides a data structure for the column vectors as well as a set of operations on these v...
unsigned int getRows() const
Return the number of rows of the matrix.
void resize(unsigned int n_data)
Resize containers for sort methods.
vpRobustEstimatorType
Enumeration of influence functions.
void resize(const unsigned int i, const bool flagNullify=true)