46 #include <visp3/core/vpDebug.h>
47 #include <visp3/core/vpColVector.h>
48 #include <visp3/core/vpMath.h>
50 #include <visp3/core/vpRobust.h>
69 : normres(), sorted_normres(), sorted_residues(), NoiseThreshold(0.0017), sig_prev(0), it(0), swap(0), size(n_data)
71 vpCDEBUG(2) <<
"vpRobust constructor reached" << std::endl;
74 sorted_normres.
resize(n_data);
75 sorted_residues.
resize(n_data);
88 sorted_normres.
resize(n_data);
89 sorted_residues.
resize(n_data);
142 unsigned int n_data = residues.
getRows();
145 sorted_residues = residues;
147 unsigned int ind_med = (
unsigned int)(ceil(n_data/2.0))-1;
150 med = select(sorted_residues, 0, (
int)n_data-1, (
int)ind_med);
154 for(
unsigned int i=0; i<n_data; i++)
156 normres[i] = (fabs(residues[i]- med));
157 sorted_normres[i] = (fabs(sorted_residues[i]- med));
162 normmedian = select(sorted_normres, 0, (
int)n_data-1, (
int)ind_med);
165 sigma = 1.4826*normmedian;
169 if(sigma < NoiseThreshold)
171 sigma= NoiseThreshold;
178 psiTukey(sigma, normres,weights);
180 vpCDEBUG(2) <<
"Tukey's function computed" << std::endl;
186 psiCauchy(sigma, normres,weights);
196 psiHuber(sigma, normres,weights);
214 unsigned int n_all_data = all_residues.
getRows();
218 normmedian = computeNormalizedMedian(all_normres,residues,all_residues,weights);
222 sigma = 1.4826*normmedian;
226 if(sigma < NoiseThreshold)
228 sigma= NoiseThreshold;
236 psiTukey(sigma, all_normres,weights);
238 vpCDEBUG(2) <<
"Tukey's function computed" << std::endl;
244 psiCauchy(sigma, all_normres,weights);
254 psiHuber(sigma, all_normres,weights);
264 double vpRobust::computeNormalizedMedian(
vpColVector &all_normres,
273 unsigned int n_all_data = all_residues.
getRows();
274 unsigned int n_data = residues.
getRows();
279 sorted_residues = residues;
281 no_null_weight_residues.
resize(n_data);
289 unsigned int index =0;
290 for(
unsigned int j=0;j<n_data;j++)
293 if(std::fabs(weights[j]) > std::numeric_limits<double>::epsilon())
295 no_null_weight_residues[index]=residues[j];
299 sorted_residues.
resize(index);
300 memcpy(sorted_residues.
data,no_null_weight_residues.
data,index*
sizeof(
double));
303 vpCDEBUG(2) <<
"vpRobust MEstimator reached. No. data = " << n_data
310 unsigned int ind_med = (
unsigned int)(ceil(n_data/2.0))-1;
311 med = select(sorted_residues, 0, (
int)n_data-1, (
int)ind_med);
315 for(i=0; i<n_all_data; i++)
317 all_normres[i] = (fabs(all_residues[i]- med));
320 for(i=0; i<n_data; i++)
322 sorted_normres[i] = (fabs(sorted_residues[i]- med));
328 normmedian = select(sorted_normres, 0, (
int)n_data-1, (
int)ind_med);
350 unsigned int n_data = residues.
getRows();
354 vpCDEBUG(2) <<
"vpRobust MEstimator reached. No. data = " << n_data
358 unsigned int ind_med = (
unsigned int)(ceil(n_data/2.0))-1;
359 med = select(residues, 0, (
int)n_data-1, (
int)ind_med);
362 for(
unsigned int i=0; i<n_data; i++)
363 norm_res[i] = (fabs(residues[i]- med));
370 normmedian = select(norm_res, 0, (
int)n_data-1, (
int)ind_med);
372 sigma = 1.4826*normmedian;
377 sigma = simultscale(residues);
382 if(sigma < NoiseThreshold)
384 sigma= NoiseThreshold;
387 vpCDEBUG(2) <<
"MAD and C computed" << std::endl;
389 psiHuber(sigma, norm_res,w);
397 vpRobust::scale(vpRobustEstimatorType method,
vpColVector &x)
402 double Expectation=0;
406 for(
unsigned int i=0; i<n; i++)
409 chiTmp = constrainedChi(method, x[i]);
410 Expectation += chiTmp*(1-erf(chiTmp));
414 #if VP_DEBUG_MODE == 3
416 std::cout <<
"erf = " << 1-erf(chiTmp) << std::endl;
417 std::cout <<
"x[i] = " << x[i] <<std::endl;
418 std::cout <<
"chi = " << chiTmp << std::endl;
419 std::cout <<
"Sum chi = " << chiTmp*
vpMath::sqr(sig_prev) << std::endl;
420 std::cout <<
"Expectation = " << chiTmp*(1-erf(chiTmp)) << std::endl;
428 sigma2 = Sum_chi*
vpMath::sqr(sig_prev)/((n-p)*Expectation);
431 #if VP_DEBUG_MODE == 3
433 std::cout <<
"Expectation = " << Expectation << std::endl;
434 std::cout <<
"Sum chi = " << Sum_chi << std::endl;
435 std::cout <<
"sig_prev" << sig_prev << std::endl;
436 std::cout <<
"sig_out" << sqrt(fabs(sigma2)) << std::endl;
441 return sqrt(fabs(sigma2));
452 double Expectation=0;
456 for(
unsigned int i=0; i<n; i++)
459 chiTmp = simult_chi_huber(x[i]);
460 Expectation += chiTmp*(1-erf(chiTmp));
464 #if VP_DEBUG_MODE == 3
466 std::cout <<
"erf = " << 1-erf(chiTmp) << std::endl;
467 std::cout <<
"x[i] = " << x[i] <<std::endl;
468 std::cout <<
"chi = " << chiTmp << std::endl;
469 std::cout <<
"Sum chi = " << chiTmp*
vpMath::sqr(sig_prev) << std::endl;
470 std::cout <<
"Expectation = " << chiTmp*(1-erf(chiTmp)) << std::endl;
478 sigma2 = Sum_chi*
vpMath::sqr(sig_prev)/((n-p)*Expectation);
481 #if VP_DEBUG_MODE == 3
483 std::cout <<
"Expectation = " << Expectation << std::endl;
484 std::cout <<
"Sum chi = " << Sum_chi << std::endl;
485 std::cout <<
"sig_prev" << sig_prev << std::endl;
486 std::cout <<
"sig_out" << sqrt(fabs(sigma2)) << std::endl;
491 return sqrt(fabs(sigma2));
496 vpRobust::constrainedChi(vpRobustEstimatorType method,
double x)
501 return constrainedChiTukey(x);
503 return constrainedChiCauchy(x);
505 return constrainedChiHuber(x);
514 vpRobust::constrainedChiTukey(
double x)
521 if(fabs(x) <= 4.7*sig_prev)
534 vpRobust::constrainedChiCauchy(
double x)
547 vpRobust::constrainedChiHuber(
double x)
550 double u = x/sig_prev;
562 vpRobust::simult_chi_huber(
double x)
565 double u = x/sig_prev;
593 unsigned int n_data = x.
getRows();
594 double cst_const = vpCST*4.6851;
596 for(
unsigned int i=0; i<n_data; i++)
599 if(std::fabs(sig) <= std::numeric_limits<double>::epsilon() && std::fabs(weights[i]) > std::numeric_limits<double>::epsilon())
605 double xi_sig = x[i]/sig;
608 if((std::fabs(xi_sig)<=(cst_const)) && std::fabs(weights[i]) > std::numeric_limits<double>::epsilon())
631 unsigned int n_data = x.
getRows();
633 for(
unsigned int i=0; i<n_data; i++)
636 if(std::fabs(weights[i]) > std::numeric_limits<double>::epsilon())
638 double xi_sig = x[i]/sig;
642 weights[i] = c/fabs(xi_sig);
657 unsigned int n_data = x.
getRows();
658 double const_sig = 2.3849*sig;
661 for(
unsigned int i=0; i<n_data; i++)
690 unsigned int n_data = r.
getRows();
693 for(
unsigned int i=0; i<n_data; i++)
725 double v = a[(
unsigned int)r];
729 while (a[(
unsigned int)++i] < v) ;
730 while (v < a[(
unsigned int)--j])
if (j == l)
break;
732 exch(a[(
unsigned int)i], a[(
unsigned int)j]);
734 exch(a[(
unsigned int)i], a[(
unsigned int)r]);
746 vpRobust::select(
vpColVector &a,
int l,
int r,
int k)
750 int i = partition(a, l, r);
754 return a[(
unsigned int)k];
759 vpRobust::erf(
double x)
761 return x < 0.0 ? -gammp(0.5,x*x) : gammp(0.5,x*x);
765 vpRobust::gammp(
double a,
double x)
767 double gamser=0.,gammcf=0.,gln;
769 if (x < 0.0 || a <= 0.0)
770 std::cout <<
"Invalid arguments in routine GAMMP";
773 gser(&gamser,a,x,&gln);
778 gcf(&gammcf,a,x,&gln);
784 vpRobust::gser(
double *gamser,
double a,
double x,
double *gln)
792 std::cout <<
"x less than 0 in routine GSER";
800 for (
int n=1; n<=vpITMAX; n++)
805 if (fabs(del) < fabs(sum)*vpEPS)
807 *gamser=sum*exp(-x+a*log(x)-(*gln));
811 std::cout <<
"a too large, vpITMAX too small in routine GSER";
817 vpRobust::gcf(
double *gammcf,
double a,
double x,
double *gln)
819 double gold=0.0,g,fac=1.0,b1=1.0;
820 double b0=0.0,anf,ana,an,a1,a0=1.0;
824 for (
int n=1; n<=vpITMAX; n++)
834 if (std::fabs(a1) > std::numeric_limits<double>::epsilon())
838 if (fabs((g-gold)/g) < vpEPS)
840 *gammcf=exp(-x+a*log(x)-(*gln))*g;
846 std::cout <<
"a too large, vpITMAX too small in routine GCF";
850 vpRobust::gammln(
double xx)
853 static double cof[6]={76.18009173,-86.50532033,24.01409822,
854 -1.231739516,0.120858003e-2,-0.536382e-5};
858 tmp -= (x+0.5)*log(tmp);
860 for (
int j=0; j<=5; j++)
865 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.
Type * data
Address of the first element of the data array.
vpColVector simultMEstimator(vpColVector &residues)
Simult Mestimator.
static double sqr(double x)
unsigned int getRows() const
Return the number of rows of the 2D array.
vpRobust(unsigned int n_data)
Default Constructor.
Implementation of column vector and the associated operations.
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)