use std::sync::Arc;
use antecedent_core::Lag;
use antecedent_discovery::{DiscoveryConstraints, MultiDatasetConstraints, TemporalConstraints};
use antecedent_stats::{ConditionalIndependence, WeightedPartialCorrelation, ci_from_name};
use crate::error::CausalError;
pub const DEFAULT_MAX_COND_SIZE: usize = 2;
pub const DEFAULT_ALPHA: f64 = 0.05;
pub const DEFAULT_RPCMCI_MIN_REGIME_LEN: usize = 40;
#[must_use]
pub fn pcmci_constraints(max_lag: u32, alpha: f64) -> DiscoveryConstraints {
DiscoveryConstraints {
temporal: TemporalConstraints {
max_lag: Lag::from_raw(max_lag),
min_lag: Lag::from_raw(1),
},
alpha,
max_cond_size: DEFAULT_MAX_COND_SIZE,
..DiscoveryConstraints::default()
}
}
#[must_use]
pub fn contemporaneous_constraints(max_lag: u32, alpha: f64) -> DiscoveryConstraints {
DiscoveryConstraints {
temporal: TemporalConstraints {
max_lag: Lag::from_raw(max_lag),
min_lag: Lag::CONTEMPORANEOUS,
},
alpha,
max_cond_size: DEFAULT_MAX_COND_SIZE,
..DiscoveryConstraints::default()
}
}
#[must_use]
pub fn static_pc_constraints(alpha: f64, max_cond_size: usize) -> DiscoveryConstraints {
DiscoveryConstraints {
temporal: TemporalConstraints {
max_lag: Lag::CONTEMPORANEOUS,
min_lag: Lag::CONTEMPORANEOUS,
},
alpha,
max_cond_size,
..DiscoveryConstraints::default()
}
}
#[must_use]
pub fn jpcmci_constraints(
max_lag: u32,
alpha: f64,
multi_dataset: MultiDatasetConstraints,
) -> DiscoveryConstraints {
let mut c = contemporaneous_constraints(max_lag, alpha);
c.multi_dataset = multi_dataset;
c
}
pub fn resolve_ci(
name: &str,
weights: Option<Vec<f64>>,
) -> Result<Arc<dyn ConditionalIndependence + Send + Sync>, CausalError> {
let key = name.trim().to_ascii_lowercase();
if matches!(key.as_str(), "weighted_parcorr" | "weighted_partial_corr") {
let Some(w) = weights else {
return Err(CausalError::Compile {
message: "weights required when ci='weighted_parcorr'".into(),
});
};
return Ok(Arc::new(WeightedPartialCorrelation::new(w)));
}
if weights.is_some() {
return Err(CausalError::Compile {
message: "observation weights are only supported when ci='weighted_parcorr'".into(),
});
}
ci_from_name(name).map_err(|e| CausalError::Compile { message: e.to_string() })
}