use crate::data::FA2Data;
use crate::layout::FA2Layout;
use crate::traits::Float;
#[derive(Debug, Clone)]
pub(crate) enum RepulsionMode<F: Float> {
Pairwise,
BarnesHut { theta: F },
}
#[derive(Debug, Clone)]
pub struct FA2Settings<F: Float> {
pub(crate) repulsion_mode: RepulsionMode<F>,
pub(crate) edge_weight_influence: F,
pub(crate) gravity: F,
pub(crate) strong_gravity_mode: bool,
pub(crate) scaling_ratio: F,
pub(crate) slow_down: F,
pub(crate) parallel: bool,
}
impl<F: Float> Default for FA2Settings<F> {
fn default() -> Self {
Self {
repulsion_mode: RepulsionMode::Pairwise,
edge_weight_influence: F::one(),
gravity: F::one(),
strong_gravity_mode: false,
scaling_ratio: F::one(),
slow_down: F::one(),
parallel: false,
}
}
}
impl<F: Float> FA2Settings<F> {
pub fn from_graph_order(order: usize) -> Self {
Self {
repulsion_mode: if order >= 2048 {
RepulsionMode::BarnesHut {
theta: F::from(0.5).unwrap(),
}
} else {
RepulsionMode::Pairwise
},
strong_gravity_mode: true,
gravity: F::from(0.05).unwrap(),
scaling_ratio: F::from(10.0).unwrap(),
slow_down: F::one() + F::from(order).unwrap().ln(),
..Default::default()
}
}
pub fn parallel(mut self, yes: bool) -> Self {
self.parallel = yes;
self
}
pub fn with_pairwise_repulsion(mut self) -> Self {
self.repulsion_mode = RepulsionMode::Pairwise;
self
}
pub fn with_barnes_hut_theta(mut self, theta: F) -> Self {
self.repulsion_mode = RepulsionMode::BarnesHut { theta };
self
}
pub fn with_barnes_hut(self) -> Self {
self.with_barnes_hut_theta(F::from(0.5).unwrap())
}
pub(crate) fn unwrap_barnes_hut_theta(&self) -> F {
match &self.repulsion_mode {
RepulsionMode::BarnesHut { theta } => *theta,
_ => panic!("not using barnes hut!"),
}
}
pub fn build(self, data: FA2Data<F>) -> FA2Layout<F> {
FA2Layout::new(self, data)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_from_graph_order() {
let settings = FA2Settings::<f32>::from_graph_order(32);
assert_eq!(settings.slow_down, 4.465736);
let settings = FA2Settings::<f64>::from_graph_order(32);
assert_eq!(settings.slow_down, 4.465735902799727);
}
}