def __init__(self, df, scale, validate_args=None):
     self._dim = scale.shape[-1]
     assert df > self._dim - 1
     self.df = df
     self.cholesky_factor = transforms.LowerCholeskyTransform()(scale)
     self.chi_sqd_dists = [dist.Chi2(self.df - i) for i in range(self._dim)]
     batch_shape, event_shape = scale.shape[:-2], scale.shape[-2:]
     super().__init__(batch_shape, event_shape, validate_args)
    def __init__(self, multiplicity, in_features, dropout=0.0):
        """Creat a chi square layer.

        Args:
            multiplicity: Number of parallel representations for each input feature.
            in_features: Number of input features.

        """
        super().__init__(multiplicity, in_features, dropout)
        self.df = nn.Parameter(torch.rand(1, in_features, multiplicity))
        self.chi2 = dist.Chi2(df=self.df)
Exemple #3
0
    def __init__(self, in_features: int, out_channels: int, num_repetitions: int = 1, dropout=0.0):
        """Creat a chi square layer.

        Args:
            out_channels: Number of parallel representations for each input feature.
            in_features: Number of input features.
            num_repetitions: Number of parallel repetitions of this layer.

        """
        super().__init__(in_features, out_channels, num_repetitions, dropout)
        self.df = nn.Parameter(torch.rand(1, in_features, out_channels, num_repetitions))
        self.chi2 = dist.Chi2(df=self.df)
Exemple #4
0
def draw_chisquare(size):
    chi_distr = distr.Chi2(1.0)
    samples = chi_distr.sample((size,))
    return samples
    def sample(self, sample_shape=torch.Size()):
        # # Step 1: get spherical sample u
        # zeros = torch.zeros_like(self.loc)
        # ones = torch.ones_like(self.loc)
        # sphere_samp = db.Normal(zeros, ones).sample(sample_shape)
        # norm_r = (sphere_samp ** 2.0).sum(-1, keepdim=True).sqrt()

        # sphere_samp = sphere_samp / norm_r
        # local_loc, local_scale, sphere_samp = torch.broadcast_tensors(
        #     self.loc, self.scale, sphere_samp
        # )
        # local_cov = self.scale_to_cov(local_scale)
        # scale_mat = torch.cholesky(local_cov)

        # # Step 2: sample radius
        # batch_shape = self.loc.shape[:-1]

        # t2_dist = db.Chi2(
        #     df=torch.tensor(self.d, device=self.loc.device).expand(batch_shape)
        # )
        # t_samp = t2_dist.sample(sample_shape)
        # t_samp = t_samp.sqrt()
        # s2_dist = db.Chi2(df=self.df.expand(batch_shape))
        # s_samp = s2_dist.rsample(sample_shape)
        # s_samp = s_samp.sqrt()
        # radius = self.df.sqrt() * t_samp / s_samp
        # radius = radius.unsqueeze(-1)

        # u = torch.matmul(scale_mat, sphere_samp.unsqueeze(-1)).squeeze(-1)

        # assert radius.shape[:-1] == u.shape[:-1]
        # samp = local_loc + (radius * u)
        # if self.verbose:
        #     print(
        #         "z range: {0:.2f} / {1:.2f}".format(
        #             samp.min().item(), samp.max().item(),
        #         )
        #     )
        # return samp

        # Step 1: get spherical sample u
        zeros = torch.zeros_like(self.loc)
        ones = torch.ones_like(self.loc)
        sphere_samp = db.Normal(zeros, ones).sample(sample_shape)
        norm_r = (sphere_samp ** 2.0).sum(-1, keepdim=True).sqrt()

        sphere_samp = sphere_samp / norm_r
        local_loc, local_scale, sphere_samp = torch.broadcast_tensors(
            self.loc, self.scale, sphere_samp
        )
        scale_mat = local_scale

        # Step 2: sample radius
        batch_shape = list(self.loc.shape)
        batch_shape[-1] = 1  # Radius = 1 parameter

        t2_dist = db.Chi2(
            df=torch.tensor(self.d, device=self.loc.device).expand(batch_shape)
        )
        t_samp = t2_dist.sample(sample_shape)
        t_samp = t_samp.sqrt()
        s2_dist = db.Chi2(df=self.df.expand(batch_shape))
        s_samp = s2_dist.rsample(sample_shape)
        s_samp = s_samp.sqrt()
        radius = self.df.sqrt() * t_samp / s_samp
        # radius = radius.unsqueeze(-1)
        u = scale_mat * sphere_samp

        assert radius.shape[:-1] == u.shape[:-1]
        samp = local_loc + (radius * u)
        if self.verbose:
            print(
                "z range: {0:.2f} / {1:.2f}".format(
                    samp.min().item(), samp.max().item(),
                )
            )
        return samp