Skip to content

Commit 92d9670

Browse files
committed
feat: add conditional pdf and log pdf functions.
1 parent b266da0 commit 92d9670

File tree

1 file changed

+27
-51
lines changed

1 file changed

+27
-51
lines changed

stonesoup/models/base.py

+27-51
Original file line numberDiff line numberDiff line change
@@ -431,65 +431,41 @@ def rvs(
431431
)
432432
return noise
433433

434-
def pdf(self, state1: State, state2: State, **kwargs) -> Union[Probability, np.ndarray]:
435-
return Probability.from_log_ufunc(self.logpdf(state1, state2, **kwargs))
436-
437-
def logpdf(self, state1: State, state2: State, **kwargs) -> Union[float, np.ndarray]:
438-
return NotImplementedError
439-
440-
# def pdf(self, state1: State, state2: State, **kwargs) -> Probability | np.ndarray:
441-
# import numpy as np
442-
# import matplotlib.pyplot as plt
443-
# from scipy.stats import norm
434+
def condpdf(self, state1: State, state2: State, latents: Optional[Latents] = None, **kwargs) -> Union[Probability, np.ndarray]:
435+
r"""Model conditional pdf/likelihood evaluation function"""
436+
return Probability.from_log_ufunc(self.logcondpdf(state1, state2, latents=latents, **kwargs))
444437

445-
# # Parameters
446-
# x_min = -10.0
447-
# x_max = 10.0
448-
# N = 2**8
449438

450-
# # Generate k and w
451-
# k = np.arange(N)
452-
# w = (0.5 - N / 2 + k) * (2 * np.pi / (x_max - x_min))
439+
def logcondpdf(self, state1: State, state2: State, latents: Optional[Latents] = None, **kwargs) -> Union[float, np.ndarray]:
440+
r"""Model log conditional pdf/likelihood evaluation function"""
441+
if latents is None:
442+
raise ValueError("Latents cannot be none.")
453443

454-
# # Characteristic function
455-
# cffun = lambda w: np.exp(-0.5 * w**2)
456-
457-
# alpha=1
458-
# nu=2
459-
460-
# cffun = lambda w: ( 1 - (1j * w) / alpha) ** (-nu)
461-
462-
# cf = cffun(w[int(N/2):])
463-
# cf = np.concatenate([np.conj(cf[::-1]), cf])
444+
mean = self.mean(latents=latents, **kwargs)
445+
if mean is None or None in mean:
446+
raise ValueError("Cannot generate pdf from None-type mean")
447+
assert isinstance(mean, StateVector)
464448

465-
# # Compute dx, C, and D
466-
# dx = (x_max - x_min) / N
449+
covar = self.covar(latents=latents, **kwargs)
450+
if covar is None or None in covar:
451+
raise ValueError("Cannot generate pdf from None-type covariance")
452+
assert isinstance(covar, CovarianceMatrix)
467453

468-
# C = (-1+0j) ** ((1 - 1 / N) * (x_min / dx + k)) / (x_max - x_min)
469454

470-
# D = (-1+0j) ** (-2 * (x_min / (x_max - x_min)) * k)
455+
likelihood = np.atleast_1d(
456+
multivariate_normal.logpdf((state1.state_vector - self.function(state2, **kwargs)).T,
457+
mean=mean, cov=covar))
471458

472-
# # Compute the PDF
473-
# pdf = np.real(C * np.fft.fft(D * cf))
459+
if len(likelihood) == 1:
460+
likelihood = likelihood[0]
474461

475-
# # Compute the CDF
476-
# cdf = np.cumsum(pdf * dx)
462+
return likelihood
477463

478-
# # Generate x values
479-
# x = x_min + k * dx
464+
def logpdf(self, state1: State, state2: State, **kwargs) -> Probability | np.ndarray:
465+
r"""Model log pdf/likelihood evaluation function"""
466+
return NotImplementedError
480467

481-
# # Plot the PDF
482-
# plt.figure()
483-
# plt.plot(x, pdf, label='inverse CF')
484-
# plt.plot(x, norm.pdf(x), label='scipy')
485-
# plt.title('PDF')
486-
# plt.grid()
487-
# plt.legend()
488-
# plt.show()
489468

490-
# # Plot the CDF
491-
# # plt.figure()
492-
# # plt.plot(x, cdf)
493-
# # plt.title('CDF')
494-
# # plt.grid()
495-
# # plt.show()
469+
def pdf(self, state1: State, state2: State, **kwargs) -> Probability | np.ndarray:
470+
r"""Model pdf/likelihood evaluation function"""
471+
return Probability.from_log_ufunc(self.logpdf(state1, state2, **kwargs))

0 commit comments

Comments
 (0)