File size: 4,834 Bytes
1bfe9c1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
// ๐ŸŒŒ [BioPhys 6.0] ์„ฑ์ƒ๊ต์„ธํฌ(Astrocyte) 3์ค‘ ์‹œ๋ƒ…์Šค ์žฅ๊ธฐ ๊ธฐ์–ต ์กฐ์ ˆ๊ธฐ (src/astrocyte_glia_controller.rs)
// ๋ฐ€๋ฆฌ์ดˆ(ms) ๋‰ด๋Ÿฐ ์ŠคํŒŒ์ดํฌ ์œ„์— ์ดˆ(sec) ๋‹จ์œ„ ์นผ์Š˜ ํŒŒ๋™(Caยฒโบ Waves)์„ ์˜ค๋ฒ„๋ ˆ์ดํ•˜์—ฌ ์žฅ๊ธฐ ๊ฐ•ํ™”(LTP) ๋ฐ ๋ง๊ฐ(LTD)์„ ๋ฉ”ํƒ€ ์กฐ์ ˆํ•˜๋Š” ๊ธ€๋ฆฌ์•„ ์‹ ๊ฒฝ๋ง ์—”์ง„

use std::time::Instant;

/// ๐Ÿ”ฌ ์„ฑ์ƒ๊ต์„ธํฌ ์„ค์ • ํŒŒ๋ผ๋ฏธํ„ฐ (Config)
#[derive(Clone, Debug)]
pub struct AstrocyteConfig {
    pub num_astrocytes: usize,
    pub calcium_decay_rate: f32,       // ์นผ์Š˜ ๋†๋„ ์ž์—ฐ ๊ฐ์‡ ์œจ (๊ธฐ๋ณธ: 0.08)
    pub gliotransmitter_potency: f32, // ๊ธ€๋ฆฌ์˜คํŠธ๋žœ์Šค๋ฏธํ„ฐ ๋ฐฉ์ถœ ๊ฐ•๋„ (๊ธฐ๋ณธ: 1.45)
    pub ltp_consolidation_threshold: f32, // ์žฅ๊ธฐ ๊ธฐ์–ต ๊ณ ์ • ์ž„๊ณ„์น˜ (๊ธฐ๋ณธ: 0.65)
}

impl Default for AstrocyteConfig {
    fn default() -> Self {
        Self {
            num_astrocytes: 64,
            calcium_decay_rate: 0.08,
            gliotransmitter_potency: 1.45,
            ltp_consolidation_threshold: 0.65,
        }
    }
}

/// ๐ŸŒŸ ๊ฐœ๋ณ„ ์„ฑ์ƒ๊ต์„ธํฌ ๋„๋ฉ”์ธ ๋…ธ๋“œ (Astrocyte Micro-Domain)
#[derive(Clone, Debug)]
pub struct AstrocyteDomain {
    pub domain_id: usize,
    pub intracellular_calcium: f32, // ์„ธํฌ๋‚ด ์นผ์Š˜ ์ด์˜จ ๋†๋„ [Caยฒโบ]
    pub gliotransmitter_level: f32, // ๊ธ€๋ฆฌ์˜คํŠธ๋žœ์Šค๋ฏธํ„ฐ(D-Serine/ATP) ๋ถ„๋น„๋Ÿ‰
    pub consolidated_memory_strength: f32, // ์˜๊ตฌ ๋ณด์กด ๊ธฐ์–ต ๊ฐ•๋„
}

impl AstrocyteDomain {
    pub fn new(domain_id: usize) -> Self {
        Self {
            domain_id,
            intracellular_calcium: 0.1,
            gliotransmitter_level: 0.0,
            consolidated_memory_strength: 1.0,
        }
    }
}

/// ๐Ÿ›๏ธ ์„ฑ์ƒ๊ต์„ธํฌ ๊ธ€๋ฆฌ์•„ ๋ฉ”ํƒ€ ์ปจํŠธ๋กค๋Ÿฌ (Main Engine Struct)
pub struct AstrocyteGliaController {
    pub config: AstrocyteConfig,
    pub astrocytes: Vec<AstrocyteDomain>,
    pub global_calcium_wave_energy: f32,
    pub total_memories_consolidated: usize,
}

