use kizzasi_tokenizer::{LinearQuantizer, MuLawCodec, Quantizer, SignalTokenizer};
use scirs2_core::ndarray::Array1;
fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("=== Basic Quantizer Examples ===\n");
println!("1. Linear Quantizer (8-bit)");
println!("----------------------------");
let quantizer = LinearQuantizer::new(-1.0, 1.0, 8)?;
println!("Created quantizer with {} levels", quantizer.num_levels());
let signal = Array1::from_vec(vec![0.0, 0.25, 0.5, 0.75, 1.0, -0.25, -0.5, -0.75, -1.0]);
println!("Original signal: {:?}", signal);
let encoded = quantizer.encode(&signal)?;
println!("Encoded tokens: {:?}", encoded);
let decoded = quantizer.decode(&encoded)?;
println!("Decoded signal: {:?}", decoded);
let error: f32 = signal
.iter()
.zip(decoded.iter())
.map(|(a, b)| (a - b).powi(2))
.sum::<f32>()
/ signal.len() as f32;
println!("Mean Squared Error: {:.6}\n", error);
println!("2. μ-law Codec (Logarithmic)");
println!("----------------------------");
let mulaw = MuLawCodec::new(8);
println!("Created μ-law codec with μ={}", mulaw.mu());
let signal = Array1::from_vec(vec![
0.0, 0.01, 0.05, 0.1, 0.2, 0.5, 0.8, 1.0, -0.01, -0.05, -0.1, -0.2, -0.5, -0.8, -1.0,
]);
println!("Original signal: {:?}", signal);
let encoded = mulaw.encode(&signal)?;
println!("Encoded tokens: {:?}", encoded);
let decoded = mulaw.decode(&encoded)?;
println!("Decoded signal: {:?}", decoded);
let small_signal_idx = 1; let large_signal_idx = 7; let small_error = (signal[small_signal_idx] - decoded[small_signal_idx]).abs();
let large_error = (signal[large_signal_idx] - decoded[large_signal_idx]).abs();
println!("Error for small signal (0.01): {:.6}", small_error);
println!("Error for large signal (1.0): {:.6}", large_error);
println!(
"μ-law provides better resolution for small signals (relative error: {:.2}% vs {:.2}%)\n",
(small_error / signal[small_signal_idx].abs()) * 100.0,
(large_error / signal[large_signal_idx].abs()) * 100.0
);
println!("3. Linear vs μ-law Comparison");
println!("------------------------------");
let n_samples = 100;
let sine_wave: Array1<f32> = Array1::from_vec(
(0..n_samples)
.map(|i| (2.0 * std::f32::consts::PI * i as f32 / n_samples as f32).sin() * 0.5)
.collect(),
);
let linear_quantizer = LinearQuantizer::new(-1.0, 1.0, 8)?;
let mulaw_codec = MuLawCodec::new(8);
let linear_decoded = linear_quantizer.decode(&linear_quantizer.encode(&sine_wave)?)?;
let mulaw_decoded = mulaw_codec.decode(&mulaw_codec.encode(&sine_wave)?)?;
let compute_snr = |original: &Array1<f32>, reconstructed: &Array1<f32>| -> f32 {
let signal_power: f32 = original.iter().map(|x| x.powi(2)).sum();
let noise_power: f32 = original
.iter()
.zip(reconstructed.iter())
.map(|(a, b)| (a - b).powi(2))
.sum();
10.0 * (signal_power / noise_power).log10()
};
let linear_snr = compute_snr(&sine_wave, &linear_decoded);
let mulaw_snr = compute_snr(&sine_wave, &mulaw_decoded);
println!("Sine wave SNR with Linear quantizer: {:.2} dB", linear_snr);
println!("Sine wave SNR with μ-law codec: {:.2} dB", mulaw_snr);
println!("\n4. Effect of Bit Depth");
println!("----------------------");
for bits in [4, 6, 8, 10, 12] {
let quantizer = LinearQuantizer::new(-1.0, 1.0, bits)?;
let decoded = quantizer.decode(&quantizer.encode(&sine_wave)?)?;
let snr = compute_snr(&sine_wave, &decoded);
println!("{:2}-bit quantization: SNR = {:.2} dB", bits, snr);
}
Ok(())
}