ncps/lib.rs
1//! # NCPS - Neural Circuit Policies for Rust
2//!
3//! [](https://crates.io/crates/ncps)
4//! [](https://docs.rs/ncps)
5//!
6//! A Rust implementation of Neural Circuit Policies (NCPs) using the [Burn](https://burn.dev)
7//! deep learning framework. NCPs are biologically-inspired recurrent neural networks with
8//! sparse, structured connectivity patterns.
9//!
10//! ## Why NCPs?
11//!
12//! | Feature | Traditional RNN | NCP |
13//! |---------|-----------------|-----|
14//! | Connectivity | Dense (O(N²)) | Sparse (O(N)) |
15//! | Parameters | Many | Few |
16//! | Interpretability | Black box | Structured layers |
17//! | Time handling | Discrete | Continuous |
18//!
19//! NCPs are particularly well-suited for:
20//! - **Time series** with irregular sampling
21//! - **Robotics** and control systems
22//! - **Edge deployment** where parameters matter
23//! - **Interpretable AI** applications
24//!
25//! ## Quick Start
26//!
27//! Add to your `Cargo.toml`:
28//!
29//! ```toml
30//! [dependencies]
31//! ncps = "0.1"
32//! burn = { version = "0.16", features = ["ndarray"] }
33//! ```
34//!
35//! ### Basic Usage
36//!
37//! ```rust
38//! use ncps::prelude::*;
39//!
40//! // 1. Create wiring (defines network structure)
41//! let mut wiring = AutoNCP::new(
42//! 32, // total neurons
43//! 8, // output size
44//! 0.5, // sparsity (50% connections removed)
45//! 42, // random seed
46//! );
47//!
48//! // 2. Build with your input dimension
49//! wiring.build(16); // 16 input features
50//!
51//! // 3. Verify configuration
52//! assert_eq!(wiring.units(), 32);
53//! assert_eq!(wiring.output_dim(), Some(8));
54//! assert!(wiring.is_built());
55//! ```
56//!
57//! ### Full RNN Example
58//!
59//! ```ignore
60//! use ncps::prelude::*;
61//! use burn::tensor::Tensor;
62//! use burn::backend::NdArray;
63//!
64//! type Backend = NdArray<f32>;
65//!
66//! let device = Default::default();
67//!
68//! // Create wiring
69//! let mut wiring = AutoNCP::new(64, 10, 0.5, 42);
70//! wiring.build(20); // 20 input features
71//!
72//! // Create CfC RNN layer
73//! let cfc = CfC::<Backend>::with_wiring(20, wiring, &device);
74//!
75//! // Process sequence: [batch=4, seq_len=100, features=20]
76//! let input: Tensor<Backend, 3> = Tensor::zeros([4, 100, 20], &device);
77//! let (output, final_state) = cfc.forward(input, None, None);
78//!
79//! // output: [4, 100, 10] - output at each timestep
80//! // final_state: [4, 64] - hidden state for continuation
81//! ```
82//!
83//! ## Architecture Overview
84//!
85//! ```text
86//! ┌─────────────────────────┐
87//! │ Your Application │
88//! └───────────┬─────────────┘
89//! │
90//! ┌───────────▼─────────────┐
91//! │ RNN Layers (cfc, ltc) │ ◄── Use these!
92//! │ Sequence processing │
93//! └───────────┬─────────────┘
94//! │
95//! ┌───────────▼─────────────┐
96//! │ Cells (cfc_cell, etc) │ ◄── Single timestep
97//! │ Low-level operations │
98//! └───────────┬─────────────┘
99//! │
100//! ┌───────────▼─────────────┐
101//! │ Wirings (ncp, etc) │ ◄── Network structure
102//! │ Connectivity patterns │
103//! └─────────────────────────┘
104//! ```
105//!
106//! ## Module Guide
107//!
108//! | Module | Purpose | Start Here? |
109//! |--------|---------|-------------|
110//! | [`rnn`] | Full RNN layers for sequences | ✅ Yes |
111//! | [`wirings`] | Network connectivity patterns | ✅ Yes |
112//! | [`cells`] | Single-timestep processing | For advanced use |
113//! | [`activation`] | Activation functions | Rarely needed |
114//!
115//! ## Choosing Components
116//!
117//! ### RNN Layer: CfC vs LTC
118//!
119//! | Choose [`CfC`](rnn::CfC) when... | Choose [`LTC`](rnn::LTC) when... |
120//! |----------------------------------|----------------------------------|
121//! | Speed matters | Biological accuracy matters |
122//! | Training large models | Research applications |
123//! | Production deployment | Variable time constants needed |
124//!
125//! ### Wiring: AutoNCP vs NCP vs FullyConnected
126//!
127//! | Choose [`AutoNCP`](wirings::AutoNCP) when... | Choose [`NCP`](wirings::NCP) when... | Choose [`FullyConnected`](wirings::FullyConnected) when... |
128//! |-----------------------------------------------|--------------------------------------|-------------------------------------------------------------|
129//! | Starting out (recommended) | Need exact layer sizes | Need baseline comparison |
130//! | Want automatic configuration | Fine-tuning connectivity | Maximum expressiveness |
131//! | Most use cases | Research/ablation studies | Don't care about sparsity |
132//!
133//! ## Common Patterns
134//!
135//! ### Sequence Classification
136//!
137//! ```ignore
138//! // Only return the final output
139//! let cfc = CfC::<Backend>::with_wiring(input_size, wiring, &device)
140//! .with_return_sequences(false);
141//!
142//! let (output, _) = cfc.forward(input, None, None);
143//! // output: [batch, 1, output_size]
144//! ```
145//!
146//! ### Stateful Processing (streaming)
147//!
148//! ```ignore
149//! // Preserve state across batches
150//! let (out1, state) = cfc.forward(batch1, None, None);
151//! let (out2, state) = cfc.forward(batch2, Some(state), None);
152//! let (out3, state) = cfc.forward(batch3, Some(state), None);
153//! ```
154//!
155//! ### Different Input Formats
156//!
157//! ```ignore
158//! // Sequence-first format: [seq_len, batch, features]
159//! let cfc = CfC::<Backend>::new(input_size, hidden_size, &device)
160//! .with_batch_first(false);
161//! ```
162//!
163//! ## Important: The `.build()` Step
164//!
165//! **All wirings must be built before use:**
166//!
167//! ```rust
168//! use ncps::wirings::{AutoNCP, Wiring};
169//!
170//! let mut wiring = AutoNCP::new(32, 8, 0.5, 42);
171//!
172//! // ❌ Not ready yet - sensory connections don't exist
173//! assert!(!wiring.is_built());
174//!
175//! // ✅ Build with input dimension
176//! wiring.build(16);
177//! assert!(wiring.is_built());
178//!
179//! // Now you can use it with RNN layers
180//! ```
181//!
182//! ## References
183//!
184//! - [Neural Circuit Policies Paper](https://publik.tuwien.ac.at/files/publik_292280.pdf)
185//! - [Closed-form Continuous-time Paper](https://arxiv.org/abs/2106.13898)
186//! - [Original Python Implementation](https://github.com/mlech26l/ncps)
187//!
188//! ## Feature Flags
189//!
190//! This crate uses Burn's backend system. Configure via Burn's features:
191//!
192//! ```toml
193//! # CPU (default)
194//! burn = { version = "0.16", features = ["ndarray"] }
195//!
196//! # GPU (WGPU)
197//! burn = { version = "0.16", features = ["wgpu"] }
198//!
199//! # GPU (Candle)
200//! burn = { version = "0.16", features = ["candle"] }
201//! ```
202
203pub mod activation;
204pub mod cells;
205pub mod rnn;
206pub mod wirings;
207
208pub mod prelude {
209 pub use crate::activation::LeCun;
210 pub use crate::cells::{CfCCell, CfcMode, LSTMCell, LTCCell, MappingMode};
211 pub use crate::rnn::{CfC, LTC};
212 pub use crate::wirings::{AutoNCP, FullyConnected, NCP, Random, Wiring};
213}