1use crate::prelude::*;
33use hashbrown::{HashMap, HashSet};
34use itertools::Itertools;
35use std::{
36 hash::Hash,
37 ops::{Deref, DerefMut},
38};
39
40pub mod undirected;
41pub use undirected::*;
42pub mod directed;
43pub use directed::*;
44pub mod linalg;
45pub use linalg::*;
46pub mod common;
47pub use common::*;
48#[cfg(feature = "rayon")]
49pub mod parallel;
50#[cfg(feature = "rayon")]
51pub use parallel::*;
52
53pub trait GraphBasics<'a> {
70 type NodeRef: Eq + Hash + Copy;
71 type EdgeRef: Eq + Hash + Copy;
72
73 type NodeIndex: Copy + Eq + Hash + From<usize> + Into<usize>;
74 type EdgeIndex: Copy + Eq + Hash + From<usize> + Into<usize>;
75
76 fn nodes(&'a self) -> impl Iterator<Item = Self::NodeRef>;
77 fn node_count(&'a self) -> usize;
78
79 fn edges(&'a self) -> impl Iterator<Item = Self::EdgeRef>;
80 fn edge_count(&'a self) -> usize;
81
82 fn is_directed(&self) -> bool;
83 fn node(&'a self, node_index: Self::NodeIndex) -> Option<Self::NodeRef>;
84 fn edge(&'a self, edge_index: Self::EdgeIndex) -> Option<Self::EdgeRef>;
85 fn node_iter(
86 &'a self,
87 node_index: impl Iterator<Item = Self::NodeIndex>,
88 ) -> impl Iterator<Item = Option<Self::NodeRef>>;
89 fn edge_iter(
90 &'a self,
91 edge_index: impl Iterator<Item = Self::EdgeIndex>,
92 ) -> impl Iterator<Item = Option<Self::EdgeRef>>;
93}
94
95#[macro_export]
96macro_rules! impl_graph_basics {
97 ($graph:ty, $node:ty, $edge:ty, $dir:literal $(, <$($gens:tt),*>)? $(, |$(const $cgens:ident: $ity:ty),*|)? ) => {
98 impl<'a, N, E$(, $($gens),*)?$(, $(const $cgens: $ity),*)?> GraphBasics<'a>
100 for $graph
101 where N: 'a + Clone + Eq + Hash,
102 E: 'a + Clone + Eq + Hash,
103 {
104 type NodeRef = $node;
105 type EdgeRef = $edge;
106 type EdgeIndex = usize;
107 type NodeIndex = usize;
108
109 fn nodes(&'a self) -> impl Iterator<Item = Self::NodeRef> {
110 self.nodes.iter()
111 }
112
113 fn edges(&'a self) -> impl Iterator<Item = Self::EdgeRef> {
114 self.edges.iter()
115 }
116 fn node_count(&'a self) -> usize {
117 self.nodes.len()
118 }
119
120 fn edge_count(&'a self) -> usize {
121 self.edges.len()
122 }
123 fn is_directed(&self) -> bool {
124 $dir
125 }
126 fn node(&'a self, node_index: <Self as GraphBasics<'a>>::NodeIndex) -> Option<<Self as GraphBasics<'a>>::NodeRef> {
127 self.nodes.get(node_index)
128 }
129 fn edge(&'a self, edge_index: <Self as GraphBasics<'a>>::EdgeIndex) -> Option<<Self as GraphBasics<'a>>::EdgeRef> {
130 self.edges.get(edge_index)
131 }
132 fn node_iter(&'a self, node_index: impl Iterator<Item = <Self as GraphBasics<'a>>::NodeIndex>) -> impl Iterator<Item = Option<<Self as GraphBasics<'a>>::NodeRef>> {
133 node_index.map(|i| self.node(i))
134 }
135 fn edge_iter(&'a self, edge_index: impl Iterator<Item = <Self as GraphBasics<'a>>::EdgeIndex>) -> impl Iterator<Item = Option<<Self as GraphBasics<'a>>::EdgeRef>> {
136 edge_index.map(|i| self.edge(i))
137 }
138 }
139 };
140}
141
142impl<'a, T, U> GraphBasics<'a> for U
143where
144 T: GraphBasics<'a> + 'a,
145 U: Deref<Target = T>,
146{
147 type NodeRef = T::NodeRef;
148
149 type EdgeRef = T::EdgeRef;
150
151 type NodeIndex = T::NodeIndex;
152
153 type EdgeIndex = T::EdgeIndex;
154
155 fn nodes(&'a self) -> impl Iterator<Item = Self::NodeRef> {
156 (**self).nodes()
157 }
158
159 fn node_count(&'a self) -> usize {
160 (**self).node_count()
161 }
162
163 fn edges(&'a self) -> impl Iterator<Item = Self::EdgeRef> {
164 (**self).edges()
165 }
166
167 fn edge_count(&'a self) -> usize {
168 (**self).edge_count()
169 }
170
171 fn is_directed(&self) -> bool {
172 (**self).is_directed()
173 }
174
175 fn node(&'a self, node_index: Self::NodeIndex) -> Option<Self::NodeRef> {
176 (**self).node(node_index)
177 }
178
179 fn edge(&'a self, edge_index: Self::EdgeIndex) -> Option<Self::EdgeRef> {
180 (**self).edge(edge_index)
181 }
182
183 fn node_iter(
184 &'a self,
185 node_index: impl Iterator<Item = Self::NodeIndex>,
186 ) -> impl Iterator<Item = Option<Self::NodeRef>> {
187 node_index.map(|i| (**self).node(i))
188 }
189
190 fn edge_iter(
191 &'a self,
192 edge_index: impl Iterator<Item = Self::EdgeIndex>,
193 ) -> impl Iterator<Item = Option<Self::EdgeRef>> {
194 edge_index.map(|i| (**self).edge(i))
195 }
196}
197
198pub trait Weights<'a, N: 'a, E: 'a>: GraphBasics<'a> {
204 fn node_weights(&'a self) -> impl Iterator<Item = &'a N> + 'a;
205 fn edge_weights(&'a self) -> impl Iterator<Item = &'a E> + 'a;
206 fn node_weights_mut(&'a mut self) -> impl Iterator<Item = &'a mut N> + 'a;
207 fn edge_weights_mut(&'a mut self) -> impl Iterator<Item = &'a mut E> + 'a;
208 fn node_weight_mut(
209 &'a mut self,
210 node_index: <Self as GraphBasics<'a>>::NodeIndex,
211 ) -> Option<&'a mut N>;
212 fn edge_weight_mut(
213 &'a mut self,
214 edge_index: <Self as GraphBasics<'a>>::EdgeIndex,
215 ) -> Option<&'a mut E>;
216 fn node_weight(&'a self, node_index: <Self as GraphBasics<'a>>::NodeIndex) -> Option<&'a N>;
217 fn edge_weight(&'a self, edge_index: <Self as GraphBasics<'a>>::EdgeIndex) -> Option<&'a E>;
218 unsafe fn node_weight_unchecked(
220 &'a self,
221 node_index: <Self as GraphBasics<'a>>::NodeIndex,
222 ) -> &'a N;
223 unsafe fn edge_weight_unchecked(
224 &'a self,
225 edge_index: <Self as GraphBasics<'a>>::EdgeIndex,
226 ) -> &'a E;
227 unsafe fn node_weight_unchecked_mut(
228 &'a mut self,
229 node_index: <Self as GraphBasics<'a>>::NodeIndex,
230 ) -> &'a mut N;
231 unsafe fn edge_weight_unchecked_mut(
232 &'a mut self,
233 edge_index: <Self as GraphBasics<'a>>::EdgeIndex,
234 ) -> &'a mut E;
235 fn edge_weight_copied(&'a self, edge_index: <Self as GraphBasics<'a>>::EdgeIndex) -> Option<E>
236 where
237 E: Copy;
238 fn node_weight_copied(&'a self, node_index: <Self as GraphBasics<'a>>::NodeIndex) -> Option<N>
239 where
240 N: Copy;
241 unsafe fn edge_weight_copied_unchecked(
242 &'a self,
243 edge_index: <Self as GraphBasics<'a>>::EdgeIndex,
244 ) -> E
245 where
246 E: Copy;
247 unsafe fn node_weight_copied_unchecked(
248 &'a self,
249 node_index: <Self as GraphBasics<'a>>::NodeIndex,
250 ) -> N
251 where
252 N: Copy;
253}
254
255#[macro_export]
256macro_rules! impl_weights {
257 ($graph:ty$(, <$($gens:tt),*>)? $(, |$(const $cgens:ident: $ity:ty),*|)?) => {
258 impl<'a, N: 'a, E: 'a$(, $($gens),*)?$(, $(const $cgens: $ity),*)?> Weights<'a, N, E> for $graph
259 where
260 N: Clone + Eq + Hash,
261 E: Clone + Eq + Hash,
262 {
263 fn node_weights(&'a self) -> impl Iterator<Item = &'a N> + 'a {
264 self.nodes.iter().map(|node| &node.weight)
265 }
266
267 fn edge_weights(&'a self) -> impl Iterator<Item = &'a E> + 'a {
268 self.edges.iter().map(|edge| &edge.weight)
269 }
270
271 fn node_weights_mut(&'a mut self) -> impl Iterator<Item = &'a mut N> + 'a {
272 self.nodes.iter_mut().map(|node| &mut node.weight)
273 }
274
275 fn edge_weights_mut(&'a mut self) -> impl Iterator<Item = &'a mut E> + 'a {
276 self.edges.iter_mut().map(|edge| &mut edge.weight)
277 }
278
279 fn node_weight_mut(&'a mut self, node_index: <Self as GraphBasics<'a>>::NodeIndex) -> Option<&'a mut N> {
280 self.nodes.get_mut(node_index).map(|node| &mut node.weight)
281 }
282
283 fn edge_weight_mut(&'a mut self, edge_index: <Self as GraphBasics<'a>>::EdgeIndex) -> Option<&'a mut E> {
284 self.edges.get_mut(edge_index).map(|edge| &mut edge.weight)
285 }
286
287 fn node_weight(&'a self, node_index: <Self as GraphBasics<'a>>::NodeIndex) -> Option<&'a N> {
288 self.nodes.get(node_index).map(|node| &node.weight)
289 }
290
291 fn edge_weight(&'a self, edge_index: <Self as GraphBasics<'a>>::EdgeIndex) -> Option<&'a E> {
292 self.edges.get(edge_index).map(|edge| &edge.weight)
293 }
294
295 unsafe fn node_weight_unchecked(&'a self, node_index: <Self as GraphBasics<'a>>::NodeIndex) -> &'a N {
296 unsafe {&self.nodes.get_unchecked(node_index).weight}
297 }
298
299 unsafe fn edge_weight_unchecked(&'a self, edge_index: <Self as GraphBasics<'a>>::EdgeIndex) -> &'a E {
300 unsafe {&self.edges.get_unchecked(edge_index).weight}
301 }
302
303 unsafe fn node_weight_unchecked_mut(&'a mut self, node_index: <Self as GraphBasics<'a>>::NodeIndex) -> &'a mut N {
304 unsafe {&mut self.nodes.get_unchecked_mut(node_index).weight}
305 }
306
307 unsafe fn edge_weight_unchecked_mut(&'a mut self, edge_index: <Self as GraphBasics<'a>>::EdgeIndex) -> &'a mut E {
308 unsafe {&mut self.edges.get_unchecked_mut(edge_index).weight}
309 }
310
311 fn edge_weight_copied(&'a self, edge_index: <Self as GraphBasics<'a>>::EdgeIndex) -> Option<E> where E: Copy {
312 Some(self.edges[edge_index].weight)
313 }
314
315 fn node_weight_copied(&'a self, node_index: <Self as GraphBasics<'a>>::NodeIndex) -> Option<N> where N: Copy {
316 Some(self.nodes[node_index].weight)
317 }
318
319 unsafe fn edge_weight_copied_unchecked(&'a self, edge_index: <Self as GraphBasics<'a>>::EdgeIndex) -> E where E: Copy {
320 unsafe{self.edges.get_unchecked(edge_index).weight}
321 }
322
323 unsafe fn node_weight_copied_unchecked(&'a self, node_index: <Self as GraphBasics<'a>>::NodeIndex) -> N where N: Copy {
324 unsafe{self.nodes.get_unchecked(node_index).weight}
325 }
326 }
327
328 }
329}
330
331impl<'a, T: 'a, U, N: 'a, E: 'a> Weights<'a, N, E> for U
332where
333 T: Weights<'a, N, E>,
334 U: DerefMut<Target = T>,
335{
336 fn node_weights_mut(&'a mut self) -> impl Iterator<Item = &'a mut N> + 'a {
337 (**self).node_weights_mut()
338 }
339
340 fn edge_weights_mut(&'a mut self) -> impl Iterator<Item = &'a mut E> + 'a {
341 (**self).edge_weights_mut()
342 }
343
344 fn node_weight_mut(
345 &'a mut self,
346 node_index: <Self as GraphBasics<'a>>::NodeIndex,
347 ) -> Option<&'a mut N> {
348 (**self).node_weight_mut(node_index)
349 }
350
351 fn edge_weight_mut(
352 &'a mut self,
353 edge_index: <Self as GraphBasics<'a>>::EdgeIndex,
354 ) -> Option<&'a mut E> {
355 (**self).edge_weight_mut(edge_index)
356 }
357
358 fn node_weight(&'a self, node_index: <Self as GraphBasics<'a>>::NodeIndex) -> Option<&'a N> {
359 (**self).node_weight(node_index)
360 }
361
362 fn edge_weight(&'a self, edge_index: <Self as GraphBasics<'a>>::EdgeIndex) -> Option<&'a E> {
363 (**self).edge_weight(edge_index)
364 }
365
366 unsafe fn node_weight_unchecked(
367 &'a self,
368 node_index: <Self as GraphBasics<'a>>::NodeIndex,
369 ) -> &'a N {
370 unsafe { (**self).node_weight_unchecked(node_index) }
371 }
372
373 unsafe fn edge_weight_unchecked(
374 &'a self,
375 edge_index: <Self as GraphBasics<'a>>::EdgeIndex,
376 ) -> &'a E {
377 unsafe { (**self).edge_weight_unchecked(edge_index) }
378 }
379
380 unsafe fn node_weight_unchecked_mut(
381 &'a mut self,
382 node_index: <Self as GraphBasics<'a>>::NodeIndex,
383 ) -> &'a mut N {
384 unsafe { (**self).node_weight_unchecked_mut(node_index) }
385 }
386
387 unsafe fn edge_weight_unchecked_mut(
388 &'a mut self,
389 edge_index: <Self as GraphBasics<'a>>::EdgeIndex,
390 ) -> &'a mut E {
391 unsafe { (**self).edge_weight_unchecked_mut(edge_index) }
392 }
393
394 fn edge_weight_copied(&'a self, edge_index: <Self as GraphBasics<'a>>::EdgeIndex) -> Option<E>
395 where
396 E: Copy,
397 {
398 (**self).edge_weight_copied(edge_index)
399 }
400
401 fn node_weight_copied(&'a self, node_index: <Self as GraphBasics<'a>>::NodeIndex) -> Option<N>
402 where
403 N: Copy,
404 {
405 (**self).node_weight_copied(node_index)
406 }
407
408 unsafe fn edge_weight_copied_unchecked(
409 &'a self,
410 edge_index: <Self as GraphBasics<'a>>::EdgeIndex,
411 ) -> E
412 where
413 E: Copy,
414 {
415 unsafe { (**self).edge_weight_copied_unchecked(edge_index) }
416 }
417
418 unsafe fn node_weight_copied_unchecked(
419 &'a self,
420 node_index: <Self as GraphBasics<'a>>::NodeIndex,
421 ) -> N
422 where
423 N: Copy,
424 {
425 unsafe { (**self).node_weight_copied_unchecked(node_index) }
426 }
427
428 fn node_weights(&'a self) -> impl Iterator<Item = &'a N> + 'a {
429 (**self).node_weights()
430 }
431
432 fn edge_weights(&'a self) -> impl Iterator<Item = &'a E> + 'a {
433 (**self).edge_weights()
434 }
435}
436
437#[cfg(feature = "temporal")]
438pub trait TemporalProperties<'a>: GraphBasics<'a> {
439 type Inner: GraphBasics<'a>;
440 fn step(&mut self) {
441 *self.get_time_mut() += 1;
442 }
443 fn get_time(&self) -> usize;
444 fn get_time_mut(&mut self) -> &mut usize;
447
448 fn snapshot(&'a self) -> &'a Self::Inner;
449
450 fn temporal_behaviour(&self, edge_index: <Self as GraphBasics<'a>>::EdgeIndex) -> Option<TemporalBehaviour>;
451}
452
453pub trait HypergraphBasics<'a>: GraphBasics<'a> {
454 fn uniform(&self) -> bool;
458
459 type DualType;
462 fn dual(&self) -> Self::DualType;
463}
464
465pub trait StatisticalFilters {}
466
467pub trait Dynamics {}
468
469pub trait Generate<N, E, T: GraphType> {
470 fn from_file<P: AsRef<std::path::Path>>(path: P) -> Self;
472 fn random_hypergraph(node_count: usize, edges_by_size: HashMap<usize, usize>) -> Self;
474 fn random_weighted_hypergraph(
475 node_count: usize,
476 edges_by_size: HashMap<usize, usize>,
477 node_weight_sampler: impl Fn() -> N,
478 edge_weight_sampler: impl Fn() -> E,
479 ) -> Self;
480}
481