def __init__( self, factor, name="", arg_names=None, factor_out=FactorValue, plates: Tuple[Plate, ...] = (), vjp=False, factor_vjp=None, factor_jacobian=None, jacobian=None, numerical_jacobian=True, jacfwd=True, eps=1e-8, **kwargs: Variable, ): args = tuple(kwargs.values()) arg_names = tuple(kwargs.keys()) super().__init__( factor, *args, name=name, arg_names=arg_names, factor_out=factor_out, plates=plates, vjp=vjp, factor_vjp=factor_vjp, factor_jacobian=factor_jacobian, jacobian=jacobian, numerical_jacobian=numerical_jacobian, jacfwd=jacfwd, eps=eps, )
def __init__(self, factor: Callable, name="", vectorised=False, is_scalar=False, **kwargs: Variable): """ A node in a graph representing a factor Parameters ---------- factor A wrapper around some callable args Variables representing positional arguments for the function kwargs Variables representing keyword arguments for the function """ self.vectorised = vectorised self.is_scalar = is_scalar self._factor = factor args = getfullargspec(self._factor).args kwargs = { **kwargs, **{ arg: Variable(arg) for arg in args if arg not in kwargs and arg != "self" } } super().__init__(**kwargs, name=name or factor.__name__)
def test_factor_jacobian(): shape = 4, 3 z_ = Variable("z", *(Plate() for _ in shape)) likelihood = NormalMessage(np.random.randn(*shape), np.random.exponential(size=shape)) likelihood_factor = likelihood.as_factor(z_) values = {z_: likelihood.sample()} fval, jval = likelihood_factor.func_jacobian(values) grad = jval.grad() ngrad = approx_fprime(values[z_].ravel(), lambda x: likelihood.logpdf(x.reshape(*shape)).sum(), 1e-8).reshape(*shape) assert np.allclose(ngrad, grad[z_])
def __init__( self, **kwargs: Variable ): """ A node in a factor graph Parameters ---------- args Positional arguments passed to the factor kwargs Key word arguments passed to the value """ self._kwargs = kwargs self._variable_name_kw = { v.name: kw for kw, v in kwargs.items()} self.id = next(self._id)
def subset( self, plates_index: Dict[Plate, Union[List[int], range, slice]], plate_sizes: Optional[Dict[Plate, int]] = None, ) -> "Factor": if not self.plates: return self plate_sizes = plate_sizes or dict(zip(self.plates, self.shape)) index = Variable.make_indexes(self, plates_index, plate_sizes) subset_factor = self._factor[index] kws = self._subset_jacobian(subset_factor, index) subset = ", ".join( map("{0.name}={1}".format, self.plates, map(np.size, index))) kws["name"] = f"{self.name}[{subset}]" kws["eps"] = self.eps kws["factor_out"] = self.factor_out kws["plates"] = self.plates return Factor(subset_factor, *self.args, **kws)
def make_y(): return Variable("y")
def make_x(): return Variable("x")