#[derive(Debug, Clone)]
#[allow(dead_code)]
pub struct GraphData {
pub(crate) n: usize,
pub(crate) out_offsets: Vec<usize>,
pub(crate) out_targets: Vec<usize>,
pub(crate) out_weights: Vec<f64>,
pub(crate) total_weight: f64,
pub(crate) out_degree: Vec<f64>,
pub(crate) node_weight: Vec<f64>,
pub(crate) directed: bool,
pub(crate) in_offsets: Vec<usize>,
pub(crate) in_targets: Vec<usize>,
pub(crate) in_weights: Vec<f64>,
pub(crate) in_degree: Vec<f64>,
}
impl GraphData {
pub fn node_count(&self) -> usize {
self.n
}
pub fn total_weight(&self) -> f64 {
self.total_weight
}
pub fn total_node_weight(&self) -> f64 {
self.node_weight.iter().sum()
}
pub fn is_directed(&self) -> bool {
self.directed
}
#[inline]
pub fn neighbors(&self, node: usize) -> impl Iterator<Item = (usize, f64)> + '_ {
let start = self.out_offsets[node];
let end = self.out_offsets[node + 1];
self.out_targets[start..end]
.iter()
.zip(self.out_weights[start..end].iter())
.map(|(&t, &w)| (t, w))
}
#[inline]
pub fn neighbor_slices(&self, node: usize) -> (&[usize], &[f64]) {
let start = self.out_offsets[node];
let end = self.out_offsets[node + 1];
(&self.out_targets[start..end], &self.out_weights[start..end])
}
#[inline]
pub fn degree_of(&self, node: usize) -> f64 {
if self.directed {
self.out_degree[node] + self.in_degree[node]
} else {
self.out_degree[node]
}
}
#[inline]
pub fn node_weight(&self, node: usize) -> f64 {
self.node_weight[node]
}
#[inline]
pub fn out_neighbors(&self, node: usize) -> impl Iterator<Item = (usize, f64)> + '_ {
let start = self.out_offsets[node];
let end = self.out_offsets[node + 1];
self.out_targets[start..end]
.iter()
.zip(self.out_weights[start..end].iter())
.map(|(&t, &w)| (t, w))
}
#[inline]
pub fn out_neighbor_slices(&self, node: usize) -> (&[usize], &[f64]) {
let start = self.out_offsets[node];
let end = self.out_offsets[node + 1];
(&self.out_targets[start..end], &self.out_weights[start..end])
}
#[inline]
pub fn out_degree_of(&self, node: usize) -> f64 {
self.out_degree[node]
}
#[inline]
pub fn in_neighbors(&self, node: usize) -> impl Iterator<Item = (usize, f64)> + '_ {
let (targets, weights) = self.in_neighbor_slices(node);
targets.iter().zip(weights.iter()).map(|(&t, &w)| (t, w))
}
#[inline]
pub fn in_neighbor_slices(&self, node: usize) -> (&[usize], &[f64]) {
if self.directed && node < self.in_offsets.len() - 1 {
let start = self.in_offsets[node];
let end = self.in_offsets[node + 1];
(&self.in_targets[start..end], &self.in_weights[start..end])
} else {
(&[], &[])
}
}
#[inline]
pub fn in_degree_of(&self, node: usize) -> f64 {
if self.directed && node < self.in_degree.len() {
self.in_degree[node]
} else {
0.0
}
}
}