1crate::ix!();
2
3#[derive(Clone)]
20pub struct ICentralWorkspace {
21 parents: ParentsMap,
22 distances: DistanceMap,
23 deltas: DeltaMap,
24 new_deltas: DeltaMap,
25 capital_deltas: DeltaMap,
26 new_capital_deltas: DeltaMap,
27 sigmas: SigmaMap,
28 new_sigmas: SigmaMap,
29 inc_sigmas: SigmaMap,
30 visit_markers: VisitMarkers,
31 stack: NodeIdStack,
32}
33
34impl Default for ICentralWorkspace {
35
36 fn default() -> Self {
37 Self::empty("default_icentral_workspace")
38 }
39}
40
41delegate_to_parents![ICentralWorkspace];
42delegate_to_visit_markers![ICentralWorkspace];
43delegate_to_bfs_stack![ICentralWorkspace];
44
45delegate_to_distances![ICentralWorkspace];
46
47delegate_to_sigmas![ICentralWorkspace];
48delegate_to_sigmas![ICentralWorkspace; new_sigmas];
49delegate_to_sigmas![ICentralWorkspace; inc_sigmas];
50
51delegate_to_deltas![ICentralWorkspace];
52delegate_to_deltas![ICentralWorkspace; new_deltas];
53delegate_to_deltas![ICentralWorkspace; capital_deltas];
54delegate_to_deltas![ICentralWorkspace; new_capital_deltas];
55
56impl ICentralWorkspace {
57
58 pub fn new_sigmas(&self) -> &SigmaMap {
59 &self.new_sigmas
60 }
61
62 pub fn sigmas(&self) -> &SigmaMap {
63 &self.sigmas
64 }
65
66 pub fn set_new_sigmas_from(&mut self, other: &SigmaMap) {
67 self.new_sigmas = other.clone();
68 }
69
70 pub fn fix_order_of_workspace_stack(&mut self)
81 {
82 for i in 1..self.stack.len() {
83
84 let im1 = self.stack_node_at_index(i - 1);
85 let i0 = self.stack_node_at_index(i);
86
87 if self.distance(im1) > self.distance(i0) {
88
89 let mut j: usize = i;
90
91 let jm1 = self.stack_node_at_index(j - 1);
92 let j0 = self.stack_node_at_index(j);
93
94 while self.distance(jm1) > self.distance(j0) {
95
96 let tmp: NodeId = self.stack_node_at_index(j - 1);
97
98 self.stack_set_node_at_index(
99 j - 1,
100 self.stack_node_at_index(j)
101 );
102
103 self.stack_set_node_at_index(j, tmp);
104
105 j -= 1;
106 }
107 }
108 }
109 }
110
111 pub fn compute_new_path_counts_and_paths(
112 &mut self,
113 src: NodeId,
114 dst: NodeId)
115 {
116 if !self.distance_is_one_step_away(dst,src) {
117
118 self.clear_node_parents(dst);
119
120 self.add_parent(dst,src);
121
122 self.set_sigma_value_for_node(
123 dst,
124 self.sigma_value_for_node(src)
125 );
126
127 } else {
128
129 self.add_parent(dst,src);
130
131 self.increment_sigma_value_for_node(
132 dst,
133 self.sigma_value_for_node(src)
134 );
135 }
136 }
137
138 pub fn update_for_partial_bbfs_addition(&mut self,
139 queue: &mut NodeIdQueue,
140 w: NodeId,
141 v: NodeId)
142 {
143 if self.distance_is_farther_than_one_away(w,v) {
144
145 self.set_distance_one_step_away(w,v);
146
147 self.clear_node_parents(w);
148
149 self.add_parent(w,v);
150
151 self.sigma_set_node_to_zero(w);
152
153 self.inc_sigmas_set_sigma_value_for_node(
154 w,
155 self.inc_sigmas_sigma_value_for_node(v)
156 );
157
158 self.increment_sigma_value_for_node(
159 w,
160 self.inc_sigmas_sigma_value_for_node(w)
161 );
162
163 if self.unvisited(w) {
164
165 self.visit(w);
166
167 queue.enqueue(w);
168 }
169
170 } else {
171
172 if self.distance_is_one_step_away(w,v) {
173
174 self.inc_sigmas_set_sigma_value_for_node(
175 w,
176 self.inc_sigmas_sigma_value_for_node(v)
177 );
178
179 self.increment_sigma_value_for_node(
180 w,
181 self.inc_sigmas_sigma_value_for_node(v)
182 );
183
184 if !self.has_parent(w,v) {
185 self.add_parent(w,v);
186 }
187
188 if self.unvisited(w) {
189 self.visit(w);
190 queue.enqueue(w);
191 }
192 }
193 }
194 }
195
196 pub fn deltas(&self) -> &DeltaMap {
197 &self.deltas
198 }
199
200 pub fn get_new_delta_ratio(&self,
201 v_p: NodeId,
202 v_n: NodeId) -> f64
203 {
204 self.new_deltas_delta_ratio(v_p, v_n)
205 }
206
207 pub fn set_deltas_from_new_deltas(&mut self) {
208 self.deltas = self.new_deltas.clone();
209 }
210
211 pub fn set_sigmas_from_other(&mut self, new: &SigmaMap) {
212 self.sigmas = new.clone();
213 }
214
215 pub fn get_sigma_ratio(&self,
216 v_p: NodeId,
217 v_n: NodeId) -> f64
218 {
219 self.sigma_ratio(v_p, v_n)
220 }
221
222 pub fn get_new_sigma_ratio(&self,
223 v_p: NodeId,
224 v_n: NodeId) -> f64
225 {
226 self.new_sigmas_sigma_ratio(v_p, v_n)
227 }
228
229 pub fn update_new_capital_deltas_with_new_delta_ratio(
230 &mut self,
231 v_p: NodeId,
232 v_n: NodeId)
233 {
234 let new_sp_sn = self.get_new_delta_ratio(v_p,v_n);
235
236 let t0 = self.new_capital_deltas_delta_value_for_node(v_p);
237 let t1 = self.new_capital_deltas_delta_value_for_node(v_n);
238
239 self.new_capital_deltas_set_delta_value_for_node(
240 v_p,
241 t0 + t1 * new_sp_sn
242 );
243 }
244
245 pub fn update_new_capital_deltas_with_new_sigma_ratio(
246 &mut self,
247 v_p: NodeId,
248 v_n: NodeId)
249 {
250 let sp_sn = self.get_new_sigma_ratio(v_p,v_n);
251
252 let ndp = self.new_capital_deltas_delta_value_for_node(v_p);
253 let ndn = self.new_capital_deltas_delta_value_for_node(v_n);
254
255 self.new_capital_deltas_set_delta_value_for_node(
256 v_p,
257 ndp + ndn * sp_sn
258 );
259 }
260
261 pub fn update_new_deltas_with_new_delta_ratio(
262 &mut self,
263 v_p: NodeId,
264 v_n: NodeId)
265 {
266 let new_sp_sn = self.get_new_delta_ratio(v_p,v_n);
267
268 let ndp = self.new_deltas_delta_value_for_node(v_p);
269 let ndn = self.new_deltas_delta_value_for_node(v_n);
270 let one_p_ndn = 1.0 + ndn;
271
272 self.new_deltas_set_delta_value_for_node(
273 v_p,
274 ndp + new_sp_sn * one_p_ndn
275 );
276 }
277
278 pub fn update_new_deltas_with_new_sigma_ratio(
279 &mut self,
280 v_p: NodeId,
281 v_n: NodeId)
282 {
283 let sp_sn = self.get_new_sigma_ratio(v_p, v_n);
284 let ndp = self.new_deltas_delta_value_for_node(v_p);
285 let ndn = self.new_deltas_delta_value_for_node(v_n);
286 let one_p_ndn = 1.0 + ndn;
287
288 self.new_deltas_set_delta_value_for_node(
289 v_p,
290 ndp + sp_sn * one_p_ndn
291 );
292 }
293
294 pub fn maybe_update_capital_deltas(&mut self,
295 component: &Component,
296 source: NodeId,
297 v_p: NodeId,
298 v_n: NodeId)
299 {
300 if component.has_articulation_point(source) {
301
302 self.update_capital_deltas(v_p,v_n);
303 }
304 }
305
306 pub fn maybe_update_new_capital_deltas(&mut self,
307 component: &Component,
308 source: NodeId,
309 v_p: NodeId,
310 v_n: NodeId)
311 {
312 if component.has_articulation_point(source) {
313
314 self.update_new_capital_deltas_with_new_sigma_ratio(v_p,v_n);
316 }
317 }
318
319 pub fn update_capital_deltas(&mut self, v_p: NodeId, v_n: NodeId) {
320
321 let sp_sn = self.get_sigma_ratio(v_p,v_n);
322
323 let dp = self.capital_deltas_delta_value_for_node(v_p);
324 let dn = self.capital_deltas_delta_value_for_node(v_n);
325
326 let dn_by_sp_sn = dn * sp_sn;
327
328 self.capital_deltas_set_delta_value_for_node(
329 v_p,
330 dp + dn_by_sp_sn
331 );
332 }
333
334 pub fn update_deltas_for_each_p(
335 &mut self,
336 component: &Component,
337 source: NodeId,
338 v_n: NodeId)
339 {
340 for &v_p in self.parents_for_node(v_n).iter() {
341
342 self.update_all_deltas_for_component(
343 component,
344 source,
345 v_p,
346 v_n
347 );
348 }
349 }
350
351 pub fn update_all_deltas_for_component(
352 &mut self,
353 component: &Component,
354 source: NodeId,
355 v_p: NodeId,
356 v_n: NodeId)
357 {
358 self.update_deltas(v_p,v_n);
359
360 self.maybe_update_capital_deltas(component,source,v_p,v_n);
361
362 self.update_new_deltas_with_new_sigma_ratio(v_p,v_n);
363
364 self.maybe_update_new_capital_deltas(component, source, v_p, v_n);
365 }
366
367 pub fn update_deltas(&mut self, v_p: NodeId, v_n: NodeId) {
368
369 let sp_sn = self.get_sigma_ratio(v_p,v_n);
370 let dn = self.delta_value_for_node(v_n);
371 let dp = self.delta_value_for_node(v_p);
372 let one_p_dn = 1.0 + dn;
373
374 self.set_delta_value_for_node(
375 v_p,
376 dp + sp_sn * one_p_dn
377 );
378 }
379
380 pub fn maybe_update_capital_deltas_for_component(
381 &mut self,
382 component: &Component,
383 source: NodeId,
384 v_n: NodeId)
385 {
386 if component.has_both_articulation_points(source, v_n)
387 {
388 self.update_both_capital_deltas_for_component(
389 component,
390 source,
391 v_n
392 );
393 }
394 }
395
396 pub fn update_both_capital_deltas_for_component(
397 &mut self,
398 component: &Component,
399 source: NodeId,
400 v_n: NodeId)
401 {
402 let c_t = component
403 .subgraphs_product_through_articulation_points(
404 source,
405 v_n
406 );
407
408 self.capital_deltas_increment_delta_value_for_node(
409 v_n,
410 c_t
411 );
412
413 self.new_capital_deltas_increment_delta_value_for_node(
414 v_n,
415 c_t
416 );
417 }
418
419 pub fn process_outer_layer_neighbor(&mut self,
420 bc_mem: &mut BcMemWorkspace,
421 neighbor: NodeId,
422 queue: &mut NodeIdQueue,
423 v: NodeId)
424 -> Result<(), BetweennessCentralityError>
425 {
426 self.set_distance_one_step_away(neighbor,v);
427
428 bc_mem.new_parents_add_parent(neighbor, v);
430
431 let parents = self.parents_for_node(neighbor);
432
433 for &parent in parents.iter() {
434
435 self.attenuate_deltas(
436 parent,
437 neighbor
438 );
439 }
440
441 self.clear_node_parents(neighbor);
442
443 bc_mem.new_sigmas_sigma_set_node_to_zero(neighbor);
445
446 self.inc_sigmas_set_sigma_value_for_node(
447 neighbor,
448 self.inc_sigmas_sigma_value_for_node(v)
449 );
450
451 bc_mem.new_sigmas_increment_sigma_value_for_node(
452 neighbor,
453 self.inc_sigmas_sigma_value_for_node(neighbor)
454 );
455
456 if self.unvisited(neighbor) {
457
458 self.visit(neighbor);
459
460 queue.enqueue(neighbor);
462 }
463
464 Ok(())
465 }
466
467 pub fn process_first_layer_neighbor(&mut self,
468 bc_mem: &mut BcMemWorkspace,
469 neighbor: NodeId,
470 queue: &mut NodeIdQueue,
471 v: NodeId)
472 -> Result<(), BetweennessCentralityError>
473 {
474 self.inc_sigmas_increment_sigma_value_for_node(
475 neighbor,
476 self.inc_sigmas_sigma_value_for_node(v)
477 );
478
479 bc_mem.new_sigmas_increment_sigma_value_for_node(
480 neighbor,
481 self.inc_sigmas_sigma_value_for_node(v)
482 );
483
484 if !self.has_parent(neighbor, v) {
485
486 bc_mem.new_parents_add_parent(neighbor, v);
487 }
488
489 if self.unvisited(neighbor) {
490
491 self.visit(neighbor);
492
493 queue.enqueue(neighbor);
495 }
496
497 Ok(())
498 }
499
500 pub fn attenuate_deltas(&mut self, src: NodeId, dst: NodeId)
501 {
502 let sigma_ratio = self.sigma_ratio(src, dst);
503
504 let t1 = 1.0 + self.delta_value_for_node(dst);
505
506 let attenuation = sigma_ratio * t1;
507
508 self.attenuate_delta_value_for_node(
509 src,
510 attenuation
511 );
512 }
513
514 pub fn calculate_deltas_step_with_sigma_ratio(
515 &self,
516 sigma_ratio: f64,
517 w: NodeId) -> f64
518 {
519 let one_p_delta_w = 1.0 + self.delta_value_for_node(w);
520
521 let step = sigma_ratio * one_p_delta_w;
522
523 step
524 }
525
526 pub fn calculate_deltas_step(
527 &self,
528 v: NodeId,
529 w: NodeId) -> f64
530 {
531 let sigma_ratio = self.sigma_ratio(v,w);
532
533 self.calculate_deltas_step_with_sigma_ratio(
534 sigma_ratio,
535 w
536 )
537 }
538
539 pub fn update_delta_bc_of_vertices_for_node(
540 &self,
541 w: NodeId,
542 delta_bc_of_vertices: &mut BetweennessScores)
543 {
544 delta_bc_of_vertices.decrease_score_for_node(
545 w,
546 self.delta_value_for_node(w) / 2.0
547 );
548
549 delta_bc_of_vertices.increase_score_for_node(
550 w,
551 self.new_deltas_delta_value_for_node(w) / 2.0
552 );
553 }
554
555 pub fn refill_deltass(&mut self, len: usize) {
556 self.deltas.reinit(len);
557 self.capital_deltas.reinit(len);
558 self.new_capital_deltas.reinit(len);
559 self.new_deltas.reinit(len);
560 }
561}
562
563impl fmt::Debug for ICentralWorkspace {
564
565 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
566 fmt.debug_struct("ICentralWorkspace")
567 .field("capital_deltas", &self.capital_deltas)
568 .field("capital_deltas_len", &self.capital_deltas.len())
569 .field("deltas", &self.deltas)
570 .field("deltas_len", &self.deltas.len())
571 .field("distances", &self.distances)
572 .field("distances_len", &self.distances.len())
573 .field("new_capital_deltas", &self.new_capital_deltas)
574 .field("new_deltas", &self.new_deltas)
575 .field("new_sigmas", &self.new_sigmas)
576 .field("new_sigmas_len", &self.new_sigmas.len())
577 .field("parents", &self.parents)
578 .field("parents_len", &self.parents.len())
579 .field("inc_sigmas", &self.inc_sigmas)
580 .field("sigmas_len", &self.sigmas.len())
581 .field("stack", &self.stack)
582 .field("visit_markers", &self.visit_markers)
583 .finish_non_exhaustive()
584 }
585}
586
587impl CreateNamedEmpty for ICentralWorkspace {
588
589 fn empty(name: &str) -> Self {
591
592 let parents_name = name![name, "parents"];
593 let distances_name = name![name, "distances"];
594 let deltas_name = name![name, "deltas"];
595 let new_deltas_name = name![name, "new_deltas"];
596 let capital_deltas_name = name![name, "capital_deltas"];
597 let new_capital_deltas_name = name![name, "new_capital_deltas"];
598 let sigmas_name = name![name, "sigmas"];
599 let new_sigmas_name = name![name, "new_sigmas"];
600 let inc_sigmas_name = name![name, "inc_sigmas"];
601 let visit_markers_name = name![name, "visit_markers"];
602 let stack_name = name![name, "stack"];
603
604 Self {
605 parents: ParentsMap::empty_mapped(parents_name),
606 distances: DistanceMap::empty_mapped(distances_name),
607 deltas: DeltaMap::empty_mapped(deltas_name),
608 new_deltas: DeltaMap::empty_mapped(new_deltas_name),
609 capital_deltas: DeltaMap::empty_mapped(capital_deltas_name),
610 new_capital_deltas: DeltaMap::empty_mapped(new_capital_deltas_name),
611 sigmas: SigmaMap::empty_mapped(sigmas_name),
612 new_sigmas: SigmaMap::empty_mapped(new_sigmas_name),
613 inc_sigmas: SigmaMap::empty_mapped(inc_sigmas_name),
614 visit_markers: VisitMarkers::empty_mapped(visit_markers_name),
615 stack: NodeIdStack::empty(stack_name),
616 }
617 }
618}
619
620impl ICentralWorkspace {
621
622 pub fn new_init_all(n: usize, name: &str) -> Self {
623
624 let parents_name = name![name, "parents"];
625 let distances_name = name![name, "distances"];
626 let deltas_name = name![name, "deltas"];
627 let new_deltas_name = name![name, "new_deltas"];
628 let capital_deltas_name = name![name, "capital_deltas"];
629 let new_capital_deltas_name = name![name, "new_capital_deltas"];
630 let sigmas_name = name![name, "sigmas"];
631 let new_sigmas_name = name![name, "new_sigmas"];
632 let inc_sigmas_name = name![name, "inc_sigmas"];
633 let visit_markers_name = name![name, "visit_markers"];
634 let stack_name = name![name, "stack"];
635
636 Self {
637 parents: ParentsMap::new(n,parents_name),
638 distances: DistanceMap::new(n,distances_name),
639 deltas: DeltaMap::new(n,deltas_name),
640 new_deltas: DeltaMap::new(n,new_deltas_name),
641 capital_deltas: DeltaMap::new(n,capital_deltas_name),
642 new_capital_deltas: DeltaMap::new(n,new_capital_deltas_name),
643 sigmas: SigmaMap::new(n,sigmas_name),
644 new_sigmas: SigmaMap::new(n,new_sigmas_name),
645 inc_sigmas: SigmaMap::new(n,inc_sigmas_name),
646 visit_markers: VisitMarkers::new(n,visit_markers_name),
647 stack: NodeIdStack::empty(stack_name),
648 }
649 }
650
651 pub fn init_all(&mut self, n: usize) {
652 debug!("ICentralWorkspace init_all!, n={}", n);
653
654 self.parents.reinit(n);
655 self.sigmas.reinit(n);
656 self.distances.reinit(n);
657 self.inc_sigmas.reinit(n);
658 self.deltas.reinit(n);
659 self.capital_deltas.reinit(n);
660 self.visit_markers.reinit(n);
661
662 self.stack.clear();
663
664 debug!("workspace initialization *complete*");
665
666 }
676
677 pub fn init_new(&mut self, n: usize) {
682 self.new_sigmas.reinit(n);
683 self.new_deltas.reinit(n);
684 self.new_capital_deltas.reinit(n);
685 }
686}