pybhpt 0.9.4__cp314-cp314-macosx_14_0_x86_64.whl → 0.9.8__cp314-cp314-macosx_14_0_x86_64.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 pybhpt might be problematic. Click here for more details.

Binary file
pybhpt/geo.py CHANGED
@@ -4,21 +4,147 @@ from cybhpt_full import kerr_mino_frequencies_wrapper, kerr_orbital_constants_wr
4
4
  import numpy as np
5
5
 
6
6
  def kerrgeo_Vt_radial(a, En, Lz, Q, r):
7
+ """
8
+ The radial part of the potential Vt for the geodesic evolution of $t_p$.
9
+
10
+ Parameters
11
+ ----------
12
+ a : float
13
+ The black hole spin parameter.
14
+ En : float
15
+ The orbital energy of the particle.
16
+ Lz : float
17
+ The z-component of the orbital angular momentum of the particle.
18
+ Q : float
19
+ The Carter constant of the particle.
20
+ r : float
21
+ The radial coordinate.
22
+
23
+ Returns
24
+ -------
25
+ float
26
+ The value of the radial potential Vt at the given parameters.
27
+ """
7
28
  return kerr_geo_V01(a, En, Lz, Q, r)
8
29
 
9
30
  def kerrgeo_Vt_polar(a, En, Lz, Q, theta):
31
+ """
32
+ The polar part of the potential Vt for the geodesic evolution of $t_p$.
33
+
34
+ Parameters
35
+ ----------
36
+ a : float
37
+ The black hole spin parameter.
38
+ En : float
39
+ The orbital energy of the particle.
40
+ Lz : float
41
+ The z-component of the orbital angular momentum of the particle.
42
+ Q : float
43
+ The Carter constant of the particle.
44
+ theta : float
45
+ The polar angle coordinate.
46
+
47
+ Returns
48
+ -------
49
+ float
50
+ The value of the polar potential Vt at the given parameters.
51
+ """
10
52
  return kerr_geo_V02(a, En, Lz, Q, theta)
11
53
 
12
54
  def kerrgeo_Vr(a, En, Lz, Q, r):
55
+ """
56
+ The (squared) radial potential Vr for the geodesic evolution of $r_p$.
57
+
58
+ Parameters
59
+ ----------
60
+ a : float
61
+ The black hole spin parameter.
62
+ En : float
63
+ The orbital energy of the particle.
64
+ Lz : float
65
+ The z-component of the orbital angular momentum of the particle.
66
+ Q : float
67
+ The Carter constant of the particle.
68
+ r : float
69
+ The radial coordinate.
70
+
71
+ Returns
72
+ -------
73
+ float
74
+ The value of the radial potential Vr at the given parameters.
75
+ """
13
76
  return kerr_geo_V11(a, En, Lz, Q, r)
14
77
 
15
78
  def kerrgeo_Vtheta(a, En, Lz, Q, theta):
79
+ """
80
+ The (squared) polar potential Vtheta for the geodesic evolution of $\theta_p$.
81
+
82
+ Parameters
83
+ ----------
84
+ a : float
85
+ The black hole spin parameter.
86
+ En : float
87
+ The orbital energy of the particle.
88
+ Lz : float
89
+ The z-component of the orbital angular momentum of the particle.
90
+ Q : float
91
+ The Carter constant of the particle.
92
+ theta : float
93
+ The polar angle coordinate.
94
+
95
+ Returns
96
+ -------
97
+ float
98
+ The value of the polar potential Vtheta at the given parameters.
99
+ """
16
100
  return kerr_geo_V22(a, En, Lz, Q, theta)
17
101
 
18
102
  def kerrgeo_Vphi_radial(a, En, Lz, Q, r):
103
+ """
104
+ The (squared) radial potential Vphi for the geodesic evolution of $r_p$.
105
+
106
+ Parameters
107
+ ----------
108
+ a : float
109
+ The black hole spin parameter.
110
+ En : float
111
+ The orbital energy of the particle.
112
+ Lz : float
113
+ The z-component of the orbital angular momentum of the particle.
114
+ Q : float
115
+ The Carter constant of the particle.
116
+ r : float
117
+ The radial coordinate.
118
+
119
+ Returns
120
+ -------
121
+ float
122
+ The value of the radial potential Vphi at the given parameters.
123
+ """
19
124
  return kerr_geo_V31(a, En, Lz, Q, r)
20
125
 
21
126
  def kerrgeo_Vphi_polar(a, En, Lz, Q, theta):
127
+ """
128
+ The (squared) polar potential Vphi for the geodesic evolution of $r_p$.
129
+
130
+ Parameters
131
+ ----------
132
+ a : float
133
+ The black hole spin parameter.
134
+ En : float
135
+ The orbital energy of the particle.
136
+ Lz : float
137
+ The z-component of the orbital angular momentum of the particle.
138
+ Q : float
139
+ The Carter constant of the particle.
140
+ theta : float
141
+ The polar angle coordinate.
142
+
143
+ Returns
144
+ -------
145
+ float
146
+ The value of the polar potential Vphi at the given parameters.
147
+ """
22
148
  return kerr_geo_V32(a, En, Lz, Q, theta)
23
149
 
24
150
  def kerr_mino_frequencies(a, p, e, x):
