def test_fdd(): p = GP(1, EQ()) # Test specification without noise. for fdd in [p(1), FDD(p, 1)]: assert isinstance(fdd, FDD) assert identical(fdd.x, 1) assert fdd.p is p assert isinstance(fdd.noise, matrix.Zero) rep = ("<FDD:\n" " process=GP(1, EQ()),\n" " input=1,\n" " noise=<zero matrix: batch=(), shape=(1, 1), dtype=int>>") assert str(fdd) == rep assert repr(fdd) == rep # Check `dtype` and `num_elements`. assert B.dtype(fdd) == int assert num_elements(fdd) == 1 # Test specification with noise. fdd = p(1.0, np.array([1, 2])) assert isinstance(fdd, FDD) assert identical(fdd.x, 1.0) assert fdd.p is p assert isinstance(fdd.noise, matrix.Diagonal) assert str(fdd) == ( "<FDD:\n" " process=GP(1, EQ()),\n" " input=1.0,\n" " noise=<diagonal matrix: batch=(), shape=(2, 2), dtype=int64>>") assert repr(fdd) == ( "<FDD:\n" " process=GP(1, EQ()),\n" " input=1.0,\n" " noise=<diagonal matrix: batch=(), shape=(2, 2), dtype=int64\n" " diag=[1 2]>>") assert B.dtype(fdd) == float assert num_elements(fdd) == 1 # Test construction with `id`. fdd = FDD(5, 1) assert fdd.p is 5 assert identical(fdd.x, 1) assert fdd.noise is None
def posterior_kernel(self, measure, p_i, p_j): if num_elements(self.fdd.x) == 0: # There are no observations! Just return prior. return measure.kernels[p_i, p_j] return PosteriorKernel( measure.kernels[p_i, p_j], measure.kernels[self.fdd.p, p_i], measure.kernels[self.fdd.p, p_j], self.fdd.x, self.K_x(measure), )
def posterior_mean(self, measure, p): if num_elements(self.fdd.x) == 0: # There are no observations! Just return prior. return measure.means[p] return PosteriorMean( measure.means[p], measure.means[self.fdd.p], measure.kernels[self.fdd.p, p], self.fdd.x, self.K_x(measure), self.y, )
def sample(self, n: int, *fdds: FDD): """Sample multiple processes simultaneously. Args: n (int, optional): Number of samples. Defaults to `1`. *fdds (:class:`.fdd.FDD`): Locations to sample at. Returns: tuple: Tuple of samples. """ sample = combine(*fdds).sample(n) # Unpack sample. lengths = [num_elements(fdd) for fdd in fdds] i, samples = 0, [] for length in lengths: samples.append(sample[i:i + length, :]) i += length return samples[0] if len(samples) == 1 else samples
def sample(self, state: B.RandomState, n: B.Int, *fdds: FDD): """Sample multiple processes simultaneously. Args: state (random state, optional): Random state. n (int, optional): Number of samples. Defaults to `1`. *fdds (:class:`.fdd.FDD`): Locations to sample at. Returns: tuple: Tuple of samples. """ # Apply `self` to make sure that we sample under this measure. state, sample = self(combine(*fdds)).sample(state, n) # Unpack sample. lengths = [num_elements(fdd) for fdd in fdds] i, samples = 0, [] for length in lengths: samples.append(sample[..., i : i + length, :]) i += length return (state,) + tuple(samples)
def test_num_elements(): assert num_elements((1, B.ones(5))) == 6
def num_elements(fdd: FDD): return num_elements(fdd.x)
def ones(x): return Constant(B.one(x), num_elements(x), 1)
def infer_size(k: Kernel, x: FDD): return num_elements(x)
def infer_size(k: Kernel, x: B.Numeric): return num_elements(x) * dimensionality(k)
def infer_size(k: Kernel, x: FDD): return Dimension(num_elements(x))
def infer_size(k: Kernel, x: B.Numeric): d = dimensionality(k) if d is None: raise RuntimeError(f"Could not infer dimensionality of {k}.") return Dimension(num_elements(x) * d)