Linear Layers¶
Fully-connected hyperbolic layers across the Poincaré, Hyperboloid, and Proper Velocity models. For which linear layer to pick (defaults, speed/expressiveness trade-offs) see the NN Layers guide.
Channel convention
Hyperboloid linear layers (HTCLinear, FGGLinear, HypLinearHyperboloid*) take
ambient in_features = d+1. Poincaré and PV layers take spatial
in_dim = d. HTCLinear is the exception whose out_features is spatial — its
output shape is (B, out_features + 1).
Poincaré¶
hyperbolix.nn_layers.HypLinearPoincare ¶
HypLinearPoincare(
manifold_module: Manifold,
in_dim: int,
out_dim: int,
*,
rngs: Rngs,
input_space: str = "manifold",
curvature: float | Callable[[], Any] = 1.0,
param_dtype: DTypeLike = jnp.float32,
)
Bases: Module
Hyperbolic Neural Networks fully connected layer (Poincaré ball model).
Computation steps: 0) Project the input tensor to the tangent space (optional) 1) Perform matrix vector multiplication in the tangent space at the origin. 2) Map the result to the manifold. 3) Add the manifold bias to the result.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
manifold_module
|
object
|
Class-based Poincare manifold instance |
required |
in_dim
|
int
|
Dimension of the input space |
required |
out_dim
|
int
|
Dimension of the output space |
required |
rngs
|
Rngs
|
Random number generators for parameter initialization |
required |
input_space
|
str
|
Type of the input tensor, either 'tangent' or 'manifold' (default: 'manifold'). Note: This is a static configuration - changing it after initialization requires recompilation. |
'manifold'
|
curvature
|
float or callable
|
Curvature tag for the manifold-valued |
1.0
|
param_dtype
|
DTypeLike
|
Storage dtype of the trainable parameters (default: jnp.float32).
Compute precision of manifold operations is set by |
float32
|
Notes
JIT Compatibility: This layer is designed to work with nnx.jit. Configuration parameters (input_space) are treated as static and will be baked into the compiled function. Changing these values after JIT compilation will trigger automatic recompilation.
References
Ganea Octavian, Gary Bécigneul, and Thomas Hofmann. "Hyperbolic neural networks." Advances in neural information processing systems 31 (2018).
Source code in hyperbolix/nn_layers/poincare_linear.py
__call__ ¶
Forward pass through the hyperbolic linear layer.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
Array of shape (batch, in_dim)
|
Input tensor where the hyperbolic_axis is last |
required |
c
|
float
|
Manifold curvature (default: 1.0) |
1.0
|
Returns:
| Name | Type | Description |
|---|---|---|
res |
Array of shape (batch, out_dim)
|
Output on the Poincaré ball manifold |
Source code in hyperbolix/nn_layers/poincare_linear.py
hyperbolix.nn_layers.HypLinearPoincarePP ¶
HypLinearPoincarePP(
manifold_module: Poincare,
in_dim: int,
out_dim: int,
*,
rngs: Rngs,
input_space: str = "manifold",
clamping_factor: float = 1.0,
smoothing_factor: float = 50.0,
param_dtype: DTypeLike = jnp.float32,
)
Bases: Module
Hyperbolic Neural Networks ++ fully connected layer (Poincaré ball model).
Computation steps: 0) Project the input tensor onto the manifold (optional) 1) Compute the multinomial linear regression score(s) 2) Calculate the generalized linear transformation from the regression score(s)
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
manifold_module
|
object
|
Class-based Poincare manifold instance |
required |
in_dim
|
int
|
Dimension of the input space |
required |
out_dim
|
int
|
Dimension of the output space |
required |
rngs
|
Rngs
|
Random number generators for parameter initialization |
required |
input_space
|
str
|
Type of the input tensor, either 'tangent' or 'manifold' (default: 'manifold'). Note: This is a static configuration - changing it after initialization requires recompilation. |
'manifold'
|
clamping_factor
|
float
|
Clamping factor for the multinomial linear regression output (default: 1.0) |
1.0
|
smoothing_factor
|
float
|
Smoothing factor for the multinomial linear regression output (default: 50.0) |
50.0
|
param_dtype
|
DTypeLike
|
Storage dtype of the trainable parameters (default: jnp.float32).
Compute precision of manifold operations is set by |
float32
|
Notes
JIT Compatibility: This layer is designed to work with nnx.jit. Configuration parameters (input_space, clamping_factor, smoothing_factor) are treated as static and will be baked into the compiled function.
References
Shimizu Ryohei, Yusuke Mukuta, and Tatsuya Harada. "Hyperbolic neural networks++." arXiv preprint arXiv:2006.08210 (2020).
Source code in hyperbolix/nn_layers/poincare_linear.py
__call__ ¶
Forward pass through the HNN++ hyperbolic linear layer.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
Array of shape (batch, in_dim)
|
Input tensor where the hyperbolic_axis is last |
required |
c
|
float
|
Manifold curvature (default: 1.0) |
1.0
|
Returns:
| Name | Type | Description |
|---|---|---|
res |
Array of shape (batch, out_dim)
|
Output on the Poincaré ball manifold |
Source code in hyperbolix/nn_layers/poincare_linear.py
hyperbolix.nn_layers.HypLinearPoincareBusemann ¶
HypLinearPoincareBusemann(
manifold_module: Poincare,
in_dim: int,
out_dim: int,
*,
rngs: Rngs,
input_space: str = "manifold",
activation: Callable[[Array], Array] | None = None,
v_max: float = 10.0,
use_gyro_bias: bool = False,
param_dtype: DTypeLike = jnp.float32,
)
Bases: Module
Busemann fully connected (BFC) layer (Poincaré ball model).
Maps a Poincaré ball point to a Poincaré ball point (Chen et al. 2026, Thm. 4.1). Each
output coordinate is the activated Busemann logit φ(-alpha_k·B^{v_k}(x) + b_k); the point is
recovered via ω = sinh(√c·φ(u))/√c, y = ω / (1 + √(1 + c‖ω‖²)), then projected.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
manifold_module
|
Poincare
|
Class-based Poincaré manifold instance. |
required |
in_dim
|
int
|
Input spatial dimension (the ball has no time component). |
required |
out_dim
|
int
|
Output spatial dimension. |
required |
rngs
|
Rngs
|
Random number generators for parameter initialization. |
required |
input_space
|
str
|
|
'manifold'
|
activation
|
Callable or None
|
Optional Euclidean activation |
None
|
v_max
|
float
|
Output-side guard: |
10.0
|
use_gyro_bias
|
bool
|
If True, add a learnable intrinsic bias |
False
|
param_dtype
|
DTypeLike
|
Storage dtype of the trainable parameters (default: jnp.float32). |
float32
|
References
Chen, Schölkopf, and Sebe. "Hyperbolic Busemann Neural Networks." 2026, Thm. 4.1.
Source code in hyperbolix/nn_layers/busemann_linear.py
__call__ ¶
Forward pass returning a Poincaré ball point, shape (batch, out_dim).
Source code in hyperbolix/nn_layers/busemann_linear.py
Hyperboloid¶
HypLinearHyperboloidPLFC is the point-to-hyperplane Lorentz FC (Shi et al. 2026),
the Lorentz analog of the HNN++ formulation; the Busemann FC decides with
point-to-horosphere distances. HTCLinear (the robust default) is documented here;
the foundational htc() function lives in Primitives.
hyperbolix.nn_layers.HTCLinear ¶
HTCLinear(
in_features: int,
out_features: int,
*,
rngs: Rngs,
use_bias: bool = True,
init_bound: float = 0.02,
eps: float = 1e-07,
param_dtype: DTypeLike = jnp.float32,
)
Bases: Module
Hyperbolic Transformation Component with learnable linear transformation.
This module wraps a Euclidean linear layer with the HTC operation, enabling learnable transformations between hyperboloid manifolds with different curvatures.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
in_features
|
int
|
Input feature dimension (full hyperboloid dimension, including time component). |
required |
out_features
|
int
|
Output spatial dimension (time component is reconstructed automatically). |
required |
rngs
|
Rngs
|
Random number generators for parameter initialization. |
required |
use_bias
|
bool
|
Whether to include a bias term (default: True). |
True
|
init_bound
|
float
|
Bound for uniform weight initialization. Weights are initialized from Uniform(-init_bound, init_bound). Small values keep initial outputs close to the hyperboloid origin for stable training (default: 0.02). |
0.02
|
eps
|
float
|
Small value for numerical stability (default: 1e-7). |
1e-07
|
param_dtype
|
DTypeLike
|
Storage dtype of the trainable parameters (default: jnp.float32).
Compute precision of manifold operations is set by the manifold's |
float32
|
Attributes:
| Name | Type | Description |
|---|---|---|
kernel |
Param
|
Weight matrix of shape (in_features, out_features). |
bias |
Param or None
|
Bias vector of shape (out_features,) if use_bias=True, else None. |
eps |
float
|
Numerical stability parameter. |
Notes
Weight Initialization: This layer uses small uniform initialization U(-0.02, 0.02) by default, matching the initialization used by FHNN/FHCNN layers. Standard deep learning initializations (Xavier, Lecun) produce weights that are too large for hyperbolic operations, causing gradient explosion and training instability.
See Also
hyperbolix.nn_layers.hyperboloid_core.htc : Core HTC function for functional transformations. HypLinearHyperboloidFHCNN : Alternative hyperbolic linear layer with sigmoid scaling.
References
Hypformer paper (citation to be added)
Examples:
>>> from flax import nnx
>>> from hyperbolix.nn_layers import HTCLinear
>>> from hyperbolix.manifolds import Hyperboloid
>>>
>>> # Create layer
>>> layer = HTCLinear(in_features=5, out_features=8, rngs=nnx.Rngs(0))
>>>
>>> # Forward pass
>>> manifold = Hyperboloid()
>>> x = jnp.ones((32, 5)) # batch of 32 points
>>> x = jax.vmap(manifold.proj, in_axes=(0, None))(x, 1.0)
>>> y = layer(x, c_in=1.0, c_out=2.0)
>>> y.shape
(32, 9) # 8 spatial + 1 time
Source code in hyperbolix/nn_layers/hyperboloid_linear.py
__call__ ¶
__call__(
x: Float[Array, "batch in_features"],
c_in: float = 1.0,
c_out: float = 1.0,
) -> Float[Array, "batch out_features_plus_1"]
Apply HTC linear transformation.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
Array of shape (batch, in_features)
|
Input points on hyperboloid with curvature c_in. |
required |
c_in
|
float
|
Input curvature (default: 1.0). |
1.0
|
c_out
|
float
|
Output curvature (default: 1.0). |
1.0
|
Returns:
| Name | Type | Description |
|---|---|---|
y |
Array of shape (batch, out_features+1)
|
Output points on hyperboloid with curvature c_out. |
Source code in hyperbolix/nn_layers/hyperboloid_linear.py
hyperbolix.nn_layers.HypLinearHyperboloidFHCNN ¶
HypLinearHyperboloidFHCNN(
manifold_module: Manifold,
in_dim: int,
out_dim: int,
*,
rngs: Rngs,
input_space: str = "manifold",
init_scale: float = 2.3,
learnable_scale: bool = False,
eps: float = 1e-05,
activation: Callable[[Array], Array] | None = None,
normalize: bool = False,
param_dtype: DTypeLike = jnp.float32,
)
Bases: Module
Fully Hyperbolic Convolutional Neural Networks fully connected layer (Hyperboloid model).
Computation steps: 0) Project the input tensor to the manifold (optional) 1) Apply activation (optional) 2) a) If normalize is True, compute the time and space coordinates of the output by applying a scaled sigmoid of the weight and biases transformed coordinates of the input or the result of the previous step. b) If normalize is False, compute the weight and biases transformed space coordinates of the input or the result of the previous step and set the time coordinate such that the result lies on the manifold.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
manifold_module
|
object
|
Class-based Hyperboloid manifold instance |
required |
in_dim
|
int
|
Dimension of the input space |
required |
out_dim
|
int
|
Dimension of the output space |
required |
rngs
|
Rngs
|
Random number generators for parameter initialization |
required |
input_space
|
str
|
Type of the input tensor, either 'tangent' or 'manifold' (default: 'manifold'). Note: This is a static configuration - changing it after initialization requires recompilation. |
'manifold'
|
init_scale
|
float
|
Initial value for the sigmoid scale parameter (default: 2.3) |
2.3
|
learnable_scale
|
bool
|
Whether the scale parameter should be learnable (default: False) |
False
|
eps
|
float
|
Small value to ensure that the time coordinate is bigger than 1/sqrt(c) (default: 1e-5) |
1e-05
|
activation
|
callable or None
|
Activation function to apply before the linear transformation (default: None). Note: This is a static configuration - changing it after initialization requires recompilation. |
None
|
normalize
|
bool
|
Whether to normalize the space coordinates before rescaling (default: False). Note: This is a static configuration - changing it after initialization requires recompilation. |
False
|
param_dtype
|
DTypeLike
|
Storage dtype of the trainable parameters (default: jnp.float32).
Compute precision of manifold operations is set by |
float32
|
Notes
JIT Compatibility: This layer is designed to work with nnx.jit. Configuration parameters (input_space, activation, normalize) are treated as static and will be baked into the compiled function.
Relationship to HTC/HRC:
When normalize=False and c_in = c_out, this layer uses the same time reconstruction
pattern as htc: time = sqrt(||space||^2 + 1/c). The key difference is that FHCNN
applies a linear transform to the full input and discards the computed time, while htc
uses the linear output directly as spatial components. When normalize=True, FHCNN uses
a learned sigmoid scaling which differs from both htc and hrc.
See Also
htc : Hyperbolic Transformation Component with curvature change support. Similar time reconstruction pattern when normalize=False. HTCLinear : Module wrapper for htc with learnable linear transformation.
References
Ahmad Bdeir, Kristian Schwethelm, and Niels Landwehr. "Fully hyperbolic convolutional neural networks for computer vision." arXiv preprint arXiv:2303.15919 (2023).
Source code in hyperbolix/nn_layers/hyperboloid_linear.py
__call__ ¶
Forward pass through the FHCNN hyperbolic linear layer.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
Array of shape (batch, in_dim)
|
Input tensor where the hyperbolic_axis is last. x.shape[-1] must equal self.in_dim. |
required |
c
|
float
|
Manifold curvature (default: 1.0) |
1.0
|
Returns:
| Name | Type | Description |
|---|---|---|
res |
Array of shape (batch, out_dim)
|
Output on the Hyperboloid manifold |
Source code in hyperbolix/nn_layers/hyperboloid_linear.py
hyperbolix.nn_layers.HypLinearHyperboloidFHNN ¶
HypLinearHyperboloidFHNN(
manifold_module: Manifold,
in_dim: int,
out_dim: int,
*,
rngs: Rngs,
input_space: str = "manifold",
init_scale: float = 2.3,
eps: float = 1e-05,
activation: Callable[[Array], Array] | None = None,
dropout_rate: float | None = None,
param_dtype: DTypeLike = jnp.float32,
)
Bases: Module
Fully Hyperbolic Neural Networks linear layer (Chen et al. 2021).
Time-primary parameterization: the time coordinate is computed via scaled sigmoid with an additive floor at 1/sqrt(c), and spatial coordinates are rescaled so the output lies on the hyperboloid.
Computation steps: 0) Project the input tensor to the manifold (optional) 1) Apply activation (optional) 2) Apply dropout (optional) 3) Linear transform: z = W @ x + b 4) Time: y0 = exp(scale) * sigmoid(z0) + 1/sqrt(c) + eps 5) Spatial: y_rem = sqrt(y0^2 - 1/c) / ||z_rem|| * z_rem 6) Output: [y0, y_rem] on the hyperboloid
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
manifold_module
|
object
|
Class-based Hyperboloid manifold instance |
required |
in_dim
|
int
|
Ambient input dimension (d+1, including time) |
required |
out_dim
|
int
|
Ambient output dimension (d+1, including time) |
required |
rngs
|
Rngs
|
Random number generators for parameter initialization |
required |
input_space
|
str
|
Type of the input tensor, either 'tangent' or 'manifold' (default: 'manifold'). Note: This is a static configuration - changing it after initialization requires recompilation. |
'manifold'
|
init_scale
|
float
|
Initial value for the learnable sigmoid scale (default: 2.3) |
2.3
|
eps
|
float
|
Numerical stability epsilon (default: 1e-5) |
1e-05
|
activation
|
callable or None
|
Activation function to apply before the linear transformation (default: None). Note: This is a static configuration - changing it after initialization requires recompilation. |
None
|
dropout_rate
|
float or None
|
Dropout rate applied before the linear transformation (default: None). |
None
|
param_dtype
|
DTypeLike
|
Storage dtype of the trainable parameters (default: jnp.float32).
Compute precision of manifold operations is set by |
float32
|
Notes
JIT Compatibility: This layer is designed to work with nnx.jit. Configuration parameters (input_space, activation) are treated as static and will be baked into the compiled function.
Weight Initialization: Weights are initialized as tangent vectors at the hyperboloid origin: U(-0.02, 0.02) with the time column (column 0) zeroed. This matches the Chen et al. 2021 init.
Relationship to FHCNN: Both FHNN and FHCNN ensure outputs lie on the hyperboloid, but differ in which coordinate is primary. FHNN controls the time coordinate via sigmoid with an additive floor at 1/sqrt(c), then derives the spatial norm from the hyperboloid constraint. FHCNN (normalize=True) controls the spatial norm via sigmoid, then derives time.
See Also
HypLinearHyperboloidFHCNN : FHCNN layer with spatial-primary parameterization. HypLinearHyperboloidPLFC : PLFC layer using MLR + sinh diffeomorphism.
References
Weize Chen, et al. "Fully hyperbolic neural networks." arXiv preprint arXiv:2105.14686 (2021).
Source code in hyperbolix/nn_layers/hyperboloid_linear.py
__call__ ¶
__call__(
x: Float[Array, "batch in_dim"],
c: float = 1.0,
deterministic: bool = True,
) -> Float[Array, "batch out_dim"]
Forward pass through the FHNN hyperbolic linear layer.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
Array of shape (batch, in_dim)
|
Input tensor. x.shape[-1] must equal self.in_dim. |
required |
c
|
float
|
Manifold curvature (default: 1.0) |
1.0
|
deterministic
|
bool
|
If True, dropout is disabled (default: True). |
True
|
Returns:
| Name | Type | Description |
|---|---|---|
res |
Array of shape (batch, out_dim)
|
Output on the Hyperboloid manifold |
Source code in hyperbolix/nn_layers/hyperboloid_linear.py
hyperbolix.nn_layers.HypLinearHyperboloidPLFC ¶
HypLinearHyperboloidPLFC(
manifold_module: Hyperboloid,
in_dim: int,
out_dim: int,
*,
rngs: Rngs,
input_space: str = "manifold",
clamping_factor: float = 1.0,
smoothing_factor: float = 50.0,
v_max: float = 10.0,
use_gyro_bias: bool = False,
kernel_init_std: float = 0.02,
param_dtype: DTypeLike = jnp.float32,
)
Bases: Module
Point-to-hyperplane Lorentz fully connected (PLFC) layer (Hyperboloid model).
Each output coordinate is the signed Lorentz distance from the input point to a
learned Lorentz hyperplane (the Lorentz MLR score). The output point is recovered
in closed form via the element-wise sinh diffeomorphism and the hyperboloid time
constraint, so the signed distance from the output to the k-th coordinate
hyperplane equals the k-th score (margin preservation, Shi et al. 2026, Thm. 1-2).
This is the Lorentz analog of the HNN++ point-to-hyperplane FC formulation
(Shimizu et al. 2020). Formerly named HypLinearHyperboloidPP.
Computation steps:
0) Project the input tensor onto the manifold (optional)
1) Compute the multinomial linear regression score(s) via compute_mlr
2) Hard-clamp the scaled scores sqrt(c)*v to ±v_max (output-side guard)
3) Apply element-wise sinh diffeomorphism to obtain spatial coordinates
4) Reconstruct time coordinate from the hyperboloid constraint
5) Optionally add an intrinsic gyro-bias y ← y ⊕ exp_0([0, b])
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
manifold_module
|
object
|
Class-based Hyperboloid manifold instance |
required |
in_dim
|
int
|
Full input dimension (ambient, d+1) |
required |
out_dim
|
int
|
Full output dimension (ambient, d+1) |
required |
rngs
|
Rngs
|
Random number generators for parameter initialization |
required |
input_space
|
str
|
Type of the input tensor, either 'tangent' or 'manifold' (default: 'manifold'). Note: This is a static configuration - changing it after initialization requires recompilation. |
'manifold'
|
clamping_factor
|
float
|
Clamping factor for the multinomial linear regression output (default: 1.0) |
1.0
|
smoothing_factor
|
float
|
Smoothing factor for the multinomial linear regression output (default: 50.0) |
50.0
|
v_max
|
float
|
Output-side guard: the sinh argument |
10.0
|
use_gyro_bias
|
bool
|
If True, add a learnable intrinsic bias via Lorentz gyroaddition,
|
False
|
kernel_init_std
|
float
|
Standard deviation of the normal kernel init (default: 0.02, the Shi et al.
2026 PLFC reference value). Use 1.0 to recover the previous HNN++-style
init (Shimizu et al. 2020); note that large kernels push the pre-guard
scores toward the |
0.02
|
param_dtype
|
DTypeLike
|
Storage dtype of the trainable parameters (default: jnp.float32).
Compute precision of manifold operations is set by |
float32
|
Notes
JIT Compatibility: This layer is designed to work with nnx.jit. Configuration parameters (input_space, clamping_factor, smoothing_factor, v_max) are treated as static and will be baked into the compiled function.
References
Xianglong Shi, Ziheng Chen, Yunhan Jiang, and Nicu Sebe. "Intrinsic Lorentz Neural Network." ICLR 2026, Sec. 4.1 (PLFC layer, Theorem 1). Shimizu Ryohei, Yusuke Mukuta, and Tatsuya Harada. "Hyperbolic neural networks++." arXiv preprint arXiv:2006.08210 (2020).
Source code in hyperbolix/nn_layers/hyperboloid_linear.py
__call__ ¶
Forward pass through the PLFC hyperboloid linear layer.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
Array of shape (batch, in_dim)
|
Input tensor. x.shape[-1] must equal self.in_dim. |
required |
c
|
float
|
Manifold curvature (default: 1.0) |
1.0
|
Returns:
| Name | Type | Description |
|---|---|---|
res |
Array of shape (batch, out_dim)
|
Output on the Hyperboloid manifold |
Source code in hyperbolix/nn_layers/hyperboloid_linear.py
hyperbolix.nn_layers.HypLinearHyperboloidBusemann ¶
HypLinearHyperboloidBusemann(
manifold_module: Hyperboloid,
in_dim: int,
out_dim: int,
*,
rngs: Rngs,
input_space: str = "manifold",
activation: Callable[[Array], Array] | None = None,
v_max: float = 10.0,
use_gyro_bias: bool = False,
param_dtype: DTypeLike = jnp.float32,
)
Bases: Module
Busemann fully connected (BFC) layer (Hyperboloid / Lorentz model).
Maps a hyperboloid point to a hyperboloid point (Chen et al. 2026, Thm. 4.2). Each output
spatial coordinate is the activated Busemann logit φ(-alpha_k·B^{v_k}(x) + b_k); the point
is recovered via the shared sinh_lift_to_hyperboloid output map (the same closed form
as HypLinearHyperboloidPLFC, but with a point-to-horosphere score instead of
point-to-hyperplane).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
manifold_module
|
Hyperboloid
|
Class-based Hyperboloid manifold instance. |
required |
in_dim
|
int
|
Input ambient dimension ( |
required |
out_dim
|
int
|
Output ambient dimension ( |
required |
rngs
|
Rngs
|
Random number generators for parameter initialization. |
required |
input_space
|
str
|
|
'manifold'
|
activation
|
Callable or None
|
Optional Euclidean activation |
None
|
v_max
|
float
|
Output-side guard: |
10.0
|
use_gyro_bias
|
bool
|
If True, add a learnable intrinsic bias |
False
|
param_dtype
|
DTypeLike
|
Storage dtype of the trainable parameters (default: jnp.float32). |
float32
|
References
Chen, Schölkopf, and Sebe. "Hyperbolic Busemann Neural Networks." 2026, Thm. 4.2.
Source code in hyperbolix/nn_layers/busemann_linear.py
__call__ ¶
Forward pass returning a hyperboloid point, shape (batch, out_dim).
Source code in hyperbolix/nn_layers/busemann_linear.py
FGG Linear (Klis et al. 2026)¶
FGGLinear achieves linear (not logarithmic) growth of hyperbolic distance via the
sinh/arcsinh cancellation in the Lorentzian activation chain. It defaults to a
norm-preserving fan_out init suited to unnormalized stacks — see the
init-scales note.
hyperbolix.nn_layers.FGGLinear ¶
FGGLinear(
in_features: int,
out_features: int,
*,
rngs: Rngs,
activation: Callable[[Array], Array] | None = None,
reset_params: str = "fan_out",
use_weight_norm: bool = False,
init_bias: float = 0.0,
gain: float = 1.0,
eps: float = 1e-07,
param_dtype: DTypeLike = jnp.float32,
)
Bases: Module
Fast and Geometrically Grounded Lorentz linear layer.
Implements the FGG linear layer from Klis et al. 2026. The key insight is that the sinh/arcsinh cancellation in the Lorentzian activation chain simplifies the forward pass to: matmul with spacelike V matrix -> Euclidean activation -> time reconstruction. This achieves linear growth of hyperbolic distance (vs logarithmic for Chen et al. 2022) and ~3x faster training/inference.
Forward pass: 1. Build spacelike V matrix from (U, b) with Minkowski metric absorbed 2. z = x @ V (Minkowski inner products via a single matmul) 3. z = h(z) (Euclidean activation, e.g. ReLU) 4. y_0 = sqrt(||z||^2 + 1/c) (time reconstruction) 5. y = [y_0, z] (on hyperboloid)
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
in_features
|
int
|
Input ambient dimension (D_in + 1), including time component. |
required |
out_features
|
int
|
Output ambient dimension (D_out + 1), including time component. |
required |
rngs
|
Rngs
|
Random number generators for parameter initialization. |
required |
activation
|
Callable or None
|
Euclidean activation function applied after matmul (default: None). |
None
|
reset_params
|
str
|
Weight initialization scheme: |
'fan_out'
|
use_weight_norm
|
bool
|
If True, reparameterize U as |
False
|
init_bias
|
float
|
Initial value for bias entries (default: 0.0). A zero bias removes the
|
0.0
|
gain
|
float
|
Multiplier on the random init (default: 1.0). With |
1.0
|
eps
|
float
|
Numerical stability floor (default: 1e-7). |
1e-07
|
param_dtype
|
DTypeLike
|
Storage dtype of the trainable parameters (default: jnp.float32).
Compute precision of manifold operations is set by the manifold's |
float32
|
References
Klis et al. "Fast and Geometrically Grounded Lorentz Neural Networks" (2026).
Examples:
>>> from flax import nnx
>>> from hyperbolix.nn_layers import FGGLinear
>>> import jax.numpy as jnp
>>>
>>> layer = FGGLinear(33, 65, rngs=nnx.Rngs(0), activation=jax.nn.relu)
>>> x = jnp.ones((8, 33))
>>> # project to hyperboloid
>>> x = x.at[:, 0].set(jnp.sqrt(jnp.sum(x[:, 1:]**2, axis=-1) + 1.0))
>>> y = layer(x, c=1.0)
>>> y.shape
(8, 65)
Source code in hyperbolix/nn_layers/hyperboloid_linear.py
__call__ ¶
__call__(
x_BAi: Float[Array, "batch in_features"], c: float = 1.0
) -> Float[Array, "batch out_features"]
Forward pass through the FGG linear layer.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x_BAi
|
(Array, shape(B, Ai))
|
Input points on the hyperboloid with curvature |
required |
c
|
float
|
Curvature parameter (default: 1.0). |
1.0
|
Returns:
| Name | Type | Description |
|---|---|---|
y_BAo |
(Array, shape(B, Ao))
|
Output points on the hyperboloid with curvature |
Source code in hyperbolix/nn_layers/hyperboloid_linear.py
Proper Velocity¶
HypLinearPV implements the PV fully-connected layer from Chen et al. 2026
(Thm 5.3 / Eq. 22): \(y_k = (1/\sqrt{c}) \cdot \sinh(\sqrt{c} \cdot v_k(x))\) where
\(v_k(x)\) is the PV multinomial-logistic-regression signed margin. PV is an
unconstrained \(\mathbb{R}^n\) model, so inputs and outputs are Euclidean with no
projection step.
hyperbolix.nn_layers.HypLinearPV ¶
HypLinearPV(
manifold_module: ProperVelocity,
in_dim: int,
out_dim: int,
*,
rngs: Rngs,
input_space: str = "manifold",
inner_activation: Callable[[Array], Array]
| None = None,
clamping_factor: float = 1.0,
smoothing_factor: float = 50.0,
kernel_init_std: float | None = None,
param_dtype: DTypeLike = jnp.float32,
)
Bases: Module
Hyperbolic Neural Networks fully connected layer (Proper Velocity model).
Implements Chen et al. 2026, Thm 5.3 / Eq. 22:
y_k = (1/√c) · sinh(√c · v_k(x))
where v_k(x) is the PV multinomial-logistic-regression signed margin
from Eq. 19 (implemented as ProperVelocity.compute_mlr). The optional
inner_activation realizes the Eq. 23 ablation from the paper.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
manifold_module
|
ProperVelocity
|
Class-based Proper Velocity manifold instance. |
required |
in_dim
|
int
|
Dimension of the input space. |
required |
out_dim
|
int
|
Dimension of the output space. |
required |
rngs
|
Rngs
|
Random number generators for parameter initialization. |
required |
input_space
|
str
|
Type of the input tensor, either 'tangent' or 'manifold' (default: 'manifold'). Note: This is a static configuration — changing it after initialization requires recompilation. |
'manifold'
|
inner_activation
|
Callable[[Array], Array] | None
|
Optional activation applied to |
None
|
clamping_factor
|
float
|
Clamping factor for the MLR output (default: 1.0). |
1.0
|
smoothing_factor
|
float
|
Smoothing factor for the MLR output (default: 50.0). |
50.0
|
kernel_init_std
|
float | None
|
Standard deviation for the Gaussian kernel init. If |
None
|
param_dtype
|
DTypeLike
|
Storage dtype of the trainable parameters (default: jnp.float32).
Compute precision of manifold operations is set by |
float32
|
Notes
JIT Compatibility: Configuration parameters (input_space, clamping_factor, smoothing_factor, inner_activation) are treated as static and are baked into the compiled function.
References
Chen et al. "Proper Velocity Neural Networks." ICLR 2026.
Source code in hyperbolix/nn_layers/pv_linear.py
__call__ ¶
Forward pass through the PV linear layer.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
Array of shape (batch, in_dim)
|
Input — PV manifold points or tangent vectors at origin, depending on
|
required |
c
|
float
|
Manifold curvature (default: 1.0). |
1.0
|
Returns:
| Name | Type | Description |
|---|---|---|
res |
Array of shape (batch, out_dim)
|
Output points on the PV manifold. |
Source code in hyperbolix/nn_layers/pv_linear.py
Example¶
import jax
from flax import nnx
from hyperbolix.nn_layers import HypLinearPoincare
from hyperbolix.manifolds import Poincare
poincare = Poincare()
layer = HypLinearPoincare(manifold_module=poincare, in_dim=32, out_dim=16, rngs=nnx.Rngs(0))
x = jax.random.normal(jax.random.PRNGKey(1), (10, 32)) * 0.3
x_proj = jax.vmap(poincare.proj, in_axes=(0, None))(x, 1.0)
output = layer(x_proj, c=1.0)
print(output.shape) # (10, 16)
See the NN Layers guide for multi-layer composition patterns (HTC classifier, hybrid CNN + Poincaré head).