evtgen is hosted by Hepforge, IPPP Durham
EvtGen  2.0.0
Monte Carlo generator of particle decays, in particular the weak decays of heavy flavour particles such as B mesons.
EvtSpinDensity.cpp
Go to the documentation of this file.
1 
2 /***********************************************************************
3 * Copyright 1998-2020 CERN for the benefit of the EvtGen authors *
4 * *
5 * This file is part of EvtGen. *
6 * *
7 * EvtGen 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 * EvtGen 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 EvtGen. If not, see <https://www.gnu.org/licenses/>. *
19 ***********************************************************************/
20 
22 
23 #include "EvtGenBase/EvtComplex.hh"
24 #include "EvtGenBase/EvtPatches.hh"
25 #include "EvtGenBase/EvtReport.hh"
26 
27 #include <assert.h>
28 #include <iostream>
29 #include <math.h>
30 #include <stdlib.h>
31 using std::endl;
32 using std::ostream;
33 
35 {
36  dim = 0;
37  rho = 0;
38 
39  int i, j;
40  setDim( density.dim );
41 
42  for ( i = 0; i < dim; i++ ) {
43  for ( j = 0; j < dim; j++ ) {
44  rho[i][j] = density.rho[i][j];
45  }
46  }
47 }
48 
50 {
51  int i, j;
52  setDim( density.dim );
53 
54  for ( i = 0; i < dim; i++ ) {
55  for ( j = 0; j < dim; j++ ) {
56  rho[i][j] = density.rho[i][j];
57  }
58  }
59 
60  return *this;
61 }
62 
64 {
65  if ( dim != 0 ) {
66  int i;
67  for ( i = 0; i < dim; i++ )
68  delete[] rho[i];
69  }
70 
71  delete[] rho;
72 }
73 
75 {
76  dim = 0;
77  rho = 0;
78 }
79 
81 {
82  if ( dim == n )
83  return;
84  if ( dim != 0 ) {
85  int i;
86  for ( i = 0; i < dim; i++ )
87  delete[] rho[i];
88  delete[] rho;
89  rho = 0;
90  dim = 0;
91  }
92  if ( n == 0 )
93  return;
94  dim = n;
95  rho = new EvtComplexPtr[n];
96  int i;
97  for ( i = 0; i < n; i++ ) {
98  rho[i] = new EvtComplex[n];
99  }
100 }
101 
103 {
104  return dim;
105 }
106 
107 void EvtSpinDensity::set( int i, int j, const EvtComplex& rhoij )
108 {
109  assert( i < dim && j < dim );
110  rho[i][j] = rhoij;
111 }
112 
113 const EvtComplex& EvtSpinDensity::get( int i, int j ) const
114 {
115  assert( i < dim && j < dim );
116  return rho[i][j];
117 }
118 
120 {
121  setDim( n );
122  int i, j;
123 
124  for ( i = 0; i < n; i++ ) {
125  for ( j = 0; j < n; j++ ) {
126  rho[i][j] = EvtComplex( 0.0 );
127  }
128  rho[i][i] = EvtComplex( 1.0 );
129  }
130 }
131 
133 {
134  int i, j;
135  EvtComplex prob( 0.0, 0.0 );
136  double norm = 0.0;
137 
138  if ( dim != d.dim ) {
139  EvtGenReport( EVTGEN_ERROR, "EvtGen" )
140  << "Not matching dimensions in NormalizedProb" << endl;
141  ::abort();
142  }
143 
144  for ( i = 0; i < dim; i++ ) {
145  norm += real( rho[i][i] );
146  for ( j = 0; j < dim; j++ ) {
147  prob += rho[i][j] * d.rho[i][j];
148  }
149  }
150 
151  if ( imag( prob ) > 0.00000001 * real( prob ) ) {
152  EvtGenReport( EVTGEN_ERROR, "EvtGen" )
153  << "Imaginary probability:" << prob << " " << norm << endl;
154  }
155  if ( real( prob ) < 0.0 ) {
156  EvtGenReport( EVTGEN_ERROR, "EvtGen" )
157  << "Negative probability:" << prob << " " << norm << endl;
158  }
159 
160  return real( prob ) / norm;
161 }
162 
164 {
165  if ( dim < 1 ) {
166  EvtGenReport( EVTGEN_ERROR, "EvtGen" )
167  << "dim=" << dim << "in SpinDensity::Check" << endl;
168  }
169 
170  int i, j;
171 
172  double trace( 0.0 );
173 
174  for ( i = 0; i < dim; i++ ) {
175  trace += abs( rho[i][i] );
176  }
177 
178  for ( i = 0; i < dim; i++ ) {
179  if ( real( rho[i][i] ) < 0.0 )
180  return 0;
181  if ( imag( rho[i][i] ) * 1000000.0 > trace ) {
182  EvtGenReport( EVTGEN_INFO, "EvtGen" ) << *this << endl;
183  EvtGenReport( EVTGEN_INFO, "EvtGen" ) << trace << endl;
184  EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "Failing 1" << endl;
185  return 0;
186  }
187  }
188 
189  for ( i = 0; i < dim; i++ ) {
190  for ( j = i + 1; j < dim; j++ ) {
191  if ( fabs( real( rho[i][j] - rho[j][i] ) ) >
192  0.00000001 * ( abs( rho[i][i] ) + abs( rho[j][j] ) ) ) {
193  EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "Failing 2" << endl;
194  return 0;
195  }
196  if ( fabs( imag( rho[i][j] + rho[j][i] ) ) >
197  0.00000001 * ( abs( rho[i][i] ) + abs( rho[j][j] ) ) ) {
198  EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "Failing 3" << endl;
199  return 0;
200  }
201  }
202  }
203 
204  return 1;
205 }
206 
207 ostream& operator<<( ostream& s, const EvtSpinDensity& d )
208 {
209  int i, j;
210 
211  s << endl;
212  s << "Dimension:" << d.dim << endl;
213 
214  for ( i = 0; i < d.dim; i++ ) {
215  for ( j = 0; j < d.dim; j++ ) {
216  s << d.rho[i][j] << " ";
217  }
218  s << endl;
219  }
220 
221  return s;
222 }
void setDiag(int n)
std::ostream & EvtGenReport(EvtGenSeverity severity, const char *facility=0)
Definition: EvtReport.cpp:33
const EvtComplex & get(int i, int j) const
EvtSpinDensity & operator=(const EvtSpinDensity &density)
virtual ~EvtSpinDensity()
double abs(const EvtComplex &c)
Definition: EvtComplex.hh:201
double imag(const EvtComplex &c)
Definition: EvtComplex.hh:235
int getDim() const
void set(int i, int j, const EvtComplex &rhoij)
EvtComplexPtrPtr rho
void setDim(int n)
double real(const EvtComplex &c)
Definition: EvtComplex.hh:230
ostream & operator<<(ostream &s, const EvtSpinDensity &d)
double normalizedProb(const EvtSpinDensity &d)