use crate::DType;
use numr::error::Result;
use numr::runtime::Runtime;
use numr::sparse::SparseTensor;
use numr::tensor::Tensor;
#[derive(Debug, Clone)]
pub struct GraphData<R: Runtime<DType = DType>> {
pub adjacency: SparseTensor<R>,
pub num_nodes: usize,
pub directed: bool,
}
impl<R: Runtime<DType = DType>> GraphData<R> {
pub fn new(adjacency: SparseTensor<R>, directed: bool) -> Self {
let num_nodes = adjacency.nrows();
Self {
adjacency,
num_nodes,
directed,
}
}
pub fn from_edge_list<T: numr::dtype::Element>(
sources: &[i64],
targets: &[i64],
weights: Option<&[T]>,
num_nodes: usize,
directed: bool,
device: &R::Device,
) -> Result<Self> {
let num_edges = sources.len();
if directed {
let vals: Vec<T> = if let Some(w) = weights {
w.to_vec()
} else {
vec![T::one(); num_edges]
};
let adjacency = SparseTensor::<R>::from_coo_slices(
sources,
targets,
&vals,
[num_nodes, num_nodes],
device,
)?;
let adjacency = adjacency.to_csr()?;
Ok(Self::new(adjacency, directed))
} else {
let mut all_sources = Vec::with_capacity(num_edges * 2);
let mut all_targets = Vec::with_capacity(num_edges * 2);
let mut all_weights = Vec::with_capacity(num_edges * 2);
for i in 0..num_edges {
let w = if let Some(ws) = weights {
ws[i]
} else {
T::one()
};
all_sources.push(sources[i]);
all_targets.push(targets[i]);
all_weights.push(w);
all_sources.push(targets[i]);
all_targets.push(sources[i]);
all_weights.push(w);
}
let adjacency = SparseTensor::<R>::from_coo_slices(
&all_sources,
&all_targets,
&all_weights,
[num_nodes, num_nodes],
device,
)?;
let adjacency = adjacency.to_csr()?;
Ok(Self::new(adjacency, directed))
}
}
}
#[derive(Debug, Clone)]
pub struct ShortestPathResult<R: Runtime<DType = DType>> {
pub distances: Tensor<R>,
pub predecessors: Tensor<R>,
}
#[derive(Debug, Clone)]
pub struct AllPairsResult<R: Runtime<DType = DType>> {
pub distances: Tensor<R>,
pub predecessors: Tensor<R>,
}
#[derive(Debug, Clone)]
pub struct PathResult<R: Runtime<DType = DType>> {
pub distance: f64,
pub path: Tensor<R>,
}
#[derive(Debug, Clone)]
pub struct MSTResult<R: Runtime<DType = DType>> {
pub sources: Tensor<R>,
pub targets: Tensor<R>,
pub weights: Tensor<R>,
pub total_weight: f64,
}
#[derive(Debug, Clone)]
pub struct ComponentResult<R: Runtime<DType = DType>> {
pub labels: Tensor<R>,
pub num_components: usize,
}
#[derive(Debug, Clone)]
pub struct FlowResult<R: Runtime<DType = DType>> {
pub max_flow: f64,
pub flow: Tensor<R>,
}
#[derive(Debug, Clone)]
pub struct EigCentralityOptions {
pub max_iter: usize,
pub tol: f64,
}
impl Default for EigCentralityOptions {
fn default() -> Self {
Self {
max_iter: 100,
tol: 1e-6,
}
}
}
#[derive(Debug, Clone)]
pub struct PageRankOptions {
pub damping: f64,
pub max_iter: usize,
pub tol: f64,
}
impl Default for PageRankOptions {
fn default() -> Self {
Self {
damping: 0.85,
max_iter: 100,
tol: 1e-6,
}
}
}
#[derive(Debug, Clone, Default)]
pub struct MinCostFlowOptions {
pub costs: Option<Vec<f64>>,
pub max_flow: Option<f64>,
}