Skip to main content

feagi_brain_development/connectivity/rules/
trivial.rs

1// Copyright 2025 Neuraville Inc.
2// SPDX-License-Identifier: Apache-2.0
3
4/*!
5Trivial connectivity rules - simple, non-compute-intensive morphologies.
6*/
7
8use crate::rng::get_rng;
9use crate::types::Position;
10use rand::Rng;
11
12type Dimensions = (usize, usize, usize);
13
14/// Randomizer - select random position in destination area
15pub fn syn_randomizer(dst_dimensions: Dimensions) -> Position {
16    let mut rng = get_rng();
17    (
18        rng.gen_range(0..dst_dimensions.0 as u32),
19        rng.gen_range(0..dst_dimensions.1 as u32),
20        rng.gen_range(0..dst_dimensions.2 as u32),
21    )
22}
23
24/// Lateral pairs X - connect neurons in pairs along X axis
25/// Even neurons connect to right neighbor, odd to left neighbor
26pub fn syn_lateral_pairs_x(
27    neuron_location: Position,
28    src_dimensions: Dimensions,
29) -> Option<Position> {
30    let (x, y, z) = neuron_location;
31
32    if x % 2 == 0 {
33        // Even neurons connect to the right
34        if (x + 1) < src_dimensions.0 as u32 {
35            Some((x + 1, y, z))
36        } else {
37            None
38        }
39    } else {
40        // Odd neurons connect to the left
41        if x > 0 {
42            Some((x - 1, y, z))
43        } else {
44            None
45        }
46    }
47}
48
49/// Last to first - connect last neuron to first (feedback connection)
50pub fn syn_last_to_first(
51    neuron_location: Position,
52    src_dimensions: Dimensions,
53) -> Option<Position> {
54    let last_pos = (
55        src_dimensions.0 as u32 - 1,
56        src_dimensions.1 as u32 - 1,
57        src_dimensions.2 as u32 - 1,
58    );
59
60    if neuron_location == last_pos {
61        Some((0, 0, 0))
62    } else {
63        None
64    }
65}
66
67#[cfg(test)]
68mod tests {
69    use super::*;
70
71    #[test]
72    fn test_randomizer() {
73        let dims = (10, 10, 10);
74        for _ in 0..100 {
75            let pos = syn_randomizer(dims);
76            assert!(pos.0 < 10);
77            assert!(pos.1 < 10);
78            assert!(pos.2 < 10);
79        }
80    }
81
82    #[test]
83    fn test_lateral_pairs() {
84        // Even neuron
85        let result = syn_lateral_pairs_x((2, 5, 3), (10, 10, 10));
86        assert_eq!(result, Some((3, 5, 3)));
87
88        // Odd neuron
89        let result = syn_lateral_pairs_x((3, 5, 3), (10, 10, 10));
90        assert_eq!(result, Some((2, 5, 3)));
91
92        // Edge case: even at boundary (9 pairs with 8)
93        let result = syn_lateral_pairs_x((8, 5, 3), (10, 10, 10));
94        assert_eq!(result, Some((9, 5, 3)));
95
96        // Edge case: even at left boundary (0 pairs with 1)
97        let result = syn_lateral_pairs_x((0, 5, 3), (10, 10, 10));
98        assert_eq!(result, Some((1, 5, 3)));
99    }
100
101    #[test]
102    fn test_last_to_first() {
103        let dims = (10, 10, 10);
104
105        // Last position
106        let result = syn_last_to_first((9, 9, 9), dims);
107        assert_eq!(result, Some((0, 0, 0)));
108
109        // Not last position
110        let result = syn_last_to_first((5, 5, 5), dims);
111        assert_eq!(result, None);
112    }
113}