optirs-learned 0.3.1

OptiRS learned optimizers and meta-learning
Documentation
use std::fmt::Debug;
// Differentiable neural architecture search
//
// This module implements differentiable NAS approaches like DARTS,
// where architecture parameters are optimized using gradient descent.

use scirs2_core::numeric::Float;
use std::collections::HashMap;

use super::super::architecture::ArchitectureCandidate;

/// Differentiable NAS state
#[derive(Debug)]
pub struct DifferentiableNASState<T: Float + Debug + Send + Sync + 'static> {
    /// Architecture parameters (α)
    pub arch_parameters: Vec<T>,

    /// Model weights (w)
    pub model_weights: Vec<T>,

    /// Mixed operation weights
    pub mixed_op_weights: HashMap<String, Vec<T>>,

    /// Training configuration
    pub config: DARTSConfig,

    /// Current epoch
    pub current_epoch: usize,

    /// Loss history
    pub loss_history: Vec<T>,
}

/// DARTS configuration
#[derive(Debug, Clone)]
pub struct DARTSConfig {
    /// Learning rate for architecture parameters
    pub arch_lr: f64,

    /// Learning rate for model weights
    pub weight_lr: f64,

    /// Weight decay
    pub weight_decay: f64,

    /// Momentum
    pub momentum: f64,

    /// Temperature for Gumbel softmax
    pub temperature: f64,

    /// Number of epochs
    pub epochs: usize,
}

impl Default for DARTSConfig {
    fn default() -> Self {
        Self {
            arch_lr: 3e-4,
            weight_lr: 0.025,
            weight_decay: 3e-4,
            momentum: 0.9,
            temperature: 1.0,
            epochs: 50,
        }
    }
}

impl<T: Float + Debug + Default + std::fmt::Debug + Send + Sync> DifferentiableNASState<T> {
    pub fn new() -> Self {
        Self {
            arch_parameters: Vec::new(),
            model_weights: Vec::new(),
            mixed_op_weights: HashMap::new(),
            config: DARTSConfig::default(),
            current_epoch: 0,
            loss_history: Vec::new(),
        }
    }

    /// Generate discrete architecture from continuous parameters
    pub fn generate_architecture(&self) -> Result<ArchitectureCandidate, super::SearchError> {
        use super::super::architecture::{ArchitectureSpec, LayerSpec, LayerDimensions, LayerType, ActivationType, GlobalArchitectureConfig};

        // Simplified architecture generation from parameters
        let layers = vec![
            LayerSpec::new(
                LayerType::Linear,
                LayerDimensions { input_dim: 128, output_dim: 64, hidden_dims: vec![] },
                ActivationType::ReLU,
            )
        ];

        let arch_spec = ArchitectureSpec::new(layers, GlobalArchitectureConfig::default());
        Ok(ArchitectureCandidate::new("darts_arch".to_string(), arch_spec))
    }
}

/// Progressive search state
#[derive(Debug)]
pub struct ProgressiveSearchState<T: Float + Debug + Send + Sync + 'static> {
    /// Current search phase
    pub current_phase: usize,

    /// Phases configuration
    pub phases: Vec<SearchPhase>,

    /// Candidates from previous phases
    pub phase_candidates: HashMap<usize, Vec<ArchitectureCandidate>>,

    /// Progressive parameters
    _phantom: std::marker::PhantomData<T>,
}

/// Search phase configuration
#[derive(Debug, Clone)]
pub struct SearchPhase {
    /// Phase name
    pub name: String,

    /// Search space for this phase
    pub search_space_size: usize,

    /// Number of candidates to evaluate
    pub num_candidates: usize,

    /// Phase duration (epochs/iterations)
    pub duration: usize,
}

impl<T: Float + Debug + Default + std::fmt::Debug + Send + Sync> ProgressiveSearchState<T> {
    pub fn new() -> Self {
        let phases = vec![
            SearchPhase {
                name: "coarse".to_string(),
                search_space_size: 1000,
                num_candidates: 100,
                duration: 10,
            },
            SearchPhase {
                name: "fine".to_string(),
                search_space_size: 10000,
                num_candidates: 50,
                duration: 20,
            },
        ];

        Self {
            current_phase: 0,
            phases,
            phase_candidates: HashMap::new(),
            _phantom: std::marker::PhantomData,
        }
    }
}

/// Multi-objective state
#[derive(Debug)]
pub struct MultiObjectiveState<T: Float + Debug + Send + Sync + 'static> {
    /// Pareto front
    pub pareto_front: Vec<ArchitectureCandidate>,

    /// Objective functions
    pub objectives: Vec<String>,

    /// Multi-objective algorithm
    pub algorithm: MultiObjectiveAlgorithm,

    /// Parameters
    _phantom: std::marker::PhantomData<T>,
}

/// Multi-objective algorithms
#[derive(Debug, Clone, Copy)]
pub enum MultiObjectiveAlgorithm {
    NSGA2,
    SPEA2,
    MOEAD,
    ParEGO,
}

impl<T: Float + Debug + Default + std::fmt::Debug + Send + Sync> MultiObjectiveState<T> {
    pub fn new() -> Self {
        Self {
            pareto_front: Vec::new(),
            objectives: vec!["performance".to_string(), "efficiency".to_string()],
            algorithm: MultiObjectiveAlgorithm::NSGA2,
            _phantom: std::marker::PhantomData,
        }
    }
}