anomaly_grid/
lib.rs

1//! Anomaly Grid - Sequential Pattern Analysis Library
2//!
3//! A focused library for anomaly detection in finite-alphabet sequences using
4//! variable-order Markov chains with hierarchical context selection.
5//!
6//! This library provides pattern-based anomaly detection through
7//! information-theoretic measures and probability estimation.
8//!
9//! # Features
10//!
11//! - **Variable-Order Markov Models**: Hierarchical context selection with Laplace smoothing
12//! - **Information Theory**: Shannon entropy, KL divergence, and surprise quantification  
13//! - **Hierarchical Context Selection**: Automatic fallback from longer to shorter contexts
14//! - **Parallel Processing**: Batch analysis using Rayon for multiple sequences
15//! - **Numerical Stability**: Robust probability estimation with smoothing
16//!
17//! # Quick Start
18//!
19//! ```rust
20//! use anomaly_grid::*;
21//!
22//! # fn main() -> Result<(), Box<dyn std::error::Error>> {
23//! // Create and train detector
24//! let mut detector = AnomalyDetector::new(3)?;
25//! let normal_sequence = vec![
26//!     "A".to_string(), "B".to_string(), "C".to_string(),
27//!     "A".to_string(), "B".to_string(), "C".to_string(),
28//! ];
29//! detector.train(&normal_sequence)?;
30//!
31//! // Detect anomalies
32//! let test_sequence = vec![
33//!     "A".to_string(), "X".to_string(), "Y".to_string(),
34//! ];
35//! let anomalies = detector.detect_anomalies(&test_sequence, 0.1)?;
36//!
37//! for anomaly in anomalies {
38//!     println!("Anomaly: {:?}, Likelihood: {:.6}",
39//!              anomaly.sequence, anomaly.likelihood);
40//! }
41//! # Ok(())
42//! # }
43//! ```
44//!
45//! # Architecture
46//!
47//! The library is organized into three main modules:
48//!
49//! - [`context_tree`]: Context storage and probability estimation
50//! - [`markov_model`]: Variable-order Markov chain implementation  
51//! - [`anomaly_detector`]: Anomaly detection using Markov models
52//!
53//! # Use Cases
54//!
55//! - **Network Security**: Detecting unusual protocol sequences and attack patterns
56//! - **User Behavior Analysis**: Identifying privilege escalation and suspicious activities
57//! - **Financial Fraud**: Detecting unusual transaction patterns and velocity attacks
58//! - **System Monitoring**: Identifying anomalous log sequences and security incidents
59//! - **Bioinformatics**: Detecting mutations and unusual genetic sequences
60
61pub mod anomaly_detector;
62pub mod config;
63pub mod constants;
64pub mod context_tree;
65pub mod error;
66pub mod markov_model;
67pub mod performance;
68
69// Re-export main types for convenience
70pub use anomaly_detector::{batch_process_sequences, AnomalyDetector, AnomalyScore};
71pub use config::AnomalyGridConfig;
72pub use context_tree::{ContextNode, ContextTree};
73pub use error::{AnomalyGridError, AnomalyGridResult};
74pub use markov_model::MarkovModel;
75pub use performance::{
76    optimize_context_tree, ContextStatistics, OptimizationConfig, PerformanceMetrics,
77};
78
79/// Library version
80pub const VERSION: &str = env!("CARGO_PKG_VERSION");
81
82/// Get library information
83pub fn info() -> String {
84    format!("Anomaly Grid v{VERSION} - Markov Chain-based Sequence Anomaly Detection")
85}
86
87#[cfg(test)]
88mod tests {
89    use super::*;
90
91    #[test]
92    fn test_library_info() {
93        let info = info();
94        assert!(info.contains("Anomaly Grid"));
95        assert!(info.contains(VERSION));
96    }
97
98    #[test]
99    fn test_basic_workflow() {
100        let mut detector = AnomalyDetector::new(2).expect("Failed to create detector");
101        let sequence = vec![
102            "A".to_string(),
103            "B".to_string(),
104            "A".to_string(),
105            "B".to_string(),
106        ];
107
108        // Training should succeed
109        assert!(detector.train(&sequence).is_ok());
110
111        // Detection should work
112        let test_sequence = vec!["A".to_string(), "X".to_string(), "Y".to_string()];
113        let anomalies = detector
114            .detect_anomalies(&test_sequence, 0.5)
115            .expect("Failed to detect anomalies");
116
117        // Should detect some anomalies or handle gracefully
118        for anomaly in anomalies {
119            assert!(anomaly.likelihood >= 0.0);
120            assert!(anomaly.likelihood <= 1.0);
121            assert!(anomaly.anomaly_strength >= 0.0);
122            assert!(anomaly.anomaly_strength <= 1.0);
123        }
124    }
125
126    #[test]
127    fn test_module_integration() {
128        // Test that all modules work together
129        let mut tree = ContextTree::new(2).expect("Failed to create context tree");
130        let sequence = vec!["A".to_string(), "B".to_string(), "C".to_string()];
131        let config = AnomalyGridConfig::default();
132
133        assert!(tree.build_from_sequence(&sequence, &config).is_ok());
134        assert!(!tree.contexts.is_empty());
135
136        let mut model = MarkovModel::new(2).expect("Failed to create Markov model");
137        assert!(model.train(&sequence).is_ok());
138
139        let likelihood = model.calculate_likelihood(&sequence);
140        assert!(likelihood > 0.0);
141        assert!(likelihood <= 1.0);
142
143        let mut detector = AnomalyDetector::new(2).expect("Failed to create detector");
144        assert!(detector.train(&sequence).is_ok());
145
146        let anomalies = detector
147            .detect_anomalies(&sequence, 0.1)
148            .expect("Failed to detect anomalies");
149        // Normal sequence should have few anomalies
150        assert!(anomalies.len() <= 1);
151    }
152}