@@ -373,25 +499,256 @@ class KerrGeodesic:
373
499
  """
374
500
  return np.dot(np.array([n, k, m]), (self.frequencies))
375
501
 
376
- def minotime(self, t):
502
+ def psi_radial(self, la):
503
+ """
504
+ Function that returns the radial true anomaly for a given Mino time value.
505
+
506
+ Parameters
507
+ ----------
508
+ la : float or numpy.ndarray
509
+ The Mino time value(s). If a numpy array is provided, the function will return a numpy array of the same shape.
510
+
511
+ Returns
512
+ -------
513
+ numpy.ndarray
514
+ The radial true anomaly for the given Mino time value(s).
515
+ """
516
+ if isinstance(la, np.ndarray) or isinstance(la, list):
517
+ return self.base.psi_radial_vec(np.array(la))
518
+ else:
519
+ return self.base.psi_radial(la)
520
+
521
+ def psi_polar(self, la):
522
+ """
523
+ Function that returns the polar Darwin phase for a given Mino time value.
524
+
525
+ Parameters
526
+ ----------
527
+ la : float or numpy.ndarray
528
+ The Mino time value(s). If a numpy array is provided, the function will return a numpy array of the same shape.
529
+
530
+ Returns
531
+ -------
532
+ numpy.ndarray
533
+ The polar Darwin phase for the given Mino time value(s).
534
+ """
535
+ if isinstance(la, np.ndarray) or isinstance(la, list):
536
+ return self.base.psi_polar_vec(np.array(la))
537
+ else:
538
+ return self.base.psi_polar(la)
539
+
540
+ def psi_radial_of_t(self, t):
541
+ """
542
+ Function that returns the radial true anomaly for a given time value.
543
+
544
+ Parameters
545
+ ----------
546
+ t : float or numpy.ndarray
547
+ The time value(s). If a numpy array is provided, the function will return a numpy array of the same shape.
548
+
549
+ Returns
550
+ -------
551
+ numpy.ndarray
552
+ The radial true anomaly for the given time value(s).
553
+ """
554
+ if isinstance(t, np.ndarray) or isinstance(t, list):
555
+ return self.base.psi_radial_time_vec(np.array(t))
556
+ else:
557
+ return self.base.psi_radial_time(t)
558
+
559
+ def psi_polar_of_t(self, t):
560
+ """
561
+ Function that returns the polar Darwin phase for a given time value.
562
+
563
+ Parameters
564
+ ----------
565
+ t : float or numpy.ndarray
566
+ The time value(s). If a numpy array is provided, the function will return a numpy array of the same shape.
567
+
568
+ Returns
569
+ -------
570
+ numpy.ndarray
571
+ The polar Darwin phase for the given time value(s).
572
+ """
573
+ if isinstance(t, np.ndarray) or isinstance(t, list):
574
+ return self.base.psi_polar_time_vec(np.array(t))
575
+ else:
576
+ return self.base.psi_polar_time(t)
577
+
578
+ def time_position(self, la):
579
+ """
580
+ Function that returns the time position for a given Mino time value.
581
+
582
+ Parameters
583
+ ----------
584
+ la : float or numpy.ndarray
585
+ The Mino time value(s). If a numpy array is provided, the function will return a numpy array of the same shape.
586
+
587
+ Returns
588
+ -------
589
+ numpy.ndarray
590
+ The time position for the given Mino time value(s).
591
+ """
592
+ if isinstance(la, np.ndarray) or isinstance(la, list):
593
+ return self.base.time_position_vec(np.array(la))
594
+ else:
595
+ return self.base.time_position(la)
596
+
597
+ def radial_position(self, la):
598
+ """
599
+ Function that returns the radial position for a given Mino time value.
600
+
601
+ Parameters
602
+ ----------
603
+ la : float or numpy.ndarray
604
+ The Mino time value(s). If a numpy array is provided, the function will return a numpy array of the same shape.
605
+
606
+ Returns
607
+ -------
608
+ numpy.ndarray
609
+ The radial position for the given Mino time value(s).
610
+ """
611
+ if isinstance(la, np.ndarray) or isinstance(la, list):
612
+ return self.base.radial_position_vec(np.array(la))
613
+ else:
614
+ return self.base.radial_position(la)
615
+
616
+ def polar_position(self, la):
617
+ """
618
+ Function that returns the polar position for a given Mino time value.
619
+
620
+ Parameters
621
+ ----------
622
+ la : float or numpy.ndarray
623
+ The Mino time value(s). If a numpy array is provided, the function will return a numpy array of the same shape.
624
+
625
+ Returns
626
+ -------
627
+ numpy.ndarray
628
+ The polar position for the given Mino time value(s).
629
+ """
630
+ if isinstance(la, np.ndarray) or isinstance(la, list):
631
+ return self.base.polar_position_vec(np.array(la))
632
+ else:
633
+ return self.base.polar_position(la)
634
+
635
+ def azimuthal_position(self, la):
636
+ """
637
+ Function that returns the azimuthal position for a given Mino time value.
638
+
639
+ Parameters
640
+ ----------
641
+ la : float or numpy.ndarray
642
+ The Mino time value(s). If a numpy array is provided, the function will return a numpy array of the same shape.
643
+
644
+ Returns
645
+ -------
646
+ numpy.ndarray
647
+ The azimuthal position for the given Mino time value(s).
648
+ """
649
+ if isinstance(la, np.ndarray) or isinstance(la, list):
650
+ return self.base.azimuthal_position_vec(np.array(la))
651
+ else:
652
+ return self.base.azimuthal_position(la)
653
+
654
+ def radial_position_of_t(self, t):
655
+ """
656
+ Function that returns the radial position for a given Mino time value.
657
+
658
+ Parameters
659
+ ----------
660
+ t : float or numpy.ndarray
661
+ The Mino time value(s). If a numpy array is provided, the function will return a numpy array of the same shape.
662
+
663
+ Returns
664
+ -------
665
+ numpy.ndarray
666
+ The radial position for the given Mino time value(s).
667
+ """
668
+ if isinstance(t, np.ndarray) or isinstance(t, list):
669
+ return self.base.radial_position_time_vec(np.array(t))
670
+ else:
671
+ return self.base.radial_position_time(t)
672
+
673
+ def polar_position_of_t(self, t):
674
+ """
675
+ Function that returns the polar position for a given time value.
676
+
677
+ Parameters
678
+ ----------
679
+ t : float or numpy.ndarray
680
+ The time value(s). If a numpy array is provided, the function will return a numpy array of the same shape.
681
+
682
+ Returns
683
+ -------
684
+ numpy.ndarray
685
+ The polar position for the given time value(s).
686
+ """
687
+ if isinstance(t, np.ndarray) or isinstance(t, list):
688
+ return self.base.polar_position_time_vec(np.array(t))
689
+ else:
690
+ return self.base.polar_position_time(t)
691
+
692
+ def azimuthal_position_of_t(self, t):
693
+ """
694
+ Function that returns the azimuthal position for a given time value.
695
+
696
+ Parameters
697
+ ----------
698
+ t : float or numpy.ndarray
699
+ The time value(s). If a numpy array is provided, the function will return a numpy array of the same shape.
700
+
701
+ Returns
702
+ -------
703
+ numpy.ndarray
704
+ The azimuthal position for the given time value(s).
705
+ """
706
+ if isinstance(t, np.ndarray) or isinstance(t, list):
707
+ return self.base.azimuthal_position_time_vec(np.array(t))
708
+ else:
709
+ return self.base.azimuthal_position_time(t)
710
+
711
+ def mino_of_t(self, t):
377
712
  """
378
713
  Function that returns the Mino time for a given Boyer-Lindquist time.
379
714
 
380
715
  Parameters
381
716
  ----------
382
- t : float
383
- The Boyer-Lindquist time.
717
+ t : float or numpy.ndarray
718
+ The Boyer-Lindquist time value(s). If a numpy array is provided, the function will return a numpy array of the same shape.
384
719
 
385
- Returns
720
+ Returns
386
721
  -------
387
- float
388
- The Mino time for the given Boyer-Lindquist time.
722
+ numpy.ndarray
723
+ The Mino time for the given Boyer-Lindquist time value(s).
389
724
  """
390
- return self.base.mino_time(t)
725
+ if isinstance(t, np.ndarray) or isinstance(t, list):
726
+ return self.base.mino_time_vec(np.array(t))
727
+ else:
728
+ return self.base.mino_time(t)
391
729
 
392
- def __call__(self, la):
730
+ def position_of_t(self, t):
393
731
  """
