50 #include <visp/vpDebug.h>
51 #include <visp/vpColVector.h>
52 #include <visp/vpMath.h>
54 #include <visp/vpRobust.h>
73 : normres(), sorted_normres(), sorted_residues(), NoiseThreshold(0.0017), sig_prev(0), it(0), swap(0), size(n_data)
75 vpCDEBUG(2) <<
"vpRobust constructor reached" << std::endl;
78 sorted_normres.
resize(n_data);
79 sorted_residues.
resize(n_data);
92 sorted_normres.
resize(n_data);
93 sorted_residues.
resize(n_data);
146 unsigned int n_data = residues.
getRows();
149 sorted_residues = residues;
151 unsigned int ind_med = (
unsigned int)(ceil(n_data/2.0))-1;
154 med = select(sorted_residues, 0, (
int)n_data-1, (
int)ind_med);
158 for(
unsigned int i=0; i<n_data; i++)
160 normres[i] = (fabs(residues[i]- med));
161 sorted_normres[i] = (fabs(sorted_residues[i]- med));
166 normmedian = select(sorted_normres, 0, (
int)n_data-1, (
int)ind_med);
169 sigma = 1.4826*normmedian;
173 if(sigma < NoiseThreshold)
175 sigma= NoiseThreshold;
182 psiTukey(sigma, normres,weights);
184 vpCDEBUG(2) <<
"Tukey's function computed" << std::endl;
190 psiCauchy(sigma, normres,weights);
200 psiHuber(sigma, normres,weights);
218 unsigned int n_all_data = all_residues.
getRows();
222 normmedian = computeNormalizedMedian(all_normres,residues,all_residues,weights);
226 sigma = 1.4826*normmedian;
230 if(sigma < NoiseThreshold)
232 sigma= NoiseThreshold;
240 psiTukey(sigma, all_normres,weights);
242 vpCDEBUG(2) <<
"Tukey's function computed" << std::endl;
248 psiCauchy(sigma, all_normres,weights);
258 psiHuber(sigma, all_normres,weights);
268 double vpRobust::computeNormalizedMedian(
vpColVector &all_normres,
277 unsigned int n_all_data = all_residues.
getRows();
278 unsigned int n_data = residues.
getRows();
283 sorted_residues = residues;
285 no_null_weight_residues.
resize(n_data);
293 unsigned int index =0;
294 for(
unsigned int j=0;j<n_data;j++)
297 if(std::fabs(weights[j]) > std::numeric_limits<double>::epsilon())
299 no_null_weight_residues[index]=residues[j];
303 sorted_residues.
resize(index);
304 memcpy(sorted_residues.
data,no_null_weight_residues.
data,index*
sizeof(
double));
307 vpCDEBUG(2) <<
"vpRobust MEstimator reached. No. data = " << n_data
314 unsigned int ind_med = (
unsigned int)(ceil(n_data/2.0))-1;
315 med = select(sorted_residues, 0, (
int)n_data-1, (
int)ind_med);
319 for(i=0; i<n_all_data; i++)
321 all_normres[i] = (fabs(all_residues[i]- med));
324 for(i=0; i<n_data; i++)
326 sorted_normres[i] = (fabs(sorted_residues[i]- med));
332 normmedian = select(sorted_normres, 0, (
int)n_data-1, (
int)ind_med);
354 unsigned int n_data = residues.
getRows();
358 vpCDEBUG(2) <<
"vpRobust MEstimator reached. No. data = " << n_data
362 unsigned int ind_med = (
unsigned int)(ceil(n_data/2.0))-1;
363 med = select(residues, 0, (
int)n_data-1, (
int)ind_med);
366 for(
unsigned int i=0; i<n_data; i++)
367 norm_res[i] = (fabs(residues[i]- med));
374 normmedian = select(norm_res, 0, (
int)n_data-1, (
int)ind_med);
376 sigma = 1.4826*normmedian;
381 sigma = simultscale(residues);
386 if(sigma < NoiseThreshold)
388 sigma= NoiseThreshold;
391 vpCDEBUG(2) <<
"MAD and C computed" << std::endl;
393 psiHuber(sigma, norm_res,w);
401 vpRobust::scale(vpRobustEstimatorType method,
vpColVector &x)
406 double Expectation=0;
410 for(
unsigned int i=0; i<n; i++)
413 chiTmp = constrainedChi(method, x[i]);
414 Expectation += chiTmp*(1-erf(chiTmp));
418 #if VP_DEBUG_MODE == 3
420 std::cout <<
"erf = " << 1-erf(chiTmp) << std::endl;
421 std::cout <<
"x[i] = " << x[i] <<std::endl;
422 std::cout <<
"chi = " << chiTmp << std::endl;
423 std::cout <<
"Sum chi = " << chiTmp*
vpMath::sqr(sig_prev) << std::endl;
424 std::cout <<
"Expectation = " << chiTmp*(1-erf(chiTmp)) << std::endl;
432 sigma2 = Sum_chi*
vpMath::sqr(sig_prev)/((n-p)*Expectation);
435 #if VP_DEBUG_MODE == 3
437 std::cout <<
"Expectation = " << Expectation << std::endl;
438 std::cout <<
"Sum chi = " << Sum_chi << std::endl;
439 std::cout <<
"sig_prev" << sig_prev << std::endl;
440 std::cout <<
"sig_out" << sqrt(fabs(sigma2)) << std::endl;
445 return sqrt(fabs(sigma2));
456 double Expectation=0;
460 for(
unsigned int i=0; i<n; i++)
463 chiTmp = simult_chi_huber(x[i]);
464 Expectation += chiTmp*(1-erf(chiTmp));
468 #if VP_DEBUG_MODE == 3
470 std::cout <<
"erf = " << 1-erf(chiTmp) << std::endl;
471 std::cout <<
"x[i] = " << x[i] <<std::endl;
472 std::cout <<
"chi = " << chiTmp << std::endl;
473 std::cout <<
"Sum chi = " << chiTmp*
vpMath::sqr(sig_prev) << std::endl;
474 std::cout <<
"Expectation = " << chiTmp*(1-erf(chiTmp)) << std::endl;
482 sigma2 = Sum_chi*
vpMath::sqr(sig_prev)/((n-p)*Expectation);
485 #if VP_DEBUG_MODE == 3
487 std::cout <<
"Expectation = " << Expectation << std::endl;
488 std::cout <<
"Sum chi = " << Sum_chi << std::endl;
489 std::cout <<
"sig_prev" << sig_prev << std::endl;
490 std::cout <<
"sig_out" << sqrt(fabs(sigma2)) << std::endl;
495 return sqrt(fabs(sigma2));
500 vpRobust::constrainedChi(vpRobustEstimatorType method,
double x)
505 return constrainedChiTukey(x);
507 return constrainedChiCauchy(x);
509 return constrainedChiHuber(x);
518 vpRobust::constrainedChiTukey(
double x)
525 if(fabs(x) <= 4.7*sig_prev)
538 vpRobust::constrainedChiCauchy(
double x)
551 vpRobust::constrainedChiHuber(
double x)
554 double u = x/sig_prev;
566 vpRobust::simult_chi_huber(
double x)
569 double u = x/sig_prev;
597 unsigned int n_data = x.
getRows();
598 double cst_const = vpCST*4.6851;
600 for(
unsigned int i=0; i<n_data; i++)
603 if(std::fabs(sig) <= std::numeric_limits<double>::epsilon() && std::fabs(weights[i]) > std::numeric_limits<double>::epsilon())
609 double xi_sig = x[i]/sig;
612 if((std::fabs(xi_sig)<=(cst_const)) && std::fabs(weights[i]) > std::numeric_limits<double>::epsilon())
635 unsigned int n_data = x.
getRows();
637 for(
unsigned int i=0; i<n_data; i++)
640 if(std::fabs(weights[i]) > std::numeric_limits<double>::epsilon())
642 double xi_sig = x[i]/sig;
646 weights[i] = c/fabs(xi_sig);
661 unsigned int n_data = x.
getRows();
662 double const_sig = 2.3849*sig;
665 for(
unsigned int i=0; i<n_data; i++)
694 unsigned int n_data = r.
getRows();
697 for(
unsigned int i=0; i<n_data; i++)
729 double v = a[(
unsigned int)r];
733 while (a[(
unsigned int)++i] < v) ;
734 while (v < a[(
unsigned int)--j])
if (j == l)
break;
736 exch(a[(
unsigned int)i], a[(
unsigned int)j]);
738 exch(a[(
unsigned int)i], a[(
unsigned int)r]);
750 vpRobust::select(
vpColVector &a,
int l,
int r,
int k)
754 int i = partition(a, l, r);
758 return a[(
unsigned int)k];
763 vpRobust::erf(
double x)
765 return x < 0.0 ? -gammp(0.5,x*x) : gammp(0.5,x*x);
769 vpRobust::gammp(
double a,
double x)
771 double gamser=0.,gammcf=0.,gln;
773 if (x < 0.0 || a <= 0.0)
774 std::cout <<
"Invalid arguments in routine GAMMP";
777 gser(&gamser,a,x,&gln);
782 gcf(&gammcf,a,x,&gln);
788 vpRobust::gser(
double *gamser,
double a,
double x,
double *gln)
796 std::cout <<
"x less than 0 in routine GSER";
804 for (
int n=1; n<=vpITMAX; n++)
809 if (fabs(del) < fabs(sum)*vpEPS)
811 *gamser=sum*exp(-x+a*log(x)-(*gln));
815 std::cout <<
"a too large, vpITMAX too small in routine GSER";
821 vpRobust::gcf(
double *gammcf,
double a,
double x,
double *gln)
823 double gold=0.0,g,fac=1.0,b1=1.0;
824 double b0=0.0,anf,ana,an,a1,a0=1.0;
828 for (
int n=1; n<=vpITMAX; n++)
838 if (std::fabs(a1) > std::numeric_limits<double>::epsilon())
842 if (fabs((g-gold)/g) < vpEPS)
844 *gammcf=exp(-x+a*log(x)-(*gln))*g;
850 std::cout <<
"a too large, vpITMAX too small in routine GCF";
854 vpRobust::gammln(
double xx)
857 static double cof[6]={76.18009173,-86.50532033,24.01409822,
858 -1.231739516,0.120858003e-2,-0.536382e-5};
862 tmp -= (x+0.5)*log(tmp);
864 for (
int j=0; j<=5; j++)
869 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)