ml4gw 0.4.1__py3-none-any.whl → 0.5.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.

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