394
- Function that returns the position vector for a given Mino time value.
732
+ Function that returns the position vector (r, theta, phi) for a given Boyer-Lindquist time value.
733
+
734
+ Parameters
735
+ ----------
736
+ t : float or numpy.ndarray
737
+ The Boyer-Lindquist time value(s). If a numpy array is provided, the function will return a numpy array of the same shape.
738
+
739
+ Returns
740
+ -------
741
+ numpy.ndarray
742
+ The position vector (r, theta, phi) for the given Boyer-Lindquist time value(s).
743
+ """
744
+ if isinstance(t, np.ndarray) or isinstance(t, list):
745
+ return self.base.position_time_vec(np.array(t))
746
+ else:
747
+ return self.base.position_time(t)
748
+
749
+ def position(self, la):
750
+ """
751
+ Function that returns the position vector (t, r, theta, phi) for a given Mino time value.
395
752
  Parameters
396
753
  ----------
397
754
  la : float or numpy.ndarray
@@ -399,9 +756,12 @@ class KerrGeodesic:
399
756
  Returns
400
757
  -------
401
758
  numpy.ndarray
402
- The position vector for the given Mino time value(s).
759
+ The position vector (t, r, theta, phi) for the given Mino time value(s).
403
760
  """
404
761
  if isinstance(la, np.ndarray) or isinstance(la, list):
405
762
  return self.base.position_vec(np.array(la))
406
763
  else:
407
- return self.base.position(la)
764
+ return self.base.position(la)
765
+
766
+ def __call__(self, la):
767
+ return self.position(la)
pybhpt/radial.py CHANGED
@@ -11,14 +11,55 @@ def available_methods():
11
11
  """
12
12
  return available_methods_cython()
13
13
 
14
- def renormalized_angular_momentum(s, l, m, a, omega):
15
- return nu_cython(s, l, m, a, omega)
14
+ def renormalized_angular_momentum(s, j, m, a, omega):
15
+ """
16
+ Computes the renormalized angular momentum for the given parameters.
16
17
 
17
- def renormalized_angular_momentum_monodromy(s, l, m, a, omega, la):
18
- return nu_2_cython(s, l, m, a, omega, la)
18
+ Parameters
19
+ ----------
20
+ s : int
21
+ The spin weight of the field.
22
+ j : int
23
+ The spheroidal harmonic mode number.
24
+ m : int
25
+ The azimuthal harmonic mode number.
26
+ a : float
27
+ The black hole spin parameter.
28
+ omega : float
29
+ The frequency of the mode.
19
30
 
20
- def hypergeo_2F1(a, b, c, x):
21
- return hypergeo_2F1_cython(a, b, c, x)
31
+ Returns
32
+ -------
33
+ complex
34
+ The renormalized angular momentum.
35
+ """
36
+ return nu_cython(s, j, m, a, omega)
37
+
38
+ def renormalized_angular_momentum_monodromy(s, j, m, a, omega, la):
39
+ """
40
+ Computes the renormalized angular momentum using the monodromy method for the given parameters.
41
+
42
+ Parameters
43
+ ----------
44
+ s : int
45
+ The spin weight of the field.
46
+ j : int
47
+ The spheroidal harmonic mode number.
48
+ m : int
49
+ The azimuthal harmonic mode number.
50
+ a : float
51
+ The black hole spin parameter.
52
+ omega : complex
53
+ The frequency of the mode.
54
+ la : complex
55
+ The spheroidal eigenvalue.
56
+
57
+ Returns
58
+ -------
59
+ complex
60
+ The renormalized angular momentum.
61
+ """
62
+ return nu_2_cython(s, j, m, a, omega, la)
22
63
 
23
64
  class RadialTeukolsky:
24
65
  """A class for solving the homogeneous radial Teukolsky equation.
@@ -378,4 +419,26 @@ class RadialTeukolsky:
378
419
  elif deriv == 2:
379
420
  return self.radialderivatives2(bc)
380
421
  else:
381
- raise ValueError("RadialTeukolsky only solves up to the second derivative")
422
+ raise ValueError("RadialTeukolsky only solves up to the second derivative")
423
+
424
+ def hypergeo_2F1(a, b, c, x):
425
+ """
426
+ Gauss hypergeometric function 2F1(a, b; c; x). Note that this function is not very stable across the complex domain.
427
+
428
+ Parameters
429
+ ----------
430
+ a : complex
431
+ The first parameter of the hypergeometric function.
432
+ b : complex
433
+ The second parameter of the hypergeometric function.
434
+ c : complex
435
+ The third parameter of the hypergeometric function.
436
+ x : complex
437
+ The argument of the hypergeometric function.
438
+
439
+ Returns
440
+ -------
441
+ complex
442
+ The value of the hypergeometric function 2F1(a, b; c; x).
443
+ """
444
+ return hypergeo_2F1_cython(a, b, c, x)
pybhpt/swsh.py CHANGED
@@ -4,114 +4,133 @@ from scipy.special import sph_harm
4
4
  from scipy.special import binom
5
5
  from scipy.special import factorial
6
6
  import numpy as np
7
+ from cybhpt_full import YslmCy, clebschCy, w3jCy
7
8
 
8
9
  """
9
10
  Wigner 3j-symbol and Clebsch-Gordon coefficients
