232 fCovarianceMatrix(1,1),
254 : fMeanValues(nVariables),
256 fCovarianceMatrix(nVariables,nVariables),
257 fEigenVectors(nVariables,nVariables),
258 fEigenValues(nVariables),
259 fOffDiagonal(nVariables),
262 if (nVariables <= 1) {
263 Error(
"TPrincipal",
"You can't be serious - nVariables == 1!!!");
274 while (strlen(opt) > 0) {
290 Error(
"TPrincipal",
"Couldn't create vector mean values");
292 Error(
"TPrincipal",
"Couldn't create vector sigmas");
294 Error(
"TPrincipal",
"Couldn't create covariance matrix");
296 Error(
"TPrincipal",
"Couldn't create eigenvector matrix");
298 Error(
"TPrincipal",
"Couldn't create eigenvalue vector");
300 Error(
"TPrincipal",
"Couldn't create offdiagonal vector");
305 Error(
"TPrincipal",
"Couldn't create user data vector");
314 fNumberOfDataPoints(pr.fNumberOfDataPoints),
315 fNumberOfVariables(pr.fNumberOfVariables),
316 fMeanValues(pr.fMeanValues),
318 fCovarianceMatrix(pr.fCovarianceMatrix),
319 fEigenVectors(pr.fEigenVectors),
320 fEigenValues(pr.fEigenValues),
321 fOffDiagonal(pr.fOffDiagonal),
322 fUserData(pr.fUserData),
324 fHistograms(pr.fHistograms),
325 fIsNormalised(pr.fIsNormalised),
326 fStoreData(pr.fStoreData)
431 meanValues[i] *= cor;
432 meanValues[i] += p[i] * invnp;
433 const Double_t t1 = (p[i] - meanValues[i]) * invnpM1;
436 for (j = 0; j < i + 1; j++) {
438 covMatrix[index] *= cor;
439 covMatrix[index] +=
t1 * (p[j] - meanValues[j]);
468 while ((
h = (
TH1*)next()))
476 b->Add(&
fSigmas,
"Sigma value vector");
583 Int_t len = strlen(opt);
585 for (i = 0; i < len; i++) {
612 Warning(
"MakeHistograms",
"Unknown option: %c",opt[i]);
617 if (!makeX && !makeD && !makeP && !makeE && !makeS)
653 hE =
new TH1F(
Form(
"%s_e",
name),
"Eigenvalues of Covariance matrix",
663 hS->
SetYTitle(
"#sum_{i=1}^{M} (x_{i} - x'_{N,i})^{2}");
676 Form(
"Pattern space, variable %d", i),
688 Form(
"Distance from pattern to "
689 "feature space, variable %d", i),
694 hD[i]->
SetXTitle(
Form(
"|x_{%d} - x'_{%d,N}|/#sigma_{%d}",i,i,i));
708 Form(
"Feature space, variable %d", i),
719 if (!makeX && !makeP && !makeD && !makeS) {
742 if (makeP||makeD||makeS)
746 if (makeD || makeS) {
762 (hD[k])->Fill(
d[k],j);
806 for (j = 0; j <= i; j++)
814 for (j = 0; j <= i; j++) {
901 const char *prefix = (isMethod ?
Form(
"%s::", classname) :
"");
902 const char *cv_qual = (isMethod ?
"" :
"static ");
904 std::ofstream outFile(filename,std::ios::out|std::ios::trunc);
906 Error(
"MakeRealCode",
"couldn't open output file '%s'",filename);
910 std::cout <<
"Writing on file \"" << filename <<
"\" ... " << std::flush;
915 outFile <<
"// -*- mode: c++ -*-" << std::endl;
917 outFile <<
"// " << std::endl
918 <<
"// File " << filename
919 <<
" generated by TPrincipal::MakeCode" << std::endl;
922 outFile <<
"// on " << date.
AsString() << std::endl;
924 outFile <<
"// ROOT version " <<
gROOT->GetVersion()
925 << std::endl <<
"//" << std::endl;
927 outFile <<
"// This file contains the functions " << std::endl
929 <<
"// void " << prefix
930 <<
"X2P(Double_t *x, Double_t *p); " << std::endl
931 <<
"// void " << prefix
932 <<
"P2X(Double_t *p, Double_t *x, Int_t nTest);"
933 << std::endl <<
"//" << std::endl
934 <<
"// The first for transforming original data x in " << std::endl
935 <<
"// pattern space, to principal components p in " << std::endl
936 <<
"// feature space. The second function is for the" << std::endl
937 <<
"// inverse transformation, but using only nTest" << std::endl
938 <<
"// of the principal components in the expansion" << std::endl
939 <<
"// " << std::endl
940 <<
"// See TPrincipal class documentation for more "
941 <<
"information " << std::endl <<
"// " << std::endl;
943 outFile <<
"#ifndef __CINT__" << std::endl;
946 outFile <<
"#include \"" << classname <<
".h\"" << std::endl;
949 outFile <<
"#include <Rtypes.h> // needed for Double_t etc" << std::endl;
951 outFile <<
"#endif" << std::endl << std::endl;
960 outFile <<
"//" << std::endl
961 <<
"// Static data variables" << std::endl
962 <<
"//" << std::endl;
963 outFile << cv_qual <<
"Int_t " << prefix <<
"gNVariables = "
970 outFile << std::endl <<
"// Assignment of eigenvector matrix." << std::endl
971 <<
"// Elements are stored row-wise, that is" << std::endl
972 <<
"// M[i][j] = e[i * nVariables + j] " << std::endl
973 <<
"// where i and j are zero-based" << std::endl;
974 outFile << cv_qual <<
"Double_t " << prefix
975 <<
"gEigenVectors[] = {" << std::flush;
980 outFile << (index != 0 ?
"," :
"" ) << std::endl
984 outFile <<
"};" << std::endl << std::endl;
987 outFile <<
"// Assignment to eigen value vector. Zero-based." << std::endl;
988 outFile << cv_qual <<
"Double_t " << prefix
989 <<
"gEigenValues[] = {" << std::flush;
991 outFile << (i != 0 ?
"," :
"") << std::endl
993 outFile << std::endl <<
"};" << std::endl << std::endl;
996 outFile <<
"// Assignment to mean value vector. Zero-based." << std::endl;
997 outFile << cv_qual <<
"Double_t " << prefix
998 <<
"gMeanValues[] = {" << std::flush;
1000 outFile << (i != 0 ?
"," :
"") << std::endl
1002 outFile << std::endl <<
"};" << std::endl << std::endl;
1005 outFile <<
"// Assignment to sigma value vector. Zero-based." << std::endl;
1006 outFile << cv_qual <<
"Double_t " << prefix
1007 <<
"gSigmaValues[] = {" << std::flush;
1009 outFile << (i != 0 ?
"," :
"") << std::endl
1012 outFile << std::endl <<
"};" << std::endl << std::endl;
1019 outFile <<
"// " << std::endl
1021 << (isMethod ?
"method " :
"function ")
1022 <<
" void " << prefix
1023 <<
"X2P(Double_t *x, Double_t *p)"
1024 << std::endl <<
"// " << std::endl;
1025 outFile <<
"void " << prefix
1026 <<
"X2P(Double_t *x, Double_t *p) {" << std::endl
1027 <<
" for (Int_t i = 0; i < gNVariables; i++) {" << std::endl
1028 <<
" p[i] = 0;" << std::endl
1029 <<
" for (Int_t j = 0; j < gNVariables; j++)" << std::endl
1030 <<
" p[i] += (x[j] - gMeanValues[j]) " << std::endl
1031 <<
" * gEigenVectors[j * gNVariables + i] "
1032 <<
"/ gSigmaValues[j];" << std::endl << std::endl <<
" }"
1033 << std::endl <<
"}" << std::endl << std::endl;
1037 outFile <<
"// " << std::endl <<
"// The "
1038 << (isMethod ?
"method " :
"function ")
1039 <<
" void " << prefix
1040 <<
"P2X(Double_t *p, Double_t *x, Int_t nTest)"
1041 << std::endl <<
"// " << std::endl;
1042 outFile <<
"void " << prefix
1043 <<
"P2X(Double_t *p, Double_t *x, Int_t nTest) {" << std::endl
1044 <<
" for (Int_t i = 0; i < gNVariables; i++) {" << std::endl
1045 <<
" x[i] = gMeanValues[i];" << std::endl
1046 <<
" for (Int_t j = 0; j < nTest; j++)" << std::endl
1047 <<
" x[i] += p[j] * gSigmaValues[i] " << std::endl
1048 <<
" * gEigenVectors[i * gNVariables + j];" << std::endl
1049 <<
" }" << std::endl <<
"}" << std::endl << std::endl;
1052 outFile <<
"// EOF for " << filename << std::endl;
1057 std::cout <<
"done" << std::endl;
1070 for (
Int_t j = 0; j < nTest; j++)
1093 Int_t len = strlen(opt);
1094 for (
Int_t i = 0; i < len; i++) {
1113 Warning(
"Print",
"Unknown option '%c'",opt[i]);
1118 if (printM||printS||printE) {
1119 std::cout <<
" Variable # " << std::flush;
1121 std::cout <<
"| Mean Value " << std::flush;
1123 std::cout <<
"| Sigma " << std::flush;
1125 std::cout <<
"| Eigenvalue" << std::flush;
1126 std::cout << std::endl;
1128 std::cout <<
"-------------" << std::flush;
1130 std::cout <<
"+------------" << std::flush;
1132 std::cout <<
"+------------" << std::flush;
1134 std::cout <<
"+------------" << std::flush;
1135 std::cout << std::endl;
1138 std::cout << std::setw(12) << i <<
" " << std::flush;
1140 std::cout <<
"| " << std::setw(10) << std::setprecision(4)
1143 std::cout <<
"| " << std::setw(10) << std::setprecision(4)
1144 <<
fSigmas(i) <<
" " << std::flush;
1146 std::cout <<
"| " << std::setw(10) << std::setprecision(4)
1148 std::cout << std::endl;
1150 std::cout << std::endl;
1155 std::cout <<
"Eigenvector # " << i << std::flush;
1188 s[i] += (
x[j] - xp[j])*(
x[j] - xp[j]);
1207 Warning(
"Test",
"Couldn't get histogram of square residuals");
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
TMatrixTColumn_const< Double_t > TMatrixDColumn_const
char * Form(const char *fmt,...)
Using a TBrowser one can browse all ROOT objects.
This class stores the date and time with a precision of one second in an unsigned 32 bit word (950130...
const char * AsString() const
Return the date & time as a string (ctime() format).
1-D histogram with a float per channel (see TH1 documentation)}
TH1 is the base class of all histogram classes in ROOT.
virtual void SetXTitle(const char *title)
virtual Bool_t Add(TF1 *h1, Double_t c1=1, Option_t *option="")
Performs the operation: this = this + c1*f1 if errors are defined (see TH1::Sumw2),...
virtual Int_t Fill(Double_t x)
Increment bin with abscissa X by 1.
virtual void Draw(Option_t *option="")
Draw this histogram with options.
virtual void SetYTitle(const char *title)
virtual void Scale(Double_t c1=1, Option_t *option="")
Multiply this histogram by a constant c1.
2-D histogram with a float per channel (see TH1 documentation)}
virtual void Add(TObject *obj)
virtual TObject * FindObject(const char *name) const
Find an object in this list using its name.
virtual void Delete(Option_t *option="")
Remove all objects from the list AND delete all heap based objects.
const TVectorD & GetEigenValues() const
const TMatrixD & GetEigenVectors() const
virtual TMatrixTBase< Element > & Zero()
Set matrix elements to zero.
TMatrixTSym< Element > & Use(Int_t row_lwb, Int_t row_upb, Element *data)
virtual const Element * GetMatrixArray() const
The TNamed class is the base class for all named ROOT classes.
virtual void SetName(const char *name)
Set the name of the TNamed.
TNamed & operator=(const TNamed &rhs)
TNamed assignment operator.
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Principal Components Analysis (PCA)
virtual void MakeMethods(const char *classname="PCA", Option_t *option="")
Generate the file <classname>PCA.cxx which contains the implementation of two methods:
virtual void AddRow(const Double_t *x)
Add a data point and update the covariance matrix.
virtual void X2P(const Double_t *x, Double_t *p)
Calculate the principal components from the original data vector x, and return it in p.
Double_t fTrace
Trace of covarience matrix.
virtual void Print(Option_t *opt="MSE") const
Print the statistics Options are.
const Double_t * GetRow(Int_t row)
Return a row of the user supplied data.
TPrincipal()
Empty constructor. Do not use.
virtual void Browse(TBrowser *b)
Browse the TPrincipal object in the TBrowser.
virtual void MakeHistograms(const char *name="pca", Option_t *option="epsdx")
Make histograms of the result of the analysis.
TVectorD fUserData
Vector of original data points.
virtual void MakeCode(const char *filename="pca", Option_t *option="")
Generates the file <filename>, with .C appended if it does argument doesn't end in ....
TMatrixD fCovarianceMatrix
Covariance matrix.
Int_t fNumberOfVariables
Number of variables.
TVectorD fSigmas
vector of sigmas
TVectorD fOffDiagonal
Elements of the tridiagonal.
TVectorD fEigenValues
Eigenvalue vector of trans.
virtual ~TPrincipal()
Destructor.
TVectorD fMeanValues
Mean value over all data points.
TList * fHistograms
List of histograms.
void MakeRealCode(const char *filename, const char *prefix, Option_t *option="")
This is the method that actually generates the code for the transformations to and from feature space...
Bool_t fStoreData
Should we store input data?
TMatrixD fEigenVectors
Eigenvector matrix of trans.
virtual void Clear(Option_t *option="")
Clear the data in Object.
virtual void P2X(const Double_t *p, Double_t *x, Int_t nTest)
Calculate x as a function of nTest of the most significant principal components p,...
Int_t fNumberOfDataPoints
Number of data points.
void MakeNormalised()
Normalize the covariance matrix.
virtual void MakePrincipals()
Perform the principal components analysis.
virtual void SumOfSquareResiduals(const Double_t *x, Double_t *s)
Calculates the sum of the square residuals, that is.
void Test(Option_t *option="")
Test the PCA, bye calculating the sum square of residuals (see method SumOfSquareResiduals),...
Bool_t fIsNormalised
Normalize matrix?
TPrincipal & operator=(const TPrincipal &)
Assignment operator.
Bool_t EndsWith(const char *pat, ECaseCompare cmp=kExact) const
Return true if string ends with the specified string.
const char * Data() const
TVectorT< Element > & Zero()
Set vector elements to zero.
TVectorT< Element > & ResizeTo(Int_t lwb, Int_t upb)
Resize the vector to [lwb:upb] .
Element * GetMatrixArray()
Double_t Sqrt(Double_t x)
#define sym(otri1, otri2)