impl AstrocyteGliaController {
    pub fn new(config: AstrocyteConfig) -> Self {
        let astrocytes = (0..config.num_astrocytes)
            .map(|i| AstrocyteDomain::new(i))
            .collect();
        Self {
            config,
            astrocytes,
            global_calcium_wave_energy: 0.0,
            total_memories_consolidated: 0,
        }
    }

    /// [3์ค‘ ์‹œ๋ƒ…์Šค ์ƒํ˜ธ์ž‘์šฉ ๋ฐ ์นผ์Š˜ ํŒŒ๋™ ์ „ํŒŒ]: ๋‰ด๋Ÿฐ ์ŠคํŒŒ์ดํฌ๋ฅผ ๊ฐ์ง€ํ•˜๊ณ  ๋ฉ”ํƒ€ ๊ฐ€์†Œ์„ฑ ์กฐ์ ˆ
    pub fn modulate_synaptic_field(&mut self, spike_activities: &[f32]) -> (f32, u128) {
        let t_start = Instant::now();
        let num_astro = self.astrocytes.len();
        let mut total_calcium = 0.0f32;

        for (i, ast) in self.astrocytes.iter_mut().enumerate() {
            // 1. ์‹œ๋ƒ…์Šค ํ™œ๋™ ๊ฐ์ง€ ๋ฐ ์นผ์Š˜ ์œ ์ž… (IP3-mediated Caยฒโบ release)
            let sensory_idx = i % spike_activities.len().max(1);
            let raw_activity = if !spike_activities.is_empty() { spike_activities[sensory_idx].abs() } else { 0.0 };

            ast.intracellular_calcium += raw_activity * 0.25;
            ast.intracellular_calcium *= 1.0 - self.config.calcium_decay_rate; // ์ž์—ฐ ๊ฐ์‡ 

            // 2. ๊ธ€๋ฆฌ์˜คํŠธ๋žœ์Šค๋ฏธํ„ฐ ๋ฐฉ์ถœ
            if ast.intracellular_calcium > 0.3 {
                ast.gliotransmitter_level = (ast.intracellular_calcium * self.config.gliotransmitter_potency).min(2.0);
            } else {
                ast.gliotransmitter_level *= 0.9;
            }

            // 3. ์žฅ๊ธฐ ๊ธฐ์–ต ๊ณ ์ • (LTP Consolidation)
            if ast.gliotransmitter_level > self.config.ltp_consolidation_threshold {
                ast.consolidated_memory_strength += 0.05;
                self.total_memories_consolidated += 1;
            } else if ast.intracellular_calcium < 0.05 {
                // ๋…ธ์ด์ฆˆ์„ฑ ๋‹จ๊ธฐ ๊ธฐ์–ต ์ž์—ฐ ๋ง๊ฐ (LTD)
                ast.consolidated_memory_strength = (ast.consolidated_memory_strength * 0.98).max(0.5);
            }

            total_calcium += ast.intracellular_calcium;
        }

        self.global_calcium_wave_energy = total_calcium / num_astro as f32;
        let latency_us = t_start.elapsed().as_micros();

        (self.global_calcium_wave_energy, latency_us)
    }

    /// [๊ธ€๋ฆฌ์•„ ๋ฉ”ํƒ€-๊ฐ€์†Œ์„ฑ ๊ฐ€์ค‘์น˜ ์Šค์ผ€์ผ ๋ฐ˜ํ™˜]
    pub fn get_synaptic_gain(&self, domain_idx: usize) -> f32 {
        let idx = domain_idx % self.astrocytes.len();
        self.astrocytes[idx].consolidated_memory_strength
    }

    /// [์„ฑ์ƒ๊ต์„ธํฌ ์ƒํƒœ ์š”์•ฝ]
    pub fn telemetry_summary(&self) -> String {
        format!(
            "๐Ÿงฌ [์„ฑ์ƒ๊ต์„ธํฌ ๊ธ€๋ฆฌ์•„]: ๋„๋ฉ”์ธ {}๊ฐœ | ๊ธ€๋กœ๋ฒŒ Caยฒโบ ํŒŒ๋™ ์—๋„ˆ์ง€: {:.4} | ๊ณ ์ •๋œ ์žฅ๊ธฐ ๊ธฐ์–ต ์ˆ˜: {}๊ฐœ",
            self.config.num_astrocytes, self.global_calcium_wave_energy, self.total_memories_consolidated
        )
    }
}