pyhgf: A neural network library for predictive coding.
The 4 matches · 1 of them tie a paragraph to a whole file, not to given lines: a weak match, whose lines are not tinted
- [1] § 2 Design and implementation › 2.2 Optimisation and inference ↔ dynamax/ssm.py, lines 37–89 · score 0.63 · gradient descent, state space, maximizing, easily, likelihood, smoothly
- [2] § 2 Design and implementation › 2.1 Computational framework ↔ pyhgf/updates/posterior/continuous/posterior_update_mean_continuous_node.py, lines 10–94 · score 0.54 · field approximations, parent nodes, adjacent, prediction error, linear, child
- [3] § 2 Design and implementation › 2.2 Optimisation and inference ↔ pyhgf/model/network.py, lines 80–149 · score 0.51 · HGF toolbox, NUTS, neural network, space, backend, optimisation
- [4] § 2 Design and implementation › 2.1 Computational framework ↔ pyhgf/utils/beliefs_propagation.py, the whole file · a weak match · score 0.50 · belief propagation, Update sequences, posterior updates, roots, transformations, prediction errors
Paper
Loaded from Europe PMC by your browser, not stored by OSCR: doi.org · Europe PMC
The paper is loaded when this pane is shown.
The authors' code
Python · 506 lines · 20 KB · MIT · 1 match
- """
- Base classes for state space models (SSMs).
- """
- import jax.numpy as jnp
- import jax.random as jr
- import optax
- from abc import ABC
- from abc import abstractmethod
- from fastprogress.fastprogress import progress_bar
- from functools import partial
- from jax import jit, lax, vmap
- from jax.tree_util import tree_map
- from jaxtyping import Array, Float, Real
- from numbers import Integral
- from tensorflow_probability.substrates.jax import distributions as tfd
- from typing import Optional, Union, Tuple, Any, runtime_checkable
- from typing_extensions import Protocol
- from dynamax.parameters import to_unconstrained, from_unconstrained
- from dynamax.parameters import ParameterSet, PropertySet
- from dynamax.types import PRNGKeyT, Scalar
- from dynamax.utils.optimize import run_sgd
- from dynamax.utils.utils import ensure_array_has_batch_dim
- @runtime_checkable
- class Posterior(Protocol):
- """A :class:`NamedTuple` with parameters stored as :class:`jax.DeviceArray` in the leaf nodes."""
- pass
- @runtime_checkable
- class SuffStatsSSM(Protocol):
- """A :class:`NamedTuple` with sufficient statics stored as :class:`jax.DeviceArray` in the leaf nodes."""
- pass
- class SSM(ABC):
- r"""A base class for state space models. Such models consist of parameters, which
- we may learn, as well as hyperparameters, which specify static properties of the
- model. This base class allows parameters to be indicated a standardized way
- so that they can easily be converted to/from unconstrained form for optimization.
- **Abstract Methods**
- Models that inherit from `SSM` must implement a few key functions and properties:
- * :meth:`initial_distribution` returns the distribution over the initial state given parameters
- * :meth:`transition_distribution` returns the conditional distribution over the next state given the current state and parameters
- * :meth:`emission_distribution` returns the conditional distribution over the emission given the current state and parameters
- * :meth:`log_prior` (optional) returns the log prior probability of the parameters
- * :attr:`emission_shape` returns a tuple specification of the emission shape
- * :attr:`inputs_shape` returns a tuple specification of the input shape, or `None` if there are no inputs.
- The shape properties are required for properly handling batches of data.
- **Sampling and Computing Log Probabilities**
- Once these have been implemented, subclasses will inherit the ability to sample
- and compute log joint probabilities from the base class functions:
- * :meth:`sample` draws samples of the states and emissions for given parameters
- * :meth:`log_prob` computes the log joint probability of the states and emissions for given parameters
- **Inference**
- Many subclasses of SSMs expose basic functions for performing state inference.
- * :meth:`marginal_log_prob` computes the marginal log probability of the emissions, summing over latent states
- * :meth:`filter` computes the filtered posteriors
- * :meth:`smoother` computes the smoothed posteriors
- **Learning**
- Likewise, many SSMs will support learning with expectation-maximization (EM) or stochastic gradient descent (SGD).
- For expectation-maximization, subclasses must implement the E- and M-steps.
- * :meth:`e_step` computes the expected sufficient statistics for a sequence of emissions, given parameters
- * :meth:`m_step` finds new parameters that maximize the expected log joint probability
- Once these are implemented, the generic SSM class allows to fit the model with EM
- * :meth:`fit_em` run EM to find parameters that maximize the likelihood (or posterior) probability.
- For SGD, any subclass that implements :meth:`marginal_log_prob` inherits the base class fitting function
- * :meth:`fit_sgd` run SGD to minimize the *negative* marginal log probability.
- """
- @abstractmethod
- def initial_distribution(
- self,
- params: ParameterSet,
- inputs: Optional[Float[Array, " input_dim"]]
- ) -> tfd.Distribution:
- r"""Return an initial distribution over latent states.
- Args:
- params: model parameters $\theta$
- inputs: optional inputs $u_t$
- Returns:
- distribution over initial latent state, $p(z_1 \mid \theta)$.
- """
- raise NotImplementedError
- @abstractmethod
- def transition_distribution(
- self,
- params: ParameterSet,
- state: Float[Array, " state_dim"],
- inputs: Optional[Float[Array, " input_dim"]]
- ) -> tfd.Distribution:
- r"""Return a distribution over next latent state given current state.
- Args:
- params: model parameters $\theta$
- state: current latent state $z_t$
- inputs: current inputs $u_t$
- Returns:
- conditional distribution of next latent state $p(z_{t+1} \mid z_t, u_t, \theta)$.
- """
- raise NotImplementedError
- @abstractmethod
- def emission_distribution(
- self,
- params: ParameterSet,
- state: Float[Array, " state_dim"],
- inputs: Optional[Float[Array, " input_dim"]]=None
- ) -> tfd.Distribution:
- r"""Return a distribution over emissions given current state.
- Args:
- params: model parameters $\theta$
- state: current latent state $z_t$
- inputs: current inputs $u_t$
- Returns:
- conditional distribution of current emission $p(y_t \mid z_t, u_t, \theta)$
- """
- raise NotImplementedError
- def log_prior(
- self,
- params: ParameterSet
- ) -> Scalar:
- r"""Return the log prior probability of any model parameters.
- Returns:
- lp (Scalar): log prior probability.
- """
- return 0.0
- @property
- @abstractmethod
- def emission_shape(self) -> Tuple[int]:
- r"""Return a pytree matching the pytree of tuples specifying the shape of a single time step's emissions.
- For example, a `GaussianHMM` with $D$ dimensional emissions would return `(D,)`.
- """
- raise NotImplementedError
- @property
- def inputs_shape(self) -> Optional[Tuple[int]]:
- r"""Return a pytree matching the pytree of tuples specifying the shape of a single time step's inputs.
- """
- return None
- # All SSMs support sampling
- def sample(
- self,
- params: ParameterSet,
- key: PRNGKeyT,
- num_timesteps: int,
- inputs: Optional[Float[Array, "num_timesteps input_dim"]]=None
- ) -> Tuple[Float[Array, "num_timesteps state_dim"],
- Float[Array, "num_timesteps emission_dim"]]:
- r"""Sample states $z_{1:T}$ and emissions $y_{1:T}$ given parameters $\theta$ and (optionally) inputs $u_{1:T}$.
- Args:
- params: model parameters $\theta$
- key: random number generator
- num_timesteps: number of timesteps $T$
- inputs: inputs $u_{1:T}$
- Returns:
- latent states and emissions
- """
- def _step(prev_state, args):
- """Sample the next state and emission given the previous state and input."""
- key, inpt = args
- key1, key2 = jr.split(key, 2)
- state = self.transition_distribution(params, prev_state, inpt).sample(seed=key2)
- emission = self.emission_distribution(params, state, inpt).sample(seed=key1)
- return state, (state, emission)
- # Sample the initial state
- key1, key2, key = jr.split(key, 3)
- initial_input = tree_map(lambda x: x[0], inputs)
- initial_state = self.initial_distribution(params, initial_input).sample(seed=key1)
- initial_emission = self.emission_distribution(params, initial_state, initial_input).sample(seed=key2)
- # Sample the remaining emissions and states
- next_keys = jr.split(key, num_timesteps - 1)
- next_inputs = tree_map(lambda x: x[1:], inputs)
- _, (next_states, next_emissions) = lax.scan(_step, initial_state, (next_keys, next_inputs))
- # Concatenate the initial state and emission with the following ones
- expand_and_cat = lambda x0, x1T: jnp.concatenate((jnp.expand_dims(x0, 0), x1T))
- states = tree_map(expand_and_cat, initial_state, next_states)
- emissions = tree_map(expand_and_cat, initial_emission, next_emissions)
- return states, emissions
- def log_prob(
- self,
- params: ParameterSet,
- states: Float[Array, "num_timesteps state_dim"],
- emissions: Float[Array, "num_timesteps emission_dim"],
- inputs: Optional[Float[Array, "num_timesteps input_dim"]]=None
- ) -> Scalar:
- r"""Compute the log joint probability of the states and observations"""
- def _step(carry, args):
- """Compute the log probability of the next time step."""
- lp, prev_state = carry
- state, emission, inpt = args
- lp += self.transition_distribution(params, prev_state, inpt).log_prob(state)
- lp += self.emission_distribution(params, state, inpt).log_prob(emission)
- return (lp, state), None
- # Compute log prob of initial time step
- initial_state = tree_map(lambda x: x[0], states)
- initial_emission = tree_map(lambda x: x[0], emissions)
- initial_input = tree_map(lambda x: x[0], inputs)
- lp = self.initial_distribution(params, initial_input).log_prob(initial_state)
- lp += self.emission_distribution(params, initial_state, initial_input).log_prob(initial_emission)
- # Scan over remaining time steps
- next_states = tree_map(lambda x: x[1:], states)
- next_emissions = tree_map(lambda x: x[1:], emissions)
- next_inputs = tree_map(lambda x: x[1:], inputs)
- (lp, _), _ = lax.scan(_step, (lp, initial_state), (next_states, next_emissions, next_inputs))
- return lp
- # Some SSMs will implement these inference functions.
- def marginal_log_prob(
- self,
- params: ParameterSet,
- emissions: Float[Array, "ntime emission_dim"],
- inputs: Optional[Float[Array, "ntime input_dim"]]=None
- ) -> Scalar:
- r"""Compute log marginal likelihood of observations, $\log \sum_{z_{1:T}} p(y_{1:T}, z_{1:T} \mid \theta)$.
- Args:
- params: model parameters $\theta$
- state: current latent state $z_t$
- inputs: current inputs $u_t$
- Returns:
- marginal log probability
- """
- raise NotImplementedError
- def filter(
- self,
- params: ParameterSet,
- emissions: Float[Array, "ntime emission_dim"],
- inputs: Optional[Float[Array, "ntime input_dim"]]=None
- ) -> Posterior:
- r"""Compute filtering distributions, $p(z_t \mid y_{1:t}, u_{1:t}, \theta)$ for $t=1,\ldots,T$.
- Args:
- params: model parameters $\theta$
- state: current latent state $z_t$
- inputs: current inputs $u_t$
- Returns:
- filtering distributions
- """
- raise NotImplementedError
- def smoother(
- self,
- params: ParameterSet,
- emissions: Float[Array, "ntime emission_dim"],
- inputs: Optional[Float[Array, "ntime input_dim"]]=None
- ) -> Posterior:
- r"""Compute smoothing distribution, $p(z_t \mid y_{1:T}, u_{1:T}, \theta)$ for $t=1,\ldots,T$.
- Args:
- params: model parameters $\theta$
- state: current latent state $z_t$
- inputs: current inputs $u_t$
- Returns:
- smoothing distributions
- """
- raise NotImplementedError
- # Learning algorithms
- def e_step(
- self,
- params: ParameterSet,
- emissions: Float[Array, "num_timesteps emission_dim"],
- inputs: Optional[Float[Array, "num_timesteps input_dim"]]=None
- ) -> Tuple[SuffStatsSSM, Scalar]:
- r"""Perform an E-step to compute expected sufficient statistics under the posterior, $p(z_{1:T} \mid y_{1:T}, u_{1:T}, \theta)$.
- Args:
- params: model parameters $\theta$
- emissions: emissions $y_{1:T}$
- inputs: optional inputs $u_{1:T}$
- Returns:
- Expected sufficient statistics under the posterior.
- """
- raise NotImplementedError
- def m_step(
- self,
- params: ParameterSet,
- props: PropertySet,
- batch_stats: SuffStatsSSM,
- m_step_state: Any
- ) -> ParameterSet:
- r"""Perform an M-step to find parameters that maximize the expected log joint probability.
- Specifically, compute
- $$\theta^\star = \mathrm{argmax}_\theta \; \mathbb{E}_{p(z_{1:T} \mid y_{1:T}, u_{1:T}, \theta)} \big[\log p(y_{1:T}, z_{1:T}, \theta \mid u_{1:T}) \big]$$
- Args:
- params: model parameters $\theta$
- props: properties specifying which parameters should be learned
- batch_stats: sufficient statistics from each sequence
- m_step_state: any required state for optimizing the model parameters.
- Returns:
- new parameters
- """
- raise NotImplementedError
- def fit_em(
- self,
- params: ParameterSet,
- props: PropertySet,
- emissions: Union[Real[Array, "num_timesteps emission_dim"],
- Real[Array, "num_batches num_timesteps emission_dim"]],
- inputs: Optional[Union[Float[Array, "num_timesteps input_dim"],
- Float[Array, "num_batches num_timesteps input_dim"]]]=None,
- num_iters: int=50,
- verbose: bool=True,
- print_every: int=1,
- ) -> Tuple[ParameterSet, Float[Array, " num_iters"]]:
- r"""Compute parameter MLE/ MAP estimate using Expectation-Maximization (EM).
- EM aims to find parameters that maximize the marginal log probability,
- $$\theta^\star = \mathrm{argmax}_\theta \; \log p(y_{1:T}, \theta \mid u_{1:T})$$
- It does so by iteratively forming a lower bound (the "E-step") and then maximizing it (the "M-step").
- *Note:* ``emissions`` *and* ``inputs`` *can either be single sequences or batches of sequences.*
- Args:
- params: model parameters $\theta$. Parameters you supply yourself must have the
- same shapes and dtypes that ``initialize`` produces.
- props: properties specifying which parameters should be learned
- emissions: one or more sequences of emissions
- inputs: one or more sequences of corresponding inputs
- num_iters: number of iterations of EM to run
- verbose: whether or not to show a progress bar. Use ``False`` when calling
- ``fit_em`` inside ``jit`` or ``vmap``.
- print_every: number of EM iterations between progress bar updates. Ignored when
- ``verbose=False``.
- Returns:
- tuple of new parameters and log likelihoods over the course of EM iterations.
- """
- # Make sure the emissions and inputs have batch dimensions
- batch_emissions = ensure_array_has_batch_dim(emissions, self.emission_shape)
- batch_inputs = ensure_array_has_batch_dim(inputs, self.inputs_shape)
- def em_step(carry, _):
- """Perform one EM step."""
- params, m_step_state = carry
- batch_stats, lls = vmap(partial(self.e_step, params))(batch_emissions, batch_inputs)
- lp = self.log_prior(params) + lls.sum()
- params, m_step_state = self.m_step(params, props, batch_stats, m_step_state)
- return (params, m_step_state), lp
- @partial(jit, static_argnums=1)
- def run_em(carry, num_steps):
- """Run `num_steps` EM steps."""
- return lax.scan(em_step, carry, xs=None, length=num_steps)
- if num_iters <= 0:
- return params, jnp.array([])
- # The scan carries (params, m_step_state), so their structure, shapes and dtypes must
- # not change between iterations; initialize() produces parameters that match the M-step.
- carry = (params, self.initialize_m_step_state(params, props))
- if not verbose:
- (params, _), log_probs = run_em(carry, num_iters)
- return params, log_probs
- if not isinstance(print_every, Integral) or print_every < 1:
- raise ValueError(f"print_every must be a positive integer, got {print_every!r}")
- # Run `print_every` iterations per dispatch and update the bar in between. The bar counts
- # dispatched blocks without waiting for the device, so it can run ahead of the computation.
- log_probs = []
- pbar = progress_bar(range(num_iters))
- pbar.update(0)
- for start in range(0, num_iters, print_every):
- num_steps = min(print_every, num_iters - start)
- carry, chunk_log_probs = run_em(carry, num_steps)
- log_probs.append(chunk_log_probs)
- pbar.update(start + num_steps)
- return carry[0], jnp.concatenate(log_probs)
- def fit_sgd(
- self,
- params: ParameterSet,
- props: PropertySet,
- emissions: Union[Float[Array, "num_timesteps emission_dim"],
- Float[Array, "num_batches num_timesteps emission_dim"]],
- inputs: Optional[Union[Float[Array, "num_timesteps input_dim"],
- Float[Array, "num_batches num_timesteps input_dim"]]]=None,
- optimizer: optax.GradientTransformation=optax.adam(1e-3),
- batch_size: int=1,
- num_epochs: int=50,
- shuffle: bool=False,
- key: PRNGKeyT=jr.PRNGKey(0)
- ) -> Tuple[ParameterSet, Float[Array, " niter"]]:
- r"""Compute parameter MLE/ MAP estimate using Stochastic Gradient Descent (SGD).
- SGD aims to find parameters that maximize the marginal log probability,
- $$\theta^\star = \mathrm{argmax}_\theta \; \log p(y_{1:T}, \theta \mid u_{1:T})$$
- by minimizing the _negative_ of that quantity.
- *Note:* ``emissions`` *and* ``inputs`` *can either be single sequences or batches of sequences.*
- On each iteration, the algorithm grabs a *minibatch* of sequences and takes a gradient step.
- One pass through the entire set of sequences is called an *epoch*.
- Args:
- params: model parameters $\theta$
- props: properties specifying which parameters should be learned
- emissions: one or more sequences of emissions
- inputs: one or more sequences of corresponding inputs
- optimizer: an `optax` optimizer for minimization
- batch_size: number of sequences per minibatch
- num_epochs: number of epochs of SGD to run
- key: a random number generator for selecting minibatches
- verbose: whether or not to show a progress bar
- Returns:
- tuple of new parameters and losses (negative scaled marginal log probs) over the course of SGD iterations.
- """
- # Make sure the emissions and inputs have batch dimensions
- batch_emissions = ensure_array_has_batch_dim(emissions, self.emission_shape)
- batch_inputs = ensure_array_has_batch_dim(inputs, self.inputs_shape)
- unc_params = to_unconstrained(params, props)
- def _loss_fn(unc_params, minibatch):
- """Default objective function."""
- params = from_unconstrained(unc_params, props)
- minibatch_emissions, minibatch_inputs = minibatch
- scale = len(batch_emissions) / len(minibatch_emissions)
- minibatch_lls = vmap(partial(self.marginal_log_prob, params))(minibatch_emissions, minibatch_inputs)
- lp = self.log_prior(params) + minibatch_lls.sum() * scale
- return -lp / batch_emissions.size
- dataset = (batch_emissions, batch_inputs)
- unc_params, losses = run_sgd(_loss_fn,
- unc_params,
- dataset,
- optimizer=optimizer,
- batch_size=batch_size,
- num_epochs=num_epochs,
- shuffle=shuffle,
- key=key)
- params = from_unconstrained(unc_params, props)
- return params, losses
ssm.py at commit b58635f, under MIT · at the source
Overview
- Interacting Minds Centre, Aarhus University, Aarhus, Denmark
- Department of Psychiatry, University of Oxford, Oxford, United Kingdom
- Scuola Internazionale Superiore di Studi Avanzati (SISSA), Trieste, Italy
Abstract
Bayesian models of cognition have gained considerable traction in computational neuroscience and psychiatry. Their scope is now expected to expand rapidly to artificial intelligence, providing general inference frameworks to support embodied, adaptable, and energy-efficient autonomous agents. A central theory in this domain is predictive coding, which posits that learning and behaviour are driven by hierarchical probabilistic inferences about the causes of sensory inputs. Biological realism constrains these networks to rely on simple local computations in the form of precision-weighted predictions and prediction errors. This can make this framework highly efficient, but its implementation comes with unique challenges on the software development side. Embedding such models in standard neural network libraries often becomes limiting, as these libraries’ compilation and differentiation backends can force a conceptual separation between optimisation algorithms and the systems being optimised. This critically departs from other biological principles such as self-monitoring, self-organisation, cellular growth, and functional plasticity. In this paper, we introduce pyhgf: a Python package backed by JAX and Rust for creating, manipulating, and sampling dynamic networks for predictive coding. We improve over other frameworks by enclosing the network components as transparent, modular, and malleable variables in the message-passing steps. The resulting graphs can implement arbitrary algorithms as belief propagation. Moreover, the transparency of core variables can also translate into inference processes that leverage self-organisation principles and express structure learning, meta-learning, or causal discovery as the consequence of network structural adaptation to surprising inputs. The main functions of the library are differentiable and seamlessly integrate into sampling or optimisation workflows. Additionally, we offer generalised Bayesian filtering and the hierarchical Gaussian filter as key examples of dynamic networks implemented in our library. The source code, tutorials, and documentation are hosted under the main repository at https://
Reproduced under the paper's license (CC BY), from the paper cited above.
Repositories
Its files are read in the Code ↔ Paper reader above, with 4 matches between paragraphs and lines of code.
ComputationalPsychiatry/pyhgf
2b4bf6772f990b0595a63b8fc740d07cbfe71e44, 25 September 2026Availability: 1 check, the latest on 27 September 2026: the link answers
- 27 September 2026: the link answers
197 files
- build.rs, Rust, 6 lines
- docs/
paper.ipynb , Jupyter, 715 lines - docs/
readme.ipynb , Jupyter, 38 lines - docs/
source/ , Python, 150 linesconf.py - docs/
source/ , Jupyter, 391 linesnotebooks/ 0.1-Theory.ipynb - docs/
source/ , Jupyter, 445 linesnotebooks/ 0.2-Creating_networks.ip ynb - docs/
source/ , Jupyter, 509 linesnotebooks/ 0.3-Generalised_filterin g.ipynb - docs/
source/ , Jupyter, 217 linesnotebooks/ 0.4-Planning_and_acting. ipynb - docs/
source/ , Jupyter, 400 linesnotebooks/ 0.5-Deep_networks_theory .ipynb - docs/
source/ , Jupyter, 875 linesnotebooks/ 0.6-Prospective_configur ation.ipynb - docs/
source/ , Jupyter, 192 linesnotebooks/ 0.7-Deep_networks_implem entation.ipynb - docs/
source/ , Jupyter, 504 linesnotebooks/ 0.8-Convolutional_networ ks.ipynb - docs/
source/ , Jupyter, 526 linesnotebooks/ 0.9-Transformers.ipynb - docs/
source/ , Jupyter, 305 linesnotebooks/ 1.1-Binary_HGF.ipynb - docs/
source/ , Jupyter, 269 linesnotebooks/ 1.2-Categorical_HGF.ipyn b - docs/
source/ , Jupyter, 406 linesnotebooks/ 1.3-Continuous_HGF.ipynb - docs/
source/ , Jupyter, 262 linesnotebooks/ 2-Using_custom_response_ functions.ipynb - docs/
source/ , Jupyter, 297 linesnotebooks/ 3-Multilevel_HGF.ipynb - docs/
source/ , Jupyter, 200 linesnotebooks/ 4-Parameter_recovery.ipy nb - docs/
source/ , Jupyter, 357 linesnotebooks/ 5-Non_linear_value_coupl ing.ipynb - docs/
source/ , Jupyter, 119 linesnotebooks/ Example_1_Heart_rate_var iability.ipynb - docs/
source/ , Jupyter, 128 linesnotebooks/ Example_2_Input_node_vol atility_coupling.ipynb - docs/
source/ , Jupyter, 461 linesnotebooks/ Example_3_Multi_armed_ba ndit.ipynb - docs/
source/ , Jupyter, 485 linesnotebooks/ Example_4_Causal_discove ry.ipynb - docs/
source/ , Jupyter, 741 linesnotebooks/ Example_5_Iowa_Gambling_ Task.ipynb - docs/
source/ , Jupyter, 373 linesnotebooks/ Exercise_1_Introduction_ to_the_generalised_hiera rchical_gaussian_filter. ipynb - docs/
source/ , Jupyter, 607 linesnotebooks/ Exercise_2_Bayesian_rein forcement_learning.ipynb - pyhgf/
__init__.py , Python, 179 lines - pyhgf/
distribution.py , Python, 66 lines - pyhgf/
math.py , Python, 498 lines - pyhgf/
model/ , Python, 87 lines__init__.py - pyhgf/
model/ , Python, 720 linesadd_nodes.py - pyhgf/
model/ , Python, 173 linesbuilder.py - pyhgf/
model/ , Python, 476 linesconv.py - pyhgf/
model/ , Python, 2,068 linesdeep_network.py - pyhgf/
model/ , Python, 186 lineserror_types.py - pyhgf/
model/ , Python, 591 linesfused.py - pyhgf/
model/ , Python, 30 lineshgf.py - pyhgf/
model/ , Python, 407 lineshybrid.py - pyhgf/
model/ , Python, 774 lines, 1 matchnetwork.py - pyhgf/
model/ , Python, 312 linestransformer.py - pyhgf/
model/ , Python, 333 linestransplant.py - pyhgf/
plots/ , Python, 1 line__init__.py - pyhgf/
plots/ , Python, 10 linesgraphviz/ __init__.py - pyhgf/
plots/ , Python, 223 linesgraphviz/ plot_network.py - pyhgf/
plots/ , Python, 13 linesmatplotlib/ __init__.py - pyhgf/
plots/ , Python, 57 linesmatplotlib/ plot_correlations.py - pyhgf/
plots/ , Python, 228 linesmatplotlib/ plot_layers.py - pyhgf/
plots/ , Python, 285 linesmatplotlib/ plot_nodes.py - pyhgf/
plots/ , Python, 87 linesmatplotlib/ plot_samples.py - pyhgf/
plots/ , Python, 175 linesmatplotlib/ plot_trajectories.py - pyhgf/
plots/ , Python, 5 linesnetworkx/ __init__.py - pyhgf/
plots/ , Python, 202 linesnetworkx/ plot_network.py - pyhgf/
response.py , Python, 215 lines - pyhgf/
typing/ , Python, 47 lines__init__.py - pyhgf/
typing/ , Python, 91 linestyping.py - pyhgf/
typing/ , Python, 542 linesvectorised.py - pyhgf/
updates/ , Python, 1 line__init__.py - pyhgf/
updates/ , Python, 38 linesobservation.py - pyhgf/
updates/ , Python, 1 lineposterior/ __init__.py - pyhgf/
updates/ , Python, 87 linesposterior/ categorical.py - pyhgf/
updates/ , Python, 19 linesposterior/ continuous/ __init__.py - pyhgf/
updates/ , Python, 128 linesposterior/ continuous/ continuous_node_posterio r_update.py - pyhgf/
updates/ , Python, 155 linesposterior/ continuous/ continuous_node_posterio r_update_ehgf.py - pyhgf/
updates/ , Python, 220 linesposterior/ continuous/ continuous_node_posterio r_update_unbounded.py - pyhgf/
updates/ , Python, 359 lines, 1 matchposterior/ continuous/ posterior_update_mean_co ntinuous_node.py - pyhgf/
updates/ , Python, 769 linesposterior/ continuous/ posterior_update_precisi on_continuous_node.py - pyhgf/
updates/ , Python, 81 linesposterior/ exponential.py - pyhgf/
updates/ , Python, 1 lineprediction/ __init__.py - pyhgf/
updates/ , Python, 93 linesprediction/ binary.py - pyhgf/
updates/ , Python, 570 linesprediction/ continuous.py - pyhgf/
updates/ , Python, 52 linesprediction/ dirichlet.py - pyhgf/
updates/ , Python, 1 lineprediction_error/ __init__.py - pyhgf/
updates/ , Python, 106 linesprediction_error/ binary.py - pyhgf/
updates/ , Python, 47 linesprediction_error/ categorical.py - pyhgf/
updates/ , Python, 176 linesprediction_error/ continuous.py - pyhgf/
updates/ , Python, 393 linesprediction_error/ dirichlet.py - pyhgf/
updates/ , Python, 120 linesprediction_error/ exponential.py - pyhgf/
updates/ , Python, 1 linevectorised/ __init__.py - pyhgf/
updates/ , Python, 12 linesvectorised/ binary/ __init__.py - pyhgf/
updates/ , Python, 99 linesvectorised/ binary/ prediction.py - pyhgf/
updates/ , Python, 51 linesvectorised/ binary/ prediction_error.py - pyhgf/
updates/ , Python, 11 linesvectorised/ categorical/ __init__.py - pyhgf/
updates/ , Python, 83 linesvectorised/ categorical/ prediction.py - pyhgf/
updates/ , Python, 44 linesvectorised/ categorical/ prediction_error.py - pyhgf/
updates/ , Python, 38 linesvectorised/ continuous/ __init__.py - pyhgf/
updates/ , Python, 657 linesvectorised/ continuous/ posterior.py - pyhgf/
updates/ , Python, 192 linesvectorised/ continuous/ prediction.py - pyhgf/
updates/ , Python, 95 linesvectorised/ continuous/ prediction_error.py - pyhgf/
updates/ , Python, 566 linesvectorised/ learning.py - pyhgf/
updates/ , Python, 37 linesvectorised/ volatile/ __init__.py - pyhgf/
updates/ , Python, 325 linesvectorised/ volatile/ posterior.py - pyhgf/
updates/ , Python, 413 linesvectorised/ volatile/ prediction.py - pyhgf/
updates/ , Python, 503 linesvectorised/ volatile/ prediction_error.py - pyhgf/
utils/ , Python, 26 lines__init__.py - pyhgf/
utils/ , Python, 176 linesadd_edges.py - pyhgf/
utils/ , Python, 78 linesadd_parent.py - pyhgf/
utils/ , Python, 159 lines, 1 matchbeliefs_propagation.py - pyhgf/
utils/ , Python, 81 linesfill_categorical_state_n ode.py - pyhgf/
utils/ , Python, 22 linesget_input_idxs.py - pyhgf/
utils/ , Python, 317 linesget_update_sequence.py - pyhgf/
utils/ , Python, 55 lineslist_branches.py - pyhgf/
utils/ , Python, 265 linesremove_node.py - pyhgf/
utils/ , Python, 116 linessample.py - pyhgf/
utils/ , Python, 42 linessample_node_distribution .py - pyhgf/
utils/ , Python, 114 linesto_pandas.py - pyhgf/
utils/ , Python, 2,035 linesvectorised_belief_propag ation.py - pyhgf/
utils/ , Python, 214 linesweight_initialisation.py - src/
lib.rs , Rust, 23 lines - src/
math.rs , Rust, 735 lines - src/
model/ , Rust, 795 linesdeep_network.rs - src/
model/ , Rust, 5 linesmod.rs - src/
model/ , Rust, 918 linesnetwork.rs - src/
optimiser.rs , Rust, 105 lines - src/
updates/ , Rust, 6 linesmod.rs - src/
updates/ , Rust, 4 linesnodalised/ mod.rs - src/
updates/ , Rust, 13 linesnodalised/ observations.rs - src/
updates/ , Rust, 652 linesnodalised/ posterior/ continuous.rs - src/
updates/ , Rust, 1 linenodalised/ posterior/ mod.rs - src/
updates/ , Rust, 26 linesnodalised/ prediction/ binary.rs - src/
updates/ , Rust, 243 linesnodalised/ prediction/ continuous.rs - src/
updates/ , Rust, 2 linesnodalised/ prediction/ mod.rs - src/
updates/ , Rust, 15 linesnodalised/ prediction_error/ binary.rs - src/
updates/ , Rust, 33 linesnodalised/ prediction_error/ continuous.rs - src/
updates/ , Rust, 18 linesnodalised/ prediction_error/ exponential.rs - src/
updates/ , Rust, 3 linesnodalised/ prediction_error/ mod.rs - src/
updates/ , Rust, 5 linesvectorised/ binary/ mod.rs - src/
updates/ , Rust, 38 linesvectorised/ binary/ prediction.rs - src/
updates/ , Rust, 14 linesvectorised/ binary/ prediction_error.rs - src/
updates/ , Rust, 5 linesvectorised/ categorical/ mod.rs - src/
updates/ , Rust, 35 linesvectorised/ categorical/ prediction.rs - src/
updates/ , Rust, 14 linesvectorised/ categorical/ prediction_error.rs - src/
updates/ , Rust, 136 linesvectorised/ learning.rs - src/
updates/ , Rust, 42 linesvectorised/ mod.rs - src/
updates/ , Rust, 30 linesvectorised/ volatile/ mod.rs - src/
updates/ , Rust, 135 linesvectorised/ volatile/ posterior.rs - src/
updates/ , Rust, 353 linesvectorised/ volatile/ prediction.rs - src/
updates/ , Rust, 397 linesvectorised/ volatile/ prediction_error.rs - src/
utils/ , Rust, 30 linesbeliefs_propagation.rs - src/
utils/ , Rust, 99 linesfunction_pointer.rs - src/
utils/ , Rust, 4 linesmod.rs - src/
utils/ , Rust, 242 linesset_sequence.rs - src/
utils/ , Rust, 294 linesweight_initialisation.rs - src/
vectorised/ , Rust, 824 linesbatched.rs - src/
vectorised/ , Rust, 749 lineslayer.rs - src/
vectorised/ , Rust, 60 linesmat.rs - src/
vectorised/ , Rust, 12 linesmod.rs - src/
vectorised/ , Rust, 1,237 linesnetwork.rs - src/
vectorised/ , Rust, 283 linesoptimiser.rs - tests/
conftest.py , Python, 8 lines - tests/
test_binary.py , Python, 124 lines - tests/
test_binary.rs , Rust, 252 lines - tests/
test_builder.py , Python, 376 lines - tests/
test_categorical.py , Python, 86 lines - tests/
test_continuous.py , Python, 172 lines - tests/
test_continuous.rs , Rust, 133 lines - tests/
test_conv.py , Python, 609 lines - tests/
test_deepnetwork.py , Python, 1,759 lines - tests/
test_distribution.py , Python, 13 lines - tests/
test_eqx_types.py , Python, 703 lines - tests/
test_error_types.py , Python, 276 lines - tests/
test_fused.py , Python, 277 lines - tests/
test_hybrid.py , Python, 205 lines - tests/
test_math.py , Python, 106 lines - tests/
test_model.py , Python, 360 lines - tests/
test_nodes/ , Python, 1 line__init__.py - tests/
test_nodes/ , Python, 150 linestest_binary.py - tests/
test_nodes/ , Python, 114 linestest_continuous.py - tests/
test_nodes/ , Python, 94 linestest_exponential_family. py - tests/
test_pcmodule_state.py , Python, 247 lines - tests/
test_plots/ , Python, 1 line__init__.py - tests/
test_plots/ , Python, 225 linesconftest.py - tests/
test_plots/ , Python, 29 linestest_plot_correlations.p y - tests/
test_plots/ , Python, 9 linestest_plot_deep_network.p y - tests/
test_plots/ , Python, 177 linestest_plot_layers.py - tests/
test_plots/ , Python, 36 linestest_plot_network.py - tests/
test_plots/ , Python, 29 linestest_plot_nodes.py - tests/
test_plots/ , Python, 31 linestest_plot_samples.py - tests/
test_plots/ , Python, 29 linestest_plot_trajectories.p y - tests/
test_responses.py , Python, 50 lines - tests/
test_rs_deepnetwork.py , Python, 671 lines - tests/
test_transformer.py , Python, 737 lines - tests/
test_transplant.py , Python, 172 lines - tests/
test_updates/ , Python, 1 line__init__.py - tests/
test_updates/ , Python, 1 lineposterior/ __init__.py - tests/
test_updates/ , Python, 99 linesposterior/ test_posterior_update_co ntinuous.py - tests/
test_updates/ , Python, 1 lineprediction/ __init__.py - tests/
test_updates/ , Python, 205 linesprediction/ test_autoconnection_stre ngth.py - tests/
test_updates/ , Python, 1 lineprediction_errors/ __init__.py - tests/
test_updates/ , Python, 54 linesprediction_errors/ test_dirichlet.py - tests/
test_utils.py , Python, 262 lines - tests/
test_vectorised_continuo , Python, 705 linesus.py - tests/
test_weight_belief.py , Python, 733 lines - tests/
test_weight_gradient.py , Python, 69 lines - tests/
test_xla_runtime.py , Python, 126 lines - LICENSE, License, 11 lines
- README.md, Text, 210 lines
probml/dynamax
b58635f7bca2d8f936c0d711df3a1ad45f64511c, 16 September 2026Availability: 1 check, the latest on 27 September 2026: the link answers
- 27 September 2026: the link answers
104 files
- docs/
conf.py , Python, 105 lines - docs/
notebooks/ , Jupyter, 411 linesgeneralized_gaussian_ssm / cmgf_logistic_regression _demo.ipynb - docs/
notebooks/ , Jupyter, 265 linesgeneralized_gaussian_ssm / cmgf_mlp_classification_ demo.ipynb - docs/
notebooks/ , Jupyter, 169 linesgeneralized_gaussian_ssm / cmgf_poisson_demo.ipynb - docs/
notebooks/ , Jupyter, 327 lineshmm/ autoregressive_hmm.ipynb - docs/
notebooks/ , Jupyter, 259 lineshmm/ casino_hmm_inference.ipy nb - docs/
notebooks/ , Jupyter, 279 lineshmm/ casino_hmm_learning.ipyn b - docs/
notebooks/ , Jupyter, 385 lineshmm/ custom_hmm.ipynb - docs/
notebooks/ , Jupyter, 311 lineshmm/ gaussian_hmm.ipynb - docs/
notebooks/ , Jupyter, 140 lineslinear_gaussian_ssm/ kf_linreg.ipynb - docs/
notebooks/ , Jupyter, 303 lineslinear_gaussian_ssm/ kf_tracking.ipynb - docs/
notebooks/ , Jupyter, 367 lineslinear_gaussian_ssm/ lgssm_hmc.ipynb - docs/
notebooks/ , Jupyter, 286 lineslinear_gaussian_ssm/ lgssm_learning.ipynb - docs/
notebooks/ , Jupyter, 174 lineslinear_gaussian_ssm/ lgssm_parallel_inference .ipynb - docs/
notebooks/ , Jupyter, 246 linesnonlinear_gaussian_ssm/ ekf_mlp.ipynb - docs/
notebooks/ , Jupyter, 287 linesnonlinear_gaussian_ssm/ ekf_ukf_pendulum.ipynb - docs/
notebooks/ , Jupyter, 204 linesnonlinear_gaussian_ssm/ ekf_ukf_spiral.ipynb - docs/
notebooks/ , Jupyter, 216 linesslds/ rbpf_maneuver.ipynb - dynamax/
__init__.py , Python, 12 lines - dynamax/
_version.py , Python, 683 lines - dynamax/
generalized_gaussian_ssm , Python, 4 lines/ __init__.py - dynamax/
generalized_gaussian_ssm , Python, 1 line/ demos/ __init__.py - dynamax/
generalized_gaussian_ssm , Python, 75 lines/ demos/ cmgf_logreg_estimator.py - dynamax/
generalized_gaussian_ssm , Jupyter, 488 lines/ demos/ cmgf_multiclass_logreg_d emo.ipynb - dynamax/
generalized_gaussian_ssm , Jupyter, 360 lines/ demos/ dirichlet_kalman-filter_ demo.ipynb - dynamax/
generalized_gaussian_ssm , Python, 419 lines/ inference.py - dynamax/
generalized_gaussian_ssm , Python, 74 lines/ inference_test.py - dynamax/
generalized_gaussian_ssm , Python, 134 lines/ models.py - dynamax/
generalized_gaussian_ssm , Python, 63 lines/ models_test.py - dynamax/
hidden_markov_model/ , Python, 27 lines__init__.py - dynamax/
hidden_markov_model/ , Jupyter, 277 linesdemos/ bach_chorales_hmm.ipynb - dynamax/
hidden_markov_model/ , Jupyter, 232 linesdemos/ bernoulli_hmm_example.ip ynb - dynamax/
hidden_markov_model/ , Python, 72 linesdemos/ categorical_glm_hmm_demo .py - dynamax/
hidden_markov_model/ , Jupyter, 278 linesdemos/ fixed_lag_smoother_hmm.i pynb - dynamax/
hidden_markov_model/ , Jupyter, 171 linesdemos/ low_rank_gaussian_hmm.ip ynb - dynamax/
hidden_markov_model/ , Jupyter, 122 linesdemos/ multinomial_hmm.ipynb - dynamax/
hidden_markov_model/ , Jupyter, 211 linesdemos/ parallel_message_passing .ipynb - dynamax/
hidden_markov_model/ , Jupyter, 338 linesdemos/ poisson_hmm_changepoint. ipynb - dynamax/
hidden_markov_model/ , Python, 88 linesdemos/ poisson_hmm_earthquakes. py - dynamax/
hidden_markov_model/ , Jupyter, 268 linesdemos/ poisson_hmm_neurons.ipyn b - dynamax/
hidden_markov_model/ , Jupyter, 143 linesdemos/ switching_linear_regress ion.ipynb - dynamax/
hidden_markov_model/ , Python, 659 linesinference.py - dynamax/
hidden_markov_model/ , Python, 368 linesinference_test.py - dynamax/
hidden_markov_model/ , Python, 1 linemodels/ __init__.py - dynamax/
hidden_markov_model/ , Python, 684 linesmodels/ abstractions.py - dynamax/
hidden_markov_model/ , Python, 254 linesmodels/ arhmm.py - dynamax/
hidden_markov_model/ , Python, 208 linesmodels/ bernoulli_hmm.py - dynamax/
hidden_markov_model/ , Python, 193 linesmodels/ categorical_glm_hmm.py - dynamax/
hidden_markov_model/ , Python, 188 linesmodels/ categorical_hmm.py - dynamax/
hidden_markov_model/ , Python, 196 linesmodels/ gamma_hmm.py - dynamax/
hidden_markov_model/ , Python, 1,224 linesmodels/ gaussian_hmm.py - dynamax/
hidden_markov_model/ , Python, 614 linesmodels/ gmm_hmm.py - dynamax/
hidden_markov_model/ , Python, 101 linesmodels/ initial.py - dynamax/
hidden_markov_model/ , Python, 271 linesmodels/ linreg_hmm.py - dynamax/
hidden_markov_model/ , Python, 216 linesmodels/ logreg_hmm.py - dynamax/
hidden_markov_model/ , Python, 207 linesmodels/ multinomial_hmm.py - dynamax/
hidden_markov_model/ , Python, 202 linesmodels/ poisson_hmm.py - dynamax/
hidden_markov_model/ , Python, 246 linesmodels/ test_models.py - dynamax/
hidden_markov_model/ , Python, 122 linesmodels/ transitions.py - dynamax/
hidden_markov_model/ , Python, 208 linesparallel_inference.py - dynamax/
linear_gaussian_ssm/ , Python, 22 lines__init__.py - dynamax/
linear_gaussian_ssm/ , Python, 1 linedemos/ __init__.py - dynamax/
linear_gaussian_ssm/ , Jupyter, 93 linesdemos/ lgssm_blocked_gibbs.ipyn b - dynamax/
linear_gaussian_ssm/ , Python, 643 linesinference.py - dynamax/
linear_gaussian_ssm/ , Python, 212 linesinference_test.py - dynamax/
linear_gaussian_ssm/ , Python, 479 linesinfo_inference.py - dynamax/
linear_gaussian_ssm/ , Python, 182 linesinfo_inference_test.py - dynamax/
linear_gaussian_ssm/ , Python, 750 linesmodels.py - dynamax/
linear_gaussian_ssm/ , Python, 103 linesmodels_test.py - dynamax/
linear_gaussian_ssm/ , Python, 414 linesparallel_inference.py - dynamax/
linear_gaussian_ssm/ , Python, 331 linesparallel_inference_test. py - dynamax/
nonlinear_gaussian_ssm/ , Python, 7 lines__init__.py - dynamax/
nonlinear_gaussian_ssm/ , Python, 299 linesinference_ekf.py - dynamax/
nonlinear_gaussian_ssm/ , Python, 131 linesinference_ekf_test.py - dynamax/
nonlinear_gaussian_ssm/ , Python, 188 linesinference_test_utils.py - dynamax/
nonlinear_gaussian_ssm/ , Python, 318 linesinference_ukf.py - dynamax/
nonlinear_gaussian_ssm/ , Python, 36 linesinference_ukf_test.py - dynamax/
nonlinear_gaussian_ssm/ , Python, 116 linesmodels.py - dynamax/
nonlinear_gaussian_ssm/ , Python, 222 linessarkka_lib.py - dynamax/
parameters.py , Python, 165 lines - dynamax/
parameters_test.py , Python, 166 lines - dynamax/
slds/ , Python, 2 lines__init__.py - dynamax/
slds/ , Python, 349 linesinference.py - dynamax/
slds/ , Python, 132 linesinference_test.py - dynamax/
slds/ , Python, 171 linesmixture_kalman_filter_de mo.py - dynamax/
slds/ , Python, 137 linesmodels.py - dynamax/
ssm.py , Python, 506 lines, 1 match - dynamax/
ssm_test.py , Python, 192 lines - dynamax/
types.py , Python, 11 lines - dynamax/
utils/ , Python, 1 line__init__.py - dynamax/
utils/ , Python, 41 linesbijectors.py - dynamax/
utils/ , Python, 451 linesdistributions.py - dynamax/
utils/ , Python, 238 linesdistributions_test.py - dynamax/
utils/ , Python, 107 linesoptimize.py - dynamax/
utils/ , Python, 156 linesplotting.py - dynamax/
utils/ , Python, 32 linestest_optimize.py - dynamax/
utils/ , Python, 218 linesutils.py - dynamax/
utils/ , Python, 46 linesutils_test.py - dynamax/
warnings.py , Python, 23 lines - logo/
make_logo.ipynb , Jupyter, 166 lines - setup.py, Python, 9 lines
- versioneer.py, Python, 2,277 lines
- LICENSE, License, 21 lines
- README.md, Text, 188 lines
The paper's code and data availability statement is in the Data section.
Tracing map
Proposed by the machine: these links were found in the paper and verified at the source, without human review. The map will receive a Zenodo DOI once one of the paper's authors has validated it with their ORCID.
What the map holds:
- 2 repositories of the authors' code, each at its verified commit, with its license and how the link was found in the paper;
- 297 scripts, each with its path and the digest of its content;
- 4 matches between paragraphs of the paper and lines of the code (method lexical-v1);
- neither the text of the paper nor the code itself.
Its JSON (tracing-map.json) is deposited on Zenodo with its DOI once the map is validated.
Data
No dataset and no data link were found in the paper.
Data Availability
The source code and data used to produce the results and analyses presented in this manuscript are available from the main Git repository: https://
Reproduced under the paper's license (CC BY), from the paper cited above.
Versions
The history of this record: each version stored by the harvester or made by a correction of its authors or of the maintainers of its code, and what changed in its facts. The texts of the paper (its abstract, its availability statements) are not part of it; versions that changed only those are not listed.
Version 1, 27 September 2026: the first record
Recorded: type, language, journal, volume, issue, pages, dates, 7 authors, 8 MeSH terms, 2 funders, 44 references.
Cite
This paper
Legrand, N., Weber, L., Waade, P. T., Møller Daugaard, A. H., Khodadadi, M., Mikuš, N., & Mathys, C. (2026). pyhgf: A neural network library for predictive coding. PLoS computational biology, 22(6), e1014340. https://
BibTeX
@article{legrand2026pyhg
author = {Legrand, Nicolas and Weber, Lilian and Waade, Peter Thestrup and Møller Daugaard, Anna Hedvig and Khodadadi, Mojtaba and Mikuš, Nace and Mathys, Christoph},
title = {{pyhgf: A neural network library for predictive coding}},
journal = {PLoS computational biology},
year = {2026},
month = jun,
volume = {22},
number = {6},
pages = {e1014340},
publisher = {PLOS},
issn = {1553-734X},
doi = {10.1371/
url = {https://
pmid = {42330057},
pmcid = {PMC13318038}
}
RIS
TY - JOUR
AU - Legrand, Nicolas
AU - Weber, Lilian
AU - Waade, Peter Thestrup
AU - Møller Daugaard, Anna Hedvig
AU - Khodadadi, Mojtaba
AU - Mikuš, Nace
AU - Mathys, Christoph
TI - pyhgf: A neural network library for predictive coding
T2 - PLoS computational biology
J2 - PLoS Comput Biol
PY - 2026
DA - 2026/
VL - 22
IS - 6
SP - e1014340
SN - 1553-734X
PB - PLOS
DO - 10.1371/
UR - https://
LA - en
ER -
CSL-JSON
{
"id": "10.1371/
"type": "article-journal",
"title": "pyhgf: A neural network library for predictive coding",
"container-title": "PLoS computational biology",
"author": [
{
"family": "Legrand",
"given": "Nicolas"
},
{
"family": "Weber",
"given": "Lilian"
},
{
"family": "Waade",
"given": "Peter Thestrup"
},
{
"family": "Møller Daugaard",
"given": "Anna Hedvig"
},
{
"family": "Khodadadi",
"given": "Mojtaba"
},
{
"family": "Mikuš",
"given": "Nace"
},
{
"family": "Mathys",
"given": "Christoph"
}
],
"container-title-short":
"volume": "22",
"issue": "6",
"page": "e1014340",
"DOI": "10.1371/
"PMID": "42330057",
"PMCID": "PMC13318038",
"ISSN": "1553-734X",
"publisher": "PLOS",
"URL": "https://
"language": "en",
"issued": {
"date-parts": [
[
2026,
6,
22
]
]
}
}
The tracing map gets a citation of its own once an author has validated it and it has a DOI.
Similar papers
The papers with a page that share the most with this one: the tools found in their code, their categories, datasets, cited references and authors, the rarest counting most.
- [1] doi:10.1038/s42003-026-10957-8 [code]
- Brain defence by the extracellular matrix protein Cochlin.Journal: Communications biologyIn common: ArviZ, PyMC, JAX, 7 other tools
- [2] doi:10.1126/sciadv.aed4944 [code]
- Focused ultrasound blood-brain barrier opening reveals a paradoxical remote metabolic response in the primate brain.Journal: Science advancesIn common: ArviZ, PyMC, JAX, 5 other tools, 1 reference
- [3] doi:10.1038/s41467-026-72940-5 [code]
- Cerebellar growth is associated with domain-specific cerebral maturation and socio-linguistic behavior.Journal: Nature communicationsIn common: ArviZ, PyMC, xarray, 6 other tools
- [4] doi:10.1038/s41398-026-03902-0 [code]
- Mapping heterogeneous brain structural subtypes in alzheimer's disease and mild cognitive impairment using normative models.Journal: Translational psychiatryIn common: ArviZ, PyMC, xarray, 6 other tools
- [5] doi:10.1162/imag.a.1269 [code]
- From early to contemporary normative modeling: Mapping individual differences in neurophysiological signals.Journal: Imaging neuroscience (Cambridge, Mass.)In common: ArviZ, PyMC, xarray, 6 other tools
- [6] doi:10.7554/elife.100605 [code]
- Age-related changes in ‘cortical’ 1/
f dynamics are linked to cardiac activity Journal: n/aIn common: ArviZ, PyMC, NetworkX, 6 other tools - [7] doi:10.7554/elife.108223 [code]
- Two time scales of adaptation in human learning rates.Journal: eLifeIn common: ArviZ, seaborn, pandas, 3 other tools, 3 references
- [8] doi:10.1038/s41467-026-75959-w [code]
- Charting higher-order models of brain function beyond pairwise interactions.Journal: Nature communicationsIn common: JAX, xarray, NetworkX, 6 other tools
- [9] doi: [code]
- Naturalistic behavior and self-generated neural activity predictive of self-correctionJournal: bioRxiv : the preprint server for biologyIn common: JAX, xarray, NetworkX, 6 other tools
- [10] doi:10.1038/s41591-026-04287-9 [code]
- An international mega-analysis of psychedelic drug effects on brain circuit function.Journal: Nature medicineIn common: ArviZ, PyMC, seaborn, 5 other tools
Contribute
The authors of this paper can claim it, correct its record and validate its tracing map, and the maintainers of its code (its owner, or a public member of its organization) correct what it says of their repository; anyone signed in can ask for its removal. Every request goes to OSCR's own machine, which answers it; your account page follows them.
Sign in with ORCID to claim this paper as one of its authors, correct its record or validate its tracing map: when the paper's metadata lists your ORCID iD, you are recognized at once. Maintainers of its code: sign in with GitHub, then claim the repository on your account page.
Claim this paper
Correct its record
Say what each link of this record is, remove the ones that are not the paper's, add the ones that are missing. The correction becomes a new version of the record, in its Versions section.
Validate its tracing map
You validate the map as this page shows it: 2 repositories of the authors' code, each at its verified commit and with its license, 297 scripts, and 4 matches between paragraphs and code (see the Code and Map sections). It then receives a DOI on Zenodo, with you (your ORCID iD) and OSCR as its creators; the code itself is not deposited.
The map's fingerprint: sha256:edbfc234a0f8c30d…
Add the badge to its README
The badge links the code to this page. Copy one of these into the README of the paper's code: only you decide where it goes, and nothing is changed for you.
Markdown
[, paste the snippet at the top, then “Commit changes…” and, to review it first, “Create a new branch and start a pull request”. You open the pull request; OSCR asks for no permission.
Request its removal
To ask OSCR to remove this record, the copies of its authors' scripts or its tracing map, use the removal request page: signed in, you say who you are, what to remove and why, then review and confirm the request. Published rules decide every request (how).
Discussion, reproductions, activity
Discussion: questions and error reports about this paper and its code, from signed-in readers and its authors. It opens with sign-in.
Reproductions: reports from readers who ran the authors' code: what they reproduced, with which environment, commit and data. It opens with sign-in.
Activity: what happens around this paper: new versions of its record, its map's validation, discussions and reproductions. It opens with sign-in.