10
11
  """
11
12
 
12
13
  def fac(n):
14
+ """
15
+ Computes the factorial of a non-negative integer n.
16
+
17
+ Parameters
18
+ ----------
19
+ n : int
20
+ A non-negative integer.
21
+
22
+ Returns
23
+ -------
24
+ float
25
+ The factorial of n.
26
+ """
13
27
  if n < 0:
14
28
  return 0
15
29
  return float(np.math.factorial(n))
16
30
 
17
- def Yslm(s, l, m, th):
31
+ def Yslm(s, l, m, th, ph = None):
32
+ """
33
+ Evaluate the spin-weighted spherical harmonic $Y_{s}^{lm}$ at a given angle theta.
34
+
35
+ Parameters
36
+ ----------
37
+ s : int
38
+ The spin weight of the harmonic.
39
+ l : int
40
+ The angular number of the spherical harmonic.
41
+ m : int
42
+ The azimuthal number of the spherical harmonic.
43
+ th : array_like
44
+ The polar angle(s) at which to evaluate the spherical harmonic.
45
+
46
+ Returns
47
+ -------
48
+ array_like
49
+ The values of the spherical harmonic at the specified angles.
50
+ """
51
+ assert isinstance(s, int) and isinstance(l, int) and isinstance(m, int), "s, l, and m must be integers"
52
+ if ph is not None:
53
+ return Yslm(s, l, m, th)*np.exp(1.j*m*ph)
18
54
  if np.abs(s) > l:
19
55
  return 0.*th
20
56
  if s == 0:
21
57
  return np.real(sph_harm(m, l, 0., th))
22
58
  elif s + m < 0:
23
- return (-1.)**(s+m)*YslmBase(-s, l, -m, np.cos(th))
24
- # elif th > np.pi/2.:
25
- # return (-1.)**(l + m)*YslmBase(-s, l, m, -np.cos(th))
59
+ return (-1.)**(s+m)*YslmBase(-s, l, -m, th)
60
+ else:
61
+ return YslmBase(s, l, m, th)
62
+
63
+ def YslmBase(s, l, m, th):
64
+ assert isinstance(s, int) and isinstance(l, int) and isinstance(m, int), "s, l, and m must be integers"
65
+ if not isinstance(th, (int, float)):
66
+ b = np.broadcast(th)
67
+ out = np.empty(b.shape)
68
+ out.flat = [YslmCy(s, l, m, thi) for (thi,) in b]
26
69
  else:
27
- return YslmBase(s, l, m, np.cos(th))
70
+ out = YslmCy(s, l, m, th)
71
+ return out
28
72
 
29
- def YslmBase(s, l, m, z):
30
- rmax = l - s
31
- pref = (0.5)**(l)*(-1.)**m*np.sqrt(factorial(l+m)/factorial(l+s)*factorial(l-m)/factorial(l-s)*(2*l+1)/(4.*np.pi))*np.sqrt(1. - z)**(s + m)*np.sqrt(1. + z)**(s - m)
32
-
33
- yslm = 0.*pref
34
- for r in range(0, rmax + 1):
35
- yslm += binom(l - s, r)*binom(l + s, r + s - m)*(z - 1.)**(rmax - r)*(z + 1.)**(r)
36
-
37
- return pref*yslm
73
+ def Yslm_eigenvalue(s, l, *args):
74
+ return l*(l + 1.) - s*(s + 1.)
38
75
 
39
76
  def clebsch(l1, l2, l3, m1, m2, m3):
40
- return (-1)**(l1 - l2 + m3)*np.sqrt(2*l3 + 1)*w3j(l1, l2, l3, m1, m2, -m3);
77
+ """
78
+ Compute the Clebsch-Gordon coefficient <l1,m1,l2,m2|l3,m3>.
79
+
80
+ Parameters
81
+ ----------
82
+ l1 : int
83
+ The angular number of the first state.
84
+ l2 : int
85
+ The angular number of the second state.
86
+ l3 : int
87
+ The angular number of the combined state.
88
+ m1 : int
89
+ The azimuthal number of the first state.
90
+ m2 : int
91
+ The azimuthal number of the second state.
92
+ m3 : int
93
+ The azimuthal number of the combined state.
94
+
95
+ Returns
96
+ -------
97
+ float
98
+ The Clebsch-Gordon coefficient <l1,m1,l2,m2|l3,m3>.
99
+ """
100
+ assert isinstance(l1, int) and isinstance(l2, int) and isinstance(l3, int), "l1, l2, and l3 must be integers"
101
+ assert isinstance(m1, int) and isinstance(m2, int) and isinstance(m3, int), "m1, m2, and m3 must be integers"
102
+ return clebschCy(l1, l2, l3, m1, m2, m3)
41
103
 
42
104
  def w3j(l1, l2, l3, m1, m2, m3):
43
- if m1 + m2 + m3 != 0:
44
- return 0
45
- elif abs(l1 - l2) > l3:
46
- return 0
47
- elif l1 + l2 < l3:
48
- return 0
49
-
50
- if abs(m1) > l1:
51
- return 0
52
- elif abs(m2) > l2:
53
- return 0
54
- elif abs(m3) > l3:
55
- return 0
56
-
57
- sumTerm = w3j_tsum(l1, l2, l3, m1, m2, m3)
58
- if sumTerm == 0:
59
- return 0
60
- sumSign = np.sign(sumTerm)
61
- tempLog = 0.5*(np.log(fac(l1 + m1)) + np.log(fac(l2 + m2)) + np.log(fac(l3 + m3)))
62
- tempLog += 0.5*(np.log(fac(l1 - m1)) + np.log(fac(l2 - m2)) + np.log(fac(l3 - m3)))
63
- tempLog += np.log(triangle_coeff(l1, l2, l3))
64
- tempLog += np.log(abs(sumTerm))
65
-
66
- temp = sumSign*np.exp(tempLog)
67
- temp *= (-1)**(l1-l2-m3)
68
-
69
- return temp
70
-
71
- def w3j_tsum(l1, l2, l3, m1, m2, m3):
72
- t_min_num = w3j_t_min(l1, l2, l3, m1, m2, m3)
73
- t_max_num = w3j_t_max(l1, l2, l3, m1, m2, m3)
74
- x = 0
75
- if t_max_num < t_min_num:
76
- t_max_num = t_min_num
77
-
78
- for t in range(t_min_num - 1, t_max_num + 2):
79
- term = (fac(t)*fac(l3 - l2 + m1 + t)*fac(l3 - l1 - m2 + t)
80
- *fac(l1 + l2 - l3 - t)*fac(l1 - t - m1)*fac(l2 - t + m2))
81
- if term > 0:
82
- x += (-1)**t/term
83
-
84
- return x
85
-
86
- def w3j_t_min(l1, l2, l3, m1, m2, m3):
87
- temp = 0
105
+ """
106
+ Compute the Wigner 3j-symbol
107
+ | l1 l2 l3 |
108
+ | m1 m2 m3 |
109
+
110
+ Parameters
111
+ ----------
112
+ l1 : int
113
+ The angular number of the first state.
114
+ l2 : int
115
+ The angular number of the second state.
116
+ l3 : int
117
+ The angular number of the combined state.
118
+ m1 : int
119
+ The azimuthal number of the first state.
120
+ m2 : int
121
+ The azimuthal number of the second state.
122
+ m3 : int
123
+ The azimuthal number of the combined state.
124
+
125
+ Returns
126
+ -------
127
+ float
128
+ The Wigner 3j-symbol $ \begin{pmatrix} l1 & l2 & l3 \\ m1 & m2 & m3 \end{pmatrix} $
129
+ """
130
+ assert isinstance(l1, int) and isinstance(l2, int) and isinstance(l3, int), "l1, l2, and l3 must be integers"
131
+ assert isinstance(m1, int) and isinstance(m2, int) and isinstance(m3, int), "m1, m2, and m3 must be integers"
132
+ return w3jCy(l1, l2, l3, m1, m2, m3)
88
133
 
89
- comp = l3 - l2 + m1
90
- if temp + comp < 0:
91
- temp = -comp
92
- comp = l3 - l1 - m2
93
- if temp + comp < 0:
94
- temp = -comp
95
-
96
- return temp
97
-
98
- def w3j_t_max(l1, l2, l3, m1, m2, m3):
99
- temp = 1
100
- comp = l1 + l2 - l3
101
- if comp - temp > 0:
102
- temp = comp
103
- comp = l1 - m1
104
- if comp - temp > 0:
105
- temp = comp
106
- comp = l2 + m2
107
- if comp - temp > 0:
108
- temp = comp
109
-
110
- return temp;
111
-
112
- def triangle_coeff(l1, l2, l3):
113
- return np.sqrt(fac(l1 + l2 - l3)*fac(l3 + l1 - l2)*fac(l2 + l3 - l1)/fac(l1 + l2 + l3 + 1))
114
-
115
134
  """
