#include "TRobustEstimator.h"
#include "TRandom.h"
#include "TMath.h"
#include "TH1D.h"
#include "TPaveLabel.h"
#include "TDecompChol.h"
ClassImp(TRobustEstimator)
const Double_t kChiMedian[50]= {
0.454937, 1.38629, 2.36597, 3.35670, 4.35146, 5.34812, 6.34581, 7.34412, 8.34283,
9.34182, 10.34, 11.34, 12.34, 13.34, 14.34, 15.34, 16.34, 17.34, 18.34, 19.34,
20.34, 21.34, 22.34, 23.34, 24.34, 25.34, 26.34, 27.34, 28.34, 29.34, 30.34,
31.34, 32.34, 33.34, 34.34, 35.34, 36.34, 37.34, 38.34, 39.34, 40.34,
41.34, 42.34, 43.34, 44.34, 45.34, 46.34, 47.34, 48.34, 49.33};
const Double_t kChiQuant[50]={
5.02389, 7.3776,9.34840,11.1433,12.8325,
14.4494,16.0128,17.5346,19.0228,20.4831,21.920,23.337,
24.736,26.119,27.488,28.845,30.191,31.526,32.852,34.170,
35.479,36.781,38.076,39.364,40.646,41.923,43.194,44.461,
45.722,46.979,48.232,49.481,50.725,51.966,53.203,54.437,
55.668,56.896,58.120,59.342,60.561,61.777,62.990,64.201,
65.410,66.617,67.821,69.022,70.222,71.420};
TRobustEstimator::TRobustEstimator(){
}
TRobustEstimator::TRobustEstimator(Int_t nvectors, Int_t nvariables, Int_t hh)
:fMean(nvariables),
fCovariance(nvariables),
fInvcovariance(nvariables),
fCorrelation(nvariables),
fRd(nvectors),
fSd(nvectors),
fOut(1),
fHyperplane(nvariables),
fData(nvectors, nvariables)
{
if ((nvectors<=1)||(nvariables<=0)){
Error("TRobustEstimator","Not enough vectors or variables");
return;
}
if (nvariables==1){
Error("TRobustEstimator","For the univariate case, use the default constructor and EvaluateUni() function");
return;
}
fN=nvectors;
fNvar=nvariables;
if (hh<(fN+fNvar+1)/2){
if (hh>0)
Warning("TRobustEstimator","chosen h is too small, default h is taken instead");
fH=(fN+fNvar+1)/2;
} else
fH=hh;
fVarTemp=0;
fVecTemp=0;
fExact=0;
}
void TRobustEstimator::AddColumn(Double_t *col)
{
if (fVarTemp==fNvar) {
fNvar++;
fCovariance.ResizeTo(fNvar, fNvar);
fInvcovariance.ResizeTo(fNvar, fNvar);
fCorrelation.ResizeTo(fNvar, fNvar);
fMean.ResizeTo(fNvar);
fHyperplane.ResizeTo(fNvar);
fData.ResizeTo(fN, fNvar);
}
for (Int_t i=0; i<fN; i++) {
fData(i, fVarTemp)=col[i];
}
fVarTemp++;
}
void TRobustEstimator::AddRow(Double_t *row)
{
if(fVecTemp==fN) {
fN++;
fRd.ResizeTo(fN);
fSd.ResizeTo(fN);
fData.ResizeTo(fN, fNvar);
}
for (Int_t i=0; i<fNvar; i++)
fData(fVecTemp, i)=row[i];
fVecTemp++;
}
void TRobustEstimator::Evaluate()
{
Double_t kEps=1e-14;
if (fH==fN){
Warning("Evaluate","Chosen h = #observations, so classic estimates of location and scatter will be calculated");
Classic();
return;
}
Int_t i, j, k;
Int_t ii, jj;
Int_t nmini = 300;
Int_t k1=500;
Int_t nbest=10;
TMatrixD sscp(fNvar+1, fNvar+1);
TVectorD vec(fNvar);
Int_t *index = new Int_t[fN];
Double_t *ndist = new Double_t[fN];
Double_t det;
Double_t *deti=new Double_t[nbest];
for (i=0; i<nbest; i++)
deti[i]=1e16;
for (i=0; i<fN; i++)
fRd(i)=0;
if (fN<nmini*2) {
TMatrixD mstock(nbest, fNvar);
TMatrixD cstock(fNvar, fNvar*nbest);
for (k=0; k<k1; k++) {
CreateSubset(fN, fH, fNvar, index, fData, sscp, ndist);
ClearSscp(sscp);
for (i=0; i<fH; i++) {
for(j=0; j<fNvar; j++)
vec(j)=fData[index[i]][j];
AddToSscp(sscp, vec);
}
Covar(sscp, fMean, fCovariance, fSd, fH);
det = fCovariance.Determinant();
if (det < kEps) {
fExact = Exact(ndist);
delete [] index;
delete [] ndist;
delete [] deti;
return;
}
det = CStep(fN, fH, index, fData, sscp, ndist);
if (det < kEps) {
fExact = Exact(ndist);
delete [] index;
delete [] ndist;
delete [] deti;
return;
}
det = CStep(fN, fH, index, fData, sscp, ndist);
if (det < kEps) {
fExact = Exact(ndist);
delete [] index;
delete [] ndist;
delete [] deti;
return;
} else {
Int_t maxind=TMath::LocMax(nbest, deti);
if(det<deti[maxind]) {
deti[maxind]=det;
for(ii=0; ii<fNvar; ii++) {
mstock(maxind, ii)=fMean(ii);
for(jj=0; jj<fNvar; jj++)
cstock(ii, jj+maxind*fNvar)=fCovariance(ii, jj);
}
}
}
}
for (i=0; i<nbest; i++) {
for(ii=0; ii<fNvar; ii++) {
fMean(ii)=mstock(i, ii);
for (jj=0; jj<fNvar; jj++)
fCovariance(ii, jj)=cstock(ii, jj+i*fNvar);
}
det=1;
while (det>kEps) {
det=CStep(fN, fH, index, fData, sscp, ndist);
if(TMath::Abs(det-deti[i])<kEps)
break;
else
deti[i]=det;
}
for(ii=0; ii<fNvar; ii++) {
mstock(i,ii)=fMean(ii);
for (jj=0; jj<fNvar; jj++)
cstock(ii,jj+i*fNvar)=fCovariance(ii, jj);
}
}
Int_t detind=TMath::LocMin(nbest, deti);
for(ii=0; ii<fNvar; ii++) {
fMean(ii)=mstock(detind,ii);
for(jj=0; jj<fNvar; jj++)
fCovariance(ii, jj)=cstock(ii,jj+detind*fNvar);
}
if (deti[detind]!=0) {
Int_t nout = RDist(sscp);
Double_t cutoff=kChiQuant[fNvar-1];
fOut.Set(nout);
j=0;
for (i=0; i<fN; i++) {
if(fRd(i)>cutoff) {
fOut[j]=i;
j++;
}
}
} else {
fExact=Exact(ndist);
}
delete [] index;
delete [] ndist;
delete [] deti;
return;
}
Int_t indsubdat[5];
Int_t nsub;
for (ii=0; ii<5; ii++)
indsubdat[ii]=0;
nsub = Partition(nmini, indsubdat);
Int_t sum=0;
for (ii=0; ii<5; ii++)
sum+=indsubdat[ii];
Int_t *subdat=new Int_t[sum];
RDraw(subdat, nsub, indsubdat);
Int_t nbestsub=nbest*nsub;
TMatrixD mstockbig(nbestsub, fNvar);
TMatrixD cstockbig(fNvar, fNvar*nbestsub);
TMatrixD hyperplane(nbestsub, fNvar);
for (i=0; i<nbestsub; i++) {
for(j=0; j<fNvar; j++)
hyperplane(i,j)=0;
}
Double_t *detibig = new Double_t[nbestsub];
Int_t maxind;
maxind=TMath::LocMax(5, indsubdat);
TMatrixD dattemp(indsubdat[maxind], fNvar);
Int_t k2=Int_t(k1/nsub);
for (Int_t kgroup=0; kgroup<nsub; kgroup++) {
Int_t ntemp=indsubdat[kgroup];
Int_t temp=0;
for (i=0; i<kgroup; i++)
temp+=indsubdat[i];
Int_t par;
for(i=0; i<ntemp; i++) {
for (j=0; j<fNvar; j++) {
dattemp(i,j)=fData[subdat[temp+i]][j];
}
}
Int_t htemp=Int_t(fH*ntemp/fN);
for (i=0; i<nbest; i++)
deti[i]=1e16;
for(k=0; k<k2; k++) {
CreateSubset(ntemp, htemp, fNvar, index, dattemp, sscp, ndist);
ClearSscp(sscp);
for (i=0; i<htemp; i++) {
for(j=0; j<fNvar; j++) {
vec(j)=dattemp(index[i],j);
}
AddToSscp(sscp, vec);
}
Covar(sscp, fMean, fCovariance, fSd, htemp);
det = fCovariance.Determinant();
if (det<kEps) {
par =Exact2(mstockbig, cstockbig, hyperplane, deti, nbest, kgroup, sscp,ndist);
if(par==nbest+1) {
delete [] detibig;
delete [] deti;
delete [] subdat;
delete [] ndist;
delete [] index;
return;
} else
deti[par]=det;
} else {
det = CStep(ntemp, htemp, index, dattemp, sscp, ndist);
if (det<kEps) {
par=Exact2(mstockbig, cstockbig, hyperplane, deti, nbest, kgroup, sscp, ndist);
if(par==nbest+1) {
delete [] detibig;
delete [] deti;
delete [] subdat;
delete [] ndist;
delete [] index;
return;
} else
deti[par]=det;
} else {
det=CStep(ntemp,htemp, index, dattemp, sscp, ndist);
if(det<kEps){
par=Exact2(mstockbig, cstockbig, hyperplane, deti, nbest, kgroup, sscp,ndist);
if(par==nbest+1) {
delete [] detibig;
delete [] deti;
delete [] subdat;
delete [] ndist;
delete [] index;
return;
} else {
deti[par]=det;
}
} else {
maxind=TMath::LocMax(nbest, deti);
if(det<deti[maxind]) {
deti[maxind]=det;
for(i=0; i<fNvar; i++) {
mstockbig(nbest*kgroup+maxind,i)=fMean(i);
for(j=0; j<fNvar; j++) {
cstockbig(i,nbest*kgroup*fNvar+maxind*fNvar+j)=fCovariance(i,j);
}
}
}
}
}
}
maxind=TMath::LocMax(nbest, deti);
if (deti[maxind]<kEps)
break;
}
for(i=0; i<nbest; i++) {
detibig[kgroup*nbest + i]=deti[i];
}
}
TMatrixD datmerged(sum, fNvar);
for(i=0; i<sum; i++) {
for (j=0; j<fNvar; j++)
datmerged(i,j)=fData[subdat[i]][j];
}
Int_t hmerged=Int_t(sum*fH/fN);
Int_t nh;
for(k=0; k<nbestsub; k++) {
for(ii=0; ii<fNvar; ii++) {
fMean(ii)=mstockbig(k,ii);
for(jj=0; jj<fNvar; jj++)
fCovariance(ii, jj)=cstockbig(ii,k*fNvar+jj);
}
if(detibig[k]==0) {
for(i=0; i<fNvar; i++)
fHyperplane(i)=hyperplane(k,i);
CreateOrtSubset(datmerged,index, hmerged, sum, sscp, ndist);
}
det=CStep(sum, hmerged, index, datmerged, sscp, ndist);
if (det<kEps) {
nh= Exact(ndist);
if (nh>=fH) {
fExact = nh;
delete [] detibig;
delete [] deti;
delete [] subdat;
delete [] ndist;
delete [] index;
return;
} else {
CreateOrtSubset(datmerged, index, hmerged, sum, sscp, ndist);
}
}
det=CStep(sum, hmerged, index, datmerged, sscp, ndist);
if (det<kEps) {
nh=Exact(ndist);
if (nh>=fH) {
fExact = nh;
delete [] detibig;
delete [] deti;
delete [] subdat;
delete [] ndist;
delete [] index;
return;
}
}
detibig[k]=det;
for(i=0; i<fNvar; i++) {
mstockbig(k,i)=fMean(i);
for(j=0; j<fNvar; j++) {
cstockbig(i,k*fNvar+j)=fCovariance(i, j);
}
}
}
Int_t minind=TMath::LocMin(nbestsub, detibig);
det=detibig[minind];
for(i=0; i<fNvar; i++) {
fMean(i)=mstockbig(minind,i);
fHyperplane(i)=hyperplane(minind,i);
for(j=0; j<fNvar; j++)
fCovariance(i, j)=cstockbig(i,minind*fNvar + j);
}
if(det<kEps)
CreateOrtSubset(fData, index, fH, fN, sscp, ndist);
det=1;
while (det>kEps) {
det=CStep(fN, fH, index, fData, sscp, ndist);
if(TMath::Abs(det-detibig[minind])<kEps) {
break;
} else {
detibig[minind]=det;
}
}
if(det<kEps) {
Exact(ndist);
fExact=kTRUE;
}
Int_t nout = RDist(sscp);
Double_t cutoff=kChiQuant[fNvar-1];
fOut.Set(nout);
j=0;
for (i=0; i<fN; i++) {
if(fRd(i)>cutoff) {
fOut[j]=i;
j++;
}
}
delete [] detibig;
delete [] deti;
delete [] subdat;
delete [] ndist;
delete [] index;
return;
}
void TRobustEstimator::EvaluateUni(Int_t nvectors, Double_t *data, Double_t &mean, Double_t &sigma, Int_t hh)
{
if (hh==0)
hh=(nvectors+2)/2;
Double_t faclts[]={2.6477,2.5092,2.3826,2.2662,2.1587,2.0589,1.9660,1.879,1.7973,1.7203,1.6473};
Int_t *index=new Int_t[nvectors];
TMath::Sort(nvectors, data, index, kFALSE);
Int_t nquant;
nquant=TMath::Min(Int_t(Double_t(((hh*1./nvectors)-0.5)*40))+1, 11);
Double_t factor=faclts[nquant-1];
Double_t *aw=new Double_t[nvectors];
Double_t *aw2=new Double_t[nvectors];
Double_t sq=0;
Double_t sqmin=0;
Int_t ndup=0;
Int_t len=nvectors-hh;
Double_t *slutn=new Double_t[len];
for(Int_t i=0; i<len; i++)
slutn[i]=0;
for(Int_t jint=0; jint<len; jint++) {
aw[jint]=0;
for (Int_t j=0; j<hh; j++) {
aw[jint]+=data[index[j+jint]];
if(jint==0)
sq+=data[index[j]]*data[index[j]];
}
aw2[jint]=aw[jint]*aw[jint]/hh;
if(jint==0) {
sq=sq-aw2[jint];
sqmin=sq;
slutn[ndup]=aw[jint];
} else {
sq=sq - data[index[jint-1]]*data[index[jint-1]]+
data[index[jint+hh]]*data[index[jint+hh]]-
aw2[jint]+aw2[jint-1];
if(sq<sqmin) {
ndup=0;
sqmin=sq;
slutn[ndup]=aw[jint];
} else {
if(sq==sqmin) {
ndup++;
slutn[ndup]=aw[jint];
}
}
}
}
slutn[0]=slutn[Int_t((ndup)/2)]/hh;
Double_t bstd=factor*TMath::Sqrt(sqmin/hh);
mean=slutn[0];
sigma=bstd;
delete [] aw;
delete [] aw2;
delete [] slutn;
delete [] index;
}
Int_t TRobustEstimator::GetBDPoint()
{
Int_t n;
n=(fN-fH+1)/fN;
return n;
}
Double_t TRobustEstimator::GetChiQuant(Int_t i) const
{
if (i < 0 || i >= 50) return 0;
return kChiQuant[i];
}
void TRobustEstimator::GetCovariance(TMatrixDSym &matr)
{
if (matr.GetNrows()!=fNvar || matr.GetNcols()!=fNvar){
Warning("GetCovariance","provided matrix is of the wrong size, it will be resized");
matr.ResizeTo(fNvar, fNvar);
}
matr=fCovariance;
}
void TRobustEstimator::GetCorrelation(TMatrixDSym &matr)
{
if (matr.GetNrows()!=fNvar || matr.GetNcols()!=fNvar) {
Warning("GetCorrelation","provided matrix is of the wrong size, it will be resized");
matr.ResizeTo(fNvar, fNvar);
}
matr=fCorrelation;
}
const TVectorD* TRobustEstimator::GetHyperplane() const
{
if (fExact==0) {
Error("GetHyperplane","the data doesn't lie on a hyperplane!\n");
return 0;
} else {
return &fHyperplane;
}
}
void TRobustEstimator::GetHyperplane(TVectorD &vec)
{
if (fExact==0){
Error("GetHyperplane","the data doesn't lie on a hyperplane!\n");
return;
}
if (vec.GetNoElements()!=fNvar) {
Warning("GetHyperPlane","provided vector is of the wrong size, it will be resized");
vec.ResizeTo(fNvar);
}
vec=fHyperplane;
}
void TRobustEstimator::GetMean(TVectorD &means)
{
if (means.GetNoElements()!=fNvar) {
Warning("GetMean","provided vector is of the wrong size, it will be resized");
means.ResizeTo(fNvar);
}
means=fMean;
}
void TRobustEstimator::GetRDistances(TVectorD &rdist)
{
if (rdist.GetNoElements()!=fN) {
Warning("GetRDistances","provided vector is of the wrong size, it will be resized");
rdist.ResizeTo(fN);
}
rdist=fRd;
}
Int_t TRobustEstimator::GetNOut()
{
return fOut.GetSize();
}
void TRobustEstimator::AddToSscp(TMatrixD &sscp, TVectorD &vec)
{
Int_t i, j;
for (j=1; j<fNvar+1; j++) {
sscp(0, j) +=vec(j-1);
sscp(j, 0) = sscp(0, j);
}
for (i=1; i<fNvar+1; i++) {
for (j=1; j<fNvar+1; j++) {
sscp(i, j) += vec(i-1)*vec(j-1);
}
}
}
void TRobustEstimator::ClearSscp(TMatrixD &sscp)
{
for (Int_t i=0; i<fNvar+1; i++) {
for (Int_t j=0; j<fNvar+1; j++) {
sscp(i, j)=0;
}
}
}
void TRobustEstimator::Classic()
{
TMatrixD sscp(fNvar+1, fNvar+1);
TVectorD temp(fNvar);
ClearSscp(sscp);
for (Int_t i=0; i<fN; i++) {
for (Int_t j=0; j<fNvar; j++)
temp(j)=fData(i, j);
AddToSscp(sscp, temp);
}
Covar(sscp, fMean, fCovariance, fSd, fN);
Correl();
}
void TRobustEstimator::Covar(TMatrixD &sscp, TVectorD &m, TMatrixDSym &cov, TVectorD &sd, Int_t nvec)
{
Int_t i, j;
Double_t f;
for (i=0; i<fNvar; i++) {
m(i)=sscp(0, i+1);
sd[i]=sscp(i+1, i+1);
f=(sd[i]-m(i)*m(i)/nvec)/(nvec-1);
if (f>1e-14) sd[i]=TMath::Sqrt(f);
else sd[i]=0;
m(i)/=nvec;
}
for (i=0; i<fNvar; i++) {
for (j=0; j<fNvar; j++) {
cov(i, j)=sscp(i+1, j+1)-nvec*m(i)*m(j);
cov(i, j)/=nvec-1;
}
}
}
void TRobustEstimator::Correl()
{
Int_t i, j;
Double_t *sd=new Double_t[fNvar];
for(j=0; j<fNvar; j++)
sd[j]=1./TMath::Sqrt(fCovariance(j, j));
for(i=0; i<fNvar; i++) {
for (j=0; j<fNvar; j++) {
if (i==j)
fCorrelation(i, j)=1.;
else
fCorrelation(i, j)=fCovariance(i, j)*sd[i]*sd[j];
}
}
delete [] sd;
}
void TRobustEstimator::CreateSubset(Int_t ntotal, Int_t htotal, Int_t p, Int_t *index, TMatrixD &data, TMatrixD &sscp, Double_t *ndist)
{
Double_t kEps = 1e-14;
Int_t i, j;
Bool_t repeat=kFALSE;
Int_t nindex=0;
Int_t num;
for(i=0; i<ntotal; i++)
index[i]=ntotal+1;
for (i=0; i<p+1; i++) {
num=Int_t(gRandom->Uniform(0, 1)*(ntotal-1));
if (i>0){
for(j=0; j<=i-1; j++) {
if(index[j]==num)
repeat=kTRUE;
}
}
if(repeat==kTRUE) {
i--;
repeat=kFALSE;
} else {
index[i]=num;
nindex++;
}
}
ClearSscp(sscp);
TVectorD vec(fNvar);
Double_t det;
for (i=0; i<p+1; i++) {
for (j=0; j<fNvar; j++) {
vec[j]=data[index[i]][j];
}
AddToSscp(sscp, vec);
}
Covar(sscp, fMean, fCovariance, fSd, p+1);
det=fCovariance.Determinant();
while((det<kEps)&&(nindex < htotal)) {
repeat=kFALSE;
do{
num=Int_t(gRandom->Uniform(0,1)*(ntotal-1));
repeat=kFALSE;
for(i=0; i<nindex; i++) {
if(index[i]==num) {
repeat=kTRUE;
break;
}
}
}while(repeat==kTRUE);
index[nindex]=num;
nindex++;
for(j=0; j<fNvar; j++)
vec[j]=data[index[nindex-1]][j];
AddToSscp(sscp, vec);
Covar(sscp, fMean, fCovariance, fSd, nindex);
det=fCovariance.Determinant();
}
if(nindex!=htotal) {
TDecompChol chol(fCovariance);
fInvcovariance = chol.Invert();
TVectorD temp(fNvar);
for(j=0; j<ntotal; j++) {
ndist[j]=0;
for(i=0; i<fNvar; i++)
temp[i]=data[j][i] - fMean(i);
temp*=fInvcovariance;
for(i=0; i<fNvar; i++)
ndist[j]+=(data[j][i]-fMean(i))*temp[i];
}
KOrdStat(ntotal, ndist, htotal-1,index);
}
}
void TRobustEstimator::CreateOrtSubset(TMatrixD &dat,Int_t *index, Int_t hmerged, Int_t nmerged, TMatrixD &sscp, Double_t *ndist)
{
Int_t i, j;
TVectorD vec(fNvar);
for (i=0; i<nmerged; i++) {
ndist[i]=0;
for(j=0; j<fNvar; j++) {
ndist[i]+=fHyperplane[j]*(dat[i][j]-fMean[j]);
ndist[i]=TMath::Abs(ndist[i]);
}
}
KOrdStat(nmerged, ndist, hmerged-1, index);
ClearSscp(sscp);
for (i=0; i<hmerged; i++) {
for(j=0; j<fNvar; j++)
vec[j]=dat[index[i]][j];
AddToSscp(sscp, vec);
}
Covar(sscp, fMean, fCovariance, fSd, hmerged);
}
Double_t TRobustEstimator::CStep(Int_t ntotal, Int_t htotal, Int_t *index, TMatrixD &data, TMatrixD &sscp, Double_t *ndist)
{
Int_t i, j;
TVectorD vec(fNvar);
Double_t det;
TDecompChol chol(fCovariance);
fInvcovariance = chol.Invert();
TVectorD temp(fNvar);
for(j=0; j<ntotal; j++) {
ndist[j]=0;
for(i=0; i<fNvar; i++)
temp[i]=data[j][i]-fMean[i];
temp*=fInvcovariance;
for(i=0; i<fNvar; i++)
ndist[j]+=(data[j][i]-fMean[i])*temp[i];
}
KOrdStat(ntotal, ndist, htotal-1, index);
ClearSscp(sscp);
for (i=0; i<htotal; i++) {
for (j=0; j<fNvar; j++)
temp[j]=data[index[i]][j];
AddToSscp(sscp, temp);
}
Covar(sscp, fMean, fCovariance, fSd, htotal);
det = fCovariance.Determinant();
return det;
}
Int_t TRobustEstimator::Exact(Double_t *ndist)
{
Int_t i, j;
TMatrixDSymEigen eigen(fCovariance);
TVectorD eigenValues=eigen.GetEigenValues();
TMatrixD eigenMatrix=eigen.GetEigenVectors();
for (j=0; j<fNvar; j++) {
fHyperplane[j]=eigenMatrix(j,fNvar-1);
}
for (i=0; i<fN; i++) {
ndist[i]=0;
for(j=0; j<fNvar; j++) {
ndist[i]+=fHyperplane[j]*(fData[i][j]-fMean[j]);
ndist[i]=TMath::Abs(ndist[i]);
}
}
Int_t nhyp=0;
for (i=0; i<fN; i++) {
if(ndist[i] < 1e-14) nhyp++;
}
return nhyp;
}
Int_t TRobustEstimator::Exact2(TMatrixD &mstockbig, TMatrixD &cstockbig, TMatrixD &hyperplane,
Double_t *deti, Int_t nbest, Int_t kgroup,
TMatrixD &sscp, Double_t *ndist)
{
Int_t i, j;
TVectorD vec(fNvar);
Int_t maxind = TMath::LocMax(nbest, deti);
Int_t nh=Exact(ndist);
if(nh>=fH) {
ClearSscp(sscp);
for (i=0; i<fN; i++) {
if(ndist[i]<1e-14) {
for (j=0; j<fNvar; j++)
vec[j]=fData[i][j];
AddToSscp(sscp, vec);
}
}
Covar(sscp, fMean, fCovariance, fSd, nh);
fExact=nh;
return nbest+1;
} else {
for(i=0; i<fNvar; i++) {
mstockbig(nbest*kgroup+maxind,i)=fMean(i);
hyperplane(nbest*kgroup+maxind,i)=fHyperplane(i);
for(j=0; j<fNvar; j++) {
cstockbig(i,nbest*kgroup*fNvar+maxind*fNvar+j)=fCovariance(i,j);
}
}
return maxind;
}
}
Int_t TRobustEstimator::Partition(Int_t nmini, Int_t *indsubdat)
{
Int_t nsub;
if ((fN>=2*nmini) && (fN<=(3*nmini-1))) {
if (fN%2==1){
indsubdat[0]=Int_t(fN*0.5);
indsubdat[1]=Int_t(fN*0.5)+1;
} else
indsubdat[0]=indsubdat[1]=Int_t(fN/2);
nsub=2;
}
else{
if((fN>=3*nmini) && (fN<(4*nmini -1))) {
if(fN%3==0){
indsubdat[0]=indsubdat[1]=indsubdat[2]=Int_t(fN/3);
} else {
indsubdat[0]=Int_t(fN/3);
indsubdat[1]=Int_t(fN/3)+1;
if (fN%3==1) indsubdat[2]=Int_t(fN/3);
else indsubdat[2]=Int_t(fN/3)+1;
}
nsub=3;
}
else{
if((fN>=4*nmini)&&(fN<=(5*nmini-1))){
if (fN%4==0) indsubdat[0]=indsubdat[1]=indsubdat[2]=indsubdat[3]=Int_t(fN/4);
else {
indsubdat[0]=Int_t(fN/4);
indsubdat[1]=Int_t(fN/4)+1;
if(fN%4==1) indsubdat[2]=indsubdat[3]=Int_t(fN/4);
if(fN%4==2) {
indsubdat[2]=Int_t(fN/4)+1;
indsubdat[3]=Int_t(fN/4);
}
if(fN%4==3) indsubdat[2]=indsubdat[3]=Int_t(fN/4)+1;
}
nsub=4;
} else {
for(Int_t i=0; i<5; i++)
indsubdat[i]=nmini;
nsub=5;
}
}
}
return nsub;
}
Int_t TRobustEstimator::RDist(TMatrixD &sscp)
{
Int_t i, j;
Int_t nout=0;
TVectorD temp(fNvar);
TDecompChol chol(fCovariance);
fInvcovariance = chol.Invert();
for (i=0; i<fN; i++) {
fRd[i]=0;
for(j=0; j<fNvar; j++) {
temp[j]=fData[i][j]-fMean[j];
}
temp*=fInvcovariance;
for(j=0; j<fNvar; j++) {
fRd[i]+=(fData[i][j]-fMean[j])*temp[j];
}
}
Double_t med;
Double_t chi = kChiMedian[fNvar-1];
med=TMath::Median(fN, fRd.GetMatrixArray());
med/=chi;
fCovariance*=med;
TDecompChol chol2(fCovariance);
fInvcovariance = chol2.Invert();
for (i=0; i<fN; i++) {
fRd[i]=0;
for(j=0; j<fNvar; j++) {
temp[j]=fData[i][j]-fMean[j];
}
temp*=fInvcovariance;
for(j=0; j<fNvar; j++) {
fRd[i]+=(fData[i][j]-fMean[j])*temp[j];
}
}
Double_t cutoff = kChiQuant[fNvar-1];
ClearSscp(sscp);
for(i=0; i<fN; i++) {
if (fRd[i]<=cutoff) {
for(j=0; j<fNvar; j++)
temp[j]=fData[i][j];
AddToSscp(sscp,temp);
} else {
nout++;
}
}
Covar(sscp, fMean, fCovariance, fSd, fN-nout);
return nout;
}
void TRobustEstimator::RDraw(Int_t *subdat, Int_t ngroup, Int_t *indsubdat)
{
Int_t jndex = 0;
Int_t nrand;
Int_t i, k, m, j;
for (k=1; k<=ngroup; k++) {
for (m=1; m<=indsubdat[k-1]; m++) {
nrand = Int_t(gRandom->Uniform(0, 1) * (fN-jndex))+1;
jndex++;
if (jndex==1) {
subdat[0]=nrand;
} else {
subdat[jndex-1]=nrand+jndex-2;
for (i=1; i<=jndex-1; i++) {
if(subdat[i-1] > nrand+i-2) {
for(j=jndex; j>=i+1; j--) {
subdat[j-1]=subdat[j-2];
}
subdat[i-1]=nrand+i-2;
break;
}
}
}
}
}
}
Double_t TRobustEstimator::KOrdStat(Int_t ntotal, Double_t *a, Int_t k, Int_t *work){
Bool_t isAllocated = kFALSE;
const Int_t kWorkMax=100;
Int_t i, ir, j, l, mid;
Int_t arr;
Int_t *ind;
Int_t workLocal[kWorkMax];
Int_t temp;
if (work) {
ind = work;
} else {
ind = workLocal;
if (ntotal > kWorkMax) {
isAllocated = kTRUE;
ind = new Int_t[ntotal];
}
}
for (Int_t ii=0; ii<ntotal; ii++) {
ind[ii]=ii;
}
Int_t rk = k;
l=0;
ir = ntotal-1;
for(;;) {
if (ir<=l+1) {
if (ir == l+1 && a[ind[ir]]<a[ind[l]])
{temp = ind[l]; ind[l]=ind[ir]; ind[ir]=temp;}
Double_t tmp = a[ind[rk]];
if (isAllocated)
delete [] ind;
return tmp;
} else {
mid = (l+ir) >> 1;
{temp = ind[mid]; ind[mid]=ind[l+1]; ind[l+1]=temp;}
if (a[ind[l]]>a[ind[ir]])
{temp = ind[l]; ind[l]=ind[ir]; ind[ir]=temp;}
if (a[ind[l+1]]>a[ind[ir]])
{temp=ind[l+1]; ind[l+1]=ind[ir]; ind[ir]=temp;}
if (a[ind[l]]>a[ind[l+1]])
{temp = ind[l]; ind[l]=ind[l+1]; ind[l+1]=temp;}
i=l+1;
j=ir;
arr = ind[l+1];
for (;;) {
do i++; while (a[ind[i]]<a[arr]);
do j--; while (a[ind[j]]>a[arr]);
if (j<i) break;
{temp=ind[i]; ind[i]=ind[j]; ind[j]=temp;}
}
ind[l+1]=ind[j];
ind[j]=arr;
if (j>=rk) ir = j-1;
if (j<=rk) l=i;
}
}
}
TRobustEstimator.cxx:1000 TRobustEstimator.cxx:1001 TRobustEstimator.cxx:1002 TRobustEstimator.cxx:1003 TRobustEstimator.cxx:1004 TRobustEstimator.cxx:1005 TRobustEstimator.cxx:1006 TRobustEstimator.cxx:1007 TRobustEstimator.cxx:1008 TRobustEstimator.cxx:1009 TRobustEstimator.cxx:1010 TRobustEstimator.cxx:1011 TRobustEstimator.cxx:1012 TRobustEstimator.cxx:1013 TRobustEstimator.cxx:1014 TRobustEstimator.cxx:1015 TRobustEstimator.cxx:1016 TRobustEstimator.cxx:1017 TRobustEstimator.cxx:1018 TRobustEstimator.cxx:1019 TRobustEstimator.cxx:1020 TRobustEstimator.cxx:1021 TRobustEstimator.cxx:1022 TRobustEstimator.cxx:1023 TRobustEstimator.cxx:1024 TRobustEstimator.cxx:1025 TRobustEstimator.cxx:1026 TRobustEstimator.cxx:1027 TRobustEstimator.cxx:1028 TRobustEstimator.cxx:1029 TRobustEstimator.cxx:1030 TRobustEstimator.cxx:1031 TRobustEstimator.cxx:1032 TRobustEstimator.cxx:1033 TRobustEstimator.cxx:1034 TRobustEstimator.cxx:1035 TRobustEstimator.cxx:1036 TRobustEstimator.cxx:1037 TRobustEstimator.cxx:1038 TRobustEstimator.cxx:1039 TRobustEstimator.cxx:1040 TRobustEstimator.cxx:1041 TRobustEstimator.cxx:1042 TRobustEstimator.cxx:1043 TRobustEstimator.cxx:1044 TRobustEstimator.cxx:1045 TRobustEstimator.cxx:1046 TRobustEstimator.cxx:1047 TRobustEstimator.cxx:1048 TRobustEstimator.cxx:1049 TRobustEstimator.cxx:1050 TRobustEstimator.cxx:1051 TRobustEstimator.cxx:1052 TRobustEstimator.cxx:1053 TRobustEstimator.cxx:1054 TRobustEstimator.cxx:1055 TRobustEstimator.cxx:1056 TRobustEstimator.cxx:1057 TRobustEstimator.cxx:1058 TRobustEstimator.cxx:1059 TRobustEstimator.cxx:1060 TRobustEstimator.cxx:1061 TRobustEstimator.cxx:1062 TRobustEstimator.cxx:1063 TRobustEstimator.cxx:1064 TRobustEstimator.cxx:1065 TRobustEstimator.cxx:1066 TRobustEstimator.cxx:1067 TRobustEstimator.cxx:1068 TRobustEstimator.cxx:1069 TRobustEstimator.cxx:1070 TRobustEstimator.cxx:1071 TRobustEstimator.cxx:1072 TRobustEstimator.cxx:1073 TRobustEstimator.cxx:1074 TRobustEstimator.cxx:1075 TRobustEstimator.cxx:1076 TRobustEstimator.cxx:1077 TRobustEstimator.cxx:1078 TRobustEstimator.cxx:1079 TRobustEstimator.cxx:1080 TRobustEstimator.cxx:1081 TRobustEstimator.cxx:1082 TRobustEstimator.cxx:1083 TRobustEstimator.cxx:1084 TRobustEstimator.cxx:1085 TRobustEstimator.cxx:1086 TRobustEstimator.cxx:1087 TRobustEstimator.cxx:1088 TRobustEstimator.cxx:1089 TRobustEstimator.cxx:1090 TRobustEstimator.cxx:1091 TRobustEstimator.cxx:1092 TRobustEstimator.cxx:1093 TRobustEstimator.cxx:1094 TRobustEstimator.cxx:1095 TRobustEstimator.cxx:1096 TRobustEstimator.cxx:1097 TRobustEstimator.cxx:1098 TRobustEstimator.cxx:1099 TRobustEstimator.cxx:1100 TRobustEstimator.cxx:1101 TRobustEstimator.cxx:1102 TRobustEstimator.cxx:1103 TRobustEstimator.cxx:1104 TRobustEstimator.cxx:1105 TRobustEstimator.cxx:1106 TRobustEstimator.cxx:1107 TRobustEstimator.cxx:1108 TRobustEstimator.cxx:1109 TRobustEstimator.cxx:1110 TRobustEstimator.cxx:1111 TRobustEstimator.cxx:1112 TRobustEstimator.cxx:1113 TRobustEstimator.cxx:1114 TRobustEstimator.cxx:1115 TRobustEstimator.cxx:1116 TRobustEstimator.cxx:1117 TRobustEstimator.cxx:1118 TRobustEstimator.cxx:1119 TRobustEstimator.cxx:1120 TRobustEstimator.cxx:1121 TRobustEstimator.cxx:1122 TRobustEstimator.cxx:1123 TRobustEstimator.cxx:1124 TRobustEstimator.cxx:1125 TRobustEstimator.cxx:1126 TRobustEstimator.cxx:1127 TRobustEstimator.cxx:1128 TRobustEstimator.cxx:1129 TRobustEstimator.cxx:1130 TRobustEstimator.cxx:1131 TRobustEstimator.cxx:1132 TRobustEstimator.cxx:1133 TRobustEstimator.cxx:1134 TRobustEstimator.cxx:1135 TRobustEstimator.cxx:1136 TRobustEstimator.cxx:1137 TRobustEstimator.cxx:1138 TRobustEstimator.cxx:1139 TRobustEstimator.cxx:1140 TRobustEstimator.cxx:1141 TRobustEstimator.cxx:1142 TRobustEstimator.cxx:1143 TRobustEstimator.cxx:1144 TRobustEstimator.cxx:1145 TRobustEstimator.cxx:1146 TRobustEstimator.cxx:1147 TRobustEstimator.cxx:1148 TRobustEstimator.cxx:1149 TRobustEstimator.cxx:1150 TRobustEstimator.cxx:1151 TRobustEstimator.cxx:1152 TRobustEstimator.cxx:1153 TRobustEstimator.cxx:1154 TRobustEstimator.cxx:1155 TRobustEstimator.cxx:1156 TRobustEstimator.cxx:1157 TRobustEstimator.cxx:1158 TRobustEstimator.cxx:1159 TRobustEstimator.cxx:1160 TRobustEstimator.cxx:1161 TRobustEstimator.cxx:1162 TRobustEstimator.cxx:1163 TRobustEstimator.cxx:1164 TRobustEstimator.cxx:1165 TRobustEstimator.cxx:1166 TRobustEstimator.cxx:1167 TRobustEstimator.cxx:1168 TRobustEstimator.cxx:1169 TRobustEstimator.cxx:1170 TRobustEstimator.cxx:1171 TRobustEstimator.cxx:1172 TRobustEstimator.cxx:1173 TRobustEstimator.cxx:1174 TRobustEstimator.cxx:1175 TRobustEstimator.cxx:1176 TRobustEstimator.cxx:1177 TRobustEstimator.cxx:1178 TRobustEstimator.cxx:1179 TRobustEstimator.cxx:1180 TRobustEstimator.cxx:1181 TRobustEstimator.cxx:1182 TRobustEstimator.cxx:1183 TRobustEstimator.cxx:1184 TRobustEstimator.cxx:1185 TRobustEstimator.cxx:1186 TRobustEstimator.cxx:1187 TRobustEstimator.cxx:1188 TRobustEstimator.cxx:1189 TRobustEstimator.cxx:1190 TRobustEstimator.cxx:1191 TRobustEstimator.cxx:1192 TRobustEstimator.cxx:1193 TRobustEstimator.cxx:1194 TRobustEstimator.cxx:1195 TRobustEstimator.cxx:1196 TRobustEstimator.cxx:1197 TRobustEstimator.cxx:1198 TRobustEstimator.cxx:1199 TRobustEstimator.cxx:1200 TRobustEstimator.cxx:1201 TRobustEstimator.cxx:1202 TRobustEstimator.cxx:1203 TRobustEstimator.cxx:1204 TRobustEstimator.cxx:1205 TRobustEstimator.cxx:1206 TRobustEstimator.cxx:1207 TRobustEstimator.cxx:1208 TRobustEstimator.cxx:1209 TRobustEstimator.cxx:1210 TRobustEstimator.cxx:1211 TRobustEstimator.cxx:1212 TRobustEstimator.cxx:1213 TRobustEstimator.cxx:1214 TRobustEstimator.cxx:1215 TRobustEstimator.cxx:1216 TRobustEstimator.cxx:1217 TRobustEstimator.cxx:1218 TRobustEstimator.cxx:1219 TRobustEstimator.cxx:1220 TRobustEstimator.cxx:1221 TRobustEstimator.cxx:1222 TRobustEstimator.cxx:1223 TRobustEstimator.cxx:1224 TRobustEstimator.cxx:1225 TRobustEstimator.cxx:1226 TRobustEstimator.cxx:1227 TRobustEstimator.cxx:1228 TRobustEstimator.cxx:1229 TRobustEstimator.cxx:1230 TRobustEstimator.cxx:1231 TRobustEstimator.cxx:1232 TRobustEstimator.cxx:1233 TRobustEstimator.cxx:1234 TRobustEstimator.cxx:1235 TRobustEstimator.cxx:1236 TRobustEstimator.cxx:1237 TRobustEstimator.cxx:1238 TRobustEstimator.cxx:1239 TRobustEstimator.cxx:1240 TRobustEstimator.cxx:1241 TRobustEstimator.cxx:1242 TRobustEstimator.cxx:1243 TRobustEstimator.cxx:1244 TRobustEstimator.cxx:1245 TRobustEstimator.cxx:1246 TRobustEstimator.cxx:1247 TRobustEstimator.cxx:1248 TRobustEstimator.cxx:1249 TRobustEstimator.cxx:1250 TRobustEstimator.cxx:1251 TRobustEstimator.cxx:1252 TRobustEstimator.cxx:1253 TRobustEstimator.cxx:1254 TRobustEstimator.cxx:1255 TRobustEstimator.cxx:1256 TRobustEstimator.cxx:1257 TRobustEstimator.cxx:1258 TRobustEstimator.cxx:1259 TRobustEstimator.cxx:1260 TRobustEstimator.cxx:1261 TRobustEstimator.cxx:1262 TRobustEstimator.cxx:1263 TRobustEstimator.cxx:1264 TRobustEstimator.cxx:1265 TRobustEstimator.cxx:1266 TRobustEstimator.cxx:1267 TRobustEstimator.cxx:1268 TRobustEstimator.cxx:1269 TRobustEstimator.cxx:1270 TRobustEstimator.cxx:1271 TRobustEstimator.cxx:1272 TRobustEstimator.cxx:1273 TRobustEstimator.cxx:1274 TRobustEstimator.cxx:1275 TRobustEstimator.cxx:1276 TRobustEstimator.cxx:1277 TRobustEstimator.cxx:1278 TRobustEstimator.cxx:1279 TRobustEstimator.cxx:1280 TRobustEstimator.cxx:1281 TRobustEstimator.cxx:1282 TRobustEstimator.cxx:1283 TRobustEstimator.cxx:1284 TRobustEstimator.cxx:1285 TRobustEstimator.cxx:1286 TRobustEstimator.cxx:1287 TRobustEstimator.cxx:1288 TRobustEstimator.cxx:1289 TRobustEstimator.cxx:1290 TRobustEstimator.cxx:1291 TRobustEstimator.cxx:1292 TRobustEstimator.cxx:1293 TRobustEstimator.cxx:1294 TRobustEstimator.cxx:1295 TRobustEstimator.cxx:1296 TRobustEstimator.cxx:1297 TRobustEstimator.cxx:1298 TRobustEstimator.cxx:1299 TRobustEstimator.cxx:1300 TRobustEstimator.cxx:1301 TRobustEstimator.cxx:1302 TRobustEstimator.cxx:1303 TRobustEstimator.cxx:1304 TRobustEstimator.cxx:1305 TRobustEstimator.cxx:1306 TRobustEstimator.cxx:1307 TRobustEstimator.cxx:1308 TRobustEstimator.cxx:1309 TRobustEstimator.cxx:1310 TRobustEstimator.cxx:1311 TRobustEstimator.cxx:1312 TRobustEstimator.cxx:1313 TRobustEstimator.cxx:1314 TRobustEstimator.cxx:1315 TRobustEstimator.cxx:1316 TRobustEstimator.cxx:1317 TRobustEstimator.cxx:1318 TRobustEstimator.cxx:1319 TRobustEstimator.cxx:1320 TRobustEstimator.cxx:1321 TRobustEstimator.cxx:1322