Jump to content

Connect SuperML | Leeroopedia MCP: Equip your AI agents with best practices, code verification, and debugging knowledge. Powered by Leeroo — building Organizational Superintelligence. Contact us at founders@leeroo.com.

Implementation:Pyro ppl Pyro SineBivariateVonMises

From Leeroopedia


Knowledge Sources
Domains Probability_Distributions, Directional_Statistics
Last Updated 2026-02-09 09:00 GMT

Overview

A unimodal distribution for two dependent circular random variables on the 2-torus, implementing the Sine model of the bivariate von Mises distribution.

Description

The SineBivariateVonMises distribution models the joint distribution of two dependent angles on the product of circles (S^1 x S^1). The density is given by:

C^{-1} exp(kappa_1 cos(x1 - mu_1) + kappa_2 cos(x2 - mu_2) + rho sin(x1 - mu_1) sin(x2 - mu_2))

where C is a normalizing constant computed using modified Bessel functions of the first kind.

The distribution is parameterized by:

  • phi_loc and psi_loc -- location parameters for the two angles
  • phi_concentration and psi_concentration -- concentration parameters (kappa_1 and kappa_2)
  • correlation -- the direct correlation parameter (rho), or equivalently weighted_correlation which sets rho as weighted_corr * sqrt(kappa_1 * kappa_2)

This is a submodel of the full bivariate von Mises distribution, known as the Sine Distribution in directional statistics (Mardia et al., 2007). It is particularly useful for modeling coupled angles such as torsion angles (phi, psi) in peptide chains for protein structure prediction.

The sampling algorithm follows Kent, Ganeiber, and Mardia (2018) using an Angular Central Gaussian envelope method with accept-reject sampling. The normalizing constant is computed via a series expansion using log-binomial coefficients and modified Bessel functions, remaining accurate for concentrations up to 10,000.

Important considerations:

  • The distribution becomes bimodal when rho^2 / (kappa_1 * kappa_2) -> 1, which causes sampling efficiency to degrade. Use the weighted_correlation parameter with a prior that avoids this regime.
  • The correlation and weighted_correlation parameters are mutually exclusive.
  • Compatible with SVI as a likelihood but not for latent variables.
  • The event shape is always [2], representing the two angles.

Usage

Use this distribution for modeling pairs of dependent circular variables, especially for protein torsion angle modeling. Inference should be performed with NUTS or HMC using priors that keep the distribution unimodal. For SVI, use this as a likelihood only.

Code Reference

Source Location

Signature

class SineBivariateVonMises(TorchDistribution):
    arg_constraints = {
        "phi_loc": constraints.real,
        "psi_loc": constraints.real,
        "phi_concentration": constraints.positive,
        "psi_concentration": constraints.positive,
        "correlation": constraints.real,
    }
    support = constraints.independent(constraints.real, 1)
    max_sample_iter = 1000

    def __init__(
        self,
        phi_loc,
        psi_loc,
        phi_concentration,
        psi_concentration,
        correlation=None,
        weighted_correlation=None,
        validate_args=None,
    )

Import

from pyro.distributions import SineBivariateVonMises

I/O Contract

Inputs

Name Type Required Description
phi_loc torch.Tensor Yes Location parameter for the first angle (phi).
psi_loc torch.Tensor Yes Location parameter for the second angle (psi).
phi_concentration torch.Tensor Yes Concentration parameter (kappa_1) for the first angle. Must be positive and at most 10,000.
psi_concentration torch.Tensor Yes Concentration parameter (kappa_2) for the second angle. Must be positive and at most 10,000.
correlation torch.Tensor or None No Direct correlation parameter (rho). Mutually exclusive with weighted_correlation. Exactly one must be provided.
weighted_correlation torch.Tensor or None No Weighted correlation in [-1, 1], sets rho = weighted_corr * sqrt(kappa_1 * kappa_2). Mutually exclusive with correlation.
validate_args bool or None No Whether to enable argument validation.

Outputs

Name Type Description
sample torch.Tensor Samples of shape sample_shape + batch_shape + (2,), where the last dimension contains (phi, psi) angles in [-pi, pi).
log_prob torch.Tensor Log probability density of shape sample_shape + batch_shape.
mean torch.Tensor The mean direction (phi_loc, psi_loc) stacked along the last dimension.
norm_const torch.Tensor Log normalizing constant, computed lazily.

Usage Examples

Basic Usage with Direct Correlation

import torch
from pyro.distributions import SineBivariateVonMises

dist = SineBivariateVonMises(
    phi_loc=torch.tensor(0.0),
    psi_loc=torch.tensor(0.0),
    phi_concentration=torch.tensor(5.0),
    psi_concentration=torch.tensor(5.0),
    correlation=torch.tensor(2.0),
)

# Sample angle pairs
samples = dist.sample(torch.Size([1000]))
print(samples.shape)  # torch.Size([1000, 2])

# Compute log probability
log_p = dist.log_prob(samples)
print(log_p.shape)  # torch.Size([1000])

Using Weighted Correlation for Stable Sampling

import torch
from pyro.distributions import SineBivariateVonMises

# Use weighted_correlation to avoid bimodality
dist = SineBivariateVonMises(
    phi_loc=torch.tensor(1.0),
    psi_loc=torch.tensor(-1.0),
    phi_concentration=torch.tensor(10.0),
    psi_concentration=torch.tensor(10.0),
    weighted_correlation=torch.tensor(0.5),
)

samples = dist.sample(torch.Size([500]))

Batched Distribution

import torch
from pyro.distributions import SineBivariateVonMises

# Batch of 3 distributions
dist = SineBivariateVonMises(
    phi_loc=torch.zeros(3),
    psi_loc=torch.zeros(3),
    phi_concentration=torch.tensor([2.0, 5.0, 10.0]),
    psi_concentration=torch.tensor([2.0, 5.0, 10.0]),
    correlation=torch.tensor([0.5, 1.0, 1.5]),
)

samples = dist.sample()
print(samples.shape)  # torch.Size([3, 2])

Related Pages

Page Connections

Double-click a node to navigate. Hold to expand connections.
Principle
Implementation
Heuristic
Environment