Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
CladDerivator.h
Go to the documentation of this file.
1/// \file CladDerivator.h
2///
3/// \brief The file is a bridge between ROOT and clad automatic differentiation
4/// plugin.
5///
6/// \author Vassil Vassilev <vvasilev@cern.ch>
7///
8/// \date July, 2018
9
10/*************************************************************************
11 * Copyright (C) 1995-2018, Rene Brun and Fons Rademakers. *
12 * All rights reserved. *
13 * *
14 * For the licensing terms see $ROOTSYS/LICENSE. *
15 * For the list of contributors see $ROOTSYS/README/CREDITS. *
16 *************************************************************************/
17
18#ifndef CLAD_DERIVATOR
19#define CLAD_DERIVATOR
20
21#ifndef __CLING__
22#error "This file must not be included by compiled programs."
23#endif //__CLING__
24
25#include <plugins/include/clad/Differentiator/Differentiator.h>
26#include "TMath.h"
27namespace clad {
28namespace custom_derivatives {
29namespace TMath {
30template <typename T>
31ValueAndPushforward<T, T> Abs_pushforward(T x, T d_x)
32{
33 return {::TMath::Abs(x), ((x < 0) ? -1 : 1) * d_x};
34}
35
36template <typename T>
37ValueAndPushforward<T, T> ACos_pushforward(T x, T d_x)
38{
39 return {::TMath::ACos(x), (-1. / ::TMath::Sqrt(1 - x * x)) * d_x};
40}
41
42template <typename T>
43ValueAndPushforward<T, T> ACosH_pushforward(T x, T d_x)
44{
45 return {::TMath::ACosH(x), (1. / ::TMath::Sqrt(x * x - 1)) * d_x};
46}
47
48template <typename T>
49ValueAndPushforward<T, T> ASin_pushforward(T x, T d_x)
50{
51 return {::TMath::ASin(x), (1. / ::TMath::Sqrt(1 - x * x)) * d_x};
52}
53
54template <typename T>
55ValueAndPushforward<T, T> ASinH_pushforward(T x, T d_x)
56{
57 return {::TMath::ASinH(x), (1. / ::TMath::Sqrt(x * x + 1)) * d_x};
58}
59
60template <typename T>
61ValueAndPushforward<T, T> ATan_pushforward(T x, T d_x)
62{
63 return {::TMath::ATan(x), (1. / (x * x + 1)) * d_x};
64}
65
66template <typename T>
67ValueAndPushforward<T, T> ATanH_pushforward(T x, T d_x)
68{
69 return {::TMath::ATanH(x), (1. / (1 - x * x)) * d_x};
70}
71
72template <typename T>
73ValueAndPushforward<T, T> Cos_pushforward(T x, T d_x)
74{
75 return {::TMath::Cos(x), -::TMath::Sin(x) * d_x};
76}
77
78template <typename T>
79ValueAndPushforward<T, T> CosH_pushforward(T x, T d_x)
80{
81 return {::TMath::CosH(x), ::TMath::SinH(x) * d_x};
82}
83
84template <typename T>
85ValueAndPushforward<T, T> Erf_pushforward(T x, T d_x)
86{
87 return {::TMath::Erf(x), (2 * ::TMath::Exp(-x * x) / ::TMath::Sqrt(::TMath::Pi())) * d_x};
88}
89
90template <typename T>
91ValueAndPushforward<T, T> Erfc_pushforward(T x, T d_x)
92{
93 return {::TMath::Erfc(x), -Erf_pushforward(x, d_x).pushforward};
94}
95
96template <typename T>
97ValueAndPushforward<T, T> Exp_pushforward(T x, T d_x)
98{
99 return {::TMath::Exp(x), ::TMath::Exp(x) * d_x};
100}
101
102template <typename T>
103ValueAndPushforward<T, T> Hypot_pushforward(T x, T y, T d_x, T d_y)
104{
105 return {::TMath::Hypot(x, y), x / ::TMath::Hypot(x, y) * d_x + y / ::TMath::Hypot(x, y) * d_y};
106}
107
108template <typename T, typename U>
109void Hypot_pullback(T x, T y, U p, clad::array_ref<T> d_x, clad::array_ref<T> d_y)
110{
111 T h = ::TMath::Hypot(x, y);
112 *d_x += x / h * p;
113 *d_y += y / h * p;
114}
115
116template <typename T>
117ValueAndPushforward<T, T> Log_pushforward(T x, T d_x)
118{
119 return {::TMath::Log(x), (1. / x) * d_x};
120}
121
122template <typename T>
123ValueAndPushforward<T, T> Log10_pushforward(T x, T d_x)
124{
125 return {::TMath::Log10(x), (1.0 / (x * ::TMath::Ln10())) * d_x};
126}
127
128template <typename T>
129ValueAndPushforward<T, T> Log2_pushforward(T x, T d_x)
130{
131 return {::TMath::Log2(x), (1.0 / (x * ::TMath::Log(2.0))) * d_x};
132}
133
134template <typename T>
135ValueAndPushforward<T, T> Max_pushforward(T x, T y, T d_x, T d_y)
136{
137 T derivative = 0;
138 if (x >= y)
139 derivative = d_x;
140 else
141 derivative = d_y;
142 return {::TMath::Max(x, y), derivative};
143}
144
145template <typename T, typename U>
146void Max_pullback(T a, T b, U p, clad::array_ref<T> d_a, clad::array_ref<T> d_b)
147{
148 if (a >= b)
149 *d_a += p;
150 else
151 *d_b += p;
152}
153
154template <typename T>
155ValueAndPushforward<T, T> Min_pushforward(T x, T y, T d_x, T d_y)
156{
157 T derivative = 0;
158 if (x <= y)
159 derivative = d_x;
160 else
161 derivative = d_y;
162 return {::TMath::Min(x, y), derivative};
163}
164
165template <typename T, typename U>
166void Min_pullback(T a, T b, U p, clad::array_ref<T> d_a, clad::array_ref<T> d_b)
167{
168 if (a <= b)
169 *d_a += p;
170 else
171 *d_b += p;
172}
173
174template <typename T>
175ValueAndPushforward<T, T> Power_pushforward(T x, T y, T d_x, T d_y)
176{
177 T pushforward = y * ::TMath::Power(x, y - 1) * d_x;
178 if (d_y) {
179 pushforward += (::TMath::Power(x, y) * ::TMath::Log(x)) * d_y;
180 }
181 return {::TMath::Power(x, y), pushforward};
182}
183
184template <typename T, typename U>
185void Power_pullback(T x, T y, U p, clad::array_ref<T> d_x, clad::array_ref<T> d_y)
186{
187 auto t = pow_pushforward(x, y, 1, 0);
188 *d_x += t.pushforward * p;
189 t = pow_pushforward(x, y, 0, 1);
190 *d_y += t.pushforward * p;
191}
192
193template <typename T>
194ValueAndPushforward<T, T> Sin_pushforward(T x, T d_x)
195{
196 return {::TMath::Sin(x), ::TMath::Cos(x) * d_x};
197}
198
199template <typename T>
200ValueAndPushforward<T, T> SinH_pushforward(T x, T d_x)
201{
202 return {::TMath::SinH(x), ::TMath::CosH(x) * d_x};
203}
204
205template <typename T>
206ValueAndPushforward<T, T> Sq_pushforward(T x, T d_x)
207{
208 return {::TMath::Sq(x), 2 * x * d_x};
209}
210
211template <typename T>
212ValueAndPushforward<T, T> Sqrt_pushforward(T x, T d_x)
213{
214 return {::TMath::Sqrt(x), (0.5 / ::TMath::Sqrt(x)) * d_x};
215}
216
217template <typename T>
218ValueAndPushforward<T, T> Tan_pushforward(T x, T d_x)
219{
220 return {::TMath::Tan(x), (1. / ::TMath::Sq(::TMath::Cos(x))) * d_x};
221}
222
223template <typename T>
224ValueAndPushforward<T, T> TanH_pushforward(T x, T d_x)
225{
226 return {::TMath::TanH(x), (1. / ::TMath::Sq(::TMath::CosH(x))) * d_x};
227}
228
229#ifdef WIN32
230// Additional custom derivatives that can be removed
231// after Issue #12108 in ROOT is resolved
232// constexpr is removed
233ValueAndPushforward<Double_t, Double_t> Pi_pushforward()
234{
235 return {3.1415926535897931, 0.};
236}
237// constexpr is removed
238ValueAndPushforward<Double_t, Double_t> Ln10_pushforward()
239{
240 return {2.3025850929940459, 0.};
241}
242#endif
243} // namespace TMath
244
245
246namespace ROOT {
247namespace Math {
248
249inline void landau_pdf_pullback(double x, double xi, double x0, double d_out, double *d_x, double *d_xi, double *d_x0)
250{
251 if (xi <= 0) {
252 return;
253 }
254 // clang-format off
255 static double p1[5] = {0.4259894875,-0.1249762550, 0.03984243700, -0.006298287635, 0.001511162253};
256 static double q1[5] = {1.0 ,-0.3388260629, 0.09594393323, -0.01608042283, 0.003778942063};
257
258 static double p2[5] = {0.1788541609, 0.1173957403, 0.01488850518, -0.001394989411, 0.0001283617211};
259 static double q2[5] = {1.0 , 0.7428795082, 0.3153932961, 0.06694219548, 0.008790609714};
260
261 static double p3[5] = {0.1788544503, 0.09359161662,0.006325387654, 0.00006611667319,-0.000002031049101};
262 static double q3[5] = {1.0 , 0.6097809921, 0.2560616665, 0.04746722384, 0.006957301675};
263
264 static double p4[5] = {0.9874054407, 118.6723273, 849.2794360, -743.7792444, 427.0262186};
265 static double q4[5] = {1.0 , 106.8615961, 337.6496214, 2016.712389, 1597.063511};
266
267 static double p5[5] = {1.003675074, 167.5702434, 4789.711289, 21217.86767, -22324.94910};
268 static double q5[5] = {1.0 , 156.9424537, 3745.310488, 9834.698876, 66924.28357};
269
270 static double p6[5] = {1.000827619, 664.9143136, 62972.92665, 475554.6998, -5743609.109};
271 static double q6[5] = {1.0 , 651.4101098, 56974.73333, 165917.4725, -2815759.939};
272
273 static double a1[3] = {0.04166666667,-0.01996527778, 0.02709538966};
274
275 static double a2[2] = {-1.845568670,-4.284640743};
276 // clang-format on
277 const double _const0 = 0.3989422803;
278 double v = (x - x0) / xi;
279 double _d_v = 0;
280 double _d_denlan = 0;
281 if (v < -5.5) {
282 double _t0;
283 double u = ::std::exp(v + 1.);
284 double _d_u = 0;
285 if (u >= 1.e-10) {
286 const double ue = ::std::exp(-1 / u);
287 const double us = ::std::sqrt(u);
288 double _t3;
289 double _d_ue = 0;
290 double _d_us = 0;
291 double denlan = _const0 * (ue / us) * (1 + (a1[0] + (a1[1] + a1[2] * u) * u) * u);
292 _d_denlan += d_out / xi;
293 *d_xi += d_out * -(denlan / (xi * xi));
294 denlan = _t3;
295 double _r_d3 = _d_denlan;
296 _d_denlan -= _r_d3;
297 _d_ue += _const0 * _r_d3 * (1 + (a1[0] + (a1[1] + a1[2] * u) * u) * u) / us;
298 double _r5 = _const0 * _r_d3 * (1 + (a1[0] + (a1[1] + a1[2] * u) * u) * u) * -(ue / (us * us));
299 _d_us += _r5;
300 _d_u += a1[2] * _const0 * (ue / us) * _r_d3 * u * u;
301 _d_u += (a1[1] + a1[2] * u) * _const0 * (ue / us) * _r_d3 * u;
302 _d_u += (a1[0] + (a1[1] + a1[2] * u) * u) * _const0 * (ue / us) * _r_d3;
303 double _r_d2 = _d_us;
304 _d_us -= _r_d2;
305 double _r4 = 0;
306 _r4 += _r_d2 * clad::custom_derivatives::sqrt_pushforward(u, 1.).pushforward;
307 _d_u += _r4;
308 double _r_d1 = _d_ue;
309 _d_ue -= _r_d1;
310 double _r2 = 0;
311 _r2 += _r_d1 * clad::custom_derivatives::exp_pushforward(-1 / u, 1.).pushforward;
312 double _r3 = _r2 * -(-1 / (u * u));
313 _d_u += _r3;
314 }
315 u = _t0;
316 double _r_d0 = _d_u;
317 _d_u -= _r_d0;
318 double _r1 = 0;
319 _r1 += _r_d0 * clad::custom_derivatives::exp_pushforward(v + 1., 1.).pushforward;
320 _d_v += _r1;
321 } else if (v < -1) {
322 double _t4;
323 double u = ::std::exp(-v - 1);
324 double _d_u = 0;
325 double _t5;
326 double _t8 = ::std::exp(-u);
327 double _t7 = ::std::sqrt(u);
328 double _t6 = (q1[0] + (q1[1] + (q1[2] + (q1[3] + q1[4] * v) * v) * v) * v);
329 double denlan = _t8 * _t7 * (p1[0] + (p1[1] + (p1[2] + (p1[3] + p1[4] * v) * v) * v) * v) / _t6;
330 _d_denlan += d_out / xi;
331 *d_xi += d_out * -(denlan / (xi * xi));
332 denlan = _t5;
333 double _r_d5 = _d_denlan;
334 _d_denlan -= _r_d5;
335 double _r7 = 0;
336 _r7 += _r_d5 / _t6 * (p1[0] + (p1[1] + (p1[2] + (p1[3] + p1[4] * v) * v) * v) * v) * _t7 *
337 clad::custom_derivatives::exp_pushforward(-u, 1.).pushforward;
338 _d_u += -_r7;
339 double _r8 = 0;
340 _r8 += _t8 * _r_d5 / _t6 * (p1[0] + (p1[1] + (p1[2] + (p1[3] + p1[4] * v) * v) * v) * v) *
341 clad::custom_derivatives::sqrt_pushforward(u, 1.).pushforward;
342 _d_u += _r8;
343 _d_v += p1[4] * _t8 * _t7 * _r_d5 / _t6 * v * v * v;
344 _d_v += (p1[3] + p1[4] * v) * _t8 * _t7 * _r_d5 / _t6 * v * v;
345 _d_v += (p1[2] + (p1[3] + p1[4] * v) * v) * _t8 * _t7 * _r_d5 / _t6 * v;
346 _d_v += (p1[1] + (p1[2] + (p1[3] + p1[4] * v) * v) * v) * _t8 * _t7 * _r_d5 / _t6;
347 double _r9 = _r_d5 * -(_t8 * _t7 * (p1[0] + (p1[1] + (p1[2] + (p1[3] + p1[4] * v) * v) * v) * v) / (_t6 * _t6));
348 _d_v += q1[4] * _r9 * v * v * v;
349 _d_v += (q1[3] + q1[4] * v) * _r9 * v * v;
350 _d_v += (q1[2] + (q1[3] + q1[4] * v) * v) * _r9 * v;
351 _d_v += (q1[1] + (q1[2] + (q1[3] + q1[4] * v) * v) * v) * _r9;
352 u = _t4;
353 double _r_d4 = _d_u;
354 _d_u -= _r_d4;
355 double _r6 = 0;
356 _r6 += _r_d4 * clad::custom_derivatives::exp_pushforward(-v - 1, 1.).pushforward;
357 _d_v += -_r6;
358 } else if (v < 1) {
359 double _t9;
360 double _t10 = (q2[0] + (q2[1] + (q2[2] + (q2[3] + q2[4] * v) * v) * v) * v);
361 double denlan = (p2[0] + (p2[1] + (p2[2] + (p2[3] + p2[4] * v) * v) * v) * v) / _t10;
362 _d_denlan += d_out / xi;
363 *d_xi += d_out * -(denlan / (xi * xi));
364 denlan = _t9;
365 double _r_d6 = _d_denlan;
366 _d_denlan -= _r_d6;
367 _d_v += p2[4] * _r_d6 / _t10 * v * v * v;
368 _d_v += (p2[3] + p2[4] * v) * _r_d6 / _t10 * v * v;
369 _d_v += (p2[2] + (p2[3] + p2[4] * v) * v) * _r_d6 / _t10 * v;
370 _d_v += (p2[1] + (p2[2] + (p2[3] + p2[4] * v) * v) * v) * _r_d6 / _t10;
371 double _r10 = _r_d6 * -((p2[0] + (p2[1] + (p2[2] + (p2[3] + p2[4] * v) * v) * v) * v) / (_t10 * _t10));
372 _d_v += q2[4] * _r10 * v * v * v;
373 _d_v += (q2[3] + q2[4] * v) * _r10 * v * v;
374 _d_v += (q2[2] + (q2[3] + q2[4] * v) * v) * _r10 * v;
375 _d_v += (q2[1] + (q2[2] + (q2[3] + q2[4] * v) * v) * v) * _r10;
376 } else if (v < 5) {
377 double _t11;
378 double _t12 = (q3[0] + (q3[1] + (q3[2] + (q3[3] + q3[4] * v) * v) * v) * v);
379 double denlan = (p3[0] + (p3[1] + (p3[2] + (p3[3] + p3[4] * v) * v) * v) * v) / _t12;
380 _d_denlan += d_out / xi;
381 *d_xi += d_out * -(denlan / (xi * xi));
382 denlan = _t11;
383 double _r_d7 = _d_denlan;
384 _d_denlan -= _r_d7;
385 _d_v += p3[4] * _r_d7 / _t12 * v * v * v;
386 _d_v += (p3[3] + p3[4] * v) * _r_d7 / _t12 * v * v;
387 _d_v += (p3[2] + (p3[3] + p3[4] * v) * v) * _r_d7 / _t12 * v;
388 _d_v += (p3[1] + (p3[2] + (p3[3] + p3[4] * v) * v) * v) * _r_d7 / _t12;
389 double _r11 = _r_d7 * -((p3[0] + (p3[1] + (p3[2] + (p3[3] + p3[4] * v) * v) * v) * v) / (_t12 * _t12));
390 _d_v += q3[4] * _r11 * v * v * v;
391 _d_v += (q3[3] + q3[4] * v) * _r11 * v * v;
392 _d_v += (q3[2] + (q3[3] + q3[4] * v) * v) * _r11 * v;
393 _d_v += (q3[1] + (q3[2] + (q3[3] + q3[4] * v) * v) * v) * _r11;
394 } else if (v < 12) {
395 double u = 1 / v;
396 double _d_u = 0;
397 double _t14;
398 double _t15 = (q4[0] + (q4[1] + (q4[2] + (q4[3] + q4[4] * u) * u) * u) * u);
399 double denlan = u * u * (p4[0] + (p4[1] + (p4[2] + (p4[3] + p4[4] * u) * u) * u) * u) / _t15;
400 _d_denlan += d_out / xi;
401 *d_xi += d_out * -(denlan / (xi * xi));
402 denlan = _t14;
403 double _r_d9 = _d_denlan;
404 _d_denlan -= _r_d9;
405 _d_u += _r_d9 / _t15 * (p4[0] + (p4[1] + (p4[2] + (p4[3] + p4[4] * u) * u) * u) * u) * u;
406 _d_u += u * _r_d9 / _t15 * (p4[0] + (p4[1] + (p4[2] + (p4[3] + p4[4] * u) * u) * u) * u);
407 _d_u += p4[4] * u * u * _r_d9 / _t15 * u * u * u;
408 _d_u += (p4[3] + p4[4] * u) * u * u * _r_d9 / _t15 * u * u;
409 _d_u += (p4[2] + (p4[3] + p4[4] * u) * u) * u * u * _r_d9 / _t15 * u;
410 _d_u += (p4[1] + (p4[2] + (p4[3] + p4[4] * u) * u) * u) * u * u * _r_d9 / _t15;
411 double _r13 = _r_d9 * -(u * u * (p4[0] + (p4[1] + (p4[2] + (p4[3] + p4[4] * u) * u) * u) * u) / (_t15 * _t15));
412 _d_u += q4[4] * _r13 * u * u * u;
413 _d_u += (q4[3] + q4[4] * u) * _r13 * u * u;
414 _d_u += (q4[2] + (q4[3] + q4[4] * u) * u) * _r13 * u;
415 _d_u += (q4[1] + (q4[2] + (q4[3] + q4[4] * u) * u) * u) * _r13;
416 double _r_d8 = _d_u;
417 _d_u -= _r_d8;
418 double _r12 = _r_d8 * -(1 / (v * v));
419 _d_v += _r12;
420 } else if (v < 50) {
421 double u = 1 / v;
422 double _d_u = 0;
423 double _t17;
424 double _t18 = (q5[0] + (q5[1] + (q5[2] + (q5[3] + q5[4] * u) * u) * u) * u);
425 double denlan = u * u * (p5[0] + (p5[1] + (p5[2] + (p5[3] + p5[4] * u) * u) * u) * u) / _t18;
426 _d_denlan += d_out / xi;
427 *d_xi += d_out * -(denlan / (xi * xi));
428 denlan = _t17;
429 double _r_d11 = _d_denlan;
430 _d_denlan -= _r_d11;
431 _d_u += _r_d11 / _t18 * (p5[0] + (p5[1] + (p5[2] + (p5[3] + p5[4] * u) * u) * u) * u) * u;
432 _d_u += u * _r_d11 / _t18 * (p5[0] + (p5[1] + (p5[2] + (p5[3] + p5[4] * u) * u) * u) * u);
433 _d_u += p5[4] * u * u * _r_d11 / _t18 * u * u * u;
434 _d_u += (p5[3] + p5[4] * u) * u * u * _r_d11 / _t18 * u * u;
435 _d_u += (p5[2] + (p5[3] + p5[4] * u) * u) * u * u * _r_d11 / _t18 * u;
436 _d_u += (p5[1] + (p5[2] + (p5[3] + p5[4] * u) * u) * u) * u * u * _r_d11 / _t18;
437 double _r15 = _r_d11 * -(u * u * (p5[0] + (p5[1] + (p5[2] + (p5[3] + p5[4] * u) * u) * u) * u) / (_t18 * _t18));
438 _d_u += q5[4] * _r15 * u * u * u;
439 _d_u += (q5[3] + q5[4] * u) * _r15 * u * u;
440 _d_u += (q5[2] + (q5[3] + q5[4] * u) * u) * _r15 * u;
441 _d_u += (q5[1] + (q5[2] + (q5[3] + q5[4] * u) * u) * u) * _r15;
442 double _r_d10 = _d_u;
443 _d_u -= _r_d10;
444 double _r14 = _r_d10 * -(1 / (v * v));
445 _d_v += _r14;
446 } else if (v < 300) {
447 double _t19;
448 double u = 1 / v;
449 double _d_u = 0;
450 double _t20;
451 double _t21 = (q6[0] + (q6[1] + (q6[2] + (q6[3] + q6[4] * u) * u) * u) * u);
452 double denlan = u * u * (p6[0] + (p6[1] + (p6[2] + (p6[3] + p6[4] * u) * u) * u) * u) / _t21;
453 _d_denlan += d_out / xi;
454 *d_xi += d_out * -(denlan / (xi * xi));
455 denlan = _t20;
456 double _r_d13 = _d_denlan;
457 _d_denlan -= _r_d13;
458 _d_u += _r_d13 / _t21 * (p6[0] + (p6[1] + (p6[2] + (p6[3] + p6[4] * u) * u) * u) * u) * u;
459 _d_u += u * _r_d13 / _t21 * (p6[0] + (p6[1] + (p6[2] + (p6[3] + p6[4] * u) * u) * u) * u);
460 _d_u += p6[4] * u * u * _r_d13 / _t21 * u * u * u;
461 _d_u += (p6[3] + p6[4] * u) * u * u * _r_d13 / _t21 * u * u;
462 _d_u += (p6[2] + (p6[3] + p6[4] * u) * u) * u * u * _r_d13 / _t21 * u;
463 _d_u += (p6[1] + (p6[2] + (p6[3] + p6[4] * u) * u) * u) * u * u * _r_d13 / _t21;
464 double _r17 = _r_d13 * -(u * u * (p6[0] + (p6[1] + (p6[2] + (p6[3] + p6[4] * u) * u) * u) * u) / (_t21 * _t21));
465 _d_u += q6[4] * _r17 * u * u * u;
466 _d_u += (q6[3] + q6[4] * u) * _r17 * u * u;
467 _d_u += (q6[2] + (q6[3] + q6[4] * u) * u) * _r17 * u;
468 _d_u += (q6[1] + (q6[2] + (q6[3] + q6[4] * u) * u) * u) * _r17;
469 u = _t19;
470 double _r_d12 = _d_u;
471 _d_u -= _r_d12;
472 double _r16 = _r_d12 * -(1 / (v * v));
473 _d_v += _r16;
474 } else {
475 double _t22;
476 double _t25 = ::std::log(v);
477 double _t24 = (v + 1);
478 double _t23 = (v - v * _t25 / _t24);
479 double u = 1 / _t23;
480 double _d_u = 0;
481 double _t26;
482 double denlan = u * u * (1 + (a2[0] + a2[1] * u) * u);
483 _d_denlan += d_out / xi;
484 *d_xi += d_out * -(denlan / (xi * xi));
485 denlan = _t26;
486 double _r_d15 = _d_denlan;
487 _d_denlan -= _r_d15;
488 _d_u += _r_d15 * (1 + (a2[0] + a2[1] * u) * u) * u;
489 _d_u += u * _r_d15 * (1 + (a2[0] + a2[1] * u) * u);
490 _d_u += a2[1] * u * u * _r_d15 * u;
491 _d_u += (a2[0] + a2[1] * u) * u * u * _r_d15;
492 u = _t22;
493 double _r_d14 = _d_u;
494 _d_u -= _r_d14;
495 double _r18 = _r_d14 * -(1 / (_t23 * _t23));
496 _d_v += _r18;
497 _d_v += -_r18 / _t24 * _t25;
498 double _r19 = 0;
499 _r19 += v * -_r18 / _t24 * clad::custom_derivatives::log_pushforward(v, 1.).pushforward;
500 _d_v += _r19;
501 double _r20 = -_r18 * -(v * _t25 / (_t24 * _t24));
502 _d_v += _r20;
503 }
504 *d_x += _d_v / xi;
505 *d_x0 += -_d_v / xi;
506 double _r0 = _d_v * -((x - x0) / (xi * xi));
507 *d_xi += _r0;
508}
509
510inline void landau_cdf_pullback(double x, double xi, double x0, double d_out, double *d_x, double *d_xi, double *d_x0)
511{
512 // clang-format off
513 static double p1[5] = {0.2514091491e+0,-0.6250580444e-1, 0.1458381230e-1,-0.2108817737e-2, 0.7411247290e-3};
514 static double q1[5] = {1.0 ,-0.5571175625e-2, 0.6225310236e-1,-0.3137378427e-2, 0.1931496439e-2};
515
516 static double p2[4] = {0.2868328584e+0, 0.3564363231e+0, 0.1523518695e+0, 0.2251304883e-1};
517 static double q2[4] = {1.0 , 0.6191136137e+0, 0.1720721448e+0, 0.2278594771e-1};
518
519 static double p3[4] = {0.2868329066e+0, 0.3003828436e+0, 0.9950951941e-1, 0.8733827185e-2};
520 static double q3[4] = {1.0 , 0.4237190502e+0, 0.1095631512e+0, 0.8693851567e-2};
521
522 static double p4[4] = {0.1000351630e+1, 0.4503592498e+1, 0.1085883880e+2, 0.7536052269e+1};
523 static double q4[4] = {1.0 , 0.5539969678e+1, 0.1933581111e+2, 0.2721321508e+2};
524
525 static double p5[4] = {0.1000006517e+1, 0.4909414111e+2, 0.8505544753e+2, 0.1532153455e+3};
526 static double q5[4] = {1.0 , 0.5009928881e+2, 0.1399819104e+3, 0.4200002909e+3};
527
528 static double p6[4] = {0.1000000983e+1, 0.1329868456e+3, 0.9162149244e+3,-0.9605054274e+3};
529 static double q6[4] = {1.0 , 0.1339887843e+3, 0.1055990413e+4, 0.5532224619e+3};
530
531 static double a1[4] = {0 ,-0.4583333333e+0, 0.6675347222e+0,-0.1641741416e+1};
532 static double a2[4] = {0 , 1.0 ,-0.4227843351e+0,-0.2043403138e+1};
533 // clang-format on
534
535 const double v = (x - x0) / xi;
536 double _d_v = 0;
537 if (v < -5.5) {
538 double _d_u = 0;
539 const double _const0 = 0.3989422803;
540 double u = ::std::exp(v + 1);
541 double _t3 = ::std::exp(-1. / u);
542 double _t2 = ::std::sqrt(u);
543 double _r2 = 0;
544 _r2 += _const0 * d_out * (1 + (a1[1] + (a1[2] + a1[3] * u) * u) * u) * _t2 *
545 clad::custom_derivatives::exp_pushforward(-1. / u, 1.).pushforward;
546 double _r3 = _r2 * -(-1. / (u * u));
547 _d_u += _r3;
548 double _r4 = 0;
549 _r4 += _const0 * _t3 * d_out * (1 + (a1[1] + (a1[2] + a1[3] * u) * u) * u) *
550 clad::custom_derivatives::sqrt_pushforward(u, 1.).pushforward;
551 _d_u += _r4;
552 _d_u += a1[3] * _const0 * _t3 * _t2 * d_out * u * u;
553 _d_u += (a1[2] + a1[3] * u) * _const0 * _t3 * _t2 * d_out * u;
554 _d_u += (a1[1] + (a1[2] + a1[3] * u) * u) * _const0 * _t3 * _t2 * d_out;
555 _d_v += _d_u * clad::custom_derivatives::exp_pushforward(v + 1, 1.).pushforward;
556 } else if (v < -1) {
557 double _d_u = 0;
558 double u = ::std::exp(-v - 1);
559 double _t8 = ::std::exp(-u);
560 double _t7 = ::std::sqrt(u);
561 double _t6 = (q1[0] + (q1[1] + (q1[2] + (q1[3] + q1[4] * v) * v) * v) * v);
562 double _r6 = 0;
563 _r6 += d_out / _t6 * (p1[0] + (p1[1] + (p1[2] + (p1[3] + p1[4] * v) * v) * v) * v) / _t7 *
564 clad::custom_derivatives::exp_pushforward(-u, 1.).pushforward;
565 _d_u += -_r6;
566 double _r7 = d_out / _t6 * (p1[0] + (p1[1] + (p1[2] + (p1[3] + p1[4] * v) * v) * v) * v) * -(_t8 / (_t7 * _t7));
567 double _r8 = 0;
568 _r8 += _r7 * clad::custom_derivatives::sqrt_pushforward(u, 1.).pushforward;
569 _d_u += _r8;
570 _d_v += p1[4] * (_t8 / _t7) * d_out / _t6 * v * v * v;
571 _d_v += (p1[3] + p1[4] * v) * (_t8 / _t7) * d_out / _t6 * v * v;
572 _d_v += (p1[2] + (p1[3] + p1[4] * v) * v) * (_t8 / _t7) * d_out / _t6 * v;
573 _d_v += (p1[1] + (p1[2] + (p1[3] + p1[4] * v) * v) * v) * (_t8 / _t7) * d_out / _t6;
574 double _r9 = d_out * -((_t8 / _t7) * (p1[0] + (p1[1] + (p1[2] + (p1[3] + p1[4] * v) * v) * v) * v) / (_t6 * _t6));
575 _d_v += q1[4] * _r9 * v * v * v;
576 _d_v += (q1[3] + q1[4] * v) * _r9 * v * v;
577 _d_v += (q1[2] + (q1[3] + q1[4] * v) * v) * _r9 * v;
578 _d_v += (q1[1] + (q1[2] + (q1[3] + q1[4] * v) * v) * v) * _r9;
579 _d_v += -_d_u * clad::custom_derivatives::exp_pushforward(-v - 1, 1.).pushforward;
580 } else if (v < 1) {
581 double _t10 = (q2[0] + (q2[1] + (q2[2] + q2[3] * v) * v) * v);
582 _d_v += p2[3] * d_out / _t10 * v * v;
583 _d_v += (p2[2] + p2[3] * v) * d_out / _t10 * v;
584 _d_v += (p2[1] + (p2[2] + p2[3] * v) * v) * d_out / _t10;
585 double _r10 = d_out * -((p2[0] + (p2[1] + (p2[2] + p2[3] * v) * v) * v) / (_t10 * _t10));
586 _d_v += q2[3] * _r10 * v * v;
587 _d_v += (q2[2] + q2[3] * v) * _r10 * v;
588 _d_v += (q2[1] + (q2[2] + q2[3] * v) * v) * _r10;
589 } else if (v < 4) {
590 double _t12 = (q3[0] + (q3[1] + (q3[2] + q3[3] * v) * v) * v);
591 _d_v += p3[3] * d_out / _t12 * v * v;
592 _d_v += (p3[2] + p3[3] * v) * d_out / _t12 * v;
593 _d_v += (p3[1] + (p3[2] + p3[3] * v) * v) * d_out / _t12;
594 double _r11 = d_out * -((p3[0] + (p3[1] + (p3[2] + p3[3] * v) * v) * v) / (_t12 * _t12));
595 _d_v += q3[3] * _r11 * v * v;
596 _d_v += (q3[2] + q3[3] * v) * _r11 * v;
597 _d_v += (q3[1] + (q3[2] + q3[3] * v) * v) * _r11;
598 } else if (v < 12) {
599 double _d_u = 0;
600 double u = 1. / v;
601 double _t15 = (q4[0] + (q4[1] + (q4[2] + q4[3] * u) * u) * u);
602 _d_u += p4[3] * d_out / _t15 * u * u;
603 _d_u += (p4[2] + p4[3] * u) * d_out / _t15 * u;
604 _d_u += (p4[1] + (p4[2] + p4[3] * u) * u) * d_out / _t15;
605 double _r13 = d_out * -((p4[0] + (p4[1] + (p4[2] + p4[3] * u) * u) * u) / (_t15 * _t15));
606 _d_u += q4[3] * _r13 * u * u;
607 _d_u += (q4[2] + q4[3] * u) * _r13 * u;
608 _d_u += (q4[1] + (q4[2] + q4[3] * u) * u) * _r13;
609 double _r12 = _d_u * -(1. / (v * v));
610 _d_v += _r12;
611 } else if (v < 50) {
612 double _d_u = 0;
613 double u = 1. / v;
614 double _t18 = (q5[0] + (q5[1] + (q5[2] + q5[3] * u) * u) * u);
615 _d_u += p5[3] * d_out / _t18 * u * u;
616 _d_u += (p5[2] + p5[3] * u) * d_out / _t18 * u;
617 _d_u += (p5[1] + (p5[2] + p5[3] * u) * u) * d_out / _t18;
618 double _r15 = d_out * -((p5[0] + (p5[1] + (p5[2] + p5[3] * u) * u) * u) / (_t18 * _t18));
619 _d_u += q5[3] * _r15 * u * u;
620 _d_u += (q5[2] + q5[3] * u) * _r15 * u;
621 _d_u += (q5[1] + (q5[2] + q5[3] * u) * u) * _r15;
622 double _r14 = _d_u * -(1. / (v * v));
623 _d_v += _r14;
624 } else if (v < 300) {
625 double _d_u = 0;
626 double u = 1. / v;
627 double _t21 = (q6[0] + (q6[1] + (q6[2] + q6[3] * u) * u) * u);
628 _d_u += p6[3] * d_out / _t21 * u * u;
629 _d_u += (p6[2] + p6[3] * u) * d_out / _t21 * u;
630 _d_u += (p6[1] + (p6[2] + p6[3] * u) * u) * d_out / _t21;
631 double _r17 = d_out * -((p6[0] + (p6[1] + (p6[2] + p6[3] * u) * u) * u) / (_t21 * _t21));
632 _d_u += q6[3] * _r17 * u * u;
633 _d_u += (q6[2] + q6[3] * u) * _r17 * u;
634 _d_u += (q6[1] + (q6[2] + q6[3] * u) * u) * _r17;
635 double _r16 = _d_u * -(1. / (v * v));
636 _d_v += _r16;
637 } else {
638 double _d_u = 0;
639 double _t25 = ::std::log(v);
640 double _t24 = (v + 1);
641 double _t23 = (v - v * _t25 / _t24);
642 double u = 1. / _t23;
643 double _t26;
644 _d_u += a2[3] * -d_out * u * u;
645 _d_u += (a2[2] + a2[3] * u) * -d_out * u;
646 _d_u += (a2[1] + (a2[2] + a2[3] * u) * u) * -d_out;
647 double _r18 = _d_u * -(1. / (_t23 * _t23));
648 _d_v += _r18;
649 _d_v += -_r18 / _t24 * _t25;
650 double _r19 = 0;
651 _r19 += v * -_r18 / _t24 * clad::custom_derivatives::log_pushforward(v, 1.).pushforward;
652 _d_v += _r19;
653 double _r20 = -_r18 * -(v * _t25 / (_t24 * _t24));
654 _d_v += _r20;
655 }
656
657 *d_x += _d_v / xi;
658 *d_x0 += -_d_v / xi;
659 *d_xi += _d_v * -((x - x0) / (xi * xi));
660}
661
662} // namespace Math
663} // namespace ROOT
664
665} // namespace custom_derivatives
666} // namespace clad
667
668#endif // CLAD_DERIVATOR
#define b(i)
Definition RSha256.hxx:100
#define a(i)
Definition RSha256.hxx:99
#define h(i)
Definition RSha256.hxx:106
winID h TVirtualViewer3D TVirtualGLPainter p
Double_t y[n]
Definition legend1.C:17
Double_t x[n]
Definition legend1.C:17
Namespace for new Math classes and functions.
tbb::task_arena is an alias of tbb::interface7::task_arena, which doesn't allow to forward declare tb...
TMath.
Definition TMathBase.h:35
Double_t CosH(Double_t)
Returns the hyperbolic cosine of x.
Definition TMath.h:612
Double_t ACos(Double_t)
Returns the principal value of the arc cosine of x, expressed in radians.
Definition TMath.h:632
Short_t Max(Short_t a, Short_t b)
Returns the largest of a and b.
Definition TMathBase.h:250
Double_t ASin(Double_t)
Returns the principal value of the arc sine of x, expressed in radians.
Definition TMath.h:624
Double_t Log2(Double_t x)
Returns the binary (base-2) logarithm of x.
Definition TMath.cxx:107
Double_t Exp(Double_t x)
Returns the base-e exponential function of x, which is e raised to the power x.
Definition TMath.h:709
Double_t Erf(Double_t x)
Computation of the error function erf(x).
Definition TMath.cxx:190
Double_t ATan(Double_t)
Returns the principal value of the arc tangent of x, expressed in radians.
Definition TMath.h:640
Double_t ASinH(Double_t)
Returns the area hyperbolic sine of x.
Definition TMath.cxx:67
Double_t TanH(Double_t)
Returns the hyperbolic tangent of x.
Definition TMath.h:618
Double_t ACosH(Double_t)
Returns the nonnegative area hyperbolic cosine of x.
Definition TMath.cxx:81
Double_t Log(Double_t x)
Returns the natural logarithm of x.
Definition TMath.h:756
Double_t Erfc(Double_t x)
Computes the complementary error function erfc(x).
Definition TMath.cxx:199
Double_t Sq(Double_t x)
Returns x*x.
Definition TMath.h:656
Double_t Sqrt(Double_t x)
Returns the square root of x.
Definition TMath.h:662
LongDouble_t Power(LongDouble_t x, LongDouble_t y)
Returns x raised to the power y.
Definition TMath.h:721
Short_t Min(Short_t a, Short_t b)
Returns the smallest of a and b.
Definition TMathBase.h:198
constexpr Double_t Ln10()
Natural log of 10 (to convert log to ln)
Definition TMath.h:100
Double_t Hypot(Double_t x, Double_t y)
Returns sqrt(x*x + y*y)
Definition TMath.cxx:59
Double_t Cos(Double_t)
Returns the cosine of an angle of x radians.
Definition TMath.h:594
constexpr Double_t Pi()
Definition TMath.h:37
Double_t Sin(Double_t)
Returns the sine of an angle of x radians.
Definition TMath.h:588
Double_t Tan(Double_t)
Returns the tangent of an angle of x radians.
Definition TMath.h:600
Double_t ATanH(Double_t)
Returns the area hyperbolic tangent of x.
Definition TMath.cxx:95
Double_t Log10(Double_t x)
Returns the common (base-10) logarithm of x.
Definition TMath.h:762
Short_t Abs(Short_t d)
Returns the absolute value of parameter Short_t d.
Definition TMathBase.h:123
Double_t SinH(Double_t)
Returns the hyperbolic sine of `x.
Definition TMath.h:606
void landau_pdf_pullback(double x, double xi, double x0, double d_out, double *d_x, double *d_xi, double *d_x0)
void landau_cdf_pullback(double x, double xi, double x0, double d_out, double *d_x, double *d_xi, double *d_x0)
ValueAndPushforward< T, T > CosH_pushforward(T x, T d_x)
ValueAndPushforward< T, T > Abs_pushforward(T x, T d_x)
void Min_pullback(T a, T b, U p, clad::array_ref< T > d_a, clad::array_ref< T > d_b)
ValueAndPushforward< T, T > Sq_pushforward(T x, T d_x)
void Max_pullback(T a, T b, U p, clad::array_ref< T > d_a, clad::array_ref< T > d_b)
ValueAndPushforward< T, T > Erf_pushforward(T x, T d_x)
ValueAndPushforward< T, T > Erfc_pushforward(T x, T d_x)
ValueAndPushforward< T, T > Sin_pushforward(T x, T d_x)
ValueAndPushforward< T, T > Max_pushforward(T x, T y, T d_x, T d_y)
ValueAndPushforward< T, T > Hypot_pushforward(T x, T y, T d_x, T d_y)
ValueAndPushforward< T, T > ASinH_pushforward(T x, T d_x)
ValueAndPushforward< T, T > ACosH_pushforward(T x, T d_x)
ValueAndPushforward< T, T > ASin_pushforward(T x, T d_x)
ValueAndPushforward< T, T > Cos_pushforward(T x, T d_x)
ValueAndPushforward< T, T > Sqrt_pushforward(T x, T d_x)
ValueAndPushforward< T, T > Tan_pushforward(T x, T d_x)
void Hypot_pullback(T x, T y, U p, clad::array_ref< T > d_x, clad::array_ref< T > d_y)
ValueAndPushforward< T, T > Power_pushforward(T x, T y, T d_x, T d_y)
void Power_pullback(T x, T y, U p, clad::array_ref< T > d_x, clad::array_ref< T > d_y)
ValueAndPushforward< T, T > Min_pushforward(T x, T y, T d_x, T d_y)
ValueAndPushforward< T, T > Log_pushforward(T x, T d_x)
ValueAndPushforward< T, T > Log10_pushforward(T x, T d_x)
ValueAndPushforward< T, T > TanH_pushforward(T x, T d_x)
ValueAndPushforward< T, T > ACos_pushforward(T x, T d_x)
ValueAndPushforward< T, T > SinH_pushforward(T x, T d_x)
ValueAndPushforward< T, T > Exp_pushforward(T x, T d_x)
ValueAndPushforward< T, T > Log2_pushforward(T x, T d_x)
ValueAndPushforward< T, T > ATanH_pushforward(T x, T d_x)
ValueAndPushforward< T, T > ATan_pushforward(T x, T d_x)