Diffusion and flow matching
Sequential directed-bond torsion rotations
Free account with email, Google or GitHub. Your code runs in an isolated PyTorch sandbox.
Your task
Rotate selected atoms around supplied directed bonds in order. Recompute each bond axis from the current conformation and return the final positions and full intermediate trajectory.
Function signature
directed_bond_torsion_rotation(
positions: torch.Tensor,
directed_edges: torch.Tensor,
rotate_mask: torch.Tensor,
torsion_angles: torch.Tensor,
valid_mask: torch.Tensor,
edge_mask: torch.Tensor,
eps: float = 1e-08,
) -> dict[str, torch.Tensor]Worked example
The first rotation changes the next bond axis
Use one molecule with atoms [(0,0,0),(1,0,0),(1,1,0),(1,1,1)], all valid, and active bonds (0,1) then (1,2). Rotate atoms [1,2,3] for the first bond and [2,3] for the second, using positive quarter-turns for both. Bond (0,1) has inward axis (-1,0,0) and pivot atom 1. It moves atoms 2 and 3 to (1,0,-1) and (1,1,-1). Now bond (1,2) has inward axis (0,0,1), computed from those updated coordinates. Atom 3’s offset from pivot atom 2 is (0,1,0); its quarter-turn becomes (-1,0,0), giving final atom 3 at (0,0,-1). The trajectory records both conformations. Using the original second axis gives a different result.
Parameters
| Parameter | Shape and meaning |
|---|---|
positionstorch.Tensor | [B, N, 3]Ligand atom coordinates |
directed_edgestorch.Tensor | [B, K, 2]int64 directed endpoints (u,v) |
rotate_masktorch.Tensor | [B, K, N]Bool downstream atom sets, excludes u/includes v for active bonds |
torsion_anglestorch.Tensor | [B, K]Supplied signed radians |
valid_masktorch.Tensor | [B, N][B,N] bool observed atoms |
edge_masktorch.Tensor | [B, K]Bool active directed bonds |
epsfloatDefault 1e-08 | Positive bond-axis length threshold. Rotate only when the current directed bond has squared length strictly greater than eps². |
Return
dict[str, torch.Tensor]
Return exactly the named fields applicable to this operation.
Required behavior
- Inputs
positions[B,N,3],directed_edges[B,K,2]int64,rotate_mask[B,K,N] bool andtorsion_angles[B,K] in radians. Process bondsj=0..K-1in the supplied order using the CURRENT updated coordinates. - For edge
(u,v), the inward positive axis isa=\frac{x_u-x_v}{\|x_u-x_v\|}and the pivot isx_v. Apply\operatorname{Exp}(\mathrm{angle\_j}\cdot a)to selected offsetsx_n-x_v; leave unselected atoms unchanged. Column action is used: row-coordinate offsets multiply the rotation matrix transpose. - The cross-product Rodrigues form is
x_{\mathrm{new}}=x+\operatorname{sin}(\operatorname{angle})\cdot (a\times d)+2\cdot \operatorname{sin}(\operatorname{angle}/2)^{2}\cdot (a\times (a\times d)),d=x-x_{v}. Zero angle must retain its correct angular derivative, not skip the differentiable computation. valid_mask[B,N]=Truemeans observed;edge_mask[B,K]=Trueenables a bond. An active bond requires in-range, distinct, valid endpoints,rotate_mask[u]=Falseandrotate_mask[v]=True; violations raiseValueError. Inactive bond indices may be-1and their angles may be nonfinite; ignore them before gathering or trigonometry.- Invalid atom coordinates may be nonfinite and are zeroed before use;
rotate_maskvalues on invalid atoms are ignored. Other observed coordinates/angles must be finite.\mathrm{eps}>0, default10^{-8}, is a bond-length threshold. - An active but coincident/short bond with
\mathrm{length}\le \varepsilonis skipped, its axis is zero andaxis_valid=False. This defined fallback replaces the original undefined zero-length normalization. Otherwiseaxis_valid=Trueandbond_axesrecords that step's unit inward axis. - Return final
positions,trajectory[B,K,N,3] after each processed bond,bond_axes[B,K,3] andaxis_valid[B,K].B\ge 1; emptyNandKare allowed, butN=0requires all edges inactive.K=0returns maskedpositionsand empty history. - No bond detection, graph search, rigid realignment or random draws are hidden.
\varepsilonis the onlykey; nonpositive\varepsilonraisesValueError.
Why this matters
Rotating a selected atom group around a bond changes conformation. The sign comes from the directed axis, and earlier rotations can change the axis used by later bonds.
Starter code
You write the body of this function in the BioTorch workspace. Your code runs in an isolated PyTorch sandbox; Run checks the public examples and Submit grades the full test suite, including gradients.
import torch
def directed_bond_torsion_rotation(
positions: torch.Tensor, # (B, N, 3)
directed_edges: torch.Tensor, # (B, K, 2)
rotate_mask: torch.Tensor, # (B, K, N)
torsion_angles: torch.Tensor, # (B, K)
valid_mask: torch.Tensor, # (B, N)
edge_mask: torch.Tensor, # (B, K)
eps: float = 1e-08,
) -> dict[str, torch.Tensor]:
"""Return dict[str, torch.Tensor]:
positions: (B, N, 3).
trajectory: (B, K, N, 3).
bond_axes: (B, K, 3).
axis_valid: (B, K)."""
# Implement the operation. Inputs and test setup are supplied by BioTorch.
raise NotImplementedError("Implement directed_bond_torsion_rotation")
Ready to implement it?
3 progressive hints, a solution walkthrough, and grading that checks values, shapes and gradients are waiting in the workspace.
Free account with email, Google or GitHub. Your code runs in an isolated PyTorch sandbox.
Sources and further reading
A primitive exercise, not an end-to-end reproduction of the named models. No affiliation or endorsement is implied.