116
135
  SWSH Eigenvalue Functions
117
136
  """
@@ -200,7 +219,7 @@ def swsh_eigs(s, l, m, g, nmax=None, return_eigenvectors=True):
200
219
  kval = l - lmin
201
220
 
202
221
  if nmax is None:
203
- buffer = round(20 + 2*g)
222
+ buffer = round(20 + 2*np.abs(g))
204
223
  Nmax = kval + buffer + 2
205
224
  else:
206
225
  if nmax < kval:
@@ -213,26 +232,53 @@ def swsh_eigs(s, l, m, g, nmax=None, return_eigenvectors=True):
213
232
 
214
233
  return out
215
234
 
216
- def Yslm_eigenvalue(s, l, *args):
217
- return l*(l + 1.) - s*(s + 1.)
235
+ def swsh_coeffs(s, l, m, g, th):
236
+ if g == 0.:
237
+ return Yslm(s, l, m, th)
238
+
239
+ _, eig = swsh_eigs(s, l, m, g, nmax=None, return_eigenvectors=True)
240
+ if g.imag == 0.:
241
+ coeffs = np.real(eig[l - max(abs(s), abs(m))])
242
+ else:
243
+ coeffs = eig[l - max(abs(s), abs(m))]
244
+ return coeffs
218
245
 
219
246
  def swsh_eigenvalue(s, l, m, g, nmax=None):
247
+ """
248
+ Compute the eigenvalue of the spin-weighted spheroidal harmonic.
249
+
250
+ Parameters
251
+ ----------
252
+ s : int
253
+ The spin weight of the harmonic.
254
+ l : int
255
+ The angular number of the harmonic.
256
+ m : int
257
+ The azimuthal number of the harmonic.
258
+ g : float or complex
259
+ The spheroidicity parameter.
260
+ nmax : int, optional
261
+ The maximum number of basis functions to use in the computation. If None, a default value is chosen.
262
+
263
+ Returns
264
+ -------
265
+ float or complex
266
+ The eigenvalue of the spin-weighted spheroidal harmonic.
267
+ """
220
268
  if g == 0.:
221
269
  return Yslm_eigenvalue(s, l)
222
270
 
223
271
  las = swsh_eigs(s, l, m, g, nmax=nmax, return_eigenvectors=False)
224
272
 
225
- return np.real(las[::-1][l - max(abs(s), abs(m))])
226
-
227
- def swsh_coeffs(s, l, m, g, th):
228
- if g == 0.:
229
- return Yslm(s, l, m, th)
230
-
231
- _, eig = swsh_eigs(s, l, m, g, nmax=None, return_eigenvectors=True)
232
- coeffs = np.real(eig[l - max(abs(s), abs(m))])
233
-
234
- return np.real(eig[l - max(abs(s), abs(m))])
235
-
273
+ idx = l - max(abs(s), abs(m))
274
+ sorted_indices = np.argsort(np.real(las))
275
+ if idx < 0 or idx >= len(sorted_indices):
276
+ raise IndexError(f"Index {idx} out of bounds for eigenvalue array of length {len(sorted_indices)}")
277
+ if g.imag == 0.:
278
+ eigen = np.real(las)[sorted_indices[idx]]
279
+ else:
280
+ eigen = las[sorted_indices[idx]]
281
+ return eigen
236
282
  class SWSHBase:
237
283
  def __init__(self, *args):
238
284
  arg_num = np.array(args).shape[0]
@@ -247,7 +293,9 @@ class SWSHBase:
247
293
 
248
294
  if arg_num > 3:
249
295
  self.spheroidicity = args[3]
250
-
296
+ if self.spheroidicity.imag == 0:
297
+ self.spheroidicity = np.real(self.spheroidicity)
298
+
251
299
  class SWSHSeriesBase(SWSHBase):
252
300
  def __init__(self, s, l, m, g):
253
301
  SWSHBase.__init__(self, s, l, m, g)
@@ -259,7 +307,7 @@ class SWSHSeriesBase(SWSHBase):
259
307
  kval = self.l - self.lmin
260
308
 
261
309
  if nmax is None:
262
- buffer = round(20 + 2*self.spheroidicity)
310
+ buffer = round(20 + np.abs(2*self.spheroidicity))
263
311
  Nmax = kval + buffer + 2
264
312
  else:
265
313
  if nmax < kval:
@@ -283,45 +331,115 @@ class SWSHSeriesBase(SWSHBase):
283
331
  return scipy.sparse.linalg.eigs(mat, **kwargs)
284
332
 
285
333
  def generate_eigenvalue(self):
286
- las = np.real(self.eigs(return_eigenvectors=False))
287
- pos = np.argsort(las)[self.l - self.lmin]
334
+ if self.spheroidicity.imag == 0.:
335
+ las = np.real(self.eigs(return_eigenvectors=False))
336
+ else:
337
+ las = self.eigs(return_eigenvectors=False)
338
+ pos = np.argsort(np.real(las))[self.l - self.lmin]
288
339
  return las[pos]
289
-
340
+
290
341
  def generate_eigs(self):
291
342
  las, eigs = self.eigs()
292
- pos = np.argsort(np.real(las))[self.l - self.lmin]
293
- eigs_temp = np.real(eigs[:, pos])
294
- eigs_return = np.sign(eigs_temp[self.l - self.lmin])*eigs_temp
295
- return (np.real(las[pos]), eigs_return)
343
+ pos_vec = np.argsort(np.real(las))
344
+ pos = pos_vec[self.l - self.lmin]
345
+ if self.spheroidicity.imag == 0.:
346
+ eigs_temp = np.real(eigs[:, pos])
347
+ eigs_return = np.sign(eigs_temp[self.l - self.lmin])*eigs_temp
348
+ eig = np.real(las[pos])
349
+ else:
350
+ eigs_temp = eigs[:, pos]
351
+ ref = eigs_temp[self.l - self.lmin]
352
+ eigs_temp = eigs_temp/ref
353
+ eigs_norm = np.linalg.norm(eigs_temp)
354
+ eigs_return = eigs_temp/eigs_norm
355
+ eig = las[pos]
356
+ return (eig, eigs_return)
357
+ class SpinWeightedSpheroidalHarmonic(SWSHSeriesBase):
358
+ """
359
+ A class for generating a spin-weighted spheroidal harmonic.
360
+
361
+ Parameters
362
+ ----------
363
+ s : int
364
+ The spin weight of the harmonic.
365
+ l : int
366
+ The angular number of the harmonic.
367
+ m : int
368
+ The azimuthal number of the harmonic.
369
+ g : float or complex
370
+ The spheroidicity parameter.
371
+
372
+ Attributes
373
+ ----------
374
+ couplingcoefficients : array_like
375
+ The coupling coefficients between the spin-weighted spheroidal harmonic and the spin-weighted spherical
296
376
 
