use crate::config::blueprints::NeuronType;
fn emulate_gsop_math(
weight: i32,
dopamine: i16,
dist_to_spike: Option<u32>,
burst_count: u8,
p: &NeuronType,
) -> i32 {
let sign = if weight >= 0 { 1 } else { -1 };
let abs_w = weight.abs();
let pot_mod = ((dopamine as i32) * (p.d1_affinity as i32)) >> 7;
let dep_mod = ((dopamine as i32) * (p.d2_affinity as i32)) >> 7;
let raw_pot = (p.gsop_potentiation as i32) + pot_mod;
let raw_dep = (p.gsop_depression as i32) - dep_mod;
let final_dep = raw_dep.max(0);
let rank = (abs_w >> 27) as usize;
let rank_safe = rank.min(15);
let inertia = p.inertia_curve[rank_safe] as i32;
let burst_mult = if burst_count > 0 {
burst_count as i32
} else {
1
};
let delta_pot = (raw_pot * inertia * burst_mult) >> 7;
let delta_dep = (final_dep * inertia * burst_mult) >> 7;
let is_active = dist_to_spike.is_some();
let min_dist = dist_to_spike.unwrap_or(u32::MAX);
let cooling_shift = if is_active { (min_dist >> 4) as u32 } else { 0 };
let delta = if is_active {
delta_pot >> cooling_shift
} else {
-delta_dep
};
let decay = 128i32;
let delta = (delta * decay) >> 7;
let mut new_abs = abs_w + delta;
if new_abs < 0 {
new_abs = 0;
}
if new_abs > 2140000000 {
new_abs = 2140000000;
}
sign * new_abs
}
fn test_neuron() -> NeuronType {
let mut nt = NeuronType::default();
nt.gsop_potentiation = 80;
nt.gsop_depression = 40;
nt.d1_affinity = 128; nt.d2_affinity = 128; nt.inertia_curve = [
128, 120, 112, 104, 96, 88, 80, 72, 64, 56, 48, 40, 32, 24, 16, 8,
];
nt
}
#[test]
fn test_gsop_potentiation_basic() {
let nt = test_neuron();
let w = emulate_gsop_math(100, 0, Some(0), 0, &nt);
assert_eq!(w, 180);
}
#[test]
fn test_gsop_depression_basic() {
let nt = test_neuron();
let w = emulate_gsop_math(100, 0, None, 0, &nt);
assert_eq!(w, 60);
}
#[test]
fn test_gsop_clamp_max() {
let nt = test_neuron();
let w = emulate_gsop_math(2140000000, 0, Some(0), 0, &nt);
assert_eq!(w, 2140000000);
}
#[test]
fn test_gsop_spatial_cooling() {
let nt = test_neuron();
let w = emulate_gsop_math(1000, 0, Some(32), 0, &nt);
assert_eq!(w, 1020);
}