jraphx.utils
Utility functions and operations for graph processing and manipulation.
Scatter Operations
The scatter module provides efficient implementations of scatter operations for aggregating node features.
scatter_add
- scatter_add(src: Array, index: Array, dim_size: int | None = None, dim: int = -2) Array[source]
Sums all values from the
srctensor at the indices specified in theindextensor along a given dimensiondim.Uses JAX’s optimized segment_sum for better performance.
Note
dim_sizedetermines the output shape and is therefore a static argument. When it isNoneit is inferred fromindex, which requiresindexto be concrete and hence is not available underjax.jit.- Parameters:
src (
Array) – The source tensor.index (
Array) – The index tensor.dim_size (
int|None, default:None) – The size of the output tensor at dimensiondim. If set toNone, will create a minimal-sized output tensor according toindex.max() + 1. (default:None)dim (
int, default:-2) – The dimension along which to index. (default:-2)
- Returns:
Tensor with scattered values summed at each index.
- Returns:
Array–
Scatter sum operation for aggregating values by index.
Example:
from jraphx.utils.scatter import scatter_add import jax.numpy as jnp src = jnp.array([1.0, 2.0, 3.0, 4.0]) index = jnp.array([0, 0, 1, 1]) # Sum values by index out = scatter_add(src, index, dim_size=2) # Result: [3.0, 7.0]
scatter_mean
- scatter_mean(src: Array, index: Array, dim_size: int | None = None, dim: int = -2) Array[source]
Scatter mean operation - averages values from src at indices specified by index.
Empty segments are filled with zero.
- Parameters:
- Returns:
Array– Tensor with scattered values
Scatter mean operation for averaging values by index.
Example:
from jraphx.utils.scatter import scatter_mean import jax.numpy as jnp src = jnp.array([1.0, 2.0, 3.0, 4.0]) index = jnp.array([0, 0, 1, 1]) # Average values by index out = scatter_mean(src, index, dim_size=2) # Result: [1.5, 3.5]
scatter_max
- scatter_max(src: Array, index: Array, dim_size: int | None = None, dim: int = -2, fill_value: float | None = None) Array[source]
Scatter max operation - takes maximum of values from src at indices specified by index.
Segments that receive no value are filled with
fill_value. Emptiness is determined fromindexalone, so genuine infinities and NaNs present insrcare propagated untouched and the output keepssrc’s dtype.- Parameters:
src (
Array) – Source tensor to scatterindex (
Array) – Indices where to scatterdim_size (
int|None, default:None) – Size of the output dimension, inferred fromindexifNone(which requires a concreteindex)dim (
int, default:-2) – Dimension along which to scatterfill_value (
float|None, default:None) – Value assigned to empty segments, cast tosrc.dtype.Nonemeans zero.
- Returns:
Array– Tensor with scattered values
Scatter max operation for finding maximum values by index.
Example:
from jraphx.utils.scatter import scatter_max import jax.numpy as jnp src = jnp.array([1.0, 3.0, 2.0, 4.0]) index = jnp.array([0, 0, 1, 1]) # Find max values by index out = scatter_max(src, index, dim_size=2) # Result: [3.0, 4.0]
scatter_min
- scatter_min(src: Array, index: Array, dim_size: int | None = None, dim: int = -2, fill_value: float | None = None) Array[source]
Scatter min operation - takes minimum of values from src at indices specified by index.
Segments that receive no value are filled with
fill_value. Emptiness is determined fromindexalone, so genuine infinities and NaNs present insrcare propagated untouched and the output keepssrc’s dtype.- Parameters:
src (
Array) – Source tensor to scatterindex (
Array) – Indices where to scatterdim_size (
int|None, default:None) – Size of the output dimension, inferred fromindexifNone(which requires a concreteindex)dim (
int, default:-2) – Dimension along which to scatterfill_value (
float|None, default:None) – Value assigned to empty segments, cast tosrc.dtype.Nonemeans zero.
- Returns:
Array– Tensor with scattered values
Scatter min operation for finding minimum values by index.
scatter_std
- scatter_std(src: Array, index: Array, dim_size: int | None = None, dim: int = -2, unbiased: bool = True) Array[source]
Scatter standard deviation - computes std of values at indices.
The deviations are accumulated around the per-segment mean, which avoids the catastrophic cancellation of the
E[X^2] - E[X]^2form. Segments holding fewer than two values (and empty segments) get a standard deviation of zero.- Parameters:
src (
Array) – Source tensor to scatterindex (
Array) – Indices where to scatterdim_size (
int|None, default:None) – Size of the output dimension, inferred fromindexifNone(which requires a concreteindex)dim (
int, default:-2) – Dimension along which to scatterunbiased (
bool, default:True) – Whether to apply Bessel’s correction, i.e. divide bycount - 1instead ofcount
- Returns:
Array– Tensor with scattered standard deviations
Scatter standard deviation operation. Bessel’s correction is applied by default (
unbiased=True, dividing bycount - 1); passunbiased=Falsefor the population standard deviation.
scatter
- scatter(src: Array, index: Array, dim_size: int | None = None, dim: int = -2, reduce: str = 'add') Array[source]
Generic scatter operation using JAX’s optimized segment operations.
This function scatters values from src tensor at indices specified by index tensor, applying the specified reduction operation. Uses JAX’s built-in segment operations which are XLA-optimized for better performance on GPU/TPU.
- Parameters:
src (
Array) – Source tensor to scatter [N, *]index (
Array) – One-dimensional indices where to scatter [N], one per row ofsrcdim_size (
int|None, default:None) – Size of the output dimension, inferred fromindexifNone(which requires a concreteindex)dim (
int, default:-2) – Dimension along which to scatter (default: -2, which maps to 0)reduce (
str, default:'add') – Reduction operation - “add” (alias “sum”), “mean”, “max”, “min”
- Returns:
Array– Output tensor with scattered values [*, dim_size, *]
Generic scatter operation with configurable reduction.
Parameters:
src: Source tensor to scatter
index: Index tensor for scattering
dim: Dimension to scatter along
dim_size: Size of the output dimension
reduce: Reduction operation (‘add’, with ‘sum’ as an alias, ‘mean’, ‘max’, ‘min’). Any other value raises a
ValueError.
Graph Utilities
degree
- degree(index: Array, num_nodes: int | None = None, dtype: str | type | dtype | None = None) Array[source]
Computes the (unweighted) degree of a given one-dimensional index tensor.
- Parameters:
index (
Array) – Index tensor.num_nodes (
int|None, default:None) – The number of nodes, i.e. the maximum entry ofindexplus one. (default:None)dtype (
str|type|dtype|None, default:None) – The desired data type of the returned tensor; strings such as"int32"or"jnp.float16"are resolved withparse_dtype().
- Returns:
Array– Node degrees, one entry per node.
Example
>>> import jax.numpy as jnp >>> row = jnp.array([0, 1, 0, 2, 0]) >>> degree(row, dtype=jnp.int32) Array([3, 1, 1], dtype=int32)
Compute the degree of each node in a graph.
Example:
from jraphx.utils import degree import jax.numpy as jnp edge_index = jnp.array([[0, 1, 2], [1, 2, 0]]) # Compute in-degree and out-degree in_deg = degree(edge_index[1], num_nodes=3) out_deg = degree(edge_index[0], num_nodes=3)
parse_dtype
- parse_dtype(dtype: str | type | dtype) type[source]
Resolve a dtype spec to the matching jax.numpy scalar type (e.g.
jnp.float32).- Parameters:
dtype (
str|type|dtype) – A string naming a jax.numpy dtype, with or without ajnp./jax.numpy./np./numpy.prefix ("float32","jnp.bfloat16","int32", …); an already-resolved scalar type such asjnp.float32; or ajax.numpy.dtype/numpy.dtypeobject. Non-string dtypes are normalized to the jax.numpy scalar type. The Python builtinsfloatandintare rejected – name the width explicitly.- Returns:
type– The matching jax.numpy scalar type, e.g.jnp.float32.- Raises:
TypeError – If
dtypeis neither a string nor a dtype-like value.ValueError – If
dtypedoes not name a concrete jax.numpy dtype. Abstract categories such as"floating"or"integer"are rejected here rather than failing later at the first array construction.
Resolve a dtype spec – a plain or prefixed string, a scalar type, or a dtype object – to the matching jax.numpy scalar type. Every jraphx
dtypeargument accepts these specs, so a dtype can come straight from a configuration file.Example:
from jraphx.utils import degree, parse_dtype import jax.numpy as jnp assert parse_dtype("float32") is jnp.float32 assert parse_dtype("jnp.bfloat16") is jnp.bfloat16 edge_index = jnp.array([[0, 1, 2], [1, 2, 0]]) deg = degree(edge_index[1], num_nodes=3, dtype="int32")
to_undirected
- to_undirected(edge_index: Array, edge_attr: Array | None = None, num_nodes: int | None = None, reduce: str = 'add') tuple[Array, Array | None][source]
Converts the graph given by
edge_indexto an undirected graph such that \((j,i) \in \mathcal{E}\) for every edge \((i,j) \in \mathcal{E}\).The result is coalesced: the edge list is row-wise sorted, duplicated edges appear once, and their features are merged with
reduce.- Parameters:
edge_index (
Array) – The edge indices.edge_attr (
Array|None, default:None) – Edge weights or multi-dimensional edge features. (default:None)num_nodes (
int|None, default:None) – The number of nodes, i.e.max_val + 1ofedge_index. (default:None)reduce (
str, default:'add') – The reduce operation to use for merging edge features ("add"/"sum","mean","min","max"). (default:"add")
- Returns:
tuple[Array,Array|None] – Tuple of (undirected edge_index, undirected edge_attr).
Note
The number of unique edges is data-dependent, so this function cannot be traced by
jax.jit.Convert a directed graph to undirected by adding reverse edges. The result is coalesced: the edge list is row-wise sorted, duplicated edges appear once, and their features are merged with
reduce. The number of resulting edges is data-dependent, so this function cannot be traced byjax.jit().Example:
from jraphx.utils import to_undirected import jax.numpy as jnp edge_index = jnp.array([[0, 1], [1, 2]]) edge_attr = jnp.array([[1.0], [2.0]]) # Convert to undirected edge_index_undirected, edge_attr_undirected = to_undirected( edge_index, edge_attr )
add_self_loops
- add_self_loops(edge_index: Array, edge_attr: Array | None = None, fill_value: float | str = 1.0, num_nodes: int | None = None) tuple[Array, Array | None][source]
Adds a self-loop \((i,i) \in \mathcal{E}\) to every node \(i \in \mathcal{V}\) in the graph given by
edge_index. In case the graph is weighted or has multi-dimensional edge features (edge_attris notNone), edge features of self-loops will be added according tofill_value. One self-loop is appended per node unconditionally, so a node that already has a self-loop ends up with two; useadd_remaining_self_loops()to add only the missing ones.- Parameters:
edge_index (
Array) – The edge indices.edge_attr (
Array|None, default:None) – Edge weights or multi-dimensional edge features. (default:None)fill_value (
Union[float,str], default:1.0) – The way to generate edge features of self-loops. If float, edge features are set to this value. If str, edge features are computed by aggregating existing edge features that point to each node using the specified reduction (‘mean’, ‘add’ (alias ‘sum’), ‘max’, ‘min’). (default:1.0)num_nodes (
int|None, default:None) – The number of nodes, i.e.max_val + 1ofedge_index. (default:None)
- Returns:
tuple[Array,Array|None] – Tuple of (edge_index with self-loops, edge_attr with self-loops).
Note
The output shape depends on
num_nodes, so it must be given as a static integer underjax.jit. Inferring it fromedge_indexreads the array on the host.Add self-loop edges to a graph.
Example:
from jraphx.utils import add_self_loops import jax.numpy as jnp edge_index = jnp.array([[0, 1], [1, 2]]) # Add self-loops edge_index_with_loops, edge_attr = add_self_loops( edge_index, num_nodes=3 )
remove_self_loops
- remove_self_loops(edge_index: Array, edge_attr: Array | None = None) tuple[Array, Array | None][source]
Remove self-loops from edge indices.
- Parameters:
edge_index (
Array) – Edge indices [2, num_edges]edge_attr (
Array|None, default:None) – Optional edge attributes [num_edges, *]
- Returns:
tuple[Array,Array|None] – Tuple of (edge_index without self-loops, edge_attr without self-loops)
Remove self-loop edges from a graph.
coalesce
- coalesce(edge_index: Array, edge_attr: Array | None = None, num_nodes: int | None = None, reduce: str = 'add') tuple[Array, Array | None][source]
Row-wise sorts
edge_indexand removes its duplicated entries. Duplicate entries inedge_attrare merged by scattering them together according to the givenreduceoption.- Parameters:
edge_index (
Array) – The edge indices.edge_attr (
Array|None, default:None) – Edge weights or multi-dimensional edge features. (default:None)num_nodes (
int|None, default:None) – The number of nodes, i.e.max_val + 1ofedge_index. Used only to validateedge_index. (default:None)reduce (
str, default:'add') – The reduce operation to use for merging edge features ("add"/"sum","mean","min","max"). (default:"add")
- Returns:
tuple[Array,Array|None] – Tuple of (coalesced edge_index, coalesced edge_attr).- Raises:
ValueError – If
edge_indexaddresses a node outside ofnum_nodes.
Note
The number of unique edges is data-dependent, so this function cannot be traced by
jax.jit.Remove duplicate edges and optionally sum their attributes.
Example:
from jraphx.utils import coalesce import jax.numpy as jnp # Graph with duplicate edges edge_index = jnp.array([[0, 0, 1], [1, 1, 2]]) edge_attr = jnp.array([[1.0], [2.0], [3.0]]) # Remove duplicates and sum attributes edge_index_clean, edge_attr_clean = coalesce( edge_index, edge_attr, reduce='sum' )
Conversion Utilities
to_dense_adj
- to_dense_adj(edge_index: Array, edge_attr: Array | None = None, max_num_nodes: int | None = None) Array[source]
Convert edge indices to dense adjacency matrix.
Parallel edges are accumulated, so a duplicated edge contributes the sum of its attributes (or its multiplicity when
edge_attrisNone).- Parameters:
edge_index (
Array) – Edge indices [2, num_edges]edge_attr (
Array|None, default:None) – Optional edge attributes [num_edges] or [num_edges, num_features]max_num_nodes (
int|None, default:None) – Number of nodes of the dense output. Inferred fromedge_indexwhenNone, which requires a concreteedge_index.
- Returns:
Array– Dense adjacency matrix [num_nodes, num_nodes] or [num_nodes, num_nodes, num_features]
Convert edge indices to a dense adjacency matrix.
Example:
from jraphx.utils import to_dense_adj import jax.numpy as jnp edge_index = jnp.array([[0, 1, 2], [1, 2, 0]]) # Convert to dense adjacency matrix adj = to_dense_adj(edge_index, max_num_nodes=3)
to_edge_index
- to_edge_index(adj: Array) tuple[Array, Array][source]
Convert adjacency matrix to edge indices.
An edge is emitted for every entry that is non-zero (for a feature tensor, for every entry with at least one non-zero feature), and its stored value is always returned as the edge attribute.
- Parameters:
adj (
Array) – Adjacency matrix [num_nodes, num_nodes] or [num_nodes, num_nodes, num_features]- Returns:
tuple[Array,Array] – Tuple of (edge_index [2, num_edges], edge_attr [num_edges] or [num_edges, num_features])
Note
The number of edges is data-dependent, so this function cannot be traced by
jax.jit.Convert adjacency representation to edge index format. Returns a
(edge_index, edge_attr)tuple; the stored value of every non-zero entry is always returned as the edge attribute.