NAGASH 0.9.8
Next Generation Analysis System
Loading...
Searching...
No Matches
PCATool.cxx
Go to the documentation of this file.
1//***************************************************************************************
4//***************************************************************************************
5
6#include "NAGASH/PCATool.h"
7
8using namespace std;
9using namespace NAGASH;
10using namespace Eigen;
11
12namespace NAGASH
13{
14 PCATool::PCATool(std::shared_ptr<MSGTool> MSG, int size) : Tool(MSG)
15 {
16 Size = size;
17 Covariance_Matrix = MatrixXd(size, size);
18 Observable_Vector = VectorXd(size);
19 }
20
21 void PCATool::SetObservable(int index, double val)
22 {
23 auto titleguard = MSGUser()->StartTitleWithGuard("PCATool::SetObservable");
24 if (index < 0 || index >= Size)
25 {
26 MSGUser()->MSG_ERROR("Observable index out of range: ", index);
27 return;
28 }
29 Observable_Vector(index) = val;
30 }
31
32 void PCATool::SetCovariance(int index_i, int index_j, double cov)
33 {
34 auto titleguard = MSGUser()->StartTitleWithGuard("PCATool::SetCovariance");
35 if (index_i < 0 || index_i >= Size)
36 {
37 MSGUser()->MSG_ERROR("Observable index out of range: ", index_i);
38 return;
39 }
40 if (index_j < 0 || index_j >= Size)
41 {
42 MSGUser()->MSG_ERROR("Observable index out of range: ", index_j);
43 return;
44 }
45 if (index_i > index_j)
46 SetCovariance(index_j, index_i, cov);
47
48 Covariance_Matrix(index_i, index_j) = cov;
49 Covariance_Matrix(index_j, index_i) = cov;
50 isProcessed = false;
51 }
52
53 void PCATool::SetUncertainty(int index, double unc)
54 {
55 auto titleguard = MSGUser()->StartTitleWithGuard("PCATool::SetUncertainty");
56 SetCovariance(index, index, unc * unc);
57 }
58
60 {
61 auto titleguard = MSGUser()->StartTitleWithGuard("PCATool::Process");
62
63 MSGUser()->MSG_INFO("Calculate Eigen Values");
64 Eigen::SelfAdjointEigenSolver<Eigen::MatrixXd> eigensolver(Covariance_Matrix);
65 if (eigensolver.info() != Eigen::Success)
66 abort();
67 EigenValue = eigensolver.eigenvalues();
68 MSGUser()->MSG_INFO("Calculate Eigen Vectors");
69 Transform_Matrix = eigensolver.eigenvectors();
70 MSGUser()->MSG_INFO("Calculate New Correlation Matrix");
72 MSGUser()->MSG_INFO("Calculate Rotated Observables");
74
75 MSGUser()->MSG_INFO("Calculate Inverse Transform Matrix");
76 MatrixXd TransMatrix_Inv = Transform_Matrix.transpose().inverse();
77 MSGUser()->MSG_INFO("Calculate New Variations");
78 MSGUser()->MSG_INFO("Decide NVariations");
79 MatrixXd m_Covariance_Matrix(Size, Size);
80 for (int i = 0; i < Size; i++)
81 for (int j = 0; j < Size; j++)
82 m_Covariance_Matrix(i, j) = 0;
83
84 for (int i = 0; i < Size; i++)
85 {
86 for (int j = 0; j < 2; j++)
87 {
88 double factor = 0;
89 if (j == 0)
90 factor = 1;
91 else
92 factor = -1;
93
94 VectorXd RotatedNewVariation = New_Observable_Vector;
95 RotatedNewVariation(Size - 1 - i) = New_Observable_Vector(Size - 1 - i) +
96 factor * sqrt(New_Covariance_Matrix(Size - 1 - i, Size - 1 - i));
97 VectorXd newvar = TransMatrix_Inv * RotatedNewVariation;
98 if (j == 0)
99 New_Observable_UpVariations.push_back(newvar);
100 else
101 New_Observable_DownVariations.push_back(newvar);
102 }
103
104 for (int j = 0; j < Size; j++)
105 {
106 for (int k = 0; k < Size; k++)
107 {
108 double diff_j = (New_Observable_UpVariations[i])(j)-Observable_Vector(j);
109 double diff_k = (New_Observable_UpVariations[i])(k)-Observable_Vector(k);
110
111 m_Covariance_Matrix(j, k) = m_Covariance_Matrix(j, k) + diff_j * diff_k;
112 }
113 }
114
115 // Check Unc
116 bool isOK = true;
117 for (int j = 0; j < Size; j++)
118 {
119 double unc = sqrt(Covariance_Matrix(j, j));
120 if (unc < 1e-8)
121 continue;
122 double m_unc = sqrt(m_Covariance_Matrix(j, j));
123
124 double factor = 1.0;
125 int iunc = factor * unc;
126 while (iunc < 10 || iunc >= 100)
127 {
128 if (iunc < 10)
129 {
130 factor = factor * 10;
131 }
132 if (iunc >= 100)
133 {
134 factor = factor / 10;
135 }
136 iunc = factor * unc;
137 }
138
139 int imunc = factor * m_unc;
140 if (imunc != iunc)
141 {
142 isOK = false;
143 break;
144 }
145 }
146
147 if (isOK)
148 {
149 NVariation = i + 1;
150 break;
151 }
152 }
153
154 if (NVariation < 0)
156
157 isProcessed = true;
158 }
159
161 {
162 if (!isProcessed)
163 Process();
164 return NVariation;
165 }
166
167 double PCATool::GetPCAResult(int ivar, int index, double nsigma)
168 {
169 auto titleguard = MSGUser()->StartTitleWithGuard("PCATool::GetPCAResult");
170 if (ivar < 0 || ivar >= Size)
171 {
172 MSGUser()->MSG_ERROR("Variation Index not in range: ", ivar);
173 return 0;
174 }
175 if (index < 0 || index >= Size)
176 {
177 MSGUser()->MSG_ERROR("Observable Index not in range: ", index);
178 return 0;
179 }
180
181 if (!isProcessed)
182 Process();
183
184 if (ivar >= NVariation)
185 {
186 MSGUser()->MSG_ERROR("Variation Index larger than NVariation: ", ivar);
187 return 0;
188 }
189
190 double diff;
191 if (nsigma > 0)
192 {
193 diff = (New_Observable_UpVariations[ivar])(index)-Observable_Vector(index);
194 }
195 else
196 {
197 diff = (New_Observable_DownVariations[ivar])(index)-Observable_Vector(index);
198 }
199 return fabs(nsigma) * diff + Observable_Vector(index);
200 }
201
202 double PCATool::GetPCAResult(int index)
203 {
204 auto titleguard = MSGUser()->StartTitleWithGuard("PCATool::GetPCAResult");
205 if (index < 0 || index >= Size)
206 {
207 MSGUser()->MSG_ERROR("Observable Index not in range: ", index);
208 return 0;
209 }
210 if (!isProcessed)
211 Process();
212 return New_Observable_Vector(index);
213 }
214
215 double PCATool::GetPCAUpVariation(int ivar, int index)
216 {
217 return GetPCAResult(ivar, index, 1.0);
218 }
219
220 double PCATool::GetPCADownVariation(int ivar, int index)
221 {
222 return GetPCAResult(ivar, index, -1.0);
223 }
224
225 double PCATool::GetEigenValue(int ivar)
226 {
227 if (ivar < 0 || ivar >= Size)
228 {
229 MSGUser()->MSG_ERROR("Variation Index not in range: ", ivar);
230 return 0;
231 }
232 if (!isProcessed)
233 Process();
234 return EigenValue(Size - 1 - ivar);
235 }
236} // namespace NAGASH
double GetPCADownVariation(int ivar, int index)
Definition PCATool.cxx:220
Eigen::VectorXd Observable_Vector
Definition PCATool.h:53
PCATool(std::shared_ptr< MSGTool > MSG, int size)
Definition PCATool.cxx:14
double GetEigenValue(int ivar)
Definition PCATool.cxx:225
Eigen::MatrixXd Covariance_Matrix
Definition PCATool.h:49
double GetPCAResult(int ivar, int index, double nsigma)
Definition PCATool.cxx:167
std::vector< Eigen::VectorXd > New_Observable_UpVariations
Definition PCATool.h:58
void SetObservable(int index, double val)
Definition PCATool.cxx:21
bool isProcessed
Definition PCATool.h:45
void SetUncertainty(int index, double unc)
Definition PCATool.cxx:53
double GetPCAUpVariation(int ivar, int index)
Definition PCATool.cxx:215
Eigen::VectorXd EigenValue
Definition PCATool.h:56
void SetCovariance(int index_i, int index_j, double cov)
Definition PCATool.cxx:32
Eigen::MatrixXd Transform_Matrix
Definition PCATool.h:50
Eigen::MatrixXd New_Covariance_Matrix
Definition PCATool.h:51
int GetNPCAVariation()
Definition PCATool.cxx:160
std::vector< Eigen::VectorXd > New_Observable_DownVariations
Definition PCATool.h:59
Eigen::VectorXd New_Observable_Vector
Definition PCATool.h:54
Provide interface for all tools in NAGASH.
Definition Tool.h:72
std::shared_ptr< MSGTool > MSGUser()
return the MSGTool inside.
Definition Tool.h:91