LAL: Linear Arrangement Library 23.01.00
A library focused on algorithms on linear arrangements of graphs.
Loading...
Searching...
No Matches
degrees.hpp
1/*********************************************************************
2 *
3 * Linear Arrangement Library - A library that implements a collection
4 * algorithms for linear arrangments of graphs.
5 *
6 * Copyright (C) 2019 - 2023
7 *
8 * This file is part of Linear Arrangement Library. The full code is available
9 * at:
10 * https://github.com/LAL-project/linear-arrangement-library.git
11 *
12 * Linear Arrangement Library is free software: you can redistribute it
13 * and/or modify it under the terms of the GNU Affero General Public License
14 * as published by the Free Software Foundation, either version 3 of the
15 * License, or (at your option) any later version.
16 *
17 * Linear Arrangement Library is distributed in the hope that it will be
18 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU Affero General Public License for more details.
21 *
22 * You should have received a copy of the GNU Affero General Public License
23 * along with Linear Arrangement Library. If not, see <http://www.gnu.org/licenses/>.
24 *
25 * Contact:
26 *
27 * LluĂ­s Alemany Puig (lalemany@cs.upc.edu)
28 * LARCA (Laboratory for Relational Algorithmics, Complexity and Learning)
29 * CQL (Complexity and Quantitative Linguistics Lab)
30 * Jordi Girona St 1-3, Campus Nord UPC, 08034 Barcelona. CATALONIA, SPAIN
31 * Webpage: https://cqllab.upc.edu/people/lalemany/
32 *
33 * Ramon Ferrer i Cancho (rferrericancho@cs.upc.edu)
34 * LARCA (Laboratory for Relational Algorithmics, Complexity and Learning)
35 * CQL (Complexity and Quantitative Linguistics Lab)
36 * Office S124, Omega building
37 * Jordi Girona St 1-3, Campus Nord UPC, 08034 Barcelona. CATALONIA, SPAIN
38 * Webpage: https://cqllab.upc.edu/people/rferrericancho/
39 *
40 ********************************************************************/
41
42#pragma once
43
44// C++ includes
45#if defined DEBUG
46#include <cassert>
47#endif
48
49// lal includes
50#include <lal/numeric/rational.hpp>
51#include <lal/graphs/undirected_graph.hpp>
52#include <lal/graphs/directed_graph.hpp>
53#include <lal/graphs/free_tree.hpp>
54#include <lal/graphs/rooted_tree.hpp>
55
56namespace lal {
57namespace properties {
58
59/* -------------------------------------------------------------------------- */
60
61#ifndef SWIG
62
76template <class graph_t, class return_type>
77inline
79(const graph_t& g, uint64_t p, uint64_t (graph_t::*degree_function)(node) const noexcept)
80noexcept
81{
82 static_assert(
83 std::is_same_v<return_type, uint64_t> ||
84 std::is_same_v<return_type, numeric::integer>
85 );
86
87 // sum of powers
88 return_type S(0);
89 // variable used to calculate powers
90 return_type du(0);
91
92 for (node u = 0; u < g.get_num_nodes(); ++u) {
93 const uint64_t deg = (g.*degree_function)(u);
94 // calculate the power of the degree 'deg'
95 if constexpr (std::is_same_v<return_type, numeric::integer>) {
96 du.set_number(deg);
97 du.powt(p);
98 }
99 else {
100 du = 1;
101 for (uint64_t i = 0; i < p; ++i) {
102 du *= deg;
103 }
104 }
105 // accumulate power
106 S += du;
107 }
108 return S;
109}
110
111#endif
112
126inline
128(const graphs::undirected_graph& g, uint64_t p) noexcept
129{
130 return
131 sum_powers_degrees<graphs::undirected_graph, numeric::integer>
133}
147inline
149(const graphs::undirected_graph& g, uint64_t p) noexcept
150{
151 return
152 sum_powers_degrees<graphs::undirected_graph, uint64_t>
154}
155
169inline
171(const graphs::directed_graph& g, uint64_t p) noexcept
172{
173 return
174 sum_powers_degrees<graphs::directed_graph, numeric::integer>
176}
190inline
192(const graphs::directed_graph& g, uint64_t p) noexcept
193{
194 return
195 sum_powers_degrees<graphs::directed_graph, uint64_t>
197}
198
212inline
214(const graphs::directed_graph& g, uint64_t p) noexcept
215{
216 return
217 sum_powers_degrees<graphs::directed_graph, numeric::integer>
219}
233inline
235(const graphs::directed_graph& g, uint64_t p) noexcept
236{
237 return
238 sum_powers_degrees<graphs::directed_graph, uint64_t>
240}
241
256inline
258(const graphs::rooted_tree& t, uint64_t p)
259noexcept
260{
261 (void(p));
262
263#if defined DEBUG
264 assert(t.is_rooted_tree());
265#endif
266 return t.get_num_edges();
267}
282inline
283uint64_t sum_powers_in_degrees(const graphs::rooted_tree& t, uint64_t p) noexcept
284{
285 (void(p));
286
287#if defined DEBUG
288 assert(t.is_rooted_tree());
289#endif
290 return t.get_num_edges();
291}
292
306inline
308(const graphs::directed_graph& g, uint64_t p) noexcept
309{
310 return
311 sum_powers_degrees<graphs::directed_graph, numeric::integer>
313}
327inline
329(const graphs::directed_graph& g, uint64_t p) noexcept
330{
331 return
332 sum_powers_degrees<graphs::directed_graph, uint64_t>
334}
335
336/* -------------------------------------------------------------------------- */
337
338#ifndef SWIG
339
354template <class graph_t, class return_type>
355inline
356return_type moment_degree
357(const graph_t& g, uint64_t p, uint64_t (graph_t::*degree_function)(node) const noexcept)
358noexcept
359{
360 static_assert(
361 std::is_floating_point_v<return_type> ||
362 std::is_same_v<return_type, numeric::rational>
363 );
364
365 if constexpr (std::is_floating_point_v<return_type>) {
366 const uint64_t S =
367 sum_powers_degrees<graph_t,uint64_t>(g,p,degree_function);
368 return static_cast<return_type>(S)/static_cast<return_type>(g.get_num_nodes());
369 }
370 else {
371 const numeric::integer S =
372 sum_powers_degrees<graph_t,numeric::integer>(g,p,degree_function);
373 return numeric::rational(S,g.get_num_nodes());
374 }
375}
376
377#endif
378
394inline
396(const graphs::undirected_graph& g, uint64_t p) noexcept
397{
398 return
399 moment_degree<graphs::undirected_graph, numeric::rational>
401}
411inline
412double moment_degree(const graphs::undirected_graph& g, uint64_t p) noexcept
413{
414 return
415 moment_degree<graphs::undirected_graph, double>
417}
418
434inline
436(const graphs::directed_graph& g, uint64_t p) noexcept
437{
438 return
439 moment_degree<graphs::directed_graph, numeric::rational>
441}
451inline
452double moment_degree(const graphs::directed_graph& g, uint64_t p) noexcept
453{
454 return
455 moment_degree<graphs::directed_graph, double>
457}
458
474inline
476(const graphs::directed_graph& g, uint64_t p) noexcept
477{
478 return
479 moment_degree<graphs::directed_graph, numeric::rational>
481}
491inline
492double moment_in_degree(const graphs::directed_graph& g, uint64_t p) noexcept
493{
494 return
495 moment_degree<graphs::directed_graph, double>
497}
498
517inline
519noexcept
520{
521 (void(p));
522
523#if defined DEBUG
524 assert(t.is_rooted_tree());
525#endif
526 const auto n = t.get_num_nodes();
527 return numeric::rational(n - 1, n);
528}
539inline
540double moment_in_degree(const graphs::rooted_tree& t, uint64_t p)
541noexcept
542{
543 (void(p));
544
545#if defined DEBUG
546 assert(t.is_rooted_tree());
547#endif
548 const auto n = t.get_num_nodes();
549 return static_cast<double>(n - 1)/static_cast<double>(n);
550}
551
567inline
569(const graphs::directed_graph& g, uint64_t p) noexcept
570{
571 return
572 moment_degree<graphs::directed_graph, numeric::rational>
574}
585inline
586double moment_out_degree(const graphs::directed_graph& g, uint64_t p) noexcept
587{
588 return
589 moment_degree<graphs::directed_graph, double>
591}
592
593
594/* -------------------------------------------------------------------------- */
595
596
616inline
618{
619 const uint64_t n = t.get_num_nodes();
620
621 // for n <= 3, <k^2>_star = <k^2>_linear
622 // which means that hubiness is not defined:
623 // division by 0.
624#if defined DEBUG
625 assert(t.is_tree());
626 assert(n > 3);
627#endif
628
629 const numeric::rational k2_tree = moment_degree_rational(t, 2);
630 const numeric::rational k2_linear = numeric::rational(4*n - 6, n);
631 const numeric::rational k2_star = numeric::rational(n - 1);
632 return (k2_tree - k2_linear)/(k2_star - k2_linear);
633}
634
654inline
656{
657 const uint64_t n = t.get_num_nodes();
658
659 // for n <= 3, <k^2>_star = <k^2>_linear
660 // which means that hubiness is not defined:
661 // division by 0.
662#if defined DEBUG
663 assert(t.is_rooted_tree());
664 assert(n > 3);
665#endif
666
667 const numeric::rational k2_tree = moment_degree_rational(t, 2);
668 const numeric::rational k2_linear = numeric::rational(4*n - 6, n);
669 const numeric::rational k2_star = numeric::rational(n - 1);
670 return (k2_tree - k2_linear)/(k2_star - k2_linear);
671}
672
682inline
683double hubiness(const graphs::free_tree& t) noexcept
684{
685 const uint64_t n = t.get_num_nodes();
686
687 // for n <= 3, <k^2>_star = <k^2>_linear
688 // which means that hubiness is not defined:
689 // division by 0.
690#if defined DEBUG
691 assert(t.is_tree());
692 assert(n > 3);
693#endif
694
695 const double k2_tree = moment_degree(t, 2);
696 const double k2_linear = static_cast<double>(4*n - 6)/static_cast<double>(n);
697 const double k2_star = static_cast<double>(n - 1);
698 return (k2_tree - k2_linear)/(k2_star - k2_linear);
699}
700
711inline
712double hubiness(const graphs::rooted_tree& t) noexcept
713{
714 const uint64_t n = t.get_num_nodes();
715
716 // for n <= 3, <k^2>_star = <k^2>_linear
717 // which means that hubiness is not defined:
718 // division by 0.
719#if defined DEBUG
720 assert(t.is_rooted_tree());
721 assert(n > 3);
722#endif
723
724 const double k2_tree = moment_degree(t, 2);
725 const double k2_linear = static_cast<double>(4*n - 6)/static_cast<double>(n);
726 const double k2_star = static_cast<double>(n - 1);
727 return (k2_tree - k2_linear)/(k2_star - k2_linear);
728}
729
730} // -- namespace properties
731} // -- namespace lal
Directed graph class.
Definition: directed_graph.hpp:68
uint64_t get_out_degree(node u) const noexcept
Returns the out-degree of a node.
Definition: directed_graph.hpp:358
uint64_t get_degree(node u) const noexcept
Returns the in-degree plus the out-degree of this vertex.
Definition: directed_graph.hpp:354
uint64_t get_in_degree(node u) const noexcept
Returns the in-degree of a node.
Definition: directed_graph.hpp:365
Free tree graph class.
Definition: free_tree.hpp:60
Rooted tree graph class.
Definition: rooted_tree.hpp:103
Undirected graph class.
Definition: undirected_graph.hpp:67
uint64_t get_degree(node u) const noexcept
Returns the number of neighbours of u.
Definition: undirected_graph.hpp:327
Arbitrary precision integer.
Definition: integer.hpp:60
Exact rational number.
Definition: rational.hpp:63
numeric::rational moment_in_degree_rational(const graphs::directed_graph &g, uint64_t p) noexcept
Computes the -th moment of in-degree about zero of a directed graph as an exact rational value.
Definition: degrees.hpp:476
numeric::rational hubiness_rational(const graphs::free_tree &t) noexcept
Computes the hubiness coefficient as an exact rational number.
Definition: degrees.hpp:617
return_type sum_powers_degrees(const graph_t &g, uint64_t p, uint64_t(graph_t::*degree_function)(node) const noexcept) noexcept
Generic template function for the sum of degrees.
Definition: degrees.hpp:79
return_type moment_degree(const graph_t &g, uint64_t p, uint64_t(graph_t::*degree_function)(node) const noexcept) noexcept
Generic template function for the moment of degree about 0.
Definition: degrees.hpp:357
numeric::integer sum_powers_out_degrees_integer(const graphs::directed_graph &g, uint64_t p) noexcept
Computes the sum of out-degrees raised to the -th power.
Definition: degrees.hpp:308
numeric::integer sum_powers_in_degrees_integer(const graphs::directed_graph &g, uint64_t p) noexcept
Computes the sum of in-degrees raised to the -th power.
Definition: degrees.hpp:214
uint64_t sum_powers_out_degrees(const graphs::directed_graph &g, uint64_t p) noexcept
Computes the sum of out-degrees raised to the -th power.
Definition: degrees.hpp:329
numeric::rational moment_out_degree_rational(const graphs::directed_graph &g, uint64_t p) noexcept
Computes the -th moment of out-degree about zero of a directed graph as an exact rational value.
Definition: degrees.hpp:569
double moment_in_degree(const graphs::directed_graph &g, uint64_t p) noexcept
Computes the -th moment of in-degree about zero of a directed graph as a floating point value.
Definition: degrees.hpp:492
numeric::integer sum_powers_degrees_integer(const graphs::undirected_graph &g, uint64_t p) noexcept
Computes the sum of degrees raised to the -th power.
Definition: degrees.hpp:128
double hubiness(const graphs::free_tree &t) noexcept
Computes the hubiness coefficient as a floating point value.
Definition: degrees.hpp:683
uint64_t sum_powers_in_degrees(const graphs::directed_graph &g, uint64_t p) noexcept
Computes the sum of in-degrees raised to the -th power.
Definition: degrees.hpp:235
numeric::rational moment_degree_rational(const graphs::undirected_graph &g, uint64_t p) noexcept
Computes the -th moment of degree about zero of a graph as an exact rational value.
Definition: degrees.hpp:396
double moment_out_degree(const graphs::directed_graph &g, uint64_t p) noexcept
Computes the -th moment of out-degree about zero of a directed graph as a floating point value.
Definition: degrees.hpp:586
Main namespace of the library.
Definition: basic_types.hpp:50
uint64_t node
Node type. See Node / Vertex page for further details.
Definition: basic_types.hpp:53