ml4gw 0.2.0__py3-none-any.whl → 0.4.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of ml4gw might be problematic. Click here for more details.

@@ -0,0 +1,1359 @@
1
+ import torch
2
+ from torchtyping import TensorType
3
+
4
+ from . import phenom_d_data
5
+ from .taylorf2 import MTSUN_SI, PI, taylorf2_amplitude, taylorf2_phase
6
+
7
+
8
+ # Utility functions taken from PhenomD utilities in lalsimulation
9
+ # https://git.ligo.org/lscsoft/lalsuite/-/blob/master/lalsimulation/lib/LALSimIMRPhenomD_internals.c
10
+ def sigma1Fit(eta, eta2, xi):
11
+ return (
12
+ 2096.551999295543
13
+ + 1463.7493168261553 * eta
14
+ + (
15
+ 1312.5493286098522
16
+ + 18307.330017082117 * eta
17
+ - 43534.1440746107 * eta2
18
+ + (
19
+ -833.2889543511114
20
+ + 32047.31997183187 * eta
21
+ - 108609.45037520859 * eta2
22
+ )
23
+ * xi
24
+ + (
25
+ 452.25136398112204
26
+ + 8353.439546391714 * eta
27
+ - 44531.3250037322 * eta2
28
+ )
29
+ * xi
30
+ * xi
31
+ )
32
+ * xi
33
+ )
34
+
35
+
36
+ def sigma2Fit(eta, eta2, xi):
37
+ return (
38
+ -10114.056472621156
39
+ - 44631.01109458185 * eta
40
+ + (
41
+ -6541.308761668722
42
+ - 266959.23419307504 * eta
43
+ + 686328.3229317984 * eta2
44
+ + (
45
+ 3405.6372187679685
46
+ - 437507.7208209015 * eta
47
+ + 1.6318171307344697e6 * eta2
48
+ )
49
+ * xi
50
+ + (
51
+ -7462.648563007646
52
+ - 114585.25177153319 * eta
53
+ + 674402.4689098676 * eta2
54
+ )
55
+ * xi
56
+ * xi
57
+ )
58
+ * xi
59
+ )
60
+
61
+
62
+ def sigma3Fit(eta, eta2, xi):
63
+ return (
64
+ 22933.658273436497
65
+ + 230960.00814979506 * eta
66
+ + (
67
+ 14961.083974183695
68
+ + 1.1940181342318142e6 * eta
69
+ - 3.1042239693052764e6 * eta2
70
+ + (
71
+ -3038.166617199259
72
+ + 1.8720322849093592e6 * eta
73
+ - 7.309145012085539e6 * eta2
74
+ )
75
+ * xi
76
+ + (
77
+ 42738.22871475411
78
+ + 467502.018616601 * eta
79
+ - 3.064853498512499e6 * eta2
80
+ )
81
+ * xi
82
+ * xi
83
+ )
84
+ * xi
85
+ )
86
+
87
+
88
+ def sigma4Fit(eta, eta2, xi):
89
+ return (
90
+ -14621.71522218357
91
+ - 377812.8579387104 * eta
92
+ + (
93
+ -9608.682631509726
94
+ - 1.7108925257214056e6 * eta
95
+ + 4.332924601416521e6 * eta2
96
+ + (
97
+ -22366.683262266528
98
+ - 2.5019716386377467e6 * eta
99
+ + 1.0274495902259542e7 * eta2
100
+ )
101
+ * xi
102
+ + (
103
+ -85360.30079034246
104
+ - 570025.3441737515 * eta
105
+ + 4.396844346849777e6 * eta2
106
+ )
107
+ * xi
108
+ * xi
109
+ )
110
+ * xi
111
+ )
112
+
113
+
114
+ def gamma1_fun(eta, eta2, xi):
115
+ return (
116
+ 0.006927402739328343
117
+ + 0.03020474290328911 * eta
118
+ + (
119
+ 0.006308024337706171
120
+ - 0.12074130661131138 * eta
121
+ + 0.26271598905781324 * eta2
122
+ + (
123
+ 0.0034151773647198794
124
+ - 0.10779338611188374 * eta
125
+ + 0.27098966966891747 * eta2
126
+ )
127
+ * xi
128
+ + (
129
+ 0.0007374185938559283
130
+ - 0.02749621038376281 * eta
131
+ + 0.0733150789135702 * eta2
132
+ )
133
+ * xi
134
+ * xi
135
+ )
136
+ * xi
137
+ )
138
+
139
+
140
+ def gamma2_fun(eta, eta2, xi):
141
+ return (
142
+ 1.010344404799477
143
+ + 0.0008993122007234548 * eta
144
+ + (
145
+ 0.283949116804459
146
+ - 4.049752962958005 * eta
147
+ + 13.207828172665366 * eta2
148
+ + (
149
+ 0.10396278486805426
150
+ - 7.025059158961947 * eta
151
+ + 24.784892370130475 * eta2
152
+ )
153
+ * xi
154
+ + (
155
+ 0.03093202475605892
156
+ - 2.6924023896851663 * eta
157
+ + 9.609374464684983 * eta2
158
+ )
159
+ * xi
160
+ * xi
161
+ )
162
+ * xi
163
+ )
164
+
165
+
166
+ def gamma3_fun(eta, eta2, xi):
167
+ return (
168
+ 1.3081615607036106
169
+ - 0.005537729694807678 * eta
170
+ + (
171
+ -0.06782917938621007
172
+ - 0.6689834970767117 * eta
173
+ + 3.403147966134083 * eta2
174
+ + (
175
+ -0.05296577374411866
176
+ - 0.9923793203111362 * eta
177
+ + 4.820681208409587 * eta2
178
+ )
179
+ * xi
180
+ + (
181
+ -0.006134139870393713
182
+ - 0.38429253308696365 * eta
183
+ + 1.7561754421985984 * eta2
184
+ )
185
+ * xi
186
+ * xi
187
+ )
188
+ * xi
189
+ )
190
+
191
+
192
+ def beta1Fit(eta, eta2, xi):
193
+ return (
194
+ 97.89747327985583
195
+ - 42.659730877489224 * eta
196
+ + (
197
+ 153.48421037904913
198
+ - 1417.0620760768954 * eta
199
+ + 2752.8614143665027 * eta2
200
+ + (
201
+ 138.7406469558649
202
+ - 1433.6585075135881 * eta
203
+ + 2857.7418952430758 * eta2
204
+ )
205
+ * xi
206
+ + (
207
+ 41.025109467376126
208
+ - 423.680737974639 * eta
209
+ + 850.3594335657173 * eta2
210
+ )
211
+ * xi
212
+ * xi
213
+ )
214
+ * xi
215
+ )
216
+
217
+
218
+ def beta2Fit(eta, eta2, xi):
219
+ return (
220
+ -3.282701958759534
221
+ - 9.051384468245866 * eta
222
+ + (
223
+ -12.415449742258042
224
+ + 55.4716447709787 * eta
225
+ - 106.05109938966335 * eta2
226
+ + (
227
+ -11.953044553690658
228
+ + 76.80704618365418 * eta
229
+ - 155.33172948098394 * eta2
230
+ )
231
+ * xi
232
+ + (
233
+ -3.4129261592393263
234
+ + 25.572377569952536 * eta
235
+ - 54.408036707740465 * eta2
236
+ )
237
+ * xi
238
+ * xi
239
+ )
240
+ * xi
241
+ )
242
+
243
+
244
+ def beta3Fit(eta, eta2, xi):
245
+ return (
246
+ -0.000025156429818799565
247
+ + 0.000019750256942201327 * eta
248
+ + (
249
+ -0.000018370671469295915
250
+ + 0.000021886317041311973 * eta
251
+ + 0.00008250240316860033 * eta2
252
+ + (
253
+ 7.157371250566708e-6
254
+ - 0.000055780000112270685 * eta
255
+ + 0.00019142082884072178 * eta2
256
+ )
257
+ * xi
258
+ + (
259
+ 5.447166261464217e-6
260
+ - 0.00003220610095021982 * eta
261
+ + 0.00007974016714984341 * eta2
262
+ )
263
+ * xi
264
+ * xi
265
+ )
266
+ * xi
267
+ )
268
+
269
+
270
+ def alpha1Fit(eta, eta2, xi):
271
+ return (
272
+ 43.31514709695348
273
+ + 638.6332679188081 * eta
274
+ + (
275
+ -32.85768747216059
276
+ + 2415.8938269370315 * eta
277
+ - 5766.875169379177 * eta2
278
+ + (
279
+ -61.85459307173841
280
+ + 2953.967762459948 * eta
281
+ - 8986.29057591497 * eta2
282
+ )
283
+ * xi
284
+ + (
285
+ -21.571435779762044
286
+ + 981.2158224673428 * eta
287
+ - 3239.5664895930286 * eta2
288
+ )
289
+ * xi
290
+ * xi
291
+ )
292
+ * xi
293
+ )
294
+
295
+
296
+ def alpha2Fit(eta, eta2, xi):
297
+ return (
298
+ -0.07020209449091723
299
+ - 0.16269798450687084 * eta
300
+ + (
301
+ -0.1872514685185499
302
+ + 1.138313650449945 * eta
303
+ - 2.8334196304430046 * eta2
304
+ + (
305
+ -0.17137955686840617
306
+ + 1.7197549338119527 * eta
307
+ - 4.539717148261272 * eta2
308
+ )
309
+ * xi
310
+ + (
311
+ -0.049983437357548705
312
+ + 0.6062072055948309 * eta
313
+ - 1.682769616644546 * eta2
314
+ )
315
+ * xi
316
+ * xi
317
+ )
318
+ * xi
319
+ )
320
+
321
+
322
+ def alpha3Fit(eta, eta2, xi):
323
+ return (
324
+ 9.5988072383479
325
+ - 397.05438595557433 * eta
326
+ + (
327
+ 16.202126189517813
328
+ - 1574.8286986717037 * eta
329
+ + 3600.3410843831093 * eta2
330
+ + (
331
+ 27.092429659075467
332
+ - 1786.482357315139 * eta
333
+ + 5152.919378666511 * eta2
334
+ )
335
+ * xi
336
+ + (
337
+ 11.175710130033895
338
+ - 577.7999423177481 * eta
339
+ + 1808.730762932043 * eta2
340
+ )
341
+ * xi
342
+ * xi
343
+ )
344
+ * xi
345
+ )
346
+
347
+
348
+ def alpha4Fit(eta, eta2, xi):
349
+ return (
350
+ -0.02989487384493607
351
+ + 1.4022106448583738 * eta
352
+ + (
353
+ -0.07356049468633846
354
+ + 0.8337006542278661 * eta
355
+ + 0.2240008282397391 * eta2
356
+ + (
357
+ -0.055202870001177226
358
+ + 0.5667186343606578 * eta
359
+ + 0.7186931973380503 * eta2
360
+ )
361
+ * xi
362
+ + (
363
+ -0.015507437354325743
364
+ + 0.15750322779277187 * eta
365
+ + 0.21076815715176228 * eta2
366
+ )
367
+ * xi
368
+ * xi
369
+ )
370
+ * xi
371
+ )
372
+
373
+
374
+ def alpha5Fit(eta, eta2, xi):
375
+ return (
376
+ 0.9974408278363099
377
+ - 0.007884449714907203 * eta
378
+ + (
379
+ -0.059046901195591035
380
+ + 1.3958712396764088 * eta
381
+ - 4.516631601676276 * eta2
382
+ + (
383
+ -0.05585343136869692
384
+ + 1.7516580039343603 * eta
385
+ - 5.990208965347804 * eta2
386
+ )
387
+ * xi
388
+ + (
389
+ -0.017945336522161195
390
+ + 0.5965097794825992 * eta
391
+ - 2.0608879367971804 * eta2
392
+ )
393
+ * xi
394
+ * xi
395
+ )
396
+ * xi
397
+ )
398
+
399
+
400
+ def rho1_fun(eta, eta2, xi):
401
+ return (
402
+ 3931.8979897196696
403
+ - 17395.758706812805 * eta
404
+ + (
405
+ 3132.375545898835
406
+ + 343965.86092361377 * eta
407
+ - 1.2162565819981997e6 * eta2
408
+ + (
409
+ -70698.00600428853
410
+ + 1.383907177859705e6 * eta
411
+ - 3.9662761890979446e6 * eta2
412
+ )
413
+ * xi
414
+ + (
415
+ -60017.52423652596
416
+ + 803515.1181825735 * eta
417
+ - 2.091710365941658e6 * eta2
418
+ )
419
+ * xi
420
+ * xi
421
+ )
422
+ * xi
423
+ )
424
+
425
+
426
+ def rho2_fun(eta, eta2, xi):
427
+ return (
428
+ -40105.47653771657
429
+ + 112253.0169706701 * eta
430
+ + (
431
+ 23561.696065836168
432
+ - 3.476180699403351e6 * eta
433
+ + 1.137593670849482e7 * eta2
434
+ + (
435
+ 754313.1127166454
436
+ - 1.308476044625268e7 * eta
437
+ + 3.6444584853928134e7 * eta2
438
+ )
439
+ * xi
440
+ + (
441
+ 596226.612472288
442
+ - 7.4277901143564405e6 * eta
443
+ + 1.8928977514040343e7 * eta2
444
+ )
445
+ * xi
446
+ * xi
447
+ )
448
+ * xi
449
+ )
450
+
451
+
452
+ def rho3_fun(eta, eta2, xi):
453
+ return (
454
+ 83208.35471266537
455
+ - 191237.7264145924 * eta
456
+ + (
457
+ -210916.2454782992
458
+ + 8.71797508352568e6 * eta
459
+ - 2.6914942420669552e7 * eta2
460
+ + (
461
+ -1.9889806527362722e6
462
+ + 3.0888029960154563e7 * eta
463
+ - 8.390870279256162e7 * eta2
464
+ )
465
+ * xi
466
+ + (
467
+ -1.4535031953446497e6
468
+ + 1.7063528990822166e7 * eta
469
+ - 4.2748659731120914e7 * eta2
470
+ )
471
+ * xi
472
+ * xi
473
+ )
474
+ * xi
475
+ )
476
+
477
+
478
+ def FinalSpin0815(eta, eta2, chi1, chi2):
479
+ Seta = torch.sqrt(1.0 - 4.0 * eta)
480
+ Seta = torch.nan_to_num(Seta) # avoid nan around eta = 0.25
481
+ m1 = 0.5 * (1.0 + Seta)
482
+ m2 = 0.5 * (1.0 - Seta)
483
+ m1s = m1 * m1
484
+ m2s = m2 * m2
485
+ s = m1s * chi1 + m2s * chi2
486
+ eta3 = eta2 * eta
487
+ s2 = s * s
488
+ s3 = s2 * s
489
+ return eta * (
490
+ 3.4641016151377544
491
+ - 4.399247300629289 * eta
492
+ + 9.397292189321194 * eta2
493
+ - 13.180949901606242 * eta3
494
+ + (
495
+ (1.0 / eta - 0.0850917821418767 - 5.837029316602263 * eta)
496
+ + (0.1014665242971878 - 2.0967746996832157 * eta) * s
497
+ + (-1.3546806617824356 + 4.108962025369336 * eta) * s2
498
+ + (-0.8676969352555539 + 2.064046835273906 * eta) * s3
499
+ )
500
+ * s
501
+ )
502
+
503
+
504
+ def PhenomInternal_EradRational0815(eta, eta2, chi1, chi2):
505
+ Seta = torch.sqrt(1.0 - 4.0 * eta)
506
+ m1 = 0.5 * (1.0 + Seta)
507
+ m2 = 0.5 * (1.0 - Seta)
508
+ m1s = m1 * m1
509
+ m2s = m2 * m2
510
+ s = (m1s * chi1 + m2s * chi2) / (m1s + m2s)
511
+
512
+ eta3 = eta2 * eta
513
+
514
+ return (
515
+ eta
516
+ * (
517
+ 0.055974469826360077
518
+ + 0.5809510763115132 * eta
519
+ - 0.9606726679372312 * eta2
520
+ + 3.352411249771192 * eta3
521
+ )
522
+ * (
523
+ 1.0
524
+ + (
525
+ -0.0030302335878845507
526
+ - 2.0066110851351073 * eta
527
+ + 7.7050567802399215 * eta2
528
+ )
529
+ * s
530
+ )
531
+ ) / (
532
+ 1.0
533
+ + (
534
+ -0.6714403054720589
535
+ - 1.4756929437702908 * eta
536
+ + 7.304676214885011 * eta2
537
+ )
538
+ * s
539
+ )
540
+
541
+
542
+ def AmpIntColFitCoeff(eta, eta2, xi):
543
+ return (
544
+ 0.8149838730507785
545
+ + 2.5747553517454658 * eta
546
+ + (
547
+ 1.1610198035496786
548
+ - 2.3627771785551537 * eta
549
+ + 6.771038707057573 * eta2
550
+ + (
551
+ 0.7570782938606834
552
+ - 2.7256896890432474 * eta
553
+ + 7.1140380397149965 * eta2
554
+ )
555
+ * xi
556
+ + (
557
+ 0.1766934149293479
558
+ - 0.7978690983168183 * eta
559
+ + 2.1162391502005153 * eta2
560
+ )
561
+ * xi
562
+ * xi
563
+ )
564
+ * xi
565
+ )
566
+
567
+
568
+ def delta_values(f1, f2, f3, v1, v2, v3, d1, d2):
569
+ f12 = f1 * f1
570
+ f13 = f1 * f12
571
+ f14 = f1 * f13
572
+ f15 = f1 * f14
573
+ f22 = f2 * f2
574
+ f23 = f2 * f22
575
+ f24 = f2 * f23
576
+ f32 = f3 * f3
577
+ f33 = f3 * f32
578
+ f34 = f3 * f33
579
+ f35 = f3 * f34
580
+ delta_0 = -(
581
+ (
582
+ d2 * f15 * f22 * f3
583
+ - 2 * d2 * f14 * f23 * f3
584
+ + d2 * f13 * f24 * f3
585
+ - d2 * f15 * f2 * f32
586
+ + d2 * f14 * f22 * f32
587
+ - d1 * f13 * f23 * f32
588
+ + d2 * f13 * f23 * f32
589
+ + d1 * f12 * f24 * f32
590
+ - d2 * f12 * f24 * f32
591
+ + d2 * f14 * f2 * f33
592
+ + 2 * d1 * f13 * f22 * f33
593
+ - 2 * d2 * f13 * f22 * f33
594
+ - d1 * f12 * f23 * f33
595
+ + d2 * f12 * f23 * f33
596
+ - d1 * f1 * f24 * f33
597
+ - d1 * f13 * f2 * f34
598
+ - d1 * f12 * f22 * f34
599
+ + 2 * d1 * f1 * f23 * f34
600
+ + d1 * f12 * f2 * f35
601
+ - d1 * f1 * f22 * f35
602
+ + 4 * f12 * f23 * f32 * v1
603
+ - 3 * f1 * f24 * f32 * v1
604
+ - 8 * f12 * f22 * f33 * v1
605
+ + 4 * f1 * f23 * f33 * v1
606
+ + f24 * f33 * v1
607
+ + 4 * f12 * f2 * f34 * v1
608
+ + f1 * f22 * f34 * v1
609
+ - 2 * f23 * f34 * v1
610
+ - 2 * f1 * f2 * f35 * v1
611
+ + f22 * f35 * v1
612
+ - f15 * f32 * v2
613
+ + 3 * f14 * f33 * v2
614
+ - 3 * f13 * f34 * v2
615
+ + f12 * f35 * v2
616
+ - f15 * f22 * v3
617
+ + 2 * f14 * f23 * v3
618
+ - f13 * f24 * v3
619
+ + 2 * f15 * f2 * f3 * v3
620
+ - f14 * f22 * f3 * v3
621
+ - 4 * f13 * f23 * f3 * v3
622
+ + 3 * f12 * f24 * f3 * v3
623
+ - 4 * f14 * f2 * f32 * v3
624
+ + 8 * f13 * f22 * f32 * v3
625
+ - 4 * f12 * f23 * f32 * v3
626
+ )
627
+ / ((f1 - f2) ** 2 * (f1 - f3) ** 3 * (f3 - f2) ** 2)
628
+ )
629
+
630
+ delta_1 = -(
631
+ (
632
+ -(d2 * f15 * f22)
633
+ + 2 * d2 * f14 * f23
634
+ - d2 * f13 * f24
635
+ - d2 * f14 * f22 * f3
636
+ + 2 * d1 * f13 * f23 * f3
637
+ + 2 * d2 * f13 * f23 * f3
638
+ - 2 * d1 * f12 * f24 * f3
639
+ - d2 * f12 * f24 * f3
640
+ + d2 * f15 * f32
641
+ - 3 * d1 * f13 * f22 * f32
642
+ - d2 * f13 * f22 * f32
643
+ + 2 * d1 * f12 * f23 * f32
644
+ - 2 * d2 * f12 * f23 * f32
645
+ + d1 * f1 * f24 * f32
646
+ + 2 * d2 * f1 * f24 * f32
647
+ - d2 * f14 * f33
648
+ + d1 * f12 * f22 * f33
649
+ + 3 * d2 * f12 * f22 * f33
650
+ - 2 * d1 * f1 * f23 * f33
651
+ - 2 * d2 * f1 * f23 * f33
652
+ + d1 * f24 * f33
653
+ + d1 * f13 * f34
654
+ + d1 * f1 * f22 * f34
655
+ - 2 * d1 * f23 * f34
656
+ - d1 * f12 * f35
657
+ + d1 * f22 * f35
658
+ - 8 * f12 * f23 * f3 * v1
659
+ + 6 * f1 * f24 * f3 * v1
660
+ + 12 * f12 * f22 * f32 * v1
661
+ - 8 * f1 * f23 * f32 * v1
662
+ - 4 * f12 * f34 * v1
663
+ + 2 * f1 * f35 * v1
664
+ + 2 * f15 * f3 * v2
665
+ - 4 * f14 * f32 * v2
666
+ + 4 * f12 * f34 * v2
667
+ - 2 * f1 * f35 * v2
668
+ - 2 * f15 * f3 * v3
669
+ + 8 * f12 * f23 * f3 * v3
670
+ - 6 * f1 * f24 * f3 * v3
671
+ + 4 * f14 * f32 * v3
672
+ - 12 * f12 * f22 * f32 * v3
673
+ + 8 * f1 * f23 * f32 * v3
674
+ )
675
+ / ((f1 - f2) ** 2 * (f1 - f3) ** 3 * (-f2 + f3) ** 2)
676
+ )
677
+
678
+ delta_2 = -(
679
+ (
680
+ d2 * f15 * f2
681
+ - d1 * f13 * f23
682
+ - 3 * d2 * f13 * f23
683
+ + d1 * f12 * f24
684
+ + 2 * d2 * f12 * f24
685
+ - d2 * f15 * f3
686
+ + d2 * f14 * f2 * f3
687
+ - d1 * f12 * f23 * f3
688
+ + d2 * f12 * f23 * f3
689
+ + d1 * f1 * f24 * f3
690
+ - d2 * f1 * f24 * f3
691
+ - d2 * f14 * f32
692
+ + 3 * d1 * f13 * f2 * f32
693
+ + d2 * f13 * f2 * f32
694
+ - d1 * f1 * f23 * f32
695
+ + d2 * f1 * f23 * f32
696
+ - 2 * d1 * f24 * f32
697
+ - d2 * f24 * f32
698
+ - 2 * d1 * f13 * f33
699
+ + 2 * d2 * f13 * f33
700
+ - d1 * f12 * f2 * f33
701
+ - 3 * d2 * f12 * f2 * f33
702
+ + 3 * d1 * f23 * f33
703
+ + d2 * f23 * f33
704
+ + d1 * f12 * f34
705
+ - d1 * f1 * f2 * f34
706
+ + d1 * f1 * f35
707
+ - d1 * f2 * f35
708
+ + 4 * f12 * f23 * v1
709
+ - 3 * f1 * f24 * v1
710
+ + 4 * f1 * f23 * f3 * v1
711
+ - 3 * f24 * f3 * v1
712
+ - 12 * f12 * f2 * f32 * v1
713
+ + 4 * f23 * f32 * v1
714
+ + 8 * f12 * f33 * v1
715
+ - f1 * f34 * v1
716
+ - f35 * v1
717
+ - f15 * v2
718
+ - f14 * f3 * v2
719
+ + 8 * f13 * f32 * v2
720
+ - 8 * f12 * f33 * v2
721
+ + f1 * f34 * v2
722
+ + f35 * v2
723
+ + f15 * v3
724
+ - 4 * f12 * f23 * v3
725
+ + 3 * f1 * f24 * v3
726
+ + f14 * f3 * v3
727
+ - 4 * f1 * f23 * f3 * v3
728
+ + 3 * f24 * f3 * v3
729
+ - 8 * f13 * f32 * v3
730
+ + 12 * f12 * f2 * f32 * v3
731
+ - 4 * f23 * f32 * v3
732
+ )
733
+ / ((f1 - f2) ** 2 * (f1 - f3) ** 3 * (-f2 + f3) ** 2)
734
+ )
735
+
736
+ delta_3 = -(
737
+ (
738
+ -2 * d2 * f14 * f2
739
+ + d1 * f13 * f22
740
+ + 3 * d2 * f13 * f22
741
+ - d1 * f1 * f24
742
+ - d2 * f1 * f24
743
+ + 2 * d2 * f14 * f3
744
+ - 2 * d1 * f13 * f2 * f3
745
+ - 2 * d2 * f13 * f2 * f3
746
+ + d1 * f12 * f22 * f3
747
+ - d2 * f12 * f22 * f3
748
+ + d1 * f24 * f3
749
+ + d2 * f24 * f3
750
+ + d1 * f13 * f32
751
+ - d2 * f13 * f32
752
+ - 2 * d1 * f12 * f2 * f32
753
+ + 2 * d2 * f12 * f2 * f32
754
+ + d1 * f1 * f22 * f32
755
+ - d2 * f1 * f22 * f32
756
+ + d1 * f12 * f33
757
+ - d2 * f12 * f33
758
+ + 2 * d1 * f1 * f2 * f33
759
+ + 2 * d2 * f1 * f2 * f33
760
+ - 3 * d1 * f22 * f33
761
+ - d2 * f22 * f33
762
+ - 2 * d1 * f1 * f34
763
+ + 2 * d1 * f2 * f34
764
+ - 4 * f12 * f22 * v1
765
+ + 2 * f24 * v1
766
+ + 8 * f12 * f2 * f3 * v1
767
+ - 4 * f1 * f22 * f3 * v1
768
+ - 4 * f12 * f32 * v1
769
+ + 8 * f1 * f2 * f32 * v1
770
+ - 4 * f22 * f32 * v1
771
+ - 4 * f1 * f33 * v1
772
+ + 2 * f34 * v1
773
+ + 2 * f14 * v2
774
+ - 4 * f13 * f3 * v2
775
+ + 4 * f1 * f33 * v2
776
+ - 2 * f34 * v2
777
+ - 2 * f14 * v3
778
+ + 4 * f12 * f22 * v3
779
+ - 2 * f24 * v3
780
+ + 4 * f13 * f3 * v3
781
+ - 8 * f12 * f2 * f3 * v3
782
+ + 4 * f1 * f22 * f3 * v3
783
+ + 4 * f12 * f32 * v3
784
+ - 8 * f1 * f2 * f32 * v3
785
+ + 4 * f22 * f32 * v3
786
+ )
787
+ / ((f1 - f2) ** 2 * (f1 - f3) ** 3 * (-f2 + f3) ** 2)
788
+ )
789
+
790
+ delta_4 = -(
791
+ (
792
+ d2 * f13 * f2
793
+ - d1 * f12 * f22
794
+ - 2 * d2 * f12 * f22
795
+ + d1 * f1 * f23
796
+ + d2 * f1 * f23
797
+ - d2 * f13 * f3
798
+ + 2 * d1 * f12 * f2 * f3
799
+ + d2 * f12 * f2 * f3
800
+ - d1 * f1 * f22 * f3
801
+ + d2 * f1 * f22 * f3
802
+ - d1 * f23 * f3
803
+ - d2 * f23 * f3
804
+ - d1 * f12 * f32
805
+ + d2 * f12 * f32
806
+ - d1 * f1 * f2 * f32
807
+ - 2 * d2 * f1 * f2 * f32
808
+ + 2 * d1 * f22 * f32
809
+ + d2 * f22 * f32
810
+ + d1 * f1 * f33
811
+ - d1 * f2 * f33
812
+ + 3 * f1 * f22 * v1
813
+ - 2 * f23 * v1
814
+ - 6 * f1 * f2 * f3 * v1
815
+ + 3 * f22 * f3 * v1
816
+ + 3 * f1 * f32 * v1
817
+ - f33 * v1
818
+ - f13 * v2
819
+ + 3 * f12 * f3 * v2
820
+ - 3 * f1 * f32 * v2
821
+ + f33 * v2
822
+ + f13 * v3
823
+ - 3 * f1 * f22 * v3
824
+ + 2 * f23 * v3
825
+ - 3 * f12 * f3 * v3
826
+ + 6 * f1 * f2 * f3 * v3
827
+ - 3 * f22 * f3 * v3
828
+ )
829
+ / ((f1 - f2) ** 2 * (f1 - f3) ** 3 * (-f2 + f3) ** 2)
830
+ )
831
+
832
+ return delta_0, delta_1, delta_2, delta_3, delta_4
833
+
834
+
835
+ def chiPN(Seta, eta, chi1, chi2):
836
+ chi_s = chi1 + chi2
837
+ chi_a = chi1 - chi2
838
+
839
+ return 0.5 * (chi_s * (1.0 - eta * 76.0 / 113.0) + Seta * chi_a)
840
+
841
+
842
+ def _linear_interp_finspin(finspin):
843
+ # Put QNM data in same device as input
844
+ QNMData_a = phenom_d_data.QNMData_a.to(device=finspin.device)
845
+ QNMData_fdamp = phenom_d_data.QNMData_fdamp.to(device=finspin.device)
846
+ QNMData_fring = phenom_d_data.QNMData_fring.to(device=finspin.device)
847
+ # chi is a batch of final spins i.e. torch.Size([n])
848
+ right_spin_idx = torch.bucketize(finspin, QNMData_a)
849
+ right_spin_val = QNMData_a[right_spin_idx]
850
+ # QNMData_a is sorted, hence take the previous index
851
+ left_spin_idx = right_spin_idx - 1
852
+ left_spin_val = QNMData_a[left_spin_idx]
853
+
854
+ if not torch.all(left_spin_val < right_spin_val):
855
+ raise RuntimeError(
856
+ "Left value in grid should be greater than right. "
857
+ "Maybe be caused for extremal spin values."
858
+ )
859
+ left_fring = QNMData_fring[left_spin_idx]
860
+ right_fring = QNMData_fring[right_spin_idx]
861
+ slope_fring = right_fring - left_fring
862
+ slope_fring /= right_spin_val - left_spin_val
863
+
864
+ left_fdamp = QNMData_fdamp[left_spin_idx]
865
+ right_fdamp = QNMData_fdamp[right_spin_idx]
866
+ slope_fdamp = right_fdamp - left_fdamp
867
+ slope_fdamp /= right_spin_val - left_spin_val
868
+
869
+ return (
870
+ slope_fring * (finspin - left_spin_val) + left_fring,
871
+ slope_fdamp * (finspin - left_spin_val) + left_fdamp,
872
+ )
873
+
874
+
875
+ def fmaxCalc(fRD, fDM, gamma2, gamma3):
876
+ res = torch.zeros_like(gamma2)
877
+ res = torch.abs(fRD + (-fDM * gamma3) / gamma2) * (gamma2 > 1).to(
878
+ torch.int
879
+ ) + torch.abs(
880
+ fRD + (fDM * (-1 + torch.sqrt(1 - gamma2 * gamma2)) * gamma3) / gamma2
881
+ ) * (
882
+ gamma2 <= 1
883
+ ).to(
884
+ torch.int
885
+ )
886
+ return res
887
+
888
+
889
+ def fring_fdamp(eta, eta2, chi1, chi2):
890
+ finspin = FinalSpin0815(eta, eta2, chi1, chi2)
891
+ Erad = PhenomInternal_EradRational0815(eta, eta2, chi1, chi2)
892
+
893
+ fRD, fDM = _linear_interp_finspin(finspin)
894
+ fRD /= 1.0 - Erad
895
+ fDM /= 1.0 - Erad
896
+
897
+ return fRD, fDM
898
+
899
+
900
+ def phenom_d_inspiral_phase(Mf, mass_1, mass_2, eta, eta2, xi, chi1, chi2):
901
+ ins_phasing, ins_Dphasing = taylorf2_phase(Mf, mass_1, mass_2, chi1, chi2)
902
+
903
+ sigma1 = sigma1Fit(eta, eta2, xi)
904
+ sigma2 = sigma2Fit(eta, eta2, xi)
905
+ sigma3 = sigma3Fit(eta, eta2, xi)
906
+ sigma4 = sigma4Fit(eta, eta2, xi)
907
+
908
+ ins_phasing += (Mf.T * sigma1 / eta).T
909
+ ins_phasing += (Mf.T ** (4.0 / 3.0) * 0.75 * sigma2 / eta).T
910
+ ins_phasing += (Mf.T ** (5.0 / 3.0) * 0.6 * sigma3 / eta).T
911
+ ins_phasing += (Mf.T**2.0 * 0.5 * sigma4 / eta).T
912
+
913
+ ins_Dphasing = (ins_Dphasing.T + sigma1 / eta).T
914
+ ins_Dphasing += (Mf.T ** (1.0 / 3.0) * sigma2 / eta).T
915
+ ins_Dphasing += (Mf.T ** (2.0 / 3.0) * sigma3 / eta).T
916
+ ins_Dphasing += (Mf.T * sigma4 / eta).T
917
+
918
+ return ins_phasing, ins_Dphasing
919
+
920
+
921
+ def phenom_d_int_phase(Mf, eta, eta2, xi):
922
+ beta1 = beta1Fit(eta, eta2, xi)
923
+ beta2 = beta2Fit(eta, eta2, xi)
924
+ beta3 = beta3Fit(eta, eta2, xi)
925
+ # Merger phase
926
+ # Leading beta0 is not added here
927
+ # overall 1/eta is not multiplied
928
+ int_phasing = (Mf.T * beta1).T
929
+ int_phasing += (torch.log(Mf).T * beta2).T
930
+ int_phasing -= (Mf.T ** (-3.0) / 3.0 * beta3).T
931
+
932
+ # overall 1/eta is multiple in derivative of
933
+ # intermediate phase
934
+ int_Dphasing = (Mf.T ** (-4.0) * beta3).T
935
+ int_Dphasing += (Mf.T ** (-1.0) * beta2).T
936
+ int_Dphasing = (int_Dphasing.T + beta1).T
937
+ int_Dphasing = (int_Dphasing.T / eta).T
938
+ return int_phasing, int_Dphasing
939
+
940
+
941
+ def phenom_d_mrd_phase(Mf, eta, eta2, chi1, chi2, xi):
942
+ alpha1 = alpha1Fit(eta, eta2, xi)
943
+ alpha2 = alpha2Fit(eta, eta2, xi)
944
+ alpha3 = alpha3Fit(eta, eta2, xi)
945
+ alpha4 = alpha4Fit(eta, eta2, xi)
946
+ alpha5 = alpha5Fit(eta, eta2, xi)
947
+
948
+ # merger ringdown
949
+ fRD, fDM = fring_fdamp(eta, eta2, chi1, chi2)
950
+ f_minus_alpha5_fRD = (Mf.T - alpha5 * fRD).T
951
+
952
+ # Leading 1/eta is not multiplied at this stage
953
+ mrd_phasing = (Mf.T * alpha1).T
954
+ mrd_phasing -= (1 / Mf.T * alpha2).T
955
+ mrd_phasing += (4.0 / 3.0) * (Mf.T ** (3.0 / 4.0) * alpha3).T
956
+ mrd_phasing += (torch.atan(f_minus_alpha5_fRD.T / fDM) * alpha4).T
957
+
958
+ mrd_Dphasing = (alpha4 * fDM / (f_minus_alpha5_fRD.T**2 + fDM**2)).T
959
+ mrd_Dphasing += (Mf.T ** (-1.0 / 4.0) * alpha3).T
960
+ mrd_Dphasing += (Mf.T ** (-2.0) * alpha2).T
961
+ mrd_Dphasing = (mrd_Dphasing.T + alpha1).T
962
+ mrd_Dphasing = (mrd_Dphasing.T / eta).T
963
+
964
+ return mrd_phasing, mrd_Dphasing
965
+
966
+
967
+ def phenom_d_phase(Mf, mass_1, mass_2, eta, eta2, chi1, chi2, xi):
968
+ ins_phase, ins_Dphase = phenom_d_inspiral_phase(
969
+ Mf, mass_1, mass_2, eta, eta2, xi, chi1, chi2
970
+ )
971
+ int_phase, int_Dphase = phenom_d_int_phase(Mf, eta, eta2, xi)
972
+ mrd_phase, mrd_Dphase = phenom_d_mrd_phase(Mf, eta, eta2, chi1, chi2, xi)
973
+
974
+ # merger ringdown
975
+ fRD, fDM = fring_fdamp(eta, eta2, chi1, chi2)
976
+ # definitions in Eq. (35) of arXiv:1508.07253
977
+ # PHI_fJoin_INS in header LALSimIMRPhenomD.h
978
+ # C1 continuity at intermediate region i.e. f_1
979
+ PHI_fJoin_INS = 0.018 * torch.ones_like(Mf)
980
+ ins_phase_f1, ins_Dphase_f1 = phenom_d_inspiral_phase(
981
+ PHI_fJoin_INS, mass_1, mass_2, eta, eta2, xi, chi1, chi2
982
+ )
983
+ int_phase_f1, int_Dphase_f1 = phenom_d_int_phase(
984
+ PHI_fJoin_INS, eta, eta2, xi
985
+ )
986
+ C2Int = ins_Dphase_f1 - int_Dphase_f1
987
+ C1Int = ins_phase_f1 - (int_phase_f1.T / eta).T - C2Int * PHI_fJoin_INS
988
+ # C1 continuity at ringdown
989
+ fRDJoin = (0.5 * torch.ones_like(Mf).T * fRD).T
990
+ int_phase_rd, int_Dphase_rd = phenom_d_int_phase(fRDJoin, eta, eta2, xi)
991
+ mrd_phase_rd, mrd_Dphase_rd = phenom_d_mrd_phase(
992
+ fRDJoin, eta, eta2, chi1, chi2, xi
993
+ )
994
+ PhiIntTempVal = (int_phase_rd.T / eta).T + C1Int + C2Int * fRDJoin
995
+ # C2MRD = int_Dphase_rd - mrd_Dphase_rd
996
+ C2MRD = C2Int + int_Dphase_rd - mrd_Dphase_rd
997
+ C1MRD = PhiIntTempVal - (mrd_phase_rd.T / eta).T - C2MRD * fRDJoin
998
+
999
+ int_phase = (int_phase.T / eta).T
1000
+ int_phase += C1Int
1001
+ int_phase += Mf * C2Int
1002
+
1003
+ mrd_phase = (mrd_phase.T / eta).T
1004
+ mrd_phase += C1MRD
1005
+ mrd_phase += Mf * C2MRD
1006
+
1007
+ # construct full IMR phase
1008
+ theta_minus_f1 = torch.heaviside(
1009
+ PHI_fJoin_INS - Mf, torch.tensor(0.0, device=Mf.device)
1010
+ )
1011
+ theta_plus_f1 = torch.heaviside(
1012
+ Mf - PHI_fJoin_INS, torch.tensor(1.0, device=Mf.device)
1013
+ )
1014
+ theta_minus_f2 = torch.heaviside(
1015
+ fRDJoin - Mf, torch.tensor(0.0, device=Mf.device)
1016
+ )
1017
+ theta_plus_f2 = torch.heaviside(
1018
+ Mf - fRDJoin, torch.tensor(1.0, device=Mf.device)
1019
+ )
1020
+
1021
+ phasing = theta_minus_f1 * ins_phase
1022
+ phasing += theta_plus_f1 * int_phase * theta_minus_f2
1023
+ phasing += theta_plus_f2 * mrd_phase
1024
+
1025
+ Dphasing = theta_minus_f1 * ins_Dphase
1026
+ Dphasing += theta_plus_f1 * int_Dphase * theta_minus_f2
1027
+ Dphasing += theta_plus_f2 * mrd_Dphase
1028
+
1029
+ return phasing, Dphasing
1030
+
1031
+
1032
+ def phenom_d_inspiral_amp(Mf, eta, eta2, Seta, xi, chi1, chi2, chi12, chi22):
1033
+ SetaPlus1 = 1 + Seta
1034
+
1035
+ Mf_one_third = Mf ** (1.0 / 3.0)
1036
+ Mf_two_third = Mf_one_third * Mf_one_third
1037
+ Mf_four_third = Mf_two_third * Mf_two_third
1038
+ Mf_five_third = Mf_four_third * Mf_one_third
1039
+ Mf_seven_third = Mf_five_third * Mf_two_third
1040
+ MF_eight_third = Mf_seven_third * Mf_one_third
1041
+ Mf_two = Mf * Mf
1042
+ Mf_three = Mf_two * Mf
1043
+
1044
+ prefactors_two_thirds = ((-969 + 1804 * eta) * PI ** (2.0 / 3.0)) / 672
1045
+ prefactors_one = (
1046
+ (
1047
+ chi1 * (81 * SetaPlus1 - 44 * eta)
1048
+ + chi2 * (81 - 81 * Seta - 44 * eta)
1049
+ )
1050
+ * PI
1051
+ ) / 48.0
1052
+ prefactors_four_thirds = (
1053
+ (
1054
+ -27312085.0
1055
+ - 10287648 * chi22
1056
+ - 10287648 * chi12 * SetaPlus1
1057
+ + 10287648 * chi22 * Seta
1058
+ + 24
1059
+ * (
1060
+ -1975055
1061
+ + 857304 * chi12
1062
+ - 994896 * chi1 * chi2
1063
+ + 857304 * chi22
1064
+ )
1065
+ * eta
1066
+ + 35371056 * eta2 * PI ** (4.0 / 3.0)
1067
+ )
1068
+ ) / 8.128512e6
1069
+ prefactors_five_thirds = (
1070
+ PI ** (5.0 / 3.0)
1071
+ * (
1072
+ chi2
1073
+ * (
1074
+ -285197 * (-1 + Seta)
1075
+ + 4 * (-91902 + 1579 * Seta) * eta
1076
+ - 35632 * eta2
1077
+ )
1078
+ + chi1
1079
+ * (
1080
+ 285197 * SetaPlus1
1081
+ - 4 * (91902 + 1579 * Seta) * eta
1082
+ - 35632 * eta2
1083
+ )
1084
+ + 42840 * (-1.0 + 4 * eta) * PI
1085
+ )
1086
+ ) / 32256.0
1087
+ prefactors_two = (
1088
+ -(
1089
+ PI**2
1090
+ * (
1091
+ -336
1092
+ * (
1093
+ -3248849057.0
1094
+ + 2943675504 * chi12
1095
+ - 3339284256 * chi1 * chi2
1096
+ + 2943675504 * chi22
1097
+ )
1098
+ * eta2
1099
+ - 324322727232 * eta2 * eta
1100
+ - 7
1101
+ * (
1102
+ -177520268561
1103
+ + 107414046432 * chi22
1104
+ + 107414046432 * chi12 * SetaPlus1
1105
+ - 107414046432 * chi22 * Seta
1106
+ + 11087290368
1107
+ * (chi1 + chi2 + chi1 * Seta - chi2 * Seta)
1108
+ * PI
1109
+ )
1110
+ + 12
1111
+ * eta
1112
+ * (
1113
+ -545384828789
1114
+ - 176491177632 * chi1 * chi2
1115
+ + 202603761360 * chi22
1116
+ + 77616 * chi12 * (2610335 + 995766 * Seta)
1117
+ - 77287373856 * chi22 * Seta
1118
+ + 5841690624 * (chi1 + chi2) * PI
1119
+ + 21384760320 * PI**2
1120
+ )
1121
+ )
1122
+ )
1123
+ / 6.0085960704e10
1124
+ )
1125
+ prefactors_seven_thirds = rho1_fun(eta, eta2, xi)
1126
+ prefactors_eight_thirds = rho2_fun(eta, eta2, xi)
1127
+ prefactors_three = rho3_fun(eta, eta2, xi)
1128
+
1129
+ amp = torch.ones_like(Mf)
1130
+ amp += (
1131
+ Mf_two_third.T * prefactors_two_thirds
1132
+ + Mf_four_third.T * prefactors_four_thirds
1133
+ + Mf_five_third.T * prefactors_five_thirds
1134
+ + Mf_seven_third.T * prefactors_seven_thirds
1135
+ + MF_eight_third.T * prefactors_eight_thirds
1136
+ + Mf.T * prefactors_one
1137
+ + Mf_two.T * prefactors_two
1138
+ + Mf_three.T * prefactors_three
1139
+ ).T
1140
+
1141
+ Damp = (
1142
+ (2.0 / 3.0) / Mf_one_third.T * prefactors_two_thirds
1143
+ + (4.0 / 3.0) * Mf_one_third.T * prefactors_four_thirds
1144
+ + (5.0 / 3.0) * Mf_two_third.T * prefactors_five_thirds
1145
+ + (7.0 / 3.0) * Mf_four_third.T * prefactors_seven_thirds
1146
+ + (8.0 / 3.0) * Mf_five_third.T * prefactors_eight_thirds
1147
+ + prefactors_one
1148
+ + 2.0 * Mf.T * prefactors_two
1149
+ + 3.0 * Mf_two.T * prefactors_three
1150
+ ).T
1151
+
1152
+ return amp, Damp
1153
+
1154
+
1155
+ def phenom_d_mrd_amp(Mf, eta, eta2, chi1, chi2, xi):
1156
+ # merger ringdown
1157
+ fRD, fDM = fring_fdamp(eta, eta2, chi1, chi2)
1158
+
1159
+ gamma1 = gamma1_fun(eta, eta2, xi)
1160
+ gamma2 = gamma2_fun(eta, eta2, xi)
1161
+ gamma3 = gamma3_fun(eta, eta2, xi)
1162
+ fDMgamma3 = fDM * gamma3
1163
+ pow2_fDMgamma3 = (torch.ones_like(Mf).T * fDMgamma3 * fDMgamma3).T
1164
+ fminfRD = Mf - (torch.ones_like(Mf).T * fRD).T
1165
+ exp_times_lorentzian = torch.exp(fminfRD.T * gamma2 / fDMgamma3).T
1166
+ exp_times_lorentzian *= fminfRD**2 + pow2_fDMgamma3
1167
+
1168
+ amp = (1 / exp_times_lorentzian.T * gamma1 * gamma3 * fDM).T
1169
+ Damp = (fminfRD.T * -2 * fDM * gamma1 * gamma3) / (
1170
+ fminfRD * fminfRD + pow2_fDMgamma3
1171
+ ).T - (gamma2 * gamma1)
1172
+ Damp = Damp.T / exp_times_lorentzian
1173
+ return amp, Damp
1174
+
1175
+
1176
+ def phenom_d_int_amp(Mf, eta, eta2, Seta, chi1, chi2, chi12, chi22, xi):
1177
+ # merger ringdown
1178
+ fRD, fDM = fring_fdamp(eta, eta2, chi1, chi2)
1179
+ # Geometric frequency definition from PhenomD header file
1180
+ AMP_fJoin_INS = 0.014
1181
+
1182
+ Mf1 = AMP_fJoin_INS * torch.ones_like(Mf)
1183
+ gamma2 = gamma2_fun(eta, eta2, xi)
1184
+ gamma3 = gamma3_fun(eta, eta2, xi)
1185
+
1186
+ fpeak = fmaxCalc(fRD, fDM, gamma2, gamma3)
1187
+ Mf3 = (torch.ones_like(Mf).T * fpeak).T
1188
+ dfx = 0.5 * (Mf3 - Mf1)
1189
+ Mf2 = Mf1 + dfx
1190
+
1191
+ v1, d1 = phenom_d_inspiral_amp(
1192
+ Mf1, eta, eta2, Seta, xi, chi1, chi2, chi12, chi22
1193
+ )
1194
+ v3, d2 = phenom_d_mrd_amp(Mf3, eta, eta2, chi1, chi2, xi)
1195
+ v2 = (torch.ones_like(Mf).T * AmpIntColFitCoeff(eta, eta2, xi)).T
1196
+
1197
+ delta_0, delta_1, delta_2, delta_3, delta_4 = delta_values(
1198
+ f1=Mf1, f2=Mf2, f3=Mf3, v1=v1, v2=v2, v3=v3, d1=d1, d2=d2
1199
+ )
1200
+
1201
+ amp = (
1202
+ delta_0
1203
+ + Mf * delta_1
1204
+ + Mf**2 * (delta_2 + Mf * delta_3 + Mf**2 * delta_4)
1205
+ )
1206
+ Damp = delta_1 + Mf * (
1207
+ 2 * delta_2 + 3 * Mf * delta_3 + 4 * Mf**2 * delta_4
1208
+ )
1209
+ return amp, Damp
1210
+
1211
+
1212
+ def phenom_d_amp(
1213
+ Mf, mass_1, mass_2, eta, eta2, Seta, chi1, chi2, chi12, chi22, xi, distance
1214
+ ):
1215
+ ins_amp, ins_Damp = phenom_d_inspiral_amp(
1216
+ Mf, eta, eta2, Seta, xi, chi1, chi2, chi12, chi22
1217
+ )
1218
+ int_amp, int_Damp = phenom_d_int_amp(
1219
+ Mf, eta, eta2, Seta, chi1, chi2, chi12, chi22, xi
1220
+ )
1221
+ mrd_amp, mrd_Damp = phenom_d_mrd_amp(Mf, eta, eta2, chi1, chi2, xi)
1222
+
1223
+ gamma2 = gamma2_fun(eta, eta2, xi)
1224
+ gamma3 = gamma3_fun(eta, eta2, xi)
1225
+ fRD, fDM = fring_fdamp(eta, eta2, chi1, chi2)
1226
+ Mf_peak = fmaxCalc(fRD, fDM, gamma2, gamma3)
1227
+ # Geometric peak and joining frequencies
1228
+ Mf_peak = (torch.ones_like(Mf).T * Mf_peak).T
1229
+ Mf_join_ins = 0.014 * torch.ones_like(Mf)
1230
+
1231
+ # construct full IMR Amp
1232
+ theta_minus_f1 = torch.heaviside(
1233
+ Mf_join_ins - Mf, torch.tensor(0.0, device=Mf.device)
1234
+ )
1235
+ theta_plus_f1 = torch.heaviside(
1236
+ Mf - Mf_join_ins, torch.tensor(1.0, device=Mf.device)
1237
+ )
1238
+ theta_minus_f2 = torch.heaviside(
1239
+ Mf_peak - Mf, torch.tensor(0.0, device=Mf.device)
1240
+ )
1241
+ theta_plus_f2 = torch.heaviside(
1242
+ Mf - Mf_peak, torch.tensor(1.0, device=Mf.device)
1243
+ )
1244
+
1245
+ amp = theta_minus_f1 * ins_amp
1246
+ amp += theta_plus_f1 * int_amp * theta_minus_f2
1247
+ amp += theta_plus_f2 * mrd_amp
1248
+
1249
+ Damp = theta_minus_f1 * ins_Damp
1250
+ Damp += theta_plus_f1 * int_Damp * theta_minus_f2
1251
+ Damp += theta_plus_f2 * mrd_Damp
1252
+
1253
+ return amp, Damp
1254
+
1255
+
1256
+ def phenom_d_htilde(
1257
+ f: TensorType,
1258
+ chirp_mass: TensorType,
1259
+ mass_ratio: TensorType,
1260
+ chi1: TensorType,
1261
+ chi2: TensorType,
1262
+ distance: TensorType,
1263
+ phic: TensorType,
1264
+ f_ref: float,
1265
+ ):
1266
+ total_mass = chirp_mass * (1 + mass_ratio) ** 1.2 / mass_ratio**0.6
1267
+ mass_1 = total_mass / (1 + mass_ratio)
1268
+ mass_2 = mass_1 * mass_ratio
1269
+ eta = (chirp_mass / total_mass) ** (5 / 3)
1270
+ eta2 = eta * eta
1271
+ Seta = torch.sqrt(1.0 - 4.0 * eta)
1272
+ chi = chiPN(Seta, eta, chi1, chi2)
1273
+ chi22 = chi2 * chi2
1274
+ chi12 = chi1 * chi1
1275
+ xi = -1.0 + chi
1276
+ M_s = total_mass * MTSUN_SI
1277
+
1278
+ gamma2 = gamma2_fun(eta, eta2, xi)
1279
+ gamma3 = gamma3_fun(eta, eta2, xi)
1280
+
1281
+ fRD, fDM = fring_fdamp(eta, eta2, chi1, chi2)
1282
+ Mf_peak = fmaxCalc(fRD, fDM, gamma2, gamma3)
1283
+ _, t0 = phenom_d_mrd_phase(Mf_peak, eta, eta2, chi1, chi2, xi)
1284
+
1285
+ Mf = torch.outer(M_s, f)
1286
+ Mf_ref = torch.outer(M_s, f_ref * torch.ones_like(f))
1287
+
1288
+ Psi, _ = phenom_d_phase(Mf, mass_1, mass_2, eta, eta2, chi1, chi2, xi)
1289
+ Psi_ref, _ = phenom_d_phase(
1290
+ Mf_ref, mass_1, mass_2, eta, eta2, chi1, chi2, xi
1291
+ )
1292
+
1293
+ Psi = (Psi.T - 2 * phic).T
1294
+ Psi -= Psi_ref
1295
+ Psi -= ((Mf - Mf_ref).T * t0).T
1296
+
1297
+ amp, _ = phenom_d_amp(
1298
+ Mf,
1299
+ mass_1,
1300
+ mass_2,
1301
+ eta,
1302
+ eta2,
1303
+ Seta,
1304
+ chi1,
1305
+ chi2,
1306
+ chi12,
1307
+ chi22,
1308
+ xi,
1309
+ distance,
1310
+ )
1311
+
1312
+ amp_0 = taylorf2_amplitude(
1313
+ Mf, mass_1, mass_2, eta, distance
1314
+ ) # this includes f^(-7/6) dependence
1315
+
1316
+ h0 = -amp_0 * amp * torch.exp(-1j * Psi)
1317
+
1318
+ return h0
1319
+
1320
+
1321
+ def IMRPhenomD(
1322
+ f: TensorType,
1323
+ chirp_mass: TensorType,
1324
+ mass_ratio: TensorType,
1325
+ chi1: TensorType,
1326
+ chi2: TensorType,
1327
+ distance: TensorType,
1328
+ phic: TensorType,
1329
+ inclination: TensorType,
1330
+ f_ref: float,
1331
+ ):
1332
+ """
1333
+ IMRPhenomD waveform
1334
+
1335
+ Returns:
1336
+ --------
1337
+ hp, hc
1338
+ """
1339
+ # shape assumed (n_batch, params)
1340
+ if (
1341
+ chirp_mass.shape[0] != mass_ratio.shape[0]
1342
+ or mass_ratio.shape[0] != chi1.shape[0]
1343
+ or chi1.shape[0] != chi2.shape[0]
1344
+ or chi2.shape[0] != distance.shape[0]
1345
+ or distance.shape[0] != phic.shape[0]
1346
+ or phic.shape[0] != inclination.shape[0]
1347
+ ):
1348
+ raise RuntimeError("Tensors should have same batch size")
1349
+ cfac = torch.cos(inclination)
1350
+ pfac = 0.5 * (1.0 + cfac * cfac)
1351
+
1352
+ htilde = phenom_d_htilde(
1353
+ f, chirp_mass, mass_ratio, chi1, chi2, distance, phic, f_ref
1354
+ )
1355
+
1356
+ hp = (htilde.T * pfac).T
1357
+ hc = -1j * (htilde.T * cfac).T
1358
+
1359
+ return hp, hc