use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct IneruConfig {
pub window_size: usize,
pub memory_capacity: usize,
pub embedding_dim: usize,
pub surprise_threshold: f32,
pub anomaly_detection: bool,
pub anomaly_threshold: f32,
pub attention_decay: f32,
pub compression_enabled: bool,
pub compression_ratio: f32,
}
impl Default for IneruConfig {
fn default() -> Self {
Self {
window_size: 1000,
memory_capacity: 10000,
embedding_dim: 16,
surprise_threshold: 0.5,
anomaly_detection: true,
anomaly_threshold: 0.3,
attention_decay: 0.99,
compression_enabled: false,
compression_ratio: 1.0,
}
}
}
impl IneruConfig {
pub fn iot() -> Self {
Self {
window_size: 100, memory_capacity: 500, embedding_dim: 8, surprise_threshold: 0.7, anomaly_detection: false, anomaly_threshold: 0.3,
attention_decay: 0.95,
compression_enabled: true,
compression_ratio: 0.5,
}
}
pub fn full_power() -> Self {
Self {
window_size: 10000, memory_capacity: 100000, embedding_dim: 32, surprise_threshold: 0.3, anomaly_detection: true,
anomaly_threshold: 0.2,
attention_decay: 0.995,
compression_enabled: false,
compression_ratio: 1.0,
}
}
pub fn validate(&self) -> Result<(), String> {
if self.window_size == 0 {
return Err("window_size must be > 0".to_string());
}
if self.memory_capacity == 0 {
return Err("memory_capacity must be > 0".to_string());
}
if self.embedding_dim == 0 {
return Err("embedding_dim must be > 0".to_string());
}
if self.surprise_threshold < 0.0 || self.surprise_threshold > 1.0 {
return Err("surprise_threshold must be between 0.0 and 1.0".to_string());
}
if self.anomaly_threshold < 0.0 || self.anomaly_threshold > 1.0 {
return Err("anomaly_threshold must be between 0.0 and 1.0".to_string());
}
if self.attention_decay < 0.0 || self.attention_decay > 1.0 {
return Err("attention_decay must be between 0.0 and 1.0".to_string());
}
Ok(())
}
pub fn estimated_memory_bytes(&self) -> usize {
let pattern_size = self.embedding_dim * 4 + 32 + 8 + 100; let short_term = self.window_size * pattern_size;
let long_term = self.memory_capacity * pattern_size;
short_term + long_term
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_default_config() {
let config = IneruConfig::default();
assert!(config.validate().is_ok());
}
#[test]
fn test_iot_config() {
let config = IneruConfig::iot();
assert!(config.validate().is_ok());
assert!(config.window_size < IneruConfig::default().window_size);
}
#[test]
fn test_validation() {
let mut config = IneruConfig::default();
config.window_size = 0;
assert!(config.validate().is_err());
config = IneruConfig::default();
config.surprise_threshold = 1.5;
assert!(config.validate().is_err());
}
#[test]
fn test_memory_estimation() {
let config = IneruConfig::default();
let bytes = config.estimated_memory_bytes();
assert!(bytes > 0);
let iot_config = IneruConfig::iot();
let iot_bytes = iot_config.estimated_memory_bytes();
assert!(iot_bytes < bytes);
}
}