297
- class SWSH(SWSHSeriesBase):
377
+ """
298
378
  def __init__(self, s, l, m, g):
299
379
  SWSHSeriesBase.__init__(self, s, l, m, g)
300
380
  if self.spheroidicity == 0.:
301
381
  self.eval = self.Yslm
302
382
  self.eigenvalue = Yslm_eigenvalue(self.s, self.l)
303
- self.coeffs = np.zeros(self.l - self.lmin)
383
+ self.coeffs = np.zeros(self.l - self.lmin + 1)
304
384
  self.coeffs[-1] = 1.
305
385
  else:
306
386
  self.eval = self.Sslm
307
387
  self.eigenvalue, self.coeffs = self.generate_eigs()
308
-
388
+
389
+ @property
390
+ def couplingcoefficients(self):
391
+ return self.coeffs
392
+
309
393
  def Yslm(self, l, th):
394
+ """
395
+ Evaluate the spin-weighted spherical harmonic $Y_{s}^{lm}(theta)$ at a given angle theta.
396
+
397
+ Parameters
398
+ ----------
399
+ l : int
400
+ The angular number of the spherical harmonic.
401
+ th : array_like
402
+ The polar angle(s) at which to evaluate the spherical harmonic.
403
+
404
+ Returns
405
+ -------
406
+ array_like
407
+ The values of the spherical harmonic at the specified angles.
408
+ """
310
409
  return Yslm(self.s, l, self.m, th)
311
410
 
312
411
  def Sslm(self, *args):
412
+ """
413
+ Evaluate the spin-weighted spheroidal harmonic $S_{s}^{lm}(theta)$ at a given angle theta.
414
+
415
+ Parameters
416
+ ----------
417
+ th : array_like
418
+ The polar angle(s) at which to evaluate the spheroidal harmonic.
419
+
420
+ Returns
421
+ -------
422
+ array_like
423
+ The values of the spheroidal harmonic at the specified angles.
424
+ """
313
425
  th = args[-1]
314
426
  term_num = self.coeffs.shape[0]
315
- pts_num = th.shape[0]
316
- Yslm_array = np.empty((term_num, pts_num))
427
+ if isinstance(th, (int, float)):
428
+ Yslm_array = np.empty(term_num)
429
+ else:
430
+ pts_num = th.shape[0]
431
+ Yslm_array = np.empty((term_num, pts_num))
317
432
  for i in range(term_num):
318
433
  Yslm_array[i] = self.Yslm(self.lmin + i, th)
319
434
 
320
435
  return np.dot(self.coeffs, Yslm_array)
321
436
 
322
- def __call__(self, th):
323
- return self.eval(self.l, th)
324
-
437
+ def __call__(self, th, ph = None):
438
+ out = self.eval(self.l, th)
439
+ if ph is not None:
440
+ out = out*np.exp(1.j*self.m*ph)
441
+ return out
442
+
325
443
  def muCoupling(s, l):
326
444
  """
327
445
  Eigenvalue for the spin-weighted spherical harmonic lowering operator
@@ -332,6 +450,25 @@ def muCoupling(s, l):
332
450
  return np.sqrt((l - s + 1.)*(l + s))
333
451
 
334
452
  def Asjlm(s, j, l, m):
453
+ """
454
+ Coupling coefficient between scalar and spin-weighted spherical harmonics
455
+
456
+ Parameters
457
+ ----------
458
+ s : int
459
+ The spin weight of the harmonic.
460
+ j : int
461
+ The angular number of the scalar harmonic.
462
+ l : int
463
+ The angular number of the spin-weighted harmonic.
464
+ m : int
465
+ The azimuthal number of the harmonics.
466
+
467
+ Returns
468
+ -------
469
+ float
470
+ The coupling coefficient $A_{s}^{jlm}$
471
+ """
335
472
  if s >= 0:
336
473
  return (-1.)**(m + s)*np.sqrt(4**s*fac(s)**2*(2*l + 1)*(2*j + 1)/fac(2*s))*w3j(s, l, j, 0, m, -m)*w3j(s, l, j, s, -s, 0)
337
474
  else:
pybhpt/teuk.py CHANGED
@@ -194,52 +194,243 @@ class TeukolskyMode:
194
194
  Flips the spin-weight and frequency of the Teukolsky solutions from :math:`s \rightarrow -s` and :math:`\omega \rightarrow -\omega`
