//! LogCoshLoss Demonstration and Examples //! //! This module provides comprehensive examples and demonstrations of the LogCoshLoss //! implementation, showcasing its key features and usage patterns. use super::{LogCoshLoss, LogCoshLossBuilder, Loss, Reduction, LossCharacteristics, LossComparison}; use rtx_tensor::{Tensor, Device}; use crate::Result; /// Comprehensive demonstration of LogCoshLoss features pub fn demonstrate_logcosh_loss() -> Result<()> { println!("LogCoshLoss Demonstration"); println!("========================"); let device = Device::cuda(0).unwrap_or(Device::default()); // Basic usage println!("\n1. Basic Usage:"); let loss = LogCoshLoss::new(); let predictions = Tensor::from_data(vec![1.0, 2.0, 3.0], [3], &device)?; let targets = Tensor::from_data(vec![1.2, 1.8, 3.5], [3], &device)?; let loss_value = loss.forward(&predictions, &targets)?; println!("Basic loss value: {}", loss_value.to_cpu()?[0]); // Builder pattern println!("\n2. Builder Pattern:"); let custom_loss = LogCoshLoss::builder() .reduction(Reduction::Sum) .build(); let sum_loss = custom_loss.forward(&predictions, &targets)?; println!("Sum reduction loss: {}", sum_loss.to_cpu()?[0]); // Different reduction modes println!("\n3. Reduction Modes:"); for reduction in [Reduction::None, Reduction::Mean, Reduction::Sum] { let loss = LogCoshLoss::new().with_reduction(reduction); let result = loss.forward(&predictions, &targets)?; println!("{:?} reduction: {:?}", reduction, result.to_cpu()?); } // Mathematical properties println!("\n4. Mathematical Properties:"); let loss = LogCoshLoss::new(); for error in [0.0, 0.1, 0.5, 1.0, 2.0, 5.0, 10.0] { let characteristics = loss.get_characteristics(error); println!("Error {}: Loss={:.6}, Grad={:.6}, Quadratic={}, Linear={}", error, characteristics.loss_value, characteristics.derivative, characteristics.is_quadratic_region, characteristics.is_linear_region); } // Numerical stability println!("\n5. Numerical Stability:"); let large_errors = vec![50.0, 100.0, 1000.0]; for &error in &large_errors { let loss_val = loss.compute_single_loss(error); let expected_linear = error - 2.0f32.ln(); println!("Error {}: LogCosh={:.6}, Linear approx={:.6}, Diff={:.6}", error, loss_val, expected_linear, (loss_val - expected_linear).abs()); } // Gradient verification println!("\n6. Gradient Verification:"); for error in [0.1, 1.0, 5.0] { let analytical = loss.derivative(error); let numerical = loss.numerical_gradient(error, 1e-5); let error_pct = ((analytical - numerical) / analytical).abs() * 100.0; println!("Error {}: Analytical={:.6}, Numerical={:.6}, Error={:.3}%", error, analytical, numerical, error_pct); } Ok(()) } /// Demonstrate comparison with other loss functions pub fn demonstrate_loss_comparisons() { println!("\nLoss Function Comparisons"); println!("========================"); // Test with various error patterns let small_errors = vec![0.01, 0.05, 0.1, 0.2, 0.3]; let large_errors = vec![1.0, 2.0, 5.0, 10.0, 20.0]; let mixed_errors = vec![0.1, 0.5, 1.0, 3.0, 10.0, 0.2, 15.0]; println!("\n1. LogCosh vs MSE (Small Errors):"); let small_comparison = LossComparison::logcosh_vs_mse(&small_errors); println!("LogCosh mean: {:.6}, MSE mean: {:.6}", small_comparison.logcosh_mean, small_comparison.comparison_mean); println!("Robustness ratio: {:.3}, Recommendation: {}", small_comparison.robustness_ratio, small_comparison.recommendation); println!("\n2. LogCosh vs MSE (Large Errors):"); let large_comparison = LossComparison::logcosh_vs_mse(&large_errors); println!("LogCosh mean: {:.6}, MSE mean: {:.6}", large_comparison.logcosh_mean, large_comparison.comparison_mean); println!("Robustness ratio: {:.3}, Recommendation: {}", large_comparison.robustness_ratio, large_comparison.recommendation); println!("\n3. LogCosh vs Huber (Mixed Errors):"); let huber_comparison = LossComparison::logcosh_vs_huber(&mixed_errors, 1.0); println!("LogCosh mean: {:.6}, Huber mean: {:.6}", huber_comparison.logcosh_mean, huber_comparison.comparison_mean); println!("Robustness ratio: {:.3}, Recommendation: {}", huber_comparison.robustness_ratio, huber_comparison.recommendation); } /// Demonstrate advanced features pub fn demonstrate_advanced_features() -> Result<()> { println!("\nAdvanced Features"); println!("================"); let device = Device::cuda(0).unwrap_or(Device::default()); let loss = LogCoshLoss::new(); // Weighted loss computation println!("\n1. Weighted Loss:"); let predictions = Tensor::from_data(vec![1.0, 2.0, 3.0, 4.0], [4], &device)?; let targets = Tensor::from_data(vec![1.1, 1.9, 3.2, 3.8], [4], &device)?; let weights = Tensor::from_data(vec![1.0, 2.0, 0.5, 1.5], [4], &device)?; let unweighted = loss.forward(&predictions, &targets)?; let weighted = loss.forward_weighted(&predictions, &targets, Some(&weights))?; println!("Unweighted loss: {:.6}", unweighted.to_cpu()?[0]); println!("Weighted loss: {:.6}", weighted.to_cpu()?[0]); // Adaptive loss with delta parameter println!("\n2. Adaptive Loss:"); for delta in [0.5, 1.0, 2.0] { let adaptive_loss = loss.forward_adaptive(&predictions, &targets, delta)?; println!("Delta {}: Adaptive loss = {:.6}", delta, adaptive_loss.to_cpu()?[0]); } // Loss statistics println!("\n3. Loss Statistics:"); let stats = loss.compute_loss_statistics(&predictions, &targets)?; println!("Samples: {}, Mean loss: {:.6}, Variance: {:.6}", stats.num_samples, stats.mean_loss, stats.loss_variance); println!("Quadratic region: {:.1}%, Linear region: {:.1}%", stats.quadratic_region_fraction * 100.0, stats.linear_region_fraction * 100.0); // Forward with characteristics println!("\n4. Forward with Characteristics:"); let (loss_val, characteristics) = loss.forward_with_characteristics(&predictions, &targets)?; println!("Total loss: {:.6}", loss_val.to_cpu()?[0]); for (i, char) in characteristics.iter().enumerate() { println!("Sample {}: Error={:.3}, Loss={:.6}, In quadratic region={}", i, char.error, char.loss_value, char.is_quadratic_region); } Ok(()) } /// Run all demonstrations pub fn run_all_demonstrations() -> Result<()> { demonstrate_logcosh_loss()?; demonstrate_loss_comparisons(); demonstrate_advanced_features()?; Ok(()) } #[cfg(all(test, feature = "disabled_tests"))] mod demo_tests { use super::*; #[test] fn test_demonstrations_run() { // These would normally run the demonstrations // For now, just test that the demo functions compile assert!(true); } }