Skip to main content

feagi_brain_development/connectivity/rules/
expander.rs

1// Copyright 2025 Neuraville Inc.
2// SPDX-License-Identifier: Apache-2.0
3
4/*!
5Expander morphology - scales coordinates from source to destination.
6*/
7
8use crate::types::{BduResult, Position};
9
10/// Expander mapping - scales coordinates by dimension ratios.
11pub fn syn_expander(
12    _src_area_id: &str,
13    _dst_area_id: &str,
14    neuron_location: Position,
15    src_dimensions: (usize, usize, usize),
16    dst_dimensions: (usize, usize, usize),
17) -> BduResult<Position> {
18    let (src_x, src_y, src_z) = src_dimensions;
19    let (dst_x, dst_y, dst_z) = dst_dimensions;
20
21    // Calculate expansion ratios
22    let ratio_x = dst_x as f32 / src_x as f32;
23    let ratio_y = dst_y as f32 / src_y as f32;
24    let ratio_z = dst_z as f32 / src_z as f32;
25
26    // Scale neuron position
27    let (x, y, z) = neuron_location;
28    let scaled_x = ((x as f32 * ratio_x) as usize).min(dst_x - 1) as u32;
29    let scaled_y = ((y as f32 * ratio_y) as usize).min(dst_y - 1) as u32;
30    let scaled_z = ((z as f32 * ratio_z) as usize).min(dst_z - 1) as u32;
31
32    Ok((scaled_x, scaled_y, scaled_z))
33}
34
35/// Batch expander for parallel processing (sequential fallback for WASM)
36pub fn syn_expander_batch(
37    src_area_id: &str,
38    dst_area_id: &str,
39    neuron_locations: &[Position],
40    src_dimensions: (usize, usize, usize),
41    dst_dimensions: (usize, usize, usize),
42) -> BduResult<Vec<Position>> {
43    #[cfg(feature = "parallel")]
44    {
45        use rayon::prelude::*;
46        neuron_locations
47            .par_iter()
48            .map(|&loc| {
49                syn_expander(
50                    src_area_id,
51                    dst_area_id,
52                    loc,
53                    src_dimensions,
54                    dst_dimensions,
55                )
56            })
57            .collect::<Result<Vec<_>, _>>()
58    }
59
60    #[cfg(not(feature = "parallel"))]
61    {
62        neuron_locations
63            .iter()
64            .map(|&loc| {
65                syn_expander(
66                    src_area_id,
67                    dst_area_id,
68                    loc,
69                    src_dimensions,
70                    dst_dimensions,
71                )
72            })
73            .collect::<Result<Vec<_>, _>>()
74    }
75}
76
77#[cfg(test)]
78mod tests {
79    use super::*;
80
81    #[test]
82    fn test_expander_scale_up() {
83        let result = syn_expander("src", "dst", (5, 5, 5), (10, 10, 10), (20, 20, 20));
84        assert!(result.is_ok());
85        assert_eq!(result.unwrap(), (10, 10, 10));
86    }
87
88    #[test]
89    fn test_expander_scale_down() {
90        let result = syn_expander("src", "dst", (10, 10, 10), (20, 20, 20), (10, 10, 10));
91        assert!(result.is_ok());
92        assert_eq!(result.unwrap(), (5, 5, 5));
93    }
94}