graphembed/embed/gkernel/pgraph.rs
1//! This module describes Edge and Node data we use in petgraph in an implementation of a nodesketch type algorithm.
2//!
3//! Nodes can have multiple discrete labels to modelize multi communities membership and various relations
4//! between nodes.
5//! Edges can be directed or not and can have at most one discrete label, but there can be many edges between 2 given nodes
6//! Edge can also have a weight, by default set 1.
7//!
8use std::cmp::Eq;
9use std::hash::Hash;
10
11// use std::fmt::Display;
12
13use probminhash::probminhasher::*;
14/// Our labels must satisfy this trait.
15///
16/// - For having String as possible labels we need Clone.
17///
18/// - To hash strings or Vectors with sha2 crate we must be able to associate to labels something statisfying a Vec\<u8\>.
19/// This is provided by Sig (and is required by Probminhash3sha which do not need copy on items hashed)
20pub trait LabelT: Send + Sync + Eq + Hash + Clone + Default + std::fmt::Debug + sig::Sig {}
21
22impl LabelT for u8 {}
23impl LabelT for u16 {}
24impl LabelT for u32 {}
25impl LabelT for u64 {}
26impl LabelT for i32 {}
27impl LabelT for i16 {}
28impl LabelT for String {}
29
30/// A label type encoding a couple of Node label and edge label representing a transiiton from/to a node via a labelled edge
31
32#[derive(Clone, Debug, Hash, PartialEq, Eq, Default)]
33pub struct NElabel<Nlabel, Elabel>(pub(crate) Nlabel, pub(crate) Elabel);
34
35impl<Nlabel, Elabel> sig::Sig for NElabel<Nlabel, Elabel>
36where
37 Nlabel: LabelT,
38 Elabel: LabelT,
39{
40 fn get_sig(&self) -> Vec<u8> {
41 let mut s = self.0.get_sig().clone();
42 s.append(&mut self.1.get_sig().clone());
43 s
44 }
45} // end of impl Sig for NElabel
46
47/// defines associated data to a Node.
48/// A node can have many (discrete) labels (may be participate in many communities).
49#[derive(Clone, Debug)]
50pub struct Nweight<Nlabel> {
51 /// memberships
52 labels: Vec<Nlabel>,
53}
54
55impl<Nlabel> Nweight<Nlabel>
56where
57 Nlabel: LabelT,
58{
59 //
60 pub fn new(labels: Vec<Nlabel>) -> Self {
61 Nweight { labels }
62 }
63 /// has_label ?
64 pub fn has_label(&self, label: &Nlabel) -> bool {
65 self.labels.iter().any(|l| l == label)
66 }
67
68 pub fn get_labels(&self) -> &[Nlabel] {
69 &self.labels
70 }
71} // end of Nweight
72
73//===================================================================================
74
75/// Our edge label, called Eweight as petgraph items attached to an entity is called a weight.
76/// The edge has a f32 weight which defaults to 1.
77/// Edges may have discrete labels attached to it, initialized via the label option argument.
78pub struct Eweight<Elabel> {
79 /// edge type/data
80 label: Option<Elabel>,
81 //
82 weight: f32,
83}
84
85impl<Elabel> Eweight<Elabel>
86where
87 Elabel: LabelT,
88{
89 pub fn new(label: Option<Elabel>, weight: f32) -> Self {
90 Eweight { label, weight }
91 }
92
93 // retrieve the label of the edge
94 pub fn get_label(&self) -> Option<&Elabel> {
95 self.label.as_ref()
96 }
97
98 /// retrieves edge weight
99 pub fn get_weight(&self) -> f32 {
100 self.weight
101 }
102} // end of Eweight
103
104/// Data associated to an edge should satisfy Default and so Eweight\<Elabel\> should satisfy Default.
105impl<Elabel> Default for Eweight<Elabel>
106where
107 Elabel: LabelT,
108{
109 fn default() -> Self {
110 Eweight {
111 label: None,
112 weight: 1.,
113 }
114 }
115}
116
117//=============================================================================
118
119/// A structure defining a node must implement this trait. See examples in gkernel::exio
120pub trait HasNweight<Nlabel: LabelT> {
121 fn get_nweight(&self) -> &Nweight<Nlabel>;
122}
123
124/// A structure defining an edge must implement this trait. See examples in gkernel::exio
125pub trait HasEweight<Elabel: LabelT> {
126 fn get_eweight(&self) -> &Eweight<Elabel>;
127}