fix(dqn): NaN sort panic, Adam eps per Rainbow paper, dedup DistributionalType

- Fix NaN panic at dqn.rs:1716 with unwrap_or(Ordering::Equal)
- Fix Adam epsilon 1e-8 → 1.5e-4 per Hessel et al. 2018
- Remove duplicate DistributionalType enum from quantile_regression.rs

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
jgrusewski
2026-02-20 14:51:48 +01:00
parent 6007f98c26
commit 3e5db0b377
3 changed files with 4 additions and 23 deletions

View File

@@ -1713,7 +1713,7 @@ impl DQN {
// Log top-5 best actions (shows which actions network prefers)
let mut indexed: Vec<(usize, f32)> = q_vec.iter().enumerate()
.map(|(i, &v)| (i, v)).collect();
indexed.sort_by(|a, b| b.1.partial_cmp(&a.1).unwrap());
indexed.sort_by(|a, b| b.1.partial_cmp(&a.1).unwrap_or(std::cmp::Ordering::Equal));
tracing::info!(
"Top-5 actions: {}",

View File

@@ -309,21 +309,8 @@ pub fn quantile_huber_loss(
quantile_loss?.mean_all()
}
/// Distributional type enum (C51 vs QR-DQN)
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
pub enum DistributionalType {
/// Categorical DQN (C51) - fixed bins
C51,
/// Quantile Regression DQN - adaptive quantiles
QRDQN,
}
impl Default for DistributionalType {
fn default() -> Self {
// Default to QR-DQN for better trading risk modeling
Self::QRDQN
}
}
// Re-export from distributional module (single source of truth)
pub use super::distributional::DistributionalType;
#[cfg(test)]
mod tests {
@@ -337,12 +324,6 @@ mod tests {
assert_eq!(config.kappa, 1.0);
}
#[test]
fn test_distributional_type_default() {
let dist_type = DistributionalType::default();
assert_eq!(dist_type, DistributionalType::QRDQN);
}
#[test]
fn test_sample_uniform_quantiles() -> Result<(), MLError> {
let config = QuantileConfig::default();

View File

@@ -78,7 +78,7 @@ impl RainbowAgent {
lr: config.learning_rate,
beta_1: 0.9,
beta_2: 0.999,
eps: 1e-8,
eps: 1.5e-4, // Rainbow paper (Hessel et al. 2018) standard for distributional stability
weight_decay: None,
amsgrad: false,
};