Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
VariablePCATransform.cxx
Go to the documentation of this file.
1// @(#)root/tmva $Id$
2// Author: Andreas Hoecker, Joerg Stelzer, Helge Voss, Eckhard von Toerne
3
4/**********************************************************************************
5 * Project: TMVA - a Root-integrated toolkit for multivariate data analysis *
6 * Package: TMVA *
7 * Class : VariablePCATransform *
8 * *
9 * *
10 * Description: *
11 * Implementation (see header for description) *
12 * *
13 * Authors (alphabetical): *
14 * Andreas Hoecker <Andreas.Hocker@cern.ch> - CERN, Switzerland *
15 * Peter Speckmayer <Peter.Speckmayer@cern.ch> - CERN, Switzerland *
16 * Joerg Stelzer <Joerg.Stelzer@cern.ch> - CERN, Switzerland *
17 * Eckhard v. Toerne <evt@uni-bonn.de> - U of Bonn, Germany *
18 * Helge Voss <Helge.Voss@cern.ch> - MPI-K Heidelberg, Germany *
19 * *
20 * Copyright (c) 2005-2011: *
21 * CERN, Switzerland *
22 * MPI-K Heidelberg, Germany *
23 * U. of Bonn, Germany *
24 * *
25 * Redistribution and use in source and binary forms, with or without *
26 * modification, are permitted according to the terms listed in LICENSE *
27 * (see tmva/doc/LICENSE) *
28 **********************************************************************************/
29
30/*! \class TMVA::VariablePCATransform
31\ingroup TMVA
32Linear interpolation class
33*/
34
36
37#include "TMVA/DataSet.h"
38#include "TMVA/Event.h"
39#include "TMVA/MsgLogger.h"
40#include "TMVA/Tools.h"
41#include "TMVA/Types.h"
42
43#include "TMatrixD.h"
44#include "TMatrixDBase.h"
45#include "TPrincipal.h"
46#include "TVectorD.h"
47#include "TVectorF.h"
48
49#include <iostream>
50#include <iomanip>
51#include <stdexcept>
52#include <algorithm>
53
54
55////////////////////////////////////////////////////////////////////////////////
56/// constructor
57
62
63////////////////////////////////////////////////////////////////////////////////
64/// destructor
65
67{
68 for (UInt_t i=0; i<fMeanValues.size(); i++) {
69 if (fMeanValues.at(i) != 0) delete fMeanValues.at(i);
70 if (fEigenVectors.at(i) != 0) delete fEigenVectors.at(i);
71 }
72}
73
74////////////////////////////////////////////////////////////////////////////////
75/// initialization of the transformation.
76/// Has to be called in the preparation and not in the constructor,
77/// since the number of classes it not known at construction, but
78/// only after the creation of the DataSet which might be later.
79
83
84////////////////////////////////////////////////////////////////////////////////
85/// calculate the principal components using the ROOT class TPrincipal
86/// and the normalization
87
89{
90 Initialize();
91
92 if (!IsEnabled() || IsCreated()) return kTRUE;
93
94 Log() << kINFO << "Preparing the Principle Component (PCA) transformation..." << Endl;
95
96 UInt_t inputSize = fGet.size();
97
98 SetNVariables(inputSize);
99
100 // TPrincipal doesn't support PCA transformation for 1 or less variables
101 if (inputSize <= 1) {
102 Log() << kFATAL << "Cannot perform PCA transformation for " << inputSize << " variable only" << Endl;
103 return kFALSE;
104 }
105
106 if (inputSize > 200) {
107 Log() << kINFO << "----------------------------------------------------------------------------"
108 << Endl;
109 Log() << kINFO
110 << ": More than 200 variables, will not calculate PCA!" << Endl;
111 Log() << kINFO << "----------------------------------------------------------------------------"
112 << Endl;
113 return kFALSE;
114 }
115
116 CalculatePrincipalComponents( events );
117
118 SetCreated( kTRUE );
119
120 return kTRUE;
121}
122
123////////////////////////////////////////////////////////////////////////////////
124/// apply the principal component analysis
125
127{
128 if (!IsCreated()) return 0;
129
130 // const Int_t inputSize = fGet.size();
131 // const UInt_t nCls = GetNClasses();
132
133 // if we have more than one class, take the last PCA analysis where all classes are combined if
134 // the cls parameter is outside the defined classes
135 // If there is only one class, then no extra class for all events of all classes has to be created
136
137 //if (cls < 0 || cls > GetNClasses()) cls = (fMeanValues.size()==1?0:2);//( GetNClasses() == 1 ? 0 : 1 ); ;
138 // EVT this is a workaround to address the reader problem with transforma and EvaluateMVA(std::vector<float/double> ,...)
139 if (cls < 0 || cls >= (int) fMeanValues.size()) cls = fMeanValues.size()-1;
140 // EVT workaround end
141
142 // Perform PCA and put it into PCAed events tree
143
144 if (fTransformedEvent==0 ) {
145 fTransformedEvent = new Event();
146 }
147
148 std::vector<Float_t> input;
149 std::vector<Char_t> mask;
150 std::vector<Float_t> principalComponents;
151
152 Bool_t hasMaskedEntries = GetInput( ev, input, mask );
153
154 if( hasMaskedEntries ){ // targets might be masked (for events where the targets have not been computed yet)
155 UInt_t numMasked = std::count(mask.begin(), mask.end(), (Char_t)kTRUE);
156 UInt_t numOK = std::count(mask.begin(), mask.end(), (Char_t)kFALSE);
157 if( numMasked>0 && numOK>0 ){
158 Log() << kFATAL << "You mixed variables and targets in the decorrelation transformation. This is not possible." << Endl;
159 }
160 SetOutput( fTransformedEvent, input, mask, ev );
161 return fTransformedEvent;
162 }
163
165 SetOutput( fTransformedEvent, principalComponents, mask, ev );
166
167 return fTransformedEvent;
168}
169
170////////////////////////////////////////////////////////////////////////////////
171/// apply the principal component analysis
172/// TODO: implementation of inverse transformation
173/// Log() << kFATAL << "Inverse transformation for PCA transformation not yet implemented. Hence, this transformation cannot be applied together with regression. Please contact the authors if necessary." << Endl;
174
176{
177 if (!IsCreated()) return 0;
178 // const Int_t inputSize = fGet.size();
179 const UInt_t nCls = GetNClasses();
180 //UInt_t evCls = ev->GetClass();
181
182 // if we have more than one class, take the last PCA analysis where all classes are combined if
183 // the cls parameter is outside the defined classes
184 // If there is only one class, then no extra class for all events of all classes has to be created
185 if (cls < 0 || UInt_t(cls) > nCls) cls = (fMeanValues.size()==1?0:2);//( GetNClasses() == 1 ? 0 : 1 ); ;
186 // Perform PCA and put it into PCAed events tree
187
188 if (fBackTransformedEvent==0 ) fBackTransformedEvent = new Event();
189
190 std::vector<Float_t> principalComponents;
191 std::vector<Char_t> mask;
192 std::vector<Float_t> output;
193
194 GetInput( ev, principalComponents, mask, kTRUE );
196 SetOutput( fBackTransformedEvent, output, mask, ev, kTRUE );
197
198 return fBackTransformedEvent;
199}
200
201////////////////////////////////////////////////////////////////////////////////
202/// calculate the principal components for the signal and the background data
203/// it uses the MakePrincipal method of ROOT's TPrincipal class
204
205void TMVA::VariablePCATransform::CalculatePrincipalComponents( const std::vector< Event*>& events )
206{
207 UInt_t nvars = 0, ntgts = 0, nspcts = 0;
208 CountVariableTypes( nvars, ntgts, nspcts );
209 if( nvars>0 && ntgts>0 )
210 Log() << kFATAL << "Variables and targets cannot be mixed in PCA transformation." << Endl;
211
212 const Int_t inputSize = fGet.size();
213
214 // if we have more than one class, add another PCA analysis which combines all classes
215 const UInt_t nCls = GetNClasses();
216 const UInt_t maxPCA = (nCls<=1) ? nCls : nCls+1;
217
218 // PCA [signal/background/class x/class y/... /all classes]
219 std::vector<TPrincipal*> pca(maxPCA);
220 for (UInt_t i=0; i<maxPCA; i++) pca[i] = new TPrincipal(nvars,"");
221
222 // !! Not normalizing and not storing input data, for performance reasons. Should perhaps restore normalization.
223 // But this can be done afterwards by adding a normalisation transformation (user defined)
224
225 Long64_t ievt, entries = events.size();
226 Double_t *dvec = new Double_t[inputSize];
227
228 std::vector<Float_t> input;
229 std::vector<Char_t> mask;
230 for (ievt=0; ievt<entries; ievt++) {
231 const Event* ev = events[ievt];
232 UInt_t cls = ev->GetClass();
233
234 Bool_t hasMaskedEntries = GetInput( ev, input, mask );
235 if (hasMaskedEntries){
236 Log() << kWARNING << "Print event which triggers an error" << Endl;
237 std::ostringstream oss;
238 ev->Print(oss);
239 Log() << oss.str();
240 Log() << kFATAL << "Masked entries found in event read in when calculating the principal components for the PCA transformation." << Endl;
241 }
242
243 UInt_t iinp = 0;
244 for( std::vector<Float_t>::iterator itInp = input.begin(), itInpEnd = input.end(); itInp != itInpEnd; ++itInp )
245 {
246 Float_t value = (*itInp);
248 ++iinp;
249 }
250
251 pca.at(cls)->AddRow( dvec );
252 if (nCls > 1) pca.at(maxPCA-1)->AddRow( dvec );
253 }
254
255 // delete possible leftovers
256 for (UInt_t i=0; i<fMeanValues.size(); i++) if (fMeanValues[i] != 0) delete fMeanValues[i];
257 for (UInt_t i=0; i<fEigenVectors.size(); i++) if (fEigenVectors[i] != 0) delete fEigenVectors[i];
258 fMeanValues.resize(maxPCA,0);
259 fEigenVectors.resize(maxPCA,0);
260
261 for (UInt_t i=0; i<maxPCA; i++ ) {
262 pca.at(i)->MakePrincipals();
263
264 // retrieve mean values, eigenvectors and sigmas
265 fMeanValues[i] = new TVectorD( *(pca.at(i)->GetMeanValues()) ); // need to copy since we want to own
266 fEigenVectors[i] = new TMatrixD( *(pca.at(i)->GetEigenVectors()) );
267 }
268
269 for (UInt_t i=0; i<maxPCA; i++) delete pca.at(i);
270 delete [] dvec;
271}
272
273////////////////////////////////////////////////////////////////////////////////
274/// Calculate the principal components from the original data vector
275/// x, and return it in p (function extracted from TPrincipal::X2P)
276/// It's the users responsibility to make sure that both x and p are
277/// of the right size (i.e., memory must be allocated for p)
278
279void TMVA::VariablePCATransform::X2P( std::vector<Float_t>& pc, const std::vector<Float_t>& x, Int_t cls ) const
280{
281 const Int_t nInput = x.size();
282 pc.assign(nInput,0);
283
284 for (Int_t i = 0; i < nInput; i++) {
285 Double_t pv = 0;
286 for (Int_t j = 0; j < nInput; j++)
287 pv += (((Double_t)x.at(j)) - (*fMeanValues.at(cls))(j)) * (*fEigenVectors.at(cls))(j,i);
288 pc[i] = pv;
289 }
290}
291
292////////////////////////////////////////////////////////////////////////////////
293/// Perform the back-transformation from the principal components
294/// pc, and return x
295/// It's the users responsibility to make sure that both x and pc are
296/// of the right size (i.e., memory must be allocated for p)
297
298void TMVA::VariablePCATransform::P2X( std::vector<Float_t>& x, const std::vector<Float_t>& pc, Int_t cls ) const
299{
300 const Int_t nInput = pc.size();
301 x.assign(nInput,0);
302
303 for (Int_t i = 0; i < nInput; i++) {
304 Double_t xv = 0;
305 for (Int_t j = 0; j < nInput; j++)
306 xv += (((Double_t)pc.at(j)) * (*fEigenVectors.at(cls))(i,j) ) + (*fMeanValues.at(cls))(j);
307 x[i] = xv;
308 }
309}
310
311////////////////////////////////////////////////////////////////////////////////
312/// write mean values to stream
313
315{
316 for (Int_t sbType=0; sbType<2; sbType++) {
317 o << "# PCA mean values " << std::endl;
318 const TVectorD* means = fMeanValues[sbType];
319 o << (sbType==0 ? "Signal" : "Background") << " " << means->GetNrows() << std::endl;
320 for (Int_t row = 0; row<means->GetNrows(); row++) {
321 o << std::setprecision(12) << std::setw(20) << (*means)[row];
322 }
323 o << std::endl;
324 }
325 o << "##" << std::endl;
326
327 // write eigenvectors to stream
328 for (Int_t sbType=0; sbType<2; sbType++) {
329 o << "# PCA eigenvectors " << std::endl;
330 const TMatrixD* mat = fEigenVectors[sbType];
331 o << (sbType==0 ? "Signal" : "Background") << " " << mat->GetNrows() << " x " << mat->GetNcols() << std::endl;
332 for (Int_t row = 0; row<mat->GetNrows(); row++) {
333 for (Int_t col = 0; col<mat->GetNcols(); col++) {
334 o << std::setprecision(12) << std::setw(20) << (*mat)[row][col] << " ";
335 }
336 o << std::endl;
337 }
338 }
339 o << "##" << std::endl;
340}
341
342////////////////////////////////////////////////////////////////////////////////
343/// create XML description of PCA transformation
344
346 void* trfxml = gTools().AddChild(parent, "Transform");
347 gTools().AddAttr(trfxml, "Name", "PCA");
348
350
351 // write mean values to stream
352 for (UInt_t sbType=0; sbType<fMeanValues.size(); sbType++) {
353 void* meanxml = gTools().AddChild( trfxml, "Statistics");
354 const TVectorD* means = fMeanValues[sbType];
355 gTools().AddAttr( meanxml, "Class", (sbType==0 ? "Signal" :(sbType==1 ? "Background":"Combined")) );
356 gTools().AddAttr( meanxml, "ClassIndex", sbType );
357 gTools().AddAttr( meanxml, "NRows", means->GetNrows() );
358 TString meansdef = "";
359 for (Int_t row = 0; row<means->GetNrows(); row++)
360 meansdef += gTools().StringFromDouble((*means)[row]) + " ";
362 }
363
364 // write eigenvectors to stream
365 for (UInt_t sbType=0; sbType<fEigenVectors.size(); sbType++) {
366 void* evxml = gTools().AddChild( trfxml, "Eigenvectors");
367 const TMatrixD* mat = fEigenVectors[sbType];
368 gTools().AddAttr( evxml, "Class", (sbType==0 ? "Signal" :(sbType==1 ? "Background":"Combined") ) );
369 gTools().AddAttr( evxml, "ClassIndex", sbType );
370 gTools().AddAttr( evxml, "NRows", mat->GetNrows() );
371 gTools().AddAttr( evxml, "NCols", mat->GetNcols() );
372 TString evdef = "";
373 for (Int_t row = 0; row<mat->GetNrows(); row++)
374 for (Int_t col = 0; col<mat->GetNcols(); col++)
375 evdef += gTools().StringFromDouble((*mat)[row][col]) + " ";
377 }
378}
379
380////////////////////////////////////////////////////////////////////////////////
381/// Read the transformation matrices from the xml node
382
384{
389
391
392 void* inpnode = NULL;
393
394 inpnode = gTools().GetChild(trfnode, "Selection"); // new xml format
395 if( inpnode!=NULL )
396 newFormat = kTRUE; // new xml format
397
398 if( newFormat ){
399 // ------------- new format --------------------
400 // read input
402
403 }
404
405 void* ch = gTools().GetChild(trfnode);
406 while (ch) {
407 nodeName = gTools().GetName(ch);
408 if (nodeName == "Statistics") {
409 // read mean values
410 gTools().ReadAttr(ch, "Class", classtype);
411 gTools().ReadAttr(ch, "ClassIndex", clsIdx);
412 gTools().ReadAttr(ch, "NRows", nrows);
413
414 // set the correct size
415 if (fMeanValues.size()<=clsIdx) fMeanValues.resize(clsIdx+1,0);
416 if (fMeanValues[clsIdx]==0) fMeanValues[clsIdx] = new TVectorD( nrows );
417 fMeanValues[clsIdx]->ResizeTo( nrows );
418
419 // now read vector entries
420 std::stringstream s(gTools().GetContent(ch));
421 for (Int_t row = 0; row<nrows; row++) s >> (*fMeanValues[clsIdx])(row);
422 }
423 else if ( nodeName == "Eigenvectors" ) {
424 // Read eigenvectors
425 gTools().ReadAttr(ch, "Class", classtype);
426 gTools().ReadAttr(ch, "ClassIndex", clsIdx);
427 gTools().ReadAttr(ch, "NRows", nrows);
428 gTools().ReadAttr(ch, "NCols", ncols);
429
430 if (fEigenVectors.size()<=clsIdx) fEigenVectors.resize(clsIdx+1,0);
431 if (fEigenVectors[clsIdx]==0) fEigenVectors[clsIdx] = new TMatrixD( nrows, ncols );
432 fEigenVectors[clsIdx]->ResizeTo( nrows, ncols );
433
434 // now read matrix entries
435 std::stringstream s(gTools().GetContent(ch));
436 for (Int_t row = 0; row<nrows; row++)
437 for (Int_t col = 0; col<ncols; col++)
438 s >> (*fEigenVectors[clsIdx])[row][col];
439 } // done reading eigenvectors
440 ch = gTools().GetNextChild(ch);
441 }
442
443 SetCreated();
444}
445
446////////////////////////////////////////////////////////////////////////////////
447/// Read mean values from input stream
448
450{
451 char buf[512];
452 istr.getline(buf,512);
453 TString strvar, dummy;
454 Int_t nrows(0), ncols(0);
455 UInt_t classIdx=(classname=="signal"?0:1);
456
457 for (UInt_t i=0; i<fMeanValues.size(); i++) {
458 if (fMeanValues.at(i) != 0) delete fMeanValues.at(i);
459 if (fEigenVectors.at(i) != 0) delete fEigenVectors.at(i);
460 }
461 fMeanValues.resize(3);
462 fEigenVectors.resize(3);
463
464 Log() << kINFO << "VariablePCATransform::ReadTransformationFromStream(): " << Endl;
465
466 while (!(buf[0]=='#'&& buf[1]=='#')) { // if line starts with ## return
467 char* p = buf;
468 while (*p==' ' || *p=='\t') p++; // 'remove' leading whitespace
469 if (*p=='#' || *p=='\0') {
470 istr.getline(buf,512);
471 continue; // if comment or empty line, read the next line
472 }
473 std::stringstream sstr(buf);
474 sstr >> strvar;
475 if (strvar=="signal" || strvar=="background") {
476
477 sstr >> nrows;
478 Int_t sbType = (strvar=="signal" ? 0 : 1);
479
480 if (fMeanValues[sbType] == 0) fMeanValues[sbType] = new TVectorD( nrows );
481 else fMeanValues[sbType]->ResizeTo( nrows );
482
483 // now read vector entries
484 for (Int_t row = 0; row<nrows; row++) istr >> (*fMeanValues[sbType])(row);
485
486 } // done reading vector
487
488 istr.getline(buf,512); // reading the next line
489 }
490
491 // Read eigenvectors from input stream
492 istr.getline(buf,512);
493 while (!(buf[0]=='#'&& buf[1]=='#')) { // if line starts with ## return
494 char* p = buf;
495 while(*p==' ' || *p=='\t') p++; // 'remove' leading whitespace
496 if (*p=='#' || *p=='\0') {
497 istr.getline(buf,512);
498 continue; // if comment or empty line, read the next line
499 }
500 std::stringstream sstr(buf);
501 sstr >> strvar;
502 if (strvar=="signal" || strvar=="background") {
503
504 // coverity[tainted_data_argument]
505 sstr >> nrows >> dummy >> ncols;
506 Int_t sbType = (strvar=="signal" ? 0 : 1);
507
508 if (fEigenVectors[sbType] == 0) fEigenVectors[sbType] = new TMatrixD( nrows, ncols );
509 else fEigenVectors[sbType]->ResizeTo( nrows, ncols );
510
511 // now read matrix entries
512 for (Int_t row = 0; row<fEigenVectors[sbType]->GetNrows(); row++) {
513 for (Int_t col = 0; col<fEigenVectors[sbType]->GetNcols(); col++) {
514 istr >> (*fEigenVectors[sbType])[row][col];
515 }
516 }
517
518 } // done reading matrix
519 istr.getline(buf,512); // reading the next line
520 }
521 fMeanValues[2] = new TVectorD( *fMeanValues[classIdx] );
522 fEigenVectors[2] = new TMatrixD( *fEigenVectors[classIdx] );
523
524 SetCreated();
525}
526
527////////////////////////////////////////////////////////////////////////////////
528/// creates C++ code fragment of the PCA transform for inclusion in standalone C++ class
529
532{
533 UInt_t nvar = fEigenVectors[0]->GetNrows();
534
535 // creates a PCA transformation function
536 UInt_t numC = fMeanValues.size();
537 if (part==1) {
538 fout << std::endl;
539 fout << " void X2P_"<<trCounter<<"( const double*, double*, int ) const;" << std::endl;
540 fout << " double fMeanValues_"<<trCounter<<"["<<numC<<"]["
541 << fMeanValues[0]->GetNrows() << "];" << std::endl; // mean values
542 fout << " double fEigenVectors_"<<trCounter<<"["<<numC<<"]["
543 << fEigenVectors[0]->GetNrows() << "]["
544 << fEigenVectors[0]->GetNcols() <<"];" << std::endl; // eigenvectors
545 fout << std::endl;
546 }
547
548 // sanity check
549 if (numC>1){
550 if (fMeanValues[0]->GetNrows() != fMeanValues[1]->GetNrows() ||
551 fEigenVectors[0]->GetNrows() != fEigenVectors[1]->GetNrows() ||
552 fEigenVectors[0]->GetNcols() != fEigenVectors[1]->GetNcols()) {
553 Log() << kFATAL << "<MakeFunction> Mismatch in vector/matrix dimensions" << Endl;
554 }
555 }
556
557 if (part==2) {
558
559 fout << std::endl;
560 fout << "//_______________________________________________________________________" << std::endl;
561 fout << "inline void " << fcncName << "::X2P_"<<trCounter<<"( const double* x, double* p, int index ) const" << std::endl;
562 fout << "{" << std::endl;
563 fout << " // Calculate the principal components from the original data vector" << std::endl;
564 fout << " // x, and return it in p (function extracted from TPrincipal::X2P)" << std::endl;
565 fout << " // It's the users responsibility to make sure that both x and p are" << std::endl;
566 fout << " // of the right size (i.e., memory must be allocated for p)." << std::endl;
567 fout << " const int nVar = " << nvar << ";" << std::endl;
568 fout << std::endl;
569 fout << " for (int i = 0; i < nVar; i++) {" << std::endl;
570 fout << " p[i] = 0;" << std::endl;
571 fout << " for (int j = 0; j < nVar; j++) p[i] += (x[j] - fMeanValues_"<<trCounter<<"[index][j]) * fEigenVectors_"<<trCounter<<"[index][j][i];" << std::endl;
572 fout << " }" << std::endl;
573 fout << "}" << std::endl;
574 fout << std::endl;
575 fout << "//_______________________________________________________________________" << std::endl;
576 fout << "inline void " << fcncName << "::InitTransform_"<<trCounter<<"()" << std::endl;
577 fout << "{" << std::endl;
578 fout << " // PCA transformation, initialisation" << std::endl;
579
580 // fill vector of mean values
581 fout << " // initialise vector of mean values" << std::endl;
582 std::streamsize dp = fout.precision();
583 for (UInt_t index=0; index<numC; index++) {
584 for (int i=0; i<fMeanValues[index]->GetNrows(); i++) {
585 fout << " fMeanValues_"<<trCounter<<"["<<index<<"]["<<i<<"] = " << std::setprecision(12)
586 << (*fMeanValues[index])(i) << ";" << std::endl;
587 }
588 }
589
590 // fill matrix of eigenvectors
591 fout << std::endl;
592 fout << " // initialise matrix of eigenvectors" << std::endl;
593 for (UInt_t index=0; index<numC; index++) {
594 for (int i=0; i<fEigenVectors[index]->GetNrows(); i++) {
595 for (int j=0; j<fEigenVectors[index]->GetNcols(); j++) {
596 fout << " fEigenVectors_"<<trCounter<<"["<<index<<"]["<<i<<"]["<<j<<"] = " << std::setprecision(12)
597 << (*fEigenVectors[index])(i,j) << ";" << std::endl;
598 }
599 }
600 }
601 fout << std::setprecision(dp);
602 fout << "}" << std::endl;
603 fout << std::endl;
604 fout << "//_______________________________________________________________________" << std::endl;
605 fout << "inline void " << fcncName << "::Transform_"<<trCounter<<"( std::vector<double>& iv, int cls ) const" << std::endl;
606 fout << "{" << std::endl;
607 fout << " // PCA transformation" << std::endl;
608 fout << " const int nVar = " << nvar << ";" << std::endl;
609 fout << " double *dv = new double[nVar];" << std::endl;
610 fout << " double *rv = new double[nVar];" << std::endl;
611 fout << " if (cls < 0 || cls > "<<GetNClasses()<<") {"<< std::endl;
612 fout << " if ("<<GetNClasses()<<" > 1 ) cls = "<<GetNClasses()<<";"<< std::endl;
613 fout << " else cls = "<<(numC==1?0:2)<<";"<< std::endl;
614 fout << " }"<< std::endl;
615
617
618 fout << " for (int ivar=0; ivar<nVar; ivar++) dv[ivar] = iv[indicesGet.at(ivar)];" << std::endl;
619
620 fout << std::endl;
621 fout << " // Perform PCA and put it into PCAed events tree" << std::endl;
622 fout << " this->X2P_"<<trCounter<<"( dv, rv, cls );" << std::endl;
623 fout << " for (int ivar=0; ivar<nVar; ivar++) iv[indicesPut.at(ivar)] = rv[ivar];" << std::endl;
624
625 fout << std::endl;
626 fout << " delete [] dv;" << std::endl;
627 fout << " delete [] rv;" << std::endl;
628 fout << "}" << std::endl;
629 }
630}
char Char_t
Character 1 byte (char)
Definition RtypesCore.h:51
unsigned int UInt_t
Unsigned integer 4 bytes (unsigned int)
Definition RtypesCore.h:60
float Float_t
Float 4 bytes (float)
Definition RtypesCore.h:71
constexpr Bool_t kFALSE
Definition RtypesCore.h:108
double Double_t
Double 8 bytes.
Definition RtypesCore.h:73
constexpr Bool_t kTRUE
Definition RtypesCore.h:107
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
winID h TVirtualViewer3D TVirtualGLPainter p
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void input
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t mask
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t index
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void value
TMatrixT< Double_t > TMatrixD
Definition TMatrixDfwd.h:23
TVectorT< Double_t > TVectorD
Definition TVectorDfwd.h:23
Class that contains all the data information.
Definition DataSetInfo.h:62
Bool_t AddRawLine(void *node, const char *raw)
XML helpers.
Definition Tools.cxx:1190
TString StringFromDouble(Double_t d)
string tools
Definition Tools.cxx:1233
const char * GetName(void *node)
XML helpers.
Definition Tools.cxx:1182
void ReadAttr(void *node, const char *, T &value)
read attribute from xml
Definition Tools.h:329
void * GetChild(void *parent, const char *childname=nullptr)
get child node
Definition Tools.cxx:1150
void AddAttr(void *node, const char *, const T &value, Int_t precision=16)
add attribute to xml
Definition Tools.h:347
void * AddChild(void *parent, const char *childname, const char *content=nullptr, bool isRootNode=false)
add child node
Definition Tools.cxx:1124
void * GetNextChild(void *prevchild, const char *childname=nullptr)
XML helpers.
Definition Tools.cxx:1162
Singleton class for Global types used by TMVA.
Definition Types.h:71
void MakeFunction(std::ostream &fout, const TString &fncName, Int_t part, UInt_t trCounter, Int_t cls) override
creates C++ code fragment of the PCA transform for inclusion in standalone C++ class
void CalculatePrincipalComponents(const std::vector< Event * > &)
calculate the principal components for the signal and the background data it uses the MakePrincipal m...
void WriteTransformationToStream(std::ostream &) const override
write mean values to stream
void P2X(std::vector< Float_t > &, const std::vector< Float_t > &, Int_t cls) const
Perform the back-transformation from the principal components pc, and return x It's the users respons...
Bool_t PrepareTransformation(const std::vector< Event * > &) override
calculate the principal components using the ROOT class TPrincipal and the normalization
virtual ~VariablePCATransform(void)
destructor
const Event * InverseTransform(const Event *const, Int_t cls) const override
apply the principal component analysis TODO: implementation of inverse transformation Log() << kFATAL...
void Initialize() override
initialization of the transformation.
const Event * Transform(const Event *const, Int_t cls) const override
apply the principal component analysis
void X2P(std::vector< Float_t > &, const std::vector< Float_t > &, Int_t cls) const
Calculate the principal components from the original data vector x, and return it in p (function extr...
void ReadTransformationFromStream(std::istream &, const TString &) override
Read mean values from input stream.
VariablePCATransform(DataSetInfo &dsi)
constructor
void ReadFromXML(void *trfnode) override
Read the transformation matrices from the xml node.
void AttachXMLTo(void *parent) override
create XML description of PCA transformation
Linear interpolation class.
virtual void MakeFunction(std::ostream &fout, const TString &fncName, Int_t part, UInt_t trCounter, Int_t cls)=0
getinput and setoutput equivalent
virtual void ReadFromXML(void *trfnode)=0
Read the input variables from the XML node.
virtual void AttachXMLTo(void *parent)=0
create XML description the transformation (write out info of selected variables)
Principal Components Analysis (PCA)
Definition TPrincipal.h:21
Basic string class.
Definition TString.h:138
Double_t x[n]
Definition legend1.C:17
Tools & gTools()
MsgLogger & Endl(MsgLogger &ml)
Definition MsgLogger.h:148
static void output()