Skip to content

Commit 01ddcb8

Browse files
authored
HSGP periodic (#6877)
* implement periodic psd and pass test * simplify hsgp test, set up for mark other cov_func * attempt at if-else logic in HSGP class API * np.pi in w0 * check arguments for period and nonperiod case * tests run but failing * fix one of the mypy errors * periodic cov pytest uses J not m because mpyp * avoid AttributeError by init parameterization * get rid of mypy "None" error * self.prior_linearized inside if avoids double call * need to add the mean function in prior * run pre-commit locally * add docs to test about why test_prior fails * freshen up the docs * improve coverage of args * mypy ignore type * fix parameterization test * use power_spectral_density_approx because cant sum * tbe -> the typo docs * expand warning and change the triggering clause * separate into HSGP and HSGPPeriodic * remove commented periodic in HSGP test * appease mypy * add scale parameter for HSGP
1 parent a1dce17 commit 01ddcb8

File tree

5 files changed

+452
-33
lines changed

5 files changed

+452
-33
lines changed

pymc/gp/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,4 @@
2222
MarginalKron,
2323
MarginalSparse,
2424
)
25-
from pymc.gp.hsgp_approx import HSGP
25+
from pymc.gp.hsgp_approx import HSGP, HSGPPeriodic

pymc/gp/cov.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -790,6 +790,28 @@ def full_from_distance(self, dist: TensorLike, squared: bool = False) -> TensorV
790790
r2 = dist if squared else dist**2
791791
return pt.exp(-0.5 * r2)
792792

793+
def power_spectral_density_approx(self, J: TensorLike) -> TensorVariable:
794+
"""
795+
Technically, this is not a spectral density but these are the first `m` coefficients of
796+
the low rank approximation for the periodic kernel, which are used in the same way.
797+
`J` is a vector of `np.arange(m)`.
798+
799+
The coefficients of the HSGP approximation for the `Periodic` kernel are given by:
800+
801+
.. math::
802+
803+
\tilde{q}_j^2 = \frac{2 \text{I}_j (\\ell^{-2})}{\\exp(\\ell^{-2})} \\
804+
\tilde{q}_0^2 = \frac{\text{I}_0 (\\ell^{-2})}{\\exp(\\ell^{-2})}
805+
806+
where $\text{I}_j$ is the modified Bessel function of the first kind.
807+
"""
808+
a = 1 / pt.square(self.ls)
809+
c = pt.where(J > 0, 2, 1)
810+
811+
q2 = c * pt.iv(J, a) / pt.exp(a)
812+
813+
return q2
814+
793815

794816
class Linear(Covariance):
795817
r"""

0 commit comments

Comments
 (0)