native_neural_network_std 0.2.1

Ergonomic std wrapper for the `native_neural_network` crate (no_std) — std-friendly re-exports and utilities.
Documentation
pub use native_neural_network::sphere5d::NeuronPoint;

#[derive(Debug)]
pub enum SphereStdError {
    InvalidRadius,
    CapacityTooSmall,
    InvalidLayout,
    BiasOutOfBounds,
}

impl From<native_neural_network::sphere5d::SphereError> for SphereStdError {
    fn from(e: native_neural_network::sphere5d::SphereError) -> Self {
        match e {
            native_neural_network::sphere5d::SphereError::InvalidRadius => {
                SphereStdError::InvalidRadius
            }
            native_neural_network::sphere5d::SphereError::CapacityTooSmall => {
                SphereStdError::CapacityTooSmall
            }
            native_neural_network::sphere5d::SphereError::InvalidLayout => {
                SphereStdError::InvalidLayout
            }
            native_neural_network::sphere5d::SphereError::BiasOutOfBounds => {
                SphereStdError::BiasOutOfBounds
            }
        }
    }
}

pub struct Sphere5DStd {
    points: Vec<NeuronPoint>,
    radius: f32,
    len: usize,
}

impl Sphere5DStd {
    pub fn new(capacity: usize, radius: f32) -> Result<Self, SphereStdError> {
        if !radius.is_finite() || radius <= 0.0 {
            return Err(SphereStdError::InvalidRadius);
        }
        let points = vec![NeuronPoint::default(); capacity];
        Ok(Self {
            points,
            radius,
            len: 0,
        })
    }

    pub fn capacity(&self) -> usize {
        self.points.len()
    }
    pub fn len(&self) -> usize {
        self.len
    }
    pub fn is_empty(&self) -> bool {
        self.len == 0
    }

    pub fn add_neuron(
        &mut self,
        layer: usize,
        neuron: usize,
        bias: f32,
        activation: f32,
    ) -> Option<usize> {
        let mut sphere =
            match native_neural_network::sphere5d::Sphere5D::new(&mut self.points[..], self.radius)
            {
                Ok(s) => s,
                Err(_) => return None,
            };
        let res = sphere.add_neuron(layer, neuron, bias, activation);
        self.len = sphere.len();
        res
    }

    pub fn nearest(&self, position: [f32; 5]) -> Option<(usize, f32)> {
        if self.len == 0 {
            return None;
        }
        let mut best_idx = 0usize;
        let mut best_d2 = 0f32;
        for i in 0..self.len {
            let d2 = {
                let a = self.points[i].position;
                let mut acc = 0.0f32;
                let mut j = 0usize;
                while j < 5 {
                    let d = a[j] - position[j];
                    acc += d * d;
                    j += 1;
                }
                acc
            };
            if i == 0 || d2 < best_d2 {
                best_d2 = d2;
                best_idx = i;
            }
        }
        Some((best_idx, native_neural_network::math::sqrtf(best_d2)))
    }

    pub fn neighbors_within(
        &self,
        position: [f32; 5],
        max_distance: f32,
        out_indices: &mut [usize],
    ) -> usize {
        if max_distance < 0.0 || out_indices.is_empty() {
            return 0;
        }
        let max_d2 = max_distance * max_distance;
        let mut written = 0usize;
        for i in 0..self.len {
            if written >= out_indices.len() {
                break;
            }
            let mut acc = 0.0f32;
            let mut j = 0usize;
            while j < 5 {
                let d = self.points[i].position[j] - position[j];
                acc += d * d;
                j += 1;
            }
            if acc <= max_d2 {
                out_indices[written] = i;
                written += 1;
            }
        }
        written
    }

    pub fn fill_from_network(
        &mut self,
        network: &crate::std::network_std::NeuralNetworkStd,
    ) -> Result<(), SphereStdError> {
        let nn_view = native_neural_network::network::NeuralNetwork::from_parts(
            &network.layers,
            &network.weights,
            &network.biases,
        )
        .ok_or(SphereStdError::InvalidLayout)?;
        let mut sphere =
            native_neural_network::sphere5d::Sphere5D::new(&mut self.points[..], self.radius)
                .map_err(SphereStdError::from)?;
        sphere
            .fill_from_network(&nn_view)
            .map_err(SphereStdError::from)?;
        self.len = sphere.len();
        Ok(())
    }
}