CMS 3D CMS Logo

MiniPropagators.cc
Go to the documentation of this file.
2 #include "vdt/atan2.h"
3 #include "vdt/tan.h"
4 #include "vdt/sincos.h"
5 #include "vdt/sqrt.h"
6 
8 
9  State::State(const MPlexLV& par, int ti) {
10  x = par.constAt(ti, 0, 0);
11  y = par.constAt(ti, 1, 0);
12  z = par.constAt(ti, 2, 0);
13  const float pt = 1.0f / par.constAt(ti, 3, 0);
14  px = pt * std::cos(par.constAt(ti, 4, 0));
15  py = pt * std::sin(par.constAt(ti, 4, 0));
16  pz = pt / std::tan(par.constAt(ti, 5, 0));
17  }
18 
19  bool InitialState::propagate_to_r(PropAlgo_e algo, float R, State& c, bool update_momentum) const {
20  switch (algo) {
21  case PA_Line: {
22  }
23  case PA_Quadratic: {
24  }
25 
26  case PA_Exact: {
27  // Momentum is always updated -- used as temporary for stepping.
28  const float k = 1.0f / inv_k;
29 
30  const float curv = 0.5f * inv_k * inv_pt;
31  const float oo_curv = 1.0f / curv; // 2 * radius of curvature
32  const float lambda = pz * inv_pt;
33 
34  float D = 0;
35 
36  c = *this;
37  c.dalpha = 0;
38  for (int i = 0; i < Config::Niter; ++i) {
39  // compute tangental and ideal distance for the current iteration.
40  // 3-rd order asin for symmetric incidence (shortest arc lenght).
41  float r0 = std::hypot(c.x, c.y);
42  float td = (R - r0) * curv;
43  float id = oo_curv * td * (1.0f + 0.16666666f * td * td);
44  // This would be for line approximation:
45  // float id = R - r0;
46  D += id;
47 
48  //printf("%-3d r0=%f R-r0=%f td=%f id=%f id_line=%f delta_id=%g\n",
49  // i, r0, R-r0, td, id, R - r0, id - (R-r0));
50 
51  float alpha = id * inv_pt * inv_k;
52  float sina, cosa;
53  vdt::fast_sincosf(alpha, sina, cosa);
54 
55  // update parameters
56  c.dalpha += alpha;
57  c.x += k * (c.px * sina - c.py * (1.0f - cosa));
58  c.y += k * (c.py * sina + c.px * (1.0f - cosa));
59 
60  const float o_px = c.px; // copy before overwriting
61  c.px = c.px * cosa - c.py * sina;
62  c.py = c.py * cosa + o_px * sina;
63  }
64 
65  c.z += lambda * D;
66  }
67  }
68  // should have some epsilon constant / member? relative vs. abs?
69  c.fail_flag = std::abs(std::hypot(c.x, c.y) - R) < 0.1f ? 0 : 1;
70  return c.fail_flag;
71  }
72 
73  bool InitialState::propagate_to_z(PropAlgo_e algo, float Z, State& c, bool update_momentum) const {
74  switch (algo) {
75  case PA_Line: {
76  }
77  case PA_Quadratic: {
78  }
79 
80  case PA_Exact: {
81  const float k = 1.0f / inv_k;
82 
83  const float dz = Z - z;
84  const float alpha = dz * inv_k / pz;
85 
86  float sina, cosa;
87  vdt::fast_sincosf(alpha, sina, cosa);
88 
89  c.dalpha = alpha;
90  c.x = x + k * (px * sina - py * (1.0f - cosa));
91  c.y = y + k * (py * sina + px * (1.0f - cosa));
92  c.z = Z;
93 
94  if (update_momentum) {
95  c.px = px * cosa - py * sina;
96  c.py = py * cosa + px * sina;
97  c.pz = pz;
98  }
99  } break;
100  }
101  c.fail_flag = 0;
102  return c.fail_flag;
103  }
104 
105  //===========================================================================
106  // Vectorized version
107  //===========================================================================
108 
109  MPF fast_atan2(const MPF& y, const MPF& x) {
110  MPF t;
111  for (int i = 0; i < y.kTotSize; ++i) {
112  t[i] = vdt::fast_atan2f(y[i], x[i]);
113  }
114  return t;
115  }
116 
117  MPF fast_tan(const MPF& a) {
118  MPF t;
119  for (int i = 0; i < a.kTotSize; ++i) {
120  t[i] = vdt::fast_tanf(a[i]);
121  }
122  return t;
123  }
124 
125  void fast_sincos(const MPF& a, MPF& s, MPF& c) {
126  for (int i = 0; i < a.kTotSize; ++i) {
127  vdt::fast_sincosf(a[i], s[i], c[i]);
128  }
129  }
130 
132  x = par.ReduceFixedIJ(0, 0);
133  y = par.ReduceFixedIJ(1, 0);
134  z = par.ReduceFixedIJ(2, 0);
135  const MPF pt = 1.0f / par.ReduceFixedIJ(3, 0);
136  fast_sincos(par.ReduceFixedIJ(4, 0), py, px);
137  px *= pt;
138  py *= pt;
139  pz = pt / fast_tan(par.ReduceFixedIJ(5, 0));
140  }
141 
142  // propagate to radius; returns number of failed propagations
144  PropAlgo_e algo, const MPF& R, StatePlex& c, bool update_momentum, int N_proc) const {
145  switch (algo) {
146  case PA_Line: {
147  }
148  case PA_Quadratic: {
149  }
150 
151  case PA_Exact: {
152  // Momentum is always updated -- used as temporary for stepping.
153  const MPF k = 1.0f / inv_k;
154 
155  const MPF curv = 0.5f * inv_k * inv_pt;
156  const MPF oo_curv = 1.0f / curv; // 2 * radius of curvature
157  const MPF lambda = pz * inv_pt;
158 
159  MPF D = 0;
160 
161  c = *this;
162  c.dalpha = 0;
163  for (int i = 0; i < Config::Niter; ++i) {
164  // compute tangental and ideal distance for the current iteration.
165  // 3-rd order asin for symmetric incidence (shortest arc lenght).
166  MPF r0 = Matriplex::hypot(c.x, c.y);
167  MPF td = (R - r0) * curv;
168  MPF id = oo_curv * td * (1.0f + 0.16666666f * td * td);
169  // This would be for line approximation:
170  // float id = R - r0;
171  D += id;
172 
173  //printf("%-3d r0=%f R-r0=%f td=%f id=%f id_line=%f delta_id=%g\n",
174  // i, r0, R-r0, td, id, R - r0, id - (R-r0));
175 
176  MPF alpha = id * inv_pt * inv_k;
177 
178  MPF sina, cosa;
179  fast_sincos(alpha, sina, cosa);
180 
181  // update parameters
182  c.dalpha += alpha;
183  c.x += k * (c.px * sina - c.py * (1.0f - cosa));
184  c.y += k * (c.py * sina + c.px * (1.0f - cosa));
185 
186  MPF o_px = c.px; // copy before overwriting
187  c.px = c.px * cosa - c.py * sina;
188  c.py = c.py * cosa + o_px * sina;
189  }
190 
191  c.z += lambda * D;
192  }
193  }
194 
195  // should have some epsilon constant / member? relative vs. abs?
196  MPF r = Matriplex::hypot(c.x, c.y);
197  c.fail_flag = 0;
198  int n_fail = 0;
199  for (int i = 0; i < N_proc; ++i) {
200  if (std::abs(R[i] - r[i]) > 0.1f) {
201  c.fail_flag[i] = 1;
202  ++n_fail;
203  }
204  }
205  return n_fail;
206  }
207 
209  PropAlgo_e algo, const MPF& Z, StatePlex& c, bool update_momentum, int N_proc) const {
210  switch (algo) {
211  case PA_Line: {
212  }
213  case PA_Quadratic: {
214  }
215 
216  case PA_Exact: {
217  MPF k = 1.0f / inv_k;
218 
219  MPF dz = Z - z;
220  MPF alpha = dz * inv_k / pz;
221 
222  MPF sina, cosa;
223  fast_sincos(alpha, sina, cosa);
224 
225  c.dalpha = alpha;
226  c.x = x + k * (px * sina - py * (1.0f - cosa));
227  c.y = y + k * (py * sina + px * (1.0f - cosa));
228  c.z = Z;
229 
230  if (update_momentum) {
231  c.px = px * cosa - py * sina;
232  c.py = py * cosa + px * sina;
233  c.pz = pz;
234  }
235  } break;
236  }
237  c.fail_flag = 0;
238  return 0;
239  }
240 
241 } // namespace mkfit::mini_propagators
MPlex< T, D1, D2, N > hypot(const MPlex< T, D1, D2, N > &a, const MPlex< T, D1, D2, N > &b)
Definition: Matriplex.h:417
Sin< T >::type sin(const T &t)
Definition: Sin.h:22
int propagate_to_r(PropAlgo_e algo, const MPF &R, StatePlex &c, bool update_momentum, int N_proc=NN) const
int propagate_to_z(PropAlgo_e algo, const MPF &Z, StatePlex &c, bool update_momentum, int N_proc=NN) const
Matriplex::Matriplex< float, LL, 1, NN > MPlexLV
Definition: Matrix.h:49
bool propagate_to_z(PropAlgo_e algo, float Z, State &c, bool update_momentum) const
Cos< T >::type cos(const T &t)
Definition: Cos.h:22
MPF fast_tan(const MPF &a)
Tan< T >::type tan(const T &t)
Definition: Tan.h:22
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
double f[11][100]
DecomposeProduct< arg, typename Div::arg > D
Definition: Factorize.h:141
double a
Definition: hdecay.h:121
float x
MPF fast_atan2(const MPF &y, const MPF &x)
void fast_sincos(const MPF &a, MPF &s, MPF &c)
bool propagate_to_r(PropAlgo_e algo, float R, State &c, bool update_momentum) const
constexpr int Niter
Definition: Config.h:49