LAL: Linear Arrangement Library 24.10.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 - 2024
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 (lluis.alemany.puig@upc.edu)
28 * LQMC (Quantitative, Mathematical, and Computational Linguisitcs)
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 * LQMC (Quantitative, Mathematical, and Computational Linguisitcs)
35 * CQL (Complexity and Quantitative Linguistics Lab)
36 * Office 220, 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#if !defined __LAL_SWIG_PYTHON
62
76template <class graph_t, class return_type>
77[[nodiscard]] return_type sum_powers_degrees
78(
79 const graph_t& g,
80 const uint64_t p,
81 uint64_t (graph_t::*degree_function)(node) const noexcept
82)
83noexcept
84{
85 static_assert(
86 std::is_same_v<return_type, uint64_t> ||
87 std::is_same_v<return_type, numeric::integer>
88 );
89
90 // sum of powers
91 return_type S(0);
92 // variable used to calculate powers
93 return_type du(0);
94
95 for (node u = 0; u < g.get_num_nodes(); ++u) {
96 const uint64_t deg = (g.*degree_function)(u);
97 // calculate the power of the degree 'deg'
98 if constexpr (std::is_same_v<return_type, numeric::integer>) {
99 du.set_number(deg);
100 du.powt(p);
101 }
102 else {
103 du = 1;
104 for (uint64_t i = 0; i < p; ++i) {
105 du *= deg;
106 }
107 }
108 // accumulate power
109 S += du;
110 }
111 return S;
112}
113
114#endif
115
150[[nodiscard]] inline uint64_t sum_powers_degrees
151(const graphs::undirected_graph& g, const uint64_t p)
152noexcept
153{
154 return
157}
158
173(const graphs::directed_graph& g, const uint64_t p)
174noexcept
175{
176 return
179}
193[[nodiscard]] inline uint64_t sum_powers_degrees
194(const graphs::directed_graph& g, const uint64_t p)
195noexcept
196{
197 return
200}
201
236[[nodiscard]] inline uint64_t sum_powers_in_degrees
237(const graphs::directed_graph& g, const uint64_t p)
238noexcept
239{
240 return
243}
244
260(const graphs::rooted_tree& t, const uint64_t p)
261noexcept
262{
263 (void(p));
264
265#if defined DEBUG
266 assert(t.is_rooted_tree());
267#endif
268 return t.get_num_edges();
269}
284[[nodiscard]] inline uint64_t sum_powers_in_degrees
285(
286 const graphs::rooted_tree& t,
287 [[maybe_unused]] const uint64_t p
288)
289noexcept
290{
291#if defined DEBUG
292 assert(t.is_rooted_tree());
293#endif
294 return t.get_num_edges();
295}
296
310[[nodiscard]] inline
332[[nodiscard]] inline uint64_t sum_powers_out_degrees
333(const graphs::directed_graph& g, const uint64_t p)
334noexcept
335{
336 return
339}
340
341/* -------------------------------------------------------------------------- */
342
343#if !defined __LAL_SWIG_PYTHON
344
359template <class graph_t, class return_type>
360[[nodiscard]] return_type moment_degree
361(
362 const graph_t& g,
363 const uint64_t p,
364 uint64_t (graph_t::*degree_function)(node) const noexcept
365)
366noexcept
367{
368 static_assert(
369 std::is_floating_point_v<return_type> ||
370 std::is_same_v<return_type, numeric::rational>
371 );
372
373 if constexpr (std::is_floating_point_v<return_type>) {
374 const uint64_t S =
375 sum_powers_degrees<graph_t,uint64_t>(g,p,degree_function);
376 return static_cast<return_type>(S)/static_cast<return_type>(g.get_num_nodes());
377 }
378 else {
379 const numeric::integer S =
381 return numeric::rational(S,g.get_num_nodes());
382 }
383}
384
385#endif
386
403(const graphs::undirected_graph& g, const uint64_t p)
404noexcept
405{
406 return
409}
419[[nodiscard]] inline double moment_degree
420(const graphs::undirected_graph& g, const uint64_t p)
421noexcept
422{
423 return
426}
427
444(const graphs::directed_graph& g, const uint64_t p)
445noexcept
446{
447 return
450}
460[[nodiscard]] inline double moment_degree
461(const graphs::directed_graph& g, const uint64_t p)
462noexcept
463{
464 return
467}
468
485(const graphs::directed_graph& g, const uint64_t p)
486noexcept
487{
488 return
491}
501[[nodiscard]] inline double moment_in_degree
502(const graphs::directed_graph& g, const uint64_t p)
503noexcept
504{
505 return
508}
509
529(
530 const graphs::rooted_tree& t,
531 [[maybe_unused]] const uint64_t p
532)
533noexcept
534{
535#if defined DEBUG
536 assert(t.is_rooted_tree());
537#endif
538 const auto n = t.get_num_nodes();
539 return numeric::rational(n - 1, n);
540}
551inline
553(
554 const graphs::rooted_tree& t,
555 [[maybe_unused]] const uint64_t p
556)
557noexcept
558{
559#if defined DEBUG
560 assert(t.is_rooted_tree());
561#endif
562 const auto n = t.get_num_nodes();
563 return static_cast<double>(n - 1)/static_cast<double>(n);
564}
565
582(const graphs::directed_graph& g, const uint64_t p)
583noexcept
584{
585 return
588}
599[[nodiscard]] inline double moment_out_degree
600(const graphs::directed_graph& g, const uint64_t p)
601noexcept
602{
603 return
606}
607
608
609/* -------------------------------------------------------------------------- */
610
611
632(const graphs::free_tree& t)
633noexcept
634{
635 const uint64_t n = t.get_num_nodes();
636
637 // for n <= 3, <k^2>_star = <k^2>_linear
638 // which means that hubiness is not defined:
639 // division by 0.
640#if defined DEBUG
641 assert(t.is_tree());
642 assert(n > 3);
643#endif
644
645 const numeric::rational k2_tree = moment_degree_rational(t, 2);
646 const numeric::rational k2_linear = numeric::rational(4*n - 6, n);
647 const numeric::rational k2_star = numeric::rational(n - 1);
648 return (k2_tree - k2_linear)/(k2_star - k2_linear);
649}
650
671(const graphs::rooted_tree& t)
672noexcept
673{
674 const uint64_t n = t.get_num_nodes();
675
676 // for n <= 3, <k^2>_star = <k^2>_linear
677 // which means that hubiness is not defined:
678 // division by 0.
679#if defined DEBUG
680 assert(t.is_rooted_tree());
681 assert(n > 3);
682#endif
683
684 const numeric::rational k2_tree = moment_degree_rational(t, 2);
685 const numeric::rational k2_linear = numeric::rational(4*n - 6, n);
686 const numeric::rational k2_star = numeric::rational(n - 1);
687 return (k2_tree - k2_linear)/(k2_star - k2_linear);
688}
689
699[[nodiscard]] inline double hubiness
700(const graphs::free_tree& t)
701noexcept
702{
703 const uint64_t n = t.get_num_nodes();
704
705 // for n <= 3, <k^2>_star = <k^2>_linear
706 // which means that hubiness is not defined:
707 // division by 0.
708#if defined DEBUG
709 assert(t.is_tree());
710 assert(n > 3);
711#endif
712
713 const double k2_tree = moment_degree(t, 2);
714 const double k2_linear = static_cast<double>(4*n - 6)/static_cast<double>(n);
715 const double k2_star = static_cast<double>(n - 1);
716 return (k2_tree - k2_linear)/(k2_star - k2_linear);
717}
718
729[[nodiscard]] inline double hubiness
730(const graphs::rooted_tree& t)
731noexcept
732{
733 const uint64_t n = t.get_num_nodes();
734
735 // for n <= 3, <k^2>_star = <k^2>_linear
736 // which means that hubiness is not defined:
737 // division by 0.
738#if defined DEBUG
739 assert(t.is_rooted_tree());
740 assert(n > 3);
741#endif
742
743 const double k2_tree = moment_degree(t, 2);
744 const double k2_linear = static_cast<double>(4*n - 6)/static_cast<double>(n);
745 const double k2_star = static_cast<double>(n - 1);
746 return (k2_tree - k2_linear)/(k2_star - k2_linear);
747}
748
749} // -- namespace properties
750} // -- namespace lal
Directed graph class.
Definition directed_graph.hpp:67
uint64_t get_out_degree(const node u) const noexcept
Returns the out-degree of a node.
Definition directed_graph.hpp:420
uint64_t get_degree(const node u) const noexcept
Returns the in-degree plus the out-degree of this vertex.
Definition directed_graph.hpp:416
uint64_t get_in_degree(const node u) const noexcept
Returns the in-degree of a node.
Definition directed_graph.hpp:427
Free tree graph class.
Definition free_tree.hpp:60
Rooted tree graph class.
Definition rooted_tree.hpp:109
Undirected graph class.
Definition undirected_graph.hpp:66
uint64_t get_degree(const node u) const noexcept
Returns the number of neighbors of u.
Definition undirected_graph.hpp:384
Arbitrary precision integer.
Definition integer.hpp:60
Exact rational number.
Definition rational.hpp:63
numeric::rational moment_degree_rational(const graphs::undirected_graph &g, const uint64_t p) noexcept
Computes the -th moment of degree about zero of a graph as an exact rational value.
Definition degrees.hpp:403
return_type sum_powers_degrees(const graph_t &g, const uint64_t p, uint64_t(graph_t::*degree_function)(node) const noexcept) noexcept
Generic template function for the sum of degrees.
Definition degrees.hpp:78
numeric::rational hubiness_rational(const graphs::free_tree &t) noexcept
Computes the hubiness coefficient as an exact rational number.
Definition degrees.hpp:632
return_type moment_degree(const graph_t &g, const 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:361
numeric::integer sum_powers_out_degrees_integer(const graphs::directed_graph &g, const uint64_t p) noexcept
Computes the sum of out-degrees raised to the -th power.
Definition degrees.hpp:312
double moment_out_degree(const graphs::directed_graph &g, const 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:600
uint64_t sum_powers_out_degrees(const graphs::directed_graph &g, const uint64_t p) noexcept
Computes the sum of out-degrees raised to the -th power.
Definition degrees.hpp:333
double hubiness(const graphs::free_tree &t) noexcept
Computes the hubiness coefficient as a floating point value.
Definition degrees.hpp:700
numeric::integer sum_powers_degrees_integer(const graphs::undirected_graph &g, const uint64_t p) noexcept
Computes the sum of degrees raised to the -th power.
Definition degrees.hpp:130
numeric::integer sum_powers_in_degrees_integer(const graphs::directed_graph &g, const uint64_t p) noexcept
Computes the sum of in-degrees raised to the -th power.
Definition degrees.hpp:216
uint64_t sum_powers_in_degrees(const graphs::directed_graph &g, const uint64_t p) noexcept
Computes the sum of in-degrees raised to the -th power.
Definition degrees.hpp:237
numeric::rational moment_in_degree_rational(const graphs::directed_graph &g, const 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:485
numeric::rational moment_out_degree_rational(const graphs::directed_graph &g, const 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:582
double moment_in_degree(const graphs::directed_graph &g, const 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:502
Main namespace of the library.
Definition basic_types.hpp:48
uint64_t node
Node type. See Node / Vertex page for further details.
Definition basic_types.hpp:51