Add graph references
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
igraph library.
|
||||
Copyright (C) 2013-2024 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/>.
|
||||
*/
|
||||
|
||||
#ifndef IGRAPH_BENCH_H
|
||||
#define IGRAPH_BENCH_H
|
||||
|
||||
#include <sys/resource.h> /* getrusage */
|
||||
#include <sys/time.h> /* gettimeofday */
|
||||
#include <unistd.h> /* sleep */
|
||||
|
||||
static inline void igraph_get_cpu_time(double *data) {
|
||||
|
||||
struct rusage self;
|
||||
struct timeval real;
|
||||
gettimeofday(&real, NULL);
|
||||
getrusage(RUSAGE_SELF, &self);
|
||||
data[0] = (double) real.tv_sec + 1e-6 * real.tv_usec; /* real */
|
||||
data[1] = (double) self.ru_utime.tv_sec + 1e-6 * self.ru_utime.tv_usec; /* user */
|
||||
data[2] = (double) self.ru_stime.tv_sec + 1e-6 * self.ru_stime.tv_usec; /* system */
|
||||
}
|
||||
|
||||
#define BENCH_INIT() \
|
||||
do { \
|
||||
printf("\n|> Benchmark file: %s\n", IGRAPH_FILE_BASENAME); \
|
||||
sleep(1); \
|
||||
} while (0)
|
||||
|
||||
#define REPEAT(CODE, N) \
|
||||
do { \
|
||||
igraph_int_t rep_i; \
|
||||
for (rep_i=0; rep_i < N; ++rep_i) { CODE; } \
|
||||
} while (0)
|
||||
|
||||
#define BENCH(NAME, ...) do { \
|
||||
double start[3], stop[3]; \
|
||||
double r, u, s; \
|
||||
igraph_get_cpu_time(start); \
|
||||
{ __VA_ARGS__; } \
|
||||
igraph_get_cpu_time(stop); \
|
||||
r = 1e-3 * round(1e3 * (stop[0] - start[0])); \
|
||||
u = 1e-3 * round(1e3 * (stop[1] - start[1])); \
|
||||
s = 1e-3 * round(1e3 * (stop[2] - start[2])); \
|
||||
printf("| %-80s %5.3gs %5.3gs %5.3gs\n", NAME, r, u, s); \
|
||||
} while (0)
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,150 @@
|
||||
/*
|
||||
IGraph library.
|
||||
Copyright (C) 2025 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 "bench.h"
|
||||
#include "igraph_spatial.h"
|
||||
|
||||
#include <float.h>
|
||||
|
||||
void bench_lune(igraph_int_t test_nr, igraph_int_t point_count, igraph_int_t dimensions, igraph_real_t beta) {
|
||||
igraph_matrix_t points;
|
||||
igraph_t g;
|
||||
char msg[200];
|
||||
|
||||
igraph_matrix_init(&points, point_count, dimensions);
|
||||
|
||||
for (igraph_int_t point = 0; point < point_count; point++) {
|
||||
for (igraph_int_t dim = 0; dim < dimensions; dim++) {
|
||||
MATRIX(points, point, dim) = RNG_UNIF01();
|
||||
}
|
||||
}
|
||||
|
||||
snprintf(msg, sizeof(msg) / sizeof(msg[0]),
|
||||
"%3"IGRAPH_PRId" Lune based beta skeleton in %dD, beta=%.3f, n=%6" IGRAPH_PRId,
|
||||
test_nr, (int) dimensions, beta, point_count);
|
||||
|
||||
BENCH(msg, igraph_lune_beta_skeleton(&g, &points, beta));
|
||||
|
||||
igraph_destroy(&g);
|
||||
igraph_matrix_destroy(&points);
|
||||
|
||||
}
|
||||
|
||||
void bench_circle(igraph_int_t test_nr, igraph_int_t point_count, igraph_int_t dimensions, igraph_real_t beta) {
|
||||
igraph_matrix_t points;
|
||||
igraph_t g;
|
||||
char msg[200];
|
||||
|
||||
igraph_matrix_init(&points, point_count, dimensions);
|
||||
|
||||
for (igraph_int_t point = 0; point < point_count; point++) {
|
||||
for (igraph_int_t dim = 0; dim < dimensions; dim++) {
|
||||
MATRIX(points, point, dim) = RNG_UNIF01();
|
||||
}
|
||||
}
|
||||
|
||||
snprintf(msg, sizeof(msg) / sizeof(msg[0]),
|
||||
"%3"IGRAPH_PRId" Circle based beta skeleton in %dD, beta=%3f, n=%6" IGRAPH_PRId,
|
||||
test_nr, (int) dimensions, beta, point_count);
|
||||
|
||||
BENCH(msg, igraph_circle_beta_skeleton(&g, &points, beta));
|
||||
|
||||
igraph_destroy(&g);
|
||||
igraph_matrix_destroy(&points);
|
||||
|
||||
}
|
||||
|
||||
void bench_gabriel(igraph_int_t test_nr, igraph_int_t point_count, igraph_int_t dimensions, igraph_real_t beta_cutoff) {
|
||||
igraph_matrix_t points;
|
||||
igraph_vector_t edge_weights;
|
||||
igraph_t g;
|
||||
char msg[200];
|
||||
|
||||
igraph_matrix_init(&points, point_count, dimensions);
|
||||
igraph_vector_init(&edge_weights, 0);
|
||||
|
||||
for (igraph_int_t point = 0; point < point_count; point++) {
|
||||
for (igraph_int_t dim = 0; dim < dimensions; dim++) {
|
||||
MATRIX(points, point, dim) = RNG_UNIF01();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
snprintf(msg, sizeof(msg) / sizeof(msg[0]),
|
||||
"%3"IGRAPH_PRId" Beta weighted gabriel graph in %dD, cutoff=%3f, n=%6" IGRAPH_PRId,
|
||||
test_nr, (int) dimensions, beta_cutoff, point_count);
|
||||
|
||||
BENCH(msg, igraph_beta_weighted_gabriel_graph(&g, &edge_weights, &points, beta_cutoff));
|
||||
|
||||
igraph_vector_destroy(&edge_weights);
|
||||
igraph_destroy(&g);
|
||||
igraph_matrix_destroy(&points);
|
||||
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
igraph_int_t test_nr = 0;
|
||||
bench_lune(++test_nr, 100, 2, 2);
|
||||
bench_lune(++test_nr, 1000, 2, 2);
|
||||
bench_lune(++test_nr, 10000, 2, 2);
|
||||
bench_lune(++test_nr, 100000, 2, 2);
|
||||
bench_lune(++test_nr, 100, 3, 2);
|
||||
bench_lune(++test_nr, 1000, 3, 2);
|
||||
bench_lune(++test_nr, 10000, 3, 2);
|
||||
bench_lune(++test_nr, 100000, 3, 2);
|
||||
bench_lune(++test_nr, 1000, 4, 2);
|
||||
|
||||
bench_lune(++test_nr, 10000, 2, 1);
|
||||
bench_lune(++test_nr, 10000, 2, 2);
|
||||
bench_lune(++test_nr, 10000, 2, 4);
|
||||
bench_lune(++test_nr, 10000, 2, 8);
|
||||
bench_lune(++test_nr, 10000, 2, 16);
|
||||
bench_lune(++test_nr, 10000, 2, 32);
|
||||
bench_lune(++test_nr, 10000, 2, 64);
|
||||
bench_lune(++test_nr, 10000, 2, 128);
|
||||
bench_lune(++test_nr, 10000, 2, 256);
|
||||
bench_lune(++test_nr, 10000, 2, 512);
|
||||
bench_lune(++test_nr, 10000, 2, 1024);
|
||||
bench_lune(++test_nr, 1000, 2, 0.9);
|
||||
bench_lune(++test_nr, 1000, 2, 0.5);
|
||||
bench_lune(++test_nr, 1000, 2, 0.1);
|
||||
|
||||
|
||||
bench_circle(++test_nr, 100, 2, 2);
|
||||
bench_circle(++test_nr, 1000, 2, 2);
|
||||
bench_circle(++test_nr, 10000, 2, 2);
|
||||
bench_circle(++test_nr, 100000, 2, 2);
|
||||
|
||||
bench_circle(++test_nr, 10000, 2, 2);
|
||||
bench_circle(++test_nr, 10000, 2, 3);
|
||||
bench_circle(++test_nr, 10000, 2, 5);
|
||||
bench_circle(++test_nr, 10000, 2, 15);
|
||||
bench_circle(++test_nr, 10000, 2, 50);
|
||||
|
||||
bench_gabriel(++test_nr, 100, 2, 2);
|
||||
bench_gabriel(++test_nr, 1000, 2, 2);
|
||||
bench_gabriel(++test_nr, 10000, 2, 2);
|
||||
bench_gabriel(++test_nr, 100000, 2, 2);
|
||||
|
||||
bench_gabriel(++test_nr, 100, 3, 2);
|
||||
bench_gabriel(++test_nr, 1000, 3, 2);
|
||||
bench_gabriel(++test_nr, 10000, 3, 2);
|
||||
bench_gabriel(++test_nr, 100000, 3, 2);
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
igraph library.
|
||||
Copyright (C) 2024 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 "bench.h"
|
||||
|
||||
int main(void) {
|
||||
igraph_t g;
|
||||
igraph_vector_int_t colors;
|
||||
|
||||
igraph_rng_seed(igraph_rng_default(), 42);
|
||||
BENCH_INIT();
|
||||
|
||||
igraph_vector_int_init(&colors, 0);
|
||||
|
||||
igraph_erdos_renyi_game_gnm(&g, 50000, 1000000, IGRAPH_UNDIRECTED, IGRAPH_SIMPLE_SW, IGRAPH_EDGE_UNLABELED);
|
||||
BENCH(" 1 COLORED_NEIGHBORS, random graph with 50,000 vertices and 2,000,000 edges",
|
||||
igraph_vertex_coloring_greedy(&g, &colors, IGRAPH_COLORING_GREEDY_COLORED_NEIGHBORS)
|
||||
);
|
||||
BENCH(" 2 DSATUR, random graph with 50,000 vertices and 2,000,000 edges",
|
||||
igraph_vertex_coloring_greedy(&g, &colors, IGRAPH_COLORING_GREEDY_DSATUR)
|
||||
);
|
||||
igraph_destroy(&g);
|
||||
|
||||
printf("\n");
|
||||
|
||||
igraph_barabasi_game(&g, 100000, 1, 15, NULL, 0, 0, 0, IGRAPH_BARABASI_PSUMTREE, NULL);
|
||||
BENCH(" 1 COLORED_NEIGHBORS, pref. attach. graph n=100,000 m=15",
|
||||
igraph_vertex_coloring_greedy(&g, &colors, IGRAPH_COLORING_GREEDY_COLORED_NEIGHBORS)
|
||||
);
|
||||
BENCH(" 2 DSATUR, pref. attach. graph n=100,000 m=15",
|
||||
igraph_vertex_coloring_greedy(&g, &colors, IGRAPH_COLORING_GREEDY_DSATUR)
|
||||
);
|
||||
igraph_destroy(&g);
|
||||
|
||||
igraph_vector_int_destroy(&colors);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
igraph library.
|
||||
Copyright (C) 2024 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 "bench.h"
|
||||
|
||||
void run_bench(const igraph_t *graph, const igraph_vector_t *weights,
|
||||
const char *name, int rep) {
|
||||
igraph_vector_int_t membership;
|
||||
igraph_vector_t vertex_weight;
|
||||
igraph_int_t vcount = igraph_vcount(graph);
|
||||
igraph_int_t ecount = igraph_ecount(graph);
|
||||
char msg[256], msg2[128];
|
||||
|
||||
igraph_vector_int_init(&membership, vcount);
|
||||
igraph_vector_init(&vertex_weight, vcount);
|
||||
|
||||
igraph_strength(graph, &vertex_weight, igraph_vss_all(), IGRAPH_ALL, IGRAPH_LOOPS, weights);
|
||||
|
||||
snprintf(msg2, sizeof(msg2) / sizeof(msg2[0]),
|
||||
"%s, vcount=%" IGRAPH_PRId ", ecount=%" IGRAPH_PRId ", %s, %dx",
|
||||
name, vcount, ecount, weights == NULL ? "unweighted" : "weighted",
|
||||
rep);
|
||||
|
||||
|
||||
snprintf(msg, sizeof(msg) / sizeof(msg[0]), "1 Louvain, %s", msg2);
|
||||
BENCH(msg, REPEAT(igraph_community_multilevel(graph, weights, 1.0, &membership, NULL, NULL), rep));
|
||||
|
||||
snprintf(msg, sizeof(msg) / sizeof(msg[0]), "2 Leiden , %s", msg2);
|
||||
BENCH(msg, REPEAT(igraph_community_leiden(graph, weights, &vertex_weight, NULL, 1.0 / igraph_vector_sum(weights), 0.01, false, 1, &membership, NULL, NULL), rep));
|
||||
|
||||
printf("\n");
|
||||
|
||||
igraph_vector_destroy(&vertex_weight);
|
||||
igraph_vector_int_destroy(&membership);
|
||||
}
|
||||
|
||||
void rand_weights(const igraph_t *graph, igraph_vector_t *weights) {
|
||||
igraph_int_t ecount = igraph_ecount(graph);
|
||||
igraph_vector_resize(weights, ecount);
|
||||
for (igraph_int_t i=0; i < ecount; i++) {
|
||||
VECTOR(*weights)[i] = RNG_UNIF01();
|
||||
}
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
igraph_t graph;
|
||||
igraph_vector_t weights;
|
||||
|
||||
igraph_rng_seed(igraph_rng_default(), 137);
|
||||
BENCH_INIT();
|
||||
|
||||
igraph_vector_init(&weights, 0);
|
||||
|
||||
igraph_erdos_renyi_game_gnm(&graph, 100, 500, false, false, false);
|
||||
rand_weights(&graph, &weights);
|
||||
run_bench(&graph, &weights, "G(n,m)", 1000);
|
||||
igraph_destroy(&graph);
|
||||
|
||||
igraph_erdos_renyi_game_gnm(&graph, 1000, 5000, false, false, false);
|
||||
rand_weights(&graph, &weights);
|
||||
run_bench(&graph, &weights, "G(n,m)", 100);
|
||||
igraph_destroy(&graph);
|
||||
|
||||
igraph_erdos_renyi_game_gnm(&graph, 1000, 50000, false, false, false);
|
||||
rand_weights(&graph, &weights);
|
||||
run_bench(&graph, &weights, "G(n,m)", 10);
|
||||
igraph_destroy(&graph);
|
||||
|
||||
igraph_erdos_renyi_game_gnm(&graph, 10000, 50000, false, false, false);
|
||||
rand_weights(&graph, &weights);
|
||||
run_bench(&graph, &weights, "G(n,m)", 10);
|
||||
igraph_destroy(&graph);
|
||||
|
||||
igraph_erdos_renyi_game_gnm(&graph, 100000, 500000, false, false, false);
|
||||
rand_weights(&graph, &weights);
|
||||
run_bench(&graph, &weights, "G(n,m)", 1);
|
||||
igraph_destroy(&graph);
|
||||
|
||||
igraph_forest_fire_game(&graph, 1000, 0.2, 1, 2, false);
|
||||
rand_weights(&graph, &weights);
|
||||
run_bench(&graph, &weights, "forest fire", 100);
|
||||
igraph_destroy(&graph);
|
||||
|
||||
igraph_barabasi_game(&graph, 1000, 1, 5, NULL, true, 0, false, IGRAPH_BARABASI_PSUMTREE, NULL);
|
||||
rand_weights(&graph, &weights);
|
||||
run_bench(&graph, &weights, "PA", 100);
|
||||
igraph_destroy(&graph);
|
||||
|
||||
igraph_vector_destroy(&weights);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
igraph library.
|
||||
Copyright (C) 2024 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 "bench.h"
|
||||
|
||||
/* Benchmarks related to biconnected components. */
|
||||
|
||||
void run_bench(igraph_int_t vcount, igraph_real_t meandeg, igraph_int_t rep) {
|
||||
igraph_t g;
|
||||
igraph_bool_t b;
|
||||
igraph_vector_int_t ivec;
|
||||
char msg[128];
|
||||
|
||||
igraph_erdos_renyi_game_gnm(&g, vcount, round(meandeg * vcount / 2), IGRAPH_DIRECTED, IGRAPH_LOOPS_SW, IGRAPH_EDGE_UNLABELED);
|
||||
igraph_vector_int_init(&ivec, igraph_vcount(&g));
|
||||
|
||||
snprintf(msg, sizeof(msg) / sizeof(msg[0]),
|
||||
" 1 Weakly connected? vcount=%" IGRAPH_PRId ", meandeg=%g, %" IGRAPH_PRId "x",
|
||||
vcount, meandeg, 10*rep);
|
||||
|
||||
igraph_invalidate_cache(&g);
|
||||
BENCH(msg, REPEAT(igraph_is_connected(&g, &b, IGRAPH_WEAK), rep));
|
||||
|
||||
snprintf(msg, sizeof(msg) / sizeof(msg[0]),
|
||||
" 2 Weak components. vcount=%" IGRAPH_PRId ", meandeg=%g, %" IGRAPH_PRId "x",
|
||||
vcount, meandeg, rep);
|
||||
|
||||
igraph_invalidate_cache(&g);
|
||||
BENCH(msg, REPEAT(igraph_connected_components(&g, &ivec, NULL, NULL, IGRAPH_WEAK), rep));
|
||||
|
||||
snprintf(msg, sizeof(msg) / sizeof(msg[0]),
|
||||
" 3 Strongly connected? vcount=%" IGRAPH_PRId ", meandeg=%g, %" IGRAPH_PRId "x",
|
||||
vcount, meandeg, 10*rep);
|
||||
|
||||
igraph_invalidate_cache(&g);
|
||||
BENCH(msg, REPEAT(igraph_is_connected(&g, &b, IGRAPH_STRONG), rep));
|
||||
|
||||
snprintf(msg, sizeof(msg) / sizeof(msg[0]),
|
||||
" 4 Strong components. vcount=%" IGRAPH_PRId ", meandeg=%g, %" IGRAPH_PRId "x",
|
||||
vcount, meandeg, rep);
|
||||
|
||||
igraph_invalidate_cache(&g);
|
||||
BENCH(msg, REPEAT(igraph_connected_components(&g, &ivec, NULL, NULL, IGRAPH_STRONG), rep));
|
||||
|
||||
snprintf(msg, sizeof(msg) / sizeof(msg[0]),
|
||||
" 5 Biconnected? vcount=%" IGRAPH_PRId ", meandeg=%g, %" IGRAPH_PRId "x",
|
||||
vcount, meandeg, rep);
|
||||
|
||||
igraph_invalidate_cache(&g);
|
||||
BENCH(msg, REPEAT(igraph_is_biconnected(&g, &b), rep));
|
||||
|
||||
snprintf(msg, sizeof(msg) / sizeof(msg[0]),
|
||||
" 6 Bridges. vcount=%" IGRAPH_PRId ", meandeg=%g, %" IGRAPH_PRId "x",
|
||||
vcount, meandeg, rep);
|
||||
|
||||
igraph_invalidate_cache(&g);
|
||||
BENCH(msg, REPEAT(igraph_bridges(&g, &ivec), rep));
|
||||
|
||||
snprintf(msg, sizeof(msg) / sizeof(msg[0]),
|
||||
" 7 Articulation pts. vcount=%" IGRAPH_PRId ", meandeg=%g, %" IGRAPH_PRId "x",
|
||||
vcount, meandeg, rep);
|
||||
|
||||
igraph_invalidate_cache(&g);
|
||||
BENCH(msg, REPEAT(igraph_articulation_points(&g, &ivec), rep));
|
||||
|
||||
igraph_vector_int_destroy(&ivec);
|
||||
igraph_destroy(&g);
|
||||
|
||||
printf("\n");
|
||||
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
|
||||
igraph_rng_seed(igraph_rng_default(), 137);
|
||||
BENCH_INIT();
|
||||
|
||||
// Note that whether these random graphs end up being connected
|
||||
// with high probability depends not only on their mean degree,
|
||||
// but also their vertex count.
|
||||
|
||||
run_bench(10000, 0.5, 100); // no giant component
|
||||
run_bench(10000, 3, 100); // not weakly connected
|
||||
run_bench(10000, 10, 100); // not strongly connected
|
||||
run_bench(10000, 20, 100); // strongly connnected
|
||||
|
||||
run_bench(100000, 0.5, 100); // no giant component
|
||||
run_bench(100000, 3, 100); // not weakly connected
|
||||
run_bench(100000, 10, 100); // not strongly connected
|
||||
run_bench(100000, 20, 100); // strongly connnected
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
igraph library.
|
||||
Copyright (C) 2024 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 "bench.h"
|
||||
|
||||
void gnp(igraph_int_t n, igraph_real_t p, igraph_bool_t directed, igraph_edge_type_sw_t allowed_edge_types) {
|
||||
igraph_t g;
|
||||
igraph_erdos_renyi_game_gnp(&g, n, p, directed, allowed_edge_types, IGRAPH_EDGE_UNLABELED);
|
||||
igraph_destroy(&g);
|
||||
}
|
||||
|
||||
void gnm(igraph_int_t n, igraph_real_t meandeg, igraph_bool_t directed, igraph_edge_type_sw_t allowed_edge_types) {
|
||||
igraph_t g;
|
||||
igraph_erdos_renyi_game_gnm(&g, n, round(directed ? n * meandeg : 0.5 * n * meandeg), directed, allowed_edge_types, IGRAPH_EDGE_UNLABELED);
|
||||
igraph_destroy(&g);
|
||||
}
|
||||
|
||||
void chung_lu(const igraph_vector_t *outdeg, const igraph_vector_t *indeg, igraph_bool_t loops) {
|
||||
igraph_t g;
|
||||
igraph_chung_lu_game(&g, outdeg, indeg, loops, IGRAPH_CHUNG_LU_ORIGINAL);
|
||||
igraph_destroy(&g);
|
||||
}
|
||||
|
||||
void run_bench(igraph_int_t vcount, igraph_real_t meandeg, igraph_int_t rep) {
|
||||
igraph_t g;
|
||||
igraph_real_t p = meandeg / vcount;
|
||||
igraph_vector_t outdeg, indeg;
|
||||
char msg[128], msg2[80];
|
||||
|
||||
snprintf(msg2, sizeof(msg2) / sizeof(msg2[0]),
|
||||
"vcount=%" IGRAPH_PRId ", meandeg=%g, %" IGRAPH_PRId "x",
|
||||
vcount, meandeg, rep);
|
||||
|
||||
igraph_vector_init(&outdeg, 0);
|
||||
igraph_vector_init(&indeg, 0);
|
||||
|
||||
igraph_erdos_renyi_game_gnp(&g, vcount, p, IGRAPH_UNDIRECTED, IGRAPH_SIMPLE_SW, IGRAPH_EDGE_UNLABELED);
|
||||
igraph_strength(&g, &outdeg, igraph_vss_all(), IGRAPH_ALL, IGRAPH_LOOPS, NULL);
|
||||
igraph_destroy(&g);
|
||||
|
||||
snprintf(msg, sizeof(msg) / sizeof(msg[0]),
|
||||
" 1 G(n,p) undirected, no loops / no multi, %s", msg2);
|
||||
BENCH(msg, REPEAT(gnp(vcount, p, IGRAPH_UNDIRECTED, IGRAPH_SIMPLE_SW), rep));
|
||||
|
||||
snprintf(msg, sizeof(msg) / sizeof(msg[0]),
|
||||
" 2 G(n,m) undirected, no loops / no multi, %s", msg2);
|
||||
BENCH(msg, REPEAT(gnm(vcount, meandeg, IGRAPH_UNDIRECTED, IGRAPH_SIMPLE_SW), rep));
|
||||
|
||||
snprintf(msg, sizeof(msg) / sizeof(msg[0]),
|
||||
" 3 Chung-Lu undirected, no loops, %s", msg2);
|
||||
BENCH(msg, REPEAT(chung_lu(&outdeg, NULL, IGRAPH_NO_LOOPS), rep));
|
||||
|
||||
printf("\n");
|
||||
|
||||
snprintf(msg, sizeof(msg) / sizeof(msg[0]),
|
||||
" 4 G(n,p) undirected, loops / no multi, %s", msg2);
|
||||
BENCH(msg, REPEAT(gnp(vcount, p, IGRAPH_UNDIRECTED, IGRAPH_LOOPS_SW), rep));
|
||||
|
||||
snprintf(msg, sizeof(msg) / sizeof(msg[0]),
|
||||
" 5 G(n,m) undirected, loops / no multi, %s", msg2);
|
||||
BENCH(msg, REPEAT(gnm(vcount, meandeg, IGRAPH_UNDIRECTED, IGRAPH_LOOPS_SW), rep));
|
||||
|
||||
snprintf(msg, sizeof(msg) / sizeof(msg[0]),
|
||||
" 6 Chung-Lu undirected, loops, %s", msg2);
|
||||
BENCH(msg, REPEAT(chung_lu(&outdeg, NULL, IGRAPH_LOOPS), rep));
|
||||
|
||||
printf("\n");
|
||||
|
||||
igraph_erdos_renyi_game_gnp(&g, vcount, p, IGRAPH_DIRECTED, IGRAPH_SIMPLE_SW, IGRAPH_EDGE_UNLABELED);
|
||||
igraph_strength(&g, &outdeg, igraph_vss_all(), IGRAPH_OUT, IGRAPH_LOOPS, NULL);
|
||||
igraph_strength(&g, &indeg, igraph_vss_all(), IGRAPH_IN, IGRAPH_LOOPS, NULL);
|
||||
igraph_destroy(&g);
|
||||
|
||||
snprintf(msg, sizeof(msg) / sizeof(msg[0]),
|
||||
" 7 G(n,p) directed, no loops / no multi, %s", msg2);
|
||||
BENCH(msg, REPEAT(gnp(vcount, p, IGRAPH_DIRECTED, IGRAPH_SIMPLE_SW), rep));
|
||||
|
||||
snprintf(msg, sizeof(msg) / sizeof(msg[0]),
|
||||
" 8 G(n,m) directed, no loops / no multi, %s", msg2);
|
||||
BENCH(msg, REPEAT(gnm(vcount, meandeg, IGRAPH_DIRECTED, IGRAPH_SIMPLE_SW), rep));
|
||||
|
||||
snprintf(msg, sizeof(msg) / sizeof(msg[0]),
|
||||
" 9 Chung-Lu directed, no loops, %s", msg2);
|
||||
BENCH(msg, REPEAT(chung_lu(&outdeg, &indeg, IGRAPH_NO_LOOPS), rep));
|
||||
|
||||
printf("\n");
|
||||
|
||||
snprintf(msg, sizeof(msg) / sizeof(msg[0]),
|
||||
"10 G(n,p) directed, loops / no multi, %s", msg2);
|
||||
BENCH(msg, REPEAT(gnp(vcount, p, IGRAPH_DIRECTED, IGRAPH_LOOPS_SW), rep));
|
||||
|
||||
snprintf(msg, sizeof(msg) / sizeof(msg[0]),
|
||||
"11 G(n,m) directed, loops / no multi, %s", msg2);
|
||||
BENCH(msg, REPEAT(gnm(vcount, meandeg, IGRAPH_DIRECTED, IGRAPH_LOOPS_SW), rep));
|
||||
|
||||
snprintf(msg, sizeof(msg) / sizeof(msg[0]),
|
||||
"12 Chung-Lu directed, loops, %s", msg2);
|
||||
BENCH(msg, REPEAT(chung_lu(&outdeg, &indeg, IGRAPH_LOOPS), rep));
|
||||
|
||||
printf("\n\n");
|
||||
|
||||
igraph_vector_destroy(&indeg);
|
||||
igraph_vector_destroy(&outdeg);
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
|
||||
igraph_rng_seed(igraph_rng_default(), 137);
|
||||
BENCH_INIT();
|
||||
|
||||
run_bench(100, 3, 10000);
|
||||
run_bench(10000, 3, 100);
|
||||
run_bench(1000000, 3, 1);
|
||||
|
||||
run_bench(10000, 1, 1000);
|
||||
run_bench(10000, 100, 10);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,144 @@
|
||||
/*
|
||||
igraph library.
|
||||
Copyright (C) 2024 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 "bench.h"
|
||||
|
||||
#define TOSTR1(x) #x
|
||||
#define TOSTR(x) TOSTR1(x)
|
||||
|
||||
#define BENCH_UNDIR(N, REP) \
|
||||
do { \
|
||||
igraph_barabasi_game(&graph, N, 1, 3, NULL, true, 0, IGRAPH_UNDIRECTED, IGRAPH_BARABASI_PSUMTREE, NULL); \
|
||||
igraph_degree(&graph, °, igraph_vss_all(), IGRAPH_ALL, IGRAPH_LOOPS); \
|
||||
igraph_destroy(&graph); \
|
||||
\
|
||||
BENCH("Undirected simple, PA, n = " TOSTR(N) ", " TOSTR(REP) "x", \
|
||||
REPEAT(igraph_is_graphical(°, NULL, IGRAPH_SIMPLE_SW, &graphical), REP); \
|
||||
); \
|
||||
\
|
||||
BENCH("Undirected loops, PA, n = " TOSTR(N) ", " TOSTR(REP) "x", \
|
||||
REPEAT(igraph_is_graphical(°, NULL, IGRAPH_LOOPS_SW, &graphical), REP); \
|
||||
); \
|
||||
\
|
||||
BENCH("Undirected multi, PA, n = " TOSTR(N) ", " TOSTR(REP) "x", \
|
||||
REPEAT(igraph_is_graphical(°, NULL, IGRAPH_MULTI_SW, &graphical), REP); \
|
||||
); \
|
||||
\
|
||||
BENCH("Undirected multi, loops, PA, n = " TOSTR(N) ", " TOSTR(REP) "x", \
|
||||
REPEAT(igraph_is_graphical(°, NULL, IGRAPH_MULTI_SW | IGRAPH_LOOPS_SW, &graphical), 100); \
|
||||
); \
|
||||
\
|
||||
igraph_erdos_renyi_game_gnp(&graph, N, 12.0/N, IGRAPH_UNDIRECTED, IGRAPH_LOOPS_SW, IGRAPH_EDGE_UNLABELED); \
|
||||
igraph_degree(&graph, °, igraph_vss_all(), IGRAPH_ALL, IGRAPH_LOOPS); \
|
||||
igraph_destroy(&graph); \
|
||||
\
|
||||
BENCH("Undirected simple, G(n,p), n = " TOSTR(N) ", " TOSTR(REP) "x", \
|
||||
REPEAT(igraph_is_graphical(°, NULL, IGRAPH_SIMPLE_SW, &graphical), REP); \
|
||||
); \
|
||||
\
|
||||
BENCH("Undirected loops, G(n,p), n = " TOSTR(N) ", " TOSTR(REP) "x", \
|
||||
REPEAT(igraph_is_graphical(°, NULL, IGRAPH_LOOPS_SW, &graphical), REP); \
|
||||
); \
|
||||
\
|
||||
BENCH("Undirected multi, G(n,p), n = " TOSTR(N) ", " TOSTR(REP) "x", \
|
||||
REPEAT(igraph_is_graphical(°, NULL, IGRAPH_MULTI_SW, &graphical), REP); \
|
||||
); \
|
||||
\
|
||||
BENCH("Undirected multi, loops, G(n,p), n = " TOSTR(N) ", " TOSTR(REP) "x", \
|
||||
REPEAT(igraph_is_graphical(°, NULL, IGRAPH_MULTI_SW | IGRAPH_LOOPS_SW, &graphical), 100); \
|
||||
); \
|
||||
\
|
||||
} while (0)
|
||||
|
||||
|
||||
#define BENCH_DIR(N, REP) \
|
||||
do { \
|
||||
igraph_barabasi_game(&graph, N, 1, 3, NULL, true, 0, IGRAPH_DIRECTED, IGRAPH_BARABASI_PSUMTREE, NULL); \
|
||||
igraph_degree(&graph, &outdeg, igraph_vss_all(), IGRAPH_OUT, IGRAPH_LOOPS); \
|
||||
igraph_degree(&graph, &indeg, igraph_vss_all(), IGRAPH_IN, IGRAPH_LOOPS); \
|
||||
igraph_destroy(&graph); \
|
||||
\
|
||||
BENCH("Directed simple, PA, n = " TOSTR(N) ", " TOSTR(REP) "x", \
|
||||
REPEAT(igraph_is_graphical(&outdeg, &indeg, IGRAPH_SIMPLE_SW, &graphical), REP); \
|
||||
); \
|
||||
\
|
||||
BENCH("Directed loops, PA, n = " TOSTR(N) ", " TOSTR(REP) "x", \
|
||||
REPEAT(igraph_is_graphical(&outdeg, &indeg, IGRAPH_LOOPS_SW, &graphical), REP); \
|
||||
); \
|
||||
\
|
||||
BENCH("Directed multi, PA, n = " TOSTR(N) ", " TOSTR(REP) "x", \
|
||||
REPEAT(igraph_is_graphical(&outdeg, &indeg, IGRAPH_MULTI_SW, &graphical), REP); \
|
||||
); \
|
||||
\
|
||||
BENCH("Directed multi, loops, PA, n = " TOSTR(N) ", " TOSTR(REP) "x", \
|
||||
REPEAT(igraph_is_graphical(&outdeg, &indeg, IGRAPH_MULTI_SW | IGRAPH_LOOPS_SW, &graphical), REP); \
|
||||
); \
|
||||
\
|
||||
igraph_erdos_renyi_game_gnp(&graph, N, 12.0/N, IGRAPH_DIRECTED, IGRAPH_LOOPS_SW, IGRAPH_EDGE_UNLABELED); \
|
||||
igraph_degree(&graph, &outdeg, igraph_vss_all(), IGRAPH_OUT, IGRAPH_LOOPS); \
|
||||
igraph_degree(&graph, &indeg, igraph_vss_all(), IGRAPH_IN, IGRAPH_LOOPS); \
|
||||
igraph_destroy(&graph); \
|
||||
\
|
||||
BENCH("Directed simple, G(n,p), n = " TOSTR(N) ", " TOSTR(REP) "x", \
|
||||
REPEAT(igraph_is_graphical(&outdeg, &indeg, IGRAPH_SIMPLE_SW, &graphical), REP); \
|
||||
); \
|
||||
\
|
||||
BENCH("Directed loops, G(n,p), n = " TOSTR(N) ", " TOSTR(REP) "x", \
|
||||
REPEAT(igraph_is_graphical(&outdeg, &indeg, IGRAPH_LOOPS_SW, &graphical), REP); \
|
||||
); \
|
||||
\
|
||||
BENCH("Directed multi, G(n,p), n = " TOSTR(N) ", " TOSTR(REP) "x", \
|
||||
REPEAT(igraph_is_graphical(&outdeg, &indeg, IGRAPH_MULTI_SW, &graphical), REP); \
|
||||
); \
|
||||
\
|
||||
BENCH("Directed multi, loops, G(n,p), n = " TOSTR(N) ", " TOSTR(REP) "x", \
|
||||
REPEAT(igraph_is_graphical(&outdeg, &indeg, IGRAPH_MULTI_SW | IGRAPH_LOOPS_SW, &graphical), REP); \
|
||||
); \
|
||||
\
|
||||
} while (0)
|
||||
|
||||
|
||||
int main(void) {
|
||||
igraph_t graph;
|
||||
igraph_vector_int_t deg, outdeg, indeg;
|
||||
igraph_bool_t graphical;
|
||||
|
||||
BENCH_INIT();
|
||||
igraph_rng_seed(igraph_rng_default(), 42);
|
||||
|
||||
igraph_vector_int_init(°, 0);
|
||||
igraph_vector_int_init(&outdeg, 0);
|
||||
igraph_vector_int_init(&indeg, 0);
|
||||
|
||||
BENCH_UNDIR(50, 2000000);
|
||||
BENCH_DIR(50, 2000000);
|
||||
printf("\n");
|
||||
BENCH_UNDIR(1000, 100000);
|
||||
BENCH_DIR(1000, 100000);
|
||||
printf("\n");
|
||||
BENCH_UNDIR(1000000, 100);
|
||||
BENCH_DIR(1000000, 100);
|
||||
|
||||
igraph_vector_int_destroy(°);
|
||||
igraph_vector_int_destroy(&outdeg);
|
||||
igraph_vector_int_destroy(&indeg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
igraph library.
|
||||
Copyright (C) 2024 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 "bench.h"
|
||||
|
||||
/*
|
||||
* Benchmark creating graphs from dense adjacency matrices.
|
||||
*
|
||||
* When there are a small number of non-zero elements (low mean degree),
|
||||
* iterating through the matrix dominates the timing. When there are
|
||||
* many non-zero elements, creating the graphfrom its edge list dominates.
|
||||
*/
|
||||
|
||||
void adjacency(const igraph_matrix_t *adjmatrix, igraph_adjacency_t mode, igraph_loops_t loops) {
|
||||
igraph_t g;
|
||||
igraph_adjacency(&g, adjmatrix, mode, loops);
|
||||
igraph_destroy(&g);
|
||||
}
|
||||
|
||||
void weighted_adjacency(const igraph_matrix_t *adjmatrix, igraph_adjacency_t mode, igraph_vector_t *weights, igraph_loops_t loops) {
|
||||
igraph_t g;
|
||||
igraph_weighted_adjacency(&g, adjmatrix, mode, weights, loops);
|
||||
igraph_destroy(&g);
|
||||
}
|
||||
|
||||
void run_bench(igraph_int_t vcount, igraph_int_t meandeg, igraph_int_t rep) {
|
||||
igraph_t g;
|
||||
igraph_matrix_t mat;
|
||||
igraph_vector_t weights;
|
||||
char msg[128];
|
||||
igraph_adjacency_t types[] = {
|
||||
IGRAPH_ADJ_DIRECTED,
|
||||
IGRAPH_ADJ_MAX,
|
||||
IGRAPH_ADJ_PLUS,
|
||||
IGRAPH_ADJ_UPPER /* similar to DIRECTED when unweighted, similar to MAX when weighted */
|
||||
};
|
||||
const char *names[] = { "DIRECTED", "MAX", "PLUS", "UPPER" };
|
||||
|
||||
igraph_matrix_init(&mat, 0, 0);
|
||||
|
||||
igraph_erdos_renyi_game_gnm(&g, vcount, meandeg * vcount / 2, IGRAPH_DIRECTED, IGRAPH_LOOPS_SW | IGRAPH_MULTI_SW,
|
||||
false);
|
||||
igraph_get_adjacency(&g, &mat, IGRAPH_GET_ADJACENCY_BOTH, NULL, IGRAPH_LOOPS_ONCE);
|
||||
|
||||
igraph_vector_init(&weights, igraph_ecount(&g));
|
||||
|
||||
igraph_destroy(&g);
|
||||
|
||||
for (size_t i=0; i < sizeof(types) / sizeof(types[0]); i++) {
|
||||
snprintf(msg, sizeof(msg) / sizeof(msg[0]),
|
||||
"%2d vcount=%" IGRAPH_PRId ", meandeg=%3" IGRAPH_PRId ", %8s, unweighted, %" IGRAPH_PRId "x",
|
||||
(int) i+1, vcount, meandeg, names[i], rep);
|
||||
|
||||
BENCH(msg, REPEAT(adjacency(&mat, types[i], IGRAPH_LOOPS_ONCE), rep));
|
||||
|
||||
snprintf(msg, sizeof(msg) / sizeof(msg[0]),
|
||||
"%2d vcount=%" IGRAPH_PRId ", meandeg=%3" IGRAPH_PRId ", %8s, weighted, %" IGRAPH_PRId "x",
|
||||
(int) i+1, vcount, meandeg, names[i], rep);
|
||||
|
||||
BENCH(msg, REPEAT(weighted_adjacency(&mat, types[i], &weights, IGRAPH_LOOPS_ONCE), rep));
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
igraph_vector_destroy(&weights);
|
||||
igraph_matrix_destroy(&mat);
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
|
||||
igraph_rng_seed(igraph_rng_default(), 137);
|
||||
BENCH_INIT();
|
||||
|
||||
run_bench(100, 5, 10000);
|
||||
run_bench(100, 50, 10000);
|
||||
run_bench(1000, 5, 100);
|
||||
run_bench(1000, 50, 100);
|
||||
run_bench(1000, 500, 100);
|
||||
run_bench(10000, 5, 1);
|
||||
run_bench(10000, 50, 1);
|
||||
run_bench(10000, 500, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
igraph library.
|
||||
Copyright (C) 2024 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 "bench.h"
|
||||
|
||||
int main(void) {
|
||||
igraph_t graph;
|
||||
igraph_real_t avglen;
|
||||
igraph_matrix_t mat;
|
||||
|
||||
BENCH_INIT();
|
||||
igraph_rng_seed(igraph_rng_default(), 42);
|
||||
|
||||
igraph_matrix_init(&mat, 0, 0);
|
||||
|
||||
igraph_kautz(&graph, 4, 5);
|
||||
igraph_matrix_resize(&mat, igraph_vcount(&graph), igraph_vcount(&graph)); /* preallocate matrix */
|
||||
|
||||
BENCH(" 1 Kautz(4, 5) average_path_length directed",
|
||||
igraph_average_path_length(&graph, NULL, &avglen, NULL, IGRAPH_DIRECTED, 1);
|
||||
);
|
||||
BENCH(" 2 Kautz(4, 5) distances directed",
|
||||
igraph_distances(&graph, NULL, &mat, igraph_vss_all(), igraph_vss_all(), IGRAPH_OUT);
|
||||
);
|
||||
BENCH(" 3 Kautz(4, 5) average_path_length undirected",
|
||||
igraph_average_path_length(&graph, NULL, &avglen, NULL, IGRAPH_UNDIRECTED, 1);
|
||||
);
|
||||
BENCH(" 4 Kautz(4, 5) distances undirected",
|
||||
igraph_distances(&graph, NULL, &mat, igraph_vss_all(), igraph_vss_all(), IGRAPH_ALL);
|
||||
);
|
||||
|
||||
igraph_destroy(&graph);
|
||||
|
||||
{
|
||||
igraph_vector_int_t dims;
|
||||
igraph_vector_bool_t periodic;
|
||||
igraph_vector_int_init_int(&dims, 3, 15, 15, 15);
|
||||
igraph_vector_bool_init_int(&periodic, 3, 1, 1, 1);
|
||||
igraph_square_lattice(&graph, &dims, 1, IGRAPH_UNDIRECTED, 0, &periodic);
|
||||
igraph_vector_int_destroy(&dims);
|
||||
igraph_vector_bool_destroy(&periodic);
|
||||
igraph_rewire(&graph, 100, IGRAPH_SIMPLE_SW, NULL);
|
||||
igraph_matrix_resize(&mat, igraph_vcount(&graph), igraph_vcount(&graph)); /* preallocate matrix */
|
||||
}
|
||||
|
||||
BENCH(" 5 Rewired 15x15x15 lattice average_path_length",
|
||||
igraph_average_path_length(&graph, NULL, &avglen, NULL, IGRAPH_UNDIRECTED, 1);
|
||||
);
|
||||
BENCH(" 6 Rewired 15x15x15 lattice distances undirected",
|
||||
igraph_distances(&graph, NULL, &mat, igraph_vss_all(), igraph_vss_all(), IGRAPH_ALL);
|
||||
);
|
||||
|
||||
igraph_destroy(&graph);
|
||||
|
||||
igraph_erdos_renyi_game_gnm(&graph, 10000, 12000, IGRAPH_DIRECTED, IGRAPH_LOOPS_SW, IGRAPH_EDGE_UNLABELED);
|
||||
igraph_matrix_resize(&mat, igraph_vcount(&graph), igraph_vcount(&graph)); /* preallocate matrix */
|
||||
|
||||
BENCH(" 7 Erdos-Renyi n=10000 m=12000 average_path_length directed",
|
||||
igraph_average_path_length(&graph, NULL, &avglen, NULL, IGRAPH_DIRECTED, 1);
|
||||
);
|
||||
BENCH(" 8 Erdos-Renyi n=10000 m=12000 distances directed",
|
||||
igraph_distances(&graph, NULL, &mat, igraph_vss_all(), igraph_vss_all(), IGRAPH_OUT);
|
||||
);
|
||||
|
||||
/* The undirected computation will be much slower on this graph, as the largest weakly connected
|
||||
* component is much larger. */
|
||||
BENCH(" 9 Erdos-Renyi n=10000 m=12000 average_path_length undirected",
|
||||
igraph_average_path_length(&graph, NULL, &avglen, NULL, IGRAPH_UNDIRECTED, 1);
|
||||
);
|
||||
BENCH("10 Erdos-Renyi n=10000 m=12000 distances undirected",
|
||||
igraph_distances(&graph, NULL, &mat, igraph_vss_all(), igraph_vss_all(), IGRAPH_ALL);
|
||||
);
|
||||
|
||||
igraph_destroy(&graph);
|
||||
igraph_matrix_destroy(&mat);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
igraph library.
|
||||
Copyright (C) 2024 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 "bench.h"
|
||||
|
||||
int main(void) {
|
||||
igraph_t graph;
|
||||
igraph_vector_t betweenness;
|
||||
|
||||
BENCH_INIT();
|
||||
igraph_rng_seed(igraph_rng_default(), 42);
|
||||
|
||||
igraph_vector_init(&betweenness, 0);
|
||||
|
||||
/* Kautz and De Bruijn graphs are connected, therefore there should not be a dramatic difference
|
||||
* in the performance of the directed and undirected calculations. */
|
||||
|
||||
igraph_kautz(&graph, 4, 5);
|
||||
BENCH(" 1 Betweenness, Kautz(4,5), directed",
|
||||
igraph_betweenness(&graph, NULL, &betweenness, igraph_vss_all(), IGRAPH_DIRECTED, false));
|
||||
BENCH(" 2 Betweenness, Kautz(4,5), undirected",
|
||||
igraph_betweenness(&graph, NULL, &betweenness, igraph_vss_all(), IGRAPH_UNDIRECTED, false));
|
||||
igraph_destroy(&graph);
|
||||
|
||||
igraph_de_bruijn(&graph, 6, 5);
|
||||
BENCH(" 3 Betweenness, DeBruijn(6,5), directed",
|
||||
igraph_betweenness(&graph, NULL, &betweenness, igraph_vss_all(), IGRAPH_DIRECTED, false));
|
||||
igraph_destroy(&graph);
|
||||
|
||||
{
|
||||
igraph_vector_int_t dims;
|
||||
|
||||
igraph_vector_int_init_int_end(&dims, -1, 8, 8, 8, 8, -1);
|
||||
igraph_square_lattice(&graph, &dims, 1, IGRAPH_UNDIRECTED, /* mutual */ 0, /* periodic */ 0);
|
||||
BENCH(" 4 Betweenness, Grid(8,8,8,8), undirected",
|
||||
igraph_betweenness(&graph, NULL, &betweenness, igraph_vss_all(), IGRAPH_UNDIRECTED, false));
|
||||
igraph_destroy(&graph);
|
||||
igraph_vector_int_destroy(&dims);
|
||||
|
||||
igraph_vector_int_init_int_end(&dims, -1, 10, 10, 10, 10, -1);
|
||||
igraph_square_lattice(&graph, &dims, 1, IGRAPH_UNDIRECTED, /* mutual */ 0, /* periodic */ 0);
|
||||
BENCH(" 5 Betweenness, Grid(10,10,10,10), cutoff 5",
|
||||
igraph_betweenness_cutoff(&graph, NULL, &betweenness, igraph_vss_all(), IGRAPH_UNDIRECTED, false, 5));
|
||||
BENCH(" 6 Betweenness, Grid(10,10,10,10), cutoff 8",
|
||||
igraph_betweenness_cutoff(&graph, NULL, &betweenness, igraph_vss_all(), IGRAPH_UNDIRECTED, false, 8));
|
||||
igraph_destroy(&graph);
|
||||
igraph_vector_int_destroy(&dims);
|
||||
}
|
||||
|
||||
igraph_barabasi_game(&graph, 8000, 1, 1, NULL, 1, 0, IGRAPH_UNDIRECTED, IGRAPH_BARABASI_PSUMTREE, NULL);
|
||||
BENCH(" 7 Betweenness, Barabasi n=8000 m=1, undirected",
|
||||
igraph_betweenness(&graph, NULL, &betweenness, igraph_vss_all(), IGRAPH_UNDIRECTED, false));
|
||||
BENCH(" 8 Betweenness, Barabasi n=8000 m=1, undirected, cutoff 6",
|
||||
igraph_betweenness_cutoff(&graph, NULL, &betweenness, igraph_vss_all(), IGRAPH_UNDIRECTED, false, 6));
|
||||
igraph_destroy(&graph);
|
||||
|
||||
igraph_barabasi_game(&graph, 30000, 1, 5, NULL, 1, 0, IGRAPH_DIRECTED, IGRAPH_BARABASI_PSUMTREE, NULL);
|
||||
BENCH(" 9 Betweenness, Barabasi n=30000 m=5, directed",
|
||||
igraph_betweenness(&graph, NULL, &betweenness, igraph_vss_all(), IGRAPH_DIRECTED, false));
|
||||
BENCH("10 Betweenness, Barabasi n=30000 m=5, directed, cutoff 5",
|
||||
igraph_betweenness_cutoff(&graph, NULL, &betweenness, igraph_vss_all(), IGRAPH_DIRECTED, false, 5));
|
||||
igraph_destroy(&graph);
|
||||
|
||||
igraph_vector_destroy(&betweenness);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,164 @@
|
||||
/*
|
||||
igraph library.
|
||||
Copyright (C) 2024 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 "bench.h"
|
||||
|
||||
void rand_weight_vec(igraph_vector_t *vec, const igraph_t *graph) {
|
||||
const igraph_int_t n = igraph_ecount(graph);
|
||||
igraph_vector_resize(vec, n);
|
||||
for (igraph_int_t i=0; i < n; ++i) {
|
||||
VECTOR(*vec)[i] = RNG_UNIF(1, 10);
|
||||
}
|
||||
}
|
||||
|
||||
#define TOSTR1(x) #x
|
||||
#define TOSTR(x) TOSTR1(x)
|
||||
|
||||
int main(void) {
|
||||
igraph_t graph;
|
||||
igraph_vector_t betweenness, weight;
|
||||
|
||||
/* These betweenness benchmarks are identical to the weighted closeness ones. */
|
||||
|
||||
/* This benchmark compares directed/undirected and weighted/unweighted calculations
|
||||
* on the same graphs. */
|
||||
|
||||
BENCH_INIT();
|
||||
igraph_rng_seed(igraph_rng_default(), 42);
|
||||
|
||||
igraph_vector_init(&betweenness, 0);
|
||||
igraph_vector_init(&weight, 0);
|
||||
|
||||
igraph_kautz(&graph, 4, 3);
|
||||
|
||||
/* Kautz and De Bruijn graphs are connected, therefore there should not be a dramatic difference
|
||||
* in the performance of the directed and undirected calculations. */
|
||||
|
||||
#define NAME "Kautz(4,3)"
|
||||
#define REP 100
|
||||
|
||||
BENCH(" 1 Betweenness, unweighted, " NAME ", directed, " TOSTR(REP) "x",
|
||||
REPEAT(igraph_betweenness(&graph, NULL, &betweenness, igraph_vss_all(), IGRAPH_DIRECTED, false), REP)
|
||||
);
|
||||
BENCH(" 2 Betweenness, unweighted, " NAME ", undirected, " TOSTR(REP) "x",
|
||||
REPEAT(igraph_betweenness(&graph, NULL, &betweenness, igraph_vss_all(), IGRAPH_UNDIRECTED, false), REP)
|
||||
);
|
||||
|
||||
rand_weight_vec(&weight, &graph);
|
||||
|
||||
BENCH(" 3 Betweenness, weighted, " NAME ", directed, " TOSTR(REP) "x",
|
||||
REPEAT(igraph_betweenness(&graph, &weight, &betweenness, igraph_vss_all(), IGRAPH_DIRECTED, false), REP)
|
||||
);
|
||||
BENCH(" 4 Betweenness, weighted, " NAME ", undirected, " TOSTR(REP) "x",
|
||||
REPEAT(igraph_betweenness(&graph, &weight, &betweenness, igraph_vss_all(), IGRAPH_UNDIRECTED, false), REP)
|
||||
);
|
||||
|
||||
igraph_destroy(&graph);
|
||||
|
||||
#undef NAME
|
||||
#undef REP
|
||||
|
||||
#define NAME "DeBruijn(5,5)"
|
||||
#define REP 1
|
||||
|
||||
igraph_de_bruijn(&graph, 5, 5);
|
||||
|
||||
BENCH(" 5 Betweenness, unweighted, " NAME ", directed, " TOSTR(REP) "x",
|
||||
REPEAT(igraph_betweenness(&graph, NULL, &betweenness, igraph_vss_all(), IGRAPH_DIRECTED, false), REP)
|
||||
);
|
||||
BENCH(" 6 Betweenness, unweighted, " NAME ", undirected, " TOSTR(REP) "x",
|
||||
REPEAT(igraph_betweenness(&graph, NULL, &betweenness, igraph_vss_all(), IGRAPH_UNDIRECTED, false), REP)
|
||||
);
|
||||
|
||||
rand_weight_vec(&weight, &graph);
|
||||
|
||||
BENCH(" 7 Betweenness, weighted, " NAME ", directed, " TOSTR(REP) "x",
|
||||
REPEAT(igraph_betweenness(&graph, &weight, &betweenness, igraph_vss_all(), IGRAPH_DIRECTED, false), REP)
|
||||
);
|
||||
BENCH(" 8 Betweenness, weighted, " NAME ", undirected, " TOSTR(REP) "x",
|
||||
REPEAT(igraph_betweenness(&graph, &weight, &betweenness, igraph_vss_all(), IGRAPH_UNDIRECTED, false), REP)
|
||||
);
|
||||
|
||||
igraph_destroy(&graph);
|
||||
|
||||
#undef NAME
|
||||
#undef REP
|
||||
|
||||
/* Choose the parameters of the Erdős-Rényi model so that the graph will have a large strongly connected
|
||||
* giant component. With 3000 vertices and 10000 edges, it is likely to contain over 90% of vertices.
|
||||
* If the graph does not have a giant component, then the directed betweenness calculation will be very
|
||||
* fast, and not directly comparable to the undirected one. */
|
||||
|
||||
#define NAME "GNM(3000,10000)"
|
||||
#define REP 1
|
||||
|
||||
igraph_erdos_renyi_game_gnm(&graph, 3000, 10000, IGRAPH_DIRECTED, IGRAPH_LOOPS_SW, IGRAPH_EDGE_UNLABELED);
|
||||
|
||||
BENCH(" 9 Betweenness, unweighted, " NAME ", directed, " TOSTR(REP) "x",
|
||||
REPEAT(igraph_betweenness(&graph, NULL, &betweenness, igraph_vss_all(), IGRAPH_DIRECTED, false), REP)
|
||||
);
|
||||
BENCH("10 Betweenness, unweighted, " NAME ", undirected, " TOSTR(REP) "x",
|
||||
REPEAT(igraph_betweenness(&graph, NULL, &betweenness, igraph_vss_all(), IGRAPH_UNDIRECTED, false), REP)
|
||||
);
|
||||
|
||||
rand_weight_vec(&weight, &graph);
|
||||
|
||||
BENCH("11 Betweenness, weighted, " NAME ", directed, " TOSTR(REP) "x",
|
||||
REPEAT(igraph_betweenness(&graph, &weight, &betweenness, igraph_vss_all(), IGRAPH_DIRECTED, false), REP)
|
||||
);
|
||||
BENCH("12 Betweenness, weighted, " NAME ", undirected, " TOSTR(REP) "x",
|
||||
REPEAT(igraph_betweenness(&graph, &weight, &betweenness, igraph_vss_all(), IGRAPH_UNDIRECTED, false), REP)
|
||||
);
|
||||
|
||||
igraph_destroy(&graph);
|
||||
|
||||
#undef NAME
|
||||
#undef REP
|
||||
|
||||
/* Benchmark a much denser Erdős-Rényi graph as well. */
|
||||
|
||||
#define NAME "GNM(3000,30000)"
|
||||
#define REP 1
|
||||
|
||||
igraph_erdos_renyi_game_gnm(&graph, 3000, 30000, IGRAPH_DIRECTED, IGRAPH_LOOPS_SW, IGRAPH_EDGE_UNLABELED);
|
||||
|
||||
BENCH("13 Betweenness, unweighted, " NAME ", directed, " TOSTR(REP) "x",
|
||||
REPEAT(igraph_betweenness(&graph, NULL, &betweenness, igraph_vss_all(), IGRAPH_DIRECTED, false), REP)
|
||||
);
|
||||
BENCH("14 Betweenness, unweighted, " NAME ", undirected, " TOSTR(REP) "x",
|
||||
REPEAT(igraph_betweenness(&graph, NULL, &betweenness, igraph_vss_all(), IGRAPH_UNDIRECTED, false), REP)
|
||||
);
|
||||
|
||||
rand_weight_vec(&weight, &graph);
|
||||
|
||||
BENCH("15 Betweenness, weighted, " NAME ", directed, " TOSTR(REP) "x",
|
||||
REPEAT(igraph_betweenness(&graph, &weight, &betweenness, igraph_vss_all(), IGRAPH_DIRECTED, false), REP)
|
||||
);
|
||||
BENCH("16 Betweenness, weighted, " NAME ", undirected, " TOSTR(REP) "x",
|
||||
REPEAT(igraph_betweenness(&graph, &weight, &betweenness, igraph_vss_all(), IGRAPH_UNDIRECTED, false), REP)
|
||||
);
|
||||
|
||||
igraph_destroy(&graph);
|
||||
|
||||
igraph_vector_destroy(&weight);
|
||||
igraph_vector_destroy(&betweenness);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
igraph library.
|
||||
Copyright (C) 2024 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 "bench.h"
|
||||
|
||||
int main(void) {
|
||||
igraph_t g;
|
||||
igraph_vector_int_list_t res;
|
||||
igraph_int_t res_int;
|
||||
|
||||
igraph_rng_seed(igraph_rng_default(), 42);
|
||||
BENCH_INIT();
|
||||
|
||||
igraph_vector_int_list_init(&res, 0);
|
||||
|
||||
igraph_erdos_renyi_game_gnm(&g, 100, 3000, IGRAPH_UNDIRECTED, IGRAPH_SIMPLE_SW, IGRAPH_EDGE_UNLABELED);
|
||||
BENCH(" 1 Cliques in random graph with 100 vertices and 3000 edges",
|
||||
igraph_cliques(&g, &res, /* min_size= */ 0, /* max_size= */ 0, -1);
|
||||
);
|
||||
igraph_destroy(&g);
|
||||
igraph_vector_int_list_clear(&res);
|
||||
|
||||
igraph_erdos_renyi_game_gnm(&g, 200, 10000, IGRAPH_UNDIRECTED, IGRAPH_SIMPLE_SW, IGRAPH_EDGE_UNLABELED);
|
||||
BENCH(" 2 Cliques in random graph with 200 vertices and 10000 edges, up to size 5",
|
||||
igraph_cliques(&g, &res, /* min_size= */ 0, /* max_size= */ 5, -1);
|
||||
);
|
||||
igraph_vector_int_list_clear(&res);
|
||||
BENCH(" 3 Clique number of the same graph with 200 vertices and 10000 edges",
|
||||
igraph_clique_number(&g, &res_int);
|
||||
);
|
||||
igraph_vector_int_list_clear(&res);
|
||||
igraph_destroy(&g);
|
||||
|
||||
igraph_vector_int_list_destroy(&res);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,164 @@
|
||||
/*
|
||||
igraph library.
|
||||
Copyright (C) 2024 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 "bench.h"
|
||||
|
||||
void rand_weight_vec(igraph_vector_t *vec, const igraph_t *graph) {
|
||||
const igraph_int_t n = igraph_ecount(graph);
|
||||
igraph_vector_resize(vec, n);
|
||||
for (igraph_int_t i=0; i < n; ++i) {
|
||||
VECTOR(*vec)[i] = RNG_UNIF(1, 10);
|
||||
}
|
||||
}
|
||||
|
||||
#define TOSTR1(x) #x
|
||||
#define TOSTR(x) TOSTR1(x)
|
||||
|
||||
int main(void) {
|
||||
igraph_t graph;
|
||||
igraph_vector_t closeness, weight;
|
||||
|
||||
/* These closeness benchmarks are identical to the weighted betweenness ones. */
|
||||
|
||||
/* This benchmark compares directed/undirected and weighted/unweighted calculations
|
||||
* on the same graphs. */
|
||||
|
||||
BENCH_INIT();
|
||||
igraph_rng_seed(igraph_rng_default(), 42);
|
||||
|
||||
igraph_vector_init(&closeness, 0);
|
||||
igraph_vector_init(&weight, 0);
|
||||
|
||||
igraph_kautz(&graph, 4, 3);
|
||||
|
||||
/* Kautz and De Bruijn graphs are connected, therefore there should not be a dramatic difference
|
||||
* in the performance of the directed and undirected calculations. */
|
||||
|
||||
#define NAME "Kautz(4,3)"
|
||||
#define REP 100
|
||||
|
||||
BENCH(" 1 Closeness, unweighted, " NAME ", directed, " TOSTR(REP) "x",
|
||||
REPEAT(igraph_closeness(&graph, &closeness, NULL, NULL, igraph_vss_all(), IGRAPH_OUT, NULL, 1), REP)
|
||||
);
|
||||
BENCH(" 2 Closeness, unweighted, " NAME ", undirected, " TOSTR(REP) "x",
|
||||
REPEAT(igraph_closeness(&graph, &closeness, NULL, NULL, igraph_vss_all(), IGRAPH_ALL, NULL, 1), REP)
|
||||
);
|
||||
|
||||
rand_weight_vec(&weight, &graph);
|
||||
|
||||
BENCH(" 3 Closeness, weighted, " NAME ", directed, " TOSTR(REP) "x",
|
||||
REPEAT(igraph_closeness(&graph, &closeness, NULL, NULL, igraph_vss_all(), IGRAPH_OUT, &weight, 1), REP)
|
||||
);
|
||||
BENCH(" 4 Closeness, weighted, " NAME ", undirected, " TOSTR(REP) "x",
|
||||
REPEAT(igraph_closeness(&graph, &closeness, NULL, NULL, igraph_vss_all(), IGRAPH_ALL, &weight, 1), REP)
|
||||
);
|
||||
|
||||
igraph_destroy(&graph);
|
||||
|
||||
#undef NAME
|
||||
#undef REP
|
||||
|
||||
#define NAME "DeBruijn(5,5)"
|
||||
#define REP 1
|
||||
|
||||
igraph_de_bruijn(&graph, 5, 5);
|
||||
|
||||
BENCH(" 5 Closeness, unweighted, " NAME ", directed, " TOSTR(REP) "x",
|
||||
REPEAT(igraph_closeness(&graph, &closeness, NULL, NULL, igraph_vss_all(), IGRAPH_OUT, NULL, 1), REP)
|
||||
);
|
||||
BENCH(" 6 Closeness, unweighted, " NAME ", undirected, " TOSTR(REP) "x",
|
||||
REPEAT(igraph_closeness(&graph, &closeness, NULL, NULL, igraph_vss_all(), IGRAPH_ALL, NULL, 1), REP)
|
||||
);
|
||||
|
||||
rand_weight_vec(&weight, &graph);
|
||||
|
||||
BENCH(" 7 Closeness, weighted, " NAME ", directed, " TOSTR(REP) "x",
|
||||
REPEAT(igraph_closeness(&graph, &closeness, NULL, NULL, igraph_vss_all(), IGRAPH_OUT, &weight, 1), REP)
|
||||
);
|
||||
BENCH(" 8 Closeness, weighted, " NAME ", undirected, " TOSTR(REP) "x",
|
||||
REPEAT(igraph_closeness(&graph, &closeness, NULL, NULL, igraph_vss_all(), IGRAPH_ALL, &weight, 1), REP)
|
||||
);
|
||||
|
||||
igraph_destroy(&graph);
|
||||
|
||||
#undef NAME
|
||||
#undef REP
|
||||
|
||||
/* Choose the parameters of the Erdős-Rényi model so that the graph will have a large strongly connected
|
||||
* giant component. With 3000 vertices and 10000 edges, it is likely to contain over 90% of vertices.
|
||||
* If the graph does not have a giant component, then the directed betweenness calculation will be very
|
||||
* fast, and not directly comparable to the undirected one. */
|
||||
|
||||
#define NAME "GNM(3000,10000)"
|
||||
#define REP 1
|
||||
|
||||
igraph_erdos_renyi_game_gnm(&graph, 3000, 10000, IGRAPH_DIRECTED, IGRAPH_LOOPS_SW, IGRAPH_EDGE_UNLABELED);
|
||||
|
||||
BENCH(" 9 Closeness, unweighted, " NAME ", directed, " TOSTR(REP) "x",
|
||||
REPEAT(igraph_closeness(&graph, &closeness, NULL, NULL, igraph_vss_all(), IGRAPH_OUT, NULL, 1), REP)
|
||||
);
|
||||
BENCH("10 Closeness, unweighted, " NAME ", undirected, " TOSTR(REP) "x",
|
||||
REPEAT(igraph_closeness(&graph, &closeness, NULL, NULL, igraph_vss_all(), IGRAPH_ALL, NULL, 1), REP)
|
||||
);
|
||||
|
||||
rand_weight_vec(&weight, &graph);
|
||||
|
||||
BENCH("11 Closeness, weighted, " NAME ", directed, " TOSTR(REP) "x",
|
||||
REPEAT(igraph_closeness(&graph, &closeness, NULL, NULL, igraph_vss_all(), IGRAPH_OUT, &weight, 1), REP)
|
||||
);
|
||||
BENCH("12 Closeness, weighted, " NAME ", undirected, " TOSTR(REP) "x",
|
||||
REPEAT(igraph_closeness(&graph, &closeness, NULL, NULL, igraph_vss_all(), IGRAPH_ALL, &weight, 1), REP)
|
||||
);
|
||||
|
||||
igraph_destroy(&graph);
|
||||
|
||||
#undef NAME
|
||||
#undef REP
|
||||
|
||||
/* Benchmark a much denser Erdős-Rényi graph as well. */
|
||||
|
||||
#define NAME "GNM(3000,30000)"
|
||||
#define REP 1
|
||||
|
||||
igraph_erdos_renyi_game_gnm(&graph, 3000, 30000, IGRAPH_DIRECTED, IGRAPH_LOOPS_SW, IGRAPH_EDGE_UNLABELED);
|
||||
|
||||
BENCH("13 Closeness, unweighted, " NAME ", directed, " TOSTR(REP) "x",
|
||||
REPEAT(igraph_closeness(&graph, &closeness, NULL, NULL, igraph_vss_all(), IGRAPH_OUT, NULL, 1), REP)
|
||||
);
|
||||
BENCH("14 Closeness, unweighted, " NAME ", undirected, " TOSTR(REP) "x",
|
||||
REPEAT(igraph_closeness(&graph, &closeness, NULL, NULL, igraph_vss_all(), IGRAPH_ALL, NULL, 1), REP)
|
||||
);
|
||||
|
||||
rand_weight_vec(&weight, &graph);
|
||||
|
||||
BENCH("15 Closeness, weighted, " NAME ", directed, " TOSTR(REP) "x",
|
||||
REPEAT(igraph_closeness(&graph, &closeness, NULL, NULL, igraph_vss_all(), IGRAPH_OUT, &weight, 1), REP)
|
||||
);
|
||||
BENCH("16 Closeness, weighted, " NAME ", undirected, " TOSTR(REP) "x",
|
||||
REPEAT(igraph_closeness(&graph, &closeness, NULL, NULL, igraph_vss_all(), IGRAPH_ALL, &weight, 1), REP)
|
||||
);
|
||||
|
||||
igraph_destroy(&graph);
|
||||
|
||||
igraph_vector_destroy(&weight);
|
||||
igraph_vector_destroy(&closeness);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
igraph library.
|
||||
Copyright (C) 2024 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 "bench.h"
|
||||
|
||||
int main(void) {
|
||||
igraph_t g;
|
||||
igraph_graph_list_t res;
|
||||
|
||||
igraph_rng_seed(igraph_rng_default(), 42);
|
||||
BENCH_INIT();
|
||||
|
||||
igraph_graph_list_init(&res, 0);
|
||||
|
||||
igraph_empty(&g, 1000, IGRAPH_UNDIRECTED);
|
||||
BENCH(" 1 Decompose graph with 1000 isolated vertices",
|
||||
igraph_decompose(&g, &res, IGRAPH_WEAK, -1, -1);
|
||||
);
|
||||
igraph_destroy(&g);
|
||||
igraph_graph_list_clear(&res);
|
||||
|
||||
igraph_empty(&g, 10000, IGRAPH_UNDIRECTED);
|
||||
BENCH(" 2 Decompose graph with 10000 isolated vertices",
|
||||
igraph_decompose(&g, &res, IGRAPH_WEAK, -1, -1);
|
||||
);
|
||||
igraph_destroy(&g);
|
||||
igraph_graph_list_clear(&res);
|
||||
|
||||
igraph_empty(&g, 100000, IGRAPH_UNDIRECTED);
|
||||
BENCH(" 3 Decompose graph with 100000 isolated vertices",
|
||||
igraph_decompose(&g, &res, IGRAPH_WEAK, -1, -1);
|
||||
);
|
||||
igraph_destroy(&g);
|
||||
igraph_graph_list_clear(&res);
|
||||
|
||||
igraph_graph_list_destroy(&res);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,142 @@
|
||||
/*
|
||||
igraph library.
|
||||
Copyright (C) 2024 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 "bench.h"
|
||||
|
||||
#define TOSTR1(x) #x
|
||||
#define TOSTR(x) TOSTR1(x)
|
||||
|
||||
/* Calls igraph_degree_1() separately for each vertex. */
|
||||
void deg1(const igraph_t *g, igraph_vector_int_t *res, igraph_neimode_t mode, igraph_loops_t loops) {
|
||||
igraph_int_t n = igraph_vcount(g);
|
||||
igraph_vector_int_resize(res, n);
|
||||
for (igraph_int_t i=0; i < n; i++) {
|
||||
igraph_degree_1(g, &VECTOR(*res)[i], i, mode, loops);
|
||||
}
|
||||
}
|
||||
|
||||
/* Calls igraph_degree() separately for each vertex, pre-allocates work vector. */
|
||||
void degv(const igraph_t *g, igraph_vector_int_t *res, igraph_neimode_t mode, igraph_loops_t loops) {
|
||||
igraph_int_t n = igraph_vcount(g);
|
||||
igraph_vector_int_t work;
|
||||
|
||||
igraph_vector_int_resize(res, n);
|
||||
igraph_vector_int_init(&work, 1);
|
||||
for (igraph_int_t i=0; i < n; i++) {
|
||||
igraph_degree(g, &work, igraph_vss_1(i), mode, loops);
|
||||
}
|
||||
igraph_vector_int_destroy(&work);
|
||||
}
|
||||
|
||||
/* Calls igraph_degree() separately for each vertex, allocates a new work vector each time. */
|
||||
void degv2(const igraph_t *g, igraph_vector_int_t *res, igraph_neimode_t mode, igraph_loops_t loops) {
|
||||
igraph_int_t n = igraph_vcount(g);
|
||||
|
||||
for (igraph_int_t i=0; i < n; i++) {
|
||||
igraph_vector_int_t work;
|
||||
igraph_vector_int_init(&work, 1);
|
||||
igraph_degree(g, &work, igraph_vss_1(i), mode, loops);
|
||||
igraph_vector_int_destroy(&work);
|
||||
}
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
igraph_t g;
|
||||
igraph_vector_int_t degs;
|
||||
|
||||
igraph_rng_seed(igraph_rng_default(), 137);
|
||||
BENCH_INIT();
|
||||
|
||||
igraph_barabasi_game(&g, 100000, 1, 10, NULL, true, 0, IGRAPH_UNDIRECTED, IGRAPH_BARABASI_PSUMTREE_MULTIPLE, NULL);
|
||||
igraph_vector_int_init(°s, igraph_vcount(&g));
|
||||
|
||||
#define REP 1000
|
||||
|
||||
printf("Count loops twice, O(1) per degree, fast methods only.\n");
|
||||
|
||||
BENCH(" 1 igraph_degree(), preferential attachment n=100000, m=10, " TOSTR(REP) "x",
|
||||
REPEAT(igraph_degree(&g, °s, igraph_vss_all(), IGRAPH_ALL, IGRAPH_LOOPS), REP);
|
||||
);
|
||||
BENCH(" 2 deg1(), preferential attachment n=100000, m=10, " TOSTR(REP) "x",
|
||||
REPEAT(deg1(&g, °s, IGRAPH_ALL, IGRAPH_LOOPS), REP);
|
||||
);
|
||||
|
||||
#undef REP
|
||||
|
||||
#define REP 100
|
||||
|
||||
printf("\nCount loops twice, O(1) per degree.\n");
|
||||
|
||||
BENCH(" 1 igraph_degree(), preferential attachment n=100000, m=10, " TOSTR(REP) "x",
|
||||
REPEAT(igraph_degree(&g, °s, igraph_vss_all(), IGRAPH_ALL, IGRAPH_LOOPS), REP);
|
||||
);
|
||||
BENCH(" 2 deg1(), preferential attachment n=100000, m=10, " TOSTR(REP) "x",
|
||||
REPEAT(deg1(&g, °s, IGRAPH_ALL, IGRAPH_LOOPS), REP);
|
||||
);
|
||||
BENCH(" 3 degv(), preferential attachment n=100000, m=10, " TOSTR(REP) "x",
|
||||
REPEAT(degv(&g, °s, IGRAPH_ALL, IGRAPH_LOOPS), REP);
|
||||
);
|
||||
BENCH(" 4 degv2(), preferential attachment n=100000, m=10, " TOSTR(REP) "x",
|
||||
REPEAT(degv2(&g, °s, IGRAPH_ALL, IGRAPH_LOOPS), REP);
|
||||
);
|
||||
|
||||
#undef REP
|
||||
|
||||
#define REP 100
|
||||
|
||||
printf("\nCount loops twice, O(1) per degree.\n");
|
||||
|
||||
BENCH(" 1 igraph_degree(), preferential attachment n=100000, m=10, " TOSTR(REP) "x",
|
||||
REPEAT(igraph_degree(&g, °s, igraph_vss_all(), IGRAPH_ALL, IGRAPH_LOOPS), REP);
|
||||
);
|
||||
BENCH(" 2 deg1(), preferential attachment n=100000, m=10, " TOSTR(REP) "x",
|
||||
REPEAT(deg1(&g, °s, IGRAPH_ALL, IGRAPH_LOOPS), REP);
|
||||
);
|
||||
BENCH(" 3 degv(), preferential attachment n=100000, m=10, " TOSTR(REP) "x",
|
||||
REPEAT(degv(&g, °s, IGRAPH_ALL, IGRAPH_LOOPS), REP);
|
||||
);
|
||||
BENCH(" 4 degv2(), preferential attachment n=100000, m=10, " TOSTR(REP) "x",
|
||||
REPEAT(degv2(&g, °s, IGRAPH_ALL, IGRAPH_LOOPS), REP);
|
||||
);
|
||||
|
||||
#undef REP
|
||||
|
||||
#define REP 100
|
||||
|
||||
printf("\nDo not count loops, O(d) per degree.\n");
|
||||
|
||||
BENCH(" 1 igraph_degree(), preferential attachment n=100000, m=10, " TOSTR(REP) "x",
|
||||
REPEAT(igraph_degree(&g, °s, igraph_vss_all(), IGRAPH_ALL, IGRAPH_NO_LOOPS), REP);
|
||||
);
|
||||
BENCH(" 2 deg1(), preferential attachment n=100000, m=10, " TOSTR(REP) "x",
|
||||
REPEAT(deg1(&g, °s, IGRAPH_ALL, IGRAPH_NO_LOOPS), REP);
|
||||
);
|
||||
BENCH(" 3 degv(), preferential attachment n=100000, m=10, " TOSTR(REP) "x",
|
||||
REPEAT(degv(&g, °s, IGRAPH_ALL, IGRAPH_NO_LOOPS), REP);
|
||||
);
|
||||
BENCH(" 4 degv2(), preferential attachment n=100000, m=10, " TOSTR(REP) "x",
|
||||
REPEAT(degv2(&g, °s, IGRAPH_ALL, IGRAPH_NO_LOOPS), REP);
|
||||
);
|
||||
|
||||
igraph_vector_int_destroy(°s);
|
||||
igraph_destroy(&g);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
igraph library.
|
||||
Copyright (C) 2024 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 "bench.h"
|
||||
|
||||
int main(void) {
|
||||
igraph_t g, template;
|
||||
igraph_vector_int_t degrees, outdeg, indeg;
|
||||
|
||||
BENCH_INIT();
|
||||
igraph_rng_seed(igraph_rng_default(), 42);
|
||||
|
||||
/* This benchmark indirectly tests the performance of igraph_set_t at the
|
||||
* moment because igraph_degree_sequence_game() (especially the
|
||||
* IGRAPH_DEGSEQ_CONFIGURATION_SIMPLE mode) heavily relies on sets.
|
||||
* This might change in future versions so the name of the benchmark
|
||||
* reflects the name of the function that is tested directly */
|
||||
|
||||
igraph_vector_int_init(°rees, 1000);
|
||||
igraph_vector_int_fill(°rees, 7);
|
||||
BENCH(" 1 Degseq of undirected k-regular, N=1000, k=7, CONFIGURATION_SIMPLE",
|
||||
igraph_degree_sequence_game(&g, °rees, /* indeg = */ NULL, IGRAPH_DEGSEQ_CONFIGURATION_SIMPLE)
|
||||
);
|
||||
igraph_destroy(&g);
|
||||
igraph_vector_int_destroy(°rees);
|
||||
|
||||
igraph_rng_seed(igraph_rng_default(), 42);
|
||||
igraph_vector_int_init(°rees, 0);
|
||||
igraph_barabasi_game(&template, 1000, /* power = */ 1, /* m = */ 1,
|
||||
/* outseq = */ NULL, /* outpref = */ true, /* A = */ 0,
|
||||
IGRAPH_UNDIRECTED, IGRAPH_BARABASI_PSUMTREE, /* start_from = */ NULL
|
||||
);
|
||||
igraph_degree(&template, °rees, igraph_vss_all(), IGRAPH_ALL, IGRAPH_LOOPS);
|
||||
BENCH(" 2 Degseq of undirected BA, N=1000, m=1, CONFIGURATION_SIMPLE",
|
||||
igraph_degree_sequence_game(&g, °rees, /* indeg = */ NULL, IGRAPH_DEGSEQ_CONFIGURATION_SIMPLE)
|
||||
);
|
||||
igraph_destroy(&g);
|
||||
igraph_destroy(&template);
|
||||
igraph_vector_int_destroy(°rees);
|
||||
|
||||
igraph_rng_seed(igraph_rng_default(), 42);
|
||||
igraph_vector_int_init(°rees, 0);
|
||||
igraph_erdos_renyi_game_gnm(&template, 200, 600, IGRAPH_UNDIRECTED, IGRAPH_SIMPLE_SW, IGRAPH_EDGE_UNLABELED);
|
||||
igraph_degree(&template, °rees, igraph_vss_all(), IGRAPH_ALL, IGRAPH_LOOPS);
|
||||
BENCH(" 3 Degseq of undirected G(n,m), N=150, m=450, CONFIGURATION_SIMPLE",
|
||||
igraph_degree_sequence_game(&g, °rees, /* indeg = */ NULL, IGRAPH_DEGSEQ_CONFIGURATION_SIMPLE)
|
||||
);
|
||||
igraph_destroy(&g);
|
||||
igraph_destroy(&template);
|
||||
igraph_vector_int_destroy(°rees);
|
||||
|
||||
igraph_rng_seed(igraph_rng_default(), 42);
|
||||
igraph_vector_int_init(°rees, 0);
|
||||
igraph_grg_game(&template, 10000, 0.013, /* torus = */ false, /* x = */ NULL, /* y = */ NULL);
|
||||
igraph_degree(&template, °rees, igraph_vss_all(), IGRAPH_ALL, IGRAPH_LOOPS);
|
||||
BENCH(" 4 Degseq of GRG, N=10000, r=0.013, CONFIGURATION_SIMPLE",
|
||||
igraph_degree_sequence_game(&g, °rees, /* indeg = */ NULL, IGRAPH_DEGSEQ_CONFIGURATION_SIMPLE)
|
||||
);
|
||||
igraph_destroy(&g);
|
||||
igraph_destroy(&template);
|
||||
igraph_vector_int_destroy(°rees);
|
||||
|
||||
igraph_vector_int_init(°rees, 1000);
|
||||
igraph_vector_int_fill(°rees, 5);
|
||||
BENCH(" 5 Degseq of directed k-regular, N=1000, k=5, CONFIGURATION_SIMPLE",
|
||||
igraph_degree_sequence_game(&g, °rees, °rees, IGRAPH_DEGSEQ_CONFIGURATION_SIMPLE)
|
||||
);
|
||||
igraph_destroy(&g);
|
||||
igraph_vector_int_destroy(°rees);
|
||||
|
||||
igraph_rng_seed(igraph_rng_default(), 42);
|
||||
igraph_vector_int_init(&outdeg, 0);
|
||||
igraph_vector_int_init(&indeg, 0);
|
||||
igraph_barabasi_game(&template, 5000, /* power = */ 1, /* m = */ 2,
|
||||
/* outseq = */ NULL, /* outpref = */ true, /* A = */ 0,
|
||||
IGRAPH_DIRECTED, IGRAPH_BARABASI_PSUMTREE, /* start_from = */ NULL
|
||||
);
|
||||
igraph_degree(&template, &outdeg, igraph_vss_all(), IGRAPH_OUT, IGRAPH_LOOPS);
|
||||
igraph_degree(&template, &indeg, igraph_vss_all(), IGRAPH_IN, IGRAPH_LOOPS);
|
||||
BENCH(" 6 Degseq of directed BA, N=500, m=2, CONFIGURATION_SIMPLE",
|
||||
igraph_degree_sequence_game(&g, &outdeg, &indeg, IGRAPH_DEGSEQ_CONFIGURATION_SIMPLE)
|
||||
);
|
||||
igraph_destroy(&g);
|
||||
igraph_destroy(&template);
|
||||
igraph_vector_int_destroy(&indeg);
|
||||
igraph_vector_int_destroy(&outdeg);
|
||||
|
||||
igraph_rng_seed(igraph_rng_default(), 42);
|
||||
igraph_vector_int_init(&outdeg, 0);
|
||||
igraph_vector_int_init(&indeg, 0);
|
||||
igraph_erdos_renyi_game_gnm(&template, 15000, 45000, IGRAPH_DIRECTED, IGRAPH_SIMPLE_SW, IGRAPH_EDGE_UNLABELED);
|
||||
igraph_degree(&template, &outdeg, igraph_vss_all(), IGRAPH_OUT, IGRAPH_LOOPS);
|
||||
igraph_degree(&template, &indeg, igraph_vss_all(), IGRAPH_IN, IGRAPH_LOOPS);
|
||||
BENCH(" 7 Degseq of directed G(n,m), N=15000, m=45000, CONFIGURATION_SIMPLE",
|
||||
igraph_degree_sequence_game(&g, &outdeg, &indeg, IGRAPH_DEGSEQ_CONFIGURATION_SIMPLE)
|
||||
);
|
||||
igraph_destroy(&g);
|
||||
igraph_destroy(&template);
|
||||
igraph_vector_int_destroy(&indeg);
|
||||
igraph_vector_int_destroy(&outdeg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
igraph library.
|
||||
Copyright (C) 2025 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 "bench.h"
|
||||
|
||||
void bench_delaunay(const char *message, igraph_int_t point_count, igraph_int_t dimensions) {
|
||||
igraph_matrix_t points;
|
||||
igraph_t g;
|
||||
char msg[200];
|
||||
|
||||
igraph_matrix_init(&points, point_count, dimensions);
|
||||
|
||||
for (igraph_int_t point = 0; point < point_count; point++) {
|
||||
for (igraph_int_t dim = 0; dim < dimensions; dim++) {
|
||||
MATRIX(points, point, dim) = RNG_UNIF01();
|
||||
}
|
||||
}
|
||||
|
||||
snprintf(msg, sizeof(msg) / sizeof(msg[0]),
|
||||
"%s Delaunay triangulation in %dD, n=%6" IGRAPH_PRId,
|
||||
message, (int) dimensions, point_count);
|
||||
|
||||
BENCH(msg, igraph_delaunay_graph(&g, &points));
|
||||
|
||||
igraph_destroy(&g);
|
||||
igraph_matrix_destroy(&points);
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
BENCH_INIT();
|
||||
igraph_rng_seed(igraph_rng_default(), 20250814);
|
||||
|
||||
bench_delaunay(" 1", 1000000, 1);
|
||||
bench_delaunay(" 2", 100000, 2);
|
||||
bench_delaunay(" 3", 10000, 2);
|
||||
bench_delaunay(" 4", 1000, 2);
|
||||
bench_delaunay(" 5", 100, 2);
|
||||
bench_delaunay(" 6", 10000, 3);
|
||||
bench_delaunay(" 7", 1000, 3);
|
||||
bench_delaunay(" 8", 100, 3);
|
||||
bench_delaunay(" 9", 2000, 4);
|
||||
bench_delaunay("10", 500, 5);
|
||||
bench_delaunay("11", 200, 6);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,168 @@
|
||||
/*
|
||||
igraph library.
|
||||
Copyright (C) 2025 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 "bench.h"
|
||||
|
||||
void bench_gnp(igraph_int_t n, igraph_real_t p, igraph_bool_t directed, igraph_real_t negloop, int rep) {
|
||||
igraph_t g;
|
||||
igraph_matrix_t res;
|
||||
igraph_vector_t weights;
|
||||
char msg[200];
|
||||
|
||||
igraph_matrix_init(&res, 0, 0);
|
||||
igraph_vector_init(&weights, 0);
|
||||
|
||||
/* IGRAPH_NO_LOOPS, as loops are not allowed with negative weights. */
|
||||
igraph_erdos_renyi_game_gnp(&g, n, p, directed, IGRAPH_MULTI_SW, IGRAPH_EDGE_UNLABELED);
|
||||
igraph_matrix_resize(&res, igraph_vcount(&g), igraph_vcount(&g));
|
||||
igraph_vector_resize(&weights, igraph_ecount(&g));
|
||||
|
||||
for (igraph_int_t i=0; i < igraph_ecount(&g); i++) {
|
||||
VECTOR(weights)[i] = RNG_EXP(1);
|
||||
}
|
||||
|
||||
snprintf(msg, sizeof(msg) / sizeof(msg[0]),
|
||||
" 1 n=%d, p=%g, %s, Unweighted, %dx",
|
||||
(int) n, p, directed ? " directed" : "undirected", rep);
|
||||
BENCH(msg,
|
||||
REPEAT(igraph_distances(&g, NULL, &res, igraph_vss_all(), igraph_vss_all(), IGRAPH_OUT), rep);
|
||||
);
|
||||
|
||||
snprintf(msg, sizeof(msg) / sizeof(msg[0]),
|
||||
" 2 n=%d, p=%g, %s, Dijkstra, %dx",
|
||||
(int) n, p, directed ? " directed" : "undirected", rep);
|
||||
BENCH(msg,
|
||||
REPEAT(igraph_distances_dijkstra(&g, &res, igraph_vss_all(), igraph_vss_all(), &weights, IGRAPH_OUT), rep)
|
||||
);
|
||||
|
||||
snprintf(msg, sizeof(msg) / sizeof(msg[0]),
|
||||
" 3 n=%d, p=%g, %s, Unweighted Floyd-Warshall, %dx",
|
||||
(int) n, p, directed ? " directed" : "undirected", rep);
|
||||
BENCH(msg,
|
||||
REPEAT(igraph_distances_floyd_warshall(&g, &res, igraph_vss_all(), igraph_vss_all(), NULL, IGRAPH_OUT, IGRAPH_FLOYD_WARSHALL_ORIGINAL), rep)
|
||||
);
|
||||
|
||||
snprintf(msg, sizeof(msg) / sizeof(msg[0]),
|
||||
" 4 n=%d, p=%g, %s, Unweighted Floyd-Warshall-tree-speedup, %dx",
|
||||
(int) n, p, directed ? " directed" : "undirected", rep);
|
||||
BENCH(msg,
|
||||
REPEAT(igraph_distances_floyd_warshall(&g, &res, igraph_vss_all(), igraph_vss_all(), NULL, IGRAPH_OUT, IGRAPH_FLOYD_WARSHALL_TREE), rep)
|
||||
);
|
||||
|
||||
snprintf(msg, sizeof(msg) / sizeof(msg[0]),
|
||||
" 5 n=%d, p=%g, %s, Floyd-Warshall, %dx",
|
||||
(int) n, p, directed ? " directed" : "undirected", rep);
|
||||
BENCH(msg,
|
||||
REPEAT(igraph_distances_floyd_warshall(&g, &res, igraph_vss_all(), igraph_vss_all(), &weights, IGRAPH_OUT, IGRAPH_FLOYD_WARSHALL_ORIGINAL), rep)
|
||||
);
|
||||
|
||||
snprintf(msg, sizeof(msg) / sizeof(msg[0]),
|
||||
" 6 n=%d, p=%g, %s, Floyd-Warshall-tree-speedup, %dx",
|
||||
(int) n, p, directed ? " directed" : "undirected", rep);
|
||||
BENCH(msg,
|
||||
REPEAT(igraph_distances_floyd_warshall(&g, &res, igraph_vss_all(), igraph_vss_all(), &weights, IGRAPH_OUT, IGRAPH_FLOYD_WARSHALL_TREE), rep)
|
||||
);
|
||||
|
||||
/* Negative weights, only for directed graphs. */
|
||||
|
||||
if (! directed) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Add a small number of negative weights, rely on luck, as well as tuning 'negloop',
|
||||
* to avoid negative loops. */
|
||||
for (igraph_int_t i=0; i < trunc(negloop * igraph_ecount(&g)); i++) {
|
||||
/* For reproducibility, do not write two RNG_...() calls within the same statement,
|
||||
* as the C language does not guarantee any evaluation order between them. */
|
||||
igraph_real_t w = RNG_UNIF(-negloop, 0);
|
||||
VECTOR(weights)[RNG_INTEGER(0, igraph_ecount(&g)-1)] = w;
|
||||
}
|
||||
|
||||
snprintf(msg, sizeof(msg) / sizeof(msg[0]),
|
||||
" 7 n=%d, p=%g, %s, Bellman-Ford (negative), %dx",
|
||||
(int) n, p, directed ? " directed" : "undirected", rep);
|
||||
BENCH(msg,
|
||||
REPEAT(igraph_distances_bellman_ford(&g, &res, igraph_vss_all(), igraph_vss_all(), &weights, IGRAPH_OUT), rep)
|
||||
);
|
||||
|
||||
snprintf(msg, sizeof(msg) / sizeof(msg[0]),
|
||||
" 8 n=%d, p=%g, %s, Johnson (negative), %dx",
|
||||
(int) n, p, directed ? " directed" : "undirected", rep);
|
||||
BENCH(msg,
|
||||
REPEAT(igraph_distances_johnson(&g, &res, igraph_vss_all(), igraph_vss_all(), &weights, IGRAPH_OUT), rep)
|
||||
);
|
||||
|
||||
snprintf(msg, sizeof(msg) / sizeof(msg[0]),
|
||||
" 9 n=%d, p=%g, %s, Floyd-Warshall (negative), %dx",
|
||||
(int) n, p, directed ? " directed" : "undirected", rep);
|
||||
BENCH(msg,
|
||||
REPEAT(igraph_distances_floyd_warshall(&g, &res, igraph_vss_all(), igraph_vss_all(), &weights, IGRAPH_OUT, IGRAPH_FLOYD_WARSHALL_ORIGINAL), rep)
|
||||
);
|
||||
|
||||
snprintf(msg, sizeof(msg) / sizeof(msg[0]),
|
||||
"10 n=%d, p=%g, %s, Floyd-Warshall-tree-speedup (negative), %dx",
|
||||
(int) n, p, directed ? " directed" : "undirected", rep);
|
||||
BENCH(msg,
|
||||
REPEAT(igraph_distances_floyd_warshall(&g, &res, igraph_vss_all(), igraph_vss_all(), &weights, IGRAPH_OUT, IGRAPH_FLOYD_WARSHALL_TREE), rep)
|
||||
);
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
|
||||
igraph_rng_seed(igraph_rng_default(), 137);
|
||||
BENCH_INIT();
|
||||
|
||||
/*
|
||||
bench_gnp(100, 0.5, IGRAPH_DIRECTED, 0.01, 200); printf("\n");
|
||||
bench_gnp(100, 0.5, IGRAPH_UNDIRECTED, 0.01, 200); printf("\n");
|
||||
|
||||
bench_gnp(30, 0.5, IGRAPH_DIRECTED, 0.01, 2000); printf("\n");
|
||||
bench_gnp(30, 0.5, IGRAPH_UNDIRECTED, 0.01, 2000); printf("\n");
|
||||
|
||||
bench_gnp(100, 0.1, IGRAPH_DIRECTED, 0.01, 1000); printf("\n");
|
||||
bench_gnp(100, 0.1, IGRAPH_UNDIRECTED, 0.01, 1000); printf("\n");
|
||||
|
||||
bench_gnp(500, 0.1, IGRAPH_DIRECTED, 0.005, 10); printf("\n");
|
||||
bench_gnp(500, 0.1, IGRAPH_UNDIRECTED, 0.005, 10); printf("\n");
|
||||
|
||||
bench_gnp(1500, 0.02, IGRAPH_DIRECTED, 0.01, 1); printf("\n");
|
||||
bench_gnp(1500, 0.02, IGRAPH_UNDIRECTED, 0.01, 1); printf("\n");
|
||||
*/
|
||||
|
||||
bench_gnp(1000, 0.1, IGRAPH_DIRECTED, 0.002, 1); printf("\n");
|
||||
|
||||
bench_gnp(300, 0.1, IGRAPH_DIRECTED, 0.005, 50); printf("\n");
|
||||
|
||||
bench_gnp(100, 0.1, IGRAPH_DIRECTED, 0.01, 500); printf("\n");
|
||||
|
||||
bench_gnp(50, 0.1, IGRAPH_DIRECTED, 0.01, 10000); printf("\n");
|
||||
|
||||
bench_gnp(30, 0.1, IGRAPH_DIRECTED, 0.01, 20000); printf("\n");
|
||||
|
||||
bench_gnp(20, 0.2, IGRAPH_DIRECTED, 0.01, 40000); printf("\n");
|
||||
|
||||
bench_gnp(10, 0.2, IGRAPH_DIRECTED, 0.01, 100000); printf("\n");
|
||||
|
||||
bench_gnp(1500, 0.01, IGRAPH_DIRECTED, 0.01, 1); printf("\n");
|
||||
|
||||
bench_gnp(100, 0.5, IGRAPH_DIRECTED, 0.01, 1000); printf("\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,175 @@
|
||||
/*
|
||||
igraph library.
|
||||
Copyright (C) 2024 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 "bench.h"
|
||||
|
||||
#define TOSTR1(x) #x
|
||||
#define TOSTR(x) TOSTR1(x)
|
||||
|
||||
#define BENCH_BLOCK() \
|
||||
BENCH(" 1 vc=" TOSTR(VCOUNT) ", ec=" TOSTR(ECOUNT) ", k=3, all, " TOSTR(REP) "x", \
|
||||
REPEAT(igraph_ecc(&g, &ecc, igraph_ess_all(IGRAPH_EDGEORDER_ID), 3, false, true), REP); \
|
||||
); \
|
||||
BENCH(" 2 vc=" TOSTR(VCOUNT) ", ec=" TOSTR(ECOUNT) ", k=3, subset: all, " TOSTR(REP) "x", \
|
||||
REPEAT(igraph_ecc(&g, &ecc, igraph_ess_range(0, igraph_ecount(&g)), 3, false, true), REP); \
|
||||
); \
|
||||
\
|
||||
igraph_random_sample(&eids, 0, igraph_ecount(&g)-1, SS); \
|
||||
\
|
||||
BENCH(" 3 vc=" TOSTR(VCOUNT) ", ec=" TOSTR(ECOUNT) ", k=3, subset: " TOSTR(SS) ", " TOSTR(SREP) "x", \
|
||||
REPEAT(igraph_ecc(&g, &ecc, igraph_ess_vector(&eids), 3, false, true), SREP); \
|
||||
); \
|
||||
\
|
||||
BENCH(" 4 vc=" TOSTR(VCOUNT) ", ec=" TOSTR(ECOUNT) ", k=4, all, " TOSTR(REP) "x", \
|
||||
REPEAT(igraph_ecc(&g, &ecc, igraph_ess_all(IGRAPH_EDGEORDER_ID), 4, false, true), REP); \
|
||||
); \
|
||||
\
|
||||
BENCH(" 4 vc=" TOSTR(VCOUNT) ", ec=" TOSTR(ECOUNT) ", k=4, subset: all, " TOSTR(REP) "x", \
|
||||
REPEAT(igraph_ecc(&g, &ecc, igraph_ess_range(0, igraph_ecount(&g)), 4, false, true), REP); \
|
||||
); \
|
||||
BENCH(" 5 vc=" TOSTR(VCOUNT) ", ec=" TOSTR(ECOUNT) ", k=4, subset: " TOSTR(SS) ", " TOSTR(SREP) "x", \
|
||||
REPEAT(igraph_ecc(&g, &ecc, igraph_ess_vector(&eids), 4, false, true), SREP); \
|
||||
);
|
||||
|
||||
int main(void) {
|
||||
igraph_t g;
|
||||
igraph_vector_t ecc;
|
||||
igraph_vector_int_t eids;
|
||||
|
||||
igraph_rng_seed(igraph_rng_default(), 137);
|
||||
BENCH_INIT();
|
||||
|
||||
igraph_vector_init(&ecc, 0);
|
||||
igraph_vector_int_init(&eids, 0);
|
||||
|
||||
printf("Erdos-Renyi GNM:\n\n");
|
||||
|
||||
#define VCOUNT 100
|
||||
#define ECOUNT 5000
|
||||
#define REP 100
|
||||
#define SS 100
|
||||
#define SREP 1000
|
||||
|
||||
igraph_erdos_renyi_game_gnm(&g, VCOUNT, ECOUNT, IGRAPH_DIRECTED, IGRAPH_SIMPLE_SW, IGRAPH_EDGE_UNLABELED);
|
||||
igraph_vector_resize(&ecc, igraph_ecount(&g));
|
||||
|
||||
BENCH_BLOCK()
|
||||
|
||||
igraph_destroy(&g);
|
||||
|
||||
#undef VCOUNT
|
||||
#undef ECOUNT
|
||||
#undef REP
|
||||
#undef SS
|
||||
#undef SREP
|
||||
|
||||
printf("\n");
|
||||
|
||||
#define VCOUNT 1000
|
||||
#define ECOUNT 5000
|
||||
#define REP 100
|
||||
#define SS 100
|
||||
#define SREP 1000
|
||||
|
||||
igraph_erdos_renyi_game_gnm(&g, VCOUNT, ECOUNT, IGRAPH_DIRECTED, IGRAPH_SIMPLE_SW, IGRAPH_EDGE_UNLABELED);
|
||||
igraph_vector_resize(&ecc, igraph_ecount(&g));
|
||||
|
||||
BENCH_BLOCK()
|
||||
|
||||
igraph_destroy(&g);
|
||||
|
||||
#undef VCOUNT
|
||||
#undef ECOUNT
|
||||
#undef REP
|
||||
#undef SS
|
||||
#undef SREP
|
||||
|
||||
printf("\n");
|
||||
|
||||
#define VCOUNT 10000
|
||||
#define ECOUNT 10000
|
||||
#define REP 100
|
||||
#define SS 100
|
||||
#define SREP 1000
|
||||
|
||||
igraph_erdos_renyi_game_gnm(&g, VCOUNT, ECOUNT, IGRAPH_DIRECTED, IGRAPH_SIMPLE_SW, IGRAPH_EDGE_UNLABELED);
|
||||
igraph_vector_resize(&ecc, igraph_ecount(&g));
|
||||
|
||||
BENCH_BLOCK()
|
||||
|
||||
igraph_destroy(&g);
|
||||
|
||||
#undef VCOUNT
|
||||
#undef ECOUNT
|
||||
#undef REP
|
||||
#undef SS
|
||||
#undef SREP
|
||||
|
||||
printf("\n");
|
||||
|
||||
#define VCOUNT 10000
|
||||
#define ECOUNT 50000
|
||||
#define REP 100
|
||||
#define SS 100
|
||||
#define SREP 1000
|
||||
|
||||
igraph_erdos_renyi_game_gnm(&g, VCOUNT, ECOUNT, IGRAPH_DIRECTED, IGRAPH_SIMPLE_SW, IGRAPH_EDGE_UNLABELED);
|
||||
igraph_vector_resize(&ecc, igraph_ecount(&g));
|
||||
|
||||
BENCH_BLOCK()
|
||||
|
||||
igraph_destroy(&g);
|
||||
|
||||
#undef VCOUNT
|
||||
#undef ECOUNT
|
||||
#undef REP
|
||||
#undef SS
|
||||
#undef SREP
|
||||
|
||||
printf("\n");
|
||||
|
||||
#define VCOUNT 10000
|
||||
#define ECOUNT 50000
|
||||
#define REP 100
|
||||
#define SS 100
|
||||
#define SREP 1000
|
||||
|
||||
printf("Barabasi:\n\n");
|
||||
|
||||
igraph_barabasi_game(&g,
|
||||
VCOUNT, 1, ECOUNT / VCOUNT, NULL, true, 0,
|
||||
IGRAPH_UNDIRECTED, IGRAPH_BARABASI_PSUMTREE_MULTIPLE, NULL);
|
||||
igraph_vector_resize(&ecc, igraph_ecount(&g));
|
||||
|
||||
BENCH_BLOCK()
|
||||
|
||||
igraph_destroy(&g);
|
||||
|
||||
#undef VCOUNT
|
||||
#undef ECOUNT
|
||||
#undef REP
|
||||
#undef SS
|
||||
#undef SREP
|
||||
|
||||
igraph_vector_int_destroy(&eids);
|
||||
igraph_vector_destroy(&ecc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
igraph library.
|
||||
Copyright (C) 2025 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 "bench.h"
|
||||
|
||||
// Function to generate random vertex indices for subgraph extraction
|
||||
void generate_random_vertices(igraph_vector_int_t *vertices,
|
||||
igraph_int_t graph_size,
|
||||
igraph_int_t subset_size) {
|
||||
igraph_vector_int_init(vertices, 0);
|
||||
igraph_vector_int_resize(vertices, subset_size);
|
||||
|
||||
// Create a vector to track used vertices
|
||||
igraph_vector_int_t used_vertices;
|
||||
igraph_vector_int_init(&used_vertices, graph_size);
|
||||
for (igraph_int_t i = 0; i < graph_size; i++) {
|
||||
VECTOR(used_vertices)[i] = i;
|
||||
}
|
||||
|
||||
// Randomly select subset_size unique vertices
|
||||
for (igraph_int_t i = 0; i < subset_size; i++) {
|
||||
igraph_int_t index = RNG_INTEGER(0, graph_size - i - 1);
|
||||
VECTOR(*vertices)[i] = VECTOR(used_vertices)[index];
|
||||
|
||||
// Remove the selected vertex from used_vertices
|
||||
VECTOR(used_vertices)[index] = VECTOR(used_vertices)[graph_size - i - 1];
|
||||
}
|
||||
|
||||
// Sort the vertices to simulate real-world scenarios
|
||||
igraph_vector_int_sort(vertices);
|
||||
|
||||
igraph_vector_int_destroy(&used_vertices);
|
||||
}
|
||||
|
||||
// Benchmark function
|
||||
void bench_induced_subgraph(igraph_t *graph, igraph_vector_int_t *vertices,
|
||||
igraph_subgraph_implementation_t impl) {
|
||||
igraph_t subgraph;
|
||||
igraph_vs_t vs;
|
||||
|
||||
igraph_vs_vector(&vs, vertices);
|
||||
igraph_induced_subgraph(graph, &subgraph, vs, impl);
|
||||
igraph_vs_destroy(&vs);
|
||||
igraph_destroy(&subgraph);
|
||||
}
|
||||
|
||||
void run_bench(int i, int n, int m, int subset_percentage) {
|
||||
igraph_t graph;
|
||||
igraph_vector_int_t vertices;
|
||||
|
||||
// Calculate subset size based on percentage
|
||||
igraph_int_t subset_size = (n * subset_percentage) / 100;
|
||||
|
||||
// Prepare random graph and vertices
|
||||
igraph_erdos_renyi_game_gnm(&graph, n, m, IGRAPH_UNDIRECTED, IGRAPH_SIMPLE_SW, IGRAPH_EDGE_UNLABELED);
|
||||
generate_random_vertices(&vertices, n, subset_size);
|
||||
|
||||
char msg[255];
|
||||
int rep = 300000000 / (n * subset_percentage);
|
||||
|
||||
// Benchmark method 1 (COPY_AND_DELETE)
|
||||
snprintf(msg, sizeof(msg),
|
||||
"Method 1 (COPY_AND_DELETE): n=%5d, subset=%3d%%, %dx", n,
|
||||
subset_percentage, rep);
|
||||
BENCH(msg, REPEAT(bench_induced_subgraph(&graph, &vertices,
|
||||
IGRAPH_SUBGRAPH_COPY_AND_DELETE),
|
||||
rep));
|
||||
|
||||
// Benchmark method 2 (CREATE_FROM_SCRATCH)
|
||||
snprintf(msg, sizeof(msg),
|
||||
"Method 2 (CREATE_FROM_SCRATCH): n=%5d, subset=%3d%%, %dx", n,
|
||||
subset_percentage, rep);
|
||||
BENCH(msg, REPEAT(bench_induced_subgraph(&graph, &vertices,
|
||||
IGRAPH_SUBGRAPH_CREATE_FROM_SCRATCH),
|
||||
rep));
|
||||
|
||||
// Cleanup
|
||||
igraph_vector_int_destroy(&vertices);
|
||||
igraph_destroy(&graph);
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
int i = 0;
|
||||
|
||||
// Initialize random number generator
|
||||
igraph_rng_seed(igraph_rng_default(), 42);
|
||||
BENCH_INIT();
|
||||
|
||||
// Macro to run benchmarks for different graph sizes and subset percentages
|
||||
#define BENCHSET(n, m) \
|
||||
run_bench(++i, n, m, 20); /* 20% subset */ \
|
||||
run_bench(++i, n, m, 25); /* 25% subset */ \
|
||||
run_bench(++i, n, m, 30); /* 30% subset */ \
|
||||
run_bench(++i, n, m, 35); /* 35% subset */ \
|
||||
run_bench(++i, n, m, 40); /* 40% subset */ \
|
||||
run_bench(++i, n, m, 45); /* 45% subset */ \
|
||||
run_bench(++i, n, m, 50); /* 50% subset */ \
|
||||
run_bench(++i, n, m, 55); /* 55% subset */ \
|
||||
printf("\n");
|
||||
|
||||
// Benchmark different graph sizes
|
||||
BENCHSET(100, 500);
|
||||
BENCHSET(1000, 5000);
|
||||
BENCHSET(10000, 50000);
|
||||
BENCHSET(100000, 500000);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
igraph library.
|
||||
Copyright (C) 2024 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 "bench.h"
|
||||
|
||||
#define TOSTR1(x) #x
|
||||
#define TOSTR(x) TOSTR1(x)
|
||||
#define BARABASI_GRAPH_VERTEX_COUNT 100000
|
||||
|
||||
void unit_test_subgraph_edges(
|
||||
const igraph_t *graph, igraph_vector_int_t *vertices,
|
||||
igraph_int_t induced_subgraph_vertice_count, igraph_int_t benchmark_count,
|
||||
const char* bench_message
|
||||
) {
|
||||
igraph_vector_int_t edges;
|
||||
igraph_vector_int_init(&edges, 0);
|
||||
|
||||
IGRAPH_UNUSED(vertices);
|
||||
|
||||
BENCH(bench_message,
|
||||
REPEAT(
|
||||
igraph_induced_subgraph_edges(graph, igraph_vss_range(0, induced_subgraph_vertice_count), &edges),
|
||||
benchmark_count
|
||||
)
|
||||
);
|
||||
|
||||
igraph_vector_int_destroy(&edges);
|
||||
}
|
||||
|
||||
void bench_induced_subgraph_edges(void) {
|
||||
igraph_t g;
|
||||
igraph_vector_int_t vertices;
|
||||
|
||||
igraph_vector_int_init_range(&vertices, 0, BARABASI_GRAPH_VERTEX_COUNT);
|
||||
igraph_vector_int_shuffle(&vertices);
|
||||
|
||||
igraph_barabasi_game(&g, BARABASI_GRAPH_VERTEX_COUNT, 1, 100, NULL, true, 0,
|
||||
IGRAPH_UNDIRECTED, IGRAPH_BARABASI_PSUMTREE_MULTIPLE, NULL);
|
||||
|
||||
printf("induced_subgraph_edges() for BA graph\n");
|
||||
|
||||
#define REP 10
|
||||
|
||||
#define INDUCED_SUBGRAPH_VERTEX_COUNT 100
|
||||
unit_test_subgraph_edges(&g, &vertices, INDUCED_SUBGRAPH_VERTEX_COUNT, REP,
|
||||
"n=" TOSTR(BARABASI_GRAPH_VERTEX_COUNT) ", "
|
||||
"m=100, "
|
||||
"e=" TOSTR(INDUCED_SUBGRAPH_VERTEX_COUNT) ", "
|
||||
TOSTR(REP) " x"
|
||||
);
|
||||
#undef INDUCED_SUBGRAPH_VERTEX_COUNT
|
||||
|
||||
#define INDUCED_SUBGRAPH_VERTEX_COUNT 1000
|
||||
unit_test_subgraph_edges(&g, &vertices, INDUCED_SUBGRAPH_VERTEX_COUNT, REP,
|
||||
"n=" TOSTR(BARABASI_GRAPH_VERTEX_COUNT) ", "
|
||||
"m=100, "
|
||||
"e=" TOSTR(INDUCED_SUBGRAPH_VERTEX_COUNT) ", "
|
||||
TOSTR(REP) " x"
|
||||
);
|
||||
#undef INDUCED_SUBGRAPH_VERTEX_COUNT
|
||||
|
||||
#define INDUCED_SUBGRAPH_VERTEX_COUNT 10000
|
||||
unit_test_subgraph_edges(&g, &vertices, INDUCED_SUBGRAPH_VERTEX_COUNT, REP,
|
||||
"n=" TOSTR(BARABASI_GRAPH_VERTEX_COUNT) ", "
|
||||
"m=100, "
|
||||
"e=" TOSTR(INDUCED_SUBGRAPH_VERTEX_COUNT) ", "
|
||||
TOSTR(REP) " x"
|
||||
);
|
||||
#undef INDUCED_SUBGRAPH_VERTEX_COUNT
|
||||
|
||||
#undef REP
|
||||
|
||||
igraph_destroy(&g);
|
||||
igraph_vector_int_destroy(&vertices);
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
igraph_rng_seed(igraph_rng_default(), 137);
|
||||
BENCH_INIT();
|
||||
bench_induced_subgraph_edges();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
igraph library.
|
||||
Copyright (C) 2024 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 "bench.h"
|
||||
|
||||
#define TOSTR1(x) #x
|
||||
#define TOSTR(x) TOSTR1(x)
|
||||
|
||||
int main(void) {
|
||||
igraph_t graph;
|
||||
igraph_vector_t distances;
|
||||
igraph_matrix_t layout;
|
||||
|
||||
igraph_rng_seed(igraph_rng_default(), 42);
|
||||
BENCH_INIT();
|
||||
|
||||
igraph_matrix_init(&layout, 0, 0);
|
||||
|
||||
|
||||
igraph_small(&graph, 12, IGRAPH_UNDIRECTED,
|
||||
0,1, 0,2, 0,3, 1,2, 1,3, 2,3,
|
||||
3,4, 4,5, 5,6,
|
||||
6,7, 7,8, 6,8, 7,9, 6,9, 8,9, 7,10, 8,10, 9,10, 10,11, 9,11, 8,11, 7,11,
|
||||
-1);
|
||||
igraph_vector_init_real(&distances,
|
||||
igraph_ecount(&graph),
|
||||
0.1, 0.09, 0.12, 0.09, 0.1, 0.1,
|
||||
0.9, 0.9, 0.9,
|
||||
0.2, 0.1, 0.1, 0.1, 0.1, 0.1, 0.08, 0.05, 0.1, 0.08, 0.12, 0.09, 0.11
|
||||
);
|
||||
|
||||
#define EPOCHS 5000
|
||||
#define REP 40
|
||||
|
||||
BENCH("Small graph, epochs: " TOSTR(EPOCHS) ", repetitions: " TOSTR(REP), REPEAT(igraph_layout_umap(&graph, &layout, 0, &distances, 0.01, EPOCHS, 0), REP);
|
||||
);
|
||||
|
||||
#undef EPOCHS
|
||||
#undef REP
|
||||
#define EPOCHS 500
|
||||
#define REP 400
|
||||
|
||||
BENCH("Small graph, epochs: " TOSTR(EPOCHS) ", repetitions: " TOSTR(REP), REPEAT(igraph_layout_umap(&graph, &layout, 0, &distances, 0.01, EPOCHS, 0) , REP);
|
||||
);
|
||||
|
||||
#undef EPOCHS
|
||||
#undef REP
|
||||
#define EPOCHS 60
|
||||
#define REP 1
|
||||
#define VCOUNT 10000
|
||||
#define DENS 0.001
|
||||
|
||||
igraph_destroy(&graph);
|
||||
igraph_erdos_renyi_game_gnp(&graph, VCOUNT, DENS, IGRAPH_DIRECTED, IGRAPH_SIMPLE_SW, IGRAPH_EDGE_UNLABELED);
|
||||
igraph_vector_resize(&distances, igraph_ecount(&graph));
|
||||
for (igraph_int_t i=0; i < igraph_ecount(&graph); i++) {
|
||||
VECTOR(distances)[i] = RNG_UNIF(0.05, 0.15);
|
||||
}
|
||||
|
||||
BENCH("Larger graph, epochs: " TOSTR(EPOCHS) ", repetitions: " TOSTR(REP), REPEAT(igraph_layout_umap(&graph, &layout, 0, &distances, 0.01, EPOCHS, 0) , REP);
|
||||
);
|
||||
|
||||
|
||||
igraph_matrix_destroy(&layout);
|
||||
igraph_destroy(&graph);
|
||||
igraph_vector_destroy(&distances);
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
igraph library.
|
||||
Copyright (C) 2024 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 "bench.h"
|
||||
|
||||
#define TOSTR1(x) #x
|
||||
#define TOSTR(x) TOSTR1(x)
|
||||
|
||||
void bench(int m, int n, int rep) {
|
||||
igraph_matrix_t mat;
|
||||
|
||||
igraph_matrix_init(&mat, m, n);
|
||||
for (igraph_int_t j=0; j < n; j++) {
|
||||
for (igraph_int_t i=0; i < m; i++) {
|
||||
MATRIX(mat, i, j) = RNG_UNIF(-1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
char name[200];
|
||||
sprintf(name, "Transpose %5d x %5d, %dx", m, n, rep);
|
||||
BENCH( name, REPEAT(igraph_matrix_transpose(&mat), rep) );
|
||||
|
||||
igraph_matrix_destroy(&mat);
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
BENCH_INIT();
|
||||
|
||||
bench(30, 30, 100000);
|
||||
bench(100, 100, 10000);
|
||||
bench(1000, 1000, 100);
|
||||
bench(1024, 1024, 100); /* naive implementation has bad cache behaviour with power of 2 sizes */
|
||||
bench(1023, 1025, 100); /* non-symmetric */
|
||||
bench(3000, 3000, 10);
|
||||
/* skinny non-symmetric: */
|
||||
bench(100, 10000, 100);
|
||||
bench(10000, 100, 100);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
igraph library.
|
||||
Copyright (C) 2013-2024 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 "bench.h"
|
||||
|
||||
int main(void) {
|
||||
|
||||
igraph_t g;
|
||||
igraph_int_t toremovev[] = {
|
||||
2609, 2098, 14517, 7540, 19560, 8855,
|
||||
5939, 14947, 441, 16976, 19642, 4188,
|
||||
15447, 11837, 2333, 7309, 18539, 14099,
|
||||
14264, 9240
|
||||
};
|
||||
const igraph_vector_int_t toremove =
|
||||
igraph_vector_int_view(toremovev, sizeof(toremovev) / sizeof(toremovev[0]));;
|
||||
igraph_vector_int_list_t res;
|
||||
|
||||
BENCH_INIT();
|
||||
|
||||
igraph_full(&g, 200, IGRAPH_UNDIRECTED, IGRAPH_NO_LOOPS);
|
||||
igraph_delete_edges(&g, igraph_ess_vector(&toremove));
|
||||
|
||||
igraph_vector_int_list_init(&res, 0);
|
||||
|
||||
BENCH(" 1 Maximal cliques of almost complete graph",
|
||||
igraph_maximal_cliques(&g, &res,
|
||||
/* min_size= */ IGRAPH_UNLIMITED, /* max_size= */ IGRAPH_UNLIMITED,
|
||||
/* max_results= */ IGRAPH_UNLIMITED);
|
||||
);
|
||||
|
||||
igraph_destroy(&g);
|
||||
|
||||
igraph_vector_int_list_destroy(&res);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
igraph library.
|
||||
Copyright (C) 2025 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 "bench.h"
|
||||
|
||||
void bench_pointcloud(const char *message, igraph_metric_t metric, igraph_int_t point_count, igraph_int_t dimensions, igraph_int_t neighbors, igraph_real_t cutoff) {
|
||||
igraph_matrix_t points;
|
||||
igraph_t g;
|
||||
char msg[200];
|
||||
const char *metricname;
|
||||
|
||||
igraph_matrix_init(&points, point_count, dimensions);
|
||||
|
||||
for (igraph_int_t point = 0; point < point_count; point++) {
|
||||
for (igraph_int_t dim = 0; dim < dimensions; dim++) {
|
||||
MATRIX(points, point, dim) = RNG_UNIF01();
|
||||
}
|
||||
}
|
||||
|
||||
switch (metric) {
|
||||
case IGRAPH_METRIC_L2: metricname = "L2"; break;
|
||||
case IGRAPH_METRIC_L1: metricname = "L1"; break;
|
||||
}
|
||||
|
||||
snprintf(msg, sizeof(msg) / sizeof(msg[0]),
|
||||
"%s RKNN with %s, %dD, n=%6" IGRAPH_PRId ", k=%2d, r=%g",
|
||||
message, metricname, (int) dimensions, point_count, (int) neighbors, cutoff);
|
||||
|
||||
BENCH(msg, igraph_nearest_neighbor_graph(&g, &points, metric, neighbors, cutoff, false));
|
||||
|
||||
igraph_destroy(&g);
|
||||
igraph_matrix_destroy(&points);
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
BENCH_INIT();
|
||||
igraph_rng_seed(igraph_rng_default(), 20250728);
|
||||
|
||||
bench_pointcloud(" 1", IGRAPH_METRIC_L2, 100000, 1, 10, 0.1);
|
||||
bench_pointcloud(" 2", IGRAPH_METRIC_L2, 100000, 2, 10, 0.1);
|
||||
bench_pointcloud(" 3", IGRAPH_METRIC_L2, 100000, 3, 10, 0.1);
|
||||
bench_pointcloud(" 4", IGRAPH_METRIC_L2, 100000, 4, 10, 0.1);
|
||||
|
||||
bench_pointcloud(" 5", IGRAPH_METRIC_L2, 10000, 1, -1, 0.001);
|
||||
bench_pointcloud(" 6", IGRAPH_METRIC_L2, 10000, 2, -1, 0.01);
|
||||
bench_pointcloud(" 7", IGRAPH_METRIC_L2, 10000, 3, -1, 0.01);
|
||||
bench_pointcloud(" 8", IGRAPH_METRIC_L2, 10000, 4, -1, 0.1);
|
||||
|
||||
bench_pointcloud(" 9", IGRAPH_METRIC_L2, 1000, 1, -1, -1);
|
||||
bench_pointcloud("10", IGRAPH_METRIC_L2, 1000, 2, -1, -1);
|
||||
bench_pointcloud("11", IGRAPH_METRIC_L2, 1000, 3, -1, -1);
|
||||
bench_pointcloud("12", IGRAPH_METRIC_L2, 1000, 4, -1, -1);
|
||||
|
||||
bench_pointcloud("13", IGRAPH_METRIC_L2, 100000, 1, 10, -1);
|
||||
bench_pointcloud("14", IGRAPH_METRIC_L2, 100000, 2, 10, -1);
|
||||
bench_pointcloud("15", IGRAPH_METRIC_L2, 100000, 3, 10, -1);
|
||||
bench_pointcloud("16", IGRAPH_METRIC_L2, 100000, 4, 10, -1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,473 @@
|
||||
/*
|
||||
igraph library.
|
||||
Copyright (C) 2021-2024 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 "bench.h"
|
||||
|
||||
typedef struct igraph_lazy_adjlist2_t {
|
||||
const igraph_t *graph;
|
||||
igraph_int_t length;
|
||||
igraph_int_t data_length;
|
||||
igraph_vector_int_t *adjs;
|
||||
igraph_int_t *data;
|
||||
igraph_int_t next_data;
|
||||
igraph_neimode_t mode;
|
||||
igraph_loops_t loops;
|
||||
igraph_bool_t multiple;
|
||||
} igraph_lazy_adjlist2_t;
|
||||
|
||||
igraph_error_t igraph_lazy_adjlist2_init(const igraph_t *graph,
|
||||
igraph_lazy_adjlist2_t *al,
|
||||
igraph_neimode_t mode,
|
||||
igraph_loops_t loops,
|
||||
igraph_bool_t multiple) {
|
||||
if (mode != IGRAPH_IN && mode != IGRAPH_OUT && mode != IGRAPH_ALL) {
|
||||
IGRAPH_ERROR("Cannor create lazy adjacency list view", IGRAPH_EINVMODE);
|
||||
}
|
||||
|
||||
if (!igraph_is_directed(graph)) {
|
||||
mode = IGRAPH_ALL;
|
||||
}
|
||||
|
||||
al->mode = mode;
|
||||
al->loops = loops;
|
||||
al->multiple = multiple;
|
||||
al->graph = graph;
|
||||
|
||||
al->length = igraph_vcount(graph);
|
||||
al->data_length = igraph_ecount(graph) * 2;
|
||||
al->adjs = IGRAPH_CALLOC(al->length, igraph_vector_int_t);
|
||||
al->data = IGRAPH_CALLOC(al->data_length, igraph_int_t);
|
||||
al->next_data = 0;
|
||||
|
||||
if (al->adjs == NULL || al->data == NULL) {
|
||||
IGRAPH_ERROR("Cannot create lazy adjacency list view", IGRAPH_ENOMEM);
|
||||
}
|
||||
|
||||
return IGRAPH_SUCCESS;
|
||||
}
|
||||
|
||||
void igraph_lazy_adjlist2_destroy(igraph_lazy_adjlist2_t *al) {
|
||||
IGRAPH_FREE(al->adjs);
|
||||
IGRAPH_FREE(al->data);
|
||||
}
|
||||
|
||||
igraph_vector_int_t *igraph_i_lazy_adjlist2_get_real(
|
||||
igraph_lazy_adjlist2_t *al, igraph_int_t pno
|
||||
) {
|
||||
igraph_int_t no = pno;
|
||||
igraph_error_t ret;
|
||||
|
||||
if (al->adjs[no].stor_begin == NULL) {
|
||||
al->adjs[no] = igraph_vector_int_view(al->data + al->next_data, al->data_length - al->next_data);
|
||||
/* igraph_neighbors calls a resize. Since we're handling our own
|
||||
* vectors, we can't have our stor_begin be realloced. A realloc should only
|
||||
* happen when the vector is too small to handle the neighbors, which
|
||||
* should never happen, because the stor_end is set to one past the
|
||||
* end of the latest integer.
|
||||
*/
|
||||
ret = igraph_neighbors(al->graph, &al->adjs[no], no, al->mode, al->loops, al->multiple);
|
||||
if (ret != IGRAPH_SUCCESS) {
|
||||
igraph_error("", IGRAPH_FILE_BASENAME, __LINE__, ret);
|
||||
return NULL;
|
||||
}
|
||||
al->next_data += igraph_vector_int_size(&(al->adjs[no]));
|
||||
}
|
||||
|
||||
return &al->adjs[no];
|
||||
}
|
||||
|
||||
igraph_error_t igraph_neighborhood_adjl2(const igraph_t *graph, igraph_vector_int_list_t *res,
|
||||
igraph_vs_t vids, igraph_int_t order,
|
||||
igraph_neimode_t mode, igraph_int_t mindist) {
|
||||
|
||||
igraph_int_t no_of_nodes = igraph_vcount(graph);
|
||||
igraph_dqueue_int_t q;
|
||||
igraph_vit_t vit;
|
||||
igraph_int_t i, j;
|
||||
igraph_int_t *added;
|
||||
igraph_vector_int_t *neis;
|
||||
igraph_vector_int_t tmp;
|
||||
igraph_lazy_adjlist2_t adjlist2;
|
||||
|
||||
if (order < 0) {
|
||||
IGRAPH_ERROR("Negative order in neighborhood size", IGRAPH_EINVAL);
|
||||
}
|
||||
|
||||
if (mindist < 0 || mindist > order) {
|
||||
IGRAPH_ERROR("Minimum distance should be between zero and order",
|
||||
IGRAPH_EINVAL);
|
||||
}
|
||||
|
||||
added = IGRAPH_CALLOC(no_of_nodes, igraph_int_t);
|
||||
if (added == 0) {
|
||||
IGRAPH_ERROR("Cannot calculate neighborhood size", IGRAPH_ENOMEM);
|
||||
}
|
||||
IGRAPH_FINALLY(igraph_free, added);
|
||||
IGRAPH_DQUEUE_INT_INIT_FINALLY(&q, 100);
|
||||
IGRAPH_CHECK(igraph_vit_create(graph, vids, &vit));
|
||||
IGRAPH_FINALLY(igraph_vit_destroy, &vit);
|
||||
IGRAPH_VECTOR_INT_INIT_FINALLY(&tmp, 0);
|
||||
IGRAPH_CHECK(igraph_vector_int_list_reserve(res, IGRAPH_VIT_SIZE(vit)));
|
||||
igraph_vector_int_list_clear(res);
|
||||
|
||||
if (!igraph_is_directed(graph) || mode == IGRAPH_ALL) {
|
||||
IGRAPH_CHECK(igraph_lazy_adjlist2_init(graph, &adjlist2, mode, IGRAPH_LOOPS_TWICE, IGRAPH_MULTIPLE));
|
||||
} else {
|
||||
IGRAPH_CHECK(igraph_lazy_adjlist2_init(graph, &adjlist2, mode, IGRAPH_LOOPS_ONCE, IGRAPH_MULTIPLE));
|
||||
}
|
||||
IGRAPH_FINALLY(igraph_lazy_adjlist2_destroy, &adjlist2);
|
||||
for (i = 0; !IGRAPH_VIT_END(vit); IGRAPH_VIT_NEXT(vit), i++) {
|
||||
igraph_int_t node = IGRAPH_VIT_GET(vit);
|
||||
added[node] = i + 1;
|
||||
igraph_vector_int_clear(&tmp);
|
||||
if (mindist == 0) {
|
||||
IGRAPH_CHECK(igraph_vector_int_push_back(&tmp, node));
|
||||
}
|
||||
if (order > 0) {
|
||||
IGRAPH_CHECK(igraph_dqueue_int_push(&q, node));
|
||||
IGRAPH_CHECK(igraph_dqueue_int_push(&q, 0));
|
||||
}
|
||||
|
||||
while (!igraph_dqueue_int_empty(&q)) {
|
||||
igraph_int_t actnode = igraph_dqueue_int_pop(&q);
|
||||
igraph_int_t actdist = igraph_dqueue_int_pop(&q);
|
||||
igraph_int_t n;
|
||||
neis = igraph_i_lazy_adjlist2_get_real(&adjlist2, actnode);
|
||||
n = igraph_vector_int_size(neis);
|
||||
|
||||
if (actdist < order - 1) {
|
||||
/* we add them to the q */
|
||||
for (j = 0; j < n; j++) {
|
||||
igraph_int_t nei = VECTOR(*neis)[j];
|
||||
if (added[nei] != i + 1) {
|
||||
added[nei] = i + 1;
|
||||
IGRAPH_CHECK(igraph_dqueue_int_push(&q, nei));
|
||||
IGRAPH_CHECK(igraph_dqueue_int_push(&q, actdist + 1));
|
||||
if (actdist + 1 >= mindist) {
|
||||
IGRAPH_CHECK(igraph_vector_int_push_back(&tmp, nei));
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* we just count them but don't add them to q */
|
||||
for (j = 0; j < n; j++) {
|
||||
igraph_int_t nei = VECTOR(*neis)[j];
|
||||
if (added[nei] != i + 1) {
|
||||
added[nei] = i + 1;
|
||||
if (actdist + 1 >= mindist) {
|
||||
IGRAPH_CHECK(igraph_vector_int_push_back(&tmp, nei));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} /* while q not empty */
|
||||
|
||||
IGRAPH_CHECK(igraph_vector_int_list_push_back_copy(res, &tmp));
|
||||
}
|
||||
|
||||
igraph_lazy_adjlist2_destroy(&adjlist2);
|
||||
igraph_vector_int_destroy(&tmp);
|
||||
igraph_vit_destroy(&vit);
|
||||
igraph_dqueue_int_destroy(&q);
|
||||
IGRAPH_FREE(added);
|
||||
IGRAPH_FINALLY_CLEAN(5);
|
||||
|
||||
return IGRAPH_SUCCESS;
|
||||
}
|
||||
|
||||
igraph_error_t igraph_neighborhood_adjl(const igraph_t *graph, igraph_vector_int_list_t *res,
|
||||
igraph_vs_t vids, igraph_int_t order,
|
||||
igraph_neimode_t mode, igraph_int_t mindist) {
|
||||
|
||||
igraph_int_t no_of_nodes = igraph_vcount(graph);
|
||||
igraph_dqueue_int_t q;
|
||||
igraph_vit_t vit;
|
||||
igraph_int_t i, j;
|
||||
igraph_int_t *added;
|
||||
igraph_vector_int_t *neis;
|
||||
igraph_vector_int_t tmp;
|
||||
igraph_lazy_adjlist_t adjlist;
|
||||
|
||||
if (order < 0) {
|
||||
IGRAPH_ERROR("Negative order in neighborhood size", IGRAPH_EINVAL);
|
||||
}
|
||||
|
||||
if (mindist < 0 || mindist > order) {
|
||||
IGRAPH_ERROR("Minimum distance should be between zero and order",
|
||||
IGRAPH_EINVAL);
|
||||
}
|
||||
|
||||
added = IGRAPH_CALLOC(no_of_nodes, igraph_int_t);
|
||||
if (added == 0) {
|
||||
IGRAPH_ERROR("Cannot calculate neighborhood size", IGRAPH_ENOMEM);
|
||||
}
|
||||
IGRAPH_FINALLY(igraph_free, added);
|
||||
IGRAPH_DQUEUE_INT_INIT_FINALLY(&q, 100);
|
||||
IGRAPH_CHECK(igraph_vit_create(graph, vids, &vit));
|
||||
IGRAPH_FINALLY(igraph_vit_destroy, &vit);
|
||||
IGRAPH_VECTOR_INT_INIT_FINALLY(&tmp, 0);
|
||||
IGRAPH_CHECK(igraph_vector_int_list_reserve(res, IGRAPH_VIT_SIZE(vit)));
|
||||
igraph_vector_int_list_clear(res);
|
||||
|
||||
if (!igraph_is_directed(graph) || mode == IGRAPH_ALL) {
|
||||
IGRAPH_CHECK(igraph_lazy_adjlist_init(graph, &adjlist, mode, IGRAPH_LOOPS_TWICE, IGRAPH_MULTIPLE));
|
||||
} else {
|
||||
IGRAPH_CHECK(igraph_lazy_adjlist_init(graph, &adjlist, mode, IGRAPH_LOOPS_ONCE, IGRAPH_MULTIPLE));
|
||||
}
|
||||
IGRAPH_FINALLY(igraph_lazy_adjlist_destroy, &adjlist);
|
||||
for (i = 0; !IGRAPH_VIT_END(vit); IGRAPH_VIT_NEXT(vit), i++) {
|
||||
igraph_int_t node = IGRAPH_VIT_GET(vit);
|
||||
added[node] = i + 1;
|
||||
igraph_vector_int_clear(&tmp);
|
||||
if (mindist == 0) {
|
||||
IGRAPH_CHECK(igraph_vector_int_push_back(&tmp, node));
|
||||
}
|
||||
if (order > 0) {
|
||||
IGRAPH_CHECK(igraph_dqueue_int_push(&q, node));
|
||||
IGRAPH_CHECK(igraph_dqueue_int_push(&q, 0));
|
||||
}
|
||||
|
||||
while (!igraph_dqueue_int_empty(&q)) {
|
||||
igraph_int_t actnode = igraph_dqueue_int_pop(&q);
|
||||
igraph_int_t actdist = igraph_dqueue_int_pop(&q);
|
||||
igraph_int_t n;
|
||||
neis = igraph_lazy_adjlist_get(&adjlist, actnode);
|
||||
n = igraph_vector_int_size(neis);
|
||||
|
||||
if (actdist < order - 1) {
|
||||
/* we add them to the q */
|
||||
for (j = 0; j < n; j++) {
|
||||
igraph_int_t nei = VECTOR(*neis)[j];
|
||||
if (added[nei] != i + 1) {
|
||||
added[nei] = i + 1;
|
||||
IGRAPH_CHECK(igraph_dqueue_int_push(&q, nei));
|
||||
IGRAPH_CHECK(igraph_dqueue_int_push(&q, actdist + 1));
|
||||
if (actdist + 1 >= mindist) {
|
||||
IGRAPH_CHECK(igraph_vector_int_push_back(&tmp, nei));
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* we just count them but don't add them to q */
|
||||
for (j = 0; j < n; j++) {
|
||||
igraph_int_t nei = VECTOR(*neis)[j];
|
||||
if (added[nei] != i + 1) {
|
||||
added[nei] = i + 1;
|
||||
if (actdist + 1 >= mindist) {
|
||||
IGRAPH_CHECK(igraph_vector_int_push_back(&tmp, nei));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} /* while q not empty */
|
||||
|
||||
IGRAPH_CHECK(igraph_vector_int_list_push_back_copy(res, &tmp));
|
||||
}
|
||||
|
||||
igraph_lazy_adjlist_destroy(&adjlist);
|
||||
igraph_vector_int_destroy(&tmp);
|
||||
igraph_vit_destroy(&vit);
|
||||
igraph_dqueue_int_destroy(&q);
|
||||
IGRAPH_FREE(added);
|
||||
IGRAPH_FINALLY_CLEAN(5);
|
||||
|
||||
return IGRAPH_SUCCESS;
|
||||
}
|
||||
|
||||
igraph_error_t igraph_neighborhood_adj(const igraph_t *graph, igraph_vector_int_list_t *res,
|
||||
igraph_vs_t vids, igraph_int_t order,
|
||||
igraph_neimode_t mode, igraph_int_t mindist) {
|
||||
|
||||
igraph_int_t no_of_nodes = igraph_vcount(graph);
|
||||
igraph_dqueue_int_t q;
|
||||
igraph_vit_t vit;
|
||||
igraph_int_t i, j;
|
||||
igraph_int_t *added;
|
||||
igraph_vector_int_t *neis;
|
||||
igraph_vector_int_t tmp;
|
||||
igraph_adjlist_t adjlist;
|
||||
|
||||
if (order < 0) {
|
||||
IGRAPH_ERROR("Negative order in neighborhood size", IGRAPH_EINVAL);
|
||||
}
|
||||
|
||||
if (mindist < 0 || mindist > order) {
|
||||
IGRAPH_ERROR("Minimum distance should be between zero and order",
|
||||
IGRAPH_EINVAL);
|
||||
}
|
||||
|
||||
added = IGRAPH_CALLOC(no_of_nodes, igraph_int_t);
|
||||
if (added == 0) {
|
||||
IGRAPH_ERROR("Cannot calculate neighborhood size", IGRAPH_ENOMEM);
|
||||
}
|
||||
IGRAPH_FINALLY(igraph_free, added);
|
||||
IGRAPH_DQUEUE_INT_INIT_FINALLY(&q, 100);
|
||||
IGRAPH_CHECK(igraph_vit_create(graph, vids, &vit));
|
||||
IGRAPH_FINALLY(igraph_vit_destroy, &vit);
|
||||
IGRAPH_VECTOR_INT_INIT_FINALLY(&tmp, 0);
|
||||
IGRAPH_CHECK(igraph_vector_int_list_reserve(res, IGRAPH_VIT_SIZE(vit)));
|
||||
igraph_vector_int_list_clear(res);
|
||||
|
||||
if (!igraph_is_directed(graph) || mode == IGRAPH_ALL) {
|
||||
IGRAPH_CHECK(igraph_adjlist_init(graph, &adjlist, mode, IGRAPH_LOOPS_TWICE, IGRAPH_MULTIPLE));
|
||||
} else {
|
||||
IGRAPH_CHECK(igraph_adjlist_init(graph, &adjlist, mode, IGRAPH_LOOPS_ONCE, IGRAPH_MULTIPLE));
|
||||
}
|
||||
IGRAPH_FINALLY(igraph_adjlist_destroy, &adjlist);
|
||||
for (i = 0; !IGRAPH_VIT_END(vit); IGRAPH_VIT_NEXT(vit), i++) {
|
||||
igraph_int_t node = IGRAPH_VIT_GET(vit);
|
||||
added[node] = i + 1;
|
||||
igraph_vector_int_clear(&tmp);
|
||||
if (mindist == 0) {
|
||||
IGRAPH_CHECK(igraph_vector_int_push_back(&tmp, node));
|
||||
}
|
||||
if (order > 0) {
|
||||
IGRAPH_CHECK(igraph_dqueue_int_push(&q, node));
|
||||
IGRAPH_CHECK(igraph_dqueue_int_push(&q, 0));
|
||||
}
|
||||
|
||||
while (!igraph_dqueue_int_empty(&q)) {
|
||||
igraph_int_t actnode = igraph_dqueue_int_pop(&q);
|
||||
igraph_int_t actdist = igraph_dqueue_int_pop(&q);
|
||||
igraph_int_t n;
|
||||
neis = igraph_adjlist_get(&adjlist, actnode);
|
||||
n = igraph_vector_int_size(neis);
|
||||
|
||||
if (actdist < order - 1) {
|
||||
/* we add them to the q */
|
||||
for (j = 0; j < n; j++) {
|
||||
igraph_int_t nei = VECTOR(*neis)[j];
|
||||
if (added[nei] != i + 1) {
|
||||
added[nei] = i + 1;
|
||||
IGRAPH_CHECK(igraph_dqueue_int_push(&q, nei));
|
||||
IGRAPH_CHECK(igraph_dqueue_int_push(&q, actdist + 1));
|
||||
if (actdist + 1 >= mindist) {
|
||||
IGRAPH_CHECK(igraph_vector_int_push_back(&tmp, nei));
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* we just count them but don't add them to q */
|
||||
for (j = 0; j < n; j++) {
|
||||
igraph_int_t nei = VECTOR(*neis)[j];
|
||||
if (added[nei] != i + 1) {
|
||||
added[nei] = i + 1;
|
||||
if (actdist + 1 >= mindist) {
|
||||
IGRAPH_CHECK(igraph_vector_int_push_back(&tmp, nei));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} /* while q not empty */
|
||||
|
||||
IGRAPH_CHECK(igraph_vector_int_list_push_back_copy(res, &tmp));
|
||||
}
|
||||
|
||||
igraph_adjlist_destroy(&adjlist);
|
||||
igraph_vector_int_destroy(&tmp);
|
||||
igraph_vit_destroy(&vit);
|
||||
igraph_dqueue_int_destroy(&q);
|
||||
IGRAPH_FREE(added);
|
||||
IGRAPH_FINALLY_CLEAN(5);
|
||||
|
||||
return IGRAPH_SUCCESS;
|
||||
}
|
||||
|
||||
void do_benchmark(igraph_t *g, igraph_vs_t vids, igraph_int_t repeat)
|
||||
{
|
||||
igraph_vector_int_list_t result_orig;
|
||||
igraph_vector_int_list_t result_adj;
|
||||
igraph_vector_int_list_t result_adjl;
|
||||
igraph_vector_int_list_t result_adjl2;
|
||||
|
||||
igraph_vector_int_list_init(&result_orig, 0);
|
||||
igraph_vector_int_list_init(&result_adj, 0);
|
||||
igraph_vector_int_list_init(&result_adjl, 0);
|
||||
igraph_vector_int_list_init(&result_adjl2, 0);
|
||||
|
||||
for (igraph_int_t order = 1; order <= 3; order++) {
|
||||
printf("order %" IGRAPH_PRId ":\n", order);
|
||||
BENCH("Original function:",
|
||||
REPEAT(igraph_neighborhood(g, &result_orig, vids, order,
|
||||
/*mode*/ IGRAPH_ALL, /*mindist*/ 0), repeat));
|
||||
|
||||
BENCH("Using a lazy adjlist:",
|
||||
REPEAT(igraph_neighborhood_adjl(g, &result_adjl, vids, order,
|
||||
/*mode*/ IGRAPH_ALL, /*mindist*/ 0), repeat));
|
||||
|
||||
BENCH("Using lazy adjlist 2:",
|
||||
REPEAT(igraph_neighborhood_adjl2(g, &result_adjl2, vids, order,
|
||||
/*mode*/ IGRAPH_ALL, /*mindist*/ 0), repeat));
|
||||
|
||||
BENCH("Using adjlist:",
|
||||
REPEAT(igraph_neighborhood_adj(g, &result_adj, vids, order,
|
||||
/*mode*/ IGRAPH_ALL, /*mindist*/ 0), repeat));
|
||||
for (igraph_int_t i = 0; i <= order; i++) {
|
||||
IGRAPH_ASSERT(!igraph_vector_int_lex_cmp(&VECTOR(result_orig)[i], &VECTOR(result_adj)[i]));
|
||||
IGRAPH_ASSERT(!igraph_vector_int_lex_cmp(&VECTOR(result_adj)[i], &VECTOR(result_adjl)[i]));
|
||||
IGRAPH_ASSERT(!igraph_vector_int_lex_cmp(&VECTOR(result_adjl)[i], &VECTOR(result_adjl2)[i]));
|
||||
}
|
||||
}
|
||||
igraph_vector_int_list_destroy(&result_orig);
|
||||
igraph_vector_int_list_destroy(&result_adj);
|
||||
igraph_vector_int_list_destroy(&result_adjl);
|
||||
igraph_vector_int_list_destroy(&result_adjl2);
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
igraph_t g_full, g_ring, g_er;
|
||||
igraph_vs_t vids_all, vids_50, vids_5000, vids_200;
|
||||
|
||||
igraph_vs_all(&vids_all);
|
||||
igraph_vs_range(&vids_50, 0, 50);
|
||||
igraph_vs_range(&vids_5000, 0, 5000);
|
||||
igraph_vs_range(&vids_200, 0, 200);
|
||||
|
||||
igraph_full(&g_full, 500, IGRAPH_UNDIRECTED, IGRAPH_NO_LOOPS);
|
||||
igraph_ring(&g_ring, 50000, IGRAPH_UNDIRECTED, /* mutual */ 0, /*circular*/ 0);
|
||||
igraph_erdos_renyi_game_gnm(&g_er, 2000, 20000, IGRAPH_UNDIRECTED, IGRAPH_SIMPLE_SW, IGRAPH_EDGE_UNLABELED);
|
||||
|
||||
printf("Select all vertices:\n\n");
|
||||
printf("Full graph:\n");
|
||||
do_benchmark(&g_full, vids_all, 10);
|
||||
printf("\nRing graph:\n");
|
||||
do_benchmark(&g_ring, vids_all, 40);
|
||||
printf("\nRandom graph:\n");
|
||||
do_benchmark(&g_er, vids_all, 15);
|
||||
|
||||
printf("\n\nSelect 10%% of vertices:\n\n");
|
||||
printf("Full graph:\n");
|
||||
do_benchmark(&g_full, vids_50, 100);
|
||||
printf("\nRing graph:\n");
|
||||
do_benchmark(&g_ring, vids_5000, 400);
|
||||
printf("\nRandom graph:\n");
|
||||
do_benchmark(&g_er, vids_200, 150);
|
||||
|
||||
igraph_destroy(&g_full);
|
||||
igraph_destroy(&g_ring);
|
||||
igraph_destroy(&g_er);
|
||||
igraph_vs_destroy(&vids_all);
|
||||
igraph_vs_destroy(&vids_50);
|
||||
igraph_vs_destroy(&vids_5000);
|
||||
igraph_vs_destroy(&vids_200);
|
||||
}
|
||||
@@ -0,0 +1,137 @@
|
||||
/*
|
||||
igraph library.
|
||||
Copyright (C) 2024 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 "bench.h"
|
||||
|
||||
int main(void) {
|
||||
igraph_t graph;
|
||||
igraph_vector_t res;
|
||||
igraph_arpack_options_t arpack_opts;
|
||||
|
||||
BENCH_INIT();
|
||||
igraph_rng_seed(igraph_rng_default(), 42);
|
||||
|
||||
igraph_arpack_options_init(&arpack_opts);
|
||||
|
||||
igraph_vector_init(&res, 0);
|
||||
|
||||
igraph_barabasi_game(&graph, 100000, 1, 4, NULL, 1, 0, IGRAPH_DIRECTED, IGRAPH_BARABASI_PSUMTREE, NULL);
|
||||
BENCH(" 1 PageRank, Barabasi n=100000 m=4, PRPACK, 10x",
|
||||
REPEAT(igraph_pagerank(&graph, NULL, &res, NULL, 0.85, IGRAPH_DIRECTED, igraph_vss_all(),
|
||||
IGRAPH_PAGERANK_ALGO_PRPACK, NULL), 10)
|
||||
);
|
||||
BENCH(" 2 PageRank, Barabasi n=100000 m=4, ARPACK, 10x",
|
||||
REPEAT(igraph_pagerank(&graph, NULL, &res, NULL, 0.85, IGRAPH_DIRECTED, igraph_vss_all(),
|
||||
IGRAPH_PAGERANK_ALGO_ARPACK, &arpack_opts), 10)
|
||||
);
|
||||
igraph_destroy(&graph);
|
||||
|
||||
igraph_barabasi_game(&graph, 100000, 1, 10, NULL, 1, 0, IGRAPH_DIRECTED, IGRAPH_BARABASI_PSUMTREE, NULL);
|
||||
BENCH(" 3 PageRank, Barabasi n=100000 m=10, PRPACK, 5x",
|
||||
REPEAT(igraph_pagerank(&graph, NULL, &res, NULL, 0.85, IGRAPH_DIRECTED, igraph_vss_all(),
|
||||
IGRAPH_PAGERANK_ALGO_PRPACK, NULL), 5)
|
||||
);
|
||||
BENCH(" 4 PageRank, Barabasi n=100000 m=10, ARPACK, 5x",
|
||||
REPEAT(igraph_pagerank(&graph, NULL, &res, NULL, 0.85, IGRAPH_DIRECTED, igraph_vss_all(),
|
||||
IGRAPH_PAGERANK_ALGO_ARPACK, &arpack_opts), 5)
|
||||
);
|
||||
igraph_destroy(&graph);
|
||||
|
||||
igraph_erdos_renyi_game_gnm(&graph, 100, 1000, IGRAPH_DIRECTED, IGRAPH_LOOPS_SW, IGRAPH_EDGE_UNLABELED);
|
||||
BENCH(" 5 PageRank, GNM(100,1000), PRPACK, 1000x",
|
||||
REPEAT(igraph_pagerank(&graph, NULL, &res, NULL, 0.85, IGRAPH_DIRECTED, igraph_vss_all(),
|
||||
IGRAPH_PAGERANK_ALGO_PRPACK, NULL), 1000)
|
||||
);
|
||||
BENCH(" 6 PageRank, GNM(100,1000), ARPACK, 1000x",
|
||||
REPEAT(igraph_pagerank(&graph, NULL, &res, NULL, 0.85, IGRAPH_DIRECTED, igraph_vss_all(),
|
||||
IGRAPH_PAGERANK_ALGO_ARPACK, &arpack_opts), 1000)
|
||||
);
|
||||
igraph_destroy(&graph);
|
||||
|
||||
igraph_erdos_renyi_game_gnm(&graph, 200, 4000, IGRAPH_DIRECTED, IGRAPH_LOOPS_SW, IGRAPH_EDGE_UNLABELED);
|
||||
BENCH(" 7 PageRank, GNM(200,4000), PRPACK, 1000x",
|
||||
REPEAT(igraph_pagerank(&graph, NULL, &res, NULL, 0.85, IGRAPH_DIRECTED, igraph_vss_all(),
|
||||
IGRAPH_PAGERANK_ALGO_PRPACK, NULL), 1000)
|
||||
);
|
||||
BENCH(" 8 PageRank, GNM(200,4000), ARPACK, 1000x",
|
||||
REPEAT(igraph_pagerank(&graph, NULL, &res, NULL, 0.85, IGRAPH_DIRECTED, igraph_vss_all(),
|
||||
IGRAPH_PAGERANK_ALGO_ARPACK, &arpack_opts), 1000)
|
||||
);
|
||||
igraph_destroy(&graph);
|
||||
|
||||
igraph_erdos_renyi_game_gnm(&graph, 10000, 20000, IGRAPH_DIRECTED, IGRAPH_LOOPS_SW, IGRAPH_EDGE_UNLABELED);
|
||||
BENCH(" 9 PageRank, GNM(10000,20000), PRPACK, 100x",
|
||||
REPEAT(igraph_pagerank(&graph, NULL, &res, NULL, 0.85, IGRAPH_DIRECTED, igraph_vss_all(),
|
||||
IGRAPH_PAGERANK_ALGO_PRPACK, NULL), 100)
|
||||
);
|
||||
BENCH("10 PageRank, GNM(10000,20000), ARPACK, 100x",
|
||||
REPEAT(igraph_pagerank(&graph, NULL, &res, NULL, 0.85, IGRAPH_DIRECTED, igraph_vss_all(),
|
||||
IGRAPH_PAGERANK_ALGO_ARPACK, &arpack_opts), 100)
|
||||
);
|
||||
igraph_destroy(&graph);
|
||||
|
||||
igraph_erdos_renyi_game_gnm(&graph, 100000, 100000, IGRAPH_DIRECTED, IGRAPH_LOOPS_SW, IGRAPH_EDGE_UNLABELED);
|
||||
BENCH("11 PageRank, GNM(100000,100000), PRPACK, 10x",
|
||||
REPEAT(igraph_pagerank(&graph, NULL, &res, NULL, 0.85, IGRAPH_DIRECTED, igraph_vss_all(),
|
||||
IGRAPH_PAGERANK_ALGO_PRPACK, NULL), 10)
|
||||
);
|
||||
BENCH("12 PageRank, GNM(100000,100000), ARPACK, 10x",
|
||||
REPEAT(igraph_pagerank(&graph, NULL, &res, NULL, 0.85, IGRAPH_DIRECTED, igraph_vss_all(),
|
||||
IGRAPH_PAGERANK_ALGO_ARPACK, &arpack_opts), 10)
|
||||
);
|
||||
igraph_destroy(&graph);
|
||||
|
||||
igraph_erdos_renyi_game_gnm(&graph, 100000, 500000, IGRAPH_DIRECTED, IGRAPH_LOOPS_SW, IGRAPH_EDGE_UNLABELED);
|
||||
BENCH("13 PageRank, GNM(100000,500000), PRPACK, 10x",
|
||||
REPEAT(igraph_pagerank(&graph, NULL, &res, NULL, 0.85, IGRAPH_DIRECTED, igraph_vss_all(),
|
||||
IGRAPH_PAGERANK_ALGO_PRPACK, NULL), 10)
|
||||
);
|
||||
BENCH("14 PageRank, GNM(100000,500000), ARPACK, 10x",
|
||||
REPEAT(igraph_pagerank(&graph, NULL, &res, NULL, 0.85, IGRAPH_DIRECTED, igraph_vss_all(),
|
||||
IGRAPH_PAGERANK_ALGO_ARPACK, &arpack_opts), 10)
|
||||
);
|
||||
igraph_destroy(&graph);
|
||||
|
||||
igraph_kautz(&graph, 6, 6);
|
||||
BENCH("13 PageRank, Kautz(6,6), PRPACK, 1x",
|
||||
REPEAT(igraph_pagerank(&graph, NULL, &res, NULL, 0.85, IGRAPH_DIRECTED, igraph_vss_all(),
|
||||
IGRAPH_PAGERANK_ALGO_PRPACK, NULL), 1)
|
||||
);
|
||||
BENCH("14 PageRank, Kautz(6,6), ARPACK, 1x",
|
||||
REPEAT(igraph_pagerank(&graph, NULL, &res, NULL, 0.85, IGRAPH_DIRECTED, igraph_vss_all(),
|
||||
IGRAPH_PAGERANK_ALGO_ARPACK, &arpack_opts), 1)
|
||||
);
|
||||
igraph_destroy(&graph);
|
||||
|
||||
igraph_de_bruijn(&graph, 7, 7);
|
||||
BENCH("13 PageRank, DeBruijn(7,7), PRPACK, 1x",
|
||||
REPEAT(igraph_pagerank(&graph, NULL, &res, NULL, 0.85, IGRAPH_DIRECTED, igraph_vss_all(),
|
||||
IGRAPH_PAGERANK_ALGO_PRPACK, NULL), 1)
|
||||
);
|
||||
BENCH("14 PageRank, DeBruijn(7,7), ARPACK, 1x",
|
||||
REPEAT(igraph_pagerank(&graph, NULL, &res, NULL, 0.85, IGRAPH_DIRECTED, igraph_vss_all(),
|
||||
IGRAPH_PAGERANK_ALGO_ARPACK, &arpack_opts), 1)
|
||||
);
|
||||
igraph_destroy(&graph);
|
||||
|
||||
igraph_vector_destroy(&res);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,156 @@
|
||||
/*
|
||||
igraph library.
|
||||
Copyright (C) 2024 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 "bench.h"
|
||||
|
||||
void rand_weight_vec(igraph_vector_t *vec, const igraph_t *graph) {
|
||||
igraph_int_t i, n = igraph_ecount(graph);
|
||||
igraph_vector_resize(vec, n);
|
||||
for (i=0; i < n; ++i) {
|
||||
VECTOR(*vec)[i] = RNG_UNIF(1, 10);
|
||||
}
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
igraph_t graph;
|
||||
igraph_vector_t res, weights;
|
||||
igraph_arpack_options_t arpack_opts;
|
||||
|
||||
BENCH_INIT();
|
||||
igraph_rng_seed(igraph_rng_default(), 42);
|
||||
|
||||
igraph_arpack_options_init(&arpack_opts);
|
||||
|
||||
igraph_vector_init(&res, 0);
|
||||
igraph_vector_init(&weights, 0);
|
||||
|
||||
igraph_barabasi_game(&graph, 100000, 1, 4, NULL, 1, 0, IGRAPH_DIRECTED, IGRAPH_BARABASI_PSUMTREE, NULL);
|
||||
rand_weight_vec(&weights, &graph);
|
||||
BENCH(" 1 PageRank weighted, Barabasi n=100000 m=4, PRPACK, 10x",
|
||||
REPEAT(igraph_pagerank(&graph, &weights, &res, NULL, 0.85, IGRAPH_DIRECTED, igraph_vss_all(),
|
||||
IGRAPH_PAGERANK_ALGO_PRPACK, NULL), 10)
|
||||
);
|
||||
BENCH(" 2 PageRank weighted, Barabasi n=100000 m=4, ARPACK, 10x",
|
||||
REPEAT(igraph_pagerank(&graph, &weights, &res, NULL, 0.85, IGRAPH_DIRECTED, igraph_vss_all(),
|
||||
IGRAPH_PAGERANK_ALGO_ARPACK, &arpack_opts), 10)
|
||||
);
|
||||
igraph_destroy(&graph);
|
||||
|
||||
igraph_barabasi_game(&graph, 100000, 1, 10, NULL, 1, 0, IGRAPH_DIRECTED, IGRAPH_BARABASI_PSUMTREE, NULL);
|
||||
rand_weight_vec(&weights, &graph);
|
||||
BENCH(" 3 PageRank weighted, Barabasi n=100000 m=10, PRPACK, 5x",
|
||||
REPEAT(igraph_pagerank(&graph, &weights, &res, NULL, 0.85, IGRAPH_DIRECTED, igraph_vss_all(),
|
||||
IGRAPH_PAGERANK_ALGO_PRPACK, NULL), 5)
|
||||
);
|
||||
BENCH(" 4 PageRank weighted, Barabasi n=100000 m=10, ARPACK, 5x",
|
||||
REPEAT(igraph_pagerank(&graph, &weights, &res, NULL, 0.85, IGRAPH_DIRECTED, igraph_vss_all(),
|
||||
IGRAPH_PAGERANK_ALGO_ARPACK, &arpack_opts), 5)
|
||||
);
|
||||
igraph_destroy(&graph);
|
||||
|
||||
igraph_erdos_renyi_game_gnm(&graph, 100, 1000, IGRAPH_DIRECTED, IGRAPH_LOOPS_SW, IGRAPH_EDGE_UNLABELED);
|
||||
rand_weight_vec(&weights, &graph);
|
||||
BENCH(" 5 PageRank weighted, GNM(100,1000), PRPACK, 1000x",
|
||||
REPEAT(igraph_pagerank(&graph, &weights, &res, NULL, 0.85, IGRAPH_DIRECTED, igraph_vss_all(),
|
||||
IGRAPH_PAGERANK_ALGO_PRPACK, NULL), 1000)
|
||||
);
|
||||
BENCH(" 6 PageRank weighted, GNM(100,1000), ARPACK, 1000x",
|
||||
REPEAT(igraph_pagerank(&graph, &weights, &res, NULL, 0.85, IGRAPH_DIRECTED, igraph_vss_all(),
|
||||
IGRAPH_PAGERANK_ALGO_ARPACK, &arpack_opts), 1000)
|
||||
);
|
||||
igraph_destroy(&graph);
|
||||
|
||||
igraph_erdos_renyi_game_gnm(&graph, 200, 4000, IGRAPH_DIRECTED, IGRAPH_LOOPS_SW, IGRAPH_EDGE_UNLABELED);
|
||||
rand_weight_vec(&weights, &graph);
|
||||
BENCH(" 7 PageRank weighted, GNM(200,4000), PRPACK, 1000x",
|
||||
REPEAT(igraph_pagerank(&graph, &weights, &res, NULL, 0.85, IGRAPH_DIRECTED, igraph_vss_all(),
|
||||
IGRAPH_PAGERANK_ALGO_PRPACK, NULL), 1000)
|
||||
);
|
||||
BENCH(" 8 PageRank weighted, GNM(200,4000), ARPACK, 1000x",
|
||||
REPEAT(igraph_pagerank(&graph, &weights, &res, NULL, 0.85, IGRAPH_DIRECTED, igraph_vss_all(),
|
||||
IGRAPH_PAGERANK_ALGO_ARPACK, &arpack_opts), 1000)
|
||||
);
|
||||
igraph_destroy(&graph);
|
||||
|
||||
igraph_erdos_renyi_game_gnm(&graph, 10000, 20000, IGRAPH_DIRECTED, IGRAPH_LOOPS_SW, IGRAPH_EDGE_UNLABELED);
|
||||
rand_weight_vec(&weights, &graph);
|
||||
BENCH(" 9 PageRank weighted, GNM(10000,20000), PRPACK, 100x",
|
||||
REPEAT(igraph_pagerank(&graph, &weights, &res, NULL, 0.85, IGRAPH_DIRECTED, igraph_vss_all(),
|
||||
IGRAPH_PAGERANK_ALGO_PRPACK, NULL), 100)
|
||||
);
|
||||
BENCH("10 PageRank weighted, GNM(10000,20000), ARPACK, 100x",
|
||||
REPEAT(igraph_pagerank(&graph, &weights, &res, NULL, 0.85, IGRAPH_DIRECTED, igraph_vss_all(),
|
||||
IGRAPH_PAGERANK_ALGO_ARPACK, &arpack_opts), 100)
|
||||
);
|
||||
igraph_destroy(&graph);
|
||||
|
||||
igraph_erdos_renyi_game_gnm(&graph, 100000, 100000, IGRAPH_DIRECTED, IGRAPH_LOOPS_SW, IGRAPH_EDGE_UNLABELED);
|
||||
rand_weight_vec(&weights, &graph);
|
||||
BENCH("11 PageRank weighted, GNM(100000,100000), PRPACK, 10x",
|
||||
REPEAT(igraph_pagerank(&graph, &weights, &res, NULL, 0.85, IGRAPH_DIRECTED, igraph_vss_all(),
|
||||
IGRAPH_PAGERANK_ALGO_PRPACK, NULL), 10)
|
||||
);
|
||||
BENCH("12 PageRank weighted, GNM(100000,100000), ARPACK, 10x",
|
||||
REPEAT(igraph_pagerank(&graph, &weights, &res, NULL, 0.85, IGRAPH_DIRECTED, igraph_vss_all(),
|
||||
IGRAPH_PAGERANK_ALGO_ARPACK, &arpack_opts), 10)
|
||||
);
|
||||
igraph_destroy(&graph);
|
||||
|
||||
igraph_erdos_renyi_game_gnm(&graph, 100000, 500000, IGRAPH_DIRECTED, IGRAPH_LOOPS_SW, IGRAPH_EDGE_UNLABELED);
|
||||
rand_weight_vec(&weights, &graph);
|
||||
BENCH("13 PageRank weighted, GNM(100000,500000), PRPACK, 10x",
|
||||
REPEAT(igraph_pagerank(&graph, &weights, &res, NULL, 0.85, IGRAPH_DIRECTED, igraph_vss_all(),
|
||||
IGRAPH_PAGERANK_ALGO_PRPACK, NULL), 10)
|
||||
);
|
||||
BENCH("14 PageRank weighted, GNM(100000,500000), ARPACK, 10x",
|
||||
REPEAT(igraph_pagerank(&graph, &weights, &res, NULL, 0.85, IGRAPH_DIRECTED, igraph_vss_all(),
|
||||
IGRAPH_PAGERANK_ALGO_ARPACK, &arpack_opts), 10)
|
||||
);
|
||||
igraph_destroy(&graph);
|
||||
|
||||
igraph_kautz(&graph, 6, 6);
|
||||
rand_weight_vec(&weights, &graph);
|
||||
BENCH("13 PageRank weighted, Kautz(6,6), PRPACK, 1x",
|
||||
REPEAT(igraph_pagerank(&graph, &weights, &res, NULL, 0.85, IGRAPH_DIRECTED, igraph_vss_all(),
|
||||
IGRAPH_PAGERANK_ALGO_PRPACK, NULL), 1)
|
||||
);
|
||||
BENCH("14 PageRank weighted, Kautz(6,6), ARPACK, 1x",
|
||||
REPEAT(igraph_pagerank(&graph, &weights, &res, NULL, 0.85, IGRAPH_DIRECTED, igraph_vss_all(),
|
||||
IGRAPH_PAGERANK_ALGO_ARPACK, &arpack_opts), 1)
|
||||
);
|
||||
igraph_destroy(&graph);
|
||||
|
||||
igraph_de_bruijn(&graph, 7, 7);
|
||||
rand_weight_vec(&weights, &graph);
|
||||
BENCH("13 PageRank weighted, DeBruijn(7,7), PRPACK, 1x",
|
||||
REPEAT(igraph_pagerank(&graph, &weights, &res, NULL, 0.85, IGRAPH_DIRECTED, igraph_vss_all(),
|
||||
IGRAPH_PAGERANK_ALGO_PRPACK, NULL), 1)
|
||||
);
|
||||
BENCH("14 PageRank weighted, DeBruijn(7,7), ARPACK, 1x",
|
||||
REPEAT(igraph_pagerank(&graph, &weights, &res, NULL, 0.85, IGRAPH_DIRECTED, igraph_vss_all(),
|
||||
IGRAPH_PAGERANK_ALGO_ARPACK, &arpack_opts), 1)
|
||||
);
|
||||
igraph_destroy(&graph);
|
||||
|
||||
igraph_vector_destroy(&weights);
|
||||
igraph_vector_destroy(&res);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,168 @@
|
||||
/*
|
||||
igraph library.
|
||||
Copyright (C) 2024 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 <plfit_sampling.h>
|
||||
|
||||
#include "bench.h"
|
||||
|
||||
igraph_vector_t data;
|
||||
|
||||
double rpareto(double xmin, double alpha) {
|
||||
/* 1-u is used in the base here because we want to avoid the case of
|
||||
* sampling zero */
|
||||
return pow(1 - RNG_UNIF01(), -1.0 / alpha) * xmin;
|
||||
}
|
||||
|
||||
double rzeta(igraph_int_t xmin, double alpha) {
|
||||
double u, v, t;
|
||||
igraph_int_t x;
|
||||
double alpha_minus_1 = alpha-1;
|
||||
double minus_1_over_alpha_minus_1 = -1.0 / (alpha-1);
|
||||
double b;
|
||||
double one_over_b_minus_1;
|
||||
|
||||
xmin = (igraph_int_t) round(xmin);
|
||||
|
||||
/* Rejection sampling for the win. We use Y=floor(U^{-1/alpha} * xmin) as the
|
||||
* envelope distribution, similarly to Chapter X.6 of Luc Devroye's book
|
||||
* (where xmin is assumed to be 1): http://luc.devroye.org/chapter_ten.pdf
|
||||
*
|
||||
* Some notes that should help me recover what I was doing:
|
||||
*
|
||||
* p_i = 1/zeta(alpha, xmin) * i^-alpha
|
||||
* q_i = (xmin/i)^{alpha-1} - (xmin/(i+1))^{alpha-1}
|
||||
* = (i/xmin)^{1-alpha} - ((i+1)/xmin)^{1-alpha}
|
||||
* = [i^{1-alpha} - (i+1)^{1-alpha}] / xmin^{1-alpha}
|
||||
*
|
||||
* p_i / q_i attains its maximum at xmin=i, so the rejection constant is:
|
||||
*
|
||||
* c = p_xmin / q_xmin
|
||||
*
|
||||
* We have to accept the sample if V <= (p_i / q_i) * (q_xmin / p_xmin) =
|
||||
* (i/xmin)^-alpha * [xmin^{1-alpha} - (xmin+1)^{1-alpha}] / [i^{1-alpha} - (i+1)^{1-alpha}] =
|
||||
* [xmin - xmin^alpha / (xmin+1)^{alpha-1}] / [i - i^alpha / (i+1)^{alpha-1}] =
|
||||
* xmin/i * [1-(xmin/(xmin+1))^{alpha-1}]/[1-(i/(i+1))^{alpha-1}]
|
||||
*
|
||||
* In other words (and substituting i with X, which is the same),
|
||||
*
|
||||
* V * (X/xmin) <= [1 - (1+1/xmin)^{1-alpha}] / [1 - (1+1/i)^{1-alpha}]
|
||||
*
|
||||
* Let b := (1+1/xmin)^{alpha-1} and let T := (1+1/i)^{alpha-1}. Then:
|
||||
*
|
||||
* V * (X/xmin) <= [(b-1)/b] / [(T-1)/T]
|
||||
* V * (X/xmin) * (T-1) / (b-1) <= T / b
|
||||
*
|
||||
* which is the same as in Devroye's book, except for the X/xmin term, and
|
||||
* the definition of b.
|
||||
*/
|
||||
b = pow(1 + 1.0/xmin, alpha_minus_1);
|
||||
one_over_b_minus_1 = 1.0/(b-1);
|
||||
do {
|
||||
do {
|
||||
u = RNG_UNIF01();
|
||||
v = RNG_UNIF01();
|
||||
/* 1-u is used in the base here because we want to avoid the case of
|
||||
* having zero in x */
|
||||
x = (igraph_int_t) floor(pow(1-u, minus_1_over_alpha_minus_1) * xmin);
|
||||
} while (x < xmin);
|
||||
t = pow((x+1.0)/x, alpha_minus_1);
|
||||
} while (v*x*(t-1)*one_over_b_minus_1*b > t*xmin);
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
int generate_continuous(double xmin, double alpha, size_t num_samples) {
|
||||
IGRAPH_CHECK(igraph_vector_resize(&data, num_samples));
|
||||
|
||||
for (size_t i = 0; i < num_samples; i++) {
|
||||
VECTOR(data)[i] = rpareto(xmin, alpha);
|
||||
}
|
||||
|
||||
return IGRAPH_SUCCESS;
|
||||
}
|
||||
|
||||
int generate_discrete(double xmin, double alpha, size_t num_samples) {
|
||||
IGRAPH_CHECK(igraph_vector_resize(&data, num_samples));
|
||||
|
||||
for (size_t i = 0; i < num_samples; i++) {
|
||||
VECTOR(data)[i] = rzeta(xmin, alpha);
|
||||
}
|
||||
|
||||
return IGRAPH_SUCCESS;
|
||||
}
|
||||
|
||||
int fit_continuous(double known_xmin) {
|
||||
igraph_plfit_result_t result;
|
||||
IGRAPH_CHECK(igraph_power_law_fit(&data, &result, known_xmin, /* force_continuous = */ 1));
|
||||
return IGRAPH_SUCCESS;
|
||||
}
|
||||
|
||||
int fit_discrete(double known_xmin) {
|
||||
igraph_plfit_result_t result;
|
||||
IGRAPH_CHECK(igraph_power_law_fit(&data, &result, known_xmin, 0));
|
||||
return IGRAPH_SUCCESS;
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
igraph_rng_seed(igraph_rng_default(), 42);
|
||||
|
||||
igraph_vector_init(&data, 0);
|
||||
|
||||
BENCH_INIT();
|
||||
|
||||
generate_continuous(1, 3, 100000);
|
||||
BENCH(" 1 Continuous, xmin = 1, alpha = 3, samples = 100K, fitting alpha only", fit_continuous(1));
|
||||
|
||||
generate_continuous(1, 3, 200000);
|
||||
BENCH(" 2 Continuous, xmin = 1, alpha = 3, samples = 200K, fitting alpha only", fit_continuous(1));
|
||||
|
||||
generate_continuous(1, 3, 500000);
|
||||
BENCH(" 3 Continuous, xmin = 1, alpha = 3, samples = 500K, fitting alpha only", fit_continuous(1));
|
||||
|
||||
generate_continuous(1, 3, 5000);
|
||||
BENCH(" 4 Continuous, xmin = 1, alpha = 3, samples = 5K, fitting xmin and alpha", fit_continuous(-1));
|
||||
|
||||
generate_continuous(1, 3, 10000);
|
||||
BENCH(" 5 Continuous, xmin = 1, alpha = 3, samples = 10K, fitting xmin and alpha", fit_continuous(-1));
|
||||
|
||||
generate_continuous(1, 3, 15000);
|
||||
BENCH(" 6 Continuous, xmin = 1, alpha = 3, samples = 15K, fitting xmin and alpha", fit_continuous(-1));
|
||||
|
||||
generate_discrete(3, 3, 1000000);
|
||||
BENCH(" 7 Discrete, xmin = 3, alpha = 3, samples = 1M, fitting alpha only", fit_discrete(3));
|
||||
|
||||
generate_discrete(3, 3, 5000000);
|
||||
BENCH(" 8 Discrete, xmin = 3, alpha = 3, samples = 5M, fitting alpha only", fit_discrete(3));
|
||||
|
||||
generate_discrete(3, 3, 10000000);
|
||||
BENCH(" 9 Discrete, xmin = 3, alpha = 3, samples = 10M, fitting alpha only", fit_discrete(3));
|
||||
|
||||
generate_discrete(3, 3, 1000000);
|
||||
BENCH("10 Discrete, xmin = 3, alpha = 3, samples = 1M, fitting xmin and alpha", fit_discrete(-1));
|
||||
|
||||
generate_discrete(3, 3, 5000000);
|
||||
BENCH("11 Discrete, xmin = 3, alpha = 3, samples = 5M, fitting xmin and alpha", fit_discrete(-1));
|
||||
|
||||
generate_discrete(3, 3, 10000000);
|
||||
BENCH("12 Discrete, xmin = 3, alpha = 3, samples = 10M, fitting xmin and alpha", fit_discrete(-1));
|
||||
|
||||
igraph_vector_destroy(&data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
igraph library.
|
||||
Copyright (C) 2024 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 "bench.h"
|
||||
|
||||
/* This program benchmarks igraph_qsort() indirectly through vector_sort() */
|
||||
|
||||
int main(void) {
|
||||
igraph_vector_int_t vec;
|
||||
|
||||
igraph_rng_seed(igraph_rng_default(), 137);
|
||||
BENCH_INIT();
|
||||
|
||||
|
||||
igraph_vector_int_init(&vec, 0);
|
||||
|
||||
#define N 10000000
|
||||
|
||||
igraph_vector_int_resize(&vec, N);
|
||||
for (igraph_int_t i=0; i < N; i++) {
|
||||
VECTOR(vec)[i] = RNG_INTEGER(0, N-1);
|
||||
}
|
||||
BENCH("Sort vector of length " IGRAPH_I_STRINGIFY(N), igraph_vector_int_sort(&vec));
|
||||
|
||||
#undef N
|
||||
#define N 1000000
|
||||
|
||||
igraph_vector_int_resize(&vec, N);
|
||||
for (igraph_int_t i=0; i < N; i++) {
|
||||
VECTOR(vec)[i] = RNG_INTEGER(0, N-1);
|
||||
}
|
||||
BENCH("Sort vector of length " IGRAPH_I_STRINGIFY(N), igraph_vector_int_sort(&vec));
|
||||
|
||||
#undef N
|
||||
#define N 100000
|
||||
|
||||
igraph_vector_int_resize(&vec, N);
|
||||
for (igraph_int_t i=0; i < N; i++) {
|
||||
VECTOR(vec)[i] = RNG_INTEGER(0, N-1);
|
||||
}
|
||||
BENCH("Sort vector of length " IGRAPH_I_STRINGIFY(N), igraph_vector_int_sort(&vec));
|
||||
|
||||
igraph_vector_int_destroy(&vec);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,201 @@
|
||||
/*
|
||||
igraph library.
|
||||
Copyright (C) 2024 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 "bench.h"
|
||||
|
||||
int main(void) {
|
||||
igraph_t graph;
|
||||
igraph_vector_int_t vertices;
|
||||
igraph_vector_int_t edges;
|
||||
igraph_vector_t weights;
|
||||
igraph_int_t ec, i;
|
||||
|
||||
igraph_rng_seed(igraph_rng_default(), 137);
|
||||
BENCH_INIT();
|
||||
|
||||
igraph_vector_int_init(&vertices, 0);
|
||||
igraph_vector_int_init(&edges, 0);
|
||||
igraph_vector_init(&weights, 0);
|
||||
|
||||
/* create a small graph, and a compatible weight vector */
|
||||
igraph_de_bruijn(&graph, 3, 2); /* 9 vertices, 27 edges, average degree: 6 */
|
||||
ec = igraph_ecount(&graph);
|
||||
|
||||
igraph_vector_resize(&weights, ec);
|
||||
for (i = 0; i < ec; ++i) {
|
||||
VECTOR(weights)[i] = igraph_rng_get_unif01(igraph_rng_default());
|
||||
}
|
||||
|
||||
/* Only edges */
|
||||
|
||||
BENCH(" 1 Random edge walk, directed, unweighted, small graph ",
|
||||
igraph_random_walk(&graph, NULL, NULL, &edges, 0, IGRAPH_OUT, 50000000, IGRAPH_RANDOM_WALK_STUCK_RETURN)
|
||||
);
|
||||
|
||||
BENCH(" 2 Random edge walk, directed, weighted, small graph ",
|
||||
igraph_random_walk(&graph, &weights, NULL, &edges, 0, IGRAPH_OUT, 50000000, IGRAPH_RANDOM_WALK_STUCK_RETURN)
|
||||
);
|
||||
|
||||
BENCH(" 3 Random edge walk, undirected, unweighted, small graph ",
|
||||
igraph_random_walk(&graph, NULL, NULL, &edges, 0, IGRAPH_ALL, 50000000, IGRAPH_RANDOM_WALK_STUCK_RETURN)
|
||||
);
|
||||
|
||||
BENCH(" 4 Random edge walk, undirected, weighted, small graph ",
|
||||
igraph_random_walk(&graph, &weights, NULL, &edges, 0, IGRAPH_ALL, 50000000, IGRAPH_RANDOM_WALK_STUCK_RETURN)
|
||||
);
|
||||
|
||||
/* Only vertices */
|
||||
|
||||
BENCH(" 5 Random vertex walk, directed, unweighted, small graph ",
|
||||
igraph_random_walk(&graph, NULL, &vertices, NULL, 0, IGRAPH_OUT, 50000000, IGRAPH_RANDOM_WALK_STUCK_RETURN)
|
||||
);
|
||||
|
||||
BENCH(" 6 Random vertex walk, directed, weighted, small graph ",
|
||||
igraph_random_walk(&graph, &weights, &vertices, NULL, 0, IGRAPH_OUT, 50000000, IGRAPH_RANDOM_WALK_STUCK_RETURN)
|
||||
);
|
||||
|
||||
BENCH(" 7 Random vertex walk, undirected, unweighted, small graph ",
|
||||
igraph_random_walk(&graph, NULL, &vertices, NULL, 0, IGRAPH_ALL, 50000000, IGRAPH_RANDOM_WALK_STUCK_RETURN)
|
||||
);
|
||||
|
||||
BENCH(" 8 Random vertex walk, undirected, weighted, small graph ",
|
||||
igraph_random_walk(&graph, &weights, &vertices, NULL, 0, IGRAPH_ALL, 50000000, IGRAPH_RANDOM_WALK_STUCK_RETURN)
|
||||
);
|
||||
|
||||
/* Both edges and vertices */
|
||||
|
||||
BENCH(" 9 Random walk, directed, unweighted, small graph ",
|
||||
igraph_random_walk(&graph, NULL, &vertices, &edges, 0, IGRAPH_OUT, 50000000, IGRAPH_RANDOM_WALK_STUCK_RETURN)
|
||||
);
|
||||
|
||||
BENCH(" 10 Random walk, directed, weighted, small graph ",
|
||||
igraph_random_walk(&graph, &weights, &vertices, &edges, 0, IGRAPH_OUT, 50000000, IGRAPH_RANDOM_WALK_STUCK_RETURN)
|
||||
);
|
||||
|
||||
igraph_destroy(&graph);
|
||||
|
||||
/* create a big graph, and a compatible weight vector */
|
||||
igraph_de_bruijn(&graph, 8, 5); /* 32768 vertices, 262144 edges, average degree: 16 */
|
||||
ec = igraph_ecount(&graph);
|
||||
|
||||
igraph_vector_resize(&weights, ec);
|
||||
for (i = 0; i < ec; ++i) {
|
||||
VECTOR(weights)[i] = igraph_rng_get_unif01(igraph_rng_default());
|
||||
}
|
||||
|
||||
/* Only edges */
|
||||
|
||||
BENCH(" 11 Random edge walk, directed, unweighted, large graph ",
|
||||
igraph_random_walk(&graph, NULL, NULL, &edges, 0, IGRAPH_OUT, 50000000, IGRAPH_RANDOM_WALK_STUCK_RETURN)
|
||||
);
|
||||
|
||||
BENCH(" 12 Random edge walk, directed, weighted, large graph ",
|
||||
igraph_random_walk(&graph, &weights, NULL, &edges, 0, IGRAPH_OUT, 50000000, IGRAPH_RANDOM_WALK_STUCK_RETURN)
|
||||
);
|
||||
|
||||
BENCH(" 13 Random edge walk, undirected, unweighted, large graph ",
|
||||
igraph_random_walk(&graph, NULL, NULL, &edges, 0, IGRAPH_ALL, 50000000, IGRAPH_RANDOM_WALK_STUCK_RETURN)
|
||||
);
|
||||
|
||||
BENCH(" 14 Random edge walk, undirected, weighted, large graph ",
|
||||
igraph_random_walk(&graph, &weights, NULL, &edges, 0, IGRAPH_ALL, 50000000, IGRAPH_RANDOM_WALK_STUCK_RETURN)
|
||||
);
|
||||
|
||||
/* Only vertices */
|
||||
|
||||
BENCH(" 15 Random vertex walk, directed, unweighted, large graph ",
|
||||
igraph_random_walk(&graph, NULL, &vertices, NULL, 0, IGRAPH_OUT, 50000000, IGRAPH_RANDOM_WALK_STUCK_RETURN)
|
||||
);
|
||||
|
||||
BENCH(" 16 Random vertex walk, directed, weighted, large graph ",
|
||||
igraph_random_walk(&graph, &weights, &vertices, NULL, 0, IGRAPH_OUT, 50000000, IGRAPH_RANDOM_WALK_STUCK_RETURN)
|
||||
);
|
||||
|
||||
BENCH(" 17 Random vertex walk, undirected, unweighted, large graph ",
|
||||
igraph_random_walk(&graph, NULL, &vertices, NULL, 0, IGRAPH_ALL, 50000000, IGRAPH_RANDOM_WALK_STUCK_RETURN)
|
||||
);
|
||||
|
||||
BENCH(" 18 Random vertex walk, undirected, weighted, large graph ",
|
||||
igraph_random_walk(&graph, &weights, &vertices, NULL, 0, IGRAPH_ALL, 50000000, IGRAPH_RANDOM_WALK_STUCK_RETURN)
|
||||
);
|
||||
|
||||
/* Both edges and vertices */
|
||||
|
||||
BENCH(" 19 Random walk, directed, unweighted, large graph ",
|
||||
igraph_random_walk(&graph, NULL, &vertices, &edges, 0, IGRAPH_OUT, 50000000, IGRAPH_RANDOM_WALK_STUCK_RETURN)
|
||||
);
|
||||
|
||||
BENCH(" 20 Random walk, directed, weighted, large graph ",
|
||||
igraph_random_walk(&graph, &weights, &vertices, &edges, 0, IGRAPH_OUT, 50000000, IGRAPH_RANDOM_WALK_STUCK_RETURN)
|
||||
);
|
||||
|
||||
/* Only edges */
|
||||
|
||||
BENCH(" 21 Short edge walk, directed, unweighted, large graph, x 100",
|
||||
REPEAT(igraph_random_walk(&graph, NULL, NULL, &edges, 0, IGRAPH_OUT, 10000, IGRAPH_RANDOM_WALK_STUCK_RETURN), 100)
|
||||
);
|
||||
|
||||
BENCH(" 22 Short edge walk, directed, weighted, large graph, x 100",
|
||||
REPEAT(igraph_random_walk(&graph, &weights, NULL, &edges, 0, IGRAPH_OUT, 10000, IGRAPH_RANDOM_WALK_STUCK_RETURN), 100)
|
||||
);
|
||||
|
||||
BENCH(" 23 Short edge walk, undirected, unweighted, large graph, x 100",
|
||||
REPEAT(igraph_random_walk(&graph, NULL, NULL, &edges, 0, IGRAPH_ALL, 10000, IGRAPH_RANDOM_WALK_STUCK_RETURN), 100)
|
||||
);
|
||||
|
||||
BENCH(" 24 Short edge walk, undirected, weighted, large graph, x 100",
|
||||
REPEAT(igraph_random_walk(&graph, &weights, NULL, &edges, 0, IGRAPH_ALL, 10000, IGRAPH_RANDOM_WALK_STUCK_RETURN), 100)
|
||||
);
|
||||
|
||||
/* Only vertices */
|
||||
|
||||
BENCH(" 25 Short vertex walk, directed, unweighted, large graph, x 100",
|
||||
REPEAT(igraph_random_walk(&graph, NULL, &vertices, NULL, 0, IGRAPH_OUT, 10000, IGRAPH_RANDOM_WALK_STUCK_RETURN), 100)
|
||||
);
|
||||
|
||||
BENCH(" 26 Short vertex walk, directed, weighted, large graph, x 100",
|
||||
REPEAT(igraph_random_walk(&graph, &weights, &vertices, NULL, 0, IGRAPH_OUT, 10000, IGRAPH_RANDOM_WALK_STUCK_RETURN), 100)
|
||||
);
|
||||
|
||||
BENCH(" 27 Short vertex walk, undirected, unweighted, large graph, x 100",
|
||||
REPEAT(igraph_random_walk(&graph, NULL, &vertices, NULL, 0, IGRAPH_ALL, 10000, IGRAPH_RANDOM_WALK_STUCK_RETURN), 100)
|
||||
);
|
||||
|
||||
BENCH(" 28 Short vertex walk, undirected, weighted, large graph, x 100",
|
||||
REPEAT(igraph_random_walk(&graph, &weights, &vertices, NULL, 0, IGRAPH_ALL, 10000, IGRAPH_RANDOM_WALK_STUCK_RETURN), 100)
|
||||
);
|
||||
|
||||
/* Both edges and vertices */
|
||||
|
||||
BENCH(" 29 Short random walk, directed, unweighted, large graph, x 100",
|
||||
REPEAT(igraph_random_walk(&graph, NULL, &vertices, &edges, 0, IGRAPH_OUT, 10000, IGRAPH_RANDOM_WALK_STUCK_RETURN), 100)
|
||||
);
|
||||
|
||||
BENCH(" 30 Short random walk, directed, weighted, large graph, x 100",
|
||||
REPEAT(igraph_random_walk(&graph, &weights, &vertices, &edges, 0, IGRAPH_OUT, 10000, IGRAPH_RANDOM_WALK_STUCK_RETURN), 100)
|
||||
);
|
||||
|
||||
igraph_destroy(&graph);
|
||||
|
||||
igraph_vector_destroy(&weights);
|
||||
igraph_vector_int_destroy(&vertices);
|
||||
igraph_vector_int_destroy(&edges);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
igraph library.
|
||||
Copyright (C) 2025 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 "bench.h"
|
||||
|
||||
#define TOSTR1(x) #x
|
||||
#define TOSTR(x) TOSTR1(x)
|
||||
|
||||
void bench(const igraph_t *graph, const char *what, int rep) {
|
||||
const igraph_int_t vcount = igraph_vcount(graph);
|
||||
const igraph_int_t ecount = igraph_ecount(graph);
|
||||
igraph_vector_int_t degrees;
|
||||
igraph_t new_graph;
|
||||
|
||||
igraph_vector_int_init(°rees, 0);
|
||||
igraph_degree(graph, °rees, igraph_vss_all(), IGRAPH_ALL, IGRAPH_LOOPS);
|
||||
|
||||
char name[200];
|
||||
sprintf(name, "%s, n=%5" IGRAPH_PRId ", m=%5" IGRAPH_PRId ", LARGEST, %dx", what, vcount, ecount, rep);
|
||||
BENCH(name, REPEAT(igraph_realize_degree_sequence(&new_graph, °rees, NULL, IGRAPH_SIMPLE_SW, IGRAPH_REALIZE_DEGSEQ_LARGEST), rep));
|
||||
igraph_destroy(&new_graph);
|
||||
|
||||
sprintf(name, "%s, n=%5" IGRAPH_PRId ", m=%5" IGRAPH_PRId ", SMALLEST, %dx", what, vcount, ecount, rep);
|
||||
BENCH(name, REPEAT(igraph_realize_degree_sequence(&new_graph, °rees, NULL, IGRAPH_SIMPLE_SW, IGRAPH_REALIZE_DEGSEQ_SMALLEST), rep));
|
||||
igraph_destroy(&new_graph);
|
||||
|
||||
sprintf(name, "%s, n=%5" IGRAPH_PRId ", m=%5" IGRAPH_PRId ", INDEX, %dx", what, vcount, ecount, rep);
|
||||
BENCH(name, REPEAT(igraph_realize_degree_sequence(&new_graph, °rees, NULL, IGRAPH_SIMPLE_SW, IGRAPH_REALIZE_DEGSEQ_INDEX), rep));
|
||||
igraph_destroy(&new_graph);
|
||||
|
||||
printf("\n");
|
||||
|
||||
igraph_vector_int_destroy(°rees);
|
||||
}
|
||||
|
||||
void bench_gnm(igraph_int_t n, igraph_int_t m, int rep) {
|
||||
igraph_t graph;
|
||||
igraph_erdos_renyi_game_gnm(&graph, n, m, IGRAPH_UNDIRECTED, IGRAPH_SIMPLE_SW, IGRAPH_EDGE_UNLABELED);
|
||||
bench(&graph, "G(n,m)", rep);
|
||||
igraph_destroy(&graph);
|
||||
}
|
||||
|
||||
void bench_ba(igraph_int_t n, igraph_int_t m, int rep) {
|
||||
igraph_t graph;
|
||||
igraph_barabasi_game(&graph, n, 1, m, NULL, true, 0, IGRAPH_UNDIRECTED, IGRAPH_BARABASI_PSUMTREE, NULL);
|
||||
bench(&graph, "BA", rep);
|
||||
igraph_destroy(&graph);
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
|
||||
igraph_rng_seed(igraph_rng_default(), 789);
|
||||
BENCH_INIT();
|
||||
|
||||
bench_gnm(100, 200, 10000);
|
||||
bench_gnm(100, 1000, 10000);
|
||||
|
||||
bench_gnm(10000, 20000, 1);
|
||||
bench_gnm(10000, 100000, 1);
|
||||
|
||||
bench_ba(100, 1, 10000);
|
||||
bench_ba(100, 10, 10000);
|
||||
|
||||
bench_ba(10000, 1, 1);
|
||||
bench_ba(10000, 10, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
igraph library.
|
||||
Copyright (C) 2025 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 "bench.h"
|
||||
|
||||
void bench(const char *name, igraph_t *graph, int rep) {
|
||||
igraph_int_t vcount = igraph_vcount(graph);
|
||||
igraph_int_t ecount = igraph_ecount(graph);
|
||||
igraph_int_t trials = 10*ecount;
|
||||
char msg[200];
|
||||
|
||||
snprintf(msg, sizeof(msg) / sizeof(msg[0]),
|
||||
"%s, |V|=%6" IGRAPH_PRId ", |E|=%6" IGRAPH_PRId ", %6" IGRAPH_PRId " swaps, %dx",
|
||||
name, vcount, ecount, trials, rep);
|
||||
|
||||
BENCH(msg, REPEAT(igraph_rewire(graph, trials, IGRAPH_SIMPLE_SW, NULL), rep));
|
||||
}
|
||||
|
||||
void bench_er(igraph_int_t n, igraph_int_t m, int rep) {
|
||||
igraph_t graph;
|
||||
|
||||
igraph_erdos_renyi_game_gnm(&graph, n, m, IGRAPH_UNDIRECTED, IGRAPH_SIMPLE_SW, IGRAPH_EDGE_UNLABELED);
|
||||
|
||||
bench("G(n,m)", &graph, rep);
|
||||
|
||||
igraph_destroy(&graph);
|
||||
}
|
||||
|
||||
void bench_ba(igraph_int_t n, igraph_int_t m, int rep) {
|
||||
igraph_t graph;
|
||||
|
||||
igraph_barabasi_game(&graph, n, 1, m ,NULL, true, 1, IGRAPH_UNDIRECTED, IGRAPH_BARABASI_BAG, NULL);
|
||||
|
||||
bench("BA", &graph, rep);
|
||||
|
||||
igraph_destroy(&graph);
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
igraph_rng_seed(igraph_rng_default(), 137);
|
||||
BENCH_INIT();
|
||||
|
||||
bench_er(100, 3000, 100);
|
||||
bench_er(300, 3000, 100);
|
||||
bench_er(1000, 3000, 100);
|
||||
bench_er(3000, 3000, 100);
|
||||
bench_er(10000, 3000, 100);
|
||||
|
||||
printf("\n");
|
||||
bench_er(300, 30000, 10);
|
||||
bench_er(1000, 30000, 10);
|
||||
bench_er(3000, 30000, 10);
|
||||
bench_er(10000, 30000, 10);
|
||||
|
||||
printf("\n");
|
||||
bench_ba(1000, 3, 100);
|
||||
bench_ba(10000, 3, 10);
|
||||
bench_ba(100000, 3, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,145 @@
|
||||
/*
|
||||
igraph library.
|
||||
Copyright (C) 2024 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 "bench.h"
|
||||
|
||||
#define TOSTR1(x) #x
|
||||
#define TOSTR(x) TOSTR1(x)
|
||||
|
||||
void rand_weight_vec(igraph_vector_t *vec, const igraph_t *graph) {
|
||||
igraph_int_t i, n = igraph_ecount(graph);
|
||||
igraph_vector_resize(vec, n);
|
||||
for (i=0; i < n; ++i) {
|
||||
VECTOR(*vec)[i] = RNG_UNIF(1, 10);
|
||||
}
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
|
||||
igraph_t g;
|
||||
igraph_vector_t strength, weights;
|
||||
|
||||
igraph_rng_seed(igraph_rng_default(), 54);
|
||||
BENCH_INIT();
|
||||
|
||||
igraph_vector_init(&strength, 0);
|
||||
igraph_vector_init(&weights, 0);
|
||||
|
||||
/* igraph_strength() uses an optimized, cache friendly code path when given
|
||||
* a vertex selector for which igraph_vs_is_all() returns true (this is
|
||||
* currently igraph_vs_all()). We pass both igraph_vss_all() and
|
||||
* igraph_vss_range(0, igraph_vcount(graph)) as vertex selectors
|
||||
* to compare the performance of the two code paths.
|
||||
*
|
||||
* NOTE: While currently igraph_vs_is_all() does not return true for
|
||||
* a range-type vertex selector, this may change in the future.
|
||||
* An altrenative is to to use igraph_vs_vector(), with the vector
|
||||
* initialized to a range.
|
||||
*/
|
||||
|
||||
#define N 1000
|
||||
#define M 10
|
||||
#define REP 10000
|
||||
|
||||
igraph_barabasi_game(&g, N, 1, M, NULL, true, 0, IGRAPH_UNDIRECTED, IGRAPH_BARABASI_PSUMTREE_MULTIPLE, NULL);
|
||||
rand_weight_vec(&weights, &g);
|
||||
|
||||
BENCH(" 1a igraph_strength(), preferential attachment n=" TOSTR(N) ", m=" TOSTR(M) ", " TOSTR(REP) "x",
|
||||
REPEAT(igraph_strength(&g, &strength, igraph_vss_all(), IGRAPH_ALL, IGRAPH_LOOPS, &weights), REP)
|
||||
);
|
||||
BENCH(" 1b igraph_strength(), preferential attachment n=" TOSTR(N) ", m=" TOSTR(M) ", " TOSTR(REP) "x",
|
||||
REPEAT(igraph_strength(&g, &strength, igraph_vss_range(0, igraph_vcount(&g)), IGRAPH_ALL, IGRAPH_LOOPS, &weights), REP)
|
||||
);
|
||||
printf("\n");
|
||||
|
||||
igraph_destroy(&g);
|
||||
|
||||
#undef N
|
||||
#undef M
|
||||
#undef REP
|
||||
|
||||
#define N 10000
|
||||
#define M 10
|
||||
#define REP 1000
|
||||
|
||||
igraph_barabasi_game(&g, N, 1, M, NULL, true, 0, IGRAPH_UNDIRECTED, IGRAPH_BARABASI_PSUMTREE_MULTIPLE, NULL);
|
||||
rand_weight_vec(&weights, &g);
|
||||
|
||||
BENCH(" 2a igraph_strength(), preferential attachment n=" TOSTR(N) ", m=" TOSTR(M) ", " TOSTR(REP) "x",
|
||||
REPEAT(igraph_strength(&g, &strength, igraph_vss_all(), IGRAPH_ALL, IGRAPH_LOOPS, &weights), REP)
|
||||
);
|
||||
BENCH(" 2b igraph_strength(), preferential attachment n=" TOSTR(N) ", m=" TOSTR(M) ", " TOSTR(REP) "x",
|
||||
REPEAT(igraph_strength(&g, &strength, igraph_vss_range(0, igraph_vcount(&g)), IGRAPH_ALL, IGRAPH_LOOPS, &weights), REP)
|
||||
);
|
||||
printf("\n");
|
||||
|
||||
igraph_destroy(&g);
|
||||
|
||||
#undef N
|
||||
#undef M
|
||||
#undef REP
|
||||
|
||||
#define N 100000
|
||||
#define M 10
|
||||
#define REP 100
|
||||
|
||||
igraph_barabasi_game(&g, N, 1, M, NULL, true, 0, IGRAPH_UNDIRECTED, IGRAPH_BARABASI_PSUMTREE_MULTIPLE, NULL);
|
||||
rand_weight_vec(&weights, &g);
|
||||
|
||||
BENCH(" 3a igraph_strength(), preferential attachment n=" TOSTR(N) ", m=" TOSTR(M) ", " TOSTR(REP) "x",
|
||||
REPEAT(igraph_strength(&g, &strength, igraph_vss_all(), IGRAPH_ALL, IGRAPH_LOOPS, &weights), REP)
|
||||
);
|
||||
BENCH(" 3b igraph_strength(), preferential attachment n=" TOSTR(N) ", m=" TOSTR(M) ", " TOSTR(REP) "x",
|
||||
REPEAT(igraph_strength(&g, &strength, igraph_vss_range(0, igraph_vcount(&g)), IGRAPH_ALL, IGRAPH_LOOPS, &weights), REP)
|
||||
);
|
||||
printf("\n");
|
||||
|
||||
igraph_destroy(&g);
|
||||
|
||||
#undef N
|
||||
#undef M
|
||||
#undef REP
|
||||
|
||||
#define N 100000
|
||||
#define M 100
|
||||
#define REP 10
|
||||
|
||||
igraph_barabasi_game(&g, N, 1, M, NULL, true, 0, IGRAPH_UNDIRECTED, IGRAPH_BARABASI_PSUMTREE_MULTIPLE, NULL);
|
||||
rand_weight_vec(&weights, &g);
|
||||
|
||||
BENCH(" 4a igraph_strength(), preferential attachment n=" TOSTR(N) ", m=" TOSTR(M) ", " TOSTR(REP) "x",
|
||||
REPEAT(igraph_strength(&g, &strength, igraph_vss_all(), IGRAPH_ALL, IGRAPH_LOOPS, &weights), REP)
|
||||
);
|
||||
BENCH(" 4b igraph_strength(), preferential attachment n=" TOSTR(N) ", m=" TOSTR(M) ", " TOSTR(REP) "x",
|
||||
REPEAT(igraph_strength(&g, &strength, igraph_vss_range(0, igraph_vcount(&g)), IGRAPH_ALL, IGRAPH_LOOPS, &weights), REP)
|
||||
);
|
||||
printf("\n");
|
||||
|
||||
igraph_destroy(&g);
|
||||
|
||||
#undef N
|
||||
#undef M
|
||||
#undef REP
|
||||
|
||||
igraph_vector_destroy(&weights);
|
||||
igraph_vector_destroy(&strength);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,252 @@
|
||||
/*
|
||||
igraph library.
|
||||
Copyright (C) 2013-2024 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 "bench.h"
|
||||
|
||||
int main(void) {
|
||||
|
||||
igraph_t g;
|
||||
igraph_vector_t trans;
|
||||
igraph_vs_t all_vertices;
|
||||
igraph_real_t avg_trans, global_trans, tri_count;
|
||||
|
||||
igraph_rng_seed(igraph_rng_default(), 42);
|
||||
BENCH_INIT();
|
||||
|
||||
#define N 6000
|
||||
#define M 2000000
|
||||
|
||||
igraph_erdos_renyi_game_gnm(&g, N, M, IGRAPH_UNDIRECTED, IGRAPH_SIMPLE_SW, IGRAPH_EDGE_UNLABELED);
|
||||
igraph_vector_init(&trans, igraph_vcount(&g));
|
||||
igraph_vs_range(&all_vertices, 0, igraph_vcount(&g));
|
||||
|
||||
BENCH(" 1 Local transitivity, all vertices method, GNM",
|
||||
igraph_transitivity_local_undirected(&g, &trans, igraph_vss_all(),
|
||||
IGRAPH_TRANSITIVITY_NAN);
|
||||
);
|
||||
|
||||
BENCH(" 2 Local transitivity, subset method, GNM",
|
||||
igraph_transitivity_local_undirected(&g, &trans, all_vertices,
|
||||
IGRAPH_TRANSITIVITY_NAN);
|
||||
);
|
||||
|
||||
BENCH(" 3 Average local transitivity GNM",
|
||||
igraph_transitivity_avglocal_undirected(&g, &avg_trans, IGRAPH_TRANSITIVITY_NAN);
|
||||
);
|
||||
|
||||
BENCH(" 4 Global transitivity GNM",
|
||||
igraph_transitivity_undirected(&g, &global_trans, IGRAPH_TRANSITIVITY_NAN);
|
||||
);
|
||||
|
||||
BENCH(" 5 Count triangles per vertex, all vertices method, GNM",
|
||||
igraph_count_adjacent_triangles(&g, &trans, igraph_vss_all());
|
||||
);
|
||||
|
||||
BENCH(" 6 Count triangles per vertex, subset method, GNM",
|
||||
igraph_count_adjacent_triangles(&g, &trans, all_vertices);
|
||||
);
|
||||
|
||||
BENCH(" 7 Count all triangles, GNM",
|
||||
igraph_count_triangles(&g, &tri_count);
|
||||
);
|
||||
|
||||
igraph_vs_destroy(&all_vertices);
|
||||
igraph_destroy(&g);
|
||||
|
||||
printf("\n");
|
||||
|
||||
igraph_barabasi_game(&g, N, /*power=*/ 1, M / N, /*outseq=*/ 0,
|
||||
/*outpref=*/ 0, /*A=*/ 1, IGRAPH_UNDIRECTED,
|
||||
IGRAPH_BARABASI_PSUMTREE, /*start_from=*/ 0);
|
||||
igraph_vector_resize(&trans, igraph_vcount(&g));
|
||||
igraph_vs_range(&all_vertices, 0, igraph_vcount(&g));
|
||||
|
||||
BENCH(" 1 Local transitivity, all vertices method, Barabasi",
|
||||
igraph_transitivity_local_undirected(&g, &trans, igraph_vss_all(),
|
||||
IGRAPH_TRANSITIVITY_NAN);
|
||||
);
|
||||
|
||||
BENCH(" 2 Local transitivity, subset method, Barabasi",
|
||||
igraph_transitivity_local_undirected(&g, &trans, all_vertices,
|
||||
IGRAPH_TRANSITIVITY_NAN);
|
||||
);
|
||||
|
||||
BENCH(" 3 Average local transitivity, Barabasi",
|
||||
igraph_transitivity_avglocal_undirected(&g, &avg_trans, IGRAPH_TRANSITIVITY_NAN);
|
||||
);
|
||||
|
||||
BENCH(" 4 Global transitivity, Barabasi",
|
||||
igraph_transitivity_undirected(&g, &global_trans, IGRAPH_TRANSITIVITY_NAN);
|
||||
);
|
||||
|
||||
BENCH(" 5 Count triangles per vertex, all vertices method, Barabasi",
|
||||
igraph_count_adjacent_triangles(&g, &trans, igraph_vss_all());
|
||||
);
|
||||
|
||||
BENCH(" 6 Count triangles per vertex, subset method, Barabasi",
|
||||
igraph_count_adjacent_triangles(&g, &trans, all_vertices);
|
||||
);
|
||||
|
||||
BENCH(" 7 Count all triangles, Barabasi",
|
||||
igraph_count_triangles(&g, &tri_count);
|
||||
);
|
||||
|
||||
igraph_vs_destroy(&all_vertices);
|
||||
igraph_destroy(&g);
|
||||
|
||||
printf("\n");
|
||||
|
||||
#undef N
|
||||
#undef M
|
||||
|
||||
#define N 1000000
|
||||
#define M 10000000
|
||||
|
||||
igraph_erdos_renyi_game_gnm(&g, N, M, IGRAPH_UNDIRECTED, IGRAPH_SIMPLE_SW, IGRAPH_EDGE_UNLABELED);
|
||||
igraph_vector_init(&trans, igraph_vcount(&g));
|
||||
igraph_vs_range(&all_vertices, 0, igraph_vcount(&g));
|
||||
|
||||
BENCH(" 1 Local transitivity, all vertices method, large GNM",
|
||||
igraph_transitivity_local_undirected(&g, &trans, igraph_vss_all(),
|
||||
IGRAPH_TRANSITIVITY_NAN);
|
||||
);
|
||||
|
||||
BENCH(" 2 Local transitivity, subset method, large GNM",
|
||||
igraph_transitivity_local_undirected(&g, &trans, all_vertices,
|
||||
IGRAPH_TRANSITIVITY_NAN);
|
||||
);
|
||||
|
||||
BENCH(" 3 Average local transitivity, large GNM",
|
||||
igraph_transitivity_avglocal_undirected(&g, &avg_trans, IGRAPH_TRANSITIVITY_NAN);
|
||||
);
|
||||
|
||||
BENCH(" 4 Global transitivity, large GNM",
|
||||
igraph_transitivity_undirected(&g, &global_trans, IGRAPH_TRANSITIVITY_NAN);
|
||||
);
|
||||
|
||||
BENCH(" 5 Count triangles per vertex, all vertices method, large GNM",
|
||||
igraph_count_adjacent_triangles(&g, &trans, igraph_vss_all());
|
||||
);
|
||||
|
||||
BENCH(" 6 Count triangles per vertex, subset method, large GNM",
|
||||
igraph_count_adjacent_triangles(&g, &trans, all_vertices);
|
||||
);
|
||||
|
||||
BENCH(" 7 Count all triangles, large GNM",
|
||||
igraph_count_triangles(&g, &tri_count);
|
||||
);
|
||||
|
||||
igraph_vs_destroy(&all_vertices);
|
||||
igraph_destroy(&g);
|
||||
|
||||
printf("\n");
|
||||
|
||||
igraph_erdos_renyi_game_gnm(&g, 500, 2000, IGRAPH_UNDIRECTED, IGRAPH_SIMPLE_SW, IGRAPH_EDGE_UNLABELED);
|
||||
igraph_vector_resize(&trans, igraph_vcount(&g));
|
||||
igraph_vs_range(&all_vertices, 0, igraph_vcount(&g));
|
||||
|
||||
#define REPS 1000
|
||||
|
||||
BENCH(" 1 Local transitivity, all vertices method, small GNM",
|
||||
REPEAT(igraph_transitivity_local_undirected(&g, &trans, igraph_vss_all(),
|
||||
IGRAPH_TRANSITIVITY_NAN), REPS);
|
||||
);
|
||||
|
||||
BENCH(" 2 Local transitivity, subset method, small GNM",
|
||||
REPEAT(igraph_transitivity_local_undirected(&g, &trans, all_vertices,
|
||||
IGRAPH_TRANSITIVITY_NAN), REPS);
|
||||
);
|
||||
|
||||
BENCH(" 3 Average local transitivity, small GNM",
|
||||
REPEAT(igraph_transitivity_avglocal_undirected(&g, &avg_trans, IGRAPH_TRANSITIVITY_NAN),
|
||||
REPS);
|
||||
);
|
||||
|
||||
BENCH(" 4 Global transitivity, small GNM",
|
||||
REPEAT(igraph_transitivity_undirected(&g, &global_trans, IGRAPH_TRANSITIVITY_NAN),
|
||||
REPS);
|
||||
);
|
||||
|
||||
BENCH(" 5 Count triangles per vertex, all vertices method, small GNM",
|
||||
REPEAT(igraph_count_adjacent_triangles(&g, &trans, igraph_vss_all()), REPS);
|
||||
);
|
||||
|
||||
BENCH(" 6 Count triangles per vertex, subset method, small GNM",
|
||||
REPEAT(igraph_count_adjacent_triangles(&g, &trans, all_vertices), REPS);
|
||||
);
|
||||
|
||||
BENCH(" 7 Count all triangles, small GNM",
|
||||
REPEAT(igraph_count_triangles(&g, &tri_count), REPS);
|
||||
);
|
||||
|
||||
igraph_vs_destroy(&all_vertices);
|
||||
igraph_destroy(&g);
|
||||
|
||||
#undef REPS
|
||||
|
||||
printf("\n");
|
||||
|
||||
igraph_erdos_renyi_game_gnm(&g, 50, 300, IGRAPH_UNDIRECTED, IGRAPH_SIMPLE_SW, IGRAPH_EDGE_UNLABELED);
|
||||
igraph_vector_resize(&trans, igraph_vcount(&g));
|
||||
igraph_vs_range(&all_vertices, 0, igraph_vcount(&g));
|
||||
|
||||
#define REPS 10000
|
||||
|
||||
BENCH(" 1 Local transitivity, all vertices method, tiny GNM",
|
||||
REPEAT(igraph_transitivity_local_undirected(&g, &trans, igraph_vss_all(),
|
||||
IGRAPH_TRANSITIVITY_NAN), REPS);
|
||||
);
|
||||
|
||||
BENCH(" 2 Local transitivity, subset method, tiny GNM",
|
||||
REPEAT(igraph_transitivity_local_undirected(&g, &trans, all_vertices,
|
||||
IGRAPH_TRANSITIVITY_NAN), REPS);
|
||||
);
|
||||
|
||||
BENCH(" 3 Average local transitivity, tiny GNM",
|
||||
REPEAT(igraph_transitivity_avglocal_undirected(&g, &avg_trans, IGRAPH_TRANSITIVITY_NAN),
|
||||
REPS);
|
||||
);
|
||||
|
||||
BENCH(" 4 Global transitivity, tiny GNM",
|
||||
REPEAT(igraph_transitivity_undirected(&g, &global_trans, IGRAPH_TRANSITIVITY_NAN),
|
||||
REPS);
|
||||
);
|
||||
|
||||
BENCH(" 5 Count triangles per vertex, all vertices method, tiny GNM",
|
||||
REPEAT(igraph_count_adjacent_triangles(&g, &trans, igraph_vss_all()), REPS);
|
||||
);
|
||||
|
||||
BENCH(" 6 Count triangles per vertex, subset method, tiny GNM",
|
||||
REPEAT(igraph_count_adjacent_triangles(&g, &trans, all_vertices), REPS);
|
||||
);
|
||||
|
||||
BENCH(" 7 Count all triangles, tiny GNM",
|
||||
REPEAT(igraph_count_triangles(&g, &tri_count), REPS);
|
||||
);
|
||||
|
||||
igraph_vs_destroy(&all_vertices);
|
||||
igraph_destroy(&g);
|
||||
|
||||
#undef REPS
|
||||
|
||||
igraph_vector_destroy(&trans);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
igraph library.
|
||||
Copyright (C) 2024 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 "bench.h"
|
||||
|
||||
#define TOSTR1(x) #x
|
||||
#define TOSTR(x) TOSTR1(x)
|
||||
|
||||
void tree_game(igraph_int_t n, igraph_bool_t directed, igraph_random_tree_t method) {
|
||||
igraph_t g;
|
||||
igraph_tree_game(&g, n, directed, method);
|
||||
igraph_destroy(&g);
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
|
||||
igraph_rng_seed(igraph_rng_default(), 137);
|
||||
BENCH_INIT();
|
||||
|
||||
#define VCOUNT 100
|
||||
#define REP 100000
|
||||
|
||||
BENCH(" 1 vcount=" TOSTR(VCOUNT) ", Prufer, " TOSTR(REP) "x",
|
||||
REPEAT(tree_game(VCOUNT, IGRAPH_UNDIRECTED, IGRAPH_RANDOM_TREE_PRUFER), REP);
|
||||
);
|
||||
|
||||
BENCH(" 2 vcount=" TOSTR(VCOUNT) ", LERW, " TOSTR(REP) "x",
|
||||
REPEAT(tree_game(VCOUNT, IGRAPH_UNDIRECTED, IGRAPH_RANDOM_TREE_LERW), REP);
|
||||
);
|
||||
|
||||
#undef VCOUNT
|
||||
#undef DENS
|
||||
#undef REP
|
||||
|
||||
printf("\n");
|
||||
|
||||
#define VCOUNT 1000
|
||||
#define REP 10000
|
||||
|
||||
BENCH(" 1 vcount=" TOSTR(VCOUNT) ", Prufer, " TOSTR(REP) "x",
|
||||
REPEAT(tree_game(VCOUNT, IGRAPH_UNDIRECTED, IGRAPH_RANDOM_TREE_PRUFER), REP);
|
||||
);
|
||||
|
||||
BENCH(" 2 vcount=" TOSTR(VCOUNT) ", LERW, " TOSTR(REP) "x",
|
||||
REPEAT(tree_game(VCOUNT, IGRAPH_UNDIRECTED, IGRAPH_RANDOM_TREE_LERW), REP);
|
||||
);
|
||||
|
||||
#undef VCOUNT
|
||||
#undef DENS
|
||||
#undef REP
|
||||
|
||||
printf("\n");
|
||||
|
||||
#define VCOUNT 10000
|
||||
#define REP 1000
|
||||
|
||||
BENCH(" 3 vcount=" TOSTR(VCOUNT) ", Prufer, " TOSTR(REP) "x",
|
||||
REPEAT(tree_game(VCOUNT, IGRAPH_UNDIRECTED, IGRAPH_RANDOM_TREE_PRUFER), REP);
|
||||
);
|
||||
|
||||
BENCH(" 4 vcount=" TOSTR(VCOUNT) ", LERW, " TOSTR(REP) "x",
|
||||
REPEAT(tree_game(VCOUNT, IGRAPH_UNDIRECTED, IGRAPH_RANDOM_TREE_LERW), REP);
|
||||
);
|
||||
|
||||
#undef VCOUNT
|
||||
#undef DENS
|
||||
#undef REP
|
||||
|
||||
printf("\n");
|
||||
|
||||
#define VCOUNT 100000
|
||||
#define REP 100
|
||||
|
||||
BENCH(" 3 vcount=" TOSTR(VCOUNT) ", Prufer, " TOSTR(REP) "x",
|
||||
REPEAT(tree_game(VCOUNT, IGRAPH_UNDIRECTED, IGRAPH_RANDOM_TREE_PRUFER), REP);
|
||||
);
|
||||
|
||||
BENCH(" 4 vcount=" TOSTR(VCOUNT) ", LERW, " TOSTR(REP) "x",
|
||||
REPEAT(tree_game(VCOUNT, IGRAPH_UNDIRECTED, IGRAPH_RANDOM_TREE_LERW), REP);
|
||||
);
|
||||
|
||||
#undef VCOUNT
|
||||
#undef DENS
|
||||
#undef REP
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
igraph library.
|
||||
Copyright (C) 2024 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 "bench.h"
|
||||
|
||||
int main(void) {
|
||||
|
||||
igraph_t g;
|
||||
igraph_int_t vconn;
|
||||
|
||||
igraph_rng_seed(igraph_rng_default(), 54);
|
||||
BENCH_INIT();
|
||||
|
||||
igraph_grg_game(&g, 100, 0.2, /* torus = */ false, /* x = */ NULL, /* y = */ NULL);
|
||||
|
||||
BENCH(" 1 Vertex connectivity of geometric random graph, n=100, r=0.2",
|
||||
igraph_vertex_connectivity(&g, &vconn, /* checks = */ false);
|
||||
);
|
||||
|
||||
igraph_destroy(&g);
|
||||
|
||||
igraph_grg_game(&g, 200, 0.141, /* torus = */ false, /* x = */ NULL, /* y = */ NULL);
|
||||
|
||||
BENCH(" 2 Vertex connectivity of geometric random graph, n=200, r=0.141",
|
||||
igraph_vertex_connectivity(&g, &vconn, /* checks = */ false);
|
||||
);
|
||||
|
||||
igraph_destroy(&g);
|
||||
|
||||
igraph_grg_game(&g, 400, 0.1, /* torus = */ false, /* x = */ NULL, /* y = */ NULL);
|
||||
|
||||
BENCH(" 3 Vertex connectivity of geometric random graph, n=400, r=0.1",
|
||||
igraph_vertex_connectivity(&g, &vconn, /* checks = */ false);
|
||||
);
|
||||
|
||||
igraph_destroy(&g);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,165 @@
|
||||
/*
|
||||
igraph library.
|
||||
Copyright (C) 2024 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 "bench.h"
|
||||
|
||||
#define TOSTR1(x) #x
|
||||
#define TOSTR(x) TOSTR1(x)
|
||||
|
||||
int main(void) {
|
||||
igraph_t g;
|
||||
igraph_vector_int_t membership;
|
||||
igraph_vector_t distances;
|
||||
igraph_vector_t weights;
|
||||
igraph_vector_int_t generators;
|
||||
|
||||
igraph_rng_seed(igraph_rng_default(), 137);
|
||||
BENCH_INIT();
|
||||
|
||||
igraph_vector_int_init(&membership, 0);
|
||||
igraph_vector_init(&distances, 0);
|
||||
igraph_vector_init(&weights, 0);
|
||||
igraph_vector_int_init(&generators, 0);
|
||||
|
||||
#define VCOUNT 100
|
||||
#define DENS 0.5
|
||||
#define REP 1000
|
||||
|
||||
igraph_erdos_renyi_game_gnp(&g, VCOUNT, DENS, IGRAPH_DIRECTED, IGRAPH_SIMPLE_SW, IGRAPH_EDGE_UNLABELED);
|
||||
igraph_vector_int_resize(&membership, igraph_vcount(&g));
|
||||
igraph_vector_resize(&distances, igraph_vcount(&g));
|
||||
igraph_vector_resize(&weights, igraph_ecount(&g));
|
||||
|
||||
for (igraph_int_t i=0; i < igraph_ecount(&g); i++) {
|
||||
VECTOR(weights)[i] = RNG_EXP(1);
|
||||
}
|
||||
|
||||
igraph_random_sample(&generators, 0, igraph_vcount(&g)-1, 20);
|
||||
|
||||
BENCH(" 1 vcount=" TOSTR(VCOUNT) ", p=" TOSTR(DENS) ", Unweighted, " TOSTR(REP) "x",
|
||||
REPEAT(igraph_voronoi(&g, &membership, &distances, &generators, NULL, IGRAPH_OUT, IGRAPH_VORONOI_RANDOM), REP);
|
||||
);
|
||||
BENCH(" 2 vcount=" TOSTR(VCOUNT) ", p=" TOSTR(DENS) ", Dijkstra, " TOSTR(REP) "x",
|
||||
REPEAT(igraph_voronoi(&g, &membership, &distances, &generators, &weights, IGRAPH_OUT, IGRAPH_VORONOI_RANDOM), REP);
|
||||
);
|
||||
|
||||
igraph_destroy(&g);
|
||||
|
||||
#undef VCOUNT
|
||||
#undef DENS
|
||||
#undef REP
|
||||
|
||||
printf("\n");
|
||||
|
||||
#define VCOUNT 500
|
||||
#define DENS 0.1
|
||||
#define REP 1000
|
||||
|
||||
igraph_erdos_renyi_game_gnp(&g, VCOUNT, DENS, IGRAPH_DIRECTED, IGRAPH_SIMPLE_SW, IGRAPH_EDGE_UNLABELED);
|
||||
igraph_vector_int_resize(&membership, igraph_vcount(&g));
|
||||
igraph_vector_resize(&distances, igraph_vcount(&g));
|
||||
igraph_vector_resize(&weights, igraph_ecount(&g));
|
||||
|
||||
for (igraph_int_t i=0; i < igraph_ecount(&g); i++) {
|
||||
VECTOR(weights)[i] = RNG_EXP(1);
|
||||
}
|
||||
|
||||
igraph_random_sample(&generators, 0, igraph_vcount(&g)-1, 20);
|
||||
|
||||
BENCH(" 1 vcount=" TOSTR(VCOUNT) ", p=" TOSTR(DENS) ", Unweighted, " TOSTR(REP) "x",
|
||||
REPEAT(igraph_voronoi(&g, &membership, &distances, &generators, NULL, IGRAPH_OUT, IGRAPH_VORONOI_RANDOM), REP);
|
||||
);
|
||||
BENCH(" 2 vcount=" TOSTR(VCOUNT) ", p=" TOSTR(DENS) ", Dijkstra, " TOSTR(REP) "x",
|
||||
REPEAT(igraph_voronoi(&g, &membership, &distances, &generators, &weights, IGRAPH_OUT, IGRAPH_VORONOI_RANDOM), REP);
|
||||
);
|
||||
|
||||
igraph_destroy(&g);
|
||||
|
||||
#undef VCOUNT
|
||||
#undef DENS
|
||||
#undef REP
|
||||
|
||||
printf("\n");
|
||||
|
||||
#define VCOUNT 5000
|
||||
#define DENS 0.01
|
||||
#define REP 100
|
||||
|
||||
igraph_erdos_renyi_game_gnp(&g, VCOUNT, DENS, IGRAPH_DIRECTED, IGRAPH_SIMPLE_SW, IGRAPH_EDGE_UNLABELED);
|
||||
igraph_vector_int_resize(&membership, igraph_vcount(&g));
|
||||
igraph_vector_resize(&distances, igraph_vcount(&g));
|
||||
igraph_vector_resize(&weights, igraph_ecount(&g));
|
||||
|
||||
for (igraph_int_t i=0; i < igraph_ecount(&g); i++) {
|
||||
VECTOR(weights)[i] = RNG_EXP(1);
|
||||
}
|
||||
|
||||
igraph_random_sample(&generators, 0, igraph_vcount(&g)-1, 20);
|
||||
|
||||
BENCH(" 1 vcount=" TOSTR(VCOUNT) ", p=" TOSTR(DENS) ", Unweighted, " TOSTR(REP) "x",
|
||||
REPEAT(igraph_voronoi(&g, &membership, &distances, &generators, NULL, IGRAPH_OUT, IGRAPH_VORONOI_RANDOM), REP);
|
||||
);
|
||||
BENCH(" 2 vcount=" TOSTR(VCOUNT) ", p=" TOSTR(DENS) ", Dijkstra, " TOSTR(REP) "x",
|
||||
REPEAT(igraph_voronoi(&g, &membership, &distances, &generators, &weights, IGRAPH_OUT, IGRAPH_VORONOI_RANDOM), REP);
|
||||
);
|
||||
|
||||
igraph_destroy(&g);
|
||||
|
||||
#undef VCOUNT
|
||||
#undef DENS
|
||||
#undef REP
|
||||
|
||||
printf("\n");
|
||||
|
||||
#define VCOUNT 100000
|
||||
#define DENS 0.0001
|
||||
#define REP 1
|
||||
|
||||
igraph_erdos_renyi_game_gnp(&g, VCOUNT, DENS, IGRAPH_DIRECTED, IGRAPH_SIMPLE_SW, IGRAPH_EDGE_UNLABELED);
|
||||
igraph_vector_int_resize(&membership, igraph_vcount(&g));
|
||||
igraph_vector_resize(&distances, igraph_vcount(&g));
|
||||
igraph_vector_resize(&weights, igraph_ecount(&g));
|
||||
|
||||
for (igraph_int_t i=0; i < igraph_ecount(&g); i++) {
|
||||
VECTOR(weights)[i] = RNG_EXP(1);
|
||||
}
|
||||
|
||||
igraph_random_sample(&generators, 0, igraph_vcount(&g)-1, 100);
|
||||
|
||||
BENCH(" 1 vcount=" TOSTR(VCOUNT) ", p=" TOSTR(DENS) ", Unweighted, " TOSTR(REP) "x",
|
||||
REPEAT(igraph_voronoi(&g, &membership, &distances, &generators, NULL, IGRAPH_OUT, IGRAPH_VORONOI_RANDOM), REP);
|
||||
);
|
||||
BENCH(" 2 vcount=" TOSTR(VCOUNT) ", p=" TOSTR(DENS) ", Dijkstra, " TOSTR(REP) "x",
|
||||
REPEAT(igraph_voronoi(&g, &membership, &distances, &generators, &weights, IGRAPH_OUT, IGRAPH_VORONOI_RANDOM), REP);
|
||||
);
|
||||
|
||||
igraph_destroy(&g);
|
||||
|
||||
#undef VCOUNT
|
||||
#undef DENS
|
||||
#undef REP
|
||||
|
||||
igraph_vector_int_destroy(&generators);
|
||||
igraph_vector_destroy(&weights);
|
||||
igraph_vector_destroy(&distances);
|
||||
igraph_vector_int_destroy(&membership);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,456 @@
|
||||
/*
|
||||
igraph library.
|
||||
Copyright (C) 2013-2024 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 "bench.h"
|
||||
|
||||
typedef struct igraph_incadjlist_inter_t {
|
||||
igraph_int_t length;
|
||||
igraph_vector_int_t *incadjs;
|
||||
} igraph_incadjlist_inter_t;
|
||||
|
||||
#define igraph_incadjlist_inter_get(il,no) (&(il)->incadjs[(igraph_int_t)(no)])
|
||||
#define igraph_incadjlist_sep_get_inc(il,no) (&(il)->incs[(igraph_int_t)(no)])
|
||||
#define igraph_incadjlist_sep_get_adj(il,no) (&(il)->adjs[(igraph_int_t)(no)])
|
||||
|
||||
void igraph_incadjlist_inter_destroy(igraph_incadjlist_inter_t *il) {
|
||||
igraph_int_t i;
|
||||
for (i = 0; i < il->length; i++) {
|
||||
/* This works if some igraph_vector_int_t's contain NULL,
|
||||
because igraph_vector_int_destroy can handle this. */
|
||||
igraph_vector_int_destroy(&il->incadjs[i]);
|
||||
}
|
||||
IGRAPH_FREE(il->incadjs);
|
||||
}
|
||||
|
||||
igraph_error_t igraph_incadjlist_inter_init(const igraph_t *graph,
|
||||
igraph_incadjlist_inter_t *il,
|
||||
igraph_neimode_t mode) {
|
||||
igraph_int_t i, j, n;
|
||||
igraph_vector_int_t tmp;
|
||||
|
||||
if (mode != IGRAPH_IN && mode != IGRAPH_OUT && mode != IGRAPH_ALL) {
|
||||
IGRAPH_ERROR("Cannot create incadjlist.", IGRAPH_EINVMODE);
|
||||
}
|
||||
|
||||
igraph_vector_int_init(&tmp, 0);
|
||||
IGRAPH_FINALLY(igraph_vector_int_destroy, &tmp);
|
||||
|
||||
if (!igraph_is_directed(graph)) {
|
||||
mode = IGRAPH_ALL;
|
||||
}
|
||||
|
||||
il->length = igraph_vcount(graph);
|
||||
il->incadjs = IGRAPH_CALLOC(il->length, igraph_vector_int_t);
|
||||
if (il->incadjs == 0) {
|
||||
IGRAPH_ERROR("Cannot create incadjlist.", IGRAPH_ENOMEM); /* LCOV_EXCL_LINE */
|
||||
}
|
||||
IGRAPH_FINALLY(igraph_incadjlist_inter_destroy, il);
|
||||
|
||||
for (i = 0; i < il->length; i++) {
|
||||
//IGRAPH_ALLOW_INTERRUPTION();
|
||||
|
||||
IGRAPH_CHECK(igraph_incident(graph, &tmp, i, mode, IGRAPH_LOOPS));
|
||||
|
||||
n = igraph_vector_int_size(&tmp);
|
||||
IGRAPH_CHECK(igraph_vector_int_init(&il->incadjs[i], n * 2));
|
||||
|
||||
for (j = 0; j < n; j++) {
|
||||
VECTOR(il->incadjs[i])[j * 2] = VECTOR(tmp)[j];
|
||||
VECTOR(il->incadjs[i])[j * 2 + 1] =
|
||||
IGRAPH_OTHER(graph, VECTOR(tmp)[j], i);
|
||||
}
|
||||
}
|
||||
|
||||
igraph_vector_int_destroy(&tmp);
|
||||
IGRAPH_FINALLY_CLEAN(2); /* + igraph_incadjlist_inter_destroy */
|
||||
|
||||
return IGRAPH_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
typedef struct igraph_incadjlist_sep_t {
|
||||
igraph_int_t length;
|
||||
igraph_vector_int_t *incs;
|
||||
igraph_vector_int_t *adjs;
|
||||
} igraph_incadjlist_sep_t;
|
||||
|
||||
void igraph_incadjlist_sep_destroy(igraph_incadjlist_sep_t *il) {
|
||||
igraph_int_t i;
|
||||
for (i = 0; i < il->length; i++) {
|
||||
/* This works if some igraph_vector_int_t's contain NULL,
|
||||
because igraph_vector_int_destroy can handle this. */
|
||||
igraph_vector_int_destroy(&il->incs[i]);
|
||||
igraph_vector_int_destroy(&il->adjs[i]);
|
||||
}
|
||||
IGRAPH_FREE(il->incs);
|
||||
IGRAPH_FREE(il->adjs);
|
||||
}
|
||||
|
||||
igraph_error_t igraph_incadjlist_sep_init(const igraph_t *graph,
|
||||
igraph_incadjlist_sep_t *il,
|
||||
igraph_neimode_t mode) {
|
||||
igraph_int_t i, j, n;
|
||||
igraph_vector_int_t tmp;
|
||||
|
||||
if (mode != IGRAPH_IN && mode != IGRAPH_OUT && mode != IGRAPH_ALL) {
|
||||
IGRAPH_ERROR("Cannot create incadjlist.", IGRAPH_EINVMODE);
|
||||
}
|
||||
|
||||
igraph_vector_int_init(&tmp, 0);
|
||||
IGRAPH_FINALLY(igraph_vector_int_destroy, &tmp);
|
||||
|
||||
if (!igraph_is_directed(graph)) {
|
||||
mode = IGRAPH_ALL;
|
||||
}
|
||||
|
||||
il->length = igraph_vcount(graph);
|
||||
il->incs = IGRAPH_CALLOC(il->length, igraph_vector_int_t);
|
||||
if (il->incs == 0) {
|
||||
IGRAPH_ERROR("Cannot create incadjlist.", IGRAPH_ENOMEM); /* LCOV_EXCL_LINE */
|
||||
}
|
||||
|
||||
il->adjs = IGRAPH_CALLOC(il->length, igraph_vector_int_t);
|
||||
if (il->adjs == 0) {
|
||||
IGRAPH_FREE(il->incs);
|
||||
IGRAPH_ERROR("Cannot create incadjlist.", IGRAPH_ENOMEM); /* LCOV_EXCL_LINE */
|
||||
}
|
||||
|
||||
IGRAPH_FINALLY(igraph_incadjlist_sep_destroy, il);
|
||||
|
||||
for (i = 0; i < il->length; i++) {
|
||||
//IGRAPH_ALLOW_INTERRUPTION();
|
||||
|
||||
IGRAPH_CHECK(igraph_incident(graph, &tmp, i, mode, IGRAPH_LOOPS));
|
||||
|
||||
n = igraph_vector_int_size(&tmp);
|
||||
IGRAPH_CHECK(igraph_vector_int_init(&il->incs[i], n));
|
||||
IGRAPH_CHECK(igraph_vector_int_init(&il->adjs[i], n));
|
||||
|
||||
for (j = 0; j < n; j++) {
|
||||
VECTOR(il->incs[i])[j] = VECTOR(tmp)[j];
|
||||
VECTOR(il->adjs[i])[j] =
|
||||
IGRAPH_OTHER(graph, VECTOR(tmp)[j], i);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
igraph_vector_int_destroy(&tmp);
|
||||
IGRAPH_FINALLY_CLEAN(2); /* + igraph_incadjlist_sep_destroy */
|
||||
|
||||
return IGRAPH_SUCCESS;
|
||||
}
|
||||
|
||||
/* In the below tests, the 'dummy' variable is used to prevent the compilers
|
||||
* from optimizing away the entire side-effects-free function. We use XOR
|
||||
* instead of e.g. addition in order to prevent triggering undefined behaviour. */
|
||||
|
||||
igraph_int_t test_direct(igraph_t *g)
|
||||
{
|
||||
igraph_int_t dummy = 0;
|
||||
igraph_int_t vcount = igraph_vcount(g);
|
||||
igraph_int_t ecount = igraph_ecount(g);
|
||||
|
||||
igraph_int_t ei = 0;
|
||||
igraph_int_t eo = 0;
|
||||
for (igraph_int_t i = 0; i < vcount; i++) {
|
||||
while (ei < ecount && VECTOR(g->from)[VECTOR(g->oi)[ei]] == i) {
|
||||
igraph_int_t neighbor = VECTOR(g->to)[VECTOR(g->oi)[ei]];
|
||||
dummy ^= neighbor ^ VECTOR(g->oi)[ei];
|
||||
ei++;
|
||||
}
|
||||
while (eo < ecount && VECTOR(g->to)[VECTOR(g->ii)[eo]] == i) {
|
||||
igraph_int_t neighbor = VECTOR(g->from)[VECTOR(g->ii)[eo]];
|
||||
dummy ^= neighbor ^ VECTOR(g->ii)[eo] ;
|
||||
eo++;
|
||||
}
|
||||
}
|
||||
return dummy;
|
||||
}
|
||||
|
||||
igraph_int_t test_adj(igraph_t *g, igraph_adjlist_t *adj)
|
||||
{
|
||||
igraph_int_t dummy = 0;
|
||||
igraph_int_t vcount = igraph_vcount(g);
|
||||
|
||||
for (igraph_int_t i = 0; i < vcount; i++) {
|
||||
igraph_vector_int_t *neis = igraph_adjlist_get(adj, i);
|
||||
igraph_int_t nneis = igraph_vector_int_size(neis);
|
||||
for (int j = 0; j < nneis; j++) {
|
||||
igraph_int_t neighbor = VECTOR(*neis)[j];
|
||||
dummy ^= neighbor;
|
||||
}
|
||||
}
|
||||
return dummy;
|
||||
}
|
||||
|
||||
igraph_int_t test_inc_adj(igraph_t *g, igraph_inclist_t *inc, igraph_adjlist_t *adj)
|
||||
{
|
||||
igraph_int_t dummy = 0;
|
||||
igraph_int_t vcount = igraph_vcount(g);
|
||||
|
||||
for (igraph_int_t i = 0; i < vcount; i++) {
|
||||
igraph_vector_int_t *adjs = igraph_adjlist_get(adj, i);
|
||||
igraph_vector_int_t *incs = igraph_inclist_get(inc, i);
|
||||
igraph_int_t nneis = igraph_vector_int_size(adjs);
|
||||
for (int j = 0; j < nneis; j++) {
|
||||
igraph_int_t edge = VECTOR(*incs)[j];
|
||||
igraph_int_t neighbor = VECTOR(*adjs)[j];
|
||||
dummy ^= neighbor ^ edge;
|
||||
}
|
||||
}
|
||||
return dummy;
|
||||
}
|
||||
|
||||
igraph_int_t test_inc_other(igraph_t *g, igraph_inclist_t *inc)
|
||||
{
|
||||
igraph_int_t dummy = 0;
|
||||
igraph_int_t vcount = igraph_vcount(g);
|
||||
|
||||
for (igraph_int_t i = 0; i < vcount; i++) {
|
||||
igraph_vector_int_t *neis = igraph_inclist_get(inc, i);
|
||||
igraph_int_t nneis = igraph_vector_int_size(neis);
|
||||
for (igraph_int_t j = 0; j < nneis; j++) {
|
||||
igraph_int_t edge = VECTOR(*neis)[j];
|
||||
igraph_int_t neighbor = IGRAPH_OTHER(g, edge, i);
|
||||
dummy ^= neighbor ^ edge;
|
||||
}
|
||||
}
|
||||
return dummy;
|
||||
}
|
||||
|
||||
igraph_int_t test_incadj_sep(igraph_t *g, igraph_incadjlist_sep_t *inc)
|
||||
{
|
||||
igraph_int_t dummy = 0;
|
||||
igraph_int_t vcount = igraph_vcount(g);
|
||||
|
||||
for (igraph_int_t i = 0; i < vcount; i++) {
|
||||
igraph_vector_int_t *incs = igraph_incadjlist_sep_get_inc(inc, i);
|
||||
igraph_vector_int_t *adjs = igraph_incadjlist_sep_get_adj(inc, i);
|
||||
igraph_int_t nneis = igraph_vector_int_size(incs);
|
||||
for (igraph_int_t j = 0; j < nneis; j++) {
|
||||
igraph_int_t edge = VECTOR(*incs)[j];
|
||||
igraph_int_t neighbor = VECTOR(*adjs)[j];
|
||||
dummy ^= neighbor ^ edge;
|
||||
}
|
||||
}
|
||||
return dummy;
|
||||
}
|
||||
|
||||
igraph_int_t test_incadj_inter(igraph_t *g, igraph_incadjlist_inter_t *inc)
|
||||
{
|
||||
igraph_int_t dummy = 0;
|
||||
igraph_int_t vcount = igraph_vcount(g);
|
||||
|
||||
for (igraph_int_t i = 0; i < vcount; i++) {
|
||||
igraph_vector_int_t *ias = igraph_incadjlist_inter_get(inc, i);
|
||||
igraph_int_t nneis = igraph_vector_int_size(ias) / 2;
|
||||
for (igraph_int_t j = 0; j < nneis; j++) {
|
||||
igraph_int_t edge = VECTOR(*ias)[j * 2];
|
||||
igraph_int_t neighbor = VECTOR(*ias)[j * 2 + 1];
|
||||
dummy ^= neighbor ^ edge;
|
||||
}
|
||||
}
|
||||
return dummy;
|
||||
}
|
||||
|
||||
igraph_int_t test_inc_to(igraph_t *g, igraph_inclist_t *inc)
|
||||
{
|
||||
igraph_int_t dummy = 0;
|
||||
igraph_int_t vcount = igraph_vcount(g);
|
||||
|
||||
for (igraph_int_t i = 0; i < vcount; i++) {
|
||||
igraph_vector_int_t *neis = igraph_inclist_get(inc, i);
|
||||
igraph_int_t nneis = igraph_vector_int_size(neis);
|
||||
for (igraph_int_t j = 0; j < nneis; j++) {
|
||||
igraph_int_t edge = VECTOR(*neis)[j];
|
||||
igraph_int_t neighbor = IGRAPH_TO(g, edge);
|
||||
dummy ^= neighbor ^ edge;
|
||||
}
|
||||
}
|
||||
return dummy;
|
||||
}
|
||||
|
||||
igraph_int_t test_inc_nop(igraph_t *g, igraph_inclist_t *inc)
|
||||
{
|
||||
igraph_int_t dummy = 0;
|
||||
igraph_int_t vcount = igraph_vcount(g);
|
||||
|
||||
for (igraph_int_t i = 0; i < vcount; i++) {
|
||||
igraph_vector_int_t *neis = igraph_inclist_get(inc, i);
|
||||
igraph_int_t nneis = igraph_vector_int_size(neis);
|
||||
for (igraph_int_t j = 0; j < nneis; j++) {
|
||||
igraph_int_t edge = VECTOR(*neis)[j];
|
||||
dummy ^= edge;
|
||||
}
|
||||
}
|
||||
return dummy;
|
||||
}
|
||||
|
||||
/* Used to prevent optimizing away the result.
|
||||
* This must be a global variable to prevent "variable set but not used"
|
||||
* warnings from some compilers. */
|
||||
volatile igraph_int_t result;
|
||||
|
||||
void do_benchmarks(char *name, igraph_t *g, int repeat) {
|
||||
igraph_adjlist_t adj;
|
||||
igraph_inclist_t inc;
|
||||
igraph_incadjlist_inter_t incadj_inter;
|
||||
igraph_incadjlist_sep_t incadj_sep;
|
||||
|
||||
/* The init() call is in a REPEAT loop, so we include destroy() as well to avoid a memory leak.
|
||||
* This is representative of real use cases, where init/destroy should always come in pairs. */
|
||||
printf("%s", name);
|
||||
BENCH("1 init/destroy adjlist.",
|
||||
REPEAT(
|
||||
do {
|
||||
igraph_adjlist_init(g, &adj, IGRAPH_ALL, IGRAPH_LOOPS_TWICE, IGRAPH_MULTIPLE);
|
||||
igraph_adjlist_destroy(&adj);
|
||||
} while (0),
|
||||
repeat);
|
||||
);
|
||||
|
||||
printf("%s", name);
|
||||
BENCH("2 init/destroy inclist.",
|
||||
REPEAT(
|
||||
do {
|
||||
igraph_inclist_init(g, &inc, IGRAPH_ALL, IGRAPH_LOOPS_TWICE);
|
||||
igraph_inclist_destroy(&inc);
|
||||
} while (0),
|
||||
repeat);
|
||||
);
|
||||
|
||||
printf("%s", name);
|
||||
BENCH("3 init/destroy adjlist, remove loops and multiple (which aren't present).",
|
||||
REPEAT(
|
||||
do {
|
||||
igraph_adjlist_init(g, &adj, IGRAPH_ALL, IGRAPH_NO_LOOPS, IGRAPH_NO_MULTIPLE);
|
||||
igraph_adjlist_destroy(&adj);
|
||||
} while (0),
|
||||
repeat);
|
||||
);
|
||||
|
||||
printf("%s", name);
|
||||
BENCH("4 init/destroy inclist, remove loops (which aren't present).",
|
||||
REPEAT(
|
||||
do {
|
||||
igraph_inclist_init(g, &inc, IGRAPH_ALL, IGRAPH_NO_LOOPS);
|
||||
igraph_inclist_destroy(&inc);
|
||||
} while (0),
|
||||
repeat);
|
||||
);
|
||||
|
||||
/* Initialize adjlist / inclist for the following benchmarks. */
|
||||
igraph_adjlist_init(g, &adj, IGRAPH_ALL, IGRAPH_LOOPS_TWICE, IGRAPH_MULTIPLE);
|
||||
igraph_inclist_init(g, &inc, IGRAPH_ALL, IGRAPH_LOOPS_TWICE);
|
||||
|
||||
printf("%s", name);
|
||||
BENCH("5 go over vertices (multiple times) using adjlist.",
|
||||
REPEAT(result = test_adj(g, &adj), repeat);
|
||||
);
|
||||
|
||||
printf("%s", name);
|
||||
BENCH("6 go over vertices (multiple times) using inclist, IGRAPH_OTHER.",
|
||||
REPEAT(result = test_inc_other(g, &inc), repeat);
|
||||
);
|
||||
|
||||
printf("%s", name);
|
||||
BENCH("7 go over vertices (multiple times) using inclist, IGRAPH_TO.",
|
||||
REPEAT(result = test_inc_to(g, &inc), repeat);
|
||||
);
|
||||
|
||||
printf("%s", name);
|
||||
BENCH("8 go over edges using inclist, don't retrieve vertex.",
|
||||
REPEAT(result = test_inc_nop(g, &inc), repeat);
|
||||
);
|
||||
|
||||
printf("%s", name);
|
||||
BENCH("9 go over edges and vertices using adjlist and inclist.",
|
||||
REPEAT(result = test_inc_adj(g, &inc, &adj), repeat);
|
||||
);
|
||||
|
||||
igraph_adjlist_destroy(&adj);
|
||||
igraph_inclist_destroy(&inc);
|
||||
|
||||
printf("%s", name);
|
||||
BENCH("10 go over edges and vertices using graph internals directly.",
|
||||
REPEAT(result = test_direct(g), repeat);
|
||||
);
|
||||
|
||||
printf("%s", name);
|
||||
BENCH("11 init/destroy interleaved incadjlist.",
|
||||
REPEAT(
|
||||
do {
|
||||
igraph_incadjlist_inter_init(g, &incadj_inter, IGRAPH_ALL);
|
||||
igraph_incadjlist_inter_destroy(&incadj_inter);
|
||||
} while (0),
|
||||
repeat);
|
||||
);
|
||||
|
||||
igraph_incadjlist_inter_init(g, &incadj_inter, IGRAPH_ALL);
|
||||
|
||||
printf("%s", name);
|
||||
BENCH("12 go over edges and vertices using interleaved incadjlist.",
|
||||
REPEAT(result = test_incadj_inter(g, &incadj_inter), repeat);
|
||||
);
|
||||
|
||||
igraph_incadjlist_inter_destroy(&incadj_inter);
|
||||
|
||||
printf("%s", name);
|
||||
BENCH("13 init/destroy incadjlist with two vectors.",
|
||||
REPEAT(
|
||||
do {
|
||||
igraph_incadjlist_sep_init(g, &incadj_sep, IGRAPH_ALL);
|
||||
igraph_incadjlist_sep_destroy(&incadj_sep);
|
||||
} while (0), repeat);
|
||||
);
|
||||
|
||||
igraph_incadjlist_sep_init(g, &incadj_sep, IGRAPH_ALL);
|
||||
|
||||
printf("%s", name);
|
||||
BENCH("14 go over edges and vertices using incadjlist.",
|
||||
REPEAT(result = test_incadj_sep(g, &incadj_sep), repeat);
|
||||
);
|
||||
|
||||
igraph_incadjlist_sep_destroy(&incadj_sep);
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
igraph_t g;
|
||||
|
||||
igraph_rng_seed(igraph_rng_default(), 42);
|
||||
BENCH_INIT();
|
||||
|
||||
printf("Full graph tests:\n");
|
||||
igraph_full(&g, 10000, IGRAPH_UNDIRECTED, IGRAPH_NO_LOOPS);
|
||||
do_benchmarks(" fg - ", &g, 1);
|
||||
igraph_destroy(&g);
|
||||
|
||||
printf("\nRandom graph tests:\n");
|
||||
igraph_erdos_renyi_game_gnm(&g, 10000, 49994999, IGRAPH_UNDIRECTED, IGRAPH_SIMPLE_SW, IGRAPH_EDGE_UNLABELED);
|
||||
do_benchmarks(" rg - ", &g, 1);
|
||||
igraph_destroy(&g);
|
||||
|
||||
printf("\nSmall graph tests:\n");
|
||||
igraph_full(&g, 1000, IGRAPH_UNDIRECTED, IGRAPH_NO_LOOPS);
|
||||
do_benchmarks(" sg - ", &g, 100);
|
||||
igraph_destroy(&g);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
igraph library.
|
||||
Copyright (C) 2024 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 "bench.h"
|
||||
|
||||
void rand_vec(igraph_vector_int_t *v, igraph_int_t n, igraph_int_t k) {
|
||||
igraph_vector_int_resize(v, n);
|
||||
for (igraph_int_t i=0; i < n; i++) {
|
||||
VECTOR(*v)[i] = RNG_INTEGER(0, k);
|
||||
}
|
||||
}
|
||||
|
||||
void run_bench(int i, int n, int r) {
|
||||
igraph_vector_int_t a, b;
|
||||
igraph_int_t na = n, nb = r*n;
|
||||
int rep = 300000000 / nb;
|
||||
char msg[255];
|
||||
|
||||
igraph_vector_int_init(&a, na);
|
||||
igraph_vector_int_init(&b, nb);
|
||||
|
||||
rand_vec(&a, na, nb);
|
||||
igraph_vector_int_sort(&a);
|
||||
rand_vec(&b, nb, nb);
|
||||
igraph_vector_int_sort(&b);
|
||||
|
||||
snprintf(msg, sizeof(msg) / sizeof(msg[0]),
|
||||
"%2d n = %5d, r = %3d, %dx", i, n, r, rep);
|
||||
|
||||
/* 'volatile' is needed to prevent the compiler from optimizing
|
||||
* away multiple calls to the function with the same parameters within REPEAT.
|
||||
* This would normally happen due to the use of IGRAPH_FUNCATTR_PURE.
|
||||
* ATTENTION! 'volatile', when used this way, may not prevent this optimization
|
||||
* with future compiler versions. */
|
||||
volatile igraph_int_t res;
|
||||
BENCH(msg, REPEAT(res = igraph_vector_int_intersection_size_sorted(&a, &b), rep));
|
||||
(void) res; /* silence unused-but-set-variable warning */
|
||||
|
||||
igraph_vector_int_destroy(&a);
|
||||
igraph_vector_int_destroy(&b);
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
int i = 0;
|
||||
|
||||
igraph_rng_seed(igraph_rng_default(), 137);
|
||||
BENCH_INIT();
|
||||
|
||||
#define BENCHSET(n) \
|
||||
run_bench(++i, n, 1); \
|
||||
run_bench(++i, n, 3); \
|
||||
run_bench(++i, n, 10); \
|
||||
run_bench(++i, n, 30); \
|
||||
run_bench(++i, n, 100); \
|
||||
printf("\n");
|
||||
|
||||
BENCHSET(1);
|
||||
BENCHSET(3);
|
||||
BENCHSET(10);
|
||||
BENCHSET(30);
|
||||
BENCHSET(100);
|
||||
BENCHSET(300);
|
||||
BENCHSET(1000);
|
||||
BENCHSET(3000);
|
||||
BENCHSET(10000);
|
||||
BENCHSET(30000);
|
||||
BENCHSET(100000);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
igraph library.
|
||||
Copyright (C) 2024 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 "bench.h"
|
||||
|
||||
void match(const igraph_t *graph,
|
||||
const igraph_t patt[], igraph_int_t n,
|
||||
igraph_vector_int_list_t *maps) {
|
||||
|
||||
igraph_vector_int_list_clear(maps);
|
||||
for (igraph_int_t i=0; i < n; i++) {
|
||||
igraph_subisomorphic_lad(&patt[i], graph, NULL, NULL, NULL, maps, false);
|
||||
}
|
||||
}
|
||||
|
||||
#define NP 8
|
||||
|
||||
int main(void) {
|
||||
igraph_t graph;
|
||||
igraph_t patt[NP];
|
||||
igraph_vector_int_list_t maps;
|
||||
|
||||
BENCH_INIT();
|
||||
|
||||
igraph_vector_int_list_init(&maps, 0);
|
||||
|
||||
for (igraph_int_t i=0; i < NP; i++) {
|
||||
igraph_ring(&patt[i], i+1, IGRAPH_DIRECTED, false, true);
|
||||
}
|
||||
|
||||
igraph_kautz(&graph, 3, 3);
|
||||
BENCH("1 Kautz(3,3) 10x", REPEAT(match(&graph, patt, NP, &maps), 10));
|
||||
igraph_destroy(&graph);
|
||||
|
||||
igraph_kautz(&graph, 3, 4);
|
||||
BENCH("2 Kautz(3,4) 3x", REPEAT(match(&graph, patt, NP, &maps), 3));
|
||||
igraph_destroy(&graph);
|
||||
|
||||
igraph_kautz(&graph, 4, 3);
|
||||
BENCH("3 Kautz(4,3) 1x", REPEAT(match(&graph, patt, NP, &maps), 1));
|
||||
igraph_destroy(&graph);
|
||||
|
||||
for (igraph_int_t i=0; i < NP; i++) {
|
||||
igraph_destroy(&patt[i]);
|
||||
}
|
||||
|
||||
igraph_vector_int_list_destroy(&maps);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
igraph library.
|
||||
Copyright (C) 2025 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 "bench.h"
|
||||
|
||||
void run_bench(int n) {
|
||||
igraph_t graph;
|
||||
igraph_matrix_t modmat;
|
||||
int rep;
|
||||
char msg[255];
|
||||
|
||||
rep = 20000 / n;
|
||||
rep = rep*rep;
|
||||
|
||||
igraph_matrix_init(&modmat, n, n);
|
||||
|
||||
igraph_erdos_renyi_game_gnm(&graph, n, 10 * n, IGRAPH_DIRECTED, IGRAPH_LOOPS_SW, IGRAPH_EDGE_UNLABELED);
|
||||
|
||||
snprintf(msg, sizeof(msg) / sizeof(msg[0]),
|
||||
"G(n,m), directed, n = %5d, m = %7" IGRAPH_PRId ", %dx", n, igraph_ecount(&graph), rep);
|
||||
BENCH(msg, REPEAT(igraph_modularity_matrix(&graph, NULL, 1.0, &modmat, IGRAPH_DIRECTED), rep));
|
||||
|
||||
snprintf(msg, sizeof(msg) / sizeof(msg[0]),
|
||||
"G(n,m), undirected, n = %5d, m = %7" IGRAPH_PRId ", %dx", n, igraph_ecount(&graph), rep);
|
||||
BENCH(msg, REPEAT(igraph_modularity_matrix(&graph, NULL, 1.0, &modmat, IGRAPH_UNDIRECTED), rep));
|
||||
|
||||
igraph_destroy(&graph);
|
||||
|
||||
igraph_erdos_renyi_game_gnp(&graph, n, 0.1, IGRAPH_DIRECTED, IGRAPH_LOOPS_SW, IGRAPH_EDGE_UNLABELED);
|
||||
|
||||
snprintf(msg, sizeof(msg) / sizeof(msg[0]),
|
||||
"G(n,p), directed, n = %5d, m = %7" IGRAPH_PRId ", %dx", n, igraph_ecount(&graph), rep);
|
||||
BENCH(msg, REPEAT(igraph_modularity_matrix(&graph, NULL, 1.0, &modmat, IGRAPH_DIRECTED), rep));
|
||||
|
||||
snprintf(msg, sizeof(msg) / sizeof(msg[0]),
|
||||
"G(n,p), undirected, n = %5d, m = %7" IGRAPH_PRId ", %dx", n, igraph_ecount(&graph), rep);
|
||||
BENCH(msg, REPEAT(igraph_modularity_matrix(&graph, NULL, 1.0, &modmat, IGRAPH_UNDIRECTED), rep));
|
||||
igraph_destroy(&graph);
|
||||
|
||||
igraph_matrix_destroy(&modmat);
|
||||
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
|
||||
igraph_rng_seed(igraph_rng_default(), 137);
|
||||
BENCH_INIT();
|
||||
|
||||
run_bench(100);
|
||||
run_bench(1000);
|
||||
run_bench(10000);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,164 @@
|
||||
/*
|
||||
igraph library.
|
||||
Copyright (C) 2024 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 "bench.h"
|
||||
|
||||
void run_bench(const igraph_t *graph, const igraph_vector_t *weights, int rep, const char *name) {
|
||||
igraph_vector_int_t edges;
|
||||
igraph_int_t vcount = igraph_vcount(graph);
|
||||
igraph_int_t ecount = igraph_ecount(graph);
|
||||
char msg[128];
|
||||
|
||||
igraph_vector_int_init(&edges, vcount - 1);
|
||||
|
||||
snprintf(msg, sizeof(msg) / sizeof(msg[0]),
|
||||
"%s, vcount=%" IGRAPH_PRId ", ecount=%" IGRAPH_PRId ", unweigthed, %dx",
|
||||
name, vcount, ecount, rep);
|
||||
BENCH(msg, REPEAT(igraph_minimum_spanning_tree(graph, &edges, NULL, IGRAPH_MST_UNWEIGHTED), rep));
|
||||
|
||||
snprintf(msg, sizeof(msg) / sizeof(msg[0]),
|
||||
"%s, vcount=%" IGRAPH_PRId ", ecount=%" IGRAPH_PRId ", Prim, %dx",
|
||||
name, vcount, ecount, rep);
|
||||
BENCH(msg, REPEAT(igraph_minimum_spanning_tree(graph, &edges, weights, IGRAPH_MST_UNWEIGHTED), rep));
|
||||
|
||||
snprintf(msg, sizeof(msg) / sizeof(msg[0]),
|
||||
"%s, vcount=%" IGRAPH_PRId ", ecount=%" IGRAPH_PRId ", Kruskal, %dx",
|
||||
name, vcount, ecount, rep);
|
||||
BENCH(msg, REPEAT(igraph_minimum_spanning_tree(graph, &edges, weights, IGRAPH_MST_UNWEIGHTED), rep));
|
||||
|
||||
printf("\n");
|
||||
|
||||
igraph_vector_int_destroy(&edges);
|
||||
}
|
||||
|
||||
void rand_weights(const igraph_t *graph, igraph_vector_t *weights) {
|
||||
igraph_int_t ecount = igraph_ecount(graph);
|
||||
igraph_vector_resize(weights, ecount);
|
||||
for (igraph_int_t i=0; i < ecount; i++) {
|
||||
VECTOR(*weights)[i] = RNG_UNIF01();
|
||||
}
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
igraph_t g;
|
||||
igraph_vector_t weights;
|
||||
|
||||
igraph_rng_seed(igraph_rng_default(), 137);
|
||||
BENCH_INIT();
|
||||
|
||||
igraph_vector_init(&weights, 0);
|
||||
|
||||
igraph_barabasi_game(&g, 100, 1, 1, NULL, true, 0, false, IGRAPH_BARABASI_PSUMTREE, NULL);
|
||||
rand_weights(&g, &weights);
|
||||
run_bench(&g, &weights, 50000, "PA");
|
||||
igraph_destroy(&g);
|
||||
|
||||
igraph_barabasi_game(&g, 100, 1, 5, NULL, true, 0, false, IGRAPH_BARABASI_PSUMTREE, NULL);
|
||||
rand_weights(&g, &weights);
|
||||
run_bench(&g, &weights, 10000, "PA");
|
||||
igraph_destroy(&g);
|
||||
|
||||
igraph_barabasi_game(&g, 1000, 1, 5, NULL, true, 0, false, IGRAPH_BARABASI_PSUMTREE, NULL);
|
||||
rand_weights(&g, &weights);
|
||||
run_bench(&g, &weights, 1000, "PA");
|
||||
igraph_destroy(&g);
|
||||
|
||||
igraph_barabasi_game(&g, 10000, 1, 5, NULL, true, 0, false, IGRAPH_BARABASI_PSUMTREE, NULL);
|
||||
rand_weights(&g, &weights);
|
||||
run_bench(&g, &weights, 100, "PA");
|
||||
igraph_destroy(&g);
|
||||
|
||||
igraph_barabasi_game(&g, 100, 1, 50, NULL, true, 0, false, IGRAPH_BARABASI_PSUMTREE, NULL);
|
||||
rand_weights(&g, &weights);
|
||||
run_bench(&g, &weights, 1000, "PA");
|
||||
igraph_destroy(&g);
|
||||
|
||||
igraph_barabasi_game(&g, 1000, 1, 50, NULL, true, 0, false, IGRAPH_BARABASI_PSUMTREE, NULL);
|
||||
rand_weights(&g, &weights);
|
||||
run_bench(&g, &weights, 100, "PA");
|
||||
igraph_destroy(&g);
|
||||
|
||||
igraph_barabasi_game(&g, 10000, 1, 50, NULL, true, 0, false, IGRAPH_BARABASI_PSUMTREE, NULL);
|
||||
rand_weights(&g, &weights);
|
||||
run_bench(&g, &weights, 10, "PA");
|
||||
igraph_destroy(&g);
|
||||
|
||||
igraph_barabasi_game(&g, 1000, 1, 500, NULL, true, 0, false, IGRAPH_BARABASI_PSUMTREE, NULL);
|
||||
rand_weights(&g, &weights);
|
||||
run_bench(&g, &weights, 10, "PA");
|
||||
igraph_destroy(&g);
|
||||
|
||||
igraph_barabasi_game(&g, 10000, 1, 500, NULL, true, 0, false, IGRAPH_BARABASI_PSUMTREE, NULL);
|
||||
rand_weights(&g, &weights);
|
||||
run_bench(&g, &weights, 1, "PA");
|
||||
igraph_destroy(&g);
|
||||
|
||||
igraph_erdos_renyi_game_gnm(&g, 1000, 500, IGRAPH_UNDIRECTED, IGRAPH_SIMPLE_SW, IGRAPH_EDGE_UNLABELED);
|
||||
rand_weights(&g, &weights);
|
||||
run_bench(&g, &weights, 60000, "G(n,m)");
|
||||
igraph_destroy(&g);
|
||||
|
||||
igraph_erdos_renyi_game_gnm(&g, 1000, 1000, IGRAPH_UNDIRECTED, IGRAPH_SIMPLE_SW, IGRAPH_EDGE_UNLABELED);
|
||||
rand_weights(&g, &weights);
|
||||
run_bench(&g, &weights, 30000, "G(n,m)");
|
||||
igraph_destroy(&g);
|
||||
|
||||
igraph_erdos_renyi_game_gnm(&g, 1000, 3000, IGRAPH_UNDIRECTED, IGRAPH_SIMPLE_SW, IGRAPH_EDGE_UNLABELED);
|
||||
rand_weights(&g, &weights);
|
||||
run_bench(&g, &weights, 10000, "G(n,m)");
|
||||
igraph_destroy(&g);
|
||||
|
||||
igraph_erdos_renyi_game_gnm(&g, 1000, 10000, IGRAPH_UNDIRECTED, IGRAPH_SIMPLE_SW, IGRAPH_EDGE_UNLABELED);
|
||||
rand_weights(&g, &weights);
|
||||
run_bench(&g, &weights, 3000, "G(n,m)");
|
||||
igraph_destroy(&g);
|
||||
|
||||
igraph_erdos_renyi_game_gnm(&g, 1000, 30000, IGRAPH_UNDIRECTED, IGRAPH_SIMPLE_SW, IGRAPH_EDGE_UNLABELED);
|
||||
rand_weights(&g, &weights);
|
||||
run_bench(&g, &weights, 1000, "G(n,m)");
|
||||
igraph_destroy(&g);
|
||||
|
||||
igraph_erdos_renyi_game_gnm(&g, 1000, 100000, IGRAPH_UNDIRECTED, IGRAPH_SIMPLE_SW, IGRAPH_EDGE_UNLABELED);
|
||||
rand_weights(&g, &weights);
|
||||
run_bench(&g, &weights, 300, "G(n,m)");
|
||||
igraph_destroy(&g);
|
||||
|
||||
igraph_full(&g, 100, false, false);
|
||||
rand_weights(&g, &weights);
|
||||
run_bench(&g, &weights, 10000, "K");
|
||||
igraph_destroy(&g);
|
||||
|
||||
igraph_full(&g, 1000, false, false);
|
||||
rand_weights(&g, &weights);
|
||||
run_bench(&g, &weights, 100, "K");
|
||||
igraph_destroy(&g);
|
||||
|
||||
{
|
||||
igraph_t K;
|
||||
igraph_full(&K, 100, false, false);
|
||||
igraph_disjoint_union(&g, &K, &K);
|
||||
igraph_destroy(&K);
|
||||
}
|
||||
rand_weights(&g, &weights);
|
||||
run_bench(&g, &weights, 10000, "K + K");
|
||||
igraph_destroy(&g);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
igraph library.
|
||||
Copyright (C) 2010-2012 Gabor Csardi <csardi.gabor@gmail.com>
|
||||
334 Harvard street, Cambridge, MA 02139 USA
|
||||
|
||||
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, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA
|
||||
*/
|
||||
|
||||
#include <igraph.h>
|
||||
|
||||
#include "../unit/test_utilities.h"
|
||||
|
||||
int main(void) {
|
||||
igraph_t graph;
|
||||
igraph_vector_int_list_t separators;
|
||||
|
||||
igraph_small(&graph, 0, /*directed=*/ 0,
|
||||
0, 1, 0, 2, 1, 3, 1, 4, 2, 3, 2, 5, 3, 4, 3, 5, 4, 6, 5, 6, -1);
|
||||
igraph_vector_int_list_init(&separators, 0);
|
||||
|
||||
igraph_all_minimal_st_separators(&graph, &separators);
|
||||
|
||||
print_vector_int_list(&separators);
|
||||
igraph_vector_int_list_destroy(&separators);
|
||||
igraph_destroy(&graph);
|
||||
|
||||
VERIFY_FINALLY_STACK();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
0: ( 1 2 )
|
||||
1: ( 0 3 4 )
|
||||
2: ( 0 3 5 )
|
||||
3: ( 4 5 )
|
||||
4: ( 1 3 6 )
|
||||
5: ( 2 3 6 )
|
||||
6: ( 2 3 4 )
|
||||
7: ( 1 3 5 )
|
||||
8: ( 0 3 6 )
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
igraph library.
|
||||
Copyright (C) 2013 Gabor Csardi <csardi.gabor@gmail.com>
|
||||
334 Harvard street, Cambridge, MA 02139 USA
|
||||
|
||||
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, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA
|
||||
*/
|
||||
|
||||
#include <igraph.h>
|
||||
|
||||
#include "../unit/test_utilities.h"
|
||||
|
||||
int main(void) {
|
||||
|
||||
igraph_t graph;
|
||||
igraph_vector_t mod;
|
||||
|
||||
igraph_empty(&graph, 25, IGRAPH_UNDIRECTED);
|
||||
igraph_vector_init(&mod, 0);
|
||||
igraph_community_multilevel(&graph, /*weights=*/ 0, /*resolution=*/ 1,
|
||||
/*membership=*/ 0, /*memberships=*/ 0, &mod);
|
||||
|
||||
if (igraph_vector_size(&mod) != 1 ||
|
||||
!isnan(VECTOR(mod)[0])) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
igraph_vector_destroy(&mod);
|
||||
igraph_destroy(&graph);
|
||||
|
||||
VERIFY_FINALLY_STACK();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,159 @@
|
||||
/*
|
||||
igraph library.
|
||||
Copyright (C) 2024 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 "../unit/test_utilities.h"
|
||||
|
||||
/* Regression test for https://github.com/igraph/igraph/issues/1760 */
|
||||
|
||||
int test_unweighted(const igraph_t* g, igraph_int_t from, const igraph_vs_t* to) {
|
||||
igraph_vector_int_list_t vpath, epath;
|
||||
igraph_int_t num_paths;
|
||||
igraph_vector_int_t parents;
|
||||
igraph_vector_int_t inbound_edges;
|
||||
|
||||
printf("Unweighted case\n");
|
||||
printf("---------------\n\n");
|
||||
|
||||
IGRAPH_CHECK(igraph_vs_size(g, to, &num_paths));
|
||||
IGRAPH_CHECK(igraph_vector_int_list_init(&vpath, 0));
|
||||
IGRAPH_CHECK(igraph_vector_int_list_init(&epath, 0));
|
||||
IGRAPH_CHECK(igraph_vector_int_init(&parents, 0));
|
||||
IGRAPH_CHECK(igraph_vector_int_init(&inbound_edges, 0));
|
||||
|
||||
IGRAPH_CHECK(igraph_get_shortest_paths(
|
||||
g, NULL, &vpath, &epath, from, *to, IGRAPH_IN,
|
||||
&parents, &inbound_edges
|
||||
));
|
||||
|
||||
printf("Vertices:\n");
|
||||
print_vector_int_list(&vpath);
|
||||
printf("\n");
|
||||
|
||||
printf("Edges:\n");
|
||||
print_vector_int_list(&epath);
|
||||
printf("\n");
|
||||
|
||||
printf("Parents:\n");
|
||||
print_vector_int(&parents);
|
||||
printf("\n");
|
||||
|
||||
printf("Inbound edges:\n");
|
||||
print_vector_int(&inbound_edges);
|
||||
printf("\n");
|
||||
|
||||
igraph_vector_int_destroy(&inbound_edges);
|
||||
igraph_vector_int_destroy(&parents);
|
||||
igraph_vector_int_list_destroy(&epath);
|
||||
igraph_vector_int_list_destroy(&vpath);
|
||||
|
||||
return IGRAPH_SUCCESS;
|
||||
}
|
||||
|
||||
int test_weighted(
|
||||
const igraph_t* g, const igraph_vector_t* weights, igraph_int_t from,
|
||||
const igraph_vs_t* to, igraph_bool_t use_bellman_ford
|
||||
) {
|
||||
igraph_vector_int_list_t vpath, epath;
|
||||
igraph_int_t num_paths;
|
||||
igraph_vector_int_t parents;
|
||||
igraph_vector_int_t inbound_edges;
|
||||
|
||||
printf("Weighted case\n");
|
||||
printf("-------------\n\n");
|
||||
|
||||
printf("Algorithm: %s\n\n", use_bellman_ford ? "Bellman-Ford" : "Dijkstra");
|
||||
|
||||
IGRAPH_CHECK(igraph_vs_size(g, to, &num_paths));
|
||||
IGRAPH_CHECK(igraph_vector_int_list_init(&vpath, 0));
|
||||
IGRAPH_CHECK(igraph_vector_int_list_init(&epath, 0));
|
||||
IGRAPH_CHECK(igraph_vector_int_init(&parents, 0));
|
||||
IGRAPH_CHECK(igraph_vector_int_init(&inbound_edges, 0));
|
||||
|
||||
if (use_bellman_ford) {
|
||||
IGRAPH_CHECK(igraph_get_shortest_paths_bellman_ford(
|
||||
g, &vpath, &epath, from, *to, weights, IGRAPH_IN,
|
||||
&parents, &inbound_edges
|
||||
));
|
||||
} else {
|
||||
IGRAPH_CHECK(igraph_get_shortest_paths_dijkstra(
|
||||
g, &vpath, &epath, from, *to, weights, IGRAPH_IN,
|
||||
&parents, &inbound_edges
|
||||
));
|
||||
}
|
||||
|
||||
printf("Vertices:\n");
|
||||
print_vector_int_list(&vpath);
|
||||
printf("\n");
|
||||
|
||||
printf("Edges:\n");
|
||||
print_vector_int_list(&epath);
|
||||
printf("\n");
|
||||
|
||||
printf("Parents:\n");
|
||||
print_vector_int(&parents);
|
||||
printf("\n");
|
||||
|
||||
printf("Inbound edges:\n");
|
||||
print_vector_int(&inbound_edges);
|
||||
printf("\n");
|
||||
|
||||
igraph_vector_int_destroy(&inbound_edges);
|
||||
igraph_vector_int_destroy(&parents);
|
||||
igraph_vector_int_list_destroy(&epath);
|
||||
igraph_vector_int_list_destroy(&vpath);
|
||||
|
||||
return IGRAPH_SUCCESS;
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
igraph_t g;
|
||||
igraph_vector_t weights;
|
||||
igraph_vs_t to;
|
||||
|
||||
igraph_set_warning_handler(igraph_warning_handler_ignore);
|
||||
|
||||
igraph_small(&g, 4, /* directed = */ 1, 0, 1, 1, 2, 1, 3, -1);
|
||||
igraph_vs_vector_small(&to, 0, 3, -1);
|
||||
igraph_vector_init(&weights, 3);
|
||||
VECTOR(weights)[0] = 1;
|
||||
VECTOR(weights)[1] = 2;
|
||||
VECTOR(weights)[2] = 2;
|
||||
|
||||
/* Test unweighted case */
|
||||
if (test_unweighted(&g, 2, &to)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Test weighted case */
|
||||
if (test_weighted(&g, &weights, 2, &to, /* use_bellman_ford = */ 0)) {
|
||||
return 2;
|
||||
}
|
||||
if (test_weighted(&g, &weights, 2, &to, /* use_bellman_ford = */ 1)) {
|
||||
return 3;
|
||||
}
|
||||
|
||||
igraph_vector_destroy(&weights);
|
||||
igraph_vs_destroy(&to);
|
||||
igraph_destroy(&g);
|
||||
|
||||
VERIFY_FINALLY_STACK();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
Unweighted case
|
||||
---------------
|
||||
|
||||
Vertices:
|
||||
{
|
||||
0: ( 2 1 0 )
|
||||
1: ( )
|
||||
}
|
||||
|
||||
Edges:
|
||||
{
|
||||
0: ( 1 0 )
|
||||
1: ( )
|
||||
}
|
||||
|
||||
Parents:
|
||||
( 1 2 -1 -2 )
|
||||
|
||||
Inbound edges:
|
||||
( 0 1 -1 -1 )
|
||||
|
||||
Weighted case
|
||||
-------------
|
||||
|
||||
Algorithm: Dijkstra
|
||||
|
||||
Vertices:
|
||||
{
|
||||
0: ( 2 1 0 )
|
||||
1: ( )
|
||||
}
|
||||
|
||||
Edges:
|
||||
{
|
||||
0: ( 1 0 )
|
||||
1: ( )
|
||||
}
|
||||
|
||||
Parents:
|
||||
( 1 2 -1 -2 )
|
||||
|
||||
Inbound edges:
|
||||
( 0 1 -1 -1 )
|
||||
|
||||
Weighted case
|
||||
-------------
|
||||
|
||||
Algorithm: Bellman-Ford
|
||||
|
||||
Vertices:
|
||||
{
|
||||
0: ( 2 1 0 )
|
||||
1: ( )
|
||||
}
|
||||
|
||||
Edges:
|
||||
{
|
||||
0: ( 1 0 )
|
||||
1: ( )
|
||||
}
|
||||
|
||||
Parents:
|
||||
( 1 2 -1 -2 )
|
||||
|
||||
Inbound edges:
|
||||
( 0 1 -1 -1 )
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
igraph library.
|
||||
Copyright (C) 2024 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 "../unit/test_utilities.h"
|
||||
|
||||
/* Regression test for https://github.com/igraph/igraph/issues/1814 */
|
||||
|
||||
void test_igraph_to_undirected(igraph_to_undirected_t mode) {
|
||||
igraph_t g;
|
||||
igraph_attribute_combination_t comb;
|
||||
|
||||
igraph_small(&g, 4, IGRAPH_DIRECTED,
|
||||
0,1, 0,1, 1,0,
|
||||
1,1, 1,1,
|
||||
-1);
|
||||
|
||||
SETEAN(&g, "weight", 0, 1);
|
||||
SETEAN(&g, "weight", 1, 2);
|
||||
SETEAN(&g, "weight", 2, 3);
|
||||
SETEAN(&g, "weight", 3, 4);
|
||||
SETEAN(&g, "weight", 4, 2);
|
||||
|
||||
igraph_attribute_combination(
|
||||
&comb, "weight", IGRAPH_ATTRIBUTE_COMBINE_SUM,
|
||||
IGRAPH_NO_MORE_ATTRIBUTES
|
||||
);
|
||||
igraph_to_undirected(&g, mode, &comb);
|
||||
igraph_attribute_combination_destroy(&comb);
|
||||
|
||||
igraph_write_graph_gml(&g, stdout, IGRAPH_WRITE_GML_DEFAULT_SW, 0, "");
|
||||
|
||||
igraph_destroy(&g);
|
||||
|
||||
VERIFY_FINALLY_STACK();
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
igraph_set_attribute_table(&igraph_cattribute_table);
|
||||
|
||||
printf("to_undirected(COLLAPSE)\n");
|
||||
printf("=======================\n\n");
|
||||
test_igraph_to_undirected(IGRAPH_TO_UNDIRECTED_COLLAPSE);
|
||||
printf("\n");
|
||||
|
||||
printf("to_undirected(MUTUAL)\n");
|
||||
printf("=====================\n\n");
|
||||
test_igraph_to_undirected(IGRAPH_TO_UNDIRECTED_MUTUAL);
|
||||
printf("\n");
|
||||
|
||||
printf("to_undirected(EACH)\n");
|
||||
printf("===================\n\n");
|
||||
test_igraph_to_undirected(IGRAPH_TO_UNDIRECTED_EACH);
|
||||
printf("\n");
|
||||
|
||||
VERIFY_FINALLY_STACK();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
to_undirected(COLLAPSE)
|
||||
=======================
|
||||
|
||||
Version 1
|
||||
graph
|
||||
[
|
||||
directed 0
|
||||
node
|
||||
[
|
||||
id 0
|
||||
]
|
||||
node
|
||||
[
|
||||
id 1
|
||||
]
|
||||
node
|
||||
[
|
||||
id 2
|
||||
]
|
||||
node
|
||||
[
|
||||
id 3
|
||||
]
|
||||
edge
|
||||
[
|
||||
source 1
|
||||
target 0
|
||||
weight 6
|
||||
]
|
||||
edge
|
||||
[
|
||||
source 1
|
||||
target 1
|
||||
weight 6
|
||||
]
|
||||
]
|
||||
|
||||
to_undirected(MUTUAL)
|
||||
=====================
|
||||
|
||||
Version 1
|
||||
graph
|
||||
[
|
||||
directed 0
|
||||
node
|
||||
[
|
||||
id 0
|
||||
]
|
||||
node
|
||||
[
|
||||
id 1
|
||||
]
|
||||
node
|
||||
[
|
||||
id 2
|
||||
]
|
||||
node
|
||||
[
|
||||
id 3
|
||||
]
|
||||
edge
|
||||
[
|
||||
source 1
|
||||
target 0
|
||||
weight 5
|
||||
]
|
||||
edge
|
||||
[
|
||||
source 1
|
||||
target 1
|
||||
weight 2
|
||||
]
|
||||
edge
|
||||
[
|
||||
source 1
|
||||
target 1
|
||||
weight 4
|
||||
]
|
||||
]
|
||||
|
||||
to_undirected(EACH)
|
||||
===================
|
||||
|
||||
Version 1
|
||||
graph
|
||||
[
|
||||
directed 0
|
||||
node
|
||||
[
|
||||
id 0
|
||||
]
|
||||
node
|
||||
[
|
||||
id 1
|
||||
]
|
||||
node
|
||||
[
|
||||
id 2
|
||||
]
|
||||
node
|
||||
[
|
||||
id 3
|
||||
]
|
||||
edge
|
||||
[
|
||||
source 1
|
||||
target 0
|
||||
weight 1
|
||||
]
|
||||
edge
|
||||
[
|
||||
source 1
|
||||
target 0
|
||||
weight 2
|
||||
]
|
||||
edge
|
||||
[
|
||||
source 1
|
||||
target 0
|
||||
weight 3
|
||||
]
|
||||
edge
|
||||
[
|
||||
source 1
|
||||
target 1
|
||||
weight 4
|
||||
]
|
||||
edge
|
||||
[
|
||||
source 1
|
||||
target 1
|
||||
weight 2
|
||||
]
|
||||
]
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
igraph library.
|
||||
Copyright (C) 2024 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 "../unit/test_utilities.h"
|
||||
|
||||
int main(void) {
|
||||
FILE *file;
|
||||
igraph_t graph;
|
||||
igraph_error_t err;
|
||||
|
||||
igraph_set_attribute_table(&igraph_cattribute_table);
|
||||
|
||||
igraph_set_error_handler(igraph_error_handler_printignore);
|
||||
|
||||
file = fopen("bug_1970.graphml", "r");
|
||||
IGRAPH_ASSERT(file != NULL);
|
||||
|
||||
err = igraph_read_graph_graphml(&graph, file, 0);
|
||||
fclose(file);
|
||||
IGRAPH_ASSERT(err != IGRAPH_SUCCESS);
|
||||
|
||||
/* graph creation should have failed, no need to destroy 'graph' */
|
||||
|
||||
VERIFY_FINALLY_STACK();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
<graphml><key id="one" for="edge" attr.type="double"/><key id="one" for="edge" attr.type="string"></key><graph></graph></graphml>
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
igraph library.
|
||||
Copyright (C) 2022 The igraph development team
|
||||
|
||||
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, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA
|
||||
|
||||
*/
|
||||
|
||||
#include <igraph.h>
|
||||
|
||||
#include "../unit/test_utilities.h"
|
||||
|
||||
/* Regression test for https://github.com/igraph/igraph/issues/2150 */
|
||||
|
||||
int main(void) {
|
||||
igraph_t graph;
|
||||
igraph_vector_t w;
|
||||
igraph_vector_int_list_t res;
|
||||
|
||||
igraph_full(&graph, 3, IGRAPH_UNDIRECTED, IGRAPH_NO_LOOPS);
|
||||
igraph_vector_init_int(&w, 3, 1, 2, 3);
|
||||
igraph_vector_int_list_init(&res, 0);
|
||||
|
||||
igraph_weighted_cliques(&graph, &w, &res, false, 1, 3, IGRAPH_UNLIMITED);
|
||||
|
||||
igraph_vector_int_list_destroy(&res);
|
||||
igraph_vector_destroy(&w);
|
||||
igraph_destroy(&graph);
|
||||
|
||||
VERIFY_FINALLY_STACK();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
igraph library.
|
||||
Copyright (C) 2024 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 "../unit/test_utilities.h"
|
||||
|
||||
int main(void) {
|
||||
FILE *file;
|
||||
igraph_t graph;
|
||||
|
||||
igraph_set_attribute_table(&igraph_cattribute_table);
|
||||
igraph_set_error_handler(igraph_error_handler_ignore);
|
||||
igraph_set_warning_handler(igraph_warning_handler_ignore);
|
||||
|
||||
file = fopen("bug_2497.gml", "r");
|
||||
IGRAPH_ASSERT(file != NULL);
|
||||
|
||||
IGRAPH_ASSERT(IGRAPH_FINALLY_STACK_EMPTY);
|
||||
IGRAPH_ASSERT(igraph_read_graph_gml(&graph, file) == IGRAPH_SUCCESS);
|
||||
IGRAPH_ASSERT(IGRAPH_FINALLY_STACK_EMPTY);
|
||||
|
||||
fclose(file);
|
||||
|
||||
igraph_write_graph_gml(&graph, stdout, IGRAPH_WRITE_GML_DEFAULT_SW, NULL, "");
|
||||
IGRAPH_ASSERT(IGRAPH_FINALLY_STACK_EMPTY);
|
||||
|
||||
igraph_destroy(&graph);
|
||||
|
||||
VERIFY_FINALLY_STACK();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
graph [
|
||||
node [ id 2 ]
|
||||
node [ ]
|
||||
]
|
||||
@@ -0,0 +1,13 @@
|
||||
Version 1
|
||||
graph
|
||||
[
|
||||
directed 0
|
||||
node
|
||||
[
|
||||
id 0
|
||||
]
|
||||
node
|
||||
[
|
||||
id 1
|
||||
]
|
||||
]
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
igraph library.
|
||||
Copyright (C) 2024 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 <stdio.h>
|
||||
|
||||
#include "../unit/test_utilities.h"
|
||||
|
||||
int main(void) {
|
||||
igraph_t g;
|
||||
igraph_error_t result;
|
||||
FILE *ifile;
|
||||
|
||||
igraph_set_error_handler(igraph_error_handler_ignore);
|
||||
|
||||
igraph_set_attribute_table(&igraph_cattribute_table);
|
||||
|
||||
ifile = fopen("bug_2506_1.graphml", "r");
|
||||
IGRAPH_ASSERT(ifile != NULL);
|
||||
|
||||
result = igraph_read_graph_graphml(&g, ifile, 0);
|
||||
fclose(ifile);
|
||||
|
||||
if (result == IGRAPH_UNIMPLEMENTED) {
|
||||
/* maybe it is simply disabled at compile-time */
|
||||
return 77;
|
||||
}
|
||||
|
||||
IGRAPH_ASSERT(result == IGRAPH_PARSEERROR);
|
||||
IGRAPH_ASSERT(IGRAPH_FINALLY_STACK_EMPTY);
|
||||
|
||||
ifile = fopen("bug_2506_2.graphml", "r");
|
||||
IGRAPH_ASSERT(ifile != NULL);
|
||||
|
||||
result = igraph_read_graph_graphml(&g, ifile, 0);
|
||||
fclose(ifile);
|
||||
|
||||
IGRAPH_ASSERT(result == IGRAPH_PARSEERROR);
|
||||
IGRAPH_ASSERT(IGRAPH_FINALLY_STACK_EMPTY);
|
||||
|
||||
ifile = fopen("bug_2506_3.graphml", "r");
|
||||
IGRAPH_ASSERT(ifile != NULL);
|
||||
|
||||
result = igraph_read_graph_graphml(&g, ifile, 0);
|
||||
fclose(ifile);
|
||||
|
||||
IGRAPH_ASSERT(result == IGRAPH_PARSEERROR);
|
||||
IGRAPH_ASSERT(IGRAPH_FINALLY_STACK_EMPTY);
|
||||
|
||||
VERIFY_FINALLY_STACK();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
<graphml>
|
||||
<key id="d3" for="" attr.type="s"></key><key id="d3" for="" attr.type=""></key>
|
||||
<graph></graph>
|
||||
</graphml>
|
||||
@@ -0,0 +1 @@
|
||||
<graphml><key id="" for="graph" attr.type="string"/><key id="" for="graph" attr.type="double"/><graph></graph></graphml>
|
||||
@@ -0,0 +1 @@
|
||||
<graphml><key id="e" for="graph" attr.name="" attr.type="string"/><key id="g" for="graph" attr.name="" attr.type="double"/><graph></graph></graphml>
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
igraph library.
|
||||
Copyright (C) 2024 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 "../unit/test_utilities.h"
|
||||
|
||||
int main(void) {
|
||||
igraph_t g;
|
||||
igraph_vector_int_list_t result;
|
||||
|
||||
igraph_vector_int_list_init(&result, 0);
|
||||
|
||||
igraph_small(&g, 2, IGRAPH_UNDIRECTED, 0, 1, -1);
|
||||
igraph_all_minimal_st_separators(&g, &result);
|
||||
print_vector_int_list(&result);
|
||||
igraph_destroy(&g);
|
||||
|
||||
igraph_small(&g, 3, IGRAPH_UNDIRECTED, 0, 1, -1);
|
||||
igraph_all_minimal_st_separators(&g, &result);
|
||||
print_vector_int_list(&result);
|
||||
igraph_destroy(&g);
|
||||
|
||||
igraph_vector_int_list_destroy(&result);
|
||||
|
||||
VERIFY_FINALLY_STACK();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
}
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
|
||||
/*
|
||||
igraph library.
|
||||
Copyright (C) 2007-2012 Gabor Csardi <csardi.gabor@gmail.com>
|
||||
334 Harvard street, Cambridge, MA 02139 USA
|
||||
|
||||
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, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA
|
||||
|
||||
*/
|
||||
|
||||
#include <igraph.h>
|
||||
|
||||
#include "../unit/test_utilities.h"
|
||||
|
||||
int main(void) {
|
||||
igraph_t g;
|
||||
igraph_vector_int_t membership;
|
||||
|
||||
/* label propagation is a stochastic method */
|
||||
igraph_rng_seed(igraph_rng_default(), 765);
|
||||
|
||||
igraph_small(&g, 0, /* directed = */ 1,
|
||||
0, 1, 0, 2, 1, 0, 1, 0, 1, 1, 2, 0, 2, 1, 2, 1, 2, 1, -1);
|
||||
igraph_vector_int_init(&membership, 0);
|
||||
|
||||
igraph_community_label_propagation(&g, &membership, IGRAPH_OUT, NULL, NULL, NULL, IGRAPH_LPA_FAST);
|
||||
|
||||
print_vector_int(&membership);
|
||||
igraph_vector_int_destroy(&membership);
|
||||
|
||||
igraph_destroy(&g);
|
||||
|
||||
VERIFY_FINALLY_STACK();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
igraph library.
|
||||
Copyright (C) 2024 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 <stdio.h>
|
||||
|
||||
#include "../unit/test_utilities.h"
|
||||
|
||||
void check_attr(igraph_t *graph) {
|
||||
IGRAPH_ASSERT(igraph_cattribute_has_attr(graph, IGRAPH_ATTRIBUTE_GRAPH, "name"));
|
||||
IGRAPH_ASSERT(igraph_cattribute_has_attr(graph, IGRAPH_ATTRIBUTE_GRAPH, "type"));
|
||||
IGRAPH_ASSERT(igraph_cattribute_has_attr(graph, IGRAPH_ATTRIBUTE_GRAPH, "p"));
|
||||
IGRAPH_ASSERT(igraph_cattribute_has_attr(graph, IGRAPH_ATTRIBUTE_VERTEX, "name"));
|
||||
IGRAPH_ASSERT(igraph_cattribute_has_attr(graph, IGRAPH_ATTRIBUTE_EDGE, "weight"));
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
|
||||
igraph_t graph;
|
||||
igraph_error_handler_t* oldhandler;
|
||||
int result;
|
||||
FILE *ifile = fopen("cattr_bool_bug.graphml", "r");
|
||||
|
||||
if (!ifile) {
|
||||
printf("Cannot open input file\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
igraph_set_attribute_table(&igraph_cattribute_table);
|
||||
|
||||
oldhandler = igraph_set_error_handler(igraph_error_handler_ignore);
|
||||
if ((result = igraph_read_graph_graphml(&graph, ifile, 0))) {
|
||||
/* Maybe it is simply disabled at compile-time. If so, skip test. */
|
||||
if (result == IGRAPH_UNIMPLEMENTED) {
|
||||
return 77;
|
||||
}
|
||||
printf("Failed to read GraphML file\n");
|
||||
return 1;
|
||||
}
|
||||
igraph_set_error_handler(oldhandler);
|
||||
|
||||
fclose(ifile);
|
||||
|
||||
printf("Checkng attributes of original graph\n");
|
||||
check_attr(&graph);
|
||||
|
||||
printf("Checkng attributes of directed version\n");
|
||||
igraph_to_directed(&graph, IGRAPH_TO_DIRECTED_ARBITRARY);
|
||||
check_attr(&graph);
|
||||
|
||||
IGRAPH_ASSERT(! GAB(&graph, "loops"));
|
||||
|
||||
igraph_destroy(&graph);
|
||||
|
||||
VERIFY_FINALLY_STACK();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<graphml xmlns="http://graphml.graphdrawing.org/xmlns"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns
|
||||
http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd">
|
||||
<!-- Created by igraph -->
|
||||
<key id="g_name" for="graph" attr.name="name" attr.type="string"/>
|
||||
<key id="g_type" for="graph" attr.name="type" attr.type="string"/>
|
||||
<key id="g_loops" for="graph" attr.name="loops" attr.type="boolean"/>
|
||||
<key id="g_p" for="graph" attr.name="p" attr.type="double"/>
|
||||
<key id="v_id" for="node" attr.name="name" attr.type="string"/>
|
||||
<key id="e_weight" for="edge" attr.name="weight" attr.type="double"/>
|
||||
<graph id="G" edgedefault="undirected">
|
||||
<data key="g_name">Erdos renyi (gnp) graph</data>
|
||||
<data key="g_type">gnp</data>
|
||||
<data key="g_loops">false</data>
|
||||
<data key="g_p">0.2</data>
|
||||
<node id="n0">
|
||||
<data key="v_id">n0</data>
|
||||
</node>
|
||||
<node id="n1">
|
||||
<data key="v_id">n1</data>
|
||||
</node>
|
||||
<node id="n2">
|
||||
<data key="v_id">n2</data>
|
||||
</node>
|
||||
<node id="n3">
|
||||
<data key="v_id">n3</data>
|
||||
</node>
|
||||
<node id="n4">
|
||||
<data key="v_id">n4</data>
|
||||
</node>
|
||||
<node id="n5">
|
||||
<data key="v_id">n5</data>
|
||||
</node>
|
||||
<node id="n6">
|
||||
<data key="v_id">n6</data>
|
||||
</node>
|
||||
<node id="n7">
|
||||
<data key="v_id">n7</data>
|
||||
</node>
|
||||
<node id="n8">
|
||||
<data key="v_id">n8</data>
|
||||
</node>
|
||||
<node id="n9">
|
||||
<data key="v_id">n9</data>
|
||||
</node>
|
||||
<edge source="n0" target="n1">
|
||||
<data key="e_weight">10</data>
|
||||
</edge>
|
||||
<edge source="n0" target="n3">
|
||||
<data key="e_weight">11</data>
|
||||
</edge>
|
||||
<edge source="n4" target="n5">
|
||||
<data key="e_weight">12</data>
|
||||
</edge>
|
||||
<edge source="n0" target="n6">
|
||||
<data key="e_weight">13</data>
|
||||
</edge>
|
||||
<edge source="n5" target="n6">
|
||||
<data key="e_weight">14</data>
|
||||
</edge>
|
||||
<edge source="n4" target="n7">
|
||||
<data key="e_weight">15</data>
|
||||
</edge>
|
||||
<edge source="n5" target="n7">
|
||||
<data key="e_weight">16</data>
|
||||
</edge>
|
||||
<edge source="n5" target="n9">
|
||||
<data key="e_weight">17</data>
|
||||
</edge>
|
||||
<edge source="n7" target="n9">
|
||||
<data key="e_weight">18</data>
|
||||
</edge>
|
||||
</graph>
|
||||
</graphml>
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
igraph library.
|
||||
Copyright (C) 2024 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 <stdio.h>
|
||||
|
||||
#include "../unit/test_utilities.h"
|
||||
|
||||
#define FILENAME "mybool.graphml.xml"
|
||||
|
||||
int main(void) {
|
||||
|
||||
igraph_t graph;
|
||||
igraph_error_handler_t* oldhandler;
|
||||
int result;
|
||||
FILE* ifile = fopen("cattr_bool_bug2.graphml", "r");
|
||||
|
||||
if (!ifile) {
|
||||
printf("Cannot open input file\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
igraph_set_attribute_table(&igraph_cattribute_table);
|
||||
|
||||
oldhandler = igraph_set_error_handler(igraph_error_handler_ignore);
|
||||
if ((result = igraph_read_graph_graphml(&graph, ifile, 0))) {
|
||||
/* maybe it is simply disabled at compile-time */
|
||||
if (result == IGRAPH_UNIMPLEMENTED) {
|
||||
return 77;
|
||||
}
|
||||
printf("Failed to read GraphML file\n");
|
||||
return 1;
|
||||
}
|
||||
igraph_set_error_handler(oldhandler);
|
||||
|
||||
fclose(ifile);
|
||||
|
||||
IGRAPH_ASSERT(igraph_cattribute_has_attr(&graph, IGRAPH_ATTRIBUTE_GRAPH, "mybool"));
|
||||
|
||||
/* Boolean attribute value is expected to be true */
|
||||
IGRAPH_ASSERT(igraph_cattribute_GAB(&graph, "mybool"));
|
||||
|
||||
igraph_destroy(&graph);
|
||||
|
||||
VERIFY_FINALLY_STACK();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd">
|
||||
<key attr.name="mybool" attr.type="boolean" for="graph" id="d0" />
|
||||
<graph edgedefault="undirected">
|
||||
<data key="d0">True</data>
|
||||
</graph>
|
||||
</graphml>
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
igraph library.
|
||||
Copyright (C) 2024 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 <stdio.h>
|
||||
|
||||
#include "../unit/test_utilities.h"
|
||||
|
||||
void snap_to_zero(igraph_real_t* value) {
|
||||
if (fabs(*value) < 1e-5) {
|
||||
*value = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
igraph_t graph;
|
||||
igraph_matrix_t layout;
|
||||
igraph_int_t i;
|
||||
|
||||
if (igraph_empty(&graph, 2, 0)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (igraph_add_edge(&graph, 0, 1)) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
if (igraph_matrix_init(&layout, 0, 0)) {
|
||||
return 3;
|
||||
}
|
||||
|
||||
if (igraph_layout_kamada_kawai_3d(&graph, &layout, 0, 200, 0, 2, 0, 0, 0, 0, 0, 0, 0)) {
|
||||
return 4;
|
||||
}
|
||||
|
||||
/* Snap numbers close to zero in the layout; there are false failures on
|
||||
* MinGW if we don't do so */
|
||||
for (i = 0; i < 2; i++) {
|
||||
snap_to_zero(&MATRIX(layout, i, 0));
|
||||
snap_to_zero(&MATRIX(layout, i, 1));
|
||||
snap_to_zero(&MATRIX(layout, i, 2));
|
||||
}
|
||||
print_matrix_format(&layout, stdout, "%.2f");
|
||||
|
||||
igraph_matrix_destroy(&layout);
|
||||
igraph_destroy(&graph);
|
||||
|
||||
VERIFY_FINALLY_STACK();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
[ 0.00 0.00 -0.91
|
||||
0.00 0.00 0.51 ]
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
igraph library.
|
||||
Copyright (C) 2006-2012 Gabor Csardi <csardi.gabor@gmail.com>
|
||||
334 Harvard st, Cambridge MA, 02139 USA
|
||||
|
||||
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, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA
|
||||
*/
|
||||
|
||||
#include <igraph.h>
|
||||
|
||||
#include "../unit/test_utilities.h"
|
||||
|
||||
int main(void) {
|
||||
|
||||
igraph_t g;
|
||||
FILE *f;
|
||||
igraph_matrix_t coords;
|
||||
igraph_vector_int_t roots;
|
||||
igraph_int_t i, n;
|
||||
|
||||
f = fopen("igraph_layout_reingold_tilford_bug_879.in", "r");
|
||||
IGRAPH_ASSERT(f != NULL);
|
||||
igraph_read_graph_edgelist(&g, f, 0, IGRAPH_UNDIRECTED);
|
||||
igraph_matrix_init(&coords, 0, 0);
|
||||
igraph_vector_int_init(&roots, 0);
|
||||
igraph_vector_int_push_back(&roots, 0);
|
||||
|
||||
igraph_layout_reingold_tilford(&g, &coords, IGRAPH_OUT, &roots, 0);
|
||||
|
||||
n = igraph_vcount(&g);
|
||||
for (i = 0; i < n; i++) {
|
||||
printf("%6.3f %6.3f\n", MATRIX(coords, i, 0), MATRIX(coords, i, 1));
|
||||
}
|
||||
|
||||
igraph_matrix_destroy(&coords);
|
||||
igraph_vector_int_destroy(&roots);
|
||||
igraph_destroy(&g);
|
||||
|
||||
VERIFY_FINALLY_STACK();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
0 1
|
||||
0 2
|
||||
0 3
|
||||
1 4
|
||||
2 5
|
||||
2 6
|
||||
3 7
|
||||
4 8
|
||||
4 9
|
||||
4 10
|
||||
4 11
|
||||
4 12
|
||||
7 13
|
||||
7 14
|
||||
7 15
|
||||
@@ -0,0 +1,16 @@
|
||||
0.000 0.000
|
||||
-1.833 1.000
|
||||
-0.333 1.000
|
||||
2.167 1.000
|
||||
-1.833 2.000
|
||||
-0.833 2.000
|
||||
0.167 2.000
|
||||
2.167 2.000
|
||||
-3.833 3.000
|
||||
-2.833 3.000
|
||||
-1.833 3.000
|
||||
-0.833 3.000
|
||||
0.167 3.000
|
||||
1.167 3.000
|
||||
2.167 3.000
|
||||
3.167 3.000
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
igraph library.
|
||||
Copyright (C) 2021-2022 The igraph development team
|
||||
|
||||
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, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA
|
||||
*/
|
||||
|
||||
#include <igraph.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "../unit/test_utilities.h"
|
||||
|
||||
int test_file(const char* fname) {
|
||||
FILE *ifile;
|
||||
igraph_t g;
|
||||
int retval;
|
||||
|
||||
ifile = fopen(fname, "r");
|
||||
if (ifile == 0) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
retval = igraph_read_graph_gml(&g, ifile);
|
||||
if (!retval) {
|
||||
/* input was accepted, this is a bug; attempt to clean up after
|
||||
* ourselves nevertheless */
|
||||
igraph_destroy(&g);
|
||||
fclose(ifile);
|
||||
return 2;
|
||||
}
|
||||
|
||||
fclose(ifile);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#undef RUN_TEST
|
||||
#define RUN_TEST(fname) { \
|
||||
index++; \
|
||||
if (test_file(fname)) { \
|
||||
return index; \
|
||||
} \
|
||||
VERIFY_FINALLY_STACK(); \
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
int index = 0;
|
||||
|
||||
/* We do not care about errors; all we care about is that the library
|
||||
* should not segfault and should not accept invalid input either */
|
||||
igraph_set_error_handler(igraph_error_handler_ignore);
|
||||
|
||||
RUN_TEST("invalid1.gml");
|
||||
RUN_TEST("invalid2.gml");
|
||||
/* invalid3.gml was removed, parser now supports it */
|
||||
RUN_TEST("invalid4.gml");
|
||||
RUN_TEST("invalid5.gml");
|
||||
RUN_TEST("invalid6.gml");
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
igraph library.
|
||||
Copyright (C) 2021 The igraph development team
|
||||
|
||||
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, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA
|
||||
*/
|
||||
|
||||
#include <igraph.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "../unit/test_utilities.h"
|
||||
|
||||
int test_file(const char* fname, igraph_bool_t should_parse) {
|
||||
FILE *ifile;
|
||||
igraph_t g;
|
||||
igraph_error_t retval;
|
||||
|
||||
ifile = fopen(fname, "r");
|
||||
if (ifile == 0) {
|
||||
printf("Cannot open input file: %s\n", fname);
|
||||
return 1;
|
||||
}
|
||||
|
||||
retval = igraph_read_graph_graphml(&g, ifile, 0);
|
||||
if (retval == IGRAPH_SUCCESS) {
|
||||
/* destroy the graph if we managed to parse it */
|
||||
igraph_destroy(&g);
|
||||
}
|
||||
|
||||
fclose(ifile);
|
||||
|
||||
if (!should_parse && retval == IGRAPH_SUCCESS) {
|
||||
/* input was accepted but it should not have been, this is a bug */
|
||||
return 2;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
#undef RUN_TEST
|
||||
#define RUN_TEST(fname, should_parse) { \
|
||||
index++; \
|
||||
if (test_file(fname, should_parse)) { \
|
||||
return index; \
|
||||
} \
|
||||
VERIFY_FINALLY_STACK(); \
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
int index = 0;
|
||||
|
||||
/* We do not care about errors; all we care about is that the library
|
||||
* should not segfault, should not accept invalid input and should not
|
||||
* print anything to stdout or stderr while parsing, apart from warnings */
|
||||
igraph_set_error_handler(igraph_error_handler_ignore);
|
||||
igraph_set_warning_handler(igraph_warning_handler_ignore);
|
||||
|
||||
RUN_TEST("invalid1.graphml", /* should_parse = */ 0);
|
||||
RUN_TEST("invalid2.graphml", /* should_parse = */ 1);
|
||||
RUN_TEST("invalid3.graphml", /* should_parse = */ 0);
|
||||
RUN_TEST("invalid4.graphml", /* should_parse = */ 0);
|
||||
RUN_TEST("invalid5.graphml", /* should_parse = */ 0);
|
||||
RUN_TEST("invalid6.graphml", /* should_parse = */ 0);
|
||||
|
||||
VERIFY_FINALLY_STACK();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
igraph library.
|
||||
Copyright (C) 2021 The igraph development team
|
||||
|
||||
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, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA
|
||||
*/
|
||||
|
||||
#include <igraph.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int test_file(const char* fname) {
|
||||
FILE *ifile;
|
||||
igraph_t g;
|
||||
int retval;
|
||||
|
||||
ifile = fopen(fname, "r");
|
||||
if (ifile == 0) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
retval = igraph_read_graph_pajek(&g, ifile);
|
||||
if (!retval) {
|
||||
/* input was accepted, this is a bug; attempt to clean up after
|
||||
* ourselves nevertheless */
|
||||
igraph_destroy(&g);
|
||||
fclose(ifile);
|
||||
return 2;
|
||||
}
|
||||
|
||||
fclose(ifile);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define RUN_TEST(fname) { \
|
||||
index++; \
|
||||
if (test_file(fname)) { \
|
||||
return index; \
|
||||
} \
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
int index = 0;
|
||||
|
||||
/* Turn on attribute handling */
|
||||
igraph_set_attribute_table(&igraph_cattribute_table);
|
||||
|
||||
/* We do not care about errors; all we care about is that the library
|
||||
* should not segfault and should not accept invalid input either */
|
||||
igraph_set_error_handler(igraph_error_handler_ignore);
|
||||
|
||||
RUN_TEST("invalid_pajek1.net");
|
||||
RUN_TEST("invalid_pajek2.net");
|
||||
RUN_TEST("invalid_pajek3.net");
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,463 @@
|
||||
Creator "Mark Newman on Fri Jul 21 12:39:27 2006"
|
||||
graph
|
||||
[
|
||||
ntde
|
||||
[
|
||||
id 1
|
||||
]
|
||||
node
|
||||
[
|
||||
id 2
|
||||
]
|
||||
node
|
||||
[
|
||||
id 3
|
||||
]
|
||||
node
|
||||
[
|
||||
id 4
|
||||
]
|
||||
node
|
||||
[
|
||||
id 5
|
||||
]
|
||||
node
|
||||
[
|
||||
id 6
|
||||
]
|
||||
node
|
||||
[
|
||||
id 7
|
||||
]
|
||||
node
|
||||
[
|
||||
id 8
|
||||
]
|
||||
node
|
||||
[
|
||||
id 9
|
||||
]
|
||||
node
|
||||
[
|
||||
id 10
|
||||
]
|
||||
node
|
||||
[
|
||||
id 11
|
||||
]
|
||||
node
|
||||
[
|
||||
id 12
|
||||
]
|
||||
node
|
||||
[
|
||||
id 13
|
||||
]
|
||||
node
|
||||
[
|
||||
id 14
|
||||
]
|
||||
node
|
||||
[
|
||||
id 15
|
||||
]
|
||||
node
|
||||
[
|
||||
id 16
|
||||
]
|
||||
node
|
||||
[
|
||||
id 17
|
||||
]
|
||||
node
|
||||
[
|
||||
id 18
|
||||
]
|
||||
node
|
||||
[
|
||||
id 19
|
||||
]
|
||||
node
|
||||
[
|
||||
id 20
|
||||
]
|
||||
node
|
||||
[
|
||||
id 21
|
||||
]
|
||||
node
|
||||
[
|
||||
id 22
|
||||
]
|
||||
node
|
||||
[
|
||||
id 23
|
||||
]
|
||||
node
|
||||
[
|
||||
id 24
|
||||
]
|
||||
node
|
||||
[
|
||||
id 25
|
||||
]
|
||||
node
|
||||
[
|
||||
id 26
|
||||
]
|
||||
node
|
||||
[
|
||||
id 27
|
||||
]
|
||||
node
|
||||
[
|
||||
id 28
|
||||
]
|
||||
node
|
||||
[
|
||||
id 29
|
||||
]
|
||||
node
|
||||
[
|
||||
id 30
|
||||
]
|
||||
node
|
||||
[
|
||||
id 31
|
||||
]
|
||||
node
|
||||
[
|
||||
id 32
|
||||
]
|
||||
node
|
||||
[
|
||||
id 33
|
||||
]
|
||||
node
|
||||
[
|
||||
id 34
|
||||
]
|
||||
edge
|
||||
[
|
||||
source 2
|
||||
target 1
|
||||
]
|
||||
edge
|
||||
[
|
||||
source 3
|
||||
target 1
|
||||
]
|
||||
edge
|
||||
[
|
||||
source 3
|
||||
target 2
|
||||
]
|
||||
edge
|
||||
[
|
||||
source 4
|
||||
target 1
|
||||
]
|
||||
edge
|
||||
[
|
||||
source 4
|
||||
target 2
|
||||
]
|
||||
edge
|
||||
[
|
||||
source 4
|
||||
target 3
|
||||
]
|
||||
edge
|
||||
[
|
||||
source 5
|
||||
target 1
|
||||
]
|
||||
edge
|
||||
[
|
||||
source 2
|
||||
target 1
|
||||
]
|
||||
edge
|
||||
[
|
||||
source 7
|
||||
target 1
|
||||
]
|
||||
edge
|
||||
[
|
||||
source 7
|
||||
target 5
|
||||
]
|
||||
edge
|
||||
[
|
||||
source 7
|
||||
target 6
|
||||
]
|
||||
edge
|
||||
[
|
||||
source 8
|
||||
target 1
|
||||
]
|
||||
edge
|
||||
[
|
||||
source 8
|
||||
target 2
|
||||
]
|
||||
edge
|
||||
[
|
||||
source 8
|
||||
target 3
|
||||
]
|
||||
edge
|
||||
[
|
||||
source 8
|
||||
target 4
|
||||
]
|
||||
edge
|
||||
[
|
||||
source 9
|
||||
target 1
|
||||
]
|
||||
edge
|
||||
[
|
||||
source 9
|
||||
target 3
|
||||
]
|
||||
edge
|
||||
[
|
||||
source 10
|
||||
target 3
|
||||
]
|
||||
edge
|
||||
[
|
||||
source 11
|
||||
target 1
|
||||
|
||||
source 20
|
||||
target 1
|
||||
]
|
||||
edge
|
||||
[
|
||||
source 20
|
||||
target 2
|
||||
]
|
||||
edge
|
||||
[
|
||||
source 22
|
||||
target 1
|
||||
]
|
||||
edge
|
||||
[
|
||||
source 22
|
||||
target 2
|
||||
]
|
||||
edge
|
||||
[
|
||||
source 26
|
||||
target 24
|
||||
]
|
||||
edge
|
||||
[
|
||||
source 26
|
||||
target 25
|
||||
]
|
||||
edge
|
||||
[
|
||||
source 28
|
||||
target 3
|
||||
]
|
||||
edge
|
||||
[
|
||||
source 28
|
||||
target 24
|
||||
]
|
||||
edge
|
||||
[
|
||||
source 28
|
||||
target 25
|
||||
]
|
||||
edge
|
||||
[
|
||||
source 29
|
||||
target 3
|
||||
]
|
||||
edge
|
||||
[
|
||||
source 30
|
||||
target 24
|
||||
]
|
||||
edge
|
||||
[
|
||||
source 30
|
||||
target 27
|
||||
]
|
||||
edge
|
||||
[
|
||||
source 31
|
||||
target 2
|
||||
]
|
||||
edge
|
||||
[
|
||||
source 31
|
||||
target 9
|
||||
]
|
||||
edge
|
||||
[
|
||||
source 32
|
||||
target 1
|
||||
]
|
||||
edge
|
||||
[
|
||||
source 32
|
||||
target 25
|
||||
]
|
||||
edge
|
||||
[
|
||||
source 32
|
||||
target 26
|
||||
]
|
||||
edge
|
||||
[
|
||||
source 32
|
||||
target 29
|
||||
]
|
||||
edge
|
||||
[
|
||||
source 33
|
||||
target 3
|
||||
]
|
||||
edge
|
||||
[
|
||||
source 33
|
||||
target 9
|
||||
]
|
||||
edge
|
||||
[
|
||||
source 33
|
||||
target 15
|
||||
]
|
||||
edge
|
||||
[
|
||||
source 33
|
||||
target 16
|
||||
]
|
||||
edge
|
||||
[
|
||||
source 33
|
||||
target 19
|
||||
]
|
||||
edge
|
||||
[
|
||||
source 33
|
||||
target 21
|
||||
]
|
||||
edge
|
||||
[
|
||||
source 33
|
||||
target 23
|
||||
]
|
||||
edge
|
||||
[
|
||||
source 33
|
||||
target 24
|
||||
]
|
||||
edge
|
||||
[
|
||||
source 33
|
||||
target 30
|
||||
]
|
||||
edge
|
||||
[
|
||||
source 33
|
||||
target 31
|
||||
]
|
||||
edge
|
||||
[
|
||||
source 33
|
||||
target 32
|
||||
]
|
||||
edge
|
||||
[
|
||||
source 34
|
||||
target 9
|
||||
]
|
||||
edge
|
||||
[
|
||||
source 34
|
||||
target 10
|
||||
]
|
||||
edge
|
||||
[
|
||||
source 34
|
||||
target 14
|
||||
]
|
||||
edge
|
||||
[
|
||||
source 34
|
||||
target 15
|
||||
]
|
||||
edge
|
||||
[
|
||||
source 34
|
||||
target 16
|
||||
]
|
||||
edge
|
||||
[
|
||||
source 34
|
||||
target 19
|
||||
]
|
||||
edge
|
||||
[
|
||||
source 34
|
||||
target 20
|
||||
]
|
||||
edge
|
||||
[
|
||||
source 34
|
||||
target 21
|
||||
]
|
||||
edge
|
||||
[
|
||||
source 34
|
||||
target 23
|
||||
]
|
||||
edge
|
||||
[
|
||||
source 34
|
||||
target 24
|
||||
]
|
||||
edge
|
||||
[
|
||||
source 34
|
||||
target 27
|
||||
]
|
||||
edge
|
||||
[
|
||||
source 34
|
||||
target 28
|
||||
]
|
||||
edge
|
||||
[
|
||||
source 34
|
||||
target 29
|
||||
]
|
||||
edge
|
||||
[
|
||||
source 17
|
||||
target 30
|
||||
]
|
||||
edge
|
||||
[
|
||||
source 34
|
||||
target 31
|
||||
]
|
||||
edge
|
||||
[
|
||||
source 34
|
||||
target 32
|
||||
]
|
||||
edge
|
||||
[
|
||||
source 34
|
||||
target 33
|
||||
]
|
||||
]
|
||||
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.5" encoding="UTF-8"?>
|
||||
<!-- This file was written b JAVA GraphML Library.-->
|
||||
<graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlnheuaLocation="http://graphml.graphdrawing.org/xmlns http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd">
|
||||
<key id="d0" for="nodd" attr.name="color" attr.type="string">
|
||||
<default>yellow</default>
|
||||
</key>
|
||||
<key id="d1" for="edge" attr.name="weight" attr.type="double"/>
|
||||
<key id="d2" for="graph" attr.name="date" attr.type="string"></key>
|
||||
<key id="d3" for="graph" attr.name="uòused" attr.type="string"></key>
|
||||
<key id="d4" for="node" attr.name="gender" attr.type="boolean">
|
||||
, <default>1</default>
|
||||
</key>
|
||||
<graph id="G" edgedefault="undirected">
|
||||
<data key="d2">2006-11-12*</data>
|
||||
<node idey="d0">blue</data>
|
||||
</edge>
|
||||
</graph>
|
||||
</graphml>
|
||||
@@ -0,0 +1 @@
|
||||
d 1
|
||||
@@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- This file wa2s written idJAVA GraphML Library.-->
|
||||
<graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:xsi="http://www.w4.org/2001/XM/graphml.graphdrawisd">
|
||||
<key id="d0" for="node" attr.name="color" attr.type="string">
|
||||
<default>yellow</default>
|
||||
</key>
|
||||
<key id="d1" for="edge" attr.name="weigrt" attr.type="double"/>
|
||||
<key id="d2" for="graph" attr.ttr.type="string">
|
||||
@ <default>yellow</default>we </key>
|
||||
<key id="d1" for="edge" attr.name="weight" attr.type="double"/>
|
||||
"http://graphml.graphdrawingg/2001/XMLrawing.org/xmlns/1.0/graphml.xsd">
|
||||
<key id="d0" for="node" attr.name="color" attr.type="string">
|
||||
<default>yellow</default>
|
||||
</key>
|
||||
<key id="d1" for="edge" attr.name="weight" attr.type="double"/>
|
||||
|
||||
<key id="d2" for="graph" attr.ttr.type="string">
|
||||
@ <default>yellow</default>we </key>
|
||||
<key id="d1" for="edge" attr.name="weight" attr.typ="unused" attr.type="string"></key>
|
||||
<key id="d3" for="node" attr.name="gender" attr.type="boolean">
|
||||
<default>1</default>
|
||||
</key>
|
||||
<graph id="G" edgedefaud="n0">
|
||||
/edge>
|
||||
</graph>
|
||||
</graphml>
|
||||
@@ -0,0 +1 @@
|
||||
Version-0
|
||||
Binary file not shown.
@@ -0,0 +1,4 @@
|
||||
graph[node[a
|
||||
r
|
||||
r P p
|
||||
r d v]]
|
||||
@@ -0,0 +1,30 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- y.-->
|
||||
<graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmxsi="httce"
|
||||
>
|
||||
<key id="d0" for="node" attr.name="y" attr.type="string">yellYw</key>
|
||||
<key id="d1" for="edge" attr.name="wt" attr.type="do"/>
|
||||
<key id="d2" for="graph" attr.name="date" attr.type="string"></key>
|
||||
<key id="d3" for="graph" attr.name="ed" attr.type="string"></key>
|
||||
<key id="d4" for="node" attr.name="gr" attr.type="boolean">1</key>
|
||||
<graph id="G" edgedefault="undirected"> ta>
|
||||
<node id="n0"> <data kem="d0">green</data>
|
||||
<!-- ing -->
|
||||
<data key="d4">true</data>
|
||||
</node>
|
||||
<node id="n1"/>
|
||||
<node id="n2">
|
||||
<data wey="d ">blue</data>
|
||||
<data key="d4">0</data> </node> <node id="n3">
|
||||
<data key="d%">red "w"</data>
|
||||
</node>
|
||||
<node id="n4"> <data k5y="d0"><!-- ey --></data> <data key="d4">false</data>
|
||||
</node>
|
||||
<node id="n5">
|
||||
<data key="d0">t</data>
|
||||
<data Hey="d4">
|
||||
i <key id="sing" for="edge" ae="de"/>
|
||||
<key id="" atype="double"/>
|
||||
<key id="sinik" forype="double"/>
|
||||
<key id="si" for="edge" attme="in" e="de"/>
|
||||
<id="
|
||||
@@ -0,0 +1 @@
|
||||
graph[node[id 2]edge[source 2targetrgett 2]]
|
||||
@@ -0,0 +1 @@
|
||||
<graphml><key id="" xmlns:xi="http://graphml.graphdrawing.org/xmlns" xi:id=""
|
||||
@@ -0,0 +1 @@
|
||||
*Vertices 1 3
|
||||
@@ -0,0 +1,3 @@
|
||||
*Network TRALALA
|
||||
*vertices 4 1
|
||||
0 "3."
|
||||
@@ -0,0 +1,2 @@
|
||||
%foo
|
||||
*Vertices 1 2 1
|
||||
@@ -0,0 +1,167 @@
|
||||
/*
|
||||
igraph library.
|
||||
Copyright (C) 2008-2012 Gabor Csardi <csardi.gabor@gmail.com>
|
||||
334 Harvard street, Cambridge, MA 02139 USA
|
||||
|
||||
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, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA
|
||||
|
||||
*/
|
||||
|
||||
#include <igraph.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "core/indheap.h"
|
||||
|
||||
#include "test_utilities.h"
|
||||
|
||||
int main(void) {
|
||||
|
||||
igraph_vector_t elems;
|
||||
igraph_2wheap_t Q;
|
||||
igraph_int_t i;
|
||||
igraph_real_t prev = IGRAPH_INFINITY;
|
||||
|
||||
igraph_rng_seed(igraph_rng_default(), 42); /* make tests deterministic */
|
||||
|
||||
igraph_vector_init(&elems, 100);
|
||||
for (i = 0; i < igraph_vector_size(&elems); i++) {
|
||||
VECTOR(elems)[i] = RNG_UNIF01();
|
||||
}
|
||||
|
||||
igraph_2wheap_init(&Q, igraph_vector_size(&elems));
|
||||
for (i = 0; i < igraph_vector_size(&elems); i++) {
|
||||
igraph_2wheap_push_with_index(&Q, i, VECTOR(elems)[i]);
|
||||
}
|
||||
|
||||
/*****/
|
||||
|
||||
for (i = 0; i < igraph_vector_size(&elems); i++) {
|
||||
if (VECTOR(elems)[i] != igraph_2wheap_get(&Q, i)) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*****/
|
||||
|
||||
for (i = 0; i < igraph_vector_size(&elems); i++) {
|
||||
igraph_int_t j;
|
||||
igraph_real_t tmp = igraph_2wheap_max(&Q);
|
||||
if (tmp > prev) {
|
||||
return 2;
|
||||
}
|
||||
if (tmp != igraph_2wheap_delete_max_index(&Q, &j)) {
|
||||
return 3;
|
||||
}
|
||||
if (VECTOR(elems)[j] != tmp) {
|
||||
return 4;
|
||||
}
|
||||
prev = tmp;
|
||||
}
|
||||
|
||||
/*****/
|
||||
|
||||
for (i = 0; i < igraph_vector_size(&elems); i++) {
|
||||
igraph_2wheap_push_with_index(&Q, i, VECTOR(elems)[i]);
|
||||
}
|
||||
if (igraph_2wheap_size(&Q) != igraph_vector_size(&elems)) {
|
||||
return 5;
|
||||
}
|
||||
for (i = 0; i < igraph_vector_size(&elems); i++) {
|
||||
VECTOR(elems)[i] = RNG_UNIF01();
|
||||
igraph_2wheap_modify(&Q, i, VECTOR(elems)[i]);
|
||||
}
|
||||
for (i = 0; i < igraph_vector_size(&elems); i++) {
|
||||
if (VECTOR(elems)[i] != igraph_2wheap_get(&Q, i)) {
|
||||
return 6;
|
||||
}
|
||||
}
|
||||
prev = IGRAPH_INFINITY;
|
||||
for (i = 0; i < igraph_vector_size(&elems); i++) {
|
||||
igraph_int_t j;
|
||||
igraph_real_t tmp = igraph_2wheap_max(&Q);
|
||||
if (tmp > prev) {
|
||||
return 7;
|
||||
}
|
||||
if (tmp != igraph_2wheap_delete_max_index(&Q, &j)) {
|
||||
return 8;
|
||||
}
|
||||
if (VECTOR(elems)[j] != tmp) {
|
||||
return 9;
|
||||
}
|
||||
prev = tmp;
|
||||
}
|
||||
if (!igraph_2wheap_empty(&Q)) {
|
||||
return 10;
|
||||
}
|
||||
if (igraph_2wheap_size(&Q) != 0) {
|
||||
return 11;
|
||||
}
|
||||
|
||||
igraph_2wheap_destroy(&Q);
|
||||
igraph_vector_destroy(&elems);
|
||||
|
||||
/* Hand-made example */
|
||||
|
||||
#define MAX do { igraph_2wheap_delete_max(&Q); igraph_2wheap_check(&Q); } while (0)
|
||||
#define PUSH(i,e) do { igraph_2wheap_push_with_index(&Q, (i), -(e)); igraph_2wheap_check(&Q); } while (0);
|
||||
#define MOD(i, e) do { igraph_2wheap_modify(&Q, (i), -(e)); igraph_2wheap_check(&Q); } while (0)
|
||||
|
||||
igraph_2wheap_init(&Q, 21);
|
||||
/* 0.00 [ 4] */ PUSH(4, 0);
|
||||
/* MAX */ MAX;
|
||||
/* 0.63 [11] */ PUSH(11, 0.63);
|
||||
/* 0.05 [15] */ PUSH(15, 0.05);
|
||||
/* MAX */ MAX;
|
||||
/* 0.4 [12] */ PUSH(12, 0.4);
|
||||
/* 0.4 [13] */ PUSH(13, 0.4);
|
||||
/* 0.12 [16] */ PUSH(16, 0.12);
|
||||
/* MAX */ MAX;
|
||||
/* 1.1 [ 0] */ PUSH(0, 1.1);
|
||||
/* 1.1 [14] */ PUSH(14, 1.1);
|
||||
/* MAX */ MAX;
|
||||
/* [11]/0.44 */ MOD(11, 0.44);
|
||||
/* MAX */ MAX;
|
||||
/* MAX */ MAX;
|
||||
/* 1.1 [20] */ PUSH(20, 1.1);
|
||||
/* MAX */ MAX;
|
||||
/* 1.3 [ 7] */ PUSH(7, 1.3);
|
||||
/* 1.7 [ 9] */ PUSH(9, 1.7);
|
||||
/* MAX */ MAX;
|
||||
/* 1.6 [19] */ PUSH(19, 1.6);
|
||||
/* MAX */ MAX;
|
||||
/* 2.1 [17] */ PUSH(17, 2.1);
|
||||
/* 1.3 [18] */ PUSH(18, 1.3);
|
||||
/* MAX */ MAX;
|
||||
/* 2.3 [ 1] */ PUSH(1, 2.3);
|
||||
/* 2.2 [ 5] */ PUSH(5, 2.2);
|
||||
/* 2.3 [10] */ PUSH(10, 2.3);
|
||||
/* MAX */ MAX;
|
||||
/* [17]/1.5 */ MOD(17, 1.5);
|
||||
/* MAX */ MAX;
|
||||
/* 1.8 [ 6] */ PUSH(6, 1.8);
|
||||
/* MAX */ MAX;
|
||||
/* 1.3 [ 3] */ PUSH(3, 1.3);
|
||||
/* [ 6]/1.3 */ MOD(6, 1.3);
|
||||
/* MAX */ MAX;
|
||||
/* 1.6 [ 8] */ PUSH(8, 1.6);
|
||||
/* MAX */ MAX;
|
||||
|
||||
igraph_2wheap_destroy(&Q);
|
||||
|
||||
VERIFY_FINALLY_STACK();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,257 @@
|
||||
/*
|
||||
igraph library.
|
||||
Copyright (C) 2012 Gabor Csardi <csardi.gabor@gmail.com>
|
||||
334 Harvard street, Cambridge, MA 02139 USA
|
||||
|
||||
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, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA
|
||||
|
||||
*/
|
||||
|
||||
#include <igraph.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "test_utilities.h"
|
||||
|
||||
/* ----------------------------------------------------------- */
|
||||
|
||||
/* Vertices/edges with the same parity match */
|
||||
igraph_bool_t compat_parity(const igraph_t *graph1,
|
||||
const igraph_t *graph2,
|
||||
const igraph_int_t g1_num,
|
||||
const igraph_int_t g2_num,
|
||||
void *arg) {
|
||||
IGRAPH_UNUSED(graph1);
|
||||
IGRAPH_UNUSED(graph2);
|
||||
IGRAPH_UNUSED(arg);
|
||||
return (g1_num % 2) == (g2_num % 2);
|
||||
}
|
||||
|
||||
/* Nothing vertex/edge 0 in graph1 */
|
||||
igraph_bool_t compat_not0(const igraph_t *graph1,
|
||||
const igraph_t *graph2,
|
||||
const igraph_int_t g1_num,
|
||||
const igraph_int_t g2_num,
|
||||
void *arg) {
|
||||
IGRAPH_UNUSED(graph1);
|
||||
IGRAPH_UNUSED(graph2);
|
||||
IGRAPH_UNUSED(arg);
|
||||
IGRAPH_UNUSED(g2_num);
|
||||
return g1_num != 0;
|
||||
}
|
||||
|
||||
int match_rings(void) {
|
||||
|
||||
igraph_t r1, r2;
|
||||
igraph_bool_t iso;
|
||||
igraph_int_t count;
|
||||
igraph_ring(&r1, 10, /*directed=*/ 0, /*mutual=*/ 0, /*circular=*/ 1);
|
||||
igraph_ring(&r2, 10, /*directed=*/ 0, /*mutual=*/ 0, /*circular=*/ 1);
|
||||
|
||||
igraph_isomorphic_vf2(&r1, &r2, /*colors(4x)*/ 0, 0, 0, 0,
|
||||
&iso, /*map12=*/ 0, /*map21=*/ 0,
|
||||
/*node_compat_fn=*/ 0, /*edge_compat_fn=*/ 0,
|
||||
/*arg=*/ 0);
|
||||
if (!iso) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
igraph_isomorphic_vf2(&r1, &r2, /*colors(4x)*/ 0, 0, 0, 0,
|
||||
&iso, /*map12=*/ 0, /*map21=*/ 0,
|
||||
compat_parity, /*edge_compat_fn=*/ 0, /*arg=*/ 0);
|
||||
if (!iso) {
|
||||
exit(2);
|
||||
}
|
||||
|
||||
igraph_isomorphic_vf2(&r1, &r2, /*colors(4x)*/ 0, 0, 0, 0,
|
||||
&iso, /*map12=*/ 0, /*map21=*/ 0,
|
||||
compat_not0, /*edge_compat_fn=*/ 0, /*arg=*/ 0);
|
||||
if (iso) {
|
||||
exit(3);
|
||||
}
|
||||
|
||||
/* ------- */
|
||||
|
||||
igraph_isomorphic_vf2(&r1, &r2, /*colors(4x)*/ 0, 0, 0, 0,
|
||||
&iso, /*map12=*/ 0, /*map21=*/ 0,
|
||||
/*node_compat_fn=*/ 0, compat_parity, /*arg=*/ 0);
|
||||
if (!iso) {
|
||||
exit(4);
|
||||
}
|
||||
|
||||
igraph_isomorphic_vf2(&r1, &r2, /*colors(4x)*/ 0, 0, 0, 0,
|
||||
&iso, /*map12=*/ 0, /*map21=*/ 0,
|
||||
/*node_compat_fn=*/ 0, compat_not0, /*arg=*/ 0);
|
||||
if (iso) {
|
||||
exit(5);
|
||||
}
|
||||
|
||||
/* ------- */
|
||||
|
||||
igraph_count_isomorphisms_vf2(&r1, &r2, /*colors(4x)*/ 0, 0, 0, 0,
|
||||
&count, /*node_compat_fn=*/ 0,
|
||||
/*edge_compat_fn=*/ 0, /*arg=*/ 0);
|
||||
|
||||
if (count != 20) {
|
||||
exit(6);
|
||||
}
|
||||
|
||||
igraph_count_isomorphisms_vf2(&r1, &r2, /*colors(4x)*/ 0, 0, 0, 0,
|
||||
&count, compat_parity, /*edge_compat_fn=*/ 0,
|
||||
/*arg=*/ 0);
|
||||
|
||||
if (count != 10) {
|
||||
exit(7);
|
||||
}
|
||||
|
||||
igraph_count_isomorphisms_vf2(&r1, &r2, /*colors(4x)*/ 0, 0, 0, 0,
|
||||
&count, compat_not0, /*edge_compat_fn=*/ 0,
|
||||
/*arg=*/ 0);
|
||||
|
||||
if (count != 0) {
|
||||
exit(8);
|
||||
}
|
||||
|
||||
/* ------- */
|
||||
|
||||
igraph_count_isomorphisms_vf2(&r1, &r2, /*colors(4x)*/ 0, 0, 0, 0,
|
||||
&count, /*node_compat_fn=*/ 0, compat_parity,
|
||||
/*arg=*/ 0);
|
||||
|
||||
if (count != 10) {
|
||||
exit(9);
|
||||
}
|
||||
|
||||
igraph_count_isomorphisms_vf2(&r1, &r2, /*colors(4x)*/ 0, 0, 0, 0,
|
||||
&count, /*node_compat_fn=*/ 0, compat_not0,
|
||||
/*arg=*/ 0);
|
||||
|
||||
if (count != 0) {
|
||||
exit(10);
|
||||
}
|
||||
|
||||
igraph_destroy(&r1);
|
||||
igraph_destroy(&r2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int match_rings_open_closed(void) {
|
||||
igraph_t ro, rc;
|
||||
igraph_bool_t iso;
|
||||
igraph_int_t count;
|
||||
igraph_ring(&ro, 10, /*directed=*/ 0, /*mutual=*/ 0, /*circular=*/ 0);
|
||||
igraph_ring(&rc, 10, /*directed=*/ 0, /*mutual=*/ 0, /*circular=*/ 1);
|
||||
|
||||
igraph_subisomorphic_vf2(&rc, &ro, /*colors(4x)*/ 0, 0, 0, 0,
|
||||
&iso, /*map12=*/ 0, /*map21=*/ 0,
|
||||
/*node_compat_fn=*/ 0, /*edge_compat_fn=*/ 0,
|
||||
/*arg=*/ 0);
|
||||
if (!iso) {
|
||||
exit(31);
|
||||
}
|
||||
|
||||
igraph_subisomorphic_vf2(&rc, &ro, /*colors(4x)*/ 0, 0, 0, 0,
|
||||
&iso, /*map12=*/ 0, /*map21=*/ 0,
|
||||
compat_parity, /*edge_compat_fn=*/ 0,
|
||||
/*arg=*/ 0);
|
||||
if (!iso) {
|
||||
exit(32);
|
||||
}
|
||||
|
||||
igraph_subisomorphic_vf2(&rc, &ro, /*colors(4x)*/ 0, 0, 0, 0,
|
||||
&iso, /*map12=*/ 0, /*map21=*/ 0,
|
||||
compat_not0, /*edge_compat_fn=*/ 0,
|
||||
/*arg=*/ 0);
|
||||
if (iso) {
|
||||
exit(33);
|
||||
}
|
||||
|
||||
/* ------- */
|
||||
|
||||
igraph_subisomorphic_vf2(&rc, &ro, /*colors(4x)*/ 0, 0, 0, 0,
|
||||
&iso, /*map12=*/ 0, /*map21=*/ 0,
|
||||
/*node_compat_fn=*/ 0, compat_parity,
|
||||
/*arg=*/ 0);
|
||||
if (!iso) {
|
||||
exit(34);
|
||||
}
|
||||
|
||||
igraph_subisomorphic_vf2(&rc, &ro, /*colors(4x)*/ 0, 0, 0, 0,
|
||||
&iso, /*map12=*/ 0, /*map21=*/ 0,
|
||||
/*node_compat_fn=*/ 0, compat_not0,
|
||||
/*arg=*/ 0);
|
||||
if (!iso) {
|
||||
exit(35);
|
||||
}
|
||||
|
||||
/* ------- */
|
||||
|
||||
igraph_count_subisomorphisms_vf2(&rc, &ro, /*colors(4x)*/ 0, 0, 0, 0,
|
||||
&count, /*node_compat_fn=*/ 0,
|
||||
/*edge_compat_fn=*/ 0, /*arg=*/ 0);
|
||||
|
||||
if (count != 20) {
|
||||
exit(36);
|
||||
}
|
||||
|
||||
igraph_count_subisomorphisms_vf2(&rc, &ro, /*colors(4x)*/ 0, 0, 0, 0,
|
||||
&count, compat_parity,
|
||||
/*edge_compat_fn=*/ 0, /*arg=*/ 0);
|
||||
|
||||
if (count != 10) {
|
||||
exit(37);
|
||||
}
|
||||
|
||||
igraph_count_subisomorphisms_vf2(&rc, &ro, /*colors(4x)*/ 0, 0, 0, 0,
|
||||
&count, compat_not0, /*edge_compat_fn=*/ 0,
|
||||
/*arg=*/ 0);
|
||||
|
||||
if (count != 0) {
|
||||
exit(38);
|
||||
}
|
||||
|
||||
/* ------- */
|
||||
|
||||
igraph_count_subisomorphisms_vf2(&rc, &ro, /*colors(4x)*/ 0, 0, 0, 0,
|
||||
&count, /*node_compat_fn=*/ 0,
|
||||
compat_parity, /*arg=*/ 0);
|
||||
|
||||
if (count != 10) {
|
||||
exit(39);
|
||||
}
|
||||
|
||||
igraph_count_subisomorphisms_vf2(&rc, &ro, /*colors(4x)*/ 0, 0, 0, 0,
|
||||
&count, /*node_compat_fn=*/ 0, compat_not0,
|
||||
/*arg=*/ 0);
|
||||
|
||||
if (count != 2) {
|
||||
exit(40);
|
||||
}
|
||||
|
||||
igraph_destroy(&ro);
|
||||
igraph_destroy(&rc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------- */
|
||||
|
||||
int main(void) {
|
||||
match_rings();
|
||||
match_rings_open_closed();
|
||||
|
||||
VERIFY_FINALLY_STACK();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,305 @@
|
||||
/*
|
||||
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"
|
||||
|
||||
void print_params(const igraph_t *graph, igraph_neimode_t mode, igraph_loops_t loops) {
|
||||
printf(igraph_is_directed(graph) ? "directed; " : "undirected; ");
|
||||
switch (mode) {
|
||||
case IGRAPH_ALL: printf("ALL; "); break;
|
||||
case IGRAPH_OUT: printf("OUT; "); break;
|
||||
case IGRAPH_IN : printf("IN; "); break;
|
||||
}
|
||||
switch (loops) {
|
||||
case IGRAPH_NO_LOOPS: printf("NO_LOOPS; "); break;
|
||||
case IGRAPH_LOOPS_ONCE: printf("LOOPS_ONCE; "); break;
|
||||
case IGRAPH_LOOPS_TWICE: printf("LOOPS_TWICE; "); break;
|
||||
}
|
||||
}
|
||||
|
||||
void print_multiple(igraph_bool_t multiple) {
|
||||
printf(multiple ? "MULTIPLE; " : "NO_MULTIPLE; ");
|
||||
}
|
||||
|
||||
/* Print adjacency list based on igraph_neighbors() */
|
||||
void print_adj1(const igraph_t *graph, igraph_neimode_t mode, igraph_loops_t loops, igraph_bool_t multiple) {
|
||||
igraph_int_t vcount = igraph_vcount(graph);
|
||||
igraph_vector_int_t neis;
|
||||
|
||||
print_params(graph, mode, loops);
|
||||
print_multiple(multiple);
|
||||
printf("\n");
|
||||
|
||||
igraph_vector_int_init(&neis, 0);
|
||||
for (igraph_int_t v=0; v < vcount; v++) {
|
||||
printf("%3" IGRAPH_PRId ": ", v);
|
||||
igraph_neighbors(graph, &neis, v, mode, loops, multiple);
|
||||
print_vector_int(&neis);
|
||||
}
|
||||
igraph_vector_int_destroy(&neis);
|
||||
}
|
||||
|
||||
/* Print adjacency list based on igraph_adjlist_init() */
|
||||
void print_adj2(const igraph_t *graph, igraph_neimode_t mode, igraph_loops_t loops, igraph_bool_t multiple) {
|
||||
igraph_int_t vcount = igraph_vcount(graph);
|
||||
igraph_adjlist_t al;
|
||||
|
||||
print_params(graph, mode, loops);
|
||||
print_multiple(multiple);
|
||||
printf("\n");
|
||||
|
||||
igraph_adjlist_init(graph, &al, mode, loops, multiple);
|
||||
for (igraph_int_t v=0; v < vcount; v++) {
|
||||
printf("%3" IGRAPH_PRId ": ", v);
|
||||
print_vector_int(igraph_adjlist_get(&al, v));
|
||||
}
|
||||
igraph_adjlist_destroy(&al);
|
||||
}
|
||||
|
||||
/* Print incidence list based on igraph_incident() */
|
||||
void print_inc1(const igraph_t *graph, igraph_neimode_t mode, igraph_loops_t loops) {
|
||||
igraph_int_t vcount = igraph_vcount(graph);
|
||||
igraph_vector_int_t incs;
|
||||
|
||||
print_params(graph, mode, loops);
|
||||
printf("\n");
|
||||
|
||||
igraph_vector_int_init(&incs, 0);
|
||||
for (igraph_int_t v=0; v < vcount; v++) {
|
||||
printf("%3" IGRAPH_PRId ": ", v);
|
||||
igraph_incident(graph, &incs, v, mode, loops);
|
||||
print_vector_int(&incs);
|
||||
}
|
||||
igraph_vector_int_destroy(&incs);
|
||||
}
|
||||
|
||||
/* Print incidence list based on igraph_inclist_init() */
|
||||
void print_inc2(const igraph_t *graph, igraph_neimode_t mode, igraph_loops_t loops) {
|
||||
igraph_int_t vcount = igraph_vcount(graph);
|
||||
igraph_inclist_t il;
|
||||
|
||||
print_params(graph, mode, loops);
|
||||
printf("\n");
|
||||
|
||||
igraph_inclist_init(graph, &il, mode, loops);
|
||||
for (igraph_int_t v=0; v < vcount; v++) {
|
||||
printf("%3" IGRAPH_PRId ": ", v);
|
||||
print_vector_int(igraph_inclist_get(&il, v));
|
||||
}
|
||||
igraph_inclist_destroy(&il);
|
||||
}
|
||||
|
||||
/* Verifies that igraph_neighbors() and igraph_incident() produce results in the same order. */
|
||||
void verify_ordering1(const igraph_t *graph, igraph_neimode_t mode, igraph_loops_t loops) {
|
||||
igraph_vector_int_t neis, incs;
|
||||
igraph_int_t vcount = igraph_vcount(graph);
|
||||
|
||||
if (! igraph_is_directed(graph)) {
|
||||
mode = IGRAPH_ALL;
|
||||
}
|
||||
|
||||
igraph_vector_int_init(&neis, 0);
|
||||
igraph_vector_int_init(&incs, 0);
|
||||
|
||||
for (igraph_int_t v=0; v < vcount; v++) {
|
||||
igraph_neighbors(graph, &neis, v, mode, loops, IGRAPH_MULTIPLE);
|
||||
igraph_incident(graph, &incs, v, mode, loops);
|
||||
|
||||
igraph_int_t n = igraph_vector_int_size(&neis);
|
||||
IGRAPH_ASSERT(igraph_vector_int_size(&incs) == n);
|
||||
|
||||
for (igraph_int_t i=0; i < n; i++) {
|
||||
igraph_int_t u1, u2;
|
||||
|
||||
u1 = VECTOR(neis)[i];
|
||||
switch (mode) {
|
||||
case IGRAPH_ALL: u2 = IGRAPH_OTHER(graph, VECTOR(incs)[i], v); break;
|
||||
case IGRAPH_OUT: u2 = IGRAPH_TO(graph, VECTOR(incs)[i]); break;
|
||||
case IGRAPH_IN: u2 = IGRAPH_FROM(graph, VECTOR(incs)[i]); break;
|
||||
}
|
||||
|
||||
if (u1 != u2) {
|
||||
IGRAPH_FATALF(
|
||||
"For vertex %d, the %dth neighbor vertex between adj (%d) and inc (%d) differs.",
|
||||
(int) v, (int) i, (int) u1, (int) u2
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
igraph_vector_int_destroy(&incs);
|
||||
igraph_vector_int_destroy(&neis);
|
||||
}
|
||||
|
||||
/* Verifies that igraph_adjlist_init() and igraph_inclist_init() produce results in the same order. */
|
||||
void verify_ordering2(const igraph_t *graph, igraph_neimode_t mode, igraph_loops_t loops) {
|
||||
igraph_adjlist_t al;
|
||||
igraph_inclist_t il;
|
||||
|
||||
igraph_int_t vcount = igraph_vcount(graph);
|
||||
|
||||
if (! igraph_is_directed(graph)) {
|
||||
mode = IGRAPH_ALL;
|
||||
}
|
||||
|
||||
igraph_adjlist_init(graph, &al, mode, loops, IGRAPH_MULTIPLE);
|
||||
igraph_inclist_init(graph, &il, mode, loops);
|
||||
|
||||
for (igraph_int_t v=0; v < vcount; v++) {
|
||||
igraph_vector_int_t *neis = igraph_adjlist_get(&al, v);
|
||||
igraph_vector_int_t *incs = igraph_inclist_get(&il, v);
|
||||
|
||||
igraph_int_t n = igraph_vector_int_size(neis);
|
||||
IGRAPH_ASSERT(igraph_vector_int_size(incs) == n);
|
||||
|
||||
for (igraph_int_t i=0; i < n; i++) {
|
||||
igraph_int_t u1, u2;
|
||||
|
||||
u1 = VECTOR(*neis)[i];
|
||||
switch (mode) {
|
||||
case IGRAPH_ALL: u2 = IGRAPH_OTHER(graph, VECTOR(*incs)[i], v); break;
|
||||
case IGRAPH_OUT: u2 = IGRAPH_TO(graph, VECTOR(*incs)[i]); break;
|
||||
case IGRAPH_IN: u2 = IGRAPH_FROM(graph, VECTOR(*incs)[i]); break;
|
||||
}
|
||||
|
||||
if (u1 != u2) {
|
||||
IGRAPH_FATALF(
|
||||
"For vertex %d, the %dth neighbor vertex between adj (%d) and inc (%d) differs.",
|
||||
(int) v, (int) i, (int) u1, (int) u2
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
igraph_adjlist_destroy(&al);
|
||||
igraph_inclist_destroy(&il);
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
igraph_t dg, ug;
|
||||
|
||||
igraph_small(&dg, 7, IGRAPH_DIRECTED,
|
||||
// 0 1 2 3 4 5 6 7 8 9 10 11 12
|
||||
4,4, 0,3, 0,3, 2,3, 1,4, 2,4, 3,4, 3,2, 4,4, 2,3, 1,1, 6,6, 6,6,
|
||||
-1);
|
||||
|
||||
igraph_copy(&ug, &dg);
|
||||
igraph_to_undirected(&ug, IGRAPH_TO_UNDIRECTED_EACH, NULL);
|
||||
|
||||
printf("UNDIRECTED\n\n");
|
||||
|
||||
printf("igraph_neighbors()\n");
|
||||
print_adj1(&ug, IGRAPH_ALL, IGRAPH_NO_LOOPS, IGRAPH_MULTIPLE);
|
||||
print_adj1(&ug, IGRAPH_ALL, IGRAPH_LOOPS_ONCE, IGRAPH_MULTIPLE);
|
||||
print_adj1(&ug, IGRAPH_ALL, IGRAPH_LOOPS_TWICE, IGRAPH_MULTIPLE);
|
||||
|
||||
printf("\nigraph_adjlist_init()\n");
|
||||
print_adj2(&ug, IGRAPH_ALL, IGRAPH_NO_LOOPS, IGRAPH_MULTIPLE);
|
||||
print_adj2(&ug, IGRAPH_ALL, IGRAPH_LOOPS_ONCE, IGRAPH_MULTIPLE);
|
||||
print_adj2(&ug, IGRAPH_ALL, IGRAPH_LOOPS_TWICE, IGRAPH_MULTIPLE);
|
||||
|
||||
printf("\nigraph_incident()\n");
|
||||
print_inc1(&ug, IGRAPH_ALL, IGRAPH_NO_LOOPS);
|
||||
print_inc1(&ug, IGRAPH_ALL, IGRAPH_LOOPS_ONCE);
|
||||
print_inc1(&ug, IGRAPH_ALL, IGRAPH_LOOPS_TWICE);
|
||||
|
||||
printf("\nigraph_inclist_init()\n");
|
||||
print_inc2(&ug, IGRAPH_ALL, IGRAPH_NO_LOOPS);
|
||||
print_inc2(&ug, IGRAPH_ALL, IGRAPH_LOOPS_ONCE);
|
||||
print_inc2(&ug, IGRAPH_ALL, IGRAPH_LOOPS_TWICE);
|
||||
|
||||
printf("\nDIRECTED ALL\n\n");
|
||||
|
||||
printf("igraph_neighbors()\n");
|
||||
print_adj1(&dg, IGRAPH_ALL, IGRAPH_NO_LOOPS, IGRAPH_MULTIPLE);
|
||||
print_adj1(&dg, IGRAPH_ALL, IGRAPH_LOOPS_ONCE, IGRAPH_MULTIPLE);
|
||||
print_adj1(&dg, IGRAPH_ALL, IGRAPH_LOOPS_TWICE, IGRAPH_MULTIPLE);
|
||||
|
||||
printf("\nigraph_adjlist_init()\n");
|
||||
print_adj2(&dg, IGRAPH_ALL, IGRAPH_NO_LOOPS, IGRAPH_MULTIPLE);
|
||||
print_adj2(&dg, IGRAPH_ALL, IGRAPH_LOOPS_ONCE, IGRAPH_MULTIPLE);
|
||||
print_adj2(&dg, IGRAPH_ALL, IGRAPH_LOOPS_TWICE, IGRAPH_MULTIPLE);
|
||||
|
||||
printf("\nigraph_incident()\n");
|
||||
print_inc1(&dg, IGRAPH_ALL, IGRAPH_NO_LOOPS);
|
||||
print_inc1(&dg, IGRAPH_ALL, IGRAPH_LOOPS_ONCE);
|
||||
print_inc1(&dg, IGRAPH_ALL, IGRAPH_LOOPS_TWICE);
|
||||
|
||||
printf("\nigraph_inclist_init()\n");
|
||||
print_inc2(&dg, IGRAPH_ALL, IGRAPH_NO_LOOPS);
|
||||
print_inc2(&dg, IGRAPH_ALL, IGRAPH_LOOPS_ONCE);
|
||||
print_inc2(&dg, IGRAPH_ALL, IGRAPH_LOOPS_TWICE);
|
||||
|
||||
printf("\nDIRECTED OUT\n\n");
|
||||
|
||||
printf("igraph_neighbors()\n");
|
||||
print_adj1(&dg, IGRAPH_OUT, IGRAPH_NO_LOOPS, IGRAPH_MULTIPLE);
|
||||
print_adj1(&dg, IGRAPH_OUT, IGRAPH_LOOPS_ONCE, IGRAPH_MULTIPLE);
|
||||
|
||||
printf("\nigraph_adjlist_init()\n");
|
||||
print_adj2(&dg, IGRAPH_OUT, IGRAPH_NO_LOOPS, IGRAPH_MULTIPLE);
|
||||
print_adj2(&dg, IGRAPH_OUT, IGRAPH_LOOPS_ONCE, IGRAPH_MULTIPLE);
|
||||
|
||||
printf("\nigraph_incident()\n");
|
||||
print_inc1(&dg, IGRAPH_OUT, IGRAPH_NO_LOOPS);
|
||||
print_inc1(&dg, IGRAPH_OUT, IGRAPH_LOOPS_ONCE);
|
||||
|
||||
printf("\nigraph_inclist_init()\n");
|
||||
print_inc2(&dg, IGRAPH_OUT, IGRAPH_NO_LOOPS);
|
||||
print_inc2(&dg, IGRAPH_OUT, IGRAPH_LOOPS_ONCE);
|
||||
|
||||
/* Verify that neighbour lists (adjlist) and incident edge lists (inclist)
|
||||
* have the same ordering with all parameter combinations. */
|
||||
|
||||
verify_ordering1(&ug, IGRAPH_ALL, IGRAPH_NO_LOOPS);
|
||||
verify_ordering1(&ug, IGRAPH_ALL, IGRAPH_LOOPS_ONCE);
|
||||
verify_ordering1(&ug, IGRAPH_ALL, IGRAPH_LOOPS_TWICE);
|
||||
|
||||
verify_ordering1(&dg, IGRAPH_ALL, IGRAPH_NO_LOOPS);
|
||||
verify_ordering1(&dg, IGRAPH_ALL, IGRAPH_LOOPS_ONCE);
|
||||
verify_ordering1(&dg, IGRAPH_ALL, IGRAPH_LOOPS_TWICE);
|
||||
|
||||
verify_ordering1(&dg, IGRAPH_OUT, IGRAPH_NO_LOOPS);
|
||||
verify_ordering1(&dg, IGRAPH_OUT, IGRAPH_LOOPS_ONCE);
|
||||
|
||||
verify_ordering1(&dg, IGRAPH_IN, IGRAPH_NO_LOOPS);
|
||||
verify_ordering1(&dg, IGRAPH_IN, IGRAPH_LOOPS_ONCE);
|
||||
|
||||
verify_ordering2(&ug, IGRAPH_ALL, IGRAPH_NO_LOOPS);
|
||||
verify_ordering2(&ug, IGRAPH_ALL, IGRAPH_LOOPS_ONCE);
|
||||
verify_ordering2(&ug, IGRAPH_ALL, IGRAPH_LOOPS_TWICE);
|
||||
|
||||
verify_ordering2(&dg, IGRAPH_ALL, IGRAPH_NO_LOOPS);
|
||||
verify_ordering2(&dg, IGRAPH_ALL, IGRAPH_LOOPS_ONCE);
|
||||
verify_ordering2(&dg, IGRAPH_ALL, IGRAPH_LOOPS_TWICE);
|
||||
|
||||
verify_ordering2(&dg, IGRAPH_OUT, IGRAPH_NO_LOOPS);
|
||||
verify_ordering2(&dg, IGRAPH_OUT, IGRAPH_LOOPS_ONCE);
|
||||
|
||||
verify_ordering2(&dg, IGRAPH_IN, IGRAPH_NO_LOOPS);
|
||||
verify_ordering2(&dg, IGRAPH_IN, IGRAPH_LOOPS_ONCE);
|
||||
|
||||
igraph_destroy(&ug);
|
||||
igraph_destroy(&dg);
|
||||
|
||||
VERIFY_FINALLY_STACK();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,285 @@
|
||||
UNDIRECTED
|
||||
|
||||
igraph_neighbors()
|
||||
undirected; ALL; NO_LOOPS; MULTIPLE;
|
||||
0: ( 3 3 )
|
||||
1: ( 4 )
|
||||
2: ( 3 3 3 4 )
|
||||
3: ( 0 0 2 2 2 4 )
|
||||
4: ( 1 2 3 )
|
||||
5: ( )
|
||||
6: ( )
|
||||
undirected; ALL; LOOPS_ONCE; MULTIPLE;
|
||||
0: ( 3 3 )
|
||||
1: ( 1 4 )
|
||||
2: ( 3 3 3 4 )
|
||||
3: ( 0 0 2 2 2 4 )
|
||||
4: ( 1 2 3 4 4 )
|
||||
5: ( )
|
||||
6: ( 6 6 )
|
||||
undirected; ALL; LOOPS_TWICE; MULTIPLE;
|
||||
0: ( 3 3 )
|
||||
1: ( 1 1 4 )
|
||||
2: ( 3 3 3 4 )
|
||||
3: ( 0 0 2 2 2 4 )
|
||||
4: ( 1 2 3 4 4 4 4 )
|
||||
5: ( )
|
||||
6: ( 6 6 6 6 )
|
||||
|
||||
igraph_adjlist_init()
|
||||
undirected; ALL; NO_LOOPS; MULTIPLE;
|
||||
0: ( 3 3 )
|
||||
1: ( 4 )
|
||||
2: ( 3 3 3 4 )
|
||||
3: ( 0 0 2 2 2 4 )
|
||||
4: ( 1 2 3 )
|
||||
5: ( )
|
||||
6: ( )
|
||||
undirected; ALL; LOOPS_ONCE; MULTIPLE;
|
||||
0: ( 3 3 )
|
||||
1: ( 1 4 )
|
||||
2: ( 3 3 3 4 )
|
||||
3: ( 0 0 2 2 2 4 )
|
||||
4: ( 1 2 3 4 4 )
|
||||
5: ( )
|
||||
6: ( 6 6 )
|
||||
undirected; ALL; LOOPS_TWICE; MULTIPLE;
|
||||
0: ( 3 3 )
|
||||
1: ( 1 1 4 )
|
||||
2: ( 3 3 3 4 )
|
||||
3: ( 0 0 2 2 2 4 )
|
||||
4: ( 1 2 3 4 4 4 4 )
|
||||
5: ( )
|
||||
6: ( 6 6 6 6 )
|
||||
|
||||
igraph_incident()
|
||||
undirected; ALL; NO_LOOPS;
|
||||
0: ( 2 1 )
|
||||
1: ( 4 )
|
||||
2: ( 9 7 3 5 )
|
||||
3: ( 2 1 9 7 3 6 )
|
||||
4: ( 4 5 6 )
|
||||
5: ( )
|
||||
6: ( )
|
||||
undirected; ALL; LOOPS_ONCE;
|
||||
0: ( 2 1 )
|
||||
1: ( 10 4 )
|
||||
2: ( 9 7 3 5 )
|
||||
3: ( 2 1 9 7 3 6 )
|
||||
4: ( 4 5 6 8 0 )
|
||||
5: ( )
|
||||
6: ( 12 11 )
|
||||
undirected; ALL; LOOPS_TWICE;
|
||||
0: ( 2 1 )
|
||||
1: ( 10 10 4 )
|
||||
2: ( 9 7 3 5 )
|
||||
3: ( 2 1 9 7 3 6 )
|
||||
4: ( 4 5 6 8 0 8 0 )
|
||||
5: ( )
|
||||
6: ( 12 11 12 11 )
|
||||
|
||||
igraph_inclist_init()
|
||||
undirected; ALL; NO_LOOPS;
|
||||
0: ( 2 1 )
|
||||
1: ( 4 )
|
||||
2: ( 9 7 3 5 )
|
||||
3: ( 2 1 9 7 3 6 )
|
||||
4: ( 4 5 6 )
|
||||
5: ( )
|
||||
6: ( )
|
||||
undirected; ALL; LOOPS_ONCE;
|
||||
0: ( 2 1 )
|
||||
1: ( 10 4 )
|
||||
2: ( 9 7 3 5 )
|
||||
3: ( 2 1 9 7 3 6 )
|
||||
4: ( 4 5 6 8 0 )
|
||||
5: ( )
|
||||
6: ( 12 11 )
|
||||
undirected; ALL; LOOPS_TWICE;
|
||||
0: ( 2 1 )
|
||||
1: ( 10 10 4 )
|
||||
2: ( 9 7 3 5 )
|
||||
3: ( 2 1 9 7 3 6 )
|
||||
4: ( 4 5 6 8 0 8 0 )
|
||||
5: ( )
|
||||
6: ( 12 11 12 11 )
|
||||
|
||||
DIRECTED ALL
|
||||
|
||||
igraph_neighbors()
|
||||
directed; ALL; NO_LOOPS; MULTIPLE;
|
||||
0: ( 3 3 )
|
||||
1: ( 4 )
|
||||
2: ( 3 3 3 4 )
|
||||
3: ( 0 0 2 2 2 4 )
|
||||
4: ( 1 2 3 )
|
||||
5: ( )
|
||||
6: ( )
|
||||
directed; ALL; LOOPS_ONCE; MULTIPLE;
|
||||
0: ( 3 3 )
|
||||
1: ( 1 4 )
|
||||
2: ( 3 3 3 4 )
|
||||
3: ( 0 0 2 2 2 4 )
|
||||
4: ( 1 2 3 4 4 )
|
||||
5: ( )
|
||||
6: ( 6 6 )
|
||||
directed; ALL; LOOPS_TWICE; MULTIPLE;
|
||||
0: ( 3 3 )
|
||||
1: ( 1 1 4 )
|
||||
2: ( 3 3 3 4 )
|
||||
3: ( 0 0 2 2 2 4 )
|
||||
4: ( 1 2 3 4 4 4 4 )
|
||||
5: ( )
|
||||
6: ( 6 6 6 6 )
|
||||
|
||||
igraph_adjlist_init()
|
||||
directed; ALL; NO_LOOPS; MULTIPLE;
|
||||
0: ( 3 3 )
|
||||
1: ( 4 )
|
||||
2: ( 3 3 3 4 )
|
||||
3: ( 0 0 2 2 2 4 )
|
||||
4: ( 1 2 3 )
|
||||
5: ( )
|
||||
6: ( )
|
||||
directed; ALL; LOOPS_ONCE; MULTIPLE;
|
||||
0: ( 3 3 )
|
||||
1: ( 1 4 )
|
||||
2: ( 3 3 3 4 )
|
||||
3: ( 0 0 2 2 2 4 )
|
||||
4: ( 1 2 3 4 4 )
|
||||
5: ( )
|
||||
6: ( 6 6 )
|
||||
directed; ALL; LOOPS_TWICE; MULTIPLE;
|
||||
0: ( 3 3 )
|
||||
1: ( 1 1 4 )
|
||||
2: ( 3 3 3 4 )
|
||||
3: ( 0 0 2 2 2 4 )
|
||||
4: ( 1 2 3 4 4 4 4 )
|
||||
5: ( )
|
||||
6: ( 6 6 6 6 )
|
||||
|
||||
igraph_incident()
|
||||
directed; ALL; NO_LOOPS;
|
||||
0: ( 2 1 )
|
||||
1: ( 4 )
|
||||
2: ( 9 7 3 5 )
|
||||
3: ( 2 1 7 9 3 6 )
|
||||
4: ( 4 5 6 )
|
||||
5: ( )
|
||||
6: ( )
|
||||
directed; ALL; LOOPS_ONCE;
|
||||
0: ( 2 1 )
|
||||
1: ( 10 4 )
|
||||
2: ( 9 7 3 5 )
|
||||
3: ( 2 1 7 9 3 6 )
|
||||
4: ( 4 5 6 8 0 )
|
||||
5: ( )
|
||||
6: ( 12 11 )
|
||||
directed; ALL; LOOPS_TWICE;
|
||||
0: ( 2 1 )
|
||||
1: ( 10 10 4 )
|
||||
2: ( 9 7 3 5 )
|
||||
3: ( 2 1 7 9 3 6 )
|
||||
4: ( 4 5 6 8 8 0 0 )
|
||||
5: ( )
|
||||
6: ( 12 12 11 11 )
|
||||
|
||||
igraph_inclist_init()
|
||||
directed; ALL; NO_LOOPS;
|
||||
0: ( 2 1 )
|
||||
1: ( 4 )
|
||||
2: ( 9 7 3 5 )
|
||||
3: ( 2 1 7 9 3 6 )
|
||||
4: ( 4 5 6 )
|
||||
5: ( )
|
||||
6: ( )
|
||||
directed; ALL; LOOPS_ONCE;
|
||||
0: ( 2 1 )
|
||||
1: ( 10 4 )
|
||||
2: ( 9 7 3 5 )
|
||||
3: ( 2 1 7 9 3 6 )
|
||||
4: ( 4 5 6 8 0 )
|
||||
5: ( )
|
||||
6: ( 12 11 )
|
||||
directed; ALL; LOOPS_TWICE;
|
||||
0: ( 2 1 )
|
||||
1: ( 10 10 4 )
|
||||
2: ( 9 7 3 5 )
|
||||
3: ( 2 1 7 9 3 6 )
|
||||
4: ( 4 5 6 8 8 0 0 )
|
||||
5: ( )
|
||||
6: ( 12 12 11 11 )
|
||||
|
||||
DIRECTED OUT
|
||||
|
||||
igraph_neighbors()
|
||||
directed; OUT; NO_LOOPS; MULTIPLE;
|
||||
0: ( 3 3 )
|
||||
1: ( 4 )
|
||||
2: ( 3 3 4 )
|
||||
3: ( 2 4 )
|
||||
4: ( )
|
||||
5: ( )
|
||||
6: ( )
|
||||
directed; OUT; LOOPS_ONCE; MULTIPLE;
|
||||
0: ( 3 3 )
|
||||
1: ( 1 4 )
|
||||
2: ( 3 3 4 )
|
||||
3: ( 2 4 )
|
||||
4: ( 4 4 )
|
||||
5: ( )
|
||||
6: ( 6 6 )
|
||||
|
||||
igraph_adjlist_init()
|
||||
directed; OUT; NO_LOOPS; MULTIPLE;
|
||||
0: ( 3 3 )
|
||||
1: ( 4 )
|
||||
2: ( 3 3 4 )
|
||||
3: ( 2 4 )
|
||||
4: ( )
|
||||
5: ( )
|
||||
6: ( )
|
||||
directed; OUT; LOOPS_ONCE; MULTIPLE;
|
||||
0: ( 3 3 )
|
||||
1: ( 1 4 )
|
||||
2: ( 3 3 4 )
|
||||
3: ( 2 4 )
|
||||
4: ( 4 4 )
|
||||
5: ( )
|
||||
6: ( 6 6 )
|
||||
|
||||
igraph_incident()
|
||||
directed; OUT; NO_LOOPS;
|
||||
0: ( 2 1 )
|
||||
1: ( 4 )
|
||||
2: ( 9 3 5 )
|
||||
3: ( 7 6 )
|
||||
4: ( )
|
||||
5: ( )
|
||||
6: ( )
|
||||
directed; OUT; LOOPS_ONCE;
|
||||
0: ( 2 1 )
|
||||
1: ( 10 4 )
|
||||
2: ( 9 3 5 )
|
||||
3: ( 7 6 )
|
||||
4: ( 8 0 )
|
||||
5: ( )
|
||||
6: ( 12 11 )
|
||||
|
||||
igraph_inclist_init()
|
||||
directed; OUT; NO_LOOPS;
|
||||
0: ( 2 1 )
|
||||
1: ( 4 )
|
||||
2: ( 9 3 5 )
|
||||
3: ( 7 6 )
|
||||
4: ( )
|
||||
5: ( )
|
||||
6: ( )
|
||||
directed; OUT; LOOPS_ONCE;
|
||||
0: ( 2 1 )
|
||||
1: ( 10 4 )
|
||||
2: ( 9 3 5 )
|
||||
3: ( 7 6 )
|
||||
4: ( 8 0 )
|
||||
5: ( )
|
||||
6: ( 12 11 )
|
||||
@@ -0,0 +1,348 @@
|
||||
/*
|
||||
igraph library.
|
||||
Copyright (C) 2021 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"
|
||||
|
||||
int test_simple_trees(void) {
|
||||
igraph_t g, g2;
|
||||
igraph_adjlist_t adjlist;
|
||||
igraph_bool_t iso;
|
||||
|
||||
/* Directed, out */
|
||||
igraph_kary_tree(&g, 42, 3, IGRAPH_TREE_OUT);
|
||||
igraph_adjlist_init(&g, &adjlist, IGRAPH_OUT, IGRAPH_LOOPS_ONCE, IGRAPH_MULTIPLE);
|
||||
igraph_adjlist(&g2, &adjlist, IGRAPH_OUT, /*duplicate=*/ 0);
|
||||
igraph_isomorphic(&g, &g2, &iso);
|
||||
IGRAPH_ASSERT(iso);
|
||||
igraph_adjlist_destroy(&adjlist);
|
||||
igraph_destroy(&g2);
|
||||
igraph_destroy(&g);
|
||||
|
||||
/* Directed, in */
|
||||
igraph_kary_tree(&g, 42, 3, IGRAPH_TREE_OUT);
|
||||
igraph_adjlist_init(&g, &adjlist, IGRAPH_IN, IGRAPH_LOOPS_ONCE, IGRAPH_MULTIPLE);
|
||||
igraph_adjlist(&g2, &adjlist, IGRAPH_IN, /*duplicate=*/ 0);
|
||||
igraph_isomorphic(&g, &g2, &iso);
|
||||
IGRAPH_ASSERT(iso);
|
||||
igraph_adjlist_destroy(&adjlist);
|
||||
igraph_destroy(&g2);
|
||||
igraph_destroy(&g);
|
||||
|
||||
/* Undirected */
|
||||
igraph_kary_tree(&g, 42, 3, IGRAPH_TREE_UNDIRECTED);
|
||||
igraph_adjlist_init(&g, &adjlist, IGRAPH_OUT, IGRAPH_LOOPS_TWICE, IGRAPH_MULTIPLE);
|
||||
igraph_adjlist(&g2, &adjlist, IGRAPH_ALL, /*duplicate=*/ 1);
|
||||
igraph_isomorphic(&g, &g2, &iso);
|
||||
IGRAPH_ASSERT(iso);
|
||||
igraph_adjlist_destroy(&adjlist);
|
||||
igraph_destroy(&g2);
|
||||
igraph_destroy(&g);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define TEST_ADJLIST(label, mode, loops, multiple) { \
|
||||
igraph_adjlist_init(&g, &adjlist, mode, loops, multiple); \
|
||||
printf(label ": "); \
|
||||
print_adjlist(&adjlist); \
|
||||
printf("\n"); \
|
||||
igraph_adjlist_destroy(&adjlist); \
|
||||
}
|
||||
|
||||
#define TEST_LAZY_ADJLIST(label, mode, loops, multiple) { \
|
||||
igraph_lazy_adjlist_init(&g, &lazy_adjlist, mode, loops, multiple); \
|
||||
printf(label ": "); \
|
||||
print_lazy_adjlist(&lazy_adjlist); \
|
||||
printf("\n"); \
|
||||
igraph_lazy_adjlist_destroy(&lazy_adjlist); \
|
||||
}
|
||||
|
||||
int test_loop_elimination_for_undirected_graph(void) {
|
||||
igraph_t g;
|
||||
igraph_adjlist_t adjlist;
|
||||
igraph_lazy_adjlist_t lazy_adjlist;
|
||||
|
||||
igraph_small(
|
||||
&g, 5, /* directed = */ 0,
|
||||
0, 1, 0, 3,
|
||||
1, 2,
|
||||
2, 2, 2, 3,
|
||||
3, 0, 3, 4,
|
||||
4, 4, 4, 4,
|
||||
-1
|
||||
);
|
||||
|
||||
printf("Testing loop edge elimination in undirected graph\n\n");
|
||||
|
||||
/* We are testing IGRAPH_ALL, IGRAPH_IN and IGRAPH_OUT below; it should
|
||||
* make no difference */
|
||||
TEST_ADJLIST("Loops eliminated", IGRAPH_ALL, IGRAPH_NO_LOOPS, IGRAPH_MULTIPLE);
|
||||
TEST_ADJLIST("Loops listed once", IGRAPH_IN, IGRAPH_LOOPS_ONCE, IGRAPH_MULTIPLE);
|
||||
TEST_ADJLIST("Loops listed twice", IGRAPH_OUT, IGRAPH_LOOPS_TWICE, IGRAPH_MULTIPLE);
|
||||
|
||||
printf("============================================================\n\n");
|
||||
|
||||
printf("Testing lazy loop edge elimination in undirected graph\n\n");
|
||||
|
||||
/* We are testing IGRAPH_ALL, IGRAPH_IN and IGRAPH_OUT below; it should
|
||||
* make no difference */
|
||||
TEST_LAZY_ADJLIST("Loops eliminated", IGRAPH_ALL, IGRAPH_NO_LOOPS, IGRAPH_MULTIPLE);
|
||||
TEST_LAZY_ADJLIST("Loops listed once", IGRAPH_IN, IGRAPH_LOOPS_ONCE, IGRAPH_MULTIPLE);
|
||||
TEST_LAZY_ADJLIST("Loops listed twice", IGRAPH_OUT, IGRAPH_LOOPS_TWICE, IGRAPH_MULTIPLE);
|
||||
|
||||
printf("============================================================\n\n");
|
||||
|
||||
igraph_destroy(&g);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int test_loop_elimination_for_directed_graph(void) {
|
||||
igraph_t g;
|
||||
igraph_adjlist_t adjlist;
|
||||
igraph_lazy_adjlist_t lazy_adjlist;
|
||||
|
||||
igraph_small(
|
||||
&g, 5, /* directed = */ 1,
|
||||
0, 1, 0, 3,
|
||||
1, 2,
|
||||
2, 2, 2, 3,
|
||||
3, 0, 3, 4,
|
||||
4, 4, 4, 4,
|
||||
-1
|
||||
);
|
||||
|
||||
printf("Testing loop edge elimination in directed graph\n\n");
|
||||
|
||||
TEST_ADJLIST("In-edges, loops eliminated", IGRAPH_IN, IGRAPH_NO_LOOPS, IGRAPH_MULTIPLE);
|
||||
TEST_ADJLIST("In-edges, loops listed once", IGRAPH_IN, IGRAPH_LOOPS_ONCE, IGRAPH_MULTIPLE);
|
||||
TEST_ADJLIST("In-edges, loops listed once even if IGRAPH_LOOPS_TWICE is given",
|
||||
IGRAPH_IN, IGRAPH_LOOPS_TWICE, IGRAPH_MULTIPLE);
|
||||
|
||||
TEST_ADJLIST("Out-edges, loops eliminated", IGRAPH_OUT, IGRAPH_NO_LOOPS, IGRAPH_MULTIPLE);
|
||||
TEST_ADJLIST("Out-edges, loops listed once", IGRAPH_OUT, IGRAPH_LOOPS_ONCE, IGRAPH_MULTIPLE);
|
||||
TEST_ADJLIST("Out-edges, loops listed once even if IGRAPH_LOOPS_TWICE is given",
|
||||
IGRAPH_OUT, IGRAPH_LOOPS_TWICE, IGRAPH_MULTIPLE);
|
||||
|
||||
TEST_ADJLIST("In- and out-edges, loops eliminated", IGRAPH_ALL, IGRAPH_NO_LOOPS, IGRAPH_MULTIPLE);
|
||||
TEST_ADJLIST("In- and out-edges, loops listed once", IGRAPH_ALL, IGRAPH_LOOPS_ONCE, IGRAPH_MULTIPLE);
|
||||
TEST_ADJLIST("In- and out-edges, loops listed twice", IGRAPH_ALL, IGRAPH_LOOPS_TWICE, IGRAPH_MULTIPLE);
|
||||
|
||||
printf("============================================================\n\n");
|
||||
|
||||
printf("Testing lazy loop edge elimination in directed graph\n\n");
|
||||
|
||||
TEST_LAZY_ADJLIST("In-edges, loops eliminated", IGRAPH_IN, IGRAPH_NO_LOOPS, IGRAPH_MULTIPLE);
|
||||
TEST_LAZY_ADJLIST("In-edges, loops listed once", IGRAPH_IN, IGRAPH_LOOPS_ONCE, IGRAPH_MULTIPLE);
|
||||
TEST_LAZY_ADJLIST("In-edges, loops listed once even if IGRAPH_LOOPS_TWICE is given",
|
||||
IGRAPH_IN, IGRAPH_LOOPS_TWICE, IGRAPH_MULTIPLE);
|
||||
|
||||
TEST_LAZY_ADJLIST("Out-edges, loops eliminated", IGRAPH_OUT, IGRAPH_NO_LOOPS, IGRAPH_MULTIPLE);
|
||||
TEST_LAZY_ADJLIST("Out-edges, loops listed once", IGRAPH_OUT, IGRAPH_LOOPS_ONCE, IGRAPH_MULTIPLE);
|
||||
TEST_LAZY_ADJLIST("Out-edges, loops listed once even if IGRAPH_LOOPS_TWICE is given",
|
||||
IGRAPH_OUT, IGRAPH_LOOPS_TWICE, IGRAPH_MULTIPLE);
|
||||
|
||||
TEST_LAZY_ADJLIST("In- and out-edges, loops eliminated", IGRAPH_ALL, IGRAPH_NO_LOOPS, IGRAPH_MULTIPLE);
|
||||
TEST_LAZY_ADJLIST("In- and out-edges, loops listed once", IGRAPH_ALL, IGRAPH_LOOPS_ONCE, IGRAPH_MULTIPLE);
|
||||
TEST_LAZY_ADJLIST("In- and out-edges, loops listed twice", IGRAPH_ALL, IGRAPH_LOOPS_TWICE, IGRAPH_MULTIPLE);
|
||||
|
||||
printf("============================================================\n\n");
|
||||
|
||||
igraph_destroy(&g);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int test_multiedge_elimination_for_undirected_graph(void) {
|
||||
igraph_t g;
|
||||
igraph_adjlist_t adjlist;
|
||||
igraph_lazy_adjlist_t lazy_adjlist;
|
||||
|
||||
igraph_small(
|
||||
&g, 5, /* directed = */ 0,
|
||||
0, 1, 0, 3, 0, 8,
|
||||
1, 2,
|
||||
2, 2, 2, 3,
|
||||
3, 0, 3, 4,
|
||||
4, 4, 4, 4, 4, 5, 4, 5, 4, 5,
|
||||
5, 6,
|
||||
6, 7, 6, 8,
|
||||
8, 0,
|
||||
-1
|
||||
);
|
||||
|
||||
printf("Testing multiple edge elimination in undirected graph\n\n");
|
||||
|
||||
/* We are testing IGRAPH_ALL, IGRAPH_IN and IGRAPH_OUT below; it should
|
||||
* make no difference */
|
||||
TEST_ADJLIST("Loops also eliminated", IGRAPH_ALL, IGRAPH_NO_LOOPS, IGRAPH_NO_MULTIPLE);
|
||||
TEST_ADJLIST("Loops listed once", IGRAPH_IN, IGRAPH_LOOPS_ONCE, IGRAPH_NO_MULTIPLE);
|
||||
TEST_ADJLIST("Loops listed twice", IGRAPH_OUT, IGRAPH_LOOPS_TWICE, IGRAPH_NO_MULTIPLE);
|
||||
|
||||
printf("============================================================\n\n");
|
||||
|
||||
printf("Testing lazy multiple edge elimination in undirected graph\n\n");
|
||||
|
||||
/* We are testing IGRAPH_ALL, IGRAPH_IN and IGRAPH_OUT below; it should
|
||||
* make no difference */
|
||||
TEST_LAZY_ADJLIST("Loops also eliminated", IGRAPH_ALL, IGRAPH_NO_LOOPS, IGRAPH_NO_MULTIPLE);
|
||||
TEST_LAZY_ADJLIST("Loops listed once", IGRAPH_IN, IGRAPH_LOOPS_ONCE, IGRAPH_NO_MULTIPLE);
|
||||
TEST_LAZY_ADJLIST("Loops listed twice", IGRAPH_OUT, IGRAPH_LOOPS_TWICE, IGRAPH_NO_MULTIPLE);
|
||||
|
||||
printf("============================================================\n\n");
|
||||
|
||||
igraph_destroy(&g);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int test_multiedge_elimination_for_directed_graph(void) {
|
||||
igraph_t g;
|
||||
igraph_adjlist_t adjlist;
|
||||
igraph_lazy_adjlist_t lazy_adjlist;
|
||||
|
||||
igraph_small(
|
||||
&g, 5, /* directed = */ 1,
|
||||
0, 1, 0, 3, 0, 8,
|
||||
1, 2,
|
||||
2, 2, 2, 3,
|
||||
3, 0, 3, 4,
|
||||
4, 4, 4, 4, 4, 5, 4, 5, 4, 5,
|
||||
5, 6,
|
||||
6, 7, 6, 8,
|
||||
8, 0,
|
||||
-1
|
||||
);
|
||||
|
||||
printf("Testing multiple edge elimination in directed graph\n\n");
|
||||
|
||||
TEST_ADJLIST("In-edges, loops also eliminated", IGRAPH_IN, IGRAPH_NO_LOOPS, IGRAPH_NO_MULTIPLE);
|
||||
TEST_ADJLIST("In-edges, loops listed once", IGRAPH_IN, IGRAPH_LOOPS_ONCE, IGRAPH_NO_MULTIPLE);
|
||||
TEST_ADJLIST("In-edges, loops listed once even if IGRAPH_LOOPS_TWICE is given",
|
||||
IGRAPH_IN, IGRAPH_LOOPS_TWICE, IGRAPH_NO_MULTIPLE);
|
||||
|
||||
TEST_ADJLIST("Out-edges, loops also eliminated", IGRAPH_OUT, IGRAPH_NO_LOOPS, IGRAPH_NO_MULTIPLE);
|
||||
TEST_ADJLIST("Out-edges, loops listed once", IGRAPH_OUT, IGRAPH_LOOPS_ONCE, IGRAPH_NO_MULTIPLE);
|
||||
TEST_ADJLIST("Out-edges, loops listed once even if IGRAPH_LOOPS_TWICE is given",
|
||||
IGRAPH_OUT, IGRAPH_LOOPS_TWICE, IGRAPH_NO_MULTIPLE);
|
||||
|
||||
TEST_ADJLIST("In- and out-edges, loops also eliminated", IGRAPH_ALL, IGRAPH_NO_LOOPS, IGRAPH_NO_MULTIPLE);
|
||||
TEST_ADJLIST("In- and out-edges, loops listed once", IGRAPH_ALL, IGRAPH_LOOPS_ONCE, IGRAPH_NO_MULTIPLE);
|
||||
TEST_ADJLIST("In- and out-edges, loops listed twice", IGRAPH_ALL, IGRAPH_LOOPS_TWICE, IGRAPH_NO_MULTIPLE);
|
||||
|
||||
printf("============================================================\n\n");
|
||||
|
||||
printf("Testing lazy multiple edge elimination in directed graph\n\n");
|
||||
|
||||
TEST_LAZY_ADJLIST("In-edges, loops also eliminated", IGRAPH_IN, IGRAPH_NO_LOOPS, IGRAPH_NO_MULTIPLE);
|
||||
TEST_LAZY_ADJLIST("In-edges, loops listed once", IGRAPH_IN, IGRAPH_LOOPS_ONCE, IGRAPH_NO_MULTIPLE);
|
||||
TEST_LAZY_ADJLIST("In-edges, loops listed once even if IGRAPH_LOOPS_TWICE is given",
|
||||
IGRAPH_IN, IGRAPH_LOOPS_TWICE, IGRAPH_NO_MULTIPLE);
|
||||
|
||||
TEST_LAZY_ADJLIST("Out-edges, loops also eliminated", IGRAPH_OUT, IGRAPH_NO_LOOPS, IGRAPH_NO_MULTIPLE);
|
||||
TEST_LAZY_ADJLIST("Out-edges, loops listed once", IGRAPH_OUT, IGRAPH_LOOPS_ONCE, IGRAPH_NO_MULTIPLE);
|
||||
TEST_LAZY_ADJLIST("Out-edges, loops listed once even if IGRAPH_LOOPS_TWICE is given",
|
||||
IGRAPH_OUT, IGRAPH_LOOPS_TWICE, IGRAPH_NO_MULTIPLE);
|
||||
|
||||
TEST_LAZY_ADJLIST("In- and out-edges, loops also eliminated", IGRAPH_ALL, IGRAPH_NO_LOOPS, IGRAPH_NO_MULTIPLE);
|
||||
TEST_LAZY_ADJLIST("In- and out-edges, loops listed once", IGRAPH_ALL, IGRAPH_LOOPS_ONCE, IGRAPH_NO_MULTIPLE);
|
||||
TEST_LAZY_ADJLIST("In- and out-edges, loops listed twice", IGRAPH_ALL, IGRAPH_LOOPS_TWICE, IGRAPH_NO_MULTIPLE);
|
||||
|
||||
printf("============================================================\n\n");
|
||||
|
||||
igraph_destroy(&g);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int test_caching(void) {
|
||||
igraph_t g_simple, g_loop, g_multiloop, g_multi, g_multi_and_loop;
|
||||
char *g_desc[] = {"simple", "loop", "multiloop", "multi", "multi and loop"};
|
||||
igraph_adjlist_t adjlist;
|
||||
igraph_loops_t loops[] = {IGRAPH_NO_LOOPS, IGRAPH_LOOPS_ONCE, IGRAPH_LOOPS_TWICE};
|
||||
igraph_bool_t multiple[] = {IGRAPH_NO_MULTIPLE, IGRAPH_MULTIPLE};
|
||||
igraph_neimode_t modes[] = {IGRAPH_OUT, IGRAPH_ALL};
|
||||
|
||||
igraph_vector_int_t edge;
|
||||
igraph_int_t vloop[] = {0,0};
|
||||
igraph_int_t vmult[] = {0,1};
|
||||
|
||||
igraph_full(&g_simple, 5, IGRAPH_UNDIRECTED, /*loops*/ 0);
|
||||
igraph_full(&g_loop, 5, IGRAPH_UNDIRECTED, /*loops*/ 0);
|
||||
igraph_full(&g_multiloop, 5, IGRAPH_UNDIRECTED, /*loops*/ 0);
|
||||
igraph_full(&g_multi, 5, IGRAPH_UNDIRECTED, /*loops*/ 0);
|
||||
igraph_full(&g_multi_and_loop, 5, IGRAPH_UNDIRECTED, /*loops*/ 0);
|
||||
|
||||
edge = igraph_vector_int_view(vloop, 2);
|
||||
igraph_add_edges(&g_loop, &edge, NULL);
|
||||
igraph_add_edges(&g_multiloop, &edge, NULL);
|
||||
igraph_add_edges(&g_multiloop, &edge, NULL);
|
||||
igraph_add_edges(&g_multi_and_loop, &edge, NULL);
|
||||
|
||||
edge = igraph_vector_int_view(vmult, 2);
|
||||
|
||||
igraph_add_edges(&g_multi, &edge, NULL);
|
||||
igraph_add_edges(&g_multi_and_loop, &edge, NULL);
|
||||
|
||||
igraph_t *graphs[] = {&g_simple, &g_loop, &g_multiloop, &g_multi, &g_multi_and_loop};
|
||||
|
||||
for (int g = 0; g < 5; g++) {
|
||||
for (int loop = 0; loop < 3; loop++) {
|
||||
for (int multi = 0; multi < 2; multi++) {
|
||||
for (int mode = 0; mode < 2; mode++) {
|
||||
printf("graph: %s, loop: %d multi: %d, mode: %d\n", g_desc[g], loop, multi, mode);
|
||||
|
||||
igraph_invalidate_cache(graphs[g]);
|
||||
igraph_adjlist_init(graphs[g], &adjlist, modes[mode], loops[loop], multiple[multi]);
|
||||
if (!igraph_i_property_cache_has(graphs[g], IGRAPH_PROP_HAS_LOOP)) {
|
||||
printf("loop not cached\n");
|
||||
} else {
|
||||
printf("loop cached: %d\n", igraph_i_property_cache_get_bool(graphs[g], IGRAPH_PROP_HAS_LOOP));
|
||||
}
|
||||
if (!igraph_i_property_cache_has(graphs[g], IGRAPH_PROP_HAS_MULTI)) {
|
||||
printf("multi not cached\n");
|
||||
} else {
|
||||
printf("multi cached: %d\n", igraph_i_property_cache_get_bool(graphs[g], IGRAPH_PROP_HAS_MULTI));
|
||||
}
|
||||
igraph_adjlist_destroy(&adjlist);
|
||||
}
|
||||
}
|
||||
}
|
||||
igraph_destroy(graphs[g]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
|
||||
RUN_TEST(test_simple_trees);
|
||||
|
||||
RUN_TEST(test_loop_elimination_for_undirected_graph);
|
||||
RUN_TEST(test_loop_elimination_for_directed_graph);
|
||||
RUN_TEST(test_multiedge_elimination_for_undirected_graph);
|
||||
RUN_TEST(test_multiedge_elimination_for_directed_graph);
|
||||
|
||||
RUN_TEST(test_caching);
|
||||
|
||||
VERIFY_FINALLY_STACK();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,692 @@
|
||||
Testing loop edge elimination in undirected graph
|
||||
|
||||
Loops eliminated: {
|
||||
0: ( 1 3 3 )
|
||||
1: ( 0 2 )
|
||||
2: ( 1 3 )
|
||||
3: ( 0 0 2 4 )
|
||||
4: ( 3 )
|
||||
}
|
||||
|
||||
Loops listed once: {
|
||||
0: ( 1 3 3 )
|
||||
1: ( 0 2 )
|
||||
2: ( 1 2 3 )
|
||||
3: ( 0 0 2 4 )
|
||||
4: ( 3 4 4 )
|
||||
}
|
||||
|
||||
Loops listed twice: {
|
||||
0: ( 1 3 3 )
|
||||
1: ( 0 2 )
|
||||
2: ( 1 2 2 3 )
|
||||
3: ( 0 0 2 4 )
|
||||
4: ( 3 4 4 4 4 )
|
||||
}
|
||||
|
||||
============================================================
|
||||
|
||||
Testing lazy loop edge elimination in undirected graph
|
||||
|
||||
Loops eliminated: {
|
||||
0: ( 1 3 3 )
|
||||
1: ( 0 2 )
|
||||
2: ( 1 3 )
|
||||
3: ( 0 0 2 4 )
|
||||
4: ( 3 )
|
||||
}
|
||||
|
||||
Loops listed once: {
|
||||
0: ( 1 3 3 )
|
||||
1: ( 0 2 )
|
||||
2: ( 1 2 3 )
|
||||
3: ( 0 0 2 4 )
|
||||
4: ( 3 4 4 )
|
||||
}
|
||||
|
||||
Loops listed twice: {
|
||||
0: ( 1 3 3 )
|
||||
1: ( 0 2 )
|
||||
2: ( 1 2 2 3 )
|
||||
3: ( 0 0 2 4 )
|
||||
4: ( 3 4 4 4 4 )
|
||||
}
|
||||
|
||||
============================================================
|
||||
|
||||
Testing loop edge elimination in directed graph
|
||||
|
||||
In-edges, loops eliminated: {
|
||||
0: ( 3 )
|
||||
1: ( 0 )
|
||||
2: ( 1 )
|
||||
3: ( 0 2 )
|
||||
4: ( 3 )
|
||||
}
|
||||
|
||||
In-edges, loops listed once: {
|
||||
0: ( 3 )
|
||||
1: ( 0 )
|
||||
2: ( 1 2 )
|
||||
3: ( 0 2 )
|
||||
4: ( 3 4 4 )
|
||||
}
|
||||
|
||||
In-edges, loops listed once even if IGRAPH_LOOPS_TWICE is given: {
|
||||
0: ( 3 )
|
||||
1: ( 0 )
|
||||
2: ( 1 2 )
|
||||
3: ( 0 2 )
|
||||
4: ( 3 4 4 )
|
||||
}
|
||||
|
||||
Out-edges, loops eliminated: {
|
||||
0: ( 1 3 )
|
||||
1: ( 2 )
|
||||
2: ( 3 )
|
||||
3: ( 0 4 )
|
||||
4: ( )
|
||||
}
|
||||
|
||||
Out-edges, loops listed once: {
|
||||
0: ( 1 3 )
|
||||
1: ( 2 )
|
||||
2: ( 2 3 )
|
||||
3: ( 0 4 )
|
||||
4: ( 4 4 )
|
||||
}
|
||||
|
||||
Out-edges, loops listed once even if IGRAPH_LOOPS_TWICE is given: {
|
||||
0: ( 1 3 )
|
||||
1: ( 2 )
|
||||
2: ( 2 3 )
|
||||
3: ( 0 4 )
|
||||
4: ( 4 4 )
|
||||
}
|
||||
|
||||
In- and out-edges, loops eliminated: {
|
||||
0: ( 1 3 3 )
|
||||
1: ( 0 2 )
|
||||
2: ( 1 3 )
|
||||
3: ( 0 0 2 4 )
|
||||
4: ( 3 )
|
||||
}
|
||||
|
||||
In- and out-edges, loops listed once: {
|
||||
0: ( 1 3 3 )
|
||||
1: ( 0 2 )
|
||||
2: ( 1 2 3 )
|
||||
3: ( 0 0 2 4 )
|
||||
4: ( 3 4 4 )
|
||||
}
|
||||
|
||||
In- and out-edges, loops listed twice: {
|
||||
0: ( 1 3 3 )
|
||||
1: ( 0 2 )
|
||||
2: ( 1 2 2 3 )
|
||||
3: ( 0 0 2 4 )
|
||||
4: ( 3 4 4 4 4 )
|
||||
}
|
||||
|
||||
============================================================
|
||||
|
||||
Testing lazy loop edge elimination in directed graph
|
||||
|
||||
In-edges, loops eliminated: {
|
||||
0: ( 3 )
|
||||
1: ( 0 )
|
||||
2: ( 1 )
|
||||
3: ( 0 2 )
|
||||
4: ( 3 )
|
||||
}
|
||||
|
||||
In-edges, loops listed once: {
|
||||
0: ( 3 )
|
||||
1: ( 0 )
|
||||
2: ( 1 2 )
|
||||
3: ( 0 2 )
|
||||
4: ( 3 4 4 )
|
||||
}
|
||||
|
||||
In-edges, loops listed once even if IGRAPH_LOOPS_TWICE is given: {
|
||||
0: ( 3 )
|
||||
1: ( 0 )
|
||||
2: ( 1 2 )
|
||||
3: ( 0 2 )
|
||||
4: ( 3 4 4 )
|
||||
}
|
||||
|
||||
Out-edges, loops eliminated: {
|
||||
0: ( 1 3 )
|
||||
1: ( 2 )
|
||||
2: ( 3 )
|
||||
3: ( 0 4 )
|
||||
4: ( )
|
||||
}
|
||||
|
||||
Out-edges, loops listed once: {
|
||||
0: ( 1 3 )
|
||||
1: ( 2 )
|
||||
2: ( 2 3 )
|
||||
3: ( 0 4 )
|
||||
4: ( 4 4 )
|
||||
}
|
||||
|
||||
Out-edges, loops listed once even if IGRAPH_LOOPS_TWICE is given: {
|
||||
0: ( 1 3 )
|
||||
1: ( 2 )
|
||||
2: ( 2 3 )
|
||||
3: ( 0 4 )
|
||||
4: ( 4 4 )
|
||||
}
|
||||
|
||||
In- and out-edges, loops eliminated: {
|
||||
0: ( 1 3 3 )
|
||||
1: ( 0 2 )
|
||||
2: ( 1 3 )
|
||||
3: ( 0 0 2 4 )
|
||||
4: ( 3 )
|
||||
}
|
||||
|
||||
In- and out-edges, loops listed once: {
|
||||
0: ( 1 3 3 )
|
||||
1: ( 0 2 )
|
||||
2: ( 1 2 3 )
|
||||
3: ( 0 0 2 4 )
|
||||
4: ( 3 4 4 )
|
||||
}
|
||||
|
||||
In- and out-edges, loops listed twice: {
|
||||
0: ( 1 3 3 )
|
||||
1: ( 0 2 )
|
||||
2: ( 1 2 2 3 )
|
||||
3: ( 0 0 2 4 )
|
||||
4: ( 3 4 4 4 4 )
|
||||
}
|
||||
|
||||
============================================================
|
||||
|
||||
Testing multiple edge elimination in undirected graph
|
||||
|
||||
Loops also eliminated: {
|
||||
0: ( 1 3 8 )
|
||||
1: ( 0 2 )
|
||||
2: ( 1 3 )
|
||||
3: ( 0 2 4 )
|
||||
4: ( 3 5 )
|
||||
5: ( 4 6 )
|
||||
6: ( 5 7 8 )
|
||||
7: ( 6 )
|
||||
8: ( 0 6 )
|
||||
}
|
||||
|
||||
Loops listed once: {
|
||||
0: ( 1 3 8 )
|
||||
1: ( 0 2 )
|
||||
2: ( 1 2 3 )
|
||||
3: ( 0 2 4 )
|
||||
4: ( 3 4 5 )
|
||||
5: ( 4 6 )
|
||||
6: ( 5 7 8 )
|
||||
7: ( 6 )
|
||||
8: ( 0 6 )
|
||||
}
|
||||
|
||||
Loops listed twice: {
|
||||
0: ( 1 3 8 )
|
||||
1: ( 0 2 )
|
||||
2: ( 1 2 2 3 )
|
||||
3: ( 0 2 4 )
|
||||
4: ( 3 4 4 5 )
|
||||
5: ( 4 6 )
|
||||
6: ( 5 7 8 )
|
||||
7: ( 6 )
|
||||
8: ( 0 6 )
|
||||
}
|
||||
|
||||
============================================================
|
||||
|
||||
Testing lazy multiple edge elimination in undirected graph
|
||||
|
||||
Loops also eliminated: {
|
||||
0: ( 1 3 8 )
|
||||
1: ( 0 2 )
|
||||
2: ( 1 3 )
|
||||
3: ( 0 2 4 )
|
||||
4: ( 3 5 )
|
||||
5: ( 4 6 )
|
||||
6: ( 5 7 8 )
|
||||
7: ( 6 )
|
||||
8: ( 0 6 )
|
||||
}
|
||||
|
||||
Loops listed once: {
|
||||
0: ( 1 3 8 )
|
||||
1: ( 0 2 )
|
||||
2: ( 1 2 3 )
|
||||
3: ( 0 2 4 )
|
||||
4: ( 3 4 5 )
|
||||
5: ( 4 6 )
|
||||
6: ( 5 7 8 )
|
||||
7: ( 6 )
|
||||
8: ( 0 6 )
|
||||
}
|
||||
|
||||
Loops listed twice: {
|
||||
0: ( 1 3 8 )
|
||||
1: ( 0 2 )
|
||||
2: ( 1 2 2 3 )
|
||||
3: ( 0 2 4 )
|
||||
4: ( 3 4 4 5 )
|
||||
5: ( 4 6 )
|
||||
6: ( 5 7 8 )
|
||||
7: ( 6 )
|
||||
8: ( 0 6 )
|
||||
}
|
||||
|
||||
============================================================
|
||||
|
||||
Testing multiple edge elimination in directed graph
|
||||
|
||||
In-edges, loops also eliminated: {
|
||||
0: ( 3 8 )
|
||||
1: ( 0 )
|
||||
2: ( 1 )
|
||||
3: ( 0 2 )
|
||||
4: ( 3 )
|
||||
5: ( 4 )
|
||||
6: ( 5 )
|
||||
7: ( 6 )
|
||||
8: ( 0 6 )
|
||||
}
|
||||
|
||||
In-edges, loops listed once: {
|
||||
0: ( 3 8 )
|
||||
1: ( 0 )
|
||||
2: ( 1 2 )
|
||||
3: ( 0 2 )
|
||||
4: ( 3 4 )
|
||||
5: ( 4 )
|
||||
6: ( 5 )
|
||||
7: ( 6 )
|
||||
8: ( 0 6 )
|
||||
}
|
||||
|
||||
In-edges, loops listed once even if IGRAPH_LOOPS_TWICE is given: {
|
||||
0: ( 3 8 )
|
||||
1: ( 0 )
|
||||
2: ( 1 2 )
|
||||
3: ( 0 2 )
|
||||
4: ( 3 4 )
|
||||
5: ( 4 )
|
||||
6: ( 5 )
|
||||
7: ( 6 )
|
||||
8: ( 0 6 )
|
||||
}
|
||||
|
||||
Out-edges, loops also eliminated: {
|
||||
0: ( 1 3 8 )
|
||||
1: ( 2 )
|
||||
2: ( 3 )
|
||||
3: ( 0 4 )
|
||||
4: ( 5 )
|
||||
5: ( 6 )
|
||||
6: ( 7 8 )
|
||||
7: ( )
|
||||
8: ( 0 )
|
||||
}
|
||||
|
||||
Out-edges, loops listed once: {
|
||||
0: ( 1 3 8 )
|
||||
1: ( 2 )
|
||||
2: ( 2 3 )
|
||||
3: ( 0 4 )
|
||||
4: ( 4 5 )
|
||||
5: ( 6 )
|
||||
6: ( 7 8 )
|
||||
7: ( )
|
||||
8: ( 0 )
|
||||
}
|
||||
|
||||
Out-edges, loops listed once even if IGRAPH_LOOPS_TWICE is given: {
|
||||
0: ( 1 3 8 )
|
||||
1: ( 2 )
|
||||
2: ( 2 3 )
|
||||
3: ( 0 4 )
|
||||
4: ( 4 5 )
|
||||
5: ( 6 )
|
||||
6: ( 7 8 )
|
||||
7: ( )
|
||||
8: ( 0 )
|
||||
}
|
||||
|
||||
In- and out-edges, loops also eliminated: {
|
||||
0: ( 1 3 8 )
|
||||
1: ( 0 2 )
|
||||
2: ( 1 3 )
|
||||
3: ( 0 2 4 )
|
||||
4: ( 3 5 )
|
||||
5: ( 4 6 )
|
||||
6: ( 5 7 8 )
|
||||
7: ( 6 )
|
||||
8: ( 0 6 )
|
||||
}
|
||||
|
||||
In- and out-edges, loops listed once: {
|
||||
0: ( 1 3 8 )
|
||||
1: ( 0 2 )
|
||||
2: ( 1 2 3 )
|
||||
3: ( 0 2 4 )
|
||||
4: ( 3 4 5 )
|
||||
5: ( 4 6 )
|
||||
6: ( 5 7 8 )
|
||||
7: ( 6 )
|
||||
8: ( 0 6 )
|
||||
}
|
||||
|
||||
In- and out-edges, loops listed twice: {
|
||||
0: ( 1 3 8 )
|
||||
1: ( 0 2 )
|
||||
2: ( 1 2 2 3 )
|
||||
3: ( 0 2 4 )
|
||||
4: ( 3 4 4 5 )
|
||||
5: ( 4 6 )
|
||||
6: ( 5 7 8 )
|
||||
7: ( 6 )
|
||||
8: ( 0 6 )
|
||||
}
|
||||
|
||||
============================================================
|
||||
|
||||
Testing lazy multiple edge elimination in directed graph
|
||||
|
||||
In-edges, loops also eliminated: {
|
||||
0: ( 3 8 )
|
||||
1: ( 0 )
|
||||
2: ( 1 )
|
||||
3: ( 0 2 )
|
||||
4: ( 3 )
|
||||
5: ( 4 )
|
||||
6: ( 5 )
|
||||
7: ( 6 )
|
||||
8: ( 0 6 )
|
||||
}
|
||||
|
||||
In-edges, loops listed once: {
|
||||
0: ( 3 8 )
|
||||
1: ( 0 )
|
||||
2: ( 1 2 )
|
||||
3: ( 0 2 )
|
||||
4: ( 3 4 )
|
||||
5: ( 4 )
|
||||
6: ( 5 )
|
||||
7: ( 6 )
|
||||
8: ( 0 6 )
|
||||
}
|
||||
|
||||
In-edges, loops listed once even if IGRAPH_LOOPS_TWICE is given: {
|
||||
0: ( 3 8 )
|
||||
1: ( 0 )
|
||||
2: ( 1 2 )
|
||||
3: ( 0 2 )
|
||||
4: ( 3 4 )
|
||||
5: ( 4 )
|
||||
6: ( 5 )
|
||||
7: ( 6 )
|
||||
8: ( 0 6 )
|
||||
}
|
||||
|
||||
Out-edges, loops also eliminated: {
|
||||
0: ( 1 3 8 )
|
||||
1: ( 2 )
|
||||
2: ( 3 )
|
||||
3: ( 0 4 )
|
||||
4: ( 5 )
|
||||
5: ( 6 )
|
||||
6: ( 7 8 )
|
||||
7: ( )
|
||||
8: ( 0 )
|
||||
}
|
||||
|
||||
Out-edges, loops listed once: {
|
||||
0: ( 1 3 8 )
|
||||
1: ( 2 )
|
||||
2: ( 2 3 )
|
||||
3: ( 0 4 )
|
||||
4: ( 4 5 )
|
||||
5: ( 6 )
|
||||
6: ( 7 8 )
|
||||
7: ( )
|
||||
8: ( 0 )
|
||||
}
|
||||
|
||||
Out-edges, loops listed once even if IGRAPH_LOOPS_TWICE is given: {
|
||||
0: ( 1 3 8 )
|
||||
1: ( 2 )
|
||||
2: ( 2 3 )
|
||||
3: ( 0 4 )
|
||||
4: ( 4 5 )
|
||||
5: ( 6 )
|
||||
6: ( 7 8 )
|
||||
7: ( )
|
||||
8: ( 0 )
|
||||
}
|
||||
|
||||
In- and out-edges, loops also eliminated: {
|
||||
0: ( 1 3 8 )
|
||||
1: ( 0 2 )
|
||||
2: ( 1 3 )
|
||||
3: ( 0 2 4 )
|
||||
4: ( 3 5 )
|
||||
5: ( 4 6 )
|
||||
6: ( 5 7 8 )
|
||||
7: ( 6 )
|
||||
8: ( 0 6 )
|
||||
}
|
||||
|
||||
In- and out-edges, loops listed once: {
|
||||
0: ( 1 3 8 )
|
||||
1: ( 0 2 )
|
||||
2: ( 1 2 3 )
|
||||
3: ( 0 2 4 )
|
||||
4: ( 3 4 5 )
|
||||
5: ( 4 6 )
|
||||
6: ( 5 7 8 )
|
||||
7: ( 6 )
|
||||
8: ( 0 6 )
|
||||
}
|
||||
|
||||
In- and out-edges, loops listed twice: {
|
||||
0: ( 1 3 8 )
|
||||
1: ( 0 2 )
|
||||
2: ( 1 2 2 3 )
|
||||
3: ( 0 2 4 )
|
||||
4: ( 3 4 4 5 )
|
||||
5: ( 4 6 )
|
||||
6: ( 5 7 8 )
|
||||
7: ( 6 )
|
||||
8: ( 0 6 )
|
||||
}
|
||||
|
||||
============================================================
|
||||
|
||||
graph: simple, loop: 0 multi: 0, mode: 0
|
||||
loop cached: 0
|
||||
multi cached: 0
|
||||
graph: simple, loop: 0 multi: 0, mode: 1
|
||||
loop cached: 0
|
||||
multi cached: 0
|
||||
graph: simple, loop: 0 multi: 1, mode: 0
|
||||
loop cached: 0
|
||||
multi not cached
|
||||
graph: simple, loop: 0 multi: 1, mode: 1
|
||||
loop cached: 0
|
||||
multi not cached
|
||||
graph: simple, loop: 1 multi: 0, mode: 0
|
||||
loop not cached
|
||||
multi cached: 0
|
||||
graph: simple, loop: 1 multi: 0, mode: 1
|
||||
loop not cached
|
||||
multi cached: 0
|
||||
graph: simple, loop: 1 multi: 1, mode: 0
|
||||
loop not cached
|
||||
multi not cached
|
||||
graph: simple, loop: 1 multi: 1, mode: 1
|
||||
loop not cached
|
||||
multi not cached
|
||||
graph: simple, loop: 2 multi: 0, mode: 0
|
||||
loop not cached
|
||||
multi cached: 0
|
||||
graph: simple, loop: 2 multi: 0, mode: 1
|
||||
loop not cached
|
||||
multi cached: 0
|
||||
graph: simple, loop: 2 multi: 1, mode: 0
|
||||
loop not cached
|
||||
multi not cached
|
||||
graph: simple, loop: 2 multi: 1, mode: 1
|
||||
loop not cached
|
||||
multi not cached
|
||||
graph: loop, loop: 0 multi: 0, mode: 0
|
||||
loop cached: 1
|
||||
multi cached: 0
|
||||
graph: loop, loop: 0 multi: 0, mode: 1
|
||||
loop cached: 1
|
||||
multi cached: 0
|
||||
graph: loop, loop: 0 multi: 1, mode: 0
|
||||
loop cached: 1
|
||||
multi not cached
|
||||
graph: loop, loop: 0 multi: 1, mode: 1
|
||||
loop cached: 1
|
||||
multi not cached
|
||||
graph: loop, loop: 1 multi: 0, mode: 0
|
||||
loop not cached
|
||||
multi cached: 0
|
||||
graph: loop, loop: 1 multi: 0, mode: 1
|
||||
loop not cached
|
||||
multi cached: 0
|
||||
graph: loop, loop: 1 multi: 1, mode: 0
|
||||
loop cached: 1
|
||||
multi not cached
|
||||
graph: loop, loop: 1 multi: 1, mode: 1
|
||||
loop cached: 1
|
||||
multi not cached
|
||||
graph: loop, loop: 2 multi: 0, mode: 0
|
||||
loop not cached
|
||||
multi cached: 1
|
||||
graph: loop, loop: 2 multi: 0, mode: 1
|
||||
loop not cached
|
||||
multi cached: 1
|
||||
graph: loop, loop: 2 multi: 1, mode: 0
|
||||
loop not cached
|
||||
multi not cached
|
||||
graph: loop, loop: 2 multi: 1, mode: 1
|
||||
loop not cached
|
||||
multi not cached
|
||||
graph: multiloop, loop: 0 multi: 0, mode: 0
|
||||
loop cached: 1
|
||||
multi cached: 1
|
||||
graph: multiloop, loop: 0 multi: 0, mode: 1
|
||||
loop cached: 1
|
||||
multi cached: 1
|
||||
graph: multiloop, loop: 0 multi: 1, mode: 0
|
||||
loop cached: 1
|
||||
multi not cached
|
||||
graph: multiloop, loop: 0 multi: 1, mode: 1
|
||||
loop cached: 1
|
||||
multi not cached
|
||||
graph: multiloop, loop: 1 multi: 0, mode: 0
|
||||
loop not cached
|
||||
multi cached: 1
|
||||
graph: multiloop, loop: 1 multi: 0, mode: 1
|
||||
loop not cached
|
||||
multi cached: 1
|
||||
graph: multiloop, loop: 1 multi: 1, mode: 0
|
||||
loop cached: 1
|
||||
multi not cached
|
||||
graph: multiloop, loop: 1 multi: 1, mode: 1
|
||||
loop cached: 1
|
||||
multi not cached
|
||||
graph: multiloop, loop: 2 multi: 0, mode: 0
|
||||
loop not cached
|
||||
multi cached: 1
|
||||
graph: multiloop, loop: 2 multi: 0, mode: 1
|
||||
loop not cached
|
||||
multi cached: 1
|
||||
graph: multiloop, loop: 2 multi: 1, mode: 0
|
||||
loop not cached
|
||||
multi not cached
|
||||
graph: multiloop, loop: 2 multi: 1, mode: 1
|
||||
loop not cached
|
||||
multi not cached
|
||||
graph: multi, loop: 0 multi: 0, mode: 0
|
||||
loop cached: 0
|
||||
multi cached: 1
|
||||
graph: multi, loop: 0 multi: 0, mode: 1
|
||||
loop cached: 0
|
||||
multi cached: 1
|
||||
graph: multi, loop: 0 multi: 1, mode: 0
|
||||
loop cached: 0
|
||||
multi not cached
|
||||
graph: multi, loop: 0 multi: 1, mode: 1
|
||||
loop cached: 0
|
||||
multi not cached
|
||||
graph: multi, loop: 1 multi: 0, mode: 0
|
||||
loop not cached
|
||||
multi cached: 1
|
||||
graph: multi, loop: 1 multi: 0, mode: 1
|
||||
loop not cached
|
||||
multi cached: 1
|
||||
graph: multi, loop: 1 multi: 1, mode: 0
|
||||
loop not cached
|
||||
multi not cached
|
||||
graph: multi, loop: 1 multi: 1, mode: 1
|
||||
loop not cached
|
||||
multi not cached
|
||||
graph: multi, loop: 2 multi: 0, mode: 0
|
||||
loop not cached
|
||||
multi cached: 1
|
||||
graph: multi, loop: 2 multi: 0, mode: 1
|
||||
loop not cached
|
||||
multi cached: 1
|
||||
graph: multi, loop: 2 multi: 1, mode: 0
|
||||
loop not cached
|
||||
multi not cached
|
||||
graph: multi, loop: 2 multi: 1, mode: 1
|
||||
loop not cached
|
||||
multi not cached
|
||||
graph: multi and loop, loop: 0 multi: 0, mode: 0
|
||||
loop cached: 1
|
||||
multi cached: 1
|
||||
graph: multi and loop, loop: 0 multi: 0, mode: 1
|
||||
loop cached: 1
|
||||
multi cached: 1
|
||||
graph: multi and loop, loop: 0 multi: 1, mode: 0
|
||||
loop cached: 1
|
||||
multi not cached
|
||||
graph: multi and loop, loop: 0 multi: 1, mode: 1
|
||||
loop cached: 1
|
||||
multi not cached
|
||||
graph: multi and loop, loop: 1 multi: 0, mode: 0
|
||||
loop not cached
|
||||
multi cached: 1
|
||||
graph: multi and loop, loop: 1 multi: 0, mode: 1
|
||||
loop not cached
|
||||
multi cached: 1
|
||||
graph: multi and loop, loop: 1 multi: 1, mode: 0
|
||||
loop cached: 1
|
||||
multi not cached
|
||||
graph: multi and loop, loop: 1 multi: 1, mode: 1
|
||||
loop cached: 1
|
||||
multi not cached
|
||||
graph: multi and loop, loop: 2 multi: 0, mode: 0
|
||||
loop not cached
|
||||
multi cached: 1
|
||||
graph: multi and loop, loop: 2 multi: 0, mode: 1
|
||||
loop not cached
|
||||
multi cached: 1
|
||||
graph: multi and loop, loop: 2 multi: 1, mode: 0
|
||||
loop not cached
|
||||
multi not cached
|
||||
graph: multi and loop, loop: 2 multi: 1, mode: 1
|
||||
loop not cached
|
||||
multi not cached
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
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 <math.h>
|
||||
#include <float.h>
|
||||
|
||||
#include "test_utilities.h"
|
||||
|
||||
int main(void) {
|
||||
igraph_matrix_t rm1, rm2;
|
||||
igraph_matrix_complex_t cm1, cm2;
|
||||
const igraph_int_t nrow = 50, ncol = 60;
|
||||
|
||||
igraph_rng_seed(igraph_rng_default(), 97);
|
||||
|
||||
/* Real matrices */
|
||||
|
||||
igraph_matrix_init(&rm1, nrow, ncol);
|
||||
for (igraph_int_t i=0; i < nrow; i++) {
|
||||
for (igraph_int_t j=0; j < ncol; j++) {
|
||||
MATRIX(rm1, i, j) = RNG_UNIF(0.0, 3.0);
|
||||
}
|
||||
}
|
||||
|
||||
igraph_matrix_init_copy(&rm2, &rm1);
|
||||
for (igraph_int_t i=0; i < nrow; i++) {
|
||||
for (igraph_int_t j=0; j < ncol; j++) {
|
||||
MATRIX(rm2, i, j) = pow(MATRIX(rm2, i, j), 1 / 7.0);
|
||||
MATRIX(rm2, i, j) = pow(MATRIX(rm2, i, j), 7.0);
|
||||
}
|
||||
}
|
||||
|
||||
IGRAPH_ASSERT(igraph_matrix_all_almost_e(&rm1, &rm2, 4*DBL_EPSILON));
|
||||
MATRIX(rm2, 0, 0) *= 2;
|
||||
IGRAPH_ASSERT(! igraph_matrix_all_almost_e(&rm1, &rm2, 4*DBL_EPSILON));
|
||||
|
||||
igraph_matrix_destroy(&rm2);
|
||||
igraph_matrix_destroy(&rm1);
|
||||
|
||||
/* Complex matrices */
|
||||
|
||||
igraph_matrix_complex_init(&cm1, nrow, ncol);
|
||||
|
||||
for (igraph_int_t i=0; i < nrow; i++) {
|
||||
for (igraph_int_t j=0; j < ncol; j++) {
|
||||
IGRAPH_REAL(MATRIX(cm1, i, j)) = RNG_NORMAL(0,1);
|
||||
IGRAPH_IMAG(MATRIX(cm1, i, j)) = RNG_NORMAL(0,1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
igraph_matrix_complex_init_copy(&cm2, &cm1);
|
||||
for (igraph_int_t i=0; i < nrow; i++) {
|
||||
for (igraph_int_t j=0; j < ncol; j++) {
|
||||
MATRIX(cm2, i, j) = igraph_complex_pow_real(MATRIX(cm2, i, j), 1 / 7.0);
|
||||
MATRIX(cm2, i, j) = igraph_complex_pow_real(MATRIX(cm2, i, j), 7.0);
|
||||
}
|
||||
}
|
||||
|
||||
IGRAPH_ASSERT(igraph_matrix_complex_all_almost_e(&cm1, &cm2, 8*DBL_EPSILON));
|
||||
MATRIX(cm2, 0, 0) = igraph_complex_mul(MATRIX(cm2, 0, 0), MATRIX(cm2, 1, 1));
|
||||
IGRAPH_ASSERT(! igraph_matrix_complex_all_almost_e(&cm1, &cm2, 8*DBL_EPSILON));
|
||||
|
||||
igraph_matrix_complex_destroy(&cm2);
|
||||
igraph_matrix_complex_destroy(&cm1);
|
||||
|
||||
VERIFY_FINALLY_STACK();
|
||||
|
||||
return 0;
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user