Add graph references

This commit is contained in:
Abdelrahman Said
2026-06-28 13:49:01 +01:00
parent 0a9807e448
commit a11edf0c53
2578 changed files with 868045 additions and 0 deletions
@@ -0,0 +1,306 @@
/*
igraph library.
Copyright (C) 2022 The igraph development team <igraph@igraph.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include <igraph.h>
#include "test_utilities.h"
/* Basic check: Are means within tol*sigma from the expected value?
* This is meant to catch gross bugs while changing RNG/sampler code. */
void stats(void) {
igraph_int_t k;
const igraph_int_t n = 100000;
igraph_real_t m, tm, tsd;
igraph_real_t tol = 3;
printf("\n");
/* Binary trials with success of probability p. Counting successes. */
{
igraph_real_t p = 0.1;
m = 0;
for (k = 0; k < n; k++) {
if (RNG_UNIF01() < p) {
m += 1;
}
}
tm = n*p;
tsd = sqrt(n*p*(1-p));
printf("binary trials: %g; expected: %g; std. dev.: %g\n", m, tm, tsd);
IGRAPH_ASSERT(tm - tol*tsd < m && m < tm + tol*tsd);
}
/* Mean of Poisson distributed values. */
{
tm = 2;
m = 0;
for (k = 0; k < n; k++) {
m += RNG_POIS(tm);
}
m /= n;
tsd = sqrt(tm) / sqrt(n);
printf("pois: %g; expected: %g; std. dev.: %g\n", m, tm, tsd);
IGRAPH_ASSERT(tm - tol*tsd < m && m < tm + tol*tsd);
}
/* Mean of geometrically distributed values. */
{
igraph_real_t p = 0.25;
m = 0;
for (k = 0; k < n; k++) {
m += RNG_GEOM(p);
}
m /= n;
tm = (1-p) / p;
tsd = sqrt(1 - p) / p / sqrt(n);
printf("geom: %g; expected: %g; std. dev.: %g\n", m, tm, tsd);
IGRAPH_ASSERT(tm - tol*tsd < m && m < tm + tol*tsd);
}
/* Mean of binomially distributed values. */
{
igraph_real_t p = 0.33;
igraph_int_t nn = 77;
m = 0;
for (k = 0; k < n; k++) {
m += RNG_BINOM(nn, p);
}
m /= n;
tm = nn * p;
tsd = sqrt(nn*p*(1-p)) / sqrt(n);
printf("binom: %g; expected: %g; std. dev.: %g\n", m, tm, tsd);
IGRAPH_ASSERT(tm - tol*tsd < m && m < tm + tol*tsd);
}
/* Mean of exponentially distributed values. */
{
tm = 3;
m = 0;
for (k = 0; k < n; k++) {
m += RNG_EXP(1 / tm);
}
m /= n;
tsd = tm / sqrt(n);
printf("exp: %g; expected: %g; std. dev.: %g\n", m, tm, tsd);
IGRAPH_ASSERT(tm - tol*tsd < m && m < tm + tol*tsd);
}
/* Mean of gamma distributed values. */
{
igraph_real_t shape = 1.5, scale = 3.5;
m = 0;
for (k = 0; k < n; k++) {
m += RNG_GAMMA(shape, scale);
}
m /= n;
tm = shape*scale;
tsd = sqrt(shape) * scale / sqrt(n);
printf("gamma: %g; expected: %g; std. dev.: %g\n", m, tm, tsd);
IGRAPH_ASSERT(tm - tol*tsd < m && m < tm + tol*tsd);
}
/* Mean of normally distributed values. */
{
tm = 3.0; tsd = 2.0;
m = 0;
for (k = 0; k < n; k++) {
m += RNG_NORMAL(tm, tsd);
}
m /= n;
tsd /= sqrt(n);
printf("norm: %g; expected: %g; std. dev.: %g\n", m, tm, tsd);
IGRAPH_ASSERT(tm - tol*tsd < m && m < tm + tol*tsd);
}
{
tm = 0.5; tsd = 0.5;
m = 0;
for (k = 0; k < n; k++) {
m += RNG_BOOL();
}
m /= n;
printf("binary: %g; expected: %g; std. dev.: %g\n", m, tm, tsd);
IGRAPH_ASSERT(tm - tol*tsd < m && m < tm + tol*tsd);
}
}
/* These is merely a smoke test for various random samplers.
* It does not verify the correctness of the result, except
* for some special edge cases. */
void sample(void) {
igraph_int_t i;
igraph_real_t x;
igraph_bool_t b;
i = RNG_INTEGER(-100, 100);
printf("integer: %" IGRAPH_PRId "\n", i);
IGRAPH_ASSERT(-100 <= i && i <= 100);
i = RNG_INTEGER(2, 2);
printf("integer: %" IGRAPH_PRId "\n", i);
IGRAPH_ASSERT(i == 2);
i = RNG_INTEGER(-5, -5);
printf("integer: %" IGRAPH_PRId "\n", i);
IGRAPH_ASSERT(i == -5);
x = RNG_UNIF(-100, 100);
printf("unif: %g\n", x);
IGRAPH_ASSERT(-100 <= x && x < 100);
x = RNG_UNIF(3, 3);
printf("unif: %g\n", x);
IGRAPH_ASSERT(x == 3);
x = RNG_UNIF(-4.5, -4.5);
printf("unif: %g\n", x);
IGRAPH_ASSERT(x == -4.5);
x = RNG_UNIF01();
printf("unif01: %g\n", x);
IGRAPH_ASSERT(0 <= x);
IGRAPH_ASSERT(x < 1);
x = RNG_BINOM(10, 0.3);
printf("binom: %g\n", x);
IGRAPH_ASSERT(0 <= x && x <= 10);
x = RNG_BINOM(5, 0);
IGRAPH_ASSERT(x == 0);
x = RNG_BINOM(5, 1);
IGRAPH_ASSERT(x == 5);
x = RNG_BINOM((1LL << 31) - 1, 0.5);
IGRAPH_ASSERT(!isnan(x));
IGRAPH_ASSERT(0 <= x && x <= (1LL << 31) - 1);
#if IGRAPH_INTEGER_SIZE > 32
x = RNG_BINOM((1LL << 31), 0.5);
IGRAPH_ASSERT(!isnan(x));
IGRAPH_ASSERT(0 <= x && x <= (1LL << 31) - 1);
#endif
x = RNG_GEOM(0.2);
printf("geom: %g\n", x);
IGRAPH_ASSERT(0 <= x);
x = RNG_GEOM(1);
IGRAPH_ASSERT(x == 0);
x = RNG_GEOM(0);
IGRAPH_ASSERT(isnan(x));
x = RNG_NORMAL(0, 1);
printf("normal: %g\n", x);
IGRAPH_ASSERT(isfinite(x));
x = RNG_EXP(1);
printf("exp: %g\n", x);
IGRAPH_ASSERT(0 <= x);
x = RNG_EXP(0);
IGRAPH_ASSERT(isnan(x));
x = RNG_GAMMA(1, 1);
printf("gamma: %g\n", x);
IGRAPH_ASSERT(0 <= x);
/* Note: Some systems would reject 0 as a parameter value instead of returning 0 */
x = RNG_GAMMA(0, 1);
IGRAPH_ASSERT(x == 0);
x = RNG_GAMMA(1, 0);
IGRAPH_ASSERT(x == 0);
x = RNG_POIS(10);
printf("poisson: %g\n", x);
IGRAPH_ASSERT(0 <= x && isfinite(x));
x = RNG_POIS(0);
IGRAPH_ASSERT(x == 0);
x = RNG_POIS(-1);
IGRAPH_ASSERT(isnan(x));
x = RNG_POIS((1LL << 31) - 1);
IGRAPH_ASSERT(0 <= x && isfinite(x));
x = RNG_POIS((1LL << 31));
IGRAPH_ASSERT(0 <= x && isfinite(x));
#if IGRAPH_INTEGER_SIZE > 32
x = RNG_POIS((1LL << 32));
IGRAPH_ASSERT(0 <= x && isfinite(x));
#endif
b = RNG_BOOL();
IGRAPH_ASSERT(b == true || b == false);
}
void test_and_destroy(igraph_rng_type_t *rng_type) {
igraph_rng_t *def = igraph_rng_default();
igraph_rng_t rng;
igraph_error_handler_t *oldhandler = igraph_set_error_handler(&igraph_error_handler_printignore);
igraph_error_t err = igraph_rng_init(&rng, rng_type);
switch (err) {
case IGRAPH_SUCCESS:
break;
case IGRAPH_UNIMPLEMENTED:
return;
default:
IGRAPH_FATAL("Error while initializing RNG.");
}
igraph_set_error_handler(oldhandler);
printf("\n%s\n\n", igraph_rng_name(&rng));
igraph_rng_set_default(&rng);
igraph_rng_seed(igraph_rng_default(), 137);
sample();
stats();
igraph_rng_set_default(def);
igraph_rng_destroy(&rng);
}
int main(void) {
igraph_rng_type_t rng_types[] = {
igraph_rngtype_glibc2,
igraph_rngtype_mt19937,
igraph_rngtype_pcg32,
igraph_rngtype_pcg64
};
printf("Default\n\n");
igraph_rng_seed(igraph_rng_default(), 709);
sample();
stats();
for (size_t i = 0; i < sizeof(rng_types) / sizeof(rng_types[0]); i++) {
test_and_destroy(&rng_types[i]);
}
VERIFY_FINALLY_STACK();
return 0;
}