195
195
  """
196
196
  def flipspinweightandfrequency(self):
197
+ """
198
+ Flips the spin-weight and frequency of the Teukolsky solutions from :math:`s \rightarrow -s` and :math:`\omega \rightarrow -\omega`
199
+ """
197
200
  self.base.flip_spinweight_frequency()
198
201
 
199
- """
200
- Spherical-spheroidal mixing coefficient between a spherical harmonic :math:`l` mode with a spheroidal :math:`j` mode
201
-
202
- :param l: spherical harmonic mode
203
- :type l: int
204
- """
205
202
  def couplingcoefficient(self, l):
203
+ """
204
+ Spherical-spheroidal mixing coefficient between a spherical harmonic $l$ mode with a spheroidal $j$ mode.
205
+
206
+ Parameters
207
+ ----------
208
+ l : int
209
+ Spherical harmonic mode.
210
+
211
+ Returns
212
+ -------
213
+ float
214
+ The coupling coefficient between the spherical harmonic mode `l` and the spheroidal harmonic mode `j`.
215
+ """
206
216
  return self.base.couplingcoefficient(l)
207
217
 
208
218
  def radialpoint(self, pos):
219
+ """
220
+ The radial point for the given position `pos`.
221
+
222
+ Parameters
223
+ ----------
224
+ pos : int
225
+ The radial position.
226
+
227
+ Returns
228
+ -------
229
+ float
230
+ The radial point at the given position `pos`.
231
+ """
209
232
  return self.base.radialpoint(pos)
210
233
 
211
234
  def radialsolution(self, bc, pos):
235
+ """
236
+ The extended homogeneous radial solution for the given boundary condition `bc` and position `pos`.
237
+
238
+ Parameters
239
+ ----------
240
+ bc : str
241
+ The boundary condition, either "In" for ingoing or "Up" for upgoing.
242
+ pos : int
243
+ The radial position.
244
+
245
+ Returns
246
+ -------
247
+ complex
248
+ The radial solution at the given boundary condition `bc` and position `pos`.
249
+ """
212
250
  return self.base.radialsolution(bc, pos)
213
251
 
214
252
  def radialderivative(self, bc, pos):
253
+ """
254
+ The derivative of the extended homogeneous radial solution for the given boundary condition `bc` and position `pos`.
255
+
256
+ Parameters
257
+ ----------
258
+ bc : str
259
+ The boundary condition, either "In" for ingoing or "Up" for upgoing.
260
+ pos : int
261
+ The radial position.
262
+
263
+ Returns
264
+ -------
265
+ complex
266
+ The radial derivative at the given boundary condition `bc` and position `pos`.
267
+ """
215
268
  return self.base.radialderivative(bc, pos)
216
269
 
217
270
  def radialderivative2(self, bc, pos):
271
+ """
272
+ The second derivative of the extended homogeneous radial solution for the given boundary condition `bc` and position `pos`.
273
+
274
+ Parameters
275
+ ----------
276
+ bc : str
277
+ The boundary condition, either "In" for ingoing or "Up" for upgoing.
278
+ pos : int
279
+ The radial position.
280
+
281
+ Returns
282
+ -------
283
+ complex
284
+ The radial second derivative at the given boundary condition `bc` and position `pos`.
285
+ """
218
286
  return self.base.radialderivative2(bc, pos)
219
287
 
220
288
  def homogeneousradialsolution(self, bc, pos):
289
+ """
290
+ The homogeneous radial solution for the given boundary condition `bc` and position `pos`.
291
+
292
+ Parameters
293
+ ----------
294
+ bc : str
295
+ The boundary condition, either "In" for ingoing or "Up" for upgoing.
296
+ pos : int
297
+ The radial position.
298
+
299
+ Returns
300
+ -------
301
+ complex
302
+ The radial solution at the given boundary condition `bc` and position `pos`.
303
+ """
221
304
  return self.base.homogeneousradialsolution(bc, pos)
222
305
 
223
306
  def homogeneousradialderivative(self, bc, pos):
307
+ """
308
+ The radial derivative of the homogeneous radial solution for the given boundary condition `bc` and position `pos`.
309
+
310
+ Parameters
311
+ ----------
312
+ bc : str
313
+ The boundary condition, either "In" for ingoing or "Up" for upgoing.
314
+ pos : int
315
+ The radial position.
316
+
317
+ Returns
318
+ -------
319
+ complex
320
+ The radial derivative at the given boundary condition `bc` and position `pos`.
321
+ """
224
322
  return self.base.homogeneousradialderivative(bc, pos)
225
323
 
226
324
  def homogeneousradialderivative2(self, bc, pos):
325
+ """
326
+ The second radial derivative of the homogeneous radial solution for the given boundary condition `bc` and position `pos`.
327
+
328
+ Parameters
329
+ ----------
330
+ bc : str
331
+ The boundary condition, either "In" for ingoing or "Up" for upgoing.
332
+ pos : int
333
+ The radial position.
334
+
335
+ Returns
336
+ -------
337
+ complex
338
+ The radial second derivative at the given boundary condition `bc` and position `pos`.
339
+ """
227
340
  return self.base.homogeneousradialderivative2(bc, pos)
228
341
 
229
342
  def polarpoint(self, pos):
343
+ """
344
+ The polar point for the given position `pos`.
345
+
346
+ Parameters
347
+ ----------
348
+ pos : int
349
+ The polar position.
350
+
351
+ Returns
352
+ -------
353
+ float
354
+ The polar point at the given position `pos`.
355
+ """
230
356
  return self.base.polarpoint(pos)
231
357
 
232
358
  def polarsolution(self, pos):
359
+ """
360
+ The polar solution for the given position `pos`.
361
+
362
+ Parameters
363
+ ----------
364
+ pos : int
365
+ The polar position.
366
+
367
+ Returns
368
+ -------
369
+ float
370
+ The polar solution at the given position `pos`.
371
+ """
233
372
  return self.base.polarsolution(pos)
234
373
 
235
374
  def polarderivative(self, pos):
375
+ """
376
+ The derivative of the polar solution for the given position `pos`.
377
+
378
+ Parameters
379
+ ----------
380
+ pos : int
381
+ The polar position.
382
+
383
+ Returns
384
+ -------
385
+ float
386
+ The polar derivative at the given position `pos`.
387
+ """
236
388
  return self.base.polarderivative(pos)
237
389
 
238
390
  def polarderivative2(self, pos):
391
+ """
392
+ The second derivative of the polar solution for the given position `pos`.
393
+
394
+ Parameters
395
+ ----------
396
+ pos : int
397
+ The polar position.
398
+
399
+ Returns
400
+ -------
401
+ float
402
+ The polar second derivative at the given position `pos`.
403
+ """
239
404
  return self.base.polarderivative2(pos)
240
405
 
241
406
  def amplitude(self, bc):
407
+ """
408
+ The Teukolsky amplitude for the given boundary condition `bc`.
409
+
410
+ Parameters
411
+ ----------
412
+ bc : str
413
+ The boundary condition, either "In" for ingoing or "Up" for upgoing.
414
+
415
+ Returns
416
+ -------
417
+ complex
418
+ The Teukolsky amplitude at the given boundary condition `bc`.
419
+ """
242
420
  return self.base.teukolsky_amplitude(bc)
243
421
 
244
422
  def precision(self, bc):
423
+ """
424
+ The precision of the Teukolsky amplitude for the given boundary condition `bc`.
425
+
426
+ Parameters
427
+ ----------
428
+ bc : str
429
+ The boundary condition, either "In" for ingoing or "Up" for upgoing.
430
+
431
+ Returns
432
+ -------
433
+ float
434
+ The precision of the Teukolsky amplitude at the given boundary condition `bc`.
435
+ """
245
436
  return self.base.teukolsky_amplitude_precision(bc)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: pybhpt
3
- Version: 0.9.4
3
+ Version: 0.9.8
4
4
  Summary: Black Hole Perturbation Theory and Self-Force Algorithms in Python
5
5
  Author-Email: Zach Nasipak <znasipak@gmail.com>
6
6
  License: GPL
@@ -30,11 +30,11 @@ Description-Content-Type: text/markdown
30
30
 
31
31
  # pybhpt
32
32
 
33
- A python package for solving problems in black hole perturbation theory
33
+ A python package for solving problems in black hole perturbation theory.
34
34
 
35
35
  `pybhpt` is a collection of numerical tools for analyzing perturbations of Kerr spacetime, particularly the self-forces and metric-perturbations experienced by small bodies moving in a Kerr background. Subpackages include:
36
36
 
37
- - `pybhpt.geodesic`: a module that generates bound timelike geodesics in Kerr spacetime
37
+ - `pybhpt.geodesic`: a module that generates bound periodic timelike geodesics in Kerr spacetime
38
38
  - `pybhpt.radial`: a module that calculates homogeneous solutions of the radial Teukolsky equation
39
39
  - `pybhpt.swsh`: a module that constructs the spin-weighted spheroidal harmonics
40
40
  - `pybhpt.teuk`: a module that evaluates the inhomogeneous solutions (Teukolsky amplitudes) of the radial Teukolsky equation due to a point-particle on a bound timelike Kerr geodesic
@@ -43,9 +43,11 @@ A python package for solving problems in black hole perturbation theory
43
43
  - `pybhpt.metric`: a module that produces the coefficients needed to reconstruct the metric from the Hertz potentials
44
44
  - `pybhpt.redshift`: a module that computes the generalized Detweiler redshift invariant in a variety of gauges
45
45
 
46
+ See the [Documentation](https://pybhpt.readthedocs.io/en/latest/) pages for more information about the package, including User Guides and API. References and author information can be found at the bottom of the README.
47
+
46
48
  ## Quick Installation
47
49
 
48
- Tagged releases of `pybhpt` are available as wheel packages for macOS and 64-bit Linux on [PyPI](https://pypi.org/project/matplotlib/). Install using `pip`:
50
+ Tagged releases of `pybhpt` are available as wheel packages for macOS and 64-bit Linux on [PyPI](https://pypi.org/project/pybhpt). Install using `pip`:
49
51
  ```
50
52
  python3 -m pip install pybhpt
51
53
  ```
@@ -130,6 +132,14 @@ To include the necessary compiler on Linux:
130
132
  conda install gcc_linux-64 gxx_linux-64
131
133
  ```
132
134
 
135
+ ## References
136
+
137
+ Theoretical background for the code and explanations of the numerical methods used within are summarized in the references below:
138
+
139
+ - Z. Nasipak, *Metric reconstruction and the Hamiltonian for eccentric, precessing binaries in the small-mass-ratio limit* (2025) [arXiv:2507.07746](https://arxiv.org/abs/2507.07746)
140
+ - Z. Nasipak, *An adiabatic gravitational waveform model for compact objects undergoing quasi-circular inspirals into rotating massive black holes*, Phys. Rev. D 109, 044020 (2024) [arXiv:2310.19706](https://arxiv.org/abs/2310.19706)
141
+ - Z. Nasipak, *Adiabatic evolution due to the conservative scalar self-force during orbital resonances*, Phys. Rev. D 106, 064042 (2022) [arXiv:2207.02224](https://arxiv.org/abs/2207.02224)
142
+
133
143
  ## Authors
134
144
 
135
145
  Zachary Nasipak
@@ -0,0 +1,16 @@
1
+ cybhpt_full.cpython-314-darwin.so,sha256=T01VDZVSdS3LaK3jBmOUblHdJHSlZiis9Q88mK5s108,2336832
2
+ pybhpt-0.9.8.dist-info/RECORD,,
3
+ pybhpt-0.9.8.dist-info/WHEEL,sha256=v0AHjqCAlR6lLK4uHrc9lGGk6wkSGzsPHIgpnvL7sa0,142
4
+ pybhpt-0.9.8.dist-info/METADATA,sha256=NIzqGzLYfDWkON7jWb24fRxC7DbZzIrcdMYBF2iOWlA,6367
5
+ pybhpt-0.9.8.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
6
+ pybhpt/geo.py,sha256=VqbarbR1CC7ARD82FI8vmoNnklCZUoraRVJOii3vBlE,23803
7
+ pybhpt/redshift.py,sha256=ozDDbkv34FQ_Op3FotmHJ-J5Vfy2oF4_Ri1HRujnzAY,791
8
+ pybhpt/hertz.py,sha256=9atjscxbR7eszsY6BuJvcy0PqlgMFwYI23kUIn4mUwc,13565
9
+ pybhpt/radial.py,sha256=t9Lx6Cyuprxqk2iowbvHMvsoL-6UO-YnZmO1G1wdyMU,15597
10
+ pybhpt/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
11
+ pybhpt/swsh.py,sha256=sQR0S-tHXYaAIuuW9kHK99U39htXt5j8oGWPZzIqwt0,14826
12
+ pybhpt/metric.py,sha256=y8ip24rFto7m7rZb0-fuYMrYUmbCzInaWQVYJRI3m3o,11971
13
+ pybhpt/teuk.py,sha256=8rZ-2fyzAfTbt9T4-lkUL8wUmPpORv0VkJCfkpEBssc,13616
14
+ pybhpt/flux.py,sha256=2ahStjbsswsWMNPfDiOlQIrzulJZrhaqoDENC0bCLE4,4299
15
+ pybhpt/.dylibs/libgsl.28.dylib,sha256=cJ5srjDdZDNLeRXrwhARDtAVaHDiePifPX1yaR5KPgc,2439680
16
+ pybhpt/.dylibs/libgslcblas.0.dylib,sha256=xxE7gWPfCeMMkYxciiJ0-IcSJqLwdfHVayP70bOxWL0,272784
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: scikit-build-core 0.11.5
2
+ Generator: scikit-build-core 0.11.6
3
3
  Root-Is-Purelib: false
4
4
  Tag: cp314-cp314-macosx_14_0_x86_64
5
5
  Generator: delocate 0.13.0
@@ -1,16 +0,0 @@
1
- cybhpt_full.cpython-314-darwin.so,sha256=P1p69eiqGqqM1Y5QwYo75PF3Qufss1y2524M_1Xhxko,2286784
2
- pybhpt/geo.py,sha256=QyiwlXF0cIYSpkV7wC9-ITd2bqIumvXiIt2_uNlhJMc,12237
3
- pybhpt/redshift.py,sha256=ozDDbkv34FQ_Op3FotmHJ-J5Vfy2oF4_Ri1HRujnzAY,791
4
- pybhpt/hertz.py,sha256=9atjscxbR7eszsY6BuJvcy0PqlgMFwYI23kUIn4mUwc,13565
5
- pybhpt/radial.py,sha256=2H3rH4XczAVCbKveHmPO2wt3w8ApPZYWCAwkwnxPnps,13995
6
- pybhpt/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
- pybhpt/swsh.py,sha256=WjtpHNZ6c7RVxuml1I6_cEu8D6cb4hD6aiHZVwD7AeA,10462
8
- pybhpt/metric.py,sha256=y8ip24rFto7m7rZb0-fuYMrYUmbCzInaWQVYJRI3m3o,11971
9
- pybhpt/teuk.py,sha256=w3tcidkaOGeywZPqjggacYhxaFxgsxXdMlJ2C7TwdMQ,8220
10
- pybhpt/flux.py,sha256=2ahStjbsswsWMNPfDiOlQIrzulJZrhaqoDENC0bCLE4,4299
11
- pybhpt/.dylibs/libgsl.28.dylib,sha256=cJ5srjDdZDNLeRXrwhARDtAVaHDiePifPX1yaR5KPgc,2439680
12
- pybhpt/.dylibs/libgslcblas.0.dylib,sha256=xxE7gWPfCeMMkYxciiJ0-IcSJqLwdfHVayP70bOxWL0,272784
13
- pybhpt-0.9.4.dist-info/RECORD,,
14
- pybhpt-0.9.4.dist-info/WHEEL,sha256=IyDInmnGNwPAk8ERKOFXaEfq-LcK0Q6JmkeYwroJxhI,142
15
- pybhpt-0.9.4.dist-info/METADATA,sha256=EMPVuX-dje_Xt0axnmQHVeuax7rV66-dPzXO0_92ehc,5386
16
- pybhpt-0.9.4.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149