Skip to main content

sc_neurocore_engine/bindings/
phi.rs

1// SPDX-License-Identifier: AGPL-3.0-or-later
2// Commercial license available
3// © Concepts 1996–2026 Miroslav Šotek. All rights reserved.
4// © Code 2020–2026 Miroslav Šotek. All rights reserved.
5// ORCID: 0009-0009-3560-0851
6// Contact: www.anulum.li | protoscience@anulum.li
7// SC-NeuroCore — Phi-star PyO3 binding
8
9//! Python binding for Gaussian integrated-information estimation.
10
11use numpy::{PyReadonlyArray2, PyUntypedArrayMethods};
12use pyo3::exceptions::PyValueError;
13use pyo3::prelude::*;
14
15/// Register the Phi-star estimator with the extension module.
16pub(crate) fn register(module: &Bound<'_, PyModule>) -> PyResult<()> {
17    module.add_function(wrap_pyfunction!(py_phi_star, module)?)?;
18    Ok(())
19}
20
21/// Estimate integrated information from a channel-major time series.
22#[pyfunction]
23fn py_phi_star(data: PyReadonlyArray2<'_, f64>, tau: usize) -> PyResult<f64> {
24    if !data.is_c_contiguous() {
25        return Err(PyValueError::new_err(
26            "py_phi_star requires C-contiguous array input",
27        ));
28    }
29    let shape = data.shape();
30    let n_channels = shape[0];
31    let n_timesteps = shape[1];
32    let flat = data.as_slice().map_err(|error| {
33        PyValueError::new_err(format!("py_phi_star requires C-contiguous array: {error}"))
34    })?;
35    let channels: Vec<Vec<f64>> = (0..n_channels)
36        .map(|index| flat[index * n_timesteps..(index + 1) * n_timesteps].to_vec())
37        .collect();
38    Ok(crate::phi::phi_star(&channels, tau))
39}