ROOTPWA
testPWALikeli.cc
Go to the documentation of this file.
1 
2 //
3 // Copyright 2009 Sebastian Neubert
4 //
5 // This file is part of rootpwa
6 //
7 // rootpwa is free software: you can redistribute it and/or modify
8 // it under the terms of the GNU General Public License as published by
9 // the Free Software Foundation, either version 3 of the License, or
10 // (at your option) any later version.
11 //
12 // rootpwa is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU General Public License for more details.
16 //
17 // You should have received a copy of the GNU General Public License
18 // along with rootpwa. If not, see <http://www.gnu.org/licenses/>.
19 //
21 //-----------------------------------------------------------
22 // File and Version Information:
23 // $Id$
24 //
25 // Description:
26 // test likelihood calculation
27 // program should be executed in amplitude directory
28 //
29 //
30 // Author List:
31 // Sebastian Neubert TUM (original author)
32 //
33 //
34 //-----------------------------------------------------------
35 
36 
37 #include "TRandom3.h"
38 
39 #include "TPWALikelihood.h"
40 
41 #include "reportingUtils.hpp"
42 
43 
44 using namespace std;
45 using namespace rpwa;
46 
47 
48 int
49 main(int argc,
50  char** argv)
51 {
52  if (argc < 2) {
53  printErr << "need wave list file name as argument. aborting." << endl;
54  throw;
55  }
56  const bool useNormalizedAmps = false; // if true normalized amplitudes are used
57  const unsigned int rank = 2; // rank of spin-density matrix
58  const string waveListFileName = argv[1]; // wavelist filename
59  const string normIntFileName = "norm.int"; // file with normalization integrals
60  const string accIntFileName = "norm.int"; // file with acceptance integrals
61  const string ampDirName = "."; // decay amplitude directory name
62  const unsigned int numbAccEvents = 0; // number of events used for acceptance integrals
63 
66  L.useNormalizedAmps(useNormalizedAmps);
67  L.init(rank, waveListFileName, normIntFileName, accIntFileName, ampDirName, numbAccEvents);
68  printInfo << L;
69  const unsigned int nmbPar = L.NDim();
70  cout << "number of parameters = " << nmbPar << endl;
71 
72  // set random parameter values
73  //double par[13]={0.52707,0.21068,-0.604365,0.17596,-0.216668,-0.0990815,-0.348459,0.208961,0,0,0,0,0};
74  //double par[13]; for(int i=0;i<13;++i) par[i]=0.001;
75  //string a[13]={"a","b","c","d","e","f","g","h","i","j","k","l","flat"};
76  double par[nmbPar];
77  gRandom->SetSeed(123456789);
78  vector<unsigned int> parIndices = L.orderedParIndices();
79  for (unsigned int i = 0; i < parIndices.size(); ++i) {
80  const unsigned int parIndex = parIndices[i];
81  cout << "parameter[" << i << "] = " << L.parName(parIndex) << endl;
82  par[parIndex] = gRandom->Rndm();
83  }
84 
85  {
86  // printInfo << "parameters:" << endl;
87  // for (unsigned int i = 0; i < nmbPar; ++i)
88  // cout << "par[" << i << "] = " << par[i] << endl;
89  printInfo << "production amplitudes:" << endl;
90  double prodAmpFlat;
91  TPWALikelihood<complex<double> >::ampsArrayType prodAmps;
92  L.copyFromParArray(par, prodAmps, prodAmpFlat);
93  for (unsigned int iRank = 0; iRank < L.rank(); ++iRank)
94  for (unsigned int iRefl = 0; iRefl < 2; ++iRefl)
95  for (unsigned int iWave = 0; iWave < L.nmbWaves(2 * iRefl - 1); ++iWave)
96  cout << "prodAmps[" << iRank << "][" << iRefl << "][" << iWave << "] = "
97  << maxPrecisionDouble(prodAmps[iRank][iRefl][iWave]) << endl;
98  printInfo << "parameters:" << endl;
99  double par2[nmbPar];
100  L.copyToParArray(prodAmps, prodAmpFlat, par2);
101  // for (unsigned int i = 0; i < nmbPar; ++i)
102  // cout << "par[" << i << "] = " << par[i] << endl;
103  for (unsigned int i = 0; i < nmbPar; ++i)
104  cout << "delta par[" << i << "] = " << maxPrecision(par[i] - par2[i]) << endl;
105  }
106  return 0;
107 
108  // calculate log likelihood
109  const double logLikelihood = L.DoEval(par);
110  printInfo << "log likelihood = " << maxPrecision(logLikelihood) << endl;
111 
112  // check derivatives
113  // calculate numerical derivatives
114  double numericalDerivates[nmbPar];
115  {
116  const double delta = 1E-7;
117  for (unsigned int i = 0; i < nmbPar; ++i) {
118  const double oldParVal = par[i];
119  par[i] += delta;
120  const double logLikelihood2 = L.DoEval(par);
121  numericalDerivates[i] = (logLikelihood2 - logLikelihood) / delta;
122  par[i] = oldParVal;
123  }
124  }
125  // calculate analytical derivatives
126  double analyticalDerivates[nmbPar];
127  // double F;
128  // L.FdF(par, F, analyticalDerivates);
129  L.Gradient(par, analyticalDerivates);
130  double maxDelta = 0;
131  printInfo << "derivatives:" << endl;
132  for (unsigned int i = 0; i < parIndices.size(); ++i) {
133  const unsigned int parIndex = parIndices[i];
134  const double delta = numericalDerivates[parIndex] - analyticalDerivates[parIndex];
135  if (abs(delta) > maxDelta)
136  maxDelta = abs(delta);
137  cout << " dL / dPar[" << setw(nmbOfDigits(nmbPar - 1)) << parIndex << "]: numerical = "
138  << maxPrecisionAlign(numericalDerivates[parIndex])
139  << " vs. analytical = " << maxPrecisionAlign(analyticalDerivates[parIndex])
140  << "; (numer. - analyt.) = "
141  << maxPrecisionAlign(delta) << endl;
142  }
143  cout << " maximum deviation = " << maxPrecision(maxDelta) << endl;
144 
145  return 0;
146 }