From 837c3c6ff50c01ee9153680cabbccbfafbf65e9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kirill=20M=C3=BCller?= Date: Tue, 12 Mar 2024 10:42:06 +0100 Subject: [PATCH 01/10] chore: Update vendored sources to igraph/igraph@0f383457a13864b86a29eed4faf4efaade4c1254 feat: added generic, algorithm-agnostic versions of igraph_count_automorphisms(), igraph_automorphism_group() and igraph_canonical_permutation() refactor!: rename BLISS-specific isomorphism functions so they always have _bliss in the suffix - part 2 refactor!: rename BLISS-specific isomorphism functions so they always have _bliss in the suffix Merge branch 'master' into develop fix: fix segfault in GraphML reader refactor: remove unneeded include refactor: remove deprecated igraph_decompose_destroy() Merge branch 'master' into develop Merge branch 'master' into develop Merge branch 'master' into develop Merge branch 'master' into develop Merge branch 'master' into develop Merge branch 'master' into develop Merge branch 'master' into develop Merge branch 'master' into develop Merge branch 'master' into develop Merge branch 'master' into develop Merge branch 'master' into develop Merge pull request igraph/igraph#2470 from igraph/feat/is-biconnected Merge branch 'master' into develop Merge pull request igraph/igraph#2462 from igraph/feat/attribute-record-list Merge branch 'master' into develop fix: re-added missing master header in changelog Merge branch 'master' into develop Merge branch 'master' into develop refactor: consistently use ARPACK_DEFAULTS as the default arpack options chore: updated changelog feat: include Texinfo docs in source tarball fix: fix typo fix: look for either docbook2x-texi or docbook2texi fix: replace utf8 with utf-8 to prevent a warning when building texinfo docs ci: make sure that the Texinfo docs are also built Add target to build documentation in info format docs: clarify that Infomap considers edge directions fuzzer: update libxml2 to 2.12.3 fix: correct header includion in cliquer chore(deps): bump github/codeql-action from 2 to 3 chore(deps): bump actions/upload-artifact from 3 to 4 doc: clarify the effect of loop edges in igraph_similarity_inverse_log_weighted(), closes igraph/igraph#2448 refactor: rename deprecated functions in generated interfaces docs: fix typos refactor: clean up dfs/bfs and their docs refactor: replace void* with const igraph_vector_ptr_t* in attribute-related functions; more refactoring coming soon refactor!: strvector now contains pointers to const Merge branch 'master' into develop refactor: rename igraph_i_attribute_gettype() to igraph_i_attribute_get_type() for sake of consistency refactor: simplify attribute table init, copy and destroy methods chore: post-release tasks Merge branch 'master' into develop fix: fix stimulus function spec Merge branch 'master' into develop fix: community_spinglass_single() now uses igraph_real_t for output parameters that return real values, fixes igraph/igraph#2435 Merge branch 'master' into develop fix: fix jdm unit test and add rate-limited interruption to erdos_renyi_gnm_multi() fix: fix Stimulus type specs Merge branch 'master' into develop Merge branch 'master' into develop Merge branch 'master' into develop Merge branch 'master' into develop fix: fix Stimulus type specs fix: allow interruption for multigaph case of G(n,m) generator Merge branch 'master' into develop Merge branch 'master' into develop Merge branch 'master' into develop Merge branch 'master' into develop chore: fixed line endings and stale whitespace fix!: NCOL and LGL readers now use a default weight of 1, closes igraph/igraph#2395 fix: EDGEWEIGHTS type parameter was renamed to EDGE_WEIGHTS earlier Merge branch 'master' into develop Merge branch 'master' into develop refactor!: igraph_vector_swap() and igraph_matrix_swap() no longer return an error code Merge branch 'master' into develop Merge branch 'master' into develop Merge branch 'master' into develop Merge branch 'master' into develop Merge branch 'master' into develop Multi edge support for igraph_bipartite_game_gnm (igraph/igraph#2375) Merge branch 'master' into develop Merge branch 'master' into develop Merge branch 'master' into develop correct number of erdos_renyi arguments in voronoi test chore: fix mismerged changelog refactor!: remove deprecated allocation macros Merge branch 'master' into develop Merge branch 'master' into develop Merge branch 'master' into develop docs: clarify that usage of sub-headers is not supported closes igraph/igraph#2332 Merge branch 'master' into develop refactor: more readable variable named in similarity code Use two vertex selectors in Jaccard and Dice (igraph/igraph#2346) Merge branch 'master' into develop chore: update changelog, mentioning the the Pajek reader/writer now uses the 'name' attribute docs: update Pajek docs, mentioning that the 'name' attribute is used Merge pull request igraph/igraph#2276 from igraph/fix/pajek-names Merge pull request igraph/igraph#2265 from VRajesh7649/feat/erdos_penyi_gnm_multiedges Merge branch 'master' into develop Merge branch 'master' into develop Merge branch 'master' into develop refactor: fixed singular/plural issues with abstract types in types.yaml, now they are consistent fix: fix typo in functions.yaml refactor: rename igraph_delete_vertices_idx() to igraph_delete_vertices_map(), closes igraph/igraph#2310 Merge branch 'master' into develop Merge branch 'master' into develop Merge branch 'master' into develop Merge branch 'master' into develop Merge branch 'master' into develop Merge branch 'master' into develop Merge branch 'master' into develop Merge branch 'master' into develop Merge branch 'master' into develop Merge branch 'master' into develop chore: update changelog [skip ci] refactor: igraph_rng_set_default() now returns old RNG, fixes igraph/igraph#2273 Merge branch 'master' into develop Merge branch 'master' into develop move community_fastgreedy example to tests move community_edge_betweenness example to tests (igraph/igraph#2270) Revert "move community_edge_betweenness example to tests" move community_edge_betweenness example to tests Merge branch 'master' into develop refactor!: igraph_vector_shuffle() no longer returns an error code, closes igraph/igraph#2268 Merge branch 'master' into develop Merge branch 'master' into develop Merge branch 'master' into develop Merge branch 'master' into develop fix: standards-complient definition for igraph_allow_interruption() refactor: replace IGRAPH_SUCCESS by false in IGRAPH_ALLOW_INTERRUPTION() refactor!: interruption handlers now return igraph_bool_t Merge branch 'master' into develop refactor!: removed void* argument of interruption handlers Merge branch 'master' into develop refactor!: igraph_induced_subgraph_map() does not offset the vertex IDs in the mapping any more refactor!: igraph_delete_vertices_idx() does not offset the vertex IDs in the mapping any more Merge branch 'master' into develop Merge branch 'master' into develop Merge branch 'master' into develop add mode parameter to distances_johnson (igraph/igraph#2218) Merge branch 'master' into develop chore: added 'develop' section to changelog Merge branch 'master' into develop Merge branch 'master' into develop refactor: remove unused 'destroy' field from heap data types; ABI-breaking change; refs igraph/igraph#2214 --- R/aaa-auto.R | 931 +----- src/cpp11.cpp | 940 +++--- src/rinterface.c | 1098 ++---- src/vendor/cigraph/CHANGELOG.md | 40 + .../etc/cmake/cpack_install_script.cmake | 5 + src/vendor/cigraph/etc/cmake/packaging.cmake | 8 +- .../cigraph/include/igraph_attributes.h | 243 +- src/vendor/cigraph/include/igraph_bipartite.h | 2 +- .../cigraph/include/igraph_cocitation.h | 8 +- src/vendor/cigraph/include/igraph_community.h | 4 +- .../cigraph/include/igraph_components.h | 5 - src/vendor/cigraph/include/igraph_games.h | 2 +- src/vendor/cigraph/include/igraph_heap_pmt.h | 1 - src/vendor/cigraph/include/igraph_interface.h | 30 +- src/vendor/cigraph/include/igraph_interrupt.h | 13 +- .../cigraph/include/igraph_matrix_pmt.h | 2 +- src/vendor/cigraph/include/igraph_memory.h | 6 - src/vendor/cigraph/include/igraph_paths.h | 3 +- src/vendor/cigraph/include/igraph_pmt.h | 7 + src/vendor/cigraph/include/igraph_random.h | 2 +- src/vendor/cigraph/include/igraph_strvector.h | 9 +- src/vendor/cigraph/include/igraph_topology.h | 24 +- .../cigraph/include/igraph_typed_list_pmt.h | 1 + .../cigraph/include/igraph_vector_pmt.h | 4 +- src/vendor/cigraph/interfaces/functions.yaml | 474 +-- src/vendor/cigraph/interfaces/types.yaml | 31 +- src/vendor/cigraph/src/community/fluid.c | 4 +- .../cigraph/src/community/label_propagation.c | 4 +- .../src/community/leading_eigenvector.c | 2 +- src/vendor/cigraph/src/community/leiden.c | 4 +- .../src/community/spinglass/clustertool.cpp | 9 +- .../src/community/spinglass/pottsmodel_2.cpp | 4 +- .../src/community/spinglass/pottsmodel_2.h | 4 +- .../cigraph/src/connectivity/components.c | 33 +- src/vendor/cigraph/src/core/heap.pmt | 8 +- src/vendor/cigraph/src/core/indheap.c | 47 +- src/vendor/cigraph/src/core/indheap.h | 6 +- src/vendor/cigraph/src/core/interruption.c | 8 +- src/vendor/cigraph/src/core/interruption.h | 9 +- src/vendor/cigraph/src/core/matrix.pmt | 7 +- src/vendor/cigraph/src/core/sparsemat.c | 36 +- src/vendor/cigraph/src/core/strvector.c | 74 +- src/vendor/cigraph/src/core/typed_list.pmt | 34 + src/vendor/cigraph/src/core/vector.pmt | 10 +- src/vendor/cigraph/src/flow/st-cuts.c | 10 +- src/vendor/cigraph/src/games/erdos_renyi.c | 67 +- src/vendor/cigraph/src/games/static_fitness.c | 2 +- src/vendor/cigraph/src/graph/attributes.c | 615 +++- src/vendor/cigraph/src/graph/attributes.h | 36 +- src/vendor/cigraph/src/graph/cattributes.c | 2967 ++++------------- src/vendor/cigraph/src/graph/type_common.c | 15 +- .../cigraph/src/graph/type_indexededgelist.c | 88 +- src/vendor/cigraph/src/hrg/hrg.cc | 19 +- .../cigraph/src/internal/glpk_support.c | 4 +- src/vendor/cigraph/src/internal/utils.c | 2 +- src/vendor/cigraph/src/io/dl.c | 39 +- src/vendor/cigraph/src/io/gml.c | 187 +- src/vendor/cigraph/src/io/graphml.c | 398 +-- src/vendor/cigraph/src/io/leda.c | 4 +- src/vendor/cigraph/src/io/lgl-parser.y | 2 +- src/vendor/cigraph/src/io/lgl.c | 52 +- src/vendor/cigraph/src/io/ncol-parser.y | 2 +- src/vendor/cigraph/src/io/ncol.c | 51 +- src/vendor/cigraph/src/io/pajek-header.h | 5 +- src/vendor/cigraph/src/io/pajek-parser.y | 240 +- src/vendor/cigraph/src/io/pajek.c | 98 +- src/vendor/cigraph/src/isomorphism/bliss.cc | 150 +- src/vendor/cigraph/src/isomorphism/vf2.c | 2 +- src/vendor/cigraph/src/misc/bipartite.c | 90 +- src/vendor/cigraph/src/misc/cocitation.c | 54 +- src/vendor/cigraph/src/misc/conversion.c | 15 +- src/vendor/cigraph/src/misc/cycle_bases.c | 2 +- .../cigraph/src/misc/microscopic_update.c | 2 +- .../cigraph/src/operators/complementer.c | 3 +- .../src/operators/connect_neighborhood.c | 3 +- src/vendor/cigraph/src/operators/contract.c | 3 +- src/vendor/cigraph/src/operators/difference.c | 3 +- src/vendor/cigraph/src/operators/permute.c | 3 +- src/vendor/cigraph/src/operators/reverse.c | 3 +- .../cigraph/src/operators/rewire_edges.c | 6 +- src/vendor/cigraph/src/operators/simplify.c | 3 +- src/vendor/cigraph/src/operators/subgraph.c | 31 +- src/vendor/cigraph/src/paths/bellman_ford.c | 4 +- src/vendor/cigraph/src/paths/dijkstra.c | 4 +- src/vendor/cigraph/src/paths/johnson.c | 67 +- src/vendor/cigraph/src/paths/unweighted.c | 4 +- src/vendor/cigraph/src/random/random.c | 26 +- src/vendor/cigraph/src/random/rng_pcg32.c | 2 +- src/vendor/igraph_version.h | 4 +- src/vendor/io/lgl-parser.c | 2 +- src/vendor/io/ncol-parser.c | 2 +- src/vendor/io/pajek-parser.c | 562 ++-- src/vendor/io/parsers/pajek-parser.h | 2 +- 93 files changed, 4158 insertions(+), 5993 deletions(-) diff --git a/R/aaa-auto.R b/R/aaa-auto.R index 80f492d10ab..3693b46dad8 100644 --- a/R/aaa-auto.R +++ b/R/aaa-auto.R @@ -24,14 +24,14 @@ copy_impl <- function(from) { res } -delete_vertices_idx_impl <- function(graph, vertices) { +delete_vertices_map_impl <- function(graph, vertices) { # Argument checks ensure_igraph(graph) vertices <- as_igraph_vs(graph, vertices) on.exit( .Call(R_igraph_finalizer) ) # Function call - res <- .Call(R_igraph_delete_vertices_idx, graph, vertices-1) + res <- .Call(R_igraph_delete_vertices_map, graph, vertices-1) res } @@ -617,14 +617,6 @@ get_shortest_path_bellman_ford_impl <- function(graph, from, to, weights=NULL, m if (length(to) == 0) { stop("No vertex was specified") } - if (is.null(weights) && "weight" %in% edge_attr_names(graph)) { - weights <- E(graph)$weight - } - if (!is.null(weights) && any(!is.na(weights))) { - weights <- as.numeric(weights) - } else { - weights <- NULL - } mode <- switch(igraph.match.arg(mode), "out"=1L, "in"=2L, "all"=3L, "total"=3L) on.exit( .Call(R_igraph_finalizer) ) @@ -650,14 +642,6 @@ get_shortest_path_dijkstra_impl <- function(graph, from, to, weights=NULL, mode= if (length(to) == 0) { stop("No vertex was specified") } - if (is.null(weights) && "weight" %in% edge_attr_names(graph)) { - weights <- E(graph)$weight - } - if (!is.null(weights) && any(!is.na(weights))) { - weights <- as.numeric(weights) - } else { - weights <- NULL - } mode <- switch(igraph.match.arg(mode), "out"=1L, "in"=2L, "all"=3L, "total"=3L) on.exit( .Call(R_igraph_finalizer) ) @@ -677,14 +661,6 @@ distances_dijkstra_impl <- function(graph, from=V(graph), to=V(graph), weights, ensure_igraph(graph) from <- as_igraph_vs(graph, from) to <- as_igraph_vs(graph, to) - if (is.null(weights) && "weight" %in% edge_attr_names(graph)) { - weights <- E(graph)$weight - } - if (!is.null(weights) && any(!is.na(weights))) { - weights <- as.numeric(weights) - } else { - weights <- NULL - } mode <- switch(igraph.match.arg(mode), "out"=1L, "in"=2L, "all"=3L, "total"=3L) on.exit( .Call(R_igraph_finalizer) ) @@ -699,14 +675,6 @@ distances_dijkstra_cutoff_impl <- function(graph, from=V(graph), to=V(graph), we ensure_igraph(graph) from <- as_igraph_vs(graph, from) to <- as_igraph_vs(graph, to) - if (is.null(weights) && "weight" %in% edge_attr_names(graph)) { - weights <- E(graph)$weight - } - if (!is.null(weights) && any(!is.na(weights))) { - weights <- as.numeric(weights) - } else { - weights <- NULL - } mode <- switch(igraph.match.arg(mode), "out"=1L, "in"=2L, "all"=3L, "total"=3L) cutoff <- as.numeric(cutoff) @@ -722,14 +690,6 @@ distances_bellman_ford_impl <- function(graph, from=V(graph), to=V(graph), weigh ensure_igraph(graph) from <- as_igraph_vs(graph, from) to <- as_igraph_vs(graph, to) - if (is.null(weights) && "weight" %in% edge_attr_names(graph)) { - weights <- E(graph)$weight - } - if (!is.null(weights) && any(!is.na(weights))) { - weights <- as.numeric(weights) - } else { - weights <- NULL - } mode <- switch(igraph.match.arg(mode), "out"=1L, "in"=2L, "all"=3L, "total"=3L) on.exit( .Call(R_igraph_finalizer) ) @@ -739,23 +699,16 @@ distances_bellman_ford_impl <- function(graph, from=V(graph), to=V(graph), weigh res } -distances_johnson_impl <- function(graph, from=V(graph), to=V(graph), weights) { +distances_johnson_impl <- function(graph, from=V(graph), to=V(graph), weights=NULL, mode=c("out", "in", "all", "total")) { # Argument checks ensure_igraph(graph) from <- as_igraph_vs(graph, from) to <- as_igraph_vs(graph, to) - if (is.null(weights) && "weight" %in% edge_attr_names(graph)) { - weights <- E(graph)$weight - } - if (!is.null(weights) && any(!is.na(weights))) { - weights <- as.numeric(weights) - } else { - weights <- NULL - } + mode <- switch(igraph.match.arg(mode), "out"=1L, "in"=2L, "all"=3L, "total"=3L) on.exit( .Call(R_igraph_finalizer) ) # Function call - res <- .Call(R_igraph_distances_johnson, graph, from-1, to-1, weights) + res <- .Call(R_igraph_distances_johnson, graph, from-1, to-1, weights, mode) res } @@ -765,14 +718,6 @@ distances_floyd_warshall_impl <- function(graph, from=V(graph), to=V(graph), wei ensure_igraph(graph) from <- as_igraph_vs(graph, from) to <- as_igraph_vs(graph, to) - if (is.null(weights) && "weight" %in% edge_attr_names(graph)) { - weights <- E(graph)$weight - } - if (!is.null(weights) && any(!is.na(weights))) { - weights <- as.numeric(weights) - } else { - weights <- NULL - } mode <- switch(igraph.match.arg(mode), "out"=1L, "in"=2L, "all"=3L, "total"=3L) on.exit( .Call(R_igraph_finalizer) ) @@ -787,14 +732,6 @@ voronoi_impl <- function(graph, generators, ..., weights=NULL, mode=c("out", "in check_dots_empty() ensure_igraph(graph) generators <- as_igraph_vs(graph, generators) - if (is.null(weights) && "weight" %in% edge_attr_names(graph)) { - weights <- E(graph)$weight - } - if (!is.null(weights) && any(!is.na(weights))) { - weights <- as.numeric(weights) - } else { - weights <- NULL - } mode <- switch(igraph.match.arg(mode), "out"=1L, "in"=2L, "all"=3L, "total"=3L) tiebreaker <- switch(igraph.match.arg(tiebreaker), "first"=0L, "last"=1L, "random"=2L) @@ -809,14 +746,6 @@ get_k_shortest_paths_impl <- function(graph, from, to, ..., k, weights=NULL, mod # Argument checks check_dots_empty() ensure_igraph(graph) - if (is.null(weights) && "weight" %in% edge_attr_names(graph)) { - weights <- E(graph)$weight - } - if (!is.null(weights) && any(!is.na(weights))) { - weights <- as.numeric(weights) - } else { - weights <- NULL - } k <- as.numeric(k) from <- as_igraph_vs(graph, from) if (length(from) == 0) { @@ -831,12 +760,7 @@ get_k_shortest_paths_impl <- function(graph, from, to, ..., k, weights=NULL, mod on.exit( .Call(R_igraph_finalizer) ) # Function call res <- .Call(R_igraph_get_k_shortest_paths, graph, weights, k, from-1, to-1, mode) - if (igraph_opt("return.vs.es")) { - res$vpaths <- lapply(res$vpaths, unsafe_create_vs, graph = graph, verts = V(graph)) - } - if (igraph_opt("return.vs.es")) { - res$epaths <- lapply(res$epaths, unsafe_create_es, graph = graph, es = E(graph)) - } + res } @@ -851,14 +775,6 @@ get_widest_path_impl <- function(graph, from, to, weights=NULL, mode=c("out", "i if (length(to) == 0) { stop("No vertex was specified") } - if (is.null(weights) && "weight" %in% edge_attr_names(graph)) { - weights <- E(graph)$weight - } - if (!is.null(weights) && any(!is.na(weights))) { - weights <- as.numeric(weights) - } else { - weights <- NULL - } mode <- switch(igraph.match.arg(mode), "out"=1L, "in"=2L, "all"=3L, "total"=3L) on.exit( .Call(R_igraph_finalizer) ) @@ -881,25 +797,12 @@ get_widest_paths_impl <- function(graph, from, to=V(graph), weights=NULL, mode=c stop("No vertex was specified") } to <- as_igraph_vs(graph, to) - if (is.null(weights) && "weight" %in% edge_attr_names(graph)) { - weights <- E(graph)$weight - } - if (!is.null(weights) && any(!is.na(weights))) { - weights <- as.numeric(weights) - } else { - weights <- NULL - } mode <- switch(igraph.match.arg(mode), "out"=1L, "in"=2L, "all"=3L, "total"=3L) on.exit( .Call(R_igraph_finalizer) ) # Function call res <- .Call(R_igraph_get_widest_paths, graph, from-1, to-1, weights, mode) - if (igraph_opt("return.vs.es")) { - res$vertices <- lapply(res$vertices, unsafe_create_vs, graph = graph, verts = V(graph)) - } - if (igraph_opt("return.vs.es")) { - res$edges <- lapply(res$edges, unsafe_create_es, graph = graph, es = E(graph)) - } + res } @@ -908,14 +811,6 @@ widest_path_widths_dijkstra_impl <- function(graph, from=V(graph), to=V(graph), ensure_igraph(graph) from <- as_igraph_vs(graph, from) to <- as_igraph_vs(graph, to) - if (is.null(weights) && "weight" %in% edge_attr_names(graph)) { - weights <- E(graph)$weight - } - if (!is.null(weights) && any(!is.na(weights))) { - weights <- as.numeric(weights) - } else { - weights <- NULL - } mode <- switch(igraph.match.arg(mode), "out"=1L, "in"=2L, "all"=3L, "total"=3L) on.exit( .Call(R_igraph_finalizer) ) @@ -930,14 +825,6 @@ widest_path_widths_floyd_warshall_impl <- function(graph, from=V(graph), to=V(gr ensure_igraph(graph) from <- as_igraph_vs(graph, from) to <- as_igraph_vs(graph, to) - if (is.null(weights) && "weight" %in% edge_attr_names(graph)) { - weights <- E(graph)$weight - } - if (!is.null(weights) && any(!is.na(weights))) { - weights <- as.numeric(weights) - } else { - weights <- NULL - } mode <- switch(igraph.match.arg(mode), "out"=1L, "in"=2L, "all"=3L, "total"=3L) on.exit( .Call(R_igraph_finalizer) ) @@ -951,14 +838,6 @@ spanner_impl <- function(graph, stretch, weights=NULL) { # Argument checks ensure_igraph(graph) stretch <- as.numeric(stretch) - if (is.null(weights) && "weight" %in% edge_attr_names(graph)) { - weights <- E(graph)$weight - } - if (!is.null(weights) && any(!is.na(weights))) { - weights <- as.numeric(weights) - } else { - weights <- NULL - } on.exit( .Call(R_igraph_finalizer) ) # Function call @@ -976,21 +855,11 @@ betweenness_subset_impl <- function(graph, vids=V(graph), directed=TRUE, sources directed <- as.logical(directed) sources <- as_igraph_vs(graph, sources) targets <- as_igraph_vs(graph, targets) - if (is.null(weights) && "weight" %in% edge_attr_names(graph)) { - weights <- E(graph)$weight - } - if (!is.null(weights) && any(!is.na(weights))) { - weights <- as.numeric(weights) - } else { - weights <- NULL - } on.exit( .Call(R_igraph_finalizer) ) # Function call res <- .Call(R_igraph_betweenness_subset, graph, vids-1, directed, sources-1, targets-1, weights) - if (igraph_opt("add.vertex.names") && is_named(graph)) { - names(res) <- vertex_attr(graph, "name", vids) - } + res } @@ -1001,14 +870,6 @@ edge_betweenness_subset_impl <- function(graph, eids=E(graph), directed=TRUE, so directed <- as.logical(directed) sources <- as_igraph_vs(graph, sources) targets <- as_igraph_vs(graph, targets) - if (is.null(weights) && "weight" %in% edge_attr_names(graph)) { - weights <- E(graph)$weight - } - if (!is.null(weights) && any(!is.na(weights))) { - weights <- as.numeric(weights) - } else { - weights <- NULL - } on.exit( .Call(R_igraph_finalizer) ) # Function call @@ -1022,23 +883,13 @@ harmonic_centrality_cutoff_impl <- function(graph, vids=V(graph), mode=c("out", ensure_igraph(graph) vids <- as_igraph_vs(graph, vids) mode <- switch(igraph.match.arg(mode), "out"=1L, "in"=2L, "all"=3L, "total"=3L) - if (is.null(weights) && "weight" %in% edge_attr_names(graph)) { - weights <- E(graph)$weight - } - if (!is.null(weights) && any(!is.na(weights))) { - weights <- as.numeric(weights) - } else { - weights <- NULL - } normalized <- as.logical(normalized) cutoff <- as.numeric(cutoff) on.exit( .Call(R_igraph_finalizer) ) # Function call res <- .Call(R_igraph_harmonic_centrality_cutoff, graph, vids-1, mode, weights, normalized, cutoff) - if (igraph_opt("add.vertex.names") && is_named(graph)) { - names(res) <- vertex_attr(graph, "name", vids) - } + res } @@ -1050,14 +901,6 @@ personalized_pagerank_impl <- function(graph, algo=c("prpack", "arpack"), vids=V directed <- as.logical(directed) damping <- as.numeric(damping) if (!is.null(personalized)) personalized <- as.numeric(personalized) - if (is.null(weights) && "weight" %in% edge_attr_names(graph)) { - weights <- E(graph)$weight - } - if (!is.null(weights) && any(!is.na(weights))) { - weights <- as.numeric(weights) - } else { - weights <- NULL - } if (is.null(options)) { if (algo == 0L) { options <- list(niter=1000, eps=0.001) @@ -1071,9 +914,7 @@ personalized_pagerank_impl <- function(graph, algo=c("prpack", "arpack"), vids=V on.exit( .Call(R_igraph_finalizer) ) # Function call res <- .Call(R_igraph_personalized_pagerank, graph, algo, vids-1, directed, damping, personalized, weights, options) - if (igraph_opt("add.vertex.names") && is_named(graph)) { - names(res$vector) <- vertex_attr(graph, "name", vids) - } + res } @@ -1085,14 +926,6 @@ personalized_pagerank_vs_impl <- function(graph, algo=c("prpack", "arpack"), vid directed <- as.logical(directed) damping <- as.numeric(damping) reset.vids <- as_igraph_vs(graph, reset.vids) - if (is.null(weights) && "weight" %in% edge_attr_names(graph)) { - weights <- E(graph)$weight - } - if (!is.null(weights) && any(!is.na(weights))) { - weights <- as.numeric(weights) - } else { - weights <- NULL - } if (is.null(options)) { if (algo == 0L) { options <- list(niter=1000, eps=0.001) @@ -1106,9 +939,6 @@ personalized_pagerank_vs_impl <- function(graph, algo=c("prpack", "arpack"), vid on.exit( .Call(R_igraph_finalizer) ) # Function call res <- .Call(R_igraph_personalized_pagerank_vs, graph, algo, vids-1, directed, damping, reset.vids-1, weights, options) - if (igraph_opt("add.vertex.names") && is_named(graph)) { - names(res$vector) <- vertex_attr(graph, "name", vids) - } if (!details) { res <- res$vector } @@ -1143,14 +973,6 @@ reverse_edges_impl <- function(graph, eids=E(graph)) { average_path_length_dijkstra_impl <- function(graph, weights=NULL, directed=TRUE, unconnected=TRUE, details=FALSE) { # Argument checks ensure_igraph(graph) - if (is.null(weights) && "weight" %in% edge_attr_names(graph)) { - weights <- E(graph)$weight - } - if (!is.null(weights) && any(!is.na(weights))) { - weights <- as.numeric(weights) - } else { - weights <- NULL - } directed <- as.logical(directed) unconnected <- as.logical(unconnected) @@ -1220,14 +1042,6 @@ reciprocity_impl <- function(graph, ignore.loops=TRUE, mode=c("default", "ratio" feedback_arc_set_impl <- function(graph, weights=NULL, algo=c("approx_eades", "exact_ip")) { # Argument checks ensure_igraph(graph) - if (is.null(weights) && "weight" %in% edge_attr_names(graph)) { - weights <- E(graph)$weight - } - if (!is.null(weights) && any(!is.na(weights))) { - weights <- as.numeric(weights) - } else { - weights <- NULL - } algo <- switch(igraph.match.arg(algo), "exact_ip"=0L, "approx_eades"=1L) on.exit( .Call(R_igraph_finalizer) ) @@ -1341,99 +1155,52 @@ is_perfect_impl <- function(graph) { res } -eigenvector_centrality_impl <- function(graph, directed=FALSE, scale=TRUE, weights=NULL, options=arpack_defaults()) { +eigenvector_centrality_impl <- function(graph, directed=FALSE, scale=TRUE, weights=NULL, options=ARPACK_DEFAULTS) { # Argument checks ensure_igraph(graph) directed <- as.logical(directed) scale <- as.logical(scale) - if (is.null(weights) && "weight" %in% edge_attr_names(graph)) { - weights <- E(graph)$weight - } - if (!is.null(weights) && any(!is.na(weights))) { - weights <- as.numeric(weights) - } else { - weights <- NULL - } - options <- modify_list(arpack_defaults(), options) on.exit( .Call(R_igraph_finalizer) ) # Function call res <- .Call(R_igraph_eigenvector_centrality, graph, directed, scale, weights, options) - if (igraph_opt("add.vertex.names") && is_named(graph)) { - names(res$vector) <- vertex_attr(graph, "name", V(graph)) - } + res } -hub_score_impl <- function(graph, scale=TRUE, weights=NULL, options=arpack_defaults()) { +hub_score_impl <- function(graph, scale=TRUE, weights=NULL, options=ARPACK_DEFAULTS) { # Argument checks ensure_igraph(graph) scale <- as.logical(scale) - if (is.null(weights) && "weight" %in% edge_attr_names(graph)) { - weights <- E(graph)$weight - } - if (!is.null(weights) && any(!is.na(weights))) { - weights <- as.numeric(weights) - } else { - weights <- NULL - } - options <- modify_list(arpack_defaults(), options) on.exit( .Call(R_igraph_finalizer) ) # Function call res <- .Call(R_igraph_hub_score, graph, scale, weights, options) - if (igraph_opt("add.vertex.names") && is_named(graph)) { - names(res$vector) <- vertex_attr(graph, "name", V(graph)) - } + res } -authority_score_impl <- function(graph, scale=TRUE, weights=NULL, options=arpack_defaults()) { +authority_score_impl <- function(graph, scale=TRUE, weights=NULL, options=ARPACK_DEFAULTS) { # Argument checks ensure_igraph(graph) scale <- as.logical(scale) - if (is.null(weights) && "weight" %in% edge_attr_names(graph)) { - weights <- E(graph)$weight - } - if (!is.null(weights) && any(!is.na(weights))) { - weights <- as.numeric(weights) - } else { - weights <- NULL - } - options <- modify_list(arpack_defaults(), options) on.exit( .Call(R_igraph_finalizer) ) # Function call res <- .Call(R_igraph_authority_score, graph, scale, weights, options) - if (igraph_opt("add.vertex.names") && is_named(graph)) { - names(res$vector) <- vertex_attr(graph, "name", V(graph)) - } + res } -hub_and_authority_scores_impl <- function(graph, scale=TRUE, weights=NULL, options=arpack_defaults()) { +hub_and_authority_scores_impl <- function(graph, scale=TRUE, weights=NULL, options=ARPACK_DEFAULTS) { # Argument checks ensure_igraph(graph) scale <- as.logical(scale) - if (is.null(weights) && "weight" %in% edge_attr_names(graph)) { - weights <- E(graph)$weight - } - if (!is.null(weights) && any(!is.na(weights))) { - weights <- as.numeric(weights) - } else { - weights <- NULL - } - options <- modify_list(arpack_defaults(), options) on.exit( .Call(R_igraph_finalizer) ) # Function call res <- .Call(R_igraph_hub_and_authority_scores, graph, scale, weights, options) - if (igraph_opt("add.vertex.names") && is_named(graph)) { - names(res$hub.vector) <- vertex_attr(graph, "name", V(graph)) - } - if (igraph_opt("add.vertex.names") && is_named(graph)) { - names(res$authority.vector) <- vertex_attr(graph, "name", V(graph)) - } + res } @@ -1481,35 +1248,17 @@ avg_nearest_neighbor_degree_impl <- function(graph, vids=V(graph), mode=c("all", vids <- as_igraph_vs(graph, vids) mode <- switch(igraph.match.arg(mode), "out"=1L, "in"=2L, "all"=3L, "total"=3L) neighbor.degree.mode <- switch(igraph.match.arg(neighbor.degree.mode), "out"=1L, "in"=2L, "all"=3L, "total"=3L) - if (is.null(weights) && "weight" %in% edge_attr_names(graph)) { - weights <- E(graph)$weight - } - if (!is.null(weights) && any(!is.na(weights))) { - weights <- as.numeric(weights) - } else { - weights <- NULL - } on.exit( .Call(R_igraph_finalizer) ) # Function call res <- .Call(R_igraph_avg_nearest_neighbor_degree, graph, vids-1, mode, neighbor.degree.mode, weights) - if (igraph_opt("add.vertex.names") && is_named(graph)) { - names(res$knn) <- vertex_attr(graph, "name", vids) - } + res } degree_correlation_vector_impl <- function(graph, weights=NULL, from.mode=c("out", "in", "all", "total"), to.mode=c("in", "out", "all", "total"), directed.neighbors=TRUE) { # Argument checks ensure_igraph(graph) - if (is.null(weights) && "weight" %in% edge_attr_names(graph)) { - weights <- E(graph)$weight - } - if (!is.null(weights) && any(!is.na(weights))) { - weights <- as.numeric(weights) - } else { - weights <- NULL - } from.mode <- switch(igraph.match.arg(from.mode), "out"=1L, "in"=2L, "all"=3L, "total"=3L) to.mode <- switch(igraph.match.arg(to.mode), "out"=1L, "in"=2L, "all"=3L, "total"=3L) directed.neighbors <- as.logical(directed.neighbors) @@ -1527,21 +1276,11 @@ strength_impl <- function(graph, vids=V(graph), mode=c("all", "out", "in", "tota vids <- as_igraph_vs(graph, vids) mode <- switch(igraph.match.arg(mode), "out"=1L, "in"=2L, "all"=3L, "total"=3L) loops <- as.logical(loops) - if (is.null(weights) && "weight" %in% edge_attr_names(graph)) { - weights <- E(graph)$weight - } - if (!is.null(weights) && any(!is.na(weights))) { - weights <- as.numeric(weights) - } else { - weights <- NULL - } on.exit( .Call(R_igraph_finalizer) ) # Function call res <- .Call(R_igraph_strength, graph, vids-1, mode, loops, weights) - if (igraph_opt("add.vertex.names") && is_named(graph)) { - names(res) <- vertex_attr(graph, "name", vids) - } + res } @@ -1625,12 +1364,11 @@ centralization_closeness_tmax_impl <- function(graph=NULL, nodes=0, mode=c("out" res } -centralization_eigenvector_centrality_impl <- function(graph, directed=FALSE, scale=TRUE, options=arpack_defaults(), normalized=TRUE) { +centralization_eigenvector_centrality_impl <- function(graph, directed=FALSE, scale=TRUE, options=ARPACK_DEFAULTS, normalized=TRUE) { # Argument checks ensure_igraph(graph) directed <- as.logical(directed) scale <- as.logical(scale) - options <- modify_list(arpack_defaults(), options) normalized <- as.logical(normalized) on.exit( .Call(R_igraph_finalizer) ) @@ -1698,14 +1436,6 @@ assortativity_degree_impl <- function(graph, directed=TRUE) { joint_degree_matrix_impl <- function(graph, weights=NULL, max.out.degree=-1, max.in.degree=-1) { # Argument checks ensure_igraph(graph) - if (is.null(weights) && "weight" %in% edge_attr_names(graph)) { - weights <- E(graph)$weight - } - if (!is.null(weights) && any(!is.na(weights))) { - weights <- as.numeric(weights) - } else { - weights <- NULL - } max.out.degree <- as.numeric(max.out.degree) max.in.degree <- as.numeric(max.in.degree) @@ -1719,14 +1449,6 @@ joint_degree_matrix_impl <- function(graph, weights=NULL, max.out.degree=-1, max joint_degree_distribution_impl <- function(graph, weights=NULL, from.mode=c("out", "in", "all", "total"), to.mode=c("in", "out", "all", "total"), directed.neighbors=TRUE, normalized=TRUE, max.from.degree=-1, max.to.degree=-1) { # Argument checks ensure_igraph(graph) - if (is.null(weights) && "weight" %in% edge_attr_names(graph)) { - weights <- E(graph)$weight - } - if (!is.null(weights) && any(!is.na(weights))) { - weights <- as.numeric(weights) - } else { - weights <- NULL - } from.mode <- switch(igraph.match.arg(from.mode), "out"=1L, "in"=2L, "all"=3L, "total"=3L) to.mode <- switch(igraph.match.arg(to.mode), "out"=1L, "in"=2L, "all"=3L, "total"=3L) directed.neighbors <- as.logical(directed.neighbors) @@ -1744,14 +1466,6 @@ joint_degree_distribution_impl <- function(graph, weights=NULL, from.mode=c("out joint_type_distribution_impl <- function(graph, weights=NULL, from.types, to.types=NULL, directed=TRUE, normalized=TRUE) { # Argument checks ensure_igraph(graph) - if (is.null(weights) && "weight" %in% edge_attr_names(graph)) { - weights <- E(graph)$weight - } - if (!is.null(weights) && any(!is.na(weights))) { - weights <- as.numeric(weights) - } else { - weights <- NULL - } from.types <- as.numeric(from.types)-1 to.types <- as.numeric(to.types)-1 directed <- as.logical(directed) @@ -1786,32 +1500,20 @@ eccentricity_impl <- function(graph, vids=V(graph), mode=c("all", "out", "in", " on.exit( .Call(R_igraph_finalizer) ) # Function call res <- .Call(R_igraph_eccentricity, graph, vids-1, mode) - if (igraph_opt("add.vertex.names") && is_named(graph)) { - names(res) <- vertex_attr(graph, "name", vids) - } + res } eccentricity_dijkstra_impl <- function(graph, weights=NULL, vids=V(graph), mode=c("all", "out", "in", "total")) { # Argument checks ensure_igraph(graph) - if (is.null(weights) && "weight" %in% edge_attr_names(graph)) { - weights <- E(graph)$weight - } - if (!is.null(weights) && any(!is.na(weights))) { - weights <- as.numeric(weights) - } else { - weights <- NULL - } vids <- as_igraph_vs(graph, vids) mode <- switch(igraph.match.arg(mode), "out"=1L, "in"=2L, "all"=3L, "total"=3L) on.exit( .Call(R_igraph_finalizer) ) # Function call res <- .Call(R_igraph_eccentricity_dijkstra, graph, weights, vids-1, mode) - if (igraph_opt("add.vertex.names") && is_named(graph)) { - names(res) <- vertex_attr(graph, "name", vids) - } + res } @@ -1832,14 +1534,6 @@ graph_center_impl <- function(graph, mode=c("all", "out", "in", "total")) { graph_center_dijkstra_impl <- function(graph, weights=NULL, mode=c("all", "out", "in", "total")) { # Argument checks ensure_igraph(graph) - if (is.null(weights) && "weight" %in% edge_attr_names(graph)) { - weights <- E(graph)$weight - } - if (!is.null(weights) && any(!is.na(weights))) { - weights <- as.numeric(weights) - } else { - weights <- NULL - } mode <- switch(igraph.match.arg(mode), "out"=1L, "in"=2L, "all"=3L, "total"=3L) on.exit( .Call(R_igraph_finalizer) ) @@ -1866,14 +1560,6 @@ radius_impl <- function(graph, mode=c("all", "out", "in", "total")) { radius_dijkstra_impl <- function(graph, weights=NULL, mode=c("all", "out", "in", "total")) { # Argument checks ensure_igraph(graph) - if (is.null(weights) && "weight" %in% edge_attr_names(graph)) { - weights <- E(graph)$weight - } - if (!is.null(weights) && any(!is.na(weights))) { - weights <- as.numeric(weights) - } else { - weights <- NULL - } mode <- switch(igraph.match.arg(mode), "out"=1L, "in"=2L, "all"=3L, "total"=3L) on.exit( .Call(R_igraph_finalizer) ) @@ -1903,14 +1589,6 @@ pseudo_diameter_impl <- function(graph, start.vid, directed=TRUE, unconnected=TR pseudo_diameter_dijkstra_impl <- function(graph, weights=NULL, start.vid, directed=TRUE, unconnected=TRUE) { # Argument checks ensure_igraph(graph) - if (is.null(weights) && "weight" %in% edge_attr_names(graph)) { - weights <- E(graph)$weight - } - if (!is.null(weights) && any(!is.na(weights))) { - weights <- as.numeric(weights) - } else { - weights <- NULL - } start.vid <- as_igraph_vs(graph, start.vid) if (length(start.vid) == 0) { stop("No vertex was specified") @@ -1928,36 +1606,18 @@ pseudo_diameter_dijkstra_impl <- function(graph, weights=NULL, start.vid, direct diversity_impl <- function(graph, weights=NULL, vids=V(graph)) { # Argument checks ensure_igraph(graph) - if (is.null(weights) && "weight" %in% edge_attr_names(graph)) { - weights <- E(graph)$weight - } - if (!is.null(weights) && any(!is.na(weights))) { - weights <- as.numeric(weights) - } else { - weights <- NULL - } vids <- as_igraph_vs(graph, vids) on.exit( .Call(R_igraph_finalizer) ) # Function call res <- .Call(R_igraph_diversity, graph, weights, vids-1) - if (igraph_opt("add.vertex.names") && is_named(graph)) { - names(res) <- vertex_attr(graph, "name", vids) - } + res } random_walk_impl <- function(graph, start, steps, weights=NULL, mode=c("out", "in", "all", "total"), stuck=c("return", "error")) { # Argument checks ensure_igraph(graph) - if (is.null(weights) && "weight" %in% edge_attr_names(graph)) { - weights <- E(graph)$weight - } - if (!is.null(weights) && any(!is.na(weights))) { - weights <- as.numeric(weights) - } else { - weights <- NULL - } start <- as_igraph_vs(graph, start) if (length(start) == 0) { stop("No vertex was specified") @@ -1981,14 +1641,6 @@ random_walk_impl <- function(graph, start, steps, weights=NULL, mode=c("out", "i random_edge_walk_impl <- function(graph, start, steps, weights=NULL, mode=c("out", "in", "all", "total"), stuck=c("return", "error")) { # Argument checks ensure_igraph(graph) - if (is.null(weights) && "weight" %in% edge_attr_names(graph)) { - weights <- E(graph)$weight - } - if (!is.null(weights) && any(!is.na(weights))) { - weights <- as.numeric(weights) - } else { - weights <- NULL - } start <- as_igraph_vs(graph, start) if (length(start) == 0) { stop("No vertex was specified") @@ -2009,14 +1661,6 @@ random_edge_walk_impl <- function(graph, start, steps, weights=NULL, mode=c("out global_efficiency_impl <- function(graph, weights=NULL, directed=TRUE) { # Argument checks ensure_igraph(graph) - if (is.null(weights) && "weight" %in% edge_attr_names(graph)) { - weights <- E(graph)$weight - } - if (!is.null(weights) && any(!is.na(weights))) { - weights <- as.numeric(weights) - } else { - weights <- NULL - } directed <- as.logical(directed) on.exit( .Call(R_igraph_finalizer) ) @@ -2030,37 +1674,19 @@ local_efficiency_impl <- function(graph, vids=V(graph), weights=NULL, directed=T # Argument checks ensure_igraph(graph) vids <- as_igraph_vs(graph, vids) - if (is.null(weights) && "weight" %in% edge_attr_names(graph)) { - weights <- E(graph)$weight - } - if (!is.null(weights) && any(!is.na(weights))) { - weights <- as.numeric(weights) - } else { - weights <- NULL - } directed <- as.logical(directed) mode <- switch(igraph.match.arg(mode), "out"=1L, "in"=2L, "all"=3L, "total"=3L) on.exit( .Call(R_igraph_finalizer) ) # Function call res <- .Call(R_igraph_local_efficiency, graph, vids-1, weights, directed, mode) - if (igraph_opt("add.vertex.names") && is_named(graph)) { - names(res) <- vertex_attr(graph, "name", vids) - } + res } average_local_efficiency_impl <- function(graph, weights=NULL, directed=TRUE, mode=c("all", "out", "in", "total")) { # Argument checks ensure_igraph(graph) - if (is.null(weights) && "weight" %in% edge_attr_names(graph)) { - weights <- E(graph)$weight - } - if (!is.null(weights) && any(!is.na(weights))) { - weights <- as.numeric(weights) - } else { - weights <- NULL - } directed <- as.logical(directed) mode <- switch(igraph.match.arg(mode), "out"=1L, "in"=2L, "all"=3L, "total"=3L) @@ -2201,14 +1827,6 @@ get_laplacian_impl <- function(graph, mode=c("out", "in", "all", "total"), norma ensure_igraph(graph) mode <- switch(igraph.match.arg(mode), "out"=1L, "in"=2L, "all"=3L, "total"=3L) normalization <- switch(igraph.match.arg(normalization), "unnormalized"=0L, "symmetric"=1L, "left"=2L, "right"=3L) - if (is.null(weights) && "weight" %in% edge_attr_names(graph)) { - weights <- E(graph)$weight - } - if (!is.null(weights) && any(!is.na(weights))) { - weights <- as.numeric(weights) - } else { - weights <- NULL - } on.exit( .Call(R_igraph_finalizer) ) # Function call @@ -2222,14 +1840,6 @@ get_laplacian_sparse_impl <- function(graph, mode=c("out", "in", "all", "total") ensure_igraph(graph) mode <- switch(igraph.match.arg(mode), "out"=1L, "in"=2L, "all"=3L, "total"=3L) normalization <- switch(igraph.match.arg(normalization), "unnormalized"=0L, "symmetric"=1L, "left"=2L, "right"=3L) - if (is.null(weights) && "weight" %in% edge_attr_names(graph)) { - weights <- E(graph)$weight - } - if (!is.null(weights) && any(!is.na(weights))) { - weights <- as.numeric(weights) - } else { - weights <- NULL - } on.exit( .Call(R_igraph_finalizer) ) # Function call @@ -2270,15 +1880,6 @@ biconnected_components_impl <- function(graph) { on.exit( .Call(R_igraph_finalizer) ) # Function call res <- .Call(R_igraph_biconnected_components, graph) - if (igraph_opt("return.vs.es")) { - res$tree.edges <- lapply(res$tree.edges, unsafe_create_es, graph = graph, es = E(graph)) - } - if (igraph_opt("return.vs.es")) { - res$component.edges <- lapply(res$component.edges, unsafe_create_es, graph = graph, es = E(graph)) - } - if (igraph_opt("return.vs.es")) { - res$components <- lapply(res$components, unsafe_create_vs, graph = graph, verts = V(graph)) - } if (igraph_opt("return.vs.es")) { res$articulation.points <- create_vs(graph, res$articulation.points) } @@ -2318,9 +1919,7 @@ cliques_impl <- function(graph, min=0, max=0) { on.exit( .Call(R_igraph_finalizer) ) # Function call res <- .Call(R_igraph_cliques, graph, min, max) - if (igraph_opt("return.vs.es")) { - res <- lapply(res, unsafe_create_vs, graph = graph, verts = V(graph)) - } + res } @@ -2344,9 +1943,7 @@ largest_cliques_impl <- function(graph) { on.exit( .Call(R_igraph_finalizer) ) # Function call res <- .Call(R_igraph_largest_cliques, graph) - if (igraph_opt("return.vs.es")) { - res <- lapply(res, unsafe_create_vs, graph = graph, verts = V(graph)) - } + res } @@ -2377,14 +1974,6 @@ clique_number_impl <- function(graph) { weighted_cliques_impl <- function(graph, vertex.weights=NULL, min.weight=0, max.weight=0, maximal=FALSE) { # Argument checks ensure_igraph(graph) - if (is.null(vertex.weights) && "weight" %in% vertex_attr_names(graph)) { - vertex.weights <- V(graph)$weight - } - if (!is.null(vertex.weights) && any(!is.na(vertex.weights))) { - vertex.weights <- as.numeric(vertex.weights) - } else { - vertex.weights <- NULL - } min.weight <- as.numeric(min.weight) max.weight <- as.numeric(max.weight) maximal <- as.logical(maximal) @@ -2392,44 +1981,24 @@ weighted_cliques_impl <- function(graph, vertex.weights=NULL, min.weight=0, max. on.exit( .Call(R_igraph_finalizer) ) # Function call res <- .Call(R_igraph_weighted_cliques, graph, vertex.weights, min.weight, max.weight, maximal) - if (igraph_opt("return.vs.es")) { - res <- lapply(res, unsafe_create_vs, graph = graph, verts = V(graph)) - } + res } largest_weighted_cliques_impl <- function(graph, vertex.weights=NULL) { # Argument checks ensure_igraph(graph) - if (is.null(vertex.weights) && "weight" %in% vertex_attr_names(graph)) { - vertex.weights <- V(graph)$weight - } - if (!is.null(vertex.weights) && any(!is.na(vertex.weights))) { - vertex.weights <- as.numeric(vertex.weights) - } else { - vertex.weights <- NULL - } on.exit( .Call(R_igraph_finalizer) ) # Function call res <- .Call(R_igraph_largest_weighted_cliques, graph, vertex.weights) - if (igraph_opt("return.vs.es")) { - res <- lapply(res, unsafe_create_vs, graph = graph, verts = V(graph)) - } + res } weighted_clique_number_impl <- function(graph, vertex.weights=NULL) { # Argument checks ensure_igraph(graph) - if (is.null(vertex.weights) && "weight" %in% vertex_attr_names(graph)) { - vertex.weights <- V(graph)$weight - } - if (!is.null(vertex.weights) && any(!is.na(vertex.weights))) { - vertex.weights <- as.numeric(vertex.weights) - } else { - vertex.weights <- NULL - } on.exit( .Call(R_igraph_finalizer) ) # Function call @@ -2499,16 +2068,17 @@ layout_umap_compute_weights_impl <- function(graph, distances, weights) { res } -similarity_dice_impl <- function(graph, vids=V(graph), mode=c("all", "out", "in", "total"), loops=FALSE) { +similarity_dice_impl <- function(graph, vit.from=V(graph), vit.to=V(graph), mode=c("all", "out", "in", "total"), loops=FALSE) { # Argument checks ensure_igraph(graph) - vids <- as_igraph_vs(graph, vids) + vit.from <- as_igraph_vs(graph, vit.from) + vit.to <- as_igraph_vs(graph, vit.to) mode <- switch(igraph.match.arg(mode), "out"=1L, "in"=2L, "all"=3L, "total"=3L) loops <- as.logical(loops) on.exit( .Call(R_igraph_finalizer) ) # Function call - res <- .Call(R_igraph_similarity_dice, graph, vids-1, mode, loops) + res <- .Call(R_igraph_similarity_dice, graph, vit.from-1, vit.to-1, mode, loops) res } @@ -2553,16 +2123,17 @@ similarity_inverse_log_weighted_impl <- function(graph, vids=V(graph), mode=c("a res } -similarity_jaccard_impl <- function(graph, vids=V(graph), mode=c("all", "out", "in", "total"), loops=FALSE) { +similarity_jaccard_impl <- function(graph, vit.from=V(graph), vit.to=V(graph), mode=c("all", "out", "in", "total"), loops=FALSE) { # Argument checks ensure_igraph(graph) - vids <- as_igraph_vs(graph, vids) + vit.from <- as_igraph_vs(graph, vit.from) + vit.to <- as_igraph_vs(graph, vit.to) mode <- switch(igraph.match.arg(mode), "out"=1L, "in"=2L, "all"=3L, "total"=3L) loops <- as.logical(loops) on.exit( .Call(R_igraph_finalizer) ) # Function call - res <- .Call(R_igraph_similarity_jaccard, graph, vids-1, mode, loops) + res <- .Call(R_igraph_similarity_jaccard, graph, vit.from-1, vit.to-1, mode, loops) res } @@ -2597,22 +2168,12 @@ similarity_jaccard_pairs_impl <- function(graph, pairs, mode=c("all", "out", "in graphlets_impl <- function(graph, weights=NULL, niter=1000) { # Argument checks ensure_igraph(graph) - if (is.null(weights) && "weight" %in% edge_attr_names(graph)) { - weights <- E(graph)$weight - } - if (!is.null(weights) && any(!is.na(weights))) { - weights <- as.numeric(weights) - } else { - weights <- NULL - } niter <- as.numeric(niter) on.exit( .Call(R_igraph_finalizer) ) # Function call res <- .Call(R_igraph_graphlets, graph, weights, niter) - if (igraph_opt("return.vs.es")) { - res$cliques <- lapply(res$cliques, unsafe_create_vs, graph = graph, verts = V(graph)) - } + res } @@ -2741,14 +2302,6 @@ get_stochastic_sparse_impl <- function(graph, column.wise=FALSE, weights=NULL) { # Argument checks ensure_igraph(graph) column.wise <- as.logical(column.wise) - if (is.null(weights) && "weight" %in% edge_attr_names(graph)) { - weights <- E(graph)$weight - } - if (!is.null(weights) && any(!is.na(weights))) { - weights <- as.numeric(weights) - } else { - weights <- NULL - } on.exit( .Call(R_igraph_finalizer) ) # Function call @@ -2806,14 +2359,6 @@ adjacent_triangles_impl <- function(graph, vids=V(graph)) { local_scan_subset_ecount_impl <- function(graph, weights=NULL, subsets) { # Argument checks ensure_igraph(graph) - if (is.null(weights) && "weight" %in% edge_attr_names(graph)) { - weights <- E(graph)$weight - } - if (!is.null(weights) && any(!is.na(weights))) { - weights <- as.numeric(weights) - } else { - weights <- NULL - } on.exit( .Call(R_igraph_finalizer) ) # Function call @@ -2863,14 +2408,6 @@ induced_subgraph_map_impl <- function(graph, vids, impl) { gomory_hu_tree_impl <- function(graph, capacity=NULL) { # Argument checks ensure_igraph(graph) - if (is.null(capacity) && "capacity" %in% edge_attr_names(graph)) { - capacity <- E(graph)$capacity - } - if (!is.null(capacity) && any(!is.na(capacity))) { - capacity <- as.numeric(capacity) - } else { - capacity <- NULL - } on.exit( .Call(R_igraph_finalizer) ) # Function call @@ -2890,14 +2427,6 @@ maxflow_impl <- function(graph, source, target, capacity=NULL) { if (length(target) == 0) { stop("No vertex was specified") } - if (is.null(capacity) && "capacity" %in% edge_attr_names(graph)) { - capacity <- E(graph)$capacity - } - if (!is.null(capacity) && any(!is.na(capacity))) { - capacity <- as.numeric(capacity) - } else { - capacity <- NULL - } on.exit( .Call(R_igraph_finalizer) ) # Function call @@ -2917,14 +2446,6 @@ maxflow_impl <- function(graph, source, target, capacity=NULL) { residual_graph_impl <- function(graph, capacity, flow) { # Argument checks ensure_igraph(graph) - if (is.null(capacity) && "capacity" %in% edge_attr_names(graph)) { - capacity <- E(graph)$capacity - } - if (!is.null(capacity) && any(!is.na(capacity))) { - capacity <- as.numeric(capacity) - } else { - capacity <- NULL - } flow <- as.numeric(flow) on.exit( .Call(R_igraph_finalizer) ) @@ -2937,14 +2458,6 @@ residual_graph_impl <- function(graph, capacity, flow) { reverse_residual_graph_impl <- function(graph, capacity, flow) { # Argument checks ensure_igraph(graph) - if (is.null(capacity) && "capacity" %in% edge_attr_names(graph)) { - capacity <- E(graph)$capacity - } - if (!is.null(capacity) && any(!is.na(capacity))) { - capacity <- as.numeric(capacity) - } else { - capacity <- NULL - } flow <- as.numeric(flow) on.exit( .Call(R_igraph_finalizer) ) @@ -2987,12 +2500,7 @@ all_st_cuts_impl <- function(graph, source, target) { on.exit( .Call(R_igraph_finalizer) ) # Function call res <- .Call(R_igraph_all_st_cuts, graph, source-1, target-1) - if (igraph_opt("return.vs.es")) { - res$cuts <- lapply(res$cuts, unsafe_create_es, graph = graph, es = E(graph)) - } - if (igraph_opt("return.vs.es")) { - res$partition1s <- lapply(res$partition1s, unsafe_create_vs, graph = graph, verts = V(graph)) - } + res } @@ -3007,24 +2515,11 @@ all_st_mincuts_impl <- function(graph, source, target, capacity=NULL) { if (length(target) == 0) { stop("No vertex was specified") } - if (is.null(capacity) && "capacity" %in% edge_attr_names(graph)) { - capacity <- E(graph)$capacity - } - if (!is.null(capacity) && any(!is.na(capacity))) { - capacity <- as.numeric(capacity) - } else { - capacity <- NULL - } on.exit( .Call(R_igraph_finalizer) ) # Function call res <- .Call(R_igraph_all_st_mincuts, graph, source-1, target-1, capacity) - if (igraph_opt("return.vs.es")) { - res$cuts <- lapply(res$cuts, unsafe_create_es, graph = graph, es = E(graph)) - } - if (igraph_opt("return.vs.es")) { - res$partition1s <- lapply(res$partition1s, unsafe_create_vs, graph = graph, verts = V(graph)) - } + res } @@ -3070,9 +2565,7 @@ all_minimal_st_separators_impl <- function(graph) { on.exit( .Call(R_igraph_finalizer) ) # Function call res <- .Call(R_igraph_all_minimal_st_separators, graph) - if (igraph_opt("return.vs.es")) { - res <- lapply(res, unsafe_create_vs, graph = graph, verts = V(graph)) - } + res } @@ -3083,9 +2576,7 @@ minimum_size_separators_impl <- function(graph) { on.exit( .Call(R_igraph_finalizer) ) # Function call res <- .Call(R_igraph_minimum_size_separators, graph) - if (igraph_opt("return.vs.es")) { - res <- lapply(res, unsafe_create_vs, graph = graph, verts = V(graph)) - } + res } @@ -3112,6 +2603,28 @@ isomorphic_impl <- function(graph1, graph2) { res } +automorphism_group_impl <- function(graph, colors=NULL) { + # Argument checks + ensure_igraph(graph) + + on.exit( .Call(R_igraph_finalizer) ) + # Function call + res <- .Call(R_igraph_automorphism_group, graph, colors) + + res +} + +count_automorphisms_impl <- function(graph, colors=NULL) { + # Argument checks + ensure_igraph(graph) + + on.exit( .Call(R_igraph_finalizer) ) + # Function call + res <- .Call(R_igraph_count_automorphisms, graph, colors) + + res +} + isoclass_create_impl <- function(size, number, directed=TRUE) { # Argument checks size <- as.numeric(size) @@ -3129,46 +2642,6 @@ isomorphic_vf2_impl <- function(graph1, graph2, vertex.color1=NULL, vertex.color # Argument checks ensure_igraph(graph1) ensure_igraph(graph2) - if (missing(vertex.color1)) { - if ("color" %in% vertex_attr_names(graph1)) { - vertex.color1 <- V(graph1)$color - } else { - vertex.color1 <- NULL - } - } - if (!is.null(vertex.color1)) { - vertex.color1 <- as.numeric(vertex.color1)-1 - } - if (missing(vertex.color2)) { - if ("color" %in% vertex_attr_names(graph2)) { - vertex.color2 <- V(graph2)$color - } else { - vertex.color2 <- NULL - } - } - if (!is.null(vertex.color2)) { - vertex.color2 <- as.numeric(vertex.color2)-1 - } - if (missing(edge.color1)) { - if ("color" %in% edge_attr_names(graph1)) { - edge.color1 <- E(graph1)$color - } else { - edge.color1 <- NULL - } - } - if (!is.null(edge.color1)) { - edge.color1 <- as.numeric(edge.color1)-1 - } - if (missing(edge.color2)) { - if ("color" %in% edge_attr_names(graph2)) { - edge.color2 <- E(graph2)$color - } else { - edge.color2 <- NULL - } - } - if (!is.null(edge.color2)) { - edge.color2 <- as.numeric(edge.color2)-1 - } on.exit( .Call(R_igraph_finalizer) ) # Function call @@ -3181,46 +2654,6 @@ count_isomorphisms_vf2_impl <- function(graph1, graph2, vertex.color1, vertex.co # Argument checks ensure_igraph(graph1) ensure_igraph(graph2) - if (missing(vertex.color1)) { - if ("color" %in% vertex_attr_names(graph1)) { - vertex.color1 <- V(graph1)$color - } else { - vertex.color1 <- NULL - } - } - if (!is.null(vertex.color1)) { - vertex.color1 <- as.numeric(vertex.color1)-1 - } - if (missing(vertex.color2)) { - if ("color" %in% vertex_attr_names(graph2)) { - vertex.color2 <- V(graph2)$color - } else { - vertex.color2 <- NULL - } - } - if (!is.null(vertex.color2)) { - vertex.color2 <- as.numeric(vertex.color2)-1 - } - if (missing(edge.color1)) { - if ("color" %in% edge_attr_names(graph1)) { - edge.color1 <- E(graph1)$color - } else { - edge.color1 <- NULL - } - } - if (!is.null(edge.color1)) { - edge.color1 <- as.numeric(edge.color1)-1 - } - if (missing(edge.color2)) { - if ("color" %in% edge_attr_names(graph2)) { - edge.color2 <- E(graph2)$color - } else { - edge.color2 <- NULL - } - } - if (!is.null(edge.color2)) { - edge.color2 <- as.numeric(edge.color2)-1 - } on.exit( .Call(R_igraph_finalizer) ) # Function call @@ -3245,46 +2678,6 @@ subisomorphic_vf2_impl <- function(graph1, graph2, vertex.color1=NULL, vertex.co # Argument checks ensure_igraph(graph1) ensure_igraph(graph2) - if (missing(vertex.color1)) { - if ("color" %in% vertex_attr_names(graph1)) { - vertex.color1 <- V(graph1)$color - } else { - vertex.color1 <- NULL - } - } - if (!is.null(vertex.color1)) { - vertex.color1 <- as.numeric(vertex.color1)-1 - } - if (missing(vertex.color2)) { - if ("color" %in% vertex_attr_names(graph2)) { - vertex.color2 <- V(graph2)$color - } else { - vertex.color2 <- NULL - } - } - if (!is.null(vertex.color2)) { - vertex.color2 <- as.numeric(vertex.color2)-1 - } - if (missing(edge.color1)) { - if ("color" %in% edge_attr_names(graph1)) { - edge.color1 <- E(graph1)$color - } else { - edge.color1 <- NULL - } - } - if (!is.null(edge.color1)) { - edge.color1 <- as.numeric(edge.color1)-1 - } - if (missing(edge.color2)) { - if ("color" %in% edge_attr_names(graph2)) { - edge.color2 <- E(graph2)$color - } else { - edge.color2 <- NULL - } - } - if (!is.null(edge.color2)) { - edge.color2 <- as.numeric(edge.color2)-1 - } on.exit( .Call(R_igraph_finalizer) ) # Function call @@ -3297,46 +2690,6 @@ count_subisomorphisms_vf2_impl <- function(graph1, graph2, vertex.color1, vertex # Argument checks ensure_igraph(graph1) ensure_igraph(graph2) - if (missing(vertex.color1)) { - if ("color" %in% vertex_attr_names(graph1)) { - vertex.color1 <- V(graph1)$color - } else { - vertex.color1 <- NULL - } - } - if (!is.null(vertex.color1)) { - vertex.color1 <- as.numeric(vertex.color1)-1 - } - if (missing(vertex.color2)) { - if ("color" %in% vertex_attr_names(graph2)) { - vertex.color2 <- V(graph2)$color - } else { - vertex.color2 <- NULL - } - } - if (!is.null(vertex.color2)) { - vertex.color2 <- as.numeric(vertex.color2)-1 - } - if (missing(edge.color1)) { - if ("color" %in% edge_attr_names(graph1)) { - edge.color1 <- E(graph1)$color - } else { - edge.color1 <- NULL - } - } - if (!is.null(edge.color1)) { - edge.color1 <- as.numeric(edge.color1)-1 - } - if (missing(edge.color2)) { - if ("color" %in% edge_attr_names(graph2)) { - edge.color2 <- E(graph2)$color - } else { - edge.color2 <- NULL - } - } - if (!is.null(edge.color2)) { - edge.color2 <- as.numeric(edge.color2)-1 - } on.exit( .Call(R_igraph_finalizer) ) # Function call @@ -3345,24 +2698,25 @@ count_subisomorphisms_vf2_impl <- function(graph1, graph2, vertex.color1, vertex res } -canonical_permutation_impl <- function(graph, colors=NULL, sh=c("fm", "f", "fs", "fl", "flm", "fsm")) { +canonical_permutation_impl <- function(graph, colors=NULL) { + # Argument checks + ensure_igraph(graph) + + on.exit( .Call(R_igraph_finalizer) ) + # Function call + res <- .Call(R_igraph_canonical_permutation, graph, colors) + + res +} + +canonical_permutation_bliss_impl <- function(graph, colors=NULL, sh=c("fm", "f", "fs", "fl", "flm", "fsm")) { # Argument checks ensure_igraph(graph) - if (missing(colors)) { - if ("color" %in% vertex_attr_names(graph)) { - colors <- V(graph)$color - } else { - colors <- NULL - } - } - if (!is.null(colors)) { - colors <- as.numeric(colors)-1 - } sh <- switch(igraph.match.arg(sh), "f"=0L, "fl"=1L, "fs"=2L, "fm"=3L, "flm"=4L, "fsm"=5L) on.exit( .Call(R_igraph_finalizer) ) # Function call - res <- .Call(R_igraph_canonical_permutation, graph, colors, sh) + res <- .Call(R_igraph_canonical_permutation_bliss, graph, colors, sh) res } @@ -3383,26 +2737,6 @@ isomorphic_bliss_impl <- function(graph1, graph2, colors1=NULL, colors2=NULL, sh # Argument checks ensure_igraph(graph1) ensure_igraph(graph2) - if (missing(colors1)) { - if ("color" %in% vertex_attr_names(graph1)) { - colors1 <- V(graph1)$color - } else { - colors1 <- NULL - } - } - if (!is.null(colors1)) { - colors1 <- as.numeric(colors1)-1 - } - if (missing(colors2)) { - if ("color" %in% vertex_attr_names(graph2)) { - colors2 <- V(graph2)$color - } else { - colors2 <- NULL - } - } - if (!is.null(colors2)) { - colors2 <- as.numeric(colors2)-1 - } sh <- switch(igraph.match.arg(sh), "f"=0L, "fl"=1L, "fs"=2L, "fm"=3L, "flm"=4L, "fsm"=5L) on.exit( .Call(R_igraph_finalizer) ) @@ -3412,49 +2746,26 @@ isomorphic_bliss_impl <- function(graph1, graph2, colors1=NULL, colors2=NULL, sh res } -count_automorphisms_impl <- function(graph, colors=NULL, sh=c("fm", "f", "fs", "fl", "flm", "fsm")) { +count_automorphisms_bliss_impl <- function(graph, colors=NULL, sh=c("fm", "f", "fs", "fl", "flm", "fsm")) { # Argument checks ensure_igraph(graph) - if (missing(colors)) { - if ("color" %in% vertex_attr_names(graph)) { - colors <- V(graph)$color - } else { - colors <- NULL - } - } - if (!is.null(colors)) { - colors <- as.numeric(colors)-1 - } sh <- switch(igraph.match.arg(sh), "f"=0L, "fl"=1L, "fs"=2L, "fm"=3L, "flm"=4L, "fsm"=5L) on.exit( .Call(R_igraph_finalizer) ) # Function call - res <- .Call(R_igraph_count_automorphisms, graph, colors, sh) + res <- .Call(R_igraph_count_automorphisms_bliss, graph, colors, sh) res } -automorphism_group_impl <- function(graph, colors=NULL, sh=c("fm", "f", "fs", "fl", "flm", "fsm"), details=FALSE) { +automorphism_group_bliss_impl <- function(graph, colors=NULL, sh=c("fm", "f", "fs", "fl", "flm", "fsm"), details=FALSE) { # Argument checks ensure_igraph(graph) - if (missing(colors)) { - if ("color" %in% vertex_attr_names(graph)) { - colors <- V(graph)$color - } else { - colors <- NULL - } - } - if (!is.null(colors)) { - colors <- as.numeric(colors)-1 - } sh <- switch(igraph.match.arg(sh), "f"=0L, "fl"=1L, "fs"=2L, "fm"=3L, "flm"=4L, "fsm"=5L) on.exit( .Call(R_igraph_finalizer) ) # Function call - res <- .Call(R_igraph_automorphism_group, graph, colors, sh) - if (igraph_opt("return.vs.es")) { - res$generators <- lapply(res$generators, unsafe_create_vs, graph = graph, verts = V(graph)) - } + res <- .Call(R_igraph_automorphism_group_bliss, graph, colors, sh) if (!details) { res <- res$generators } @@ -3473,22 +2784,13 @@ graph_count_impl <- function(n, directed=FALSE) { res } -adjacency_spectral_embedding_impl <- function(graph, no, weights=NULL, which=c("lm", "la", "sa"), scaled=TRUE, cvec=strength(graph, weights=weights)/(vcount(graph)-1), options=arpack_defaults()) { +adjacency_spectral_embedding_impl <- function(graph, no, weights=NULL, which=c("lm", "la", "sa"), scaled=TRUE, cvec=strength(graph, weights=weights)/(vcount(graph)-1), options=RPACK_DEFAULTS) { # Argument checks ensure_igraph(graph) no <- as.numeric(no) - if (is.null(weights) && "weight" %in% edge_attr_names(graph)) { - weights <- E(graph)$weight - } - if (!is.null(weights) && any(!is.na(weights))) { - weights <- as.numeric(weights) - } else { - weights <- NULL - } which <- switch(igraph.match.arg(which), "lm"=0L, "la"=2L, "sa"=3L) scaled <- as.logical(scaled) cvec <- as.numeric(cvec) - options <- modify_list(arpack_defaults(), options) on.exit( .Call(R_igraph_finalizer) ) # Function call @@ -3497,25 +2799,16 @@ adjacency_spectral_embedding_impl <- function(graph, no, weights=NULL, which=c(" res } -laplacian_spectral_embedding_impl <- function(graph, no, weights=NULL, which=c("lm", "la", "sa"), type=c("default", "D-A", "DAD", "I-DAD", "OAP"), scaled=TRUE, options=arpack_defaults()) { +laplacian_spectral_embedding_impl <- function(graph, no, weights=NULL, which=c("lm", "la", "sa"), type=c("default", "D-A", "DAD", "I-DAD", "OAP"), scaled=TRUE, options=ARPACK_DEFAULTS) { # Argument checks ensure_igraph(graph) no <- as.numeric(no) - if (is.null(weights) && "weight" %in% edge_attr_names(graph)) { - weights <- E(graph)$weight - } - if (!is.null(weights) && any(!is.na(weights))) { - weights <- as.numeric(weights) - } else { - weights <- NULL - } which <- switch(igraph.match.arg(which), "lm"=0L, "la"=2L, "sa"=3L) type <- switch(igraph.match.arg(type), "default"=if (is.directed(graph)) 3L else 0L, "da"=0L, "d-a"=0L, "idad"=1L, "i-dad"=1L, "dad"=2L, "oap"=3L) scaled <- as.logical(scaled) - options <- modify_list(arpack_defaults(), options) on.exit( .Call(R_igraph_finalizer) ) # Function call @@ -3524,7 +2817,7 @@ laplacian_spectral_embedding_impl <- function(graph, no, weights=NULL, which=c(" res } -eigen_adjacency_impl <- function(graph, algorithm=c("arpack", "auto", "lapack", "comp_auto", "comp_lapack", "comp_arpack"), which=list(), options=arpack_defaults()) { +eigen_adjacency_impl <- function(graph, algorithm=c("arpack", "auto", "lapack", "comp_auto", "comp_lapack", "comp_arpack"), which=list(), options=ARPACK_DEFAULTS, storage) { # Argument checks ensure_igraph(graph) algorithm <- switch(igraph.match.arg(algorithm), "auto"=0L, "lapack"=1L, @@ -3532,11 +2825,10 @@ eigen_adjacency_impl <- function(graph, algorithm=c("arpack", "auto", "lapack", "comp_arpack"=5L) which.tmp <- eigen_defaults(); which.tmp[ names(which) ] <- which ; which <- which.tmp - options <- modify_list(arpack_defaults(), options) on.exit( .Call(R_igraph_finalizer) ) # Function call - res <- .Call(R_igraph_eigen_adjacency, graph, algorithm, which, options) + res <- .Call(R_igraph_eigen_adjacency, graph, algorithm, which, options, storage) res } @@ -3641,21 +2933,11 @@ fundamental_cycles_impl <- function(graph, start=NULL, bfs.cutoff, weights=NULL) stop("No vertex was specified") } bfs.cutoff <- as.numeric(bfs.cutoff) - if (is.null(weights) && "weight" %in% edge_attr_names(graph)) { - weights <- E(graph)$weight - } - if (!is.null(weights) && any(!is.na(weights))) { - weights <- as.numeric(weights) - } else { - weights <- NULL - } on.exit( .Call(R_igraph_finalizer) ) # Function call res <- .Call(R_igraph_fundamental_cycles, graph, start-1, bfs.cutoff, weights) - if (igraph_opt("return.vs.es")) { - res <- lapply(res, unsafe_create_es, graph = graph, es = E(graph)) - } + res } @@ -3665,21 +2947,11 @@ minimum_cycle_basis_impl <- function(graph, bfs.cutoff, complete, use.cycle.orde bfs.cutoff <- as.numeric(bfs.cutoff) complete <- as.logical(complete) use.cycle.order <- as.logical(use.cycle.order) - if (is.null(weights) && "weight" %in% edge_attr_names(graph)) { - weights <- E(graph)$weight - } - if (!is.null(weights) && any(!is.na(weights))) { - weights <- as.numeric(weights) - } else { - weights <- NULL - } on.exit( .Call(R_igraph_finalizer) ) # Function call res <- .Call(R_igraph_minimum_cycle_basis, graph, bfs.cutoff, complete, use.cycle.order, weights) - if (igraph_opt("return.vs.es")) { - res <- lapply(res, unsafe_create_es, graph = graph, es = E(graph)) - } + res } @@ -3805,10 +3077,7 @@ vertex_coloring_greedy_impl <- function(graph, heuristic=c("colored_neighbors", on.exit( .Call(R_igraph_finalizer) ) # Function call res <- .Call(R_igraph_vertex_coloring_greedy, graph, heuristic) - res <- res+1 - if (igraph_opt("add.vertex.names") && is_named(graph)) { - names(res) <- vertex_attr(graph, "name") - } + res } @@ -3833,23 +3102,13 @@ deterministic_optimal_imitation_impl <- function(graph, vid, optimality=c("maxim moran_process_impl <- function(graph, weights=NULL, quantities, strategies, mode=c("out", "in", "all", "total")) { # Argument checks ensure_igraph(graph) - if (is.null(weights) && "weight" %in% edge_attr_names(graph)) { - weights <- E(graph)$weight - } - if (!is.null(weights) && any(!is.na(weights))) { - weights <- as.numeric(weights) - } else { - weights <- NULL - } strategies <- as.numeric(strategies) mode <- switch(igraph.match.arg(mode), "out"=1L, "in"=2L, "all"=3L, "total"=3L) on.exit( .Call(R_igraph_finalizer) ) # Function call res <- .Call(R_igraph_moran_process, graph, weights, quantities, strategies, mode) - if (igraph_opt("add.vertex.names") && is_named(graph)) { - names(res$quantities) <- vertex_attr(graph, "name", V(graph)) - } + res } @@ -3907,3 +3166,15 @@ vertex_path_from_edge_path_impl <- function(graph, start, edge.path, mode=c("out res } +delete_vertices_idx_impl <- function() { + # Argument checks + + + on.exit( .Call(R_igraph_finalizer) ) + # Function call + res <- .Call(R_igraph_delete_vertices_idx) + + + res +} + diff --git a/src/cpp11.cpp b/src/cpp11.cpp index 24cf10d0302..4044dae3232 100644 --- a/src/cpp11.cpp +++ b/src/cpp11.cpp @@ -22,465 +22,469 @@ extern "C" SEXP _igraph_getsphere(SEXP spos, SEXP sradius, SEXP scolor, SEXP lig extern "C" { /* .Call calls */ -extern SEXP R_igraph_add_edges(SEXP, SEXP); -extern SEXP R_igraph_add_env(SEXP); -extern SEXP R_igraph_add_myid_to_env(SEXP); -extern SEXP R_igraph_add_version_to_env(SEXP); -extern SEXP R_igraph_add_vertices(SEXP, SEXP); -extern SEXP R_igraph_address(SEXP); -extern SEXP R_igraph_adhesion(SEXP, SEXP); -extern SEXP R_igraph_adjacency(SEXP, SEXP, SEXP); -extern SEXP R_igraph_adjacency_spectral_embedding(SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_adjacent_triangles(SEXP, SEXP); -extern SEXP R_igraph_adjacent_vertices(SEXP, SEXP, SEXP); -extern SEXP R_igraph_adjlist(SEXP, SEXP, SEXP); -extern SEXP R_igraph_all_minimal_st_separators(SEXP); -extern SEXP R_igraph_all_st_cuts(SEXP, SEXP, SEXP); -extern SEXP R_igraph_all_st_mincuts(SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_are_adjacent(SEXP, SEXP, SEXP); -extern SEXP R_igraph_arpack(SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_arpack_unpack_complex(SEXP, SEXP, SEXP); -extern SEXP R_igraph_articulation_points(SEXP); -extern SEXP R_igraph_assortativity(SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_assortativity_degree(SEXP, SEXP); -extern SEXP R_igraph_assortativity_nominal(SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_asymmetric_preference_game(SEXP, SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_atlas(SEXP); -extern SEXP R_igraph_authority_score(SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_automorphism_group(SEXP, SEXP, SEXP); -extern SEXP R_igraph_average_local_efficiency(SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_average_path_length_dijkstra(SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_avg_nearest_neighbor_degree(SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_barabasi_aging_game(SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_barabasi_game(SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_betweenness_cutoff(SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_betweenness_subset(SEXP, SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_bfs(SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_bfs_simple(SEXP, SEXP, SEXP); -extern SEXP R_igraph_biadjacency(SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_bibcoupling(SEXP, SEXP); -extern SEXP R_igraph_biconnected_components(SEXP); -extern SEXP R_igraph_bipartite_game(SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_bipartite_game_gnm(SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_bipartite_game_gnp(SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_bipartite_projection(SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_bipartite_projection_size(SEXP, SEXP); -extern SEXP R_igraph_bridges(SEXP); -extern SEXP R_igraph_callaway_traits_game(SEXP, SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_canonical_permutation(SEXP, SEXP, SEXP); -extern SEXP R_igraph_centralization(SEXP, SEXP, SEXP); -extern SEXP R_igraph_centralization_betweenness(SEXP, SEXP, SEXP); -extern SEXP R_igraph_centralization_betweenness_tmax(SEXP, SEXP, SEXP); -extern SEXP R_igraph_centralization_closeness(SEXP, SEXP, SEXP); -extern SEXP R_igraph_centralization_closeness_tmax(SEXP, SEXP, SEXP); -extern SEXP R_igraph_centralization_degree(SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_centralization_degree_tmax(SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_centralization_eigenvector_centrality(SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_centralization_eigenvector_centrality_tmax(SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_circulant(SEXP, SEXP, SEXP); -extern SEXP R_igraph_cited_type_game(SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_citing_cited_type_game(SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_clique_number(SEXP); -extern SEXP R_igraph_clique_size_hist(SEXP, SEXP, SEXP); -extern SEXP R_igraph_cliques(SEXP, SEXP, SEXP); -extern SEXP R_igraph_closeness_cutoff(SEXP, SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_cocitation(SEXP, SEXP); -extern SEXP R_igraph_cohesion(SEXP, SEXP); -extern SEXP R_igraph_cohesive_blocks(SEXP); -extern SEXP R_igraph_community_edge_betweenness(SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_community_fastgreedy(SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_community_fluid_communities(SEXP, SEXP); -extern SEXP R_igraph_community_infomap(SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_community_label_propagation(SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_community_leading_eigenvector(SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_community_leiden(SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_community_multilevel(SEXP, SEXP, SEXP); -extern SEXP R_igraph_community_optimal_modularity(SEXP, SEXP); -extern SEXP R_igraph_community_to_membership2(SEXP, SEXP, SEXP); -extern SEXP R_igraph_compare_communities(SEXP, SEXP, SEXP); -extern SEXP R_igraph_complementer(SEXP, SEXP); -extern SEXP R_igraph_compose(SEXP, SEXP, SEXP); -extern SEXP R_igraph_connect_neighborhood(SEXP, SEXP, SEXP); -extern SEXP R_igraph_connected_components(SEXP, SEXP); -extern SEXP R_igraph_constraint(SEXP, SEXP, SEXP); -extern SEXP R_igraph_contract_vertices(SEXP, SEXP, SEXP); -extern SEXP R_igraph_convex_hull(SEXP); -extern SEXP R_igraph_copy(SEXP); -extern SEXP R_igraph_copy_env(SEXP); -extern SEXP R_igraph_copy_from(SEXP); -extern SEXP R_igraph_copy_to(SEXP); -extern SEXP R_igraph_coreness(SEXP, SEXP); -extern SEXP R_igraph_correlated_game(SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_correlated_pair_game(SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_count_automorphisms(SEXP, SEXP, SEXP); -extern SEXP R_igraph_count_isomorphisms_vf2(SEXP, SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_count_multiple(SEXP, SEXP); -extern SEXP R_igraph_count_subisomorphisms_vf2(SEXP, SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_create(SEXP, SEXP, SEXP); -extern SEXP R_igraph_create_bipartite(SEXP, SEXP, SEXP); -extern SEXP R_igraph_de_bruijn(SEXP, SEXP); -extern SEXP R_igraph_decompose(SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_degree(SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_degree_correlation_vector(SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_degree_sequence_game(SEXP, SEXP, SEXP); -extern SEXP R_igraph_delete_edges(SEXP, SEXP); -extern SEXP R_igraph_delete_vertices(SEXP, SEXP); -extern SEXP R_igraph_delete_vertices_idx(SEXP, SEXP); -extern SEXP R_igraph_density(SEXP, SEXP); -extern SEXP R_igraph_deterministic_optimal_imitation(SEXP, SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_dfs(SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_diameter(SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_difference(SEXP, SEXP); -extern SEXP R_igraph_dim_select(SEXP); -extern SEXP R_igraph_disjoint_union(SEXP); -extern SEXP R_igraph_distances(SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_distances_bellman_ford(SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_distances_cutoff(SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_distances_dijkstra(SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_distances_dijkstra_cutoff(SEXP, SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_distances_floyd_warshall(SEXP, SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_distances_johnson(SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_diversity(SEXP, SEXP, SEXP); -extern SEXP R_igraph_dominator_tree(SEXP, SEXP, SEXP); -extern SEXP R_igraph_dot_product_game(SEXP, SEXP); -extern SEXP R_igraph_dyad_census(SEXP); -extern SEXP R_igraph_ecc(SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_eccentricity(SEXP, SEXP, SEXP); -extern SEXP R_igraph_eccentricity_dijkstra(SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_ecount(SEXP); -extern SEXP R_igraph_edge_betweenness_cutoff(SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_edge_betweenness_subset(SEXP, SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_edge_connectivity(SEXP, SEXP); -extern SEXP R_igraph_edge_disjoint_paths(SEXP, SEXP, SEXP); -extern SEXP R_igraph_edges(SEXP, SEXP); -extern SEXP R_igraph_eigen_adjacency(SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_eigenvector_centrality(SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_empty(SEXP, SEXP); -extern SEXP R_igraph_erdos_renyi_game(SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_es_adj(SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_es_pairs(SEXP, SEXP, SEXP); -extern SEXP R_igraph_es_path(SEXP, SEXP, SEXP); -extern SEXP R_igraph_establishment_game(SEXP, SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_eulerian_cycle(SEXP); -extern SEXP R_igraph_eulerian_path(SEXP); -extern SEXP R_igraph_even_tarjan_reduction(SEXP); -extern SEXP R_igraph_extended_chordal_ring(SEXP, SEXP, SEXP); -extern SEXP R_igraph_famous(SEXP); -extern SEXP R_igraph_farthest_points(SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_feedback_arc_set(SEXP, SEXP, SEXP); +extern SEXP R_igraph_add_edges(void *, void *); +extern SEXP R_igraph_add_env(void *); +extern SEXP R_igraph_add_myid_to_env(void *); +extern SEXP R_igraph_add_version_to_env(void *); +extern SEXP R_igraph_add_vertices(void *, void *); +extern SEXP R_igraph_address(void *); +extern SEXP R_igraph_adhesion(void *, void *); +extern SEXP R_igraph_adjacency(void *, void *, void *); +extern SEXP R_igraph_adjacency_spectral_embedding(void *, void *, void *, void *, void *, void *, void *); +extern SEXP R_igraph_adjacent_triangles(void *, void *); +extern SEXP R_igraph_adjacent_vertices(void *, void *, void *); +extern SEXP R_igraph_adjlist(void *, void *, void *); +extern SEXP R_igraph_all_minimal_st_separators(void *); +extern SEXP R_igraph_all_st_cuts(void *, void *, void *); +extern SEXP R_igraph_all_st_mincuts(void *, void *, void *, void *); +extern SEXP R_igraph_are_adjacent(void *, void *, void *); +extern SEXP R_igraph_arpack(void *, void *, void *, void *, void *); +extern SEXP R_igraph_arpack_unpack_complex(void *, void *, void *); +extern SEXP R_igraph_articulation_points(void *); +extern SEXP R_igraph_assortativity(void *, void *, void *, void *, void *); +extern SEXP R_igraph_assortativity_degree(void *, void *); +extern SEXP R_igraph_assortativity_nominal(void *, void *, void *, void *); +extern SEXP R_igraph_asymmetric_preference_game(void *, void *, void *, void *, void *, void *); +extern SEXP R_igraph_atlas(void *); +extern SEXP R_igraph_authority_score(void *, void *, void *, void *); +extern SEXP R_igraph_automorphism_group(void *, void *); +extern SEXP R_igraph_automorphism_group_bliss(void *, void *, void *); +extern SEXP R_igraph_average_local_efficiency(void *, void *, void *, void *); +extern SEXP R_igraph_average_path_length_dijkstra(void *, void *, void *, void *); +extern SEXP R_igraph_avg_nearest_neighbor_degree(void *, void *, void *, void *, void *); +extern SEXP R_igraph_barabasi_aging_game(void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *); +extern SEXP R_igraph_barabasi_game(void *, void *, void *, void *, void *, void *, void *, void *, void *); +extern SEXP R_igraph_betweenness_cutoff(void *, void *, void *, void *, void *); +extern SEXP R_igraph_betweenness_subset(void *, void *, void *, void *, void *, void *); +extern SEXP R_igraph_bfs(void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *); +extern SEXP R_igraph_bfs_simple(void *, void *, void *); +extern SEXP R_igraph_biadjacency(void *, void *, void *, void *); +extern SEXP R_igraph_bibcoupling(void *, void *); +extern SEXP R_igraph_biconnected_components(void *); +extern SEXP R_igraph_bipartite_game(void *, void *, void *, void *, void *, void *, void *); +extern SEXP R_igraph_bipartite_game_gnm(void *, void *, void *, void *, void *); +extern SEXP R_igraph_bipartite_game_gnp(void *, void *, void *, void *, void *); +extern SEXP R_igraph_bipartite_projection(void *, void *, void *, void *); +extern SEXP R_igraph_bipartite_projection_size(void *, void *); +extern SEXP R_igraph_bridges(void *); +extern SEXP R_igraph_callaway_traits_game(void *, void *, void *, void *, void *, void *); +extern SEXP R_igraph_canonical_permutation(void *, void *); +extern SEXP R_igraph_canonical_permutation_bliss(void *, void *, void *); +extern SEXP R_igraph_centralization(void *, void *, void *); +extern SEXP R_igraph_centralization_betweenness(void *, void *, void *); +extern SEXP R_igraph_centralization_betweenness_tmax(void *, void *, void *); +extern SEXP R_igraph_centralization_closeness(void *, void *, void *); +extern SEXP R_igraph_centralization_closeness_tmax(void *, void *, void *); +extern SEXP R_igraph_centralization_degree(void *, void *, void *, void *); +extern SEXP R_igraph_centralization_degree_tmax(void *, void *, void *, void *); +extern SEXP R_igraph_centralization_eigenvector_centrality(void *, void *, void *, void *, void *); +extern SEXP R_igraph_centralization_eigenvector_centrality_tmax(void *, void *, void *, void *); +extern SEXP R_igraph_circulant(void *, void *, void *); +extern SEXP R_igraph_cited_type_game(void *, void *, void *, void *, void *); +extern SEXP R_igraph_citing_cited_type_game(void *, void *, void *, void *, void *); +extern SEXP R_igraph_clique_number(void *); +extern SEXP R_igraph_clique_size_hist(void *, void *, void *); +extern SEXP R_igraph_cliques(void *, void *, void *); +extern SEXP R_igraph_closeness_cutoff(void *, void *, void *, void *, void *, void *); +extern SEXP R_igraph_cocitation(void *, void *); +extern SEXP R_igraph_cohesion(void *, void *); +extern SEXP R_igraph_cohesive_blocks(void *); +extern SEXP R_igraph_community_edge_betweenness(void *, void *, void *, void *, void *, void *, void *, void *); +extern SEXP R_igraph_community_fastgreedy(void *, void *, void *, void *, void *); +extern SEXP R_igraph_community_fluid_communities(void *, void *); +extern SEXP R_igraph_community_infomap(void *, void *, void *, void *); +extern SEXP R_igraph_community_label_propagation(void *, void *, void *, void *, void *); +extern SEXP R_igraph_community_leading_eigenvector(void *, void *, void *, void *, void *, void *, void *, void *, void *); +extern SEXP R_igraph_community_leiden(void *, void *, void *, void *, void *, void *, void *, void *); +extern SEXP R_igraph_community_multilevel(void *, void *, void *); +extern SEXP R_igraph_community_optimal_modularity(void *, void *); +extern SEXP R_igraph_community_to_membership2(void *, void *, void *); +extern SEXP R_igraph_compare_communities(void *, void *, void *); +extern SEXP R_igraph_complementer(void *, void *); +extern SEXP R_igraph_compose(void *, void *, void *); +extern SEXP R_igraph_connect_neighborhood(void *, void *, void *); +extern SEXP R_igraph_connected_components(void *, void *); +extern SEXP R_igraph_constraint(void *, void *, void *); +extern SEXP R_igraph_contract_vertices(void *, void *, void *); +extern SEXP R_igraph_convex_hull(void *); +extern SEXP R_igraph_copy(void *); +extern SEXP R_igraph_copy_env(void *); +extern SEXP R_igraph_copy_from(void *); +extern SEXP R_igraph_copy_to(void *); +extern SEXP R_igraph_coreness(void *, void *); +extern SEXP R_igraph_correlated_game(void *, void *, void *, void *); +extern SEXP R_igraph_correlated_pair_game(void *, void *, void *, void *, void *); +extern SEXP R_igraph_count_automorphisms(void *, void *); +extern SEXP R_igraph_count_automorphisms_bliss(void *, void *, void *); +extern SEXP R_igraph_count_isomorphisms_vf2(void *, void *, void *, void *, void *, void *); +extern SEXP R_igraph_count_multiple(void *, void *); +extern SEXP R_igraph_count_subisomorphisms_vf2(void *, void *, void *, void *, void *, void *); +extern SEXP R_igraph_create(void *, void *, void *); +extern SEXP R_igraph_create_bipartite(void *, void *, void *); +extern SEXP R_igraph_de_bruijn(void *, void *); +extern SEXP R_igraph_decompose(void *, void *, void *, void *); +extern SEXP R_igraph_degree(void *, void *, void *, void *); +extern SEXP R_igraph_degree_correlation_vector(void *, void *, void *, void *, void *); +extern SEXP R_igraph_degree_sequence_game(void *, void *, void *); +extern SEXP R_igraph_delete_edges(void *, void *); +extern SEXP R_igraph_delete_vertices(void *, void *); +extern SEXP R_igraph_delete_vertices_idx(void); +extern SEXP R_igraph_delete_vertices_map(void *, void *); +extern SEXP R_igraph_density(void *, void *); +extern SEXP R_igraph_deterministic_optimal_imitation(void *, void *, void *, void *, void *, void *); +extern SEXP R_igraph_dfs(void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *); +extern SEXP R_igraph_diameter(void *, void *, void *, void *); +extern SEXP R_igraph_difference(void *, void *); +extern SEXP R_igraph_dim_select(void *); +extern SEXP R_igraph_disjoint_union(void *); +extern SEXP R_igraph_distances(void *, void *, void *, void *); +extern SEXP R_igraph_distances_bellman_ford(void *, void *, void *, void *, void *); +extern SEXP R_igraph_distances_cutoff(void *, void *, void *, void *, void *); +extern SEXP R_igraph_distances_dijkstra(void *, void *, void *, void *, void *); +extern SEXP R_igraph_distances_dijkstra_cutoff(void *, void *, void *, void *, void *, void *); +extern SEXP R_igraph_distances_floyd_warshall(void *, void *, void *, void *, void *, void *); +extern SEXP R_igraph_distances_johnson(void *, void *, void *, void *, void *); +extern SEXP R_igraph_diversity(void *, void *, void *); +extern SEXP R_igraph_dominator_tree(void *, void *, void *); +extern SEXP R_igraph_dot_product_game(void *, void *); +extern SEXP R_igraph_dyad_census(void *); +extern SEXP R_igraph_ecc(void *, void *, void *, void *, void *); +extern SEXP R_igraph_eccentricity(void *, void *, void *); +extern SEXP R_igraph_eccentricity_dijkstra(void *, void *, void *, void *); +extern SEXP R_igraph_ecount(void *); +extern SEXP R_igraph_edge_betweenness_cutoff(void *, void *, void *, void *); +extern SEXP R_igraph_edge_betweenness_subset(void *, void *, void *, void *, void *, void *); +extern SEXP R_igraph_edge_connectivity(void *, void *); +extern SEXP R_igraph_edge_disjoint_paths(void *, void *, void *); +extern SEXP R_igraph_edges(void *, void *); +extern SEXP R_igraph_eigen_adjacency(void *, void *, void *, void *, void *); +extern SEXP R_igraph_eigenvector_centrality(void *, void *, void *, void *, void *); +extern SEXP R_igraph_empty(void *, void *); +extern SEXP R_igraph_erdos_renyi_game(void *, void *, void *, void *, void *); +extern SEXP R_igraph_es_adj(void *, void *, void *, void *); +extern SEXP R_igraph_es_pairs(void *, void *, void *); +extern SEXP R_igraph_es_path(void *, void *, void *); +extern SEXP R_igraph_establishment_game(void *, void *, void *, void *, void *, void *); +extern SEXP R_igraph_eulerian_cycle(void *); +extern SEXP R_igraph_eulerian_path(void *); +extern SEXP R_igraph_even_tarjan_reduction(void *); +extern SEXP R_igraph_extended_chordal_ring(void *, void *, void *); +extern SEXP R_igraph_famous(void *); +extern SEXP R_igraph_farthest_points(void *, void *, void *, void *); +extern SEXP R_igraph_feedback_arc_set(void *, void *, void *); extern SEXP R_igraph_finalizer(void); -extern SEXP R_igraph_forest_fire_game(SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_from_hrg_dendrogram(SEXP); -extern SEXP R_igraph_from_prufer(SEXP); -extern SEXP R_igraph_full(SEXP, SEXP, SEXP); -extern SEXP R_igraph_full_bipartite(SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_full_citation(SEXP, SEXP); -extern SEXP R_igraph_full_multipartite(SEXP, SEXP, SEXP); -extern SEXP R_igraph_fundamental_cycles(SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_generalized_petersen(SEXP, SEXP); -extern SEXP R_igraph_get_adjacency(SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_get_adjedgelist(SEXP, SEXP, SEXP); -extern SEXP R_igraph_get_adjlist(SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_get_all_eids_between(SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_get_all_shortest_paths(SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_get_all_shortest_paths_dijkstra(SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_get_all_simple_paths(SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_get_all_simple_paths_pp(SEXP); -extern SEXP R_igraph_get_attr_mode(SEXP, SEXP); -extern SEXP R_igraph_get_biadjacency(SEXP, SEXP); -extern SEXP R_igraph_get_diameter(SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_get_edge(SEXP, SEXP); -extern SEXP R_igraph_get_edgelist(SEXP, SEXP); -extern SEXP R_igraph_get_eids(SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_get_graph_id(SEXP); -extern SEXP R_igraph_get_isomorphisms_vf2(SEXP, SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_get_k_shortest_paths(SEXP, SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_get_laplacian(SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_get_laplacian_sparse(SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_get_shortest_path(SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_get_shortest_path_bellman_ford(SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_get_shortest_path_dijkstra(SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_get_shortest_paths(SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_get_stochastic(SEXP, SEXP, SEXP); -extern SEXP R_igraph_get_stochastic_sparse(SEXP, SEXP, SEXP); -extern SEXP R_igraph_get_subisomorphisms_vf2(SEXP, SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_get_widest_path(SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_get_widest_paths(SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_girth(SEXP, SEXP); -extern SEXP R_igraph_global_efficiency(SEXP, SEXP, SEXP); -extern SEXP R_igraph_gomory_hu_tree(SEXP, SEXP); -extern SEXP R_igraph_graph_center(SEXP, SEXP); -extern SEXP R_igraph_graph_center_dijkstra(SEXP, SEXP, SEXP); -extern SEXP R_igraph_graph_count(SEXP, SEXP); -extern SEXP R_igraph_graph_power(SEXP, SEXP, SEXP); -extern SEXP R_igraph_graph_version(SEXP); -extern SEXP R_igraph_graphlets(SEXP, SEXP, SEXP); -extern SEXP R_igraph_graphlets_candidate_basis(SEXP, SEXP); -extern SEXP R_igraph_graphlets_project(SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_grg_game(SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_growing_random_game(SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_harmonic_centrality_cutoff(SEXP, SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_has_loop(SEXP); -extern SEXP R_igraph_has_multiple(SEXP); -extern SEXP R_igraph_has_mutual(SEXP, SEXP); -extern SEXP R_igraph_hrg_consensus(SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_hrg_create(SEXP, SEXP); -extern SEXP R_igraph_hrg_fit(SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_hrg_game(SEXP); -extern SEXP R_igraph_hrg_predict(SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_hrg_resize(SEXP, SEXP); -extern SEXP R_igraph_hrg_sample(SEXP); -extern SEXP R_igraph_hrg_sample_many(SEXP, SEXP); -extern SEXP R_igraph_hrg_size(SEXP); -extern SEXP R_igraph_hsbm_game(SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_hsbm_list_game(SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_hub_and_authority_scores(SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_hub_score(SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_i_levc_arp(SEXP, SEXP, SEXP); -extern SEXP R_igraph_identical_graphs(SEXP, SEXP, SEXP); -extern SEXP R_igraph_incident(SEXP, SEXP, SEXP); -extern SEXP R_igraph_incident_edges(SEXP, SEXP, SEXP); -extern SEXP R_igraph_independence_number(SEXP); -extern SEXP R_igraph_independent_vertex_sets(SEXP, SEXP, SEXP); -extern SEXP R_igraph_induced_subgraph(SEXP, SEXP, SEXP); -extern SEXP R_igraph_induced_subgraph_map(SEXP, SEXP, SEXP); -extern SEXP R_igraph_intersection(SEXP, SEXP); -extern SEXP R_igraph_is_acyclic(SEXP); -extern SEXP R_igraph_is_biconnected(SEXP); -extern SEXP R_igraph_is_bipartite(SEXP); -extern SEXP R_igraph_is_chordal(SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_is_complete(SEXP); -extern SEXP R_igraph_is_connected(SEXP, SEXP); -extern SEXP R_igraph_is_dag(SEXP); -extern SEXP R_igraph_is_directed(SEXP); -extern SEXP R_igraph_is_eulerian(SEXP); -extern SEXP R_igraph_is_forest(SEXP, SEXP); -extern SEXP R_igraph_is_graphical(SEXP, SEXP, SEXP); -extern SEXP R_igraph_is_loop(SEXP, SEXP); -extern SEXP R_igraph_is_matching(SEXP, SEXP, SEXP); -extern SEXP R_igraph_is_maximal_matching(SEXP, SEXP, SEXP); -extern SEXP R_igraph_is_minimal_separator(SEXP, SEXP); -extern SEXP R_igraph_is_multiple(SEXP, SEXP); -extern SEXP R_igraph_is_mutual(SEXP, SEXP, SEXP); -extern SEXP R_igraph_is_perfect(SEXP); -extern SEXP R_igraph_is_separator(SEXP, SEXP); -extern SEXP R_igraph_is_simple(SEXP); -extern SEXP R_igraph_is_tree(SEXP, SEXP); -extern SEXP R_igraph_isoclass(SEXP); -extern SEXP R_igraph_isoclass_create(SEXP, SEXP, SEXP); -extern SEXP R_igraph_isoclass_subgraph(SEXP, SEXP); -extern SEXP R_igraph_isomorphic(SEXP, SEXP); -extern SEXP R_igraph_isomorphic_bliss(SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_isomorphic_vf2(SEXP, SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_join(SEXP, SEXP); -extern SEXP R_igraph_joint_degree_distribution(SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_joint_degree_matrix(SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_joint_type_distribution(SEXP, SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_k_regular_game(SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_kary_tree(SEXP, SEXP, SEXP); -extern SEXP R_igraph_kautz(SEXP, SEXP); -extern SEXP R_igraph_laplacian(SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_laplacian_spectral_embedding(SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_largest_cliques(SEXP); -extern SEXP R_igraph_largest_independent_vertex_sets(SEXP); -extern SEXP R_igraph_largest_weighted_cliques(SEXP, SEXP); -extern SEXP R_igraph_lastcit_game(SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_lattice(SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_layout_bipartite(SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_layout_circle(SEXP, SEXP); -extern SEXP R_igraph_layout_davidson_harel(SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_layout_drl(SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_layout_drl_3d(SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_layout_fruchterman_reingold(SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_layout_fruchterman_reingold_3d(SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_layout_gem(SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_layout_graphopt(SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_layout_grid(SEXP, SEXP); -extern SEXP R_igraph_layout_grid_3d(SEXP, SEXP, SEXP); -extern SEXP R_igraph_layout_kamada_kawai(SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_layout_kamada_kawai_3d(SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_layout_lgl(SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_layout_mds(SEXP, SEXP, SEXP); -extern SEXP R_igraph_layout_merge_dla(SEXP, SEXP); -extern SEXP R_igraph_layout_random(SEXP); -extern SEXP R_igraph_layout_random_3d(SEXP); -extern SEXP R_igraph_layout_reingold_tilford(SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_layout_sphere(SEXP); -extern SEXP R_igraph_layout_star(SEXP, SEXP, SEXP); -extern SEXP R_igraph_layout_sugiyama(SEXP, SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_layout_umap(SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_layout_umap_3d(SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_layout_umap_compute_weights(SEXP, SEXP, SEXP); -extern SEXP R_igraph_lcf_vector(SEXP, SEXP, SEXP); -extern SEXP R_igraph_linegraph(SEXP); -extern SEXP R_igraph_list_triangles(SEXP); -extern SEXP R_igraph_local_efficiency(SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_local_scan_0(SEXP, SEXP, SEXP); -extern SEXP R_igraph_local_scan_0_them(SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_local_scan_1_ecount(SEXP, SEXP, SEXP); -extern SEXP R_igraph_local_scan_1_ecount_them(SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_local_scan_k_ecount(SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_local_scan_k_ecount_them(SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_local_scan_neighborhood_ecount(SEXP, SEXP, SEXP); -extern SEXP R_igraph_local_scan_subset_ecount(SEXP, SEXP, SEXP); -extern SEXP R_igraph_make_weak_ref(SEXP, SEXP, SEXP); -extern SEXP R_igraph_maxflow(SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_maximal_cliques(SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_maximal_cliques_count(SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_maximal_cliques_file(SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_maximal_cliques_hist(SEXP, SEXP, SEXP); -extern SEXP R_igraph_maximal_independent_vertex_sets(SEXP); -extern SEXP R_igraph_maximum_bipartite_matching(SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_maximum_cardinality_search(SEXP); -extern SEXP R_igraph_mincut(SEXP, SEXP); -extern SEXP R_igraph_mincut_value(SEXP, SEXP); -extern SEXP R_igraph_minimum_cycle_basis(SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_minimum_size_separators(SEXP); -extern SEXP R_igraph_minimum_spanning_tree_prim(SEXP, SEXP); -extern SEXP R_igraph_minimum_spanning_tree_unweighted(SEXP); -extern SEXP R_igraph_modularity(SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_modularity_matrix(SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_moran_process(SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_motifs_randesu(SEXP, SEXP, SEXP); -extern SEXP R_igraph_motifs_randesu_estimate(SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_motifs_randesu_no(SEXP, SEXP, SEXP); -extern SEXP R_igraph_mybracket2(SEXP, SEXP, SEXP); -extern SEXP R_igraph_mybracket2_copy(SEXP, SEXP, SEXP); -extern SEXP R_igraph_mybracket2_names(SEXP, SEXP, SEXP); -extern SEXP R_igraph_mybracket2_set(SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_mybracket3_set(SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_neighborhood(SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_neighborhood_graphs(SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_neighborhood_size(SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_neighbors(SEXP, SEXP, SEXP); -extern SEXP R_igraph_no_components(SEXP, SEXP); -extern SEXP R_igraph_path_length_hist(SEXP, SEXP); -extern SEXP R_igraph_permute_vertices(SEXP, SEXP); -extern SEXP R_igraph_personalized_pagerank(SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_personalized_pagerank_vs(SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_power_law_fit(SEXP, SEXP, SEXP); -extern SEXP R_igraph_preference_game(SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_pseudo_diameter(SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_pseudo_diameter_dijkstra(SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_radius(SEXP, SEXP); -extern SEXP R_igraph_radius_dijkstra(SEXP, SEXP, SEXP); -extern SEXP R_igraph_random_edge_walk(SEXP, SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_random_sample(SEXP, SEXP, SEXP); -extern SEXP R_igraph_random_spanning_tree(SEXP, SEXP); -extern SEXP R_igraph_random_walk(SEXP, SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_read_graph_dimacs(SEXP, SEXP); -extern SEXP R_igraph_read_graph_dl(SEXP, SEXP); -extern SEXP R_igraph_read_graph_edgelist(SEXP, SEXP, SEXP); -extern SEXP R_igraph_read_graph_gml(SEXP); -extern SEXP R_igraph_read_graph_graphdb(SEXP, SEXP); -extern SEXP R_igraph_read_graph_graphml(SEXP, SEXP); -extern SEXP R_igraph_read_graph_lgl(SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_read_graph_ncol(SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_read_graph_pajek(SEXP); -extern SEXP R_igraph_realize_bipartite_degree_sequence(SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_realize_degree_sequence(SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_recent_degree_aging_game(SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_reciprocity(SEXP, SEXP, SEXP); -extern SEXP R_igraph_regular_tree(SEXP, SEXP, SEXP); -extern SEXP R_igraph_residual_graph(SEXP, SEXP, SEXP); -extern SEXP R_igraph_reverse_edges(SEXP, SEXP); -extern SEXP R_igraph_reverse_residual_graph(SEXP, SEXP, SEXP); -extern SEXP R_igraph_rewire(SEXP, SEXP, SEXP); -extern SEXP R_igraph_rewire_directed_edges(SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_rewire_edges(SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_ring(SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_roots_for_tree_layout(SEXP, SEXP, SEXP); -extern SEXP R_igraph_roulette_wheel_imitation(SEXP, SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_running_mean(SEXP, SEXP); -extern SEXP R_igraph_sample_dirichlet(SEXP, SEXP); -extern SEXP R_igraph_sample_sphere_surface(SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_sample_sphere_volume(SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_sbm_game(SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_set_verbose(SEXP); -extern SEXP R_igraph_shortest_paths(SEXP, SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_similarity_dice(SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_similarity_dice_es(SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_similarity_dice_pairs(SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_similarity_inverse_log_weighted(SEXP, SEXP, SEXP); -extern SEXP R_igraph_similarity_jaccard(SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_similarity_jaccard_es(SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_similarity_jaccard_pairs(SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_simple_interconnected_islands_game(SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_simplify(SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_simplify_and_colorize(SEXP); -extern SEXP R_igraph_sir(SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_solve_lsap(SEXP, SEXP); -extern SEXP R_igraph_spanner(SEXP, SEXP, SEXP); -extern SEXP R_igraph_spinglass_community(SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_spinglass_my_community(SEXP, SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_split_join_distance(SEXP, SEXP); -extern SEXP R_igraph_square_lattice(SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_st_edge_connectivity(SEXP, SEXP, SEXP); -extern SEXP R_igraph_st_mincut(SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_st_mincut_value(SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_st_vertex_connectivity(SEXP, SEXP, SEXP); -extern SEXP R_igraph_star(SEXP, SEXP, SEXP); -extern SEXP R_igraph_static_fitness_game(SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_static_power_law_game(SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_stochastic_imitation(SEXP, SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_strength(SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_subcomponent(SEXP, SEXP, SEXP); -extern SEXP R_igraph_subgraph_from_edges(SEXP, SEXP, SEXP); -extern SEXP R_igraph_subisomorphic(SEXP, SEXP); -extern SEXP R_igraph_subisomorphic_lad(SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_subisomorphic_vf2(SEXP, SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_symmetric_tree(SEXP, SEXP); -extern SEXP R_igraph_to_directed(SEXP, SEXP); -extern SEXP R_igraph_to_prufer(SEXP); -extern SEXP R_igraph_to_undirected(SEXP, SEXP, SEXP); -extern SEXP R_igraph_topological_sorting(SEXP, SEXP); -extern SEXP R_igraph_transitive_closure_dag(SEXP); -extern SEXP R_igraph_transitivity_avglocal_undirected(SEXP, SEXP); -extern SEXP R_igraph_transitivity_barrat(SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_transitivity_local_undirected(SEXP, SEXP, SEXP); -extern SEXP R_igraph_transitivity_local_undirected_all(SEXP, SEXP); -extern SEXP R_igraph_transitivity_undirected(SEXP, SEXP); -extern SEXP R_igraph_tree_from_parent_vector(SEXP, SEXP); -extern SEXP R_igraph_tree_game(SEXP, SEXP, SEXP); -extern SEXP R_igraph_triad_census(SEXP); -extern SEXP R_igraph_triangular_lattice(SEXP, SEXP, SEXP); -extern SEXP R_igraph_trussness(SEXP); -extern SEXP R_igraph_turan(SEXP, SEXP); -extern SEXP R_igraph_unfold_tree(SEXP, SEXP, SEXP); -extern SEXP R_igraph_union(SEXP, SEXP); -extern SEXP R_igraph_vcount(SEXP); -extern SEXP R_igraph_vertex_coloring_greedy(SEXP, SEXP); -extern SEXP R_igraph_vertex_connectivity(SEXP, SEXP); -extern SEXP R_igraph_vertex_disjoint_paths(SEXP, SEXP, SEXP); -extern SEXP R_igraph_vertex_path_from_edge_path(SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_voronoi(SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_vs_adj(SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_vs_nei(SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_walktrap_community(SEXP, SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_watts_strogatz_game(SEXP, SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_weak_ref_key(SEXP); -extern SEXP R_igraph_weak_ref_run_finalizer(SEXP); -extern SEXP R_igraph_weak_ref_value(SEXP); -extern SEXP R_igraph_weighted_adjacency(SEXP, SEXP, SEXP); -extern SEXP R_igraph_weighted_clique_number(SEXP, SEXP); -extern SEXP R_igraph_weighted_cliques(SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_wheel(SEXP, SEXP, SEXP); -extern SEXP R_igraph_widest_path_widths_dijkstra(SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_widest_path_widths_floyd_warshall(SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_write_graph_dimacs(SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_write_graph_dot(SEXP, SEXP); -extern SEXP R_igraph_write_graph_edgelist(SEXP, SEXP); -extern SEXP R_igraph_write_graph_gml(SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_write_graph_graphml(SEXP, SEXP, SEXP); -extern SEXP R_igraph_write_graph_leda(SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_write_graph_lgl(SEXP, SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_write_graph_ncol(SEXP, SEXP, SEXP, SEXP); -extern SEXP R_igraph_write_graph_pajek(SEXP, SEXP); -extern SEXP UUID_gen(SEXP); -extern SEXP make_lazy(SEXP, SEXP, SEXP); -extern SEXP make_lazy_dots(SEXP, SEXP); -extern SEXP promise_env_(SEXP); -extern SEXP promise_expr_(SEXP); +extern SEXP R_igraph_forest_fire_game(void *, void *, void *, void *, void *); +extern SEXP R_igraph_from_hrg_dendrogram(void *); +extern SEXP R_igraph_from_prufer(void *); +extern SEXP R_igraph_full(void *, void *, void *); +extern SEXP R_igraph_full_bipartite(void *, void *, void *, void *); +extern SEXP R_igraph_full_citation(void *, void *); +extern SEXP R_igraph_full_multipartite(void *, void *, void *); +extern SEXP R_igraph_fundamental_cycles(void *, void *, void *, void *); +extern SEXP R_igraph_generalized_petersen(void *, void *); +extern SEXP R_igraph_get_adjacency(void *, void *, void *, void *); +extern SEXP R_igraph_get_adjedgelist(void *, void *, void *); +extern SEXP R_igraph_get_adjlist(void *, void *, void *, void *); +extern SEXP R_igraph_get_all_eids_between(void *, void *, void *, void *); +extern SEXP R_igraph_get_all_shortest_paths(void *, void *, void *, void *); +extern SEXP R_igraph_get_all_shortest_paths_dijkstra(void *, void *, void *, void *, void *); +extern SEXP R_igraph_get_all_simple_paths(void *, void *, void *, void *, void *); +extern SEXP R_igraph_get_all_simple_paths_pp(void *); +extern SEXP R_igraph_get_attr_mode(void *, void *); +extern SEXP R_igraph_get_biadjacency(void *, void *); +extern SEXP R_igraph_get_diameter(void *, void *, void *, void *); +extern SEXP R_igraph_get_edge(void *, void *); +extern SEXP R_igraph_get_edgelist(void *, void *); +extern SEXP R_igraph_get_eids(void *, void *, void *, void *); +extern SEXP R_igraph_get_graph_id(void *); +extern SEXP R_igraph_get_isomorphisms_vf2(void *, void *, void *, void *, void *, void *); +extern SEXP R_igraph_get_k_shortest_paths(void *, void *, void *, void *, void *, void *); +extern SEXP R_igraph_get_laplacian(void *, void *, void *, void *); +extern SEXP R_igraph_get_laplacian_sparse(void *, void *, void *, void *); +extern SEXP R_igraph_get_shortest_path(void *, void *, void *, void *); +extern SEXP R_igraph_get_shortest_path_bellman_ford(void *, void *, void *, void *, void *); +extern SEXP R_igraph_get_shortest_path_dijkstra(void *, void *, void *, void *, void *); +extern SEXP R_igraph_get_shortest_paths(void *, void *, void *, void *, void *, void *, void *, void *, void *, void *); +extern SEXP R_igraph_get_stochastic(void *, void *, void *); +extern SEXP R_igraph_get_stochastic_sparse(void *, void *, void *); +extern SEXP R_igraph_get_subisomorphisms_vf2(void *, void *, void *, void *, void *, void *); +extern SEXP R_igraph_get_widest_path(void *, void *, void *, void *, void *); +extern SEXP R_igraph_get_widest_paths(void *, void *, void *, void *, void *); +extern SEXP R_igraph_girth(void *, void *); +extern SEXP R_igraph_global_efficiency(void *, void *, void *); +extern SEXP R_igraph_gomory_hu_tree(void *, void *); +extern SEXP R_igraph_graph_center(void *, void *); +extern SEXP R_igraph_graph_center_dijkstra(void *, void *, void *); +extern SEXP R_igraph_graph_count(void *, void *); +extern SEXP R_igraph_graph_power(void *, void *, void *); +extern SEXP R_igraph_graph_version(void *); +extern SEXP R_igraph_graphlets(void *, void *, void *); +extern SEXP R_igraph_graphlets_candidate_basis(void *, void *); +extern SEXP R_igraph_graphlets_project(void *, void *, void *, void *, void *); +extern SEXP R_igraph_grg_game(void *, void *, void *, void *); +extern SEXP R_igraph_growing_random_game(void *, void *, void *, void *); +extern SEXP R_igraph_harmonic_centrality_cutoff(void *, void *, void *, void *, void *, void *); +extern SEXP R_igraph_has_loop(void *); +extern SEXP R_igraph_has_multiple(void *); +extern SEXP R_igraph_has_mutual(void *, void *); +extern SEXP R_igraph_hrg_consensus(void *, void *, void *, void *); +extern SEXP R_igraph_hrg_create(void *, void *); +extern SEXP R_igraph_hrg_fit(void *, void *, void *, void *); +extern SEXP R_igraph_hrg_game(void *); +extern SEXP R_igraph_hrg_predict(void *, void *, void *, void *, void *); +extern SEXP R_igraph_hrg_resize(void *, void *); +extern SEXP R_igraph_hrg_sample(void *); +extern SEXP R_igraph_hrg_sample_many(void *, void *); +extern SEXP R_igraph_hrg_size(void *); +extern SEXP R_igraph_hsbm_game(void *, void *, void *, void *, void *); +extern SEXP R_igraph_hsbm_list_game(void *, void *, void *, void *, void *); +extern SEXP R_igraph_hub_and_authority_scores(void *, void *, void *, void *); +extern SEXP R_igraph_hub_score(void *, void *, void *, void *); +extern SEXP R_igraph_i_levc_arp(void *, void *, void *); +extern SEXP R_igraph_identical_graphs(void *, void *, void *); +extern SEXP R_igraph_incident(void *, void *, void *); +extern SEXP R_igraph_incident_edges(void *, void *, void *); +extern SEXP R_igraph_independence_number(void *); +extern SEXP R_igraph_independent_vertex_sets(void *, void *, void *); +extern SEXP R_igraph_induced_subgraph(void *, void *, void *); +extern SEXP R_igraph_induced_subgraph_map(void *, void *, void *); +extern SEXP R_igraph_intersection(void *, void *); +extern SEXP R_igraph_is_acyclic(void *); +extern SEXP R_igraph_is_biconnected(void *); +extern SEXP R_igraph_is_bipartite(void *); +extern SEXP R_igraph_is_chordal(void *, void *, void *, void *, void *); +extern SEXP R_igraph_is_complete(void *); +extern SEXP R_igraph_is_connected(void *, void *); +extern SEXP R_igraph_is_dag(void *); +extern SEXP R_igraph_is_directed(void *); +extern SEXP R_igraph_is_eulerian(void *); +extern SEXP R_igraph_is_forest(void *, void *); +extern SEXP R_igraph_is_graphical(void *, void *, void *); +extern SEXP R_igraph_is_loop(void *, void *); +extern SEXP R_igraph_is_matching(void *, void *, void *); +extern SEXP R_igraph_is_maximal_matching(void *, void *, void *); +extern SEXP R_igraph_is_minimal_separator(void *, void *); +extern SEXP R_igraph_is_multiple(void *, void *); +extern SEXP R_igraph_is_mutual(void *, void *, void *); +extern SEXP R_igraph_is_perfect(void *); +extern SEXP R_igraph_is_separator(void *, void *); +extern SEXP R_igraph_is_simple(void *); +extern SEXP R_igraph_is_tree(void *, void *); +extern SEXP R_igraph_isoclass(void *); +extern SEXP R_igraph_isoclass_create(void *, void *, void *); +extern SEXP R_igraph_isoclass_subgraph(void *, void *); +extern SEXP R_igraph_isomorphic(void *, void *); +extern SEXP R_igraph_isomorphic_bliss(void *, void *, void *, void *, void *); +extern SEXP R_igraph_isomorphic_vf2(void *, void *, void *, void *, void *, void *); +extern SEXP R_igraph_join(void *, void *); +extern SEXP R_igraph_joint_degree_distribution(void *, void *, void *, void *, void *, void *, void *, void *); +extern SEXP R_igraph_joint_degree_matrix(void *, void *, void *, void *); +extern SEXP R_igraph_joint_type_distribution(void *, void *, void *, void *, void *, void *); +extern SEXP R_igraph_k_regular_game(void *, void *, void *, void *); +extern SEXP R_igraph_kary_tree(void *, void *, void *); +extern SEXP R_igraph_kautz(void *, void *); +extern SEXP R_igraph_laplacian(void *, void *, void *, void *); +extern SEXP R_igraph_laplacian_spectral_embedding(void *, void *, void *, void *, void *, void *, void *); +extern SEXP R_igraph_largest_cliques(void *); +extern SEXP R_igraph_largest_independent_vertex_sets(void *); +extern SEXP R_igraph_largest_weighted_cliques(void *, void *); +extern SEXP R_igraph_lastcit_game(void *, void *, void *, void *, void *); +extern SEXP R_igraph_lattice(void *, void *, void *, void *, void *); +extern SEXP R_igraph_layout_bipartite(void *, void *, void *, void *, void *); +extern SEXP R_igraph_layout_circle(void *, void *); +extern SEXP R_igraph_layout_davidson_harel(void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *); +extern SEXP R_igraph_layout_drl(void *, void *, void *, void *, void *); +extern SEXP R_igraph_layout_drl_3d(void *, void *, void *, void *, void *); +extern SEXP R_igraph_layout_fruchterman_reingold(void *, void *, void *, void *, void *, void *, void *, void *, void *, void *); +extern SEXP R_igraph_layout_fruchterman_reingold_3d(void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *); +extern SEXP R_igraph_layout_gem(void *, void *, void *, void *, void *, void *, void *); +extern SEXP R_igraph_layout_graphopt(void *, void *, void *, void *, void *, void *, void *, void *); +extern SEXP R_igraph_layout_grid(void *, void *); +extern SEXP R_igraph_layout_grid_3d(void *, void *, void *); +extern SEXP R_igraph_layout_kamada_kawai(void *, void *, void *, void *, void *, void *, void *, void *, void *, void *); +extern SEXP R_igraph_layout_kamada_kawai_3d(void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *); +extern SEXP R_igraph_layout_lgl(void *, void *, void *, void *, void *, void *, void *, void *); +extern SEXP R_igraph_layout_mds(void *, void *, void *); +extern SEXP R_igraph_layout_merge_dla(void *, void *); +extern SEXP R_igraph_layout_random(void *); +extern SEXP R_igraph_layout_random_3d(void *); +extern SEXP R_igraph_layout_reingold_tilford(void *, void *, void *, void *, void *); +extern SEXP R_igraph_layout_sphere(void *); +extern SEXP R_igraph_layout_star(void *, void *, void *); +extern SEXP R_igraph_layout_sugiyama(void *, void *, void *, void *, void *, void *); +extern SEXP R_igraph_layout_umap(void *, void *, void *, void *, void *, void *, void *); +extern SEXP R_igraph_layout_umap_3d(void *, void *, void *, void *, void *, void *, void *); +extern SEXP R_igraph_layout_umap_compute_weights(void *, void *, void *); +extern SEXP R_igraph_lcf_vector(void *, void *, void *); +extern SEXP R_igraph_linegraph(void *); +extern SEXP R_igraph_list_triangles(void *); +extern SEXP R_igraph_local_efficiency(void *, void *, void *, void *, void *); +extern SEXP R_igraph_local_scan_0(void *, void *, void *); +extern SEXP R_igraph_local_scan_0_them(void *, void *, void *, void *); +extern SEXP R_igraph_local_scan_1_ecount(void *, void *, void *); +extern SEXP R_igraph_local_scan_1_ecount_them(void *, void *, void *, void *); +extern SEXP R_igraph_local_scan_k_ecount(void *, void *, void *, void *); +extern SEXP R_igraph_local_scan_k_ecount_them(void *, void *, void *, void *, void *); +extern SEXP R_igraph_local_scan_neighborhood_ecount(void *, void *, void *); +extern SEXP R_igraph_local_scan_subset_ecount(void *, void *, void *); +extern SEXP R_igraph_make_weak_ref(void *, void *, void *); +extern SEXP R_igraph_maxflow(void *, void *, void *, void *); +extern SEXP R_igraph_maximal_cliques(void *, void *, void *, void *); +extern SEXP R_igraph_maximal_cliques_count(void *, void *, void *, void *); +extern SEXP R_igraph_maximal_cliques_file(void *, void *, void *, void *, void *); +extern SEXP R_igraph_maximal_cliques_hist(void *, void *, void *); +extern SEXP R_igraph_maximal_independent_vertex_sets(void *); +extern SEXP R_igraph_maximum_bipartite_matching(void *, void *, void *, void *); +extern SEXP R_igraph_maximum_cardinality_search(void *); +extern SEXP R_igraph_mincut(void *, void *); +extern SEXP R_igraph_mincut_value(void *, void *); +extern SEXP R_igraph_minimum_cycle_basis(void *, void *, void *, void *, void *); +extern SEXP R_igraph_minimum_size_separators(void *); +extern SEXP R_igraph_minimum_spanning_tree_prim(void *, void *); +extern SEXP R_igraph_minimum_spanning_tree_unweighted(void *); +extern SEXP R_igraph_modularity(void *, void *, void *, void *, void *); +extern SEXP R_igraph_modularity_matrix(void *, void *, void *, void *); +extern SEXP R_igraph_moran_process(void *, void *, void *, void *, void *); +extern SEXP R_igraph_motifs_randesu(void *, void *, void *); +extern SEXP R_igraph_motifs_randesu_estimate(void *, void *, void *, void *, void *); +extern SEXP R_igraph_motifs_randesu_no(void *, void *, void *); +extern SEXP R_igraph_mybracket2(void *, void *, void *); +extern SEXP R_igraph_mybracket2_copy(void *, void *, void *); +extern SEXP R_igraph_mybracket2_names(void *, void *, void *); +extern SEXP R_igraph_mybracket2_set(void *, void *, void *, void *); +extern SEXP R_igraph_mybracket3_set(void *, void *, void *, void *, void *); +extern SEXP R_igraph_neighborhood(void *, void *, void *, void *, void *); +extern SEXP R_igraph_neighborhood_graphs(void *, void *, void *, void *, void *); +extern SEXP R_igraph_neighborhood_size(void *, void *, void *, void *, void *); +extern SEXP R_igraph_neighbors(void *, void *, void *); +extern SEXP R_igraph_no_components(void *, void *); +extern SEXP R_igraph_path_length_hist(void *, void *); +extern SEXP R_igraph_permute_vertices(void *, void *); +extern SEXP R_igraph_personalized_pagerank(void *, void *, void *, void *, void *, void *, void *, void *); +extern SEXP R_igraph_personalized_pagerank_vs(void *, void *, void *, void *, void *, void *, void *, void *); +extern SEXP R_igraph_power_law_fit(void *, void *, void *); +extern SEXP R_igraph_preference_game(void *, void *, void *, void *, void *, void *, void *); +extern SEXP R_igraph_pseudo_diameter(void *, void *, void *, void *); +extern SEXP R_igraph_pseudo_diameter_dijkstra(void *, void *, void *, void *, void *); +extern SEXP R_igraph_radius(void *, void *); +extern SEXP R_igraph_radius_dijkstra(void *, void *, void *); +extern SEXP R_igraph_random_edge_walk(void *, void *, void *, void *, void *, void *); +extern SEXP R_igraph_random_sample(void *, void *, void *); +extern SEXP R_igraph_random_spanning_tree(void *, void *); +extern SEXP R_igraph_random_walk(void *, void *, void *, void *, void *, void *); +extern SEXP R_igraph_read_graph_dimacs(void *, void *); +extern SEXP R_igraph_read_graph_dl(void *, void *); +extern SEXP R_igraph_read_graph_edgelist(void *, void *, void *); +extern SEXP R_igraph_read_graph_gml(void *); +extern SEXP R_igraph_read_graph_graphdb(void *, void *); +extern SEXP R_igraph_read_graph_graphml(void *, void *); +extern SEXP R_igraph_read_graph_lgl(void *, void *, void *, void *); +extern SEXP R_igraph_read_graph_ncol(void *, void *, void *, void *, void *); +extern SEXP R_igraph_read_graph_pajek(void *); +extern SEXP R_igraph_realize_bipartite_degree_sequence(void *, void *, void *, void *); +extern SEXP R_igraph_realize_degree_sequence(void *, void *, void *, void *); +extern SEXP R_igraph_recent_degree_aging_game(void *, void *, void *, void *, void *, void *, void *, void *, void *, void *); +extern SEXP R_igraph_reciprocity(void *, void *, void *); +extern SEXP R_igraph_regular_tree(void *, void *, void *); +extern SEXP R_igraph_residual_graph(void *, void *, void *); +extern SEXP R_igraph_reverse_edges(void *, void *); +extern SEXP R_igraph_reverse_residual_graph(void *, void *, void *); +extern SEXP R_igraph_rewire(void *, void *, void *); +extern SEXP R_igraph_rewire_directed_edges(void *, void *, void *, void *); +extern SEXP R_igraph_rewire_edges(void *, void *, void *, void *); +extern SEXP R_igraph_ring(void *, void *, void *, void *); +extern SEXP R_igraph_roots_for_tree_layout(void *, void *, void *); +extern SEXP R_igraph_roulette_wheel_imitation(void *, void *, void *, void *, void *, void *); +extern SEXP R_igraph_running_mean(void *, void *); +extern SEXP R_igraph_sample_dirichlet(void *, void *); +extern SEXP R_igraph_sample_sphere_surface(void *, void *, void *, void *); +extern SEXP R_igraph_sample_sphere_volume(void *, void *, void *, void *); +extern SEXP R_igraph_sbm_game(void *, void *, void *, void *, void *); +extern SEXP R_igraph_set_verbose(void *); +extern SEXP R_igraph_shortest_paths(void *, void *, void *, void *, void *, void *); +extern SEXP R_igraph_similarity_dice(void *, void *, void *, void *, void *); +extern SEXP R_igraph_similarity_dice_es(void *, void *, void *, void *); +extern SEXP R_igraph_similarity_dice_pairs(void *, void *, void *, void *); +extern SEXP R_igraph_similarity_inverse_log_weighted(void *, void *, void *); +extern SEXP R_igraph_similarity_jaccard(void *, void *, void *, void *, void *); +extern SEXP R_igraph_similarity_jaccard_es(void *, void *, void *, void *); +extern SEXP R_igraph_similarity_jaccard_pairs(void *, void *, void *, void *); +extern SEXP R_igraph_simple_interconnected_islands_game(void *, void *, void *, void *); +extern SEXP R_igraph_simplify(void *, void *, void *, void *); +extern SEXP R_igraph_simplify_and_colorize(void *); +extern SEXP R_igraph_sir(void *, void *, void *, void *); +extern SEXP R_igraph_solve_lsap(void *, void *); +extern SEXP R_igraph_spanner(void *, void *, void *); +extern SEXP R_igraph_spinglass_community(void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *); +extern SEXP R_igraph_spinglass_my_community(void *, void *, void *, void *, void *, void *); +extern SEXP R_igraph_split_join_distance(void *, void *); +extern SEXP R_igraph_square_lattice(void *, void *, void *, void *, void *); +extern SEXP R_igraph_st_edge_connectivity(void *, void *, void *); +extern SEXP R_igraph_st_mincut(void *, void *, void *, void *); +extern SEXP R_igraph_st_mincut_value(void *, void *, void *, void *); +extern SEXP R_igraph_st_vertex_connectivity(void *, void *, void *); +extern SEXP R_igraph_star(void *, void *, void *); +extern SEXP R_igraph_static_fitness_game(void *, void *, void *, void *, void *); +extern SEXP R_igraph_static_power_law_game(void *, void *, void *, void *, void *, void *, void *); +extern SEXP R_igraph_stochastic_imitation(void *, void *, void *, void *, void *, void *); +extern SEXP R_igraph_strength(void *, void *, void *, void *, void *); +extern SEXP R_igraph_subcomponent(void *, void *, void *); +extern SEXP R_igraph_subgraph_from_edges(void *, void *, void *); +extern SEXP R_igraph_subisomorphic(void *, void *); +extern SEXP R_igraph_subisomorphic_lad(void *, void *, void *, void *, void *, void *, void *); +extern SEXP R_igraph_subisomorphic_vf2(void *, void *, void *, void *, void *, void *); +extern SEXP R_igraph_symmetric_tree(void *, void *); +extern SEXP R_igraph_to_directed(void *, void *); +extern SEXP R_igraph_to_prufer(void *); +extern SEXP R_igraph_to_undirected(void *, void *, void *); +extern SEXP R_igraph_topological_sorting(void *, void *); +extern SEXP R_igraph_transitive_closure_dag(void *); +extern SEXP R_igraph_transitivity_avglocal_undirected(void *, void *); +extern SEXP R_igraph_transitivity_barrat(void *, void *, void *, void *); +extern SEXP R_igraph_transitivity_local_undirected(void *, void *, void *); +extern SEXP R_igraph_transitivity_local_undirected_all(void *, void *); +extern SEXP R_igraph_transitivity_undirected(void *, void *); +extern SEXP R_igraph_tree_from_parent_vector(void *, void *); +extern SEXP R_igraph_tree_game(void *, void *, void *); +extern SEXP R_igraph_triad_census(void *); +extern SEXP R_igraph_triangular_lattice(void *, void *, void *); +extern SEXP R_igraph_trussness(void *); +extern SEXP R_igraph_turan(void *, void *); +extern SEXP R_igraph_unfold_tree(void *, void *, void *); +extern SEXP R_igraph_union(void *, void *); +extern SEXP R_igraph_vcount(void *); +extern SEXP R_igraph_vertex_coloring_greedy(void *, void *); +extern SEXP R_igraph_vertex_connectivity(void *, void *); +extern SEXP R_igraph_vertex_disjoint_paths(void *, void *, void *); +extern SEXP R_igraph_vertex_path_from_edge_path(void *, void *, void *, void *); +extern SEXP R_igraph_voronoi(void *, void *, void *, void *, void *); +extern SEXP R_igraph_vs_adj(void *, void *, void *, void *); +extern SEXP R_igraph_vs_nei(void *, void *, void *, void *); +extern SEXP R_igraph_walktrap_community(void *, void *, void *, void *, void *, void *); +extern SEXP R_igraph_watts_strogatz_game(void *, void *, void *, void *, void *, void *); +extern SEXP R_igraph_weak_ref_key(void *); +extern SEXP R_igraph_weak_ref_run_finalizer(void *); +extern SEXP R_igraph_weak_ref_value(void *); +extern SEXP R_igraph_weighted_adjacency(void *, void *, void *); +extern SEXP R_igraph_weighted_clique_number(void *, void *); +extern SEXP R_igraph_weighted_cliques(void *, void *, void *, void *, void *); +extern SEXP R_igraph_wheel(void *, void *, void *); +extern SEXP R_igraph_widest_path_widths_dijkstra(void *, void *, void *, void *, void *); +extern SEXP R_igraph_widest_path_widths_floyd_warshall(void *, void *, void *, void *, void *); +extern SEXP R_igraph_write_graph_dimacs(void *, void *, void *, void *, void *); +extern SEXP R_igraph_write_graph_dot(void *, void *); +extern SEXP R_igraph_write_graph_edgelist(void *, void *); +extern SEXP R_igraph_write_graph_gml(void *, void *, void *, void *); +extern SEXP R_igraph_write_graph_graphml(void *, void *, void *); +extern SEXP R_igraph_write_graph_leda(void *, void *, void *, void *); +extern SEXP R_igraph_write_graph_lgl(void *, void *, void *, void *, void *); +extern SEXP R_igraph_write_graph_ncol(void *, void *, void *, void *); +extern SEXP R_igraph_write_graph_pajek(void *, void *); +extern SEXP UUID_gen(void *); +extern SEXP make_lazy(void *, void *, void *); +extern SEXP make_lazy_dots(void *, void *); +extern SEXP promise_env_(void *); +extern SEXP promise_expr_(void *); static const R_CallMethodDef CallEntries[] = { {"R_igraph_add_edges", (DL_FUNC) &R_igraph_add_edges, 2}, @@ -508,7 +512,8 @@ static const R_CallMethodDef CallEntries[] = { {"R_igraph_asymmetric_preference_game", (DL_FUNC) &R_igraph_asymmetric_preference_game, 6}, {"R_igraph_atlas", (DL_FUNC) &R_igraph_atlas, 1}, {"R_igraph_authority_score", (DL_FUNC) &R_igraph_authority_score, 4}, - {"R_igraph_automorphism_group", (DL_FUNC) &R_igraph_automorphism_group, 3}, + {"R_igraph_automorphism_group", (DL_FUNC) &R_igraph_automorphism_group, 2}, + {"R_igraph_automorphism_group_bliss", (DL_FUNC) &R_igraph_automorphism_group_bliss, 3}, {"R_igraph_average_local_efficiency", (DL_FUNC) &R_igraph_average_local_efficiency, 4}, {"R_igraph_average_path_length_dijkstra", (DL_FUNC) &R_igraph_average_path_length_dijkstra, 4}, {"R_igraph_avg_nearest_neighbor_degree", (DL_FUNC) &R_igraph_avg_nearest_neighbor_degree, 5}, @@ -528,7 +533,8 @@ static const R_CallMethodDef CallEntries[] = { {"R_igraph_bipartite_projection_size", (DL_FUNC) &R_igraph_bipartite_projection_size, 2}, {"R_igraph_bridges", (DL_FUNC) &R_igraph_bridges, 1}, {"R_igraph_callaway_traits_game", (DL_FUNC) &R_igraph_callaway_traits_game, 6}, - {"R_igraph_canonical_permutation", (DL_FUNC) &R_igraph_canonical_permutation, 3}, + {"R_igraph_canonical_permutation", (DL_FUNC) &R_igraph_canonical_permutation, 2}, + {"R_igraph_canonical_permutation_bliss", (DL_FUNC) &R_igraph_canonical_permutation_bliss, 3}, {"R_igraph_centralization", (DL_FUNC) &R_igraph_centralization, 3}, {"R_igraph_centralization_betweenness", (DL_FUNC) &R_igraph_centralization_betweenness, 3}, {"R_igraph_centralization_betweenness_tmax", (DL_FUNC) &R_igraph_centralization_betweenness_tmax, 3}, @@ -573,7 +579,8 @@ static const R_CallMethodDef CallEntries[] = { {"R_igraph_coreness", (DL_FUNC) &R_igraph_coreness, 2}, {"R_igraph_correlated_game", (DL_FUNC) &R_igraph_correlated_game, 4}, {"R_igraph_correlated_pair_game", (DL_FUNC) &R_igraph_correlated_pair_game, 5}, - {"R_igraph_count_automorphisms", (DL_FUNC) &R_igraph_count_automorphisms, 3}, + {"R_igraph_count_automorphisms", (DL_FUNC) &R_igraph_count_automorphisms, 2}, + {"R_igraph_count_automorphisms_bliss", (DL_FUNC) &R_igraph_count_automorphisms_bliss, 3}, {"R_igraph_count_isomorphisms_vf2", (DL_FUNC) &R_igraph_count_isomorphisms_vf2, 6}, {"R_igraph_count_multiple", (DL_FUNC) &R_igraph_count_multiple, 2}, {"R_igraph_count_subisomorphisms_vf2", (DL_FUNC) &R_igraph_count_subisomorphisms_vf2, 6}, @@ -586,7 +593,8 @@ static const R_CallMethodDef CallEntries[] = { {"R_igraph_degree_sequence_game", (DL_FUNC) &R_igraph_degree_sequence_game, 3}, {"R_igraph_delete_edges", (DL_FUNC) &R_igraph_delete_edges, 2}, {"R_igraph_delete_vertices", (DL_FUNC) &R_igraph_delete_vertices, 2}, - {"R_igraph_delete_vertices_idx", (DL_FUNC) &R_igraph_delete_vertices_idx, 2}, + {"R_igraph_delete_vertices_idx", (DL_FUNC) &R_igraph_delete_vertices_idx, 0}, + {"R_igraph_delete_vertices_map", (DL_FUNC) &R_igraph_delete_vertices_map, 2}, {"R_igraph_density", (DL_FUNC) &R_igraph_density, 2}, {"R_igraph_deterministic_optimal_imitation", (DL_FUNC) &R_igraph_deterministic_optimal_imitation, 6}, {"R_igraph_dfs", (DL_FUNC) &R_igraph_dfs, 12}, @@ -600,7 +608,7 @@ static const R_CallMethodDef CallEntries[] = { {"R_igraph_distances_dijkstra", (DL_FUNC) &R_igraph_distances_dijkstra, 5}, {"R_igraph_distances_dijkstra_cutoff", (DL_FUNC) &R_igraph_distances_dijkstra_cutoff, 6}, {"R_igraph_distances_floyd_warshall", (DL_FUNC) &R_igraph_distances_floyd_warshall, 6}, - {"R_igraph_distances_johnson", (DL_FUNC) &R_igraph_distances_johnson, 4}, + {"R_igraph_distances_johnson", (DL_FUNC) &R_igraph_distances_johnson, 5}, {"R_igraph_diversity", (DL_FUNC) &R_igraph_diversity, 3}, {"R_igraph_dominator_tree", (DL_FUNC) &R_igraph_dominator_tree, 3}, {"R_igraph_dot_product_game", (DL_FUNC) &R_igraph_dot_product_game, 2}, @@ -614,7 +622,7 @@ static const R_CallMethodDef CallEntries[] = { {"R_igraph_edge_connectivity", (DL_FUNC) &R_igraph_edge_connectivity, 2}, {"R_igraph_edge_disjoint_paths", (DL_FUNC) &R_igraph_edge_disjoint_paths, 3}, {"R_igraph_edges", (DL_FUNC) &R_igraph_edges, 2}, - {"R_igraph_eigen_adjacency", (DL_FUNC) &R_igraph_eigen_adjacency, 4}, + {"R_igraph_eigen_adjacency", (DL_FUNC) &R_igraph_eigen_adjacency, 5}, {"R_igraph_eigenvector_centrality", (DL_FUNC) &R_igraph_eigenvector_centrality, 5}, {"R_igraph_empty", (DL_FUNC) &R_igraph_empty, 2}, {"R_igraph_erdos_renyi_game", (DL_FUNC) &R_igraph_erdos_renyi_game, 5}, @@ -859,11 +867,11 @@ static const R_CallMethodDef CallEntries[] = { {"R_igraph_sbm_game", (DL_FUNC) &R_igraph_sbm_game, 5}, {"R_igraph_set_verbose", (DL_FUNC) &R_igraph_set_verbose, 1}, {"R_igraph_shortest_paths", (DL_FUNC) &R_igraph_shortest_paths, 6}, - {"R_igraph_similarity_dice", (DL_FUNC) &R_igraph_similarity_dice, 4}, + {"R_igraph_similarity_dice", (DL_FUNC) &R_igraph_similarity_dice, 5}, {"R_igraph_similarity_dice_es", (DL_FUNC) &R_igraph_similarity_dice_es, 4}, {"R_igraph_similarity_dice_pairs", (DL_FUNC) &R_igraph_similarity_dice_pairs, 4}, {"R_igraph_similarity_inverse_log_weighted", (DL_FUNC) &R_igraph_similarity_inverse_log_weighted, 3}, - {"R_igraph_similarity_jaccard", (DL_FUNC) &R_igraph_similarity_jaccard, 4}, + {"R_igraph_similarity_jaccard", (DL_FUNC) &R_igraph_similarity_jaccard, 5}, {"R_igraph_similarity_jaccard_es", (DL_FUNC) &R_igraph_similarity_jaccard_es, 4}, {"R_igraph_similarity_jaccard_pairs", (DL_FUNC) &R_igraph_similarity_jaccard_pairs, 4}, {"R_igraph_simple_interconnected_islands_game", (DL_FUNC) &R_igraph_simple_interconnected_islands_game, 4}, diff --git a/src/rinterface.c b/src/rinterface.c index ea9a4f8fcda..38c98df1241 100644 --- a/src/rinterface.c +++ b/src/rinterface.c @@ -85,9 +85,9 @@ SEXP R_igraph_copy(SEXP from) { } /*-------------------------------------------/ -/ igraph_delete_vertices_idx / +/ igraph_delete_vertices_map / /-------------------------------------------*/ -SEXP R_igraph_delete_vertices_idx(SEXP graph, SEXP vertices) { +SEXP R_igraph_delete_vertices_map(SEXP graph, SEXP vertices) { /* Declarations */ igraph_t c_graph; igraph_vs_t c_vertices; @@ -111,7 +111,7 @@ SEXP R_igraph_delete_vertices_idx(SEXP graph, SEXP vertices) { } IGRAPH_FINALLY(igraph_vector_int_destroy, &c_invidx); /* Call igraph */ - IGRAPH_R_CHECK(igraph_delete_vertices_idx(&c_graph, c_vertices, &c_idx, &c_invidx)); + IGRAPH_R_CHECK(igraph_delete_vertices_map(&c_graph, c_vertices, &c_idx, &c_invidx)); /* Convert output */ PROTECT(r_result=NEW_LIST(3)); @@ -245,14 +245,9 @@ SEXP R_igraph_weighted_adjacency(SEXP adjmatrix, SEXP mode, SEXP loops) { /* Convert input */ R_SEXP_to_matrix(adjmatrix, &c_adjmatrix); c_mode = (igraph_adjacency_t) Rf_asInteger(mode); - if (0 != igraph_vector_init(&c_weights, 0)) { - igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); - } - IGRAPH_FINALLY(igraph_vector_destroy, &c_weights); - weights=R_GlobalEnv; /* hack to have a non-NULL value */ c_loops = (igraph_loops_t) Rf_asInteger(loops); /* Call igraph */ - IGRAPH_R_CHECK(igraph_weighted_adjacency(&c_graph, &c_adjmatrix, c_mode, (Rf_isNull(weights) ? 0 : &c_weights), c_loops)); + IGRAPH_R_CHECK(igraph_weighted_adjacency(&c_graph, &c_adjmatrix, c_mode, c_weights, c_loops)); /* Convert output */ PROTECT(r_result=NEW_LIST(2)); @@ -261,9 +256,6 @@ SEXP R_igraph_weighted_adjacency(SEXP adjmatrix, SEXP mode, SEXP loops) { PROTECT(graph=R_igraph_to_SEXP(&c_graph)); IGRAPH_I_DESTROY(&c_graph); IGRAPH_FINALLY_CLEAN(1); - PROTECT(weights=R_igraph_0orvector_to_SEXP(&c_weights)); - igraph_vector_destroy(&c_weights); - IGRAPH_FINALLY_CLEAN(1); SET_VECTOR_ELT(r_result, 0, graph); SET_VECTOR_ELT(r_result, 1, weights); SET_STRING_ELT(r_names, 0, Rf_mkChar("graph")); @@ -1660,10 +1652,6 @@ SEXP R_igraph_closeness(SEXP graph, SEXP vids, SEXP mode, SEXP weights, SEXP nor SEXP r_result, r_names; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); - if (0 != igraph_vector_init(&c_res, 0)) { - igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); - } - IGRAPH_FINALLY(igraph_vector_destroy, &c_res); if (0 != igraph_vector_int_init(&c_reachable_count, 0)) { igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); } @@ -1671,18 +1659,14 @@ SEXP R_igraph_closeness(SEXP graph, SEXP vids, SEXP mode, SEXP weights, SEXP nor igraph_vector_int_t c_vids_data; R_SEXP_to_igraph_vs(vids, &c_graph, &c_vids, &c_vids_data); c_mode = (igraph_neimode_t) Rf_asInteger(mode); - if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } IGRAPH_R_CHECK_BOOL(normalized); c_normalized = LOGICAL(normalized)[0]; /* Call igraph */ - IGRAPH_R_CHECK(igraph_closeness(&c_graph, &c_res, &c_reachable_count, &c_all_reachable, c_vids, c_mode, (Rf_isNull(weights) ? 0 : &c_weights), c_normalized)); + IGRAPH_R_CHECK(igraph_closeness(&c_graph, c_res, &c_reachable_count, &c_all_reachable, c_vids, c_mode, c_weights, c_normalized)); /* Convert output */ PROTECT(r_result=NEW_LIST(3)); PROTECT(r_names=NEW_CHARACTER(3)); - PROTECT(res=R_igraph_vector_to_SEXP(&c_res)); - igraph_vector_destroy(&c_res); - IGRAPH_FINALLY_CLEAN(1); PROTECT(reachable_count=R_igraph_vector_int_to_SEXP(&c_reachable_count)); igraph_vector_int_destroy(&c_reachable_count); IGRAPH_FINALLY_CLEAN(1); @@ -1724,10 +1708,6 @@ SEXP R_igraph_closeness_cutoff(SEXP graph, SEXP vids, SEXP mode, SEXP weights, S SEXP r_result, r_names; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); - if (0 != igraph_vector_init(&c_res, 0)) { - igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); - } - IGRAPH_FINALLY(igraph_vector_destroy, &c_res); if (0 != igraph_vector_int_init(&c_reachable_count, 0)) { igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); } @@ -1735,20 +1715,16 @@ SEXP R_igraph_closeness_cutoff(SEXP graph, SEXP vids, SEXP mode, SEXP weights, S igraph_vector_int_t c_vids_data; R_SEXP_to_igraph_vs(vids, &c_graph, &c_vids, &c_vids_data); c_mode = (igraph_neimode_t) Rf_asInteger(mode); - if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } IGRAPH_R_CHECK_BOOL(normalized); c_normalized = LOGICAL(normalized)[0]; IGRAPH_R_CHECK_REAL(cutoff); c_cutoff = REAL(cutoff)[0]; /* Call igraph */ - IGRAPH_R_CHECK(igraph_closeness_cutoff(&c_graph, &c_res, &c_reachable_count, &c_all_reachable, c_vids, c_mode, (Rf_isNull(weights) ? 0 : &c_weights), c_normalized, c_cutoff)); + IGRAPH_R_CHECK(igraph_closeness_cutoff(&c_graph, c_res, &c_reachable_count, &c_all_reachable, c_vids, c_mode, c_weights, c_normalized, c_cutoff)); /* Convert output */ PROTECT(r_result=NEW_LIST(3)); PROTECT(r_names=NEW_CHARACTER(3)); - PROTECT(res=R_igraph_vector_to_SEXP(&c_res)); - igraph_vector_destroy(&c_res); - IGRAPH_FINALLY_CLEAN(1); PROTECT(reachable_count=R_igraph_vector_int_to_SEXP(&c_reachable_count)); igraph_vector_int_destroy(&c_reachable_count); IGRAPH_FINALLY_CLEAN(1); @@ -1933,10 +1909,9 @@ SEXP R_igraph_get_shortest_path_bellman_ford(SEXP graph, SEXP from, SEXP to, SEX IGRAPH_FINALLY(igraph_vector_int_destroy, &c_edges); c_from = (igraph_integer_t) REAL(from)[0]; c_to = (igraph_integer_t) REAL(to)[0]; - if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } c_mode = (igraph_neimode_t) Rf_asInteger(mode); /* Call igraph */ - IGRAPH_R_CHECK(igraph_get_shortest_path_bellman_ford(&c_graph, &c_vertices, &c_edges, c_from, c_to, (Rf_isNull(weights) ? 0 : (Rf_isNull(weights) ? 0 : &c_weights)), c_mode)); + IGRAPH_R_CHECK(igraph_get_shortest_path_bellman_ford(&c_graph, &c_vertices, &c_edges, c_from, c_to, (Rf_isNull(weights) ? 0 : c_weights), c_mode)); /* Convert output */ PROTECT(r_result=NEW_LIST(2)); @@ -1986,10 +1961,9 @@ SEXP R_igraph_get_shortest_path_dijkstra(SEXP graph, SEXP from, SEXP to, SEXP we IGRAPH_FINALLY(igraph_vector_int_destroy, &c_edges); c_from = (igraph_integer_t) REAL(from)[0]; c_to = (igraph_integer_t) REAL(to)[0]; - if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } c_mode = (igraph_neimode_t) Rf_asInteger(mode); /* Call igraph */ - IGRAPH_R_CHECK(igraph_get_shortest_path_dijkstra(&c_graph, &c_vertices, &c_edges, c_from, c_to, (Rf_isNull(weights) ? 0 : (Rf_isNull(weights) ? 0 : &c_weights)), c_mode)); + IGRAPH_R_CHECK(igraph_get_shortest_path_dijkstra(&c_graph, &c_vertices, &c_edges, c_from, c_to, (Rf_isNull(weights) ? 0 : c_weights), c_mode)); /* Convert output */ PROTECT(r_result=NEW_LIST(2)); @@ -2030,14 +2004,6 @@ SEXP R_igraph_get_all_shortest_paths(SEXP graph, SEXP from, SEXP to, SEXP mode) SEXP r_result, r_names; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); - if (0 != igraph_vector_int_list_init(&c_vertices, 0)) { - igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); - } - IGRAPH_FINALLY(igraph_vector_int_list_destroy, &c_vertices); - if (0 != igraph_vector_int_list_init(&c_edges, 0)) { - igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); - } - IGRAPH_FINALLY(igraph_vector_int_list_destroy, &c_edges); if (0 != igraph_vector_int_init(&c_nrgeo, 0)) { igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); } @@ -2047,17 +2013,11 @@ SEXP R_igraph_get_all_shortest_paths(SEXP graph, SEXP from, SEXP to, SEXP mode) R_SEXP_to_igraph_vs(to, &c_graph, &c_to, &c_to_data); c_mode = (igraph_neimode_t) Rf_asInteger(mode); /* Call igraph */ - IGRAPH_R_CHECK(igraph_get_all_shortest_paths(&c_graph, &c_vertices, &c_edges, &c_nrgeo, c_from, c_to, c_mode)); + IGRAPH_R_CHECK(igraph_get_all_shortest_paths(&c_graph, c_vertices, c_edges, &c_nrgeo, c_from, c_to, c_mode)); /* Convert output */ PROTECT(r_result=NEW_LIST(3)); PROTECT(r_names=NEW_CHARACTER(3)); - PROTECT(vertices=R_igraph_vector_int_list_to_SEXPp1(&c_vertices)); - igraph_vector_int_list_destroy(&c_vertices); - IGRAPH_FINALLY_CLEAN(1); - PROTECT(edges=R_igraph_vector_int_list_to_SEXPp1(&c_edges)); - igraph_vector_int_list_destroy(&c_edges); - IGRAPH_FINALLY_CLEAN(1); PROTECT(nrgeo=R_igraph_vector_int_to_SEXP(&c_nrgeo)); igraph_vector_int_destroy(&c_nrgeo); IGRAPH_FINALLY_CLEAN(1); @@ -2100,10 +2060,9 @@ SEXP R_igraph_distances_dijkstra(SEXP graph, SEXP from, SEXP to, SEXP weights, S R_SEXP_to_igraph_vs(from, &c_graph, &c_from, &c_from_data); igraph_vector_int_t c_to_data; R_SEXP_to_igraph_vs(to, &c_graph, &c_to, &c_to_data); - if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } c_mode = (igraph_neimode_t) Rf_asInteger(mode); /* Call igraph */ - IGRAPH_R_CHECK(igraph_distances_dijkstra(&c_graph, &c_res, c_from, c_to, (Rf_isNull(weights) ? 0 : &c_weights), c_mode)); + IGRAPH_R_CHECK(igraph_distances_dijkstra(&c_graph, &c_res, c_from, c_to, c_weights, c_mode)); /* Convert output */ PROTECT(res=R_igraph_matrix_to_SEXP(&c_res)); @@ -2144,12 +2103,11 @@ SEXP R_igraph_distances_dijkstra_cutoff(SEXP graph, SEXP from, SEXP to, SEXP wei R_SEXP_to_igraph_vs(from, &c_graph, &c_from, &c_from_data); igraph_vector_int_t c_to_data; R_SEXP_to_igraph_vs(to, &c_graph, &c_to, &c_to_data); - if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } c_mode = (igraph_neimode_t) Rf_asInteger(mode); IGRAPH_R_CHECK_REAL(cutoff); c_cutoff = REAL(cutoff)[0]; /* Call igraph */ - IGRAPH_R_CHECK(igraph_distances_dijkstra_cutoff(&c_graph, &c_res, c_from, c_to, (Rf_isNull(weights) ? 0 : &c_weights), c_mode, c_cutoff)); + IGRAPH_R_CHECK(igraph_distances_dijkstra_cutoff(&c_graph, &c_res, c_from, c_to, c_weights, c_mode, c_cutoff)); /* Convert output */ PROTECT(res=R_igraph_matrix_to_SEXP(&c_res)); @@ -2185,14 +2143,6 @@ SEXP R_igraph_get_all_shortest_paths_dijkstra(SEXP graph, SEXP from, SEXP to, SE SEXP r_result, r_names; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); - if (0 != igraph_vector_int_list_init(&c_vertices, 0)) { - igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); - } - IGRAPH_FINALLY(igraph_vector_int_list_destroy, &c_vertices); - if (0 != igraph_vector_int_list_init(&c_edges, 0)) { - igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); - } - IGRAPH_FINALLY(igraph_vector_int_list_destroy, &c_edges); if (0 != igraph_vector_int_init(&c_nrgeo, 0)) { igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); } @@ -2200,20 +2150,13 @@ SEXP R_igraph_get_all_shortest_paths_dijkstra(SEXP graph, SEXP from, SEXP to, SE c_from = (igraph_integer_t) REAL(from)[0]; igraph_vector_int_t c_to_data; R_SEXP_to_igraph_vs(to, &c_graph, &c_to, &c_to_data); - if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } c_mode = (igraph_neimode_t) Rf_asInteger(mode); /* Call igraph */ - IGRAPH_R_CHECK(igraph_get_all_shortest_paths_dijkstra(&c_graph, &c_vertices, &c_edges, &c_nrgeo, c_from, c_to, (Rf_isNull(weights) ? 0 : &c_weights), c_mode)); + IGRAPH_R_CHECK(igraph_get_all_shortest_paths_dijkstra(&c_graph, c_vertices, c_edges, &c_nrgeo, c_from, c_to, c_weights, c_mode)); /* Convert output */ PROTECT(r_result=NEW_LIST(3)); PROTECT(r_names=NEW_CHARACTER(3)); - PROTECT(vertices=R_igraph_vector_int_list_to_SEXPp1(&c_vertices)); - igraph_vector_int_list_destroy(&c_vertices); - IGRAPH_FINALLY_CLEAN(1); - PROTECT(edges=R_igraph_vector_int_list_to_SEXPp1(&c_edges)); - igraph_vector_int_list_destroy(&c_edges); - IGRAPH_FINALLY_CLEAN(1); PROTECT(nrgeo=R_igraph_vector_int_to_SEXP(&c_nrgeo)); igraph_vector_int_destroy(&c_nrgeo); IGRAPH_FINALLY_CLEAN(1); @@ -2256,10 +2199,9 @@ SEXP R_igraph_distances_bellman_ford(SEXP graph, SEXP from, SEXP to, SEXP weight R_SEXP_to_igraph_vs(from, &c_graph, &c_from, &c_from_data); igraph_vector_int_t c_to_data; R_SEXP_to_igraph_vs(to, &c_graph, &c_to, &c_to_data); - if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } c_mode = (igraph_neimode_t) Rf_asInteger(mode); /* Call igraph */ - IGRAPH_R_CHECK(igraph_distances_bellman_ford(&c_graph, &c_res, c_from, c_to, (Rf_isNull(weights) ? 0 : &c_weights), c_mode)); + IGRAPH_R_CHECK(igraph_distances_bellman_ford(&c_graph, &c_res, c_from, c_to, c_weights, c_mode)); /* Convert output */ PROTECT(res=R_igraph_matrix_to_SEXP(&c_res)); @@ -2278,13 +2220,14 @@ SEXP R_igraph_distances_bellman_ford(SEXP graph, SEXP from, SEXP to, SEXP weight /*-------------------------------------------/ / igraph_distances_johnson / /-------------------------------------------*/ -SEXP R_igraph_distances_johnson(SEXP graph, SEXP from, SEXP to, SEXP weights) { +SEXP R_igraph_distances_johnson(SEXP graph, SEXP from, SEXP to, SEXP weights, SEXP mode) { /* Declarations */ igraph_t c_graph; igraph_matrix_t c_res; igraph_vs_t c_from; igraph_vs_t c_to; igraph_vector_t c_weights; + igraph_neimode_t c_mode; SEXP res; SEXP r_result; @@ -2298,9 +2241,9 @@ SEXP R_igraph_distances_johnson(SEXP graph, SEXP from, SEXP to, SEXP weights) { R_SEXP_to_igraph_vs(from, &c_graph, &c_from, &c_from_data); igraph_vector_int_t c_to_data; R_SEXP_to_igraph_vs(to, &c_graph, &c_to, &c_to_data); - if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } + c_mode = (igraph_neimode_t) Rf_asInteger(mode); /* Call igraph */ - IGRAPH_R_CHECK(igraph_distances_johnson(&c_graph, &c_res, c_from, c_to, (Rf_isNull(weights) ? 0 : &c_weights))); + IGRAPH_R_CHECK(igraph_distances_johnson(&c_graph, &c_res, c_from, c_to, c_weights, c_mode)); /* Convert output */ PROTECT(res=R_igraph_matrix_to_SEXP(&c_res)); @@ -2341,11 +2284,10 @@ SEXP R_igraph_distances_floyd_warshall(SEXP graph, SEXP from, SEXP to, SEXP weig R_SEXP_to_igraph_vs(from, &c_graph, &c_from, &c_from_data); igraph_vector_int_t c_to_data; R_SEXP_to_igraph_vs(to, &c_graph, &c_to, &c_to_data); - if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } c_mode = (igraph_neimode_t) Rf_asInteger(mode); c_method = (igraph_floyd_warshall_algorithm_t) Rf_asInteger(method); /* Call igraph */ - IGRAPH_R_CHECK(igraph_distances_floyd_warshall(&c_graph, &c_res, c_from, c_to, (Rf_isNull(weights) ? 0 : &c_weights), c_mode, c_method)); + IGRAPH_R_CHECK(igraph_distances_floyd_warshall(&c_graph, &c_res, c_from, c_to, c_weights, c_mode, c_method)); /* Convert output */ PROTECT(res=R_igraph_matrix_to_SEXP(&c_res)); @@ -2389,11 +2331,10 @@ SEXP R_igraph_voronoi(SEXP graph, SEXP generators, SEXP weights, SEXP mode, SEXP IGRAPH_FINALLY(igraph_vector_destroy, &c_distances); R_SEXP_to_vector_int_copy(generators, &c_generators); IGRAPH_FINALLY(igraph_vector_int_destroy, &c_generators); - if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } c_mode = (igraph_neimode_t) Rf_asInteger(mode); c_tiebreaker = (igraph_voronoi_tiebreaker_t) Rf_asInteger(tiebreaker); /* Call igraph */ - IGRAPH_R_CHECK(igraph_voronoi(&c_graph, &c_membership, &c_distances, &c_generators, (Rf_isNull(weights) ? 0 : &c_weights), c_mode, c_tiebreaker)); + IGRAPH_R_CHECK(igraph_voronoi(&c_graph, &c_membership, &c_distances, &c_generators, c_weights, c_mode, c_tiebreaker)); /* Convert output */ PROTECT(r_result=NEW_LIST(2)); @@ -2477,32 +2418,17 @@ SEXP R_igraph_get_k_shortest_paths(SEXP graph, SEXP weights, SEXP k, SEXP from, SEXP r_result, r_names; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); - if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } - if (0 != igraph_vector_int_list_init(&c_vertex_paths, 0)) { - igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); - } - IGRAPH_FINALLY(igraph_vector_int_list_destroy, &c_vertex_paths); - if (0 != igraph_vector_int_list_init(&c_edge_paths, 0)) { - igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); - } - IGRAPH_FINALLY(igraph_vector_int_list_destroy, &c_edge_paths); IGRAPH_R_CHECK_INT(k); c_k = (igraph_integer_t) REAL(k)[0]; c_from = (igraph_integer_t) REAL(from)[0]; c_to = (igraph_integer_t) REAL(to)[0]; c_mode = (igraph_neimode_t) Rf_asInteger(mode); /* Call igraph */ - IGRAPH_R_CHECK(igraph_get_k_shortest_paths(&c_graph, (Rf_isNull(weights) ? 0 : (Rf_isNull(weights) ? 0 : &c_weights)), &c_vertex_paths, &c_edge_paths, c_k, c_from, c_to, c_mode)); + IGRAPH_R_CHECK(igraph_get_k_shortest_paths(&c_graph, (Rf_isNull(weights) ? 0 : c_weights), c_vertex_paths, c_edge_paths, c_k, c_from, c_to, c_mode)); /* Convert output */ PROTECT(r_result=NEW_LIST(2)); PROTECT(r_names=NEW_CHARACTER(2)); - PROTECT(vertex_paths=R_igraph_vector_int_list_to_SEXPp1(&c_vertex_paths)); - igraph_vector_int_list_destroy(&c_vertex_paths); - IGRAPH_FINALLY_CLEAN(1); - PROTECT(edge_paths=R_igraph_vector_int_list_to_SEXPp1(&c_edge_paths)); - igraph_vector_int_list_destroy(&c_edge_paths); - IGRAPH_FINALLY_CLEAN(1); SET_VECTOR_ELT(r_result, 0, vertex_paths); SET_VECTOR_ELT(r_result, 1, edge_paths); SET_STRING_ELT(r_names, 0, Rf_mkChar("vpaths")); @@ -2542,10 +2468,9 @@ SEXP R_igraph_get_widest_path(SEXP graph, SEXP from, SEXP to, SEXP weights, SEXP IGRAPH_FINALLY(igraph_vector_int_destroy, &c_edges); c_from = (igraph_integer_t) REAL(from)[0]; c_to = (igraph_integer_t) REAL(to)[0]; - if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } c_mode = (igraph_neimode_t) Rf_asInteger(mode); /* Call igraph */ - IGRAPH_R_CHECK(igraph_get_widest_path(&c_graph, &c_vertices, &c_edges, c_from, c_to, (Rf_isNull(weights) ? 0 : &c_weights), c_mode)); + IGRAPH_R_CHECK(igraph_get_widest_path(&c_graph, &c_vertices, &c_edges, c_from, c_to, c_weights, c_mode)); /* Convert output */ PROTECT(r_result=NEW_LIST(2)); @@ -2589,18 +2514,9 @@ SEXP R_igraph_get_widest_paths(SEXP graph, SEXP from, SEXP to, SEXP weights, SEX SEXP r_result, r_names; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); - if (0 != igraph_vector_int_list_init(&c_vertices, 0)) { - igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); - } - IGRAPH_FINALLY(igraph_vector_int_list_destroy, &c_vertices); - if (0 != igraph_vector_int_list_init(&c_edges, 0)) { - igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); - } - IGRAPH_FINALLY(igraph_vector_int_list_destroy, &c_edges); c_from = (igraph_integer_t) REAL(from)[0]; igraph_vector_int_t c_to_data; R_SEXP_to_igraph_vs(to, &c_graph, &c_to, &c_to_data); - if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } c_mode = (igraph_neimode_t) Rf_asInteger(mode); if (0 != igraph_vector_int_init(&c_parents, 0)) { igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); @@ -2611,17 +2527,11 @@ SEXP R_igraph_get_widest_paths(SEXP graph, SEXP from, SEXP to, SEXP weights, SEX } IGRAPH_FINALLY(igraph_vector_int_destroy, &c_inbound_edges); /* Call igraph */ - IGRAPH_R_CHECK(igraph_get_widest_paths(&c_graph, &c_vertices, &c_edges, c_from, c_to, (Rf_isNull(weights) ? 0 : &c_weights), c_mode, &c_parents, &c_inbound_edges)); + IGRAPH_R_CHECK(igraph_get_widest_paths(&c_graph, c_vertices, c_edges, c_from, c_to, c_weights, c_mode, &c_parents, &c_inbound_edges)); /* Convert output */ PROTECT(r_result=NEW_LIST(4)); PROTECT(r_names=NEW_CHARACTER(4)); - PROTECT(vertices=R_igraph_vector_int_list_to_SEXPp1(&c_vertices)); - igraph_vector_int_list_destroy(&c_vertices); - IGRAPH_FINALLY_CLEAN(1); - PROTECT(edges=R_igraph_vector_int_list_to_SEXPp1(&c_edges)); - igraph_vector_int_list_destroy(&c_edges); - IGRAPH_FINALLY_CLEAN(1); igraph_vector_int_destroy(&c_to_data); igraph_vs_destroy(&c_to); PROTECT(parents=R_igraph_vector_int_to_SEXP(&c_parents)); @@ -2669,10 +2579,9 @@ SEXP R_igraph_widest_path_widths_dijkstra(SEXP graph, SEXP from, SEXP to, SEXP w R_SEXP_to_igraph_vs(from, &c_graph, &c_from, &c_from_data); igraph_vector_int_t c_to_data; R_SEXP_to_igraph_vs(to, &c_graph, &c_to, &c_to_data); - if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } c_mode = (igraph_neimode_t) Rf_asInteger(mode); /* Call igraph */ - IGRAPH_R_CHECK(igraph_widest_path_widths_dijkstra(&c_graph, &c_res, c_from, c_to, (Rf_isNull(weights) ? 0 : &c_weights), c_mode)); + IGRAPH_R_CHECK(igraph_widest_path_widths_dijkstra(&c_graph, &c_res, c_from, c_to, c_weights, c_mode)); /* Convert output */ PROTECT(res=R_igraph_matrix_to_SEXP(&c_res)); @@ -2712,10 +2621,9 @@ SEXP R_igraph_widest_path_widths_floyd_warshall(SEXP graph, SEXP from, SEXP to, R_SEXP_to_igraph_vs(from, &c_graph, &c_from, &c_from_data); igraph_vector_int_t c_to_data; R_SEXP_to_igraph_vs(to, &c_graph, &c_to, &c_to_data); - if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } c_mode = (igraph_neimode_t) Rf_asInteger(mode); /* Call igraph */ - IGRAPH_R_CHECK(igraph_widest_path_widths_floyd_warshall(&c_graph, &c_res, c_from, c_to, (Rf_isNull(weights) ? 0 : &c_weights), c_mode)); + IGRAPH_R_CHECK(igraph_widest_path_widths_floyd_warshall(&c_graph, &c_res, c_from, c_to, c_weights, c_mode)); /* Convert output */ PROTECT(res=R_igraph_matrix_to_SEXP(&c_res)); @@ -2751,9 +2659,8 @@ SEXP R_igraph_spanner(SEXP graph, SEXP stretch, SEXP weights) { IGRAPH_FINALLY(igraph_vector_int_destroy, &c_spanner); IGRAPH_R_CHECK_REAL(stretch); c_stretch = REAL(stretch)[0]; - if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } /* Call igraph */ - IGRAPH_R_CHECK(igraph_spanner(&c_graph, &c_spanner, c_stretch, (Rf_isNull(weights) ? 0 : (Rf_isNull(weights) ? 0 : &c_weights)))); + IGRAPH_R_CHECK(igraph_spanner(&c_graph, &c_spanner, c_stretch, (Rf_isNull(weights) ? 0 : c_weights))); /* Convert output */ PROTECT(spanner=R_igraph_vector_int_to_SEXPp1(&c_spanner)); @@ -2781,24 +2688,16 @@ SEXP R_igraph_betweenness_cutoff(SEXP graph, SEXP vids, SEXP directed, SEXP weig SEXP r_result; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); - if (0 != igraph_vector_init(&c_res, 0)) { - igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); - } - IGRAPH_FINALLY(igraph_vector_destroy, &c_res); igraph_vector_int_t c_vids_data; R_SEXP_to_igraph_vs(vids, &c_graph, &c_vids, &c_vids_data); IGRAPH_R_CHECK_BOOL(directed); c_directed = LOGICAL(directed)[0]; - if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } IGRAPH_R_CHECK_REAL(cutoff); c_cutoff = REAL(cutoff)[0]; /* Call igraph */ - IGRAPH_R_CHECK(igraph_betweenness_cutoff(&c_graph, &c_res, c_vids, c_directed, (Rf_isNull(weights) ? 0 : &c_weights), c_cutoff)); + IGRAPH_R_CHECK(igraph_betweenness_cutoff(&c_graph, c_res, c_vids, c_directed, c_weights, c_cutoff)); /* Convert output */ - PROTECT(res=R_igraph_vector_to_SEXP(&c_res)); - igraph_vector_destroy(&c_res); - IGRAPH_FINALLY_CLEAN(1); igraph_vector_int_destroy(&c_vids_data); igraph_vs_destroy(&c_vids); r_result = res; @@ -2824,10 +2723,6 @@ SEXP R_igraph_betweenness_subset(SEXP graph, SEXP vids, SEXP directed, SEXP sour SEXP r_result; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); - if (0 != igraph_vector_init(&c_res, 0)) { - igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); - } - IGRAPH_FINALLY(igraph_vector_destroy, &c_res); igraph_vector_int_t c_vids_data; R_SEXP_to_igraph_vs(vids, &c_graph, &c_vids, &c_vids_data); IGRAPH_R_CHECK_BOOL(directed); @@ -2836,14 +2731,10 @@ SEXP R_igraph_betweenness_subset(SEXP graph, SEXP vids, SEXP directed, SEXP sour R_SEXP_to_igraph_vs(sources, &c_graph, &c_sources, &c_sources_data); igraph_vector_int_t c_targets_data; R_SEXP_to_igraph_vs(targets, &c_graph, &c_targets, &c_targets_data); - if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } /* Call igraph */ - IGRAPH_R_CHECK(igraph_betweenness_subset(&c_graph, &c_res, c_vids, c_directed, c_sources, c_targets, (Rf_isNull(weights) ? 0 : &c_weights))); + IGRAPH_R_CHECK(igraph_betweenness_subset(&c_graph, c_res, c_vids, c_directed, c_sources, c_targets, c_weights)); /* Convert output */ - PROTECT(res=R_igraph_vector_to_SEXP(&c_res)); - igraph_vector_destroy(&c_res); - IGRAPH_FINALLY_CLEAN(1); igraph_vector_int_destroy(&c_vids_data); igraph_vs_destroy(&c_vids); igraph_vector_int_destroy(&c_sources_data); @@ -2876,9 +2767,8 @@ SEXP R_igraph_edge_betweenness(SEXP graph, SEXP directed, SEXP weights) { IGRAPH_FINALLY(igraph_vector_destroy, &c_res); IGRAPH_R_CHECK_BOOL(directed); c_directed = LOGICAL(directed)[0]; - if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } /* Call igraph */ - IGRAPH_R_CHECK(igraph_edge_betweenness(&c_graph, &c_res, c_directed, (Rf_isNull(weights) ? 0 : &c_weights))); + IGRAPH_R_CHECK(igraph_edge_betweenness(&c_graph, &c_res, c_directed, c_weights)); /* Convert output */ PROTECT(res=R_igraph_vector_to_SEXP(&c_res)); @@ -2911,11 +2801,10 @@ SEXP R_igraph_edge_betweenness_cutoff(SEXP graph, SEXP directed, SEXP weights, S IGRAPH_FINALLY(igraph_vector_destroy, &c_res); IGRAPH_R_CHECK_BOOL(directed); c_directed = LOGICAL(directed)[0]; - if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } IGRAPH_R_CHECK_REAL(cutoff); c_cutoff = REAL(cutoff)[0]; /* Call igraph */ - IGRAPH_R_CHECK(igraph_edge_betweenness_cutoff(&c_graph, &c_res, c_directed, (Rf_isNull(weights) ? 0 : &c_weights), c_cutoff)); + IGRAPH_R_CHECK(igraph_edge_betweenness_cutoff(&c_graph, &c_res, c_directed, c_weights, c_cutoff)); /* Convert output */ PROTECT(res=R_igraph_vector_to_SEXP(&c_res)); @@ -2944,10 +2833,6 @@ SEXP R_igraph_edge_betweenness_subset(SEXP graph, SEXP eids, SEXP directed, SEXP SEXP r_result; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); - if (0 != igraph_vector_init(&c_res, 0)) { - igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); - } - IGRAPH_FINALLY(igraph_vector_destroy, &c_res); igraph_vector_int_t c_eids_data; R_SEXP_to_igraph_es(eids, &c_graph, &c_eids, &c_eids_data); IGRAPH_R_CHECK_BOOL(directed); @@ -2956,14 +2841,10 @@ SEXP R_igraph_edge_betweenness_subset(SEXP graph, SEXP eids, SEXP directed, SEXP R_SEXP_to_igraph_vs(sources, &c_graph, &c_sources, &c_sources_data); igraph_vector_int_t c_targets_data; R_SEXP_to_igraph_vs(targets, &c_graph, &c_targets, &c_targets_data); - if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } /* Call igraph */ - IGRAPH_R_CHECK(igraph_edge_betweenness_subset(&c_graph, &c_res, c_eids, c_directed, c_sources, c_targets, (Rf_isNull(weights) ? 0 : &c_weights))); + IGRAPH_R_CHECK(igraph_edge_betweenness_subset(&c_graph, c_res, c_eids, c_directed, c_sources, c_targets, c_weights)); /* Convert output */ - PROTECT(res=R_igraph_vector_to_SEXP(&c_res)); - igraph_vector_destroy(&c_res); - IGRAPH_FINALLY_CLEAN(1); igraph_vector_int_destroy(&c_eids_data); igraph_es_destroy(&c_eids); igraph_vector_int_destroy(&c_sources_data); @@ -2993,25 +2874,17 @@ SEXP R_igraph_harmonic_centrality_cutoff(SEXP graph, SEXP vids, SEXP mode, SEXP SEXP r_result; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); - if (0 != igraph_vector_init(&c_res, 0)) { - igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); - } - IGRAPH_FINALLY(igraph_vector_destroy, &c_res); igraph_vector_int_t c_vids_data; R_SEXP_to_igraph_vs(vids, &c_graph, &c_vids, &c_vids_data); c_mode = (igraph_neimode_t) Rf_asInteger(mode); - if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } IGRAPH_R_CHECK_BOOL(normalized); c_normalized = LOGICAL(normalized)[0]; IGRAPH_R_CHECK_REAL(cutoff); c_cutoff = REAL(cutoff)[0]; /* Call igraph */ - IGRAPH_R_CHECK(igraph_harmonic_centrality_cutoff(&c_graph, &c_res, c_vids, c_mode, (Rf_isNull(weights) ? 0 : &c_weights), c_normalized, c_cutoff)); + IGRAPH_R_CHECK(igraph_harmonic_centrality_cutoff(&c_graph, c_res, c_vids, c_mode, c_weights, c_normalized, c_cutoff)); /* Convert output */ - PROTECT(res=R_igraph_vector_to_SEXP(&c_res)); - igraph_vector_destroy(&c_res); - IGRAPH_FINALLY_CLEAN(1); igraph_vector_int_destroy(&c_vids_data); igraph_vs_destroy(&c_vids); r_result = res; @@ -3043,10 +2916,6 @@ SEXP R_igraph_personalized_pagerank(SEXP graph, SEXP algo, SEXP vids, SEXP direc /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); c_algo = (igraph_pagerank_algo_t) Rf_asInteger(algo); - if (0 != igraph_vector_init(&c_vector, 0)) { - igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); - } - IGRAPH_FINALLY(igraph_vector_destroy, &c_vector); igraph_vector_int_t c_vids_data; R_SEXP_to_igraph_vs(vids, &c_graph, &c_vids, &c_vids_data); IGRAPH_R_CHECK_BOOL(directed); @@ -3056,7 +2925,6 @@ SEXP R_igraph_personalized_pagerank(SEXP graph, SEXP algo, SEXP vids, SEXP direc if (!Rf_isNull(personalized)) { R_SEXP_to_vector(personalized, &c_personalized); } - if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } if (c_algo == IGRAPH_PAGERANK_ALGO_ARPACK) { R_SEXP_to_igraph_arpack_options(options, &c_options1); c_options = &c_options1; @@ -3064,14 +2932,11 @@ SEXP R_igraph_personalized_pagerank(SEXP graph, SEXP algo, SEXP vids, SEXP direc c_options = 0; } /* Call igraph */ - IGRAPH_R_CHECK(igraph_personalized_pagerank(&c_graph, c_algo, &c_vector, &c_value, c_vids, c_directed, c_damping, (Rf_isNull(personalized) ? 0 : &c_personalized), (Rf_isNull(weights) ? 0 : (Rf_isNull(weights) ? 0 : &c_weights)), c_options)); + IGRAPH_R_CHECK(igraph_personalized_pagerank(&c_graph, c_algo, c_vector, &c_value, c_vids, c_directed, c_damping, (Rf_isNull(personalized) ? 0 : &c_personalized), (Rf_isNull(weights) ? 0 : c_weights), c_options)); /* Convert output */ PROTECT(r_result=NEW_LIST(3)); PROTECT(r_names=NEW_CHARACTER(3)); - PROTECT(vector=R_igraph_vector_to_SEXP(&c_vector)); - igraph_vector_destroy(&c_vector); - IGRAPH_FINALLY_CLEAN(1); PROTECT(value=NEW_NUMERIC(1)); REAL(value)[0]=c_value; igraph_vector_int_destroy(&c_vids_data); @@ -3117,10 +2982,6 @@ SEXP R_igraph_personalized_pagerank_vs(SEXP graph, SEXP algo, SEXP vids, SEXP di /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); c_algo = (igraph_pagerank_algo_t) Rf_asInteger(algo); - if (0 != igraph_vector_init(&c_vector, 0)) { - igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); - } - IGRAPH_FINALLY(igraph_vector_destroy, &c_vector); igraph_vector_int_t c_vids_data; R_SEXP_to_igraph_vs(vids, &c_graph, &c_vids, &c_vids_data); IGRAPH_R_CHECK_BOOL(directed); @@ -3129,7 +2990,6 @@ SEXP R_igraph_personalized_pagerank_vs(SEXP graph, SEXP algo, SEXP vids, SEXP di c_damping = REAL(damping)[0]; igraph_vector_int_t c_reset_vids_data; R_SEXP_to_igraph_vs(reset_vids, &c_graph, &c_reset_vids, &c_reset_vids_data); - if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } if (c_algo == IGRAPH_PAGERANK_ALGO_ARPACK) { R_SEXP_to_igraph_arpack_options(options, &c_options1); c_options = &c_options1; @@ -3137,14 +2997,11 @@ SEXP R_igraph_personalized_pagerank_vs(SEXP graph, SEXP algo, SEXP vids, SEXP di c_options = 0; } /* Call igraph */ - IGRAPH_R_CHECK(igraph_personalized_pagerank_vs(&c_graph, c_algo, &c_vector, &c_value, c_vids, c_directed, c_damping, c_reset_vids, (Rf_isNull(weights) ? 0 : (Rf_isNull(weights) ? 0 : &c_weights)), c_options)); + IGRAPH_R_CHECK(igraph_personalized_pagerank_vs(&c_graph, c_algo, c_vector, &c_value, c_vids, c_directed, c_damping, c_reset_vids, (Rf_isNull(weights) ? 0 : c_weights), c_options)); /* Convert output */ PROTECT(r_result=NEW_LIST(3)); PROTECT(r_names=NEW_CHARACTER(3)); - PROTECT(vector=R_igraph_vector_to_SEXP(&c_vector)); - igraph_vector_destroy(&c_vector); - IGRAPH_FINALLY_CLEAN(1); PROTECT(value=NEW_NUMERIC(1)); REAL(value)[0]=c_value; igraph_vector_int_destroy(&c_vids_data); @@ -3282,13 +3139,12 @@ SEXP R_igraph_average_path_length_dijkstra(SEXP graph, SEXP weights, SEXP direct SEXP r_result, r_names; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); - if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } IGRAPH_R_CHECK_BOOL(directed); c_directed = LOGICAL(directed)[0]; IGRAPH_R_CHECK_BOOL(unconn); c_unconn = LOGICAL(unconn)[0]; /* Call igraph */ - IGRAPH_R_CHECK(igraph_average_path_length_dijkstra(&c_graph, &c_res, &c_unconn_pairs, (Rf_isNull(weights) ? 0 : &c_weights), c_directed, c_unconn)); + IGRAPH_R_CHECK(igraph_average_path_length_dijkstra(&c_graph, &c_res, &c_unconn_pairs, c_weights, c_directed, c_unconn)); /* Convert output */ PROTECT(r_result=NEW_LIST(2)); @@ -3476,10 +3332,9 @@ SEXP R_igraph_feedback_arc_set(SEXP graph, SEXP weights, SEXP algo) { igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_vector_int_destroy, &c_result); - if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } c_algo = (igraph_fas_algorithm_t) Rf_asInteger(algo); /* Call igraph */ - IGRAPH_R_CHECK(igraph_feedback_arc_set(&c_graph, &c_result, (Rf_isNull(weights) ? 0 : &c_weights), c_algo)); + IGRAPH_R_CHECK(igraph_feedback_arc_set(&c_graph, &c_result, c_weights, c_algo)); /* Convert output */ PROTECT(result=R_igraph_vector_int_to_SEXPp1(&c_result)); @@ -3755,28 +3610,18 @@ SEXP R_igraph_eigenvector_centrality(SEXP graph, SEXP directed, SEXP scale, SEXP SEXP r_result, r_names; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); - if (0 != igraph_vector_init(&c_vector, 0)) { - igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); - } - IGRAPH_FINALLY(igraph_vector_destroy, &c_vector); IGRAPH_R_CHECK_BOOL(directed); c_directed = LOGICAL(directed)[0]; IGRAPH_R_CHECK_BOOL(scale); c_scale = LOGICAL(scale)[0]; - if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } - R_SEXP_to_igraph_arpack_options(options, &c_options); /* Call igraph */ - IGRAPH_R_CHECK(igraph_eigenvector_centrality(&c_graph, &c_vector, &c_value, c_directed, c_scale, (Rf_isNull(weights) ? 0 : &c_weights), &c_options)); + IGRAPH_R_CHECK(igraph_eigenvector_centrality(&c_graph, c_vector, &c_value, c_directed, c_scale, c_weights, c_options)); /* Convert output */ PROTECT(r_result=NEW_LIST(3)); PROTECT(r_names=NEW_CHARACTER(3)); - PROTECT(vector=R_igraph_vector_to_SEXP(&c_vector)); - igraph_vector_destroy(&c_vector); - IGRAPH_FINALLY_CLEAN(1); PROTECT(value=NEW_NUMERIC(1)); REAL(value)[0]=c_value; - PROTECT(options=R_igraph_arpack_options_to_SEXP(&c_options)); SET_VECTOR_ELT(r_result, 0, vector); SET_VECTOR_ELT(r_result, 1, value); SET_VECTOR_ELT(r_result, 2, options); @@ -3807,26 +3652,16 @@ SEXP R_igraph_hub_score(SEXP graph, SEXP scale, SEXP weights, SEXP options) { SEXP r_result, r_names; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); - if (0 != igraph_vector_init(&c_vector, 0)) { - igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); - } - IGRAPH_FINALLY(igraph_vector_destroy, &c_vector); IGRAPH_R_CHECK_BOOL(scale); c_scale = LOGICAL(scale)[0]; - if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } - R_SEXP_to_igraph_arpack_options(options, &c_options); /* Call igraph */ - IGRAPH_R_CHECK(igraph_hub_score(&c_graph, &c_vector, &c_value, c_scale, (Rf_isNull(weights) ? 0 : &c_weights), &c_options)); + IGRAPH_R_CHECK(igraph_hub_score(&c_graph, c_vector, &c_value, c_scale, c_weights, c_options)); /* Convert output */ PROTECT(r_result=NEW_LIST(3)); PROTECT(r_names=NEW_CHARACTER(3)); - PROTECT(vector=R_igraph_vector_to_SEXP(&c_vector)); - igraph_vector_destroy(&c_vector); - IGRAPH_FINALLY_CLEAN(1); PROTECT(value=NEW_NUMERIC(1)); REAL(value)[0]=c_value; - PROTECT(options=R_igraph_arpack_options_to_SEXP(&c_options)); SET_VECTOR_ELT(r_result, 0, vector); SET_VECTOR_ELT(r_result, 1, value); SET_VECTOR_ELT(r_result, 2, options); @@ -3857,26 +3692,16 @@ SEXP R_igraph_authority_score(SEXP graph, SEXP scale, SEXP weights, SEXP options SEXP r_result, r_names; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); - if (0 != igraph_vector_init(&c_vector, 0)) { - igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); - } - IGRAPH_FINALLY(igraph_vector_destroy, &c_vector); IGRAPH_R_CHECK_BOOL(scale); c_scale = LOGICAL(scale)[0]; - if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } - R_SEXP_to_igraph_arpack_options(options, &c_options); /* Call igraph */ - IGRAPH_R_CHECK(igraph_authority_score(&c_graph, &c_vector, &c_value, c_scale, (Rf_isNull(weights) ? 0 : &c_weights), &c_options)); + IGRAPH_R_CHECK(igraph_authority_score(&c_graph, c_vector, &c_value, c_scale, c_weights, c_options)); /* Convert output */ PROTECT(r_result=NEW_LIST(3)); PROTECT(r_names=NEW_CHARACTER(3)); - PROTECT(vector=R_igraph_vector_to_SEXP(&c_vector)); - igraph_vector_destroy(&c_vector); - IGRAPH_FINALLY_CLEAN(1); PROTECT(value=NEW_NUMERIC(1)); REAL(value)[0]=c_value; - PROTECT(options=R_igraph_arpack_options_to_SEXP(&c_options)); SET_VECTOR_ELT(r_result, 0, vector); SET_VECTOR_ELT(r_result, 1, value); SET_VECTOR_ELT(r_result, 2, options); @@ -3909,33 +3734,16 @@ SEXP R_igraph_hub_and_authority_scores(SEXP graph, SEXP scale, SEXP weights, SEX SEXP r_result, r_names; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); - if (0 != igraph_vector_init(&c_hub_vector, 0)) { - igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); - } - IGRAPH_FINALLY(igraph_vector_destroy, &c_hub_vector); - if (0 != igraph_vector_init(&c_authority_vector, 0)) { - igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); - } - IGRAPH_FINALLY(igraph_vector_destroy, &c_authority_vector); IGRAPH_R_CHECK_BOOL(scale); c_scale = LOGICAL(scale)[0]; - if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } - R_SEXP_to_igraph_arpack_options(options, &c_options); /* Call igraph */ - IGRAPH_R_CHECK(igraph_hub_and_authority_scores(&c_graph, &c_hub_vector, &c_authority_vector, &c_value, c_scale, (Rf_isNull(weights) ? 0 : &c_weights), &c_options)); + IGRAPH_R_CHECK(igraph_hub_and_authority_scores(&c_graph, c_hub_vector, c_authority_vector, &c_value, c_scale, c_weights, c_options)); /* Convert output */ PROTECT(r_result=NEW_LIST(4)); PROTECT(r_names=NEW_CHARACTER(4)); - PROTECT(hub_vector=R_igraph_vector_to_SEXP(&c_hub_vector)); - igraph_vector_destroy(&c_hub_vector); - IGRAPH_FINALLY_CLEAN(1); - PROTECT(authority_vector=R_igraph_vector_to_SEXP(&c_authority_vector)); - igraph_vector_destroy(&c_authority_vector); - IGRAPH_FINALLY_CLEAN(1); PROTECT(value=NEW_NUMERIC(1)); REAL(value)[0]=c_value; - PROTECT(options=R_igraph_arpack_options_to_SEXP(&c_options)); SET_VECTOR_ELT(r_result, 0, hub_vector); SET_VECTOR_ELT(r_result, 1, authority_vector); SET_VECTOR_ELT(r_result, 2, value); @@ -4131,26 +3939,18 @@ SEXP R_igraph_avg_nearest_neighbor_degree(SEXP graph, SEXP vids, SEXP mode, SEXP R_SEXP_to_igraph_vs(vids, &c_graph, &c_vids, &c_vids_data); c_mode = (igraph_neimode_t) Rf_asInteger(mode); c_neighbor_degree_mode = (igraph_neimode_t) Rf_asInteger(neighbor_degree_mode); - if (0 != igraph_vector_init(&c_knn, 0)) { - igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); - } - IGRAPH_FINALLY(igraph_vector_destroy, &c_knn); if (0 != igraph_vector_init(&c_knnk, 0)) { igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_vector_destroy, &c_knnk); - if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } /* Call igraph */ - IGRAPH_R_CHECK(igraph_avg_nearest_neighbor_degree(&c_graph, c_vids, c_mode, c_neighbor_degree_mode, &c_knn, &c_knnk, (Rf_isNull(weights) ? 0 : &c_weights))); + IGRAPH_R_CHECK(igraph_avg_nearest_neighbor_degree(&c_graph, c_vids, c_mode, c_neighbor_degree_mode, c_knn, &c_knnk, c_weights)); /* Convert output */ PROTECT(r_result=NEW_LIST(2)); PROTECT(r_names=NEW_CHARACTER(2)); igraph_vector_int_destroy(&c_vids_data); igraph_vs_destroy(&c_vids); - PROTECT(knn=R_igraph_vector_to_SEXP(&c_knn)); - igraph_vector_destroy(&c_knn); - IGRAPH_FINALLY_CLEAN(1); PROTECT(knnk=R_igraph_vector_to_SEXP(&c_knnk)); igraph_vector_destroy(&c_knnk); IGRAPH_FINALLY_CLEAN(1); @@ -4181,7 +3981,6 @@ SEXP R_igraph_degree_correlation_vector(SEXP graph, SEXP weights, SEXP from_mode SEXP r_result; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); - if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } if (0 != igraph_vector_init(&c_knnk, 0)) { igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); } @@ -4191,7 +3990,7 @@ SEXP R_igraph_degree_correlation_vector(SEXP graph, SEXP weights, SEXP from_mode IGRAPH_R_CHECK_BOOL(directed_neighbors); c_directed_neighbors = LOGICAL(directed_neighbors)[0]; /* Call igraph */ - IGRAPH_R_CHECK(igraph_degree_correlation_vector(&c_graph, (Rf_isNull(weights) ? 0 : &c_weights), &c_knnk, c_from_mode, c_to_mode, c_directed_neighbors)); + IGRAPH_R_CHECK(igraph_degree_correlation_vector(&c_graph, c_weights, &c_knnk, c_from_mode, c_to_mode, c_directed_neighbors)); /* Convert output */ PROTECT(knnk=R_igraph_vector_to_SEXP(&c_knnk)); @@ -4219,23 +4018,15 @@ SEXP R_igraph_strength(SEXP graph, SEXP vids, SEXP mode, SEXP loops, SEXP weight SEXP r_result; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); - if (0 != igraph_vector_init(&c_res, 0)) { - igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); - } - IGRAPH_FINALLY(igraph_vector_destroy, &c_res); igraph_vector_int_t c_vids_data; R_SEXP_to_igraph_vs(vids, &c_graph, &c_vids, &c_vids_data); c_mode = (igraph_neimode_t) Rf_asInteger(mode); IGRAPH_R_CHECK_BOOL(loops); c_loops = LOGICAL(loops)[0]; - if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } /* Call igraph */ - IGRAPH_R_CHECK(igraph_strength(&c_graph, &c_res, c_vids, c_mode, c_loops, (Rf_isNull(weights) ? 0 : &c_weights))); + IGRAPH_R_CHECK(igraph_strength(&c_graph, c_res, c_vids, c_mode, c_loops, c_weights)); /* Convert output */ - PROTECT(res=R_igraph_vector_to_SEXP(&c_res)); - igraph_vector_destroy(&c_res); - IGRAPH_FINALLY_CLEAN(1); igraph_vector_int_destroy(&c_vids_data); igraph_vs_destroy(&c_vids); r_result = res; @@ -4556,11 +4347,10 @@ SEXP R_igraph_centralization_eigenvector_centrality(SEXP graph, SEXP directed, S c_directed = LOGICAL(directed)[0]; IGRAPH_R_CHECK_BOOL(scale); c_scale = LOGICAL(scale)[0]; - R_SEXP_to_igraph_arpack_options(options, &c_options); IGRAPH_R_CHECK_BOOL(normalized); c_normalized = LOGICAL(normalized)[0]; /* Call igraph */ - IGRAPH_R_CHECK(igraph_centralization_eigenvector_centrality(&c_graph, &c_vector, &c_value, c_directed, c_scale, &c_options, &c_centralization, &c_theoretical_max, c_normalized)); + IGRAPH_R_CHECK(igraph_centralization_eigenvector_centrality(&c_graph, &c_vector, &c_value, c_directed, c_scale, c_options, &c_centralization, &c_theoretical_max, c_normalized)); /* Convert output */ PROTECT(r_result=NEW_LIST(5)); @@ -4570,7 +4360,6 @@ SEXP R_igraph_centralization_eigenvector_centrality(SEXP graph, SEXP directed, S IGRAPH_FINALLY_CLEAN(1); PROTECT(value=NEW_NUMERIC(1)); REAL(value)[0]=c_value; - PROTECT(options=R_igraph_arpack_options_to_SEXP(&c_options)); PROTECT(centralization=NEW_NUMERIC(1)); REAL(centralization)[0]=c_centralization; PROTECT(theoretical_max=NEW_NUMERIC(1)); @@ -4740,7 +4529,6 @@ SEXP R_igraph_joint_degree_matrix(SEXP graph, SEXP weights, SEXP max_out_degree, SEXP r_result; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); - if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } if (0 != igraph_matrix_init(&c_jdm, 0, 0)) { igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); } @@ -4750,7 +4538,7 @@ SEXP R_igraph_joint_degree_matrix(SEXP graph, SEXP weights, SEXP max_out_degree, IGRAPH_R_CHECK_INT(max_in_degree); c_max_in_degree = (igraph_integer_t) REAL(max_in_degree)[0]; /* Call igraph */ - IGRAPH_R_CHECK(igraph_joint_degree_matrix(&c_graph, (Rf_isNull(weights) ? 0 : &c_weights), &c_jdm, c_max_out_degree, c_max_in_degree)); + IGRAPH_R_CHECK(igraph_joint_degree_matrix(&c_graph, c_weights, &c_jdm, c_max_out_degree, c_max_in_degree)); /* Convert output */ PROTECT(jdm=R_igraph_matrix_to_SEXP(&c_jdm)); @@ -4781,7 +4569,6 @@ SEXP R_igraph_joint_degree_distribution(SEXP graph, SEXP weights, SEXP from_mode SEXP r_result; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); - if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } if (0 != igraph_matrix_init(&c_p, 0, 0)) { igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); } @@ -4797,7 +4584,7 @@ SEXP R_igraph_joint_degree_distribution(SEXP graph, SEXP weights, SEXP from_mode IGRAPH_R_CHECK_INT(max_to_degree); c_max_to_degree = (igraph_integer_t) REAL(max_to_degree)[0]; /* Call igraph */ - IGRAPH_R_CHECK(igraph_joint_degree_distribution(&c_graph, (Rf_isNull(weights) ? 0 : &c_weights), &c_p, c_from_mode, c_to_mode, c_directed_neighbors, c_normalized, c_max_from_degree, c_max_to_degree)); + IGRAPH_R_CHECK(igraph_joint_degree_distribution(&c_graph, c_weights, &c_p, c_from_mode, c_to_mode, c_directed_neighbors, c_normalized, c_max_from_degree, c_max_to_degree)); /* Convert output */ PROTECT(p=R_igraph_matrix_to_SEXP(&c_p)); @@ -4826,7 +4613,6 @@ SEXP R_igraph_joint_type_distribution(SEXP graph, SEXP weights, SEXP from_types, SEXP r_result; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); - if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } if (0 != igraph_matrix_init(&c_p, 0, 0)) { igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); } @@ -4840,7 +4626,7 @@ SEXP R_igraph_joint_type_distribution(SEXP graph, SEXP weights, SEXP from_types, IGRAPH_R_CHECK_BOOL(normalized); c_normalized = LOGICAL(normalized)[0]; /* Call igraph */ - IGRAPH_R_CHECK(igraph_joint_type_distribution(&c_graph, (Rf_isNull(weights) ? 0 : &c_weights), &c_p, &c_from_types, &c_to_types, c_directed, c_normalized)); + IGRAPH_R_CHECK(igraph_joint_type_distribution(&c_graph, c_weights, &c_p, &c_from_types, &c_to_types, c_directed, c_normalized)); /* Convert output */ PROTECT(p=R_igraph_matrix_to_SEXP(&c_p)); @@ -4904,20 +4690,13 @@ SEXP R_igraph_eccentricity(SEXP graph, SEXP vids, SEXP mode) { SEXP r_result; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); - if (0 != igraph_vector_init(&c_res, 0)) { - igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); - } - IGRAPH_FINALLY(igraph_vector_destroy, &c_res); igraph_vector_int_t c_vids_data; R_SEXP_to_igraph_vs(vids, &c_graph, &c_vids, &c_vids_data); c_mode = (igraph_neimode_t) Rf_asInteger(mode); /* Call igraph */ - IGRAPH_R_CHECK(igraph_eccentricity(&c_graph, &c_res, c_vids, c_mode)); + IGRAPH_R_CHECK(igraph_eccentricity(&c_graph, c_res, c_vids, c_mode)); /* Convert output */ - PROTECT(res=R_igraph_vector_to_SEXP(&c_res)); - igraph_vector_destroy(&c_res); - IGRAPH_FINALLY_CLEAN(1); igraph_vector_int_destroy(&c_vids_data); igraph_vs_destroy(&c_vids); r_result = res; @@ -4941,21 +4720,13 @@ SEXP R_igraph_eccentricity_dijkstra(SEXP graph, SEXP weights, SEXP vids, SEXP mo SEXP r_result; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); - if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } - if (0 != igraph_vector_init(&c_res, 0)) { - igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); - } - IGRAPH_FINALLY(igraph_vector_destroy, &c_res); igraph_vector_int_t c_vids_data; R_SEXP_to_igraph_vs(vids, &c_graph, &c_vids, &c_vids_data); c_mode = (igraph_neimode_t) Rf_asInteger(mode); /* Call igraph */ - IGRAPH_R_CHECK(igraph_eccentricity_dijkstra(&c_graph, (Rf_isNull(weights) ? 0 : &c_weights), &c_res, c_vids, c_mode)); + IGRAPH_R_CHECK(igraph_eccentricity_dijkstra(&c_graph, c_weights, c_res, c_vids, c_mode)); /* Convert output */ - PROTECT(res=R_igraph_vector_to_SEXP(&c_res)); - igraph_vector_destroy(&c_res); - IGRAPH_FINALLY_CLEAN(1); igraph_vector_int_destroy(&c_vids_data); igraph_vs_destroy(&c_vids); r_result = res; @@ -5009,14 +4780,13 @@ SEXP R_igraph_graph_center_dijkstra(SEXP graph, SEXP weights, SEXP mode) { SEXP r_result; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); - if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } if (0 != igraph_vector_int_init(&c_res, 0)) { igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_vector_int_destroy, &c_res); c_mode = (igraph_neimode_t) Rf_asInteger(mode); /* Call igraph */ - IGRAPH_R_CHECK(igraph_graph_center_dijkstra(&c_graph, (Rf_isNull(weights) ? 0 : &c_weights), &c_res, c_mode)); + IGRAPH_R_CHECK(igraph_graph_center_dijkstra(&c_graph, c_weights, &c_res, c_mode)); /* Convert output */ PROTECT(res=R_igraph_vector_int_to_SEXPp1(&c_res)); @@ -5068,10 +4838,9 @@ SEXP R_igraph_radius_dijkstra(SEXP graph, SEXP weights, SEXP mode) { SEXP r_result; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); - if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } c_mode = (igraph_neimode_t) Rf_asInteger(mode); /* Call igraph */ - IGRAPH_R_CHECK(igraph_radius_dijkstra(&c_graph, (Rf_isNull(weights) ? 0 : &c_weights), &c_radius, c_mode)); + IGRAPH_R_CHECK(igraph_radius_dijkstra(&c_graph, c_weights, &c_radius, c_mode)); /* Convert output */ PROTECT(radius=NEW_NUMERIC(1)); @@ -5153,7 +4922,6 @@ SEXP R_igraph_pseudo_diameter_dijkstra(SEXP graph, SEXP weights, SEXP start_vid, SEXP r_result, r_names; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); - if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } c_start_vid = (igraph_integer_t) REAL(start_vid)[0]; c_from=0; c_to=0; @@ -5162,7 +4930,7 @@ SEXP R_igraph_pseudo_diameter_dijkstra(SEXP graph, SEXP weights, SEXP start_vid, IGRAPH_R_CHECK_BOOL(unconnected); c_unconnected = LOGICAL(unconnected)[0]; /* Call igraph */ - IGRAPH_R_CHECK(igraph_pseudo_diameter_dijkstra(&c_graph, (Rf_isNull(weights) ? 0 : &c_weights), &c_diameter, c_start_vid, &c_from, &c_to, c_directed, c_unconnected)); + IGRAPH_R_CHECK(igraph_pseudo_diameter_dijkstra(&c_graph, c_weights, &c_diameter, c_start_vid, &c_from, &c_to, c_directed, c_unconnected)); /* Convert output */ PROTECT(r_result=NEW_LIST(3)); @@ -5200,20 +4968,12 @@ SEXP R_igraph_diversity(SEXP graph, SEXP weights, SEXP vids) { SEXP r_result; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); - if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } - if (0 != igraph_vector_init(&c_res, 0)) { - igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); - } - IGRAPH_FINALLY(igraph_vector_destroy, &c_res); igraph_vector_int_t c_vids_data; R_SEXP_to_igraph_vs(vids, &c_graph, &c_vids, &c_vids_data); /* Call igraph */ - IGRAPH_R_CHECK(igraph_diversity(&c_graph, (Rf_isNull(weights) ? 0 : &c_weights), &c_res, c_vids)); + IGRAPH_R_CHECK(igraph_diversity(&c_graph, c_weights, c_res, c_vids)); /* Convert output */ - PROTECT(res=R_igraph_vector_to_SEXP(&c_res)); - igraph_vector_destroy(&c_res); - IGRAPH_FINALLY_CLEAN(1); igraph_vector_int_destroy(&c_vids_data); igraph_vs_destroy(&c_vids); r_result = res; @@ -5241,7 +5001,6 @@ SEXP R_igraph_random_walk(SEXP graph, SEXP weights, SEXP start, SEXP mode, SEXP SEXP r_result, r_names; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); - if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } if (0 != igraph_vector_int_init(&c_vertices, 0)) { igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); } @@ -5256,7 +5015,7 @@ SEXP R_igraph_random_walk(SEXP graph, SEXP weights, SEXP start, SEXP mode, SEXP c_steps = (igraph_integer_t) REAL(steps)[0]; c_stuck = (igraph_random_walk_stuck_t) Rf_asInteger(stuck); /* Call igraph */ - IGRAPH_R_CHECK(igraph_random_walk(&c_graph, (Rf_isNull(weights) ? 0 : &c_weights), &c_vertices, &c_edges, c_start, c_mode, c_steps, c_stuck)); + IGRAPH_R_CHECK(igraph_random_walk(&c_graph, c_weights, &c_vertices, &c_edges, c_start, c_mode, c_steps, c_stuck)); /* Convert output */ PROTECT(r_result=NEW_LIST(2)); @@ -5295,7 +5054,6 @@ SEXP R_igraph_random_edge_walk(SEXP graph, SEXP weights, SEXP start, SEXP mode, SEXP r_result; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); - if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } if (0 != igraph_vector_int_init(&c_edgewalk, 0)) { igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); } @@ -5306,7 +5064,7 @@ SEXP R_igraph_random_edge_walk(SEXP graph, SEXP weights, SEXP start, SEXP mode, c_steps = (igraph_integer_t) REAL(steps)[0]; c_stuck = (igraph_random_walk_stuck_t) Rf_asInteger(stuck); /* Call igraph */ - IGRAPH_R_CHECK(igraph_random_edge_walk(&c_graph, (Rf_isNull(weights) ? 0 : &c_weights), &c_edgewalk, c_start, c_mode, c_steps, c_stuck)); + IGRAPH_R_CHECK(igraph_random_edge_walk(&c_graph, c_weights, &c_edgewalk, c_start, c_mode, c_steps, c_stuck)); /* Convert output */ PROTECT(edgewalk=R_igraph_vector_int_to_SEXPp1(&c_edgewalk)); @@ -5332,11 +5090,10 @@ SEXP R_igraph_global_efficiency(SEXP graph, SEXP weights, SEXP directed) { SEXP r_result; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); - if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } IGRAPH_R_CHECK_BOOL(directed); c_directed = LOGICAL(directed)[0]; /* Call igraph */ - IGRAPH_R_CHECK(igraph_global_efficiency(&c_graph, &c_res, (Rf_isNull(weights) ? 0 : &c_weights), c_directed)); + IGRAPH_R_CHECK(igraph_global_efficiency(&c_graph, &c_res, c_weights, c_directed)); /* Convert output */ PROTECT(res=NEW_NUMERIC(1)); @@ -5363,23 +5120,15 @@ SEXP R_igraph_local_efficiency(SEXP graph, SEXP vids, SEXP weights, SEXP directe SEXP r_result; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); - if (0 != igraph_vector_init(&c_res, 0)) { - igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); - } - IGRAPH_FINALLY(igraph_vector_destroy, &c_res); igraph_vector_int_t c_vids_data; R_SEXP_to_igraph_vs(vids, &c_graph, &c_vids, &c_vids_data); - if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } IGRAPH_R_CHECK_BOOL(directed); c_directed = LOGICAL(directed)[0]; c_mode = (igraph_neimode_t) Rf_asInteger(mode); /* Call igraph */ - IGRAPH_R_CHECK(igraph_local_efficiency(&c_graph, &c_res, c_vids, (Rf_isNull(weights) ? 0 : &c_weights), c_directed, c_mode)); + IGRAPH_R_CHECK(igraph_local_efficiency(&c_graph, c_res, c_vids, c_weights, c_directed, c_mode)); /* Convert output */ - PROTECT(res=R_igraph_vector_to_SEXP(&c_res)); - igraph_vector_destroy(&c_res); - IGRAPH_FINALLY_CLEAN(1); igraph_vector_int_destroy(&c_vids_data); igraph_vs_destroy(&c_vids); r_result = res; @@ -5403,12 +5152,11 @@ SEXP R_igraph_average_local_efficiency(SEXP graph, SEXP weights, SEXP directed, SEXP r_result; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); - if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } IGRAPH_R_CHECK_BOOL(directed); c_directed = LOGICAL(directed)[0]; c_mode = (igraph_neimode_t) Rf_asInteger(mode); /* Call igraph */ - IGRAPH_R_CHECK(igraph_average_local_efficiency(&c_graph, &c_res, (Rf_isNull(weights) ? 0 : &c_weights), c_directed, c_mode)); + IGRAPH_R_CHECK(igraph_average_local_efficiency(&c_graph, &c_res, c_weights, c_directed, c_mode)); /* Convert output */ PROTECT(res=NEW_NUMERIC(1)); @@ -5865,7 +5613,7 @@ SEXP R_igraph_bipartite_game_gnp(SEXP n1, SEXP n2, SEXP p, SEXP directed, SEXP m /*-------------------------------------------/ / igraph_bipartite_game_gnm / /-------------------------------------------*/ -SEXP R_igraph_bipartite_game_gnm(SEXP n1, SEXP n2, SEXP m, SEXP directed, SEXP mode) { +SEXP R_igraph_bipartite_game_gnm(SEXP n1, SEXP n2, SEXP m, SEXP directed, SEXP mode, SEXP multiple) { /* Declarations */ igraph_t c_graph; igraph_vector_bool_t c_types; @@ -5874,6 +5622,7 @@ SEXP R_igraph_bipartite_game_gnm(SEXP n1, SEXP n2, SEXP m, SEXP directed, SEXP m igraph_integer_t c_m; igraph_bool_t c_directed; igraph_neimode_t c_mode; + igraph_bool_t c_multiple; SEXP graph; SEXP types; @@ -5892,8 +5641,10 @@ SEXP R_igraph_bipartite_game_gnm(SEXP n1, SEXP n2, SEXP m, SEXP directed, SEXP m IGRAPH_R_CHECK_BOOL(directed); c_directed = LOGICAL(directed)[0]; c_mode = (igraph_neimode_t) Rf_asInteger(mode); + IGRAPH_R_CHECK_BOOL(multiple); + c_multiple = LOGICAL(multiple)[0]; /* Call igraph */ - IGRAPH_R_CHECK(igraph_bipartite_game_gnm(&c_graph, &c_types, c_n1, c_n2, c_m, c_directed, c_mode)); + IGRAPH_R_CHECK(igraph_bipartite_game_gnm(&c_graph, &c_types, c_n1, c_n2, c_m, c_directed, c_mode, c_multiple)); /* Convert output */ PROTECT(r_result=NEW_LIST(2)); @@ -5996,9 +5747,8 @@ SEXP R_igraph_get_laplacian(SEXP graph, SEXP mode, SEXP normalization, SEXP weig IGRAPH_FINALLY(igraph_matrix_destroy, &c_res); c_mode = (igraph_neimode_t) Rf_asInteger(mode); c_normalization = (igraph_laplacian_normalization_t) Rf_asInteger(normalization); - if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } /* Call igraph */ - IGRAPH_R_CHECK(igraph_get_laplacian(&c_graph, &c_res, c_mode, c_normalization, (Rf_isNull(weights) ? 0 : &c_weights))); + IGRAPH_R_CHECK(igraph_get_laplacian(&c_graph, &c_res, c_mode, c_normalization, c_weights)); /* Convert output */ PROTECT(res=R_igraph_matrix_to_SEXP(&c_res)); @@ -6031,9 +5781,8 @@ SEXP R_igraph_get_laplacian_sparse(SEXP graph, SEXP mode, SEXP normalization, SE IGRAPH_FINALLY(igraph_sparsemat_destroy, &c_sparseres); c_mode = (igraph_neimode_t) Rf_asInteger(mode); c_normalization = (igraph_laplacian_normalization_t) Rf_asInteger(normalization); - if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } /* Call igraph */ - IGRAPH_R_CHECK(igraph_get_laplacian_sparse(&c_graph, &c_sparseres, c_mode, c_normalization, (Rf_isNull(weights) ? 0 : &c_weights))); + IGRAPH_R_CHECK(igraph_get_laplacian_sparse(&c_graph, &c_sparseres, c_mode, c_normalization, c_weights)); /* Convert output */ PROTECT(sparseres=R_igraph_sparsemat_to_SEXP(&c_sparseres)); @@ -6175,39 +5924,18 @@ SEXP R_igraph_biconnected_components(SEXP graph) { /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); c_no=0; - if (0 != igraph_vector_int_list_init(&c_tree_edges, 0)) { - igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); - } - IGRAPH_FINALLY(igraph_vector_int_list_destroy, &c_tree_edges); - if (0 != igraph_vector_int_list_init(&c_component_edges, 0)) { - igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); - } - IGRAPH_FINALLY(igraph_vector_int_list_destroy, &c_component_edges); - if (0 != igraph_vector_int_list_init(&c_components, 0)) { - igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); - } - IGRAPH_FINALLY(igraph_vector_int_list_destroy, &c_components); if (0 != igraph_vector_int_init(&c_articulation_points, 0)) { igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_vector_int_destroy, &c_articulation_points); /* Call igraph */ - IGRAPH_R_CHECK(igraph_biconnected_components(&c_graph, &c_no, &c_tree_edges, &c_component_edges, &c_components, &c_articulation_points)); + IGRAPH_R_CHECK(igraph_biconnected_components(&c_graph, &c_no, c_tree_edges, c_component_edges, c_components, &c_articulation_points)); /* Convert output */ PROTECT(r_result=NEW_LIST(5)); PROTECT(r_names=NEW_CHARACTER(5)); PROTECT(no=NEW_NUMERIC(1)); REAL(no)[0]=(double) c_no; - PROTECT(tree_edges=R_igraph_vector_int_list_to_SEXPp1(&c_tree_edges)); - igraph_vector_int_list_destroy(&c_tree_edges); - IGRAPH_FINALLY_CLEAN(1); - PROTECT(component_edges=R_igraph_vector_int_list_to_SEXPp1(&c_component_edges)); - igraph_vector_int_list_destroy(&c_component_edges); - IGRAPH_FINALLY_CLEAN(1); - PROTECT(components=R_igraph_vector_int_list_to_SEXPp1(&c_components)); - igraph_vector_int_list_destroy(&c_components); - IGRAPH_FINALLY_CLEAN(1); PROTECT(articulation_points=R_igraph_vector_int_to_SEXPp1(&c_articulation_points)); igraph_vector_int_destroy(&c_articulation_points); IGRAPH_FINALLY_CLEAN(1); @@ -6295,21 +6023,15 @@ SEXP R_igraph_cliques(SEXP graph, SEXP min_size, SEXP max_size) { SEXP r_result; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); - if (0 != igraph_vector_int_list_init(&c_res, 0)) { - igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); - } - IGRAPH_FINALLY(igraph_vector_int_list_destroy, &c_res); IGRAPH_R_CHECK_INT(min_size); c_min_size = (igraph_integer_t) REAL(min_size)[0]; IGRAPH_R_CHECK_INT(max_size); c_max_size = (igraph_integer_t) REAL(max_size)[0]; /* Call igraph */ - IGRAPH_R_CHECK(igraph_cliques(&c_graph, &c_res, c_min_size, c_max_size)); + IGRAPH_R_CHECK(igraph_cliques(&c_graph, c_res, c_min_size, c_max_size)); /* Convert output */ - PROTECT(res=R_igraph_vector_int_list_to_SEXPp1(&c_res)); - igraph_vector_int_list_destroy(&c_res); - IGRAPH_FINALLY_CLEAN(1); + r_result = res; UNPROTECT(1); @@ -6363,17 +6085,11 @@ SEXP R_igraph_largest_cliques(SEXP graph) { SEXP r_result; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); - if (0 != igraph_vector_int_list_init(&c_res, 0)) { - igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); - } - IGRAPH_FINALLY(igraph_vector_int_list_destroy, &c_res); /* Call igraph */ - IGRAPH_R_CHECK(igraph_largest_cliques(&c_graph, &c_res)); + IGRAPH_R_CHECK(igraph_largest_cliques(&c_graph, c_res)); /* Convert output */ - PROTECT(res=R_igraph_vector_int_list_to_SEXPp1(&c_res)); - igraph_vector_int_list_destroy(&c_res); - IGRAPH_FINALLY_CLEAN(1); + r_result = res; UNPROTECT(1); @@ -6456,11 +6172,6 @@ SEXP R_igraph_weighted_cliques(SEXP graph, SEXP vertex_weights, SEXP min_weight, SEXP r_result; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); - if (!Rf_isNull(vertex_weights)) { R_SEXP_to_vector(vertex_weights, &c_vertex_weights); } - if (0 != igraph_vector_int_list_init(&c_res, 0)) { - igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); - } - IGRAPH_FINALLY(igraph_vector_int_list_destroy, &c_res); IGRAPH_R_CHECK_REAL(min_weight); c_min_weight = REAL(min_weight)[0]; IGRAPH_R_CHECK_REAL(max_weight); @@ -6468,12 +6179,10 @@ SEXP R_igraph_weighted_cliques(SEXP graph, SEXP vertex_weights, SEXP min_weight, IGRAPH_R_CHECK_BOOL(maximal); c_maximal = LOGICAL(maximal)[0]; /* Call igraph */ - IGRAPH_R_CHECK(igraph_weighted_cliques(&c_graph, (Rf_isNull(vertex_weights) ? 0 : &c_vertex_weights), &c_res, c_min_weight, c_max_weight, c_maximal)); + IGRAPH_R_CHECK(igraph_weighted_cliques(&c_graph, c_vertex_weights, c_res, c_min_weight, c_max_weight, c_maximal)); /* Convert output */ - PROTECT(res=R_igraph_vector_int_list_to_SEXPp1(&c_res)); - igraph_vector_int_list_destroy(&c_res); - IGRAPH_FINALLY_CLEAN(1); + r_result = res; UNPROTECT(1); @@ -6493,18 +6202,11 @@ SEXP R_igraph_largest_weighted_cliques(SEXP graph, SEXP vertex_weights) { SEXP r_result; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); - if (!Rf_isNull(vertex_weights)) { R_SEXP_to_vector(vertex_weights, &c_vertex_weights); } - if (0 != igraph_vector_int_list_init(&c_res, 0)) { - igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); - } - IGRAPH_FINALLY(igraph_vector_int_list_destroy, &c_res); /* Call igraph */ - IGRAPH_R_CHECK(igraph_largest_weighted_cliques(&c_graph, (Rf_isNull(vertex_weights) ? 0 : &c_vertex_weights), &c_res)); + IGRAPH_R_CHECK(igraph_largest_weighted_cliques(&c_graph, c_vertex_weights, c_res)); /* Convert output */ - PROTECT(res=R_igraph_vector_int_list_to_SEXPp1(&c_res)); - igraph_vector_int_list_destroy(&c_res); - IGRAPH_FINALLY_CLEAN(1); + r_result = res; UNPROTECT(1); @@ -6524,9 +6226,8 @@ SEXP R_igraph_weighted_clique_number(SEXP graph, SEXP vertex_weights) { SEXP r_result; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); - if (!Rf_isNull(vertex_weights)) { R_SEXP_to_vector(vertex_weights, &c_vertex_weights); } /* Call igraph */ - IGRAPH_R_CHECK(igraph_weighted_clique_number(&c_graph, (Rf_isNull(vertex_weights) ? 0 : &c_vertex_weights), &c_res)); + IGRAPH_R_CHECK(igraph_weighted_clique_number(&c_graph, c_vertex_weights, &c_res)); /* Convert output */ PROTECT(res=NEW_NUMERIC(1)); @@ -6699,9 +6400,8 @@ SEXP R_igraph_layout_drl(SEXP graph, SEXP res, SEXP use_seed, SEXP options, SEXP IGRAPH_R_CHECK_BOOL(use_seed); c_use_seed = LOGICAL(use_seed)[0]; R_SEXP_to_igraph_layout_drl_options(options, &c_options); - if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } /* Call igraph */ - IGRAPH_R_CHECK(igraph_layout_drl(&c_graph, &c_res, c_use_seed, &c_options, (Rf_isNull(weights) ? 0 : (Rf_isNull(weights) ? 0 : &c_weights)))); + IGRAPH_R_CHECK(igraph_layout_drl(&c_graph, &c_res, c_use_seed, &c_options, (Rf_isNull(weights) ? 0 : c_weights))); /* Convert output */ PROTECT(res=R_igraph_matrix_to_SEXP(&c_res)); @@ -6734,9 +6434,8 @@ SEXP R_igraph_layout_drl_3d(SEXP graph, SEXP res, SEXP use_seed, SEXP options, S IGRAPH_R_CHECK_BOOL(use_seed); c_use_seed = LOGICAL(use_seed)[0]; R_SEXP_to_igraph_layout_drl_options(options, &c_options); - if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } /* Call igraph */ - IGRAPH_R_CHECK(igraph_layout_drl_3d(&c_graph, &c_res, c_use_seed, &c_options, (Rf_isNull(weights) ? 0 : (Rf_isNull(weights) ? 0 : &c_weights)))); + IGRAPH_R_CHECK(igraph_layout_drl_3d(&c_graph, &c_res, c_use_seed, &c_options, (Rf_isNull(weights) ? 0 : c_weights))); /* Convert output */ PROTECT(res=R_igraph_matrix_to_SEXP(&c_res)); @@ -6790,9 +6489,8 @@ SEXP R_igraph_layout_sugiyama(SEXP graph, SEXP layers, SEXP hgap, SEXP vgap, SEX c_vgap = REAL(vgap)[0]; IGRAPH_R_CHECK_INT(maxiter); c_maxiter = (igraph_integer_t) REAL(maxiter)[0]; - if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } /* Call igraph */ - IGRAPH_R_CHECK(igraph_layout_sugiyama(&c_graph, &c_res, &c_extd_graph, &c_extd_to_orig_eids, (Rf_isNull(layers) ? 0 : &c_layers), c_hgap, c_vgap, c_maxiter, (Rf_isNull(weights) ? 0 : &c_weights))); + IGRAPH_R_CHECK(igraph_layout_sugiyama(&c_graph, &c_res, &c_extd_graph, &c_extd_to_orig_eids, (Rf_isNull(layers) ? 0 : &c_layers), c_hgap, c_vgap, c_maxiter, c_weights)); /* Convert output */ PROTECT(r_result=NEW_LIST(3)); @@ -7117,11 +6815,12 @@ SEXP R_igraph_layout_umap_compute_weights(SEXP graph, SEXP distances, SEXP weigh /*-------------------------------------------/ / igraph_similarity_dice / /-------------------------------------------*/ -SEXP R_igraph_similarity_dice(SEXP graph, SEXP vids, SEXP mode, SEXP loops) { +SEXP R_igraph_similarity_dice(SEXP graph, SEXP vit_from, SEXP vit_to, SEXP mode, SEXP loops) { /* Declarations */ igraph_t c_graph; igraph_matrix_t c_res; - igraph_vs_t c_vids; + igraph_vs_t c_vit_from; + igraph_vs_t c_vit_to; igraph_neimode_t c_mode; igraph_bool_t c_loops; SEXP res; @@ -7133,20 +6832,24 @@ SEXP R_igraph_similarity_dice(SEXP graph, SEXP vids, SEXP mode, SEXP loops) { igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_matrix_destroy, &c_res); - igraph_vector_int_t c_vids_data; - R_SEXP_to_igraph_vs(vids, &c_graph, &c_vids, &c_vids_data); + igraph_vector_int_t c_vit_from_data; + R_SEXP_to_igraph_vs(vit_from, &c_graph, &c_vit_from, &c_vit_from_data); + igraph_vector_int_t c_vit_to_data; + R_SEXP_to_igraph_vs(vit_to, &c_graph, &c_vit_to, &c_vit_to_data); c_mode = (igraph_neimode_t) Rf_asInteger(mode); IGRAPH_R_CHECK_BOOL(loops); c_loops = LOGICAL(loops)[0]; /* Call igraph */ - IGRAPH_R_CHECK(igraph_similarity_dice(&c_graph, &c_res, c_vids, c_mode, c_loops)); + IGRAPH_R_CHECK(igraph_similarity_dice(&c_graph, &c_res, c_vit_from, c_vit_to, c_mode, c_loops)); /* Convert output */ PROTECT(res=R_igraph_matrix_to_SEXP(&c_res)); igraph_matrix_destroy(&c_res); IGRAPH_FINALLY_CLEAN(1); - igraph_vector_int_destroy(&c_vids_data); - igraph_vs_destroy(&c_vids); + igraph_vector_int_destroy(&c_vit_from_data); + igraph_vs_destroy(&c_vit_from); + igraph_vector_int_destroy(&c_vit_to_data); + igraph_vs_destroy(&c_vit_to); r_result = res; UNPROTECT(1); @@ -7270,11 +6973,12 @@ SEXP R_igraph_similarity_inverse_log_weighted(SEXP graph, SEXP vids, SEXP mode) /*-------------------------------------------/ / igraph_similarity_jaccard / /-------------------------------------------*/ -SEXP R_igraph_similarity_jaccard(SEXP graph, SEXP vids, SEXP mode, SEXP loops) { +SEXP R_igraph_similarity_jaccard(SEXP graph, SEXP vit_from, SEXP vit_to, SEXP mode, SEXP loops) { /* Declarations */ igraph_t c_graph; igraph_matrix_t c_res; - igraph_vs_t c_vids; + igraph_vs_t c_vit_from; + igraph_vs_t c_vit_to; igraph_neimode_t c_mode; igraph_bool_t c_loops; SEXP res; @@ -7286,20 +6990,24 @@ SEXP R_igraph_similarity_jaccard(SEXP graph, SEXP vids, SEXP mode, SEXP loops) { igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_matrix_destroy, &c_res); - igraph_vector_int_t c_vids_data; - R_SEXP_to_igraph_vs(vids, &c_graph, &c_vids, &c_vids_data); + igraph_vector_int_t c_vit_from_data; + R_SEXP_to_igraph_vs(vit_from, &c_graph, &c_vit_from, &c_vit_from_data); + igraph_vector_int_t c_vit_to_data; + R_SEXP_to_igraph_vs(vit_to, &c_graph, &c_vit_to, &c_vit_to_data); c_mode = (igraph_neimode_t) Rf_asInteger(mode); IGRAPH_R_CHECK_BOOL(loops); c_loops = LOGICAL(loops)[0]; /* Call igraph */ - IGRAPH_R_CHECK(igraph_similarity_jaccard(&c_graph, &c_res, c_vids, c_mode, c_loops)); + IGRAPH_R_CHECK(igraph_similarity_jaccard(&c_graph, &c_res, c_vit_from, c_vit_to, c_mode, c_loops)); /* Convert output */ PROTECT(res=R_igraph_matrix_to_SEXP(&c_res)); igraph_matrix_destroy(&c_res); IGRAPH_FINALLY_CLEAN(1); - igraph_vector_int_destroy(&c_vids_data); - igraph_vs_destroy(&c_vids); + igraph_vector_int_destroy(&c_vit_from_data); + igraph_vs_destroy(&c_vit_from); + igraph_vector_int_destroy(&c_vit_to_data); + igraph_vs_destroy(&c_vit_to); r_result = res; UNPROTECT(1); @@ -7436,13 +7144,12 @@ SEXP R_igraph_modularity(SEXP graph, SEXP membership, SEXP weights, SEXP resolut R_SEXP_to_igraph(graph, &c_graph); R_SEXP_to_vector_int_copy(membership, &c_membership); IGRAPH_FINALLY(igraph_vector_int_destroy, &c_membership); - if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } IGRAPH_R_CHECK_REAL(resolution); c_resolution = REAL(resolution)[0]; IGRAPH_R_CHECK_BOOL(directed); c_directed = LOGICAL(directed)[0]; /* Call igraph */ - IGRAPH_R_CHECK(igraph_modularity(&c_graph, &c_membership, (Rf_isNull(weights) ? 0 : (Rf_isNull(weights) ? 0 : &c_weights)), c_resolution, c_directed, &c_modularity)); + IGRAPH_R_CHECK(igraph_modularity(&c_graph, &c_membership, (Rf_isNull(weights) ? 0 : c_weights), c_resolution, c_directed, &c_modularity)); /* Convert output */ igraph_vector_int_destroy(&c_membership); @@ -7470,7 +7177,6 @@ SEXP R_igraph_modularity_matrix(SEXP graph, SEXP weights, SEXP resolution, SEXP SEXP r_result; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); - if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } IGRAPH_R_CHECK_REAL(resolution); c_resolution = REAL(resolution)[0]; if (0 != igraph_matrix_init(&c_modmat, 0, 0)) { @@ -7480,7 +7186,7 @@ SEXP R_igraph_modularity_matrix(SEXP graph, SEXP weights, SEXP resolution, SEXP IGRAPH_R_CHECK_BOOL(directed); c_directed = LOGICAL(directed)[0]; /* Call igraph */ - IGRAPH_R_CHECK(igraph_modularity_matrix(&c_graph, (Rf_isNull(weights) ? 0 : (Rf_isNull(weights) ? 0 : &c_weights)), c_resolution, &c_modmat, c_directed)); + IGRAPH_R_CHECK(igraph_modularity_matrix(&c_graph, (Rf_isNull(weights) ? 0 : c_weights), c_resolution, &c_modmat, c_directed)); /* Convert output */ PROTECT(modmat=R_igraph_matrix_to_SEXP(&c_modmat)); @@ -7545,7 +7251,6 @@ SEXP R_igraph_community_label_propagation(SEXP graph, SEXP mode, SEXP weights, S } IGRAPH_FINALLY(igraph_vector_int_destroy, &c_membership); c_mode = (igraph_neimode_t) Rf_asInteger(mode); - if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } if (!Rf_isNull(initial)) { R_SEXP_to_vector_int_copy(initial, &c_initial); IGRAPH_FINALLY(igraph_vector_int_destroy, &c_initial); @@ -7557,7 +7262,7 @@ SEXP R_igraph_community_label_propagation(SEXP graph, SEXP mode, SEXP weights, S R_SEXP_to_vector_bool(fixed, &c_fixed); } /* Call igraph */ - IGRAPH_R_CHECK(igraph_community_label_propagation(&c_graph, &c_membership, c_mode, (Rf_isNull(weights) ? 0 : (Rf_isNull(weights) ? 0 : &c_weights)), (Rf_isNull(initial) ? 0 : &c_initial), (Rf_isNull(fixed) ? 0 : &c_fixed))); + IGRAPH_R_CHECK(igraph_community_label_propagation(&c_graph, &c_membership, c_mode, (Rf_isNull(weights) ? 0 : c_weights), (Rf_isNull(initial) ? 0 : &c_initial), (Rf_isNull(fixed) ? 0 : &c_fixed))); /* Convert output */ PROTECT(membership=R_igraph_vector_int_to_SEXP(&c_membership)); @@ -7589,7 +7294,6 @@ SEXP R_igraph_community_multilevel(SEXP graph, SEXP weights, SEXP resolution) { SEXP r_result, r_names; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); - if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } IGRAPH_R_CHECK_REAL(resolution); c_resolution = REAL(resolution)[0]; if (0 != igraph_vector_int_init(&c_membership, 0)) { @@ -7605,7 +7309,7 @@ SEXP R_igraph_community_multilevel(SEXP graph, SEXP weights, SEXP resolution) { } IGRAPH_FINALLY(igraph_vector_destroy, &c_modularity); /* Call igraph */ - IGRAPH_R_CHECK(igraph_community_multilevel(&c_graph, (Rf_isNull(weights) ? 0 : (Rf_isNull(weights) ? 0 : &c_weights)), c_resolution, &c_membership, &c_memberships, &c_modularity)); + IGRAPH_R_CHECK(igraph_community_multilevel(&c_graph, (Rf_isNull(weights) ? 0 : c_weights), c_resolution, &c_membership, &c_memberships, &c_modularity)); /* Convert output */ PROTECT(r_result=NEW_LIST(3)); @@ -7651,9 +7355,8 @@ SEXP R_igraph_community_optimal_modularity(SEXP graph, SEXP weights) { igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_vector_int_destroy, &c_membership); - if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } /* Call igraph */ - IGRAPH_R_CHECK(igraph_community_optimal_modularity(&c_graph, &c_modularity, &c_membership, (Rf_isNull(weights) ? 0 : (Rf_isNull(weights) ? 0 : &c_weights)))); + IGRAPH_R_CHECK(igraph_community_optimal_modularity(&c_graph, &c_modularity, &c_membership, (Rf_isNull(weights) ? 0 : c_weights))); /* Convert output */ PROTECT(r_result=NEW_LIST(2)); @@ -7695,8 +7398,6 @@ SEXP R_igraph_community_leiden(SEXP graph, SEXP weights, SEXP vertex_weights, SE SEXP r_result, r_names; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); - if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } - if (!Rf_isNull(vertex_weights)) { R_SEXP_to_vector(vertex_weights, &c_vertex_weights); } IGRAPH_R_CHECK_REAL(resolution); c_resolution = REAL(resolution)[0]; IGRAPH_R_CHECK_REAL(beta); @@ -7714,7 +7415,7 @@ SEXP R_igraph_community_leiden(SEXP graph, SEXP weights, SEXP vertex_weights, SE } c_nb_clusters=0; /* Call igraph */ - IGRAPH_R_CHECK(igraph_community_leiden(&c_graph, (Rf_isNull(weights) ? 0 : (Rf_isNull(weights) ? 0 : &c_weights)), (Rf_isNull(vertex_weights) ? 0 : (Rf_isNull(vertex_weights) ? 0 : &c_vertex_weights)), c_resolution, c_beta, c_start, c_n_iterations, &c_membership, &c_nb_clusters, &c_quality)); + IGRAPH_R_CHECK(igraph_community_leiden(&c_graph, (Rf_isNull(weights) ? 0 : c_weights), (Rf_isNull(vertex_weights) ? 0 : c_vertex_weights), c_resolution, c_beta, c_start, c_n_iterations, &c_membership, &c_nb_clusters, &c_quality)); /* Convert output */ PROTECT(r_result=NEW_LIST(3)); @@ -7801,8 +7502,6 @@ SEXP R_igraph_community_infomap(SEXP graph, SEXP e_weights, SEXP v_weights, SEXP SEXP r_result, r_names; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); - if (!Rf_isNull(e_weights)) { R_SEXP_to_vector(e_weights, &c_e_weights); } - if (!Rf_isNull(v_weights)) { R_SEXP_to_vector(v_weights, &c_v_weights); } IGRAPH_R_CHECK_INT(nb_trials); c_nb_trials = (igraph_integer_t) REAL(nb_trials)[0]; if (0 != igraph_vector_int_init(&c_membership, 0)) { @@ -7810,7 +7509,7 @@ SEXP R_igraph_community_infomap(SEXP graph, SEXP e_weights, SEXP v_weights, SEXP } IGRAPH_FINALLY(igraph_vector_int_destroy, &c_membership); /* Call igraph */ - IGRAPH_R_CHECK(igraph_community_infomap(&c_graph, (Rf_isNull(e_weights) ? 0 : &c_e_weights), (Rf_isNull(v_weights) ? 0 : &c_v_weights), c_nb_trials, &c_membership, &c_codelength)); + IGRAPH_R_CHECK(igraph_community_infomap(&c_graph, c_e_weights, c_v_weights, c_nb_trials, &c_membership, &c_codelength)); /* Convert output */ PROTECT(r_result=NEW_LIST(2)); @@ -8242,10 +7941,9 @@ SEXP R_igraph_get_adjacency_sparse(SEXP graph, SEXP type, SEXP weights, SEXP loo } IGRAPH_FINALLY(igraph_sparsemat_destroy, &c_sparsemat); c_type = (igraph_get_adjacency_t) Rf_asInteger(type); - if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } c_loops = (igraph_loops_t) Rf_asInteger(loops); /* Call igraph */ - IGRAPH_R_CHECK(igraph_get_adjacency_sparse(&c_graph, &c_sparsemat, c_type, (Rf_isNull(weights) ? 0 : &c_weights), c_loops)); + IGRAPH_R_CHECK(igraph_get_adjacency_sparse(&c_graph, &c_sparsemat, c_type, c_weights, c_loops)); /* Convert output */ PROTECT(sparsemat=R_igraph_sparsemat_to_SEXP(&c_sparsemat)); @@ -8277,9 +7975,8 @@ SEXP R_igraph_get_stochastic(SEXP graph, SEXP column_wise, SEXP weights) { IGRAPH_FINALLY(igraph_matrix_destroy, &c_res); IGRAPH_R_CHECK_BOOL(column_wise); c_column_wise = LOGICAL(column_wise)[0]; - if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } /* Call igraph */ - IGRAPH_R_CHECK(igraph_get_stochastic(&c_graph, &c_res, c_column_wise, (Rf_isNull(weights) ? 0 : &c_weights))); + IGRAPH_R_CHECK(igraph_get_stochastic(&c_graph, &c_res, c_column_wise, c_weights)); /* Convert output */ PROTECT(res=R_igraph_matrix_to_SEXP(&c_res)); @@ -8311,9 +8008,8 @@ SEXP R_igraph_get_stochastic_sparse(SEXP graph, SEXP column_wise, SEXP weights) IGRAPH_FINALLY(igraph_sparsemat_destroy, &c_sparsemat); IGRAPH_R_CHECK_BOOL(column_wise); c_column_wise = LOGICAL(column_wise)[0]; - if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } /* Call igraph */ - IGRAPH_R_CHECK(igraph_get_stochastic_sparse(&c_graph, &c_sparsemat, c_column_wise, (Rf_isNull(weights) ? 0 : &c_weights))); + IGRAPH_R_CHECK(igraph_get_stochastic_sparse(&c_graph, &c_sparsemat, c_column_wise, c_weights)); /* Convert output */ PROTECT(sparsemat=R_igraph_sparsemat_to_SEXP(&c_sparsemat)); @@ -8504,10 +8200,9 @@ SEXP R_igraph_local_scan_0(SEXP graph, SEXP weights, SEXP mode) { igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_vector_destroy, &c_res); - if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } c_mode = (igraph_neimode_t) Rf_asInteger(mode); /* Call igraph */ - IGRAPH_R_CHECK(igraph_local_scan_0(&c_graph, &c_res, (Rf_isNull(weights) ? 0 : &c_weights), c_mode)); + IGRAPH_R_CHECK(igraph_local_scan_0(&c_graph, &c_res, c_weights, c_mode)); /* Convert output */ PROTECT(res=R_igraph_vector_to_SEXP(&c_res)); @@ -8539,10 +8234,9 @@ SEXP R_igraph_local_scan_0_them(SEXP us, SEXP them, SEXP weights_them, SEXP mode igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_vector_destroy, &c_res); - if (!Rf_isNull(weights_them)) { R_SEXP_to_vector(weights_them, &c_weights_them); } c_mode = (igraph_neimode_t) Rf_asInteger(mode); /* Call igraph */ - IGRAPH_R_CHECK(igraph_local_scan_0_them(&c_us, &c_them, &c_res, (Rf_isNull(weights_them) ? 0 : &c_weights_them), c_mode)); + IGRAPH_R_CHECK(igraph_local_scan_0_them(&c_us, &c_them, &c_res, c_weights_them, c_mode)); /* Convert output */ PROTECT(res=R_igraph_vector_to_SEXP(&c_res)); @@ -8572,10 +8266,9 @@ SEXP R_igraph_local_scan_1_ecount(SEXP graph, SEXP weights, SEXP mode) { igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_vector_destroy, &c_res); - if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } c_mode = (igraph_neimode_t) Rf_asInteger(mode); /* Call igraph */ - IGRAPH_R_CHECK(igraph_local_scan_1_ecount(&c_graph, &c_res, (Rf_isNull(weights) ? 0 : &c_weights), c_mode)); + IGRAPH_R_CHECK(igraph_local_scan_1_ecount(&c_graph, &c_res, c_weights, c_mode)); /* Convert output */ PROTECT(res=R_igraph_vector_to_SEXP(&c_res)); @@ -8607,10 +8300,9 @@ SEXP R_igraph_local_scan_1_ecount_them(SEXP us, SEXP them, SEXP weights_them, SE igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_vector_destroy, &c_res); - if (!Rf_isNull(weights_them)) { R_SEXP_to_vector(weights_them, &c_weights_them); } c_mode = (igraph_neimode_t) Rf_asInteger(mode); /* Call igraph */ - IGRAPH_R_CHECK(igraph_local_scan_1_ecount_them(&c_us, &c_them, &c_res, (Rf_isNull(weights_them) ? 0 : &c_weights_them), c_mode)); + IGRAPH_R_CHECK(igraph_local_scan_1_ecount_them(&c_us, &c_them, &c_res, c_weights_them, c_mode)); /* Convert output */ PROTECT(res=R_igraph_vector_to_SEXP(&c_res)); @@ -8643,10 +8335,9 @@ SEXP R_igraph_local_scan_k_ecount(SEXP graph, SEXP k, SEXP weights, SEXP mode) { igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_vector_destroy, &c_res); - if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } c_mode = (igraph_neimode_t) Rf_asInteger(mode); /* Call igraph */ - IGRAPH_R_CHECK(igraph_local_scan_k_ecount(&c_graph, c_k, &c_res, (Rf_isNull(weights) ? 0 : &c_weights), c_mode)); + IGRAPH_R_CHECK(igraph_local_scan_k_ecount(&c_graph, c_k, &c_res, c_weights, c_mode)); /* Convert output */ PROTECT(res=R_igraph_vector_to_SEXP(&c_res)); @@ -8681,10 +8372,9 @@ SEXP R_igraph_local_scan_k_ecount_them(SEXP us, SEXP them, SEXP k, SEXP weights_ igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_vector_destroy, &c_res); - if (!Rf_isNull(weights_them)) { R_SEXP_to_vector(weights_them, &c_weights_them); } c_mode = (igraph_neimode_t) Rf_asInteger(mode); /* Call igraph */ - IGRAPH_R_CHECK(igraph_local_scan_k_ecount_them(&c_us, &c_them, c_k, &c_res, (Rf_isNull(weights_them) ? 0 : &c_weights_them), c_mode)); + IGRAPH_R_CHECK(igraph_local_scan_k_ecount_them(&c_us, &c_them, c_k, &c_res, c_weights_them, c_mode)); /* Convert output */ PROTECT(res=R_igraph_vector_to_SEXP(&c_res)); @@ -8714,18 +8404,13 @@ SEXP R_igraph_local_scan_neighborhood_ecount(SEXP graph, SEXP weights, SEXP neig igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_vector_destroy, &c_res); - if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } - R_igraph_SEXP_to_vector_int_list(neighborhoods, &c_neighborhoods); - IGRAPH_FINALLY(igraph_vector_int_list_destroy, &c_neighborhoods); /* Call igraph */ - IGRAPH_R_CHECK(igraph_local_scan_neighborhood_ecount(&c_graph, &c_res, (Rf_isNull(weights) ? 0 : &c_weights), &c_neighborhoods)); + IGRAPH_R_CHECK(igraph_local_scan_neighborhood_ecount(&c_graph, &c_res, c_weights, c_neighborhoods)); /* Convert output */ PROTECT(res=R_igraph_vector_to_SEXP(&c_res)); igraph_vector_destroy(&c_res); IGRAPH_FINALLY_CLEAN(1); - igraph_vector_int_list_destroy(&c_neighborhoods); - IGRAPH_FINALLY_CLEAN(1); r_result = res; UNPROTECT(1); @@ -8750,18 +8435,13 @@ SEXP R_igraph_local_scan_subset_ecount(SEXP graph, SEXP weights, SEXP subsets) { igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_vector_destroy, &c_res); - if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } - R_igraph_SEXP_to_vector_int_list(subsets, &c_subsets); - IGRAPH_FINALLY(igraph_vector_int_list_destroy, &c_subsets); /* Call igraph */ - IGRAPH_R_CHECK(igraph_local_scan_subset_ecount(&c_graph, &c_res, (Rf_isNull(weights) ? 0 : &c_weights), &c_subsets)); + IGRAPH_R_CHECK(igraph_local_scan_subset_ecount(&c_graph, &c_res, c_weights, c_subsets)); /* Convert output */ PROTECT(res=R_igraph_vector_to_SEXP(&c_res)); igraph_vector_destroy(&c_res); IGRAPH_FINALLY_CLEAN(1); - igraph_vector_int_list_destroy(&c_subsets); - IGRAPH_FINALLY_CLEAN(1); r_result = res; UNPROTECT(1); @@ -8904,9 +8584,8 @@ SEXP R_igraph_gomory_hu_tree(SEXP graph, SEXP capacity) { igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_vector_destroy, &c_flows); - if (!Rf_isNull(capacity)) { R_SEXP_to_vector(capacity, &c_capacity); } /* Call igraph */ - IGRAPH_R_CHECK(igraph_gomory_hu_tree(&c_graph, &c_tree, &c_flows, (Rf_isNull(capacity) ? 0 : (Rf_isNull(capacity) ? 0 : &c_capacity)))); + IGRAPH_R_CHECK(igraph_gomory_hu_tree(&c_graph, &c_tree, &c_flows, (Rf_isNull(capacity) ? 0 : c_capacity))); /* Convert output */ PROTECT(r_result=NEW_LIST(2)); @@ -8972,9 +8651,8 @@ SEXP R_igraph_maxflow(SEXP graph, SEXP source, SEXP target, SEXP capacity) { IGRAPH_FINALLY(igraph_vector_int_destroy, &c_partition2); c_source = (igraph_integer_t) REAL(source)[0]; c_target = (igraph_integer_t) REAL(target)[0]; - if (!Rf_isNull(capacity)) { R_SEXP_to_vector(capacity, &c_capacity); } /* Call igraph */ - IGRAPH_R_CHECK(igraph_maxflow(&c_graph, &c_value, &c_flow, &c_cut, &c_partition1, &c_partition2, c_source, c_target, (Rf_isNull(capacity) ? 0 : (Rf_isNull(capacity) ? 0 : &c_capacity)), &c_stats)); + IGRAPH_R_CHECK(igraph_maxflow(&c_graph, &c_value, &c_flow, &c_cut, &c_partition1, &c_partition2, c_source, c_target, (Rf_isNull(capacity) ? 0 : c_capacity), &c_stats)); /* Convert output */ PROTECT(r_result=NEW_LIST(6)); @@ -9029,15 +8707,9 @@ SEXP R_igraph_residual_graph(SEXP graph, SEXP capacity, SEXP flow) { SEXP r_result, r_names; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); - if (!Rf_isNull(capacity)) { R_SEXP_to_vector(capacity, &c_capacity); } - if (0 != igraph_vector_init(&c_residual_capacity, 0)) { - igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); - } - IGRAPH_FINALLY(igraph_vector_destroy, &c_residual_capacity); - residual_capacity=R_GlobalEnv; /* hack to have a non-NULL value */ R_SEXP_to_vector(flow, &c_flow); /* Call igraph */ - IGRAPH_R_CHECK(igraph_residual_graph(&c_graph, (Rf_isNull(capacity) ? 0 : &c_capacity), &c_residual, (Rf_isNull(residual_capacity) ? 0 : &c_residual_capacity), &c_flow)); + IGRAPH_R_CHECK(igraph_residual_graph(&c_graph, c_capacity, &c_residual, c_residual_capacity, &c_flow)); /* Convert output */ PROTECT(r_result=NEW_LIST(2)); @@ -9046,9 +8718,6 @@ SEXP R_igraph_residual_graph(SEXP graph, SEXP capacity, SEXP flow) { PROTECT(residual=R_igraph_to_SEXP(&c_residual)); IGRAPH_I_DESTROY(&c_residual); IGRAPH_FINALLY_CLEAN(1); - PROTECT(residual_capacity=R_igraph_0orvector_to_SEXP(&c_residual_capacity)); - igraph_vector_destroy(&c_residual_capacity); - IGRAPH_FINALLY_CLEAN(1); SET_VECTOR_ELT(r_result, 0, residual); SET_VECTOR_ELT(r_result, 1, residual_capacity); SET_STRING_ELT(r_names, 0, Rf_mkChar("residual")); @@ -9074,10 +8743,9 @@ SEXP R_igraph_reverse_residual_graph(SEXP graph, SEXP capacity, SEXP flow) { SEXP r_result; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); - if (!Rf_isNull(capacity)) { R_SEXP_to_vector(capacity, &c_capacity); } R_SEXP_to_vector(flow, &c_flow); /* Call igraph */ - IGRAPH_R_CHECK(igraph_reverse_residual_graph(&c_graph, (Rf_isNull(capacity) ? 0 : &c_capacity), &c_residual, &c_flow)); + IGRAPH_R_CHECK(igraph_reverse_residual_graph(&c_graph, c_capacity, &c_residual, &c_flow)); /* Convert output */ IGRAPH_FINALLY(igraph_destroy, &c_residual); @@ -9125,9 +8793,8 @@ SEXP R_igraph_st_mincut(SEXP graph, SEXP source, SEXP target, SEXP capacity) { IGRAPH_FINALLY(igraph_vector_int_destroy, &c_partition2); c_source = (igraph_integer_t) REAL(source)[0]; c_target = (igraph_integer_t) REAL(target)[0]; - if (!Rf_isNull(capacity)) { R_SEXP_to_vector(capacity, &c_capacity); } /* Call igraph */ - IGRAPH_R_CHECK(igraph_st_mincut(&c_graph, &c_value, &c_cut, &c_partition1, &c_partition2, c_source, c_target, (Rf_isNull(capacity) ? 0 : (Rf_isNull(capacity) ? 0 : &c_capacity)))); + IGRAPH_R_CHECK(igraph_st_mincut(&c_graph, &c_value, &c_cut, &c_partition1, &c_partition2, c_source, c_target, (Rf_isNull(capacity) ? 0 : c_capacity))); /* Convert output */ PROTECT(r_result=NEW_LIST(4)); @@ -9231,28 +8898,14 @@ SEXP R_igraph_all_st_cuts(SEXP graph, SEXP source, SEXP target) { SEXP r_result, r_names; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); - if (0 != igraph_vector_int_list_init(&c_cuts, 0)) { - igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); - } - IGRAPH_FINALLY(igraph_vector_int_list_destroy, &c_cuts); - if (0 != igraph_vector_int_list_init(&c_partition1s, 0)) { - igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); - } - IGRAPH_FINALLY(igraph_vector_int_list_destroy, &c_partition1s); c_source = (igraph_integer_t) REAL(source)[0]; c_target = (igraph_integer_t) REAL(target)[0]; /* Call igraph */ - IGRAPH_R_CHECK(igraph_all_st_cuts(&c_graph, &c_cuts, &c_partition1s, c_source, c_target)); + IGRAPH_R_CHECK(igraph_all_st_cuts(&c_graph, c_cuts, c_partition1s, c_source, c_target)); /* Convert output */ PROTECT(r_result=NEW_LIST(2)); PROTECT(r_names=NEW_CHARACTER(2)); - PROTECT(cuts=R_igraph_vector_int_list_to_SEXPp1(&c_cuts)); - igraph_vector_int_list_destroy(&c_cuts); - IGRAPH_FINALLY_CLEAN(1); - PROTECT(partition1s=R_igraph_vector_int_list_to_SEXPp1(&c_partition1s)); - igraph_vector_int_list_destroy(&c_partition1s); - IGRAPH_FINALLY_CLEAN(1); SET_VECTOR_ELT(r_result, 0, cuts); SET_VECTOR_ELT(r_result, 1, partition1s); SET_STRING_ELT(r_names, 0, Rf_mkChar("cuts")); @@ -9283,31 +8936,16 @@ SEXP R_igraph_all_st_mincuts(SEXP graph, SEXP source, SEXP target, SEXP capacity SEXP r_result, r_names; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); - if (0 != igraph_vector_int_list_init(&c_cuts, 0)) { - igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); - } - IGRAPH_FINALLY(igraph_vector_int_list_destroy, &c_cuts); - if (0 != igraph_vector_int_list_init(&c_partition1s, 0)) { - igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); - } - IGRAPH_FINALLY(igraph_vector_int_list_destroy, &c_partition1s); c_source = (igraph_integer_t) REAL(source)[0]; c_target = (igraph_integer_t) REAL(target)[0]; - if (!Rf_isNull(capacity)) { R_SEXP_to_vector(capacity, &c_capacity); } /* Call igraph */ - IGRAPH_R_CHECK(igraph_all_st_mincuts(&c_graph, &c_value, &c_cuts, &c_partition1s, c_source, c_target, (Rf_isNull(capacity) ? 0 : (Rf_isNull(capacity) ? 0 : &c_capacity)))); + IGRAPH_R_CHECK(igraph_all_st_mincuts(&c_graph, &c_value, c_cuts, c_partition1s, c_source, c_target, (Rf_isNull(capacity) ? 0 : c_capacity))); /* Convert output */ PROTECT(r_result=NEW_LIST(3)); PROTECT(r_names=NEW_CHARACTER(3)); PROTECT(value=NEW_NUMERIC(1)); REAL(value)[0]=c_value; - PROTECT(cuts=R_igraph_vector_int_list_to_SEXPp1(&c_cuts)); - igraph_vector_int_list_destroy(&c_cuts); - IGRAPH_FINALLY_CLEAN(1); - PROTECT(partition1s=R_igraph_vector_int_list_to_SEXPp1(&c_partition1s)); - igraph_vector_int_list_destroy(&c_partition1s); - IGRAPH_FINALLY_CLEAN(1); SET_VECTOR_ELT(r_result, 0, value); SET_VECTOR_ELT(r_result, 1, cuts); SET_VECTOR_ELT(r_result, 2, partition1s); @@ -9335,13 +8973,8 @@ SEXP R_igraph_even_tarjan_reduction(SEXP graph) { SEXP r_result, r_names; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); - if (0 != igraph_vector_init(&c_capacity, 0)) { - igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); - } - IGRAPH_FINALLY(igraph_vector_destroy, &c_capacity); - capacity=R_GlobalEnv; /* hack to have a non-NULL value */ /* Call igraph */ - IGRAPH_R_CHECK(igraph_even_tarjan_reduction(&c_graph, &c_graphbar, (Rf_isNull(capacity) ? 0 : &c_capacity))); + IGRAPH_R_CHECK(igraph_even_tarjan_reduction(&c_graph, &c_graphbar, c_capacity)); /* Convert output */ PROTECT(r_result=NEW_LIST(2)); @@ -9350,9 +8983,6 @@ SEXP R_igraph_even_tarjan_reduction(SEXP graph) { PROTECT(graphbar=R_igraph_to_SEXP(&c_graphbar)); IGRAPH_I_DESTROY(&c_graphbar); IGRAPH_FINALLY_CLEAN(1); - PROTECT(capacity=R_igraph_0orvector_to_SEXP(&c_capacity)); - igraph_vector_destroy(&c_capacity); - IGRAPH_FINALLY_CLEAN(1); SET_VECTOR_ELT(r_result, 0, graphbar); SET_VECTOR_ELT(r_result, 1, capacity); SET_STRING_ELT(r_names, 0, Rf_mkChar("graphbar")); @@ -9434,17 +9064,11 @@ SEXP R_igraph_all_minimal_st_separators(SEXP graph) { SEXP r_result; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); - if (0 != igraph_vector_int_list_init(&c_separators, 0)) { - igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); - } - IGRAPH_FINALLY(igraph_vector_int_list_destroy, &c_separators); /* Call igraph */ - IGRAPH_R_CHECK(igraph_all_minimal_st_separators(&c_graph, &c_separators)); + IGRAPH_R_CHECK(igraph_all_minimal_st_separators(&c_graph, c_separators)); /* Convert output */ - PROTECT(separators=R_igraph_vector_int_list_to_SEXPp1(&c_separators)); - igraph_vector_int_list_destroy(&c_separators); - IGRAPH_FINALLY_CLEAN(1); + r_result = separators; UNPROTECT(1); @@ -9463,17 +9087,11 @@ SEXP R_igraph_minimum_size_separators(SEXP graph) { SEXP r_result; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); - if (0 != igraph_vector_int_list_init(&c_separators, 0)) { - igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); - } - IGRAPH_FINALLY(igraph_vector_int_list_destroy, &c_separators); /* Call igraph */ - IGRAPH_R_CHECK(igraph_minimum_size_separators(&c_graph, &c_separators)); + IGRAPH_R_CHECK(igraph_minimum_size_separators(&c_graph, c_separators)); /* Convert output */ - PROTECT(separators=R_igraph_vector_int_list_to_SEXPp1(&c_separators)); - igraph_vector_int_list_destroy(&c_separators); - IGRAPH_FINALLY_CLEAN(1); + r_result = separators; UNPROTECT(1); @@ -9531,6 +9149,55 @@ SEXP R_igraph_isomorphic(SEXP graph1, SEXP graph2) { return(r_result); } +/*-------------------------------------------/ +/ igraph_automorphism_group / +/-------------------------------------------*/ +SEXP R_igraph_automorphism_group(SEXP graph, SEXP colors) { + /* Declarations */ + igraph_t c_graph; + igraph_vector_int_t c_colors; + igraph_vector_int_list_t c_generators; + SEXP generators; + + SEXP r_result; + /* Convert input */ + R_SEXP_to_igraph(graph, &c_graph); + /* Call igraph */ + IGRAPH_R_CHECK(igraph_automorphism_group(&c_graph, (Rf_isNull(colors) ? 0 : c_colors), c_generators)); + + /* Convert output */ + + r_result = generators; + + UNPROTECT(1); + return(r_result); +} + +/*-------------------------------------------/ +/ igraph_count_automorphisms / +/-------------------------------------------*/ +SEXP R_igraph_count_automorphisms(SEXP graph, SEXP colors) { + /* Declarations */ + igraph_t c_graph; + igraph_vector_int_t c_colors; + igraph_real_t c_result; + SEXP result; + + SEXP r_result; + /* Convert input */ + R_SEXP_to_igraph(graph, &c_graph); + /* Call igraph */ + IGRAPH_R_CHECK(igraph_count_automorphisms(&c_graph, (Rf_isNull(colors) ? 0 : c_colors), &c_result)); + + /* Convert output */ + PROTECT(result=NEW_NUMERIC(1)); + REAL(result)[0]=c_result; + r_result = result; + + UNPROTECT(1); + return(r_result); +} + /*-------------------------------------------/ / igraph_isoclass_subgraph / /-------------------------------------------*/ @@ -9619,30 +9286,6 @@ SEXP R_igraph_isomorphic_vf2(SEXP graph1, SEXP graph2, SEXP vertex_color1, SEXP /* Convert input */ R_SEXP_to_igraph(graph1, &c_graph1); R_SEXP_to_igraph(graph2, &c_graph2); - if (!Rf_isNull(vertex_color1)) { - R_SEXP_to_vector_int_copy(vertex_color1, &c_vertex_color1); - } else { - IGRAPH_R_CHECK(igraph_vector_int_init(&c_vertex_color1, 0)); - } - IGRAPH_FINALLY(igraph_vector_int_destroy, &c_vertex_color1); - if (!Rf_isNull(vertex_color2)) { - R_SEXP_to_vector_int_copy(vertex_color2, &c_vertex_color2); - } else { - IGRAPH_R_CHECK(igraph_vector_int_init(&c_vertex_color2, 0)); - } - IGRAPH_FINALLY(igraph_vector_int_destroy, &c_vertex_color2); - if (!Rf_isNull(edge_color1)) { - R_SEXP_to_vector_int_copy(edge_color1, &c_edge_color1); - } else { - IGRAPH_R_CHECK(igraph_vector_int_init(&c_edge_color1, 0)); - } - IGRAPH_FINALLY(igraph_vector_int_destroy, &c_edge_color1); - if (!Rf_isNull(edge_color2)) { - R_SEXP_to_vector_int_copy(edge_color2, &c_edge_color2); - } else { - IGRAPH_R_CHECK(igraph_vector_int_init(&c_edge_color2, 0)); - } - IGRAPH_FINALLY(igraph_vector_int_destroy, &c_edge_color2); if (0 != igraph_vector_int_init(&c_map12, 0)) { igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); } @@ -9652,19 +9295,11 @@ SEXP R_igraph_isomorphic_vf2(SEXP graph1, SEXP graph2, SEXP vertex_color1, SEXP } IGRAPH_FINALLY(igraph_vector_int_destroy, &c_map21); /* Call igraph */ - IGRAPH_R_CHECK(igraph_isomorphic_vf2(&c_graph1, &c_graph2, (Rf_isNull(vertex_color1) ? 0 : (Rf_isNull(vertex_color1) ? 0 : &c_vertex_color1)), (Rf_isNull(vertex_color2) ? 0 : (Rf_isNull(vertex_color2) ? 0 : &c_vertex_color2)), (Rf_isNull(edge_color1) ? 0 : (Rf_isNull(edge_color1) ? 0 : &c_edge_color1)), (Rf_isNull(edge_color2) ? 0 : (Rf_isNull(edge_color2) ? 0 : &c_edge_color2)), &c_iso, &c_map12, &c_map21, 0, 0, 0)); + IGRAPH_R_CHECK(igraph_isomorphic_vf2(&c_graph1, &c_graph2, (Rf_isNull(vertex_color1) ? 0 : c_vertex_color1), (Rf_isNull(vertex_color2) ? 0 : c_vertex_color2), (Rf_isNull(edge_color1) ? 0 : c_edge_color1), (Rf_isNull(edge_color2) ? 0 : c_edge_color2), &c_iso, &c_map12, &c_map21, 0, 0, 0)); /* Convert output */ PROTECT(r_result=NEW_LIST(3)); PROTECT(r_names=NEW_CHARACTER(3)); - igraph_vector_int_destroy(&c_vertex_color1); - IGRAPH_FINALLY_CLEAN(1); - igraph_vector_int_destroy(&c_vertex_color2); - IGRAPH_FINALLY_CLEAN(1); - igraph_vector_int_destroy(&c_edge_color1); - IGRAPH_FINALLY_CLEAN(1); - igraph_vector_int_destroy(&c_edge_color2); - IGRAPH_FINALLY_CLEAN(1); PROTECT(iso=NEW_LOGICAL(1)); LOGICAL(iso)[0]=c_iso; PROTECT(map12=R_igraph_vector_int_to_SEXPp1(&c_map12)); @@ -9707,43 +9342,11 @@ SEXP R_igraph_count_isomorphisms_vf2(SEXP graph1, SEXP graph2, SEXP vertex_color /* Convert input */ R_SEXP_to_igraph(graph1, &c_graph1); R_SEXP_to_igraph(graph2, &c_graph2); - if (!Rf_isNull(vertex_color1)) { - R_SEXP_to_vector_int_copy(vertex_color1, &c_vertex_color1); - } else { - IGRAPH_R_CHECK(igraph_vector_int_init(&c_vertex_color1, 0)); - } - IGRAPH_FINALLY(igraph_vector_int_destroy, &c_vertex_color1); - if (!Rf_isNull(vertex_color2)) { - R_SEXP_to_vector_int_copy(vertex_color2, &c_vertex_color2); - } else { - IGRAPH_R_CHECK(igraph_vector_int_init(&c_vertex_color2, 0)); - } - IGRAPH_FINALLY(igraph_vector_int_destroy, &c_vertex_color2); - if (!Rf_isNull(edge_color1)) { - R_SEXP_to_vector_int_copy(edge_color1, &c_edge_color1); - } else { - IGRAPH_R_CHECK(igraph_vector_int_init(&c_edge_color1, 0)); - } - IGRAPH_FINALLY(igraph_vector_int_destroy, &c_edge_color1); - if (!Rf_isNull(edge_color2)) { - R_SEXP_to_vector_int_copy(edge_color2, &c_edge_color2); - } else { - IGRAPH_R_CHECK(igraph_vector_int_init(&c_edge_color2, 0)); - } - IGRAPH_FINALLY(igraph_vector_int_destroy, &c_edge_color2); c_count=0; /* Call igraph */ - IGRAPH_R_CHECK(igraph_count_isomorphisms_vf2(&c_graph1, &c_graph2, (Rf_isNull(vertex_color1) ? 0 : &c_vertex_color1), (Rf_isNull(vertex_color2) ? 0 : &c_vertex_color2), (Rf_isNull(edge_color1) ? 0 : &c_edge_color1), (Rf_isNull(edge_color2) ? 0 : &c_edge_color2), &c_count, 0, 0, 0)); + IGRAPH_R_CHECK(igraph_count_isomorphisms_vf2(&c_graph1, &c_graph2, c_vertex_color1, c_vertex_color2, c_edge_color1, c_edge_color2, &c_count, 0, 0, 0)); /* Convert output */ - igraph_vector_int_destroy(&c_vertex_color1); - IGRAPH_FINALLY_CLEAN(1); - igraph_vector_int_destroy(&c_vertex_color2); - IGRAPH_FINALLY_CLEAN(1); - igraph_vector_int_destroy(&c_edge_color1); - IGRAPH_FINALLY_CLEAN(1); - igraph_vector_int_destroy(&c_edge_color2); - IGRAPH_FINALLY_CLEAN(1); PROTECT(count=NEW_NUMERIC(1)); REAL(count)[0]=(double) c_count; r_result = count; @@ -9773,46 +9376,14 @@ SEXP R_igraph_get_isomorphisms_vf2(SEXP graph1, SEXP graph2, SEXP vertex_color1, /* Convert input */ R_SEXP_to_igraph(graph1, &c_graph1); R_SEXP_to_igraph(graph2, &c_graph2); - if (!Rf_isNull(vertex_color1)) { - R_SEXP_to_vector_int_copy(vertex_color1, &c_vertex_color1); - } else { - IGRAPH_R_CHECK(igraph_vector_int_init(&c_vertex_color1, 0)); - } - IGRAPH_FINALLY(igraph_vector_int_destroy, &c_vertex_color1); - if (!Rf_isNull(vertex_color2)) { - R_SEXP_to_vector_int_copy(vertex_color2, &c_vertex_color2); - } else { - IGRAPH_R_CHECK(igraph_vector_int_init(&c_vertex_color2, 0)); - } - IGRAPH_FINALLY(igraph_vector_int_destroy, &c_vertex_color2); - if (!Rf_isNull(edge_color1)) { - R_SEXP_to_vector_int_copy(edge_color1, &c_edge_color1); - } else { - IGRAPH_R_CHECK(igraph_vector_int_init(&c_edge_color1, 0)); - } - IGRAPH_FINALLY(igraph_vector_int_destroy, &c_edge_color1); - if (!Rf_isNull(edge_color2)) { - R_SEXP_to_vector_int_copy(edge_color2, &c_edge_color2); - } else { - IGRAPH_R_CHECK(igraph_vector_int_init(&c_edge_color2, 0)); - } - IGRAPH_FINALLY(igraph_vector_int_destroy, &c_edge_color2); if (0 != igraph_vector_int_list_init(&c_maps, 0)) { igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_vector_int_list_destroy, &c_maps); /* Call igraph */ - IGRAPH_R_CHECK(igraph_get_isomorphisms_vf2(&c_graph1, &c_graph2, (Rf_isNull(vertex_color1) ? 0 : &c_vertex_color1), (Rf_isNull(vertex_color2) ? 0 : &c_vertex_color2), (Rf_isNull(edge_color1) ? 0 : &c_edge_color1), (Rf_isNull(edge_color2) ? 0 : &c_edge_color2), &c_maps, 0, 0, 0)); + IGRAPH_R_CHECK(igraph_get_isomorphisms_vf2(&c_graph1, &c_graph2, c_vertex_color1, c_vertex_color2, c_edge_color1, c_edge_color2, &c_maps, 0, 0, 0)); /* Convert output */ - igraph_vector_int_destroy(&c_vertex_color1); - IGRAPH_FINALLY_CLEAN(1); - igraph_vector_int_destroy(&c_vertex_color2); - IGRAPH_FINALLY_CLEAN(1); - igraph_vector_int_destroy(&c_edge_color1); - IGRAPH_FINALLY_CLEAN(1); - igraph_vector_int_destroy(&c_edge_color2); - IGRAPH_FINALLY_CLEAN(1); PROTECT(maps=R_igraph_vector_int_list_to_SEXP(&c_maps)); igraph_vector_int_list_destroy(&c_maps); IGRAPH_FINALLY_CLEAN(1); @@ -9873,30 +9444,6 @@ SEXP R_igraph_subisomorphic_vf2(SEXP graph1, SEXP graph2, SEXP vertex_color1, SE /* Convert input */ R_SEXP_to_igraph(graph1, &c_graph1); R_SEXP_to_igraph(graph2, &c_graph2); - if (!Rf_isNull(vertex_color1)) { - R_SEXP_to_vector_int_copy(vertex_color1, &c_vertex_color1); - } else { - IGRAPH_R_CHECK(igraph_vector_int_init(&c_vertex_color1, 0)); - } - IGRAPH_FINALLY(igraph_vector_int_destroy, &c_vertex_color1); - if (!Rf_isNull(vertex_color2)) { - R_SEXP_to_vector_int_copy(vertex_color2, &c_vertex_color2); - } else { - IGRAPH_R_CHECK(igraph_vector_int_init(&c_vertex_color2, 0)); - } - IGRAPH_FINALLY(igraph_vector_int_destroy, &c_vertex_color2); - if (!Rf_isNull(edge_color1)) { - R_SEXP_to_vector_int_copy(edge_color1, &c_edge_color1); - } else { - IGRAPH_R_CHECK(igraph_vector_int_init(&c_edge_color1, 0)); - } - IGRAPH_FINALLY(igraph_vector_int_destroy, &c_edge_color1); - if (!Rf_isNull(edge_color2)) { - R_SEXP_to_vector_int_copy(edge_color2, &c_edge_color2); - } else { - IGRAPH_R_CHECK(igraph_vector_int_init(&c_edge_color2, 0)); - } - IGRAPH_FINALLY(igraph_vector_int_destroy, &c_edge_color2); if (0 != igraph_vector_int_init(&c_map12, 0)) { igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); } @@ -9906,19 +9453,11 @@ SEXP R_igraph_subisomorphic_vf2(SEXP graph1, SEXP graph2, SEXP vertex_color1, SE } IGRAPH_FINALLY(igraph_vector_int_destroy, &c_map21); /* Call igraph */ - IGRAPH_R_CHECK(igraph_subisomorphic_vf2(&c_graph1, &c_graph2, (Rf_isNull(vertex_color1) ? 0 : (Rf_isNull(vertex_color1) ? 0 : &c_vertex_color1)), (Rf_isNull(vertex_color2) ? 0 : (Rf_isNull(vertex_color2) ? 0 : &c_vertex_color2)), (Rf_isNull(edge_color1) ? 0 : (Rf_isNull(edge_color1) ? 0 : &c_edge_color1)), (Rf_isNull(edge_color2) ? 0 : (Rf_isNull(edge_color2) ? 0 : &c_edge_color2)), &c_iso, &c_map12, &c_map21, 0, 0, 0)); + IGRAPH_R_CHECK(igraph_subisomorphic_vf2(&c_graph1, &c_graph2, (Rf_isNull(vertex_color1) ? 0 : c_vertex_color1), (Rf_isNull(vertex_color2) ? 0 : c_vertex_color2), (Rf_isNull(edge_color1) ? 0 : c_edge_color1), (Rf_isNull(edge_color2) ? 0 : c_edge_color2), &c_iso, &c_map12, &c_map21, 0, 0, 0)); /* Convert output */ PROTECT(r_result=NEW_LIST(3)); PROTECT(r_names=NEW_CHARACTER(3)); - igraph_vector_int_destroy(&c_vertex_color1); - IGRAPH_FINALLY_CLEAN(1); - igraph_vector_int_destroy(&c_vertex_color2); - IGRAPH_FINALLY_CLEAN(1); - igraph_vector_int_destroy(&c_edge_color1); - IGRAPH_FINALLY_CLEAN(1); - igraph_vector_int_destroy(&c_edge_color2); - IGRAPH_FINALLY_CLEAN(1); PROTECT(iso=NEW_LOGICAL(1)); LOGICAL(iso)[0]=c_iso; PROTECT(map12=R_igraph_vector_int_to_SEXPp1(&c_map12)); @@ -9961,43 +9500,11 @@ SEXP R_igraph_count_subisomorphisms_vf2(SEXP graph1, SEXP graph2, SEXP vertex_co /* Convert input */ R_SEXP_to_igraph(graph1, &c_graph1); R_SEXP_to_igraph(graph2, &c_graph2); - if (!Rf_isNull(vertex_color1)) { - R_SEXP_to_vector_int_copy(vertex_color1, &c_vertex_color1); - } else { - IGRAPH_R_CHECK(igraph_vector_int_init(&c_vertex_color1, 0)); - } - IGRAPH_FINALLY(igraph_vector_int_destroy, &c_vertex_color1); - if (!Rf_isNull(vertex_color2)) { - R_SEXP_to_vector_int_copy(vertex_color2, &c_vertex_color2); - } else { - IGRAPH_R_CHECK(igraph_vector_int_init(&c_vertex_color2, 0)); - } - IGRAPH_FINALLY(igraph_vector_int_destroy, &c_vertex_color2); - if (!Rf_isNull(edge_color1)) { - R_SEXP_to_vector_int_copy(edge_color1, &c_edge_color1); - } else { - IGRAPH_R_CHECK(igraph_vector_int_init(&c_edge_color1, 0)); - } - IGRAPH_FINALLY(igraph_vector_int_destroy, &c_edge_color1); - if (!Rf_isNull(edge_color2)) { - R_SEXP_to_vector_int_copy(edge_color2, &c_edge_color2); - } else { - IGRAPH_R_CHECK(igraph_vector_int_init(&c_edge_color2, 0)); - } - IGRAPH_FINALLY(igraph_vector_int_destroy, &c_edge_color2); c_count=0; /* Call igraph */ - IGRAPH_R_CHECK(igraph_count_subisomorphisms_vf2(&c_graph1, &c_graph2, (Rf_isNull(vertex_color1) ? 0 : &c_vertex_color1), (Rf_isNull(vertex_color2) ? 0 : &c_vertex_color2), (Rf_isNull(edge_color1) ? 0 : &c_edge_color1), (Rf_isNull(edge_color2) ? 0 : &c_edge_color2), &c_count, 0, 0, 0)); + IGRAPH_R_CHECK(igraph_count_subisomorphisms_vf2(&c_graph1, &c_graph2, c_vertex_color1, c_vertex_color2, c_edge_color1, c_edge_color2, &c_count, 0, 0, 0)); /* Convert output */ - igraph_vector_int_destroy(&c_vertex_color1); - IGRAPH_FINALLY_CLEAN(1); - igraph_vector_int_destroy(&c_vertex_color2); - IGRAPH_FINALLY_CLEAN(1); - igraph_vector_int_destroy(&c_edge_color1); - IGRAPH_FINALLY_CLEAN(1); - igraph_vector_int_destroy(&c_edge_color2); - IGRAPH_FINALLY_CLEAN(1); PROTECT(count=NEW_NUMERIC(1)); REAL(count)[0]=(double) c_count; r_result = count; @@ -10027,46 +9534,14 @@ SEXP R_igraph_get_subisomorphisms_vf2(SEXP graph1, SEXP graph2, SEXP vertex_colo /* Convert input */ R_SEXP_to_igraph(graph1, &c_graph1); R_SEXP_to_igraph(graph2, &c_graph2); - if (!Rf_isNull(vertex_color1)) { - R_SEXP_to_vector_int_copy(vertex_color1, &c_vertex_color1); - } else { - IGRAPH_R_CHECK(igraph_vector_int_init(&c_vertex_color1, 0)); - } - IGRAPH_FINALLY(igraph_vector_int_destroy, &c_vertex_color1); - if (!Rf_isNull(vertex_color2)) { - R_SEXP_to_vector_int_copy(vertex_color2, &c_vertex_color2); - } else { - IGRAPH_R_CHECK(igraph_vector_int_init(&c_vertex_color2, 0)); - } - IGRAPH_FINALLY(igraph_vector_int_destroy, &c_vertex_color2); - if (!Rf_isNull(edge_color1)) { - R_SEXP_to_vector_int_copy(edge_color1, &c_edge_color1); - } else { - IGRAPH_R_CHECK(igraph_vector_int_init(&c_edge_color1, 0)); - } - IGRAPH_FINALLY(igraph_vector_int_destroy, &c_edge_color1); - if (!Rf_isNull(edge_color2)) { - R_SEXP_to_vector_int_copy(edge_color2, &c_edge_color2); - } else { - IGRAPH_R_CHECK(igraph_vector_int_init(&c_edge_color2, 0)); - } - IGRAPH_FINALLY(igraph_vector_int_destroy, &c_edge_color2); if (0 != igraph_vector_int_list_init(&c_maps, 0)) { igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_vector_int_list_destroy, &c_maps); /* Call igraph */ - IGRAPH_R_CHECK(igraph_get_subisomorphisms_vf2(&c_graph1, &c_graph2, (Rf_isNull(vertex_color1) ? 0 : &c_vertex_color1), (Rf_isNull(vertex_color2) ? 0 : &c_vertex_color2), (Rf_isNull(edge_color1) ? 0 : &c_edge_color1), (Rf_isNull(edge_color2) ? 0 : &c_edge_color2), &c_maps, 0, 0, 0)); + IGRAPH_R_CHECK(igraph_get_subisomorphisms_vf2(&c_graph1, &c_graph2, c_vertex_color1, c_vertex_color2, c_edge_color1, c_edge_color2, &c_maps, 0, 0, 0)); /* Convert output */ - igraph_vector_int_destroy(&c_vertex_color1); - IGRAPH_FINALLY_CLEAN(1); - igraph_vector_int_destroy(&c_vertex_color2); - IGRAPH_FINALLY_CLEAN(1); - igraph_vector_int_destroy(&c_edge_color1); - IGRAPH_FINALLY_CLEAN(1); - igraph_vector_int_destroy(&c_edge_color2); - IGRAPH_FINALLY_CLEAN(1); PROTECT(maps=R_igraph_vector_int_list_to_SEXP(&c_maps)); igraph_vector_int_list_destroy(&c_maps); IGRAPH_FINALLY_CLEAN(1); @@ -10079,7 +9554,37 @@ SEXP R_igraph_get_subisomorphisms_vf2(SEXP graph1, SEXP graph2, SEXP vertex_colo /*-------------------------------------------/ / igraph_canonical_permutation / /-------------------------------------------*/ -SEXP R_igraph_canonical_permutation(SEXP graph, SEXP colors, SEXP sh) { +SEXP R_igraph_canonical_permutation(SEXP graph, SEXP colors) { + /* Declarations */ + igraph_t c_graph; + igraph_vector_int_t c_colors; + igraph_vector_int_t c_labeling; + SEXP labeling; + + SEXP r_result; + /* Convert input */ + R_SEXP_to_igraph(graph, &c_graph); + if (0 != igraph_vector_int_init(&c_labeling, 0)) { + igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); + } + IGRAPH_FINALLY(igraph_vector_int_destroy, &c_labeling); + /* Call igraph */ + IGRAPH_R_CHECK(igraph_canonical_permutation(&c_graph, (Rf_isNull(colors) ? 0 : c_colors), &c_labeling)); + + /* Convert output */ + PROTECT(labeling=R_igraph_vector_int_to_SEXPp1(&c_labeling)); + igraph_vector_int_destroy(&c_labeling); + IGRAPH_FINALLY_CLEAN(1); + r_result = labeling; + + UNPROTECT(1); + return(r_result); +} + +/*-------------------------------------------/ +/ igraph_canonical_permutation_bliss / +/-------------------------------------------*/ +SEXP R_igraph_canonical_permutation_bliss(SEXP graph, SEXP colors, SEXP sh) { /* Declarations */ igraph_t c_graph; igraph_vector_int_t c_colors; @@ -10092,25 +9597,17 @@ SEXP R_igraph_canonical_permutation(SEXP graph, SEXP colors, SEXP sh) { SEXP r_result, r_names; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); - if (!Rf_isNull(colors)) { - R_SEXP_to_vector_int_copy(colors, &c_colors); - } else { - IGRAPH_R_CHECK(igraph_vector_int_init(&c_colors, 0)); - } - IGRAPH_FINALLY(igraph_vector_int_destroy, &c_colors); if (0 != igraph_vector_int_init(&c_labeling, 0)) { igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_vector_int_destroy, &c_labeling); c_sh = (igraph_bliss_sh_t) Rf_asInteger(sh); /* Call igraph */ - IGRAPH_R_CHECK(igraph_canonical_permutation(&c_graph, (Rf_isNull(colors) ? 0 : (Rf_isNull(colors) ? 0 : &c_colors)), &c_labeling, c_sh, &c_info)); + IGRAPH_R_CHECK(igraph_canonical_permutation_bliss(&c_graph, (Rf_isNull(colors) ? 0 : c_colors), &c_labeling, c_sh, &c_info)); /* Convert output */ PROTECT(r_result=NEW_LIST(2)); PROTECT(r_names=NEW_CHARACTER(2)); - igraph_vector_int_destroy(&c_colors); - IGRAPH_FINALLY_CLEAN(1); PROTECT(labeling=R_igraph_vector_int_to_SEXPp1(&c_labeling)); igraph_vector_int_destroy(&c_labeling); IGRAPH_FINALLY_CLEAN(1); @@ -10183,18 +9680,6 @@ SEXP R_igraph_isomorphic_bliss(SEXP graph1, SEXP graph2, SEXP colors1, SEXP colo /* Convert input */ R_SEXP_to_igraph(graph1, &c_graph1); R_SEXP_to_igraph(graph2, &c_graph2); - if (!Rf_isNull(colors1)) { - R_SEXP_to_vector_int_copy(colors1, &c_colors1); - } else { - IGRAPH_R_CHECK(igraph_vector_int_init(&c_colors1, 0)); - } - IGRAPH_FINALLY(igraph_vector_int_destroy, &c_colors1); - if (!Rf_isNull(colors2)) { - R_SEXP_to_vector_int_copy(colors2, &c_colors2); - } else { - IGRAPH_R_CHECK(igraph_vector_int_init(&c_colors2, 0)); - } - IGRAPH_FINALLY(igraph_vector_int_destroy, &c_colors2); if (0 != igraph_vector_int_init(&c_map12, 0)) { igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); } @@ -10205,15 +9690,11 @@ SEXP R_igraph_isomorphic_bliss(SEXP graph1, SEXP graph2, SEXP colors1, SEXP colo IGRAPH_FINALLY(igraph_vector_int_destroy, &c_map21); c_sh = (igraph_bliss_sh_t) Rf_asInteger(sh); /* Call igraph */ - IGRAPH_R_CHECK(igraph_isomorphic_bliss(&c_graph1, &c_graph2, (Rf_isNull(colors1) ? 0 : (Rf_isNull(colors1) ? 0 : &c_colors1)), (Rf_isNull(colors2) ? 0 : (Rf_isNull(colors2) ? 0 : &c_colors2)), &c_iso, &c_map12, &c_map21, c_sh, &c_info1, &c_info2)); + IGRAPH_R_CHECK(igraph_isomorphic_bliss(&c_graph1, &c_graph2, (Rf_isNull(colors1) ? 0 : c_colors1), (Rf_isNull(colors2) ? 0 : c_colors2), &c_iso, &c_map12, &c_map21, c_sh, &c_info1, &c_info2)); /* Convert output */ PROTECT(r_result=NEW_LIST(5)); PROTECT(r_names=NEW_CHARACTER(5)); - igraph_vector_int_destroy(&c_colors1); - IGRAPH_FINALLY_CLEAN(1); - igraph_vector_int_destroy(&c_colors2); - IGRAPH_FINALLY_CLEAN(1); PROTECT(iso=NEW_LOGICAL(1)); LOGICAL(iso)[0]=c_iso; PROTECT(map12=R_igraph_vector_int_to_SEXPp1(&c_map12)); @@ -10244,9 +9725,9 @@ SEXP R_igraph_isomorphic_bliss(SEXP graph1, SEXP graph2, SEXP colors1, SEXP colo } /*-------------------------------------------/ -/ igraph_count_automorphisms / +/ igraph_count_automorphisms_bliss / /-------------------------------------------*/ -SEXP R_igraph_count_automorphisms(SEXP graph, SEXP colors, SEXP sh) { +SEXP R_igraph_count_automorphisms_bliss(SEXP graph, SEXP colors, SEXP sh) { /* Declarations */ igraph_t c_graph; igraph_vector_int_t c_colors; @@ -10257,19 +9738,11 @@ SEXP R_igraph_count_automorphisms(SEXP graph, SEXP colors, SEXP sh) { SEXP r_result; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); - if (!Rf_isNull(colors)) { - R_SEXP_to_vector_int_copy(colors, &c_colors); - } else { - IGRAPH_R_CHECK(igraph_vector_int_init(&c_colors, 0)); - } - IGRAPH_FINALLY(igraph_vector_int_destroy, &c_colors); c_sh = (igraph_bliss_sh_t) Rf_asInteger(sh); /* Call igraph */ - IGRAPH_R_CHECK(igraph_count_automorphisms(&c_graph, (Rf_isNull(colors) ? 0 : (Rf_isNull(colors) ? 0 : &c_colors)), c_sh, &c_info)); + IGRAPH_R_CHECK(igraph_count_automorphisms_bliss(&c_graph, (Rf_isNull(colors) ? 0 : c_colors), c_sh, &c_info)); /* Convert output */ - igraph_vector_int_destroy(&c_colors); - IGRAPH_FINALLY_CLEAN(1); PROTECT(info=R_igraph_bliss_info_to_SEXP(&c_info)); if (c_info.group_size) { free(c_info.group_size); } r_result = info; @@ -10279,9 +9752,9 @@ SEXP R_igraph_count_automorphisms(SEXP graph, SEXP colors, SEXP sh) { } /*-------------------------------------------/ -/ igraph_automorphism_group / +/ igraph_automorphism_group_bliss / /-------------------------------------------*/ -SEXP R_igraph_automorphism_group(SEXP graph, SEXP colors, SEXP sh) { +SEXP R_igraph_automorphism_group_bliss(SEXP graph, SEXP colors, SEXP sh) { /* Declarations */ igraph_t c_graph; igraph_vector_int_t c_colors; @@ -10294,28 +9767,13 @@ SEXP R_igraph_automorphism_group(SEXP graph, SEXP colors, SEXP sh) { SEXP r_result, r_names; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); - if (!Rf_isNull(colors)) { - R_SEXP_to_vector_int_copy(colors, &c_colors); - } else { - IGRAPH_R_CHECK(igraph_vector_int_init(&c_colors, 0)); - } - IGRAPH_FINALLY(igraph_vector_int_destroy, &c_colors); - if (0 != igraph_vector_int_list_init(&c_generators, 0)) { - igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); - } - IGRAPH_FINALLY(igraph_vector_int_list_destroy, &c_generators); c_sh = (igraph_bliss_sh_t) Rf_asInteger(sh); /* Call igraph */ - IGRAPH_R_CHECK(igraph_automorphism_group(&c_graph, (Rf_isNull(colors) ? 0 : (Rf_isNull(colors) ? 0 : &c_colors)), &c_generators, c_sh, &c_info)); + IGRAPH_R_CHECK(igraph_automorphism_group_bliss(&c_graph, (Rf_isNull(colors) ? 0 : c_colors), c_generators, c_sh, &c_info)); /* Convert output */ PROTECT(r_result=NEW_LIST(2)); PROTECT(r_names=NEW_CHARACTER(2)); - igraph_vector_int_destroy(&c_colors); - IGRAPH_FINALLY_CLEAN(1); - PROTECT(generators=R_igraph_vector_int_list_to_SEXPp1(&c_generators)); - igraph_vector_int_list_destroy(&c_generators); - IGRAPH_FINALLY_CLEAN(1); PROTECT(info=R_igraph_bliss_info_to_SEXP(&c_info)); if (c_info.group_size) { free(c_info.group_size); } SET_VECTOR_ELT(r_result, 0, generators); @@ -10498,11 +9956,10 @@ SEXP R_igraph_maximum_bipartite_matching(SEXP graph, SEXP types, SEXP weights, S igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_vector_int_destroy, &c_matching); - if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } IGRAPH_R_CHECK_REAL(eps); c_eps = REAL(eps)[0]; /* Call igraph */ - IGRAPH_R_CHECK(igraph_maximum_bipartite_matching(&c_graph, (Rf_isNull(types) ? 0 : (Rf_isNull(types) ? 0 : &c_types)), &c_matching_size, &c_matching_weight, &c_matching, (Rf_isNull(weights) ? 0 : (Rf_isNull(weights) ? 0 : &c_weights)), c_eps)); + IGRAPH_R_CHECK(igraph_maximum_bipartite_matching(&c_graph, (Rf_isNull(types) ? 0 : (Rf_isNull(types) ? 0 : &c_types)), &c_matching_size, &c_matching_weight, &c_matching, (Rf_isNull(weights) ? 0 : c_weights), c_eps)); /* Convert output */ PROTECT(r_result=NEW_LIST(3)); @@ -10530,13 +9987,13 @@ SEXP R_igraph_maximum_bipartite_matching(SEXP graph, SEXP types, SEXP weights, S /*-------------------------------------------/ / igraph_eigen_adjacency / /-------------------------------------------*/ -SEXP R_igraph_eigen_adjacency(SEXP graph, SEXP algorithm, SEXP which, SEXP options) { +SEXP R_igraph_eigen_adjacency(SEXP graph, SEXP algorithm, SEXP which, SEXP options, SEXP storage) { /* Declarations */ igraph_t c_graph; igraph_eigen_algorithm_t c_algorithm; igraph_eigen_which_t c_which; igraph_arpack_options_t c_options; - + igraph_arpack_storage_t c_storage; igraph_vector_t c_values; igraph_matrix_t c_vectors; igraph_vector_complex_t c_cmplxvalues; @@ -10551,7 +10008,6 @@ SEXP R_igraph_eigen_adjacency(SEXP graph, SEXP algorithm, SEXP which, SEXP optio R_SEXP_to_igraph(graph, &c_graph); c_algorithm = (igraph_eigen_algorithm_t) Rf_asInteger(algorithm); R_SEXP_to_igraph_eigen_which(which, &c_which); - R_SEXP_to_igraph_arpack_options(options, &c_options); if (0 != igraph_vector_init(&c_values, 0)) { igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); } @@ -10571,12 +10027,11 @@ SEXP R_igraph_eigen_adjacency(SEXP graph, SEXP algorithm, SEXP which, SEXP optio IGRAPH_FINALLY(igraph_matrix_complex_destroy, &c_cmplxvectors); cmplxvectors=R_GlobalEnv; /* hack to have a non-NULL value */ /* Call igraph */ - IGRAPH_R_CHECK(igraph_eigen_adjacency(&c_graph, c_algorithm, &c_which, &c_options, 0, &c_values, &c_vectors, (Rf_isNull(cmplxvalues) ? 0 : &c_cmplxvalues), (Rf_isNull(cmplxvectors) ? 0 : &c_cmplxvectors))); + IGRAPH_R_CHECK(igraph_eigen_adjacency(&c_graph, c_algorithm, &c_which, c_options, c_storage, &c_values, &c_vectors, (Rf_isNull(cmplxvalues) ? 0 : &c_cmplxvalues), (Rf_isNull(cmplxvectors) ? 0 : &c_cmplxvectors))); /* Convert output */ - PROTECT(r_result=NEW_LIST(5)); - PROTECT(r_names=NEW_CHARACTER(5)); - PROTECT(options=R_igraph_arpack_options_to_SEXP(&c_options)); + PROTECT(r_result=NEW_LIST(6)); + PROTECT(r_names=NEW_CHARACTER(6)); PROTECT(values=R_igraph_vector_to_SEXP(&c_values)); igraph_vector_destroy(&c_values); IGRAPH_FINALLY_CLEAN(1); @@ -10590,17 +10045,19 @@ SEXP R_igraph_eigen_adjacency(SEXP graph, SEXP algorithm, SEXP which, SEXP optio igraph_matrix_complex_destroy(&c_cmplxvectors); IGRAPH_FINALLY_CLEAN(1); SET_VECTOR_ELT(r_result, 0, options); - SET_VECTOR_ELT(r_result, 1, values); - SET_VECTOR_ELT(r_result, 2, vectors); - SET_VECTOR_ELT(r_result, 3, cmplxvalues); - SET_VECTOR_ELT(r_result, 4, cmplxvectors); + SET_VECTOR_ELT(r_result, 1, storage); + SET_VECTOR_ELT(r_result, 2, values); + SET_VECTOR_ELT(r_result, 3, vectors); + SET_VECTOR_ELT(r_result, 4, cmplxvalues); + SET_VECTOR_ELT(r_result, 5, cmplxvectors); SET_STRING_ELT(r_names, 0, Rf_mkChar("options")); - SET_STRING_ELT(r_names, 1, Rf_mkChar("values")); - SET_STRING_ELT(r_names, 2, Rf_mkChar("vectors")); - SET_STRING_ELT(r_names, 3, Rf_mkChar("cmplxvalues")); - SET_STRING_ELT(r_names, 4, Rf_mkChar("cmplxvectors")); + SET_STRING_ELT(r_names, 1, Rf_mkChar("storage")); + SET_STRING_ELT(r_names, 2, Rf_mkChar("values")); + SET_STRING_ELT(r_names, 3, Rf_mkChar("vectors")); + SET_STRING_ELT(r_names, 4, Rf_mkChar("cmplxvalues")); + SET_STRING_ELT(r_names, 5, Rf_mkChar("cmplxvectors")); SET_NAMES(r_result, r_names); - UNPROTECT(6); + UNPROTECT(7); UNPROTECT(1); return(r_result); @@ -10915,23 +10372,16 @@ SEXP R_igraph_fundamental_cycles(SEXP graph, SEXP start, SEXP bfs_cutoff, SEXP w SEXP r_result; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); - if (0 != igraph_vector_int_list_init(&c_basis, 0)) { - igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); - } - IGRAPH_FINALLY(igraph_vector_int_list_destroy, &c_basis); if (!Rf_isNull(start)) { c_start = (igraph_integer_t) REAL(start)[0]; } IGRAPH_R_CHECK_INT(bfs_cutoff); c_bfs_cutoff = (igraph_integer_t) REAL(bfs_cutoff)[0]; - if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } /* Call igraph */ - IGRAPH_R_CHECK(igraph_fundamental_cycles(&c_graph, &c_basis, (Rf_isNull(start) ? 0 : c_start), c_bfs_cutoff, (Rf_isNull(weights) ? 0 : &c_weights))); + IGRAPH_R_CHECK(igraph_fundamental_cycles(&c_graph, c_basis, (Rf_isNull(start) ? 0 : c_start), c_bfs_cutoff, c_weights)); /* Convert output */ - PROTECT(basis=R_igraph_vector_int_list_to_SEXPp1(&c_basis)); - igraph_vector_int_list_destroy(&c_basis); - IGRAPH_FINALLY_CLEAN(1); + r_result = basis; UNPROTECT(1); @@ -10954,24 +10404,17 @@ SEXP R_igraph_minimum_cycle_basis(SEXP graph, SEXP bfs_cutoff, SEXP complete, SE SEXP r_result; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); - if (0 != igraph_vector_int_list_init(&c_basis, 0)) { - igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); - } - IGRAPH_FINALLY(igraph_vector_int_list_destroy, &c_basis); IGRAPH_R_CHECK_INT(bfs_cutoff); c_bfs_cutoff = (igraph_integer_t) REAL(bfs_cutoff)[0]; IGRAPH_R_CHECK_BOOL(complete); c_complete = LOGICAL(complete)[0]; IGRAPH_R_CHECK_BOOL(use_cycle_order); c_use_cycle_order = LOGICAL(use_cycle_order)[0]; - if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } /* Call igraph */ - IGRAPH_R_CHECK(igraph_minimum_cycle_basis(&c_graph, &c_basis, c_bfs_cutoff, c_complete, c_use_cycle_order, (Rf_isNull(weights) ? 0 : &c_weights))); + IGRAPH_R_CHECK(igraph_minimum_cycle_basis(&c_graph, c_basis, c_bfs_cutoff, c_complete, c_use_cycle_order, c_weights)); /* Convert output */ - PROTECT(basis=R_igraph_vector_int_list_to_SEXPp1(&c_basis)); - igraph_vector_int_list_destroy(&c_basis); - IGRAPH_FINALLY_CLEAN(1); + r_result = basis; UNPROTECT(1); @@ -11249,18 +10692,12 @@ SEXP R_igraph_vertex_coloring_greedy(SEXP graph, SEXP heuristic) { SEXP r_result; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); - if (0 != igraph_vector_int_init(&c_colors, 0)) { - igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); - } - IGRAPH_FINALLY(igraph_vector_int_destroy, &c_colors); c_heuristic = (igraph_coloring_greedy_t) Rf_asInteger(heuristic); /* Call igraph */ - IGRAPH_R_CHECK(igraph_vertex_coloring_greedy(&c_graph, &c_colors, c_heuristic)); + IGRAPH_R_CHECK(igraph_vertex_coloring_greedy(&c_graph, c_colors, c_heuristic)); /* Convert output */ - PROTECT(colors=R_igraph_vector_int_to_SEXP(&c_colors)); - igraph_vector_int_destroy(&c_colors); - IGRAPH_FINALLY_CLEAN(1); + r_result = colors; UNPROTECT(1); @@ -11284,12 +10721,11 @@ SEXP R_igraph_deterministic_optimal_imitation(SEXP graph, SEXP vid, SEXP optimal R_SEXP_to_igraph(graph, &c_graph); c_vid = (igraph_integer_t) REAL(vid)[0]; c_optimality = (igraph_optimal_t) Rf_asInteger(optimality); - R_SEXP_to_vector(quantities, &c_quantities); R_SEXP_to_vector_int_copy(strategies, &c_strategies); IGRAPH_FINALLY(igraph_vector_int_destroy, &c_strategies); c_mode = (igraph_neimode_t) Rf_asInteger(mode); /* Call igraph */ - IGRAPH_R_CHECK(igraph_deterministic_optimal_imitation(&c_graph, c_vid, c_optimality, &c_quantities, &c_strategies, c_mode)); + IGRAPH_R_CHECK(igraph_deterministic_optimal_imitation(&c_graph, c_vid, c_optimality, c_quantities, &c_strategies, c_mode)); /* Convert output */ PROTECT(strategies=R_igraph_vector_int_to_SEXP(&c_strategies)); @@ -11315,23 +10751,15 @@ SEXP R_igraph_moran_process(SEXP graph, SEXP weights, SEXP quantities, SEXP stra SEXP r_result, r_names; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); - if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } - if (0 != R_SEXP_to_vector_copy(quantities, &c_quantities)) { - igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); - } - IGRAPH_FINALLY(igraph_vector_destroy, &c_quantities); R_SEXP_to_vector_int_copy(strategies, &c_strategies); IGRAPH_FINALLY(igraph_vector_int_destroy, &c_strategies); c_mode = (igraph_neimode_t) Rf_asInteger(mode); /* Call igraph */ - IGRAPH_R_CHECK(igraph_moran_process(&c_graph, (Rf_isNull(weights) ? 0 : &c_weights), &c_quantities, &c_strategies, c_mode)); + IGRAPH_R_CHECK(igraph_moran_process(&c_graph, c_weights, c_quantities, &c_strategies, c_mode)); /* Convert output */ PROTECT(r_result=NEW_LIST(2)); PROTECT(r_names=NEW_CHARACTER(2)); - PROTECT(quantities=R_igraph_vector_to_SEXP(&c_quantities)); - igraph_vector_destroy(&c_quantities); - IGRAPH_FINALLY_CLEAN(1); PROTECT(strategies=R_igraph_vector_int_to_SEXP(&c_strategies)); igraph_vector_int_destroy(&c_strategies); IGRAPH_FINALLY_CLEAN(1); @@ -11364,12 +10792,11 @@ SEXP R_igraph_roulette_wheel_imitation(SEXP graph, SEXP vid, SEXP is_local, SEXP c_vid = (igraph_integer_t) REAL(vid)[0]; IGRAPH_R_CHECK_BOOL(is_local); c_is_local = LOGICAL(is_local)[0]; - R_SEXP_to_vector(quantities, &c_quantities); R_SEXP_to_vector_int_copy(strategies, &c_strategies); IGRAPH_FINALLY(igraph_vector_int_destroy, &c_strategies); c_mode = (igraph_neimode_t) Rf_asInteger(mode); /* Call igraph */ - IGRAPH_R_CHECK(igraph_roulette_wheel_imitation(&c_graph, c_vid, c_is_local, &c_quantities, &c_strategies, c_mode)); + IGRAPH_R_CHECK(igraph_roulette_wheel_imitation(&c_graph, c_vid, c_is_local, c_quantities, &c_strategies, c_mode)); /* Convert output */ PROTECT(strategies=R_igraph_vector_int_to_SEXP(&c_strategies)); @@ -11398,12 +10825,11 @@ SEXP R_igraph_stochastic_imitation(SEXP graph, SEXP vid, SEXP algo, SEXP quantit R_SEXP_to_igraph(graph, &c_graph); c_vid = (igraph_integer_t) REAL(vid)[0]; c_algo = (igraph_imitate_algorithm_t) Rf_asInteger(algo); - R_SEXP_to_vector(quantities, &c_quantities); R_SEXP_to_vector_int_copy(strategies, &c_strategies); IGRAPH_FINALLY(igraph_vector_int_destroy, &c_strategies); c_mode = (igraph_neimode_t) Rf_asInteger(mode); /* Call igraph */ - IGRAPH_R_CHECK(igraph_stochastic_imitation(&c_graph, c_vid, c_algo, &c_quantities, &c_strategies, c_mode)); + IGRAPH_R_CHECK(igraph_stochastic_imitation(&c_graph, c_vid, c_algo, c_quantities, &c_strategies, c_mode)); /* Convert output */ PROTECT(strategies=R_igraph_vector_int_to_SEXP(&c_strategies)); @@ -11497,6 +10923,26 @@ SEXP R_igraph_vertex_path_from_edge_path(SEXP graph, SEXP start, SEXP edge_path, IGRAPH_FINALLY_CLEAN(1); r_result = vertex_path; + UNPROTECT(1); + return(r_result); +} + +/*-------------------------------------------/ +/ igraph_delete_vertices_idx / +/-------------------------------------------*/ +SEXP R_igraph_delete_vertices_idx(void) { + /* Declarations */ + igraph_error_t c_result; + SEXP r_result; + /* Convert input */ + + /* Call igraph */ + IGRAPH_R_CHECK(igraph_delete_vertices_idx()); + + /* Convert output */ + + + UNPROTECT(1); return(r_result); } diff --git a/src/vendor/cigraph/CHANGELOG.md b/src/vendor/cigraph/CHANGELOG.md index fb9709e1b00..5fde0dd325c 100644 --- a/src/vendor/cigraph/CHANGELOG.md +++ b/src/vendor/cigraph/CHANGELOG.md @@ -1,5 +1,44 @@ # igraph C library changelog +## [develop] + +### Breaking changes + + - Interruption handlers do not take a `void*` argument any more; this is relevant to maintainers of higher-level interfaces only. + - Interruption handlers now return an `igraph_bool_t` instead of an `igraph_error_t`; the returned value must be true if the calculation has to be interrupted and false otherwise. + - `igraph_delete_vertices_map()` (formerly called `igraph_delete_vertices_idx()`) and `igraph_induced_subgraph_map()` now use -1 to represent unmapped vertices in the returned forward mapping vector and they do not offset vertex indices by 1 any more. (Note that the inverse map always behaved this way, this change makes the two mappings consistent). + - `igraph_distances_johnson()` now takes a mode parameter to determine in which direction paths should be followed. + - `igraph_vector_shuffle()` no longer returns an error code. + - `igraph_vector_swap()` no longer returns an error code. + - `igraph_matrix_swap()` no longer returns an error code. + - `igraph_rng_set_default()` now returns a pointer to the previous RNG. Furthermore, this function now only stores a pointer to the `igraph_rng_t` struct passed to it, instead of copying the struct. Thus the `igraph_rng_t` must continue to exist for as long as it is used as the default RNG. + - `igraph_similarity_jaccard()` and `igraph_similarity_dice()` now take two sets of vertices to create vertex pairs of, instead of one. + - `igraph_read_graph_ncol()` and `igraph_read_graph_lgl()` now uses a default edge weight of 1 instead of 0 for files that do not contain edge weights for at least some of the edges. + - `igraph_count_automorphisms()` has been renamed to `igraph_count_automorphisms_bliss()` because it has a BLISS-specific interface. A new `igraph_count_automorphisms()` function was added with a simplified interface that does not depend on BLISS. + - `igraph_automorphism_group()` has been renamed to `igraph_automorphism_group_bliss()` because it has a BLISS-specific interface. A new `igraph_automorphism_group()` function was added with a simplified interface that does not depend on BLISS. + - `igraph_canonical_permutation()` has been renamed to `igraph_canonical_permutation_bliss()` because it has a BLISS-specific interface. A new `igraph_canonical_permutation()` function was added with a simplified interface that does not depend on BLISS. + +### Added + + - `igraph_erdos_renyi_game_gnm()` gained a `multiple` Boolean argument to generate Erdős-Rényi graphs with multi-edges + - `igraph_bipartite_game_gnm()` gained a `multiple` Boolean argument to generate random bipartite graphs with multi-edges + +### Changed + + - The Pajek format reader and writer now map vertex labels to the `name` vertex attribute in igraph. The `id` attribute is no longer used. + +### Fixed + + - `igraph_community_spinglass_single()` now uses `igraph_real_t` for its `inner_links` and `outer_links` output parameters, as these return not simply edge counts, but the sum of the weights of some edges. + +### Removed + + - Removed `igraph_Calloc()`, `igraph_Realloc()` and `igraph_Free()`. Use `IGRAPH_CALLOC()`, `IGRAPH_REALLOC()` and `IGRAPH_FREE()` instead. + +### Deprecated + +- `igraph_delete_vertices_idx()` is now deprecated in favour of `igraph_delete_vertices_map()`, which is functionally equivalent but has a name that is consistent with `igraph_induced_subgraph_map()`. + ## [master] ### Added @@ -1308,6 +1347,7 @@ Some of the highlights are: - Provide proper support for Windows, using `__declspec(dllexport)` and `__declspec(dllimport)` for `DLL`s and static usage by using `#define IGRAPH_STATIC 1`. - Provided integer versions of `dqueue` and `stack` data types. +[develop]: https://github.com/igraph/igraph/compare/master..develop [master]: https://github.com/igraph/igraph/compare/0.10.10..master [0.10.10]: https://github.com/igraph/igraph/compare/0.10.9..0.10.10 [0.10.9]: https://github.com/igraph/igraph/compare/0.10.8..0.10.9 diff --git a/src/vendor/cigraph/etc/cmake/cpack_install_script.cmake b/src/vendor/cigraph/etc/cmake/cpack_install_script.cmake index ba50ad5f508..48af65c65b6 100644 --- a/src/vendor/cigraph/etc/cmake/cpack_install_script.cmake +++ b/src/vendor/cigraph/etc/cmake/cpack_install_script.cmake @@ -79,4 +79,9 @@ if(CPACK_SOURCE_INSTALLED_DIRECTORIES) "${CPACK_PACKAGE_DIRECTORY}/doc/html" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/doc" ) + file( + INSTALL + "${CPACK_PACKAGE_DIRECTORY}/doc/igraph-docs.info" + DESTINATION "${CMAKE_CURRENT_BINARY_DIR}/doc" + ) endif() diff --git a/src/vendor/cigraph/etc/cmake/packaging.cmake b/src/vendor/cigraph/etc/cmake/packaging.cmake index 4887b6c4b48..a45497400e6 100644 --- a/src/vendor/cigraph/etc/cmake/packaging.cmake +++ b/src/vendor/cigraph/etc/cmake/packaging.cmake @@ -4,7 +4,7 @@ set(CPACK_PACKAGE_VENDOR "The igraph development team") set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/COPYING") -if(TARGET html) +if(TARGET html AND TARGET info) # Alias "dist" to "package_source" add_custom_target(dist COMMAND "${CMAKE_COMMAND}" @@ -14,13 +14,13 @@ if(TARGET html) USES_TERMINAL ) - # We want to include the HTML docs in the source package so add a dependency - add_dependencies(dist html) + # Add dependencies to "dist" + add_dependencies(dist html info) else() add_custom_target(dist COMMAND "${CMAKE_COMMAND}" -E false COMMENT - "Cannot build source tarball since the HTML documentation was not built." + "Cannot build source tarball since the HTML or the Texinfo documentation was not built." VERBATIM USES_TERMINAL ) diff --git a/src/vendor/cigraph/include/igraph_attributes.h b/src/vendor/cigraph/include/igraph_attributes.h index 9773ce78df9..b871fe43d02 100644 --- a/src/vendor/cigraph/include/igraph_attributes.h +++ b/src/vendor/cigraph/include/igraph_attributes.h @@ -41,108 +41,135 @@ __BEGIN_DECLS /* Attributes */ /* -------------------------------------------------- */ -/** - * \section about_attributes - * - * Attributes are numbers, boolean values or strings associated with - * the vertices or edges of a graph, or with the graph itself. E.g. you may - * label vertices with symbolic names or attach numeric weights to the edges - * of a graph. In addition to these three basic types, a custom object - * type is supported as well. - * - * igraph attributes are designed to be flexible and extensible. - * In igraph attributes are implemented via an interface abstraction: - * any type implementing the functions in the interface, can be used - * for storing vertex, edge and graph attributes. This means that - * different attribute implementations can be used together with - * igraph. This is reasonable: if igraph is used from Python attributes can be - * of any Python type, from R all R types are allowed. There is also an - * experimental attribute implementation to be used when programming - * in C, but by default it is currently turned off. - * - * First we briefly look over how attribute handlers can be - * implemented. This is not something a user does every day. It is - * rather typically the job of the high level interface writers. (But - * it is possible to write an interface without implementing - * attributes.) Then we show the experimental C attribute handler. - */ - -/** - * \section about_attribute_table - * It is possible to attach an attribute handling - * interface to \a igraph. This is simply a table of functions, of - * type \ref igraph_attribute_table_t. These functions are invoked to - * notify the attribute handling code about the structural changes in - * a graph. See the documentation of this type for details. - * - * By default there is no attribute interface attached to \a igraph. - * To attach one, call \ref igraph_set_attribute_table with your new - * table. This is normally done on program startup, and is kept untouched - * for the program's lifetime. It must be done before any graph object - * is created, as graphs created with a given attribute handler - * cannot be manipulated while a different attribute handler is - * active. - */ - -/** - * \section about_attribute_combination - * - * Several graph operations may collapse multiple vertices or edges into - * a single one. Attribute combination lists are used to indicate to the attribute - * handler how to combine the attributes of the original vertices or edges and - * how to derive the final attribute value that is to be assigned to the collapsed - * vertex or edge. For example, \ref igraph_simplify() removes loops and combines - * multiple edges into a single one; in case of a graph with an edge attribute - * named \c weight the attribute combination list can tell the attribute handler - * whether the weight of a collapsed edge should be the sum, the mean or some other - * function of the weights of the original edges that were collapsed into one. - * - * One attribute combination list may contain several attribute combination - * records, one for each vertex or edge attribute that is to be handled during the - * operation. - */ - /** * \typedef igraph_attribute_type_t - * The possible types of the attributes. - * - * Note that this is only the - * type communicated by the attribute interface towards igraph - * functions. E.g. in the R attribute handler, it is safe to say - * that all complex R object attributes are strings, as long as this - * interface is able to serialize them into strings. See also \ref - * igraph_attribute_table_t. + * \brief The possible types of the attributes. + * + * Values of this enum are used by the attribute interface to communicate the + * type of an attribute to igraph's C core. When igraph is integrated in a + * high-level language, the attribute type reported by the interface may not + * necessarily have to match the exact data type in the high-level language as + * long as the attribute interface can provide a conversion from the native + * high-level attribute value to one of the data types listed here. When the + * high-level data type is complex and has no suitable conversion to one of the + * atomic igraph attribute types (numeric, string or Boolean), the attribute + * interface should report the attribute as having an "object" type, which is + * ignored by the C core. See also \ref igraph_attribute_table_t. + * * \enumval IGRAPH_ATTRIBUTE_UNSPECIFIED Currently used internally * as a "null value" or "placeholder value" in some algorithms. * Attribute records with this type must not be passed to igraph * functions. * \enumval IGRAPH_ATTRIBUTE_NUMERIC Numeric attribute. * \enumval IGRAPH_ATTRIBUTE_BOOLEAN Logical values, true or false. - * \enumval IGRAPH_ATTRIBUTE_STRING Attribute that can be converted to - * a string. + * \enumval IGRAPH_ATTRIBUTE_STRING String attribute. * \enumval IGRAPH_ATTRIBUTE_OBJECT Custom attribute type, to be * used for special data types by client applications. The R and * Python interfaces use this for attributes that hold R or Python * objects. Usually ignored by igraph functions. */ -typedef enum { IGRAPH_ATTRIBUTE_UNSPECIFIED = 0, - IGRAPH_ATTRIBUTE_DEFAULT IGRAPH_DEPRECATED_ENUMVAL = IGRAPH_ATTRIBUTE_UNSPECIFIED, - IGRAPH_ATTRIBUTE_NUMERIC = 1, - IGRAPH_ATTRIBUTE_BOOLEAN = 2, - IGRAPH_ATTRIBUTE_STRING = 3, - IGRAPH_ATTRIBUTE_OBJECT = 127 - } igraph_attribute_type_t; +typedef enum { + IGRAPH_ATTRIBUTE_UNSPECIFIED = 0, + IGRAPH_ATTRIBUTE_DEFAULT IGRAPH_DEPRECATED_ENUMVAL = IGRAPH_ATTRIBUTE_UNSPECIFIED, + IGRAPH_ATTRIBUTE_NUMERIC = 1, + IGRAPH_ATTRIBUTE_BOOLEAN = 2, + IGRAPH_ATTRIBUTE_STRING = 3, + IGRAPH_ATTRIBUTE_OBJECT = 127 +} igraph_attribute_type_t; +/** + * \typedef igraph_attribute_elemtype_t + * \brief Types of objects to which attributes can be attached. + * + * \enumval IGRAPH_ATTRIBUTE_GRAPH Denotes that an attribute belongs to the + * entire graph. + * \enumval IGRAPH_ATTRIBUTE_VERTEX Denotes that an attribute belongs to the + * vertices of a graph. + * \enumval IGRAPH_ATTRIBUTE_EDGE Denotes that an attribute belongs to the + * edges of a graph. + */ +typedef enum { + IGRAPH_ATTRIBUTE_GRAPH = 0, + IGRAPH_ATTRIBUTE_VERTEX, + IGRAPH_ATTRIBUTE_EDGE +} igraph_attribute_elemtype_t; + +/* -------------------------------------------------- */ +/* Attribute records */ +/* -------------------------------------------------- */ + +/** + * \typedef igraph_attribute_record_t + * \brief An attribute record holding the name, type and values of an attribute. + * + * This composite data type is used in the attribute interface to specify a + * name-type-value triplet where the name is the name of a graph, vertex or + * edge attribute, the type is the corresponding igraph type of the attribute + * and the value is a \em vector of attribute values. Note that for graph + * attributes we use a vector of length 1. The type of the vector depends on + * the attribute type: it is \ref igraph_vector_t for numeric attributes, + * \c igraph_strvector_t for string attributes and \c igraph_vector_bool_t + * for Boolean attributes. + * + * + * The record also stores default values for the attribute. The default values + * are used when the value vector of the record is resized with + * \ref igraph_attribute_record_resize(). It is important that the record + * stores \em one default value only, corresponding to the type of the + * attribute record. The default value is \em cleared when the type of the + * record is changed. + */ typedef struct igraph_attribute_record_t { - const char *name; + char *name; igraph_attribute_type_t type; - const void *value; + union { + void *as_raw; + igraph_vector_t *as_vector; + igraph_strvector_t *as_strvector; + igraph_vector_bool_t *as_vector_bool; + } value; + union { + igraph_real_t numeric; + igraph_bool_t boolean; + char *string; + } default_value; } igraph_attribute_record_t; -typedef enum { IGRAPH_ATTRIBUTE_GRAPH = 0, - IGRAPH_ATTRIBUTE_VERTEX, - IGRAPH_ATTRIBUTE_EDGE - } igraph_attribute_elemtype_t; +IGRAPH_EXPORT igraph_error_t igraph_attribute_record_init( + igraph_attribute_record_t *attr, const char* name, igraph_attribute_type_t type +); +IGRAPH_EXPORT igraph_error_t igraph_attribute_record_init_copy( + igraph_attribute_record_t *to, const igraph_attribute_record_t *from +); +IGRAPH_EXPORT igraph_error_t igraph_attribute_record_check_type( + const igraph_attribute_record_t *attr, igraph_attribute_type_t type +); +IGRAPH_EXPORT igraph_integer_t igraph_attribute_record_size( + const igraph_attribute_record_t *attr +); +IGRAPH_EXPORT igraph_error_t igraph_attribute_record_resize( + igraph_attribute_record_t *attr, igraph_integer_t new_size +); +IGRAPH_EXPORT igraph_error_t igraph_attribute_record_set_name( + igraph_attribute_record_t *attr, const char* name +); +IGRAPH_EXPORT igraph_error_t igraph_attribute_record_set_default_numeric( + igraph_attribute_record_t *attr, igraph_real_t value +); +IGRAPH_EXPORT igraph_error_t igraph_attribute_record_set_default_boolean( + igraph_attribute_record_t *attr, igraph_bool_t value +); +IGRAPH_EXPORT igraph_error_t igraph_attribute_record_set_default_string( + igraph_attribute_record_t *attr, const char* value +); +IGRAPH_EXPORT igraph_error_t igraph_attribute_record_set_type( + igraph_attribute_record_t *attr, igraph_attribute_type_t type +); +IGRAPH_EXPORT void igraph_attribute_record_destroy(igraph_attribute_record_t *attr); + +/* -------------------------------------------------- */ +/* Attribute combinations */ +/* -------------------------------------------------- */ /** * \typedef igraph_attribute_combination_type_t @@ -207,6 +234,22 @@ IGRAPH_EXPORT igraph_error_t igraph_attribute_combination_query(const igraph_att igraph_attribute_combination_type_t *type, igraph_function_pointer_t *func); +/* -------------------------------------------------- */ +/* List of attribute records */ +/* -------------------------------------------------- */ + +#define ATTRIBUTE_RECORD_LIST +#define BASE_ATTRIBUTE_RECORD +#include "igraph_pmt.h" +#include "igraph_typed_list_pmt.h" +#include "igraph_pmt_off.h" +#undef BASE_ATTRIBUTE_RECORD +#undef ATTRIBUTE_RECORD_LIST + +/* -------------------------------------------------- */ +/* Attribute handler interface */ +/* -------------------------------------------------- */ + /** * \struct igraph_attribute_table_t * \brief Table of functions to perform operations on attributes. @@ -218,18 +261,23 @@ IGRAPH_EXPORT igraph_error_t igraph_attribute_combination_query(const igraph_att * created, right after it is created but before any vertices or * edges are added. It is supposed to set the \c attr member of the \c * igraph_t object, which is guaranteed to be set to a null pointer - * before this function is called. It is expected to return an error code. + * before this function is called. It is expected to set the \c attr member + * to a non-null value \em or return an error code. Leaving the \c attr + * member at a null value while returning success is invalid and will trigger + * an error in the C core of igraph itself. * \member destroy This function is called whenever the graph object * is destroyed, right before freeing the allocated memory. It is supposed * to do any cleanup operations that are need to dispose of the \c attr * member of the \c igraph_t object properly. The caller will set the * \c attr member to a null pointer after this function returns. - * \member copy This function is called when copying a graph with \ref - * igraph_copy, after the structure of the graph has been already - * copied. It is supposed to populate the \c attr member of the target - * \c igraph_t object. The \c attr member of the target is guaranteed to be - * set to a null pointer before this function is called. It is expected to - * return an error code. + * \member copy This function is called when the C core wants to populate the + * attributes of a graph from another graph. The struvture of the target + * graph is already initialized by the time this function is called, and the + * \c attr member of the graph is set to null pointer. The function is + * supposed to populate the \c attr member of the target \c igraph_t object + * to a non-null value \em or return an error code. Leaving the \c attr + * member at a null value while returning success is invalid and will trigger + * an error in the C core of igraph itself. * \member add_vertices Called when vertices are added to a * graph, before adding the vertices themselves. * The number of vertices to add is supplied as an @@ -311,11 +359,14 @@ IGRAPH_EXPORT igraph_error_t igraph_attribute_combination_query(const igraph_att */ typedef struct igraph_attribute_table_t { - igraph_error_t (*init)(igraph_t *graph, igraph_vector_ptr_t *attr); + igraph_error_t (*init)(igraph_t *graph, const igraph_attribute_record_list_t *attr); void (*destroy)(igraph_t *graph); igraph_error_t (*copy)(igraph_t *to, const igraph_t *from, igraph_bool_t ga, igraph_bool_t va, igraph_bool_t ea); - igraph_error_t (*add_vertices)(igraph_t *graph, igraph_integer_t nv, igraph_vector_ptr_t *attr); + igraph_error_t (*add_vertices)( + igraph_t *graph, igraph_integer_t nv, + const igraph_attribute_record_list_t *attr + ); igraph_error_t (*permute_vertices)(const igraph_t *graph, igraph_t *newgraph, const igraph_vector_int_t *idx); @@ -323,8 +374,10 @@ typedef struct igraph_attribute_table_t { igraph_t *newgraph, const igraph_vector_int_list_t *merges, const igraph_attribute_combination_t *comb); - igraph_error_t (*add_edges)(igraph_t *graph, const igraph_vector_int_t *edges, - igraph_vector_ptr_t *attr); + igraph_error_t (*add_edges)( + igraph_t *graph, const igraph_vector_int_t *edges, + const igraph_attribute_record_list_t *attr + ); igraph_error_t (*permute_edges)(const igraph_t *graph, igraph_t *newgraph, const igraph_vector_int_t *idx); igraph_error_t (*combine_edges)(const igraph_t *graph, diff --git a/src/vendor/cigraph/include/igraph_bipartite.h b/src/vendor/cigraph/include/igraph_bipartite.h index f32fe8aa7fb..4d6963fe10c 100644 --- a/src/vendor/cigraph/include/igraph_bipartite.h +++ b/src/vendor/cigraph/include/igraph_bipartite.h @@ -85,7 +85,7 @@ IGRAPH_EXPORT igraph_error_t igraph_bipartite_game_gnp(igraph_t *graph, igraph_v IGRAPH_EXPORT igraph_error_t igraph_bipartite_game_gnm(igraph_t *graph, igraph_vector_bool_t *types, igraph_integer_t n1, igraph_integer_t n2, igraph_integer_t m, igraph_bool_t directed, - igraph_neimode_t mode); + igraph_neimode_t mode, igraph_bool_t multiple); /* Deprecated functions: */ diff --git a/src/vendor/cigraph/include/igraph_cocitation.h b/src/vendor/cigraph/include/igraph_cocitation.h index 4dfd406ab94..0ee80267511 100644 --- a/src/vendor/cigraph/include/igraph_cocitation.h +++ b/src/vendor/cigraph/include/igraph_cocitation.h @@ -43,16 +43,16 @@ IGRAPH_EXPORT igraph_error_t igraph_bibcoupling(const igraph_t *graph, igraph_ma const igraph_vs_t vids); IGRAPH_EXPORT igraph_error_t igraph_similarity_jaccard(const igraph_t *graph, igraph_matrix_t *res, - const igraph_vs_t vids, igraph_neimode_t mode, - igraph_bool_t loops); + const igraph_vs_t vit_from, const igraph_vs_t vit_to, + igraph_neimode_t mode, igraph_bool_t loops); IGRAPH_EXPORT igraph_error_t igraph_similarity_jaccard_pairs(const igraph_t *graph, igraph_vector_t *res, const igraph_vector_int_t *pairs, igraph_neimode_t mode, igraph_bool_t loops); IGRAPH_EXPORT igraph_error_t igraph_similarity_jaccard_es(const igraph_t *graph, igraph_vector_t *res, const igraph_es_t es, igraph_neimode_t mode, igraph_bool_t loops); IGRAPH_EXPORT igraph_error_t igraph_similarity_dice(const igraph_t *graph, igraph_matrix_t *res, - const igraph_vs_t vids, igraph_neimode_t mode, - igraph_bool_t loops); + const igraph_vs_t vit_from, const igraph_vs_t vit_to, + igraph_neimode_t mode, igraph_bool_t loops); IGRAPH_EXPORT igraph_error_t igraph_similarity_dice_pairs(const igraph_t *graph, igraph_vector_t *res, const igraph_vector_int_t *pairs, igraph_neimode_t mode, igraph_bool_t loops); IGRAPH_EXPORT igraph_error_t igraph_similarity_dice_es(const igraph_t *graph, igraph_vector_t *res, diff --git a/src/vendor/cigraph/include/igraph_community.h b/src/vendor/cigraph/include/igraph_community.h index c38cef130b2..2c84049a722 100644 --- a/src/vendor/cigraph/include/igraph_community.h +++ b/src/vendor/cigraph/include/igraph_community.h @@ -79,8 +79,8 @@ IGRAPH_EXPORT igraph_error_t igraph_community_spinglass_single(const igraph_t *g igraph_vector_int_t *community, igraph_real_t *cohesion, igraph_real_t *adhesion, - igraph_integer_t *inner_links, - igraph_integer_t *outer_links, + igraph_real_t *inner_links, + igraph_real_t *outer_links, igraph_integer_t spins, igraph_spincomm_update_t update_rule, igraph_real_t gamma); diff --git a/src/vendor/cigraph/include/igraph_components.h b/src/vendor/cigraph/include/igraph_components.h index 30721b801eb..2f5b4152250 100644 --- a/src/vendor/cigraph/include/igraph_components.h +++ b/src/vendor/cigraph/include/igraph_components.h @@ -33,7 +33,6 @@ #include "igraph_types.h" #include "igraph_vector.h" #include "igraph_vector_list.h" -#include "igraph_vector_ptr.h" /* because of igraph_decompose_destroy() */ __BEGIN_DECLS @@ -64,10 +63,6 @@ IGRAPH_EXPORT igraph_error_t igraph_biconnected_components(const igraph_t *graph IGRAPH_EXPORT igraph_error_t igraph_is_biconnected(const igraph_t *graph, igraph_bool_t *result); IGRAPH_EXPORT igraph_error_t igraph_bridges(const igraph_t *graph, igraph_vector_int_t *bridges); -/* Deprecated in igraph 0.10 when we switched to igraph_graph_list_t. Will be - * removed in 0.11 */ -IGRAPH_EXPORT IGRAPH_DEPRECATED void igraph_decompose_destroy(igraph_vector_ptr_t *complist); - __END_DECLS #endif diff --git a/src/vendor/cigraph/include/igraph_games.h b/src/vendor/cigraph/include/igraph_games.h index e9384fd59ca..c47d8138594 100644 --- a/src/vendor/cigraph/include/igraph_games.h +++ b/src/vendor/cigraph/include/igraph_games.h @@ -52,7 +52,7 @@ IGRAPH_EXPORT igraph_error_t igraph_barabasi_game(igraph_t *graph, igraph_intege IGRAPH_EXPORT igraph_error_t igraph_erdos_renyi_game_gnp(igraph_t *graph, igraph_integer_t n, igraph_real_t p, igraph_bool_t directed, igraph_bool_t loops); IGRAPH_EXPORT igraph_error_t igraph_erdos_renyi_game_gnm(igraph_t *graph, igraph_integer_t n, igraph_integer_t m, - igraph_bool_t directed, igraph_bool_t loops); + igraph_bool_t directed, igraph_bool_t loops, igraph_bool_t multiple); IGRAPH_EXPORT igraph_error_t igraph_degree_sequence_game(igraph_t *graph, const igraph_vector_int_t *out_deg, const igraph_vector_int_t *in_deg, igraph_degseq_t method); diff --git a/src/vendor/cigraph/include/igraph_heap_pmt.h b/src/vendor/cigraph/include/igraph_heap_pmt.h index d501700d34b..45fe0cf8ee5 100644 --- a/src/vendor/cigraph/include/igraph_heap_pmt.h +++ b/src/vendor/cigraph/include/igraph_heap_pmt.h @@ -25,7 +25,6 @@ typedef struct TYPE(igraph_heap) { BASE* stor_begin; BASE* stor_end; BASE* end; - igraph_bool_t destroy; } TYPE(igraph_heap); IGRAPH_EXPORT igraph_error_t FUNCTION(igraph_heap, init)(TYPE(igraph_heap)* h, igraph_integer_t capacity); diff --git a/src/vendor/cigraph/include/igraph_interface.h b/src/vendor/cigraph/include/igraph_interface.h index 88731a39bb5..3dcdffbf7ed 100644 --- a/src/vendor/cigraph/include/igraph_interface.h +++ b/src/vendor/cigraph/include/igraph_interface.h @@ -27,6 +27,7 @@ #include "igraph_decls.h" #include "igraph_types.h" #include "igraph_datatype.h" +#include "igraph_attributes.h" #include "igraph_error.h" #include "igraph_iterators.h" @@ -37,18 +38,26 @@ __BEGIN_DECLS /* -------------------------------------------------- */ IGRAPH_EXPORT igraph_error_t igraph_empty(igraph_t *graph, igraph_integer_t n, igraph_bool_t directed); -IGRAPH_EXPORT igraph_error_t igraph_empty_attrs(igraph_t *graph, igraph_integer_t n, igraph_bool_t directed, void *attr); +IGRAPH_EXPORT igraph_error_t igraph_empty_attrs( + igraph_t *graph, igraph_integer_t n, igraph_bool_t directed, + const igraph_attribute_record_list_t* attr +); IGRAPH_EXPORT void igraph_destroy(igraph_t *graph); IGRAPH_EXPORT igraph_error_t igraph_copy(igraph_t *to, const igraph_t *from); -IGRAPH_EXPORT igraph_error_t igraph_add_edges(igraph_t *graph, const igraph_vector_int_t *edges, - void *attr); -IGRAPH_EXPORT igraph_error_t igraph_add_vertices(igraph_t *graph, igraph_integer_t nv, - void *attr); +IGRAPH_EXPORT igraph_error_t igraph_add_edges( + igraph_t *graph, const igraph_vector_int_t *edges, + const igraph_attribute_record_list_t* attr +); +IGRAPH_EXPORT igraph_error_t igraph_add_vertices( + igraph_t *graph, igraph_integer_t nv, + const igraph_attribute_record_list_t* attr +); IGRAPH_EXPORT igraph_error_t igraph_delete_edges(igraph_t *graph, igraph_es_t edges); IGRAPH_EXPORT igraph_error_t igraph_delete_vertices(igraph_t *graph, const igraph_vs_t vertices); -IGRAPH_EXPORT igraph_error_t igraph_delete_vertices_idx(igraph_t *graph, const igraph_vs_t vertices, - igraph_vector_int_t *idx, - igraph_vector_int_t *invidx); +IGRAPH_EXPORT igraph_error_t igraph_delete_vertices_map( + igraph_t *graph, const igraph_vs_t vertices, igraph_vector_int_t *map, + igraph_vector_int_t *invmap +); IGRAPH_EXPORT IGRAPH_FUNCATTR_PURE igraph_integer_t igraph_vcount(const igraph_t *graph); IGRAPH_EXPORT IGRAPH_FUNCATTR_PURE igraph_integer_t igraph_ecount(const igraph_t *graph); IGRAPH_EXPORT igraph_error_t igraph_neighbors(const igraph_t *graph, igraph_vector_int_t *neis, igraph_integer_t vid, @@ -134,6 +143,11 @@ IGRAPH_EXPORT void igraph_i_property_cache_invalidate_all(const igraph_t *graph) #define IGRAPH_OTHER(graph,eid,vid) \ ((igraph_integer_t)(IGRAPH_TO(graph,(eid))==(vid) ? IGRAPH_FROM((graph),(eid)) : IGRAPH_TO((graph),(eid)))) +IGRAPH_DEPRECATED IGRAPH_EXPORT igraph_error_t igraph_delete_vertices_idx( + igraph_t *graph, const igraph_vs_t vertices, igraph_vector_int_t *idx, + igraph_vector_int_t *invidx +); + __END_DECLS #endif diff --git a/src/vendor/cigraph/include/igraph_interrupt.h b/src/vendor/cigraph/include/igraph_interrupt.h index 6d8fb85ca8a..ab09df8b70c 100644 --- a/src/vendor/cigraph/include/igraph_interrupt.h +++ b/src/vendor/cigraph/include/igraph_interrupt.h @@ -26,6 +26,7 @@ #include "igraph_decls.h" #include "igraph_error.h" +#include "igraph_types.h" __BEGIN_DECLS @@ -102,11 +103,11 @@ __BEGIN_DECLS * * This is the type of the interruption handler functions. * - * \param data reserved for possible future use - * \return \c IGRAPH_SUCCESS if the calculation should go on, anything else otherwise. + * \return false if the calculation should go on, true if the calculation + * should be interrupted. */ -typedef igraph_error_t igraph_interruption_handler_t (void* data); +typedef igraph_bool_t igraph_interruption_handler_t(void); /** * \function igraph_allow_interruption @@ -115,11 +116,11 @@ typedef igraph_error_t igraph_interruption_handler_t (void* data); * \ref IGRAPH_ALLOW_INTERRUPTION macro) if \a igraph is checking for interruption * requests. * - * \param data reserved for possible future use, now it is always \c NULL - * \return \c IGRAPH_SUCCESS if the calculation should go on, anything else otherwise. + * \return false if the calculation should go on, true if the calculation + * should be interrupted. */ -IGRAPH_EXPORT igraph_error_t igraph_allow_interruption(void* data); +IGRAPH_EXPORT igraph_bool_t igraph_allow_interruption(void); IGRAPH_EXPORT igraph_interruption_handler_t * igraph_set_interruption_handler (igraph_interruption_handler_t * new_handler); diff --git a/src/vendor/cigraph/include/igraph_matrix_pmt.h b/src/vendor/cigraph/include/igraph_matrix_pmt.h index 32697530ee9..b9f73daf60e 100644 --- a/src/vendor/cigraph/include/igraph_matrix_pmt.h +++ b/src/vendor/cigraph/include/igraph_matrix_pmt.h @@ -88,7 +88,7 @@ IGRAPH_EXPORT igraph_error_t FUNCTION(igraph_matrix, rbind)(TYPE(igraph_matrix) const TYPE(igraph_matrix) *from); IGRAPH_EXPORT igraph_error_t FUNCTION(igraph_matrix, cbind)(TYPE(igraph_matrix) *to, const TYPE(igraph_matrix) *from); -IGRAPH_EXPORT igraph_error_t FUNCTION(igraph_matrix, swap)(TYPE(igraph_matrix) *m1, TYPE(igraph_matrix) *m2); +IGRAPH_EXPORT void FUNCTION(igraph_matrix, swap)(TYPE(igraph_matrix) *m1, TYPE(igraph_matrix) *m2); /*--------------------------*/ /* Copying rows and columns */ diff --git a/src/vendor/cigraph/include/igraph_memory.h b/src/vendor/cigraph/include/igraph_memory.h index c381e3275e5..e6391cf5ba1 100644 --- a/src/vendor/cigraph/include/igraph_memory.h +++ b/src/vendor/cigraph/include/igraph_memory.h @@ -40,12 +40,6 @@ __BEGIN_DECLS #define IGRAPH_REALLOC(p,n,t) IGRAPH_I_ALLOC_CHECK_OVERFLOW(n, t, realloc((void*)(p), sizeof(t) * ((n) > 0 ? (n) : 1))) #define IGRAPH_FREE(p) (free( (void *)(p) ), (p) = NULL) -/* These are deprecated and scheduled for removal in 0.11 */ -#define igraph_Calloc IGRAPH_CALLOC -#define igraph_Realloc IGRAPH_REALLOC -#define igraph_Free IGRAPH_FREE -/* Deprecated section ends here */ - IGRAPH_EXPORT void *igraph_calloc(size_t count, size_t size); IGRAPH_EXPORT void *igraph_malloc(size_t size); IGRAPH_EXPORT void *igraph_realloc(void* ptr, size_t size); diff --git a/src/vendor/cigraph/include/igraph_paths.h b/src/vendor/cigraph/include/igraph_paths.h index d0e78048b33..5c0c2a9b3e0 100644 --- a/src/vendor/cigraph/include/igraph_paths.h +++ b/src/vendor/cigraph/include/igraph_paths.h @@ -114,7 +114,8 @@ IGRAPH_EXPORT igraph_error_t igraph_distances_johnson(const igraph_t *graph, igraph_matrix_t *res, const igraph_vs_t from, const igraph_vs_t to, - const igraph_vector_t *weights); + const igraph_vector_t *weights, + igraph_neimode_t mode); IGRAPH_EXPORT igraph_error_t igraph_distances_floyd_warshall(const igraph_t *graph, igraph_matrix_t *res, igraph_vs_t from, diff --git a/src/vendor/cigraph/include/igraph_pmt.h b/src/vendor/cigraph/include/igraph_pmt.h index fe8c350d3eb..b618bcfeb60 100644 --- a/src/vendor/cigraph/include/igraph_pmt.h +++ b/src/vendor/cigraph/include/igraph_pmt.h @@ -116,6 +116,9 @@ #elif defined(BASE_GRAPH) #define BASE igraph_t +#elif defined(BASE_ATTRIBUTE_RECORD) + #define BASE igraph_attribute_record_t + #else #error unknown BASE_ directive #endif @@ -156,6 +159,10 @@ #define FUNCTION(c) CONCAT2x(igraph_graph_list,c) #define INTERNAL_FUNCTION(c) CONCAT2x(igraph_i_graph_list,c) #define TYPE igraph_graph_list_t +#elif defined(ATTRIBUTE_RECORD_LIST) + #define FUNCTION(c) CONCAT2x(igraph_attribute_record_list,c) + #define INTERNAL_FUNCTION(c) CONCAT2x(igraph_i_attribute_record_list,c) + #define TYPE igraph_attribute_record_list_t #else #if defined(BASE_IGRAPH_REAL) #define FUNCTION(a,c) CONCAT2(a,c) diff --git a/src/vendor/cigraph/include/igraph_random.h b/src/vendor/cigraph/include/igraph_random.h index fcd84f40254..be8bcbbca04 100644 --- a/src/vendor/cigraph/include/igraph_random.h +++ b/src/vendor/cigraph/include/igraph_random.h @@ -152,7 +152,7 @@ IGRAPH_EXPORT extern const igraph_rng_type_t igraph_rngtype_pcg32; IGRAPH_EXPORT extern const igraph_rng_type_t igraph_rngtype_pcg64; IGRAPH_EXPORT igraph_rng_t *igraph_rng_default(void); -IGRAPH_EXPORT void igraph_rng_set_default(igraph_rng_t *rng); +IGRAPH_EXPORT igraph_rng_t *igraph_rng_set_default(igraph_rng_t *rng); /* --------------------------------- */ diff --git a/src/vendor/cigraph/include/igraph_strvector.h b/src/vendor/cigraph/include/igraph_strvector.h index f7d2d59b90f..b3d8fa39851 100644 --- a/src/vendor/cigraph/include/igraph_strvector.h +++ b/src/vendor/cigraph/include/igraph_strvector.h @@ -37,9 +37,9 @@ __BEGIN_DECLS typedef struct s_igraph_strvector { /* Empty strings "" are represented using NULL. */ - char **stor_begin; - char **stor_end; - char **end; + const char **stor_begin; + const char **stor_end; + const char **end; } igraph_strvector_t; /** @@ -87,6 +87,9 @@ IGRAPH_EXPORT igraph_error_t igraph_strvector_append( igraph_strvector_t *to, const igraph_strvector_t *from); IGRAPH_EXPORT igraph_error_t igraph_strvector_merge( igraph_strvector_t *to, igraph_strvector_t *from); +IGRAPH_EXPORT void igraph_strvector_swap(igraph_strvector_t *v1, igraph_strvector_t *v2); +IGRAPH_EXPORT igraph_error_t igraph_strvector_update( + igraph_strvector_t *to, const igraph_strvector_t *from); IGRAPH_EXPORT igraph_error_t igraph_strvector_resize( igraph_strvector_t* v, igraph_integer_t newsize); IGRAPH_EXPORT igraph_error_t igraph_strvector_push_back(igraph_strvector_t *v, diff --git a/src/vendor/cigraph/include/igraph_topology.h b/src/vendor/cigraph/include/igraph_topology.h index 3afd1e4f5cf..b217033fc17 100644 --- a/src/vendor/cigraph/include/igraph_topology.h +++ b/src/vendor/cigraph/include/igraph_topology.h @@ -57,6 +57,17 @@ IGRAPH_EXPORT igraph_error_t igraph_isomorphic(const igraph_t *graph1, const igr igraph_bool_t *iso); IGRAPH_EXPORT igraph_error_t igraph_subisomorphic(const igraph_t *graph1, const igraph_t *graph2, igraph_bool_t *iso); +IGRAPH_EXPORT igraph_error_t igraph_count_automorphisms( + const igraph_t *graph, const igraph_vector_int_t *colors, + igraph_real_t *result); +IGRAPH_EXPORT igraph_error_t igraph_automorphism_group( + const igraph_t *graph, const igraph_vector_int_t *colors, + igraph_vector_int_list_t *generators +); +IGRAPH_EXPORT igraph_error_t igraph_canonical_permutation( + const igraph_t *graph, const igraph_vector_int_t *colors, + igraph_vector_int_t *labeling +); /* LAD */ IGRAPH_EXPORT igraph_error_t igraph_subisomorphic_lad( @@ -264,7 +275,7 @@ typedef struct igraph_bliss_info_t { * \enumval IGRAPH_BLISS_FLM Largest maximally non-trivially connected * non-singleton cell. * \enumval IGRAPH_BLISS_FSM Smallest maximally non-trivially - * connected non-singletion cell. + * connected non-singleton cell. */ typedef enum { IGRAPH_BLISS_F = 0, IGRAPH_BLISS_FL, @@ -272,7 +283,7 @@ typedef enum { IGRAPH_BLISS_F = 0, IGRAPH_BLISS_FL, IGRAPH_BLISS_FLM, IGRAPH_BLISS_FSM } igraph_bliss_sh_t; -IGRAPH_EXPORT igraph_error_t igraph_canonical_permutation(const igraph_t *graph, const igraph_vector_int_t *colors, igraph_vector_int_t *labeling, +IGRAPH_EXPORT igraph_error_t igraph_canonical_permutation_bliss(const igraph_t *graph, const igraph_vector_int_t *colors, igraph_vector_int_t *labeling, igraph_bliss_sh_t sh, igraph_bliss_info_t *info); IGRAPH_EXPORT igraph_error_t igraph_isomorphic_bliss(const igraph_t *graph1, const igraph_t *graph2, const igraph_vector_int_t *colors1, const igraph_vector_int_t *colors2, @@ -281,15 +292,10 @@ IGRAPH_EXPORT igraph_error_t igraph_isomorphic_bliss(const igraph_t *graph1, con igraph_bliss_sh_t sh, igraph_bliss_info_t *info1, igraph_bliss_info_t *info2); -IGRAPH_EXPORT igraph_error_t igraph_count_automorphisms( - const igraph_t *graph, const igraph_vector_int_t *colors, - igraph_bliss_sh_t sh, igraph_bliss_info_t *info); - -IGRAPH_EXPORT IGRAPH_DEPRECATED igraph_error_t igraph_automorphisms( +IGRAPH_EXPORT igraph_error_t igraph_count_automorphisms_bliss( const igraph_t *graph, const igraph_vector_int_t *colors, igraph_bliss_sh_t sh, igraph_bliss_info_t *info); - -IGRAPH_EXPORT igraph_error_t igraph_automorphism_group( +IGRAPH_EXPORT igraph_error_t igraph_automorphism_group_bliss( const igraph_t *graph, const igraph_vector_int_t *colors, igraph_vector_int_list_t *generators, igraph_bliss_sh_t sh, igraph_bliss_info_t *info diff --git a/src/vendor/cigraph/include/igraph_typed_list_pmt.h b/src/vendor/cigraph/include/igraph_typed_list_pmt.h index 2110d5558d1..85731d9b566 100644 --- a/src/vendor/cigraph/include/igraph_typed_list_pmt.h +++ b/src/vendor/cigraph/include/igraph_typed_list_pmt.h @@ -51,6 +51,7 @@ typedef struct { /*--------------------*/ IGRAPH_EXPORT igraph_error_t FUNCTION(init)(TYPE* v, igraph_integer_t size); +IGRAPH_EXPORT igraph_error_t FUNCTION(init_copy)(TYPE* to, const TYPE* from); IGRAPH_EXPORT void FUNCTION(destroy)(TYPE* v); /*--------------------*/ diff --git a/src/vendor/cigraph/include/igraph_vector_pmt.h b/src/vendor/cigraph/include/igraph_vector_pmt.h index d324fece262..7772f73a209 100644 --- a/src/vendor/cigraph/include/igraph_vector_pmt.h +++ b/src/vendor/cigraph/include/igraph_vector_pmt.h @@ -103,7 +103,7 @@ IGRAPH_EXPORT igraph_error_t FUNCTION(igraph_vector, update)(TYPE(igraph_vector) const TYPE(igraph_vector) *from); IGRAPH_EXPORT igraph_error_t FUNCTION(igraph_vector, append)(TYPE(igraph_vector) *to, const TYPE(igraph_vector) *from); -IGRAPH_EXPORT igraph_error_t FUNCTION(igraph_vector, swap)(TYPE(igraph_vector) *v1, TYPE(igraph_vector) *v2); +IGRAPH_EXPORT void FUNCTION(igraph_vector, swap)(TYPE(igraph_vector) *v1, TYPE(igraph_vector) *v2); /*-----------------------*/ /* Exchanging elements */ @@ -114,7 +114,7 @@ IGRAPH_EXPORT igraph_error_t FUNCTION(igraph_vector, swap_elements)( IGRAPH_EXPORT igraph_error_t FUNCTION(igraph_vector, reverse)(TYPE(igraph_vector) *v); IGRAPH_EXPORT igraph_error_t FUNCTION(igraph_vector, permute)(TYPE(igraph_vector) *v, const igraph_vector_int_t *ind); -IGRAPH_EXPORT igraph_error_t FUNCTION(igraph_vector, shuffle)(TYPE(igraph_vector) *v); +IGRAPH_EXPORT void FUNCTION(igraph_vector, shuffle)(TYPE(igraph_vector) *v); /*-----------------------*/ /* Vector operations */ diff --git a/src/vendor/cigraph/interfaces/functions.yaml b/src/vendor/cigraph/interfaces/functions.yaml index d3e04847000..0cfd446fe12 100644 --- a/src/vendor/cigraph/interfaces/functions.yaml +++ b/src/vendor/cigraph/interfaces/functions.yaml @@ -34,7 +34,7 @@ igraph_delete_vertices: PARAMS: INOUT GRAPH graph, VERTEX_SELECTOR vertices DEPS: vertices ON graph -igraph_delete_vertices_idx: +igraph_delete_vertices_map: PARAMS: |- INOUT GRAPH graph, VERTEX_SELECTOR vertices, OPTIONAL OUT VECTOR_INT idx, @@ -113,12 +113,12 @@ igraph_sparse_weighted_adjacency: # construction to eliminate duplicate elements from the representation PARAMS: |- OUT GRAPH graph, INOUT SPARSEMAT adjmatrix, ADJACENCY_MODE mode=DIRECTED, - OUT EDGEWEIGHTS weights, LOOPS loops=ONCE + OUT EDGE_WEIGHTS weights, LOOPS loops=ONCE igraph_weighted_adjacency: PARAMS: |- OUT GRAPH graph, MATRIX adjmatrix, ADJACENCY_MODE mode=DIRECTED, - OUT EDGEWEIGHTS weights, LOOPS loops=ONCE + OUT EDGE_WEIGHTS weights, LOOPS loops=ONCE igraph_star: PARAMS: OUT GRAPH graph, INTEGER n, STAR_MODE mode=OUT, INTEGER center=0 @@ -236,7 +236,7 @@ igraph_erdos_renyi_game_gnp: PARAMS: OUT GRAPH graph, INTEGER n, REAL p, BOOLEAN directed=False, BOOLEAN loops=False igraph_erdos_renyi_game_gnm: - PARAMS: OUT GRAPH graph, INTEGER n, INTEGER m, BOOLEAN directed=False, BOOLEAN loops=False + PARAMS: OUT GRAPH graph, INTEGER n, INTEGER m, BOOLEAN directed=False, BOOLEAN loops=False, BOOLEAN multiple=False igraph_degree_sequence_game: PARAMS: |- @@ -426,7 +426,7 @@ igraph_diameter: igraph_diameter_dijkstra: PARAMS: |- - GRAPH graph, EDGEWEIGHTS weights=NULL, + GRAPH graph, EDGE_WEIGHTS weights=NULL, OUT REAL res, OUT INTEGER from, OUT INTEGER to, OPTIONAL OUT VECTOR_INT vertex_path, OPTIONAL OUT VECTOR_INT edge_path, @@ -435,21 +435,21 @@ igraph_diameter_dijkstra: igraph_closeness: PARAMS: |- - GRAPH graph, OUT VERTEX_QTY res, + GRAPH graph, OUT VERTEX_QTYS res, OPTIONAL OUT VECTOR_INT reachable_count, OPTIONAL OUT BOOLEAN all_reachable, VERTEX_SELECTOR vids=ALL, - NEIMODE mode=OUT, EDGEWEIGHTS weights=NULL, + NEIMODE mode=OUT, EDGE_WEIGHTS weights=NULL, BOOLEAN normalized=False DEPS: vids ON graph, weights ON graph, res ON graph vids igraph_closeness_cutoff: PARAMS: |- - GRAPH graph, OUT VERTEX_QTY res, + GRAPH graph, OUT VERTEX_QTYS res, OPTIONAL OUT VECTOR_INT reachable_count, OPTIONAL OUT BOOLEAN all_reachable, VERTEX_SELECTOR vids=ALL, - NEIMODE mode=OUT, EDGEWEIGHTS weights=NULL, + NEIMODE mode=OUT, EDGE_WEIGHTS weights=NULL, BOOLEAN normalized=False, REAL cutoff=-1 DEPS: vids ON graph, weights ON graph, res ON graph vids @@ -476,28 +476,28 @@ igraph_get_shortest_path_bellman_ford: PARAMS: |- GRAPH graph, OPTIONAL OUT VERTEX_INDICES vertices, OPTIONAL OUT EDGE_INDICES edges, - VERTEX from, VERTEX to, OPTIONAL EDGEWEIGHTS weights=NULL, NEIMODE mode=OUT + VERTEX from, VERTEX to, OPTIONAL EDGE_WEIGHTS weights=NULL, NEIMODE mode=OUT DEPS: from ON graph, to ON graph, weights ON graph, vertices ON graph, edges ON graph igraph_get_shortest_path_dijkstra: PARAMS: |- GRAPH graph, OPTIONAL OUT VERTEX_INDICES vertices, OPTIONAL OUT EDGE_INDICES edges, - VERTEX from, VERTEX to, OPTIONAL EDGEWEIGHTS weights=NULL, NEIMODE mode=OUT + VERTEX from, VERTEX to, OPTIONAL EDGE_WEIGHTS weights=NULL, NEIMODE mode=OUT DEPS: from ON graph, to ON graph, weights ON graph, vertices ON graph, edges ON graph igraph_get_shortest_path_astar: PARAMS: |- GRAPH graph, OPTIONAL OUT VERTEX_INDICES vertices, OPTIONAL OUT EDGE_INDICES edges, - VERTEX from, VERTEX to, OPTIONAL EDGEWEIGHTS weights=NULL, NEIMODE mode=OUT, + VERTEX from, VERTEX to, OPTIONAL EDGE_WEIGHTS weights=NULL, NEIMODE mode=OUT, OPTIONAL ASTAR_HEURISTIC_FUNC heuristic=NULL, EXTRA extra=NULL DEPS: from ON graph, to ON graph, weights ON graph, vertices ON graph, edges ON graph igraph_get_shortest_paths: PARAMS: |- GRAPH graph, - OPTIONAL OUT VERTEXSET_LIST vertices, OPTIONAL OUT EDGESET_LIST edges, + OPTIONAL OUT VERTEX_INDICES_LIST vertices, OPTIONAL OUT EDGE_INDICES_LIST edges, VERTEX from, VERTEX_SELECTOR to=ALL, NEIMODE mode=OUT, OPTIONAL OUT VECTOR_INT parents, OPTIONAL OUT VECTOR_INT inbound_edges @@ -505,28 +505,28 @@ igraph_get_shortest_paths: igraph_get_all_shortest_paths: PARAMS: |- - GRAPH graph, OPTIONAL OUT VERTEXSET_LIST vertices, - OPTIONAL OUT EDGESET_LIST edges, OPTIONAL OUT VECTOR_INT nrgeo, + GRAPH graph, OPTIONAL OUT VERTEX_INDICES_LIST vertices, + OPTIONAL OUT EDGE_INDICES_LIST edges, OPTIONAL OUT VECTOR_INT nrgeo, VERTEX from, VERTEX_SELECTOR to, NEIMODE mode=OUT DEPS: edges ON graph, from ON graph, to ON graph igraph_distances_dijkstra: PARAMS: |- GRAPH graph, OUT MATRIX res, VERTEX_SELECTOR from=ALL, - VERTEX_SELECTOR to=ALL, EDGEWEIGHTS weights, NEIMODE mode=OUT + VERTEX_SELECTOR to=ALL, EDGE_WEIGHTS weights, NEIMODE mode=OUT DEPS: from ON graph, to ON graph, weights ON graph igraph_distances_dijkstra_cutoff: PARAMS: |- GRAPH graph, OUT MATRIX res, VERTEX_SELECTOR from=ALL, - VERTEX_SELECTOR to=ALL, EDGEWEIGHTS weights, NEIMODE mode=OUT, REAL cutoff=-1 + VERTEX_SELECTOR to=ALL, EDGE_WEIGHTS weights, NEIMODE mode=OUT, REAL cutoff=-1 DEPS: from ON graph, to ON graph, weights ON graph igraph_get_shortest_paths_dijkstra: PARAMS: |- - GRAPH graph, OPTIONAL OUT VERTEXSET_LIST vertices, - OPTIONAL OUT EDGESET_LIST edges, VERTEX from, VERTEX_SELECTOR to=ALL, - EDGEWEIGHTS weights=NULL, NEIMODE mode=OUT, + GRAPH graph, OPTIONAL OUT VERTEX_INDICES_LIST vertices, + OPTIONAL OUT EDGE_INDICES_LIST edges, VERTEX from, VERTEX_SELECTOR to=ALL, + EDGE_WEIGHTS weights=NULL, NEIMODE mode=OUT, OPTIONAL OUT VECTOR_INT parents=0, OPTIONAL OUT VECTOR_INT inbound_edges=0 DEPS: |- @@ -535,9 +535,9 @@ igraph_get_shortest_paths_dijkstra: igraph_get_shortest_paths_bellman_ford: PARAMS: |- - GRAPH graph, OPTIONAL OUT VERTEXSET_LIST vertices, - OPTIONAL OUT EDGESET_LIST edges, VERTEX from, VERTEX_SELECTOR to=ALL, - EDGEWEIGHTS weights=NULL, NEIMODE mode=OUT, + GRAPH graph, OPTIONAL OUT VERTEX_INDICES_LIST vertices, + OPTIONAL OUT EDGE_INDICES_LIST edges, VERTEX from, VERTEX_SELECTOR to=ALL, + EDGE_WEIGHTS weights=NULL, NEIMODE mode=OUT, OPTIONAL OUT VECTOR_INT parents=0, OPTIONAL OUT VECTOR_INT inbound_edges=0 DEPS: |- @@ -546,9 +546,9 @@ igraph_get_shortest_paths_bellman_ford: igraph_get_all_shortest_paths_dijkstra: PARAMS: |- - GRAPH graph, OPTIONAL OUT VERTEXSET_LIST vertices, - OPTIONAL OUT EDGESET_LIST edges, OPTIONAL OUT VECTOR_INT nrgeo, - VERTEX from, VERTEX_SELECTOR to=ALL, EDGEWEIGHTS weights, + GRAPH graph, OPTIONAL OUT VERTEX_INDICES_LIST vertices, + OPTIONAL OUT EDGE_INDICES_LIST edges, OPTIONAL OUT VECTOR_INT nrgeo, + VERTEX from, VERTEX_SELECTOR to=ALL, EDGE_WEIGHTS weights, NEIMODE mode=OUT DEPS: |- weights ON graph, from ON graph, to ON graph, vertices ON graph, edges ON graph @@ -556,26 +556,26 @@ igraph_get_all_shortest_paths_dijkstra: igraph_distances_bellman_ford: PARAMS: |- GRAPH graph, OUT MATRIX res, VERTEX_SELECTOR from=ALL, - VERTEX_SELECTOR to=ALL, EDGEWEIGHTS weights, NEIMODE mode=OUT + VERTEX_SELECTOR to=ALL, EDGE_WEIGHTS weights, NEIMODE mode=OUT DEPS: from ON graph, to ON graph, weights ON graph igraph_distances_johnson: PARAMS: |- GRAPH graph, OUT MATRIX res, VERTEX_SELECTOR from=ALL, - VERTEX_SELECTOR to=ALL, EDGEWEIGHTS weights + VERTEX_SELECTOR to=ALL, EDGE_WEIGHTS weights=NULL, NEIMODE mode=OUT DEPS: from ON graph, to ON graph, weights ON graph igraph_distances_floyd_warshall: PARAMS: |- GRAPH graph, OUT MATRIX res, VERTEX_SELECTOR from=ALL, - VERTEX_SELECTOR to=ALL, EDGEWEIGHTS weights=NULL, NEIMODE mode=OUT, + VERTEX_SELECTOR to=ALL, EDGE_WEIGHTS weights=NULL, NEIMODE mode=OUT, FWALGORITHM method DEPS: from ON graph, to ON graph, weights ON graph igraph_voronoi: PARAMS: |- GRAPH graph, OUT VECTOR_INT membership, OUT VECTOR distances, - VERTEX_INDICES generators, EDGEWEIGHTS weights=NULL, NEIMODE mode=OUT, VORONOI_TIEBREAKER tiebreaker=RANDOM + VERTEX_INDICES generators, EDGE_WEIGHTS weights=NULL, NEIMODE mode=OUT, VORONOI_TIEBREAKER tiebreaker=RANDOM DEPS: weights ON graph, generators ON graph igraph_get_all_simple_paths: @@ -586,9 +586,9 @@ igraph_get_all_simple_paths: igraph_get_k_shortest_paths: PARAMS: |- - GRAPH graph, OPTIONAL EDGEWEIGHTS weights, - OPTIONAL OUT VERTEXSET_LIST vertex_paths, - OPTIONAL OUT EDGESET_LIST edge_paths, + GRAPH graph, OPTIONAL EDGE_WEIGHTS weights, + OPTIONAL OUT VERTEX_INDICES_LIST vertex_paths, + OPTIONAL OUT EDGE_INDICES_LIST edge_paths, INTEGER k, VERTEX from, VERTEX to, NEIMODE mode=OUT DEPS: |- from ON graph, to ON graph, weights ON graph, vertex_paths ON graph, edge_paths ON graph @@ -597,15 +597,15 @@ igraph_get_widest_path: PARAMS: |- GRAPH graph, OPTIONAL OUT VERTEX_INDICES vertices, OPTIONAL OUT EDGE_INDICES edges, - VERTEX from, VERTEX to, EDGEWEIGHTS weights=NULL, NEIMODE mode=OUT + VERTEX from, VERTEX to, EDGE_WEIGHTS weights=NULL, NEIMODE mode=OUT DEPS: |- from ON graph, to ON graph, weights ON graph, vertices ON graph, edges ON graph igraph_get_widest_paths: PARAMS: |- GRAPH graph, - OPTIONAL OUT VERTEXSET_LIST vertices, OPTIONAL OUT EDGESET_LIST edges, - VERTEX from, VERTEX_SELECTOR to=ALL, EDGEWEIGHTS weights=NULL, + OPTIONAL OUT VERTEX_INDICES_LIST vertices, OPTIONAL OUT EDGE_INDICES_LIST edges, + VERTEX from, VERTEX_SELECTOR to=ALL, EDGE_WEIGHTS weights=NULL, NEIMODE mode=OUT, OPTIONAL OUT VECTOR_INT parents, OPTIONAL OUT VECTOR_INT inbound_edges DEPS: |- @@ -615,18 +615,18 @@ igraph_get_widest_paths: igraph_widest_path_widths_dijkstra: PARAMS: |- GRAPH graph, OUT MATRIX res, VERTEX_SELECTOR from=ALL, - VERTEX_SELECTOR to=ALL, EDGEWEIGHTS weights, NEIMODE mode=OUT + VERTEX_SELECTOR to=ALL, EDGE_WEIGHTS weights, NEIMODE mode=OUT DEPS: from ON graph, to ON graph, weights ON graph igraph_widest_path_widths_floyd_warshall: PARAMS: |- GRAPH graph, OUT MATRIX res, VERTEX_SELECTOR from=ALL, - VERTEX_SELECTOR to=ALL, EDGEWEIGHTS weights, NEIMODE mode=OUT + VERTEX_SELECTOR to=ALL, EDGE_WEIGHTS weights, NEIMODE mode=OUT DEPS: from ON graph, to ON graph, weights ON graph igraph_spanner: PARAMS: |- - GRAPH graph, OUT EDGE_INDICES spanner, REAL stretch, OPTIONAL EDGEWEIGHTS weights + GRAPH graph, OUT EDGE_INDICES spanner, REAL stretch, OPTIONAL EDGE_WEIGHTS weights DEPS: weights ON graph igraph_subcomponent: @@ -635,64 +635,64 @@ igraph_subcomponent: igraph_betweenness: PARAMS: |- - GRAPH graph, OUT VERTEX_QTY res, VERTEX_SELECTOR vids=ALL, - BOOLEAN directed=True, EDGEWEIGHTS weights=NULL + GRAPH graph, OUT VERTEX_QTYS res, VERTEX_SELECTOR vids=ALL, + BOOLEAN directed=True, EDGE_WEIGHTS weights=NULL DEPS: weights ON graph, vids ON graph, res ON graph vids igraph_betweenness_cutoff: PARAMS: |- - GRAPH graph, OUT VERTEX_QTY res, VERTEX_SELECTOR vids=ALL, - BOOLEAN directed=True, EDGEWEIGHTS weights=NULL, + GRAPH graph, OUT VERTEX_QTYS res, VERTEX_SELECTOR vids=ALL, + BOOLEAN directed=True, EDGE_WEIGHTS weights=NULL, REAL cutoff=-1 DEPS: vids ON graph, weights ON graph, res ON graph vids igraph_betweenness_subset: PARAMS: |- - GRAPH graph, OUT VERTEX_QTY res, VERTEX_SELECTOR vids=ALL, + GRAPH graph, OUT VERTEX_QTYS res, VERTEX_SELECTOR vids=ALL, BOOLEAN directed=True, VERTEX_SELECTOR sources=ALL, VERTEX_SELECTOR targets=ALL, - EDGEWEIGHTS weights=NULL + EDGE_WEIGHTS weights=NULL DEPS: |- vids ON graph, weights ON graph, res ON graph, sources ON graph, targets ON graph igraph_edge_betweenness: PARAMS: |- GRAPH graph, OUT VECTOR res, BOOLEAN directed=True, - EDGEWEIGHTS weights=NULL + EDGE_WEIGHTS weights=NULL DEPS: weights ON graph igraph_edge_betweenness_cutoff: PARAMS: |- GRAPH graph, OUT VECTOR res, BOOLEAN directed=True, - EDGEWEIGHTS weights=NULL, REAL cutoff=-1 + EDGE_WEIGHTS weights=NULL, REAL cutoff=-1 DEPS: weights ON graph igraph_edge_betweenness_subset: PARAMS: |- - GRAPH graph, OUT VECTOR res, EDGE_SELECTOR eids=ALL, + GRAPH graph, OUT VERTEX_QTYS res, EDGE_SELECTOR eids=ALL, BOOLEAN directed=True, VERTEX_SELECTOR sources=ALL, VERTEX_SELECTOR targets=ALL, - EDGEWEIGHTS weights=NULL + EDGE_WEIGHTS weights=NULL DEPS: |- eids ON graph, weights ON graph, res ON graph, sources ON graph, targets ON graph igraph_harmonic_centrality: PARAMS: |- - GRAPH graph, OUT VERTEX_QTY res, VERTEX_SELECTOR vids=ALL, - NEIMODE mode=OUT, EDGEWEIGHTS weights=NULL, BOOLEAN normalized=False + GRAPH graph, OUT VERTEX_QTYS res, VERTEX_SELECTOR vids=ALL, + NEIMODE mode=OUT, EDGE_WEIGHTS weights=NULL, BOOLEAN normalized=False DEPS: weights ON graph, vids ON graph, res ON graph vids igraph_harmonic_centrality_cutoff: PARAMS: |- - GRAPH graph, OUT VERTEX_QTY res, VERTEX_SELECTOR vids=ALL, - NEIMODE mode=OUT, EDGEWEIGHTS weights=NULL, BOOLEAN normalized=False, + GRAPH graph, OUT VERTEX_QTYS res, VERTEX_SELECTOR vids=ALL, + NEIMODE mode=OUT, EDGE_WEIGHTS weights=NULL, BOOLEAN normalized=False, REAL cutoff=-1 DEPS: vids ON graph, weights ON graph, res ON graph vids igraph_pagerank: PARAMS: |- GRAPH graph, PAGERANKALGO algo=PRPACK, - OUT VERTEX_QTY vector, OUT REAL value, + OUT VERTEX_QTYS vector, OUT REAL value, VERTEX_SELECTOR vids=ALL, BOOLEAN directed=True, - REAL damping=0.85, EDGEWEIGHTS weights=NULL, + REAL damping=0.85, EDGE_WEIGHTS weights=NULL, INOUT PAGERANKOPT options=NULL DEPS: |- vids ON graph, weights ON graph, vector ON graph, @@ -701,10 +701,10 @@ igraph_pagerank: igraph_personalized_pagerank: PARAMS: |- GRAPH graph, PAGERANKALGO algo=PRPACK, - OUT VERTEX_QTY vector, OUT REAL value, + OUT VERTEX_QTYS vector, OUT REAL value, VERTEX_SELECTOR vids=ALL, BOOLEAN directed=True, REAL damping=0.85, OPTIONAL VECTOR personalized, - OPTIONAL EDGEWEIGHTS weights, + OPTIONAL EDGE_WEIGHTS weights, INOUT PAGERANKOPT options=NULL DEPS: |- vids ON graph, weights ON graph, vector ON graph vids, @@ -713,11 +713,11 @@ igraph_personalized_pagerank: igraph_personalized_pagerank_vs: PARAMS: |- GRAPH graph, PAGERANKALGO algo=PRPACK, - PRIMARY OUT VERTEX_QTY vector, OUT REAL value, + PRIMARY OUT VERTEX_QTYS vector, OUT REAL value, VERTEX_SELECTOR vids=ALL, BOOLEAN directed=True, REAL damping=0.85, VERTEX_SELECTOR reset_vids, - OPTIONAL EDGEWEIGHTS weights=NULL, + OPTIONAL EDGE_WEIGHTS weights=NULL, INOUT PAGERANKOPT options=NULL DEPS: |- vids ON graph, weights ON graph, vector ON graph vids, @@ -744,7 +744,7 @@ igraph_average_path_length: igraph_average_path_length_dijkstra: PARAMS: GRAPH graph, PRIMARY OUT REAL res, OUT REAL unconn_pairs=NULL, - EDGEWEIGHTS weights=NULL, BOOLEAN directed=True, BOOLEAN unconn=True + EDGE_WEIGHTS weights=NULL, BOOLEAN directed=True, BOOLEAN unconn=True DEPS: weights ON graph igraph_path_length_hist: @@ -771,7 +771,7 @@ igraph_transitivity_avglocal_undirected: igraph_transitivity_barrat: PARAMS: |- GRAPH graph, OUT VECTOR res, VERTEX_SELECTOR vids=ALL, - EDGEWEIGHTS weights=NULL, TRANSITIVITY_MODE mode=NAN + EDGE_WEIGHTS weights=NULL, TRANSITIVITY_MODE mode=NAN DEPS: res ON graph, vids ON graph, weights ON graph igraph_ecc: @@ -786,7 +786,7 @@ igraph_reciprocity: RECIP mode=DEFAULT igraph_constraint: - PARAMS: GRAPH graph, OUT VECTOR res, VERTEX_SELECTOR vids=ALL, OPTIONAL EDGEWEIGHTS weights + PARAMS: GRAPH graph, OUT VECTOR res, VERTEX_SELECTOR vids=ALL, OPTIONAL EDGE_WEIGHTS weights DEPS: vids ON graph, weights ON graph igraph_maxdegree: @@ -806,7 +806,7 @@ igraph_neighborhood_size: igraph_neighborhood: PARAMS: |- - GRAPH graph, OUT VERTEXSET_LIST res, + GRAPH graph, OUT VERTEX_INDICES_LIST res, VERTEX_SELECTOR vids, INTEGER order, NEIMODE mode=ALL, INTEGER mindist=0 DEPS: res ON graph, vids ON graph @@ -824,7 +824,7 @@ igraph_topological_sorting: igraph_feedback_arc_set: # Default algorithm is the approximate method because it is faster and the # function is _not_ called igraph_minimum_feedback_arc_set - PARAMS: GRAPH graph, OUT EDGE_INDICES result, EDGEWEIGHTS weights=NULL, FAS_ALGORITHM algo=APPROX_EADES + PARAMS: GRAPH graph, OUT EDGE_INDICES result, EDGE_WEIGHTS weights=NULL, FAS_ALGORITHM algo=APPROX_EADES DEPS: result ON graph, weights ON graph igraph_is_loop: @@ -866,31 +866,31 @@ igraph_add_edge: igraph_eigenvector_centrality: PARAMS: |- - GRAPH graph, OUT VERTEX_QTY vector, OUT REAL value, + GRAPH graph, OUT VERTEX_QTYS vector, OUT REAL value, BOOLEAN directed=False, BOOLEAN scale=True, - EDGEWEIGHTS weights=NULL, - INOUT ARPACKOPT options=ARPACK_DEFAULTS + EDGE_WEIGHTS weights=NULL, + INOUT ARPACK_OPTIONS options=ARPACK_DEFAULTS DEPS: weights ON graph, vector ON graph igraph_hub_score: PARAMS: |- - GRAPH graph, OUT VERTEX_QTY vector, OUT REAL value, - BOOLEAN scale=True, EDGEWEIGHTS weights=NULL, - INOUT ARPACKOPT options=ARPACK_DEFAULTS + GRAPH graph, OUT VERTEX_QTYS vector, OUT REAL value, + BOOLEAN scale=True, EDGE_WEIGHTS weights=NULL, + INOUT ARPACK_OPTIONS options=ARPACK_DEFAULTS DEPS: weights ON graph, vector ON graph igraph_authority_score: PARAMS: |- - GRAPH graph, OUT VERTEX_QTY vector, OUT REAL value, - BOOLEAN scale=True, EDGEWEIGHTS weights=NULL, - INOUT ARPACKOPT options=ARPACK_DEFAULTS + GRAPH graph, OUT VERTEX_QTYS vector, OUT REAL value, + BOOLEAN scale=True, EDGE_WEIGHTS weights=NULL, + INOUT ARPACK_OPTIONS options=ARPACK_DEFAULTS DEPS: weights ON graph, vector ON graph igraph_hub_and_authority_scores: PARAMS: |- - GRAPH graph, OUT VERTEX_QTY hub_vector, OUT VERTEX_QTY authority_vector, - OUT REAL value, BOOLEAN scale=True, EDGEWEIGHTS weights=NULL, - INOUT ARPACKOPT options=ARPACK_DEFAULTS + GRAPH graph, OUT VERTEX_QTYS hub_vector, OUT VERTEX_QTYS authority_vector, + OUT REAL value, BOOLEAN scale=True, EDGE_WEIGHTS weights=NULL, + INOUT ARPACK_OPTIONS options=ARPACK_DEFAULTS igraph_unfold_tree: PARAMS: |- @@ -919,13 +919,13 @@ igraph_avg_nearest_neighbor_degree: PARAMS: |- GRAPH graph, VERTEX_SELECTOR vids=ALL, NEIMODE mode=ALL, NEIMODE neighbor_degree_mode=ALL, - OPTIONAL OUT VERTEX_QTY knn, OPTIONAL OUT VECTOR knnk, - EDGEWEIGHTS weights=NULL + OPTIONAL OUT VERTEX_QTYS knn, OPTIONAL OUT VECTOR knnk, + EDGE_WEIGHTS weights=NULL DEPS: vids ON graph, weights ON graph, knn ON graph vids igraph_degree_correlation_vector: PARAMS: |- - GRAPH graph, EDGEWEIGHTS weights=NULL, + GRAPH graph, EDGE_WEIGHTS weights=NULL, OUT VECTOR knnk, NEIMODE from_mode=OUT, NEIMODE to_mode=IN, BOOLEAN directed_neighbors=True @@ -933,8 +933,8 @@ igraph_degree_correlation_vector: igraph_strength: PARAMS: |- - GRAPH graph, OUT VERTEX_QTY res, VERTEX_SELECTOR vids=ALL, - NEIMODE mode=ALL, BOOLEAN loops=True, EDGEWEIGHTS weights=NULL + GRAPH graph, OUT VERTEX_QTYS res, VERTEX_SELECTOR vids=ALL, + NEIMODE mode=ALL, BOOLEAN loops=True, EDGE_WEIGHTS weights=NULL DEPS: vids ON graph, weights ON graph, res ON graph vids igraph_centralization: @@ -985,7 +985,7 @@ igraph_centralization_eigenvector_centrality: PARAMS: |- GRAPH graph, OUT VECTOR vector, OUT REAL value, BOOLEAN directed=False, BOOLEAN scale=True, - INOUT ARPACKOPT options=ARPACK_DEFAULTS, + INOUT ARPACK_OPTIONS options=ARPACK_DEFAULTS, OUT REAL centralization, OUT REAL theoretical_max, BOOLEAN normalized=True @@ -1010,14 +1010,14 @@ igraph_assortativity_degree: igraph_joint_degree_matrix: PARAMS: |- - GRAPH graph, EDGEWEIGHTS weights=NULL, + GRAPH graph, EDGE_WEIGHTS weights=NULL, OUT MATRIX jdm, INTEGER max_out_degree=-1, INTEGER max_in_degree=-1 DEPS: weights ON graph igraph_joint_degree_distribution: PARAMS: |- - GRAPH graph, EDGEWEIGHTS weights=NULL, + GRAPH graph, EDGE_WEIGHTS weights=NULL, OUT MATRIX p, NEIMODE from_mode=OUT, NEIMODE to_mode=IN, BOOLEAN directed_neighbors=True, @@ -1027,7 +1027,7 @@ igraph_joint_degree_distribution: igraph_joint_type_distribution: PARAMS: |- - GRAPH graph, EDGEWEIGHTS weights=NULL, + GRAPH graph, EDGE_WEIGHTS weights=NULL, OUT MATRIX p, INDEX_VECTOR from_types, INDEX_VECTOR to_types=NULL, BOOLEAN directed=True, @@ -1041,14 +1041,14 @@ igraph_contract_vertices: igraph_eccentricity: PARAMS: |- - GRAPH graph, OUT VERTEX_QTY res, VERTEX_SELECTOR vids=ALL, + GRAPH graph, OUT VERTEX_QTYS res, VERTEX_SELECTOR vids=ALL, NEIMODE mode=ALL DEPS: vids ON graph, res ON graph vids igraph_eccentricity_dijkstra: PARAMS: |- - GRAPH graph, EDGEWEIGHTS weights=NULL, - OUT VERTEX_QTY res, VERTEX_SELECTOR vids=ALL, + GRAPH graph, EDGE_WEIGHTS weights=NULL, + OUT VERTEX_QTYS res, VERTEX_SELECTOR vids=ALL, NEIMODE mode=ALL DEPS: weights ON graph, vids ON graph, res ON graph vids @@ -1059,14 +1059,14 @@ igraph_graph_center: igraph_graph_center_dijkstra: PARAMS: |- - GRAPH graph, EDGEWEIGHTS weights=NULL, OUT VERTEX_INDICES res, NEIMODE mode=ALL + GRAPH graph, EDGE_WEIGHTS weights=NULL, OUT VERTEX_INDICES res, NEIMODE mode=ALL DEPS: weights ON graph, res ON graph igraph_radius: PARAMS: GRAPH graph, OUT REAL radius, NEIMODE mode=ALL igraph_radius_dijkstra: - PARAMS: GRAPH graph, EDGEWEIGHTS weights=NULL, OUT REAL radius, NEIMODE mode=ALL + PARAMS: GRAPH graph, EDGE_WEIGHTS weights=NULL, OUT REAL radius, NEIMODE mode=ALL DEPS: weights ON graph igraph_pseudo_diameter: @@ -1077,7 +1077,7 @@ igraph_pseudo_diameter: igraph_pseudo_diameter_dijkstra: PARAMS: |- - GRAPH graph, EDGEWEIGHTS weights=NULL, + GRAPH graph, EDGE_WEIGHTS weights=NULL, OUT REAL diameter, VERTEX start_vid, OUT INTEGER from=NULL, OUT INTEGER to=NULL, BOOLEAN directed=True, BOOLEAN unconnected=True @@ -1085,35 +1085,35 @@ igraph_pseudo_diameter_dijkstra: igraph_diversity: PARAMS: |- - GRAPH graph, EDGEWEIGHTS weights=NULL, OUT VERTEX_QTY res, + GRAPH graph, EDGE_WEIGHTS weights=NULL, OUT VERTEX_QTYS res, VERTEX_SELECTOR vids=ALL DEPS: weights ON graph, vids ON graph, res ON graph vids igraph_random_walk: PARAMS: |- - GRAPH graph, EDGEWEIGHTS weights=NULL, OUT VERTEX_INDICES vertices, OUT EDGE_INDICES edges, + GRAPH graph, EDGE_WEIGHTS weights=NULL, OUT VERTEX_INDICES vertices, OUT EDGE_INDICES edges, VERTEX start, NEIMODE mode=OUT, INTEGER steps, RWSTUCK stuck=RETURN DEPS: start ON graph, weights ON graph, vertices ON graph, edges ON graph igraph_random_edge_walk: PARAMS: |- - GRAPH graph, EDGEWEIGHTS weights=NULL, OUT EDGE_INDICES edgewalk, + GRAPH graph, EDGE_WEIGHTS weights=NULL, OUT EDGE_INDICES edgewalk, VERTEX start, NEIMODE mode=OUT, INTEGER steps, RWSTUCK stuck=RETURN DEPS: start ON graph, weights ON graph, edgewalk ON graph igraph_global_efficiency: - PARAMS: GRAPH graph, OUT REAL res, EDGEWEIGHTS weights=NULL, BOOLEAN directed=True + PARAMS: GRAPH graph, OUT REAL res, EDGE_WEIGHTS weights=NULL, BOOLEAN directed=True DEPS: weights ON graph igraph_local_efficiency: PARAMS: |- - GRAPH graph, OUT VERTEX_QTY res, VERTEX_SELECTOR vids=ALL, - EDGEWEIGHTS weights=NULL, BOOLEAN directed=True, NEIMODE mode=ALL + GRAPH graph, OUT VERTEX_QTYS res, VERTEX_SELECTOR vids=ALL, + EDGE_WEIGHTS weights=NULL, BOOLEAN directed=True, NEIMODE mode=ALL DEPS: vids ON graph, weights ON graph, res ON graph vids igraph_average_local_efficiency: PARAMS: |- - GRAPH graph, OUT REAL res, EDGEWEIGHTS weights=NULL, + GRAPH graph, OUT REAL res, EDGE_WEIGHTS weights=NULL, BOOLEAN directed=True, NEIMODE mode=ALL DEPS: weights ON graph @@ -1215,7 +1215,7 @@ igraph_bipartite_game_gnm: PARAMS: |- OUT GRAPH graph, OPTIONAL OUT BIPARTITE_TYPES types, INTEGER n1, INTEGER n2, INTEGER m, BOOLEAN directed=False, - NEIMODE mode=ALL + NEIMODE mode=ALL, BOOLEAN multiple=False igraph_bipartite_game: PARAMS: |- @@ -1231,13 +1231,13 @@ igraph_bipartite_game: igraph_get_laplacian: PARAMS: |- GRAPH graph, OUT MATRIX res, NEIMODE mode=OUT, - LAPLACIAN_NORMALIZATION normalization=UNNORMALIZED, EDGEWEIGHTS weights=NULL + LAPLACIAN_NORMALIZATION normalization=UNNORMALIZED, EDGE_WEIGHTS weights=NULL DEPS: weights ON graph igraph_get_laplacian_sparse: PARAMS: |- GRAPH graph, OUT SPARSEMAT sparseres, NEIMODE mode=OUT, - LAPLACIAN_NORMALIZATION normalization=UNNORMALIZED, EDGEWEIGHTS weights=NULL + LAPLACIAN_NORMALIZATION normalization=UNNORMALIZED, EDGE_WEIGHTS weights=NULL DEPS: weights ON graph ####################################### @@ -1264,9 +1264,9 @@ igraph_articulation_points: igraph_biconnected_components: PARAMS: |- GRAPH graph, OUT INTEGER no, - OPTIONAL OUT EDGESET_LIST tree_edges, - OPTIONAL OUT EDGESET_LIST component_edges, - OPTIONAL OUT VERTEXSET_LIST components, + OPTIONAL OUT EDGE_INDICES_LIST tree_edges, + OPTIONAL OUT EDGE_INDICES_LIST component_edges, + OPTIONAL OUT VERTEX_INDICES_LIST components, OUT VERTEX_INDICES articulation_points DEPS: |- tree_edges ON graph, component_edges ON graph, @@ -1285,7 +1285,7 @@ igraph_is_biconnected: igraph_cliques: PARAMS: |- - GRAPH graph, OUT VERTEXSET_LIST res, INTEGER min_size=0, + GRAPH graph, OUT VERTEX_INDICES_LIST res, INTEGER min_size=0, INTEGER max_size=0 DEPS: res ON graph @@ -1299,16 +1299,16 @@ igraph_clique_size_hist: GRAPH graph, OUT VECTOR hist, INTEGER min_size=0, INTEGER max_size=0 igraph_largest_cliques: - PARAMS: GRAPH graph, OUT VERTEXSET_LIST res + PARAMS: GRAPH graph, OUT VERTEX_INDICES_LIST res DEPS: res ON graph igraph_maximal_cliques: - PARAMS: GRAPH graph, OUT VERTEXSET_LIST res, INTEGER min_size=0, INTEGER max_size=0 + PARAMS: GRAPH graph, OUT VERTEX_INDICES_LIST res, INTEGER min_size=0, INTEGER max_size=0 DEPS: res ON graph igraph_maximal_cliques_subset: PARAMS: |- - GRAPH graph, VERTEX_INDICES subset, PRIMARY OUT VERTEXSET_LIST res, + GRAPH graph, VERTEX_INDICES subset, PRIMARY OUT VERTEX_INDICES_LIST res, OUT INTEGER no, OUTFILE outfile=NULL, INTEGER min_size=0, INTEGER max_size=0 DEPS: subset ON graph, res ON graph @@ -1334,31 +1334,31 @@ igraph_clique_number: igraph_weighted_cliques: PARAMS: |- - GRAPH graph, VERTEXWEIGHTS vertex_weights=NULL, OUT VERTEXSET_LIST res, + GRAPH graph, VERTEX_WEIGHTS vertex_weights=NULL, OUT VERTEX_INDICES_LIST res, REAL min_weight=0, REAL max_weight=0, BOOLEAN maximal=False DEPS: vertex_weights ON graph, res ON graph igraph_largest_weighted_cliques: PARAMS: |- - GRAPH graph, VERTEXWEIGHTS vertex_weights=NULL, OUT VERTEXSET_LIST res + GRAPH graph, VERTEX_WEIGHTS vertex_weights=NULL, OUT VERTEX_INDICES_LIST res DEPS: vertex_weights ON graph, res ON graph igraph_weighted_clique_number: - PARAMS: GRAPH graph, VERTEXWEIGHTS vertex_weights=NULL, OUT REAL res + PARAMS: GRAPH graph, VERTEX_WEIGHTS vertex_weights=NULL, OUT REAL res DEPS: vertex_weights ON graph igraph_independent_vertex_sets: PARAMS: |- - GRAPH graph, OUT VERTEXSET_LIST res, INTEGER min_size=0, + GRAPH graph, OUT VERTEX_INDICES_LIST res, INTEGER min_size=0, INTEGER max_size=0 DEPS: res ON graph igraph_largest_independent_vertex_sets: - PARAMS: GRAPH graph, OUT VERTEXSET_LIST res + PARAMS: GRAPH graph, OUT VERTEX_INDICES_LIST res DEPS: res ON graph igraph_maximal_independent_vertex_sets: - PARAMS: GRAPH graph, OUT VERTEXSET_LIST res + PARAMS: GRAPH graph, OUT VERTEX_INDICES_LIST res DEPS: res ON graph igraph_independence_number: @@ -1392,7 +1392,7 @@ igraph_layout_fruchterman_reingold: GRAPH graph, INOUT MATRIX coords=NULL, BOOLEAN use_seed=False, INTEGER niter=500, REAL start_temp=sqrt(vcount(graph)), - LAYOUT_GRID grid=AUTO, EDGEWEIGHTS weights=NULL, + LAYOUT_GRID grid=AUTO, EDGE_WEIGHTS weights=NULL, OPTIONAL VECTOR minx, OPTIONAL VECTOR maxx, OPTIONAL VECTOR miny, OPTIONAL VECTOR maxy, DEPRECATED coolexp, DEPRECATED maxdelta, DEPRECATED area, @@ -1403,7 +1403,7 @@ igraph_layout_kamada_kawai: PARAMS: |- GRAPH graph, INOUT MATRIX coords, BOOLEAN use_seed=False, INTEGER maxiter=500, REAL epsilon=0.0, - REAL kkconst=vcount(graph), EDGEWEIGHTS weights=NULL, + REAL kkconst=vcount(graph), EDGE_WEIGHTS weights=NULL, OPTIONAL VECTOR minx, OPTIONAL VECTOR maxx, OPTIONAL VECTOR miny, OPTIONAL VECTOR maxy DEPS: weights ON graph @@ -1440,7 +1440,7 @@ igraph_layout_fruchterman_reingold_3d: GRAPH graph, INOUT MATRIX coords=NULL, BOOLEAN use_seed=False, INTEGER niter=500, REAL start_temp=sqrt(vcount(graph)), - EDGEWEIGHTS weights=NULL, + EDGE_WEIGHTS weights=NULL, OPTIONAL VECTOR minx, OPTIONAL VECTOR maxx, OPTIONAL VECTOR miny, OPTIONAL VECTOR maxy, OPTIONAL VECTOR minz, OPTIONAL VECTOR maxz, @@ -1452,7 +1452,7 @@ igraph_layout_kamada_kawai_3d: PARAMS: |- GRAPH graph, INOUT MATRIX coords, BOOLEAN use_seed=False, INTEGER maxiter=500, REAL epsilon=0.0, - REAL kkconst=vcount(graph), EDGEWEIGHTS weights=NULL, + REAL kkconst=vcount(graph), EDGE_WEIGHTS weights=NULL, OPTIONAL VECTOR minx, OPTIONAL VECTOR maxx, OPTIONAL VECTOR miny, OPTIONAL VECTOR maxy, OPTIONAL VECTOR minz, OPTIONAL VECTOR maxz @@ -1468,12 +1468,12 @@ igraph_layout_graphopt: igraph_layout_drl: PARAMS: |- GRAPH graph, INOUT MATRIX res, BOOLEAN use_seed=False, - DRL_OPTIONS options=drl_defaults$default, OPTIONAL EDGEWEIGHTS weights + DRL_OPTIONS options=drl_defaults$default, OPTIONAL EDGE_WEIGHTS weights igraph_layout_drl_3d: PARAMS: |- GRAPH graph, INOUT MATRIX res, BOOLEAN use_seed=False, - DRL_OPTIONS options=drl_defaults$default, OPTIONAL EDGEWEIGHTS weights + DRL_OPTIONS options=drl_defaults$default, OPTIONAL EDGE_WEIGHTS weights igraph_layout_merge_dla: PARAMS: GRAPH_PTR_LIST graphs, MATRIX_LIST coords, OUT MATRIX res @@ -1484,7 +1484,7 @@ igraph_layout_sugiyama: OPTIONAL OUT INDEX_VECTOR extd_to_orig_eids, OPTIONAL INDEX_VECTOR layers=NULL, REAL hgap=1, REAL vgap=1, INTEGER maxiter=100, - EDGEWEIGHTS weights=NULL + EDGE_WEIGHTS weights=NULL DEPS: weights ON graph igraph_layout_mds: @@ -1545,9 +1545,9 @@ igraph_bibcoupling: igraph_similarity_dice: PARAMS: |- - GRAPH graph, OUT MATRIX res, VERTEX_SELECTOR vids=ALL, NEIMODE mode=ALL, + GRAPH graph, OUT MATRIX res, VERTEX_SELECTOR vit_from=ALL, VERTEX_SELECTOR vit_to=ALL, NEIMODE mode=ALL, BOOLEAN loops=False - DEPS: vids ON graph + DEPS: vit_from ON graph, vit_to ON graph, res ON vit_from, res ON vit_to igraph_similarity_dice_es: PARAMS: |- @@ -1567,9 +1567,9 @@ igraph_similarity_inverse_log_weighted: igraph_similarity_jaccard: PARAMS: |- - GRAPH graph, OUT MATRIX res, VERTEX_SELECTOR vids=ALL, NEIMODE mode=ALL, + GRAPH graph, OUT MATRIX res, VERTEX_SELECTOR vit_from=ALL, VERTEX_SELECTOR vit_to=ALL, NEIMODE mode=ALL, BOOLEAN loops=False - DEPS: vids ON graph res, mode ON vids + DEPS: vit_from ON graph, vit_to ON graph, res ON vit_from, res ON vit_to igraph_similarity_jaccard_es: PARAMS: |- @@ -1593,7 +1593,7 @@ igraph_compare_communities: igraph_community_spinglass: PARAMS: |- - GRAPH graph, OPTIONAL EDGEWEIGHTS weights, OUT REAL modularity, + GRAPH graph, OPTIONAL EDGE_WEIGHTS weights, OUT REAL modularity, OUT REAL temperature, OUT VECTOR_INT membership, OUT VECTOR_INT csize, INTEGER spins=25, BOOLEAN parupdate=False, REAL starttemp=1, REAL stoptemp=0.01, REAL coolfact=0.99, SPINCOMMUPDATE update_rule=CONFIG, REAL gamma=1.0, @@ -1602,15 +1602,15 @@ igraph_community_spinglass: igraph_community_spinglass_single: PARAMS: |- - GRAPH graph, OPTIONAL EDGEWEIGHTS weights, INTEGER vertex, + GRAPH graph, OPTIONAL EDGE_WEIGHTS weights, INTEGER vertex, OUT VECTOR_INT community, OUT REAL cohesion, OUT REAL adhesion, - OUT INTEGER inner_links, OUT INTEGER outer_links, + OUT REAL inner_links, OUT REAL outer_links, INTEGER spins=25, SPINCOMMUPDATE update_rule=CONFIG, REAL gamma=1.0 DEPS: weights ON graph igraph_community_walktrap: PARAMS: |- - GRAPH graph, OPTIONAL EDGEWEIGHTS weights, INTEGER steps=4, + GRAPH graph, OPTIONAL EDGE_WEIGHTS weights, INTEGER steps=4, OUT MATRIX_INT merges, OUT VECTOR modularity, OUT VECTOR_INT membership DEPS: weights ON graph @@ -1619,19 +1619,19 @@ igraph_community_edge_betweenness: GRAPH graph, OUT VECTOR_INT removed_edges, OPTIONAL OUT VECTOR edge_betweenness, OPTIONAL OUT MATRIX_INT merges, OPTIONAL OUT INDEX_VECTOR bridges, OPTIONAL OUT VECTOR modularity, OPTIONAL OUT VECTOR_INT membership, - BOOLEAN directed=True, OPTIONAL EDGEWEIGHTS weights=NULL + BOOLEAN directed=True, OPTIONAL EDGE_WEIGHTS weights=NULL DEPS: weights ON graph igraph_community_eb_get_merges: PARAMS: |- - GRAPH graph, BOOLEAN directed, EDGE_INDICES edges, OPTIONAL EDGEWEIGHTS weights, + GRAPH graph, BOOLEAN directed, EDGE_INDICES edges, OPTIONAL EDGE_WEIGHTS weights, OPTIONAL OUT MATRIX_INT merges, OPTIONAL OUT INDEX_VECTOR bridges, OPTIONAL OUT VECTOR modularity, OPTIONAL OUT VECTOR_INT membership DEPS: weights ON graph igraph_community_fastgreedy: PARAMS: |- - GRAPH graph, OPTIONAL EDGEWEIGHTS weights, OUT MATRIX_INT merges, + GRAPH graph, OPTIONAL EDGE_WEIGHTS weights, OUT MATRIX_INT merges, OPTIONAL OUT VECTOR modularity, OPTIONAL OUT VECTOR_INT membership DEPS: weights ON graph @@ -1647,14 +1647,14 @@ igraph_le_community_to_membership: igraph_modularity: PARAMS: |- - GRAPH graph, VECTOR_INT membership, OPTIONAL EDGEWEIGHTS weights=NULL, + GRAPH graph, VECTOR_INT membership, OPTIONAL EDGE_WEIGHTS weights=NULL, REAL resolution=1.0, BOOLEAN directed=True, OUT REAL modularity DEPS: weights ON graph igraph_modularity_matrix: PARAMS: |- GRAPH graph, - OPTIONAL EDGEWEIGHTS weights, + OPTIONAL EDGE_WEIGHTS weights, REAL resolution=1.0, OUT MATRIX modmat, BOOLEAN directed=True @@ -1667,15 +1667,15 @@ igraph_reindex_membership: igraph_community_leading_eigenvector: PARAMS: |- - GRAPH graph, EDGEWEIGHTS weights=NULL, + GRAPH graph, EDGE_WEIGHTS weights=NULL, OPTIONAL OUT MATRIX_INT merges, OPTIONAL OUT VECTOR_INT membership, INTEGER steps=-1, - INOUT ARPACKOPT options=ARPACK_DEFAULTS, + INOUT ARPACK_OPTIONS options=ARPACK_DEFAULTS, OPTIONAL OUT REAL modularity, BOOLEAN start=False, OPTIONAL OUT VECTOR eigenvalues, OPTIONAL OUT VECTOR_LIST eigenvectors, OPTIONAL OUT VECTOR history, - LEVCFUNC callback, EXTRA callback_extra + LEVC_FUNC callback, EXTRA callback_extra igraph_community_fluid_communities: PARAMS: |- @@ -1684,13 +1684,13 @@ igraph_community_fluid_communities: igraph_community_label_propagation: PARAMS: |- GRAPH graph, OUT VECTOR_INT membership, NEIMODE mode=ALL, - OPTIONAL EDGEWEIGHTS weights, OPTIONAL INDEX_VECTOR initial, + OPTIONAL EDGE_WEIGHTS weights, OPTIONAL INDEX_VECTOR initial, OPTIONAL VECTOR_BOOL fixed DEPS: weights ON graph igraph_community_multilevel: PARAMS: |- - GRAPH graph, OPTIONAL EDGEWEIGHTS weights, REAL resolution=1.0, + GRAPH graph, OPTIONAL EDGE_WEIGHTS weights, REAL resolution=1.0, OUT VECTOR_INT membership, OPTIONAL OUT MATRIX_INT memberships, OPTIONAL OUT VECTOR modularity DEPS: weights ON graph @@ -1698,13 +1698,13 @@ igraph_community_multilevel: igraph_community_optimal_modularity: PARAMS: |- GRAPH graph, OUT REAL modularity, OPTIONAL OUT VECTOR_INT membership, - OPTIONAL EDGEWEIGHTS weights + OPTIONAL EDGE_WEIGHTS weights DEPS: weights ON graph igraph_community_leiden: PARAMS: |- - GRAPH graph, OPTIONAL EDGEWEIGHTS weights, - OPTIONAL VERTEXWEIGHTS vertex_weights, + GRAPH graph, OPTIONAL EDGE_WEIGHTS weights, + OPTIONAL VERTEX_WEIGHTS vertex_weights, REAL resolution, REAL beta=0.01, BOOLEAN start, INTEGER n_iterations=2, OPTIONAL INOUT VECTOR_INT membership, OUT INTEGER nb_clusters, OUT REAL quality @@ -1717,8 +1717,8 @@ igraph_split_join_distance: igraph_community_infomap: PARAMS: |- - GRAPH graph, EDGEWEIGHTS e_weights=NULL, - VERTEXWEIGHTS v_weights=NULL, INTEGER nb_trials=10, + GRAPH graph, EDGE_WEIGHTS e_weights=NULL, + VERTEX_WEIGHTS v_weights=NULL, INTEGER nb_trials=10, OUT VECTOR_INT membership, OUT REAL codelength DEPS: e_weights ON graph, v_weights ON graph @@ -1728,7 +1728,7 @@ igraph_community_voronoi: OPTIONAL OUT VECTOR_INT membership, OPTIONAL OUT VERTEX_INDICES generators, OPTIONAL OUT REAL modularity, - OPTIONAL EDGE_LENGTHS lengths, OPTIONAL EDGEWEIGHTS weights, + OPTIONAL EDGE_LENGTHS lengths, OPTIONAL EDGE_WEIGHTS weights, NEIMODE mode=OUT, REAL radius=-1 DEPS: generators ON graph, weights ON graph, lengths ON graph @@ -1738,20 +1738,20 @@ igraph_community_voronoi: igraph_graphlets: PARAMS: |- - GRAPH graph, EDGEWEIGHTS weights=NULL, - OUT VERTEXSET_LIST cliques, OUT VECTOR Mu, INTEGER niter=1000 + GRAPH graph, EDGE_WEIGHTS weights=NULL, + OUT VERTEX_INDICES_LIST cliques, OUT VECTOR Mu, INTEGER niter=1000 DEPS: weights ON graph, cliques ON graph igraph_graphlets_candidate_basis: PARAMS: |- - GRAPH graph, EDGEWEIGHTS weights=NULL, - OUT VERTEXSET_LIST cliques, OUT VECTOR thresholds + GRAPH graph, EDGE_WEIGHTS weights=NULL, + OUT VERTEX_INDICES_LIST cliques, OUT VECTOR thresholds DEPS: weights ON graph, cliques ON graph igraph_graphlets_project: PARAMS: |- - GRAPH graph, EDGEWEIGHTS weights=NULL, - VERTEXSET_LIST cliques, INOUT VECTOR Muc, + GRAPH graph, EDGE_WEIGHTS weights=NULL, + VERTEX_INDICES_LIST cliques, INOUT VECTOR Muc, BOOLEAN startMu=False, INTEGER niter=1000 DEPS: weights ON graph @@ -1807,14 +1807,14 @@ igraph_from_hrg_dendrogram: igraph_get_adjacency: PARAMS: |- GRAPH graph, OUT MATRIX res, GETADJACENCY type=BOTH, - EDGEWEIGHTS weights=NULL, LOOPS loops=ONCE + EDGE_WEIGHTS weights=NULL, LOOPS loops=ONCE DEPS: weights ON graph igraph_get_adjacency_sparse: PARAMS: |- GRAPH graph, OUT SPARSEMAT sparsemat, GETADJACENCY type=BOTH, - EDGEWEIGHTS weights=NULL, LOOPS loops=ONCE + EDGE_WEIGHTS weights=NULL, LOOPS loops=ONCE DEPS: weights ON graph @@ -1824,14 +1824,14 @@ igraph_get_edgelist: igraph_get_stochastic: PARAMS: |- GRAPH graph, OUT MATRIX res, BOOLEAN column_wise=False, - EDGEWEIGHTS weights=NULL + EDGE_WEIGHTS weights=NULL DEPS: weights ON graph igraph_get_stochastic_sparse: PARAMS: |- GRAPH graph, OUT SPARSEMAT sparsemat, BOOLEAN column_wise=False, - EDGEWEIGHTS weights=NULL + EDGE_WEIGHTS weights=NULL DEPS: weights ON graph @@ -1942,50 +1942,50 @@ igraph_adjacent_triangles: igraph_local_scan_0: PARAMS: |- - GRAPH graph, OUT VECTOR res, EDGEWEIGHTS weights=NULL, + GRAPH graph, OUT VECTOR res, EDGE_WEIGHTS weights=NULL, NEIMODE mode=OUT DEPS: weights ON graph igraph_local_scan_0_them: PARAMS: |- GRAPH us, GRAPH them, OUT VECTOR res, - EDGEWEIGHTS weights_them=NULL, NEIMODE mode=OUT + EDGE_WEIGHTS weights_them=NULL, NEIMODE mode=OUT DEPS: weights_them ON them igraph_local_scan_1_ecount: PARAMS: |- - GRAPH graph, OUT VECTOR res, EDGEWEIGHTS weights=NULL, + GRAPH graph, OUT VECTOR res, EDGE_WEIGHTS weights=NULL, NEIMODE mode=OUT DEPS: weights ON graph igraph_local_scan_1_ecount_them: PARAMS: |- GRAPH us, GRAPH them, OUT VECTOR res, - EDGEWEIGHTS weights_them=NULL, NEIMODE mode=OUT + EDGE_WEIGHTS weights_them=NULL, NEIMODE mode=OUT DEPS: weights_them ON them igraph_local_scan_k_ecount: PARAMS: |- - GRAPH graph, INTEGER k, OUT VECTOR res, EDGEWEIGHTS weights=NULL, + GRAPH graph, INTEGER k, OUT VECTOR res, EDGE_WEIGHTS weights=NULL, NEIMODE mode=OUT DEPS: weights ON graph igraph_local_scan_k_ecount_them: PARAMS: |- GRAPH us, GRAPH them, INTEGER k, OUT VECTOR res, - EDGEWEIGHTS weights_them=NULL, NEIMODE mode=OUT + EDGE_WEIGHTS weights_them=NULL, NEIMODE mode=OUT DEPS: weights_them ON them igraph_local_scan_neighborhood_ecount: PARAMS: |- - GRAPH graph, OUT VECTOR res, EDGEWEIGHTS weights=NULL, - VERTEXSET_LIST neighborhoods + GRAPH graph, OUT VECTOR res, EDGE_WEIGHTS weights=NULL, + VERTEX_INDICES_LIST neighborhoods DEPS: weights ON graph igraph_local_scan_subset_ecount: PARAMS: |- - GRAPH graph, OUT VECTOR res, EDGEWEIGHTS weights=NULL, - VERTEXSET_LIST subsets + GRAPH graph, OUT VECTOR res, EDGE_WEIGHTS weights=NULL, + VERTEX_INDICES_LIST subsets DEPS: weights ON graph igraph_list_triangles: @@ -2046,7 +2046,7 @@ igraph_induced_subgraph_map: ####################################### igraph_gomory_hu_tree: - PARAMS: GRAPH graph, OUT GRAPH tree, OPTIONAL OUT VECTOR flows, OPTIONAL EDGE_CAPACITY capacity + PARAMS: GRAPH graph, OUT GRAPH tree, OPTIONAL OUT VECTOR flows, OPTIONAL EDGE_CAPACITIES capacity DEPS: capacity ON graph igraph_maxflow: @@ -2054,7 +2054,7 @@ igraph_maxflow: GRAPH graph, OUT REAL value, OPTIONAL OUT VECTOR flow, OUT EDGE_INDICES cut, OPTIONAL OUT VERTEX_INDICES partition1, OPTIONAL OUT VERTEX_INDICES partition2, VERTEX source, VERTEX target, - OPTIONAL EDGE_CAPACITY capacity, OPTIONAL OUT MAXFLOW_STATS stats + OPTIONAL EDGE_CAPACITIES capacity, OPTIONAL OUT MAXFLOW_STATS stats DEPS: |- capacity ON graph, source ON graph, target ON graph, partition1 ON graph, partition2 ON graph, flow ON graph, @@ -2063,30 +2063,30 @@ igraph_maxflow: igraph_maxflow_value: PARAMS: |- GRAPH graph, OUT REAL value, VERTEX source, VERTEX target, - OPTIONAL EDGE_CAPACITY capacity, OPTIONAL OUT MAXFLOW_STATS stats + OPTIONAL EDGE_CAPACITIES capacity, OPTIONAL OUT MAXFLOW_STATS stats DEPS: source ON graph, target ON graph, capacity ON graph igraph_mincut: PARAMS: |- GRAPH graph, OUT REAL value, OUT VERTEX_INDICES partition1, OUT VERTEX_INDICES partition2, OUT EDGE_INDICES cut, - OPTIONAL EDGE_CAPACITY capacity + OPTIONAL EDGE_CAPACITIES capacity DEPS: capacity ON graph, partition1 ON graph, partition2 ON graph, cut ON graph igraph_mincut_value: - PARAMS: GRAPH graph, OUT REAL res, OPTIONAL EDGE_CAPACITY capacity + PARAMS: GRAPH graph, OUT REAL res, OPTIONAL EDGE_CAPACITIES capacity DEPS: capacity ON graph igraph_residual_graph: PARAMS: |- - GRAPH graph, EDGE_CAPACITY capacity, OUT GRAPH residual, - OUT EDGE_CAPACITY residual_capacity, VECTOR flow + GRAPH graph, EDGE_CAPACITIES capacity, OUT GRAPH residual, + OUT EDGE_CAPACITIES residual_capacity, VECTOR flow DEPS: capacity ON graph, flow ON graph, residual_capacity ON residual igraph_reverse_residual_graph: PARAMS: |- - GRAPH graph, EDGE_CAPACITY capacity, OUT GRAPH residual, + GRAPH graph, EDGE_CAPACITIES capacity, OUT GRAPH residual, VECTOR flow DEPS: capacity ON graph, flow ON graph @@ -2095,7 +2095,7 @@ igraph_st_mincut: GRAPH graph, OUT REAL value, OUT EDGE_INDICES cut, OPTIONAL OUT VERTEX_INDICES partition1, OPTIONAL OUT VERTEX_INDICES partition2, - VERTEX source, VERTEX target, OPTIONAL EDGE_CAPACITY capacity + VERTEX source, VERTEX target, OPTIONAL EDGE_CAPACITIES capacity DEPS: |- capacity ON graph, source ON graph, target ON graph, partition1 ON graph, partition2 ON graph, cut ON graph @@ -2103,7 +2103,7 @@ igraph_st_mincut: igraph_st_mincut_value: PARAMS: |- GRAPH graph, OUT REAL res, VERTEX source, VERTEX target, - OPTIONAL EDGE_CAPACITY capacity + OPTIONAL EDGE_CAPACITIES capacity DEPS: source ON graph, target ON graph, capacity ON graph igraph_st_vertex_connectivity: @@ -2149,8 +2149,8 @@ igraph_dominator_tree: igraph_all_st_cuts: PARAMS: |- - GRAPH graph, OPTIONAL OUT EDGESET_LIST cuts, - OPTIONAL OUT VERTEXSET_LIST partition1s, + GRAPH graph, OPTIONAL OUT EDGE_INDICES_LIST cuts, + OPTIONAL OUT VERTEX_INDICES_LIST partition1s, VERTEX source, VERTEX target DEPS: |- source ON graph, target ON graph, cuts ON graph, @@ -2159,15 +2159,15 @@ igraph_all_st_cuts: igraph_all_st_mincuts: PARAMS: |- GRAPH graph, OUT REAL value, - OPTIONAL OUT EDGESET_LIST cuts, - OPTIONAL OUT VERTEXSET_LIST partition1s, - VERTEX source, VERTEX target, OPTIONAL EDGE_CAPACITY capacity + OPTIONAL OUT EDGE_INDICES_LIST cuts, + OPTIONAL OUT VERTEX_INDICES_LIST partition1s, + VERTEX source, VERTEX target, OPTIONAL EDGE_CAPACITIES capacity DEPS: |- capacity ON graph, source ON graph, target ON graph, cuts ON graph, partition1s ON graph igraph_even_tarjan_reduction: - PARAMS: GRAPH graph, OUT GRAPH graphbar, OPTIONAL OUT EDGE_CAPACITY capacity + PARAMS: GRAPH graph, OUT GRAPH graphbar, OPTIONAL OUT EDGE_CAPACITIES capacity DEPS: |- capacity ON graphbar @@ -2180,16 +2180,16 @@ igraph_is_minimal_separator: DEPS: candidate ON graph igraph_all_minimal_st_separators: - PARAMS: GRAPH graph, OUT VERTEXSET_LIST separators + PARAMS: GRAPH graph, OUT VERTEX_INDICES_LIST separators DEPS: separators ON graph igraph_minimum_size_separators: - PARAMS: GRAPH graph, OUT VERTEXSET_LIST separators + PARAMS: GRAPH graph, OUT VERTEX_INDICES_LIST separators DEPS: separators ON graph igraph_cohesive_blocks: PARAMS: |- - GRAPH graph, OUT VERTEXSET_LIST blocks, + GRAPH graph, OUT VERTEX_INDICES_LIST blocks, OUT VECTOR_INT cohesion, OUT INDEX_VECTOR parent, OUT GRAPH blockTree DEPS: blocks ON graph @@ -2211,6 +2211,16 @@ igraph_isoclass: igraph_isomorphic: PARAMS: GRAPH graph1, GRAPH graph2, OUT BOOLEAN iso +igraph_automorphism_group: + PARAMS: |- + GRAPH graph, OPTIONAL VERTEX_COLORS colors, OUT VERTEX_INDICES_LIST generators + DEPS: colors ON graph, generators ON graph + +igraph_count_automorphisms: + PARAMS: |- + GRAPH graph, OPTIONAL VERTEX_COLORS colors, OUT REAL result + DEPS: colors ON graph + igraph_isoclass_subgraph: PARAMS: GRAPH graph, VECTOR_INT vids, OUT INTEGER isoclass DEPS: vids ON graph @@ -2221,10 +2231,10 @@ igraph_isoclass_create: igraph_isomorphic_vf2: PARAMS: |- GRAPH graph1, GRAPH graph2, - OPTIONAL VERTEX_COLOR vertex_color1, - OPTIONAL VERTEX_COLOR vertex_color2, - OPTIONAL EDGE_COLOR edge_color1, - OPTIONAL EDGE_COLOR edge_color2, + OPTIONAL VERTEX_COLORS vertex_color1, + OPTIONAL VERTEX_COLORS vertex_color2, + OPTIONAL EDGE_COLORS edge_color1, + OPTIONAL EDGE_COLORS edge_color2, OUT BOOLEAN iso, OPTIONAL OUT INDEX_VECTOR map12, OPTIONAL OUT INDEX_VECTOR map21, OPTIONAL ISOCOMPAT_FUNC node_compat_fn, @@ -2237,8 +2247,8 @@ igraph_isomorphic_vf2: igraph_count_isomorphisms_vf2: PARAMS: |- GRAPH graph1, GRAPH graph2, - VERTEX_COLOR vertex_color1, VERTEX_COLOR vertex_color2, - EDGE_COLOR edge_color1, EDGE_COLOR edge_color2, + VERTEX_COLORS vertex_color1, VERTEX_COLORS vertex_color2, + EDGE_COLORS edge_color1, EDGE_COLORS edge_color2, OUT INTEGER count, ISOCOMPAT_FUNC node_compat_fn, ISOCOMPAT_FUNC edge_compat_fn, EXTRA extra DEPS: |- @@ -2248,8 +2258,8 @@ igraph_count_isomorphisms_vf2: igraph_get_isomorphisms_vf2: PARAMS: |- GRAPH graph1, GRAPH graph2, - VERTEX_COLOR vertex_color1, VERTEX_COLOR vertex_color2, - EDGE_COLOR edge_color1, EDGE_COLOR edge_color2, + VERTEX_COLORS vertex_color1, VERTEX_COLORS vertex_color2, + EDGE_COLORS edge_color1, EDGE_COLORS edge_color2, OUT VECTOR_INT_LIST maps, ISOCOMPAT_FUNC node_compat_fn, ISOCOMPAT_FUNC edge_compat_fn, EXTRA extra DEPS: |- @@ -2262,8 +2272,8 @@ igraph_subisomorphic: igraph_subisomorphic_vf2: PARAMS: |- GRAPH graph1, GRAPH graph2, - OPTIONAL VERTEX_COLOR vertex_color1, OPTIONAL VERTEX_COLOR vertex_color2, - OPTIONAL EDGE_COLOR edge_color1, OPTIONAL EDGE_COLOR edge_color2, + OPTIONAL VERTEX_COLORS vertex_color1, OPTIONAL VERTEX_COLORS vertex_color2, + OPTIONAL EDGE_COLORS edge_color1, OPTIONAL EDGE_COLORS edge_color2, OUT BOOLEAN iso, OPTIONAL OUT INDEX_VECTOR map12, OPTIONAL OUT INDEX_VECTOR map21, OPTIONAL ISOCOMPAT_FUNC node_compat_fn, OPTIONAL ISOCOMPAT_FUNC edge_compat_fn, @@ -2275,8 +2285,8 @@ igraph_subisomorphic_vf2: igraph_get_subisomorphisms_vf2_callback: PARAMS: |- GRAPH graph1, GRAPH graph2, - OPTIONAL VERTEX_COLOR vertex_color1, OPTIONAL VERTEX_COLOR vertex_color2, - OPTIONAL EDGE_COLOR edge_color1, OPTIONAL EDGE_COLOR edge_color2, + OPTIONAL VERTEX_COLORS vertex_color1, OPTIONAL VERTEX_COLORS vertex_color2, + OPTIONAL EDGE_COLORS edge_color1, OPTIONAL EDGE_COLORS edge_color2, OPTIONAL OUT INDEX_VECTOR map12, OPTIONAL OUT INDEX_VECTOR map21, ISOMORPHISM_FUNC ishohandler_fn, OPTIONAL ISOCOMPAT_FUNC node_compat_fn, OPTIONAL ISOCOMPAT_FUNC edge_compat_fn, EXTRA arg @@ -2287,8 +2297,8 @@ igraph_get_subisomorphisms_vf2_callback: igraph_count_subisomorphisms_vf2: PARAMS: |- GRAPH graph1, GRAPH graph2, - VERTEX_COLOR vertex_color1, VERTEX_COLOR vertex_color2, - EDGE_COLOR edge_color1, EDGE_COLOR edge_color2, + VERTEX_COLORS vertex_color1, VERTEX_COLORS vertex_color2, + EDGE_COLORS edge_color1, EDGE_COLORS edge_color2, OUT INTEGER count, ISOCOMPAT_FUNC node_compat_fn, ISOCOMPAT_FUNC edge_compat_fn, EXTRA extra DEPS: |- @@ -2298,8 +2308,8 @@ igraph_count_subisomorphisms_vf2: igraph_get_subisomorphisms_vf2: PARAMS: |- GRAPH graph1, GRAPH graph2, - VERTEX_COLOR vertex_color1, VERTEX_COLOR vertex_color2, - EDGE_COLOR edge_color1, EDGE_COLOR edge_color2, + VERTEX_COLORS vertex_color1, VERTEX_COLORS vertex_color2, + EDGE_COLORS edge_color1, EDGE_COLORS edge_color2, OUT VECTOR_INT_LIST maps, ISOCOMPAT_FUNC node_compat_fn, ISOCOMPAT_FUNC edge_compat_fn, EXTRA extra DEPS: |- @@ -2308,7 +2318,13 @@ igraph_get_subisomorphisms_vf2: igraph_canonical_permutation: PARAMS: |- - GRAPH graph, OPTIONAL VERTEX_COLOR colors, + GRAPH graph, OPTIONAL VERTEX_COLORS colors, + OUT INDEX_VECTOR labeling + DEPS: colors ON graph + +igraph_canonical_permutation_bliss: + PARAMS: |- + GRAPH graph, OPTIONAL VERTEX_COLORS colors, OUT INDEX_VECTOR labeling, BLISSSH sh="fm", OUT BLISSINFO info DEPS: colors ON graph @@ -2318,26 +2334,26 @@ igraph_permute_vertices: igraph_isomorphic_bliss: PARAMS: |- GRAPH graph1, GRAPH graph2, - OPTIONAL VERTEX_COLOR colors1, OPTIONAL VERTEX_COLOR colors2, + OPTIONAL VERTEX_COLORS colors1, OPTIONAL VERTEX_COLORS colors2, OUT BOOLEAN iso, OPTIONAL OUT INDEX_VECTOR map12, OPTIONAL OUT INDEX_VECTOR map21, BLISSSH sh="fm", OPTIONAL OUT BLISSINFO info1, OPTIONAL OUT BLISSINFO info2 DEPS: colors1 ON graph1, colors2 ON graph2 -igraph_count_automorphisms: +igraph_count_automorphisms_bliss: PARAMS: |- - GRAPH graph, OPTIONAL VERTEX_COLOR colors, BLISSSH sh="fm", OUT BLISSINFO info + GRAPH graph, OPTIONAL VERTEX_COLORS colors, BLISSSH sh="fm", OUT BLISSINFO info DEPS: colors ON graph -igraph_automorphism_group: +igraph_automorphism_group_bliss: PARAMS: |- - GRAPH graph, OPTIONAL VERTEX_COLOR colors, PRIMARY OUT VERTEXSET_LIST generators, + GRAPH graph, OPTIONAL VERTEX_COLORS colors, PRIMARY OUT VERTEX_INDICES_LIST generators, BLISSSH sh="fm", OUT BLISSINFO info DEPS: colors ON graph, generators ON graph igraph_subisomorphic_lad: PARAMS: |- - GRAPH pattern, GRAPH target, OPTIONAL VERTEXSET_LIST domains, + GRAPH pattern, GRAPH target, OPTIONAL VERTEX_INDICES_LIST domains, OPTIONAL OUT BOOLEAN iso, OUT INDEX_VECTOR map, OPTIONAL OUT VECTOR_INT_LIST maps, BOOLEAN induced, INTEGER time_limit @@ -2373,7 +2389,7 @@ igraph_maximum_bipartite_matching: OPTIONAL OUT INTEGER matching_size, OPTIONAL OUT REAL matching_weight, OUT INDEX_VECTOR matching, - OPTIONAL EDGEWEIGHTS weights, REAL eps=.Machine$double.eps + OPTIONAL EDGE_WEIGHTS weights, REAL eps=.Machine$double.eps DEPS: types ON graph, weights ON graph ####################################### @@ -2382,20 +2398,20 @@ igraph_maximum_bipartite_matching: igraph_adjacency_spectral_embedding: PARAMS: |- - GRAPH graph, INTEGER no, EDGEWEIGHTS weights=NULL, + GRAPH graph, INTEGER no, EDGE_WEIGHTS weights=NULL, EIGENWHICHPOS which=ASE, BOOLEAN scaled=True, OUT MATRIX X, OPTIONAL OUT MATRIX Y, OPTIONAL OUT VECTOR D, VECTOR cvec=AsmDefaultCvec, - INOUT ARPACKOPT options=ARPACK_DEFAULTS + INOUT ARPACK_OPTIONS options=RPACK_DEFAULTS DEPS: weights ON graph, cvec ON graph igraph_laplacian_spectral_embedding: PARAMS: |- - GRAPH graph, INTEGER no, EDGEWEIGHTS weights=NULL, + GRAPH graph, INTEGER no, EDGE_WEIGHTS weights=NULL, EIGENWHICHPOS which=ASE, LSETYPE type=Default, BOOLEAN scaled=True, OUT MATRIX X, OPTIONAL OUT MATRIX Y, OPTIONAL OUT VECTOR D, - INOUT ARPACKOPT options=ARPACK_DEFAULTS + INOUT ARPACK_OPTIONS options=ARPACK_DEFAULTS DEPS: weights ON graph, type ON graph ####################################### @@ -2406,8 +2422,8 @@ igraph_eigen_adjacency: PARAMS: |- GRAPH graph, EIGENALGO algorithm=ARPACK, EIGENWHICH which=Default, - INOUT ARPACKOPT options=ARPACK_DEFAULTS, - INOUT ARPACKSTORAGE storage, OUT VECTOR values, OUT MATRIX vectors, + INOUT ARPACK_OPTIONS options=ARPACK_DEFAULTS, + INOUT ARPACK_STORAGE storage, OUT VECTOR values, OUT MATRIX vectors, OUT VECTOR_COMPLEX cmplxvalues, OUT MATRIX_COMPLEX cmplxvectors ####################################### @@ -2454,15 +2470,15 @@ igraph_cmp_epsilon: igraph_eigen_matrix: PARAMS: |- - MATRIX A, SPARSEMAT sA, ARPACKFUNC fun, INT n, EXTRA extra, - EIGENALGO algorithm, EIGENWHICH which, INOUT ARPACKOPT options=ARPACK_DEFAULTS, - INOUT ARPACKSTORAGE storage, OUT VECTOR_COMPLEX values, OUT MATRIX_COMPLEX vectors + MATRIX A, SPARSEMAT sA, ARPACK_FUNC fun, INT n, EXTRA extra, + EIGENALGO algorithm, EIGENWHICH which, INOUT ARPACK_OPTIONS options=ARPACK_DEFAULTS, + INOUT ARPACK_STORAGE storage, OUT VECTOR_COMPLEX values, OUT MATRIX_COMPLEX vectors igraph_eigen_matrix_symmetric: PARAMS: |- - MATRIX A, SPARSEMAT sA, ARPACKFUNC fun, INT n, EXTRA extra, - EIGENALGO algorithm, EIGENWHICH which, INOUT ARPACKOPT options=ARPACK_DEFAULTS, - INOUT ARPACKSTORAGE storage, OUT VECTOR values, OUT MATRIX vectors + MATRIX A, SPARSEMAT sA, ARPACK_FUNC fun, INT n, EXTRA extra, + EIGENALGO algorithm, EIGENWHICH which, INOUT ARPACK_OPTIONS options=ARPACK_DEFAULTS, + INOUT ARPACK_STORAGE storage, OUT VECTOR values, OUT MATRIX vectors igraph_solve_lsap: PARAMS: MATRIX c, INTEGER n, OUT VECTOR_INT p @@ -2487,11 +2503,11 @@ igraph_eulerian_cycle: ####################################### igraph_fundamental_cycles: - PARAMS: GRAPH graph, OUT EDGESET_LIST basis, OPTIONAL VERTEX start, INTEGER bfs_cutoff, EDGEWEIGHTS weights=NULL + PARAMS: GRAPH graph, OUT EDGE_INDICES_LIST basis, OPTIONAL VERTEX start, INTEGER bfs_cutoff, EDGE_WEIGHTS weights=NULL DEPS: weights ON graph, basis ON graph, start ON graph igraph_minimum_cycle_basis: - PARAMS: GRAPH graph, OUT EDGESET_LIST basis, INTEGER bfs_cutoff, BOOLEAN complete, BOOLEAN use_cycle_order, EDGEWEIGHTS weights=NULL + PARAMS: GRAPH graph, OUT EDGE_INDICES_LIST basis, INTEGER bfs_cutoff, BOOLEAN complete, BOOLEAN use_cycle_order, EDGE_WEIGHTS weights=NULL DEPS: weights ON graph, basis ON graph ####################################### @@ -2519,14 +2535,14 @@ igraph_is_complete: PARAMS: GRAPH graph, OUT BOOLEAN res igraph_minimum_spanning_tree: - PARAMS: GRAPH graph, OUT EDGE_INDICES res, EDGEWEIGHTS weights=NULL + PARAMS: GRAPH graph, OUT EDGE_INDICES res, EDGE_WEIGHTS weights=NULL DEPS: res ON graph, weights ON graph igraph_minimum_spanning_tree_unweighted: PARAMS: GRAPH graph, OUT GRAPH mst igraph_minimum_spanning_tree_prim: - PARAMS: GRAPH graph, OUT GRAPH mst, EDGEWEIGHTS weights + PARAMS: GRAPH graph, OUT GRAPH mst, EDGE_WEIGHTS weights DEPS: weights ON graph igraph_random_spanning_tree: @@ -2541,7 +2557,7 @@ igraph_tree_game: ####################################### igraph_vertex_coloring_greedy: - PARAMS: GRAPH graph, OUT VERTEX_COLOR colors, GREEDY_COLORING_HEURISTIC heuristic=NEIGHBORS + PARAMS: GRAPH graph, OUT VERTEX_COLORS colors, GREEDY_COLORING_HEURISTIC heuristic=NEIGHBORS DEPS: colors ON graph ####################################### @@ -2550,25 +2566,25 @@ igraph_vertex_coloring_greedy: igraph_deterministic_optimal_imitation: PARAMS: |- - GRAPH graph, VERTEX vid, OPTIMALITY optimality=MAXIMUM, VERTEX_QTY quantities, + GRAPH graph, VERTEX vid, OPTIMALITY optimality=MAXIMUM, VERTEX_QTYS quantities, INOUT VECTOR_INT strategies, NEIMODE mode=OUT DEPS: vid ON graph, quantities ON graph, strategies ON graph igraph_moran_process: PARAMS: |- - GRAPH graph, EDGEWEIGHTS weights=NULL, INOUT VERTEX_QTY quantities, + GRAPH graph, EDGE_WEIGHTS weights=NULL, INOUT VERTEX_QTYS quantities, INOUT VECTOR_INT strategies, NEIMODE mode=OUT DEPS: weights ON graph, quantities ON graph, strategies ON graph igraph_roulette_wheel_imitation: PARAMS: |- - GRAPH graph, VERTEX vid, BOOLEAN is_local, VERTEX_QTY quantities, + GRAPH graph, VERTEX vid, BOOLEAN is_local, VERTEX_QTYS quantities, INOUT VECTOR_INT strategies, NEIMODE mode=OUT DEPS: vid ON graph, quantities ON graph, strategies ON graph igraph_stochastic_imitation: PARAMS: |- - GRAPH graph, VERTEX vid, IMITATE_ALGORITHM algo, VERTEX_QTY quantities, + GRAPH graph, VERTEX vid, IMITATE_ALGORITHM algo, VERTEX_QTYS quantities, INOUT VECTOR_INT strategies, NEIMODE mode=OUT DEPS: vid ON graph, quantities ON graph, strategies ON graph diff --git a/src/vendor/cigraph/interfaces/types.yaml b/src/vendor/cigraph/interfaces/types.yaml index 9799d02652d..c35461ad169 100644 --- a/src/vendor/cigraph/interfaces/types.yaml +++ b/src/vendor/cigraph/interfaces/types.yaml @@ -177,12 +177,12 @@ BIPARTITE_TYPES: CTYPE: igraph_vector_bool_t FLAGS: BY_REF -EDGE_CAPACITY: +EDGE_CAPACITIES: # A vector containing edge capacities (typically for max-flow algorithms) CTYPE: igraph_vector_t FLAGS: BY_REF -EDGE_COLOR: +EDGE_COLORS: # A vector containing edge colors CTYPE: igraph_vector_int_t FLAGS: BY_REF @@ -192,12 +192,12 @@ EDGE_LENGTHS: CTYPE: igraph_vector_t FLAGS: BY_REF -EDGEWEIGHTS: +EDGE_WEIGHTS: # A vector containing edge weights CTYPE: igraph_vector_t FLAGS: BY_REF -EDGESET_LIST: +EDGE_INDICES_LIST: # A list containing vectors of igraph integers where each such # vector represents a sequence of edge indices. CTYPE: igraph_vector_int_list_t @@ -213,7 +213,7 @@ GRAPH_PTR_LIST: CTYPE: igraph_vector_ptr_t FLAGS: BY_REF -VERTEX_QTY: +VERTEX_QTYS: # A vector of floating-point numbers where each entry corresponds to # one of the vertices in a graph and its value represents some quantity # associated to the vertex with the same index. Higher-level interfaces may @@ -227,18 +227,18 @@ SIR_LIST: CTYPE: igraph_vector_ptr_t FLAGS: BY_REF -VERTEXSET_LIST: +VERTEX_INDICES_LIST: # A list containing vectors of igraph integers where each such # vector represents a sequence of vertex indices. CTYPE: igraph_vector_int_list_t FLAGS: BY_REF -VERTEX_COLOR: +VERTEX_COLORS: # A vector containing vertex colors CTYPE: igraph_vector_int_t FLAGS: BY_REF -VERTEXWEIGHTS: +VERTEX_WEIGHTS: # A vector containing vertex weights CTYPE: igraph_vector_t FLAGS: BY_REF @@ -511,7 +511,7 @@ WRITE_GML_SW: # Callbacks ############################################################################### -ARPACKFUNC: +ARPACK_FUNC: # ARPACK matrix multiplication function. CTYPE: igraph_arpack_function_t @@ -540,7 +540,7 @@ ISOMORPHISM_FUNC: # isomorphism is found CTYPE: igraph_isohandler_t -LEVCFUNC: +LEVC_FUNC: # Callback function for igraph_leading_eigenvector_community(). Called # after each eigenvalue / eigenvector calculation. CTYPE: igraph_community_leading_eigenvector_callback_t @@ -549,12 +549,12 @@ LEVCFUNC: # Miscellaneous ############################################################################### -ARPACKOPT: +ARPACK_OPTIONS: # Structure that contains the options of the ARPACK eigensolver. CTYPE: igraph_arpack_options_t FLAGS: BY_REF -ARPACKSTORAGE: +ARPACK_STORAGE: # Pointer to a general-purpose memory block that ARPACK-based algorithms # may use as a working area. CTYPE: igraph_arpack_storage_t @@ -565,10 +565,9 @@ ASTAR_HEURISTIC_FUNC: CTYPE: igraph_astar_heuristic_func_t ATTRIBUTES: - # An opaque data structure that a high-level interface may use to pass - # information about graph/vertex/edge attributes to a low-level igraph - # C function - CTYPE: void + # A data structure specifying graph/vertex/edge attributes to add to a + # graph in a low-level igraph C function + CTYPE: igraph_attribute_record_list_t FLAGS: BY_REF BLISSINFO: diff --git a/src/vendor/cigraph/src/community/fluid.c b/src/vendor/cigraph/src/community/fluid.c index d419f7ac12f..593f0d3f0c6 100644 --- a/src/vendor/cigraph/src/community/fluid.c +++ b/src/vendor/cigraph/src/community/fluid.c @@ -132,7 +132,7 @@ igraph_error_t igraph_community_fluid_communities(const igraph_t *graph, igraph_vector_fill(&density, max_density); /* Initialize com_to_numvertices and initialize communities into membership vector */ - IGRAPH_CHECK(igraph_vector_int_shuffle(&node_order)); + igraph_vector_int_shuffle(&node_order); for (i = 0; i < no_of_communities; i++) { /* Initialize membership at initial nodes for each community * where 0 refers to have no label*/ @@ -165,7 +165,7 @@ igraph_error_t igraph_community_fluid_communities(const igraph_t *graph, running = false; /* Shuffle the node ordering vector */ - IGRAPH_CHECK(igraph_vector_int_shuffle(&node_order)); + igraph_vector_int_shuffle(&node_order); /* In the prescribed order, loop over the vertices and reassign labels */ for (i = 0; i < no_of_nodes; i++) { /* Clear dominant_labels and nonzero_labels vectors */ diff --git a/src/vendor/cigraph/src/community/label_propagation.c b/src/vendor/cigraph/src/community/label_propagation.c index 09a9eb743a7..07b38934391 100644 --- a/src/vendor/cigraph/src/community/label_propagation.c +++ b/src/vendor/cigraph/src/community/label_propagation.c @@ -272,7 +272,7 @@ igraph_error_t igraph_community_label_propagation(const igraph_t *graph, running = false; } else { /* Shuffle the node ordering vector if we are in the label updating iteration */ - IGRAPH_CHECK(igraph_vector_int_shuffle(&node_order)); + igraph_vector_int_shuffle(&node_order); } RNG_BEGIN(); @@ -403,7 +403,7 @@ igraph_error_t igraph_community_label_propagation(const igraph_t *graph, /* In the directed case, the outcome depends on the node ordering, thus we * shuffle nodes one more time. */ - IGRAPH_CHECK(igraph_vector_int_shuffle(&node_order)); + igraph_vector_int_shuffle(&node_order); IGRAPH_VECTOR_INT_INIT_FINALLY(&neis, 0); diff --git a/src/vendor/cigraph/src/community/leading_eigenvector.c b/src/vendor/cigraph/src/community/leading_eigenvector.c index 91b88c4fbfd..b351e35b7f7 100644 --- a/src/vendor/cigraph/src/community/leading_eigenvector.c +++ b/src/vendor/cigraph/src/community/leading_eigenvector.c @@ -546,7 +546,7 @@ igraph_error_t igraph_community_leading_eigenvector( } RNG_END(); igraph_vector_view(&start_vec, storage.resid, options->n); - IGRAPH_CHECK(igraph_vector_shuffle(&start_vec)); + igraph_vector_shuffle(&start_vec); { igraph_error_t retval; diff --git a/src/vendor/cigraph/src/community/leiden.c b/src/vendor/cigraph/src/community/leiden.c index e9aa9ada241..122bd0cd459 100644 --- a/src/vendor/cigraph/src/community/leiden.c +++ b/src/vendor/cigraph/src/community/leiden.c @@ -80,7 +80,7 @@ static igraph_error_t igraph_i_community_leiden_fastmovenodes( /* Shuffle nodes */ IGRAPH_CHECK(igraph_vector_int_init_range(&node_order, 0, n)); IGRAPH_FINALLY(igraph_vector_int_destroy, &node_order); - IGRAPH_CHECK(igraph_vector_int_shuffle(&node_order)); + igraph_vector_int_shuffle(&node_order); /* Add to the queue */ for (i = 0; i < n; i++) { @@ -339,7 +339,7 @@ static igraph_error_t igraph_i_community_leiden_mergenodes( /* Shuffle nodes */ IGRAPH_CHECK(igraph_vector_int_init_copy(&node_order, node_subset)); IGRAPH_FINALLY(igraph_vector_int_destroy, &node_order); - IGRAPH_CHECK(igraph_vector_int_shuffle(&node_order)); + igraph_vector_int_shuffle(&node_order); /* Initialize non singleton clusters */ IGRAPH_VECTOR_BOOL_INIT_FINALLY(&non_singleton_cluster, n); diff --git a/src/vendor/cigraph/src/community/spinglass/clustertool.cpp b/src/vendor/cigraph/src/community/spinglass/clustertool.cpp index 537a0df6f39..f423ce2e87c 100644 --- a/src/vendor/cigraph/src/community/spinglass/clustertool.cpp +++ b/src/vendor/cigraph/src/community/spinglass/clustertool.cpp @@ -389,10 +389,11 @@ static igraph_error_t igraph_i_community_spinglass_orig( * \param adhesion Pointer to a real variable, if not \c NULL the * adhesion index of the community will be stored here. * \param inner_links Pointer to an integer, if not \c NULL the - * number of edges within the community is stored here. + * number of edges within the community (or the sum of their weights) + * is stored here. * \param outer_links Pointer to an integer, if not \c NULL the * number of edges between the community and the rest of the graph - * will be stored here. + * (or the sum of their weights) will be stored here. * \param spins The number of spins to use, this can be higher than * the actual number of clusters in the network, in which case some * clusters will contain zero vertices. @@ -427,8 +428,8 @@ igraph_error_t igraph_community_spinglass_single(const igraph_t *graph, igraph_vector_int_t *community, igraph_real_t *cohesion, igraph_real_t *adhesion, - igraph_integer_t *inner_links, - igraph_integer_t *outer_links, + igraph_real_t *inner_links, + igraph_real_t *outer_links, igraph_integer_t spins, igraph_spincomm_update_t update_rule, igraph_real_t gamma) { diff --git a/src/vendor/cigraph/src/community/spinglass/pottsmodel_2.cpp b/src/vendor/cigraph/src/community/spinglass/pottsmodel_2.cpp index f454154e4dd..2e29f4f510c 100644 --- a/src/vendor/cigraph/src/community/spinglass/pottsmodel_2.cpp +++ b/src/vendor/cigraph/src/community/spinglass/pottsmodel_2.cpp @@ -773,8 +773,8 @@ double PottsModel::FindCommunityFromStart( igraph_vector_int_t *result, igraph_real_t *cohesion, igraph_real_t *adhesion, - igraph_integer_t *my_inner_links, - igraph_integer_t *my_outer_links) const { + igraph_real_t *my_inner_links, + igraph_real_t *my_outer_links) const { DLList_Iter iter, iter2; DLList_Iter l_iter; DLList to_do; diff --git a/src/vendor/cigraph/src/community/spinglass/pottsmodel_2.h b/src/vendor/cigraph/src/community/spinglass/pottsmodel_2.h index 1cecba4268c..6e96ea6c6de 100644 --- a/src/vendor/cigraph/src/community/spinglass/pottsmodel_2.h +++ b/src/vendor/cigraph/src/community/spinglass/pottsmodel_2.h @@ -110,8 +110,8 @@ class PottsModel { igraph_vector_int_t *result, igraph_real_t *cohesion, igraph_real_t *adhesion, - igraph_integer_t *inner_links, - igraph_integer_t *outer_links) const; + igraph_real_t *inner_links, + igraph_real_t *outer_links) const; }; diff --git a/src/vendor/cigraph/src/connectivity/components.c b/src/vendor/cigraph/src/connectivity/components.c index d049883335b..70a6b3f0a55 100644 --- a/src/vendor/cigraph/src/connectivity/components.c +++ b/src/vendor/cigraph/src/connectivity/components.c @@ -565,34 +565,6 @@ static igraph_error_t igraph_i_is_connected_weak(const igraph_t *graph, igraph_b return IGRAPH_SUCCESS; } -/** - * \function igraph_decompose_destroy - * \brief Frees the contents of a pointer vector holding graphs. - * - * This function destroys and frees all igraph_t - * objects held in \p complist. However, it does not destroy - * \p complist itself. Use \ref igraph_vector_ptr_destroy() to destroy - * \p complist. - * - * \param complist The list of graphs to destroy. - * - * Time complexity: O(n), n is the number of items. - * - * \deprecated 0.10.0 - */ - -void igraph_decompose_destroy(igraph_vector_ptr_t *complist) { - igraph_integer_t i, n; - - n = igraph_vector_ptr_size(complist); - for (i = 0; i < n; i++) { - if (VECTOR(*complist)[i] != 0) { - igraph_destroy(VECTOR(*complist)[i]); - IGRAPH_FREE(VECTOR(*complist)[i]); - } - } -} - static igraph_error_t igraph_i_decompose_weak(const igraph_t *graph, igraph_graph_list_t *components, igraph_integer_t maxcompno, igraph_integer_t minelements); @@ -677,6 +649,7 @@ static igraph_error_t igraph_i_decompose_weak(const igraph_t *graph, IGRAPH_VECTOR_INT_INIT_FINALLY(&verts, 0); IGRAPH_VECTOR_INT_INIT_FINALLY(&neis, 0); IGRAPH_VECTOR_INT_INIT_FINALLY(&vids_old2new, no_of_nodes); + igraph_vector_int_fill(&vids_old2new, -1); /* vids_old2new would have been created internally in igraph_induced_subgraph(), but it is slow if the graph is large and consists of many small components, @@ -784,6 +757,8 @@ static igraph_error_t igraph_i_decompose_strong(const igraph_t *graph, /* The result */ IGRAPH_VECTOR_INT_INIT_FINALLY(&vids_old2new, no_of_nodes); + igraph_vector_int_fill(&vids_old2new, -1); + IGRAPH_VECTOR_INT_INIT_FINALLY(&verts, 0); IGRAPH_VECTOR_INT_INIT_FINALLY(&next_nei, no_of_nodes); IGRAPH_VECTOR_INT_INIT_FINALLY(&out, 0); @@ -1257,8 +1232,6 @@ igraph_error_t igraph_biconnected_components(const igraph_t *graph, * \function igraph_is_biconnected * \brief Checks whether a graph is biconnected. * - * \experimental - * * A graph is biconnected if the removal of any single vertex (and * its incident edges) does not disconnect it. * diff --git a/src/vendor/cigraph/src/core/heap.pmt b/src/vendor/cigraph/src/core/heap.pmt index 0aa14c97030..72c0cdd2e32 100644 --- a/src/vendor/cigraph/src/core/heap.pmt +++ b/src/vendor/cigraph/src/core/heap.pmt @@ -62,7 +62,6 @@ igraph_error_t FUNCTION(igraph_heap, init)(TYPE(igraph_heap)* h, igraph_integer_ IGRAPH_CHECK_OOM(h->stor_begin, "Cannot initialize heap."); h->stor_end = h->stor_begin + capacity; h->end = h->stor_begin; - h->destroy = true; return IGRAPH_SUCCESS; } @@ -88,7 +87,6 @@ igraph_error_t FUNCTION(igraph_heap, init_array)(TYPE(igraph_heap) *h, const BAS IGRAPH_CHECK_OOM(h->stor_begin, "Cannot initialize heap from array."); h->stor_end = h->stor_begin + len; h->end = h->stor_end; - h->destroy = true; memcpy(h->stor_begin, data, (size_t) len * sizeof(BASE)); @@ -108,10 +106,8 @@ igraph_error_t FUNCTION(igraph_heap, init_array)(TYPE(igraph_heap) *h, const BAS */ void FUNCTION(igraph_heap, destroy)(TYPE(igraph_heap)* h) { - if (h->destroy) { - if (h->stor_begin != NULL) { - IGRAPH_FREE(h->stor_begin); /* sets to NULL */ - } + if (h->stor_begin != NULL) { + IGRAPH_FREE(h->stor_begin); /* sets to NULL */ } } diff --git a/src/vendor/cigraph/src/core/indheap.c b/src/vendor/cigraph/src/core/indheap.c index b4ee00e4b54..7e30b55aa84 100644 --- a/src/vendor/cigraph/src/core/indheap.c +++ b/src/vendor/cigraph/src/core/indheap.c @@ -69,7 +69,6 @@ igraph_error_t igraph_indheap_init(igraph_indheap_t* h, igraph_integer_t alloc_s h->stor_end = h->stor_begin + alloc_size; h->end = h->stor_begin; - h->destroy = true; return IGRAPH_SUCCESS; } @@ -106,7 +105,6 @@ igraph_error_t igraph_indheap_init_array(igraph_indheap_t *h, const igraph_real_ } h->stor_end = h->stor_begin + alloc_size; h->end = h->stor_begin + len; - h->destroy = true; memcpy(h->stor_begin, data, (size_t) len * sizeof(igraph_real_t)); for (i = 0; i < len; i++) { @@ -125,16 +123,14 @@ igraph_error_t igraph_indheap_init_array(igraph_indheap_t *h, const igraph_real_ void igraph_indheap_destroy(igraph_indheap_t* h) { IGRAPH_ASSERT(h != 0); - if (h->destroy) { - if (h->stor_begin != 0) { - IGRAPH_FREE(h->stor_begin); - h->stor_begin = 0; - } - if (h->index_begin != 0) { - IGRAPH_FREE(h->index_begin); - h->index_begin = 0; - } - } + if (h->stor_begin != 0) { + IGRAPH_FREE(h->stor_begin); + h->stor_begin = 0; + } + if (h->index_begin != 0) { + IGRAPH_FREE(h->index_begin); + h->index_begin = 0; + } } /** @@ -451,7 +447,6 @@ igraph_error_t igraph_d_indheap_init(igraph_d_indheap_t* h, igraph_integer_t all } h->stor_end = h->stor_begin + alloc_size; h->end = h->stor_begin; - h->destroy = true; h->index_begin = IGRAPH_CALLOC(alloc_size, igraph_integer_t); if (h->index_begin == 0) { IGRAPH_FREE(h->stor_begin); @@ -478,20 +473,18 @@ igraph_error_t igraph_d_indheap_init(igraph_d_indheap_t* h, igraph_integer_t all void igraph_d_indheap_destroy(igraph_d_indheap_t* h) { IGRAPH_ASSERT(h != 0); - if (h->destroy) { - if (h->stor_begin != 0) { - IGRAPH_FREE(h->stor_begin); - h->stor_begin = 0; - } - if (h->index_begin != 0) { - IGRAPH_FREE(h->index_begin); - h->index_begin = 0; - } - if (h->index2_begin != 0) { - IGRAPH_FREE(h->index2_begin); - h->index2_begin = 0; - } - } + if (h->stor_begin != 0) { + IGRAPH_FREE(h->stor_begin); + h->stor_begin = 0; + } + if (h->index_begin != 0) { + IGRAPH_FREE(h->index_begin); + h->index_begin = 0; + } + if (h->index2_begin != 0) { + IGRAPH_FREE(h->index2_begin); + h->index2_begin = 0; + } } /** diff --git a/src/vendor/cigraph/src/core/indheap.h b/src/vendor/cigraph/src/core/indheap.h index 9f340c33301..41c37587348 100644 --- a/src/vendor/cigraph/src/core/indheap.h +++ b/src/vendor/cigraph/src/core/indheap.h @@ -42,11 +42,10 @@ typedef struct s_indheap { igraph_real_t* stor_begin; igraph_real_t* stor_end; igraph_real_t* end; - igraph_bool_t destroy; igraph_integer_t* index_begin; } igraph_indheap_t; -#define IGRAPH_INDHEAP_NULL { 0,0,0,0,0 } +#define IGRAPH_INDHEAP_NULL { 0,0,0,0 } igraph_error_t igraph_indheap_init(igraph_indheap_t* h, igraph_integer_t size); igraph_error_t igraph_indheap_init_array(igraph_indheap_t *t, const igraph_real_t *data, igraph_integer_t len); @@ -81,13 +80,12 @@ typedef struct s_indheap_d { igraph_real_t* stor_begin; igraph_real_t* stor_end; igraph_real_t* end; - igraph_bool_t destroy; igraph_integer_t* index_begin; igraph_integer_t* index2_begin; } igraph_d_indheap_t; -#define IGRAPH_D_INDHEAP_NULL { 0,0,0,0,0,0 } +#define IGRAPH_D_INDHEAP_NULL { 0,0,0,0,0 } IGRAPH_PRIVATE_EXPORT igraph_error_t igraph_d_indheap_init(igraph_d_indheap_t *h, igraph_integer_t size); IGRAPH_PRIVATE_EXPORT void igraph_d_indheap_destroy(igraph_d_indheap_t *h); diff --git a/src/vendor/cigraph/src/core/interruption.c b/src/vendor/cigraph/src/core/interruption.c index 794220389ac..c1aacb62dd3 100644 --- a/src/vendor/cigraph/src/core/interruption.c +++ b/src/vendor/cigraph/src/core/interruption.c @@ -24,13 +24,13 @@ #include "igraph_interrupt.h" #include "config.h" -IGRAPH_THREAD_LOCAL igraph_interruption_handler_t *igraph_i_interruption_handler = 0; +IGRAPH_THREAD_LOCAL igraph_interruption_handler_t *igraph_i_interruption_handler = NULL; -igraph_error_t igraph_allow_interruption(void *data) { +igraph_bool_t igraph_allow_interruption(void) { if (igraph_i_interruption_handler) { - return igraph_i_interruption_handler(data); + return igraph_i_interruption_handler(); } - return IGRAPH_SUCCESS; + return false; } igraph_interruption_handler_t *igraph_set_interruption_handler (igraph_interruption_handler_t *new_handler) { diff --git a/src/vendor/cigraph/src/core/interruption.h b/src/vendor/cigraph/src/core/interruption.h index 98cbafbf3c7..5b91717bc36 100644 --- a/src/vendor/cigraph/src/core/interruption.h +++ b/src/vendor/cigraph/src/core/interruption.h @@ -37,16 +37,15 @@ extern IGRAPH_THREAD_LOCAL igraph_interruption_handler_t *igraph_i_interruption_ * \brief * * This macro should be called when interruption is allowed. It calls - * \ref igraph_allow_interruption() with the proper parameters and if that returns - * anything but \c IGRAPH_SUCCESS then - * the macro returns the "calling" function as well, with the proper - * error code (\c IGRAPH_INTERRUPTED). + * \ref igraph_allow_interruption() and if that returns anything but + * \c IGRAPH_SUCCESS then the macro returns the "calling" function as well, + * with the proper error code (\c IGRAPH_INTERRUPTED). */ #define IGRAPH_ALLOW_INTERRUPTION() \ do { \ if (igraph_i_interruption_handler) { \ - if (igraph_allow_interruption(NULL) != IGRAPH_SUCCESS) { \ + if (igraph_allow_interruption()) { \ return IGRAPH_INTERRUPTED; \ } \ } \ diff --git a/src/vendor/cigraph/src/core/matrix.pmt b/src/vendor/cigraph/src/core/matrix.pmt index 64418149cf5..b640d5b0f46 100644 --- a/src/vendor/cigraph/src/core/matrix.pmt +++ b/src/vendor/cigraph/src/core/matrix.pmt @@ -1113,12 +1113,11 @@ igraph_error_t FUNCTION(igraph_matrix, cbind)(TYPE(igraph_matrix) *to, * The contents of the two matrices will be swapped. * \param m1 The first matrix. * \param m2 The second matrix. - * \return Error code. * * Time complexity: O(1). */ -igraph_error_t FUNCTION(igraph_matrix, swap)(TYPE(igraph_matrix) *m1, TYPE(igraph_matrix) *m2) { +void FUNCTION(igraph_matrix, swap)(TYPE(igraph_matrix) *m1, TYPE(igraph_matrix) *m2) { igraph_integer_t tmp; tmp = m1->nrow; @@ -1129,9 +1128,7 @@ igraph_error_t FUNCTION(igraph_matrix, swap)(TYPE(igraph_matrix) *m1, TYPE(igrap m1->ncol = m2->ncol; m2->ncol = tmp; - IGRAPH_CHECK(FUNCTION(igraph_vector, swap)(&m1->data, &m2->data)); - - return IGRAPH_SUCCESS; + FUNCTION(igraph_vector, swap)(&m1->data, &m2->data); } /** diff --git a/src/vendor/cigraph/src/core/sparsemat.c b/src/vendor/cigraph/src/core/sparsemat.c index 524c109cb03..a072a5c342d 100644 --- a/src/vendor/cigraph/src/core/sparsemat.c +++ b/src/vendor/cigraph/src/core/sparsemat.c @@ -28,7 +28,6 @@ #include "igraph_interface.h" #include "igraph_memory.h" #include "igraph_types.h" -#include "igraph_vector_ptr.h" #include "internal/hacks.h" /* IGRAPH_STATIC_ASSERT */ @@ -1368,10 +1367,9 @@ igraph_error_t igraph_weighted_sparsemat(igraph_t *graph, const igraph_sparsemat igraph_bool_t loops) { igraph_vector_int_t edges; - igraph_vector_t weights; CS_INT pot_edges = igraph_i_sparsemat_count_elements(A); const char* default_attr = "weight"; - igraph_vector_ptr_t attr_vec; + igraph_attribute_record_list_t attrs; igraph_attribute_record_t attr_rec; CS_INT no_of_nodes = A->cs->m; @@ -1380,37 +1378,43 @@ igraph_error_t igraph_weighted_sparsemat(igraph_t *graph, const igraph_sparsemat } IGRAPH_VECTOR_INT_INIT_FINALLY(&edges, pot_edges * 2); - IGRAPH_VECTOR_INIT_FINALLY(&weights, pot_edges); - IGRAPH_VECTOR_PTR_INIT_FINALLY(&attr_vec, 1); + /* Prepare attribute record list */ + IGRAPH_CHECK(igraph_attribute_record_list_init(&attrs, 0)); + IGRAPH_FINALLY(igraph_attribute_record_list_destroy, &attrs); + + /* Prepare attribute record */ + IGRAPH_CHECK(igraph_attribute_record_init( + &attr_rec, attr ? attr : default_attr, IGRAPH_ATTRIBUTE_NUMERIC + )); + IGRAPH_FINALLY(igraph_attribute_record_destroy, &attr_rec); + + /* Convert sparse matrix, storing weights in the attribute record */ if (igraph_sparsemat_is_cc(A)) { IGRAPH_CHECK(igraph_i_weighted_sparsemat_cc(A, directed, attr, loops, - &edges, &weights)); + &edges, attr_rec.value.as_vector)); } else { IGRAPH_CHECK(igraph_i_weighted_sparsemat_triplet(A, directed, attr, loops, &edges, - &weights)); + attr_rec.value.as_vector)); } - /* Prepare attribute record */ - attr_rec.name = attr ? attr : default_attr; - attr_rec.type = IGRAPH_ATTRIBUTE_NUMERIC; - attr_rec.value = &weights; - VECTOR(attr_vec)[0] = &attr_rec; + /* Transfer ownership of attribute record to attribute record list */ + IGRAPH_CHECK(igraph_attribute_record_list_push_back(&attrs, &attr_rec)); + IGRAPH_FINALLY_CLEAN(1); /* Create graph */ IGRAPH_CHECK(igraph_empty(graph, no_of_nodes, directed)); IGRAPH_FINALLY(igraph_destroy, graph); if (igraph_vector_int_size(&edges) > 0) { - IGRAPH_CHECK(igraph_add_edges(graph, &edges, &attr_vec)); + IGRAPH_CHECK(igraph_add_edges(graph, &edges, &attrs)); } IGRAPH_FINALLY_CLEAN(1); /* Cleanup */ + igraph_attribute_record_list_destroy(&attrs); igraph_vector_int_destroy(&edges); - igraph_vector_destroy(&weights); - igraph_vector_ptr_destroy(&attr_vec); - IGRAPH_FINALLY_CLEAN(3); + IGRAPH_FINALLY_CLEAN(2); return IGRAPH_SUCCESS; } diff --git a/src/vendor/cigraph/src/core/strvector.c b/src/vendor/cigraph/src/core/strvector.c index eb4bc2ea782..31fe27aa69f 100644 --- a/src/vendor/cigraph/src/core/strvector.c +++ b/src/vendor/cigraph/src/core/strvector.c @@ -21,8 +21,9 @@ */ -#include "igraph_types.h" #include "igraph_strvector.h" + +#include "igraph_types.h" #include "igraph_memory.h" #include "igraph_error.h" @@ -70,7 +71,7 @@ igraph_error_t igraph_strvector_init(igraph_strvector_t *sv, igraph_integer_t size) { - sv->stor_begin = IGRAPH_CALLOC(size, char*); + sv->stor_begin = IGRAPH_CALLOC(size, const char *); IGRAPH_CHECK_OOM(sv->stor_begin, "Cannot initialize string vector."); sv->stor_end = sv->stor_begin + size; @@ -93,10 +94,9 @@ igraph_error_t igraph_strvector_init(igraph_strvector_t *sv, igraph_integer_t si */ void igraph_strvector_destroy(igraph_strvector_t *sv) { - char **ptr; IGRAPH_ASSERT(sv != NULL); IGRAPH_ASSERT(sv->stor_begin != NULL); - for (ptr = sv->stor_begin; ptr < sv->end; ptr++) { + for (const char **ptr = sv->stor_begin; ptr < sv->end; ptr++) { IGRAPH_FREE(*ptr); } IGRAPH_FREE(sv->stor_begin); @@ -172,9 +172,9 @@ igraph_error_t igraph_strvector_set_len(igraph_strvector_t *sv, igraph_integer_t char *tmp = IGRAPH_REALLOC(sv->stor_begin[idx], len + 1, char); IGRAPH_CHECK_OOM(tmp, "Cannot reserve space for new item in string vector."); + memcpy(tmp, value, len * sizeof(char)); + tmp[len] = '\0'; sv->stor_begin[idx] = tmp; - memcpy(sv->stor_begin[idx], value, len * sizeof(char)); - sv->stor_begin[idx][len] = '\0'; } return IGRAPH_SUCCESS; @@ -250,7 +250,7 @@ igraph_error_t igraph_strvector_init_copy(igraph_strvector_t *to, const igraph_strvector_t *from) { igraph_integer_t from_size = igraph_strvector_size(from); - to->stor_begin = IGRAPH_CALLOC(from_size, char*); + to->stor_begin = IGRAPH_CALLOC(from_size, const char *); IGRAPH_CHECK_OOM(to->stor_begin, "Cannot copy string vector."); for (igraph_integer_t i = 0; i < from_size; i++) { @@ -311,10 +311,10 @@ igraph_error_t igraph_strvector_copy(igraph_strvector_t *to, igraph_error_t igraph_strvector_append(igraph_strvector_t *to, const igraph_strvector_t *from) { - igraph_integer_t len1 = igraph_strvector_size(to), len2 = igraph_strvector_size(from); + const igraph_integer_t len1 = igraph_strvector_size(to), len2 = igraph_strvector_size(from); igraph_integer_t newlen; igraph_bool_t error = false; - char *tmp; + const char *tmp; IGRAPH_SAFE_ADD(len1, len2, &newlen); IGRAPH_CHECK(igraph_strvector_reserve(to, newlen)); @@ -362,7 +362,7 @@ igraph_error_t igraph_strvector_append(igraph_strvector_t *to, * where l1 and l2 are the lengths of \p to and \from respectively. */ igraph_error_t igraph_strvector_merge(igraph_strvector_t *to, igraph_strvector_t *from) { - char **p1, **p2, **pe; + const char **p1, **p2, **pe; igraph_integer_t newlen; IGRAPH_SAFE_ADD(igraph_strvector_size(to), igraph_strvector_size(from), &newlen); @@ -431,7 +431,7 @@ igraph_error_t igraph_strvector_resize(igraph_strvector_t *sv, igraph_integer_t sv->end = sv->stor_begin + newsize; } else if (newsize > oldsize) { IGRAPH_CHECK(igraph_strvector_reserve(sv, newsize)); - memset(sv->stor_begin + oldsize, 0, toadd * sizeof(char *)); + memset(sv->stor_begin + oldsize, 0, toadd * sizeof(const char *)); sv->end = sv->stor_begin + newsize; } @@ -484,13 +484,12 @@ igraph_integer_t igraph_strvector_capacity(const igraph_strvector_t *sv) { igraph_error_t igraph_strvector_reserve(igraph_strvector_t *sv, igraph_integer_t capacity) { igraph_integer_t current_capacity = igraph_strvector_capacity(sv); - char **tmp; if (capacity <= current_capacity) { return IGRAPH_SUCCESS; } - tmp = IGRAPH_REALLOC(sv->stor_begin, capacity, char *); + const char **tmp = IGRAPH_REALLOC(sv->stor_begin, capacity, const char *); IGRAPH_CHECK_OOM(tmp, "Cannot reserve space for new items in string vector."); sv->end = tmp + (sv->end - sv->stor_begin); @@ -516,14 +515,12 @@ igraph_error_t igraph_strvector_reserve(igraph_strvector_t *sv, igraph_integer_t */ void igraph_strvector_resize_min(igraph_strvector_t *sv) { - igraph_integer_t size; - char **tmp; if (sv->stor_end == sv->end) { return; } - size = (sv->end - sv->stor_begin); - tmp = IGRAPH_REALLOC(sv->stor_begin, size, char *); + const igraph_integer_t size = (sv->end - sv->stor_begin); + const char **tmp = IGRAPH_REALLOC(sv->stor_begin, size, const char *); if (tmp != NULL) { sv->stor_begin = tmp; @@ -586,7 +583,7 @@ static igraph_error_t igraph_i_strvector_expand_if_full(igraph_strvector_t *sv) igraph_error_t igraph_strvector_push_back(igraph_strvector_t *sv, const char *value) { IGRAPH_CHECK(igraph_i_strvector_expand_if_full(sv)); - char *tmp = strdup(value); + const char *tmp = strdup(value); IGRAPH_CHECK_OOM(tmp, "Cannot push new string to string vector."); *sv->end = tmp; sv->end++; @@ -613,7 +610,7 @@ igraph_error_t igraph_strvector_push_back_len( const char *value, igraph_integer_t len) { IGRAPH_CHECK(igraph_i_strvector_expand_if_full(sv)); - char *tmp = strndup(value, len); + const char *tmp = strndup(value, len); if (! tmp) { IGRAPH_ERROR("Cannot add string to string vector.", IGRAPH_ENOMEM); /* LCOV_EXCL_LINE */ } @@ -697,3 +694,42 @@ igraph_error_t igraph_strvector_index(const igraph_strvector_t *sv, return IGRAPH_SUCCESS; } + +/** + * \ingroup strvector + * \function igraph_strvector_update + * \brief Updates a string vector from another one. + * + * After this operation the contents of \p to will be exactly the same + * as that of \p from. The vector \p to will be resized if it was originally + * shorter or longer than \p from. + * + * \param to The string vector to update. + * \param from The string vector to update from. + * \return Error code. + */ +igraph_error_t igraph_strvector_update( + igraph_strvector_t *to, const igraph_strvector_t *from +) { + igraph_strvector_clear(to); + IGRAPH_CHECK(igraph_strvector_append(to, from)); + return IGRAPH_SUCCESS; +} + +/** + * \ingroup strvector + * \function igraph_strvector_swap + * \brief Swaps all elements of two string vectors. + * + * \param v1 The first string vector. + * \param v2 The second string vector. + * + * Time complexity: O(1). + */ +void igraph_strvector_swap(igraph_strvector_t *v1, igraph_strvector_t *v2) { + igraph_strvector_t tmp; + + tmp = *v1; + *v1 = *v2; + *v2 = tmp; +} diff --git a/src/vendor/cigraph/src/core/typed_list.pmt b/src/vendor/cigraph/src/core/typed_list.pmt index 75aaa80e8a4..1ffc3421355 100644 --- a/src/vendor/cigraph/src/core/typed_list.pmt +++ b/src/vendor/cigraph/src/core/typed_list.pmt @@ -65,6 +65,8 @@ * _item_ in the vector */ #if defined(BASE_GRAPH) #define ITEM_FUNCTION(f) CONCAT2x(igraph,f) + #elif defined(BASE_ATTRIBUTE_RECORD) + #define ITEM_FUNCTION(f) CONCAT2x(igraph_attribute_record,f) #endif #endif @@ -117,6 +119,38 @@ igraph_error_t FUNCTION(init)(TYPE* v, igraph_integer_t size) { return IGRAPH_SUCCESS; } +/** + * \ingroup vector_list + * \function igraph_vector_list_init_copy + * \brief Initializes a list of vectors from another list of vectors (constructor). + * + * + * The contents of the existing list will be copied to the new one. + * \param to Pointer to a not yet initialized list of vectors. + * \param from The original list of vectors to copy. + * \return Error code: + * \c IGRAPH_ENOMEM if there is not enough memory. + * + * Time complexity: operating system dependent, usually O(nm), n is the size of + * the list, m is the size of each element in the list, assuming that copying a + * single item takes O(m) time. + */ + +igraph_error_t FUNCTION(init_copy)(TYPE* to, const TYPE* from) { + igraph_integer_t i, size = FUNCTION(size)(from); + + IGRAPH_CHECK(FUNCTION(init)(to, 0)); + IGRAPH_FINALLY(FUNCTION(destroy), to); + + for (i = 0; i < size; i++) { + IGRAPH_CHECK(FUNCTION(push_back_copy)(to, FUNCTION(get_ptr)(from, i))); + } + + IGRAPH_FINALLY_CLEAN(1); + + return IGRAPH_SUCCESS; +} + /** * \ingroup vector_list * \function igraph_vector_list_destroy diff --git a/src/vendor/cigraph/src/core/vector.pmt b/src/vendor/cigraph/src/core/vector.pmt index 6cb5c6fcbb5..adb19b7918c 100644 --- a/src/vendor/cigraph/src/core/vector.pmt +++ b/src/vendor/cigraph/src/core/vector.pmt @@ -2553,20 +2553,17 @@ igraph_error_t FUNCTION(igraph_vector, update)(TYPE(igraph_vector) *to, * * \param v1 The first vector. * \param v2 The second vector. - * \return Error code. * * Time complexity: O(1). */ -igraph_error_t FUNCTION(igraph_vector, swap)(TYPE(igraph_vector) *v1, TYPE(igraph_vector) *v2) { +void FUNCTION(igraph_vector, swap)(TYPE(igraph_vector) *v1, TYPE(igraph_vector) *v2) { TYPE(igraph_vector) tmp; tmp = *v1; *v1 = *v2; *v2 = tmp; - - return IGRAPH_SUCCESS; } /** @@ -2629,7 +2626,6 @@ igraph_error_t FUNCTION(igraph_vector, reverse)(TYPE(igraph_vector) *v) { * these generators is less than the number of possible permutations * of the vector if the vector is long enough. * \param v The vector object. - * \return Error code, currently always \c IGRAPH_SUCCESS. * * Time complexity: O(n), * n is the number of elements in the @@ -2650,7 +2646,7 @@ igraph_error_t FUNCTION(igraph_vector, reverse)(TYPE(igraph_vector) *v) { * \example examples/simple/igraph_fisher_yates_shuffle.c */ -igraph_error_t FUNCTION(igraph_vector, shuffle)(TYPE(igraph_vector) *v) { +void FUNCTION(igraph_vector, shuffle)(TYPE(igraph_vector) *v) { igraph_integer_t n = FUNCTION(igraph_vector, size)(v); igraph_integer_t k; BASE dummy; @@ -2664,8 +2660,6 @@ igraph_error_t FUNCTION(igraph_vector, shuffle)(TYPE(igraph_vector) *v) { VECTOR(*v)[k] = dummy; } RNG_END(); - - return IGRAPH_SUCCESS; } /** diff --git a/src/vendor/cigraph/src/flow/st-cuts.c b/src/vendor/cigraph/src/flow/st-cuts.c index 692b6f6878b..75a1a4a5eb0 100644 --- a/src/vendor/cigraph/src/flow/st-cuts.c +++ b/src/vendor/cigraph/src/flow/st-cuts.c @@ -596,9 +596,7 @@ igraph_error_t igraph_dominator_tree(const igraph_t *graph, igraph_vector_int_destroy(&edges); IGRAPH_FINALLY_CLEAN(1); - IGRAPH_I_ATTRIBUTE_DESTROY(domtree); - IGRAPH_I_ATTRIBUTE_COPY(domtree, graph, - /*graph=*/ true, /*vertex=*/ true, /*edge=*/ false); + IGRAPH_CHECK(igraph_i_attribute_copy(domtree, graph, true, true, /*edges=*/ false)); } if (!dom) { @@ -766,7 +764,7 @@ igraph_error_t igraph_i_all_st_cuts_pivot( IGRAPH_FINALLY_CLEAN(1); IGRAPH_FINALLY(igraph_destroy, &Sbar); - root = VECTOR(Sbar_map)[target] - 1; + root = VECTOR(Sbar_map)[target]; /* -------------------------------------------------------------*/ /* Construct the dominator tree of Sbar */ @@ -786,7 +784,7 @@ igraph_error_t igraph_i_all_st_cuts_pivot( IGRAPH_CHECK(igraph_vector_bool_init(&GammaS, no_of_nodes)); IGRAPH_FINALLY(igraph_vector_bool_destroy, &GammaS); if (igraph_marked_queue_int_size(S) == 0) { - VECTOR(GammaS)[VECTOR(Sbar_map)[source] - 1] = true; + VECTOR(GammaS)[VECTOR(Sbar_map)[source]] = true; } else { for (i = 0; i < no_of_nodes; i++) { if (igraph_marked_queue_int_iselement(S, i)) { @@ -841,7 +839,7 @@ igraph_error_t igraph_i_all_st_cuts_pivot( Nu(v) contains all vertices that are dominated by v, for every v, this is a subtree of the dominator tree, rooted at v. The different subtrees are disjoint. */ - igraph_integer_t min = VECTOR(Sbar_map)[ VECTOR(M)[i] ] - 1; + igraph_integer_t min = VECTOR(Sbar_map)[ VECTOR(M)[i] ]; igraph_integer_t nuvsize, isvlen, j; IGRAPH_CHECK(igraph_dfs(&domtree, min, IGRAPH_IN, /*unreachable=*/ false, /*order=*/ &Nuv, diff --git a/src/vendor/cigraph/src/games/erdos_renyi.c b/src/vendor/cigraph/src/games/erdos_renyi.c index b7b2dbd6dee..ab0968bfda2 100644 --- a/src/vendor/cigraph/src/games/erdos_renyi.c +++ b/src/vendor/cigraph/src/games/erdos_renyi.c @@ -176,6 +176,63 @@ igraph_error_t igraph_erdos_renyi_game_gnp( return IGRAPH_SUCCESS; } +/** + * \ingroup generators + * \function igraph_erdos_renyi_game_gnm_multi + * \brief Generates a random (Erdős-Rényi) graph with multi-edges. + * + * \param graph Pointer to an uninitialized graph object. + * \param n The number of vertices in the graph. + * \param m The number of edges in the graph. + * \param directed Logical, whether to generate a directed graph. + * \param loops Logical, whether to generate loops (self) edges. + * \return Error code: + * \c IGRAPH_EINVAL: invalid \p n or \p m parameter. + * \c IGRAPH_ENOMEM: there is not enough + * memory for the operation. + * + * Time complexity: O(|V|+|E|), the + * number of vertices plus the number of edges in the graph. + */ +static igraph_error_t igraph_i_erdos_renyi_game_gnm_multi( + igraph_t *graph, igraph_integer_t n, igraph_integer_t m, + igraph_bool_t directed, igraph_bool_t loops +) { + + igraph_vector_int_t edges; + int iter = 0; + + /* No need for checking n or m here; it has already been done in + * igraph_erdos_renyi_game_gnm() */ + + IGRAPH_VECTOR_INT_INIT_FINALLY(&edges, 0); + IGRAPH_CHECK(igraph_vector_int_reserve(&edges, m * 2)); + + RNG_BEGIN(); + for (igraph_integer_t i = 0; i < m; i++) { + igraph_integer_t from, to; + from = RNG_INTEGER(0, n - 1); + if (loops) { + to = RNG_INTEGER(0, n - 1); + } else { + to = RNG_INTEGER(0, n - 2); + if (from == to) { + to = n - 1; + } + } + igraph_vector_int_push_back(&edges, from); /* reserved */ + igraph_vector_int_push_back(&edges, to); /* reserved */ + IGRAPH_ALLOW_INTERRUPTION_LIMITED(iter, 1 << 14); + } + RNG_END(); + + IGRAPH_CHECK(igraph_create(graph, &edges, n, directed)); + igraph_vector_int_destroy(&edges); + IGRAPH_FINALLY_CLEAN(1); + + return IGRAPH_SUCCESS; +} + /** * \ingroup generators * \function igraph_erdos_renyi_game_gnm @@ -189,6 +246,8 @@ igraph_error_t igraph_erdos_renyi_game_gnp( * \param m The number of edges in the graph. * \param directed Logical, whether to generate a directed graph. * \param loops Logical, whether to generate self-loops. + * \param multiple Logical, whether it is allowed to generate more than one + * edge between the same pair of vertices. * \return Error code: * \c IGRAPH_EINVAL: invalid \p n or \p m parameter. * \c IGRAPH_ENOMEM: there is not enough memory for the operation. @@ -203,7 +262,7 @@ igraph_error_t igraph_erdos_renyi_game_gnp( */ igraph_error_t igraph_erdos_renyi_game_gnm( igraph_t *graph, igraph_integer_t n, igraph_integer_t m, - igraph_bool_t directed, igraph_bool_t loops + igraph_bool_t directed, igraph_bool_t loops, igraph_bool_t multiple ) { /* This function uses doubles in its `s` vector, and for `maxedges` and `last`. @@ -225,6 +284,10 @@ igraph_error_t igraph_erdos_renyi_game_gnm( IGRAPH_ERROR("Invalid number of edges.", IGRAPH_EINVAL); } + if (multiple) { + return igraph_i_erdos_renyi_game_gnm_multi(graph, n, m, directed, loops); + } + if (m == 0.0 || no_of_nodes == 0) { IGRAPH_CHECK(igraph_empty(graph, n, directed)); } else { @@ -355,7 +418,7 @@ igraph_error_t igraph_erdos_renyi_game(igraph_t *graph, igraph_erdos_renyi_t typ if (type == IGRAPH_ERDOS_RENYI_GNP) { return igraph_erdos_renyi_game_gnp(graph, n, p_or_m, directed, loops); } else if (type == IGRAPH_ERDOS_RENYI_GNM) { - return igraph_erdos_renyi_game_gnm(graph, n, (igraph_integer_t) p_or_m, directed, loops); + return igraph_erdos_renyi_game_gnm(graph, n, (igraph_integer_t) p_or_m, directed, loops, IGRAPH_NO_MULTIPLE); } else { IGRAPH_ERROR("Invalid type", IGRAPH_EINVAL); } diff --git a/src/vendor/cigraph/src/games/static_fitness.c b/src/vendor/cigraph/src/games/static_fitness.c index 8c4c1f057dc..9236bd6a2e6 100644 --- a/src/vendor/cigraph/src/games/static_fitness.c +++ b/src/vendor/cigraph/src/games/static_fitness.c @@ -420,7 +420,7 @@ igraph_error_t igraph_static_power_law_game(igraph_t *graph, for (i = 0; i < no_of_nodes; i++, j--) { VECTOR(fitness_in)[i] = pow(j, alpha_in); } - IGRAPH_CHECK(igraph_vector_shuffle(&fitness_in)); + igraph_vector_shuffle(&fitness_in); IGRAPH_CHECK(igraph_static_fitness_game(graph, no_of_edges, &fitness_out, &fitness_in, loops, multiple)); diff --git a/src/vendor/cigraph/src/graph/attributes.c b/src/vendor/cigraph/src/graph/attributes.c index 731d628d9d3..1eb37e929ab 100644 --- a/src/vendor/cigraph/src/graph/attributes.c +++ b/src/vendor/cigraph/src/graph/attributes.c @@ -30,21 +30,602 @@ #include #include +/** + * \section about_attributes + * + * Attributes are numbers, boolean values or strings associated with + * the vertices or edges of a graph, or with the graph itself. E.g. you may + * label vertices with symbolic names or attach numeric weights to the edges + * of a graph. In addition to these three basic types, a custom object + * type is supported as well. + * + * igraph attributes are designed to be flexible and extensible. + * In igraph attributes are implemented via an interface abstraction: + * any type implementing the functions in the interface can be used + * for storing vertex, edge and graph attributes. This means that + * different attribute implementations can be used together with + * igraph. This is reasonable: if igraph is used from Python attributes can be + * of any Python type, from R all R types are allowed. There is also an + * experimental attribute implementation to be used when programming + * in C, but by default it is currently turned off. + * + * First we briefly look over how attribute handlers can be + * implemented. This is not something a user does every day. It is + * rather typically the job of the high level interface writers. (But + * it is possible to write an interface without implementing + * attributes.) Then we show the experimental C attribute handler. + */ + +/** + * \section about_attribute_table + * It is possible to attach an attribute handling + * interface to \a igraph. This is simply a table of functions, of + * type \ref igraph_attribute_table_t. These functions are invoked to + * notify the attribute handling code about the structural changes in + * a graph. See the documentation of this type for details. + * + * By default there is no attribute interface attached to \a igraph. + * To attach one, call \ref igraph_set_attribute_table with your new + * table. This is normally done on program startup, and is kept untouched + * for the program's lifetime. It must be done before any graph object + * is created, as graphs created with a given attribute handler + * cannot be manipulated while a different attribute handler is + * active. + */ + +/** + * \section about_attribute_record + * + * Functions in the attribute handler interface may refer to + * \em "attribute records" or \em "attribute record lists". An attribute record + * is simply a triplet consisting of an attribute name, an attribute type and + * a vector containing the values of the attribute. Attribute record lists are + * typed containers that contain a sequence of attribute records. Attribute + * record lists own the attribute records that they contain, and similarly, + * attribute records own the vectors contained in them. Destroying an attribute + * record destroys the vector of values inside it, and destroying an attribute + * record list destroys all attribute records in the list. + */ + +/** + * \section about_attribute_combination + * + * Several graph operations may collapse multiple vertices or edges into + * a single one. Attribute combination lists are used to indicate to the attribute + * handler how to combine the attributes of the original vertices or edges and + * how to derive the final attribute value that is to be assigned to the collapsed + * vertex or edge. For example, \ref igraph_simplify() removes loops and combines + * multiple edges into a single one; in case of a graph with an edge attribute + * named \c weight the attribute combination list can tell the attribute handler + * whether the weight of a collapsed edge should be the sum, the mean or some other + * function of the weights of the original edges that were collapsed into one. + * + * One attribute combination list may contain several attribute combination + * records, one for each vertex or edge attribute that is to be handled during the + * operation. + */ + +static void igraph_i_attribute_record_set_type( + igraph_attribute_record_t *attr, igraph_attribute_type_t type, void *ptr +); +static void igraph_i_attribute_record_destroy_values(igraph_attribute_record_t *attr); + +/** + * \function igraph_attribute_record_init + * \brief Initializes an attribute record with a given name and type. + * + * \param attr the attribute record to initialize + * \param name name of the attribute + * \param type type of the attribute + * \return Error code: + * \c IGRAPH_ENOMEM if there is not enough memory. + * + * Time complexity: O(1). + */ +igraph_error_t igraph_attribute_record_init( + igraph_attribute_record_t *attr, const char* name, igraph_attribute_type_t type +) { + attr->name = NULL; + attr->type = IGRAPH_ATTRIBUTE_UNSPECIFIED; + attr->value.as_raw = NULL; + attr->default_value.string = NULL; + + IGRAPH_CHECK(igraph_attribute_record_set_name(attr, name)); + IGRAPH_CHECK(igraph_attribute_record_set_type(attr, type)); + + return IGRAPH_SUCCESS; +} + +/** + * \function igraph_attribute_record_init_copy + * \brief Initializes an attribute record by copying another record. + * + * + * Copies made by this function are deep copies: a full copy of the value + * vector contained in the record is placed in the new record so they become + * independent of each other. + * + * \param to the attribute record to initialize + * \param from the attribute record to copy data from + * \return Error code: + * \c IGRAPH_ENOMEM if there is not enough memory. + * + * Time complexity: operating system dependent, usually O(n), where n is the + * size of the value vector in the attribute record. + */ +igraph_error_t igraph_attribute_record_init_copy( + igraph_attribute_record_t *to, const igraph_attribute_record_t *from +) { + IGRAPH_CHECK(igraph_attribute_record_init(to, from->name, from->type)); + + switch (from->type) { + case IGRAPH_ATTRIBUTE_NUMERIC: + IGRAPH_CHECK(igraph_vector_update(to->value.as_vector, from->value.as_vector)); + break; + + case IGRAPH_ATTRIBUTE_STRING: + IGRAPH_CHECK(igraph_strvector_update(to->value.as_strvector, from->value.as_strvector)); + break; + + case IGRAPH_ATTRIBUTE_BOOLEAN: + IGRAPH_CHECK(igraph_vector_bool_update(to->value.as_vector_bool, from->value.as_vector_bool)); + break; + + case IGRAPH_ATTRIBUTE_UNSPECIFIED: + break; + + default: + break; + } + + return IGRAPH_SUCCESS; +} + +static void igraph_i_attribute_record_destroy_values(igraph_attribute_record_t *attr) { + IGRAPH_ASSERT(attr != NULL); + + if (attr->value.as_raw) { + switch (attr->type) { + case IGRAPH_ATTRIBUTE_NUMERIC: + igraph_vector_destroy(attr->value.as_vector); + break; + + case IGRAPH_ATTRIBUTE_STRING: + igraph_strvector_destroy(attr->value.as_strvector); + break; + + case IGRAPH_ATTRIBUTE_BOOLEAN: + igraph_vector_bool_destroy(attr->value.as_vector_bool); + break; + + default: + break; + } + + igraph_free(attr->value.as_raw); + attr->value.as_raw = NULL; + } + + switch (attr->type) { + case IGRAPH_ATTRIBUTE_NUMERIC: + attr->default_value.numeric = 0; + break; + + case IGRAPH_ATTRIBUTE_STRING: + if (attr->default_value.string) { + igraph_free(attr->default_value.string); + attr->default_value.string = NULL; + } + break; + + case IGRAPH_ATTRIBUTE_BOOLEAN: + attr->default_value.boolean = 0; + break; + + default: + break; + } + + attr->type = IGRAPH_ATTRIBUTE_UNSPECIFIED; +} + +/** + * \function igraph_attribute_record_destroy + * \brief Destroys an attribute record. + * + * \param attr the previously initialized attribute record to destroy. + * + * Time complexity: operating system dependent. + */ +void igraph_attribute_record_destroy(igraph_attribute_record_t *attr) { + igraph_i_attribute_record_destroy_values(attr); + + if (attr->name) { + igraph_free(attr->name); + attr->name = NULL; + } +} + +/** + * \function igraph_attribute_record_check_type + * \brief Checks whether the type of the attribute record is equal to an expected type. + * + * \param attr the attribute record to test + * \param type the expected type of the attribute record + * \return Error code: + * \c IGRAPH_EINVAL if the type of the attribute record is not equal to + * the expected type + * + * Time complexity: O(1). + */ +igraph_error_t igraph_attribute_record_check_type( + const igraph_attribute_record_t *attr, igraph_attribute_type_t type +) { + if (type != attr->type) { + switch (type) { + case IGRAPH_ATTRIBUTE_STRING: + IGRAPH_ERROR("String attribute expected.", IGRAPH_EINVAL); + break; + case IGRAPH_ATTRIBUTE_NUMERIC: + IGRAPH_ERROR("Numeric attribute expected.", IGRAPH_EINVAL); + break; + case IGRAPH_ATTRIBUTE_BOOLEAN: + IGRAPH_ERROR("Boolean attribute expected.", IGRAPH_EINVAL); + break; + case IGRAPH_ATTRIBUTE_OBJECT: + IGRAPH_ERROR("Object attribute expected.", IGRAPH_EINVAL); + break; + default: + IGRAPH_ERROR("Attribute with unknown type expected.", IGRAPH_EINVAL); + break; + } + } + + return IGRAPH_SUCCESS; +} + +/** + * \function igraph_attribute_record_size + * \brief Returns the size of the value vector in an attribute record. + * + * \param attr the attribute record to query + * \return the number of elements in the value vector of the attribute record + */ +igraph_integer_t igraph_attribute_record_size(const igraph_attribute_record_t *attr) { + IGRAPH_ASSERT(attr != NULL); + + switch (attr->type) { + case IGRAPH_ATTRIBUTE_NUMERIC: + return igraph_vector_size(attr->value.as_vector); + + case IGRAPH_ATTRIBUTE_STRING: + return igraph_strvector_size(attr->value.as_strvector); + + case IGRAPH_ATTRIBUTE_BOOLEAN: + return igraph_vector_bool_size(attr->value.as_vector_bool); + + case IGRAPH_ATTRIBUTE_UNSPECIFIED: + return 0; + + default: + IGRAPH_ERRORF("Unsupported attribute type: %d", IGRAPH_EINVAL, (int) attr->type); + } +} + +/** + * \function igraph_attribute_record_resize + * \brief Resizes the value vector in an attribute record. + * + * When the value vector is shorter than the desired length, it + * will be expanded with \c IGRAPH_NAN for numeric vectors, \c false for Boolean + * vectors and empty strings for string vectors. + * + * \param attr the attribute record to update + * \param new_size the new size of the value vector + * \return Error code: + * \c IGRAPH_ENOMEM if there is not enough memory. + * \c IGRAPH_EINVAL if the type of the attribute record is not specified yet. + */ +igraph_error_t igraph_attribute_record_resize( + igraph_attribute_record_t *attr, igraph_integer_t new_size +) { + igraph_integer_t i; + igraph_vector_t *vec; + igraph_vector_bool_t *log; + igraph_strvector_t *str; + + IGRAPH_ASSERT(attr != NULL); + + switch (attr->type) { + + case IGRAPH_ATTRIBUTE_NUMERIC: + vec = attr->value.as_vector; + i = igraph_vector_size(vec); + IGRAPH_CHECK(igraph_vector_resize(vec, new_size)); + while (i < new_size) { + VECTOR(*vec)[i++] = attr->default_value.numeric; + } + break; + + case IGRAPH_ATTRIBUTE_BOOLEAN: + log = attr->value.as_vector_bool; + i = igraph_vector_bool_size(log); + IGRAPH_CHECK(igraph_vector_bool_resize(log, new_size)); + while (i < new_size) { + VECTOR(*log)[i++] = attr->default_value.boolean; + } + break; + + case IGRAPH_ATTRIBUTE_STRING: + str = attr->value.as_strvector; + if (attr->default_value.string == 0 || (*attr->default_value.string == 0)) { + IGRAPH_CHECK(igraph_strvector_resize(str, new_size)); + } else { + i = igraph_strvector_size(str); + IGRAPH_CHECK(igraph_strvector_resize(str, new_size)); + while (i < new_size) { + IGRAPH_CHECK(igraph_strvector_set(str, i++, attr->default_value.string)); + } + } + break; + + case IGRAPH_ATTRIBUTE_UNSPECIFIED: + IGRAPH_ERROR("Attribute record has no type yet.", IGRAPH_EINVAL); + break; + + default: + IGRAPH_ERRORF("Unsupported attribute type: %d", IGRAPH_EINVAL, (int) attr->type); + } + + return IGRAPH_SUCCESS; +} + +/** + * \function igraph_attribute_record_set_default_numeric + * \brief Sets the default value of the attribute to the given number. + * + * + * This function must be called for numeric attribute records only. When not + * specified, the default value of numeric attributes is NaN. + * + * \param attr the attribute record to update + * \param value the new default value + * \return Error code: + * \c IGRAPH_EINVAL if the attribute record has a non-numeric type + */ +igraph_error_t igraph_attribute_record_set_default_numeric( + igraph_attribute_record_t *attr, igraph_real_t value +) { + if (attr->type != IGRAPH_ATTRIBUTE_NUMERIC) { + return IGRAPH_EINVAL; + } + + attr->default_value.numeric = value; + return IGRAPH_SUCCESS; +} + +/** + * \function igraph_attribute_record_set_default_boolean + * \brief Sets the default value of the attribute to the given logical value. + * + * + * This function must be called for Boolean attribute records only. When not + * specified, the default value of Boolean attributes is \c false. + * + * \param attr the attribute record to update + * \param value the new default value + * \return Error code: + * \c IGRAPH_EINVAL if the attribute record is not of Boolean type + */ +IGRAPH_EXPORT igraph_error_t igraph_attribute_record_set_default_boolean( + igraph_attribute_record_t *attr, igraph_bool_t value +) { + if (attr->type != IGRAPH_ATTRIBUTE_BOOLEAN) { + return IGRAPH_EINVAL; + } + + attr->default_value.boolean = value; + return IGRAPH_SUCCESS; +} + +/** + * \function igraph_attribute_record_set_default_string + * \brief Sets the default value of the attribute to the given string. + * + * + * This function must be called for string attribute records only. When not + * specified, the default value of string attributes is an empty string. + * + * \param attr the attribute record to update + * \param value the new default value. \c NULL means an empty string. + * + * \return Error code: + * \c IGRAPH_ENOMEM if there is not enough memory + * \c IGRAPH_EINVAL if the attribute record is not of string type + */ +IGRAPH_EXPORT igraph_error_t igraph_attribute_record_set_default_string( + igraph_attribute_record_t *attr, const char* value +) { + char* copy; + + if (attr->type != IGRAPH_ATTRIBUTE_STRING) { + return IGRAPH_EINVAL; + } + + if (value && (*value != 0)) { + copy = strdup(value); + IGRAPH_CHECK_OOM(copy, "Insufficient memory to duplicate default value."); + } else { + copy = NULL; + } + + if (attr->default_value.string) { + igraph_free(attr->default_value.string); + } + attr->default_value.string = copy; + + return IGRAPH_SUCCESS; +} + + +/** + * \function igraph_attribute_record_set_name + * \brief Sets the attribute name in an attribute record. + * + * \param attr the attribute record to update + * \param name the new name + * \return Error code: + * \c IGRAPH_ENOMEM if there is not enough memory. + */ +igraph_error_t igraph_attribute_record_set_name( + igraph_attribute_record_t *attr, const char* name +) { + char* new_name; + + IGRAPH_ASSERT(attr != NULL); + + if (name != NULL) { + new_name = strdup(name); + IGRAPH_CHECK_OOM(new_name, "Insufficient memory for allocating attribute name."); + } else { + new_name = NULL; + } + + if (attr->name) { + igraph_free(attr->name); + } + + attr->name = new_name; + + return IGRAPH_SUCCESS; +} + +static void igraph_i_attribute_record_set_type( + igraph_attribute_record_t *attr, igraph_attribute_type_t type, void *ptr +) { + bool type_changed = attr->type != type; + + if (type_changed || attr->value.as_raw != ptr) { + igraph_i_attribute_record_destroy_values(attr); + attr->type = type; + attr->value.as_raw = ptr; + } + + if (type_changed && type == IGRAPH_ATTRIBUTE_NUMERIC) { + IGRAPH_ASSERT( + igraph_attribute_record_set_default_numeric(attr, IGRAPH_NAN) == IGRAPH_SUCCESS + ); + } +} + +/** + * \function igraph_attribute_record_set_type + * \brief Sets the type of an attribute record. + * + * + * When the new type being set is different from the old type, any values already + * stored in the attribute record will be destroyed and a new, empty attribute + * value vector will be allocated. When the new type is the same as the old + * type, this function is a no-op. + * + * \param attr the attribute record to update + * \param type the new type + * \return Error code: + * \c IGRAPH_ENOMEM if there is not enough memory. + */ +igraph_error_t igraph_attribute_record_set_type( + igraph_attribute_record_t *attr, igraph_attribute_type_t type +) { + void* ptr; + + IGRAPH_ASSERT(attr != NULL); + + if (attr->type != type) { + switch (type) { + case IGRAPH_ATTRIBUTE_NUMERIC: { + igraph_vector_t* vec = IGRAPH_CALLOC(1, igraph_vector_t); + IGRAPH_CHECK_OOM(vec, "Insufficient memory for attribute record."); + IGRAPH_FINALLY(igraph_free, vec); + IGRAPH_VECTOR_INIT_FINALLY(vec, 0); + ptr = vec; + } + break; + + case IGRAPH_ATTRIBUTE_STRING: { + igraph_strvector_t* strvec = IGRAPH_CALLOC(1, igraph_strvector_t); + IGRAPH_CHECK_OOM(strvec, "Insufficient memory for attribute record."); + IGRAPH_FINALLY(igraph_free, strvec); + IGRAPH_CHECK(igraph_strvector_init(strvec, 0)); + IGRAPH_FINALLY(igraph_strvector_destroy, strvec); + ptr = strvec; + } + break; + + case IGRAPH_ATTRIBUTE_BOOLEAN: { + igraph_vector_bool_t* boolvec = IGRAPH_CALLOC(1, igraph_vector_bool_t); + IGRAPH_CHECK_OOM(boolvec, "Insufficient memory for attribute record."); + IGRAPH_FINALLY(igraph_free, boolvec); + IGRAPH_VECTOR_BOOL_INIT_FINALLY(boolvec, 0); + ptr = boolvec; + } + break; + + default: + IGRAPH_ERRORF("Unsupported attribute type: %d", IGRAPH_EINVAL, (int) type); + } + + igraph_i_attribute_record_set_type(attr, type, ptr); + IGRAPH_FINALLY_CLEAN(2); + } + + return IGRAPH_SUCCESS; +} + +#define ATTRIBUTE_RECORD_LIST +#define BASE_ATTRIBUTE_RECORD +#define CUSTOM_INIT_DESTROY +#include "igraph_pmt.h" +#include "../core/typed_list.pmt" +#include "igraph_pmt_off.h" +#undef CUSTOM_INIT_DESTROY +#undef BASE_ATTRIBUTE_RECORD +#undef ATTRIBUTE_RECORD_LIST + +static igraph_error_t igraph_i_attribute_record_list_init_item( + const igraph_attribute_record_list_t* list, igraph_attribute_record_t* item +) { + return igraph_attribute_record_init(item, NULL, IGRAPH_ATTRIBUTE_UNSPECIFIED); +} + +static igraph_error_t igraph_i_attribute_record_list_copy_item( + igraph_attribute_record_t* dest, const igraph_attribute_record_t* source +) { + return igraph_attribute_record_init_copy(dest, source); +} + +static void igraph_i_attribute_record_list_destroy_item(igraph_attribute_record_t* item) { + igraph_attribute_record_destroy(item); +} + /* Should you ever want to have a thread-local attribute handler table, prepend * IGRAPH_THREAD_LOCAL to the following declaration and #include "config.h". */ igraph_attribute_table_t *igraph_i_attribute_table = NULL; -igraph_error_t igraph_i_attribute_init(igraph_t *graph, void *attr) { +igraph_error_t igraph_i_attribute_init( + igraph_t *graph, const igraph_attribute_record_list_t *attr +) { graph->attr = NULL; if (igraph_i_attribute_table) { - return igraph_i_attribute_table->init(graph, attr); - } else { - return IGRAPH_SUCCESS; + IGRAPH_CHECK(igraph_i_attribute_table->init(graph, attr)); + if (graph->attr == NULL) { + IGRAPH_ERROR("Attribute handler did not initialize attr pointer", IGRAPH_FAILURE); + } } + return IGRAPH_SUCCESS; } void igraph_i_attribute_destroy(igraph_t *graph) { - if (igraph_i_attribute_table) { + if (graph->attr && igraph_i_attribute_table) { igraph_i_attribute_table->destroy(graph); } graph->attr = NULL; @@ -52,15 +633,19 @@ void igraph_i_attribute_destroy(igraph_t *graph) { igraph_error_t igraph_i_attribute_copy(igraph_t *to, const igraph_t *from, igraph_bool_t ga, igraph_bool_t va, igraph_bool_t ea) { - to->attr = NULL; - if (igraph_i_attribute_table) { - return igraph_i_attribute_table->copy(to, from, ga, va, ea); - } else { - return IGRAPH_SUCCESS; + igraph_i_attribute_destroy(to); + if (from->attr && igraph_i_attribute_table) { + IGRAPH_CHECK(igraph_i_attribute_table->copy(to, from, ga, va, ea)); + if (to->attr == NULL) { + IGRAPH_ERROR("Attribute handler did not initialize attr pointer", IGRAPH_FAILURE); + } } + return IGRAPH_SUCCESS; } -igraph_error_t igraph_i_attribute_add_vertices(igraph_t *graph, igraph_integer_t nv, void *attr) { +igraph_error_t igraph_i_attribute_add_vertices( + igraph_t *graph, igraph_integer_t nv, const igraph_attribute_record_list_t *attr +) { if (igraph_i_attribute_table) { return igraph_i_attribute_table->add_vertices(graph, nv, attr); } else { @@ -98,8 +683,10 @@ igraph_error_t igraph_i_attribute_combine_vertices(const igraph_t *graph, } } -igraph_error_t igraph_i_attribute_add_edges(igraph_t *graph, - const igraph_vector_int_t *edges, void *attr) { +igraph_error_t igraph_i_attribute_add_edges( + igraph_t *graph, const igraph_vector_int_t *edges, + const igraph_attribute_record_list_t *attr +) { if (igraph_i_attribute_table) { return igraph_i_attribute_table->add_edges(graph, edges, attr); } else { @@ -163,7 +750,7 @@ igraph_bool_t igraph_i_attribute_has_attr(const igraph_t *graph, } } -igraph_error_t igraph_i_attribute_gettype(const igraph_t *graph, +igraph_error_t igraph_i_attribute_get_type(const igraph_t *graph, igraph_attribute_type_t *type, igraph_attribute_elemtype_t elemtype, const char *name) { diff --git a/src/vendor/cigraph/src/graph/attributes.h b/src/vendor/cigraph/src/graph/attributes.h index c1ceb3e7a0f..2e8a344f965 100644 --- a/src/vendor/cigraph/src/graph/attributes.h +++ b/src/vendor/cigraph/src/graph/attributes.h @@ -26,24 +26,18 @@ __BEGIN_DECLS -#define IGRAPH_I_ATTRIBUTE_DESTROY(graph) \ - do {if ((graph)->attr) igraph_i_attribute_destroy(graph);} while(0) -#define IGRAPH_I_ATTRIBUTE_COPY(to,from,ga,va,ea) do { \ - igraph_error_t igraph_i_ret2=IGRAPH_SUCCESS; \ - (to)->attr = NULL; \ - if ((from)->attr) { \ - IGRAPH_CHECK(igraph_i_ret2=igraph_i_attribute_copy((to),(from),(ga),(va),(ea))); \ - } \ - if (igraph_i_ret2 != IGRAPH_SUCCESS) { \ - IGRAPH_ERROR("", igraph_i_ret2); \ - } \ - } while(0) - -igraph_error_t igraph_i_attribute_init(igraph_t *graph, void *attr); +igraph_error_t igraph_i_attribute_init( + igraph_t *graph, const igraph_attribute_record_list_t *attr +); void igraph_i_attribute_destroy(igraph_t *graph); -igraph_error_t igraph_i_attribute_copy(igraph_t *to, const igraph_t *from, - igraph_bool_t ga, igraph_bool_t va, igraph_bool_t ea); -igraph_error_t igraph_i_attribute_add_vertices(igraph_t *graph, igraph_integer_t nv, void *attr); +igraph_error_t igraph_i_attribute_copy( + igraph_t *to, const igraph_t *from, + igraph_bool_t ga, igraph_bool_t va, igraph_bool_t ea +); +igraph_error_t igraph_i_attribute_add_vertices( + igraph_t *graph, igraph_integer_t nv, + const igraph_attribute_record_list_t *attr +); igraph_error_t igraph_i_attribute_permute_vertices(const igraph_t *graph, igraph_t *newgraph, const igraph_vector_int_t *idx); @@ -51,8 +45,10 @@ igraph_error_t igraph_i_attribute_combine_vertices(const igraph_t *graph, igraph_t *newgraph, const igraph_vector_int_list_t *merges, const igraph_attribute_combination_t *comb); -igraph_error_t igraph_i_attribute_add_edges(igraph_t *graph, - const igraph_vector_int_t *edges, void *attr); +igraph_error_t igraph_i_attribute_add_edges( + igraph_t *graph, const igraph_vector_int_t *edges, + const igraph_attribute_record_list_t *attr +); igraph_error_t igraph_i_attribute_permute_edges(const igraph_t *graph, igraph_t *newgraph, const igraph_vector_int_t *idx); @@ -71,7 +67,7 @@ igraph_error_t igraph_i_attribute_get_info(const igraph_t *graph, igraph_bool_t igraph_i_attribute_has_attr(const igraph_t *graph, igraph_attribute_elemtype_t type, const char *name); -igraph_error_t igraph_i_attribute_gettype(const igraph_t *graph, +igraph_error_t igraph_i_attribute_get_type(const igraph_t *graph, igraph_attribute_type_t *type, igraph_attribute_elemtype_t elemtype, const char *name); diff --git a/src/vendor/cigraph/src/graph/cattributes.c b/src/vendor/cigraph/src/graph/cattributes.c index 21bf872c67a..0a2ae020557 100644 --- a/src/vendor/cigraph/src/graph/cattributes.c +++ b/src/vendor/cigraph/src/graph/cattributes.c @@ -9,7 +9,6 @@ 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. @@ -32,185 +31,189 @@ /* An attribute is either a numeric vector (vector_t), a boolean vector * (vector_bool_t) or a string vector (strvector_t). - * The attribute itself is stored in a struct igraph_attribute_record_t. - * There is one such object for each attribute. The igraph_t has a pointer - * to an igraph_i_cattribute_t, which contains three vector_ptr_t's, each - * holding pointers to igraph_attribute_record_t objects. */ + * The attribute itself is stored in a struct igraph_attribute_record_t. There + * is one such object for each attribute. The igraph_t has a pointer to an + * igraph_i_cattribute_t, which contains three igraph_attribute_vector_list_t's, + * each holding pointers to igraph_attribute_record_t objects. */ -/* This function is used for producing better error messages. */ -static const char *attribute_type_name(igraph_attribute_type_t type) { - switch (type) { - case IGRAPH_ATTRIBUTE_UNSPECIFIED: - return "unspecified"; /* TODO: should probably trigger a fatal error */ - case IGRAPH_ATTRIBUTE_NUMERIC: - return "numeric"; - case IGRAPH_ATTRIBUTE_BOOLEAN: - return "boolean"; - case IGRAPH_ATTRIBUTE_STRING: - return "string"; - case IGRAPH_ATTRIBUTE_OBJECT: - return "object"; +typedef struct igraph_i_cattributes_t { + igraph_attribute_record_list_t gal; + igraph_attribute_record_list_t val; + igraph_attribute_record_list_t eal; +} igraph_i_cattributes_t; + +/* + * Finds an attribute with the given name in an attribute record list, and + * returns the index of the record in the list, or -1 if there was no such + * attribute. + */ +static igraph_integer_t igraph_i_cattribute_find_index( + const igraph_attribute_record_list_t *attrs, const char *name +) { + igraph_integer_t i, n = igraph_attribute_record_list_size(attrs); + for (i = 0; i < n; i++) { + igraph_attribute_record_t *rec = igraph_attribute_record_list_get_ptr(attrs, i); + if (!strcmp(rec->name, name)) { + return i; + } } - /* The following line is intentionally not in a default switch label - * so that the compiler can warn about unhandled enum values, - * should additional attribute types ever be added in the future. */ - IGRAPH_FATALF("Invalid attribute type %d found.", (int) type); + return -1; } -static igraph_bool_t igraph_i_cattribute_find(const igraph_vector_ptr_t *ptrvec, - const char *name, igraph_integer_t *idx) { - igraph_integer_t i, n = igraph_vector_ptr_size(ptrvec); - igraph_bool_t l = false; - for (i = 0; !l && i < n; i++) { - igraph_attribute_record_t *rec = VECTOR(*ptrvec)[i]; - l = !strcmp(rec->name, name); - } - if (idx) { - *idx = i - 1; +/* + * Finds an attribute with the given name in an attribute record list, and + * returns the attribute record or NULL if there was no such attribute. + * Optionally, the type of the attribute can be enforced; use + * IGRAPH_ATTRIBUTE_UNSPECIFIED if you do not care about the type. + */ +static igraph_attribute_record_t* igraph_i_cattribute_find( + igraph_attribute_record_list_t *attrs, const char *name, + igraph_attribute_type_t type +) { + igraph_integer_t index = igraph_i_cattribute_find_index(attrs, name); + igraph_attribute_record_t *rec; + + if (index >= 0) { + rec = igraph_attribute_record_list_get_ptr(attrs, index); + if (type == IGRAPH_ATTRIBUTE_UNSPECIFIED || type == rec->type) { + return rec; + } } - return l; + + return NULL; } /* - * Restores attribute vector lengths to their original size after a failure. - * This function assumes that none of the attribute vectors are shorter than origlen. - * Some may be longer due to a partially completed size extension: these will be - * shrunk to their original size. + * Same as igraph_i_cattribute_find(), but suitable for const attribute record + * lists. */ -static void igraph_i_cattribute_revert_attribute_vector_sizes( - igraph_vector_ptr_t *attrlist, igraph_integer_t origlen) { +static const igraph_attribute_record_t* igraph_i_cattribute_find_const( + const igraph_attribute_record_list_t *attrs, const char *name, + igraph_attribute_type_t type +) { + igraph_integer_t index = igraph_i_cattribute_find_index(attrs, name); + igraph_attribute_record_t *rec; - igraph_integer_t no_of_attrs = igraph_vector_ptr_size(attrlist); - for (igraph_integer_t i = 0; i < no_of_attrs; i++) { - igraph_attribute_record_t *rec = VECTOR(*attrlist)[i]; - if (rec->type == IGRAPH_ATTRIBUTE_NUMERIC) { - igraph_vector_t *nvec = (igraph_vector_t *) rec->value; - IGRAPH_ASSERT(igraph_vector_capacity(nvec) >= origlen); - igraph_vector_resize(nvec, origlen); /* shrinks */ - } else if (rec->type == IGRAPH_ATTRIBUTE_BOOLEAN) { - igraph_vector_bool_t *bvec = (igraph_vector_bool_t *) rec->value; - IGRAPH_ASSERT(igraph_vector_bool_capacity(bvec) >= origlen); - igraph_vector_bool_resize(bvec, origlen); /* shrinks */ - } else if (rec->type == IGRAPH_ATTRIBUTE_STRING) { - igraph_strvector_t *svec = (igraph_strvector_t *) rec->value; - IGRAPH_ASSERT(igraph_strvector_capacity(svec) >= origlen); - igraph_strvector_resize(svec, origlen); /* shrinks */ - } else { - /* Must never reach here */ - IGRAPH_FATAL("Unknown attribute type encountered."); + if (index >= 0) { + rec = igraph_attribute_record_list_get_ptr(attrs, index); + if (type == IGRAPH_ATTRIBUTE_UNSPECIFIED || type == rec->type) { + return rec; } } + + return NULL; } -typedef struct igraph_i_cattributes_t { - igraph_vector_ptr_t gal; - igraph_vector_ptr_t val; - igraph_vector_ptr_t eal; -} igraph_i_cattributes_t; +/* + * Finds an attribute with the given name in an attribute record list, and + * returns the attribute record in an output argument. Returns an error code + * if there is no such attribute. Optionally, the type of the attribute can be + * enforced; use IGRAPH_ATTRIBUTE_UNSPECIFIED if you do not care about the type. + */ +static igraph_error_t igraph_i_cattribute_find_or_return( + igraph_attribute_record_list_t *attrs, const char *name, + igraph_attribute_type_t type, igraph_attribute_record_t **ptr +) { + igraph_attribute_record_t *rec; -static igraph_error_t igraph_i_cattributes_copy_attribute_record(igraph_attribute_record_t **newrec, - const igraph_attribute_record_t *rec) { - igraph_vector_t *num, *newnum; - igraph_strvector_t *str, *newstr; + rec = igraph_i_cattribute_find(attrs, name, IGRAPH_ATTRIBUTE_UNSPECIFIED); + if (!rec) { + IGRAPH_ERRORF("Attribute '%s' does not exist.", IGRAPH_EINVAL, name); + } - *newrec = IGRAPH_CALLOC(1, igraph_attribute_record_t); - if (!(*newrec)) { - IGRAPH_ERROR("Cannot copy attributes", IGRAPH_ENOMEM); /* LCOV_EXCL_LINE */ + if (type != IGRAPH_ATTRIBUTE_UNSPECIFIED) { + IGRAPH_CHECK(igraph_attribute_record_check_type(rec, type)); } - IGRAPH_FINALLY(igraph_free, *newrec); - (*newrec)->type = rec->type; - (*newrec)->name = strdup(rec->name); - if (!(*newrec)->name) { - IGRAPH_ERROR("Cannot copy attributes", IGRAPH_ENOMEM); /* LCOV_EXCL_LINE */ + + if (ptr) { + *ptr = rec; } - IGRAPH_FINALLY(igraph_free, (void*)(*newrec)->name); - if (rec->type == IGRAPH_ATTRIBUTE_NUMERIC) { - num = (igraph_vector_t *)rec->value; - newnum = IGRAPH_CALLOC(1, igraph_vector_t); - if (!newnum) { - IGRAPH_ERROR("Cannot copy attributes", IGRAPH_ENOMEM); /* LCOV_EXCL_LINE */ - } - IGRAPH_FINALLY(igraph_free, newnum); - IGRAPH_CHECK(igraph_vector_init_copy(newnum, num)); - IGRAPH_FINALLY(igraph_vector_destroy, newnum); - (*newrec)->value = newnum; - } else if (rec->type == IGRAPH_ATTRIBUTE_STRING) { - str = (igraph_strvector_t*)rec->value; - newstr = IGRAPH_CALLOC(1, igraph_strvector_t); - if (!newstr) { - IGRAPH_ERROR("Cannot copy attributes", IGRAPH_ENOMEM); /* LCOV_EXCL_LINE */ - } - IGRAPH_FINALLY(igraph_free, newstr); - IGRAPH_CHECK(igraph_strvector_init_copy(newstr, str)); - IGRAPH_FINALLY(igraph_strvector_destroy, newstr); - (*newrec)->value = newstr; - } else if (rec->type == IGRAPH_ATTRIBUTE_BOOLEAN) { - igraph_vector_bool_t *log = (igraph_vector_bool_t*) rec->value; - igraph_vector_bool_t *newlog = IGRAPH_CALLOC(1, igraph_vector_bool_t); - if (!newlog) { - IGRAPH_ERROR("Cannot copy attributes", IGRAPH_ENOMEM); /* LCOV_EXCL_LINE */ + + return IGRAPH_SUCCESS; +} + +/* + * Finds an attribute with the given name in an attribute record list, and + * returns the attribute record in an output argument. Creates a new attribute + * with the given name if there is no such attribute. The type of the attribute + * needs to be specified so we can create the appropriate value vector if needed. + * You can specify a length; when the existing value vector for the attribute + * is shorter than this length, it will be extended to ensure that it has at + * least this many elements. You can pass 0 as the length if you do not want to + * expand value vectors. + */ +static igraph_error_t igraph_i_cattribute_find_or_create( + igraph_attribute_record_list_t *attrs, + const char *name, igraph_attribute_type_t type, + igraph_integer_t length, + igraph_attribute_record_t **ptr +) { + igraph_attribute_record_t *rec; + + rec = igraph_i_cattribute_find(attrs, name, IGRAPH_ATTRIBUTE_UNSPECIFIED); + if (rec) { + if (type != IGRAPH_ATTRIBUTE_UNSPECIFIED) { + IGRAPH_CHECK(igraph_attribute_record_check_type(rec, type)); } - IGRAPH_FINALLY(igraph_free, newlog); - IGRAPH_CHECK(igraph_vector_bool_init_copy(newlog, log)); - IGRAPH_FINALLY(igraph_vector_bool_destroy, newlog); - (*newrec)->value = newlog; + } else { + IGRAPH_CHECK(igraph_attribute_record_list_push_back_new(attrs, &rec)); + IGRAPH_CHECK(igraph_attribute_record_set_name(rec, name)); + IGRAPH_CHECK(igraph_attribute_record_set_type(rec, type)); + } + + if (length > 0 && igraph_attribute_record_size(rec) < length) { + IGRAPH_CHECK(igraph_attribute_record_resize(rec, length)); + } + + if (ptr) { + *ptr = rec; } - IGRAPH_FINALLY_CLEAN(4); return IGRAPH_SUCCESS; } -static void igraph_i_attribute_list_destroy(igraph_vector_ptr_t *attrlist) { - igraph_integer_t i; - igraph_integer_t n = igraph_vector_ptr_size(attrlist); - for (i = 0; i < n; i++) { - igraph_attribute_record_t *rec = VECTOR(*attrlist)[i]; - if (rec) { - if (rec->type == IGRAPH_ATTRIBUTE_NUMERIC) { - igraph_vector_t *num = (igraph_vector_t *) rec->value; - igraph_vector_destroy(num); - IGRAPH_FREE(num); - } else if (rec->type == IGRAPH_ATTRIBUTE_STRING) { - igraph_strvector_t *str = (igraph_strvector_t *) rec->value; - igraph_strvector_destroy(str); - IGRAPH_FREE(str); - } else if (rec->type == IGRAPH_ATTRIBUTE_BOOLEAN) { - igraph_vector_bool_t *boolvec = (igraph_vector_bool_t *) rec->value; - igraph_vector_bool_destroy(boolvec); - IGRAPH_FREE(boolvec); - } - IGRAPH_FREE(rec->name); - IGRAPH_FREE(rec); +/* + * Restores attribute vector lengths to their original size after a failure. + * This function assumes that none of the attribute vectors are shorter than origlen. + * Some may be longer due to a partially completed size extension: these will be + * shrunk to their original size. + */ +static void igraph_i_cattribute_revert_attribute_vector_sizes( + igraph_attribute_record_list_t *attrlist, igraph_integer_t origlen) { + + igraph_integer_t no_of_attrs = igraph_attribute_record_list_size(attrlist); + for (igraph_integer_t i = 0; i < no_of_attrs; i++) { + igraph_attribute_record_t *rec = igraph_attribute_record_list_get_ptr(attrlist, i); + IGRAPH_ASSERT(igraph_attribute_record_size(rec) >= origlen); + if (igraph_attribute_record_resize(rec, origlen) != IGRAPH_SUCCESS) { + /* We should have succeeded for known attribute types because we + * always shrink the vector so throw a fatal error if this happens */ + IGRAPH_FATAL("Unknown attribute type encountered."); } } - igraph_vector_ptr_destroy(attrlist); } -static igraph_error_t igraph_i_cattribute_init(igraph_t *graph, igraph_vector_ptr_t *attr) { - igraph_attribute_record_t *attr_rec; - igraph_integer_t i, n; +static igraph_error_t igraph_i_cattribute_init( + igraph_t *graph, const igraph_attribute_record_list_t *attr +) { igraph_i_cattributes_t *nattr; - n = attr ? igraph_vector_ptr_size(attr) : 0; - nattr = IGRAPH_CALLOC(1, igraph_i_cattributes_t); - if (!nattr) { - IGRAPH_ERROR("Can't init attributes", IGRAPH_ENOMEM); /* LCOV_EXCL_LINE */ - } + IGRAPH_CHECK_OOM(nattr, "Insufficient memory to allocate attribute storage."); IGRAPH_FINALLY(igraph_free, nattr); - IGRAPH_CHECK(igraph_vector_ptr_init(&nattr->gal, n)); - IGRAPH_FINALLY(igraph_i_attribute_list_destroy, &nattr->gal); - IGRAPH_CHECK(igraph_vector_ptr_init(&nattr->val, 0)); - IGRAPH_FINALLY(igraph_vector_ptr_destroy, &nattr->val); - IGRAPH_CHECK(igraph_vector_ptr_init(&nattr->eal, 0)); - IGRAPH_FINALLY(igraph_vector_ptr_destroy, &nattr->eal); - - for (i = 0; i < n; i++) { - IGRAPH_CHECK(igraph_i_cattributes_copy_attribute_record( - &attr_rec, VECTOR(*attr)[i])); - VECTOR(nattr->gal)[i] = attr_rec; + if (attr) { + IGRAPH_CHECK(igraph_attribute_record_list_init_copy(&nattr->gal, attr)); + } else { + IGRAPH_CHECK(igraph_attribute_record_list_init(&nattr->gal, 0)); } + IGRAPH_FINALLY(igraph_attribute_record_list_destroy, &nattr->gal); + + IGRAPH_CHECK(igraph_attribute_record_list_init(&nattr->val, 0)); + IGRAPH_FINALLY(igraph_attribute_record_list_destroy, &nattr->val); + + IGRAPH_CHECK(igraph_attribute_record_list_init(&nattr->eal, 0)); + IGRAPH_FINALLY(igraph_attribute_record_list_destroy, &nattr->eal); graph->attr = nattr; IGRAPH_FINALLY_CLEAN(4); @@ -220,260 +223,135 @@ static igraph_error_t igraph_i_cattribute_init(igraph_t *graph, igraph_vector_pt static void igraph_i_cattribute_destroy(igraph_t *graph) { igraph_i_cattributes_t *attr = graph->attr; - igraph_vector_ptr_t *als[3] = { &attr->gal, &attr->val, &attr->eal }; - for (size_t a = 0; a < 3; a++) { - igraph_i_attribute_list_destroy(als[a]); - } + igraph_attribute_record_list_destroy(&attr->eal); + igraph_attribute_record_list_destroy(&attr->val); + igraph_attribute_record_list_destroy(&attr->gal); IGRAPH_FREE(graph->attr); /* sets to NULL */ } -/* Almost the same as destroy, but we might have null pointers */ - -static void igraph_i_cattribute_copy_free(igraph_i_cattributes_t *attr) { - igraph_vector_ptr_t *als[3] = { &attr->gal, &attr->val, &attr->eal }; - igraph_integer_t i, n; - igraph_vector_t *num; - igraph_strvector_t *str; - igraph_vector_bool_t *boolvec; - igraph_attribute_record_t *rec; - for (size_t a = 0; a < 3; a++) { - n = igraph_vector_ptr_size(als[a]); - for (i = 0; i < n; i++) { - rec = VECTOR(*als[a])[i]; - if (!rec) { - continue; - } - if (rec->type == IGRAPH_ATTRIBUTE_NUMERIC) { - num = (igraph_vector_t*)rec->value; - igraph_vector_destroy(num); - IGRAPH_FREE(num); - } else if (rec->type == IGRAPH_ATTRIBUTE_BOOLEAN) { - boolvec = (igraph_vector_bool_t*)rec->value; - igraph_vector_bool_destroy(boolvec); - IGRAPH_FREE(boolvec); - } else if (rec->type == IGRAPH_ATTRIBUTE_STRING) { - str = (igraph_strvector_t*)rec->value; - igraph_strvector_destroy(str); - IGRAPH_FREE(str); - } - IGRAPH_FREE(rec->name); - IGRAPH_FREE(rec); - } - } -} - /* No reference counting here. If you use attributes in C you should know what you're doing. */ -static igraph_error_t igraph_i_cattribute_copy(igraph_t *to, const igraph_t *from, - igraph_bool_t ga, igraph_bool_t va, igraph_bool_t ea) { - igraph_i_cattributes_t *attrfrom = from->attr, *attrto; - igraph_vector_ptr_t *alto[3], *alfrom[3] = { &attrfrom->gal, &attrfrom->val, - &attrfrom->eal - }; - igraph_integer_t i, n; +static igraph_error_t igraph_i_cattribute_copy( + igraph_t *to, const igraph_t *from, + igraph_bool_t ga, igraph_bool_t va, igraph_bool_t ea +) { + igraph_i_cattributes_t *attrto, *attrfrom = from->attr; + igraph_attribute_record_list_t *alto[3], *alfrom[3] = { + &attrfrom->gal, &attrfrom->val, &attrfrom->eal + }; + igraph_integer_t i; igraph_bool_t copy[3] = { ga, va, ea }; - to->attr = attrto = IGRAPH_CALLOC(1, igraph_i_cattributes_t); - if (!attrto) { - IGRAPH_ERROR("Cannot copy attributes", IGRAPH_ENOMEM); /* LCOV_EXCL_LINE */ - } + + attrto = IGRAPH_CALLOC(1, igraph_i_cattributes_t); + IGRAPH_CHECK_OOM(attrto, "Insufficient memory to copy attributes."); IGRAPH_FINALLY(igraph_free, attrto); - IGRAPH_VECTOR_PTR_INIT_FINALLY(&attrto->gal, 0); - IGRAPH_VECTOR_PTR_INIT_FINALLY(&attrto->val, 0); - IGRAPH_VECTOR_PTR_INIT_FINALLY(&attrto->eal, 0); - IGRAPH_FINALLY_CLEAN(3); - IGRAPH_FINALLY(igraph_i_cattribute_copy_free, attrto); - - alto[0] = &attrto->gal; alto[1] = &attrto->val; alto[2] = &attrto->eal; - for (size_t a = 0; a < 3; a++) { - if (copy[a]) { - n = igraph_vector_ptr_size(alfrom[a]); - IGRAPH_CHECK(igraph_vector_ptr_resize(alto[a], n)); - igraph_vector_ptr_null(alto[a]); - for (i = 0; i < n; i++) { - igraph_attribute_record_t *newrec; - IGRAPH_CHECK(igraph_i_cattributes_copy_attribute_record(&newrec, - VECTOR(*alfrom[a])[i])); - VECTOR(*alto[a])[i] = newrec; - } + + alto[0] = &attrto->gal; + alto[1] = &attrto->val; + alto[2] = &attrto->eal; + + for (i = 0; i < 3; i++) { + if (copy[i]) { + IGRAPH_CHECK(igraph_attribute_record_list_init_copy(alto[i], alfrom[i])); + } else { + IGRAPH_CHECK(igraph_attribute_record_list_init(alto[i], 0)); } + IGRAPH_FINALLY(igraph_attribute_record_list_destroy, alto[i]); } - IGRAPH_FINALLY_CLEAN(2); + to->attr = attrto; + IGRAPH_FINALLY_CLEAN(4); + return IGRAPH_SUCCESS; } -static igraph_error_t igraph_i_cattribute_add_vertices_inner(igraph_t *graph, igraph_integer_t nv, - igraph_vector_ptr_t *nattr) { +static igraph_error_t igraph_i_cattribute_add_vertices_or_edges_inner( + igraph_attribute_record_list_t *val, + igraph_integer_t newlen, igraph_integer_t nv, + const igraph_attribute_record_list_t *nattr +) { + igraph_integer_t length; + igraph_integer_t nattrno = nattr == NULL ? 0 : igraph_attribute_record_list_size(nattr); + igraph_integer_t origlen = newlen - nv; + igraph_integer_t i; + + IGRAPH_ASSERT(origlen >= 0); - igraph_i_cattributes_t *attr = graph->attr; - igraph_vector_ptr_t *val = &attr->val; - igraph_integer_t length = igraph_vector_ptr_size(val); - igraph_integer_t nattrno = nattr == NULL ? 0 : igraph_vector_ptr_size(nattr); - igraph_integer_t origlen = igraph_vcount(graph) - nv; - igraph_integer_t newattrs = 0, i; - igraph_vector_int_t news; - - /* First add the new attributes if any */ - newattrs = 0; - IGRAPH_VECTOR_INT_INIT_FINALLY(&news, 0); + /* Find all the attributes that are newly added, and create new value vectors + * for them in the original graph */ for (i = 0; i < nattrno; i++) { - igraph_attribute_record_t *nattr_entry = VECTOR(*nattr)[i]; + igraph_attribute_record_t *nattr_entry = igraph_attribute_record_list_get_ptr(nattr, i); const char *nname = nattr_entry->name; - igraph_integer_t j; - igraph_bool_t l = igraph_i_cattribute_find(val, nname, &j); - if (!l) { - newattrs++; - IGRAPH_CHECK(igraph_vector_int_push_back(&news, i)); - } else { - /* check types */ - if (nattr_entry->type != - ((igraph_attribute_record_t*)VECTOR(*val)[j])->type) { - IGRAPH_ERROR("You cannot mix attribute types", IGRAPH_EINVAL); - } - } - } - - /* Add NA/empty string vectors for the existing vertices */ - if (newattrs != 0) { - for (i = 0; i < newattrs; i++) { - igraph_attribute_record_t *tmp = VECTOR(*nattr)[VECTOR(news)[i]]; - igraph_attribute_record_t *newrec = IGRAPH_CALLOC(1, igraph_attribute_record_t); - igraph_attribute_type_t type = tmp->type; - if (!newrec) { - IGRAPH_ERROR("Cannot add attributes", IGRAPH_ENOMEM); /* LCOV_EXCL_LINE */ - } - IGRAPH_FINALLY(igraph_free, newrec); - newrec->type = type; - newrec->name = strdup(tmp->name); - if (!newrec->name) { - IGRAPH_ERROR("Cannot add attributes", IGRAPH_ENOMEM); /* LCOV_EXCL_LINE */ - } - IGRAPH_FINALLY(igraph_free, (char*)newrec->name); - if (type == IGRAPH_ATTRIBUTE_NUMERIC) { - igraph_vector_t *newnum = IGRAPH_CALLOC(1, igraph_vector_t); - if (!newnum) { - IGRAPH_ERROR("Cannot add attributes", IGRAPH_ENOMEM); /* LCOV_EXCL_LINE */ - } - IGRAPH_FINALLY(igraph_free, newnum); - IGRAPH_VECTOR_INIT_FINALLY(newnum, origlen); - newrec->value = newnum; - igraph_vector_fill(newnum, IGRAPH_NAN); - } else if (type == IGRAPH_ATTRIBUTE_STRING) { - igraph_strvector_t *newstr = IGRAPH_CALLOC(1, igraph_strvector_t); - if (!newstr) { - IGRAPH_ERROR("Cannot add attributes", IGRAPH_ENOMEM); /* LCOV_EXCL_LINE */ - } - IGRAPH_FINALLY(igraph_free, newstr); - IGRAPH_STRVECTOR_INIT_FINALLY(newstr, origlen); - newrec->value = newstr; - } else if (type == IGRAPH_ATTRIBUTE_BOOLEAN) { - igraph_vector_bool_t *newbool = IGRAPH_CALLOC(1, igraph_vector_bool_t); - if (!newbool) { - IGRAPH_ERROR("Cannot add attributes", IGRAPH_ENOMEM); /* LCOV_EXCL_LINE */ - } - IGRAPH_FINALLY(igraph_free, newbool); - IGRAPH_VECTOR_BOOL_INIT_FINALLY(newbool, origlen); - newrec->value = newbool; - igraph_vector_bool_fill(newbool, false); - } - IGRAPH_CHECK(igraph_vector_ptr_push_back(val, newrec)); - IGRAPH_FINALLY_CLEAN(4); - } - length = igraph_vector_ptr_size(val); + IGRAPH_CHECK(igraph_i_cattribute_find_or_create(val, nname, nattr_entry->type, origlen, NULL)); } /* Now append the new values */ + length = igraph_attribute_record_list_size(val); for (i = 0; i < length; i++) { - igraph_attribute_record_t *oldrec = VECTOR(*val)[i]; - igraph_attribute_record_t *newrec = 0; - const char *name = oldrec->name; - igraph_integer_t j = -1; - igraph_bool_t l = false; - if (nattr) { - l = igraph_i_cattribute_find(nattr, name, &j); - } - if (l) { + igraph_attribute_record_t *oldrec = igraph_attribute_record_list_get_ptr(val, i); + const igraph_attribute_record_t *newrec = nattr + ? igraph_i_cattribute_find_const(nattr, oldrec->name, oldrec->type) + : NULL; + + IGRAPH_ASSERT(igraph_attribute_record_size(oldrec) == origlen); + + if (newrec) { /* This attribute is present in nattr */ - igraph_vector_t *oldnum, *newnum; - igraph_strvector_t *oldstr, *newstr; - igraph_vector_bool_t *oldbool, *newbool; - newrec = VECTOR(*nattr)[j]; - oldnum = (igraph_vector_t*)oldrec->value; - newnum = (igraph_vector_t*)newrec->value; - oldstr = (igraph_strvector_t*)oldrec->value; - newstr = (igraph_strvector_t*)newrec->value; - oldbool = (igraph_vector_bool_t*)oldrec->value; - newbool = (igraph_vector_bool_t*)newrec->value; - if (oldrec->type != newrec->type) { - IGRAPH_ERROR("Attribute types do not match.", IGRAPH_EINVAL); - } switch (oldrec->type) { case IGRAPH_ATTRIBUTE_NUMERIC: - if (nv != igraph_vector_size(newnum)) { + if (nv != igraph_vector_size(newrec->value.as_vector)) { IGRAPH_ERROR("Invalid numeric attribute length.", IGRAPH_EINVAL); } - IGRAPH_CHECK(igraph_vector_append(oldnum, newnum)); + IGRAPH_CHECK(igraph_vector_append( + oldrec->value.as_vector, newrec->value.as_vector + )); break; case IGRAPH_ATTRIBUTE_STRING: - if (nv != igraph_strvector_size(newstr)) { + if (nv != igraph_strvector_size(newrec->value.as_strvector)) { IGRAPH_ERROR("Invalid string attribute length.", IGRAPH_EINVAL); } - IGRAPH_CHECK(igraph_strvector_append(oldstr, newstr)); + IGRAPH_CHECK(igraph_strvector_append( + oldrec->value.as_strvector, newrec->value.as_strvector + )); break; case IGRAPH_ATTRIBUTE_BOOLEAN: - if (nv != igraph_vector_bool_size(newbool)) { + if (nv != igraph_vector_bool_size(newrec->value.as_vector_bool)) { IGRAPH_ERROR("Invalid boolean attribute length.", IGRAPH_EINVAL); } - IGRAPH_CHECK(igraph_vector_bool_append(oldbool, newbool)); + IGRAPH_CHECK(igraph_vector_bool_append( + oldrec->value.as_vector_bool, newrec->value.as_vector_bool + )); break; default: - IGRAPH_WARNING("Invalid attribute type."); + IGRAPH_WARNINGF( + "Attribute '%s' with unknown type %d ignored", + oldrec->name, (int) oldrec->type + ); break; } } else { - /* No such attribute, append NA's */ - igraph_vector_t *oldnum = (igraph_vector_t *)oldrec->value; - igraph_strvector_t *oldstr = (igraph_strvector_t*)oldrec->value; - igraph_vector_bool_t *oldbool = (igraph_vector_bool_t*)oldrec->value; - switch (oldrec->type) { - case IGRAPH_ATTRIBUTE_NUMERIC: - IGRAPH_CHECK(igraph_vector_resize(oldnum, origlen + nv)); - for (j = origlen; j < origlen + nv; j++) { - VECTOR(*oldnum)[j] = IGRAPH_NAN; - } - break; - case IGRAPH_ATTRIBUTE_STRING: - IGRAPH_CHECK(igraph_strvector_resize(oldstr, origlen + nv)); - break; - case IGRAPH_ATTRIBUTE_BOOLEAN: - IGRAPH_CHECK(igraph_vector_bool_resize(oldbool, origlen + nv)); - for (j = origlen; j < origlen + nv; j++) { - VECTOR(*oldbool)[j] = 0; - } - break; - default: - IGRAPH_WARNING("Invalid attribute type"); - break; - } + /* No such attribute among the new ones so just extend the length + * of the current record */ + IGRAPH_CHECK(igraph_attribute_record_resize(oldrec, newlen)); } - } - igraph_vector_int_destroy(&news); - IGRAPH_FINALLY_CLEAN(1); + IGRAPH_ASSERT(igraph_attribute_record_size(oldrec) == newlen); + } return IGRAPH_SUCCESS; } -static igraph_error_t igraph_i_cattribute_add_vertices(igraph_t *graph, igraph_integer_t nv, - igraph_vector_ptr_t *nattr) { - /* Record information needed to restore attribute vector sizes */ - igraph_i_cattributes_t *attr = graph->attr; - igraph_vector_ptr_t *val = &attr->val; - igraph_integer_t origlen = igraph_vcount(graph) - nv; +static igraph_error_t igraph_i_cattribute_add_vertices_or_edges( + igraph_attribute_record_list_t *val, + igraph_integer_t newlen, igraph_integer_t nv, + const igraph_attribute_record_list_t *nattr +) { + igraph_integer_t origlen = newlen - nv; + igraph_error_t err = igraph_i_cattribute_add_vertices_or_edges_inner( + val, newlen, nv, nattr + ); - /* Attempt adding attributes */ - igraph_error_t err = igraph_i_cattribute_add_vertices_inner(graph, nv, nattr); if (err != IGRAPH_SUCCESS) { /* If unsuccessful, revert attribute vector sizes. * The following function assumes that all attributes vectors that @@ -490,30 +368,16 @@ static igraph_error_t igraph_i_cattribute_add_vertices(igraph_t *graph, igraph_i */ igraph_i_cattribute_revert_attribute_vector_sizes(val, origlen); } + return err; } -static void igraph_i_cattribute_clear_attribute_container(igraph_vector_ptr_t *v) { - igraph_integer_t i, n = igraph_vector_ptr_size(v); - for (i = 0; i < n; i++) { - igraph_attribute_record_t *rec = VECTOR(*v)[i]; - IGRAPH_FREE(rec->name); - if (rec->type == IGRAPH_ATTRIBUTE_NUMERIC) { - igraph_vector_t *numv = (igraph_vector_t*) rec->value; - igraph_vector_destroy(numv); - IGRAPH_FREE(numv); - } else if (rec->type == IGRAPH_ATTRIBUTE_STRING) { - igraph_strvector_t *strv = (igraph_strvector_t*) rec->value; - igraph_strvector_destroy(strv); - IGRAPH_FREE(strv); - } else if (rec->type == IGRAPH_ATTRIBUTE_BOOLEAN) { - igraph_vector_bool_t *boolv = (igraph_vector_bool_t*) rec->value; - igraph_vector_bool_destroy(boolv); - IGRAPH_FREE(boolv); - } - IGRAPH_FREE(rec); - } - igraph_vector_ptr_clear(v); +static igraph_error_t igraph_i_cattribute_add_vertices( + igraph_t *graph, igraph_integer_t nv, + const igraph_attribute_record_list_t *nattr +) { + igraph_i_cattributes_t *attr = graph->attr; + return igraph_i_cattribute_add_vertices_or_edges(&attr->val, igraph_vcount(graph), nv, nattr); } typedef struct { @@ -631,12 +495,65 @@ static igraph_error_t igraph_i_attribute_permutation_work_area_permute_and_store return IGRAPH_SUCCESS; } -static igraph_error_t igraph_i_cattribute_permute_vertices_in_place( - igraph_t *graph, const igraph_vector_int_t *idx +static igraph_error_t igraph_i_cattribute_permute_attribute_record_list( + igraph_attribute_record_list_t *attrs, + igraph_attribute_record_list_t *new_attrs, + const igraph_vector_int_t *idx ) { - igraph_i_cattributes_t *attr = graph->attr; - igraph_vector_ptr_t *val = &attr->val; - igraph_integer_t valno = igraph_vector_ptr_size(val); + igraph_integer_t i, no_attrs, idxlen; + + no_attrs = igraph_attribute_record_list_size(attrs); + + /* When vertices or edges are permuted, we now assume that there are no + * attributes in the target attribute list yet */ + IGRAPH_ASSERT(igraph_attribute_record_list_empty(new_attrs)); + IGRAPH_FINALLY(igraph_attribute_record_list_clear, new_attrs); + + idxlen = igraph_vector_int_size(idx); + for (i = 0; i < no_attrs; i++) { + igraph_attribute_record_t *oldrec = igraph_attribute_record_list_get_ptr(attrs, i); + igraph_attribute_type_t type = oldrec->type; + + /* Create a record for the same attribute in the new graph */ + igraph_attribute_record_t *newrec; + IGRAPH_CHECK(igraph_i_cattribute_find_or_create( + new_attrs, oldrec->name, oldrec->type, idxlen, &newrec + )); + + /* The data */ + switch (type) { + case IGRAPH_ATTRIBUTE_NUMERIC: + IGRAPH_CHECK(igraph_vector_index( + oldrec->value.as_vector, newrec->value.as_vector, idx + )); + break; + case IGRAPH_ATTRIBUTE_BOOLEAN: + IGRAPH_CHECK(igraph_vector_bool_index( + oldrec->value.as_vector_bool, newrec->value.as_vector_bool, idx + )); + break; + case IGRAPH_ATTRIBUTE_STRING: + IGRAPH_CHECK(igraph_strvector_index( + oldrec->value.as_strvector, newrec->value.as_strvector, idx + )); + break; + default: + IGRAPH_WARNINGF( + "Attribute '%s' with unknown type %d ignored", + oldrec->name, (int) oldrec->type + ); + } + } + + IGRAPH_FINALLY_CLEAN(1); + + return IGRAPH_SUCCESS; +} + +static igraph_error_t igraph_i_cattribute_permute_attribute_record_list_in_place( + igraph_attribute_record_list_t *attrs, const igraph_vector_int_t *idx +) { + igraph_integer_t no_attrs = igraph_attribute_record_list_size(attrs); igraph_integer_t i, j; igraph_attribute_record_t *oldrec; igraph_vector_t *num, *num_work; @@ -646,7 +563,7 @@ static igraph_error_t igraph_i_cattribute_permute_vertices_in_place( igraph_integer_t idx_size = igraph_vector_int_size(idx); /* shortcut: don't allocate anything if there are no attributes */ - if (valno == 0) { + if (no_attrs == 0) { return IGRAPH_SUCCESS; } @@ -655,29 +572,32 @@ static igraph_error_t igraph_i_cattribute_permute_vertices_in_place( * back out from a permutation once we've started it */ IGRAPH_CHECK(igraph_i_attribute_permutation_work_area_init(&work_area, idx_size)); IGRAPH_FINALLY(igraph_i_attribute_permutation_work_area_destroy, &work_area); - for (i = 0; i < valno; i++) { - oldrec = VECTOR(*val)[i]; + for (i = 0; i < no_attrs; i++) { + oldrec = igraph_attribute_record_list_get_ptr(attrs, i); switch (oldrec->type) { case IGRAPH_ATTRIBUTE_NUMERIC: - num = (igraph_vector_t*) oldrec->value; + num = oldrec->value.as_vector; IGRAPH_CHECK(igraph_vector_reserve(num, idx_size)); IGRAPH_CHECK(igraph_i_attribute_permutation_work_area_alloc_for_numeric(&work_area)); break; case IGRAPH_ATTRIBUTE_BOOLEAN: - oldbool = (igraph_vector_bool_t*) oldrec->value; + oldbool = oldrec->value.as_vector_bool; IGRAPH_CHECK(igraph_vector_bool_reserve(oldbool, idx_size)); IGRAPH_CHECK(igraph_i_attribute_permutation_work_area_alloc_for_boolean(&work_area)); break; case IGRAPH_ATTRIBUTE_STRING: - str = (igraph_strvector_t*) oldrec->value; + str = oldrec->value.as_strvector; IGRAPH_CHECK(igraph_strvector_reserve(str, idx_size)); IGRAPH_CHECK(igraph_i_attribute_permutation_work_area_alloc_for_strings(&work_area)); break; default: - IGRAPH_WARNING("Unknown vertex attribute ignored"); + IGRAPH_WARNINGF( + "Vertex attribute '%s' with unknown type %d ignored", + oldrec->name, (int) oldrec->type + ); } } @@ -686,18 +606,16 @@ static igraph_error_t igraph_i_cattribute_permute_vertices_in_place( * instances for the permuted attributes and store them in an * igraph_vector_ptr_t until we are done with all of them. If any of the * allocations fail, we can destroy the igraph_vector_ptr_t safely */ - for (i = 0; i < valno; i++) { - oldrec = VECTOR(*val)[i]; - if (oldrec->type != IGRAPH_ATTRIBUTE_STRING) { - continue; + for (i = 0; i < no_attrs; i++) { + oldrec = igraph_attribute_record_list_get_ptr(attrs, i); + if (oldrec->type == IGRAPH_ATTRIBUTE_STRING) { + str = oldrec->value.as_strvector; + IGRAPH_CHECK( + igraph_i_attribute_permutation_work_area_permute_and_store_strvector( + &work_area, str, idx + ) + ); } - - str = (igraph_strvector_t*) oldrec->value; - IGRAPH_CHECK( - igraph_i_attribute_permutation_work_area_permute_and_store_strvector( - &work_area, str, idx - ) - ); } /* strings are done, and now all vectors involved in the process are @@ -705,13 +623,13 @@ static igraph_error_t igraph_i_cattribute_permute_vertices_in_place( * supposed to fail. We can safely replace the original string attribute * vectors with the permuted ones, and then proceed to the remaining * attributes */ - for (i = 0, j = 0; i < valno; i++) { - oldrec = VECTOR(*val)[i]; + for (i = 0, j = 0; i < no_attrs; i++) { + oldrec = igraph_attribute_record_list_get_ptr(attrs, i); if (oldrec->type != IGRAPH_ATTRIBUTE_STRING) { continue; } - str = (igraph_strvector_t*) oldrec->value; + str = oldrec->value.as_strvector; str_work = *((igraph_strvector_t*) VECTOR(*(work_area.strings))[j]); *((igraph_strvector_t*) VECTOR(*(work_area.strings))[j]) = *str; *str = str_work; @@ -719,24 +637,22 @@ static igraph_error_t igraph_i_cattribute_permute_vertices_in_place( } igraph_i_attribute_permutation_work_area_release_stored_strvectors(&work_area); - for (i = 0; i < valno; i++) { - oldrec = VECTOR(*val)[i]; + for (i = 0; i < no_attrs; i++) { + oldrec = igraph_attribute_record_list_get_ptr(attrs, i); switch (oldrec->type) { case IGRAPH_ATTRIBUTE_NUMERIC: - num = (igraph_vector_t*) oldrec->value; + num = oldrec->value.as_vector; num_work = work_area.numeric; IGRAPH_ASSERT(num_work != NULL); IGRAPH_CHECK(igraph_vector_index(num, num_work, idx)); - work_area.numeric = num; - oldrec->value = num_work; + igraph_vector_swap(num, num_work); break; case IGRAPH_ATTRIBUTE_BOOLEAN: - oldbool = (igraph_vector_bool_t*) oldrec->value; + oldbool = oldrec->value.as_vector_bool; bool_work = work_area.boolean; IGRAPH_ASSERT(bool_work != NULL); IGRAPH_CHECK(igraph_vector_bool_index(oldbool, bool_work, idx)); - work_area.boolean = oldbool; - oldrec->value = bool_work; + igraph_vector_bool_swap(oldbool, bool_work); break; case IGRAPH_ATTRIBUTE_STRING: /* nothing to do */ @@ -757,88 +673,12 @@ static igraph_error_t igraph_i_cattribute_permute_vertices( const igraph_t *graph, igraph_t *newgraph, const igraph_vector_int_t *idx ) { igraph_i_cattributes_t *attr = graph->attr, *new_attr = newgraph->attr; - igraph_vector_ptr_t *val = &attr->val, *new_val = &new_attr->val; - igraph_integer_t i, valno; - - IGRAPH_ASSERT(graph == newgraph || igraph_vector_ptr_empty(new_val)); - - /* Handle in-place permutation separately */ + igraph_attribute_record_list_t *val = &attr->val, *new_val = &new_attr->val; if (graph == newgraph) { - return igraph_i_cattribute_permute_vertices_in_place(newgraph, idx); - } - - /* New vertex attributes */ - valno = igraph_vector_ptr_size(val); - IGRAPH_CHECK(igraph_vector_ptr_resize(new_val, valno)); - IGRAPH_FINALLY(igraph_i_cattribute_clear_attribute_container, new_val); - - for (i = 0; i < valno; i++) { - igraph_attribute_record_t *oldrec = VECTOR(*val)[i]; - igraph_attribute_type_t type = oldrec->type; - igraph_vector_t *num, *newnum; - igraph_strvector_t *str, *newstr; - igraph_vector_bool_t *oldbool, *newbool; - - /* The record itself */ - igraph_attribute_record_t *new_rec = - IGRAPH_CALLOC(1, igraph_attribute_record_t); - if (! new_rec) { - IGRAPH_ERROR("Cannot create vertex attributes", IGRAPH_ENOMEM); /* LCOV_EXCL_LINE */ - } - IGRAPH_FINALLY(igraph_free, new_rec); - new_rec->name = strdup(oldrec->name); - if (! new_rec->name) { - IGRAPH_ERROR("Cannot create vertex attributes", IGRAPH_ENOMEM); /* LCOV_EXCL_LINE */ - } - IGRAPH_FINALLY(igraph_free, (char *) new_rec->name); - new_rec->type = oldrec->type; - - /* The data */ - switch (type) { - case IGRAPH_ATTRIBUTE_NUMERIC: - num = (igraph_vector_t*)oldrec->value; - newnum = IGRAPH_CALLOC(1, igraph_vector_t); - if (!newnum) { - IGRAPH_ERROR("Cannot permute vertex attributes", IGRAPH_ENOMEM); /* LCOV_EXCL_LINE */ - } - IGRAPH_FINALLY(igraph_free, newnum); - IGRAPH_VECTOR_INIT_FINALLY(newnum, 0); - IGRAPH_CHECK(igraph_vector_index(num, newnum, idx)); - new_rec->value = newnum; - break; - case IGRAPH_ATTRIBUTE_BOOLEAN: - oldbool = (igraph_vector_bool_t*)oldrec->value; - newbool = IGRAPH_CALLOC(1, igraph_vector_bool_t); - if (!newbool) { - IGRAPH_ERROR("Cannot permute vertex attributes", IGRAPH_ENOMEM); /* LCOV_EXCL_LINE */ - } - IGRAPH_FINALLY(igraph_free, newbool); - IGRAPH_VECTOR_BOOL_INIT_FINALLY(newbool, 0); - IGRAPH_CHECK(igraph_vector_bool_index(oldbool, newbool, idx)); - new_rec->value = newbool; - break; - case IGRAPH_ATTRIBUTE_STRING: - str = (igraph_strvector_t*)oldrec->value; - newstr = IGRAPH_CALLOC(1, igraph_strvector_t); - if (!newstr) { - IGRAPH_ERROR("Cannot permute vertex attributes", IGRAPH_ENOMEM); /* LCOV_EXCL_LINE */ - } - IGRAPH_FINALLY(igraph_free, newstr); - IGRAPH_STRVECTOR_INIT_FINALLY(newstr, 0); - IGRAPH_CHECK(igraph_strvector_index(str, newstr, idx)); - new_rec->value = newstr; - break; - default: - IGRAPH_WARNING("Unknown vertex attribute ignored"); - } - - VECTOR(*new_val)[i] = new_rec; - IGRAPH_FINALLY_CLEAN(4); + return igraph_i_cattribute_permute_attribute_record_list_in_place(val, idx); + } else { + return igraph_i_cattribute_permute_attribute_record_list(val, new_val, idx); } - - IGRAPH_FINALLY_CLEAN(1); - - return IGRAPH_SUCCESS; } typedef igraph_error_t igraph_cattributes_combine_num_t(const igraph_vector_t *input, @@ -853,17 +693,11 @@ typedef igraph_error_t igraph_cattributes_combine_bool_t(const igraph_vector_boo static igraph_error_t igraph_i_cattributes_cn_sum(const igraph_attribute_record_t *oldrec, igraph_attribute_record_t * newrec, const igraph_vector_int_list_t *merges) { - const igraph_vector_t *oldv = oldrec->value; - igraph_vector_t *newv = IGRAPH_CALLOC(1, igraph_vector_t); + const igraph_vector_t *oldv = oldrec->value.as_vector; + igraph_vector_t *newv = newrec->value.as_vector; igraph_integer_t newlen = igraph_vector_int_list_size(merges); igraph_integer_t i; - if (!newv) { - IGRAPH_ERROR("Cannot combine attributes", IGRAPH_ENOMEM); /* LCOV_EXCL_LINE */ - } - IGRAPH_FINALLY(igraph_free, newv); - IGRAPH_VECTOR_INIT_FINALLY(newv, newlen); - for (i = 0; i < newlen; i++) { igraph_real_t s = 0.0; igraph_vector_int_t *idx = igraph_vector_int_list_get_ptr(merges, i);; @@ -875,26 +709,17 @@ static igraph_error_t igraph_i_cattributes_cn_sum(const igraph_attribute_record_ VECTOR(*newv)[i] = s; } - IGRAPH_FINALLY_CLEAN(2); - newrec->value = newv; - return IGRAPH_SUCCESS; } static igraph_error_t igraph_i_cattributes_cn_prod(const igraph_attribute_record_t *oldrec, igraph_attribute_record_t * newrec, const igraph_vector_int_list_t *merges) { - const igraph_vector_t *oldv = oldrec->value; - igraph_vector_t *newv = IGRAPH_CALLOC(1, igraph_vector_t); + const igraph_vector_t *oldv = oldrec->value.as_vector; + igraph_vector_t *newv = newrec->value.as_vector; igraph_integer_t newlen = igraph_vector_int_list_size(merges); igraph_integer_t i; - if (!newv) { - IGRAPH_ERROR("Cannot combine attributes", IGRAPH_ENOMEM); /* LCOV_EXCL_LINE */ - } - IGRAPH_FINALLY(igraph_free, newv); - IGRAPH_VECTOR_INIT_FINALLY(newv, newlen); - for (i = 0; i < newlen; i++) { igraph_real_t s = 1.0; igraph_vector_int_t *idx = igraph_vector_int_list_get_ptr(merges, i);; @@ -906,26 +731,17 @@ static igraph_error_t igraph_i_cattributes_cn_prod(const igraph_attribute_record VECTOR(*newv)[i] = s; } - IGRAPH_FINALLY_CLEAN(2); - newrec->value = newv; - return IGRAPH_SUCCESS; } static igraph_error_t igraph_i_cattributes_cn_min(const igraph_attribute_record_t *oldrec, igraph_attribute_record_t * newrec, const igraph_vector_int_list_t *merges) { - const igraph_vector_t *oldv = oldrec->value; - igraph_vector_t *newv = IGRAPH_CALLOC(1, igraph_vector_t); + const igraph_vector_t *oldv = oldrec->value.as_vector; + igraph_vector_t *newv = newrec->value.as_vector; igraph_integer_t newlen = igraph_vector_int_list_size(merges); igraph_integer_t i; - if (!newv) { - IGRAPH_ERROR("Cannot combine attributes", IGRAPH_ENOMEM); /* LCOV_EXCL_LINE */ - } - IGRAPH_FINALLY(igraph_free, newv); - IGRAPH_VECTOR_INIT_FINALLY(newv, newlen); - for (i = 0; i < newlen; i++) { igraph_vector_int_t *idx = igraph_vector_int_list_get_ptr(merges, i);; igraph_integer_t j, n = igraph_vector_int_size(idx); @@ -940,26 +756,17 @@ static igraph_error_t igraph_i_cattributes_cn_min(const igraph_attribute_record_ VECTOR(*newv)[i] = m; } - IGRAPH_FINALLY_CLEAN(2); - newrec->value = newv; - return IGRAPH_SUCCESS; } static igraph_error_t igraph_i_cattributes_cn_max(const igraph_attribute_record_t *oldrec, igraph_attribute_record_t * newrec, const igraph_vector_int_list_t *merges) { - const igraph_vector_t *oldv = oldrec->value; - igraph_vector_t *newv = IGRAPH_CALLOC(1, igraph_vector_t); + const igraph_vector_t *oldv = oldrec->value.as_vector; + igraph_vector_t *newv = newrec->value.as_vector; igraph_integer_t newlen = igraph_vector_int_list_size(merges); igraph_integer_t i; - if (!newv) { - IGRAPH_ERROR("Cannot combine attributes", IGRAPH_ENOMEM); /* LCOV_EXCL_LINE */ - } - IGRAPH_FINALLY(igraph_free, newv); - IGRAPH_VECTOR_INIT_FINALLY(newv, newlen); - for (i = 0; i < newlen; i++) { igraph_vector_int_t *idx = igraph_vector_int_list_get_ptr(merges, i);; igraph_integer_t j, n = igraph_vector_int_size(idx); @@ -974,9 +781,6 @@ static igraph_error_t igraph_i_cattributes_cn_max(const igraph_attribute_record_ VECTOR(*newv)[i] = m; } - IGRAPH_FINALLY_CLEAN(2); - newrec->value = newv; - return IGRAPH_SUCCESS; } @@ -984,17 +788,11 @@ static igraph_error_t igraph_i_cattributes_cn_random(const igraph_attribute_reco igraph_attribute_record_t * newrec, const igraph_vector_int_list_t *merges) { - const igraph_vector_t *oldv = oldrec->value; - igraph_vector_t *newv = IGRAPH_CALLOC(1, igraph_vector_t); + const igraph_vector_t *oldv = oldrec->value.as_vector; + igraph_vector_t *newv = newrec->value.as_vector; igraph_integer_t newlen = igraph_vector_int_list_size(merges); igraph_integer_t i; - if (!newv) { - IGRAPH_ERROR("Cannot combine attributes", IGRAPH_ENOMEM); /* LCOV_EXCL_LINE */ - } - IGRAPH_FINALLY(igraph_free, newv); - IGRAPH_VECTOR_INIT_FINALLY(newv, newlen); - RNG_BEGIN(); for (i = 0; i < newlen; i++) { @@ -1012,9 +810,6 @@ static igraph_error_t igraph_i_cattributes_cn_random(const igraph_attribute_reco RNG_END(); - IGRAPH_FINALLY_CLEAN(2); - newrec->value = newv; - return IGRAPH_SUCCESS; } @@ -1022,17 +817,11 @@ static igraph_error_t igraph_i_cattributes_cn_first(const igraph_attribute_recor igraph_attribute_record_t * newrec, const igraph_vector_int_list_t *merges) { - const igraph_vector_t *oldv = oldrec->value; - igraph_vector_t *newv = IGRAPH_CALLOC(1, igraph_vector_t); + const igraph_vector_t *oldv = oldrec->value.as_vector; + igraph_vector_t *newv = newrec->value.as_vector; igraph_integer_t newlen = igraph_vector_int_list_size(merges); igraph_integer_t i; - if (!newv) { - IGRAPH_ERROR("Cannot combine attributes", IGRAPH_ENOMEM); /* LCOV_EXCL_LINE */ - } - IGRAPH_FINALLY(igraph_free, newv); - IGRAPH_VECTOR_INIT_FINALLY(newv, newlen); - for (i = 0; i < newlen; i++) { igraph_vector_int_t *idx = igraph_vector_int_list_get_ptr(merges, i);; igraph_integer_t n = igraph_vector_int_size(idx); @@ -1043,9 +832,6 @@ static igraph_error_t igraph_i_cattributes_cn_first(const igraph_attribute_recor } } - IGRAPH_FINALLY_CLEAN(2); - newrec->value = newv; - return IGRAPH_SUCCESS; } @@ -1053,17 +839,11 @@ static igraph_error_t igraph_i_cattributes_cn_last(const igraph_attribute_record igraph_attribute_record_t * newrec, const igraph_vector_int_list_t *merges) { - const igraph_vector_t *oldv = oldrec->value; - igraph_vector_t *newv = IGRAPH_CALLOC(1, igraph_vector_t); + const igraph_vector_t *oldv = oldrec->value.as_vector; + igraph_vector_t *newv = newrec->value.as_vector; igraph_integer_t newlen = igraph_vector_int_list_size(merges); igraph_integer_t i; - if (!newv) { - IGRAPH_ERROR("Cannot combine attributes", IGRAPH_ENOMEM); /* LCOV_EXCL_LINE */ - } - IGRAPH_FINALLY(igraph_free, newv); - IGRAPH_VECTOR_INIT_FINALLY(newv, newlen); - for (i = 0; i < newlen; i++) { igraph_vector_int_t *idx = igraph_vector_int_list_get_ptr(merges, i);; igraph_integer_t n = igraph_vector_int_size(idx); @@ -1074,26 +854,17 @@ static igraph_error_t igraph_i_cattributes_cn_last(const igraph_attribute_record } } - IGRAPH_FINALLY_CLEAN(2); - newrec->value = newv; - return IGRAPH_SUCCESS; } static igraph_error_t igraph_i_cattributes_cn_mean(const igraph_attribute_record_t *oldrec, igraph_attribute_record_t * newrec, const igraph_vector_int_list_t *merges) { - const igraph_vector_t *oldv = oldrec->value; - igraph_vector_t *newv = IGRAPH_CALLOC(1, igraph_vector_t); + const igraph_vector_t *oldv = oldrec->value.as_vector; + igraph_vector_t *newv = newrec->value.as_vector; igraph_integer_t newlen = igraph_vector_int_list_size(merges); igraph_integer_t i; - if (!newv) { - IGRAPH_ERROR("Cannot combine attributes", IGRAPH_ENOMEM); /* LCOV_EXCL_LINE */ - } - IGRAPH_FINALLY(igraph_free, newv); - IGRAPH_VECTOR_INIT_FINALLY(newv, newlen); - for (i = 0; i < newlen; i++) { igraph_vector_int_t *idx = igraph_vector_int_list_get_ptr(merges, i);; igraph_integer_t j, n = igraph_vector_int_size(idx); @@ -1108,9 +879,6 @@ static igraph_error_t igraph_i_cattributes_cn_mean(const igraph_attribute_record VECTOR(*newv)[i] = s; } - IGRAPH_FINALLY_CLEAN(2); - newrec->value = newv; - return IGRAPH_SUCCESS; } @@ -1119,14 +887,10 @@ static igraph_error_t igraph_i_cattributes_cn_func(const igraph_attribute_record const igraph_vector_int_list_t *merges, igraph_cattributes_combine_num_t *func) { - const igraph_vector_t *oldv = oldrec->value; + const igraph_vector_t *oldv = oldrec->value.as_vector; + igraph_vector_t *newv = newrec->value.as_vector; igraph_integer_t newlen = igraph_vector_int_list_size(merges); - igraph_vector_t *newv = IGRAPH_CALLOC(1, igraph_vector_t); - IGRAPH_CHECK_OOM(newv, "Cannot combine attributes."); - IGRAPH_FINALLY(igraph_free, newv); - IGRAPH_VECTOR_INIT_FINALLY(newv, newlen); - igraph_vector_t values; IGRAPH_VECTOR_INIT_FINALLY(&values, 0); @@ -1146,8 +910,7 @@ static igraph_error_t igraph_i_cattributes_cn_func(const igraph_attribute_record } igraph_vector_destroy(&values); - IGRAPH_FINALLY_CLEAN(3); - newrec->value = newv; + IGRAPH_FINALLY_CLEAN(1); return IGRAPH_SUCCESS; } @@ -1156,17 +919,11 @@ static igraph_error_t igraph_i_cattributes_cb_random(const igraph_attribute_reco igraph_attribute_record_t * newrec, const igraph_vector_int_list_t *merges) { - const igraph_vector_bool_t *oldv = oldrec->value; - igraph_vector_bool_t *newv = IGRAPH_CALLOC(1, igraph_vector_bool_t); + const igraph_vector_bool_t *oldv = oldrec->value.as_vector_bool; + igraph_vector_bool_t *newv = newrec->value.as_vector_bool; igraph_integer_t newlen = igraph_vector_int_list_size(merges); igraph_integer_t i; - if (!newv) { - IGRAPH_ERROR("Cannot combine attributes", IGRAPH_ENOMEM); /* LCOV_EXCL_LINE */ - } - IGRAPH_FINALLY(igraph_free, newv); - IGRAPH_VECTOR_BOOL_INIT_FINALLY(newv, newlen); - RNG_BEGIN(); for (i = 0; i < newlen; i++) { @@ -1184,9 +941,6 @@ static igraph_error_t igraph_i_cattributes_cb_random(const igraph_attribute_reco RNG_END(); - IGRAPH_FINALLY_CLEAN(2); - newrec->value = newv; - return IGRAPH_SUCCESS; } @@ -1194,17 +948,11 @@ static igraph_error_t igraph_i_cattributes_cb_first(const igraph_attribute_recor igraph_attribute_record_t * newrec, const igraph_vector_int_list_t *merges) { - const igraph_vector_bool_t *oldv = oldrec->value; - igraph_vector_bool_t *newv = IGRAPH_CALLOC(1, igraph_vector_bool_t); + const igraph_vector_bool_t *oldv = oldrec->value.as_vector_bool; + igraph_vector_bool_t *newv = newrec->value.as_vector_bool; igraph_integer_t newlen = igraph_vector_int_list_size(merges); igraph_integer_t i; - if (!newv) { - IGRAPH_ERROR("Cannot combine attributes", IGRAPH_ENOMEM); /* LCOV_EXCL_LINE */ - } - IGRAPH_FINALLY(igraph_free, newv); - IGRAPH_VECTOR_BOOL_INIT_FINALLY(newv, newlen); - for (i = 0; i < newlen; i++) { igraph_vector_int_t *idx = igraph_vector_int_list_get_ptr(merges, i);; igraph_integer_t n = igraph_vector_int_size(idx); @@ -1215,9 +963,6 @@ static igraph_error_t igraph_i_cattributes_cb_first(const igraph_attribute_recor } } - IGRAPH_FINALLY_CLEAN(2); - newrec->value = newv; - return IGRAPH_SUCCESS; } @@ -1225,17 +970,11 @@ static igraph_error_t igraph_i_cattributes_cb_last(const igraph_attribute_record igraph_attribute_record_t * newrec, const igraph_vector_int_list_t *merges) { - const igraph_vector_bool_t *oldv = oldrec->value; - igraph_vector_bool_t *newv = IGRAPH_CALLOC(1, igraph_vector_bool_t); + const igraph_vector_bool_t *oldv = oldrec->value.as_vector_bool; + igraph_vector_bool_t *newv = newrec->value.as_vector_bool; igraph_integer_t newlen = igraph_vector_int_list_size(merges); igraph_integer_t i; - if (!newv) { - IGRAPH_ERROR("Cannot combine attributes", IGRAPH_ENOMEM); /* LCOV_EXCL_LINE */ - } - IGRAPH_FINALLY(igraph_free, newv); - IGRAPH_VECTOR_BOOL_INIT_FINALLY(newv, newlen); - for (i = 0; i < newlen; i++) { igraph_vector_int_t *idx = igraph_vector_int_list_get_ptr(merges, i);; igraph_integer_t n = igraph_vector_int_size(idx); @@ -1246,9 +985,6 @@ static igraph_error_t igraph_i_cattributes_cb_last(const igraph_attribute_record } } - IGRAPH_FINALLY_CLEAN(2); - newrec->value = newv; - return IGRAPH_SUCCESS; } @@ -1256,17 +992,11 @@ static igraph_error_t igraph_i_cattributes_cb_all_is_true(const igraph_attribute igraph_attribute_record_t * newrec, const igraph_vector_int_list_t *merges) { - const igraph_vector_bool_t *oldv = oldrec->value; - igraph_vector_bool_t *newv = IGRAPH_CALLOC(1, igraph_vector_bool_t); + const igraph_vector_bool_t *oldv = oldrec->value.as_vector_bool; + igraph_vector_bool_t *newv = newrec->value.as_vector_bool; igraph_integer_t newlen = igraph_vector_int_list_size(merges); igraph_integer_t i, j, n, x; - if (!newv) { - IGRAPH_ERROR("Cannot combine attributes", IGRAPH_ENOMEM); /* LCOV_EXCL_LINE */ - } - IGRAPH_FINALLY(igraph_free, newv); - IGRAPH_VECTOR_BOOL_INIT_FINALLY(newv, newlen); - for (i = 0; i < newlen; i++) { igraph_vector_int_t *idx = igraph_vector_int_list_get_ptr(merges, i);; n = igraph_vector_int_size(idx); @@ -1280,9 +1010,6 @@ static igraph_error_t igraph_i_cattributes_cb_all_is_true(const igraph_attribute } } - IGRAPH_FINALLY_CLEAN(2); - newrec->value = newv; - return IGRAPH_SUCCESS; } @@ -1290,17 +1017,11 @@ static igraph_error_t igraph_i_cattributes_cb_any_is_true(const igraph_attribute igraph_attribute_record_t * newrec, const igraph_vector_int_list_t *merges) { - const igraph_vector_bool_t *oldv = oldrec->value; - igraph_vector_bool_t *newv = IGRAPH_CALLOC(1, igraph_vector_bool_t); + const igraph_vector_bool_t *oldv = oldrec->value.as_vector_bool; + igraph_vector_bool_t *newv = newrec->value.as_vector_bool; igraph_integer_t newlen = igraph_vector_int_list_size(merges); igraph_integer_t i, j, n, x; - if (!newv) { - IGRAPH_ERROR("Cannot combine attributes", IGRAPH_ENOMEM); /* LCOV_EXCL_LINE */ - } - IGRAPH_FINALLY(igraph_free, newv); - IGRAPH_VECTOR_BOOL_INIT_FINALLY(newv, newlen); - for (i = 0; i < newlen; i++) { igraph_vector_int_t *idx = igraph_vector_int_list_get_ptr(merges, i);; n = igraph_vector_int_size(idx); @@ -1314,9 +1035,6 @@ static igraph_error_t igraph_i_cattributes_cb_any_is_true(const igraph_attribute } } - IGRAPH_FINALLY_CLEAN(2); - newrec->value = newv; - return IGRAPH_SUCCESS; } @@ -1324,17 +1042,11 @@ static igraph_error_t igraph_i_cattributes_cb_majority(const igraph_attribute_re igraph_attribute_record_t * newrec, const igraph_vector_int_list_t *merges) { - const igraph_vector_bool_t *oldv = oldrec->value; - igraph_vector_bool_t *newv = IGRAPH_CALLOC(1, igraph_vector_bool_t); + const igraph_vector_bool_t *oldv = oldrec->value.as_vector_bool; + igraph_vector_bool_t *newv = newrec->value.as_vector_bool; igraph_integer_t newlen = igraph_vector_int_list_size(merges); igraph_integer_t i, j, n, x, num_trues; - if (!newv) { - IGRAPH_ERROR("Cannot combine attributes", IGRAPH_ENOMEM); /* LCOV_EXCL_LINE */ - } - IGRAPH_FINALLY(igraph_free, newv); - IGRAPH_VECTOR_BOOL_INIT_FINALLY(newv, newlen); - RNG_BEGIN(); for (i = 0; i < newlen; i++) { @@ -1363,9 +1075,6 @@ static igraph_error_t igraph_i_cattributes_cb_majority(const igraph_attribute_re RNG_END(); - IGRAPH_FINALLY_CLEAN(2); - newrec->value = newv; - return IGRAPH_SUCCESS; } @@ -1374,14 +1083,10 @@ static igraph_error_t igraph_i_cattributes_cb_func(const igraph_attribute_record const igraph_vector_int_list_t *merges, igraph_cattributes_combine_bool_t *func) { - const igraph_vector_bool_t *oldv = oldrec->value; + const igraph_vector_bool_t *oldv = oldrec->value.as_vector_bool; + igraph_vector_bool_t *newv = newrec->value.as_vector_bool; igraph_integer_t newlen = igraph_vector_int_list_size(merges); - igraph_vector_bool_t *newv = IGRAPH_CALLOC(1, igraph_vector_bool_t); - IGRAPH_CHECK_OOM(newv, "Cannot combine attributes."); - IGRAPH_FINALLY(igraph_free, newv); - IGRAPH_VECTOR_BOOL_INIT_FINALLY(newv, newlen); - igraph_vector_bool_t values; IGRAPH_VECTOR_BOOL_INIT_FINALLY(&values, 0); @@ -1401,8 +1106,7 @@ static igraph_error_t igraph_i_cattributes_cb_func(const igraph_attribute_record } igraph_vector_bool_destroy(&values); - IGRAPH_FINALLY_CLEAN(3); - newrec->value = newv; + IGRAPH_FINALLY_CLEAN(1); return IGRAPH_SUCCESS; } @@ -1411,16 +1115,10 @@ static igraph_error_t igraph_i_cattributes_sn_random(const igraph_attribute_reco igraph_attribute_record_t *newrec, const igraph_vector_int_list_t *merges) { - const igraph_strvector_t *oldv = oldrec->value; + const igraph_strvector_t *oldv = oldrec->value.as_strvector; + igraph_strvector_t *newv = newrec->value.as_strvector; igraph_integer_t newlen = igraph_vector_int_list_size(merges); igraph_integer_t i; - igraph_strvector_t *newv = IGRAPH_CALLOC(1, igraph_strvector_t); - - if (!newv) { - IGRAPH_ERROR("Cannot combine attributes", IGRAPH_ENOMEM); /* LCOV_EXCL_LINE */ - } - IGRAPH_FINALLY(igraph_free, newv); - IGRAPH_STRVECTOR_INIT_FINALLY(newv, newlen); RNG_BEGIN(); @@ -1442,25 +1140,16 @@ static igraph_error_t igraph_i_cattributes_sn_random(const igraph_attribute_reco RNG_END(); - IGRAPH_FINALLY_CLEAN(2); - newrec->value = newv; - return IGRAPH_SUCCESS; } -static igraph_error_t igraph_i_cattributes_sn_first(const igraph_attribute_record_t *oldrec, +static igraph_error_t igraph_i_cattributes_cs_first(const igraph_attribute_record_t *oldrec, igraph_attribute_record_t *newrec, const igraph_vector_int_list_t *merges) { - const igraph_strvector_t *oldv = oldrec->value; + const igraph_strvector_t *oldv = oldrec->value.as_strvector; igraph_integer_t i, newlen = igraph_vector_int_list_size(merges); - igraph_strvector_t *newv = IGRAPH_CALLOC(1, igraph_strvector_t); - - if (!newv) { - IGRAPH_ERROR("Cannot combine attributes", IGRAPH_ENOMEM); /* LCOV_EXCL_LINE */ - } - IGRAPH_FINALLY(igraph_free, newv); - IGRAPH_STRVECTOR_INIT_FINALLY(newv, newlen); + igraph_strvector_t *newv = newrec->value.as_strvector; for (i = 0; i < newlen; i++) { igraph_vector_int_t *idx = igraph_vector_int_list_get_ptr(merges, i);; @@ -1473,25 +1162,16 @@ static igraph_error_t igraph_i_cattributes_sn_first(const igraph_attribute_recor } } - IGRAPH_FINALLY_CLEAN(2); - newrec->value = newv; - return IGRAPH_SUCCESS; } -static igraph_error_t igraph_i_cattributes_sn_last(const igraph_attribute_record_t *oldrec, +static igraph_error_t igraph_i_cattributes_cs_last(const igraph_attribute_record_t *oldrec, igraph_attribute_record_t *newrec, const igraph_vector_int_list_t *merges) { - const igraph_strvector_t *oldv = oldrec->value; + const igraph_strvector_t *oldv = oldrec->value.as_strvector; igraph_integer_t i, newlen = igraph_vector_int_list_size(merges); - igraph_strvector_t *newv = IGRAPH_CALLOC(1, igraph_strvector_t); - - if (!newv) { - IGRAPH_ERROR("Cannot combine attributes", IGRAPH_ENOMEM); /* LCOV_EXCL_LINE */ - } - IGRAPH_FINALLY(igraph_free, newv); - IGRAPH_STRVECTOR_INIT_FINALLY(newv, newlen); + igraph_strvector_t *newv = newrec->value.as_strvector; for (i = 0; i < newlen; i++) { igraph_vector_int_t *idx = igraph_vector_int_list_get_ptr(merges, i);; @@ -1504,25 +1184,16 @@ static igraph_error_t igraph_i_cattributes_sn_last(const igraph_attribute_record } } - IGRAPH_FINALLY_CLEAN(2); - newrec->value = newv; - return IGRAPH_SUCCESS; } -static igraph_error_t igraph_i_cattributes_sn_concat(const igraph_attribute_record_t *oldrec, +static igraph_error_t igraph_i_cattributes_cs_concat(const igraph_attribute_record_t *oldrec, igraph_attribute_record_t *newrec, const igraph_vector_int_list_t *merges) { - const igraph_strvector_t *oldv = oldrec->value; + const igraph_strvector_t *oldv = oldrec->value.as_strvector; igraph_integer_t i, newlen = igraph_vector_int_list_size(merges); - igraph_strvector_t *newv = IGRAPH_CALLOC(1, igraph_strvector_t); - - if (!newv) { - IGRAPH_ERROR("Cannot combine attributes", IGRAPH_ENOMEM); /* LCOV_EXCL_LINE */ - } - IGRAPH_FINALLY(igraph_free, newv); - IGRAPH_STRVECTOR_INIT_FINALLY(newv, newlen); + igraph_strvector_t *newv = newrec->value.as_strvector; for (i = 0; i < newlen; i++) { igraph_vector_int_t *idx = igraph_vector_int_list_get_ptr(merges, i);; @@ -1535,9 +1206,7 @@ static igraph_error_t igraph_i_cattributes_sn_concat(const igraph_attribute_reco len += strlen(tmp); } tmp2 = IGRAPH_CALLOC(len + 1, char); - if (!tmp2) { - IGRAPH_ERROR("Cannot combine attributes", IGRAPH_ENOMEM); /* LCOV_EXCL_LINE */ - } + IGRAPH_CHECK_OOM(tmp2, "Cannot combine attributes"); IGRAPH_FINALLY(igraph_free, tmp2); len = 0; for (j = 0; j < n; j++) { @@ -1551,25 +1220,18 @@ static igraph_error_t igraph_i_cattributes_sn_concat(const igraph_attribute_reco IGRAPH_FINALLY_CLEAN(1); } - IGRAPH_FINALLY_CLEAN(2); - newrec->value = newv; - return IGRAPH_SUCCESS; } -static igraph_error_t igraph_i_cattributes_sn_func(const igraph_attribute_record_t *oldrec, +static igraph_error_t igraph_i_cattributes_cs_func(const igraph_attribute_record_t *oldrec, igraph_attribute_record_t *newrec, const igraph_vector_int_list_t *merges, igraph_cattributes_combine_str_t *func) { - const igraph_strvector_t *oldv = oldrec->value; + const igraph_strvector_t *oldv = oldrec->value.as_strvector; + igraph_strvector_t *newv = newrec->value.as_strvector; igraph_integer_t newlen = igraph_vector_int_list_size(merges); - igraph_strvector_t *newv = IGRAPH_CALLOC(1, igraph_strvector_t); - IGRAPH_CHECK_OOM(newv, "Cannot combine attributes."); - IGRAPH_FINALLY(igraph_free, newv); - IGRAPH_STRVECTOR_INIT_FINALLY(newv, newlen); - igraph_strvector_t values; IGRAPH_STRVECTOR_INIT_FINALLY(&values, 0); @@ -1595,8 +1257,7 @@ static igraph_error_t igraph_i_cattributes_sn_func(const igraph_attribute_record } igraph_strvector_destroy(&values); - IGRAPH_FINALLY_CLEAN(3); - newrec->value = newv; + IGRAPH_FINALLY_CLEAN(1); return IGRAPH_SUCCESS; } @@ -1611,680 +1272,69 @@ static igraph_error_t igraph_i_cattributes_sn_func(const igraph_attribute_record * type of the attribute combination to \c IGRAPH_ATTRIBUTE_COMBINE_FUNCTION * and passing in a pointer to the custom combination function when specifying * attribute combinations in \ref igraph_attribute_combination() or - * \ref igraph_attribute_combination_add() . For the C attribute handler, the - * signature of the function depends on the type of the underlying attribute. - * For numeric attributes, use: - * \verbatim igraph_error_t function(const igraph_vector_t *input, igraph_real_t *output); \endverbatim - * where \p input will receive a vector containing the value of the attribute - * for all the vertices or edges being combined, and \p output must be filled - * by the function to the combined value. Similarly, for Boolean attributes, the - * function takes a boolean vector in \p input and must return the combined Boolean - * value in \p output: - * \verbatim igraph_error_t function(const igraph_vector_bool_t *input, igraph_bool_t *output); \endverbatim - * For string attributes, the signature is slightly different: - * \verbatim igraph_error_t function(const igraph_strvector_t *input, char **output); \endverbatim - * In case of strings, all strings in the input vector are \em owned by igraph - * and must not be modified or freed in the combination handler. The string - * returned to the caller in \p output remains owned by the caller; igraph will - * make a copy it and store the copy in the appropriate part of the data - * structure holding the vertex or edge attributes. - * - */ - -typedef struct { - igraph_attribute_combination_type_t type; - union { - igraph_function_pointer_t as_void; - igraph_cattributes_combine_num_t *as_num; - igraph_cattributes_combine_str_t *as_str; - igraph_cattributes_combine_bool_t *as_bool; - } func; -} igraph_attribute_combination_todo_item_t; - -static igraph_error_t igraph_i_cattribute_combine_vertices(const igraph_t *graph, - igraph_t *newgraph, - const igraph_vector_int_list_t *merges, - const igraph_attribute_combination_t *comb) { - - igraph_i_cattributes_t *attr = graph->attr; - igraph_i_cattributes_t *toattr = newgraph->attr; - igraph_vector_ptr_t *val = &attr->val; - igraph_vector_ptr_t *new_val = &toattr->val; - igraph_integer_t valno = igraph_vector_ptr_size(val); - igraph_integer_t i, j, keepno = 0; - igraph_attribute_combination_todo_item_t *todo_items; - - IGRAPH_ASSERT(graph != newgraph); - IGRAPH_ASSERT(igraph_vector_ptr_empty(new_val)); - - todo_items = IGRAPH_CALLOC(valno, igraph_attribute_combination_todo_item_t); - if (!todo_items) { - IGRAPH_ERROR("Cannot combine vertex attributes", - IGRAPH_ENOMEM); /* LCOV_EXCL_LINE */ - } - IGRAPH_FINALLY(igraph_free, todo_items); - - for (i = 0; i < valno; i++) { - igraph_attribute_record_t *oldrec = VECTOR(*val)[i]; - const char *name = oldrec->name; - igraph_attribute_combination_type_t type; - igraph_function_pointer_t voidfunc; - IGRAPH_CHECK(igraph_attribute_combination_query(comb, name, &type, &voidfunc)); - todo_items[i].type = type; - todo_items[i].func.as_void = voidfunc; - if (type != IGRAPH_ATTRIBUTE_COMBINE_IGNORE) { - keepno++; - } - } - - IGRAPH_CHECK(igraph_vector_ptr_resize(new_val, keepno)); - IGRAPH_FINALLY(igraph_i_cattribute_clear_attribute_container, new_val); - - for (i = 0, j = 0; i < valno; i++) { - igraph_attribute_record_t *newrec, *oldrec = VECTOR(*val)[i]; - const char *name = oldrec->name; - igraph_attribute_combination_todo_item_t todo_item = todo_items[i]; - igraph_attribute_type_t attr_type = oldrec->type; - - if (todo_item.type == IGRAPH_ATTRIBUTE_COMBINE_DEFAULT || - todo_item.type == IGRAPH_ATTRIBUTE_COMBINE_IGNORE) { - continue; - } - - newrec = IGRAPH_CALLOC(1, igraph_attribute_record_t); - if (!newrec) { - IGRAPH_ERROR("Cannot combine vertex attributes", IGRAPH_ENOMEM); /* LCOV_EXCL_LINE */ - } - IGRAPH_FINALLY(igraph_free, newrec); - newrec->name = strdup(name); - if (!newrec->name) { - IGRAPH_ERROR("Cannot combine vertex attributes", IGRAPH_ENOMEM); /* LCOV_EXCL_LINE */ - } - IGRAPH_FINALLY(igraph_free, (char *) newrec->name); - newrec->type = attr_type; - - if (attr_type == IGRAPH_ATTRIBUTE_NUMERIC) { - switch (todo_item.type) { - case IGRAPH_ATTRIBUTE_COMBINE_FUNCTION: - IGRAPH_CHECK(igraph_i_cattributes_cn_func(oldrec, newrec, merges, - todo_item.func.as_num)); - break; - case IGRAPH_ATTRIBUTE_COMBINE_SUM: - IGRAPH_CHECK(igraph_i_cattributes_cn_sum(oldrec, newrec, merges)); - break; - case IGRAPH_ATTRIBUTE_COMBINE_PROD: - IGRAPH_CHECK(igraph_i_cattributes_cn_prod(oldrec, newrec, merges)); - break; - case IGRAPH_ATTRIBUTE_COMBINE_MIN: - IGRAPH_CHECK(igraph_i_cattributes_cn_min(oldrec, newrec, merges)); - break; - case IGRAPH_ATTRIBUTE_COMBINE_MAX: - IGRAPH_CHECK(igraph_i_cattributes_cn_max(oldrec, newrec, merges)); - break; - case IGRAPH_ATTRIBUTE_COMBINE_RANDOM: - IGRAPH_CHECK(igraph_i_cattributes_cn_random(oldrec, newrec, merges)); - break; - case IGRAPH_ATTRIBUTE_COMBINE_FIRST: - IGRAPH_CHECK(igraph_i_cattributes_cn_first(oldrec, newrec, merges)); - break; - case IGRAPH_ATTRIBUTE_COMBINE_LAST: - IGRAPH_CHECK(igraph_i_cattributes_cn_last(oldrec, newrec, merges)); - break; - case IGRAPH_ATTRIBUTE_COMBINE_MEAN: - IGRAPH_CHECK(igraph_i_cattributes_cn_mean(oldrec, newrec, merges)); - break; - case IGRAPH_ATTRIBUTE_COMBINE_MEDIAN: - IGRAPH_ERROR("Median calculation not implemented", - IGRAPH_UNIMPLEMENTED); - break; - case IGRAPH_ATTRIBUTE_COMBINE_CONCAT: - IGRAPH_ERROR("Cannot concatenate numeric attributes", - IGRAPH_EATTRCOMBINE); - break; - default: - IGRAPH_ERROR("Unknown attribute_combination", - IGRAPH_UNIMPLEMENTED); - break; - } - } else if (attr_type == IGRAPH_ATTRIBUTE_BOOLEAN) { - switch (todo_item.type) { - case IGRAPH_ATTRIBUTE_COMBINE_FUNCTION: - IGRAPH_CHECK(igraph_i_cattributes_cb_func(oldrec, newrec, merges, - todo_item.func.as_bool)); - break; - case IGRAPH_ATTRIBUTE_COMBINE_SUM: - case IGRAPH_ATTRIBUTE_COMBINE_MAX: - IGRAPH_CHECK(igraph_i_cattributes_cb_any_is_true(oldrec, newrec, merges)); - break; - case IGRAPH_ATTRIBUTE_COMBINE_PROD: - case IGRAPH_ATTRIBUTE_COMBINE_MIN: - IGRAPH_CHECK(igraph_i_cattributes_cb_all_is_true(oldrec, newrec, merges)); - break; - case IGRAPH_ATTRIBUTE_COMBINE_MEAN: - case IGRAPH_ATTRIBUTE_COMBINE_MEDIAN: - IGRAPH_CHECK(igraph_i_cattributes_cb_majority(oldrec, newrec, merges)); - break; - case IGRAPH_ATTRIBUTE_COMBINE_RANDOM: - IGRAPH_CHECK(igraph_i_cattributes_cb_random(oldrec, newrec, merges)); - break; - case IGRAPH_ATTRIBUTE_COMBINE_FIRST: - IGRAPH_CHECK(igraph_i_cattributes_cb_first(oldrec, newrec, merges)); - break; - case IGRAPH_ATTRIBUTE_COMBINE_LAST: - IGRAPH_CHECK(igraph_i_cattributes_cb_last(oldrec, newrec, merges)); - break; - case IGRAPH_ATTRIBUTE_COMBINE_CONCAT: - IGRAPH_ERROR("Cannot calculate concatenation of Booleans", - IGRAPH_EATTRCOMBINE); - break; - default: - IGRAPH_ERROR("Unknown attribute_combination", - IGRAPH_UNIMPLEMENTED); - break; - } - } else if (attr_type == IGRAPH_ATTRIBUTE_STRING) { - switch (todo_item.type) { - case IGRAPH_ATTRIBUTE_COMBINE_FUNCTION: - IGRAPH_CHECK(igraph_i_cattributes_sn_func(oldrec, newrec, merges, - todo_item.func.as_str)); - break; - case IGRAPH_ATTRIBUTE_COMBINE_SUM: - IGRAPH_ERROR("Cannot sum strings", IGRAPH_EATTRCOMBINE); - break; - case IGRAPH_ATTRIBUTE_COMBINE_PROD: - IGRAPH_ERROR("Cannot multiply strings", IGRAPH_EATTRCOMBINE); - break; - case IGRAPH_ATTRIBUTE_COMBINE_MIN: - IGRAPH_ERROR("Cannot find minimum of strings", - IGRAPH_EATTRCOMBINE); - break; - case IGRAPH_ATTRIBUTE_COMBINE_MAX: - IGRAPH_ERROR("Cannot find maximum of strings", - IGRAPH_EATTRCOMBINE); - break; - case IGRAPH_ATTRIBUTE_COMBINE_MEAN: - IGRAPH_ERROR("Cannot calculate mean of strings", - IGRAPH_EATTRCOMBINE); - break; - case IGRAPH_ATTRIBUTE_COMBINE_MEDIAN: - IGRAPH_ERROR("Cannot calculate median of strings", - IGRAPH_EATTRCOMBINE); - break; - case IGRAPH_ATTRIBUTE_COMBINE_RANDOM: - IGRAPH_CHECK(igraph_i_cattributes_sn_random(oldrec, newrec, merges)); - break; - case IGRAPH_ATTRIBUTE_COMBINE_FIRST: - IGRAPH_CHECK(igraph_i_cattributes_sn_first(oldrec, newrec, merges)); - break; - case IGRAPH_ATTRIBUTE_COMBINE_LAST: - IGRAPH_CHECK(igraph_i_cattributes_sn_last(oldrec, newrec, merges)); - break; - case IGRAPH_ATTRIBUTE_COMBINE_CONCAT: - IGRAPH_CHECK(igraph_i_cattributes_sn_concat(oldrec, newrec, merges)); - break; - default: - IGRAPH_ERROR("Unknown attribute_combination", - IGRAPH_UNIMPLEMENTED); - break; - } - } else { - IGRAPH_ERROR("Unknown attribute type, this should not happen", - IGRAPH_UNIMPLEMENTED); - } - - VECTOR(*new_val)[j] = newrec; - IGRAPH_FINALLY_CLEAN(2); /* newrec->name and newrec */ - - j++; - } - - IGRAPH_FREE(todo_items); - IGRAPH_FINALLY_CLEAN(2); - - return IGRAPH_SUCCESS; -} - -static igraph_error_t igraph_i_cattribute_add_edges_inner(igraph_t *graph, const igraph_vector_int_t *edges, - igraph_vector_ptr_t *nattr) { - - igraph_i_cattributes_t *attr = graph->attr; - igraph_vector_ptr_t *eal = &attr->eal; - igraph_integer_t ealno = igraph_vector_ptr_size(eal); - igraph_integer_t ne = igraph_vector_int_size(edges) / 2; - igraph_integer_t origlen = igraph_ecount(graph) - ne; - igraph_integer_t nattrno = nattr == 0 ? 0 : igraph_vector_ptr_size(nattr); - igraph_vector_int_t news; - igraph_integer_t newattrs, i; - - /* First add the new attributes if any */ - newattrs = 0; - IGRAPH_VECTOR_INT_INIT_FINALLY(&news, 0); - for (i = 0; i < nattrno; i++) { - igraph_attribute_record_t *nattr_entry = VECTOR(*nattr)[i]; - const char *nname = nattr_entry->name; - igraph_integer_t j; - igraph_bool_t l = igraph_i_cattribute_find(eal, nname, &j); - if (!l) { - newattrs++; - IGRAPH_CHECK(igraph_vector_int_push_back(&news, i)); - } else { - /* check types */ - if (nattr_entry->type != - ((igraph_attribute_record_t*)VECTOR(*eal)[j])->type) { - IGRAPH_ERROR("You cannot mix attribute types", IGRAPH_EINVAL); - } - } - } - - /* Add NaN/false/"" for the existing vertices for numeric, boolean and string attributes. */ - if (newattrs != 0) { - for (i = 0; i < newattrs; i++) { - igraph_attribute_record_t *tmp = VECTOR(*nattr)[ VECTOR(news)[i] ]; - igraph_attribute_record_t *newrec = IGRAPH_CALLOC(1, igraph_attribute_record_t); - igraph_attribute_type_t type = tmp->type; - if (!newrec) { - IGRAPH_ERROR("Cannot add attributes", IGRAPH_ENOMEM); /* LCOV_EXCL_LINE */ - } - IGRAPH_FINALLY(igraph_free, newrec); - newrec->type = type; - newrec->name = strdup(tmp->name); - if (!newrec->name) { - IGRAPH_ERROR("Cannot add attributes", IGRAPH_ENOMEM); /* LCOV_EXCL_LINE */ - } - IGRAPH_FINALLY(igraph_free, (char*)newrec->name); - if (type == IGRAPH_ATTRIBUTE_NUMERIC) { - igraph_vector_t *newnum = IGRAPH_CALLOC(1, igraph_vector_t); - if (!newnum) { - IGRAPH_ERROR("Cannot add attributes", IGRAPH_ENOMEM); /* LCOV_EXCL_LINE */ - } - IGRAPH_FINALLY(igraph_free, newnum); - IGRAPH_VECTOR_INIT_FINALLY(newnum, origlen); - newrec->value = newnum; - igraph_vector_fill(newnum, IGRAPH_NAN); - } else if (type == IGRAPH_ATTRIBUTE_BOOLEAN) { - igraph_vector_bool_t *newbool = IGRAPH_CALLOC(1, igraph_vector_bool_t); - if (!newbool) { - IGRAPH_ERROR("Cannot add attributes", IGRAPH_ENOMEM); /* LCOV_EXCL_LINE */ - } - IGRAPH_FINALLY(igraph_free, newbool); - IGRAPH_VECTOR_BOOL_INIT_FINALLY(newbool, origlen); - newrec->value = newbool; - igraph_vector_bool_fill(newbool, false); - } else if (type == IGRAPH_ATTRIBUTE_STRING) { - igraph_strvector_t *newstr = IGRAPH_CALLOC(1, igraph_strvector_t); - if (!newstr) { - IGRAPH_ERROR("Cannot add attributes", IGRAPH_ENOMEM); /* LCOV_EXCL_LINE */ - } - IGRAPH_FINALLY(igraph_free, newstr); - IGRAPH_STRVECTOR_INIT_FINALLY(newstr, origlen); - newrec->value = newstr; - } - IGRAPH_CHECK(igraph_vector_ptr_push_back(eal, newrec)); - IGRAPH_FINALLY_CLEAN(4); - } - ealno = igraph_vector_ptr_size(eal); - } - - /* Now append the new values */ - for (i = 0; i < ealno; i++) { - igraph_attribute_record_t *oldrec = VECTOR(*eal)[i]; - igraph_attribute_record_t *newrec = NULL; - const char *name = oldrec->name; - igraph_integer_t j = -1; - igraph_bool_t l = false; - if (nattr) { - l = igraph_i_cattribute_find(nattr, name, &j); - } - if (l) { - /* This attribute is present in nattr */ - igraph_vector_t *oldnum, *newnum; - igraph_strvector_t *oldstr, *newstr; - igraph_vector_bool_t *oldbool, *newbool; - newrec = VECTOR(*nattr)[j]; - oldnum = (igraph_vector_t*)oldrec->value; - newnum = (igraph_vector_t*)newrec->value; - oldstr = (igraph_strvector_t*)oldrec->value; - newstr = (igraph_strvector_t*)newrec->value; - oldbool = (igraph_vector_bool_t*)oldrec->value; - newbool = (igraph_vector_bool_t*)newrec->value; - if (oldrec->type != newrec->type) { - IGRAPH_ERROR("Attribute types do not match.", IGRAPH_EINVAL); - } - switch (oldrec->type) { - case IGRAPH_ATTRIBUTE_NUMERIC: - if (ne != igraph_vector_size(newnum)) { - IGRAPH_ERROR("Invalid numeric attribute length.", IGRAPH_EINVAL); - } - IGRAPH_CHECK(igraph_vector_append(oldnum, newnum)); - break; - case IGRAPH_ATTRIBUTE_STRING: - if (ne != igraph_strvector_size(newstr)) { - IGRAPH_ERROR("Invalid string attribute length.", IGRAPH_EINVAL); - } - IGRAPH_CHECK(igraph_strvector_append(oldstr, newstr)); - break; - case IGRAPH_ATTRIBUTE_BOOLEAN: - if (ne != igraph_vector_bool_size(newbool)) { - IGRAPH_ERROR("Invalid boolean attribute length.", IGRAPH_EINVAL); - } - IGRAPH_CHECK(igraph_vector_bool_append(oldbool, newbool)); - break; - default: - IGRAPH_WARNING("Invalid attribute type."); - break; - } - } else { - /* No such attribute, append NaN/false/"". */ - igraph_vector_t *oldnum = (igraph_vector_t *)oldrec->value; - igraph_strvector_t *oldstr = (igraph_strvector_t*)oldrec->value; - igraph_vector_bool_t *oldbool = (igraph_vector_bool_t *)oldrec->value; - switch (oldrec->type) { - case IGRAPH_ATTRIBUTE_NUMERIC: - IGRAPH_CHECK(igraph_vector_resize(oldnum, origlen + ne)); - for (j = origlen; j < origlen + ne; j++) { - VECTOR(*oldnum)[j] = IGRAPH_NAN; - } - break; - case IGRAPH_ATTRIBUTE_STRING: - IGRAPH_CHECK(igraph_strvector_resize(oldstr, origlen + ne)); - break; - case IGRAPH_ATTRIBUTE_BOOLEAN: - IGRAPH_CHECK(igraph_vector_bool_resize(oldbool, origlen + ne)); - for (j = origlen; j < origlen + ne; j++) { - VECTOR(*oldbool)[j] = 0; - } - break; - default: - IGRAPH_WARNING("Invalid attribute type"); - break; - } - } - } - - igraph_vector_int_destroy(&news); - IGRAPH_FINALLY_CLEAN(1); - - return IGRAPH_SUCCESS; -} - -static igraph_error_t igraph_i_cattribute_add_edges(igraph_t *graph, const igraph_vector_int_t *edges, - igraph_vector_ptr_t *nattr) { - /* Record information needed to restore attribute vector sizes */ - igraph_i_cattributes_t *attr = graph->attr; - igraph_vector_ptr_t *eal = &attr->eal; - igraph_integer_t ne = igraph_vector_int_size(edges) / 2; - igraph_integer_t origlen = igraph_ecount(graph) - ne; - - /* Attempt adding attributes */ - igraph_error_t err = igraph_i_cattribute_add_edges_inner(graph, edges, nattr); - if (err != IGRAPH_SUCCESS) { - /* If unsuccessful, revert attribute vector sizes. - * The following function assumes that all attributes vectors that - * are present have a length at least as great as origlen. - * This is true at the moment because any new attributes that are - * added to the graph are created directly at 'origlen' instead of - * being created at smaller sizes and resized later. - * - * NOTE: While this ensures that all attribute vector lengths are - * correct, it does not ensure that no extra attributes have - * been added to the graph. However, the presence of extra - * attributes does not make the attribute table inconsistent - * like the incorrect attribute vector lengths would. - */ - igraph_i_cattribute_revert_attribute_vector_sizes(eal, origlen); - } - return err; -} - -static igraph_error_t igraph_i_cattribute_permute_edges_in_place( - igraph_t *graph, const igraph_vector_int_t *idx -) { - igraph_i_cattributes_t *attr = graph->attr; - igraph_vector_ptr_t *eal = &attr->eal; - igraph_integer_t ealno = igraph_vector_ptr_size(eal); - igraph_integer_t i, j; - igraph_attribute_record_t *oldrec; - igraph_vector_t *num, *num_work; - igraph_strvector_t *str, str_work; - igraph_vector_bool_t *oldbool, *bool_work; - igraph_i_attribute_permutation_work_area_t work_area; - igraph_integer_t idx_size = igraph_vector_int_size(idx); - - /* shortcut: don't allocate anything if there are no attributes */ - if (ealno == 0) { - return IGRAPH_SUCCESS; - } - - IGRAPH_CHECK(igraph_i_attribute_permutation_work_area_init(&work_area, idx_size)); - IGRAPH_FINALLY(igraph_i_attribute_permutation_work_area_destroy, &work_area); - for (i = 0; i < ealno; i++) { - oldrec = VECTOR(*eal)[i]; - switch (oldrec->type) { - case IGRAPH_ATTRIBUTE_NUMERIC: - num = (igraph_vector_t*) oldrec->value; - IGRAPH_CHECK(igraph_vector_reserve(num, idx_size)); - IGRAPH_CHECK(igraph_i_attribute_permutation_work_area_alloc_for_numeric(&work_area)); - break; - - case IGRAPH_ATTRIBUTE_BOOLEAN: - oldbool = (igraph_vector_bool_t*) oldrec->value; - IGRAPH_CHECK(igraph_vector_bool_reserve(oldbool, idx_size)); - IGRAPH_CHECK(igraph_i_attribute_permutation_work_area_alloc_for_boolean(&work_area)); - break; - - case IGRAPH_ATTRIBUTE_STRING: - str = (igraph_strvector_t*) oldrec->value; - IGRAPH_CHECK(igraph_strvector_reserve(str, idx_size)); - IGRAPH_CHECK(igraph_i_attribute_permutation_work_area_alloc_for_strings(&work_area)); - break; - - default: - IGRAPH_WARNING("Unknown edge attribute ignored"); - } - } - - /* let's do string attributes first because these might need extra - * allocations that can fail. The strategy is to build new igraph_strvector_t - * instances for the permuted attributes and store them in an - * igraph_vector_ptr_t until we are done with all of them. If any of the - * allocations fail, we can destroy the igraph_vector_ptr_t safely */ - for (i = 0; i < ealno; i++) { - oldrec = VECTOR(*eal)[i]; - if (oldrec->type != IGRAPH_ATTRIBUTE_STRING) { - continue; - } - - str = (igraph_strvector_t*) oldrec->value; - IGRAPH_CHECK( - igraph_i_attribute_permutation_work_area_permute_and_store_strvector( - &work_area, str, idx - ) - ); - } - - /* strings are done, and now all vectors involved in the process are - * as large as they should be (or larger) so the operations below are not - * supposed to fail. We can safely replace the original string attribute - * vectors with the permuted ones, and then proceed to the remaining - * attributes */ - for (i = 0, j = 0; i < ealno; i++) { - oldrec = VECTOR(*eal)[i]; - if (oldrec->type != IGRAPH_ATTRIBUTE_STRING) { - continue; - } - - str = (igraph_strvector_t*) oldrec->value; - str_work = *((igraph_strvector_t*) VECTOR(*(work_area.strings))[j]); - *((igraph_strvector_t*) VECTOR(*(work_area.strings))[j]) = *str; - *str = str_work; - j++; - } - igraph_i_attribute_permutation_work_area_release_stored_strvectors(&work_area); - - /* now all vectors involved in the process are as large as they should be - * (or larger) so the operations below are not supposed to fail -- except - * for string operations that still do some extra allocations and we are - * not prepared for the failures of those. This must still be fixed. */ - for (i = 0; i < ealno; i++) { - oldrec = VECTOR(*eal)[i]; - switch (oldrec->type) { - case IGRAPH_ATTRIBUTE_NUMERIC: - num = (igraph_vector_t*) oldrec->value; - num_work = work_area.numeric; - IGRAPH_ASSERT(num_work != NULL); - IGRAPH_CHECK(igraph_vector_index(num, num_work, idx)); - work_area.numeric = num; - oldrec->value = num_work; - break; - case IGRAPH_ATTRIBUTE_BOOLEAN: - oldbool = (igraph_vector_bool_t*) oldrec->value; - bool_work = work_area.boolean; - IGRAPH_ASSERT(bool_work != NULL); - IGRAPH_CHECK(igraph_vector_bool_index(oldbool, bool_work, idx)); - work_area.boolean = oldbool; - oldrec->value = bool_work; - break; - case IGRAPH_ATTRIBUTE_STRING: - /* nothing to do */ - break; - default: - /* already warned */ - break; - } - } - - igraph_i_attribute_permutation_work_area_destroy(&work_area); - IGRAPH_FINALLY_CLEAN(1); - - return IGRAPH_SUCCESS; -} - -static igraph_error_t igraph_i_cattribute_permute_edges(const igraph_t *graph, - igraph_t *newgraph, - const igraph_vector_int_t *idx) { - - igraph_i_cattributes_t *attr = graph->attr, *new_attr = newgraph->attr; - igraph_vector_ptr_t *eal = &attr->eal, *new_eal = &new_attr->eal; - igraph_integer_t i, ealno; - - IGRAPH_ASSERT(graph == newgraph || igraph_vector_ptr_empty(new_eal)); - - if (graph == newgraph) { - return igraph_i_cattribute_permute_edges_in_place(newgraph, idx); - } - - /* New edge attributes */ - ealno = igraph_vector_ptr_size(eal); - IGRAPH_ASSERT(igraph_vector_ptr_empty(new_eal)); - IGRAPH_CHECK(igraph_vector_ptr_resize(new_eal, ealno)); - IGRAPH_FINALLY(igraph_i_cattribute_clear_attribute_container, new_eal); - - for (i = 0; i < ealno; i++) { - igraph_attribute_record_t *oldrec = VECTOR(*eal)[i]; - igraph_attribute_type_t type = oldrec->type; - igraph_vector_t *num, *newnum; - igraph_strvector_t *str, *newstr; - igraph_vector_bool_t *oldbool, *newbool; - - /* The record itself */ - igraph_attribute_record_t *new_rec = - IGRAPH_CALLOC(1, igraph_attribute_record_t); - if (!new_rec) { - IGRAPH_ERROR("Cannot create edge attributes", IGRAPH_ENOMEM); /* LCOV_EXCL_LINE */ - } - IGRAPH_FINALLY(igraph_free, new_rec); - new_rec->name = strdup(oldrec->name); - if (! new_rec->name) { - IGRAPH_ERROR("Cannot create edge attributes", IGRAPH_ENOMEM); /* LCOV_EXCL_LINE */ - } - IGRAPH_FINALLY(igraph_free, (char *) new_rec->name); - new_rec->type = oldrec->type; - - switch (type) { - case IGRAPH_ATTRIBUTE_NUMERIC: - num = (igraph_vector_t*) oldrec->value; - newnum = IGRAPH_CALLOC(1, igraph_vector_t); - if (!newnum) { - IGRAPH_ERROR("Cannot permute edge attributes", IGRAPH_ENOMEM); /* LCOV_EXCL_LINE */ - } - IGRAPH_FINALLY(igraph_free, newnum); - IGRAPH_VECTOR_INIT_FINALLY(newnum, 0); - IGRAPH_CHECK(igraph_vector_index(num, newnum, idx)); - new_rec->value = newnum; - break; - case IGRAPH_ATTRIBUTE_STRING: - str = (igraph_strvector_t*)oldrec->value; - newstr = IGRAPH_CALLOC(1, igraph_strvector_t); - if (!newstr) { - IGRAPH_ERROR("Cannot permute edge attributes", IGRAPH_ENOMEM); /* LCOV_EXCL_LINE */ - } - IGRAPH_FINALLY(igraph_free, newstr); - IGRAPH_STRVECTOR_INIT_FINALLY(newstr, 0); - IGRAPH_CHECK(igraph_strvector_index(str, newstr, idx)); - new_rec->value = newstr; - break; - case IGRAPH_ATTRIBUTE_BOOLEAN: - oldbool = (igraph_vector_bool_t*) oldrec->value; - newbool = IGRAPH_CALLOC(1, igraph_vector_bool_t); - if (!newbool) { - IGRAPH_ERROR("Cannot permute edge attributes", IGRAPH_ENOMEM); /* LCOV_EXCL_LINE */ - } - IGRAPH_FINALLY(igraph_free, newbool); - IGRAPH_VECTOR_BOOL_INIT_FINALLY(newbool, 0); - IGRAPH_CHECK(igraph_vector_bool_index(oldbool, newbool, idx)); - new_rec->value = newbool; - break; - default: - IGRAPH_WARNING("Unknown edge attribute ignored"); - } - VECTOR(*new_eal)[i] = new_rec; - IGRAPH_FINALLY_CLEAN(4); - } - IGRAPH_FINALLY_CLEAN(1); - - return IGRAPH_SUCCESS; -} + * \ref igraph_attribute_combination_add() . For the C attribute handler, the + * signature of the function depends on the type of the underlying attribute. + * For numeric attributes, use: + * \verbatim igraph_error_t function(const igraph_vector_t *input, igraph_real_t *output); \endverbatim + * where \p input will receive a vector containing the value of the attribute + * for all the vertices or edges being combined, and \p output must be filled + * by the function to the combined value. Similarly, for Boolean attributes, the + * function takes a boolean vector in \p input and must return the combined Boolean + * value in \p output: + * \verbatim igraph_error_t function(const igraph_vector_bool_t *input, igraph_bool_t *output); \endverbatim + * For string attributes, the signature is slightly different: + * \verbatim igraph_error_t function(const igraph_strvector_t *input, char **output); \endverbatim + * In case of strings, all strings in the input vector are \em owned by igraph + * and must not be modified or freed in the combination handler. The string + * returned to the caller in \p output remains owned by the caller; igraph will + * make a copy it and store the copy in the appropriate part of the data + * structure holding the vertex or edge attributes. + * + */ -static igraph_error_t igraph_i_cattribute_combine_edges(const igraph_t *graph, - igraph_t *newgraph, - const igraph_vector_int_list_t *merges, - const igraph_attribute_combination_t *comb) { +typedef struct { + igraph_attribute_combination_type_t type; + union { + igraph_function_pointer_t as_void; + igraph_cattributes_combine_num_t *as_num; + igraph_cattributes_combine_str_t *as_str; + igraph_cattributes_combine_bool_t *as_bool; + } func; +} igraph_attribute_combination_todo_item_t; - igraph_i_cattributes_t *attr = graph->attr; - igraph_i_cattributes_t *toattr = newgraph->attr; - igraph_vector_ptr_t *eal = &attr->eal; - igraph_vector_ptr_t *new_eal = &toattr->eal; - igraph_integer_t ealno = igraph_vector_ptr_size(eal); - igraph_integer_t i, j, keepno = 0; +static igraph_error_t igraph_i_cattribute_combine_attribute_record_lists( + igraph_attribute_record_list_t *attrs, igraph_attribute_record_list_t *new_attrs, + const igraph_vector_int_list_t *merges, const igraph_attribute_combination_t *comb +) { + igraph_integer_t no_attrs = igraph_attribute_record_list_size(attrs); + igraph_integer_t i, j, to_keep = 0; igraph_attribute_combination_todo_item_t *todo_items; - IGRAPH_ASSERT(graph != newgraph); - IGRAPH_ASSERT(igraph_vector_ptr_empty(new_eal)); + IGRAPH_ASSERT(attrs != new_attrs); + IGRAPH_ASSERT(igraph_attribute_record_list_empty(new_attrs)); - todo_items = IGRAPH_CALLOC(ealno, igraph_attribute_combination_todo_item_t); - if (!todo_items) { - IGRAPH_ERROR("Cannot combine edge attributes", IGRAPH_ENOMEM); /* LCOV_EXCL_LINE */ - } + todo_items = IGRAPH_CALLOC(no_attrs, igraph_attribute_combination_todo_item_t); + IGRAPH_CHECK_OOM(todo_items, "Cannot combine attributes"); IGRAPH_FINALLY(igraph_free, todo_items); - for (i = 0; i < ealno; i++) { - igraph_attribute_record_t *oldrec = VECTOR(*eal)[i]; + for (i = 0; i < no_attrs; i++) { + igraph_attribute_record_t *oldrec = igraph_attribute_record_list_get_ptr(attrs, i); const char *name = oldrec->name; - igraph_attribute_combination_type_t todo; + igraph_attribute_combination_type_t type; igraph_function_pointer_t voidfunc; - IGRAPH_CHECK(igraph_attribute_combination_query(comb, name, &todo, &voidfunc)); - todo_items[i].type = todo; + IGRAPH_CHECK(igraph_attribute_combination_query(comb, name, &type, &voidfunc)); + todo_items[i].type = type; todo_items[i].func.as_void = voidfunc; - if (todo != IGRAPH_ATTRIBUTE_COMBINE_IGNORE) { - keepno++; + if (type != IGRAPH_ATTRIBUTE_COMBINE_IGNORE) { + to_keep++; } } - IGRAPH_CHECK(igraph_vector_ptr_resize(new_eal, keepno)); - IGRAPH_FINALLY(igraph_i_cattribute_clear_attribute_container, new_eal); + IGRAPH_FINALLY(igraph_attribute_record_list_clear, new_attrs); - for (i = 0, j = 0; i < ealno; i++) { - igraph_attribute_record_t *newrec, *oldrec = VECTOR(*eal)[i]; + for (i = 0, j = 0; i < no_attrs; i++) { + igraph_attribute_record_t *oldrec = igraph_attribute_record_list_get_ptr(attrs, i); + igraph_attribute_record_t newrec; const char *name = oldrec->name; igraph_attribute_combination_todo_item_t todo_item = todo_items[i]; igraph_attribute_type_t attr_type = oldrec->type; @@ -2294,47 +1344,40 @@ static igraph_error_t igraph_i_cattribute_combine_edges(const igraph_t *graph, continue; } - newrec = IGRAPH_CALLOC(1, igraph_attribute_record_t); - if (!newrec) { - IGRAPH_ERROR("Cannot combine edge attributes", IGRAPH_ENOMEM); /* LCOV_EXCL_LINE */ - } - IGRAPH_FINALLY(igraph_free, newrec); - newrec->name = strdup(name); - if (! newrec->name) { - IGRAPH_ERROR("Cannot combine edge attributes", IGRAPH_ENOMEM); /* LCOV_EXCL_LINE */ - } - IGRAPH_FINALLY(igraph_free, (char *) newrec->name); - newrec->type = attr_type; + IGRAPH_CHECK(igraph_attribute_record_init(&newrec, name, attr_type)); + IGRAPH_FINALLY(igraph_attribute_record_destroy, &newrec); + + IGRAPH_CHECK(igraph_attribute_record_resize(&newrec, igraph_vector_int_list_size(merges))); if (attr_type == IGRAPH_ATTRIBUTE_NUMERIC) { switch (todo_item.type) { case IGRAPH_ATTRIBUTE_COMBINE_FUNCTION: - IGRAPH_CHECK(igraph_i_cattributes_cn_func(oldrec, newrec, merges, + IGRAPH_CHECK(igraph_i_cattributes_cn_func(oldrec, &newrec, merges, todo_item.func.as_num)); break; case IGRAPH_ATTRIBUTE_COMBINE_SUM: - IGRAPH_CHECK(igraph_i_cattributes_cn_sum(oldrec, newrec, merges)); + IGRAPH_CHECK(igraph_i_cattributes_cn_sum(oldrec, &newrec, merges)); break; case IGRAPH_ATTRIBUTE_COMBINE_PROD: - IGRAPH_CHECK(igraph_i_cattributes_cn_prod(oldrec, newrec, merges)); + IGRAPH_CHECK(igraph_i_cattributes_cn_prod(oldrec, &newrec, merges)); break; case IGRAPH_ATTRIBUTE_COMBINE_MIN: - IGRAPH_CHECK(igraph_i_cattributes_cn_min(oldrec, newrec, merges)); + IGRAPH_CHECK(igraph_i_cattributes_cn_min(oldrec, &newrec, merges)); break; case IGRAPH_ATTRIBUTE_COMBINE_MAX: - IGRAPH_CHECK(igraph_i_cattributes_cn_max(oldrec, newrec, merges)); + IGRAPH_CHECK(igraph_i_cattributes_cn_max(oldrec, &newrec, merges)); break; case IGRAPH_ATTRIBUTE_COMBINE_RANDOM: - IGRAPH_CHECK(igraph_i_cattributes_cn_random(oldrec, newrec, merges)); + IGRAPH_CHECK(igraph_i_cattributes_cn_random(oldrec, &newrec, merges)); break; case IGRAPH_ATTRIBUTE_COMBINE_FIRST: - IGRAPH_CHECK(igraph_i_cattributes_cn_first(oldrec, newrec, merges)); + IGRAPH_CHECK(igraph_i_cattributes_cn_first(oldrec, &newrec, merges)); break; case IGRAPH_ATTRIBUTE_COMBINE_LAST: - IGRAPH_CHECK(igraph_i_cattributes_cn_last(oldrec, newrec, merges)); + IGRAPH_CHECK(igraph_i_cattributes_cn_last(oldrec, &newrec, merges)); break; case IGRAPH_ATTRIBUTE_COMBINE_MEAN: - IGRAPH_CHECK(igraph_i_cattributes_cn_mean(oldrec, newrec, merges)); + IGRAPH_CHECK(igraph_i_cattributes_cn_mean(oldrec, &newrec, merges)); break; case IGRAPH_ATTRIBUTE_COMBINE_MEDIAN: IGRAPH_ERROR("Median calculation not implemented", @@ -2345,50 +1388,50 @@ static igraph_error_t igraph_i_cattribute_combine_edges(const igraph_t *graph, IGRAPH_EATTRCOMBINE); break; default: - IGRAPH_ERROR("Unknown attribute_combination", + IGRAPH_ERROR("Unknown attribute combination", IGRAPH_UNIMPLEMENTED); break; } } else if (attr_type == IGRAPH_ATTRIBUTE_BOOLEAN) { switch (todo_item.type) { case IGRAPH_ATTRIBUTE_COMBINE_FUNCTION: - IGRAPH_CHECK(igraph_i_cattributes_cb_func(oldrec, newrec, merges, + IGRAPH_CHECK(igraph_i_cattributes_cb_func(oldrec, &newrec, merges, todo_item.func.as_bool)); break; case IGRAPH_ATTRIBUTE_COMBINE_SUM: case IGRAPH_ATTRIBUTE_COMBINE_MAX: - IGRAPH_CHECK(igraph_i_cattributes_cb_any_is_true(oldrec, newrec, merges)); + IGRAPH_CHECK(igraph_i_cattributes_cb_any_is_true(oldrec, &newrec, merges)); break; case IGRAPH_ATTRIBUTE_COMBINE_PROD: case IGRAPH_ATTRIBUTE_COMBINE_MIN: - IGRAPH_CHECK(igraph_i_cattributes_cb_all_is_true(oldrec, newrec, merges)); + IGRAPH_CHECK(igraph_i_cattributes_cb_all_is_true(oldrec, &newrec, merges)); break; case IGRAPH_ATTRIBUTE_COMBINE_MEAN: case IGRAPH_ATTRIBUTE_COMBINE_MEDIAN: - IGRAPH_CHECK(igraph_i_cattributes_cb_majority(oldrec, newrec, merges)); + IGRAPH_CHECK(igraph_i_cattributes_cb_majority(oldrec, &newrec, merges)); break; case IGRAPH_ATTRIBUTE_COMBINE_RANDOM: - IGRAPH_CHECK(igraph_i_cattributes_cb_random(oldrec, newrec, merges)); + IGRAPH_CHECK(igraph_i_cattributes_cb_random(oldrec, &newrec, merges)); break; case IGRAPH_ATTRIBUTE_COMBINE_FIRST: - IGRAPH_CHECK(igraph_i_cattributes_cb_first(oldrec, newrec, merges)); + IGRAPH_CHECK(igraph_i_cattributes_cb_first(oldrec, &newrec, merges)); break; case IGRAPH_ATTRIBUTE_COMBINE_LAST: - IGRAPH_CHECK(igraph_i_cattributes_cb_last(oldrec, newrec, merges)); + IGRAPH_CHECK(igraph_i_cattributes_cb_last(oldrec, &newrec, merges)); break; case IGRAPH_ATTRIBUTE_COMBINE_CONCAT: IGRAPH_ERROR("Cannot calculate concatenation of Booleans", IGRAPH_EATTRCOMBINE); break; default: - IGRAPH_ERROR("Unknown attribute_combination", + IGRAPH_ERROR("Unknown attribute combination", IGRAPH_UNIMPLEMENTED); break; } } else if (attr_type == IGRAPH_ATTRIBUTE_STRING) { switch (todo_item.type) { case IGRAPH_ATTRIBUTE_COMBINE_FUNCTION: - IGRAPH_CHECK(igraph_i_cattributes_sn_func(oldrec, newrec, merges, + IGRAPH_CHECK(igraph_i_cattributes_cs_func(oldrec, &newrec, merges, todo_item.func.as_str)); break; case IGRAPH_ATTRIBUTE_COMBINE_SUM: @@ -2414,19 +1457,19 @@ static igraph_error_t igraph_i_cattribute_combine_edges(const igraph_t *graph, IGRAPH_EATTRCOMBINE); break; case IGRAPH_ATTRIBUTE_COMBINE_RANDOM: - IGRAPH_CHECK(igraph_i_cattributes_sn_random(oldrec, newrec, merges)); + IGRAPH_CHECK(igraph_i_cattributes_sn_random(oldrec, &newrec, merges)); break; case IGRAPH_ATTRIBUTE_COMBINE_FIRST: - IGRAPH_CHECK(igraph_i_cattributes_sn_first(oldrec, newrec, merges)); + IGRAPH_CHECK(igraph_i_cattributes_cs_first(oldrec, &newrec, merges)); break; case IGRAPH_ATTRIBUTE_COMBINE_LAST: - IGRAPH_CHECK(igraph_i_cattributes_sn_last(oldrec, newrec, merges)); + IGRAPH_CHECK(igraph_i_cattributes_cs_last(oldrec, &newrec, merges)); break; case IGRAPH_ATTRIBUTE_COMBINE_CONCAT: - IGRAPH_CHECK(igraph_i_cattributes_sn_concat(oldrec, newrec, merges)); + IGRAPH_CHECK(igraph_i_cattributes_cs_concat(oldrec, &newrec, merges)); break; default: - IGRAPH_ERROR("Unknown attribute_combination", + IGRAPH_ERROR("Unknown attribute combination", IGRAPH_UNIMPLEMENTED); break; } @@ -2435,10 +1478,8 @@ static igraph_error_t igraph_i_cattribute_combine_edges(const igraph_t *graph, IGRAPH_UNIMPLEMENTED); } - VECTOR(*new_eal)[j] = newrec; - IGRAPH_FINALLY_CLEAN(2); /* newrec and newrc->name */ - - j++; + IGRAPH_CHECK(igraph_attribute_record_list_push_back(new_attrs, &newrec)); + IGRAPH_FINALLY_CLEAN(1); /* ownership of newrec transferred */ } IGRAPH_FREE(todo_items); @@ -2447,6 +1488,49 @@ static igraph_error_t igraph_i_cattribute_combine_edges(const igraph_t *graph, return IGRAPH_SUCCESS; } +static igraph_error_t igraph_i_cattribute_combine_vertices( + const igraph_t *graph, igraph_t *newgraph, + const igraph_vector_int_list_t *merges, const igraph_attribute_combination_t *comb +) { + igraph_i_cattributes_t *attr = graph->attr; + igraph_i_cattributes_t *toattr = newgraph->attr; + return igraph_i_cattribute_combine_attribute_record_lists( + &attr->val, &toattr->val, merges, comb + ); +} + +static igraph_error_t igraph_i_cattribute_add_edges( + igraph_t *graph, const igraph_vector_int_t *edges, + const igraph_attribute_record_list_t *nattr +) { + igraph_integer_t ne = igraph_vector_int_size(edges) / 2; + igraph_i_cattributes_t *attr = graph->attr; + return igraph_i_cattribute_add_vertices_or_edges(&attr->eal, igraph_ecount(graph), ne, nattr); +} + +static igraph_error_t igraph_i_cattribute_permute_edges(const igraph_t *graph, + igraph_t *newgraph, + const igraph_vector_int_t *idx) { + igraph_i_cattributes_t *attr = graph->attr, *new_attr = newgraph->attr; + igraph_attribute_record_list_t *eal = &attr->eal, *new_eal = &new_attr->eal; + if (graph == newgraph) { + return igraph_i_cattribute_permute_attribute_record_list_in_place(eal, idx); + } else { + return igraph_i_cattribute_permute_attribute_record_list(eal, new_eal, idx); + } +} + +static igraph_error_t igraph_i_cattribute_combine_edges( + const igraph_t *graph, igraph_t *newgraph, + const igraph_vector_int_list_t *merges, const igraph_attribute_combination_t *comb +) { + igraph_i_cattributes_t *attr = graph->attr; + igraph_i_cattributes_t *toattr = newgraph->attr; + return igraph_i_cattribute_combine_attribute_record_lists( + &attr->eal, &toattr->eal, merges, comb + ); +} + static igraph_error_t igraph_i_cattribute_get_info(const igraph_t *graph, igraph_strvector_t *gnames, igraph_vector_int_t *gtypes, @@ -2458,14 +1542,14 @@ static igraph_error_t igraph_i_cattribute_get_info(const igraph_t *graph, igraph_strvector_t *names[3] = { gnames, vnames, enames }; igraph_vector_int_t *types[3] = { gtypes, vtypes, etypes }; igraph_i_cattributes_t *at = graph->attr; - igraph_vector_ptr_t *attr[3] = { &at->gal, &at->val, &at->eal }; + igraph_attribute_record_list_t *attr[3] = { &at->gal, &at->val, &at->eal }; igraph_integer_t i, j; for (i = 0; i < 3; i++) { igraph_strvector_t *n = names[i]; igraph_vector_int_t *t = types[i]; - igraph_vector_ptr_t *al = attr[i]; - igraph_integer_t len = igraph_vector_ptr_size(al); + igraph_attribute_record_list_t *al = attr[i]; + igraph_integer_t len = igraph_attribute_record_list_size(al); if (n) { IGRAPH_CHECK(igraph_strvector_resize(n, len)); @@ -2475,7 +1559,7 @@ static igraph_error_t igraph_i_cattribute_get_info(const igraph_t *graph, } for (j = 0; j < len; j++) { - igraph_attribute_record_t *rec = VECTOR(*al)[j]; + igraph_attribute_record_t *rec = igraph_attribute_record_list_get_ptr(al, j); const char *name = rec->name; igraph_attribute_type_t type = rec->type; if (n) { @@ -2494,134 +1578,95 @@ static igraph_bool_t igraph_i_cattribute_has_attr(const igraph_t *graph, igraph_attribute_elemtype_t type, const char *name) { igraph_i_cattributes_t *at = graph->attr; - igraph_vector_ptr_t *attr[3] = { &at->gal, &at->val, &at->eal }; - igraph_integer_t attrnum; - switch (type) { case IGRAPH_ATTRIBUTE_GRAPH: - attrnum = 0; - break; + return igraph_i_cattribute_find_index(&at->gal, name) >= 0; case IGRAPH_ATTRIBUTE_VERTEX: - attrnum = 1; - break; + return igraph_i_cattribute_find_index(&at->val, name) >= 0; case IGRAPH_ATTRIBUTE_EDGE: - attrnum = 2; - break; + return igraph_i_cattribute_find_index(&at->eal, name) >= 0; default: IGRAPH_ERROR("Unknown attribute element type", IGRAPH_EINVAL); break; } - return igraph_i_cattribute_find(attr[attrnum], name, 0); + return 0; } static igraph_error_t igraph_i_cattribute_gettype(const igraph_t *graph, igraph_attribute_type_t *type, igraph_attribute_elemtype_t elemtype, const char *name) { - igraph_integer_t attrnum; igraph_attribute_record_t *rec; igraph_i_cattributes_t *at = graph->attr; - igraph_vector_ptr_t *attr[3] = { &at->gal, &at->val, &at->eal }; - igraph_vector_ptr_t *al; - igraph_integer_t j; - igraph_bool_t l = false; + igraph_attribute_record_list_t *al; switch (elemtype) { case IGRAPH_ATTRIBUTE_GRAPH: - attrnum = 0; + al = &at->gal; break; case IGRAPH_ATTRIBUTE_VERTEX: - attrnum = 1; + al = &at->val; break; case IGRAPH_ATTRIBUTE_EDGE: - attrnum = 2; + al = &at->eal; break; default: IGRAPH_ERROR("Unknown attribute element type", IGRAPH_EINVAL); break; } - al = attr[attrnum]; - l = igraph_i_cattribute_find(al, name, &j); - if (!l) { - IGRAPH_ERROR("Unknown attribute", IGRAPH_EINVAL); - } - rec = VECTOR(*al)[j]; + IGRAPH_CHECK(igraph_i_cattribute_find_or_return(al, name, IGRAPH_ATTRIBUTE_UNSPECIFIED, &rec)); *type = rec->type; return IGRAPH_SUCCESS; } -static igraph_error_t igraph_i_cattribute_get_numeric_graph_attr(const igraph_t *graph, - const char *name, - igraph_vector_t *value) { +static igraph_error_t igraph_i_cattribute_get_numeric_graph_attr( + const igraph_t *graph, const char *name, igraph_vector_t *value +) { igraph_i_cattributes_t *attr = graph->attr; - igraph_vector_ptr_t *gal = &attr->gal; - igraph_integer_t j; + igraph_attribute_record_list_t *gal = &attr->gal; igraph_attribute_record_t *rec; igraph_vector_t *num; - igraph_bool_t l = igraph_i_cattribute_find(gal, name, &j); - if (!l) { - IGRAPH_ERRORF("The graph attribute '%s' does not exist.", IGRAPH_EINVAL, name); - } + IGRAPH_CHECK(igraph_i_cattribute_find_or_return(gal, name, IGRAPH_ATTRIBUTE_NUMERIC, &rec)); - rec = VECTOR(*gal)[j]; - if (rec->type != IGRAPH_ATTRIBUTE_NUMERIC) { - IGRAPH_ERRORF("Numeric graph attribute '%s' expected, got %s.", IGRAPH_EINVAL, name, attribute_type_name(rec->type)); - } - num = (igraph_vector_t*)rec->value; + num = rec->value.as_vector; IGRAPH_CHECK(igraph_vector_resize(value, 1)); VECTOR(*value)[0] = VECTOR(*num)[0]; return IGRAPH_SUCCESS; } -static igraph_error_t igraph_i_cattribute_get_bool_graph_attr(const igraph_t *graph, - const char *name, - igraph_vector_bool_t *value) { +static igraph_error_t igraph_i_cattribute_get_bool_graph_attr( + const igraph_t *graph, const char *name, igraph_vector_bool_t *value +) { igraph_i_cattributes_t *attr = graph->attr; - igraph_vector_ptr_t *gal = &attr->gal; - igraph_integer_t j; + igraph_attribute_record_list_t *gal = &attr->gal; igraph_attribute_record_t *rec; igraph_vector_bool_t *log; - igraph_bool_t l = igraph_i_cattribute_find(gal, name, &j); - if (!l) { - IGRAPH_ERRORF("The graph attribute '%s' does not exist.", IGRAPH_EINVAL, name); - } + IGRAPH_CHECK(igraph_i_cattribute_find_or_return(gal, name, IGRAPH_ATTRIBUTE_BOOLEAN, &rec)); - rec = VECTOR(*gal)[j]; - if (rec->type != IGRAPH_ATTRIBUTE_BOOLEAN) { - IGRAPH_ERRORF("Boolean graph attribute '%s' expected, got %s.", IGRAPH_EINVAL, name, attribute_type_name(rec->type)); - } - log = (igraph_vector_bool_t*)rec->value; + log = rec->value.as_vector_bool; IGRAPH_CHECK(igraph_vector_bool_resize(value, 1)); VECTOR(*value)[0] = VECTOR(*log)[0]; return IGRAPH_SUCCESS; } -static igraph_error_t igraph_i_cattribute_get_string_graph_attr(const igraph_t *graph, - const char *name, - igraph_strvector_t *value) { +static igraph_error_t igraph_i_cattribute_get_string_graph_attr( + const igraph_t *graph, const char *name, igraph_strvector_t *value +) { igraph_i_cattributes_t *attr = graph->attr; - igraph_vector_ptr_t *gal = &attr->gal; - igraph_integer_t j; + igraph_attribute_record_list_t *gal = &attr->gal; igraph_attribute_record_t *rec; igraph_strvector_t *str; - igraph_bool_t l = igraph_i_cattribute_find(gal, name, &j); - if (!l) { - IGRAPH_ERRORF("The graph attribute '%s' does not exist.", IGRAPH_EINVAL, name); - } + IGRAPH_CHECK(igraph_i_cattribute_find_or_return(gal, name, IGRAPH_ATTRIBUTE_STRING, &rec)); - rec = VECTOR(*gal)[j]; - if (rec->type != IGRAPH_ATTRIBUTE_STRING) { - IGRAPH_ERRORF("String graph attribute '%s' expected, got %s.", IGRAPH_EINVAL, name, attribute_type_name(rec->type)); - } - str = (igraph_strvector_t*)rec->value; + str = rec->value.as_strvector; IGRAPH_CHECK(igraph_strvector_resize(value, 1)); IGRAPH_CHECK(igraph_strvector_set(value, 0, igraph_strvector_get(str, 0))); @@ -2633,21 +1678,13 @@ static igraph_error_t igraph_i_cattribute_get_numeric_vertex_attr(const igraph_t igraph_vs_t vs, igraph_vector_t *value) { igraph_i_cattributes_t *attr = graph->attr; - igraph_vector_ptr_t *val = &attr->val; - igraph_integer_t j; + igraph_attribute_record_list_t *val = &attr->val; igraph_attribute_record_t *rec; igraph_vector_t *num; - igraph_bool_t l = igraph_i_cattribute_find(val, name, &j); - if (!l) { - IGRAPH_ERRORF("The vertex attribute '%s' does not exist.", IGRAPH_EINVAL, name); - } + IGRAPH_CHECK(igraph_i_cattribute_find_or_return(val, name, IGRAPH_ATTRIBUTE_NUMERIC, &rec)); - rec = VECTOR(*val)[j]; - if (rec->type != IGRAPH_ATTRIBUTE_NUMERIC) { - IGRAPH_ERRORF("Numeric vertex attribute '%s' expected, got %s.", IGRAPH_EINVAL, name, attribute_type_name(rec->type)); - } - num = (igraph_vector_t*)rec->value; + num = rec->value.as_vector; if (igraph_vs_is_all(&vs)) { igraph_vector_clear(value); IGRAPH_CHECK(igraph_vector_append(value, num)); @@ -2673,22 +1710,15 @@ static igraph_error_t igraph_i_cattribute_get_bool_vertex_attr(const igraph_t *g igraph_vs_t vs, igraph_vector_bool_t *value) { igraph_i_cattributes_t *attr = graph->attr; - igraph_vector_ptr_t *val = &attr->val; + igraph_attribute_record_list_t *val = &attr->val; igraph_vit_t it; - igraph_integer_t i, j, v; + igraph_integer_t i, v; igraph_attribute_record_t *rec; igraph_vector_bool_t *log; - igraph_bool_t l = igraph_i_cattribute_find(val, name, &j); - if (!l) { - IGRAPH_ERRORF("The vertex attribute '%s' does not exist.", IGRAPH_EINVAL, name); - } + IGRAPH_CHECK(igraph_i_cattribute_find_or_return(val, name, IGRAPH_ATTRIBUTE_BOOLEAN, &rec)); - rec = VECTOR(*val)[j]; - if (rec->type != IGRAPH_ATTRIBUTE_BOOLEAN) { - IGRAPH_ERRORF("Boolean vertex attribute '%s' expected, got %s.", IGRAPH_EINVAL, name, attribute_type_name(rec->type)); - } - log = (igraph_vector_bool_t*)rec->value; + log = rec->value.as_vector_bool; if (igraph_vs_is_all(&vs)) { igraph_vector_bool_clear(value); IGRAPH_CHECK(igraph_vector_bool_append(value, log)); @@ -2712,21 +1742,13 @@ static igraph_error_t igraph_i_cattribute_get_string_vertex_attr(const igraph_t igraph_vs_t vs, igraph_strvector_t *value) { igraph_i_cattributes_t *attr = graph->attr; - igraph_vector_ptr_t *val = &attr->val; - igraph_integer_t j; + igraph_attribute_record_list_t *val = &attr->val; igraph_attribute_record_t *rec; igraph_strvector_t *str; - igraph_bool_t l = igraph_i_cattribute_find(val, name, &j); - if (!l) { - IGRAPH_ERRORF("The vertex attribute '%s' does not exist.", IGRAPH_EINVAL, name); - } + IGRAPH_CHECK(igraph_i_cattribute_find_or_return(val, name, IGRAPH_ATTRIBUTE_STRING, &rec)); - rec = VECTOR(*val)[j]; - if (rec->type != IGRAPH_ATTRIBUTE_STRING) { - IGRAPH_ERRORF("String vertex attribute '%s' expected, got %s.", IGRAPH_EINVAL, name, attribute_type_name(rec->type)); - } - str = (igraph_strvector_t*)rec->value; + str = rec->value.as_strvector; if (igraph_vs_is_all(&vs)) { igraph_strvector_clear(value); IGRAPH_CHECK(igraph_strvector_append(value, str)); @@ -2748,26 +1770,17 @@ static igraph_error_t igraph_i_cattribute_get_string_vertex_attr(const igraph_t return IGRAPH_SUCCESS; } -static igraph_error_t igraph_i_cattribute_get_numeric_edge_attr(const igraph_t *graph, - const char *name, - igraph_es_t es, - igraph_vector_t *value) { +static igraph_error_t igraph_i_cattribute_get_numeric_edge_attr( + const igraph_t *graph, const char *name, igraph_es_t es, igraph_vector_t *value +) { igraph_i_cattributes_t *attr = graph->attr; - igraph_vector_ptr_t *eal = &attr->eal; - igraph_integer_t j; + igraph_attribute_record_list_t *eal = &attr->eal; igraph_attribute_record_t *rec; igraph_vector_t *num; - igraph_bool_t l = igraph_i_cattribute_find(eal, name, &j); - if (!l) { - IGRAPH_ERRORF("The edge attribute '%s' does not exist.", IGRAPH_EINVAL, name); - } + IGRAPH_CHECK(igraph_i_cattribute_find_or_return(eal, name, IGRAPH_ATTRIBUTE_NUMERIC, &rec)); - rec = VECTOR(*eal)[j]; - if (rec->type != IGRAPH_ATTRIBUTE_NUMERIC) { - IGRAPH_ERRORF("Numeric edge attribute '%s' expected, got %s.", IGRAPH_EINVAL, name, attribute_type_name(rec->type)); - } - num = (igraph_vector_t*)rec->value; + num = rec->value.as_vector; if (igraph_es_is_all(&es)) { igraph_vector_clear(value); IGRAPH_CHECK(igraph_vector_append(value, num)); @@ -2788,26 +1801,18 @@ static igraph_error_t igraph_i_cattribute_get_numeric_edge_attr(const igraph_t * return IGRAPH_SUCCESS; } -static igraph_error_t igraph_i_cattribute_get_string_edge_attr(const igraph_t *graph, - const char *name, - igraph_es_t es, - igraph_strvector_t *value) { +static igraph_error_t igraph_i_cattribute_get_string_edge_attr( + const igraph_t *graph, const char *name, igraph_es_t es, + igraph_strvector_t *value +) { igraph_i_cattributes_t *attr = graph->attr; - igraph_vector_ptr_t *eal = &attr->eal; - igraph_integer_t j; + igraph_attribute_record_list_t *eal = &attr->eal; igraph_attribute_record_t *rec; igraph_strvector_t *str; - igraph_bool_t l = igraph_i_cattribute_find(eal, name, &j); - if (!l) { - IGRAPH_ERRORF("The edge attribute '%s' does not exist.", IGRAPH_EINVAL, name); - } + IGRAPH_CHECK(igraph_i_cattribute_find_or_return(eal, name, IGRAPH_ATTRIBUTE_STRING, &rec)); - rec = VECTOR(*eal)[j]; - if (rec->type != IGRAPH_ATTRIBUTE_STRING) { - IGRAPH_ERRORF("String edge attribute '%s' expected, got %s.", IGRAPH_EINVAL, name, attribute_type_name(rec->type)); - } - str = (igraph_strvector_t*)rec->value; + str = rec->value.as_strvector; if (igraph_es_is_all(&es)) { igraph_strvector_clear(value); IGRAPH_CHECK(igraph_strvector_append(value, str)); @@ -2829,26 +1834,18 @@ static igraph_error_t igraph_i_cattribute_get_string_edge_attr(const igraph_t *g return IGRAPH_SUCCESS; } -static igraph_error_t igraph_i_cattribute_get_bool_edge_attr(const igraph_t *graph, - const char *name, - igraph_es_t es, - igraph_vector_bool_t *value) { +static igraph_error_t igraph_i_cattribute_get_bool_edge_attr( + const igraph_t *graph, const char *name, igraph_es_t es, + igraph_vector_bool_t *value +) { igraph_i_cattributes_t *attr = graph->attr; - igraph_vector_ptr_t *eal = &attr->eal; - igraph_integer_t j; + igraph_attribute_record_list_t *eal = &attr->eal; igraph_attribute_record_t *rec; igraph_vector_bool_t *log; - igraph_bool_t l = igraph_i_cattribute_find(eal, name, &j); - if (!l) { - IGRAPH_ERRORF("The edge attribute '%s' does not exist.", IGRAPH_EINVAL, name); - } + IGRAPH_CHECK(igraph_i_cattribute_find_or_return(eal, name, IGRAPH_ATTRIBUTE_BOOLEAN, &rec)); - rec = VECTOR(*eal)[j]; - if (rec->type != IGRAPH_ATTRIBUTE_BOOLEAN) { - IGRAPH_ERRORF("Boolean edge attribute '%s' expected, got %s.", IGRAPH_EINVAL, name, attribute_type_name(rec->type)); - } - log = (igraph_vector_bool_t*)rec->value; + log = rec->value.as_vector_bool; if (igraph_es_is_all(&es)) { igraph_vector_bool_clear(value); IGRAPH_CHECK(igraph_vector_bool_append(value, log)); @@ -2954,21 +1951,17 @@ const igraph_attribute_table_t igraph_cattribute_table = { * Time complexity: O(Ag), the number of graph attributes. */ igraph_real_t igraph_cattribute_GAN(const igraph_t *graph, const char *name) { - igraph_i_cattributes_t *attr = graph->attr; - igraph_vector_ptr_t *gal = &attr->gal; - igraph_integer_t j; igraph_attribute_record_t *rec; igraph_vector_t *num; - igraph_bool_t l = igraph_i_cattribute_find(gal, name, &j); - if (!l) { + rec = igraph_i_cattribute_find(&attr->gal, name, IGRAPH_ATTRIBUTE_NUMERIC); + if (!rec) { IGRAPH_WARNINGF("Graph attribute '%s' does not exist, returning default numeric attribute value.", name); return IGRAPH_NAN; } - rec = VECTOR(*gal)[j]; - num = (igraph_vector_t*)rec->value; + num = rec->value.as_vector; return VECTOR(*num)[0]; } @@ -2989,21 +1982,17 @@ igraph_real_t igraph_cattribute_GAN(const igraph_t *graph, const char *name) { * Time complexity: O(Ag), the number of graph attributes. */ igraph_bool_t igraph_cattribute_GAB(const igraph_t *graph, const char *name) { - igraph_i_cattributes_t *attr = graph->attr; - igraph_vector_ptr_t *gal = &attr->gal; - igraph_integer_t j; igraph_attribute_record_t *rec; igraph_vector_bool_t *log; - igraph_bool_t l = igraph_i_cattribute_find(gal, name, &j); - if (!l) { + rec = igraph_i_cattribute_find(&attr->gal, name, IGRAPH_ATTRIBUTE_BOOLEAN); + if (!rec) { IGRAPH_WARNINGF("Graph attribute '%s' does not exist, returning default boolean attribute value.", name); return false; } - rec = VECTOR(*gal)[j]; - log = (igraph_vector_bool_t*)rec->value; + log = rec->value.as_vector_bool; return VECTOR(*log)[0]; } @@ -3025,21 +2014,17 @@ igraph_bool_t igraph_cattribute_GAB(const igraph_t *graph, const char *name) { * Time complexity: O(Ag), the number of graph attributes. */ const char *igraph_cattribute_GAS(const igraph_t *graph, const char *name) { - igraph_i_cattributes_t *attr = graph->attr; - igraph_vector_ptr_t *gal = &attr->gal; - igraph_integer_t j; igraph_attribute_record_t *rec; igraph_strvector_t *str; - igraph_bool_t l = igraph_i_cattribute_find(gal, name, &j); - if (!l) { + rec = igraph_i_cattribute_find(&attr->gal, name, IGRAPH_ATTRIBUTE_STRING); + if (!rec) { IGRAPH_WARNINGF("Graph attribute '%s' does not exist, returning default string attribute value.", name); return ""; } - rec = VECTOR(*gal)[j]; - str = (igraph_strvector_t*)rec->value; + str = rec->value.as_strvector; return igraph_strvector_get(str, 0); } @@ -3063,19 +2048,16 @@ const char *igraph_cattribute_GAS(const igraph_t *graph, const char *name) { igraph_real_t igraph_cattribute_VAN(const igraph_t *graph, const char *name, igraph_integer_t vid) { igraph_i_cattributes_t *attr = graph->attr; - igraph_vector_ptr_t *val = &attr->val; - igraph_integer_t j; igraph_attribute_record_t *rec; igraph_vector_t *num; - igraph_bool_t l = igraph_i_cattribute_find(val, name, &j); - if (!l) { + rec = igraph_i_cattribute_find(&attr->val, name, IGRAPH_ATTRIBUTE_NUMERIC); + if (!rec) { IGRAPH_WARNINGF("Vertex attribute '%s' does not exist, returning default numeric attribute value.", name); return IGRAPH_NAN; } - rec = VECTOR(*val)[j]; - num = (igraph_vector_t*)rec->value; + num = rec->value.as_vector; return VECTOR(*num)[vid]; } @@ -3099,19 +2081,16 @@ igraph_real_t igraph_cattribute_VAN(const igraph_t *graph, const char *name, igraph_bool_t igraph_cattribute_VAB(const igraph_t *graph, const char *name, igraph_integer_t vid) { igraph_i_cattributes_t *attr = graph->attr; - igraph_vector_ptr_t *val = &attr->val; - igraph_integer_t j; igraph_attribute_record_t *rec; igraph_vector_bool_t *log; - igraph_bool_t l = igraph_i_cattribute_find(val, name, &j); - if (!l) { + rec = igraph_i_cattribute_find(&attr->val, name, IGRAPH_ATTRIBUTE_BOOLEAN); + if (!rec) { IGRAPH_WARNINGF("Vertex attribute '%s' does not exist, returning default boolean attribute value.", name); return false; } - rec = VECTOR(*val)[j]; - log = (igraph_vector_bool_t*)rec->value; + log = rec->value.as_vector_bool; return VECTOR(*log)[vid]; } @@ -3137,19 +2116,16 @@ igraph_bool_t igraph_cattribute_VAB(const igraph_t *graph, const char *name, const char *igraph_cattribute_VAS(const igraph_t *graph, const char *name, igraph_integer_t vid) { igraph_i_cattributes_t *attr = graph->attr; - igraph_vector_ptr_t *val = &attr->val; - igraph_integer_t j; igraph_attribute_record_t *rec; igraph_strvector_t *str; - igraph_bool_t l = igraph_i_cattribute_find(val, name, &j); - if (!l) { + rec = igraph_i_cattribute_find(&attr->val, name, IGRAPH_ATTRIBUTE_STRING); + if (!rec) { IGRAPH_WARNINGF("Vertex attribute '%s' does not exist, returning default string attribute value.", name); return ""; } - rec = VECTOR(*val)[j]; - str = (igraph_strvector_t*)rec->value; + str = rec->value.as_strvector; return igraph_strvector_get(str, vid); } @@ -3173,19 +2149,16 @@ const char *igraph_cattribute_VAS(const igraph_t *graph, const char *name, igraph_real_t igraph_cattribute_EAN(const igraph_t *graph, const char *name, igraph_integer_t eid) { igraph_i_cattributes_t *attr = graph->attr; - igraph_vector_ptr_t *eal = &attr->eal; - igraph_integer_t j; igraph_attribute_record_t *rec; igraph_vector_t *num; - igraph_bool_t l = igraph_i_cattribute_find(eal, name, &j); - if (!l) { + rec = igraph_i_cattribute_find(&attr->eal, name, IGRAPH_ATTRIBUTE_NUMERIC); + if (!rec) { IGRAPH_WARNINGF("Edge attribute '%s' does not exist, returning default numeric attribute value.", name); return IGRAPH_NAN; } - rec = VECTOR(*eal)[j]; - num = (igraph_vector_t*)rec->value; + num = rec->value.as_vector; return VECTOR(*num)[eid]; } @@ -3209,19 +2182,16 @@ igraph_real_t igraph_cattribute_EAN(const igraph_t *graph, const char *name, igraph_bool_t igraph_cattribute_EAB(const igraph_t *graph, const char *name, igraph_integer_t eid) { igraph_i_cattributes_t *attr = graph->attr; - igraph_vector_ptr_t *eal = &attr->eal; - igraph_integer_t j; igraph_attribute_record_t *rec; igraph_vector_bool_t *log; - igraph_bool_t l = igraph_i_cattribute_find(eal, name, &j); - if (!l) { + rec = igraph_i_cattribute_find(&attr->eal, name, IGRAPH_ATTRIBUTE_BOOLEAN); + if (!rec) { IGRAPH_WARNINGF("Edge attribute '%s' does not exist, returning default boolean attribute value.", name); return false; } - rec = VECTOR(*eal)[j]; - log = (igraph_vector_bool_t*)rec->value; + log = rec->value.as_vector_bool; return VECTOR(*log)[eid]; } @@ -3247,19 +2217,16 @@ igraph_bool_t igraph_cattribute_EAB(const igraph_t *graph, const char *name, const char *igraph_cattribute_EAS(const igraph_t *graph, const char *name, igraph_integer_t eid) { igraph_i_cattributes_t *attr = graph->attr; - igraph_vector_ptr_t *eal = &attr->eal; - igraph_integer_t j; igraph_attribute_record_t *rec; igraph_strvector_t *str; - igraph_bool_t l = igraph_i_cattribute_find(eal, name, &j); - if (!l) { + rec = igraph_i_cattribute_find(&attr->eal, name, IGRAPH_ATTRIBUTE_STRING); + if (!rec) { IGRAPH_WARNINGF("Edge attribute '%s' does not exist, returning default string attribute value.", name); return ""; } - rec = VECTOR(*eal)[j]; - str = (igraph_strvector_t*)rec->value; + str = rec->value.as_strvector; return igraph_strvector_get(str, eid); } @@ -3279,9 +2246,7 @@ const char *igraph_cattribute_EAS(const igraph_t *graph, const char *name, igraph_error_t igraph_cattribute_VANV(const igraph_t *graph, const char *name, igraph_vs_t vids, igraph_vector_t *result) { - - return igraph_i_cattribute_get_numeric_vertex_attr(graph, name, vids, - result); + return igraph_i_cattribute_get_numeric_vertex_attr(graph, name, vids, result); } /** @@ -3300,9 +2265,7 @@ igraph_error_t igraph_cattribute_VANV(const igraph_t *graph, const char *name, igraph_error_t igraph_cattribute_VABV(const igraph_t *graph, const char *name, igraph_vs_t vids, igraph_vector_bool_t *result) { - - return igraph_i_cattribute_get_bool_vertex_attr(graph, name, vids, - result); + return igraph_i_cattribute_get_bool_vertex_attr(graph, name, vids, result); } /** @@ -3321,9 +2284,7 @@ igraph_error_t igraph_cattribute_VABV(const igraph_t *graph, const char *name, igraph_error_t igraph_cattribute_EANV(const igraph_t *graph, const char *name, igraph_es_t eids, igraph_vector_t *result) { - - return igraph_i_cattribute_get_numeric_edge_attr(graph, name, eids, - result); + return igraph_i_cattribute_get_numeric_edge_attr(graph, name, eids, result); } /** @@ -3342,9 +2303,7 @@ igraph_error_t igraph_cattribute_EANV(const igraph_t *graph, const char *name, igraph_error_t igraph_cattribute_EABV(const igraph_t *graph, const char *name, igraph_es_t eids, igraph_vector_bool_t *result) { - - return igraph_i_cattribute_get_bool_edge_attr(graph, name, eids, - result); + return igraph_i_cattribute_get_bool_edge_attr(graph, name, eids, result); } /** @@ -3364,9 +2323,7 @@ igraph_error_t igraph_cattribute_EABV(const igraph_t *graph, const char *name, igraph_error_t igraph_cattribute_VASV(const igraph_t *graph, const char *name, igraph_vs_t vids, igraph_strvector_t *result) { - - return igraph_i_cattribute_get_string_vertex_attr(graph, name, vids, - result); + return igraph_i_cattribute_get_string_vertex_attr(graph, name, vids, result); } /** @@ -3386,9 +2343,7 @@ igraph_error_t igraph_cattribute_VASV(const igraph_t *graph, const char *name, igraph_error_t igraph_cattribute_EASV(const igraph_t *graph, const char *name, igraph_es_t eids, igraph_strvector_t *result) { - - return igraph_i_cattribute_get_string_edge_attr(graph, name, eids, - result); + return igraph_i_cattribute_get_string_edge_attr(graph, name, eids, result); } /** @@ -3454,44 +2409,16 @@ igraph_bool_t igraph_cattribute_has_attr(const igraph_t *graph, */ igraph_error_t igraph_cattribute_GAN_set(igraph_t *graph, const char *name, igraph_real_t value) { - igraph_i_cattributes_t *attr = graph->attr; - igraph_vector_ptr_t *gal = &attr->gal; - igraph_integer_t j; - igraph_bool_t l = igraph_i_cattribute_find(gal, name, &j); - - if (l) { - igraph_attribute_record_t *rec = VECTOR(*gal)[j]; - if (rec->type != IGRAPH_ATTRIBUTE_NUMERIC) { - IGRAPH_ERROR("Invalid attribute type", IGRAPH_EINVAL); - } else { - igraph_vector_t *num = (igraph_vector_t *)rec->value; - VECTOR(*num)[0] = value; - } - } else { - igraph_attribute_record_t *rec = IGRAPH_CALLOC(1, igraph_attribute_record_t); - igraph_vector_t *num; - if (!rec) { - IGRAPH_ERROR("Cannot add graph attribute", IGRAPH_ENOMEM); /* LCOV_EXCL_LINE */ - } - IGRAPH_FINALLY(igraph_free, rec); - rec->name = strdup(name); - if (!rec->name) { - IGRAPH_ERROR("Cannot add graph attribute", IGRAPH_ENOMEM); /* LCOV_EXCL_LINE */ - } - IGRAPH_FINALLY(igraph_free, (char*)rec->name); - rec->type = IGRAPH_ATTRIBUTE_NUMERIC; - num = IGRAPH_CALLOC(1, igraph_vector_t); - if (!num) { - IGRAPH_ERROR("Cannot add graph attribute", IGRAPH_ENOMEM); /* LCOV_EXCL_LINE */ - } - IGRAPH_FINALLY(igraph_free, num); - IGRAPH_VECTOR_INIT_FINALLY(num, 1); - VECTOR(*num)[0] = value; - rec->value = num; - IGRAPH_CHECK(igraph_vector_ptr_push_back(gal, rec)); - IGRAPH_FINALLY_CLEAN(4); - } + igraph_attribute_record_t *rec; + igraph_vector_t *num; + + IGRAPH_CHECK(igraph_i_cattribute_find_or_create( + &attr->gal, name, IGRAPH_ATTRIBUTE_NUMERIC, 1, &rec + )); + + num = rec->value.as_vector; + VECTOR(*num)[0] = value; return IGRAPH_SUCCESS; } @@ -3512,44 +2439,16 @@ igraph_error_t igraph_cattribute_GAN_set(igraph_t *graph, const char *name, */ igraph_error_t igraph_cattribute_GAB_set(igraph_t *graph, const char *name, igraph_bool_t value) { - igraph_i_cattributes_t *attr = graph->attr; - igraph_vector_ptr_t *gal = &attr->gal; - igraph_integer_t j; - igraph_bool_t l = igraph_i_cattribute_find(gal, name, &j); - - if (l) { - igraph_attribute_record_t *rec = VECTOR(*gal)[j]; - if (rec->type != IGRAPH_ATTRIBUTE_BOOLEAN) { - IGRAPH_ERROR("Invalid attribute type", IGRAPH_EINVAL); - } else { - igraph_vector_bool_t *log = (igraph_vector_bool_t *)rec->value; - VECTOR(*log)[0] = value; - } - } else { - igraph_attribute_record_t *rec = IGRAPH_CALLOC(1, igraph_attribute_record_t); - igraph_vector_bool_t *log; - if (!rec) { - IGRAPH_ERROR("Cannot add graph attribute", IGRAPH_ENOMEM); /* LCOV_EXCL_LINE */ - } - IGRAPH_FINALLY(igraph_free, rec); - rec->name = strdup(name); - if (!rec->name) { - IGRAPH_ERROR("Cannot add graph attribute", IGRAPH_ENOMEM); /* LCOV_EXCL_LINE */ - } - IGRAPH_FINALLY(igraph_free, (char*)rec->name); - rec->type = IGRAPH_ATTRIBUTE_BOOLEAN; - log = IGRAPH_CALLOC(1, igraph_vector_bool_t); - if (!log) { - IGRAPH_ERROR("Cannot add graph attribute", IGRAPH_ENOMEM); /* LCOV_EXCL_LINE */ - } - IGRAPH_FINALLY(igraph_free, log); - IGRAPH_VECTOR_BOOL_INIT_FINALLY(log, 1); - VECTOR(*log)[0] = value; - rec->value = log; - IGRAPH_CHECK(igraph_vector_ptr_push_back(gal, rec)); - IGRAPH_FINALLY_CLEAN(4); - } + igraph_attribute_record_t *rec; + igraph_vector_bool_t *log; + + IGRAPH_CHECK(igraph_i_cattribute_find_or_create( + &attr->gal, name, IGRAPH_ATTRIBUTE_BOOLEAN, 1, &rec + )); + + log = rec->value.as_vector_bool; + VECTOR(*log)[0] = value; return IGRAPH_SUCCESS; } @@ -3571,44 +2470,16 @@ igraph_error_t igraph_cattribute_GAB_set(igraph_t *graph, const char *name, */ igraph_error_t igraph_cattribute_GAS_set(igraph_t *graph, const char *name, const char *value) { - igraph_i_cattributes_t *attr = graph->attr; - igraph_vector_ptr_t *gal = &attr->gal; - igraph_integer_t j; - igraph_bool_t l = igraph_i_cattribute_find(gal, name, &j); - - if (l) { - igraph_attribute_record_t *rec = VECTOR(*gal)[j]; - if (rec->type != IGRAPH_ATTRIBUTE_STRING) { - IGRAPH_ERROR("Invalid attribute type", IGRAPH_EINVAL); - } else { - igraph_strvector_t *str = (igraph_strvector_t*)rec->value; - IGRAPH_CHECK(igraph_strvector_set(str, 0, value)); - } - } else { - igraph_attribute_record_t *rec = IGRAPH_CALLOC(1, igraph_attribute_record_t); - igraph_strvector_t *str; - if (!rec) { - IGRAPH_ERROR("Cannot add graph attribute", IGRAPH_ENOMEM); /* LCOV_EXCL_LINE */ - } - IGRAPH_FINALLY(igraph_free, rec); - rec->name = strdup(name); - if (!rec->name) { - IGRAPH_ERROR("Cannot add graph attribute", IGRAPH_ENOMEM); /* LCOV_EXCL_LINE */ - } - IGRAPH_FINALLY(igraph_free, (char*)rec->name); - rec->type = IGRAPH_ATTRIBUTE_STRING; - str = IGRAPH_CALLOC(1, igraph_strvector_t); - if (!str) { - IGRAPH_ERROR("Cannot add graph attribute", IGRAPH_ENOMEM); /* LCOV_EXCL_LINE */ - } - IGRAPH_FINALLY(igraph_free, str); - IGRAPH_STRVECTOR_INIT_FINALLY(str, 1); - IGRAPH_CHECK(igraph_strvector_set(str, 0, value)); - rec->value = str; - IGRAPH_CHECK(igraph_vector_ptr_push_back(gal, rec)); - IGRAPH_FINALLY_CLEAN(4); - } + igraph_attribute_record_t *rec; + igraph_strvector_t *str; + + IGRAPH_CHECK(igraph_i_cattribute_find_or_create( + &attr->gal, name, IGRAPH_ATTRIBUTE_STRING, 1, &rec + )); + + str = rec->value.as_strvector; + IGRAPH_CHECK(igraph_strvector_set(str, 0, value)); return IGRAPH_SUCCESS; } @@ -3633,45 +2504,13 @@ igraph_error_t igraph_cattribute_GAS_set(igraph_t *graph, const char *name, */ igraph_error_t igraph_cattribute_VAN_set(igraph_t *graph, const char *name, igraph_integer_t vid, igraph_real_t value) { - igraph_i_cattributes_t *attr = graph->attr; - igraph_vector_ptr_t *val = &attr->val; - igraph_integer_t j; - igraph_bool_t l = igraph_i_cattribute_find(val, name, &j); - - if (l) { - igraph_attribute_record_t *rec = VECTOR(*val)[j]; - if (rec->type != IGRAPH_ATTRIBUTE_NUMERIC) { - IGRAPH_ERROR("Invalid attribute type", IGRAPH_EINVAL); - } else { - igraph_vector_t *num = (igraph_vector_t*)rec->value; - VECTOR(*num)[vid] = value; - } - } else { - igraph_attribute_record_t *rec = IGRAPH_CALLOC(1, igraph_attribute_record_t); - igraph_vector_t *num; - if (!rec) { - IGRAPH_ERROR("Cannot add vertex attribute", IGRAPH_ENOMEM); /* LCOV_EXCL_LINE */ - } - IGRAPH_FINALLY(igraph_free, rec); - rec->name = strdup(name); - if (!rec->name) { - IGRAPH_ERROR("Cannot add vertex attribute", IGRAPH_ENOMEM); /* LCOV_EXCL_LINE */ - } - IGRAPH_FINALLY(igraph_free, (char*)rec->name); - rec->type = IGRAPH_ATTRIBUTE_NUMERIC; - num = IGRAPH_CALLOC(1, igraph_vector_t); - if (!num) { - IGRAPH_ERROR("Cannot add vertex attribute", IGRAPH_ENOMEM); /* LCOV_EXCL_LINE */ - } - IGRAPH_FINALLY(igraph_free, num); - IGRAPH_VECTOR_INIT_FINALLY(num, igraph_vcount(graph)); - igraph_vector_fill(num, IGRAPH_NAN); - VECTOR(*num)[vid] = value; - rec->value = num; - IGRAPH_CHECK(igraph_vector_ptr_push_back(val, rec)); - IGRAPH_FINALLY_CLEAN(4); - } + igraph_attribute_record_t *rec; + + IGRAPH_CHECK(igraph_i_cattribute_find_or_create( + &attr->val, name, IGRAPH_ATTRIBUTE_NUMERIC, igraph_vcount(graph), &rec + )); + VECTOR(*rec->value.as_vector)[vid] = value; return IGRAPH_SUCCESS; } @@ -3696,45 +2535,13 @@ igraph_error_t igraph_cattribute_VAN_set(igraph_t *graph, const char *name, */ igraph_error_t igraph_cattribute_VAB_set(igraph_t *graph, const char *name, igraph_integer_t vid, igraph_bool_t value) { - igraph_i_cattributes_t *attr = graph->attr; - igraph_vector_ptr_t *val = &attr->val; - igraph_integer_t j; - igraph_bool_t l = igraph_i_cattribute_find(val, name, &j); - - if (l) { - igraph_attribute_record_t *rec = VECTOR(*val)[j]; - if (rec->type != IGRAPH_ATTRIBUTE_BOOLEAN) { - IGRAPH_ERROR("Invalid attribute type", IGRAPH_EINVAL); - } else { - igraph_vector_bool_t *log = (igraph_vector_bool_t*)rec->value; - VECTOR(*log)[vid] = value; - } - } else { - igraph_attribute_record_t *rec = IGRAPH_CALLOC(1, igraph_attribute_record_t); - igraph_vector_bool_t *log; - if (!rec) { - IGRAPH_ERROR("Cannot add vertex attribute", IGRAPH_ENOMEM); /* LCOV_EXCL_LINE */ - } - IGRAPH_FINALLY(igraph_free, rec); - rec->name = strdup(name); - if (!rec->name) { - IGRAPH_ERROR("Cannot add vertex attribute", IGRAPH_ENOMEM); /* LCOV_EXCL_LINE */ - } - IGRAPH_FINALLY(igraph_free, (char*)rec->name); - rec->type = IGRAPH_ATTRIBUTE_BOOLEAN; - log = IGRAPH_CALLOC(1, igraph_vector_bool_t); - if (!log) { - IGRAPH_ERROR("Cannot add vertex attribute", IGRAPH_ENOMEM); /* LCOV_EXCL_LINE */ - } - IGRAPH_FINALLY(igraph_free, log); - IGRAPH_VECTOR_BOOL_INIT_FINALLY(log, igraph_vcount(graph)); - igraph_vector_bool_fill(log, false); - VECTOR(*log)[vid] = value; - rec->value = log; - IGRAPH_CHECK(igraph_vector_ptr_push_back(val, rec)); - IGRAPH_FINALLY_CLEAN(4); - } + igraph_attribute_record_t *rec; + + IGRAPH_CHECK(igraph_i_cattribute_find_or_create( + &attr->val, name, IGRAPH_ATTRIBUTE_BOOLEAN, igraph_vcount(graph), &rec + )); + VECTOR(*rec->value.as_vector_bool)[vid] = value; return IGRAPH_SUCCESS; } @@ -3760,44 +2567,13 @@ igraph_error_t igraph_cattribute_VAB_set(igraph_t *graph, const char *name, */ igraph_error_t igraph_cattribute_VAS_set(igraph_t *graph, const char *name, igraph_integer_t vid, const char *value) { - igraph_i_cattributes_t *attr = graph->attr; - igraph_vector_ptr_t *val = &attr->val; - igraph_integer_t j; - igraph_bool_t l = igraph_i_cattribute_find(val, name, &j); - - if (l) { - igraph_attribute_record_t *rec = VECTOR(*val)[j]; - if (rec->type != IGRAPH_ATTRIBUTE_STRING) { - IGRAPH_ERROR("Invalid attribute type", IGRAPH_EINVAL); - } else { - igraph_strvector_t *str = (igraph_strvector_t*)rec->value; - IGRAPH_CHECK(igraph_strvector_set(str, vid, value)); - } - } else { - igraph_attribute_record_t *rec = IGRAPH_CALLOC(1, igraph_attribute_record_t); - igraph_strvector_t *str; - if (!rec) { - IGRAPH_ERROR("Cannot add vertex attribute", IGRAPH_ENOMEM); /* LCOV_EXCL_LINE */ - } - IGRAPH_FINALLY(igraph_free, rec); - rec->name = strdup(name); - if (!rec->name) { - IGRAPH_ERROR("Cannot add vertex attribute", IGRAPH_ENOMEM); /* LCOV_EXCL_LINE */ - } - IGRAPH_FINALLY(igraph_free, (char*)rec->name); - rec->type = IGRAPH_ATTRIBUTE_STRING; - str = IGRAPH_CALLOC(1, igraph_strvector_t); - if (!str) { - IGRAPH_ERROR("Cannot add vertex attribute", IGRAPH_ENOMEM); /* LCOV_EXCL_LINE */ - } - IGRAPH_FINALLY(igraph_free, str); - IGRAPH_STRVECTOR_INIT_FINALLY(str, igraph_vcount(graph)); - IGRAPH_CHECK(igraph_strvector_set(str, vid, value)); - rec->value = str; - IGRAPH_CHECK(igraph_vector_ptr_push_back(val, rec)); - IGRAPH_FINALLY_CLEAN(4); - } + igraph_attribute_record_t *rec; + + IGRAPH_CHECK(igraph_i_cattribute_find_or_create( + &attr->val, name, IGRAPH_ATTRIBUTE_STRING, igraph_vcount(graph), &rec + )); + IGRAPH_CHECK(igraph_strvector_set(rec->value.as_strvector, vid, value)); return IGRAPH_SUCCESS; } @@ -3822,45 +2598,13 @@ igraph_error_t igraph_cattribute_VAS_set(igraph_t *graph, const char *name, */ igraph_error_t igraph_cattribute_EAN_set(igraph_t *graph, const char *name, igraph_integer_t eid, igraph_real_t value) { - igraph_i_cattributes_t *attr = graph->attr; - igraph_vector_ptr_t *eal = &attr->eal; - igraph_integer_t j; - igraph_bool_t l = igraph_i_cattribute_find(eal, name, &j); - - if (l) { - igraph_attribute_record_t *rec = VECTOR(*eal)[j]; - if (rec->type != IGRAPH_ATTRIBUTE_NUMERIC) { - IGRAPH_ERROR("Invalid attribute type", IGRAPH_EINVAL); - } else { - igraph_vector_t *num = (igraph_vector_t*)rec->value; - VECTOR(*num)[eid] = value; - } - } else { - igraph_attribute_record_t *rec = IGRAPH_CALLOC(1, igraph_attribute_record_t); - igraph_vector_t *num; - if (!rec) { - IGRAPH_ERROR("Cannot add edge attribute", IGRAPH_ENOMEM); /* LCOV_EXCL_LINE */ - } - IGRAPH_FINALLY(igraph_free, rec); - rec->name = strdup(name); - if (!rec->name) { - IGRAPH_ERROR("Cannot add edge attribute", IGRAPH_ENOMEM); /* LCOV_EXCL_LINE */ - } - IGRAPH_FINALLY(igraph_free, (char*)rec->name); - rec->type = IGRAPH_ATTRIBUTE_NUMERIC; - num = IGRAPH_CALLOC(1, igraph_vector_t); - if (!num) { - IGRAPH_ERROR("Cannot add edge attribute", IGRAPH_ENOMEM); /* LCOV_EXCL_LINE */ - } - IGRAPH_FINALLY(igraph_free, num); - IGRAPH_VECTOR_INIT_FINALLY(num, igraph_ecount(graph)); - igraph_vector_fill(num, IGRAPH_NAN); - VECTOR(*num)[eid] = value; - rec->value = num; - IGRAPH_CHECK(igraph_vector_ptr_push_back(eal, rec)); - IGRAPH_FINALLY_CLEAN(4); - } + igraph_attribute_record_t *rec; + + IGRAPH_CHECK(igraph_i_cattribute_find_or_create( + &attr->eal, name, IGRAPH_ATTRIBUTE_NUMERIC, igraph_ecount(graph), &rec + )); + VECTOR(*rec->value.as_vector)[eid] = value; return IGRAPH_SUCCESS; } @@ -3885,45 +2629,13 @@ igraph_error_t igraph_cattribute_EAN_set(igraph_t *graph, const char *name, */ igraph_error_t igraph_cattribute_EAB_set(igraph_t *graph, const char *name, igraph_integer_t eid, igraph_bool_t value) { - igraph_i_cattributes_t *attr = graph->attr; - igraph_vector_ptr_t *eal = &attr->eal; - igraph_integer_t j; - igraph_bool_t l = igraph_i_cattribute_find(eal, name, &j); - - if (l) { - igraph_attribute_record_t *rec = VECTOR(*eal)[j]; - if (rec->type != IGRAPH_ATTRIBUTE_BOOLEAN) { - IGRAPH_ERROR("Invalid attribute type", IGRAPH_EINVAL); - } else { - igraph_vector_bool_t *log = (igraph_vector_bool_t*)rec->value; - VECTOR(*log)[eid] = value; - } - } else { - igraph_attribute_record_t *rec = IGRAPH_CALLOC(1, igraph_attribute_record_t); - igraph_vector_bool_t *log; - if (!rec) { - IGRAPH_ERROR("Cannot add edge attribute", IGRAPH_ENOMEM); /* LCOV_EXCL_LINE */ - } - IGRAPH_FINALLY(igraph_free, rec); - rec->name = strdup(name); - if (!rec->name) { - IGRAPH_ERROR("Cannot add edge attribute", IGRAPH_ENOMEM); /* LCOV_EXCL_LINE */ - } - IGRAPH_FINALLY(igraph_free, (char*)rec->name); - rec->type = IGRAPH_ATTRIBUTE_BOOLEAN; - log = IGRAPH_CALLOC(1, igraph_vector_bool_t); - if (!log) { - IGRAPH_ERROR("Cannot add edge attribute", IGRAPH_ENOMEM); /* LCOV_EXCL_LINE */ - } - IGRAPH_FINALLY(igraph_free, log); - IGRAPH_VECTOR_BOOL_INIT_FINALLY(log, igraph_ecount(graph)); - igraph_vector_bool_fill(log, false); - VECTOR(*log)[eid] = value; - rec->value = log; - IGRAPH_CHECK(igraph_vector_ptr_push_back(eal, rec)); - IGRAPH_FINALLY_CLEAN(4); - } + igraph_attribute_record_t *rec; + + IGRAPH_CHECK(igraph_i_cattribute_find_or_create( + &attr->eal, name, IGRAPH_ATTRIBUTE_BOOLEAN, igraph_ecount(graph), &rec + )); + VECTOR(*rec->value.as_vector_bool)[eid] = value; return IGRAPH_SUCCESS; } @@ -3949,44 +2661,13 @@ igraph_error_t igraph_cattribute_EAB_set(igraph_t *graph, const char *name, */ igraph_error_t igraph_cattribute_EAS_set(igraph_t *graph, const char *name, igraph_integer_t eid, const char *value) { - igraph_i_cattributes_t *attr = graph->attr; - igraph_vector_ptr_t *eal = &attr->eal; - igraph_integer_t j; - igraph_bool_t l = igraph_i_cattribute_find(eal, name, &j); - - if (l) { - igraph_attribute_record_t *rec = VECTOR(*eal)[j]; - if (rec->type != IGRAPH_ATTRIBUTE_STRING) { - IGRAPH_ERROR("Invalid attribute type", IGRAPH_EINVAL); - } else { - igraph_strvector_t *str = (igraph_strvector_t*)rec->value; - IGRAPH_CHECK(igraph_strvector_set(str, eid, value)); - } - } else { - igraph_attribute_record_t *rec = IGRAPH_CALLOC(1, igraph_attribute_record_t); - igraph_strvector_t *str; - if (!rec) { - IGRAPH_ERROR("Cannot add edge attribute", IGRAPH_ENOMEM); /* LCOV_EXCL_LINE */ - } - IGRAPH_FINALLY(igraph_free, rec); - rec->name = strdup(name); - if (!rec->name) { - IGRAPH_ERROR("Cannot add edge attribute", IGRAPH_ENOMEM); /* LCOV_EXCL_LINE */ - } - IGRAPH_FINALLY(igraph_free, (char*)rec->name); - rec->type = IGRAPH_ATTRIBUTE_STRING; - str = IGRAPH_CALLOC(1, igraph_strvector_t); - if (!str) { - IGRAPH_ERROR("Cannot add edge attribute", IGRAPH_ENOMEM); /* LCOV_EXCL_LINE */ - } - IGRAPH_FINALLY(igraph_free, str); - IGRAPH_STRVECTOR_INIT_FINALLY(str, igraph_ecount(graph)); - IGRAPH_CHECK(igraph_strvector_set(str, eid, value)); - rec->value = str; - IGRAPH_CHECK(igraph_vector_ptr_push_back(eal, rec)); - IGRAPH_FINALLY_CLEAN(4); - } + igraph_attribute_record_t *rec; + + IGRAPH_CHECK(igraph_i_cattribute_find_or_create( + &attr->eal, name, IGRAPH_ATTRIBUTE_STRING, igraph_ecount(graph), &rec + )); + IGRAPH_CHECK(igraph_strvector_set(rec->value.as_strvector, eid, value)); return IGRAPH_SUCCESS; } @@ -4010,52 +2691,20 @@ igraph_error_t igraph_cattribute_EAS_set(igraph_t *graph, const char *name, igraph_error_t igraph_cattribute_VAN_setv(igraph_t *graph, const char *name, const igraph_vector_t *v) { igraph_i_cattributes_t *attr = graph->attr; - igraph_vector_ptr_t *val = &attr->val; - igraph_integer_t j; - igraph_bool_t l = igraph_i_cattribute_find(val, name, &j); + igraph_attribute_record_t *rec; + igraph_integer_t nv = igraph_vcount(graph); /* Check length first */ - if (igraph_vector_size(v) != igraph_vcount(graph)) { + if (igraph_vector_size(v) != nv) { IGRAPH_ERROR("Invalid vertex attribute vector length", IGRAPH_EINVAL); } - if (l) { - /* Already present, check type */ - igraph_attribute_record_t *rec = VECTOR(*val)[j]; - igraph_vector_t *num = (igraph_vector_t *)rec->value; - if (rec->type != IGRAPH_ATTRIBUTE_NUMERIC) { - IGRAPH_ERROR("Attribute type mismatch", IGRAPH_EINVAL); - } - igraph_vector_clear(num); - IGRAPH_CHECK(igraph_vector_append(num, v)); - } else { - /* Add it */ - igraph_attribute_record_t *rec = IGRAPH_CALLOC(1, igraph_attribute_record_t); - igraph_vector_t *num; - if (!rec) { - IGRAPH_ERROR("Cannot add vertex attribute", IGRAPH_ENOMEM); /* LCOV_EXCL_LINE */ - } - IGRAPH_FINALLY(igraph_free, rec); - rec->type = IGRAPH_ATTRIBUTE_NUMERIC; - rec->name = strdup(name); - if (!rec->name) { - IGRAPH_ERROR("Cannot add vertex attribute", IGRAPH_ENOMEM); /* LCOV_EXCL_LINE */ - } - IGRAPH_FINALLY(igraph_free, (char*)rec->name); - num = IGRAPH_CALLOC(1, igraph_vector_t); - if (!num) { - IGRAPH_ERROR("Cannot add vertex attribute", IGRAPH_ENOMEM); /* LCOV_EXCL_LINE */ - } - IGRAPH_FINALLY(igraph_free, num); - rec->value = num; - IGRAPH_CHECK(igraph_vector_init_copy(num, v)); - IGRAPH_FINALLY(igraph_vector_destroy, num); - IGRAPH_CHECK(igraph_vector_ptr_push_back(val, rec)); - IGRAPH_FINALLY_CLEAN(4); - } + IGRAPH_CHECK(igraph_i_cattribute_find_or_create(&attr->val, name, IGRAPH_ATTRIBUTE_NUMERIC, nv, &rec)); + IGRAPH_CHECK(igraph_vector_update(rec->value.as_vector, v)); return IGRAPH_SUCCESS; } + /** * \function igraph_cattribute_VAB_setv * \brief Set a boolean vertex attribute for all vertices. @@ -4075,49 +2724,16 @@ igraph_error_t igraph_cattribute_VAN_setv(igraph_t *graph, const char *name, igraph_error_t igraph_cattribute_VAB_setv(igraph_t *graph, const char *name, const igraph_vector_bool_t *v) { igraph_i_cattributes_t *attr = graph->attr; - igraph_vector_ptr_t *val = &attr->val; - igraph_integer_t j; - igraph_bool_t l = igraph_i_cattribute_find(val, name, &j); + igraph_attribute_record_t *rec; + igraph_integer_t nv = igraph_vcount(graph); /* Check length first */ - if (igraph_vector_bool_size(v) != igraph_vcount(graph)) { + if (igraph_vector_bool_size(v) != nv) { IGRAPH_ERROR("Invalid vertex attribute vector length", IGRAPH_EINVAL); } - if (l) { - /* Already present, check type */ - igraph_attribute_record_t *rec = VECTOR(*val)[j]; - igraph_vector_bool_t *log = (igraph_vector_bool_t *)rec->value; - if (rec->type != IGRAPH_ATTRIBUTE_BOOLEAN) { - IGRAPH_ERROR("Attribute type mismatch", IGRAPH_EINVAL); - } - igraph_vector_bool_clear(log); - IGRAPH_CHECK(igraph_vector_bool_append(log, v)); - } else { - /* Add it */ - igraph_attribute_record_t *rec = IGRAPH_CALLOC(1, igraph_attribute_record_t); - igraph_vector_bool_t *log; - if (!rec) { - IGRAPH_ERROR("Cannot add vertex attribute", IGRAPH_ENOMEM); /* LCOV_EXCL_LINE */ - } - IGRAPH_FINALLY(igraph_free, rec); - rec->type = IGRAPH_ATTRIBUTE_BOOLEAN; - rec->name = strdup(name); - if (!rec->name) { - IGRAPH_ERROR("Cannot add vertex attribute", IGRAPH_ENOMEM); /* LCOV_EXCL_LINE */ - } - IGRAPH_FINALLY(igraph_free, (char*)rec->name); - log = IGRAPH_CALLOC(1, igraph_vector_bool_t); - if (!log) { - IGRAPH_ERROR("Cannot add vertex attribute", IGRAPH_ENOMEM); /* LCOV_EXCL_LINE */ - } - IGRAPH_FINALLY(igraph_free, log); - rec->value = log; - IGRAPH_CHECK(igraph_vector_bool_init_copy(log, v)); - IGRAPH_FINALLY(igraph_vector_bool_destroy, log); - IGRAPH_CHECK(igraph_vector_ptr_push_back(val, rec)); - IGRAPH_FINALLY_CLEAN(4); - } + IGRAPH_CHECK(igraph_i_cattribute_find_or_create(&attr->val, name, IGRAPH_ATTRIBUTE_BOOLEAN, nv, &rec)); + IGRAPH_CHECK(igraph_vector_bool_update(rec->value.as_vector_bool, v)); return IGRAPH_SUCCESS; } @@ -4140,51 +2756,17 @@ igraph_error_t igraph_cattribute_VAB_setv(igraph_t *graph, const char *name, */ igraph_error_t igraph_cattribute_VAS_setv(igraph_t *graph, const char *name, const igraph_strvector_t *sv) { - igraph_i_cattributes_t *attr = graph->attr; - igraph_vector_ptr_t *val = &attr->val; - igraph_integer_t j; - igraph_bool_t l = igraph_i_cattribute_find(val, name, &j); + igraph_attribute_record_t *rec; + igraph_integer_t nv = igraph_vcount(graph); /* Check length first */ - if (igraph_strvector_size(sv) != igraph_vcount(graph)) { + if (igraph_strvector_size(sv) != nv) { IGRAPH_ERROR("Invalid vertex attribute vector length", IGRAPH_EINVAL); } - if (l) { - /* Already present, check type */ - igraph_attribute_record_t *rec = VECTOR(*val)[j]; - igraph_strvector_t *str = (igraph_strvector_t *)rec->value; - if (rec->type != IGRAPH_ATTRIBUTE_STRING) { - IGRAPH_ERROR("Attribute type mismatch", IGRAPH_EINVAL); - } - igraph_strvector_clear(str); - IGRAPH_CHECK(igraph_strvector_append(str, sv)); - } else { - /* Add it */ - igraph_attribute_record_t *rec = IGRAPH_CALLOC(1, igraph_attribute_record_t); - igraph_strvector_t *str; - if (!rec) { - IGRAPH_ERROR("Cannot add vertex attribute", IGRAPH_ENOMEM); /* LCOV_EXCL_LINE */ - } - IGRAPH_FINALLY(igraph_free, rec); - rec->type = IGRAPH_ATTRIBUTE_STRING; - rec->name = strdup(name); - if (!rec->name) { - IGRAPH_ERROR("Cannot add vertex attribute", IGRAPH_ENOMEM); /* LCOV_EXCL_LINE */ - } - IGRAPH_FINALLY(igraph_free, (char*)rec->name); - str = IGRAPH_CALLOC(1, igraph_strvector_t); - if (!str) { - IGRAPH_ERROR("Cannot add vertex attribute", IGRAPH_ENOMEM); /* LCOV_EXCL_LINE */ - } - IGRAPH_FINALLY(igraph_free, str); - rec->value = str; - IGRAPH_CHECK(igraph_strvector_init_copy(str, sv)); - IGRAPH_FINALLY(igraph_strvector_destroy, str); - IGRAPH_CHECK(igraph_vector_ptr_push_back(val, rec)); - IGRAPH_FINALLY_CLEAN(4); - } + IGRAPH_CHECK(igraph_i_cattribute_find_or_create(&attr->val, name, IGRAPH_ATTRIBUTE_STRING, nv, &rec)); + IGRAPH_CHECK(igraph_strvector_update(rec->value.as_strvector, sv)); return IGRAPH_SUCCESS; } @@ -4206,51 +2788,17 @@ igraph_error_t igraph_cattribute_VAS_setv(igraph_t *graph, const char *name, */ igraph_error_t igraph_cattribute_EAN_setv(igraph_t *graph, const char *name, const igraph_vector_t *v) { - igraph_i_cattributes_t *attr = graph->attr; - igraph_vector_ptr_t *eal = &attr->eal; - igraph_integer_t j; - igraph_bool_t l = igraph_i_cattribute_find(eal, name, &j); + igraph_attribute_record_t *rec; + igraph_integer_t ne = igraph_ecount(graph); /* Check length first */ - if (igraph_vector_size(v) != igraph_ecount(graph)) { + if (igraph_vector_size(v) != ne) { IGRAPH_ERROR("Invalid edge attribute vector length", IGRAPH_EINVAL); } - if (l) { - /* Already present, check type */ - igraph_attribute_record_t *rec = VECTOR(*eal)[j]; - igraph_vector_t *num = (igraph_vector_t *)rec->value; - if (rec->type != IGRAPH_ATTRIBUTE_NUMERIC) { - IGRAPH_ERROR("Attribute type mismatch", IGRAPH_EINVAL); - } - igraph_vector_clear(num); - IGRAPH_CHECK(igraph_vector_append(num, v)); - } else { - /* Add it */ - igraph_attribute_record_t *rec = IGRAPH_CALLOC(1, igraph_attribute_record_t); - igraph_vector_t *num; - if (!rec) { - IGRAPH_ERROR("Cannot add edge attribute", IGRAPH_ENOMEM); /* LCOV_EXCL_LINE */ - } - IGRAPH_FINALLY(igraph_free, rec); - rec->type = IGRAPH_ATTRIBUTE_NUMERIC; - rec->name = strdup(name); - if (!rec->name) { - IGRAPH_ERROR("Cannot add edge attribute", IGRAPH_ENOMEM); /* LCOV_EXCL_LINE */ - } - IGRAPH_FINALLY(igraph_free, (char*)rec->name); - num = IGRAPH_CALLOC(1, igraph_vector_t); - if (!num) { - IGRAPH_ERROR("Cannot add edge attribute", IGRAPH_ENOMEM); /* LCOV_EXCL_LINE */ - } - IGRAPH_FINALLY(igraph_free, num); - rec->value = num; - IGRAPH_CHECK(igraph_vector_init_copy(num, v)); - IGRAPH_FINALLY(igraph_vector_destroy, num); - IGRAPH_CHECK(igraph_vector_ptr_push_back(eal, rec)); - IGRAPH_FINALLY_CLEAN(4); - } + IGRAPH_CHECK(igraph_i_cattribute_find_or_create(&attr->eal, name, IGRAPH_ATTRIBUTE_NUMERIC, ne, &rec)); + IGRAPH_CHECK(igraph_vector_update(rec->value.as_vector, v)); return IGRAPH_SUCCESS; } @@ -4272,51 +2820,17 @@ igraph_error_t igraph_cattribute_EAN_setv(igraph_t *graph, const char *name, */ igraph_error_t igraph_cattribute_EAB_setv(igraph_t *graph, const char *name, const igraph_vector_bool_t *v) { - igraph_i_cattributes_t *attr = graph->attr; - igraph_vector_ptr_t *eal = &attr->eal; - igraph_integer_t j; - igraph_bool_t l = igraph_i_cattribute_find(eal, name, &j); + igraph_attribute_record_t *rec; + igraph_integer_t ne = igraph_ecount(graph); /* Check length first */ - if (igraph_vector_bool_size(v) != igraph_ecount(graph)) { + if (igraph_vector_bool_size(v) != ne) { IGRAPH_ERROR("Invalid edge attribute vector length", IGRAPH_EINVAL); } - if (l) { - /* Already present, check type */ - igraph_attribute_record_t *rec = VECTOR(*eal)[j]; - igraph_vector_bool_t *log = (igraph_vector_bool_t *)rec->value; - if (rec->type != IGRAPH_ATTRIBUTE_BOOLEAN) { - IGRAPH_ERROR("Attribute type mismatch", IGRAPH_EINVAL); - } - igraph_vector_bool_clear(log); - IGRAPH_CHECK(igraph_vector_bool_append(log, v)); - } else { - /* Add it */ - igraph_attribute_record_t *rec = IGRAPH_CALLOC(1, igraph_attribute_record_t); - igraph_vector_bool_t *log; - if (!rec) { - IGRAPH_ERROR("Cannot add edge attribute", IGRAPH_ENOMEM); /* LCOV_EXCL_LINE */ - } - IGRAPH_FINALLY(igraph_free, rec); - rec->type = IGRAPH_ATTRIBUTE_BOOLEAN; - rec->name = strdup(name); - if (!rec->name) { - IGRAPH_ERROR("Cannot add edge attribute", IGRAPH_ENOMEM); /* LCOV_EXCL_LINE */ - } - IGRAPH_FINALLY(igraph_free, (char*)rec->name); - log = IGRAPH_CALLOC(1, igraph_vector_bool_t); - if (!log) { - IGRAPH_ERROR("Cannot add edge attribute", IGRAPH_ENOMEM); /* LCOV_EXCL_LINE */ - } - IGRAPH_FINALLY(igraph_free, log); - rec->value = log; - IGRAPH_CHECK(igraph_vector_bool_init_copy(log, v)); - IGRAPH_FINALLY(igraph_vector_bool_destroy, log); - IGRAPH_CHECK(igraph_vector_ptr_push_back(eal, rec)); - IGRAPH_FINALLY_CLEAN(4); - } + IGRAPH_CHECK(igraph_i_cattribute_find_or_create(&attr->eal, name, IGRAPH_ATTRIBUTE_BOOLEAN, ne, &rec)); + IGRAPH_CHECK(igraph_vector_bool_update(rec->value.as_vector_bool, v)); return IGRAPH_SUCCESS; } @@ -4339,72 +2853,21 @@ igraph_error_t igraph_cattribute_EAB_setv(igraph_t *graph, const char *name, */ igraph_error_t igraph_cattribute_EAS_setv(igraph_t *graph, const char *name, const igraph_strvector_t *sv) { - igraph_i_cattributes_t *attr = graph->attr; - igraph_vector_ptr_t *eal = &attr->eal; - igraph_integer_t j; - igraph_bool_t l = igraph_i_cattribute_find(eal, name, &j); + igraph_attribute_record_t *rec; + igraph_integer_t ne = igraph_ecount(graph); /* Check length first */ - if (igraph_strvector_size(sv) != igraph_ecount(graph)) { + if (igraph_strvector_size(sv) != ne) { IGRAPH_ERROR("Invalid edge attribute vector length", IGRAPH_EINVAL); } - if (l) { - /* Already present, check type */ - igraph_attribute_record_t *rec = VECTOR(*eal)[j]; - igraph_strvector_t *str = (igraph_strvector_t *)rec->value; - if (rec->type != IGRAPH_ATTRIBUTE_STRING) { - IGRAPH_ERROR("Attribute type mismatch", IGRAPH_EINVAL); - } - igraph_strvector_clear(str); - IGRAPH_CHECK(igraph_strvector_append(str, sv)); - } else { - /* Add it */ - igraph_attribute_record_t *rec = IGRAPH_CALLOC(1, igraph_attribute_record_t); - igraph_strvector_t *str; - if (!rec) { - IGRAPH_ERROR("Cannot add vertex attribute", IGRAPH_ENOMEM); /* LCOV_EXCL_LINE */ - } - IGRAPH_FINALLY(igraph_free, rec); - rec->type = IGRAPH_ATTRIBUTE_STRING; - rec->name = strdup(name); - if (!rec->name) { - IGRAPH_ERROR("Cannot add vertex attribute", IGRAPH_ENOMEM); /* LCOV_EXCL_LINE */ - } - IGRAPH_FINALLY(igraph_free, (char*)rec->name); - str = IGRAPH_CALLOC(1, igraph_strvector_t); - if (!str) { - IGRAPH_ERROR("Cannot add vertex attribute", IGRAPH_ENOMEM); /* LCOV_EXCL_LINE */ - } - IGRAPH_FINALLY(igraph_free, str); - rec->value = str; - IGRAPH_CHECK(igraph_strvector_init_copy(str, sv)); - IGRAPH_FINALLY(igraph_strvector_destroy, str); - IGRAPH_CHECK(igraph_vector_ptr_push_back(eal, rec)); - IGRAPH_FINALLY_CLEAN(4); - } + IGRAPH_CHECK(igraph_i_cattribute_find_or_create(&attr->eal, name, IGRAPH_ATTRIBUTE_STRING, ne, &rec)); + IGRAPH_CHECK(igraph_strvector_update(rec->value.as_strvector, sv)); return IGRAPH_SUCCESS; } -static void igraph_i_cattribute_free_rec(igraph_attribute_record_t *rec) { - - if (rec->type == IGRAPH_ATTRIBUTE_NUMERIC) { - igraph_vector_t *num = (igraph_vector_t*)rec->value; - igraph_vector_destroy(num); - } else if (rec->type == IGRAPH_ATTRIBUTE_STRING) { - igraph_strvector_t *str = (igraph_strvector_t*)rec->value; - igraph_strvector_destroy(str); - } else if (rec->type == IGRAPH_ATTRIBUTE_BOOLEAN) { - igraph_vector_bool_t *boolvec = (igraph_vector_bool_t*)rec->value; - igraph_vector_bool_destroy(boolvec); - } - IGRAPH_FREE(rec->name); - IGRAPH_FREE(rec->value); - IGRAPH_FREE(rec); -} - /** * \function igraph_cattribute_remove_g * \brief Remove a graph attribute. @@ -4418,13 +2881,11 @@ static void igraph_i_cattribute_free_rec(igraph_attribute_record_t *rec) { void igraph_cattribute_remove_g(igraph_t *graph, const char *name) { igraph_i_cattributes_t *attr = graph->attr; - igraph_vector_ptr_t *gal = &attr->gal; - igraph_integer_t j; - igraph_bool_t l = igraph_i_cattribute_find(gal, name, &j); + igraph_attribute_record_list_t *gal = &attr->gal; + igraph_integer_t j = igraph_i_cattribute_find_index(gal, name); - if (l) { - igraph_i_cattribute_free_rec(VECTOR(*gal)[j]); - igraph_vector_ptr_remove(gal, j); + if (j >= 0) { + igraph_attribute_record_list_discard(gal, j); } else { IGRAPH_WARNING("Cannot remove non-existent graph attribute"); } @@ -4443,13 +2904,11 @@ void igraph_cattribute_remove_g(igraph_t *graph, const char *name) { void igraph_cattribute_remove_v(igraph_t *graph, const char *name) { igraph_i_cattributes_t *attr = graph->attr; - igraph_vector_ptr_t *val = &attr->val; - igraph_integer_t j; - igraph_bool_t l = igraph_i_cattribute_find(val, name, &j); + igraph_attribute_record_list_t *val = &attr->val; + igraph_integer_t j = igraph_i_cattribute_find_index(val, name); - if (l) { - igraph_i_cattribute_free_rec(VECTOR(*val)[j]); - igraph_vector_ptr_remove(val, j); + if (j >= 0) { + igraph_attribute_record_list_discard(val, j); } else { IGRAPH_WARNING("Cannot remove non-existent graph attribute"); } @@ -4463,18 +2922,15 @@ void igraph_cattribute_remove_v(igraph_t *graph, const char *name) { * \param name Name of the edge attribute to remove. * * \sa \ref DELEA for a simpler way. - * */ void igraph_cattribute_remove_e(igraph_t *graph, const char *name) { igraph_i_cattributes_t *attr = graph->attr; - igraph_vector_ptr_t *eal = &attr->eal; - igraph_integer_t j; - igraph_bool_t l = igraph_i_cattribute_find(eal, name, &j); + igraph_attribute_record_list_t *eal = &attr->eal; + igraph_integer_t j = igraph_i_cattribute_find_index(eal, name); - if (l) { - igraph_i_cattribute_free_rec(VECTOR(*eal)[j]); - igraph_vector_ptr_remove(eal, j); + if (j >= 0) { + igraph_attribute_record_list_discard(eal, j); } else { IGRAPH_WARNING("Cannot remove non-existent graph attribute"); } @@ -4498,27 +2954,12 @@ void igraph_cattribute_remove_all(igraph_t *graph, igraph_bool_t g, igraph_i_cattributes_t *attr = graph->attr; if (g) { - igraph_vector_ptr_t *gal = &attr->gal; - igraph_integer_t i, n = igraph_vector_ptr_size(gal); - for (i = 0; i < n; i++) { - igraph_i_cattribute_free_rec(VECTOR(*gal)[i]); - } - igraph_vector_ptr_clear(gal); + igraph_attribute_record_list_clear(&attr->gal); } if (v) { - igraph_vector_ptr_t *val = &attr->val; - igraph_integer_t i, n = igraph_vector_ptr_size(val); - for (i = 0; i < n; i++) { - igraph_i_cattribute_free_rec(VECTOR(*val)[i]); - } - igraph_vector_ptr_clear(val); + igraph_attribute_record_list_clear(&attr->val); } if (e) { - igraph_vector_ptr_t *eal = &attr->eal; - igraph_integer_t i, n = igraph_vector_ptr_size(eal); - for (i = 0; i < n; i++) { - igraph_i_cattribute_free_rec(VECTOR(*eal)[i]); - } - igraph_vector_ptr_clear(eal); + igraph_attribute_record_list_clear(&attr->eal); } } diff --git a/src/vendor/cigraph/src/graph/type_common.c b/src/vendor/cigraph/src/graph/type_common.c index da01c834c2e..3761310c1c6 100644 --- a/src/vendor/cigraph/src/graph/type_common.c +++ b/src/vendor/cigraph/src/graph/type_common.c @@ -90,7 +90,20 @@ igraph_error_t igraph_empty(igraph_t *graph, igraph_integer_t n, igraph_bool_t d * \example examples/simple/igraph_delete_vertices.c */ igraph_error_t igraph_delete_vertices(igraph_t *graph, const igraph_vs_t vertices) { - return igraph_delete_vertices_idx(graph, vertices, /* idx= */ 0, /* invidx= */ 0); + return igraph_delete_vertices_map(graph, vertices, /* idx= */ 0, /* invidx= */ 0); +} + +/** + * \function igraph_delete_vertices_idx + * \brief Removes some vertices (with all their edges) from the graph (deprecated alias). + * + * \deprecated-by igraph_delete_vertices_map 0.11.0 + */ +igraph_error_t igraph_delete_vertices_idx( + igraph_t *graph, const igraph_vs_t vertices, igraph_vector_int_t *idx, + igraph_vector_int_t *invidx +) { + return igraph_delete_vertices_map(graph, vertices, idx, invidx); } /** diff --git a/src/vendor/cigraph/src/graph/type_indexededgelist.c b/src/vendor/cigraph/src/graph/type_indexededgelist.c index 6380207380e..82cb6048b5f 100644 --- a/src/vendor/cigraph/src/graph/type_indexededgelist.c +++ b/src/vendor/cigraph/src/graph/type_indexededgelist.c @@ -95,12 +95,17 @@ static igraph_error_t igraph_i_create_start_vectors( * Time complexity: O(|V|) for a graph with * |V| vertices (and no edges). */ -igraph_error_t igraph_empty_attrs(igraph_t *graph, igraph_integer_t n, igraph_bool_t directed, void *attr) { +igraph_error_t igraph_empty_attrs( + igraph_t *graph, igraph_integer_t n, igraph_bool_t directed, + const igraph_attribute_record_list_t *attr +) { if (n < 0) { IGRAPH_ERROR("Number of vertices must not be negative.", IGRAPH_EINVAL); } + memset(graph, 0, sizeof(igraph_t)); + graph->n = 0; graph->directed = directed; IGRAPH_VECTOR_INT_INIT_FINALLY(&graph->from, 0); @@ -121,7 +126,6 @@ igraph_error_t igraph_empty_attrs(igraph_t *graph, igraph_integer_t n, igraph_bo VECTOR(graph->is)[0] = 0; /* init attributes */ - graph->attr = 0; IGRAPH_CHECK(igraph_i_attribute_init(graph, attr)); /* add the vertices */ @@ -148,8 +152,7 @@ igraph_error_t igraph_empty_attrs(igraph_t *graph, igraph_integer_t n, igraph_bo * Time complexity: operating system specific. */ void igraph_destroy(igraph_t *graph) { - - IGRAPH_I_ATTRIBUTE_DESTROY(graph); + igraph_i_attribute_destroy(graph); igraph_i_property_cache_destroy(graph->cache); IGRAPH_FREE(graph->cache); @@ -189,6 +192,8 @@ void igraph_destroy(igraph_t *graph) { */ igraph_error_t igraph_copy(igraph_t *to, const igraph_t *from) { + memset(to, 0, sizeof(igraph_t)); + to->n = from->n; to->directed = from->directed; IGRAPH_CHECK(igraph_vector_int_init_copy(&to->from, &from->from)); @@ -210,7 +215,7 @@ igraph_error_t igraph_copy(igraph_t *to, const igraph_t *from) { IGRAPH_CHECK(igraph_i_property_cache_copy(to->cache, from->cache)); IGRAPH_FINALLY(igraph_i_property_cache_destroy, to->cache); - IGRAPH_I_ATTRIBUTE_COPY(to, from, true, true, true); /* does IGRAPH_CHECK */ + IGRAPH_CHECK(igraph_i_attribute_copy(to, from, true, true, true)); IGRAPH_FINALLY_CLEAN(8); return IGRAPH_SUCCESS; @@ -245,8 +250,10 @@ igraph_error_t igraph_copy(igraph_t *to, const igraph_t *from) { * * \example examples/simple/creation.c */ -igraph_error_t igraph_add_edges(igraph_t *graph, const igraph_vector_int_t *edges, - void *attr) { +igraph_error_t igraph_add_edges( + igraph_t *graph, const igraph_vector_int_t *edges, + const igraph_attribute_record_list_t *attr +) { igraph_integer_t no_of_edges = igraph_vector_int_size(&graph->from); igraph_integer_t edges_to_add = igraph_vector_int_size(edges) / 2; igraph_integer_t new_no_of_edges; @@ -378,7 +385,9 @@ igraph_error_t igraph_add_edges(igraph_t *graph, const igraph_vector_int_t *edge * * \example examples/simple/creation.c */ -igraph_error_t igraph_add_vertices(igraph_t *graph, igraph_integer_t nv, void *attr) { +igraph_error_t igraph_add_vertices( + igraph_t *graph, igraph_integer_t nv, const igraph_attribute_record_list_t *attr +) { igraph_integer_t ec = igraph_ecount(graph); igraph_integer_t vc = igraph_vcount(graph); igraph_integer_t new_vc; @@ -605,7 +614,7 @@ igraph_error_t igraph_delete_edges(igraph_t *graph, igraph_es_t edges) { /** * \ingroup interface - * \function igraph_delete_vertices_idx + * \function igraph_delete_vertices_map * \brief Removes some vertices (with all their edges) from the graph. * * @@ -620,12 +629,10 @@ igraph_error_t igraph_delete_edges(igraph_t *graph, igraph_es_t edges) { * \param graph The graph to work on. * \param vertices The IDs of the vertices to remove, in a vector. The vector * may contain the same ID more than once. - * \param idx An optional pointer to a vector that provides the mapping from + * \param map An optional pointer to a vector that provides the mapping from * the vertex IDs \em before the removal to the vertex IDs \em after - * the removal, \em plus one. Zero is used to represent vertices that were - * removed during the operation. You can supply \c NULL here if you are not - * interested. - * \param invidx An optional pointer to a vector that provides the mapping from + * the removal. You can supply \c NULL here if you are not interested. + * \param invmap An optional pointer to a vector that provides the mapping from * the vertex IDs \em after the removal to the vertex IDs \em before * the removal. You can supply \c NULL here if you are not interested. * \return Error code: @@ -633,12 +640,10 @@ igraph_error_t igraph_delete_edges(igraph_t *graph, igraph_es_t edges) { * * Time complexity: O(|V|+|E|), |V| and |E| are the number of vertices and * edges in the original graph. - * - * \example examples/simple/igraph_delete_vertices.c */ -igraph_error_t igraph_delete_vertices_idx( - igraph_t *graph, const igraph_vs_t vertices, igraph_vector_int_t *idx, - igraph_vector_int_t *invidx +igraph_error_t igraph_delete_vertices_map( + igraph_t *graph, const igraph_vs_t vertices, igraph_vector_int_t *map, + igraph_vector_int_t *invmap ) { igraph_integer_t no_of_edges = igraph_ecount(graph); igraph_integer_t no_of_nodes = igraph_vcount(graph); @@ -649,10 +654,10 @@ igraph_error_t igraph_delete_vertices_idx( igraph_integer_t i, j; igraph_integer_t remaining_vertices, remaining_edges; - if (idx) { - my_vertex_recoding = idx; - IGRAPH_CHECK(igraph_vector_int_resize(idx, no_of_nodes)); - igraph_vector_int_null(idx); + if (map) { + my_vertex_recoding = map; + IGRAPH_CHECK(igraph_vector_int_resize(map, no_of_nodes)); + igraph_vector_int_null(map); } else { IGRAPH_VECTOR_INT_INIT_FINALLY(&vertex_recoding, no_of_nodes); } @@ -673,24 +678,25 @@ igraph_error_t igraph_delete_vertices_idx( /* create vertex recoding vector */ for (remaining_vertices = 0, i = 0; i < no_of_nodes; i++) { if (VECTOR(*my_vertex_recoding)[i] == 0) { - VECTOR(*my_vertex_recoding)[i] = remaining_vertices + 1; + VECTOR(*my_vertex_recoding)[i] = remaining_vertices; remaining_vertices++; } else { - VECTOR(*my_vertex_recoding)[i] = 0; + VECTOR(*my_vertex_recoding)[i] = -1; } } /* create edge recoding vector */ for (remaining_edges = 0, i = 0; i < no_of_edges; i++) { igraph_integer_t from = VECTOR(graph->from)[i]; igraph_integer_t to = VECTOR(graph->to)[i]; - if (VECTOR(*my_vertex_recoding)[from] != 0 && - VECTOR(*my_vertex_recoding)[to ] != 0) { + if (VECTOR(*my_vertex_recoding)[from] >= 0 && + VECTOR(*my_vertex_recoding)[to ] >= 0) { VECTOR(edge_recoding)[i] = remaining_edges + 1; remaining_edges++; } } /* start creating the graph */ + memset(&newgraph, 0, sizeof(igraph_t)); newgraph.n = remaining_vertices; newgraph.directed = graph->directed; @@ -707,8 +713,8 @@ igraph_error_t igraph_delete_vertices_idx( if (VECTOR(edge_recoding)[i] > 0) { igraph_integer_t from = VECTOR(graph->from)[i]; igraph_integer_t to = VECTOR(graph->to )[i]; - VECTOR(newgraph.from)[j] = VECTOR(*my_vertex_recoding)[from] - 1; - VECTOR(newgraph.to )[j] = VECTOR(*my_vertex_recoding)[to] - 1; + VECTOR(newgraph.from)[j] = VECTOR(*my_vertex_recoding)[from]; + VECTOR(newgraph.to )[j] = VECTOR(*my_vertex_recoding)[to]; j++; } } @@ -731,8 +737,9 @@ igraph_error_t igraph_delete_vertices_idx( IGRAPH_FINALLY(igraph_i_property_cache_destroy, newgraph.cache); /* attributes */ - IGRAPH_I_ATTRIBUTE_COPY(&newgraph, graph, - /*graph=*/ 1, /*vertex=*/0, /*edge=*/0); + IGRAPH_CHECK(igraph_i_attribute_copy( + &newgraph, graph, /* graph= */ true, /* vertex= */ false, /* edge= */ false + )); /* at this point igraph_destroy can take over the responsibility of * deallocating the graph */ @@ -744,13 +751,11 @@ igraph_error_t igraph_delete_vertices_idx( IGRAPH_VECTOR_INT_INIT_FINALLY(&iidx, remaining_vertices); for (i = 0; i < no_of_nodes; i++) { igraph_integer_t jj = VECTOR(*my_vertex_recoding)[i]; - if (jj != 0) { - VECTOR(iidx)[ jj - 1 ] = i; + if (jj >= 0) { + VECTOR(iidx)[ jj ] = i; } } - IGRAPH_CHECK(igraph_i_attribute_permute_vertices(graph, - &newgraph, - &iidx)); + IGRAPH_CHECK(igraph_i_attribute_permute_vertices(graph, &newgraph, &iidx)); IGRAPH_CHECK(igraph_vector_int_resize(&iidx, remaining_edges)); for (i = 0; i < no_of_edges; i++) { igraph_integer_t jj = VECTOR(edge_recoding)[i]; @@ -770,18 +775,17 @@ igraph_error_t igraph_delete_vertices_idx( IGRAPH_FINALLY_CLEAN(3); - /* TODO: this is duplicate */ - if (invidx) { - IGRAPH_CHECK(igraph_vector_int_resize(invidx, remaining_vertices)); + if (invmap) { + IGRAPH_CHECK(igraph_vector_int_resize(invmap, remaining_vertices)); for (i = 0; i < no_of_nodes; i++) { igraph_integer_t newid = VECTOR(*my_vertex_recoding)[i]; - if (newid != 0) { - VECTOR(*invidx)[newid - 1] = i; + if (newid >= 0) { + VECTOR(*invmap)[newid] = i; } } } - if (!idx) { + if (!map) { igraph_vector_int_destroy(my_vertex_recoding); IGRAPH_FINALLY_CLEAN(1); } diff --git a/src/vendor/cigraph/src/hrg/hrg.cc b/src/vendor/cigraph/src/hrg/hrg.cc index ca1697fc98f..e484092011b 100644 --- a/src/vendor/cigraph/src/hrg/hrg.cc +++ b/src/vendor/cigraph/src/hrg/hrg.cc @@ -636,12 +636,9 @@ igraph_error_t igraph_hrg_dendrogram(igraph_t *graph, const igraph_hrg_t *hrg) { const igraph_integer_t no_of_edges = no_of_nodes > 0 ? no_of_nodes - 1 : 0; igraph_vector_int_t edges; igraph_integer_t i, idx = 0; - igraph_vector_ptr_t vattrs; + igraph_attribute_record_list_t vattrs; igraph_vector_t prob; - igraph_attribute_record_t rec = { "probability", - IGRAPH_ATTRIBUTE_NUMERIC, - &prob - }; + igraph_attribute_record_t* rec; // Probability labels, for leaf nodes they are IGRAPH_NAN IGRAPH_VECTOR_INIT_FINALLY(&prob, no_of_nodes); @@ -653,9 +650,13 @@ igraph_error_t igraph_hrg_dendrogram(igraph_t *graph, const igraph_hrg_t *hrg) { } IGRAPH_VECTOR_INT_INIT_FINALLY(&edges, no_of_edges * 2); - IGRAPH_CHECK(igraph_vector_ptr_init(&vattrs, 1)); - IGRAPH_FINALLY(igraph_vector_ptr_destroy, &vattrs); - VECTOR(vattrs)[0] = &rec; + IGRAPH_CHECK(igraph_attribute_record_list_init(&vattrs, 1)); + IGRAPH_FINALLY(igraph_attribute_record_list_destroy, &vattrs); + + rec = igraph_attribute_record_list_get_ptr(&vattrs, 1); + IGRAPH_CHECK(igraph_attribute_record_set_name(rec, "probability")); + IGRAPH_CHECK(igraph_attribute_record_set_type(rec, IGRAPH_ATTRIBUTE_NUMERIC)); + igraph_vector_swap(rec->value.as_vector, &prob); for (i = 0; i < orig_nodes - 1; i++) { igraph_integer_t left = VECTOR(hrg->left)[i]; @@ -672,7 +673,7 @@ igraph_error_t igraph_hrg_dendrogram(igraph_t *graph, const igraph_hrg_t *hrg) { IGRAPH_CHECK(igraph_add_vertices(graph, no_of_nodes, &vattrs)); IGRAPH_CHECK(igraph_add_edges(graph, &edges, NULL)); - igraph_vector_ptr_destroy(&vattrs); + igraph_attribute_record_list_destroy(&vattrs); igraph_vector_int_destroy(&edges); igraph_vector_destroy(&prob); IGRAPH_FINALLY_CLEAN(4); // + 1 for graph diff --git a/src/vendor/cigraph/src/internal/glpk_support.c b/src/vendor/cigraph/src/internal/glpk_support.c index 384390e737d..41f0f50607d 100644 --- a/src/vendor/cigraph/src/internal/glpk_support.c +++ b/src/vendor/cigraph/src/internal/glpk_support.c @@ -49,7 +49,7 @@ int igraph_i_glpk_terminal_hook(void *info, const char *s) { if (igraph_i_interruption_handler && !igraph_i_glpk_error_info.is_interrupted && - igraph_allow_interruption(NULL) != IGRAPH_SUCCESS) { + igraph_allow_interruption() != IGRAPH_SUCCESS) { /* If an interruption has already occurred, do not set another error, to avoid an infinite loop between the term_hook (this function) and the error_hook. */ @@ -90,7 +90,7 @@ void igraph_i_glpk_interruption_hook(glp_tree *tree, void *info) { with the code GLP_ESTOP. */ if (igraph_i_interruption_handler) { - if (igraph_allow_interruption(NULL) != IGRAPH_SUCCESS) { + if (igraph_allow_interruption() != IGRAPH_SUCCESS) { glp_ios_terminate(tree); } } diff --git a/src/vendor/cigraph/src/internal/utils.c b/src/vendor/cigraph/src/internal/utils.c index 0698e47dfc8..b1553af4195 100644 --- a/src/vendor/cigraph/src/internal/utils.c +++ b/src/vendor/cigraph/src/internal/utils.c @@ -84,7 +84,7 @@ igraph_error_t igraph_i_matrix_subset_vertices( } /* This is O(1) time */ - IGRAPH_CHECK(igraph_matrix_swap(m, &tmp)); + igraph_matrix_swap(m, &tmp); igraph_matrix_destroy(&tmp); igraph_vit_destroy(&tovit); diff --git a/src/vendor/cigraph/src/io/dl.c b/src/vendor/cigraph/src/io/dl.c index 103033fbff9..ec25002608d 100644 --- a/src/vendor/cigraph/src/io/dl.c +++ b/src/vendor/cigraph/src/io/dl.c @@ -70,9 +70,10 @@ igraph_error_t igraph_read_graph_dl(igraph_t *graph, FILE *instream, igraph_integer_t n, n2; const igraph_strvector_t *namevec = 0; - igraph_vector_ptr_t name, weight; - igraph_vector_ptr_t *pname = 0, *pweight = 0; - igraph_attribute_record_t namerec, weightrec; + igraph_attribute_record_list_t name, weight; + igraph_attribute_record_list_t *pname = NULL; + igraph_attribute_record_list_t *pweight = NULL; + igraph_attribute_record_t *namerec, *weightrec; const char *namestr = "name", *weightstr = "weight"; igraph_i_dl_parsedata_t context; @@ -153,24 +154,28 @@ igraph_error_t igraph_read_graph_dl(igraph_t *graph, FILE *instream, namevec = igraph_i_trie_borrow_keys(&context.trie); } if (namevec) { - IGRAPH_CHECK(igraph_vector_ptr_init(&name, 1)); - IGRAPH_FINALLY(igraph_vector_ptr_destroy, &name); + IGRAPH_CHECK(igraph_attribute_record_list_init(&name, 1)); + IGRAPH_FINALLY(igraph_attribute_record_list_destroy, &name); + + namerec = igraph_attribute_record_list_get_ptr(&name, 0); + IGRAPH_CHECK(igraph_attribute_record_set_name(namerec, namestr)); + IGRAPH_CHECK(igraph_attribute_record_set_type(namerec, IGRAPH_ATTRIBUTE_STRING)); + IGRAPH_CHECK(igraph_strvector_update(namerec->value.as_strvector, namevec)); + pname = &name; - namerec.name = namestr; - namerec.type = IGRAPH_ATTRIBUTE_STRING; - namerec.value = namevec; - VECTOR(name)[0] = &namerec; } /* Weights */ if (igraph_vector_size(&context.weights) != 0) { - IGRAPH_CHECK(igraph_vector_ptr_init(&weight, 1)); - IGRAPH_FINALLY(igraph_vector_ptr_destroy, &weight); + IGRAPH_CHECK(igraph_attribute_record_list_init(&weight, 1)); + IGRAPH_FINALLY(igraph_attribute_record_list_destroy, &weight); + + weightrec = igraph_attribute_record_list_get_ptr(&weight, 0); + IGRAPH_CHECK(igraph_attribute_record_set_name(weightrec, weightstr)); + IGRAPH_CHECK(igraph_attribute_record_set_type(weightrec, IGRAPH_ATTRIBUTE_NUMERIC)); + igraph_vector_swap(weightrec->value.as_vector, &context.weights); + pweight = &weight; - weightrec.name = weightstr; - weightrec.type = IGRAPH_ATTRIBUTE_NUMERIC; - weightrec.value = &context.weights; - VECTOR(weight)[0] = &weightrec; } /* Create graph */ @@ -180,12 +185,12 @@ igraph_error_t igraph_read_graph_dl(igraph_t *graph, FILE *instream, IGRAPH_CHECK(igraph_add_edges(graph, &context.edges, pweight)); if (pweight) { - igraph_vector_ptr_destroy(pweight); + igraph_attribute_record_list_destroy(pweight); IGRAPH_FINALLY_CLEAN(1); } if (pname) { - igraph_vector_ptr_destroy(pname); + igraph_attribute_record_list_destroy(pname); IGRAPH_FINALLY_CLEAN(1); } diff --git a/src/vendor/cigraph/src/io/gml.c b/src/vendor/cigraph/src/io/gml.c index b0fb9622e7d..bf58853bf75 100644 --- a/src/vendor/cigraph/src/io/gml.c +++ b/src/vendor/cigraph/src/io/gml.c @@ -161,35 +161,6 @@ static igraph_error_t entity_decode(const char *src, char **dest, igraph_bool_t return IGRAPH_SUCCESS; } -static void igraph_i_gml_destroy_attrs(igraph_vector_ptr_t **ptr) { - - igraph_vector_ptr_t *vec; - for (igraph_integer_t i = 0; i < 3; i++) { - vec = ptr[i]; - for (igraph_integer_t j = 0; j < igraph_vector_ptr_size(vec); j++) { - igraph_attribute_record_t *atrec = VECTOR(*vec)[j]; - if (atrec->type == IGRAPH_ATTRIBUTE_NUMERIC) { - igraph_vector_t *value = (igraph_vector_t*)atrec->value; - if (value != 0) { - igraph_vector_destroy(value); - IGRAPH_FREE(value); - } - } else if (atrec->type == IGRAPH_ATTRIBUTE_STRING) { - igraph_strvector_t *value = (igraph_strvector_t*)atrec->value; - if (value != 0) { - igraph_strvector_destroy(value); - IGRAPH_FREE(value); - } - } else { - /* Some empty attribute records may have been created for composite attributes */ - } - IGRAPH_FREE(atrec->name); - IGRAPH_FREE(atrec); - } - igraph_vector_ptr_destroy(vec); - } -} - static igraph_real_t igraph_i_gml_toreal(igraph_gml_tree_t *node, igraph_integer_t pos) { igraph_i_gml_tree_type_t type = igraph_gml_tree_type(node, pos); @@ -262,18 +233,29 @@ void igraph_i_gml_parsedata_destroy(igraph_i_gml_parsedata_t *context) { /* Takes a vector of attribute records and removes those elements * whose type is unspecified, i.e. IGRAPH_ATTRIBUTE_UNSPECIFIED. */ -static void prune_unknown_attributes(igraph_vector_ptr_t *attrs) { - igraph_integer_t i, j; - for (i = 0, j = 0; i < igraph_vector_ptr_size(attrs); i++) { - igraph_attribute_record_t *atrec = VECTOR(*attrs)[i]; +static igraph_error_t prune_unknown_attributes(igraph_attribute_record_list_t *attrs) { + igraph_integer_t i, n; + igraph_vector_int_t to_remove; + + IGRAPH_VECTOR_INT_INIT_FINALLY(&to_remove, 0); + + n = igraph_attribute_record_list_size(attrs); + for (i = 0; i < n; i++) { + igraph_attribute_record_t *atrec = igraph_attribute_record_list_get_ptr(attrs, i); if (atrec->type == IGRAPH_ATTRIBUTE_UNSPECIFIED) { - IGRAPH_FREE(atrec->name); - IGRAPH_FREE(atrec); - } else { - VECTOR(*attrs)[j++] = VECTOR(*attrs)[i]; + IGRAPH_CHECK(igraph_vector_int_push_back(&to_remove, i)); } } - igraph_vector_ptr_resize(attrs, j); /* shrinks */ + + n = igraph_vector_int_size(&to_remove); + for (i = n - 1; i >= 0; i--) { + igraph_attribute_record_list_discard(attrs, VECTOR(to_remove)[i]); + } + + igraph_vector_int_destroy(&to_remove); + IGRAPH_FINALLY_CLEAN(1); + + return IGRAPH_SUCCESS; } /* Converts an integer id to an optionally prefixed string id. */ @@ -289,38 +271,39 @@ static const char *strid(igraph_integer_t id, const char *prefix) { static igraph_error_t create_or_update_attribute(const char *name, igraph_i_gml_tree_type_t type, igraph_trie_t *attrnames, - igraph_vector_ptr_t *attrs) { + igraph_attribute_record_list_t *attrs) { igraph_integer_t trieid, triesize = igraph_trie_size(attrnames); + igraph_attribute_type_t desired_type; + IGRAPH_CHECK(igraph_trie_get(attrnames, name, &trieid)); if (trieid == triesize) { /* new attribute */ - igraph_attribute_record_t *atrec = IGRAPH_CALLOC(1, igraph_attribute_record_t); - IGRAPH_CHECK_OOM(atrec, "Cannot read GML file."); - IGRAPH_FINALLY(igraph_free, atrec); - - atrec->name = strdup(name); - IGRAPH_CHECK_OOM(atrec->name, "Cannot read GML file."); - IGRAPH_FINALLY(igraph_free, (char *) atrec->name); + igraph_attribute_record_t atrec; if (type == IGRAPH_I_GML_TREE_INTEGER || type == IGRAPH_I_GML_TREE_REAL) { - atrec->type = IGRAPH_ATTRIBUTE_NUMERIC; + desired_type = IGRAPH_ATTRIBUTE_NUMERIC; } else if (type == IGRAPH_I_GML_TREE_STRING) { - atrec->type = IGRAPH_ATTRIBUTE_STRING; + desired_type = IGRAPH_ATTRIBUTE_STRING; } else { - atrec->type = IGRAPH_ATTRIBUTE_UNSPECIFIED; + desired_type = IGRAPH_ATTRIBUTE_UNSPECIFIED; } - IGRAPH_CHECK(igraph_vector_ptr_push_back(attrs, atrec)); - IGRAPH_FINALLY_CLEAN(2); + + IGRAPH_CHECK(igraph_attribute_record_init(&atrec, name, desired_type)); + IGRAPH_FINALLY(igraph_attribute_record_destroy, &atrec); + IGRAPH_CHECK(igraph_attribute_record_list_push_back(attrs, &atrec)); + IGRAPH_FINALLY_CLEAN(1); /* ownership of 'atrec' taken by 'attrs' */ } else { /* already seen, should we update type? */ - igraph_attribute_record_t *atrec = VECTOR(*attrs)[trieid]; - igraph_attribute_type_t type1 = atrec->type; + igraph_attribute_record_t *atrec = igraph_attribute_record_list_get_ptr(attrs, trieid); + igraph_attribute_type_t existing_type = atrec->type; if (type == IGRAPH_I_GML_TREE_STRING) { - atrec->type = IGRAPH_ATTRIBUTE_STRING; - } else if (type1 == IGRAPH_ATTRIBUTE_UNSPECIFIED) { + if (existing_type != IGRAPH_ATTRIBUTE_STRING) { + IGRAPH_CHECK(igraph_attribute_record_set_type(atrec, IGRAPH_ATTRIBUTE_STRING)); + } + } else if (existing_type == IGRAPH_ATTRIBUTE_UNSPECIFIED) { if (type == IGRAPH_I_GML_TREE_INTEGER || type == IGRAPH_I_GML_TREE_REAL) { - atrec->type = IGRAPH_ATTRIBUTE_NUMERIC; + IGRAPH_CHECK(igraph_attribute_record_set_type(atrec, IGRAPH_ATTRIBUTE_NUMERIC)); } } } @@ -333,34 +316,21 @@ static igraph_error_t create_or_update_attribute(const char *name, * no_of_edges, or 1 for vertex, edge and graph attributes. * The 'kind' parameter can be "vertex", "edge" or "graph", and * is used solely for showing better warning messages. */ -static igraph_error_t allocate_attributes(igraph_vector_ptr_t *attrs, - igraph_integer_t no_of_items, - const char *kind) { - - igraph_integer_t i, n = igraph_vector_ptr_size(attrs); +static igraph_error_t allocate_attributes( + igraph_attribute_record_list_t *attrs, igraph_integer_t no_of_items, + const char *kind +) { + igraph_integer_t i, n = igraph_attribute_record_list_size(attrs); for (i = 0; i < n; i++) { - igraph_attribute_record_t *atrec = VECTOR(*attrs)[i]; - igraph_attribute_type_t type = atrec->type; - if (type == IGRAPH_ATTRIBUTE_NUMERIC) { - igraph_vector_t *p = IGRAPH_CALLOC(1, igraph_vector_t); - IGRAPH_CHECK_OOM(p, "Cannot read GML file."); - IGRAPH_FINALLY(igraph_free, p); - IGRAPH_CHECK(igraph_vector_init(p, no_of_items)); - igraph_vector_fill(p, IGRAPH_NAN); /* use NaN as default */ - atrec->value = p; - IGRAPH_FINALLY_CLEAN(1); - } else if (type == IGRAPH_ATTRIBUTE_STRING) { - igraph_strvector_t *p = IGRAPH_CALLOC(1, igraph_strvector_t); - IGRAPH_CHECK_OOM(p, "Cannot read GML file."); - IGRAPH_FINALLY(igraph_free, p); - IGRAPH_CHECK(igraph_strvector_init(p, no_of_items)); - atrec->value = p; - IGRAPH_FINALLY_CLEAN(1); - } else if (type == IGRAPH_ATTRIBUTE_UNSPECIFIED) { - IGRAPH_WARNINGF("Composite %s attribute '%s' ignored in GML file.", kind, atrec->name); - } else { - /* Must never reach here. */ - IGRAPH_FATAL("Unexpected attribute type."); + igraph_attribute_record_t *atrec = igraph_attribute_record_list_get_ptr(attrs, i); + + /* Ww have unspecified attribute types in the attribute record list at + * this point because we need to keep the same order in the attribute + * record list as it was in the trie that we use to look up an + * attribute record by name. However, we cannot reside unknown attributes + * so we need to take care of this */ + if (atrec->type != IGRAPH_ATTRIBUTE_UNSPECIFIED) { + IGRAPH_CHECK(igraph_attribute_record_resize(atrec, no_of_items)); } } return IGRAPH_SUCCESS; @@ -425,10 +395,8 @@ igraph_error_t igraph_read_graph_gml(igraph_t *graph, FILE *instream) { igraph_trie_t vattrnames; igraph_trie_t eattrnames; igraph_trie_t gattrnames; - igraph_vector_ptr_t gattrs = IGRAPH_VECTOR_PTR_NULL, - vattrs = IGRAPH_VECTOR_PTR_NULL, - eattrs = IGRAPH_VECTOR_PTR_NULL; - igraph_vector_ptr_t *attrs[3]; + igraph_attribute_record_list_t gattrs, vattrs, eattrs; + igraph_attribute_record_list_t *attrs[3]; igraph_integer_t edgeptr = 0; igraph_i_gml_parsedata_t context; igraph_bool_t entity_warned = false; /* used to warn at most once about unsupported entities */ @@ -492,10 +460,12 @@ igraph_error_t igraph_read_graph_gml(igraph_t *graph, FILE *instream) { } gtree = igraph_gml_tree_get_tree(context.tree, gidx); - IGRAPH_FINALLY(igraph_i_gml_destroy_attrs, attrs); - IGRAPH_CHECK(igraph_vector_ptr_init(&gattrs, 0)); - IGRAPH_CHECK(igraph_vector_ptr_init(&vattrs, 0)); - IGRAPH_CHECK(igraph_vector_ptr_init(&eattrs, 0)); + IGRAPH_CHECK(igraph_attribute_record_list_init(&gattrs, 0)); + IGRAPH_FINALLY(igraph_attribute_record_list_destroy, &gattrs); + IGRAPH_CHECK(igraph_attribute_record_list_init(&vattrs, 0)); + IGRAPH_FINALLY(igraph_attribute_record_list_destroy, &vattrs); + IGRAPH_CHECK(igraph_attribute_record_list_init(&eattrs, 0)); + IGRAPH_FINALLY(igraph_attribute_record_list_destroy, &eattrs); IGRAPH_TRIE_INIT_FINALLY(&trie, 0); IGRAPH_TRIE_INIT_FINALLY(&vattrnames, 0); @@ -686,13 +656,12 @@ igraph_error_t igraph_read_graph_gml(igraph_t *graph, FILE *instream) { igraph_attribute_type_t type; igraph_integer_t ai; IGRAPH_CHECK(igraph_trie_get(&vattrnames, aname, &ai)); - atrec = VECTOR(vattrs)[ai]; + atrec = igraph_attribute_record_list_get_ptr(&vattrs, ai); type = atrec->type; if (type == IGRAPH_ATTRIBUTE_NUMERIC) { - igraph_vector_t *v = (igraph_vector_t *) atrec->value; - VECTOR(*v)[trie_id] = igraph_i_gml_toreal(node, j); + VECTOR(*atrec->value.as_vector)[trie_id] = igraph_i_gml_toreal(node, j); } else if (type == IGRAPH_ATTRIBUTE_STRING) { - igraph_strvector_t *v = (igraph_strvector_t *) atrec->value; + igraph_strvector_t *v = atrec->value.as_strvector; const char *value = igraph_i_gml_tostring(node, j); if (needs_coding(value)) { char *value_decoded; @@ -724,13 +693,12 @@ igraph_error_t igraph_read_graph_gml(igraph_t *graph, FILE *instream) { igraph_attribute_record_t *atrec; igraph_attribute_type_t type; IGRAPH_CHECK(igraph_trie_get(&eattrnames, aname, &ai)); - atrec = VECTOR(eattrs)[ai]; + atrec = igraph_attribute_record_list_get_ptr(&eattrs, ai); type = atrec->type; if (type == IGRAPH_ATTRIBUTE_NUMERIC) { - igraph_vector_t *v = (igraph_vector_t *) atrec->value; - VECTOR(*v)[edgeid] = igraph_i_gml_toreal(edge, j); + VECTOR(*atrec->value.as_vector)[edgeid] = igraph_i_gml_toreal(edge, j); } else if (type == IGRAPH_ATTRIBUTE_STRING) { - igraph_strvector_t *v = (igraph_strvector_t *) atrec->value; + igraph_strvector_t *v = atrec->value.as_strvector; const char *value = igraph_i_gml_tostring(edge, j); if (needs_coding(value)) { char *value_decoded; @@ -769,13 +737,12 @@ igraph_error_t igraph_read_graph_gml(igraph_t *graph, FILE *instream) { igraph_attribute_record_t *atrec; igraph_attribute_type_t type; IGRAPH_CHECK(igraph_trie_get(&gattrnames, name, &ai)); - atrec = VECTOR(gattrs)[ai]; + atrec = igraph_attribute_record_list_get_ptr(&gattrs, ai); type = atrec->type; if (type == IGRAPH_ATTRIBUTE_NUMERIC) { - igraph_vector_t *v = (igraph_vector_t *) atrec->value; - VECTOR(*v)[0] = igraph_i_gml_toreal(gtree, i); + VECTOR(*atrec->value.as_vector)[0] = igraph_i_gml_toreal(gtree, i); } else if (type == IGRAPH_ATTRIBUTE_STRING) { - igraph_strvector_t *v = (igraph_strvector_t *) atrec->value; + igraph_strvector_t *v = atrec->value.as_strvector; const char *value = igraph_i_gml_tostring(gtree, i); if (needs_coding(value)) { char *value_decoded; @@ -793,10 +760,10 @@ igraph_error_t igraph_read_graph_gml(igraph_t *graph, FILE *instream) { } } - /* Remove composite attributes */ - prune_unknown_attributes(&vattrs); - prune_unknown_attributes(&eattrs); - prune_unknown_attributes(&gattrs); + /* Remove composite attributes that we cannot represent in igraph */ + IGRAPH_CHECK(prune_unknown_attributes(&vattrs)); + IGRAPH_CHECK(prune_unknown_attributes(&eattrs)); + IGRAPH_CHECK(prune_unknown_attributes(&gattrs)); igraph_trie_destroy(&trie); igraph_trie_destroy(&gattrnames); @@ -811,9 +778,11 @@ igraph_error_t igraph_read_graph_gml(igraph_t *graph, FILE *instream) { IGRAPH_FINALLY_CLEAN(1); /* do not destroy 'graph', just pop it from the stack */ igraph_vector_int_destroy(&edges); - igraph_i_gml_destroy_attrs(attrs); + igraph_attribute_record_list_destroy(&eattrs); + igraph_attribute_record_list_destroy(&vattrs); + igraph_attribute_record_list_destroy(&gattrs); igraph_i_gml_parsedata_destroy(&context); - IGRAPH_FINALLY_CLEAN(3); + IGRAPH_FINALLY_CLEAN(5); return IGRAPH_SUCCESS; } diff --git a/src/vendor/cigraph/src/io/graphml.c b/src/vendor/cigraph/src/io/graphml.c index 2083154d226..23776971329 100644 --- a/src/vendor/cigraph/src/io/graphml.c +++ b/src/vendor/cigraph/src/io/graphml.c @@ -90,17 +90,13 @@ xmlEntityPtr blankEntity = &blankEntityStruct; } while (0) typedef struct igraph_i_graphml_attribute_record_t { - const char *id; /* GraphML id */ + char *id; /* GraphML id */ enum { I_GRAPHML_BOOLEAN, I_GRAPHML_INTEGER, I_GRAPHML_LONG, I_GRAPHML_FLOAT, I_GRAPHML_DOUBLE, I_GRAPHML_STRING, I_GRAPHML_UNKNOWN_TYPE } type; /* GraphML type */ - union { - igraph_real_t as_numeric; - igraph_bool_t as_boolean; - char *as_string; - } default_value; /* Default value of the attribute, if any */ igraph_attribute_record_t record; + igraph_bool_t record_disowned; /* true if ownership of the record was taken over */ } igraph_i_graphml_attribute_record_t; typedef enum { @@ -212,34 +208,16 @@ static igraph_error_t igraph_i_graphml_parse_boolean( } static void igraph_i_graphml_attribute_record_destroy(igraph_i_graphml_attribute_record_t* rec) { - if (rec->record.type == IGRAPH_ATTRIBUTE_NUMERIC) { - if (rec->record.value != 0) { - igraph_vector_destroy((igraph_vector_t*)rec->record.value); - IGRAPH_FREE(rec->record.value); - } - } else if (rec->record.type == IGRAPH_ATTRIBUTE_STRING) { - if (rec->record.value != 0) { - igraph_strvector_destroy((igraph_strvector_t*)rec->record.value); - IGRAPH_FREE(rec->record.value); - } - if (rec->default_value.as_string != 0) { - IGRAPH_FREE(rec->default_value.as_string); - } - } else if (rec->record.type == IGRAPH_ATTRIBUTE_BOOLEAN) { - if (rec->record.value != 0) { - igraph_vector_bool_destroy((igraph_vector_bool_t*)rec->record.value); - IGRAPH_FREE(rec->record.value); - } - } else if (rec->record.type == IGRAPH_ATTRIBUTE_UNSPECIFIED) { - /* no value was set */ + if (!rec->record_disowned) { + igraph_attribute_record_destroy(&rec->record); } + if (rec->id != NULL) { - xmlFree((void *) rec->id); + igraph_free(rec->id); rec->id = NULL; } - if (rec->record.name != 0) { - IGRAPH_FREE(rec->record.name); - } + + memset(rec, 0, sizeof(igraph_i_graphml_attribute_record_t)); } static igraph_error_t igraph_i_graphml_parser_state_init(struct igraph_i_graphml_parser_state* state, igraph_t* graph, igraph_integer_t index) { @@ -410,34 +388,25 @@ static void igraph_i_graphml_sax_handler_start_document(void *state0) { } static igraph_error_t igraph_i_graphml_parser_state_finish_parsing(struct igraph_i_graphml_parser_state *state) { - igraph_integer_t i, l; - igraph_attribute_record_t idrec, eidrec; + igraph_integer_t i; const char *idstr = "id"; igraph_bool_t already_has_vertex_id = false, already_has_edge_id = false; - igraph_vector_ptr_t vattr, eattr, gattr; - igraph_integer_t esize; + igraph_attribute_record_list_t vattr, eattr, gattr; + igraph_attribute_record_t *idrec; IGRAPH_ASSERT(state->successful); /* check that we have found and parsed the graph the user is interested in */ IGRAPH_ASSERT(state->index < 0); - IGRAPH_CHECK(igraph_vector_ptr_init(&vattr, igraph_vector_ptr_size(&state->v_attrs) + 1)); /* +1 for 'id' */ - IGRAPH_FINALLY(igraph_vector_ptr_destroy, &vattr); - igraph_vector_ptr_resize(&vattr, 0); /* will be filled with push_back() */ - - esize = igraph_vector_ptr_size(&state->e_attrs); - if (igraph_strvector_size(&state->edgeids) != 0) { - esize++; - } - IGRAPH_CHECK(igraph_vector_ptr_init(&eattr, esize)); - IGRAPH_FINALLY(igraph_vector_ptr_destroy, &eattr); - igraph_vector_ptr_resize(&eattr, 0); /* will be filled with push_back() */ - - IGRAPH_CHECK(igraph_vector_ptr_init(&gattr, igraph_vector_ptr_size(&state->g_attrs))); - IGRAPH_FINALLY(igraph_vector_ptr_destroy, &gattr); - igraph_vector_ptr_resize(&gattr, 0); /* will be filled with push_back() */ + IGRAPH_CHECK(igraph_attribute_record_list_init(&vattr, 0)); + IGRAPH_FINALLY(igraph_attribute_record_list_destroy, &vattr); + IGRAPH_CHECK(igraph_attribute_record_list_init(&eattr, 0)); + IGRAPH_FINALLY(igraph_attribute_record_list_destroy, &eattr); + IGRAPH_CHECK(igraph_attribute_record_list_init(&gattr, 0)); + IGRAPH_FINALLY(igraph_attribute_record_list_destroy, &gattr); + /* Add default attribute values for vertices where needed */ for (i = 0; i < igraph_vector_ptr_size(&state->v_attrs); i++) { igraph_i_graphml_attribute_record_t *graphmlrec = VECTOR(state->v_attrs)[i]; @@ -445,131 +414,68 @@ static igraph_error_t igraph_i_graphml_parser_state_finish_parsing(struct igraph /* Check that the name of the vertex attribute is not 'id'. * If it is then we cannot add the complementary 'id' attribute. */ - if (! strcmp(rec->name, idstr)) { + if (!strcmp(rec->name, idstr)) { already_has_vertex_id = 1; } - if (rec->type == IGRAPH_ATTRIBUTE_NUMERIC) { - igraph_vector_t *vec = (igraph_vector_t*)rec->value; - igraph_integer_t origsize = igraph_vector_size(vec); - igraph_integer_t nodes = igraph_trie_size(&state->node_trie); - IGRAPH_CHECK(igraph_vector_resize(vec, nodes)); - for (l = origsize; l < nodes; l++) { - VECTOR(*vec)[l] = graphmlrec->default_value.as_numeric; - } - } else if (rec->type == IGRAPH_ATTRIBUTE_STRING) { - igraph_strvector_t *strvec = (igraph_strvector_t*)rec->value; - igraph_integer_t origsize = igraph_strvector_size(strvec); - igraph_integer_t nodes = igraph_trie_size(&state->node_trie); - IGRAPH_CHECK(igraph_strvector_resize(strvec, nodes)); - for (l = origsize; l < nodes; l++) { - IGRAPH_CHECK(igraph_strvector_set(strvec, l, graphmlrec->default_value.as_string)); - } - } else if (rec->type == IGRAPH_ATTRIBUTE_BOOLEAN) { - igraph_vector_bool_t *boolvec = (igraph_vector_bool_t*)rec->value; - igraph_integer_t origsize = igraph_vector_bool_size(boolvec); - igraph_integer_t nodes = igraph_trie_size(&state->node_trie); - IGRAPH_CHECK(igraph_vector_bool_resize(boolvec, nodes)); - for (l = origsize; l < nodes; l++) { - VECTOR(*boolvec)[l] = graphmlrec->default_value.as_boolean; - } - } else if (rec->type == IGRAPH_ATTRIBUTE_UNSPECIFIED) { - continue; /* skipped attribute */ + if (rec->type != IGRAPH_ATTRIBUTE_UNSPECIFIED) { + IGRAPH_CHECK(igraph_attribute_record_resize(rec, igraph_trie_size(&state->node_trie))); + IGRAPH_CHECK(igraph_attribute_record_list_push_back(&vattr, rec)); + graphmlrec->record_disowned = true; } - igraph_vector_ptr_push_back(&vattr, rec); /* reserved */ } + + /* Add vertex ID attribute if needed */ if (!already_has_vertex_id) { - idrec.name = idstr; - idrec.type = IGRAPH_ATTRIBUTE_STRING; - idrec.value = igraph_i_trie_borrow_keys(&state->node_trie); - igraph_vector_ptr_push_back(&vattr, &idrec); /* reserved */ + IGRAPH_CHECK(igraph_attribute_record_list_push_back_new(&vattr, &idrec)); + IGRAPH_CHECK(igraph_attribute_record_set_name(idrec, idstr)); + IGRAPH_CHECK(igraph_attribute_record_set_type(idrec, IGRAPH_ATTRIBUTE_STRING)); + IGRAPH_CHECK(igraph_strvector_update(idrec->value.as_strvector, igraph_i_trie_borrow_keys(&state->node_trie))); } else { IGRAPH_WARNING("Could not add vertex ids, there is already an 'id' vertex attribute."); } + /* Add default attribute values for edges where needed */ for (i = 0; i < igraph_vector_ptr_size(&state->e_attrs); i++) { igraph_i_graphml_attribute_record_t *graphmlrec = VECTOR(state->e_attrs)[i]; igraph_attribute_record_t *rec = &graphmlrec->record; - if (! strcmp(rec->name, idstr)) { + if (!strcmp(rec->name, idstr)) { already_has_edge_id = 1; } - if (rec->type == IGRAPH_ATTRIBUTE_NUMERIC) { - igraph_vector_t *vec = (igraph_vector_t*)rec->value; - igraph_integer_t origsize = igraph_vector_size(vec); - igraph_integer_t edges = igraph_vector_int_size(&state->edgelist) / 2; - IGRAPH_CHECK(igraph_vector_resize(vec, edges)); - for (l = origsize; l < edges; l++) { - VECTOR(*vec)[l] = graphmlrec->default_value.as_numeric; - } - } else if (rec->type == IGRAPH_ATTRIBUTE_STRING) { - igraph_strvector_t *strvec = (igraph_strvector_t*)rec->value; - igraph_integer_t origsize = igraph_strvector_size(strvec); - igraph_integer_t edges = igraph_vector_int_size(&state->edgelist) / 2; - IGRAPH_CHECK(igraph_strvector_resize(strvec, edges)); - for (l = origsize; l < edges; l++) { - IGRAPH_CHECK(igraph_strvector_set(strvec, l, graphmlrec->default_value.as_string)); - } - } else if (rec->type == IGRAPH_ATTRIBUTE_BOOLEAN) { - igraph_vector_bool_t *boolvec = (igraph_vector_bool_t*)rec->value; - igraph_integer_t origsize = igraph_vector_bool_size(boolvec); - igraph_integer_t edges = igraph_vector_int_size(&state->edgelist) / 2; - IGRAPH_CHECK(igraph_vector_bool_resize(boolvec, edges)); - for (l = origsize; l < edges; l++) { - VECTOR(*boolvec)[l] = graphmlrec->default_value.as_boolean; - } - } else if (rec->type == IGRAPH_ATTRIBUTE_UNSPECIFIED) { - continue; /* skipped attribute */ + if (rec->type != IGRAPH_ATTRIBUTE_UNSPECIFIED) { + IGRAPH_CHECK(igraph_attribute_record_resize(rec, igraph_vector_int_size(&state->edgelist) / 2)); + IGRAPH_CHECK(igraph_attribute_record_list_push_back(&eattr, rec)); + graphmlrec->record_disowned = true; } - igraph_vector_ptr_push_back(&eattr, rec); /* reserved */ } + + /* Add edge ID attribute if needed */ if (igraph_strvector_size(&state->edgeids) != 0) { if (!already_has_edge_id) { - igraph_integer_t origsize = igraph_strvector_size(&state->edgeids); - eidrec.name = idstr; - eidrec.type = IGRAPH_ATTRIBUTE_STRING; - IGRAPH_CHECK(igraph_strvector_resize(&state->edgeids, igraph_vector_int_size(&state->edgelist) / 2)); - for (; origsize < igraph_strvector_size(&state->edgeids); origsize++) { - IGRAPH_CHECK(igraph_strvector_set(&state->edgeids, origsize, "")); - } - eidrec.value = &state->edgeids; - igraph_vector_ptr_push_back(&eattr, &eidrec); /* reserved */ + IGRAPH_CHECK(igraph_attribute_record_list_push_back_new(&eattr, &idrec)); + IGRAPH_CHECK(igraph_attribute_record_set_name(idrec, idstr)); + IGRAPH_CHECK(igraph_attribute_record_set_type(idrec, IGRAPH_ATTRIBUTE_STRING)); + IGRAPH_CHECK(igraph_strvector_update(idrec->value.as_strvector, igraph_i_trie_borrow_keys(&state->node_trie))); + IGRAPH_CHECK(igraph_attribute_record_resize(idrec, igraph_vector_int_size(&state->edgelist) / 2)); } else { IGRAPH_WARNING("Could not add edge ids, there is already an 'id' edge attribute."); } } + /* Add default graph attribute values where needed */ for (i = 0; i < igraph_vector_ptr_size(&state->g_attrs); i++) { igraph_i_graphml_attribute_record_t *graphmlrec = VECTOR(state->g_attrs)[i]; igraph_attribute_record_t *rec = &graphmlrec->record; - if (rec->type == IGRAPH_ATTRIBUTE_NUMERIC) { - igraph_vector_t *vec = (igraph_vector_t*)rec->value; - igraph_integer_t origsize = igraph_vector_size(vec); - IGRAPH_CHECK(igraph_vector_resize(vec, 1)); - for (l = origsize; l < 1; l++) { - VECTOR(*vec)[l] = graphmlrec->default_value.as_numeric; - } - } else if (rec->type == IGRAPH_ATTRIBUTE_STRING) { - igraph_strvector_t *strvec = (igraph_strvector_t*)rec->value; - igraph_integer_t origsize = igraph_strvector_size(strvec); - IGRAPH_CHECK(igraph_strvector_resize(strvec, 1)); - for (l = origsize; l < 1; l++) { - IGRAPH_CHECK(igraph_strvector_set(strvec, l, graphmlrec->default_value.as_string)); - } - } else if (rec->type == IGRAPH_ATTRIBUTE_BOOLEAN) { - igraph_vector_bool_t *boolvec = (igraph_vector_bool_t*)rec->value; - igraph_integer_t origsize = igraph_vector_bool_size(boolvec); - IGRAPH_CHECK(igraph_vector_bool_resize(boolvec, 1)); - for (l = origsize; l < 1; l++) { - VECTOR(*boolvec)[l] = graphmlrec->default_value.as_boolean; - } - } else if (rec->type == IGRAPH_ATTRIBUTE_UNSPECIFIED) { - continue; /* skipped attribute */ + + if (rec->type != IGRAPH_ATTRIBUTE_UNSPECIFIED) { + IGRAPH_CHECK(igraph_attribute_record_resize(rec, 1)); + IGRAPH_CHECK(igraph_attribute_record_list_push_back(&gattr, rec)); + graphmlrec->record_disowned = true; } - igraph_vector_ptr_push_back(&gattr, rec); /* reserved */ } IGRAPH_CHECK(igraph_empty_attrs(state->g, 0, state->edges_directed, &gattr)); @@ -578,9 +484,9 @@ static igraph_error_t igraph_i_graphml_parser_state_finish_parsing(struct igraph IGRAPH_CHECK(igraph_add_edges(state->g, &state->edgelist, &eattr)); IGRAPH_FINALLY_CLEAN(1); /* graph construction completed successfully */ - igraph_vector_ptr_destroy(&vattr); - igraph_vector_ptr_destroy(&eattr); - igraph_vector_ptr_destroy(&gattr); + igraph_attribute_record_list_destroy(&vattr); + igraph_attribute_record_list_destroy(&eattr); + igraph_attribute_record_list_destroy(&gattr); IGRAPH_FINALLY_CLEAN(3); return IGRAPH_SUCCESS; @@ -595,6 +501,34 @@ static igraph_error_t igraph_i_graphml_parser_state_finish_parsing(struct igraph #define XML_ATTR_VALUE(it) *(it+3), (int)((*(it+4))-(*(it+3))) #define XML_ATTR_VALUE_PF(it) (int)((*(it+4))-(*(it+3))), *(it+3) /* for use in printf-style function with "%.*s" */ +static igraph_error_t safely_convert_xml_attribute_to_string(xmlChar** it, char** str) { + /* This is quite convoluted but we need to go safely from xmlChar*-world + * to char*-world */ + xmlChar *xml_str; + char *c_str; + + xml_str = xmlStrndup(XML_ATTR_VALUE(it)); + IGRAPH_CHECK_OOM(xml_str, "Insufficient memory to duplicate attribute value."); + IGRAPH_FINALLY(xmlFree, xml_str); + + c_str = strdup(fromXmlChar(xml_str)); + IGRAPH_CHECK_OOM(c_str, "Insufficient memory to duplicate attribute value."); + + *str = c_str; + + xmlFree(xml_str); + IGRAPH_FINALLY_CLEAN(1); + + return IGRAPH_SUCCESS; +} + +static void safely_free_optional_string(char** str) { + if (*str != NULL) { + igraph_free(*str); + *str = NULL; + } +} + static igraph_bool_t xmlAttrValueEqual(xmlChar** attr, const char* expected) { size_t expected_length = strlen(expected); return ( @@ -623,27 +557,30 @@ static igraph_error_t igraph_i_graphml_add_attribute_key( xmlChar **it; xmlChar *localname; - xmlChar *xmlStr; igraph_trie_t *trie = NULL; igraph_vector_ptr_t *ptrvector = NULL; igraph_integer_t i, n; igraph_integer_t id; igraph_i_graphml_attribute_record_t *rec = NULL; + char *attr_name; + igraph_attribute_type_t igraph_attr_type; igraph_bool_t skip = false; + attr_name = NULL; + IGRAPH_FINALLY(safely_free_optional_string, &attr_name); + if (!state->successful) { /* Parser is already in an error state */ goto exit; } rec = IGRAPH_CALLOC(1, igraph_i_graphml_attribute_record_t); - if (rec == NULL) { - IGRAPH_ERROR("Cannot allocate attribute record.", IGRAPH_ENOMEM); /* LCOV_EXCL_LINE */ - } + IGRAPH_CHECK_OOM(rec, "Insufficient memory to allocate attribute record."); IGRAPH_FINALLY(igraph_free, rec); IGRAPH_FINALLY(igraph_i_graphml_attribute_record_destroy, rec); + memset(rec, 0, sizeof(igraph_i_graphml_attribute_record_t)); - rec->type = I_GRAPHML_UNKNOWN_TYPE; + igraph_attr_type = IGRAPH_ATTRIBUTE_UNSPECIFIED; for (i = 0, it = (xmlChar**)attrs; i < nb_attrs; i++, it += 5) { if (XML_ATTR_URI(it) != 0 && @@ -654,42 +591,29 @@ static igraph_error_t igraph_i_graphml_add_attribute_key( localname = XML_ATTR_LOCALNAME(it); if (xmlStrEqual(localname, toXmlChar("id"))) { - xmlStr = xmlStrndup(XML_ATTR_VALUE(it)); - IGRAPH_CHECK_OOM(xmlStr, "Cannot duplicate value of 'id' attribute."); - rec->id = fromXmlChar(xmlStr); - xmlStr = NULL; + IGRAPH_CHECK(safely_convert_xml_attribute_to_string(it, &rec->id)); } else if (xmlStrEqual(localname, toXmlChar("attr.name"))) { - xmlStr = xmlStrndup(XML_ATTR_VALUE(it)); - IGRAPH_CHECK_OOM(xmlStr, "Cannot duplicate value of 'attr.name' attribute."); - rec->record.name = fromXmlChar(xmlStr); - xmlStr = NULL; + safely_free_optional_string(&attr_name); + IGRAPH_CHECK(safely_convert_xml_attribute_to_string(it, &attr_name)); } else if (xmlStrEqual(localname, toXmlChar("attr.type"))) { if (xmlAttrValueEqual(it, "boolean")) { + igraph_attr_type = IGRAPH_ATTRIBUTE_BOOLEAN; rec->type = I_GRAPHML_BOOLEAN; - rec->record.type = IGRAPH_ATTRIBUTE_BOOLEAN; - rec->default_value.as_boolean = 0; } else if (xmlAttrValueEqual(it, "string")) { - char *str = strdup(""); - IGRAPH_CHECK_OOM(str, "Cannot allocate new empty string."); + igraph_attr_type = IGRAPH_ATTRIBUTE_STRING; rec->type = I_GRAPHML_STRING; - rec->record.type = IGRAPH_ATTRIBUTE_STRING; - rec->default_value.as_string = str; } else if (xmlAttrValueEqual(it, "float")) { + igraph_attr_type = IGRAPH_ATTRIBUTE_NUMERIC; rec->type = I_GRAPHML_FLOAT; - rec->record.type = IGRAPH_ATTRIBUTE_NUMERIC; - rec->default_value.as_numeric = IGRAPH_NAN; } else if (xmlAttrValueEqual(it, "double")) { + igraph_attr_type = IGRAPH_ATTRIBUTE_NUMERIC; rec->type = I_GRAPHML_DOUBLE; - rec->record.type = IGRAPH_ATTRIBUTE_NUMERIC; - rec->default_value.as_numeric = IGRAPH_NAN; } else if (xmlAttrValueEqual(it, "int")) { + igraph_attr_type = IGRAPH_ATTRIBUTE_NUMERIC; rec->type = I_GRAPHML_INTEGER; - rec->record.type = IGRAPH_ATTRIBUTE_NUMERIC; - rec->default_value.as_numeric = IGRAPH_NAN; } else if (xmlAttrValueEqual(it, "long")) { + igraph_attr_type = IGRAPH_ATTRIBUTE_NUMERIC; rec->type = I_GRAPHML_LONG; - rec->record.type = IGRAPH_ATTRIBUTE_NUMERIC; - rec->default_value.as_numeric = IGRAPH_NAN; } else { IGRAPH_ERRORF("Unknown attribute type '%.*s'.", IGRAPH_PARSEERROR, XML_ATTR_VALUE_PF(it)); @@ -739,9 +663,11 @@ static igraph_error_t igraph_i_graphml_add_attribute_key( } /* in case of a missing attr.name attribute, use the id as the attribute name */ - if (rec->record.name == NULL) { - rec->record.name = strdup(rec->id); - IGRAPH_CHECK_OOM(rec->record.name, "Cannot duplicate attribute ID as name."); + if (attr_name == NULL) { + /* Allocation here is protected by safely_free_optional_string(&attr_name), + * which is already in the finally stack */ + attr_name = strdup(rec->id); + IGRAPH_CHECK_OOM(attr_name, "Cannot duplicate attribute ID as name."); } /* if the attribute type is missing, ignore the attribute with a warning */ @@ -750,9 +676,10 @@ static igraph_error_t igraph_i_graphml_add_attribute_key( skip = 1; } - /* if the value of the 'for' attribute was unknown, throw an error */ + /* if the value of the 'for' attribute was missing, ignore the attribute with a warning */ if (!skip && trie == 0) { - IGRAPH_ERROR("Missing 'for' attribute in a tag.", IGRAPH_PARSEERROR); + IGRAPH_WARNINGF("Ignoring because of a missing 'for' attribute.", rec->id); + skip = 1; } /* If attribute is skipped, proceed according to the type of the associated graph element. */ @@ -770,7 +697,7 @@ static igraph_error_t igraph_i_graphml_add_attribute_key( /* If the skipped attribute was for a supported graph element, we add it * as "UNSPECIFIED" so that we can avoid reporting "unknown attribute" warnings * later. */ - rec->record.type = IGRAPH_ATTRIBUTE_UNSPECIFIED; + igraph_attr_type = IGRAPH_ATTRIBUTE_UNSPECIFIED; } } @@ -784,12 +711,12 @@ static igraph_error_t igraph_i_graphml_add_attribute_key( n = igraph_vector_ptr_size(ptrvector); for (i = 0; i < n; i++) { if (!strcmp( - rec->record.name, + attr_name, ((igraph_i_graphml_attribute_record_t*) igraph_vector_ptr_get(ptrvector, i))->record.name )) { IGRAPH_ERRORF( "Duplicate attribute name found: '%s' (for ).", - IGRAPH_PARSEERROR, rec->record.name, rec->id + IGRAPH_PARSEERROR, attr_name, rec->id ); } } @@ -803,42 +730,12 @@ static igraph_error_t igraph_i_graphml_add_attribute_key( IGRAPH_FINALLY_CLEAN(2); /* create the attribute values */ - switch (rec->record.type) { - igraph_vector_t *vec; - igraph_vector_bool_t *boolvec; - igraph_strvector_t *strvec; - case IGRAPH_ATTRIBUTE_BOOLEAN: - boolvec = IGRAPH_CALLOC(1, igraph_vector_bool_t); - IGRAPH_CHECK_OOM(boolvec, "Cannot allocate value vector for Boolean attribute."); - IGRAPH_FINALLY(igraph_free, boolvec); - IGRAPH_CHECK(igraph_vector_bool_init(boolvec, 0)); - rec->record.value = boolvec; - IGRAPH_FINALLY_CLEAN(1); - break; - case IGRAPH_ATTRIBUTE_NUMERIC: - vec = IGRAPH_CALLOC(1, igraph_vector_t); - IGRAPH_CHECK_OOM(vec, "Cannot allocate value vector for numeric attribute."); - IGRAPH_FINALLY(igraph_free, vec); - IGRAPH_CHECK(igraph_vector_init(vec, 0)); - rec->record.value = vec; - IGRAPH_FINALLY_CLEAN(1); - break; - case IGRAPH_ATTRIBUTE_STRING: - strvec = IGRAPH_CALLOC(1, igraph_strvector_t); - IGRAPH_CHECK_OOM(strvec, "Cannot allocate value vector for string attribute."); - IGRAPH_FINALLY(igraph_free, strvec); - IGRAPH_CHECK(igraph_strvector_init(strvec, 0)); - rec->record.value = strvec; - IGRAPH_FINALLY_CLEAN(1); - break; - case IGRAPH_ATTRIBUTE_UNSPECIFIED: - rec->record.value = NULL; - break; - default: - IGRAPH_FATAL("Unexpected attribute type."); - } + IGRAPH_CHECK(igraph_attribute_record_init(&rec->record, attr_name, igraph_attr_type)); exit: + safely_free_optional_string(&attr_name); + IGRAPH_FINALLY_CLEAN(1); + *record = rec; return IGRAPH_SUCCESS; } @@ -961,55 +858,35 @@ static igraph_error_t igraph_i_graphml_attribute_data_finish(struct igraph_i_gra graphmlrec = VECTOR(*ptrvector)[recid]; rec = &graphmlrec->record; + if (id >= igraph_attribute_record_size(rec) && rec->type != IGRAPH_ATTRIBUTE_UNSPECIFIED) { + IGRAPH_CHECK(igraph_attribute_record_resize(rec, id + 1)); + } + switch (rec->type) { igraph_vector_bool_t *boolvec; igraph_vector_t *vec; igraph_strvector_t *strvec; - igraph_integer_t s, i; const char* strvalue; case IGRAPH_ATTRIBUTE_BOOLEAN: - boolvec = (igraph_vector_bool_t *)rec->value; - s = igraph_vector_bool_size(boolvec); - if (id >= s) { - IGRAPH_CHECK(igraph_vector_bool_resize(boolvec, id + 1)); - for (i = s; i < id; i++) { - VECTOR(*boolvec)[i] = graphmlrec->default_value.as_boolean; - } - } + boolvec = rec->value.as_vector_bool; IGRAPH_CHECK(igraph_i_graphml_parse_boolean( - state->data_char, VECTOR(*boolvec) + id, graphmlrec->default_value.as_boolean + state->data_char, VECTOR(*boolvec) + id, rec->default_value.boolean )); break; case IGRAPH_ATTRIBUTE_NUMERIC: - vec = (igraph_vector_t *)rec->value; - s = igraph_vector_size(vec); - if (id >= s) { - IGRAPH_CHECK(igraph_vector_resize(vec, id + 1)); - for (i = s; i < id; i++) { - VECTOR(*vec)[i] = graphmlrec->default_value.as_numeric; - } - } + vec = rec->value.as_vector; IGRAPH_CHECK(igraph_i_graphml_parse_numeric( - state->data_char, VECTOR(*vec) + id, - graphmlrec->default_value.as_numeric + state->data_char, VECTOR(*vec) + id, rec->default_value.numeric )); break; case IGRAPH_ATTRIBUTE_STRING: - strvec = (igraph_strvector_t *)rec->value; - s = igraph_strvector_size(strvec); - if (id >= s) { - IGRAPH_CHECK(igraph_strvector_resize(strvec, id + 1)); - strvalue = graphmlrec->default_value.as_string; - for (i = s; i < id; i++) { - IGRAPH_CHECK(igraph_strvector_set(strvec, i, strvalue)); - } - } + strvec = rec->value.as_strvector; if (state->data_char) { strvalue = state->data_char; } else { - strvalue = graphmlrec->default_value.as_string; + strvalue = rec->default_value.string; } - IGRAPH_CHECK(igraph_strvector_set(strvec, id, strvalue)); + IGRAPH_CHECK(igraph_strvector_set(strvec, id, strvalue ? strvalue : "")); break; case IGRAPH_ATTRIBUTE_UNSPECIFIED: break; @@ -1028,8 +905,10 @@ static igraph_error_t igraph_i_graphml_attribute_data_finish(struct igraph_i_gra static igraph_error_t igraph_i_graphml_attribute_default_value_finish(struct igraph_i_graphml_parser_state *state) { igraph_i_graphml_attribute_record_t *graphmlrec = state->current_attr_record; + igraph_attribute_record_t *rec; igraph_error_t result = IGRAPH_SUCCESS; - char* str = 0; + igraph_real_t default_num; + igraph_bool_t default_bool; IGRAPH_ASSERT(state->current_attr_record != NULL); @@ -1037,26 +916,19 @@ static igraph_error_t igraph_i_graphml_attribute_default_value_finish(struct igr return IGRAPH_SUCCESS; } - switch (graphmlrec->record.type) { + rec = &graphmlrec->record; + + switch (rec->type) { case IGRAPH_ATTRIBUTE_BOOLEAN: - IGRAPH_CHECK(igraph_i_graphml_parse_boolean( - state->data_char, &graphmlrec->default_value.as_boolean, 0 - )); + IGRAPH_CHECK(igraph_i_graphml_parse_boolean(state->data_char, &default_bool, false)); + IGRAPH_CHECK(igraph_attribute_record_set_default_boolean(rec, default_bool)); break; case IGRAPH_ATTRIBUTE_NUMERIC: - IGRAPH_CHECK(igraph_i_graphml_parse_numeric( - state->data_char, &graphmlrec->default_value.as_numeric, IGRAPH_NAN - )); + IGRAPH_CHECK(igraph_i_graphml_parse_numeric(state->data_char, &default_num, IGRAPH_NAN)); + IGRAPH_CHECK(igraph_attribute_record_set_default_numeric(rec, default_num)); break; case IGRAPH_ATTRIBUTE_STRING: - str = strdup(state->data_char); - IGRAPH_CHECK_OOM(str, "Cannot allocate memory for string attribute."); - - if (graphmlrec->default_value.as_string != 0) { - IGRAPH_FREE(graphmlrec->default_value.as_string); - } - graphmlrec->default_value.as_string = str; - str = NULL; + IGRAPH_CHECK(igraph_attribute_record_set_default_string(rec, state->data_char)); break; case IGRAPH_ATTRIBUTE_UNSPECIFIED: break; @@ -1516,9 +1388,7 @@ static igraph_error_t igraph_i_xml_escape(const char* src, char** dest) { } } *dest = IGRAPH_CALLOC(destlen + 1, char); - if (!*dest) { - IGRAPH_ERROR("Not enough memory.", IGRAPH_ENOMEM); /* LCOV_EXCL_LINE */ - } + IGRAPH_CHECK_OOM(*dest, "Insufficient memory."); for (s = src, d = *dest; *s; s++, d++) { ch = (unsigned char)(*s); switch (ch) { diff --git a/src/vendor/cigraph/src/io/leda.c b/src/vendor/cigraph/src/io/leda.c index cf742cdde62..51e2cd9380c 100644 --- a/src/vendor/cigraph/src/io/leda.c +++ b/src/vendor/cigraph/src/io/leda.c @@ -84,7 +84,7 @@ igraph_error_t igraph_write_graph_leda(const igraph_t *graph, FILE *outstream, vertex_attr_name = NULL; } if (vertex_attr_name) { - IGRAPH_CHECK(igraph_i_attribute_gettype(graph, &vertex_attr_type, + IGRAPH_CHECK(igraph_i_attribute_get_type(graph, &vertex_attr_type, IGRAPH_ATTRIBUTE_VERTEX, vertex_attr_name)); if (vertex_attr_type != IGRAPH_ATTRIBUTE_NUMERIC && vertex_attr_type != IGRAPH_ATTRIBUTE_STRING && @@ -104,7 +104,7 @@ igraph_error_t igraph_write_graph_leda(const igraph_t *graph, FILE *outstream, edge_attr_name = NULL; } if (edge_attr_name) { - IGRAPH_CHECK(igraph_i_attribute_gettype(graph, &edge_attr_type, + IGRAPH_CHECK(igraph_i_attribute_get_type(graph, &edge_attr_type, IGRAPH_ATTRIBUTE_EDGE, edge_attr_name)); if (edge_attr_type != IGRAPH_ATTRIBUTE_NUMERIC && edge_attr_type != IGRAPH_ATTRIBUTE_STRING && diff --git a/src/vendor/cigraph/src/io/lgl-parser.y b/src/vendor/cigraph/src/io/lgl-parser.y index 792bbbfab28..5d439f3ff7e 100644 --- a/src/vendor/cigraph/src/io/lgl-parser.y +++ b/src/vendor/cigraph/src/io/lgl-parser.y @@ -103,7 +103,7 @@ edges : /* empty */ | edges edge ; edge : edgeid NEWLINE { IGRAPH_YY_CHECK(igraph_vector_int_push_back(context->vector, context->actvertex)); IGRAPH_YY_CHECK(igraph_vector_int_push_back(context->vector, $1)); - IGRAPH_YY_CHECK(igraph_vector_push_back(context->weights, 0)); + IGRAPH_YY_CHECK(igraph_vector_push_back(context->weights, 1.0)); } | edgeid weight NEWLINE { IGRAPH_YY_CHECK(igraph_vector_int_push_back(context->vector, context->actvertex)); diff --git a/src/vendor/cigraph/src/io/lgl.c b/src/vendor/cigraph/src/io/lgl.c index 37c6d7e2b17..7b9f072f632 100644 --- a/src/vendor/cigraph/src/io/lgl.c +++ b/src/vendor/cigraph/src/io/lgl.c @@ -77,10 +77,11 @@ vertex3name [optionalWeight] \endverbatim * graph as an edge attribute called \quote weight\endquote. * \c IGRAPH_ADD_WEIGHTS_YES adds the weights (even if they * are not present in the file, in this case they are assumed - * to be zero). \c IGRAPH_ADD_WEIGHTS_NO does not add any + * to be 1). \c IGRAPH_ADD_WEIGHTS_NO does not add any * edge attribute. \c IGRAPH_ADD_WEIGHTS_IF_PRESENT adds the * attribute if and only if there is at least one explicit - * edge weight in the input file. + * edge weight in the input file, and edges without an explicit + * weight are assumed to have a weight of 1. * \param directed Whether to create a directed graph. As this format * was originally used only for undirected graphs there is no * information in the file about the directedness of the graph. @@ -109,9 +110,9 @@ igraph_error_t igraph_read_graph_lgl(igraph_t *graph, FILE *instream, igraph_vector_int_t edges = IGRAPH_VECTOR_NULL; igraph_vector_t ws = IGRAPH_VECTOR_NULL; igraph_trie_t trie = IGRAPH_TRIE_NULL; - igraph_vector_ptr_t name, weight; - igraph_vector_ptr_t *pname = 0, *pweight = 0; - igraph_attribute_record_t namerec, weightrec; + igraph_attribute_record_list_t name, weight; + igraph_attribute_record_list_t *pname = NULL, *pweight = NULL; + igraph_attribute_record_t *namerec, *weightrec; const char *namestr = "name", *weightstr = "weight"; igraph_i_lgl_parsedata_t context; @@ -159,27 +160,30 @@ igraph_error_t igraph_read_graph_lgl(igraph_t *graph, FILE *instream, IGRAPH_FATALF("Parser returned unexpected error code (%d) when reading LGL file.", err); } - /* Prepare attributes, if needed */ - + /* Prepare attributes if needed */ if (names) { - IGRAPH_CHECK(igraph_vector_ptr_init(&name, 1)); - IGRAPH_FINALLY(igraph_vector_ptr_destroy, &name); + IGRAPH_CHECK(igraph_attribute_record_list_init(&name, 1)); + IGRAPH_FINALLY(igraph_attribute_record_list_destroy, &name); + + namerec = igraph_attribute_record_list_get_ptr(&name, 0); + IGRAPH_CHECK(igraph_attribute_record_set_name(namerec, namestr)); + IGRAPH_CHECK(igraph_attribute_record_set_type(namerec, IGRAPH_ATTRIBUTE_STRING)); + IGRAPH_CHECK(igraph_strvector_update( + namerec->value.as_strvector, igraph_i_trie_borrow_keys(context.trie)) + ); + pname = &name; - namerec.name = namestr; - namerec.type = IGRAPH_ATTRIBUTE_STRING; - namerec.value = igraph_i_trie_borrow_keys(&trie); - VECTOR(name)[0] = &namerec; } if (weights == IGRAPH_ADD_WEIGHTS_YES || (weights == IGRAPH_ADD_WEIGHTS_IF_PRESENT && context.has_weights)) { - IGRAPH_CHECK(igraph_vector_ptr_init(&weight, 1)); - IGRAPH_FINALLY(igraph_vector_ptr_destroy, &weight); - pweight = &weight; - weightrec.name = weightstr; - weightrec.type = IGRAPH_ATTRIBUTE_NUMERIC; - weightrec.value = &ws; - VECTOR(weight)[0] = &weightrec; + IGRAPH_CHECK(igraph_attribute_record_list_init(&weight, 1)); + IGRAPH_FINALLY(igraph_attribute_record_list_destroy, &weight); + + weightrec = igraph_attribute_record_list_get_ptr(&weight, 0); + IGRAPH_CHECK(igraph_attribute_record_set_name(weightrec, weightstr)); + IGRAPH_CHECK(igraph_attribute_record_set_type(weightrec, IGRAPH_ATTRIBUTE_NUMERIC)); + igraph_vector_swap(weightrec->value.as_vector, context.weights); } /* Create graph */ @@ -189,11 +193,11 @@ igraph_error_t igraph_read_graph_lgl(igraph_t *graph, FILE *instream, IGRAPH_CHECK(igraph_add_edges(graph, &edges, pweight)); if (pweight) { - igraph_vector_ptr_destroy(pweight); + igraph_attribute_record_list_destroy(pweight); IGRAPH_FINALLY_CLEAN(1); } if (pname) { - igraph_vector_ptr_destroy(pname); + igraph_attribute_record_list_destroy(pname); IGRAPH_FINALLY_CLEAN(1); } igraph_trie_destroy(&trie); @@ -280,7 +284,7 @@ igraph_error_t igraph_write_graph_lgl(const igraph_t *graph, FILE *outstream, names = NULL; } if (names) { - IGRAPH_CHECK(igraph_i_attribute_gettype(graph, &nametype, + IGRAPH_CHECK(igraph_i_attribute_get_type(graph, &nametype, IGRAPH_ATTRIBUTE_VERTEX, names)); if (nametype != IGRAPH_ATTRIBUTE_STRING) { IGRAPH_WARNINGF("Ignoring names attribute '%s', unknown attribute type.", names); @@ -294,7 +298,7 @@ igraph_error_t igraph_write_graph_lgl(const igraph_t *graph, FILE *outstream, weights = NULL; } if (weights) { - IGRAPH_CHECK(igraph_i_attribute_gettype(graph, &weighttype, + IGRAPH_CHECK(igraph_i_attribute_get_type(graph, &weighttype, IGRAPH_ATTRIBUTE_EDGE, weights)); if (weighttype != IGRAPH_ATTRIBUTE_NUMERIC) { IGRAPH_WARNINGF("Ignoring weights attribute '%s', unknown attribute type.", weights); diff --git a/src/vendor/cigraph/src/io/ncol-parser.y b/src/vendor/cigraph/src/io/ncol-parser.y index caec463cc29..e5bff3be2ec 100644 --- a/src/vendor/cigraph/src/io/ncol-parser.y +++ b/src/vendor/cigraph/src/io/ncol-parser.y @@ -95,7 +95,7 @@ input : /* empty */ ; edge : endpoints NEWLINE { - IGRAPH_YY_CHECK(igraph_vector_push_back(context->weights, 0.0)); + IGRAPH_YY_CHECK(igraph_vector_push_back(context->weights, 1.0)); } | endpoints weight NEWLINE { IGRAPH_YY_CHECK(igraph_vector_push_back(context->weights, $2)); diff --git a/src/vendor/cigraph/src/io/ncol.c b/src/vendor/cigraph/src/io/ncol.c index 8a06461b24f..f9ee490d196 100644 --- a/src/vendor/cigraph/src/io/ncol.c +++ b/src/vendor/cigraph/src/io/ncol.c @@ -81,10 +81,11 @@ void igraph_ncol_yylex_destroy_wrapper (void *scanner ) { * graph as an edge attribute called \quote weight\endquote. * \c IGRAPH_ADD_WEIGHTS_YES adds the weights (even if they * are not present in the file, in this case they are assumed - * to be zero). \c IGRAPH_ADD_WEIGHTS_NO does not add any + * to be 1). \c IGRAPH_ADD_WEIGHTS_NO does not add any * edge attribute. \c IGRAPH_ADD_WEIGHTS_IF_PRESENT adds the * attribute if and only if there is at least one explicit - * edge weight in the input file. + * edge weight in the input file, and edges without an explicit + * weight are assumed to have a weight of 1. * \param directed Whether to create a directed graph. As this format * was originally used only for undirected graphs there is no * information in the file about the directedness of the graph. @@ -114,9 +115,9 @@ igraph_error_t igraph_read_graph_ncol(igraph_t *graph, FILE *instream, igraph_trie_t trie = IGRAPH_TRIE_NULL; igraph_integer_t no_of_nodes; igraph_integer_t no_predefined = 0; - igraph_vector_ptr_t name, weight; - igraph_vector_ptr_t *pname = NULL, *pweight = NULL; - igraph_attribute_record_t namerec, weightrec; + igraph_attribute_record_list_t name, weight; + igraph_attribute_record_list_t *pname = NULL, *pweight = NULL; + igraph_attribute_record_t *namerec, *weightrec; const char *namestr = "name", *weightstr = "weight"; igraph_i_ncol_parsedata_t context; @@ -185,28 +186,32 @@ igraph_error_t igraph_read_graph_ncol(igraph_t *graph, FILE *instream, IGRAPH_WARNING("Unknown vertex/vertices found in NCOL file, predefined names extended."); } - /* Prepare attributes, if needed */ - + /* Prepare attributes if needed */ if (names) { - IGRAPH_CHECK(igraph_vector_ptr_init(&name, 1)); - IGRAPH_FINALLY(igraph_vector_ptr_destroy, &name); + IGRAPH_CHECK(igraph_attribute_record_list_init(&name, 1)); + IGRAPH_FINALLY(igraph_attribute_record_list_destroy, &name); + + namerec = igraph_attribute_record_list_get_ptr(&name, 0); + IGRAPH_CHECK(igraph_attribute_record_set_name(namerec, namestr)); + IGRAPH_CHECK(igraph_attribute_record_set_type(namerec, IGRAPH_ATTRIBUTE_STRING)); + IGRAPH_CHECK(igraph_strvector_update( + namerec->value.as_strvector, igraph_i_trie_borrow_keys(context.trie)) + ); + pname = &name; - namerec.name = namestr; - namerec.type = IGRAPH_ATTRIBUTE_STRING; - namerec.value = igraph_i_trie_borrow_keys(&trie); - VECTOR(name)[0] = &namerec; } if (weights == IGRAPH_ADD_WEIGHTS_YES || (weights == IGRAPH_ADD_WEIGHTS_IF_PRESENT && context.has_weights)) { + IGRAPH_CHECK(igraph_attribute_record_list_init(&weight, 1)); + IGRAPH_FINALLY(igraph_attribute_record_list_destroy, &weight); + + weightrec = igraph_attribute_record_list_get_ptr(&weight, 0); + IGRAPH_CHECK(igraph_attribute_record_set_name(weightrec, weightstr)); + IGRAPH_CHECK(igraph_attribute_record_set_type(weightrec, IGRAPH_ATTRIBUTE_NUMERIC)); + igraph_vector_swap(weightrec->value.as_vector, context.weights); - IGRAPH_CHECK(igraph_vector_ptr_init(&weight, 1)); - IGRAPH_FINALLY(igraph_vector_ptr_destroy, &weight); pweight = &weight; - weightrec.name = weightstr; - weightrec.type = IGRAPH_ATTRIBUTE_NUMERIC; - weightrec.value = &ws; - VECTOR(weight)[0] = &weightrec; } if (igraph_vector_int_empty(&edges)) { @@ -222,11 +227,11 @@ igraph_error_t igraph_read_graph_ncol(igraph_t *graph, FILE *instream, IGRAPH_CHECK(igraph_add_edges(graph, &edges, pweight)); if (pname) { - igraph_vector_ptr_destroy(pname); + igraph_attribute_record_list_destroy(pname); IGRAPH_FINALLY_CLEAN(1); } if (pweight) { - igraph_vector_ptr_destroy(pweight); + igraph_attribute_record_list_destroy(pweight); IGRAPH_FINALLY_CLEAN(1); } igraph_vector_destroy(&ws); @@ -309,7 +314,7 @@ igraph_error_t igraph_write_graph_ncol(const igraph_t *graph, FILE *outstream, names = NULL; } if (names) { - IGRAPH_CHECK(igraph_i_attribute_gettype(graph, &nametype, + IGRAPH_CHECK(igraph_i_attribute_get_type(graph, &nametype, IGRAPH_ATTRIBUTE_VERTEX, names)); if (nametype != IGRAPH_ATTRIBUTE_STRING) { IGRAPH_WARNINGF("Ignoring names attribute '%s', " @@ -324,7 +329,7 @@ igraph_error_t igraph_write_graph_ncol(const igraph_t *graph, FILE *outstream, weights = NULL; } if (weights) { - IGRAPH_CHECK(igraph_i_attribute_gettype(graph, &weighttype, + IGRAPH_CHECK(igraph_i_attribute_get_type(graph, &weighttype, IGRAPH_ATTRIBUTE_EDGE, weights)); if (weighttype != IGRAPH_ATTRIBUTE_NUMERIC) { IGRAPH_WARNINGF("Ignoring weights attribute '%s', " diff --git a/src/vendor/cigraph/src/io/pajek-header.h b/src/vendor/cigraph/src/io/pajek-header.h index caa2360e8f1..4500f8d7153 100644 --- a/src/vendor/cigraph/src/io/pajek-header.h +++ b/src/vendor/cigraph/src/io/pajek-header.h @@ -20,6 +20,7 @@ */ +#include "igraph_attributes.h" #include "igraph_error.h" #include "igraph_vector.h" #include "igraph_vector_ptr.h" @@ -53,9 +54,9 @@ typedef struct { igraph_integer_t actfrom; igraph_integer_t actto; igraph_trie_t *vertex_attribute_names; - igraph_vector_ptr_t *vertex_attributes; + igraph_attribute_record_list_t *vertex_attributes; igraph_trie_t *edge_attribute_names; - igraph_vector_ptr_t *edge_attributes; + igraph_attribute_record_list_t *edge_attributes; igraph_integer_t vertexid; igraph_integer_t actvertex; igraph_integer_t actedge; diff --git a/src/vendor/cigraph/src/io/pajek-parser.y b/src/vendor/cigraph/src/io/pajek-parser.y index 20d9a59ecfe..f70c640d55e 100644 --- a/src/vendor/cigraph/src/io/pajek-parser.y +++ b/src/vendor/cigraph/src/io/pajek-parser.y @@ -78,15 +78,17 @@ static igraph_error_t add_numeric_edge_attribute(const char *name, igraph_real_t value, igraph_i_pajek_parsedata_t *context); static igraph_error_t add_numeric_attribute(igraph_trie_t *names, - igraph_vector_ptr_t *attrs, + igraph_attribute_record_list_t *attrs, igraph_integer_t count, const char *attrname, + igraph_real_t default_value, igraph_integer_t vid, igraph_real_t number); static igraph_error_t add_string_attribute(igraph_trie_t *names, - igraph_vector_ptr_t *attrs, + igraph_attribute_record_list_t *attrs, igraph_integer_t count, const char *attrname, + const char *default_value, igraph_integer_t vid, const char *str, igraph_integer_t str_len); @@ -98,6 +100,10 @@ static igraph_error_t make_dynstr(const char *src, size_t len, char **res); static igraph_bool_t is_standard_vattr(const char *attrname); static igraph_bool_t is_standard_eattr(const char *attrname); static igraph_error_t deconflict_attrname(char **attrname); +static igraph_real_t get_default_value_for_numeric_vattr(const char *attrname); +static igraph_real_t get_default_value_for_numeric_eattr(const char *attrname); +static const char* get_default_value_for_string_vattr(const char *attrname); +static const char* get_default_value_for_string_eattr(const char *attrname); #define scanner context->scanner @@ -248,7 +254,6 @@ vertex: integer { }; vertexid: word { - IGRAPH_YY_CHECK(add_string_vertex_attribute("id", $1.str, $1.len, context)); IGRAPH_YY_CHECK(add_string_vertex_attribute("name", $1.str, $1.len, context)); }; @@ -548,49 +553,38 @@ int igraph_pajek_yyerror(YYLTYPE* locp, /* TODO: NA's */ static igraph_error_t add_numeric_attribute(igraph_trie_t *names, - igraph_vector_ptr_t *attrs, + igraph_attribute_record_list_t *attrs, igraph_integer_t count, const char *attrname, + igraph_real_t default_value, igraph_integer_t elem_id, igraph_real_t number) { igraph_integer_t attrsize = igraph_trie_size(names); igraph_integer_t id; igraph_vector_t *na; - igraph_attribute_record_t *rec; + igraph_attribute_record_t *prec; IGRAPH_CHECK(igraph_trie_get(names, attrname, &id)); if (id == attrsize) { - /* add a new attribute */ - rec = IGRAPH_CALLOC(1, igraph_attribute_record_t); - CHECK_OOM_RP(rec); - IGRAPH_FINALLY(igraph_free, rec); - - na = IGRAPH_CALLOC(1, igraph_vector_t); - CHECK_OOM_RP(na); - IGRAPH_FINALLY(igraph_free, na); - IGRAPH_VECTOR_INIT_FINALLY(na, count); + igraph_attribute_record_t rec; - rec->name = strdup(attrname); - CHECK_OOM_RP(rec->name); - IGRAPH_FINALLY(igraph_free, (void *) rec->name); + /* add a new attribute */ + IGRAPH_CHECK(igraph_attribute_record_init(&rec, attrname, IGRAPH_ATTRIBUTE_NUMERIC)); + IGRAPH_FINALLY(igraph_attribute_record_destroy, &rec); - rec->type = IGRAPH_ATTRIBUTE_NUMERIC; - rec->value = na; + IGRAPH_CHECK(igraph_attribute_record_set_default_numeric(&rec, default_value)); - IGRAPH_CHECK(igraph_vector_ptr_push_back(attrs, rec)); - IGRAPH_FINALLY_CLEAN(4); /* ownership of rec transferred to attrs */ + IGRAPH_CHECK(igraph_attribute_record_resize(&rec, count)); + IGRAPH_CHECK(igraph_attribute_record_list_push_back(attrs, &rec)); + IGRAPH_FINALLY_CLEAN(1); /* ownership of rec transferred to attrs */ } - rec = VECTOR(*attrs)[id]; - na = (igraph_vector_t *) rec->value; + prec = igraph_attribute_record_list_get_ptr(attrs, id); + na = prec->value.as_vector; if (igraph_vector_size(na) == elem_id) { IGRAPH_CHECK(igraph_vector_push_back(na, number)); } else if (igraph_vector_size(na) < elem_id) { - igraph_integer_t origsize=igraph_vector_size(na); - IGRAPH_CHECK(igraph_vector_resize(na, elem_id+1)); - for (;origsizename = strdup(attrname); - CHECK_OOM_RP(rec->name); - IGRAPH_FINALLY(igraph_free, (char *) rec->name); + IGRAPH_CHECK(igraph_attribute_record_init(&rec, attrname, IGRAPH_ATTRIBUTE_STRING)); + IGRAPH_FINALLY(igraph_attribute_record_destroy, &rec); - rec->type = IGRAPH_ATTRIBUTE_STRING; - rec->value = na; + IGRAPH_CHECK(igraph_attribute_record_set_default_string(&rec, default_value)); - IGRAPH_CHECK(igraph_vector_ptr_push_back(attrs, rec)); - IGRAPH_FINALLY_CLEAN(4); /* ownership of rec transferred to attrs */ + IGRAPH_CHECK(igraph_attribute_record_resize(&rec, count)); + IGRAPH_CHECK(igraph_attribute_record_list_push_back(attrs, &rec)); + IGRAPH_FINALLY_CLEAN(1); /* ownership of rec transferred to attrs */ } - rec = VECTOR(*attrs)[id]; - na = (igraph_strvector_t *) rec->value; + prec = igraph_attribute_record_list_get_ptr(attrs, id); + na = prec->value.as_strvector; if (igraph_strvector_size(na) <= elem_id) { IGRAPH_CHECK(igraph_strvector_resize(na, elem_id+1)); } @@ -675,7 +658,9 @@ static igraph_error_t add_string_vertex_attribute(const char *name, return add_string_attribute(context->vertex_attribute_names, context->vertex_attributes, context->vcount, - name, context->actvertex-1, + name, + get_default_value_for_string_vattr(name), + context->actvertex-1, value, len); } @@ -687,7 +672,9 @@ static igraph_error_t add_string_edge_attribute(const char *name, return add_string_attribute(context->edge_attribute_names, context->edge_attributes, context->actedge, - name, context->actedge-1, + name, + get_default_value_for_string_eattr(name), + context->actedge-1, value, len); } @@ -698,7 +685,9 @@ static igraph_error_t add_numeric_vertex_attribute(const char *name, return add_numeric_attribute(context->vertex_attribute_names, context->vertex_attributes, context->vcount, - name, context->actvertex-1, + name, + get_default_value_for_numeric_vattr(name), + context->actvertex-1, value); } @@ -709,7 +698,9 @@ static igraph_error_t add_numeric_edge_attribute(const char *name, return add_numeric_attribute(context->edge_attribute_names, context->edge_attributes, context->actedge, - name, context->actedge-1, + name, + get_default_value_for_numeric_eattr(name), + context->actedge-1, value); } @@ -717,10 +708,10 @@ static igraph_error_t add_bipartite_type(igraph_i_pajek_parsedata_t *context) { const char *attrname="type"; igraph_trie_t *names=context->vertex_attribute_names; - igraph_vector_ptr_t *attrs=context->vertex_attributes; + igraph_attribute_record_list_t *attrs=context->vertex_attributes; igraph_integer_t n=context->vcount, n1=context->vcount2; igraph_integer_t attrid, attrsize = igraph_trie_size(names); - igraph_attribute_record_t *rec; + igraph_attribute_record_t* rec; igraph_vector_bool_t *na; if (n1 > n) { @@ -735,29 +726,13 @@ static igraph_error_t add_bipartite_type(igraph_i_pajek_parsedata_t *context) { IGRAPH_ASSERT(attrid == attrsize); /* add a new attribute */ - rec = IGRAPH_CALLOC(1, igraph_attribute_record_t); - CHECK_OOM_RP(rec); - IGRAPH_FINALLY(igraph_free, rec); - - na = IGRAPH_CALLOC(1, igraph_vector_bool_t); - CHECK_OOM_RP(na); - IGRAPH_FINALLY(igraph_free, na); - IGRAPH_VECTOR_BOOL_INIT_FINALLY(na, n); - - rec->name = strdup(attrname); - CHECK_OOM_RP(rec->name); - IGRAPH_FINALLY(igraph_free, (char *) rec->name); + IGRAPH_CHECK(igraph_attribute_record_list_push_back_new(attrs, &rec)); + IGRAPH_CHECK(igraph_attribute_record_set_name(rec, attrname)); + IGRAPH_CHECK(igraph_attribute_record_set_type(rec, IGRAPH_ATTRIBUTE_BOOLEAN)); + IGRAPH_CHECK(igraph_attribute_record_resize(rec, n)); - rec->type = IGRAPH_ATTRIBUTE_BOOLEAN; - rec->value = na; - - IGRAPH_CHECK(igraph_vector_ptr_push_back(attrs, rec)); - IGRAPH_FINALLY_CLEAN(4); /* ownership of 'rec' transferred to 'attrs' */ - - for (igraph_integer_t i=0; ivalue.as_vector_bool; + for (igraph_integer_t i = n1; i < n; i++) { VECTOR(*na)[i] = true; } @@ -797,7 +772,7 @@ static igraph_bool_t is_standard_vattr(const char *attrname) { "font", "url", "color", "framecolor", "labelcolor" }; - for (size_t i=0; i < sizeof(names) / sizeof(names[0]); i++) { + for (size_t i = 0; i < sizeof(names) / sizeof(names[0]); i++) { if (strcmp(attrname, names[i]) == 0) { return true; } @@ -839,3 +814,108 @@ static igraph_error_t deconflict_attrname(char **attrname) { *attrname = tmp; return IGRAPH_SUCCESS; } + +typedef struct { + const char* name; + igraph_real_t default_value; +} attribute_numeric_defaults_t; + +typedef struct { + const char* name; + const char* default_value; +} attribute_string_defaults_t; + +/* The defaults listed below are Pajek's built-in defaults unless the user + * overrides them. + * + * See: https://nascol.discourse.group/t/pajek-file-format-default-values-for-attributes/38/2 + */ + +const attribute_numeric_defaults_t vattr_numeric_defaults[] = { + { "xfact", 1 }, + { "yfact", 1 }, + { "labeldist", 20 }, + { "labeldegree2", 285 }, + { "framewidth", 1 }, + { "fontsize", 15 }, + { "rotation", 0 }, + { "radius", 0 }, + { "diamondratio", 0.01 }, + { "labeldegree", 0 }, + { 0 } +}; + +const attribute_string_defaults_t vattr_string_defaults[] = { + { "color", "LightOrange" }, + { "framecolor", "Brown" }, + { "labelcolor", "Maroon" }, + { 0 } +}; + +const attribute_numeric_defaults_t eattr_numeric_defaults[] = { + { "arrowsize", 1 }, + { "edgewidth", 2 }, + { "hook1", 0 }, + { "hook2", 0 }, + { "angle1", 0 }, + { "angle2", 0 }, + { "velocity1", 1 }, + { "velocity2", 1 }, + { "arrowpos", 0 }, + { "labelpos", 0.5 }, + { "labelangle", 10 }, + { "labelangle2", 90 }, + { "labeldegree", 0 }, + { "fontsize", 15 }, + { 0 } +}; + +const attribute_string_defaults_t eattr_string_defaults[] = { + { "color", "MidnightBlue" }, + { "labelcolor", "Black" }, + { 0 } +}; + +static igraph_real_t get_default_value_for_numeric_attr( + const char *attrname, const attribute_numeric_defaults_t* table +) { + const attribute_numeric_defaults_t* ptr; + + for (ptr = table; ptr->name != 0; ptr++) { + if (!strcmp(attrname, ptr->name)) { + return ptr->default_value; + } + } + + return IGRAPH_NAN; +} + +static const char* get_default_value_for_string_attr( + const char *attrname, const attribute_string_defaults_t* table +) { + const attribute_string_defaults_t* ptr; + + for (ptr = table; ptr->name != 0; ptr++) { + if (!strcmp(attrname, ptr->name)) { + return ptr->default_value; + } + } + + return ""; +} + +static igraph_real_t get_default_value_for_numeric_vattr(const char *attrname) { + return get_default_value_for_numeric_attr(attrname, vattr_numeric_defaults); +} + +static igraph_real_t get_default_value_for_numeric_eattr(const char *attrname) { + return get_default_value_for_numeric_attr(attrname, eattr_numeric_defaults); +} + +static const char* get_default_value_for_string_vattr(const char *attrname) { + return get_default_value_for_string_attr(attrname, vattr_string_defaults); +} + +static const char* get_default_value_for_string_eattr(const char *attrname) { + return get_default_value_for_string_attr(attrname, eattr_string_defaults); +} diff --git a/src/vendor/cigraph/src/io/pajek.c b/src/vendor/cigraph/src/io/pajek.c index d54c293bb87..840bef136ba 100644 --- a/src/vendor/cigraph/src/io/pajek.c +++ b/src/vendor/cigraph/src/io/pajek.c @@ -48,32 +48,6 @@ void igraph_pajek_yylex_destroy_wrapper (void *scanner ) { (void) igraph_pajek_yylex_destroy(scanner); } -void igraph_i_pajek_destroy_attr_vector(igraph_vector_ptr_t *attrs) { - const igraph_integer_t attr_count = igraph_vector_ptr_size(attrs); - for (igraph_integer_t i = 0; i < attr_count; i++) { - igraph_attribute_record_t *rec = VECTOR(*attrs)[i]; - if (rec->type == IGRAPH_ATTRIBUTE_NUMERIC) { - igraph_vector_t *vec = (igraph_vector_t*) rec->value; - igraph_vector_destroy(vec); - IGRAPH_FREE(vec); - } else if (rec->type == IGRAPH_ATTRIBUTE_BOOLEAN) { - igraph_vector_bool_t *vec = (igraph_vector_bool_t*) rec->value; - igraph_vector_bool_destroy(vec); - IGRAPH_FREE(vec); - } else if (rec->type == IGRAPH_ATTRIBUTE_STRING) { - igraph_strvector_t *strvec = (igraph_strvector_t *)rec->value; - igraph_strvector_destroy(strvec); - IGRAPH_FREE(strvec); - } else { - /* Must never reach here */ - IGRAPH_FATAL("Unknown attribute type encountered."); - } - IGRAPH_FREE(rec->name); - IGRAPH_FREE(rec); - } - igraph_vector_ptr_destroy(attrs); -} - /** * \function igraph_read_graph_pajek * \brief Reads a file in Pajek format. @@ -135,11 +109,10 @@ void igraph_i_pajek_destroy_attr_vector(igraph_vector_ptr_t *attrs) { * character is appended to it to avoid conflict. * * - * In addition the following vertex attributes might be added: \c id - * and \c name are added (with the same value) if there are vertex IDs in the - * file. \c id is deprecated in favour of \c name and will no longer be used - * by future versions of igraph. \c x and \c y, and potentially \c z are also - * added if there are vertex coordinates in the file. + * In addition the following vertex attributes might be added: \c name is added + * (with the same value) if there are vertex IDs in the file. + * \c x and \c y, and potentially \c z are also added if there are vertex + * coordinates in the file. * * * The \c weight edge attribute will be added if there are edge weights present. @@ -172,21 +145,21 @@ igraph_error_t igraph_read_graph_pajek(igraph_t *graph, FILE *instream) { igraph_vector_int_t edges; igraph_trie_t vattrnames; - igraph_vector_ptr_t vattrs; + igraph_attribute_record_list_t vattrs; igraph_trie_t eattrnames; - igraph_vector_ptr_t eattrs; - igraph_integer_t i, j; + igraph_attribute_record_list_t eattrs; + igraph_integer_t i; igraph_i_pajek_parsedata_t context; IGRAPH_VECTOR_INT_INIT_FINALLY(&edges, 0); IGRAPH_TRIE_INIT_FINALLY(&vattrnames, 1); - IGRAPH_CHECK(igraph_vector_ptr_init(&vattrs, 0)); - IGRAPH_FINALLY(igraph_i_pajek_destroy_attr_vector, &vattrs); + IGRAPH_CHECK(igraph_attribute_record_list_init(&vattrs, 0)); + IGRAPH_FINALLY(igraph_attribute_record_list_destroy, &vattrs); IGRAPH_TRIE_INIT_FINALLY(&eattrnames, 1); - IGRAPH_CHECK(igraph_vector_ptr_init(&eattrs, 0)); - IGRAPH_FINALLY(igraph_i_pajek_destroy_attr_vector, &eattrs); + IGRAPH_CHECK(igraph_attribute_record_list_init(&eattrs, 0)); + IGRAPH_FINALLY(igraph_attribute_record_list_destroy, &eattrs); context.directed = false; /* assume undirected until an element implying directedness is encountered */ context.vector = &edges; @@ -235,33 +208,10 @@ igraph_error_t igraph_read_graph_pajek(igraph_t *graph, FILE *instream) { } /* Prepare attributes */ - const igraph_integer_t eattr_count = igraph_vector_ptr_size(&eattrs); + const igraph_integer_t eattr_count = igraph_attribute_record_list_size(&eattrs); for (i = 0; i < eattr_count; i++) { - igraph_attribute_record_t *rec = VECTOR(eattrs)[i]; - if (rec->type == IGRAPH_ATTRIBUTE_NUMERIC) { - igraph_vector_t *vec = (igraph_vector_t*)rec->value; - igraph_integer_t origsize = igraph_vector_size(vec); - IGRAPH_CHECK(igraph_vector_resize(vec, context.actedge)); - for (j = origsize; j < context.actedge; j++) { - VECTOR(*vec)[j] = IGRAPH_NAN; - } - } else if (rec->type == IGRAPH_ATTRIBUTE_BOOLEAN) { - /* Boolean attributes are not currently added by the parser. - * This section is here for future-proofing. */ - igraph_vector_bool_t *vec = (igraph_vector_bool_t*)rec->value; - igraph_integer_t origsize = igraph_vector_bool_size(vec); - IGRAPH_CHECK(igraph_vector_bool_resize(vec, context.actedge)); - for (j = origsize; j < context.actedge; j++) { - VECTOR(*vec)[j] = 0; - } - } else if (rec->type == IGRAPH_ATTRIBUTE_STRING) { - igraph_strvector_t *strvec = (igraph_strvector_t*)rec->value; - /* strvector_resize() adds empty strings */ - IGRAPH_CHECK(igraph_strvector_resize(strvec, context.actedge)); - } else { - /* Must never reach here */ - IGRAPH_FATAL("Unknown attribute type encountered."); - } + igraph_attribute_record_t *rec = igraph_attribute_record_list_get_ptr(&eattrs, i); + IGRAPH_CHECK(igraph_attribute_record_resize(rec, context.actedge)); } /* Create graph */ @@ -271,9 +221,9 @@ igraph_error_t igraph_read_graph_pajek(igraph_t *graph, FILE *instream) { IGRAPH_CHECK(igraph_add_edges(graph, &edges, &eattrs)); igraph_vector_int_destroy(&edges); - igraph_i_pajek_destroy_attr_vector(&eattrs); + igraph_attribute_record_list_destroy(&eattrs); igraph_trie_destroy(&eattrnames); - igraph_i_pajek_destroy_attr_vector(&vattrs); + igraph_attribute_record_list_destroy(&vattrs); igraph_trie_destroy(&vattrnames); igraph_pajek_yylex_destroy(context.scanner); IGRAPH_FINALLY_CLEAN(7); /* +1 for 'graph' */ @@ -445,7 +395,7 @@ igraph_error_t igraph_write_graph_pajek(const igraph_t *graph, FILE *outstream) igraph_bool_t write_vertex_attrs = false; /* Same order as the #define's */ - const char *vnames[] = { "id", "x", "y", "z", "shape", "xfact", "yfact", + const char *vnames[] = { "name", "x", "y", "z", "shape", "xfact", "yfact", "labeldist", "labeldegree2", "framewidth", "fontsize", "rotation", "radius", "diamondratio", "labeldegree", @@ -527,7 +477,7 @@ igraph_error_t igraph_write_graph_pajek(const igraph_t *graph, FILE *outstream) /* Check if graph is bipartite, i.e. whether it has a Boolean 'type' vertex attribute. */ if (igraph_i_attribute_has_attr(graph, IGRAPH_ATTRIBUTE_VERTEX, "type")) { igraph_attribute_type_t type_type; - IGRAPH_CHECK(igraph_i_attribute_gettype(graph, &type_type, IGRAPH_ATTRIBUTE_VERTEX, "type")); + IGRAPH_CHECK(igraph_i_attribute_get_type(graph, &type_type, IGRAPH_ATTRIBUTE_VERTEX, "type")); if (type_type == IGRAPH_ATTRIBUTE_BOOLEAN) { bipartite = true; write_vertex_attrs = true; /* Count top and bottom vertices, we go over them twice, @@ -578,7 +528,7 @@ igraph_error_t igraph_write_graph_pajek(const igraph_t *graph, FILE *outstream) memset(vtypes, 0, sizeof(vtypes[0])*V_LAST); for (igraph_integer_t i = 0; i < V_LAST; i++) { if (igraph_i_attribute_has_attr(graph, IGRAPH_ATTRIBUTE_VERTEX, vnames[i])) { - IGRAPH_CHECK(igraph_i_attribute_gettype( + IGRAPH_CHECK(igraph_i_attribute_get_type( graph, &vtypes[i], IGRAPH_ATTRIBUTE_VERTEX, vnames[i])); write_vertex_attrs = true; } else { @@ -588,7 +538,7 @@ igraph_error_t igraph_write_graph_pajek(const igraph_t *graph, FILE *outstream) for (igraph_integer_t i = 0; i < (igraph_integer_t) (sizeof(vnumnames) / sizeof(vnumnames[0])); i++) { igraph_attribute_type_t type; if (igraph_i_attribute_has_attr(graph, IGRAPH_ATTRIBUTE_VERTEX, vnumnames[i])) { - IGRAPH_CHECK(igraph_i_attribute_gettype( + IGRAPH_CHECK(igraph_i_attribute_get_type( graph, &type, IGRAPH_ATTRIBUTE_VERTEX, vnumnames[i])); if (type == IGRAPH_ATTRIBUTE_NUMERIC) { IGRAPH_CHECK(igraph_vector_int_push_back(&vx_numa, i)); @@ -598,7 +548,7 @@ igraph_error_t igraph_write_graph_pajek(const igraph_t *graph, FILE *outstream) for (igraph_integer_t i = 0; i < (igraph_integer_t) (sizeof(vstrnames) / sizeof(vstrnames[0])); i++) { igraph_attribute_type_t type; if (igraph_i_attribute_has_attr(graph, IGRAPH_ATTRIBUTE_VERTEX, vstrnames[i])) { - IGRAPH_CHECK(igraph_i_attribute_gettype( + IGRAPH_CHECK(igraph_i_attribute_get_type( graph, &type, IGRAPH_ATTRIBUTE_VERTEX, vstrnames[i])); if (type == IGRAPH_ATTRIBUTE_STRING) { IGRAPH_CHECK(igraph_vector_int_push_back(&vx_stra, i)); @@ -700,7 +650,7 @@ igraph_error_t igraph_write_graph_pajek(const igraph_t *graph, FILE *outstream) /* TODO: refactor and simplify since only "weight" is relevant */ for (igraph_integer_t i = 0; i < E_LAST; i++) { if (igraph_i_attribute_has_attr(graph, IGRAPH_ATTRIBUTE_EDGE, enames[i])) { - IGRAPH_CHECK(igraph_i_attribute_gettype( + IGRAPH_CHECK(igraph_i_attribute_get_type( graph, &etypes[i], IGRAPH_ATTRIBUTE_EDGE, enames[i])); } else { etypes[i] = (igraph_attribute_type_t) -1; @@ -709,7 +659,7 @@ igraph_error_t igraph_write_graph_pajek(const igraph_t *graph, FILE *outstream) for (igraph_integer_t i = 0; i < (igraph_integer_t) (sizeof(enumnames) / sizeof(enumnames[0])); i++) { igraph_attribute_type_t type; if (igraph_i_attribute_has_attr(graph, IGRAPH_ATTRIBUTE_EDGE, enumnames[i])) { - IGRAPH_CHECK(igraph_i_attribute_gettype( + IGRAPH_CHECK(igraph_i_attribute_get_type( graph, &type, IGRAPH_ATTRIBUTE_EDGE, enumnames[i])); if (type == IGRAPH_ATTRIBUTE_NUMERIC) { IGRAPH_CHECK(igraph_vector_int_push_back(&ex_numa, i)); @@ -719,7 +669,7 @@ igraph_error_t igraph_write_graph_pajek(const igraph_t *graph, FILE *outstream) for (igraph_integer_t i = 0; i < (igraph_integer_t) (sizeof(estrnames) / sizeof(estrnames[0])); i++) { igraph_attribute_type_t type; if (igraph_i_attribute_has_attr(graph, IGRAPH_ATTRIBUTE_EDGE, estrnames[i])) { - IGRAPH_CHECK(igraph_i_attribute_gettype( + IGRAPH_CHECK(igraph_i_attribute_get_type( graph, &type, IGRAPH_ATTRIBUTE_EDGE, estrnames[i])); if (type == IGRAPH_ATTRIBUTE_STRING) { IGRAPH_CHECK(igraph_vector_int_push_back(&ex_stra, i)); diff --git a/src/vendor/cigraph/src/isomorphism/bliss.cc b/src/vendor/cigraph/src/isomorphism/bliss.cc index fedc3c3c421..f57bb48bc21 100644 --- a/src/vendor/cigraph/src/isomorphism/bliss.cc +++ b/src/vendor/cigraph/src/isomorphism/bliss.cc @@ -29,6 +29,7 @@ #include "core/exceptions.h" #include +#include #include using namespace bliss; @@ -191,7 +192,7 @@ struct AbortChecker { AbortChecker() : aborted(false) { } bool operator()() { - if (igraph_allow_interruption(NULL) != IGRAPH_SUCCESS) { + if (igraph_allow_interruption() != IGRAPH_SUCCESS) { aborted = true; return true; } @@ -231,6 +232,44 @@ class AutCollector { /** * \function igraph_canonical_permutation + * \brief Canonical permutation of a graph. + * + * This function computes the vertex permutation which transforms + * the graph into a canonical form. Two graphs have the same canonical form if + * and only if they are isomorphic. Use \ref igraph_is_same_graph() to compare + * two canonical forms. + * + * + * The current implementation uses the BLISS isomorphism algorithms with + * sensible defaults. Use \ref igaph_canonical_permutation_bliss() to fine-tune + * the parameters. + * + * \param graph The input graph. Multiple edges between the same nodes + * are not supported and will cause an incorrect result to be returned. + * \param colors An optional vertex color vector for the graph. Supply a + * null pointer is the graph is not colored. + * \param labeling Pointer to a vector, the result is stored here. The + * permutation takes vertex 0 to the first element of the vector, + * vertex 1 to the second, etc. The vector will be resized as + * needed. + * \return Error code. + * + * \sa \ref igraph_is_same_graph() + * + * Time complexity: exponential, in practice it is fast for many graphs. + */ +igraph_error_t igraph_canonical_permutation( + const igraph_t *graph, const igraph_vector_int_t *colors, + igraph_vector_int_t *labeling, igraph_bliss_sh_t sh, + igraph_bliss_info_t *info +) { + return igraph_canonical_permutation_bliss( + graph, colors, labeling, IGRAPH_BLISS_FL, NULL + ); +} + +/** + * \function igraph_canonical_permutation_bliss * \brief Canonical permutation using Bliss. * * This function computes the vertex permutation which transforms @@ -258,8 +297,11 @@ class AutCollector { * * Time complexity: exponential, in practice it is fast for many graphs. */ -igraph_error_t igraph_canonical_permutation(const igraph_t *graph, const igraph_vector_int_t *colors, - igraph_vector_int_t *labeling, igraph_bliss_sh_t sh, igraph_bliss_info_t *info) { +igraph_error_t igraph_canonical_permutation_bliss( + const igraph_t *graph, const igraph_vector_int_t *colors, + igraph_vector_int_t *labeling, igraph_bliss_sh_t sh, + igraph_bliss_info_t *info +) { IGRAPH_HANDLE_EXCEPTIONS( AbstractGraph *g = bliss_from_igraph(graph); IGRAPH_FINALLY(bliss_free_graph, g); @@ -290,18 +332,53 @@ igraph_error_t igraph_canonical_permutation(const igraph_t *graph, const igraph_ } /** - * \function igraph_automorphisms - * \brief Number of automorphisms using Bliss (deprecated alias). + * \function igraph_count_automorphisms + * \brief Number of automorphisms of a graph. + * + * This function computes the number of automorphisms of a graph. Since the + * number of automorphisms may be very large, the result is returned as an + * \c igraph_real_t instead of an integer. If the number of automorphisms + * is larger than what can be represented in an \c igraph_real_t and you need + * the exact number, use \ref igraph_count_automorphisms_bliss(), which can + * return the number as a string. + * + * \param graph The input graph. Multiple edges between the same nodes + * are not supported and will cause an incorrect result to be returned. + * \param colors An optional vertex color vector for the graph. Supply a + * null pointer is the graph is not colored. + * \param result Pointer to an \c igraph_real_t, the number of automorphisms + * will be returned here. + * \return Error code. \c IGRAPH_EOVERFLOW if the number of automorphisms is + * too large to be represented in an \c igraph_real_t . * - * \deprecated-by igraph_count_automorphisms 0.10.5 + * Time complexity: exponential, in practice it is fast for many graphs. */ -igraph_error_t igraph_automorphisms(const igraph_t *graph, const igraph_vector_int_t *colors, - igraph_bliss_sh_t sh, igraph_bliss_info_t *info) { - return igraph_count_automorphisms(graph, colors, sh, info); +igraph_error_t igraph_count_automorphisms( + const igraph_t *graph, const igraph_vector_int_t *colors, + igraph_real_t *result +) { + igraph_bliss_info_t info; + double x; + + IGRAPH_CHECK(igraph_count_automorphisms_bliss(graph, colors, IGRAPH_BLISS_FL, &info)); + + x = strtod(info.group_size, NULL); + igraph_free(info.group_size); + + if (x == 0) { + return IGRAPH_FAILURE; + } else if (x == HUGE_VAL) { + return IGRAPH_EOVERFLOW; + } else { + if (result) { + *result = x; + } + return IGRAPH_SUCCESS; + } } /** - * \function igraph_count_automorphisms + * \function igraph_count_automorphisms_bliss * \brief Number of automorphisms using Bliss. * * The number of automorphisms of a graph is computed using Bliss. The @@ -322,8 +399,10 @@ igraph_error_t igraph_automorphisms(const igraph_t *graph, const igraph_vector_i * * Time complexity: exponential, in practice it is fast for many graphs. */ -igraph_error_t igraph_count_automorphisms(const igraph_t *graph, const igraph_vector_int_t *colors, - igraph_bliss_sh_t sh, igraph_bliss_info_t *info) { +igraph_error_t igraph_count_automorphisms_bliss( + const igraph_t *graph, const igraph_vector_int_t *colors, + igraph_bliss_sh_t sh, igraph_bliss_info_t *info +) { IGRAPH_HANDLE_EXCEPTIONS( AbstractGraph *g = bliss_from_igraph(graph); IGRAPH_FINALLY(bliss_free_graph, g); @@ -349,6 +428,39 @@ igraph_error_t igraph_count_automorphisms(const igraph_t *graph, const igraph_ve /** * \function igraph_automorphism_group + * \brief Automorphism group generators of a graph. + * + * This function computes the generators of the automorphism group of a graph. + * The generator set may not be minimal and may depend on the specific parameters + * of the algorithm under the hood. The generators are permutations represented + * using zero-based indexing. + * + * + * The current implementation uses BLISS behind the scenes and the result may + * be dependent on the splitting heuristics. Use \ref igraph_automorphism_group_bliss() + * if you want to fine-tune the splitting heuristics. + * + * \param graph The input graph. Multiple edges between the same nodes + * are not supported and will cause an incorrect result to be returned. + * \param colors An optional vertex color vector for the graph. Supply a + * null pointer is the graph is not colored. + * \param generators Must be an initialized interger vector list. + * The generators of the automorphism group will be stored here. + * \return Error code. + * + * Time complexity: exponential, in practice it is fast for many graphs. + */ +igraph_error_t igraph_automorphism_group( + const igraph_t *graph, const igraph_vector_int_t *colors, + igraph_vector_int_list_t *generators +) { + return igraph_automorphism_group_bliss( + graph, colors, generators, IGRAPH_BLISS_FL, NULL + ); +} + +/** + * \function igraph_automorphism_group_bliss * \brief Automorphism group generators using Bliss. * * The generators of the automorphism group of a graph are computed @@ -371,9 +483,11 @@ igraph_error_t igraph_count_automorphisms(const igraph_t *graph, const igraph_ve * * Time complexity: exponential, in practice it is fast for many graphs. */ -igraph_error_t igraph_automorphism_group( - const igraph_t *graph, const igraph_vector_int_t *colors, igraph_vector_int_list_t *generators, - igraph_bliss_sh_t sh, igraph_bliss_info_t *info) { +igraph_error_t igraph_automorphism_group_bliss( + const igraph_t *graph, const igraph_vector_int_t *colors, + igraph_vector_int_list_t *generators, igraph_bliss_sh_t sh, + igraph_bliss_info_t *info +) { IGRAPH_HANDLE_EXCEPTIONS( AbstractGraph *g = bliss_from_igraph(graph); IGRAPH_FINALLY(bliss_free_graph, g); @@ -431,7 +545,7 @@ igraph_error_t igraph_automorphism_group( * * * Isomorphism testing is implemented by producing the canonical form - * of both graphs using \ref igraph_canonical_permutation() and + * of both graphs using \ref igraph_canonical_permutation_bliss() and * comparing them. * * \param graph1 The first input graph. Multiple edges between the same nodes @@ -519,8 +633,8 @@ igraph_error_t igraph_isomorphic_bliss(const igraph_t *graph1, const igraph_t *g IGRAPH_VECTOR_INT_INIT_FINALLY(&perm1, no_of_nodes); IGRAPH_VECTOR_INT_INIT_FINALLY(&perm2, no_of_nodes); - IGRAPH_CHECK(igraph_canonical_permutation(graph1, colors1, &perm1, sh, info1)); - IGRAPH_CHECK(igraph_canonical_permutation(graph2, colors2, &perm2, sh, info2)); + IGRAPH_CHECK(igraph_canonical_permutation_bliss(graph1, colors1, &perm1, sh, info1)); + IGRAPH_CHECK(igraph_canonical_permutation_bliss(graph2, colors2, &perm2, sh, info2)); IGRAPH_CHECK(igraph_vector_int_resize(mymap12, no_of_nodes)); diff --git a/src/vendor/cigraph/src/isomorphism/vf2.c b/src/vendor/cigraph/src/isomorphism/vf2.c index 782141f0048..e230280706c 100644 --- a/src/vendor/cigraph/src/isomorphism/vf2.c +++ b/src/vendor/cigraph/src/isomorphism/vf2.c @@ -885,7 +885,7 @@ static igraph_error_t igraph_i_count_isomorphisms_vf2_cb( * \p edge_compat_fn. * \return Error code. * - * \sa igraph_count_automorphisms() + * \sa igraph_count_automorphisms_bliss() * * Time complexity: exponential. */ diff --git a/src/vendor/cigraph/src/misc/bipartite.c b/src/vendor/cigraph/src/misc/bipartite.c index 3e5da770ae2..8098b422316 100644 --- a/src/vendor/cigraph/src/misc/bipartite.c +++ b/src/vendor/cigraph/src/misc/bipartite.c @@ -280,8 +280,7 @@ static igraph_error_t igraph_i_bipartite_projection(const igraph_t *graph, IGRAPH_FINALLY(igraph_destroy, proj); /* copy graph attributes */ - IGRAPH_I_ATTRIBUTE_DESTROY(proj); - IGRAPH_I_ATTRIBUTE_COPY(proj, graph, /* graph */ true, /* vertex */ false, /* edge */ false); + IGRAPH_CHECK(igraph_i_attribute_copy(proj, graph, true, /* vertex= */ false, /* edge= */ false)); /* copy vertex attributes */ IGRAPH_CHECK(igraph_i_attribute_permute_vertices(graph, proj, &vertex_perm)); @@ -1131,6 +1130,82 @@ igraph_error_t igraph_bipartite_game_gnp(igraph_t *graph, igraph_vector_bool_t * return IGRAPH_SUCCESS; } +/** + * \function igraph_bipartite_game_gnm_multi + * \brief Generate a random bipartite graph with multi-edges. + * + * In the G(n1, n2, m) model we uniformly choose \p m edges to realize + * between the \p n1 bottom vertices and \p n2 top vertices. + * + * \param graph Pointer to an uninitialized igraph graph, the result + * is stored here. + * \param types Pointer to an initialized boolean vector, or a null + * pointer. If not a null pointer, then the vertex types are stored + * here. Bottom vertices come first, n1 of them, then n2 top + * vertices. + * \param n1 The number of bottom vertices. + * \param n2 The number of top vertices. + * \param m The number of edges. + * \param directed Boolean, whether to generate a directed graph. See + * also the \p mode argument. + * \param mode Specifies how to direct the edges in directed + * graphs. If it is \c IGRAPH_OUT, then directed edges point from + * bottom vertices to top vertices. If it is \c IGRAPH_IN, edges + * point from top vertices to bottom vertices. \c IGRAPH_OUT and + * \c IGRAPH_IN do not generate mutual edges. If this argument is + * \c IGRAPH_ALL, then each edge direction is considered + * independently and mutual edges might be generated. This + * argument is ignored for undirected graphs. + * \return Error code. + * + * \sa \ref igraph_erdos_renyi_game_gnm() for the unipartite version, + * \ref igraph_bipartite_game_gnp() for the G(n1, n2, p) model. + * + * Time complexity: O(|V|+|E|), linear in the number of vertices and + * edges. + */ + +static igraph_error_t igraph_i_bipartite_game_gnm_multi( + igraph_t *graph, igraph_vector_bool_t *types, + igraph_integer_t n1, igraph_integer_t n2, + igraph_integer_t m, igraph_bool_t directed, + igraph_neimode_t mode +) { + igraph_integer_t n; + igraph_vector_int_t edges; + + IGRAPH_SAFE_ADD(n1, n2, &n); + + IGRAPH_VECTOR_INT_INIT_FINALLY(&edges, 0); + IGRAPH_CHECK(igraph_vector_int_reserve(&edges, m * 2)); + + RNG_BEGIN(); + for (igraph_integer_t i = 0; i < m; i++) { + igraph_integer_t to, from; + + to = RNG_INTEGER(n1, n - 1); + from = RNG_INTEGER(0, n1 - 1); + + /* flip unconditionally for IGRAPH_IN, or with probability 0.5 for + * IGRAPH_ALL */ + if (mode == IGRAPH_IN || (mode == IGRAPH_ALL && RNG_UNIF01() < 0.5)) { + igraph_vector_int_push_back(&edges, to); + igraph_vector_int_push_back(&edges, from); + } else { + igraph_vector_int_push_back(&edges, from); + igraph_vector_int_push_back(&edges, to); + } + + } + RNG_END(); + + IGRAPH_CHECK(igraph_create(graph, &edges, n, directed)); + igraph_vector_int_destroy(&edges); + IGRAPH_FINALLY_CLEAN(1); + + return IGRAPH_SUCCESS; +} + /** * \function igraph_bipartite_game_gnm * \brief Generate a random bipartite graph with a fixed number of edges. @@ -1157,6 +1232,8 @@ igraph_error_t igraph_bipartite_game_gnp(igraph_t *graph, igraph_vector_bool_t * * \c IGRAPH_ALL, then each edge direction is considered * independently and mutual edges might be generated. This * argument is ignored for undirected graphs. + * \param multiple Boolean, whether it is allowed to generate more + * than one edge between the same pair of vertices. * \return Error code. * * \sa \ref igraph_erdos_renyi_game_gnm() for the unipartite version, @@ -1169,7 +1246,7 @@ igraph_error_t igraph_bipartite_game_gnp(igraph_t *graph, igraph_vector_bool_t * igraph_error_t igraph_bipartite_game_gnm(igraph_t *graph, igraph_vector_bool_t *types, igraph_integer_t n1, igraph_integer_t n2, igraph_integer_t m, igraph_bool_t directed, - igraph_neimode_t mode) { + igraph_neimode_t mode, igraph_bool_t multiple) { igraph_vector_int_t edges; igraph_vector_t s; igraph_integer_t n; @@ -1199,6 +1276,11 @@ igraph_error_t igraph_bipartite_game_gnm(igraph_t *graph, igraph_vector_bool_t * } IGRAPH_CHECK(igraph_empty(graph, n, directed)); } else { + + if (multiple) { + return igraph_i_bipartite_game_gnm_multi(graph, types, n1, n2, m, directed, mode); + } + igraph_integer_t i; igraph_real_t maxedges; @@ -1319,7 +1401,7 @@ igraph_error_t igraph_bipartite_game(igraph_t *graph, igraph_vector_bool_t *type if (type == IGRAPH_ERDOS_RENYI_GNP) { return igraph_bipartite_game_gnp(graph, types, n1, n2, p, directed, mode); } else if (type == IGRAPH_ERDOS_RENYI_GNM) { - return igraph_bipartite_game_gnm(graph, types, n1, n2, m, directed, mode); + return igraph_bipartite_game_gnm(graph, types, n1, n2, m, directed, mode, IGRAPH_NO_MULTIPLE); } else { IGRAPH_ERROR("Invalid bipartite game type.", IGRAPH_EINVAL); } diff --git a/src/vendor/cigraph/src/misc/cocitation.c b/src/vendor/cigraph/src/misc/cocitation.c index a73253f58f1..0ffc2a56094 100644 --- a/src/vendor/cigraph/src/misc/cocitation.c +++ b/src/vendor/cigraph/src/misc/cocitation.c @@ -297,9 +297,11 @@ static igraph_error_t igraph_i_neisets_intersect( * \param graph The graph object to analyze * \param res Pointer to a matrix, the result of the calculation will * be stored here. The number of its rows and columns is the same - * as the number of vertex IDs in \p vids. - * \param vids The vertex IDs of the vertices for which the - * calculation will be done. + * as the number of vertex IDs in \p vit_from and \p vit_to, respectively. + * \param vit_from The vertex IDs of the first set of vertices of the + * pairs for which the calculation will be done. + * \param vit_to The vertex IDs of the second set of vertices of the + * pairs for which the calculation will be done. * \param mode The type of neighbors to be used for the calculation in * directed graphs. Possible values: * \clist @@ -333,27 +335,27 @@ static igraph_error_t igraph_i_neisets_intersect( * \example examples/simple/igraph_similarity.c */ igraph_error_t igraph_similarity_jaccard(const igraph_t *graph, igraph_matrix_t *res, - const igraph_vs_t vids, igraph_neimode_t mode, igraph_bool_t loops) { + const igraph_vs_t from, const igraph_vs_t to, igraph_neimode_t mode, igraph_bool_t loops) { igraph_lazy_adjlist_t al; - igraph_vit_t vit, vit2; + igraph_vit_t vit_from, vit_to; igraph_integer_t i, j; igraph_integer_t len_union, len_intersection; igraph_vector_int_t *v1, *v2; igraph_integer_t k; - IGRAPH_CHECK(igraph_vit_create(graph, vids, &vit)); - IGRAPH_FINALLY(igraph_vit_destroy, &vit); - IGRAPH_CHECK(igraph_vit_create(graph, vids, &vit2)); - IGRAPH_FINALLY(igraph_vit_destroy, &vit2); + IGRAPH_CHECK(igraph_vit_create(graph, from, &vit_from)); + IGRAPH_FINALLY(igraph_vit_destroy, &vit_from); + IGRAPH_CHECK(igraph_vit_create(graph, to, &vit_to)); + IGRAPH_FINALLY(igraph_vit_destroy, &vit_to); IGRAPH_CHECK(igraph_lazy_adjlist_init(graph, &al, mode, IGRAPH_NO_LOOPS, IGRAPH_NO_MULTIPLE)); IGRAPH_FINALLY(igraph_lazy_adjlist_destroy, &al); - IGRAPH_CHECK(igraph_matrix_resize(res, IGRAPH_VIT_SIZE(vit), IGRAPH_VIT_SIZE(vit))); + IGRAPH_CHECK(igraph_matrix_resize(res, IGRAPH_VIT_SIZE(vit_from), IGRAPH_VIT_SIZE(vit_to))); if (loops) { - for (IGRAPH_VIT_RESET(vit); !IGRAPH_VIT_END(vit); IGRAPH_VIT_NEXT(vit)) { - i = IGRAPH_VIT_GET(vit); + for (IGRAPH_VIT_RESET(vit_from); !IGRAPH_VIT_END(vit_from); IGRAPH_VIT_NEXT(vit_from)) { + i = IGRAPH_VIT_GET(vit_from); v1 = igraph_lazy_adjlist_get(&al, i); IGRAPH_CHECK_OOM(v1, "Failed to query neighbors."); if (!igraph_vector_int_binsearch(v1, i, &k)) { @@ -362,18 +364,18 @@ igraph_error_t igraph_similarity_jaccard(const igraph_t *graph, igraph_matrix_t } } - for (IGRAPH_VIT_RESET(vit), i = 0; - !IGRAPH_VIT_END(vit); IGRAPH_VIT_NEXT(vit), i++) { + for (IGRAPH_VIT_RESET(vit_from), i = 0; + !IGRAPH_VIT_END(vit_from); IGRAPH_VIT_NEXT(vit_from), i++) { MATRIX(*res, i, i) = 1.0; - for (IGRAPH_VIT_RESET(vit2), j = 0; - !IGRAPH_VIT_END(vit2); IGRAPH_VIT_NEXT(vit2), j++) { + for (IGRAPH_VIT_RESET(vit_to), j = 0; + !IGRAPH_VIT_END(vit_to); IGRAPH_VIT_NEXT(vit_to), j++) { if (j <= i) { continue; } - v1 = igraph_lazy_adjlist_get(&al, IGRAPH_VIT_GET(vit)); + v1 = igraph_lazy_adjlist_get(&al, IGRAPH_VIT_GET(vit_from)); IGRAPH_CHECK_OOM(v1, "Failed to query neighbors."); - v2 = igraph_lazy_adjlist_get(&al, IGRAPH_VIT_GET(vit2)); + v2 = igraph_lazy_adjlist_get(&al, IGRAPH_VIT_GET(vit_to)); IGRAPH_CHECK_OOM(v2, "Failed to query neighbors."); IGRAPH_CHECK(igraph_i_neisets_intersect(v1, v2, &len_union, &len_intersection)); @@ -387,8 +389,8 @@ igraph_error_t igraph_similarity_jaccard(const igraph_t *graph, igraph_matrix_t } igraph_lazy_adjlist_destroy(&al); - igraph_vit_destroy(&vit); - igraph_vit_destroy(&vit2); + igraph_vit_destroy(&vit_from); + igraph_vit_destroy(&vit_to); IGRAPH_FINALLY_CLEAN(3); return IGRAPH_SUCCESS; @@ -593,9 +595,11 @@ igraph_error_t igraph_similarity_jaccard_es(const igraph_t *graph, igraph_vector * \param graph The graph object to analyze. * \param res Pointer to a matrix, the result of the calculation will * be stored here. The number of its rows and columns is the same - * as the number of vertex IDs in \p vids. - * \param vids The vertex IDs of the vertices for which the - * calculation will be done. + * as the number of vertex IDs in \p vit_from and \p vit_to, respectively. + * \param vit_from The vertex IDs of the first vertices of the + * pairs for which the calculation will be done. + * \param vit_to The vertex IDs of the second vertices of the + * pairs for which the calculation will be done. * \param mode The type of neighbors to be used for the calculation in * directed graphs. Possible values: * \clist @@ -629,10 +633,10 @@ igraph_error_t igraph_similarity_jaccard_es(const igraph_t *graph, igraph_vector * \example examples/simple/igraph_similarity.c */ igraph_error_t igraph_similarity_dice(const igraph_t *graph, igraph_matrix_t *res, - const igraph_vs_t vids, + const igraph_vs_t vit_from, const igraph_vs_t vit_to, igraph_neimode_t mode, igraph_bool_t loops) { - IGRAPH_CHECK(igraph_similarity_jaccard(graph, res, vids, mode, loops)); + IGRAPH_CHECK(igraph_similarity_jaccard(graph, res, vit_from, vit_to, mode, loops)); igraph_integer_t nr = igraph_matrix_nrow(res); igraph_integer_t nc = igraph_matrix_ncol(res); diff --git a/src/vendor/cigraph/src/misc/conversion.c b/src/vendor/cigraph/src/misc/conversion.c index a1caa0a2f0c..3dca1b6ec38 100644 --- a/src/vendor/cigraph/src/misc/conversion.c +++ b/src/vendor/cigraph/src/misc/conversion.c @@ -450,8 +450,7 @@ igraph_error_t igraph_to_directed(igraph_t *graph, no_of_nodes, IGRAPH_DIRECTED)); IGRAPH_FINALLY(igraph_destroy, &newgraph); - IGRAPH_I_ATTRIBUTE_DESTROY(&newgraph); - IGRAPH_I_ATTRIBUTE_COPY(&newgraph, graph, true, true, true); + IGRAPH_CHECK(igraph_i_attribute_copy(&newgraph, graph, true, true, true)); igraph_vector_int_destroy(&edges); IGRAPH_FINALLY_CLEAN(2); @@ -483,8 +482,7 @@ igraph_error_t igraph_to_directed(igraph_t *graph, no_of_nodes, IGRAPH_DIRECTED)); IGRAPH_FINALLY(igraph_destroy, &newgraph); - IGRAPH_I_ATTRIBUTE_DESTROY(&newgraph); - IGRAPH_I_ATTRIBUTE_COPY(&newgraph, graph, true, true, /*edges=*/false); + IGRAPH_CHECK(igraph_i_attribute_copy(&newgraph, graph, true, true, /* edges= */ false)); IGRAPH_CHECK(igraph_i_attribute_permute_edges(graph, &newgraph, &index)); igraph_vector_int_destroy(&index); @@ -584,8 +582,7 @@ igraph_error_t igraph_to_undirected(igraph_t *graph, IGRAPH_UNDIRECTED)); IGRAPH_FINALLY(igraph_destroy, &newgraph); igraph_vector_int_destroy(&edges); - IGRAPH_I_ATTRIBUTE_DESTROY(&newgraph); - IGRAPH_I_ATTRIBUTE_COPY(&newgraph, graph, true, true, true); + IGRAPH_CHECK(igraph_i_attribute_copy(&newgraph, graph, true, true, true)); IGRAPH_FINALLY_CLEAN(2); igraph_destroy(graph); *graph = newgraph; @@ -682,8 +679,7 @@ igraph_error_t igraph_to_undirected(igraph_t *graph, IGRAPH_UNDIRECTED)); IGRAPH_FINALLY(igraph_destroy, &newgraph); igraph_vector_int_destroy(&edges); - IGRAPH_I_ATTRIBUTE_DESTROY(&newgraph); - IGRAPH_I_ATTRIBUTE_COPY(&newgraph, graph, true, true, /*edges*/ false); /* no edge attributes */ + IGRAPH_CHECK(igraph_i_attribute_copy(&newgraph, graph, true, true, /* edges= */ false)); if (attr) { igraph_fixed_vectorlist_t vl; @@ -772,8 +768,7 @@ igraph_error_t igraph_to_undirected(igraph_t *graph, IGRAPH_UNDIRECTED)); IGRAPH_FINALLY(igraph_destroy, &newgraph); igraph_vector_int_destroy(&edges); - IGRAPH_I_ATTRIBUTE_DESTROY(&newgraph); - IGRAPH_I_ATTRIBUTE_COPY(&newgraph, graph, true, true, /*edges*/ false); /* no edge attributes */ + IGRAPH_CHECK(igraph_i_attribute_copy(&newgraph, graph, true, true, /* edges= */ false)); if (attr) { igraph_fixed_vectorlist_t vl; diff --git a/src/vendor/cigraph/src/misc/cycle_bases.c b/src/vendor/cigraph/src/misc/cycle_bases.c index 425a62cf5dd..811f95b9dfd 100644 --- a/src/vendor/cigraph/src/misc/cycle_bases.c +++ b/src/vendor/cigraph/src/misc/cycle_bases.c @@ -346,7 +346,7 @@ static igraph_error_t gaussian_elimination(igraph_vector_int_list_t *reduced_mat IGRAPH_FINALLY_CLEAN(2); return IGRAPH_SUCCESS; } - IGRAPH_CHECK(igraph_vector_int_swap(&work, &tmp)); + igraph_vector_int_swap(&work, &tmp); } else { /* VECTOR(*row)[0] > VECTOR(work)[0] */ break; } diff --git a/src/vendor/cigraph/src/misc/microscopic_update.c b/src/vendor/cigraph/src/misc/microscopic_update.c index 25a0936b072..efd99763cf1 100644 --- a/src/vendor/cigraph/src/misc/microscopic_update.c +++ b/src/vendor/cigraph/src/misc/microscopic_update.c @@ -601,7 +601,7 @@ igraph_error_t igraph_deterministic_optimal_imitation(const igraph_t *graph, /* at random. */ IGRAPH_VECTOR_INT_INIT_FINALLY(&adj, 0); IGRAPH_CHECK(igraph_neighbors(graph, &adj, vid, mode)); - IGRAPH_CHECK(igraph_vector_int_shuffle(&adj)); + igraph_vector_int_shuffle(&adj); /* maximum deterministic imitation */ i = vid; q = VECTOR(*quantities)[vid]; diff --git a/src/vendor/cigraph/src/operators/complementer.c b/src/vendor/cigraph/src/operators/complementer.c index f6a41c6327a..4944943ee37 100644 --- a/src/vendor/cigraph/src/operators/complementer.c +++ b/src/vendor/cigraph/src/operators/complementer.c @@ -95,8 +95,7 @@ igraph_error_t igraph_complementer(igraph_t *res, const igraph_t *graph, IGRAPH_CHECK(igraph_create(res, &edges, no_of_nodes, igraph_is_directed(graph))); igraph_vector_int_destroy(&edges); igraph_vector_int_destroy(&neis); - IGRAPH_I_ATTRIBUTE_DESTROY(res); - IGRAPH_I_ATTRIBUTE_COPY(res, graph, /*graph=*/true, /*vertex=*/true, /*edge=*/false); + IGRAPH_CHECK(igraph_i_attribute_copy(res, graph, true, true, /* edges= */ false)); IGRAPH_FINALLY_CLEAN(2); return IGRAPH_SUCCESS; } diff --git a/src/vendor/cigraph/src/operators/connect_neighborhood.c b/src/vendor/cigraph/src/operators/connect_neighborhood.c index ce56ffe5735..01974c37f79 100644 --- a/src/vendor/cigraph/src/operators/connect_neighborhood.c +++ b/src/vendor/cigraph/src/operators/connect_neighborhood.c @@ -218,8 +218,7 @@ igraph_error_t igraph_graph_power(const igraph_t *graph, igraph_t *res, } IGRAPH_CHECK(igraph_empty(res, no_of_nodes, dir)); - IGRAPH_I_ATTRIBUTE_DESTROY(res); - IGRAPH_I_ATTRIBUTE_COPY(res, graph, /* graph */ true, /* vertex */ true, /* edge */ false); + IGRAPH_CHECK(igraph_i_attribute_copy(res, graph, true, true, /* edges= */ false)); if (order == 0) { return IGRAPH_SUCCESS; } diff --git a/src/vendor/cigraph/src/operators/contract.c b/src/vendor/cigraph/src/operators/contract.c index 4413ac5022c..90a5afe5698 100644 --- a/src/vendor/cigraph/src/operators/contract.c +++ b/src/vendor/cigraph/src/operators/contract.c @@ -114,8 +114,7 @@ igraph_error_t igraph_contract_vertices(igraph_t *graph, IGRAPH_FINALLY(igraph_destroy, &res); - IGRAPH_I_ATTRIBUTE_DESTROY(&res); - IGRAPH_I_ATTRIBUTE_COPY(&res, graph, /*graph=*/ true, /*vertex=*/ false, /*edge=*/ true); + IGRAPH_CHECK(igraph_i_attribute_copy(&res, graph, true, /* vertex= */ false, true)); if (vattr) { igraph_vector_int_list_t merges; diff --git a/src/vendor/cigraph/src/operators/difference.c b/src/vendor/cigraph/src/operators/difference.c index f9c5786d65a..094e97e2847 100644 --- a/src/vendor/cigraph/src/operators/difference.c +++ b/src/vendor/cigraph/src/operators/difference.c @@ -171,8 +171,7 @@ igraph_error_t igraph_difference(igraph_t *res, /* Attributes */ if (orig->attr) { - IGRAPH_I_ATTRIBUTE_DESTROY(res); - IGRAPH_I_ATTRIBUTE_COPY(res, orig, /*graph=*/ true, /*vertex=*/ true, /*edge=*/ false); + IGRAPH_CHECK(igraph_i_attribute_copy(res, orig, true, true, /* edge= */ false)); IGRAPH_CHECK(igraph_i_attribute_permute_edges(orig, res, &edge_ids)); } diff --git a/src/vendor/cigraph/src/operators/permute.c b/src/vendor/cigraph/src/operators/permute.c index 3fcfb3b8846..7742eb1963b 100644 --- a/src/vendor/cigraph/src/operators/permute.c +++ b/src/vendor/cigraph/src/operators/permute.c @@ -110,8 +110,7 @@ igraph_error_t igraph_permute_vertices(const igraph_t *graph, igraph_t *res, /* Attributes */ if (graph->attr) { igraph_vector_int_t vtypes; - IGRAPH_I_ATTRIBUTE_DESTROY(res); - IGRAPH_I_ATTRIBUTE_COPY(res, graph, /*graph=*/1, /*vertex=*/0, /*edge=*/1); + IGRAPH_CHECK(igraph_i_attribute_copy(res, graph, true, /* vertex= */ false, true)); IGRAPH_VECTOR_INT_INIT_FINALLY(&vtypes, 0); IGRAPH_CHECK(igraph_i_attribute_get_info(graph, 0, 0, 0, &vtypes, 0, 0)); if (igraph_vector_int_size(&vtypes) != 0) { diff --git a/src/vendor/cigraph/src/operators/reverse.c b/src/vendor/cigraph/src/operators/reverse.c index ff1c011b9bd..0bf4a91ba67 100644 --- a/src/vendor/cigraph/src/operators/reverse.c +++ b/src/vendor/cigraph/src/operators/reverse.c @@ -88,8 +88,7 @@ igraph_error_t igraph_reverse_edges(igraph_t *graph, const igraph_es_t eids) { IGRAPH_CHECK(igraph_create(&new_graph, &edges, no_of_nodes, IGRAPH_DIRECTED)); IGRAPH_FINALLY(igraph_destroy, &new_graph); - IGRAPH_I_ATTRIBUTE_DESTROY(&new_graph); - IGRAPH_I_ATTRIBUTE_COPY(&new_graph, graph, 1, 1, 1); /* does IGRAPH_CHECK */ + IGRAPH_CHECK(igraph_i_attribute_copy(&new_graph, graph, true, true, true)); igraph_eit_destroy(&eit); igraph_vector_int_destroy(&edges); diff --git a/src/vendor/cigraph/src/operators/rewire_edges.c b/src/vendor/cigraph/src/operators/rewire_edges.c index 6c5b856bfe2..d6f6585e65d 100644 --- a/src/vendor/cigraph/src/operators/rewire_edges.c +++ b/src/vendor/cigraph/src/operators/rewire_edges.c @@ -274,8 +274,7 @@ igraph_error_t igraph_rewire_edges(igraph_t *graph, igraph_real_t prob, IGRAPH_FINALLY_CLEAN(1); IGRAPH_FINALLY(igraph_destroy, &newgraph); - IGRAPH_I_ATTRIBUTE_DESTROY(&newgraph); - IGRAPH_I_ATTRIBUTE_COPY(&newgraph, graph, 1, 1, 1); + IGRAPH_CHECK(igraph_i_attribute_copy(&newgraph, graph, true, true, true)); IGRAPH_FINALLY_CLEAN(1); igraph_destroy(graph); *graph = newgraph; @@ -381,8 +380,7 @@ igraph_error_t igraph_rewire_directed_edges(igraph_t *graph, igraph_real_t prob, IGRAPH_FINALLY_CLEAN(1); IGRAPH_FINALLY(igraph_destroy, &newgraph); - IGRAPH_I_ATTRIBUTE_DESTROY(&newgraph); - IGRAPH_I_ATTRIBUTE_COPY(&newgraph, graph, 1, 1, 1); + IGRAPH_CHECK(igraph_i_attribute_copy(&newgraph, graph, true, true, true)); IGRAPH_FINALLY_CLEAN(1); igraph_destroy(graph); *graph = newgraph; diff --git a/src/vendor/cigraph/src/operators/simplify.c b/src/vendor/cigraph/src/operators/simplify.c index 2ae746b4ac1..c6481e5242a 100644 --- a/src/vendor/cigraph/src/operators/simplify.c +++ b/src/vendor/cigraph/src/operators/simplify.c @@ -172,8 +172,7 @@ igraph_error_t igraph_simplify(igraph_t *graph, IGRAPH_FINALLY(igraph_destroy, &res); - IGRAPH_I_ATTRIBUTE_DESTROY(&res); - IGRAPH_I_ATTRIBUTE_COPY(&res, graph, /*graph=*/ true, /*vertex=*/ true, /*edge=*/ false); + IGRAPH_CHECK(igraph_i_attribute_copy(&res, graph, true, true, /* edges= */ false)); if (attr) { igraph_fixed_vectorlist_t vl; diff --git a/src/vendor/cigraph/src/operators/subgraph.c b/src/vendor/cigraph/src/operators/subgraph.c index d20dfd9eb0e..134a70cd7a0 100644 --- a/src/vendor/cigraph/src/operators/subgraph.c +++ b/src/vendor/cigraph/src/operators/subgraph.c @@ -82,7 +82,7 @@ static igraph_error_t igraph_i_induced_subgraph_copy_and_delete( IGRAPH_CHECK(igraph_copy(res, graph)); IGRAPH_FINALLY(igraph_destroy, res); - IGRAPH_CHECK(igraph_delete_vertices_idx(res, igraph_vss_vector(&delete), + IGRAPH_CHECK(igraph_delete_vertices_map(res, igraph_vss_vector(&delete), map, invmap)); igraph_vector_int_destroy(&delete); @@ -137,10 +137,11 @@ static igraph_error_t igraph_i_induced_subgraph_create_from_scratch( my_vids_old2new = map; if (!map_is_prepared) { IGRAPH_CHECK(igraph_vector_int_resize(map, no_of_nodes)); - igraph_vector_int_null(map); + igraph_vector_int_fill(map, -1); } } else { IGRAPH_VECTOR_INT_INIT_FINALLY(&vids_old2new, no_of_nodes); + igraph_vector_int_fill(&vids_old2new, -1); } IGRAPH_VECTOR_INT_INIT_FINALLY(&vids_vec, 0); @@ -166,10 +167,10 @@ static igraph_error_t igraph_i_induced_subgraph_create_from_scratch( /* Cater for duplicate vertex IDs in the input vertex selector; we use * the first occurrence of each vertex ID and ignore the rest */ - if (VECTOR(*my_vids_old2new)[vid] == 0) { + if (VECTOR(*my_vids_old2new)[vid] < 0) { IGRAPH_CHECK(igraph_vector_int_push_back(my_vids_new2old, vid)); - no_of_new_nodes++; VECTOR(*my_vids_old2new)[vid] = no_of_new_nodes; + no_of_new_nodes++; } } igraph_vector_int_destroy(&vids_vec); @@ -190,12 +191,12 @@ static igraph_error_t igraph_i_induced_subgraph_create_from_scratch( eid = VECTOR(nei_edges)[j]; to = VECTOR(*my_vids_old2new)[ IGRAPH_TO(graph, eid) ]; - if (!to) { + if (to < 0) { continue; } IGRAPH_CHECK(igraph_vector_int_push_back(&new_edges, new_vid)); - IGRAPH_CHECK(igraph_vector_int_push_back(&new_edges, to - 1)); + IGRAPH_CHECK(igraph_vector_int_push_back(&new_edges, to)); IGRAPH_CHECK(igraph_vector_int_push_back(&eids_new2old, eid)); } } else { @@ -212,10 +213,9 @@ static igraph_error_t igraph_i_induced_subgraph_create_from_scratch( } to = VECTOR(*my_vids_old2new)[ IGRAPH_TO(graph, eid) ]; - if (!to) { + if (to < 0) { continue; } - to -= 1; if (new_vid == to) { /* this is a loop edge; check whether we need to skip it */ @@ -242,7 +242,6 @@ static igraph_error_t igraph_i_induced_subgraph_create_from_scratch( /* Create the new graph */ IGRAPH_CHECK(igraph_create(res, &new_edges, no_of_new_nodes, directed)); - IGRAPH_I_ATTRIBUTE_DESTROY(res); /* Now we can also get rid of the new_edges vector */ igraph_vector_int_destroy(&new_edges); @@ -253,8 +252,7 @@ static igraph_error_t igraph_i_induced_subgraph_create_from_scratch( IGRAPH_FINALLY(igraph_destroy, res); /* Copy the graph attributes */ - IGRAPH_CHECK(igraph_i_attribute_copy(res, graph, - /* ga = */ 1, /* va = */ 0, /* ea = */ 0)); + IGRAPH_CHECK(igraph_i_attribute_copy(res, graph, true, /* vertex= */ false, /* edge= */ false)); /* Copy the vertex attributes */ IGRAPH_CHECK(igraph_i_attribute_permute_vertices(graph, res, my_vids_new2old)); @@ -406,12 +404,12 @@ igraph_error_t igraph_i_induced_subgraph_map(const igraph_t *graph, igraph_t *re * two methods automatically based on the ratio of the number * of vertices in the new and the old graph. * \param map Returns a map of the vertices in \p graph to the vertices - * in \p res. A 0 indicates a vertex is not mapped. An \c i + 1 at + * in \p res. -1 indicates a vertex is not mapped. A value of \c i at * position \c j indicates the vertex \c j in \p graph is mapped * to vertex i in \p res. * \param invmap Returns a map of the vertices in \p res to the vertices - * in \p graph. An i at position \c j indicates the vertex \c i - * in \p graph is mapped to vertex j in \p res. + * in \p graph. A value of \c i at position \c j indicates that + * vertex \c i in \p graph is mapped to vertex \c j in \p res. * * \return Error code: * \c IGRAPH_ENOMEM, not enough memory for @@ -437,7 +435,7 @@ igraph_error_t igraph_induced_subgraph_map(const igraph_t *graph, igraph_t *res, /** * \function igraph_induced_subgraph_edges - * \brief The edges contained within an induced subgraph. + * \brief The edges contained within an induced sugraph. * * This function finds the IDs of those edges which connect vertices from * a given list, passed in the \p vids parameter. @@ -505,7 +503,7 @@ igraph_error_t igraph_induced_subgraph_edges(const igraph_t *graph, igraph_vs_t /** * \ingroup structural * \function igraph_subgraph_edges - * \brief Creates a subgraph with the specified edges and their endpoints (deprecated alias). + * \brief Creates a subgraph with the specified edges and their endpoints. * * \deprecated-by igraph_subgraph_from_edges 0.10.3 */ @@ -521,6 +519,7 @@ igraph_error_t igraph_subgraph_edges( * \function igraph_subgraph_from_edges * \brief Creates a subgraph with the specified edges and their endpoints. * + * * This function collects the specified edges and their endpoints to a new * graph. As the edge IDs in a graph always start with zero, this function * very likely needs to reassign IDs to the edges. Vertex IDs may also be diff --git a/src/vendor/cigraph/src/paths/bellman_ford.c b/src/vendor/cigraph/src/paths/bellman_ford.c index 0b02c0c3ea2..d7d52ba54c7 100644 --- a/src/vendor/cigraph/src/paths/bellman_ford.c +++ b/src/vendor/cigraph/src/paths/bellman_ford.c @@ -580,12 +580,12 @@ igraph_error_t igraph_get_shortest_path_bellman_ford(const igraph_t *graph, /* We use the constant time vector_swap() instead of the linear-time vector_update() to move the result to the output parameter. */ if (edges) { - IGRAPH_CHECK(igraph_vector_int_swap(edges, igraph_vector_int_list_get_ptr(&edges2, 0))); + igraph_vector_int_swap(edges, igraph_vector_int_list_get_ptr(&edges2, 0)); igraph_vector_int_list_destroy(&edges2); IGRAPH_FINALLY_CLEAN(1); } if (vertices) { - IGRAPH_CHECK(igraph_vector_int_swap(vertices, igraph_vector_int_list_get_ptr(&vertices2, 0))); + igraph_vector_int_swap(vertices, igraph_vector_int_list_get_ptr(&vertices2, 0)); igraph_vector_int_list_destroy(&vertices2); IGRAPH_FINALLY_CLEAN(1); } diff --git a/src/vendor/cigraph/src/paths/dijkstra.c b/src/vendor/cigraph/src/paths/dijkstra.c index 3f5fa24f9e9..9ccfcb79c43 100644 --- a/src/vendor/cigraph/src/paths/dijkstra.c +++ b/src/vendor/cigraph/src/paths/dijkstra.c @@ -696,12 +696,12 @@ igraph_error_t igraph_get_shortest_path_dijkstra(const igraph_t *graph, /* We use the constant time vector_swap() instead of the linear-time vector_update() to move the result to the output parameter. */ if (edges) { - IGRAPH_CHECK(igraph_vector_int_swap(edges, igraph_vector_int_list_get_ptr(&edges2, 0))); + igraph_vector_int_swap(edges, igraph_vector_int_list_get_ptr(&edges2, 0)); igraph_vector_int_list_destroy(&edges2); IGRAPH_FINALLY_CLEAN(1); } if (vertices) { - IGRAPH_CHECK(igraph_vector_int_swap(vertices, igraph_vector_int_list_get_ptr(&vertices2, 0))); + igraph_vector_int_swap(vertices, igraph_vector_int_list_get_ptr(&vertices2, 0)); igraph_vector_int_list_destroy(&vertices2); IGRAPH_FINALLY_CLEAN(1); } diff --git a/src/vendor/cigraph/src/paths/johnson.c b/src/vendor/cigraph/src/paths/johnson.c index fdd09ffc8a0..ea9c7eac6f9 100644 --- a/src/vendor/cigraph/src/paths/johnson.c +++ b/src/vendor/cigraph/src/paths/johnson.c @@ -66,7 +66,12 @@ * vertex twice or more. * \param weights Optional edge weights. If it is a null-pointer, then * the unweighted breadth-first search based \ref igraph_distances() will - * be called. Edges with positive infinite weights are ignored. + * be called. Edges with positive infinite weights are ignored. + * \param mode For directed graphs; whether to follow paths along edge + * directions (\c IGRAPH_OUT), or the opposite (\c IGRAPH_IN), or + * ignore edge directions completely (\c IGRAPH_ALL). It is ignored + * for undirected graphs. \c IGRAPH_ALL should not be used with + * negative weights. * \return Error code. * * Time complexity: O(s|V|log|V|+|V||E|), |V| and |E| are the number @@ -81,7 +86,8 @@ igraph_error_t igraph_distances_johnson(const igraph_t *graph, igraph_matrix_t *res, const igraph_vs_t from, const igraph_vs_t to, - const igraph_vector_t *weights) { + const igraph_vector_t *weights, + igraph_neimode_t mode) { igraph_integer_t no_of_nodes = igraph_vcount(graph); igraph_integer_t no_of_edges = igraph_ecount(graph); @@ -96,7 +102,7 @@ igraph_error_t igraph_distances_johnson(const igraph_t *graph, /* If no weights, then we can just run the unweighted version */ if (!weights) { - return igraph_distances(graph, res, from, to, IGRAPH_OUT); + return igraph_distances(graph, res, from, to, mode); } if (igraph_vector_size(weights) != no_of_edges) { @@ -107,7 +113,7 @@ igraph_error_t igraph_distances_johnson(const igraph_t *graph, /* If no edges, then we can just run the unweighted version */ if (no_of_edges == 0) { - return igraph_distances(graph, res, from, to, IGRAPH_OUT); + return igraph_distances(graph, res, from, to, mode); } /* If no negative weights, then we can run Dijkstra's algorithm */ @@ -117,13 +123,13 @@ igraph_error_t igraph_distances_johnson(const igraph_t *graph, IGRAPH_ERROR("Weight vector must not contain NaN values.", IGRAPH_EINVAL); } if (min_weight >= 0) { - return igraph_distances_dijkstra(graph, res, from, to, weights, IGRAPH_OUT); + return igraph_distances_dijkstra(graph, res, from, to, weights, mode); } } - if (!igraph_is_directed(graph)) { - IGRAPH_ERROR("Johnson's shortest path: undirected graph and negative weight.", - IGRAPH_EINVAL); + if (!igraph_is_directed(graph) || mode == IGRAPH_ALL) { + IGRAPH_ERROR("Undirected graph with negative weight.", + IGRAPH_ENEGLOOP); } /* ------------------------------------------------------------ */ @@ -142,9 +148,16 @@ igraph_error_t igraph_distances_johnson(const igraph_t *graph, IGRAPH_VECTOR_INT_INIT_FINALLY(&edges, no_edges_reserved); igraph_get_edgelist(graph, &edges, /*bycol=*/ 0); /* reserved */ igraph_vector_int_resize(&edges, no_edges_reserved); /* reserved */ - for (i = 0, ptr = no_of_edges * 2; i < no_of_nodes; i++) { - VECTOR(edges)[ptr++] = no_of_nodes; - VECTOR(edges)[ptr++] = i; + if (mode == IGRAPH_OUT) { + for (i = 0, ptr = no_of_edges * 2; i < no_of_nodes; i++) { + VECTOR(edges)[ptr++] = no_of_nodes; + VECTOR(edges)[ptr++] = i; + } + } else { + for (i = 0, ptr = no_of_edges * 2; i < no_of_nodes; i++) { + VECTOR(edges)[ptr++] = i; + VECTOR(edges)[ptr++] = no_of_nodes; + } } IGRAPH_CHECK(igraph_add_edges(&newgraph, &edges, 0)); igraph_vector_int_destroy(&edges); @@ -162,7 +175,7 @@ igraph_error_t igraph_distances_johnson(const igraph_t *graph, IGRAPH_CHECK(igraph_distances_bellman_ford(&newgraph, &bfres, igraph_vss_1(no_of_nodes), - igraph_vss_all(), &newweights, IGRAPH_OUT)); + igraph_vss_all(), &newweights, mode)); igraph_destroy(&newgraph); IGRAPH_FINALLY_CLEAN(1); @@ -175,7 +188,11 @@ igraph_error_t igraph_distances_johnson(const igraph_t *graph, for (i = 0; i < no_of_edges; i++) { igraph_integer_t ffrom = IGRAPH_FROM(graph, i); igraph_integer_t tto = IGRAPH_TO(graph, i); - VECTOR(newweights)[i] += MATRIX(bfres, 0, ffrom) - MATRIX(bfres, 0, tto); + if (mode == IGRAPH_OUT) { + VECTOR(newweights)[i] += MATRIX(bfres, 0, ffrom) - MATRIX(bfres, 0, tto); + } else { + VECTOR(newweights)[i] += MATRIX(bfres, 0, tto) - MATRIX(bfres, 0, ffrom); + } /* If a weight becomes slightly negative due to roundoff errors, snap it to exact zero. */ @@ -185,7 +202,7 @@ igraph_error_t igraph_distances_johnson(const igraph_t *graph, /* Run Dijkstra's algorithm on the new weights */ IGRAPH_CHECK(igraph_distances_dijkstra(graph, res, from, to, &newweights, - IGRAPH_OUT)); + mode)); igraph_vector_destroy(&newweights); IGRAPH_FINALLY_CLEAN(1); @@ -202,8 +219,14 @@ igraph_error_t igraph_distances_johnson(const igraph_t *graph, if (igraph_vs_is_all(&to)) { igraph_integer_t v2; for (v2 = 0; v2 < nc; v2++) { - igraph_real_t sub = MATRIX(bfres, 0, v1) - MATRIX(bfres, 0, v2); - MATRIX(*res, i, v2) -= sub; + igraph_real_t sub; + if (mode == IGRAPH_OUT) { + sub = MATRIX(bfres, 0, v1) - MATRIX(bfres, 0, v2); + MATRIX(*res, i, v2) -= sub; + } else { + sub = MATRIX(bfres, 0, v2) - MATRIX(bfres, 0, v1); + MATRIX(*res, v2, i) -= sub; + } } } else { igraph_integer_t j; @@ -211,9 +234,15 @@ igraph_error_t igraph_distances_johnson(const igraph_t *graph, IGRAPH_CHECK(igraph_vit_create(graph, to, &tovit)); IGRAPH_FINALLY(igraph_vit_destroy, &tovit); for (j = 0, IGRAPH_VIT_RESET(tovit); j < nc; j++, IGRAPH_VIT_NEXT(tovit)) { + igraph_real_t sub; igraph_integer_t v2 = IGRAPH_VIT_GET(tovit); - igraph_real_t sub = MATRIX(bfres, 0, v1) - MATRIX(bfres, 0, v2); - MATRIX(*res, i, j) -= sub; + if (mode == IGRAPH_OUT) { + sub = MATRIX(bfres, 0, v1) - MATRIX(bfres, 0, v2); + MATRIX(*res, i, j) -= sub; + } else { + sub = MATRIX(bfres, 0, v2) - MATRIX(bfres, 0, v1); + MATRIX(*res, j, i) -= sub; + } } igraph_vit_destroy(&tovit); IGRAPH_FINALLY_CLEAN(1); @@ -238,5 +267,5 @@ igraph_error_t igraph_shortest_paths_johnson(const igraph_t *graph, const igraph_vs_t from, const igraph_vs_t to, const igraph_vector_t *weights) { - return igraph_distances_johnson(graph, res, from, to, weights); + return igraph_distances_johnson(graph, res, from, to, weights, IGRAPH_OUT); } diff --git a/src/vendor/cigraph/src/paths/unweighted.c b/src/vendor/cigraph/src/paths/unweighted.c index 2bf3affafe7..e412cb6eddf 100644 --- a/src/vendor/cigraph/src/paths/unweighted.c +++ b/src/vendor/cigraph/src/paths/unweighted.c @@ -605,12 +605,12 @@ igraph_error_t igraph_get_shortest_path(const igraph_t *graph, /* We use the constant time vector_swap() instead of the linear-time vector_update() to move the result to the output parameter. */ if (edges) { - IGRAPH_CHECK(igraph_vector_int_swap(edges, igraph_vector_int_list_get_ptr(&edges2, 0))); + igraph_vector_int_swap(edges, igraph_vector_int_list_get_ptr(&edges2, 0)); igraph_vector_int_list_destroy(&edges2); IGRAPH_FINALLY_CLEAN(1); } if (vertices) { - IGRAPH_CHECK(igraph_vector_int_swap(vertices, igraph_vector_int_list_get_ptr(&vertices2, 0))); + igraph_vector_int_swap(vertices, igraph_vector_int_list_get_ptr(&vertices2, 0)); igraph_vector_int_list_destroy(&vertices2); IGRAPH_FINALLY_CLEAN(1); } diff --git a/src/vendor/cigraph/src/random/random.c b/src/vendor/cigraph/src/random/random.c index b5b44451ae3..376af1e4109 100644 --- a/src/vendor/cigraph/src/random/random.c +++ b/src/vendor/cigraph/src/random/random.c @@ -146,32 +146,32 @@ * igraph_rng_set_default() function. */ -extern IGRAPH_THREAD_LOCAL igraph_rng_t igraph_i_rng_default; /* defined in rng_pcg32.c */ +extern igraph_rng_t igraph_i_rng_default; /* defined in rng_pcg32.c */ +IGRAPH_THREAD_LOCAL igraph_rng_t *igraph_i_rng_default_ptr = &igraph_i_rng_default; /** * \function igraph_rng_set_default * \brief Set the default igraph random number generator. * - * This function \em copies the internal structure of the given \type igraph_rng_t - * object to igraph's internal default RNG structure. The structure itself - * contains two pointers only, one to the "methods" of the RNG and one to the - * memory buffer holding the internal state of the RNG. This means that if you - * keep on generating random numbers from the RNG after setting it as the - * default, it will affect the state of the default RNG as well because the two - * share the same state pointer. However, do \em not expect - * \ref igraph_rng_default() to return the same pointer as the one you passed - * in here - the state is shared, but the entire structure is not. + * This function updates the default RNG used by igraph to be the one + * pointed to by \p rng, and returns a pointer to the previous default + * RNG. Future calls to \ref igraph_rng_default() will return the same + * pointer as \p rng. The RNG pointed to by \p rng must not be destroyed + * for as long as it is used as the default. * * \param rng The random number generator to use as default from now * on. Calling \ref igraph_rng_destroy() on it, while it is still * being used as the default will result in crashes and/or * unpredictable results. + * \return Pointer the previous default RNG. * * Time complexity: O(1). */ -void igraph_rng_set_default(igraph_rng_t *rng) { - igraph_i_rng_default = (*rng); +igraph_rng_t *igraph_rng_set_default(igraph_rng_t *rng) { + igraph_rng_t *old_rng = igraph_i_rng_default_ptr; + igraph_i_rng_default_ptr = rng; + return old_rng; } @@ -187,7 +187,7 @@ void igraph_rng_set_default(igraph_rng_t *rng) { */ igraph_rng_t *igraph_rng_default(void) { - return &igraph_i_rng_default; + return igraph_i_rng_default_ptr; } /* ------------------------------------ */ diff --git a/src/vendor/cigraph/src/random/rng_pcg32.c b/src/vendor/cigraph/src/random/rng_pcg32.c index fb51b1ba2f8..7d5655eb4fe 100644 --- a/src/vendor/cigraph/src/random/rng_pcg32.c +++ b/src/vendor/cigraph/src/random/rng_pcg32.c @@ -115,7 +115,7 @@ const igraph_rng_type_t igraph_rngtype_pcg32 = { static pcg32_random_t igraph_i_rng_default_state = PCG32_INITIALIZER; -IGRAPH_THREAD_LOCAL igraph_rng_t igraph_i_rng_default = { +igraph_rng_t igraph_i_rng_default = { addr(igraph_rngtype_pcg32), addr(igraph_i_rng_default_state), /* is_seeded = */ true diff --git a/src/vendor/igraph_version.h b/src/vendor/igraph_version.h index 431e981cfad..843560befd1 100644 --- a/src/vendor/igraph_version.h +++ b/src/vendor/igraph_version.h @@ -28,11 +28,11 @@ __BEGIN_DECLS -#define IGRAPH_VERSION "0.10.10-81-g857a12506" +#define IGRAPH_VERSION "0.10.10-275-g0f383457a" #define IGRAPH_VERSION_MAJOR 0 #define IGRAPH_VERSION_MINOR 10 #define IGRAPH_VERSION_PATCH 10 -#define IGRAPH_VERSION_PRERELEASE "81-g857a12506" +#define IGRAPH_VERSION_PRERELEASE "275-g0f383457a" IGRAPH_EXPORT void igraph_version(const char **version_string, int *major, diff --git a/src/vendor/io/lgl-parser.c b/src/vendor/io/lgl-parser.c index 1218a8a3fb7..ff1fb8cd812 100644 --- a/src/vendor/io/lgl-parser.c +++ b/src/vendor/io/lgl-parser.c @@ -1517,7 +1517,7 @@ YYLTYPE yylloc = yyloc_default; { IGRAPH_YY_CHECK(igraph_vector_int_push_back(context->vector, context->actvertex)); IGRAPH_YY_CHECK(igraph_vector_int_push_back(context->vector, (yyvsp[-1].edgenum))); - IGRAPH_YY_CHECK(igraph_vector_push_back(context->weights, 0)); + IGRAPH_YY_CHECK(igraph_vector_push_back(context->weights, 1.0)); } #line 1523 "src/vendor/io/lgl-parser.c" break; diff --git a/src/vendor/io/ncol-parser.c b/src/vendor/io/ncol-parser.c index 15916ec4094..2c64493ac68 100644 --- a/src/vendor/io/ncol-parser.c +++ b/src/vendor/io/ncol-parser.c @@ -1502,7 +1502,7 @@ YYLTYPE yylloc = yyloc_default; case 5: /* edge: endpoints "end of line" */ #line 97 "src/vendor/cigraph/src/io/ncol-parser.y" { - IGRAPH_YY_CHECK(igraph_vector_push_back(context->weights, 0.0)); + IGRAPH_YY_CHECK(igraph_vector_push_back(context->weights, 1.0)); } #line 1508 "src/vendor/io/ncol-parser.c" break; diff --git a/src/vendor/io/pajek-parser.c b/src/vendor/io/pajek-parser.c index b2e5ae639f4..2a6c3136a23 100644 --- a/src/vendor/io/pajek-parser.c +++ b/src/vendor/io/pajek-parser.c @@ -131,15 +131,17 @@ static igraph_error_t add_numeric_edge_attribute(const char *name, igraph_real_t value, igraph_i_pajek_parsedata_t *context); static igraph_error_t add_numeric_attribute(igraph_trie_t *names, - igraph_vector_ptr_t *attrs, + igraph_attribute_record_list_t *attrs, igraph_integer_t count, const char *attrname, + igraph_real_t default_value, igraph_integer_t vid, igraph_real_t number); static igraph_error_t add_string_attribute(igraph_trie_t *names, - igraph_vector_ptr_t *attrs, + igraph_attribute_record_list_t *attrs, igraph_integer_t count, const char *attrname, + const char *default_value, igraph_integer_t vid, const char *str, igraph_integer_t str_len); @@ -151,11 +153,15 @@ static igraph_error_t make_dynstr(const char *src, size_t len, char **res); static igraph_bool_t is_standard_vattr(const char *attrname); static igraph_bool_t is_standard_eattr(const char *attrname); static igraph_error_t deconflict_attrname(char **attrname); +static igraph_real_t get_default_value_for_numeric_vattr(const char *attrname); +static igraph_real_t get_default_value_for_numeric_eattr(const char *attrname); +static const char* get_default_value_for_string_vattr(const char *attrname); +static const char* get_default_value_for_string_eattr(const char *attrname); #define scanner context->scanner -#line 159 "src/vendor/io/pajek-parser.c" +#line 165 "src/vendor/io/pajek-parser.c" # ifndef YY_CAST # ifdef __cplusplus @@ -678,18 +684,18 @@ static const yytype_int8 yytranslate[] = /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ static const yytype_int16 yyrline[] = { - 0, 188, 188, 199, 199, 201, 201, 203, 205, 215, - 233, 233, 235, 236, 236, 239, 250, 255, 256, 260, - 266, 266, 270, 270, 273, 274, 277, 280, 283, 286, - 289, 292, 295, 298, 301, 306, 309, 312, 315, 318, - 321, 336, 336, 336, 336, 336, 336, 338, 339, 341, - 341, 343, 343, 348, 349, 351, 351, 353, 353, 358, - 358, 362, 362, 365, 366, 369, 372, 375, 378, 381, - 384, 387, 390, 393, 396, 399, 402, 405, 410, 413, - 416, 419, 422, 425, 428, 443, 445, 445, 447, 449, - 449, 451, 453, 458, 460, 460, 462, 464, 464, 466, - 468, 475, 477, 482, 482, 484, 486, 486, 488, 508, - 516, 524, 528, 530, 532, 534 + 0, 194, 194, 205, 205, 207, 207, 209, 211, 221, + 239, 239, 241, 242, 242, 245, 256, 260, 261, 265, + 271, 271, 275, 275, 278, 279, 282, 285, 288, 291, + 294, 297, 300, 303, 306, 311, 314, 317, 320, 323, + 326, 341, 341, 341, 341, 341, 341, 343, 344, 346, + 346, 348, 348, 353, 354, 356, 356, 358, 358, 363, + 363, 367, 367, 370, 371, 374, 377, 380, 383, 386, + 389, 392, 395, 398, 401, 404, 407, 410, 415, 418, + 421, 424, 427, 430, 433, 448, 450, 450, 452, 454, + 454, 456, 458, 463, 465, 465, 467, 469, 469, 471, + 473, 480, 482, 487, 487, 489, 491, 491, 493, 513, + 521, 529, 533, 535, 537, 539 }; #endif @@ -1486,9 +1492,9 @@ yydestruct (const char *yymsg, switch (yykind) { case YYSYMBOL_parname: /* parname */ -#line 133 "src/vendor/cigraph/src/io/pajek-parser.y" +#line 139 "src/vendor/cigraph/src/io/pajek-parser.y" { free(((*yyvaluep).dynstr)); } -#line 1492 "src/vendor/io/pajek-parser.c" +#line 1498 "src/vendor/io/pajek-parser.c" break; default: @@ -1792,7 +1798,7 @@ YYLTYPE yylloc = yyloc_default; switch (yyn) { case 2: /* input: nethead vertices edgeblock final_newlines */ -#line 188 "src/vendor/cigraph/src/io/pajek-parser.y" +#line 194 "src/vendor/cigraph/src/io/pajek-parser.y" { if (context->vcount2 > 0) { check_bipartite(context); } if (! context->eof) { @@ -1803,11 +1809,11 @@ YYLTYPE yylloc = yyloc_default; } YYACCEPT; /* stop parsing even if there is more data in the file. */ } -#line 1807 "src/vendor/io/pajek-parser.c" +#line 1813 "src/vendor/io/pajek-parser.c" break; case 8: /* verticeshead: "*Vertices line" integer */ -#line 205 "src/vendor/cigraph/src/io/pajek-parser.y" +#line 211 "src/vendor/cigraph/src/io/pajek-parser.y" { context->vcount=(yyvsp[0].intnum); context->vcount2=0; @@ -1818,11 +1824,11 @@ YYLTYPE yylloc = yyloc_default; IGRAPH_YY_ERRORF("Vertex count too large in Pajek file (%" IGRAPH_PRId ").", IGRAPH_EINVAL, context->vcount); } } -#line 1822 "src/vendor/io/pajek-parser.c" +#line 1828 "src/vendor/io/pajek-parser.c" break; case 9: /* verticeshead: "*Vertices line" integer integer */ -#line 215 "src/vendor/cigraph/src/io/pajek-parser.y" +#line 221 "src/vendor/cigraph/src/io/pajek-parser.y" { context->vcount=(yyvsp[-1].intnum); context->vcount2=(yyvsp[0].intnum); @@ -1840,23 +1846,23 @@ YYLTYPE yylloc = yyloc_default; } IGRAPH_YY_CHECK(add_bipartite_type(context)); } -#line 1844 "src/vendor/io/pajek-parser.c" +#line 1850 "src/vendor/io/pajek-parser.c" break; case 13: /* $@1: %empty */ -#line 236 "src/vendor/cigraph/src/io/pajek-parser.y" +#line 242 "src/vendor/cigraph/src/io/pajek-parser.y" { context->actvertex=(yyvsp[0].intnum); } -#line 1850 "src/vendor/io/pajek-parser.c" +#line 1856 "src/vendor/io/pajek-parser.c" break; case 14: /* vertexline: vertex $@1 vertexid vertexcoords shape vertparams "end of line" */ -#line 236 "src/vendor/cigraph/src/io/pajek-parser.y" +#line 242 "src/vendor/cigraph/src/io/pajek-parser.y" { } -#line 1856 "src/vendor/io/pajek-parser.c" +#line 1862 "src/vendor/io/pajek-parser.c" break; case 15: /* vertex: integer */ -#line 239 "src/vendor/cigraph/src/io/pajek-parser.y" +#line 245 "src/vendor/cigraph/src/io/pajek-parser.y" { igraph_integer_t v = (yyvsp[0].intnum); if (v < 1 || v > context->vcount) { @@ -1867,167 +1873,166 @@ YYLTYPE yylloc = yyloc_default; } (yyval.intnum) = v; } -#line 1871 "src/vendor/io/pajek-parser.c" +#line 1877 "src/vendor/io/pajek-parser.c" break; case 16: /* vertexid: word */ -#line 250 "src/vendor/cigraph/src/io/pajek-parser.y" +#line 256 "src/vendor/cigraph/src/io/pajek-parser.y" { - IGRAPH_YY_CHECK(add_string_vertex_attribute("id", (yyvsp[0].string).str, (yyvsp[0].string).len, context)); IGRAPH_YY_CHECK(add_string_vertex_attribute("name", (yyvsp[0].string).str, (yyvsp[0].string).len, context)); } -#line 1880 "src/vendor/io/pajek-parser.c" +#line 1885 "src/vendor/io/pajek-parser.c" break; case 18: /* vertexcoords: number number */ -#line 256 "src/vendor/cigraph/src/io/pajek-parser.y" +#line 261 "src/vendor/cigraph/src/io/pajek-parser.y" { IGRAPH_YY_CHECK(add_numeric_vertex_attribute("x", (yyvsp[-1].realnum), context)); IGRAPH_YY_CHECK(add_numeric_vertex_attribute("y", (yyvsp[0].realnum), context)); } -#line 1889 "src/vendor/io/pajek-parser.c" +#line 1894 "src/vendor/io/pajek-parser.c" break; case 19: /* vertexcoords: number number number */ -#line 260 "src/vendor/cigraph/src/io/pajek-parser.y" +#line 265 "src/vendor/cigraph/src/io/pajek-parser.y" { IGRAPH_YY_CHECK(add_numeric_vertex_attribute("x", (yyvsp[-2].realnum), context)); IGRAPH_YY_CHECK(add_numeric_vertex_attribute("y", (yyvsp[-1].realnum), context)); IGRAPH_YY_CHECK(add_numeric_vertex_attribute("z", (yyvsp[0].realnum), context)); } -#line 1899 "src/vendor/io/pajek-parser.c" +#line 1904 "src/vendor/io/pajek-parser.c" break; case 21: /* shape: word */ -#line 266 "src/vendor/cigraph/src/io/pajek-parser.y" +#line 271 "src/vendor/cigraph/src/io/pajek-parser.y" { IGRAPH_YY_CHECK(add_string_vertex_attribute("shape", (yyvsp[0].string).str, (yyvsp[0].string).len, context)); } -#line 1907 "src/vendor/io/pajek-parser.c" +#line 1912 "src/vendor/io/pajek-parser.c" break; case 25: /* vertparam: VP_X_FACT number */ -#line 274 "src/vendor/cigraph/src/io/pajek-parser.y" +#line 279 "src/vendor/cigraph/src/io/pajek-parser.y" { IGRAPH_YY_CHECK(add_numeric_vertex_attribute("xfact", (yyvsp[0].realnum), context)); } -#line 1915 "src/vendor/io/pajek-parser.c" +#line 1920 "src/vendor/io/pajek-parser.c" break; case 26: /* vertparam: VP_Y_FACT number */ -#line 277 "src/vendor/cigraph/src/io/pajek-parser.y" +#line 282 "src/vendor/cigraph/src/io/pajek-parser.y" { IGRAPH_YY_CHECK(add_numeric_vertex_attribute("yfact", (yyvsp[0].realnum), context)); } -#line 1923 "src/vendor/io/pajek-parser.c" +#line 1928 "src/vendor/io/pajek-parser.c" break; case 27: /* vertparam: VP_LR number */ -#line 280 "src/vendor/cigraph/src/io/pajek-parser.y" +#line 285 "src/vendor/cigraph/src/io/pajek-parser.y" { IGRAPH_YY_CHECK(add_numeric_vertex_attribute("labeldist", (yyvsp[0].realnum), context)); } -#line 1931 "src/vendor/io/pajek-parser.c" +#line 1936 "src/vendor/io/pajek-parser.c" break; case 28: /* vertparam: VP_LPHI number */ -#line 283 "src/vendor/cigraph/src/io/pajek-parser.y" +#line 288 "src/vendor/cigraph/src/io/pajek-parser.y" { IGRAPH_YY_CHECK(add_numeric_vertex_attribute("labeldegree2", (yyvsp[0].realnum), context)); } -#line 1939 "src/vendor/io/pajek-parser.c" +#line 1944 "src/vendor/io/pajek-parser.c" break; case 29: /* vertparam: VP_BW number */ -#line 286 "src/vendor/cigraph/src/io/pajek-parser.y" +#line 291 "src/vendor/cigraph/src/io/pajek-parser.y" { IGRAPH_YY_CHECK(add_numeric_vertex_attribute("framewidth", (yyvsp[0].realnum), context)); } -#line 1947 "src/vendor/io/pajek-parser.c" +#line 1952 "src/vendor/io/pajek-parser.c" break; case 30: /* vertparam: VP_FOS number */ -#line 289 "src/vendor/cigraph/src/io/pajek-parser.y" +#line 294 "src/vendor/cigraph/src/io/pajek-parser.y" { IGRAPH_YY_CHECK(add_numeric_vertex_attribute("fontsize", (yyvsp[0].realnum), context)); } -#line 1955 "src/vendor/io/pajek-parser.c" +#line 1960 "src/vendor/io/pajek-parser.c" break; case 31: /* vertparam: VP_PHI number */ -#line 292 "src/vendor/cigraph/src/io/pajek-parser.y" +#line 297 "src/vendor/cigraph/src/io/pajek-parser.y" { IGRAPH_YY_CHECK(add_numeric_vertex_attribute("rotation", (yyvsp[0].realnum), context)); } -#line 1963 "src/vendor/io/pajek-parser.c" +#line 1968 "src/vendor/io/pajek-parser.c" break; case 32: /* vertparam: VP_R number */ -#line 295 "src/vendor/cigraph/src/io/pajek-parser.y" +#line 300 "src/vendor/cigraph/src/io/pajek-parser.y" { IGRAPH_YY_CHECK(add_numeric_vertex_attribute("radius", (yyvsp[0].realnum), context)); } -#line 1971 "src/vendor/io/pajek-parser.c" +#line 1976 "src/vendor/io/pajek-parser.c" break; case 33: /* vertparam: VP_Q number */ -#line 298 "src/vendor/cigraph/src/io/pajek-parser.y" +#line 303 "src/vendor/cigraph/src/io/pajek-parser.y" { IGRAPH_YY_CHECK(add_numeric_vertex_attribute("diamondratio", (yyvsp[0].realnum), context)); } -#line 1979 "src/vendor/io/pajek-parser.c" +#line 1984 "src/vendor/io/pajek-parser.c" break; case 34: /* vertparam: VP_LA number */ -#line 301 "src/vendor/cigraph/src/io/pajek-parser.y" +#line 306 "src/vendor/cigraph/src/io/pajek-parser.y" { IGRAPH_YY_CHECK(add_numeric_vertex_attribute("labeldegree", (yyvsp[0].realnum), context)); } -#line 1987 "src/vendor/io/pajek-parser.c" +#line 1992 "src/vendor/io/pajek-parser.c" break; case 35: /* vpword: VP_FONT parstrval */ -#line 306 "src/vendor/cigraph/src/io/pajek-parser.y" +#line 311 "src/vendor/cigraph/src/io/pajek-parser.y" { IGRAPH_YY_CHECK(add_string_vertex_attribute("font", (yyvsp[0].string).str, (yyvsp[0].string).len, context)); } -#line 1995 "src/vendor/io/pajek-parser.c" +#line 2000 "src/vendor/io/pajek-parser.c" break; case 36: /* vpword: VP_URL parstrval */ -#line 309 "src/vendor/cigraph/src/io/pajek-parser.y" +#line 314 "src/vendor/cigraph/src/io/pajek-parser.y" { IGRAPH_YY_CHECK(add_string_vertex_attribute("url", (yyvsp[0].string).str, (yyvsp[0].string).len, context)); } -#line 2003 "src/vendor/io/pajek-parser.c" +#line 2008 "src/vendor/io/pajek-parser.c" break; case 37: /* vpword: VP_IC parstrval */ -#line 312 "src/vendor/cigraph/src/io/pajek-parser.y" +#line 317 "src/vendor/cigraph/src/io/pajek-parser.y" { IGRAPH_YY_CHECK(add_string_vertex_attribute("color", (yyvsp[0].string).str, (yyvsp[0].string).len, context)); } -#line 2011 "src/vendor/io/pajek-parser.c" +#line 2016 "src/vendor/io/pajek-parser.c" break; case 38: /* vpword: VP_BC parstrval */ -#line 315 "src/vendor/cigraph/src/io/pajek-parser.y" +#line 320 "src/vendor/cigraph/src/io/pajek-parser.y" { IGRAPH_YY_CHECK(add_string_vertex_attribute("framecolor", (yyvsp[0].string).str, (yyvsp[0].string).len, context)); } -#line 2019 "src/vendor/io/pajek-parser.c" +#line 2024 "src/vendor/io/pajek-parser.c" break; case 39: /* vpword: VP_LC parstrval */ -#line 318 "src/vendor/cigraph/src/io/pajek-parser.y" +#line 323 "src/vendor/cigraph/src/io/pajek-parser.y" { IGRAPH_YY_CHECK(add_string_vertex_attribute("labelcolor", (yyvsp[0].string).str, (yyvsp[0].string).len, context)); } -#line 2027 "src/vendor/io/pajek-parser.c" +#line 2032 "src/vendor/io/pajek-parser.c" break; case 40: /* vpword: parname parstrval */ -#line 321 "src/vendor/cigraph/src/io/pajek-parser.y" +#line 326 "src/vendor/cigraph/src/io/pajek-parser.y" { IGRAPH_FINALLY(igraph_free, (yyvsp[-1].dynstr)); if (is_standard_vattr((yyvsp[-1].dynstr))) { @@ -2041,231 +2046,231 @@ YYLTYPE yylloc = yyloc_default; IGRAPH_FREE((yyvsp[-1].dynstr)); IGRAPH_FINALLY_CLEAN(1); } -#line 2045 "src/vendor/io/pajek-parser.c" +#line 2050 "src/vendor/io/pajek-parser.c" break; case 47: /* arcs: "*Arcs line" "end of line" arcsdefs */ -#line 338 "src/vendor/cigraph/src/io/pajek-parser.y" +#line 343 "src/vendor/cigraph/src/io/pajek-parser.y" { context->directed=true; } -#line 2051 "src/vendor/io/pajek-parser.c" +#line 2056 "src/vendor/io/pajek-parser.c" break; case 48: /* arcs: "*Arcs line" number "end of line" arcsdefs */ -#line 339 "src/vendor/cigraph/src/io/pajek-parser.y" +#line 344 "src/vendor/cigraph/src/io/pajek-parser.y" { context->directed=true; } -#line 2057 "src/vendor/io/pajek-parser.c" +#line 2062 "src/vendor/io/pajek-parser.c" break; case 51: /* $@2: %empty */ -#line 343 "src/vendor/cigraph/src/io/pajek-parser.y" +#line 348 "src/vendor/cigraph/src/io/pajek-parser.y" { context->actedge++; } -#line 2063 "src/vendor/io/pajek-parser.c" +#line 2068 "src/vendor/io/pajek-parser.c" break; case 52: /* arcsline: vertex vertex $@2 weight edgeparams "end of line" */ -#line 343 "src/vendor/cigraph/src/io/pajek-parser.y" +#line 348 "src/vendor/cigraph/src/io/pajek-parser.y" { IGRAPH_YY_CHECK(igraph_vector_int_push_back(context->vector, (yyvsp[-5].intnum)-1)); IGRAPH_YY_CHECK(igraph_vector_int_push_back(context->vector, (yyvsp[-4].intnum)-1)); } -#line 2071 "src/vendor/io/pajek-parser.c" +#line 2076 "src/vendor/io/pajek-parser.c" break; case 53: /* edges: "*Edges line" "end of line" edgesdefs */ -#line 348 "src/vendor/cigraph/src/io/pajek-parser.y" +#line 353 "src/vendor/cigraph/src/io/pajek-parser.y" { context->directed=0; } -#line 2077 "src/vendor/io/pajek-parser.c" +#line 2082 "src/vendor/io/pajek-parser.c" break; case 54: /* edges: "*Edges line" number "end of line" edgesdefs */ -#line 349 "src/vendor/cigraph/src/io/pajek-parser.y" +#line 354 "src/vendor/cigraph/src/io/pajek-parser.y" { context->directed=0; } -#line 2083 "src/vendor/io/pajek-parser.c" +#line 2088 "src/vendor/io/pajek-parser.c" break; case 57: /* $@3: %empty */ -#line 353 "src/vendor/cigraph/src/io/pajek-parser.y" +#line 358 "src/vendor/cigraph/src/io/pajek-parser.y" { context->actedge++; } -#line 2089 "src/vendor/io/pajek-parser.c" +#line 2094 "src/vendor/io/pajek-parser.c" break; case 58: /* edgesline: vertex vertex $@3 weight edgeparams "end of line" */ -#line 353 "src/vendor/cigraph/src/io/pajek-parser.y" +#line 358 "src/vendor/cigraph/src/io/pajek-parser.y" { IGRAPH_YY_CHECK(igraph_vector_int_push_back(context->vector, (yyvsp[-5].intnum)-1)); IGRAPH_YY_CHECK(igraph_vector_int_push_back(context->vector, (yyvsp[-4].intnum)-1)); } -#line 2097 "src/vendor/io/pajek-parser.c" +#line 2102 "src/vendor/io/pajek-parser.c" break; case 60: /* weight: number */ -#line 358 "src/vendor/cigraph/src/io/pajek-parser.y" +#line 363 "src/vendor/cigraph/src/io/pajek-parser.y" { IGRAPH_YY_CHECK(add_numeric_edge_attribute("weight", (yyvsp[0].realnum), context)); } -#line 2105 "src/vendor/io/pajek-parser.c" +#line 2110 "src/vendor/io/pajek-parser.c" break; case 64: /* edgeparam: EP_S number */ -#line 366 "src/vendor/cigraph/src/io/pajek-parser.y" +#line 371 "src/vendor/cigraph/src/io/pajek-parser.y" { IGRAPH_YY_CHECK(add_numeric_edge_attribute("arrowsize", (yyvsp[0].realnum), context)); } -#line 2113 "src/vendor/io/pajek-parser.c" +#line 2118 "src/vendor/io/pajek-parser.c" break; case 65: /* edgeparam: EP_W number */ -#line 369 "src/vendor/cigraph/src/io/pajek-parser.y" +#line 374 "src/vendor/cigraph/src/io/pajek-parser.y" { IGRAPH_YY_CHECK(add_numeric_edge_attribute("edgewidth", (yyvsp[0].realnum), context)); } -#line 2121 "src/vendor/io/pajek-parser.c" +#line 2126 "src/vendor/io/pajek-parser.c" break; case 66: /* edgeparam: EP_H1 number */ -#line 372 "src/vendor/cigraph/src/io/pajek-parser.y" +#line 377 "src/vendor/cigraph/src/io/pajek-parser.y" { IGRAPH_YY_CHECK(add_numeric_edge_attribute("hook1", (yyvsp[0].realnum), context)); } -#line 2129 "src/vendor/io/pajek-parser.c" +#line 2134 "src/vendor/io/pajek-parser.c" break; case 67: /* edgeparam: EP_H2 number */ -#line 375 "src/vendor/cigraph/src/io/pajek-parser.y" +#line 380 "src/vendor/cigraph/src/io/pajek-parser.y" { IGRAPH_YY_CHECK(add_numeric_edge_attribute("hook2", (yyvsp[0].realnum), context)); } -#line 2137 "src/vendor/io/pajek-parser.c" +#line 2142 "src/vendor/io/pajek-parser.c" break; case 68: /* edgeparam: EP_A1 number */ -#line 378 "src/vendor/cigraph/src/io/pajek-parser.y" +#line 383 "src/vendor/cigraph/src/io/pajek-parser.y" { IGRAPH_YY_CHECK(add_numeric_edge_attribute("angle1", (yyvsp[0].realnum), context)); } -#line 2145 "src/vendor/io/pajek-parser.c" +#line 2150 "src/vendor/io/pajek-parser.c" break; case 69: /* edgeparam: EP_A2 number */ -#line 381 "src/vendor/cigraph/src/io/pajek-parser.y" +#line 386 "src/vendor/cigraph/src/io/pajek-parser.y" { IGRAPH_YY_CHECK(add_numeric_edge_attribute("angle2", (yyvsp[0].realnum), context)); } -#line 2153 "src/vendor/io/pajek-parser.c" +#line 2158 "src/vendor/io/pajek-parser.c" break; case 70: /* edgeparam: EP_K1 number */ -#line 384 "src/vendor/cigraph/src/io/pajek-parser.y" +#line 389 "src/vendor/cigraph/src/io/pajek-parser.y" { IGRAPH_YY_CHECK(add_numeric_edge_attribute("velocity1", (yyvsp[0].realnum), context)); } -#line 2161 "src/vendor/io/pajek-parser.c" +#line 2166 "src/vendor/io/pajek-parser.c" break; case 71: /* edgeparam: EP_K2 number */ -#line 387 "src/vendor/cigraph/src/io/pajek-parser.y" +#line 392 "src/vendor/cigraph/src/io/pajek-parser.y" { IGRAPH_YY_CHECK(add_numeric_edge_attribute("velocity2", (yyvsp[0].realnum), context)); } -#line 2169 "src/vendor/io/pajek-parser.c" +#line 2174 "src/vendor/io/pajek-parser.c" break; case 72: /* edgeparam: EP_AP number */ -#line 390 "src/vendor/cigraph/src/io/pajek-parser.y" +#line 395 "src/vendor/cigraph/src/io/pajek-parser.y" { IGRAPH_YY_CHECK(add_numeric_edge_attribute("arrowpos", (yyvsp[0].realnum), context)); } -#line 2177 "src/vendor/io/pajek-parser.c" +#line 2182 "src/vendor/io/pajek-parser.c" break; case 73: /* edgeparam: EP_LP number */ -#line 393 "src/vendor/cigraph/src/io/pajek-parser.y" +#line 398 "src/vendor/cigraph/src/io/pajek-parser.y" { IGRAPH_YY_CHECK(add_numeric_edge_attribute("labelpos", (yyvsp[0].realnum), context)); } -#line 2185 "src/vendor/io/pajek-parser.c" +#line 2190 "src/vendor/io/pajek-parser.c" break; case 74: /* edgeparam: EP_LR number */ -#line 396 "src/vendor/cigraph/src/io/pajek-parser.y" +#line 401 "src/vendor/cigraph/src/io/pajek-parser.y" { IGRAPH_YY_CHECK(add_numeric_edge_attribute("labelangle", (yyvsp[0].realnum), context)); } -#line 2193 "src/vendor/io/pajek-parser.c" +#line 2198 "src/vendor/io/pajek-parser.c" break; case 75: /* edgeparam: EP_LPHI number */ -#line 399 "src/vendor/cigraph/src/io/pajek-parser.y" +#line 404 "src/vendor/cigraph/src/io/pajek-parser.y" { IGRAPH_YY_CHECK(add_numeric_edge_attribute("labelangle2", (yyvsp[0].realnum), context)); } -#line 2201 "src/vendor/io/pajek-parser.c" +#line 2206 "src/vendor/io/pajek-parser.c" break; case 76: /* edgeparam: EP_LA number */ -#line 402 "src/vendor/cigraph/src/io/pajek-parser.y" +#line 407 "src/vendor/cigraph/src/io/pajek-parser.y" { IGRAPH_YY_CHECK(add_numeric_edge_attribute("labeldegree", (yyvsp[0].realnum), context)); } -#line 2209 "src/vendor/io/pajek-parser.c" +#line 2214 "src/vendor/io/pajek-parser.c" break; case 77: /* edgeparam: EP_FOS number */ -#line 405 "src/vendor/cigraph/src/io/pajek-parser.y" +#line 410 "src/vendor/cigraph/src/io/pajek-parser.y" { IGRAPH_YY_CHECK(add_numeric_edge_attribute("fontsize", (yyvsp[0].realnum), context)); } -#line 2217 "src/vendor/io/pajek-parser.c" +#line 2222 "src/vendor/io/pajek-parser.c" break; case 78: /* epword: EP_A parstrval */ -#line 410 "src/vendor/cigraph/src/io/pajek-parser.y" +#line 415 "src/vendor/cigraph/src/io/pajek-parser.y" { IGRAPH_YY_CHECK(add_string_edge_attribute("arrowtype", (yyvsp[0].string).str, (yyvsp[0].string).len, context)); } -#line 2225 "src/vendor/io/pajek-parser.c" +#line 2230 "src/vendor/io/pajek-parser.c" break; case 79: /* epword: EP_P parstrval */ -#line 413 "src/vendor/cigraph/src/io/pajek-parser.y" +#line 418 "src/vendor/cigraph/src/io/pajek-parser.y" { IGRAPH_YY_CHECK(add_string_edge_attribute("linepattern", (yyvsp[0].string).str, (yyvsp[0].string).len, context)); } -#line 2233 "src/vendor/io/pajek-parser.c" +#line 2238 "src/vendor/io/pajek-parser.c" break; case 80: /* epword: EP_L parstrval */ -#line 416 "src/vendor/cigraph/src/io/pajek-parser.y" +#line 421 "src/vendor/cigraph/src/io/pajek-parser.y" { IGRAPH_YY_CHECK(add_string_edge_attribute("label", (yyvsp[0].string).str, (yyvsp[0].string).len, context)); } -#line 2241 "src/vendor/io/pajek-parser.c" +#line 2246 "src/vendor/io/pajek-parser.c" break; case 81: /* epword: EP_LC parstrval */ -#line 419 "src/vendor/cigraph/src/io/pajek-parser.y" +#line 424 "src/vendor/cigraph/src/io/pajek-parser.y" { IGRAPH_YY_CHECK(add_string_edge_attribute("labelcolor", (yyvsp[0].string).str, (yyvsp[0].string).len, context)); } -#line 2249 "src/vendor/io/pajek-parser.c" +#line 2254 "src/vendor/io/pajek-parser.c" break; case 82: /* epword: EP_C parstrval */ -#line 422 "src/vendor/cigraph/src/io/pajek-parser.y" +#line 427 "src/vendor/cigraph/src/io/pajek-parser.y" { IGRAPH_YY_CHECK(add_string_edge_attribute("color", (yyvsp[0].string).str, (yyvsp[0].string).len, context)); } -#line 2257 "src/vendor/io/pajek-parser.c" +#line 2262 "src/vendor/io/pajek-parser.c" break; case 83: /* epword: EP_FONT parstrval */ -#line 425 "src/vendor/cigraph/src/io/pajek-parser.y" +#line 430 "src/vendor/cigraph/src/io/pajek-parser.y" { IGRAPH_YY_CHECK(add_string_edge_attribute("font", (yyvsp[0].string).str, (yyvsp[0].string).len, context)); } -#line 2265 "src/vendor/io/pajek-parser.c" +#line 2270 "src/vendor/io/pajek-parser.c" break; case 84: /* epword: parname parstrval */ -#line 428 "src/vendor/cigraph/src/io/pajek-parser.y" +#line 433 "src/vendor/cigraph/src/io/pajek-parser.y" { IGRAPH_FINALLY(igraph_free, (yyvsp[-1].dynstr)); if (is_standard_eattr((yyvsp[-1].dynstr))) { @@ -2279,68 +2284,68 @@ YYLTYPE yylloc = yyloc_default; IGRAPH_FREE((yyvsp[-1].dynstr)); IGRAPH_FINALLY_CLEAN(1); } -#line 2283 "src/vendor/io/pajek-parser.c" +#line 2288 "src/vendor/io/pajek-parser.c" break; case 85: /* arcslist: "*Arcslist line" "end of line" arcslistlines */ -#line 443 "src/vendor/cigraph/src/io/pajek-parser.y" +#line 448 "src/vendor/cigraph/src/io/pajek-parser.y" { context->directed=true; } -#line 2289 "src/vendor/io/pajek-parser.c" +#line 2294 "src/vendor/io/pajek-parser.c" break; case 91: /* arclistfrom: integer */ -#line 451 "src/vendor/cigraph/src/io/pajek-parser.y" +#line 456 "src/vendor/cigraph/src/io/pajek-parser.y" { context->actfrom=labs((yyvsp[0].intnum))-1; } -#line 2295 "src/vendor/io/pajek-parser.c" +#line 2300 "src/vendor/io/pajek-parser.c" break; case 92: /* arclistto: integer */ -#line 453 "src/vendor/cigraph/src/io/pajek-parser.y" +#line 458 "src/vendor/cigraph/src/io/pajek-parser.y" { IGRAPH_YY_CHECK(igraph_vector_int_push_back(context->vector, context->actfrom)); IGRAPH_YY_CHECK(igraph_vector_int_push_back(context->vector, labs((yyvsp[0].intnum))-1)); } -#line 2304 "src/vendor/io/pajek-parser.c" +#line 2309 "src/vendor/io/pajek-parser.c" break; case 93: /* edgeslist: "*Edgeslist line" "end of line" edgelistlines */ -#line 458 "src/vendor/cigraph/src/io/pajek-parser.y" +#line 463 "src/vendor/cigraph/src/io/pajek-parser.y" { context->directed=0; } -#line 2310 "src/vendor/io/pajek-parser.c" +#line 2315 "src/vendor/io/pajek-parser.c" break; case 99: /* edgelistfrom: integer */ -#line 466 "src/vendor/cigraph/src/io/pajek-parser.y" +#line 471 "src/vendor/cigraph/src/io/pajek-parser.y" { context->actfrom=labs((yyvsp[0].intnum))-1; } -#line 2316 "src/vendor/io/pajek-parser.c" +#line 2321 "src/vendor/io/pajek-parser.c" break; case 100: /* edgelistto: integer */ -#line 468 "src/vendor/cigraph/src/io/pajek-parser.y" +#line 473 "src/vendor/cigraph/src/io/pajek-parser.y" { IGRAPH_YY_CHECK(igraph_vector_int_push_back(context->vector, context->actfrom)); IGRAPH_YY_CHECK(igraph_vector_int_push_back(context->vector, labs((yyvsp[0].intnum))-1)); } -#line 2325 "src/vendor/io/pajek-parser.c" +#line 2330 "src/vendor/io/pajek-parser.c" break; case 102: /* matrixline: "*Matrix line" */ -#line 477 "src/vendor/cigraph/src/io/pajek-parser.y" +#line 482 "src/vendor/cigraph/src/io/pajek-parser.y" { context->actfrom=0; context->actto=0; context->directed=(context->vcount2==0); } -#line 2334 "src/vendor/io/pajek-parser.c" +#line 2339 "src/vendor/io/pajek-parser.c" break; case 105: /* adjmatrixline: adjmatrixnumbers "end of line" */ -#line 484 "src/vendor/cigraph/src/io/pajek-parser.y" +#line 489 "src/vendor/cigraph/src/io/pajek-parser.y" { context->actfrom++; context->actto=0; } -#line 2340 "src/vendor/io/pajek-parser.c" +#line 2345 "src/vendor/io/pajek-parser.c" break; case 108: /* adjmatrixentry: number */ -#line 488 "src/vendor/cigraph/src/io/pajek-parser.y" +#line 493 "src/vendor/cigraph/src/io/pajek-parser.y" { if ((yyvsp[0].realnum) != 0) { if (context->vcount2==0) { @@ -2358,11 +2363,11 @@ YYLTYPE yylloc = yyloc_default; } context->actto++; } -#line 2362 "src/vendor/io/pajek-parser.c" +#line 2367 "src/vendor/io/pajek-parser.c" break; case 109: /* integer: "number" */ -#line 508 "src/vendor/cigraph/src/io/pajek-parser.y" +#line 513 "src/vendor/cigraph/src/io/pajek-parser.y" { igraph_integer_t val; IGRAPH_YY_CHECK(igraph_i_parse_integer(igraph_pajek_yyget_text(scanner), @@ -2370,11 +2375,11 @@ YYLTYPE yylloc = yyloc_default; &val)); (yyval.intnum)=val; } -#line 2374 "src/vendor/io/pajek-parser.c" +#line 2379 "src/vendor/io/pajek-parser.c" break; case 110: /* number: "number" */ -#line 516 "src/vendor/cigraph/src/io/pajek-parser.y" +#line 521 "src/vendor/cigraph/src/io/pajek-parser.y" { igraph_real_t val; IGRAPH_YY_CHECK(igraph_i_parse_real(igraph_pajek_yyget_text(scanner), @@ -2382,46 +2387,46 @@ YYLTYPE yylloc = yyloc_default; &val)); (yyval.realnum)=val; } -#line 2386 "src/vendor/io/pajek-parser.c" +#line 2391 "src/vendor/io/pajek-parser.c" break; case 111: /* parname: word */ -#line 524 "src/vendor/cigraph/src/io/pajek-parser.y" +#line 529 "src/vendor/cigraph/src/io/pajek-parser.y" { IGRAPH_YY_CHECK(make_dynstr((yyvsp[0].string).str, (yyvsp[0].string).len, &(yyval.dynstr))); } -#line 2394 "src/vendor/io/pajek-parser.c" +#line 2399 "src/vendor/io/pajek-parser.c" break; case 112: /* parstrval: word */ -#line 528 "src/vendor/cigraph/src/io/pajek-parser.y" +#line 533 "src/vendor/cigraph/src/io/pajek-parser.y" { (yyval.string)=(yyvsp[0].string); } -#line 2400 "src/vendor/io/pajek-parser.c" +#line 2405 "src/vendor/io/pajek-parser.c" break; case 113: /* word: "word" */ -#line 530 "src/vendor/cigraph/src/io/pajek-parser.y" +#line 535 "src/vendor/cigraph/src/io/pajek-parser.y" { (yyval.string).str=igraph_pajek_yyget_text(scanner); (yyval.string).len=igraph_pajek_yyget_leng(scanner); } -#line 2407 "src/vendor/io/pajek-parser.c" +#line 2412 "src/vendor/io/pajek-parser.c" break; case 114: /* word: "number" */ -#line 532 "src/vendor/cigraph/src/io/pajek-parser.y" +#line 537 "src/vendor/cigraph/src/io/pajek-parser.y" { (yyval.string).str=igraph_pajek_yyget_text(scanner); (yyval.string).len=igraph_pajek_yyget_leng(scanner); } -#line 2414 "src/vendor/io/pajek-parser.c" +#line 2419 "src/vendor/io/pajek-parser.c" break; case 115: /* word: "quoted string" */ -#line 534 "src/vendor/cigraph/src/io/pajek-parser.y" +#line 539 "src/vendor/cigraph/src/io/pajek-parser.y" { (yyval.string).str=igraph_pajek_yyget_text(scanner)+1; (yyval.string).len=igraph_pajek_yyget_leng(scanner)-2; } -#line 2421 "src/vendor/io/pajek-parser.c" +#line 2426 "src/vendor/io/pajek-parser.c" break; -#line 2425 "src/vendor/io/pajek-parser.c" +#line 2430 "src/vendor/io/pajek-parser.c" default: break; } @@ -2650,7 +2655,7 @@ YYLTYPE yylloc = yyloc_default; return yyresult; } -#line 537 "src/vendor/cigraph/src/io/pajek-parser.y" +#line 542 "src/vendor/cigraph/src/io/pajek-parser.y" int igraph_pajek_yyerror(YYLTYPE* locp, @@ -2665,49 +2670,38 @@ int igraph_pajek_yyerror(YYLTYPE* locp, /* TODO: NA's */ static igraph_error_t add_numeric_attribute(igraph_trie_t *names, - igraph_vector_ptr_t *attrs, + igraph_attribute_record_list_t *attrs, igraph_integer_t count, const char *attrname, + igraph_real_t default_value, igraph_integer_t elem_id, igraph_real_t number) { igraph_integer_t attrsize = igraph_trie_size(names); igraph_integer_t id; igraph_vector_t *na; - igraph_attribute_record_t *rec; + igraph_attribute_record_t *prec; IGRAPH_CHECK(igraph_trie_get(names, attrname, &id)); if (id == attrsize) { - /* add a new attribute */ - rec = IGRAPH_CALLOC(1, igraph_attribute_record_t); - CHECK_OOM_RP(rec); - IGRAPH_FINALLY(igraph_free, rec); + igraph_attribute_record_t rec; - na = IGRAPH_CALLOC(1, igraph_vector_t); - CHECK_OOM_RP(na); - IGRAPH_FINALLY(igraph_free, na); - IGRAPH_VECTOR_INIT_FINALLY(na, count); - - rec->name = strdup(attrname); - CHECK_OOM_RP(rec->name); - IGRAPH_FINALLY(igraph_free, (void *) rec->name); + /* add a new attribute */ + IGRAPH_CHECK(igraph_attribute_record_init(&rec, attrname, IGRAPH_ATTRIBUTE_NUMERIC)); + IGRAPH_FINALLY(igraph_attribute_record_destroy, &rec); - rec->type = IGRAPH_ATTRIBUTE_NUMERIC; - rec->value = na; + IGRAPH_CHECK(igraph_attribute_record_set_default_numeric(&rec, default_value)); - IGRAPH_CHECK(igraph_vector_ptr_push_back(attrs, rec)); - IGRAPH_FINALLY_CLEAN(4); /* ownership of rec transferred to attrs */ + IGRAPH_CHECK(igraph_attribute_record_resize(&rec, count)); + IGRAPH_CHECK(igraph_attribute_record_list_push_back(attrs, &rec)); + IGRAPH_FINALLY_CLEAN(1); /* ownership of rec transferred to attrs */ } - rec = VECTOR(*attrs)[id]; - na = (igraph_vector_t *) rec->value; + prec = igraph_attribute_record_list_get_ptr(attrs, id); + na = prec->value.as_vector; if (igraph_vector_size(na) == elem_id) { IGRAPH_CHECK(igraph_vector_push_back(na, number)); } else if (igraph_vector_size(na) < elem_id) { - igraph_integer_t origsize=igraph_vector_size(na); - IGRAPH_CHECK(igraph_vector_resize(na, elem_id+1)); - for (;origsizename = strdup(attrname); - CHECK_OOM_RP(rec->name); - IGRAPH_FINALLY(igraph_free, (char *) rec->name); + IGRAPH_CHECK(igraph_attribute_record_init(&rec, attrname, IGRAPH_ATTRIBUTE_STRING)); + IGRAPH_FINALLY(igraph_attribute_record_destroy, &rec); - rec->type = IGRAPH_ATTRIBUTE_STRING; - rec->value = na; + IGRAPH_CHECK(igraph_attribute_record_set_default_string(&rec, default_value)); - IGRAPH_CHECK(igraph_vector_ptr_push_back(attrs, rec)); - IGRAPH_FINALLY_CLEAN(4); /* ownership of rec transferred to attrs */ + IGRAPH_CHECK(igraph_attribute_record_resize(&rec, count)); + IGRAPH_CHECK(igraph_attribute_record_list_push_back(attrs, &rec)); + IGRAPH_FINALLY_CLEAN(1); /* ownership of rec transferred to attrs */ } - rec = VECTOR(*attrs)[id]; - na = (igraph_strvector_t *) rec->value; + prec = igraph_attribute_record_list_get_ptr(attrs, id); + na = prec->value.as_strvector; if (igraph_strvector_size(na) <= elem_id) { IGRAPH_CHECK(igraph_strvector_resize(na, elem_id+1)); } @@ -2792,7 +2775,9 @@ static igraph_error_t add_string_vertex_attribute(const char *name, return add_string_attribute(context->vertex_attribute_names, context->vertex_attributes, context->vcount, - name, context->actvertex-1, + name, + get_default_value_for_string_vattr(name), + context->actvertex-1, value, len); } @@ -2804,7 +2789,9 @@ static igraph_error_t add_string_edge_attribute(const char *name, return add_string_attribute(context->edge_attribute_names, context->edge_attributes, context->actedge, - name, context->actedge-1, + name, + get_default_value_for_string_eattr(name), + context->actedge-1, value, len); } @@ -2815,7 +2802,9 @@ static igraph_error_t add_numeric_vertex_attribute(const char *name, return add_numeric_attribute(context->vertex_attribute_names, context->vertex_attributes, context->vcount, - name, context->actvertex-1, + name, + get_default_value_for_numeric_vattr(name), + context->actvertex-1, value); } @@ -2826,7 +2815,9 @@ static igraph_error_t add_numeric_edge_attribute(const char *name, return add_numeric_attribute(context->edge_attribute_names, context->edge_attributes, context->actedge, - name, context->actedge-1, + name, + get_default_value_for_numeric_eattr(name), + context->actedge-1, value); } @@ -2834,10 +2825,10 @@ static igraph_error_t add_bipartite_type(igraph_i_pajek_parsedata_t *context) { const char *attrname="type"; igraph_trie_t *names=context->vertex_attribute_names; - igraph_vector_ptr_t *attrs=context->vertex_attributes; + igraph_attribute_record_list_t *attrs=context->vertex_attributes; igraph_integer_t n=context->vcount, n1=context->vcount2; igraph_integer_t attrid, attrsize = igraph_trie_size(names); - igraph_attribute_record_t *rec; + igraph_attribute_record_t* rec; igraph_vector_bool_t *na; if (n1 > n) { @@ -2852,29 +2843,13 @@ static igraph_error_t add_bipartite_type(igraph_i_pajek_parsedata_t *context) { IGRAPH_ASSERT(attrid == attrsize); /* add a new attribute */ - rec = IGRAPH_CALLOC(1, igraph_attribute_record_t); - CHECK_OOM_RP(rec); - IGRAPH_FINALLY(igraph_free, rec); + IGRAPH_CHECK(igraph_attribute_record_list_push_back_new(attrs, &rec)); + IGRAPH_CHECK(igraph_attribute_record_set_name(rec, attrname)); + IGRAPH_CHECK(igraph_attribute_record_set_type(rec, IGRAPH_ATTRIBUTE_BOOLEAN)); + IGRAPH_CHECK(igraph_attribute_record_resize(rec, n)); - na = IGRAPH_CALLOC(1, igraph_vector_bool_t); - CHECK_OOM_RP(na); - IGRAPH_FINALLY(igraph_free, na); - IGRAPH_VECTOR_BOOL_INIT_FINALLY(na, n); - - rec->name = strdup(attrname); - CHECK_OOM_RP(rec->name); - IGRAPH_FINALLY(igraph_free, (char *) rec->name); - - rec->type = IGRAPH_ATTRIBUTE_BOOLEAN; - rec->value = na; - - IGRAPH_CHECK(igraph_vector_ptr_push_back(attrs, rec)); - IGRAPH_FINALLY_CLEAN(4); /* ownership of 'rec' transferred to 'attrs' */ - - for (igraph_integer_t i=0; ivalue.as_vector_bool; + for (igraph_integer_t i = n1; i < n; i++) { VECTOR(*na)[i] = true; } @@ -2914,7 +2889,7 @@ static igraph_bool_t is_standard_vattr(const char *attrname) { "font", "url", "color", "framecolor", "labelcolor" }; - for (size_t i=0; i < sizeof(names) / sizeof(names[0]); i++) { + for (size_t i = 0; i < sizeof(names) / sizeof(names[0]); i++) { if (strcmp(attrname, names[i]) == 0) { return true; } @@ -2956,3 +2931,108 @@ static igraph_error_t deconflict_attrname(char **attrname) { *attrname = tmp; return IGRAPH_SUCCESS; } + +typedef struct { + const char* name; + igraph_real_t default_value; +} attribute_numeric_defaults_t; + +typedef struct { + const char* name; + const char* default_value; +} attribute_string_defaults_t; + +/* The defaults listed below are Pajek's built-in defaults unless the user + * overrides them. + * + * See: https://nascol.discourse.group/t/pajek-file-format-default-values-for-attributes/38/2 + */ + +const attribute_numeric_defaults_t vattr_numeric_defaults[] = { + { "xfact", 1 }, + { "yfact", 1 }, + { "labeldist", 20 }, + { "labeldegree2", 285 }, + { "framewidth", 1 }, + { "fontsize", 15 }, + { "rotation", 0 }, + { "radius", 0 }, + { "diamondratio", 0.01 }, + { "labeldegree", 0 }, + { 0 } +}; + +const attribute_string_defaults_t vattr_string_defaults[] = { + { "color", "LightOrange" }, + { "framecolor", "Brown" }, + { "labelcolor", "Maroon" }, + { 0 } +}; + +const attribute_numeric_defaults_t eattr_numeric_defaults[] = { + { "arrowsize", 1 }, + { "edgewidth", 2 }, + { "hook1", 0 }, + { "hook2", 0 }, + { "angle1", 0 }, + { "angle2", 0 }, + { "velocity1", 1 }, + { "velocity2", 1 }, + { "arrowpos", 0 }, + { "labelpos", 0.5 }, + { "labelangle", 10 }, + { "labelangle2", 90 }, + { "labeldegree", 0 }, + { "fontsize", 15 }, + { 0 } +}; + +const attribute_string_defaults_t eattr_string_defaults[] = { + { "color", "MidnightBlue" }, + { "labelcolor", "Black" }, + { 0 } +}; + +static igraph_real_t get_default_value_for_numeric_attr( + const char *attrname, const attribute_numeric_defaults_t* table +) { + const attribute_numeric_defaults_t* ptr; + + for (ptr = table; ptr->name != 0; ptr++) { + if (!strcmp(attrname, ptr->name)) { + return ptr->default_value; + } + } + + return IGRAPH_NAN; +} + +static const char* get_default_value_for_string_attr( + const char *attrname, const attribute_string_defaults_t* table +) { + const attribute_string_defaults_t* ptr; + + for (ptr = table; ptr->name != 0; ptr++) { + if (!strcmp(attrname, ptr->name)) { + return ptr->default_value; + } + } + + return ""; +} + +static igraph_real_t get_default_value_for_numeric_vattr(const char *attrname) { + return get_default_value_for_numeric_attr(attrname, vattr_numeric_defaults); +} + +static igraph_real_t get_default_value_for_numeric_eattr(const char *attrname) { + return get_default_value_for_numeric_attr(attrname, eattr_numeric_defaults); +} + +static const char* get_default_value_for_string_vattr(const char *attrname) { + return get_default_value_for_string_attr(attrname, vattr_string_defaults); +} + +static const char* get_default_value_for_string_eattr(const char *attrname) { + return get_default_value_for_string_attr(attrname, eattr_string_defaults); +} diff --git a/src/vendor/io/parsers/pajek-parser.h b/src/vendor/io/parsers/pajek-parser.h index 79385e2e367..64ada07751d 100644 --- a/src/vendor/io/parsers/pajek-parser.h +++ b/src/vendor/io/parsers/pajek-parser.h @@ -109,7 +109,7 @@ extern int igraph_pajek_yydebug; #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED union YYSTYPE { -#line 116 "src/vendor/cigraph/src/io/pajek-parser.y" +#line 122 "src/vendor/cigraph/src/io/pajek-parser.y" igraph_integer_t intnum; igraph_real_t realnum; From fce7ecf23f11454072ad4ad134e6d1e580253bf6 Mon Sep 17 00:00:00 2001 From: Antonov548 Date: Wed, 20 Mar 2024 11:04:47 +0100 Subject: [PATCH 02/10] update vendor/cigraph --- src/vendor/cigraph/CHANGELOG.md | 4 ++ src/vendor/cigraph/CITATION.cff | 4 +- src/vendor/cigraph/azure-pipelines.yml | 19 +++---- src/vendor/cigraph/include/igraph_error.h | 21 ++----- src/vendor/cigraph/include/igraph_misc.h | 38 +++++++++++++ .../cigraph/src/centrality/betweenness.c | 12 ++-- .../cigraph/src/community/edge_betweenness.c | 5 +- .../cigraph/src/constructors/adjacency.c | 16 +++--- .../src/constructors/basic_constructors.c | 10 ++-- src/vendor/cigraph/src/core/error.c | 11 ++-- src/vendor/cigraph/src/core/sparsemat.c | 57 +++++++++++-------- src/vendor/cigraph/src/core/vector.pmt | 3 +- src/vendor/cigraph/src/games/sbm.c | 3 +- src/vendor/cigraph/src/graph/caching.c | 1 + src/vendor/cigraph/src/graph/iterators.c | 8 +-- src/vendor/cigraph/src/graph/type_common.c | 2 +- .../cigraph/src/graph/type_indexededgelist.c | 4 +- src/vendor/cigraph/src/internal/hacks.h | 5 -- src/vendor/cigraph/src/io/pajek.c | 3 +- src/vendor/cigraph/src/linalg/eigen.c | 4 +- src/vendor/cigraph/src/linalg/lapack.c | 12 ++-- src/vendor/cigraph/src/misc/bipartite.c | 2 +- src/vendor/igraph_version.h | 4 +- 23 files changed, 136 insertions(+), 112 deletions(-) create mode 100644 src/vendor/cigraph/include/igraph_misc.h diff --git a/src/vendor/cigraph/CHANGELOG.md b/src/vendor/cigraph/CHANGELOG.md index 5fde0dd325c..40c4757ce6d 100644 --- a/src/vendor/cigraph/CHANGELOG.md +++ b/src/vendor/cigraph/CHANGELOG.md @@ -17,6 +17,10 @@ - `igraph_count_automorphisms()` has been renamed to `igraph_count_automorphisms_bliss()` because it has a BLISS-specific interface. A new `igraph_count_automorphisms()` function was added with a simplified interface that does not depend on BLISS. - `igraph_automorphism_group()` has been renamed to `igraph_automorphism_group_bliss()` because it has a BLISS-specific interface. A new `igraph_automorphism_group()` function was added with a simplified interface that does not depend on BLISS. - `igraph_canonical_permutation()` has been renamed to `igraph_canonical_permutation_bliss()` because it has a BLISS-specific interface. A new `igraph_canonical_permutation()` function was added with a simplified interface that does not depend on BLISS. + - The `IGRAPH_EINVEVECTOR` error code was removed; `igraph_create()` and `igraph_add_edges()` that used to return this error code for invalid edge vectors will now return `IGRAPH_EINVAL` instead. + - The `IGRAPH_NONSQUARE` error code was removed; functions that used them now return `IGRAPH_EINVAL` instead when encountering a non-square matrix. + - The unused `IGRAPH_EDIVZERO` and `IGRAPH_EATTRIBUTES` error codes were removed with no replacement. + - A new error code called `IGRAPH_EINVEID` was added for cases when an invalid edge ID was encountered in an edge ID vector. ### Added diff --git a/src/vendor/cigraph/CITATION.cff b/src/vendor/cigraph/CITATION.cff index b616d5dc7c8..842c13a25eb 100644 --- a/src/vendor/cigraph/CITATION.cff +++ b/src/vendor/cigraph/CITATION.cff @@ -27,7 +27,7 @@ authors: family-names: Noom identifiers: - type: doi - value: 10.5281/zenodo.8094849 + value: 10.5281/zenodo.4319996 description: Zenodo repository-code: 'https://github.com/igraph/igraph' url: 'https://igraph.org' @@ -39,8 +39,6 @@ keywords: - network analysis - graph theory license: GPL-2.0-or-later -version: 0.10.5 -date-released: '2023-06-29' preferred-citation: type: article authors: diff --git a/src/vendor/cigraph/azure-pipelines.yml b/src/vendor/cigraph/azure-pipelines.yml index 94d22f556d1..d0741ac7d1e 100644 --- a/src/vendor/cigraph/azure-pipelines.yml +++ b/src/vendor/cigraph/azure-pipelines.yml @@ -12,10 +12,10 @@ variables: jobs: # In this test we install and generate locales so that igraph_enter/exit_safelocale() can be tested - job: linux_static_vendored + pool: + vmImage: 'ubuntu-20.04' # TODO: fix for ubuntu-22.04 steps: - - script: | - sudo apt-get update - sudo apt-get install ninja-build ccache language-pack-de -y + - script: sudo apt-get install ninja-build ccache language-pack-de -y displayName: Install dependencies - script: | @@ -29,6 +29,8 @@ jobs: extra_cmake_args: '-DUSE_SANITIZER=Address\;Undefined -DCMAKE_C_FLAGS="-Og -fno-sanitize-recover=undefined -fno-sanitize=float-divide-by-zero" -DCMAKE_CXX_FLAGS="-Og -fno-sanitize-recover=undefined -fno-sanitize=float-divide-by-zero"' - job: linux_static_vendored_32 + pool: + vmImage: 'ubuntu-20.04' # TODO: fix for ubuntu-22.04 steps: - script: sudo apt-get install ninja-build ccache -y displayName: Install dependencies @@ -76,21 +78,19 @@ jobs: extra_cmake_args: '-DBLA_VENDOR=OpenBLAS' build_shared: true - - job: linux_clang_18 - pool: - vmImage: 'ubuntu-22.04' + - job: linux_clang_19 steps: - script: | sudo apt-get install ninja-build ccache -y wget https://apt.llvm.org/llvm.sh chmod +x llvm.sh - sudo ./llvm.sh 18 + sudo ./llvm.sh 19 displayName: Install dependencies - template: .azure/build.yml parameters: build_type: Debug - extra_cmake_args: '-DUSE_SANITIZER=Address\;Undefined -DCMAKE_C_FLAGS="-Og -fno-sanitize-recover=undefined -fno-sanitize=float-divide-by-zero" -DCMAKE_CXX_FLAGS="-Og -fno-sanitize-recover=undefined -fno-sanitize=float-divide-by-zero" -DCMAKE_C_COMPILER=clang-18 -DCMAKE_CXX_COMPILER=clang++-18' + extra_cmake_args: '-DUSE_SANITIZER=Address\;Undefined -DCMAKE_C_FLAGS="-Og -fno-sanitize-recover=undefined -fno-sanitize=float-divide-by-zero" -DCMAKE_CXX_FLAGS="-Og -fno-sanitize-recover=undefined -fno-sanitize=float-divide-by-zero" -DCMAKE_C_COMPILER=clang-19 -DCMAKE_CXX_COMPILER=clang++-19' - job: linux_x87 steps: @@ -147,9 +147,6 @@ jobs: - job: documentation steps: - - script: sudo apt-get update - displayName: Update package registry - - script: sudo apt-get install ninja-build xmlto texinfo source-highlight libxml2-utils xsltproc fop docbook2x -y displayName: Install dependencies diff --git a/src/vendor/cigraph/include/igraph_error.h b/src/vendor/cigraph/include/igraph_error.h index c367d603510..07a5020a413 100644 --- a/src/vendor/cigraph/include/igraph_error.h +++ b/src/vendor/cigraph/include/igraph_error.h @@ -252,11 +252,8 @@ __BEGIN_DECLS * number was specified as the number of vertices. * \enumval IGRAPH_EXISTS A graph/vertex/edge attribute is already * installed with the given name. - * \enumval IGRAPH_EINVEVECTOR Invalid vector of vertex IDs. A vertex ID - * is either negative or bigger than the number of vertices minus one. * \enumval IGRAPH_EINVVID Invalid vertex ID, negative or too big. - * \enumval IGRAPH_NONSQUARE A non-square matrix was received while a - * square matrix was expected. + * \enumval IGRAPH_EINVEID Invalid edge ID, negative or too big. * \enumval IGRAPH_EINVMODE Invalid mode parameter. * \enumval IGRAPH_EFILE A file operation failed. E.g. a file doesn't exist, * or the user has no rights to open it. @@ -287,7 +284,6 @@ __BEGIN_DECLS * \enumval IGRAPH_ARPACK_UNKNOWN Unknown ARPACK error. * \enumval IGRAPH_ENEGLOOP Negative loop detected while calculating shortest paths. * \enumval IGRAPH_EINTERNAL Internal error, likely a bug in igraph. - * \enumval IGRAPH_EDIVZERO Big integer division by zero. * \enumval IGRAPH_GLP_EBOUND GLPK error (GLP_EBOUND). * \enumval IGRAPH_GLP_EROOT GLPK error (GLP_EROOT). * \enumval IGRAPH_GLP_ENOPFS GLPK error (GLP_ENOPFS). @@ -296,14 +292,9 @@ __BEGIN_DECLS * \enumval IGRAPH_GLP_EMIPGAP GLPK error (GLP_EMIPGAP). * \enumval IGRAPH_GLP_ETMLIM GLPK error (GLP_ETMLIM). * \enumval IGRAPH_GLP_ESTOP GLPK error (GLP_ESTOP). - * \enumval IGRAPH_EATTRIBUTES Attribute handler error. The user is not - * expected to find this; it is signalled if some igraph function is - * not using the attribute handler interface properly. * \enumval IGRAPH_EATTRCOMBINE Unimplemented attribute combination * method for the given attribute type. * \enumval IGRAPH_ELAPACK A LAPACK call resulted in an error. - * \enumval IGRAPH_EDRL Internal error in the DrL layout generator; not used - * any more (replaced by IGRAPH_EINTERNAL). * \enumval IGRAPH_EOVERFLOW Integer or double overflow. * \enumval IGRAPH_EGLP Internal GLPK error. * \enumval IGRAPH_CPUTIME CPU time exceeded. @@ -320,9 +311,9 @@ typedef enum { IGRAPH_PARSEERROR = 3, IGRAPH_EINVAL = 4, IGRAPH_EXISTS = 5, - IGRAPH_EINVEVECTOR = 6, + /* IGRAPH_EINVEVECTOR = 6, */ /* removed in 1.0 */ IGRAPH_EINVVID = 7, - IGRAPH_NONSQUARE = 8, + IGRAPH_EINVEID = 8, /* used to be IGRAPH_NONSQUARE before 1.0 */ IGRAPH_EINVMODE = 9, IGRAPH_EFILE = 10, IGRAPH_UNIMPLEMENTED = 12, @@ -355,7 +346,7 @@ typedef enum { IGRAPH_ARPACK_MAXIT = 39, IGRAPH_ARPACK_NOSHIFT = 40, IGRAPH_ARPACK_REORDER = 41, - IGRAPH_EDIVZERO = 42, + /* IGRAPH_EDIVZERO = 42, */ /* removed in 1.0 */ IGRAPH_GLP_EBOUND = 43, IGRAPH_GLP_EROOT = 44, IGRAPH_GLP_ENOPFS = 45, @@ -364,10 +355,10 @@ typedef enum { IGRAPH_GLP_EMIPGAP = 48, IGRAPH_GLP_ETMLIM = 49, IGRAPH_GLP_ESTOP = 50, - IGRAPH_EATTRIBUTES = 51, + /* IGRAPH_EATTRIBUTES = 51, */ /* rempved in 1.0 */ IGRAPH_EATTRCOMBINE = 52, IGRAPH_ELAPACK = 53, - IGRAPH_EDRL IGRAPH_DEPRECATED_ENUMVAL = 54, + /* IGRAPH_EDRL = 54, */ /* deprecated in 0.10.2, removed in 1.0 */ IGRAPH_EOVERFLOW = 55, IGRAPH_EGLP = 56, IGRAPH_CPUTIME = 57, diff --git a/src/vendor/cigraph/include/igraph_misc.h b/src/vendor/cigraph/include/igraph_misc.h new file mode 100644 index 00000000000..e26f0786ad8 --- /dev/null +++ b/src/vendor/cigraph/include/igraph_misc.h @@ -0,0 +1,38 @@ +/* + IGraph library. + Copyright (C) 2003-2024 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, see . +*/ + +/* Semi-public header; not included from igraph.h. This is intentional. + * The macros defined in this header are usually not useful to the end user, + * with some exceptions like the source of the R interface. You need to + * include this header explicitly if needed. */ + +#ifndef IGRAPM_MISC_H +#define IGRAPM_MISC_H + +#include "igraph_decls.h" + +__BEGIN_DECLS + +/* Magic macro to fail the build if certain condition does not hold. See: + * https://stackoverflow.com/questions/4079243/how-can-i-use-sizeof-in-a-preprocessor-macro + */ +#define IGRAPH_STATIC_ASSERT(condition) ((void)sizeof(char[1 - 2*!(condition)])) + +__END_DECLS + +#endif diff --git a/src/vendor/cigraph/src/centrality/betweenness.c b/src/vendor/cigraph/src/centrality/betweenness.c index 9adff201e2b..bed0d23a8e7 100644 --- a/src/vendor/cigraph/src/centrality/betweenness.c +++ b/src/vendor/cigraph/src/centrality/betweenness.c @@ -472,10 +472,8 @@ static igraph_error_t igraph_i_betweenness_check_weights( * calculating weighted betweenness. No edge weight may be NaN. * Supply a null pointer here for unweighted betweenness. * \return Error code: - * \c IGRAPH_ENOMEM, not enough memory for - * temporary data. - * \c IGRAPH_EINVVID, invalid vertex ID passed in - * \p vids. + * \c IGRAPH_ENOMEM, not enough memory for temporary data. + * \c IGRAPH_EINVVID, invalid vertex ID passed in \p vids. * * Time complexity: O(|V||E|), * |V| and @@ -518,10 +516,8 @@ igraph_error_t igraph_betweenness(const igraph_t *graph, igraph_vector_t *res, * If negative, the exact betweenness will be calculated, and * there will be no upper limit on path lengths. * \return Error code: - * \c IGRAPH_ENOMEM, not enough memory for - * temporary data. - * \c IGRAPH_EINVVID, invalid vertex ID passed in - * \p vids. + * \c IGRAPH_ENOMEM, not enough memory for temporary data. + * \c IGRAPH_EINVVID, invalid vertex ID passed in \p vids. * * Time complexity: O(|V||E|), * |V| and diff --git a/src/vendor/cigraph/src/community/edge_betweenness.c b/src/vendor/cigraph/src/community/edge_betweenness.c index 16b64f186fa..af0a3d3adaa 100644 --- a/src/vendor/cigraph/src/community/edge_betweenness.c +++ b/src/vendor/cigraph/src/community/edge_betweenness.c @@ -234,7 +234,10 @@ igraph_error_t igraph_community_eb_get_merges(const igraph_t *graph, igraph_integer_t max_merges; if (! igraph_vector_int_isininterval(edges, 0, no_of_edges-1)) { - IGRAPH_ERROR("Invalid edge ID.", IGRAPH_EINVAL); + IGRAPH_ERROR( + "Cannot calculate merges of edge betweenness community detection.", + IGRAPH_EINVEID + ); } if (no_removed_edges < no_of_edges) { IGRAPH_ERRORF("Number of removed edges (%" IGRAPH_PRId ") should be equal to " diff --git a/src/vendor/cigraph/src/constructors/adjacency.c b/src/vendor/cigraph/src/constructors/adjacency.c index 459403da24d..28e4a04c7f3 100644 --- a/src/vendor/cigraph/src/constructors/adjacency.c +++ b/src/vendor/cigraph/src/constructors/adjacency.c @@ -303,9 +303,9 @@ static igraph_error_t igraph_i_adjacency_min( * will return an error code. * \endclist * \return Error code, - * \c IGRAPH_NONSQUARE: non-square matrix. - * \c IGRAPH_EINVAL: Negative entry was found in adjacency matrix, or an - * odd number was found in the diagonal with \c IGRAPH_LOOPS_TWICE + * \c IGRAPH_EINVAL: Non-square adjacency matrix, negative entry in + * adjacency matrix, or an odd number was found in the diagonal with + * \c IGRAPH_LOOPS_TWICE * * Time complexity: O(|V||V|), * |V| is the number of vertices in the graph. @@ -322,7 +322,7 @@ igraph_error_t igraph_adjacency( /* Some checks */ if (igraph_matrix_nrow(adjmatrix) != igraph_matrix_ncol(adjmatrix)) { - IGRAPH_ERROR("Adjacency matrix is non-square.", IGRAPH_NONSQUARE); + IGRAPH_ERROR("Adjacency matrix is non-square.", IGRAPH_EINVAL); } if (no_of_nodes != 0 && igraph_matrix_min(adjmatrix) < 0) { @@ -720,7 +720,7 @@ static igraph_error_t igraph_i_weighted_adjacency_min( * incident on the corresponding vertex. * \endclist * \return Error code, - * \c IGRAPH_NONSQUARE: non-square matrix. + * \c IGRAPH_EINVAL: non-square matrix. * * Time complexity: O(|V||V|), * |V| is the number of vertices in the graph. @@ -737,7 +737,7 @@ igraph_error_t igraph_weighted_adjacency( /* Some checks */ if (igraph_matrix_nrow(adjmatrix) != igraph_matrix_ncol(adjmatrix)) { - IGRAPH_ERROR("Non-square matrix", IGRAPH_NONSQUARE); + IGRAPH_ERROR("Non-square matrix", IGRAPH_EINVAL); } IGRAPH_VECTOR_INT_INIT_FINALLY(&edges, 0); @@ -1070,7 +1070,7 @@ igraph_error_t igraph_sparse_adjacency(igraph_t *graph, igraph_sparsemat_t *adjm "form.", IGRAPH_EINVAL); } if (no_of_nodes != igraph_sparsemat_ncol(adjmatrix)) { - IGRAPH_ERROR("Adjacency matrix is non-square.", IGRAPH_NONSQUARE); + IGRAPH_ERROR("Adjacency matrix is non-square.", IGRAPH_EINVAL); } if (no_of_nodes != 0 && igraph_sparsemat_min(adjmatrix) < 0) { @@ -1366,7 +1366,7 @@ igraph_error_t igraph_sparse_weighted_adjacency( IGRAPH_ERROR("Sparse adjacency matrix should be in column-compressed form.", IGRAPH_EINVAL); } if (no_of_nodes != igraph_sparsemat_ncol(adjmatrix)) { - IGRAPH_ERROR("Adjacency matrix is non-square.", IGRAPH_NONSQUARE); + IGRAPH_ERROR("Adjacency matrix is non-square.", IGRAPH_EINVAL); } IGRAPH_VECTOR_INT_INIT_FINALLY(&edges, no_of_edges * 2); diff --git a/src/vendor/cigraph/src/constructors/basic_constructors.c b/src/vendor/cigraph/src/constructors/basic_constructors.c index 892c3cda350..1badfd933a2 100644 --- a/src/vendor/cigraph/src/constructors/basic_constructors.c +++ b/src/vendor/cigraph/src/constructors/basic_constructors.c @@ -51,10 +51,8 @@ * not. If yes, then the first edge points from the first * vertex ID in \p edges to the second, etc. * \return Error code: - * \c IGRAPH_EINVEVECTOR: invalid edges - * vector (odd number of vertices). - * \c IGRAPH_EINVVID: invalid (negative) - * vertex ID. + * \c IGRAPH_EINVAL: invalid edges vector (odd number of vertices). + * \c IGRAPH_EINVVID: invalid (negative) vertex ID. * * Time complexity: O(|V|+|E|), * |V| is the number of vertices, @@ -69,9 +67,9 @@ igraph_error_t igraph_create(igraph_t *graph, const igraph_vector_int_t *edges, igraph_integer_t max; if (igraph_vector_int_size(edges) % 2 != 0) { - IGRAPH_ERROR("Invalid (odd) edges vector.", IGRAPH_EINVEVECTOR); + IGRAPH_ERROR("Invalid (odd) edges vector.", IGRAPH_EINVAL); } - if (has_edges && !igraph_vector_int_isininterval(edges, 0, IGRAPH_VCOUNT_MAX-1)) { + if (!igraph_vector_int_isininterval(edges, 0, IGRAPH_VCOUNT_MAX-1)) { IGRAPH_ERROR("Invalid (negative or too large) vertex ID.", IGRAPH_EINVVID); } diff --git a/src/vendor/cigraph/src/core/error.c b/src/vendor/cigraph/src/core/error.c index 6e928cc00f2..10bd621ed37 100644 --- a/src/vendor/cigraph/src/core/error.c +++ b/src/vendor/cigraph/src/core/error.c @@ -91,9 +91,9 @@ static const char *igraph_i_error_strings[] = { /* 3 */ "Parse error", /* 4 */ "Invalid value", /* 5 */ "Already exists", - /* 6 */ "Invalid edge vector", + /* 6 */ "Invalid edge vector", /* removed in 1.0 */ /* 7 */ "Invalid vertex ID", - /* 8 */ "Non-square matrix", + /* 8 */ "Invalid edge ID", /* 9 */ "Invalid mode", /* 10 */ "File operation error", /* 11 */ "Unfold infinite iterator", @@ -131,7 +131,7 @@ static const char *igraph_i_error_strings[] = { "is to increase the size of NCV relative to NEV", /* 41 */ "The Schur form computed by LAPACK routine dlahqr " "could not be reordered by LAPACK routine dtrsen.", - /* 42 */ "Big integer division by zero", + /* 42 */ "Big integer division by zero", /* removed in 1.0 */ /* 43 */ "GLPK Error, GLP_EBOUND", /* 44 */ "GLPK Error, GLP_EROOT", /* 45 */ "GLPK Error, GLP_ENOPFS", @@ -140,11 +140,10 @@ static const char *igraph_i_error_strings[] = { /* 48 */ "GLPK Error, GLP_EMIPGAP", /* 49 */ "GLPK Error, GLP_ETMLIM", /* 50 */ "GLPK Error, GLP_STOP", - /* 51 */ "Internal attribute handler error", + /* 51 */ "Internal attribute handler error", /* removed in 1.0 */ /* 52 */ "Unimplemented attribute combination for this type", /* 53 */ "LAPACK call resulted in an error", - /* 54 */ "Internal DrL error; this error should never be visible to the user, " - "please report this error along with the steps to reproduce it.", + /* 54 */ "Internal DrL error", /* removed in 1.0 */ /* 55 */ "Integer or double overflow", /* 56 */ "Internal GPLK error", /* 57 */ "CPU time exceeded", diff --git a/src/vendor/cigraph/src/core/sparsemat.c b/src/vendor/cigraph/src/core/sparsemat.c index a072a5c342d..9d03046efc5 100644 --- a/src/vendor/cigraph/src/core/sparsemat.c +++ b/src/vendor/cigraph/src/core/sparsemat.c @@ -27,10 +27,9 @@ #include "igraph_constructors.h" #include "igraph_interface.h" #include "igraph_memory.h" +#include "igraph_misc.h" /* IGRAPH_STATIC_ASSERT */ #include "igraph_types.h" -#include "internal/hacks.h" /* IGRAPH_STATIC_ASSERT */ - #include #include @@ -1009,7 +1008,7 @@ igraph_error_t igraph_sparsemat_lsolve(const igraph_sparsemat_t *L, igraph_vector_t *res) { if (L->cs->m != L->cs->n) { - IGRAPH_ERROR("Cannot perform lower triangular solve", IGRAPH_NONSQUARE); + IGRAPH_ERROR("Cannot perform lower triangular solve on non-square matrix.", IGRAPH_EINVAL); } if (res != b) { @@ -1017,7 +1016,7 @@ igraph_error_t igraph_sparsemat_lsolve(const igraph_sparsemat_t *L, } if (! cs_lsolve(L->cs, VECTOR(*res))) { - IGRAPH_ERROR("Cannot perform lower triangular solve", IGRAPH_FAILURE); + IGRAPH_ERROR("Cannot perform lower triangular solve.", IGRAPH_FAILURE); } return IGRAPH_SUCCESS; @@ -1043,8 +1042,10 @@ igraph_error_t igraph_sparsemat_ltsolve(const igraph_sparsemat_t *L, igraph_vector_t *res) { if (L->cs->m != L->cs->n) { - IGRAPH_ERROR("Cannot perform transposed lower triangular solve", - IGRAPH_NONSQUARE); + IGRAPH_ERROR( + "Cannot perform transposed lower triangular solve on non-square matrix.", + IGRAPH_EINVAL + ); } if (res != b) { @@ -1052,7 +1053,7 @@ igraph_error_t igraph_sparsemat_ltsolve(const igraph_sparsemat_t *L, } if (!cs_ltsolve(L->cs, VECTOR(*res))) { - IGRAPH_ERROR("Cannot perform lower triangular solve", IGRAPH_FAILURE); + IGRAPH_ERROR("Cannot perform lower triangular solve.", IGRAPH_FAILURE); } return IGRAPH_SUCCESS; @@ -1077,7 +1078,10 @@ igraph_error_t igraph_sparsemat_usolve(const igraph_sparsemat_t *U, igraph_vector_t *res) { if (U->cs->m != U->cs->n) { - IGRAPH_ERROR("Cannot perform upper triangular solve", IGRAPH_NONSQUARE); + IGRAPH_ERROR( + "Cannot perform upper triangular solve on non-square matrix.", + IGRAPH_EINVAL + ); } if (res != b) { @@ -1085,7 +1089,7 @@ igraph_error_t igraph_sparsemat_usolve(const igraph_sparsemat_t *U, } if (! cs_usolve(U->cs, VECTOR(*res))) { - IGRAPH_ERROR("Cannot perform upper triangular solve", IGRAPH_FAILURE); + IGRAPH_ERROR("Cannot perform upper triangular solve.", IGRAPH_FAILURE); } return IGRAPH_SUCCESS; @@ -1111,8 +1115,10 @@ igraph_error_t igraph_sparsemat_utsolve(const igraph_sparsemat_t *U, igraph_vector_t *res) { if (U->cs->m != U->cs->n) { - IGRAPH_ERROR("Cannot perform transposed upper triangular solve", - IGRAPH_NONSQUARE); + IGRAPH_ERROR( + "Cannot perform transposed upper triangular solve on non-square matrix.", + IGRAPH_EINVAL + ); } if (res != b) { @@ -1120,7 +1126,7 @@ igraph_error_t igraph_sparsemat_utsolve(const igraph_sparsemat_t *U, } if (!cs_utsolve(U->cs, VECTOR(*res))) { - IGRAPH_ERROR("Cannot perform transposed upper triangular solve", + IGRAPH_ERROR("Cannot perform transposed upper triangular solve.", IGRAPH_FAILURE); } @@ -1150,8 +1156,10 @@ igraph_error_t igraph_sparsemat_cholsol(const igraph_sparsemat_t *A, igraph_integer_t order) { if (A->cs->m != A->cs->n) { - IGRAPH_ERROR("Cannot perform sparse symmetric solve", - IGRAPH_NONSQUARE); + IGRAPH_ERROR( + "Cannot perform sparse symmetric solve on non-square matrix.", + IGRAPH_EINVAL + ); } if (res != b) { @@ -1159,7 +1167,7 @@ igraph_error_t igraph_sparsemat_cholsol(const igraph_sparsemat_t *A, } if (! cs_cholsol(order, A->cs, VECTOR(*res))) { - IGRAPH_ERROR("Cannot perform sparse symmetric solve", IGRAPH_FAILURE); + IGRAPH_ERROR("Cannot perform sparse symmetric solve.", IGRAPH_FAILURE); } return IGRAPH_SUCCESS; @@ -1192,8 +1200,7 @@ igraph_error_t igraph_sparsemat_lusol(const igraph_sparsemat_t *A, igraph_real_t tol) { if (A->cs->m != A->cs->n) { - IGRAPH_ERROR("Cannot perform LU solve", - IGRAPH_NONSQUARE); + IGRAPH_ERROR("Cannot perform LU solve on non-square matrix.", IGRAPH_EINVAL); } if (res != b) { @@ -1201,7 +1208,7 @@ igraph_error_t igraph_sparsemat_lusol(const igraph_sparsemat_t *A, } if (! cs_lusol(order, A->cs, VECTOR(*res), tol)) { - IGRAPH_ERROR("Cannot perform LU solve", IGRAPH_FAILURE); + IGRAPH_ERROR("Cannot perform LU solve.", IGRAPH_FAILURE); } return IGRAPH_SUCCESS; @@ -1220,7 +1227,7 @@ static igraph_error_t igraph_i_sparsemat_cc(igraph_t *graph, const igraph_sparse igraph_integer_t e = 0; if (no_of_nodes != A->cs->n) { - IGRAPH_ERROR("Cannot create graph object", IGRAPH_NONSQUARE); + IGRAPH_ERROR("Cannot create graph object from non-square matrix.", IGRAPH_EINVAL); } IGRAPH_VECTOR_INT_INIT_FINALLY(&edges, no_of_edges * 2); @@ -1257,7 +1264,7 @@ static igraph_error_t igraph_i_sparsemat_triplet(igraph_t *graph, const igraph_s igraph_integer_t e; if (no_of_nodes != A->cs->n) { - IGRAPH_ERROR("Cannot create graph object", IGRAPH_NONSQUARE); + IGRAPH_ERROR("Cannot create graph object from non-square matrix.", IGRAPH_EINVAL); } IGRAPH_VECTOR_INT_INIT_FINALLY(&edges, no_of_edges * 2); @@ -1374,7 +1381,7 @@ igraph_error_t igraph_weighted_sparsemat(igraph_t *graph, const igraph_sparsemat CS_INT no_of_nodes = A->cs->m; if (no_of_nodes != A->cs->n) { - IGRAPH_ERROR("Cannot create graph object", IGRAPH_NONSQUARE); + IGRAPH_ERROR("Cannot create graph object from non-square matrix.", IGRAPH_EINVAL); } IGRAPH_VECTOR_INT_INIT_FINALLY(&edges, pot_edges * 2); @@ -1707,11 +1714,11 @@ igraph_error_t igraph_sparsemat_arpack_rssolve(const igraph_sparsemat_t *A, igraph_integer_t n = igraph_sparsemat_nrow(A); if (n != igraph_sparsemat_ncol(A)) { - IGRAPH_ERROR("Non-square matrix for ARPACK", IGRAPH_NONSQUARE); + IGRAPH_ERROR("Non-square matrix for ARPACK.", IGRAPH_EINVAL); } if (n > INT_MAX) { - IGRAPH_ERROR("Matrix too large for ARPACK", IGRAPH_EOVERFLOW); + IGRAPH_ERROR("Matrix too large for ARPACK.", IGRAPH_EOVERFLOW); } if (options == 0) { @@ -1811,11 +1818,11 @@ igraph_error_t igraph_sparsemat_arpack_rnsolve(const igraph_sparsemat_t *A, igraph_integer_t n = igraph_sparsemat_nrow(A); if (n > INT_MAX) { - IGRAPH_ERROR("Matrix too large for ARPACK", IGRAPH_EOVERFLOW); + IGRAPH_ERROR("Matrix too large for ARPACK.", IGRAPH_EOVERFLOW); } if (n != igraph_sparsemat_ncol(A)) { - IGRAPH_ERROR("Non-square matrix for ARPACK", IGRAPH_NONSQUARE); + IGRAPH_ERROR("Non-square matrix for ARPACK.", IGRAPH_EINVAL); } if (options == 0) { diff --git a/src/vendor/cigraph/src/core/vector.pmt b/src/vendor/cigraph/src/core/vector.pmt index adb19b7918c..6f841831766 100644 --- a/src/vendor/cigraph/src/core/vector.pmt +++ b/src/vendor/cigraph/src/core/vector.pmt @@ -1879,8 +1879,7 @@ igraph_error_t FUNCTION(igraph_vector, move_interval2)(TYPE(igraph_vector) *v, * are in the interval, false (zero) otherwise. If any element is NaN, it will * return \c 0 (=false). * - * Time complexity: O(n), the number - * of elements in the vector. + * Time complexity: O(n), the number of elements in the vector. */ igraph_bool_t FUNCTION(igraph_vector, isininterval)(const TYPE(igraph_vector) *v, diff --git a/src/vendor/cigraph/src/games/sbm.c b/src/vendor/cigraph/src/games/sbm.c index 12cf6639536..7c92a637cef 100644 --- a/src/vendor/cigraph/src/games/sbm.c +++ b/src/vendor/cigraph/src/games/sbm.c @@ -86,8 +86,7 @@ igraph_error_t igraph_sbm_game(igraph_t *graph, igraph_integer_t n, /* ------------------------------------------------------------ */ if (igraph_matrix_ncol(pref_matrix) != no_blocks) { - IGRAPH_ERROR("Preference matrix is not square.", - IGRAPH_NONSQUARE); + IGRAPH_ERROR("Preference matrix is not square.", IGRAPH_EINVAL); } if (no_blocks > 0) { diff --git a/src/vendor/cigraph/src/graph/caching.c b/src/vendor/cigraph/src/graph/caching.c index 2f9781c44eb..b2741710cb5 100644 --- a/src/vendor/cigraph/src/graph/caching.c +++ b/src/vendor/cigraph/src/graph/caching.c @@ -17,6 +17,7 @@ */ #include "igraph_interface.h" +#include "igraph_misc.h" /* IGRAPH_STATIC_ASSERT */ #include "graph/caching.h" diff --git a/src/vendor/cigraph/src/graph/iterators.c b/src/vendor/cigraph/src/graph/iterators.c index c82ea990d74..038dff2e132 100644 --- a/src/vendor/cigraph/src/graph/iterators.c +++ b/src/vendor/cigraph/src/graph/iterators.c @@ -1982,7 +1982,7 @@ igraph_error_t igraph_eit_create(const igraph_t *graph, igraph_es_t es, igraph_e eit->start = es.data.eid; eit->end = es.data.eid + 1; if (eit->pos >= igraph_ecount(graph)) { - IGRAPH_ERROR("Cannot create iterator, invalid edge ID.", IGRAPH_EINVAL); + IGRAPH_ERROR("Cannot create iterator.", IGRAPH_EINVEID); } break; case IGRAPH_ES_VECTOR: @@ -1993,7 +1993,7 @@ igraph_error_t igraph_eit_create(const igraph_t *graph, igraph_es_t es, igraph_e eit->vec = es.data.vecptr; eit->end = igraph_vector_int_size(eit->vec); if (!igraph_vector_int_isininterval(eit->vec, 0, igraph_ecount(graph) - 1)) { - IGRAPH_ERROR("Cannot create iterator, invalid edge ID.", IGRAPH_EINVAL); + IGRAPH_ERROR("Cannot create iterator.", IGRAPH_EINVEID); } break; case IGRAPH_ES_RANGE: @@ -2002,10 +2002,10 @@ igraph_error_t igraph_eit_create(const igraph_t *graph, igraph_es_t es, igraph_e if (es.data.range.start < 0 || es.data.range.start > no_of_edges || (no_of_edges > 0 && es.data.range.start == no_of_edges)) { - IGRAPH_ERROR("Cannot create range iterator, starting edge ID out of range.", IGRAPH_EINVAL); + IGRAPH_ERROR("Cannot create range iterator, starting edge ID out of range.", IGRAPH_EINVEID); } if (es.data.range.end < 0 || es.data.range.end > no_of_edges) { - IGRAPH_ERROR("Cannot create range iterator, ending edge ID out of range.", IGRAPH_EINVAL); + IGRAPH_ERROR("Cannot create range iterator, ending edge ID out of range.", IGRAPH_EINVEID); } } eit->type = IGRAPH_EIT_RANGE; diff --git a/src/vendor/cigraph/src/graph/type_common.c b/src/vendor/cigraph/src/graph/type_common.c index 3761310c1c6..8293d50278b 100644 --- a/src/vendor/cigraph/src/graph/type_common.c +++ b/src/vendor/cigraph/src/graph/type_common.c @@ -133,7 +133,7 @@ igraph_error_t igraph_edge( ) { if (eid < 0 || eid >= igraph_ecount(graph)) { - IGRAPH_ERROR("Invalid edge ID when retrieving edge endpoints.", IGRAPH_EINVAL); + IGRAPH_ERROR("Cannot retrieve edge endpoints.", IGRAPH_EINVEID); } if (igraph_is_directed(graph)) { diff --git a/src/vendor/cigraph/src/graph/type_indexededgelist.c b/src/vendor/cigraph/src/graph/type_indexededgelist.c index 82cb6048b5f..fbe2a8af22f 100644 --- a/src/vendor/cigraph/src/graph/type_indexededgelist.c +++ b/src/vendor/cigraph/src/graph/type_indexededgelist.c @@ -239,7 +239,7 @@ igraph_error_t igraph_copy(igraph_t *to, const igraph_t *from) { * \param attr The attributes of the new edges. You can supply a null pointer * here if you do not need edge attributes. * \return Error code: - * \c IGRAPH_EINVEVECTOR: invalid (odd) edges vector length, + * \c IGRAPH_EINVAL: invalid (odd) edges vector length, * \c IGRAPH_EINVVID: invalid vertex ID in edges vector. * * This function invalidates all iterators. @@ -262,7 +262,7 @@ igraph_error_t igraph_add_edges( igraph_bool_t directed = igraph_is_directed(graph); if (igraph_vector_int_size(edges) % 2 != 0) { - IGRAPH_ERROR("Invalid (odd) length of edges vector.", IGRAPH_EINVEVECTOR); + IGRAPH_ERROR("Invalid (odd) length of edges vector.", IGRAPH_EINVAL); } if (!igraph_vector_int_isininterval(edges, 0, igraph_vcount(graph) - 1)) { IGRAPH_ERROR("Out-of-range vertex IDs when adding edges.", IGRAPH_EINVVID); diff --git a/src/vendor/cigraph/src/internal/hacks.h b/src/vendor/cigraph/src/internal/hacks.h index b38bfce873c..fc8cf071435 100644 --- a/src/vendor/cigraph/src/internal/hacks.h +++ b/src/vendor/cigraph/src/internal/hacks.h @@ -63,11 +63,6 @@ __BEGIN_DECLS #endif #endif -/* Magic macro to fail the build if certain condition does not hold. See: - * https://stackoverflow.com/questions/4079243/how-can-i-use-sizeof-in-a-preprocessor-macro - */ -#define IGRAPH_STATIC_ASSERT(condition) ((void)sizeof(char[1 - 2*!(condition)])) - __END_DECLS #endif diff --git a/src/vendor/cigraph/src/io/pajek.c b/src/vendor/cigraph/src/io/pajek.c index 840bef136ba..ea2f524858c 100644 --- a/src/vendor/cigraph/src/io/pajek.c +++ b/src/vendor/cigraph/src/io/pajek.c @@ -26,11 +26,10 @@ #include "igraph_error.h" #include "igraph_interface.h" #include "igraph_memory.h" +#include "igraph_misc.h" /* IGRAPH_STATIC_ASSERT */ #include "graph/attributes.h" -#include "internal/hacks.h" /* IGRAPH_STATIC_ASSERT */ - #include "io/pajek-header.h" #include "io/parsers/pajek-parser.h" diff --git a/src/vendor/cigraph/src/linalg/eigen.c b/src/vendor/cigraph/src/linalg/eigen.c index 52ee6c711bd..c59bace9beb 100644 --- a/src/vendor/cigraph/src/linalg/eigen.c +++ b/src/vendor/cigraph/src/linalg/eigen.c @@ -1143,11 +1143,11 @@ static igraph_error_t igraph_i_eigen_checks(const igraph_matrix_t *A, if (A) { if (n != igraph_matrix_ncol(A) || n != igraph_matrix_nrow(A)) { - IGRAPH_ERROR("Invalid matrix", IGRAPH_NONSQUARE); + IGRAPH_ERROR("Eigenvector calculations need a square matrix.", IGRAPH_EINVAL); } } else if (sA) { if (n != igraph_sparsemat_ncol(sA) || n != igraph_sparsemat_nrow(sA)) { - IGRAPH_ERROR("Invalid matrix", IGRAPH_NONSQUARE); + IGRAPH_ERROR("Eigenvector calculations need a square matrix.", IGRAPH_EINVAL); } } diff --git a/src/vendor/cigraph/src/linalg/lapack.c b/src/vendor/cigraph/src/linalg/lapack.c index c50fe55cd56..6fdf4b3b74b 100644 --- a/src/vendor/cigraph/src/linalg/lapack.c +++ b/src/vendor/cigraph/src/linalg/lapack.c @@ -208,7 +208,7 @@ igraph_error_t igraph_lapack_dgetrs(igraph_bool_t transpose, const igraph_matrix ldb = n > 0 ? n : 1; if (n != igraph_matrix_ncol(a)) { - IGRAPH_ERROR("Cannot LU solve matrix.", IGRAPH_NONSQUARE); + IGRAPH_ERROR("Cannot LU solve non-square matrix.", IGRAPH_EINVAL); } if (n != igraph_matrix_nrow(b)) { IGRAPH_ERROR("Cannot LU solve matrix, RHS of wrong size.", IGRAPH_EINVAL); @@ -320,7 +320,7 @@ igraph_error_t igraph_lapack_dgesv(igraph_matrix_t *a, igraph_vector_int_t *ipiv igraph_vector_fortran_int_t vipiv; if (n != igraph_matrix_ncol(a)) { - IGRAPH_ERROR("Cannot LU solve matrix.", IGRAPH_NONSQUARE); + IGRAPH_ERROR("Cannot LU solve non-square matrix.", IGRAPH_EINVAL); } if (n != igraph_matrix_nrow(b)) { IGRAPH_ERROR("Cannot LU solve matrix, RHS of wrong size.", IGRAPH_EINVAL); @@ -459,7 +459,7 @@ igraph_error_t igraph_lapack_dsyevr(const igraph_matrix_t *A, int lwork = -1, liwork = -1; if (n != igraph_matrix_ncol(A)) { - IGRAPH_ERROR("Cannot find eigenvalues/vectors.", IGRAPH_NONSQUARE); + IGRAPH_ERROR("Cannot find eigenvalues/vectors of non-square matrix.", IGRAPH_EINVAL); } if (which == IGRAPH_LAPACK_DSYEV_INTERVAL && (vestimate < 1 || vestimate > n)) { @@ -641,7 +641,7 @@ igraph_error_t igraph_lapack_dgeev(const igraph_matrix_t *A, int error = *info; if (igraph_matrix_ncol(A) != n) { - IGRAPH_ERROR("Cannot calculate eigenvalues (dgeev).", IGRAPH_NONSQUARE); + IGRAPH_ERROR("Cannot calculate eigenvalues of non-square matrix.", IGRAPH_EINVAL); } IGRAPH_CHECK(igraph_matrix_init_copy(&Acopy, A)); @@ -868,7 +868,7 @@ igraph_error_t igraph_lapack_dgeevx(igraph_lapack_dgeevx_balance_t balance, ihi = &ihi_dummy; } if (igraph_matrix_ncol(A) != n) { - IGRAPH_ERROR("Cannot calculate eigenvalues (dgeevx).", IGRAPH_NONSQUARE); + IGRAPH_ERROR("Cannot calculate eigenvalues of non-square matrix.", IGRAPH_EINVAL); } switch (balance) { @@ -1003,7 +1003,7 @@ igraph_error_t igraph_lapack_dgehrd(const igraph_matrix_t *A, int i; if (igraph_matrix_ncol(A) != n) { - IGRAPH_ERROR("Hessenberg reduction failed.", IGRAPH_NONSQUARE); + IGRAPH_ERROR("Hessenberg reduction failed on non-square matrix.", IGRAPH_EINVAL); } if (ilo < 1 || ihi > n || ilo > ihi) { diff --git a/src/vendor/cigraph/src/misc/bipartite.c b/src/vendor/cigraph/src/misc/bipartite.c index 8098b422316..3c36b4cf4c5 100644 --- a/src/vendor/cigraph/src/misc/bipartite.c +++ b/src/vendor/cigraph/src/misc/bipartite.c @@ -557,7 +557,7 @@ igraph_error_t igraph_create_bipartite(igraph_t *graph, const igraph_vector_bool igraph_integer_t i; if (no_of_edges % 2 != 0) { - IGRAPH_ERROR("Invalid (odd) edges vector", IGRAPH_EINVEVECTOR); + IGRAPH_ERROR("Invalid (odd) edges vector", IGRAPH_EINVAL); } no_of_edges /= 2; diff --git a/src/vendor/igraph_version.h b/src/vendor/igraph_version.h index 843560befd1..0731e344a94 100644 --- a/src/vendor/igraph_version.h +++ b/src/vendor/igraph_version.h @@ -28,11 +28,11 @@ __BEGIN_DECLS -#define IGRAPH_VERSION "0.10.10-275-g0f383457a" +#define IGRAPH_VERSION "0.10.10-287-gb13aa4e0b" #define IGRAPH_VERSION_MAJOR 0 #define IGRAPH_VERSION_MINOR 10 #define IGRAPH_VERSION_PATCH 10 -#define IGRAPH_VERSION_PRERELEASE "275-g0f383457a" +#define IGRAPH_VERSION_PRERELEASE "287-gb13aa4e0b" IGRAPH_EXPORT void igraph_version(const char **version_string, int *major, From 90bb9e9492cd5d2997ce53633f16325359da02fd Mon Sep 17 00:00:00 2001 From: Antonov548 Date: Wed, 20 Mar 2024 12:22:04 +0100 Subject: [PATCH 03/10] compiling --- R/aaa-auto.R | 897 +++++++++++++++++- src/cpp11.cpp | 2 - src/rinterface.c | 992 ++++++++++++++++---- src/rinterface.h | 2 +- src/rinterface_extra.c | 38 +- src/vendor/cigraph/src/isomorphism/bliss.cc | 3 +- tools/stimulus/functions-R.yaml | 11 +- tools/stimulus/types-RC.yaml | 20 +- tools/stimulus/types-RR.yaml | 18 +- 9 files changed, 1730 insertions(+), 253 deletions(-) diff --git a/R/aaa-auto.R b/R/aaa-auto.R index 3693b46dad8..6ebcd536c8f 100644 --- a/R/aaa-auto.R +++ b/R/aaa-auto.R @@ -617,6 +617,14 @@ get_shortest_path_bellman_ford_impl <- function(graph, from, to, weights=NULL, m if (length(to) == 0) { stop("No vertex was specified") } + if (is.null(weights) && "weight" %in% edge_attr_names(graph)) { + weights <- E(graph)$weight + } + if (!is.null(weights) && any(!is.na(weights))) { + weights <- as.numeric(weights) + } else { + weights <- NULL + } mode <- switch(igraph.match.arg(mode), "out"=1L, "in"=2L, "all"=3L, "total"=3L) on.exit( .Call(R_igraph_finalizer) ) @@ -642,6 +650,14 @@ get_shortest_path_dijkstra_impl <- function(graph, from, to, weights=NULL, mode= if (length(to) == 0) { stop("No vertex was specified") } + if (is.null(weights) && "weight" %in% edge_attr_names(graph)) { + weights <- E(graph)$weight + } + if (!is.null(weights) && any(!is.na(weights))) { + weights <- as.numeric(weights) + } else { + weights <- NULL + } mode <- switch(igraph.match.arg(mode), "out"=1L, "in"=2L, "all"=3L, "total"=3L) on.exit( .Call(R_igraph_finalizer) ) @@ -661,6 +677,14 @@ distances_dijkstra_impl <- function(graph, from=V(graph), to=V(graph), weights, ensure_igraph(graph) from <- as_igraph_vs(graph, from) to <- as_igraph_vs(graph, to) + if (is.null(weights) && "weight" %in% edge_attr_names(graph)) { + weights <- E(graph)$weight + } + if (!is.null(weights) && any(!is.na(weights))) { + weights <- as.numeric(weights) + } else { + weights <- NULL + } mode <- switch(igraph.match.arg(mode), "out"=1L, "in"=2L, "all"=3L, "total"=3L) on.exit( .Call(R_igraph_finalizer) ) @@ -675,6 +699,14 @@ distances_dijkstra_cutoff_impl <- function(graph, from=V(graph), to=V(graph), we ensure_igraph(graph) from <- as_igraph_vs(graph, from) to <- as_igraph_vs(graph, to) + if (is.null(weights) && "weight" %in% edge_attr_names(graph)) { + weights <- E(graph)$weight + } + if (!is.null(weights) && any(!is.na(weights))) { + weights <- as.numeric(weights) + } else { + weights <- NULL + } mode <- switch(igraph.match.arg(mode), "out"=1L, "in"=2L, "all"=3L, "total"=3L) cutoff <- as.numeric(cutoff) @@ -690,6 +722,14 @@ distances_bellman_ford_impl <- function(graph, from=V(graph), to=V(graph), weigh ensure_igraph(graph) from <- as_igraph_vs(graph, from) to <- as_igraph_vs(graph, to) + if (is.null(weights) && "weight" %in% edge_attr_names(graph)) { + weights <- E(graph)$weight + } + if (!is.null(weights) && any(!is.na(weights))) { + weights <- as.numeric(weights) + } else { + weights <- NULL + } mode <- switch(igraph.match.arg(mode), "out"=1L, "in"=2L, "all"=3L, "total"=3L) on.exit( .Call(R_igraph_finalizer) ) @@ -704,6 +744,14 @@ distances_johnson_impl <- function(graph, from=V(graph), to=V(graph), weights=NU ensure_igraph(graph) from <- as_igraph_vs(graph, from) to <- as_igraph_vs(graph, to) + if (is.null(weights) && "weight" %in% edge_attr_names(graph)) { + weights <- E(graph)$weight + } + if (!is.null(weights) && any(!is.na(weights))) { + weights <- as.numeric(weights) + } else { + weights <- NULL + } mode <- switch(igraph.match.arg(mode), "out"=1L, "in"=2L, "all"=3L, "total"=3L) on.exit( .Call(R_igraph_finalizer) ) @@ -718,6 +766,14 @@ distances_floyd_warshall_impl <- function(graph, from=V(graph), to=V(graph), wei ensure_igraph(graph) from <- as_igraph_vs(graph, from) to <- as_igraph_vs(graph, to) + if (is.null(weights) && "weight" %in% edge_attr_names(graph)) { + weights <- E(graph)$weight + } + if (!is.null(weights) && any(!is.na(weights))) { + weights <- as.numeric(weights) + } else { + weights <- NULL + } mode <- switch(igraph.match.arg(mode), "out"=1L, "in"=2L, "all"=3L, "total"=3L) on.exit( .Call(R_igraph_finalizer) ) @@ -732,6 +788,14 @@ voronoi_impl <- function(graph, generators, ..., weights=NULL, mode=c("out", "in check_dots_empty() ensure_igraph(graph) generators <- as_igraph_vs(graph, generators) + if (is.null(weights) && "weight" %in% edge_attr_names(graph)) { + weights <- E(graph)$weight + } + if (!is.null(weights) && any(!is.na(weights))) { + weights <- as.numeric(weights) + } else { + weights <- NULL + } mode <- switch(igraph.match.arg(mode), "out"=1L, "in"=2L, "all"=3L, "total"=3L) tiebreaker <- switch(igraph.match.arg(tiebreaker), "first"=0L, "last"=1L, "random"=2L) @@ -746,6 +810,14 @@ get_k_shortest_paths_impl <- function(graph, from, to, ..., k, weights=NULL, mod # Argument checks check_dots_empty() ensure_igraph(graph) + if (is.null(weights) && "weight" %in% edge_attr_names(graph)) { + weights <- E(graph)$weight + } + if (!is.null(weights) && any(!is.na(weights))) { + weights <- as.numeric(weights) + } else { + weights <- NULL + } k <- as.numeric(k) from <- as_igraph_vs(graph, from) if (length(from) == 0) { @@ -760,7 +832,12 @@ get_k_shortest_paths_impl <- function(graph, from, to, ..., k, weights=NULL, mod on.exit( .Call(R_igraph_finalizer) ) # Function call res <- .Call(R_igraph_get_k_shortest_paths, graph, weights, k, from-1, to-1, mode) - + if (igraph_opt("return.vs.es")) { + res$vpaths <- lapply(res$vpaths, unsafe_create_vs, graph = graph, verts = V(graph)) + } + if (igraph_opt("return.vs.es")) { + res$epaths <- lapply(res$epaths, unsafe_create_es, graph = graph, es = E(graph)) + } res } @@ -775,6 +852,14 @@ get_widest_path_impl <- function(graph, from, to, weights=NULL, mode=c("out", "i if (length(to) == 0) { stop("No vertex was specified") } + if (is.null(weights) && "weight" %in% edge_attr_names(graph)) { + weights <- E(graph)$weight + } + if (!is.null(weights) && any(!is.na(weights))) { + weights <- as.numeric(weights) + } else { + weights <- NULL + } mode <- switch(igraph.match.arg(mode), "out"=1L, "in"=2L, "all"=3L, "total"=3L) on.exit( .Call(R_igraph_finalizer) ) @@ -797,12 +882,25 @@ get_widest_paths_impl <- function(graph, from, to=V(graph), weights=NULL, mode=c stop("No vertex was specified") } to <- as_igraph_vs(graph, to) + if (is.null(weights) && "weight" %in% edge_attr_names(graph)) { + weights <- E(graph)$weight + } + if (!is.null(weights) && any(!is.na(weights))) { + weights <- as.numeric(weights) + } else { + weights <- NULL + } mode <- switch(igraph.match.arg(mode), "out"=1L, "in"=2L, "all"=3L, "total"=3L) on.exit( .Call(R_igraph_finalizer) ) # Function call res <- .Call(R_igraph_get_widest_paths, graph, from-1, to-1, weights, mode) - + if (igraph_opt("return.vs.es")) { + res$vertices <- lapply(res$vertices, unsafe_create_vs, graph = graph, verts = V(graph)) + } + if (igraph_opt("return.vs.es")) { + res$edges <- lapply(res$edges, unsafe_create_es, graph = graph, es = E(graph)) + } res } @@ -811,6 +909,14 @@ widest_path_widths_dijkstra_impl <- function(graph, from=V(graph), to=V(graph), ensure_igraph(graph) from <- as_igraph_vs(graph, from) to <- as_igraph_vs(graph, to) + if (is.null(weights) && "weight" %in% edge_attr_names(graph)) { + weights <- E(graph)$weight + } + if (!is.null(weights) && any(!is.na(weights))) { + weights <- as.numeric(weights) + } else { + weights <- NULL + } mode <- switch(igraph.match.arg(mode), "out"=1L, "in"=2L, "all"=3L, "total"=3L) on.exit( .Call(R_igraph_finalizer) ) @@ -825,6 +931,14 @@ widest_path_widths_floyd_warshall_impl <- function(graph, from=V(graph), to=V(gr ensure_igraph(graph) from <- as_igraph_vs(graph, from) to <- as_igraph_vs(graph, to) + if (is.null(weights) && "weight" %in% edge_attr_names(graph)) { + weights <- E(graph)$weight + } + if (!is.null(weights) && any(!is.na(weights))) { + weights <- as.numeric(weights) + } else { + weights <- NULL + } mode <- switch(igraph.match.arg(mode), "out"=1L, "in"=2L, "all"=3L, "total"=3L) on.exit( .Call(R_igraph_finalizer) ) @@ -838,6 +952,14 @@ spanner_impl <- function(graph, stretch, weights=NULL) { # Argument checks ensure_igraph(graph) stretch <- as.numeric(stretch) + if (is.null(weights) && "weight" %in% edge_attr_names(graph)) { + weights <- E(graph)$weight + } + if (!is.null(weights) && any(!is.na(weights))) { + weights <- as.numeric(weights) + } else { + weights <- NULL + } on.exit( .Call(R_igraph_finalizer) ) # Function call @@ -855,11 +977,21 @@ betweenness_subset_impl <- function(graph, vids=V(graph), directed=TRUE, sources directed <- as.logical(directed) sources <- as_igraph_vs(graph, sources) targets <- as_igraph_vs(graph, targets) + if (is.null(weights) && "weight" %in% edge_attr_names(graph)) { + weights <- E(graph)$weight + } + if (!is.null(weights) && any(!is.na(weights))) { + weights <- as.numeric(weights) + } else { + weights <- NULL + } on.exit( .Call(R_igraph_finalizer) ) # Function call res <- .Call(R_igraph_betweenness_subset, graph, vids-1, directed, sources-1, targets-1, weights) - + if (igraph_opt("add.vertex.names") && is_named(graph)) { + names(res) <- vertex_attr(graph, "name", vids) + } res } @@ -870,11 +1002,21 @@ edge_betweenness_subset_impl <- function(graph, eids=E(graph), directed=TRUE, so directed <- as.logical(directed) sources <- as_igraph_vs(graph, sources) targets <- as_igraph_vs(graph, targets) + if (is.null(weights) && "weight" %in% edge_attr_names(graph)) { + weights <- E(graph)$weight + } + if (!is.null(weights) && any(!is.na(weights))) { + weights <- as.numeric(weights) + } else { + weights <- NULL + } on.exit( .Call(R_igraph_finalizer) ) # Function call res <- .Call(R_igraph_edge_betweenness_subset, graph, eids-1, directed, sources-1, targets-1, weights) - + if (igraph_opt("add.vertex.names") && is_named(graph)) { + names(res) <- vertex_attr(graph, "name", V(graph)) + } res } @@ -883,13 +1025,23 @@ harmonic_centrality_cutoff_impl <- function(graph, vids=V(graph), mode=c("out", ensure_igraph(graph) vids <- as_igraph_vs(graph, vids) mode <- switch(igraph.match.arg(mode), "out"=1L, "in"=2L, "all"=3L, "total"=3L) + if (is.null(weights) && "weight" %in% edge_attr_names(graph)) { + weights <- E(graph)$weight + } + if (!is.null(weights) && any(!is.na(weights))) { + weights <- as.numeric(weights) + } else { + weights <- NULL + } normalized <- as.logical(normalized) cutoff <- as.numeric(cutoff) on.exit( .Call(R_igraph_finalizer) ) # Function call res <- .Call(R_igraph_harmonic_centrality_cutoff, graph, vids-1, mode, weights, normalized, cutoff) - + if (igraph_opt("add.vertex.names") && is_named(graph)) { + names(res) <- vertex_attr(graph, "name", vids) + } res } @@ -901,6 +1053,14 @@ personalized_pagerank_impl <- function(graph, algo=c("prpack", "arpack"), vids=V directed <- as.logical(directed) damping <- as.numeric(damping) if (!is.null(personalized)) personalized <- as.numeric(personalized) + if (is.null(weights) && "weight" %in% edge_attr_names(graph)) { + weights <- E(graph)$weight + } + if (!is.null(weights) && any(!is.na(weights))) { + weights <- as.numeric(weights) + } else { + weights <- NULL + } if (is.null(options)) { if (algo == 0L) { options <- list(niter=1000, eps=0.001) @@ -914,7 +1074,9 @@ personalized_pagerank_impl <- function(graph, algo=c("prpack", "arpack"), vids=V on.exit( .Call(R_igraph_finalizer) ) # Function call res <- .Call(R_igraph_personalized_pagerank, graph, algo, vids-1, directed, damping, personalized, weights, options) - + if (igraph_opt("add.vertex.names") && is_named(graph)) { + names(res$vector) <- vertex_attr(graph, "name", vids) + } res } @@ -926,6 +1088,14 @@ personalized_pagerank_vs_impl <- function(graph, algo=c("prpack", "arpack"), vid directed <- as.logical(directed) damping <- as.numeric(damping) reset.vids <- as_igraph_vs(graph, reset.vids) + if (is.null(weights) && "weight" %in% edge_attr_names(graph)) { + weights <- E(graph)$weight + } + if (!is.null(weights) && any(!is.na(weights))) { + weights <- as.numeric(weights) + } else { + weights <- NULL + } if (is.null(options)) { if (algo == 0L) { options <- list(niter=1000, eps=0.001) @@ -939,6 +1109,9 @@ personalized_pagerank_vs_impl <- function(graph, algo=c("prpack", "arpack"), vid on.exit( .Call(R_igraph_finalizer) ) # Function call res <- .Call(R_igraph_personalized_pagerank_vs, graph, algo, vids-1, directed, damping, reset.vids-1, weights, options) + if (igraph_opt("add.vertex.names") && is_named(graph)) { + names(res$vector) <- vertex_attr(graph, "name", vids) + } if (!details) { res <- res$vector } @@ -973,6 +1146,14 @@ reverse_edges_impl <- function(graph, eids=E(graph)) { average_path_length_dijkstra_impl <- function(graph, weights=NULL, directed=TRUE, unconnected=TRUE, details=FALSE) { # Argument checks ensure_igraph(graph) + if (is.null(weights) && "weight" %in% edge_attr_names(graph)) { + weights <- E(graph)$weight + } + if (!is.null(weights) && any(!is.na(weights))) { + weights <- as.numeric(weights) + } else { + weights <- NULL + } directed <- as.logical(directed) unconnected <- as.logical(unconnected) @@ -1042,6 +1223,14 @@ reciprocity_impl <- function(graph, ignore.loops=TRUE, mode=c("default", "ratio" feedback_arc_set_impl <- function(graph, weights=NULL, algo=c("approx_eades", "exact_ip")) { # Argument checks ensure_igraph(graph) + if (is.null(weights) && "weight" %in% edge_attr_names(graph)) { + weights <- E(graph)$weight + } + if (!is.null(weights) && any(!is.na(weights))) { + weights <- as.numeric(weights) + } else { + weights <- NULL + } algo <- switch(igraph.match.arg(algo), "exact_ip"=0L, "approx_eades"=1L) on.exit( .Call(R_igraph_finalizer) ) @@ -1155,52 +1344,99 @@ is_perfect_impl <- function(graph) { res } -eigenvector_centrality_impl <- function(graph, directed=FALSE, scale=TRUE, weights=NULL, options=ARPACK_DEFAULTS) { +eigenvector_centrality_impl <- function(graph, directed=FALSE, scale=TRUE, weights=NULL, options=arpack_defaults()) { # Argument checks ensure_igraph(graph) directed <- as.logical(directed) scale <- as.logical(scale) + if (is.null(weights) && "weight" %in% edge_attr_names(graph)) { + weights <- E(graph)$weight + } + if (!is.null(weights) && any(!is.na(weights))) { + weights <- as.numeric(weights) + } else { + weights <- NULL + } + options <- modify_list(arpack_defaults(), options) on.exit( .Call(R_igraph_finalizer) ) # Function call res <- .Call(R_igraph_eigenvector_centrality, graph, directed, scale, weights, options) - + if (igraph_opt("add.vertex.names") && is_named(graph)) { + names(res$vector) <- vertex_attr(graph, "name", V(graph)) + } res } -hub_score_impl <- function(graph, scale=TRUE, weights=NULL, options=ARPACK_DEFAULTS) { +hub_score_impl <- function(graph, scale=TRUE, weights=NULL, options=arpack_defaults()) { # Argument checks ensure_igraph(graph) scale <- as.logical(scale) + if (is.null(weights) && "weight" %in% edge_attr_names(graph)) { + weights <- E(graph)$weight + } + if (!is.null(weights) && any(!is.na(weights))) { + weights <- as.numeric(weights) + } else { + weights <- NULL + } + options <- modify_list(arpack_defaults(), options) on.exit( .Call(R_igraph_finalizer) ) # Function call res <- .Call(R_igraph_hub_score, graph, scale, weights, options) - + if (igraph_opt("add.vertex.names") && is_named(graph)) { + names(res$vector) <- vertex_attr(graph, "name", V(graph)) + } res } -authority_score_impl <- function(graph, scale=TRUE, weights=NULL, options=ARPACK_DEFAULTS) { +authority_score_impl <- function(graph, scale=TRUE, weights=NULL, options=arpack_defaults()) { # Argument checks ensure_igraph(graph) scale <- as.logical(scale) + if (is.null(weights) && "weight" %in% edge_attr_names(graph)) { + weights <- E(graph)$weight + } + if (!is.null(weights) && any(!is.na(weights))) { + weights <- as.numeric(weights) + } else { + weights <- NULL + } + options <- modify_list(arpack_defaults(), options) on.exit( .Call(R_igraph_finalizer) ) # Function call res <- .Call(R_igraph_authority_score, graph, scale, weights, options) - + if (igraph_opt("add.vertex.names") && is_named(graph)) { + names(res$vector) <- vertex_attr(graph, "name", V(graph)) + } res } -hub_and_authority_scores_impl <- function(graph, scale=TRUE, weights=NULL, options=ARPACK_DEFAULTS) { +hub_and_authority_scores_impl <- function(graph, scale=TRUE, weights=NULL, options=arpack_defaults()) { # Argument checks ensure_igraph(graph) scale <- as.logical(scale) + if (is.null(weights) && "weight" %in% edge_attr_names(graph)) { + weights <- E(graph)$weight + } + if (!is.null(weights) && any(!is.na(weights))) { + weights <- as.numeric(weights) + } else { + weights <- NULL + } + options <- modify_list(arpack_defaults(), options) on.exit( .Call(R_igraph_finalizer) ) # Function call res <- .Call(R_igraph_hub_and_authority_scores, graph, scale, weights, options) - + if (igraph_opt("add.vertex.names") && is_named(graph)) { + names(res$hub.vector) <- vertex_attr(graph, "name", V(graph)) + } + if (igraph_opt("add.vertex.names") && is_named(graph)) { + names(res$authority.vector) <- vertex_attr(graph, "name", V(graph)) + } res } @@ -1248,17 +1484,35 @@ avg_nearest_neighbor_degree_impl <- function(graph, vids=V(graph), mode=c("all", vids <- as_igraph_vs(graph, vids) mode <- switch(igraph.match.arg(mode), "out"=1L, "in"=2L, "all"=3L, "total"=3L) neighbor.degree.mode <- switch(igraph.match.arg(neighbor.degree.mode), "out"=1L, "in"=2L, "all"=3L, "total"=3L) + if (is.null(weights) && "weight" %in% edge_attr_names(graph)) { + weights <- E(graph)$weight + } + if (!is.null(weights) && any(!is.na(weights))) { + weights <- as.numeric(weights) + } else { + weights <- NULL + } on.exit( .Call(R_igraph_finalizer) ) # Function call res <- .Call(R_igraph_avg_nearest_neighbor_degree, graph, vids-1, mode, neighbor.degree.mode, weights) - + if (igraph_opt("add.vertex.names") && is_named(graph)) { + names(res$knn) <- vertex_attr(graph, "name", vids) + } res } degree_correlation_vector_impl <- function(graph, weights=NULL, from.mode=c("out", "in", "all", "total"), to.mode=c("in", "out", "all", "total"), directed.neighbors=TRUE) { # Argument checks ensure_igraph(graph) + if (is.null(weights) && "weight" %in% edge_attr_names(graph)) { + weights <- E(graph)$weight + } + if (!is.null(weights) && any(!is.na(weights))) { + weights <- as.numeric(weights) + } else { + weights <- NULL + } from.mode <- switch(igraph.match.arg(from.mode), "out"=1L, "in"=2L, "all"=3L, "total"=3L) to.mode <- switch(igraph.match.arg(to.mode), "out"=1L, "in"=2L, "all"=3L, "total"=3L) directed.neighbors <- as.logical(directed.neighbors) @@ -1276,11 +1530,21 @@ strength_impl <- function(graph, vids=V(graph), mode=c("all", "out", "in", "tota vids <- as_igraph_vs(graph, vids) mode <- switch(igraph.match.arg(mode), "out"=1L, "in"=2L, "all"=3L, "total"=3L) loops <- as.logical(loops) + if (is.null(weights) && "weight" %in% edge_attr_names(graph)) { + weights <- E(graph)$weight + } + if (!is.null(weights) && any(!is.na(weights))) { + weights <- as.numeric(weights) + } else { + weights <- NULL + } on.exit( .Call(R_igraph_finalizer) ) # Function call res <- .Call(R_igraph_strength, graph, vids-1, mode, loops, weights) - + if (igraph_opt("add.vertex.names") && is_named(graph)) { + names(res) <- vertex_attr(graph, "name", vids) + } res } @@ -1364,11 +1628,12 @@ centralization_closeness_tmax_impl <- function(graph=NULL, nodes=0, mode=c("out" res } -centralization_eigenvector_centrality_impl <- function(graph, directed=FALSE, scale=TRUE, options=ARPACK_DEFAULTS, normalized=TRUE) { +centralization_eigenvector_centrality_impl <- function(graph, directed=FALSE, scale=TRUE, options=arpack_defaults(), normalized=TRUE) { # Argument checks ensure_igraph(graph) directed <- as.logical(directed) scale <- as.logical(scale) + options <- modify_list(arpack_defaults(), options) normalized <- as.logical(normalized) on.exit( .Call(R_igraph_finalizer) ) @@ -1436,6 +1701,14 @@ assortativity_degree_impl <- function(graph, directed=TRUE) { joint_degree_matrix_impl <- function(graph, weights=NULL, max.out.degree=-1, max.in.degree=-1) { # Argument checks ensure_igraph(graph) + if (is.null(weights) && "weight" %in% edge_attr_names(graph)) { + weights <- E(graph)$weight + } + if (!is.null(weights) && any(!is.na(weights))) { + weights <- as.numeric(weights) + } else { + weights <- NULL + } max.out.degree <- as.numeric(max.out.degree) max.in.degree <- as.numeric(max.in.degree) @@ -1449,6 +1722,14 @@ joint_degree_matrix_impl <- function(graph, weights=NULL, max.out.degree=-1, max joint_degree_distribution_impl <- function(graph, weights=NULL, from.mode=c("out", "in", "all", "total"), to.mode=c("in", "out", "all", "total"), directed.neighbors=TRUE, normalized=TRUE, max.from.degree=-1, max.to.degree=-1) { # Argument checks ensure_igraph(graph) + if (is.null(weights) && "weight" %in% edge_attr_names(graph)) { + weights <- E(graph)$weight + } + if (!is.null(weights) && any(!is.na(weights))) { + weights <- as.numeric(weights) + } else { + weights <- NULL + } from.mode <- switch(igraph.match.arg(from.mode), "out"=1L, "in"=2L, "all"=3L, "total"=3L) to.mode <- switch(igraph.match.arg(to.mode), "out"=1L, "in"=2L, "all"=3L, "total"=3L) directed.neighbors <- as.logical(directed.neighbors) @@ -1466,6 +1747,14 @@ joint_degree_distribution_impl <- function(graph, weights=NULL, from.mode=c("out joint_type_distribution_impl <- function(graph, weights=NULL, from.types, to.types=NULL, directed=TRUE, normalized=TRUE) { # Argument checks ensure_igraph(graph) + if (is.null(weights) && "weight" %in% edge_attr_names(graph)) { + weights <- E(graph)$weight + } + if (!is.null(weights) && any(!is.na(weights))) { + weights <- as.numeric(weights) + } else { + weights <- NULL + } from.types <- as.numeric(from.types)-1 to.types <- as.numeric(to.types)-1 directed <- as.logical(directed) @@ -1500,20 +1789,32 @@ eccentricity_impl <- function(graph, vids=V(graph), mode=c("all", "out", "in", " on.exit( .Call(R_igraph_finalizer) ) # Function call res <- .Call(R_igraph_eccentricity, graph, vids-1, mode) - + if (igraph_opt("add.vertex.names") && is_named(graph)) { + names(res) <- vertex_attr(graph, "name", vids) + } res } eccentricity_dijkstra_impl <- function(graph, weights=NULL, vids=V(graph), mode=c("all", "out", "in", "total")) { # Argument checks ensure_igraph(graph) + if (is.null(weights) && "weight" %in% edge_attr_names(graph)) { + weights <- E(graph)$weight + } + if (!is.null(weights) && any(!is.na(weights))) { + weights <- as.numeric(weights) + } else { + weights <- NULL + } vids <- as_igraph_vs(graph, vids) mode <- switch(igraph.match.arg(mode), "out"=1L, "in"=2L, "all"=3L, "total"=3L) on.exit( .Call(R_igraph_finalizer) ) # Function call res <- .Call(R_igraph_eccentricity_dijkstra, graph, weights, vids-1, mode) - + if (igraph_opt("add.vertex.names") && is_named(graph)) { + names(res) <- vertex_attr(graph, "name", vids) + } res } @@ -1534,6 +1835,14 @@ graph_center_impl <- function(graph, mode=c("all", "out", "in", "total")) { graph_center_dijkstra_impl <- function(graph, weights=NULL, mode=c("all", "out", "in", "total")) { # Argument checks ensure_igraph(graph) + if (is.null(weights) && "weight" %in% edge_attr_names(graph)) { + weights <- E(graph)$weight + } + if (!is.null(weights) && any(!is.na(weights))) { + weights <- as.numeric(weights) + } else { + weights <- NULL + } mode <- switch(igraph.match.arg(mode), "out"=1L, "in"=2L, "all"=3L, "total"=3L) on.exit( .Call(R_igraph_finalizer) ) @@ -1560,6 +1869,14 @@ radius_impl <- function(graph, mode=c("all", "out", "in", "total")) { radius_dijkstra_impl <- function(graph, weights=NULL, mode=c("all", "out", "in", "total")) { # Argument checks ensure_igraph(graph) + if (is.null(weights) && "weight" %in% edge_attr_names(graph)) { + weights <- E(graph)$weight + } + if (!is.null(weights) && any(!is.na(weights))) { + weights <- as.numeric(weights) + } else { + weights <- NULL + } mode <- switch(igraph.match.arg(mode), "out"=1L, "in"=2L, "all"=3L, "total"=3L) on.exit( .Call(R_igraph_finalizer) ) @@ -1589,6 +1906,14 @@ pseudo_diameter_impl <- function(graph, start.vid, directed=TRUE, unconnected=TR pseudo_diameter_dijkstra_impl <- function(graph, weights=NULL, start.vid, directed=TRUE, unconnected=TRUE) { # Argument checks ensure_igraph(graph) + if (is.null(weights) && "weight" %in% edge_attr_names(graph)) { + weights <- E(graph)$weight + } + if (!is.null(weights) && any(!is.na(weights))) { + weights <- as.numeric(weights) + } else { + weights <- NULL + } start.vid <- as_igraph_vs(graph, start.vid) if (length(start.vid) == 0) { stop("No vertex was specified") @@ -1606,18 +1931,36 @@ pseudo_diameter_dijkstra_impl <- function(graph, weights=NULL, start.vid, direct diversity_impl <- function(graph, weights=NULL, vids=V(graph)) { # Argument checks ensure_igraph(graph) + if (is.null(weights) && "weight" %in% edge_attr_names(graph)) { + weights <- E(graph)$weight + } + if (!is.null(weights) && any(!is.na(weights))) { + weights <- as.numeric(weights) + } else { + weights <- NULL + } vids <- as_igraph_vs(graph, vids) on.exit( .Call(R_igraph_finalizer) ) # Function call res <- .Call(R_igraph_diversity, graph, weights, vids-1) - + if (igraph_opt("add.vertex.names") && is_named(graph)) { + names(res) <- vertex_attr(graph, "name", vids) + } res } random_walk_impl <- function(graph, start, steps, weights=NULL, mode=c("out", "in", "all", "total"), stuck=c("return", "error")) { # Argument checks ensure_igraph(graph) + if (is.null(weights) && "weight" %in% edge_attr_names(graph)) { + weights <- E(graph)$weight + } + if (!is.null(weights) && any(!is.na(weights))) { + weights <- as.numeric(weights) + } else { + weights <- NULL + } start <- as_igraph_vs(graph, start) if (length(start) == 0) { stop("No vertex was specified") @@ -1641,6 +1984,14 @@ random_walk_impl <- function(graph, start, steps, weights=NULL, mode=c("out", "i random_edge_walk_impl <- function(graph, start, steps, weights=NULL, mode=c("out", "in", "all", "total"), stuck=c("return", "error")) { # Argument checks ensure_igraph(graph) + if (is.null(weights) && "weight" %in% edge_attr_names(graph)) { + weights <- E(graph)$weight + } + if (!is.null(weights) && any(!is.na(weights))) { + weights <- as.numeric(weights) + } else { + weights <- NULL + } start <- as_igraph_vs(graph, start) if (length(start) == 0) { stop("No vertex was specified") @@ -1661,6 +2012,14 @@ random_edge_walk_impl <- function(graph, start, steps, weights=NULL, mode=c("out global_efficiency_impl <- function(graph, weights=NULL, directed=TRUE) { # Argument checks ensure_igraph(graph) + if (is.null(weights) && "weight" %in% edge_attr_names(graph)) { + weights <- E(graph)$weight + } + if (!is.null(weights) && any(!is.na(weights))) { + weights <- as.numeric(weights) + } else { + weights <- NULL + } directed <- as.logical(directed) on.exit( .Call(R_igraph_finalizer) ) @@ -1674,19 +2033,37 @@ local_efficiency_impl <- function(graph, vids=V(graph), weights=NULL, directed=T # Argument checks ensure_igraph(graph) vids <- as_igraph_vs(graph, vids) + if (is.null(weights) && "weight" %in% edge_attr_names(graph)) { + weights <- E(graph)$weight + } + if (!is.null(weights) && any(!is.na(weights))) { + weights <- as.numeric(weights) + } else { + weights <- NULL + } directed <- as.logical(directed) mode <- switch(igraph.match.arg(mode), "out"=1L, "in"=2L, "all"=3L, "total"=3L) on.exit( .Call(R_igraph_finalizer) ) # Function call res <- .Call(R_igraph_local_efficiency, graph, vids-1, weights, directed, mode) - + if (igraph_opt("add.vertex.names") && is_named(graph)) { + names(res) <- vertex_attr(graph, "name", vids) + } res } average_local_efficiency_impl <- function(graph, weights=NULL, directed=TRUE, mode=c("all", "out", "in", "total")) { # Argument checks ensure_igraph(graph) + if (is.null(weights) && "weight" %in% edge_attr_names(graph)) { + weights <- E(graph)$weight + } + if (!is.null(weights) && any(!is.na(weights))) { + weights <- as.numeric(weights) + } else { + weights <- NULL + } directed <- as.logical(directed) mode <- switch(igraph.match.arg(mode), "out"=1L, "in"=2L, "all"=3L, "total"=3L) @@ -1827,6 +2204,14 @@ get_laplacian_impl <- function(graph, mode=c("out", "in", "all", "total"), norma ensure_igraph(graph) mode <- switch(igraph.match.arg(mode), "out"=1L, "in"=2L, "all"=3L, "total"=3L) normalization <- switch(igraph.match.arg(normalization), "unnormalized"=0L, "symmetric"=1L, "left"=2L, "right"=3L) + if (is.null(weights) && "weight" %in% edge_attr_names(graph)) { + weights <- E(graph)$weight + } + if (!is.null(weights) && any(!is.na(weights))) { + weights <- as.numeric(weights) + } else { + weights <- NULL + } on.exit( .Call(R_igraph_finalizer) ) # Function call @@ -1840,6 +2225,14 @@ get_laplacian_sparse_impl <- function(graph, mode=c("out", "in", "all", "total") ensure_igraph(graph) mode <- switch(igraph.match.arg(mode), "out"=1L, "in"=2L, "all"=3L, "total"=3L) normalization <- switch(igraph.match.arg(normalization), "unnormalized"=0L, "symmetric"=1L, "left"=2L, "right"=3L) + if (is.null(weights) && "weight" %in% edge_attr_names(graph)) { + weights <- E(graph)$weight + } + if (!is.null(weights) && any(!is.na(weights))) { + weights <- as.numeric(weights) + } else { + weights <- NULL + } on.exit( .Call(R_igraph_finalizer) ) # Function call @@ -1880,6 +2273,15 @@ biconnected_components_impl <- function(graph) { on.exit( .Call(R_igraph_finalizer) ) # Function call res <- .Call(R_igraph_biconnected_components, graph) + if (igraph_opt("return.vs.es")) { + res$tree.edges <- lapply(res$tree.edges, unsafe_create_es, graph = graph, es = E(graph)) + } + if (igraph_opt("return.vs.es")) { + res$component.edges <- lapply(res$component.edges, unsafe_create_es, graph = graph, es = E(graph)) + } + if (igraph_opt("return.vs.es")) { + res$components <- lapply(res$components, unsafe_create_vs, graph = graph, verts = V(graph)) + } if (igraph_opt("return.vs.es")) { res$articulation.points <- create_vs(graph, res$articulation.points) } @@ -1919,7 +2321,9 @@ cliques_impl <- function(graph, min=0, max=0) { on.exit( .Call(R_igraph_finalizer) ) # Function call res <- .Call(R_igraph_cliques, graph, min, max) - + if (igraph_opt("return.vs.es")) { + res <- lapply(res, unsafe_create_vs, graph = graph, verts = V(graph)) + } res } @@ -1943,7 +2347,9 @@ largest_cliques_impl <- function(graph) { on.exit( .Call(R_igraph_finalizer) ) # Function call res <- .Call(R_igraph_largest_cliques, graph) - + if (igraph_opt("return.vs.es")) { + res <- lapply(res, unsafe_create_vs, graph = graph, verts = V(graph)) + } res } @@ -1974,6 +2380,14 @@ clique_number_impl <- function(graph) { weighted_cliques_impl <- function(graph, vertex.weights=NULL, min.weight=0, max.weight=0, maximal=FALSE) { # Argument checks ensure_igraph(graph) + if (is.null(vertex.weights) && "weight" %in% vertex_attr_names(graph)) { + vertex.weights <- V(graph)$weight + } + if (!is.null(vertex.weights) && any(!is.na(vertex.weights))) { + vertex.weights <- as.numeric(vertex.weights) + } else { + vertex.weights <- NULL + } min.weight <- as.numeric(min.weight) max.weight <- as.numeric(max.weight) maximal <- as.logical(maximal) @@ -1981,24 +2395,44 @@ weighted_cliques_impl <- function(graph, vertex.weights=NULL, min.weight=0, max. on.exit( .Call(R_igraph_finalizer) ) # Function call res <- .Call(R_igraph_weighted_cliques, graph, vertex.weights, min.weight, max.weight, maximal) - + if (igraph_opt("return.vs.es")) { + res <- lapply(res, unsafe_create_vs, graph = graph, verts = V(graph)) + } res } largest_weighted_cliques_impl <- function(graph, vertex.weights=NULL) { # Argument checks ensure_igraph(graph) + if (is.null(vertex.weights) && "weight" %in% vertex_attr_names(graph)) { + vertex.weights <- V(graph)$weight + } + if (!is.null(vertex.weights) && any(!is.na(vertex.weights))) { + vertex.weights <- as.numeric(vertex.weights) + } else { + vertex.weights <- NULL + } on.exit( .Call(R_igraph_finalizer) ) # Function call res <- .Call(R_igraph_largest_weighted_cliques, graph, vertex.weights) - + if (igraph_opt("return.vs.es")) { + res <- lapply(res, unsafe_create_vs, graph = graph, verts = V(graph)) + } res } weighted_clique_number_impl <- function(graph, vertex.weights=NULL) { # Argument checks ensure_igraph(graph) + if (is.null(vertex.weights) && "weight" %in% vertex_attr_names(graph)) { + vertex.weights <- V(graph)$weight + } + if (!is.null(vertex.weights) && any(!is.na(vertex.weights))) { + vertex.weights <- as.numeric(vertex.weights) + } else { + vertex.weights <- NULL + } on.exit( .Call(R_igraph_finalizer) ) # Function call @@ -2168,12 +2602,22 @@ similarity_jaccard_pairs_impl <- function(graph, pairs, mode=c("all", "out", "in graphlets_impl <- function(graph, weights=NULL, niter=1000) { # Argument checks ensure_igraph(graph) + if (is.null(weights) && "weight" %in% edge_attr_names(graph)) { + weights <- E(graph)$weight + } + if (!is.null(weights) && any(!is.na(weights))) { + weights <- as.numeric(weights) + } else { + weights <- NULL + } niter <- as.numeric(niter) on.exit( .Call(R_igraph_finalizer) ) # Function call res <- .Call(R_igraph_graphlets, graph, weights, niter) - + if (igraph_opt("return.vs.es")) { + res$cliques <- lapply(res$cliques, unsafe_create_vs, graph = graph, verts = V(graph)) + } res } @@ -2302,6 +2746,14 @@ get_stochastic_sparse_impl <- function(graph, column.wise=FALSE, weights=NULL) { # Argument checks ensure_igraph(graph) column.wise <- as.logical(column.wise) + if (is.null(weights) && "weight" %in% edge_attr_names(graph)) { + weights <- E(graph)$weight + } + if (!is.null(weights) && any(!is.na(weights))) { + weights <- as.numeric(weights) + } else { + weights <- NULL + } on.exit( .Call(R_igraph_finalizer) ) # Function call @@ -2359,6 +2811,14 @@ adjacent_triangles_impl <- function(graph, vids=V(graph)) { local_scan_subset_ecount_impl <- function(graph, weights=NULL, subsets) { # Argument checks ensure_igraph(graph) + if (is.null(weights) && "weight" %in% edge_attr_names(graph)) { + weights <- E(graph)$weight + } + if (!is.null(weights) && any(!is.na(weights))) { + weights <- as.numeric(weights) + } else { + weights <- NULL + } on.exit( .Call(R_igraph_finalizer) ) # Function call @@ -2408,6 +2868,14 @@ induced_subgraph_map_impl <- function(graph, vids, impl) { gomory_hu_tree_impl <- function(graph, capacity=NULL) { # Argument checks ensure_igraph(graph) + if (is.null(capacity) && "capacity" %in% edge_attr_names(graph)) { + capacity <- E(graph)$capacity + } + if (!is.null(capacity) && any(!is.na(capacity))) { + capacity <- as.numeric(capacity) + } else { + capacity <- NULL + } on.exit( .Call(R_igraph_finalizer) ) # Function call @@ -2427,6 +2895,14 @@ maxflow_impl <- function(graph, source, target, capacity=NULL) { if (length(target) == 0) { stop("No vertex was specified") } + if (is.null(capacity) && "capacity" %in% edge_attr_names(graph)) { + capacity <- E(graph)$capacity + } + if (!is.null(capacity) && any(!is.na(capacity))) { + capacity <- as.numeric(capacity) + } else { + capacity <- NULL + } on.exit( .Call(R_igraph_finalizer) ) # Function call @@ -2446,6 +2922,14 @@ maxflow_impl <- function(graph, source, target, capacity=NULL) { residual_graph_impl <- function(graph, capacity, flow) { # Argument checks ensure_igraph(graph) + if (is.null(capacity) && "capacity" %in% edge_attr_names(graph)) { + capacity <- E(graph)$capacity + } + if (!is.null(capacity) && any(!is.na(capacity))) { + capacity <- as.numeric(capacity) + } else { + capacity <- NULL + } flow <- as.numeric(flow) on.exit( .Call(R_igraph_finalizer) ) @@ -2458,6 +2942,14 @@ residual_graph_impl <- function(graph, capacity, flow) { reverse_residual_graph_impl <- function(graph, capacity, flow) { # Argument checks ensure_igraph(graph) + if (is.null(capacity) && "capacity" %in% edge_attr_names(graph)) { + capacity <- E(graph)$capacity + } + if (!is.null(capacity) && any(!is.na(capacity))) { + capacity <- as.numeric(capacity) + } else { + capacity <- NULL + } flow <- as.numeric(flow) on.exit( .Call(R_igraph_finalizer) ) @@ -2500,7 +2992,12 @@ all_st_cuts_impl <- function(graph, source, target) { on.exit( .Call(R_igraph_finalizer) ) # Function call res <- .Call(R_igraph_all_st_cuts, graph, source-1, target-1) - + if (igraph_opt("return.vs.es")) { + res$cuts <- lapply(res$cuts, unsafe_create_es, graph = graph, es = E(graph)) + } + if (igraph_opt("return.vs.es")) { + res$partition1s <- lapply(res$partition1s, unsafe_create_vs, graph = graph, verts = V(graph)) + } res } @@ -2515,11 +3012,24 @@ all_st_mincuts_impl <- function(graph, source, target, capacity=NULL) { if (length(target) == 0) { stop("No vertex was specified") } + if (is.null(capacity) && "capacity" %in% edge_attr_names(graph)) { + capacity <- E(graph)$capacity + } + if (!is.null(capacity) && any(!is.na(capacity))) { + capacity <- as.numeric(capacity) + } else { + capacity <- NULL + } on.exit( .Call(R_igraph_finalizer) ) # Function call res <- .Call(R_igraph_all_st_mincuts, graph, source-1, target-1, capacity) - + if (igraph_opt("return.vs.es")) { + res$cuts <- lapply(res$cuts, unsafe_create_es, graph = graph, es = E(graph)) + } + if (igraph_opt("return.vs.es")) { + res$partition1s <- lapply(res$partition1s, unsafe_create_vs, graph = graph, verts = V(graph)) + } res } @@ -2565,7 +3075,9 @@ all_minimal_st_separators_impl <- function(graph) { on.exit( .Call(R_igraph_finalizer) ) # Function call res <- .Call(R_igraph_all_minimal_st_separators, graph) - + if (igraph_opt("return.vs.es")) { + res <- lapply(res, unsafe_create_vs, graph = graph, verts = V(graph)) + } res } @@ -2576,7 +3088,9 @@ minimum_size_separators_impl <- function(graph) { on.exit( .Call(R_igraph_finalizer) ) # Function call res <- .Call(R_igraph_minimum_size_separators, graph) - + if (igraph_opt("return.vs.es")) { + res <- lapply(res, unsafe_create_vs, graph = graph, verts = V(graph)) + } res } @@ -2606,17 +3120,39 @@ isomorphic_impl <- function(graph1, graph2) { automorphism_group_impl <- function(graph, colors=NULL) { # Argument checks ensure_igraph(graph) + if (missing(colors)) { + if ("color" %in% vertex_attr_names(graph)) { + colors <- V(graph)$color + } else { + colors <- NULL + } + } + if (!is.null(colors)) { + colors <- as.numeric(colors)-1 + } on.exit( .Call(R_igraph_finalizer) ) # Function call res <- .Call(R_igraph_automorphism_group, graph, colors) - + if (igraph_opt("return.vs.es")) { + res <- lapply(res, unsafe_create_vs, graph = graph, verts = V(graph)) + } res } count_automorphisms_impl <- function(graph, colors=NULL) { # Argument checks ensure_igraph(graph) + if (missing(colors)) { + if ("color" %in% vertex_attr_names(graph)) { + colors <- V(graph)$color + } else { + colors <- NULL + } + } + if (!is.null(colors)) { + colors <- as.numeric(colors)-1 + } on.exit( .Call(R_igraph_finalizer) ) # Function call @@ -2642,6 +3178,46 @@ isomorphic_vf2_impl <- function(graph1, graph2, vertex.color1=NULL, vertex.color # Argument checks ensure_igraph(graph1) ensure_igraph(graph2) + if (missing(vertex.color1)) { + if ("color" %in% vertex_attr_names(graph1)) { + vertex.color1 <- V(graph1)$color + } else { + vertex.color1 <- NULL + } + } + if (!is.null(vertex.color1)) { + vertex.color1 <- as.numeric(vertex.color1)-1 + } + if (missing(vertex.color2)) { + if ("color" %in% vertex_attr_names(graph2)) { + vertex.color2 <- V(graph2)$color + } else { + vertex.color2 <- NULL + } + } + if (!is.null(vertex.color2)) { + vertex.color2 <- as.numeric(vertex.color2)-1 + } + if (missing(edge.color1)) { + if ("color" %in% edge_attr_names(graph1)) { + edge.color1 <- E(graph1)$color + } else { + edge.color1 <- NULL + } + } + if (!is.null(edge.color1)) { + edge.color1 <- as.numeric(edge.color1)-1 + } + if (missing(edge.color2)) { + if ("color" %in% edge_attr_names(graph2)) { + edge.color2 <- E(graph2)$color + } else { + edge.color2 <- NULL + } + } + if (!is.null(edge.color2)) { + edge.color2 <- as.numeric(edge.color2)-1 + } on.exit( .Call(R_igraph_finalizer) ) # Function call @@ -2654,6 +3230,46 @@ count_isomorphisms_vf2_impl <- function(graph1, graph2, vertex.color1, vertex.co # Argument checks ensure_igraph(graph1) ensure_igraph(graph2) + if (missing(vertex.color1)) { + if ("color" %in% vertex_attr_names(graph1)) { + vertex.color1 <- V(graph1)$color + } else { + vertex.color1 <- NULL + } + } + if (!is.null(vertex.color1)) { + vertex.color1 <- as.numeric(vertex.color1)-1 + } + if (missing(vertex.color2)) { + if ("color" %in% vertex_attr_names(graph2)) { + vertex.color2 <- V(graph2)$color + } else { + vertex.color2 <- NULL + } + } + if (!is.null(vertex.color2)) { + vertex.color2 <- as.numeric(vertex.color2)-1 + } + if (missing(edge.color1)) { + if ("color" %in% edge_attr_names(graph1)) { + edge.color1 <- E(graph1)$color + } else { + edge.color1 <- NULL + } + } + if (!is.null(edge.color1)) { + edge.color1 <- as.numeric(edge.color1)-1 + } + if (missing(edge.color2)) { + if ("color" %in% edge_attr_names(graph2)) { + edge.color2 <- E(graph2)$color + } else { + edge.color2 <- NULL + } + } + if (!is.null(edge.color2)) { + edge.color2 <- as.numeric(edge.color2)-1 + } on.exit( .Call(R_igraph_finalizer) ) # Function call @@ -2678,6 +3294,46 @@ subisomorphic_vf2_impl <- function(graph1, graph2, vertex.color1=NULL, vertex.co # Argument checks ensure_igraph(graph1) ensure_igraph(graph2) + if (missing(vertex.color1)) { + if ("color" %in% vertex_attr_names(graph1)) { + vertex.color1 <- V(graph1)$color + } else { + vertex.color1 <- NULL + } + } + if (!is.null(vertex.color1)) { + vertex.color1 <- as.numeric(vertex.color1)-1 + } + if (missing(vertex.color2)) { + if ("color" %in% vertex_attr_names(graph2)) { + vertex.color2 <- V(graph2)$color + } else { + vertex.color2 <- NULL + } + } + if (!is.null(vertex.color2)) { + vertex.color2 <- as.numeric(vertex.color2)-1 + } + if (missing(edge.color1)) { + if ("color" %in% edge_attr_names(graph1)) { + edge.color1 <- E(graph1)$color + } else { + edge.color1 <- NULL + } + } + if (!is.null(edge.color1)) { + edge.color1 <- as.numeric(edge.color1)-1 + } + if (missing(edge.color2)) { + if ("color" %in% edge_attr_names(graph2)) { + edge.color2 <- E(graph2)$color + } else { + edge.color2 <- NULL + } + } + if (!is.null(edge.color2)) { + edge.color2 <- as.numeric(edge.color2)-1 + } on.exit( .Call(R_igraph_finalizer) ) # Function call @@ -2690,6 +3346,46 @@ count_subisomorphisms_vf2_impl <- function(graph1, graph2, vertex.color1, vertex # Argument checks ensure_igraph(graph1) ensure_igraph(graph2) + if (missing(vertex.color1)) { + if ("color" %in% vertex_attr_names(graph1)) { + vertex.color1 <- V(graph1)$color + } else { + vertex.color1 <- NULL + } + } + if (!is.null(vertex.color1)) { + vertex.color1 <- as.numeric(vertex.color1)-1 + } + if (missing(vertex.color2)) { + if ("color" %in% vertex_attr_names(graph2)) { + vertex.color2 <- V(graph2)$color + } else { + vertex.color2 <- NULL + } + } + if (!is.null(vertex.color2)) { + vertex.color2 <- as.numeric(vertex.color2)-1 + } + if (missing(edge.color1)) { + if ("color" %in% edge_attr_names(graph1)) { + edge.color1 <- E(graph1)$color + } else { + edge.color1 <- NULL + } + } + if (!is.null(edge.color1)) { + edge.color1 <- as.numeric(edge.color1)-1 + } + if (missing(edge.color2)) { + if ("color" %in% edge_attr_names(graph2)) { + edge.color2 <- E(graph2)$color + } else { + edge.color2 <- NULL + } + } + if (!is.null(edge.color2)) { + edge.color2 <- as.numeric(edge.color2)-1 + } on.exit( .Call(R_igraph_finalizer) ) # Function call @@ -2701,6 +3397,16 @@ count_subisomorphisms_vf2_impl <- function(graph1, graph2, vertex.color1, vertex canonical_permutation_impl <- function(graph, colors=NULL) { # Argument checks ensure_igraph(graph) + if (missing(colors)) { + if ("color" %in% vertex_attr_names(graph)) { + colors <- V(graph)$color + } else { + colors <- NULL + } + } + if (!is.null(colors)) { + colors <- as.numeric(colors)-1 + } on.exit( .Call(R_igraph_finalizer) ) # Function call @@ -2712,6 +3418,16 @@ canonical_permutation_impl <- function(graph, colors=NULL) { canonical_permutation_bliss_impl <- function(graph, colors=NULL, sh=c("fm", "f", "fs", "fl", "flm", "fsm")) { # Argument checks ensure_igraph(graph) + if (missing(colors)) { + if ("color" %in% vertex_attr_names(graph)) { + colors <- V(graph)$color + } else { + colors <- NULL + } + } + if (!is.null(colors)) { + colors <- as.numeric(colors)-1 + } sh <- switch(igraph.match.arg(sh), "f"=0L, "fl"=1L, "fs"=2L, "fm"=3L, "flm"=4L, "fsm"=5L) on.exit( .Call(R_igraph_finalizer) ) @@ -2737,6 +3453,26 @@ isomorphic_bliss_impl <- function(graph1, graph2, colors1=NULL, colors2=NULL, sh # Argument checks ensure_igraph(graph1) ensure_igraph(graph2) + if (missing(colors1)) { + if ("color" %in% vertex_attr_names(graph1)) { + colors1 <- V(graph1)$color + } else { + colors1 <- NULL + } + } + if (!is.null(colors1)) { + colors1 <- as.numeric(colors1)-1 + } + if (missing(colors2)) { + if ("color" %in% vertex_attr_names(graph2)) { + colors2 <- V(graph2)$color + } else { + colors2 <- NULL + } + } + if (!is.null(colors2)) { + colors2 <- as.numeric(colors2)-1 + } sh <- switch(igraph.match.arg(sh), "f"=0L, "fl"=1L, "fs"=2L, "fm"=3L, "flm"=4L, "fsm"=5L) on.exit( .Call(R_igraph_finalizer) ) @@ -2749,6 +3485,16 @@ isomorphic_bliss_impl <- function(graph1, graph2, colors1=NULL, colors2=NULL, sh count_automorphisms_bliss_impl <- function(graph, colors=NULL, sh=c("fm", "f", "fs", "fl", "flm", "fsm")) { # Argument checks ensure_igraph(graph) + if (missing(colors)) { + if ("color" %in% vertex_attr_names(graph)) { + colors <- V(graph)$color + } else { + colors <- NULL + } + } + if (!is.null(colors)) { + colors <- as.numeric(colors)-1 + } sh <- switch(igraph.match.arg(sh), "f"=0L, "fl"=1L, "fs"=2L, "fm"=3L, "flm"=4L, "fsm"=5L) on.exit( .Call(R_igraph_finalizer) ) @@ -2761,11 +3507,24 @@ count_automorphisms_bliss_impl <- function(graph, colors=NULL, sh=c("fm", "f", " automorphism_group_bliss_impl <- function(graph, colors=NULL, sh=c("fm", "f", "fs", "fl", "flm", "fsm"), details=FALSE) { # Argument checks ensure_igraph(graph) + if (missing(colors)) { + if ("color" %in% vertex_attr_names(graph)) { + colors <- V(graph)$color + } else { + colors <- NULL + } + } + if (!is.null(colors)) { + colors <- as.numeric(colors)-1 + } sh <- switch(igraph.match.arg(sh), "f"=0L, "fl"=1L, "fs"=2L, "fm"=3L, "flm"=4L, "fsm"=5L) on.exit( .Call(R_igraph_finalizer) ) # Function call res <- .Call(R_igraph_automorphism_group_bliss, graph, colors, sh) + if (igraph_opt("return.vs.es")) { + res$generators <- lapply(res$generators, unsafe_create_vs, graph = graph, verts = V(graph)) + } if (!details) { res <- res$generators } @@ -2788,9 +3547,18 @@ adjacency_spectral_embedding_impl <- function(graph, no, weights=NULL, which=c(" # Argument checks ensure_igraph(graph) no <- as.numeric(no) + if (is.null(weights) && "weight" %in% edge_attr_names(graph)) { + weights <- E(graph)$weight + } + if (!is.null(weights) && any(!is.na(weights))) { + weights <- as.numeric(weights) + } else { + weights <- NULL + } which <- switch(igraph.match.arg(which), "lm"=0L, "la"=2L, "sa"=3L) scaled <- as.logical(scaled) cvec <- as.numeric(cvec) + options <- modify_list(arpack_defaults(), options) on.exit( .Call(R_igraph_finalizer) ) # Function call @@ -2799,16 +3567,25 @@ adjacency_spectral_embedding_impl <- function(graph, no, weights=NULL, which=c(" res } -laplacian_spectral_embedding_impl <- function(graph, no, weights=NULL, which=c("lm", "la", "sa"), type=c("default", "D-A", "DAD", "I-DAD", "OAP"), scaled=TRUE, options=ARPACK_DEFAULTS) { +laplacian_spectral_embedding_impl <- function(graph, no, weights=NULL, which=c("lm", "la", "sa"), type=c("default", "D-A", "DAD", "I-DAD", "OAP"), scaled=TRUE, options=arpack_defaults()) { # Argument checks ensure_igraph(graph) no <- as.numeric(no) + if (is.null(weights) && "weight" %in% edge_attr_names(graph)) { + weights <- E(graph)$weight + } + if (!is.null(weights) && any(!is.na(weights))) { + weights <- as.numeric(weights) + } else { + weights <- NULL + } which <- switch(igraph.match.arg(which), "lm"=0L, "la"=2L, "sa"=3L) type <- switch(igraph.match.arg(type), "default"=if (is.directed(graph)) 3L else 0L, "da"=0L, "d-a"=0L, "idad"=1L, "i-dad"=1L, "dad"=2L, "oap"=3L) scaled <- as.logical(scaled) + options <- modify_list(arpack_defaults(), options) on.exit( .Call(R_igraph_finalizer) ) # Function call @@ -2817,7 +3594,7 @@ laplacian_spectral_embedding_impl <- function(graph, no, weights=NULL, which=c(" res } -eigen_adjacency_impl <- function(graph, algorithm=c("arpack", "auto", "lapack", "comp_auto", "comp_lapack", "comp_arpack"), which=list(), options=ARPACK_DEFAULTS, storage) { +eigen_adjacency_impl <- function(graph, algorithm=c("arpack", "auto", "lapack", "comp_auto", "comp_lapack", "comp_arpack"), which=list(), options=arpack_defaults(), storage) { # Argument checks ensure_igraph(graph) algorithm <- switch(igraph.match.arg(algorithm), "auto"=0L, "lapack"=1L, @@ -2825,6 +3602,7 @@ eigen_adjacency_impl <- function(graph, algorithm=c("arpack", "auto", "lapack", "comp_arpack"=5L) which.tmp <- eigen_defaults(); which.tmp[ names(which) ] <- which ; which <- which.tmp + options <- modify_list(arpack_defaults(), options) on.exit( .Call(R_igraph_finalizer) ) # Function call @@ -2933,11 +3711,21 @@ fundamental_cycles_impl <- function(graph, start=NULL, bfs.cutoff, weights=NULL) stop("No vertex was specified") } bfs.cutoff <- as.numeric(bfs.cutoff) + if (is.null(weights) && "weight" %in% edge_attr_names(graph)) { + weights <- E(graph)$weight + } + if (!is.null(weights) && any(!is.na(weights))) { + weights <- as.numeric(weights) + } else { + weights <- NULL + } on.exit( .Call(R_igraph_finalizer) ) # Function call res <- .Call(R_igraph_fundamental_cycles, graph, start-1, bfs.cutoff, weights) - + if (igraph_opt("return.vs.es")) { + res <- lapply(res, unsafe_create_es, graph = graph, es = E(graph)) + } res } @@ -2947,11 +3735,21 @@ minimum_cycle_basis_impl <- function(graph, bfs.cutoff, complete, use.cycle.orde bfs.cutoff <- as.numeric(bfs.cutoff) complete <- as.logical(complete) use.cycle.order <- as.logical(use.cycle.order) + if (is.null(weights) && "weight" %in% edge_attr_names(graph)) { + weights <- E(graph)$weight + } + if (!is.null(weights) && any(!is.na(weights))) { + weights <- as.numeric(weights) + } else { + weights <- NULL + } on.exit( .Call(R_igraph_finalizer) ) # Function call res <- .Call(R_igraph_minimum_cycle_basis, graph, bfs.cutoff, complete, use.cycle.order, weights) - + if (igraph_opt("return.vs.es")) { + res <- lapply(res, unsafe_create_es, graph = graph, es = E(graph)) + } res } @@ -3077,7 +3875,10 @@ vertex_coloring_greedy_impl <- function(graph, heuristic=c("colored_neighbors", on.exit( .Call(R_igraph_finalizer) ) # Function call res <- .Call(R_igraph_vertex_coloring_greedy, graph, heuristic) - + res <- res+1 + if (igraph_opt("add.vertex.names") && is_named(graph)) { + names(res) <- vertex_attr(graph, "name") + } res } @@ -3102,13 +3903,23 @@ deterministic_optimal_imitation_impl <- function(graph, vid, optimality=c("maxim moran_process_impl <- function(graph, weights=NULL, quantities, strategies, mode=c("out", "in", "all", "total")) { # Argument checks ensure_igraph(graph) + if (is.null(weights) && "weight" %in% edge_attr_names(graph)) { + weights <- E(graph)$weight + } + if (!is.null(weights) && any(!is.na(weights))) { + weights <- as.numeric(weights) + } else { + weights <- NULL + } strategies <- as.numeric(strategies) mode <- switch(igraph.match.arg(mode), "out"=1L, "in"=2L, "all"=3L, "total"=3L) on.exit( .Call(R_igraph_finalizer) ) # Function call res <- .Call(R_igraph_moran_process, graph, weights, quantities, strategies, mode) - + if (igraph_opt("add.vertex.names") && is_named(graph)) { + names(res$quantities) <- vertex_attr(graph, "name", V(graph)) + } res } @@ -3166,15 +3977,3 @@ vertex_path_from_edge_path_impl <- function(graph, start, edge.path, mode=c("out res } -delete_vertices_idx_impl <- function() { - # Argument checks - - - on.exit( .Call(R_igraph_finalizer) ) - # Function call - res <- .Call(R_igraph_delete_vertices_idx) - - - res -} - diff --git a/src/cpp11.cpp b/src/cpp11.cpp index 4044dae3232..4ddc397a6e7 100644 --- a/src/cpp11.cpp +++ b/src/cpp11.cpp @@ -128,7 +128,6 @@ extern SEXP R_igraph_degree_correlation_vector(void *, void *, void *, void *, v extern SEXP R_igraph_degree_sequence_game(void *, void *, void *); extern SEXP R_igraph_delete_edges(void *, void *); extern SEXP R_igraph_delete_vertices(void *, void *); -extern SEXP R_igraph_delete_vertices_idx(void); extern SEXP R_igraph_delete_vertices_map(void *, void *); extern SEXP R_igraph_density(void *, void *); extern SEXP R_igraph_deterministic_optimal_imitation(void *, void *, void *, void *, void *, void *); @@ -593,7 +592,6 @@ static const R_CallMethodDef CallEntries[] = { {"R_igraph_degree_sequence_game", (DL_FUNC) &R_igraph_degree_sequence_game, 3}, {"R_igraph_delete_edges", (DL_FUNC) &R_igraph_delete_edges, 2}, {"R_igraph_delete_vertices", (DL_FUNC) &R_igraph_delete_vertices, 2}, - {"R_igraph_delete_vertices_idx", (DL_FUNC) &R_igraph_delete_vertices_idx, 0}, {"R_igraph_delete_vertices_map", (DL_FUNC) &R_igraph_delete_vertices_map, 2}, {"R_igraph_density", (DL_FUNC) &R_igraph_density, 2}, {"R_igraph_deterministic_optimal_imitation", (DL_FUNC) &R_igraph_deterministic_optimal_imitation, 6}, diff --git a/src/rinterface.c b/src/rinterface.c index 38c98df1241..a1a8ef221e0 100644 --- a/src/rinterface.c +++ b/src/rinterface.c @@ -245,9 +245,14 @@ SEXP R_igraph_weighted_adjacency(SEXP adjmatrix, SEXP mode, SEXP loops) { /* Convert input */ R_SEXP_to_matrix(adjmatrix, &c_adjmatrix); c_mode = (igraph_adjacency_t) Rf_asInteger(mode); + if (0 != igraph_vector_init(&c_weights, 0)) { + igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); + } + IGRAPH_FINALLY(igraph_vector_destroy, &c_weights); + weights=R_GlobalEnv; /* hack to have a non-NULL value */ c_loops = (igraph_loops_t) Rf_asInteger(loops); /* Call igraph */ - IGRAPH_R_CHECK(igraph_weighted_adjacency(&c_graph, &c_adjmatrix, c_mode, c_weights, c_loops)); + IGRAPH_R_CHECK(igraph_weighted_adjacency(&c_graph, &c_adjmatrix, c_mode, (Rf_isNull(weights) ? 0 : &c_weights), c_loops)); /* Convert output */ PROTECT(r_result=NEW_LIST(2)); @@ -256,6 +261,9 @@ SEXP R_igraph_weighted_adjacency(SEXP adjmatrix, SEXP mode, SEXP loops) { PROTECT(graph=R_igraph_to_SEXP(&c_graph)); IGRAPH_I_DESTROY(&c_graph); IGRAPH_FINALLY_CLEAN(1); + PROTECT(weights=R_igraph_0orvector_to_SEXP(&c_weights)); + igraph_vector_destroy(&c_weights); + IGRAPH_FINALLY_CLEAN(1); SET_VECTOR_ELT(r_result, 0, graph); SET_VECTOR_ELT(r_result, 1, weights); SET_STRING_ELT(r_names, 0, Rf_mkChar("graph")); @@ -1652,6 +1660,10 @@ SEXP R_igraph_closeness(SEXP graph, SEXP vids, SEXP mode, SEXP weights, SEXP nor SEXP r_result, r_names; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); + if (0 != igraph_vector_init(&c_res, 0)) { + igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); + } + IGRAPH_FINALLY(igraph_vector_destroy, &c_res); if (0 != igraph_vector_int_init(&c_reachable_count, 0)) { igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); } @@ -1659,14 +1671,18 @@ SEXP R_igraph_closeness(SEXP graph, SEXP vids, SEXP mode, SEXP weights, SEXP nor igraph_vector_int_t c_vids_data; R_SEXP_to_igraph_vs(vids, &c_graph, &c_vids, &c_vids_data); c_mode = (igraph_neimode_t) Rf_asInteger(mode); + if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } IGRAPH_R_CHECK_BOOL(normalized); c_normalized = LOGICAL(normalized)[0]; /* Call igraph */ - IGRAPH_R_CHECK(igraph_closeness(&c_graph, c_res, &c_reachable_count, &c_all_reachable, c_vids, c_mode, c_weights, c_normalized)); + IGRAPH_R_CHECK(igraph_closeness(&c_graph, &c_res, &c_reachable_count, &c_all_reachable, c_vids, c_mode, (Rf_isNull(weights) ? 0 : &c_weights), c_normalized)); /* Convert output */ PROTECT(r_result=NEW_LIST(3)); PROTECT(r_names=NEW_CHARACTER(3)); + PROTECT(res=R_igraph_vector_to_SEXP(&c_res)); + igraph_vector_destroy(&c_res); + IGRAPH_FINALLY_CLEAN(1); PROTECT(reachable_count=R_igraph_vector_int_to_SEXP(&c_reachable_count)); igraph_vector_int_destroy(&c_reachable_count); IGRAPH_FINALLY_CLEAN(1); @@ -1708,6 +1724,10 @@ SEXP R_igraph_closeness_cutoff(SEXP graph, SEXP vids, SEXP mode, SEXP weights, S SEXP r_result, r_names; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); + if (0 != igraph_vector_init(&c_res, 0)) { + igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); + } + IGRAPH_FINALLY(igraph_vector_destroy, &c_res); if (0 != igraph_vector_int_init(&c_reachable_count, 0)) { igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); } @@ -1715,16 +1735,20 @@ SEXP R_igraph_closeness_cutoff(SEXP graph, SEXP vids, SEXP mode, SEXP weights, S igraph_vector_int_t c_vids_data; R_SEXP_to_igraph_vs(vids, &c_graph, &c_vids, &c_vids_data); c_mode = (igraph_neimode_t) Rf_asInteger(mode); + if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } IGRAPH_R_CHECK_BOOL(normalized); c_normalized = LOGICAL(normalized)[0]; IGRAPH_R_CHECK_REAL(cutoff); c_cutoff = REAL(cutoff)[0]; /* Call igraph */ - IGRAPH_R_CHECK(igraph_closeness_cutoff(&c_graph, c_res, &c_reachable_count, &c_all_reachable, c_vids, c_mode, c_weights, c_normalized, c_cutoff)); + IGRAPH_R_CHECK(igraph_closeness_cutoff(&c_graph, &c_res, &c_reachable_count, &c_all_reachable, c_vids, c_mode, (Rf_isNull(weights) ? 0 : &c_weights), c_normalized, c_cutoff)); /* Convert output */ PROTECT(r_result=NEW_LIST(3)); PROTECT(r_names=NEW_CHARACTER(3)); + PROTECT(res=R_igraph_vector_to_SEXP(&c_res)); + igraph_vector_destroy(&c_res); + IGRAPH_FINALLY_CLEAN(1); PROTECT(reachable_count=R_igraph_vector_int_to_SEXP(&c_reachable_count)); igraph_vector_int_destroy(&c_reachable_count); IGRAPH_FINALLY_CLEAN(1); @@ -1909,9 +1933,10 @@ SEXP R_igraph_get_shortest_path_bellman_ford(SEXP graph, SEXP from, SEXP to, SEX IGRAPH_FINALLY(igraph_vector_int_destroy, &c_edges); c_from = (igraph_integer_t) REAL(from)[0]; c_to = (igraph_integer_t) REAL(to)[0]; + if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } c_mode = (igraph_neimode_t) Rf_asInteger(mode); /* Call igraph */ - IGRAPH_R_CHECK(igraph_get_shortest_path_bellman_ford(&c_graph, &c_vertices, &c_edges, c_from, c_to, (Rf_isNull(weights) ? 0 : c_weights), c_mode)); + IGRAPH_R_CHECK(igraph_get_shortest_path_bellman_ford(&c_graph, &c_vertices, &c_edges, c_from, c_to, (Rf_isNull(weights) ? 0 : (Rf_isNull(weights) ? 0 : &c_weights)), c_mode)); /* Convert output */ PROTECT(r_result=NEW_LIST(2)); @@ -1961,9 +1986,10 @@ SEXP R_igraph_get_shortest_path_dijkstra(SEXP graph, SEXP from, SEXP to, SEXP we IGRAPH_FINALLY(igraph_vector_int_destroy, &c_edges); c_from = (igraph_integer_t) REAL(from)[0]; c_to = (igraph_integer_t) REAL(to)[0]; + if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } c_mode = (igraph_neimode_t) Rf_asInteger(mode); /* Call igraph */ - IGRAPH_R_CHECK(igraph_get_shortest_path_dijkstra(&c_graph, &c_vertices, &c_edges, c_from, c_to, (Rf_isNull(weights) ? 0 : c_weights), c_mode)); + IGRAPH_R_CHECK(igraph_get_shortest_path_dijkstra(&c_graph, &c_vertices, &c_edges, c_from, c_to, (Rf_isNull(weights) ? 0 : (Rf_isNull(weights) ? 0 : &c_weights)), c_mode)); /* Convert output */ PROTECT(r_result=NEW_LIST(2)); @@ -2004,6 +2030,14 @@ SEXP R_igraph_get_all_shortest_paths(SEXP graph, SEXP from, SEXP to, SEXP mode) SEXP r_result, r_names; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); + if (0 != igraph_vector_int_list_init(&c_vertices, 0)) { + igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); + } + IGRAPH_FINALLY(igraph_vector_int_list_destroy, &c_vertices); + if (0 != igraph_vector_int_list_init(&c_edges, 0)) { + igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); + } + IGRAPH_FINALLY(igraph_vector_int_list_destroy, &c_edges); if (0 != igraph_vector_int_init(&c_nrgeo, 0)) { igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); } @@ -2013,11 +2047,17 @@ SEXP R_igraph_get_all_shortest_paths(SEXP graph, SEXP from, SEXP to, SEXP mode) R_SEXP_to_igraph_vs(to, &c_graph, &c_to, &c_to_data); c_mode = (igraph_neimode_t) Rf_asInteger(mode); /* Call igraph */ - IGRAPH_R_CHECK(igraph_get_all_shortest_paths(&c_graph, c_vertices, c_edges, &c_nrgeo, c_from, c_to, c_mode)); + IGRAPH_R_CHECK(igraph_get_all_shortest_paths(&c_graph, &c_vertices, &c_edges, &c_nrgeo, c_from, c_to, c_mode)); /* Convert output */ PROTECT(r_result=NEW_LIST(3)); PROTECT(r_names=NEW_CHARACTER(3)); + PROTECT(vertices=R_igraph_vector_int_list_to_SEXPp1(&c_vertices)); + igraph_vector_int_list_destroy(&c_vertices); + IGRAPH_FINALLY_CLEAN(1); + PROTECT(edges=R_igraph_vector_int_list_to_SEXPp1(&c_edges)); + igraph_vector_int_list_destroy(&c_edges); + IGRAPH_FINALLY_CLEAN(1); PROTECT(nrgeo=R_igraph_vector_int_to_SEXP(&c_nrgeo)); igraph_vector_int_destroy(&c_nrgeo); IGRAPH_FINALLY_CLEAN(1); @@ -2060,9 +2100,10 @@ SEXP R_igraph_distances_dijkstra(SEXP graph, SEXP from, SEXP to, SEXP weights, S R_SEXP_to_igraph_vs(from, &c_graph, &c_from, &c_from_data); igraph_vector_int_t c_to_data; R_SEXP_to_igraph_vs(to, &c_graph, &c_to, &c_to_data); + if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } c_mode = (igraph_neimode_t) Rf_asInteger(mode); /* Call igraph */ - IGRAPH_R_CHECK(igraph_distances_dijkstra(&c_graph, &c_res, c_from, c_to, c_weights, c_mode)); + IGRAPH_R_CHECK(igraph_distances_dijkstra(&c_graph, &c_res, c_from, c_to, (Rf_isNull(weights) ? 0 : &c_weights), c_mode)); /* Convert output */ PROTECT(res=R_igraph_matrix_to_SEXP(&c_res)); @@ -2103,11 +2144,12 @@ SEXP R_igraph_distances_dijkstra_cutoff(SEXP graph, SEXP from, SEXP to, SEXP wei R_SEXP_to_igraph_vs(from, &c_graph, &c_from, &c_from_data); igraph_vector_int_t c_to_data; R_SEXP_to_igraph_vs(to, &c_graph, &c_to, &c_to_data); + if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } c_mode = (igraph_neimode_t) Rf_asInteger(mode); IGRAPH_R_CHECK_REAL(cutoff); c_cutoff = REAL(cutoff)[0]; /* Call igraph */ - IGRAPH_R_CHECK(igraph_distances_dijkstra_cutoff(&c_graph, &c_res, c_from, c_to, c_weights, c_mode, c_cutoff)); + IGRAPH_R_CHECK(igraph_distances_dijkstra_cutoff(&c_graph, &c_res, c_from, c_to, (Rf_isNull(weights) ? 0 : &c_weights), c_mode, c_cutoff)); /* Convert output */ PROTECT(res=R_igraph_matrix_to_SEXP(&c_res)); @@ -2143,6 +2185,14 @@ SEXP R_igraph_get_all_shortest_paths_dijkstra(SEXP graph, SEXP from, SEXP to, SE SEXP r_result, r_names; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); + if (0 != igraph_vector_int_list_init(&c_vertices, 0)) { + igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); + } + IGRAPH_FINALLY(igraph_vector_int_list_destroy, &c_vertices); + if (0 != igraph_vector_int_list_init(&c_edges, 0)) { + igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); + } + IGRAPH_FINALLY(igraph_vector_int_list_destroy, &c_edges); if (0 != igraph_vector_int_init(&c_nrgeo, 0)) { igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); } @@ -2150,13 +2200,20 @@ SEXP R_igraph_get_all_shortest_paths_dijkstra(SEXP graph, SEXP from, SEXP to, SE c_from = (igraph_integer_t) REAL(from)[0]; igraph_vector_int_t c_to_data; R_SEXP_to_igraph_vs(to, &c_graph, &c_to, &c_to_data); + if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } c_mode = (igraph_neimode_t) Rf_asInteger(mode); /* Call igraph */ - IGRAPH_R_CHECK(igraph_get_all_shortest_paths_dijkstra(&c_graph, c_vertices, c_edges, &c_nrgeo, c_from, c_to, c_weights, c_mode)); + IGRAPH_R_CHECK(igraph_get_all_shortest_paths_dijkstra(&c_graph, &c_vertices, &c_edges, &c_nrgeo, c_from, c_to, (Rf_isNull(weights) ? 0 : &c_weights), c_mode)); /* Convert output */ PROTECT(r_result=NEW_LIST(3)); PROTECT(r_names=NEW_CHARACTER(3)); + PROTECT(vertices=R_igraph_vector_int_list_to_SEXPp1(&c_vertices)); + igraph_vector_int_list_destroy(&c_vertices); + IGRAPH_FINALLY_CLEAN(1); + PROTECT(edges=R_igraph_vector_int_list_to_SEXPp1(&c_edges)); + igraph_vector_int_list_destroy(&c_edges); + IGRAPH_FINALLY_CLEAN(1); PROTECT(nrgeo=R_igraph_vector_int_to_SEXP(&c_nrgeo)); igraph_vector_int_destroy(&c_nrgeo); IGRAPH_FINALLY_CLEAN(1); @@ -2199,9 +2256,10 @@ SEXP R_igraph_distances_bellman_ford(SEXP graph, SEXP from, SEXP to, SEXP weight R_SEXP_to_igraph_vs(from, &c_graph, &c_from, &c_from_data); igraph_vector_int_t c_to_data; R_SEXP_to_igraph_vs(to, &c_graph, &c_to, &c_to_data); + if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } c_mode = (igraph_neimode_t) Rf_asInteger(mode); /* Call igraph */ - IGRAPH_R_CHECK(igraph_distances_bellman_ford(&c_graph, &c_res, c_from, c_to, c_weights, c_mode)); + IGRAPH_R_CHECK(igraph_distances_bellman_ford(&c_graph, &c_res, c_from, c_to, (Rf_isNull(weights) ? 0 : &c_weights), c_mode)); /* Convert output */ PROTECT(res=R_igraph_matrix_to_SEXP(&c_res)); @@ -2241,9 +2299,10 @@ SEXP R_igraph_distances_johnson(SEXP graph, SEXP from, SEXP to, SEXP weights, SE R_SEXP_to_igraph_vs(from, &c_graph, &c_from, &c_from_data); igraph_vector_int_t c_to_data; R_SEXP_to_igraph_vs(to, &c_graph, &c_to, &c_to_data); + if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } c_mode = (igraph_neimode_t) Rf_asInteger(mode); /* Call igraph */ - IGRAPH_R_CHECK(igraph_distances_johnson(&c_graph, &c_res, c_from, c_to, c_weights, c_mode)); + IGRAPH_R_CHECK(igraph_distances_johnson(&c_graph, &c_res, c_from, c_to, (Rf_isNull(weights) ? 0 : &c_weights), c_mode)); /* Convert output */ PROTECT(res=R_igraph_matrix_to_SEXP(&c_res)); @@ -2284,10 +2343,11 @@ SEXP R_igraph_distances_floyd_warshall(SEXP graph, SEXP from, SEXP to, SEXP weig R_SEXP_to_igraph_vs(from, &c_graph, &c_from, &c_from_data); igraph_vector_int_t c_to_data; R_SEXP_to_igraph_vs(to, &c_graph, &c_to, &c_to_data); + if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } c_mode = (igraph_neimode_t) Rf_asInteger(mode); c_method = (igraph_floyd_warshall_algorithm_t) Rf_asInteger(method); /* Call igraph */ - IGRAPH_R_CHECK(igraph_distances_floyd_warshall(&c_graph, &c_res, c_from, c_to, c_weights, c_mode, c_method)); + IGRAPH_R_CHECK(igraph_distances_floyd_warshall(&c_graph, &c_res, c_from, c_to, (Rf_isNull(weights) ? 0 : &c_weights), c_mode, c_method)); /* Convert output */ PROTECT(res=R_igraph_matrix_to_SEXP(&c_res)); @@ -2331,10 +2391,11 @@ SEXP R_igraph_voronoi(SEXP graph, SEXP generators, SEXP weights, SEXP mode, SEXP IGRAPH_FINALLY(igraph_vector_destroy, &c_distances); R_SEXP_to_vector_int_copy(generators, &c_generators); IGRAPH_FINALLY(igraph_vector_int_destroy, &c_generators); + if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } c_mode = (igraph_neimode_t) Rf_asInteger(mode); c_tiebreaker = (igraph_voronoi_tiebreaker_t) Rf_asInteger(tiebreaker); /* Call igraph */ - IGRAPH_R_CHECK(igraph_voronoi(&c_graph, &c_membership, &c_distances, &c_generators, c_weights, c_mode, c_tiebreaker)); + IGRAPH_R_CHECK(igraph_voronoi(&c_graph, &c_membership, &c_distances, &c_generators, (Rf_isNull(weights) ? 0 : &c_weights), c_mode, c_tiebreaker)); /* Convert output */ PROTECT(r_result=NEW_LIST(2)); @@ -2418,17 +2479,32 @@ SEXP R_igraph_get_k_shortest_paths(SEXP graph, SEXP weights, SEXP k, SEXP from, SEXP r_result, r_names; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); + if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } + if (0 != igraph_vector_int_list_init(&c_vertex_paths, 0)) { + igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); + } + IGRAPH_FINALLY(igraph_vector_int_list_destroy, &c_vertex_paths); + if (0 != igraph_vector_int_list_init(&c_edge_paths, 0)) { + igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); + } + IGRAPH_FINALLY(igraph_vector_int_list_destroy, &c_edge_paths); IGRAPH_R_CHECK_INT(k); c_k = (igraph_integer_t) REAL(k)[0]; c_from = (igraph_integer_t) REAL(from)[0]; c_to = (igraph_integer_t) REAL(to)[0]; c_mode = (igraph_neimode_t) Rf_asInteger(mode); /* Call igraph */ - IGRAPH_R_CHECK(igraph_get_k_shortest_paths(&c_graph, (Rf_isNull(weights) ? 0 : c_weights), c_vertex_paths, c_edge_paths, c_k, c_from, c_to, c_mode)); + IGRAPH_R_CHECK(igraph_get_k_shortest_paths(&c_graph, (Rf_isNull(weights) ? 0 : (Rf_isNull(weights) ? 0 : &c_weights)), &c_vertex_paths, &c_edge_paths, c_k, c_from, c_to, c_mode)); /* Convert output */ PROTECT(r_result=NEW_LIST(2)); PROTECT(r_names=NEW_CHARACTER(2)); + PROTECT(vertex_paths=R_igraph_vector_int_list_to_SEXPp1(&c_vertex_paths)); + igraph_vector_int_list_destroy(&c_vertex_paths); + IGRAPH_FINALLY_CLEAN(1); + PROTECT(edge_paths=R_igraph_vector_int_list_to_SEXPp1(&c_edge_paths)); + igraph_vector_int_list_destroy(&c_edge_paths); + IGRAPH_FINALLY_CLEAN(1); SET_VECTOR_ELT(r_result, 0, vertex_paths); SET_VECTOR_ELT(r_result, 1, edge_paths); SET_STRING_ELT(r_names, 0, Rf_mkChar("vpaths")); @@ -2468,9 +2544,10 @@ SEXP R_igraph_get_widest_path(SEXP graph, SEXP from, SEXP to, SEXP weights, SEXP IGRAPH_FINALLY(igraph_vector_int_destroy, &c_edges); c_from = (igraph_integer_t) REAL(from)[0]; c_to = (igraph_integer_t) REAL(to)[0]; + if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } c_mode = (igraph_neimode_t) Rf_asInteger(mode); /* Call igraph */ - IGRAPH_R_CHECK(igraph_get_widest_path(&c_graph, &c_vertices, &c_edges, c_from, c_to, c_weights, c_mode)); + IGRAPH_R_CHECK(igraph_get_widest_path(&c_graph, &c_vertices, &c_edges, c_from, c_to, (Rf_isNull(weights) ? 0 : &c_weights), c_mode)); /* Convert output */ PROTECT(r_result=NEW_LIST(2)); @@ -2514,9 +2591,18 @@ SEXP R_igraph_get_widest_paths(SEXP graph, SEXP from, SEXP to, SEXP weights, SEX SEXP r_result, r_names; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); + if (0 != igraph_vector_int_list_init(&c_vertices, 0)) { + igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); + } + IGRAPH_FINALLY(igraph_vector_int_list_destroy, &c_vertices); + if (0 != igraph_vector_int_list_init(&c_edges, 0)) { + igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); + } + IGRAPH_FINALLY(igraph_vector_int_list_destroy, &c_edges); c_from = (igraph_integer_t) REAL(from)[0]; igraph_vector_int_t c_to_data; R_SEXP_to_igraph_vs(to, &c_graph, &c_to, &c_to_data); + if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } c_mode = (igraph_neimode_t) Rf_asInteger(mode); if (0 != igraph_vector_int_init(&c_parents, 0)) { igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); @@ -2527,11 +2613,17 @@ SEXP R_igraph_get_widest_paths(SEXP graph, SEXP from, SEXP to, SEXP weights, SEX } IGRAPH_FINALLY(igraph_vector_int_destroy, &c_inbound_edges); /* Call igraph */ - IGRAPH_R_CHECK(igraph_get_widest_paths(&c_graph, c_vertices, c_edges, c_from, c_to, c_weights, c_mode, &c_parents, &c_inbound_edges)); + IGRAPH_R_CHECK(igraph_get_widest_paths(&c_graph, &c_vertices, &c_edges, c_from, c_to, (Rf_isNull(weights) ? 0 : &c_weights), c_mode, &c_parents, &c_inbound_edges)); /* Convert output */ PROTECT(r_result=NEW_LIST(4)); PROTECT(r_names=NEW_CHARACTER(4)); + PROTECT(vertices=R_igraph_vector_int_list_to_SEXPp1(&c_vertices)); + igraph_vector_int_list_destroy(&c_vertices); + IGRAPH_FINALLY_CLEAN(1); + PROTECT(edges=R_igraph_vector_int_list_to_SEXPp1(&c_edges)); + igraph_vector_int_list_destroy(&c_edges); + IGRAPH_FINALLY_CLEAN(1); igraph_vector_int_destroy(&c_to_data); igraph_vs_destroy(&c_to); PROTECT(parents=R_igraph_vector_int_to_SEXP(&c_parents)); @@ -2579,9 +2671,10 @@ SEXP R_igraph_widest_path_widths_dijkstra(SEXP graph, SEXP from, SEXP to, SEXP w R_SEXP_to_igraph_vs(from, &c_graph, &c_from, &c_from_data); igraph_vector_int_t c_to_data; R_SEXP_to_igraph_vs(to, &c_graph, &c_to, &c_to_data); + if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } c_mode = (igraph_neimode_t) Rf_asInteger(mode); /* Call igraph */ - IGRAPH_R_CHECK(igraph_widest_path_widths_dijkstra(&c_graph, &c_res, c_from, c_to, c_weights, c_mode)); + IGRAPH_R_CHECK(igraph_widest_path_widths_dijkstra(&c_graph, &c_res, c_from, c_to, (Rf_isNull(weights) ? 0 : &c_weights), c_mode)); /* Convert output */ PROTECT(res=R_igraph_matrix_to_SEXP(&c_res)); @@ -2621,9 +2714,10 @@ SEXP R_igraph_widest_path_widths_floyd_warshall(SEXP graph, SEXP from, SEXP to, R_SEXP_to_igraph_vs(from, &c_graph, &c_from, &c_from_data); igraph_vector_int_t c_to_data; R_SEXP_to_igraph_vs(to, &c_graph, &c_to, &c_to_data); + if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } c_mode = (igraph_neimode_t) Rf_asInteger(mode); /* Call igraph */ - IGRAPH_R_CHECK(igraph_widest_path_widths_floyd_warshall(&c_graph, &c_res, c_from, c_to, c_weights, c_mode)); + IGRAPH_R_CHECK(igraph_widest_path_widths_floyd_warshall(&c_graph, &c_res, c_from, c_to, (Rf_isNull(weights) ? 0 : &c_weights), c_mode)); /* Convert output */ PROTECT(res=R_igraph_matrix_to_SEXP(&c_res)); @@ -2659,8 +2753,9 @@ SEXP R_igraph_spanner(SEXP graph, SEXP stretch, SEXP weights) { IGRAPH_FINALLY(igraph_vector_int_destroy, &c_spanner); IGRAPH_R_CHECK_REAL(stretch); c_stretch = REAL(stretch)[0]; + if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } /* Call igraph */ - IGRAPH_R_CHECK(igraph_spanner(&c_graph, &c_spanner, c_stretch, (Rf_isNull(weights) ? 0 : c_weights))); + IGRAPH_R_CHECK(igraph_spanner(&c_graph, &c_spanner, c_stretch, (Rf_isNull(weights) ? 0 : (Rf_isNull(weights) ? 0 : &c_weights)))); /* Convert output */ PROTECT(spanner=R_igraph_vector_int_to_SEXPp1(&c_spanner)); @@ -2688,16 +2783,24 @@ SEXP R_igraph_betweenness_cutoff(SEXP graph, SEXP vids, SEXP directed, SEXP weig SEXP r_result; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); + if (0 != igraph_vector_init(&c_res, 0)) { + igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); + } + IGRAPH_FINALLY(igraph_vector_destroy, &c_res); igraph_vector_int_t c_vids_data; R_SEXP_to_igraph_vs(vids, &c_graph, &c_vids, &c_vids_data); IGRAPH_R_CHECK_BOOL(directed); c_directed = LOGICAL(directed)[0]; + if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } IGRAPH_R_CHECK_REAL(cutoff); c_cutoff = REAL(cutoff)[0]; /* Call igraph */ - IGRAPH_R_CHECK(igraph_betweenness_cutoff(&c_graph, c_res, c_vids, c_directed, c_weights, c_cutoff)); + IGRAPH_R_CHECK(igraph_betweenness_cutoff(&c_graph, &c_res, c_vids, c_directed, (Rf_isNull(weights) ? 0 : &c_weights), c_cutoff)); /* Convert output */ + PROTECT(res=R_igraph_vector_to_SEXP(&c_res)); + igraph_vector_destroy(&c_res); + IGRAPH_FINALLY_CLEAN(1); igraph_vector_int_destroy(&c_vids_data); igraph_vs_destroy(&c_vids); r_result = res; @@ -2723,6 +2826,10 @@ SEXP R_igraph_betweenness_subset(SEXP graph, SEXP vids, SEXP directed, SEXP sour SEXP r_result; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); + if (0 != igraph_vector_init(&c_res, 0)) { + igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); + } + IGRAPH_FINALLY(igraph_vector_destroy, &c_res); igraph_vector_int_t c_vids_data; R_SEXP_to_igraph_vs(vids, &c_graph, &c_vids, &c_vids_data); IGRAPH_R_CHECK_BOOL(directed); @@ -2731,10 +2838,14 @@ SEXP R_igraph_betweenness_subset(SEXP graph, SEXP vids, SEXP directed, SEXP sour R_SEXP_to_igraph_vs(sources, &c_graph, &c_sources, &c_sources_data); igraph_vector_int_t c_targets_data; R_SEXP_to_igraph_vs(targets, &c_graph, &c_targets, &c_targets_data); + if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } /* Call igraph */ - IGRAPH_R_CHECK(igraph_betweenness_subset(&c_graph, c_res, c_vids, c_directed, c_sources, c_targets, c_weights)); + IGRAPH_R_CHECK(igraph_betweenness_subset(&c_graph, &c_res, c_vids, c_directed, c_sources, c_targets, (Rf_isNull(weights) ? 0 : &c_weights))); /* Convert output */ + PROTECT(res=R_igraph_vector_to_SEXP(&c_res)); + igraph_vector_destroy(&c_res); + IGRAPH_FINALLY_CLEAN(1); igraph_vector_int_destroy(&c_vids_data); igraph_vs_destroy(&c_vids); igraph_vector_int_destroy(&c_sources_data); @@ -2767,8 +2878,9 @@ SEXP R_igraph_edge_betweenness(SEXP graph, SEXP directed, SEXP weights) { IGRAPH_FINALLY(igraph_vector_destroy, &c_res); IGRAPH_R_CHECK_BOOL(directed); c_directed = LOGICAL(directed)[0]; + if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } /* Call igraph */ - IGRAPH_R_CHECK(igraph_edge_betweenness(&c_graph, &c_res, c_directed, c_weights)); + IGRAPH_R_CHECK(igraph_edge_betweenness(&c_graph, &c_res, c_directed, (Rf_isNull(weights) ? 0 : &c_weights))); /* Convert output */ PROTECT(res=R_igraph_vector_to_SEXP(&c_res)); @@ -2801,10 +2913,11 @@ SEXP R_igraph_edge_betweenness_cutoff(SEXP graph, SEXP directed, SEXP weights, S IGRAPH_FINALLY(igraph_vector_destroy, &c_res); IGRAPH_R_CHECK_BOOL(directed); c_directed = LOGICAL(directed)[0]; + if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } IGRAPH_R_CHECK_REAL(cutoff); c_cutoff = REAL(cutoff)[0]; /* Call igraph */ - IGRAPH_R_CHECK(igraph_edge_betweenness_cutoff(&c_graph, &c_res, c_directed, c_weights, c_cutoff)); + IGRAPH_R_CHECK(igraph_edge_betweenness_cutoff(&c_graph, &c_res, c_directed, (Rf_isNull(weights) ? 0 : &c_weights), c_cutoff)); /* Convert output */ PROTECT(res=R_igraph_vector_to_SEXP(&c_res)); @@ -2833,6 +2946,10 @@ SEXP R_igraph_edge_betweenness_subset(SEXP graph, SEXP eids, SEXP directed, SEXP SEXP r_result; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); + if (0 != igraph_vector_init(&c_res, 0)) { + igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); + } + IGRAPH_FINALLY(igraph_vector_destroy, &c_res); igraph_vector_int_t c_eids_data; R_SEXP_to_igraph_es(eids, &c_graph, &c_eids, &c_eids_data); IGRAPH_R_CHECK_BOOL(directed); @@ -2841,10 +2958,14 @@ SEXP R_igraph_edge_betweenness_subset(SEXP graph, SEXP eids, SEXP directed, SEXP R_SEXP_to_igraph_vs(sources, &c_graph, &c_sources, &c_sources_data); igraph_vector_int_t c_targets_data; R_SEXP_to_igraph_vs(targets, &c_graph, &c_targets, &c_targets_data); + if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } /* Call igraph */ - IGRAPH_R_CHECK(igraph_edge_betweenness_subset(&c_graph, c_res, c_eids, c_directed, c_sources, c_targets, c_weights)); + IGRAPH_R_CHECK(igraph_edge_betweenness_subset(&c_graph, &c_res, c_eids, c_directed, c_sources, c_targets, (Rf_isNull(weights) ? 0 : &c_weights))); /* Convert output */ + PROTECT(res=R_igraph_vector_to_SEXP(&c_res)); + igraph_vector_destroy(&c_res); + IGRAPH_FINALLY_CLEAN(1); igraph_vector_int_destroy(&c_eids_data); igraph_es_destroy(&c_eids); igraph_vector_int_destroy(&c_sources_data); @@ -2874,17 +2995,25 @@ SEXP R_igraph_harmonic_centrality_cutoff(SEXP graph, SEXP vids, SEXP mode, SEXP SEXP r_result; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); + if (0 != igraph_vector_init(&c_res, 0)) { + igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); + } + IGRAPH_FINALLY(igraph_vector_destroy, &c_res); igraph_vector_int_t c_vids_data; R_SEXP_to_igraph_vs(vids, &c_graph, &c_vids, &c_vids_data); c_mode = (igraph_neimode_t) Rf_asInteger(mode); + if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } IGRAPH_R_CHECK_BOOL(normalized); c_normalized = LOGICAL(normalized)[0]; IGRAPH_R_CHECK_REAL(cutoff); c_cutoff = REAL(cutoff)[0]; /* Call igraph */ - IGRAPH_R_CHECK(igraph_harmonic_centrality_cutoff(&c_graph, c_res, c_vids, c_mode, c_weights, c_normalized, c_cutoff)); + IGRAPH_R_CHECK(igraph_harmonic_centrality_cutoff(&c_graph, &c_res, c_vids, c_mode, (Rf_isNull(weights) ? 0 : &c_weights), c_normalized, c_cutoff)); /* Convert output */ + PROTECT(res=R_igraph_vector_to_SEXP(&c_res)); + igraph_vector_destroy(&c_res); + IGRAPH_FINALLY_CLEAN(1); igraph_vector_int_destroy(&c_vids_data); igraph_vs_destroy(&c_vids); r_result = res; @@ -2916,6 +3045,10 @@ SEXP R_igraph_personalized_pagerank(SEXP graph, SEXP algo, SEXP vids, SEXP direc /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); c_algo = (igraph_pagerank_algo_t) Rf_asInteger(algo); + if (0 != igraph_vector_init(&c_vector, 0)) { + igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); + } + IGRAPH_FINALLY(igraph_vector_destroy, &c_vector); igraph_vector_int_t c_vids_data; R_SEXP_to_igraph_vs(vids, &c_graph, &c_vids, &c_vids_data); IGRAPH_R_CHECK_BOOL(directed); @@ -2925,6 +3058,7 @@ SEXP R_igraph_personalized_pagerank(SEXP graph, SEXP algo, SEXP vids, SEXP direc if (!Rf_isNull(personalized)) { R_SEXP_to_vector(personalized, &c_personalized); } + if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } if (c_algo == IGRAPH_PAGERANK_ALGO_ARPACK) { R_SEXP_to_igraph_arpack_options(options, &c_options1); c_options = &c_options1; @@ -2932,11 +3066,14 @@ SEXP R_igraph_personalized_pagerank(SEXP graph, SEXP algo, SEXP vids, SEXP direc c_options = 0; } /* Call igraph */ - IGRAPH_R_CHECK(igraph_personalized_pagerank(&c_graph, c_algo, c_vector, &c_value, c_vids, c_directed, c_damping, (Rf_isNull(personalized) ? 0 : &c_personalized), (Rf_isNull(weights) ? 0 : c_weights), c_options)); + IGRAPH_R_CHECK(igraph_personalized_pagerank(&c_graph, c_algo, &c_vector, &c_value, c_vids, c_directed, c_damping, (Rf_isNull(personalized) ? 0 : &c_personalized), (Rf_isNull(weights) ? 0 : (Rf_isNull(weights) ? 0 : &c_weights)), c_options)); /* Convert output */ PROTECT(r_result=NEW_LIST(3)); PROTECT(r_names=NEW_CHARACTER(3)); + PROTECT(vector=R_igraph_vector_to_SEXP(&c_vector)); + igraph_vector_destroy(&c_vector); + IGRAPH_FINALLY_CLEAN(1); PROTECT(value=NEW_NUMERIC(1)); REAL(value)[0]=c_value; igraph_vector_int_destroy(&c_vids_data); @@ -2982,6 +3119,10 @@ SEXP R_igraph_personalized_pagerank_vs(SEXP graph, SEXP algo, SEXP vids, SEXP di /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); c_algo = (igraph_pagerank_algo_t) Rf_asInteger(algo); + if (0 != igraph_vector_init(&c_vector, 0)) { + igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); + } + IGRAPH_FINALLY(igraph_vector_destroy, &c_vector); igraph_vector_int_t c_vids_data; R_SEXP_to_igraph_vs(vids, &c_graph, &c_vids, &c_vids_data); IGRAPH_R_CHECK_BOOL(directed); @@ -2990,6 +3131,7 @@ SEXP R_igraph_personalized_pagerank_vs(SEXP graph, SEXP algo, SEXP vids, SEXP di c_damping = REAL(damping)[0]; igraph_vector_int_t c_reset_vids_data; R_SEXP_to_igraph_vs(reset_vids, &c_graph, &c_reset_vids, &c_reset_vids_data); + if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } if (c_algo == IGRAPH_PAGERANK_ALGO_ARPACK) { R_SEXP_to_igraph_arpack_options(options, &c_options1); c_options = &c_options1; @@ -2997,11 +3139,14 @@ SEXP R_igraph_personalized_pagerank_vs(SEXP graph, SEXP algo, SEXP vids, SEXP di c_options = 0; } /* Call igraph */ - IGRAPH_R_CHECK(igraph_personalized_pagerank_vs(&c_graph, c_algo, c_vector, &c_value, c_vids, c_directed, c_damping, c_reset_vids, (Rf_isNull(weights) ? 0 : c_weights), c_options)); + IGRAPH_R_CHECK(igraph_personalized_pagerank_vs(&c_graph, c_algo, &c_vector, &c_value, c_vids, c_directed, c_damping, c_reset_vids, (Rf_isNull(weights) ? 0 : (Rf_isNull(weights) ? 0 : &c_weights)), c_options)); /* Convert output */ PROTECT(r_result=NEW_LIST(3)); PROTECT(r_names=NEW_CHARACTER(3)); + PROTECT(vector=R_igraph_vector_to_SEXP(&c_vector)); + igraph_vector_destroy(&c_vector); + IGRAPH_FINALLY_CLEAN(1); PROTECT(value=NEW_NUMERIC(1)); REAL(value)[0]=c_value; igraph_vector_int_destroy(&c_vids_data); @@ -3139,12 +3284,13 @@ SEXP R_igraph_average_path_length_dijkstra(SEXP graph, SEXP weights, SEXP direct SEXP r_result, r_names; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); + if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } IGRAPH_R_CHECK_BOOL(directed); c_directed = LOGICAL(directed)[0]; IGRAPH_R_CHECK_BOOL(unconn); c_unconn = LOGICAL(unconn)[0]; /* Call igraph */ - IGRAPH_R_CHECK(igraph_average_path_length_dijkstra(&c_graph, &c_res, &c_unconn_pairs, c_weights, c_directed, c_unconn)); + IGRAPH_R_CHECK(igraph_average_path_length_dijkstra(&c_graph, &c_res, &c_unconn_pairs, (Rf_isNull(weights) ? 0 : &c_weights), c_directed, c_unconn)); /* Convert output */ PROTECT(r_result=NEW_LIST(2)); @@ -3332,9 +3478,10 @@ SEXP R_igraph_feedback_arc_set(SEXP graph, SEXP weights, SEXP algo) { igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_vector_int_destroy, &c_result); + if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } c_algo = (igraph_fas_algorithm_t) Rf_asInteger(algo); /* Call igraph */ - IGRAPH_R_CHECK(igraph_feedback_arc_set(&c_graph, &c_result, c_weights, c_algo)); + IGRAPH_R_CHECK(igraph_feedback_arc_set(&c_graph, &c_result, (Rf_isNull(weights) ? 0 : &c_weights), c_algo)); /* Convert output */ PROTECT(result=R_igraph_vector_int_to_SEXPp1(&c_result)); @@ -3610,18 +3757,28 @@ SEXP R_igraph_eigenvector_centrality(SEXP graph, SEXP directed, SEXP scale, SEXP SEXP r_result, r_names; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); + if (0 != igraph_vector_init(&c_vector, 0)) { + igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); + } + IGRAPH_FINALLY(igraph_vector_destroy, &c_vector); IGRAPH_R_CHECK_BOOL(directed); c_directed = LOGICAL(directed)[0]; IGRAPH_R_CHECK_BOOL(scale); c_scale = LOGICAL(scale)[0]; + if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } + R_SEXP_to_igraph_arpack_options(options, &c_options); /* Call igraph */ - IGRAPH_R_CHECK(igraph_eigenvector_centrality(&c_graph, c_vector, &c_value, c_directed, c_scale, c_weights, c_options)); + IGRAPH_R_CHECK(igraph_eigenvector_centrality(&c_graph, &c_vector, &c_value, c_directed, c_scale, (Rf_isNull(weights) ? 0 : &c_weights), &c_options)); /* Convert output */ PROTECT(r_result=NEW_LIST(3)); PROTECT(r_names=NEW_CHARACTER(3)); + PROTECT(vector=R_igraph_vector_to_SEXP(&c_vector)); + igraph_vector_destroy(&c_vector); + IGRAPH_FINALLY_CLEAN(1); PROTECT(value=NEW_NUMERIC(1)); REAL(value)[0]=c_value; + PROTECT(options=R_igraph_arpack_options_to_SEXP(&c_options)); SET_VECTOR_ELT(r_result, 0, vector); SET_VECTOR_ELT(r_result, 1, value); SET_VECTOR_ELT(r_result, 2, options); @@ -3652,16 +3809,26 @@ SEXP R_igraph_hub_score(SEXP graph, SEXP scale, SEXP weights, SEXP options) { SEXP r_result, r_names; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); + if (0 != igraph_vector_init(&c_vector, 0)) { + igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); + } + IGRAPH_FINALLY(igraph_vector_destroy, &c_vector); IGRAPH_R_CHECK_BOOL(scale); c_scale = LOGICAL(scale)[0]; + if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } + R_SEXP_to_igraph_arpack_options(options, &c_options); /* Call igraph */ - IGRAPH_R_CHECK(igraph_hub_score(&c_graph, c_vector, &c_value, c_scale, c_weights, c_options)); + IGRAPH_R_CHECK(igraph_hub_score(&c_graph, &c_vector, &c_value, c_scale, (Rf_isNull(weights) ? 0 : &c_weights), &c_options)); /* Convert output */ PROTECT(r_result=NEW_LIST(3)); PROTECT(r_names=NEW_CHARACTER(3)); + PROTECT(vector=R_igraph_vector_to_SEXP(&c_vector)); + igraph_vector_destroy(&c_vector); + IGRAPH_FINALLY_CLEAN(1); PROTECT(value=NEW_NUMERIC(1)); REAL(value)[0]=c_value; + PROTECT(options=R_igraph_arpack_options_to_SEXP(&c_options)); SET_VECTOR_ELT(r_result, 0, vector); SET_VECTOR_ELT(r_result, 1, value); SET_VECTOR_ELT(r_result, 2, options); @@ -3692,16 +3859,26 @@ SEXP R_igraph_authority_score(SEXP graph, SEXP scale, SEXP weights, SEXP options SEXP r_result, r_names; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); + if (0 != igraph_vector_init(&c_vector, 0)) { + igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); + } + IGRAPH_FINALLY(igraph_vector_destroy, &c_vector); IGRAPH_R_CHECK_BOOL(scale); c_scale = LOGICAL(scale)[0]; + if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } + R_SEXP_to_igraph_arpack_options(options, &c_options); /* Call igraph */ - IGRAPH_R_CHECK(igraph_authority_score(&c_graph, c_vector, &c_value, c_scale, c_weights, c_options)); + IGRAPH_R_CHECK(igraph_authority_score(&c_graph, &c_vector, &c_value, c_scale, (Rf_isNull(weights) ? 0 : &c_weights), &c_options)); /* Convert output */ PROTECT(r_result=NEW_LIST(3)); PROTECT(r_names=NEW_CHARACTER(3)); + PROTECT(vector=R_igraph_vector_to_SEXP(&c_vector)); + igraph_vector_destroy(&c_vector); + IGRAPH_FINALLY_CLEAN(1); PROTECT(value=NEW_NUMERIC(1)); REAL(value)[0]=c_value; + PROTECT(options=R_igraph_arpack_options_to_SEXP(&c_options)); SET_VECTOR_ELT(r_result, 0, vector); SET_VECTOR_ELT(r_result, 1, value); SET_VECTOR_ELT(r_result, 2, options); @@ -3734,16 +3911,33 @@ SEXP R_igraph_hub_and_authority_scores(SEXP graph, SEXP scale, SEXP weights, SEX SEXP r_result, r_names; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); + if (0 != igraph_vector_init(&c_hub_vector, 0)) { + igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); + } + IGRAPH_FINALLY(igraph_vector_destroy, &c_hub_vector); + if (0 != igraph_vector_init(&c_authority_vector, 0)) { + igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); + } + IGRAPH_FINALLY(igraph_vector_destroy, &c_authority_vector); IGRAPH_R_CHECK_BOOL(scale); c_scale = LOGICAL(scale)[0]; + if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } + R_SEXP_to_igraph_arpack_options(options, &c_options); /* Call igraph */ - IGRAPH_R_CHECK(igraph_hub_and_authority_scores(&c_graph, c_hub_vector, c_authority_vector, &c_value, c_scale, c_weights, c_options)); + IGRAPH_R_CHECK(igraph_hub_and_authority_scores(&c_graph, &c_hub_vector, &c_authority_vector, &c_value, c_scale, (Rf_isNull(weights) ? 0 : &c_weights), &c_options)); /* Convert output */ PROTECT(r_result=NEW_LIST(4)); PROTECT(r_names=NEW_CHARACTER(4)); + PROTECT(hub_vector=R_igraph_vector_to_SEXP(&c_hub_vector)); + igraph_vector_destroy(&c_hub_vector); + IGRAPH_FINALLY_CLEAN(1); + PROTECT(authority_vector=R_igraph_vector_to_SEXP(&c_authority_vector)); + igraph_vector_destroy(&c_authority_vector); + IGRAPH_FINALLY_CLEAN(1); PROTECT(value=NEW_NUMERIC(1)); REAL(value)[0]=c_value; + PROTECT(options=R_igraph_arpack_options_to_SEXP(&c_options)); SET_VECTOR_ELT(r_result, 0, hub_vector); SET_VECTOR_ELT(r_result, 1, authority_vector); SET_VECTOR_ELT(r_result, 2, value); @@ -3939,18 +4133,26 @@ SEXP R_igraph_avg_nearest_neighbor_degree(SEXP graph, SEXP vids, SEXP mode, SEXP R_SEXP_to_igraph_vs(vids, &c_graph, &c_vids, &c_vids_data); c_mode = (igraph_neimode_t) Rf_asInteger(mode); c_neighbor_degree_mode = (igraph_neimode_t) Rf_asInteger(neighbor_degree_mode); + if (0 != igraph_vector_init(&c_knn, 0)) { + igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); + } + IGRAPH_FINALLY(igraph_vector_destroy, &c_knn); if (0 != igraph_vector_init(&c_knnk, 0)) { igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_vector_destroy, &c_knnk); + if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } /* Call igraph */ - IGRAPH_R_CHECK(igraph_avg_nearest_neighbor_degree(&c_graph, c_vids, c_mode, c_neighbor_degree_mode, c_knn, &c_knnk, c_weights)); + IGRAPH_R_CHECK(igraph_avg_nearest_neighbor_degree(&c_graph, c_vids, c_mode, c_neighbor_degree_mode, &c_knn, &c_knnk, (Rf_isNull(weights) ? 0 : &c_weights))); /* Convert output */ PROTECT(r_result=NEW_LIST(2)); PROTECT(r_names=NEW_CHARACTER(2)); igraph_vector_int_destroy(&c_vids_data); igraph_vs_destroy(&c_vids); + PROTECT(knn=R_igraph_vector_to_SEXP(&c_knn)); + igraph_vector_destroy(&c_knn); + IGRAPH_FINALLY_CLEAN(1); PROTECT(knnk=R_igraph_vector_to_SEXP(&c_knnk)); igraph_vector_destroy(&c_knnk); IGRAPH_FINALLY_CLEAN(1); @@ -3981,6 +4183,7 @@ SEXP R_igraph_degree_correlation_vector(SEXP graph, SEXP weights, SEXP from_mode SEXP r_result; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); + if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } if (0 != igraph_vector_init(&c_knnk, 0)) { igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); } @@ -3990,7 +4193,7 @@ SEXP R_igraph_degree_correlation_vector(SEXP graph, SEXP weights, SEXP from_mode IGRAPH_R_CHECK_BOOL(directed_neighbors); c_directed_neighbors = LOGICAL(directed_neighbors)[0]; /* Call igraph */ - IGRAPH_R_CHECK(igraph_degree_correlation_vector(&c_graph, c_weights, &c_knnk, c_from_mode, c_to_mode, c_directed_neighbors)); + IGRAPH_R_CHECK(igraph_degree_correlation_vector(&c_graph, (Rf_isNull(weights) ? 0 : &c_weights), &c_knnk, c_from_mode, c_to_mode, c_directed_neighbors)); /* Convert output */ PROTECT(knnk=R_igraph_vector_to_SEXP(&c_knnk)); @@ -4018,15 +4221,23 @@ SEXP R_igraph_strength(SEXP graph, SEXP vids, SEXP mode, SEXP loops, SEXP weight SEXP r_result; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); + if (0 != igraph_vector_init(&c_res, 0)) { + igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); + } + IGRAPH_FINALLY(igraph_vector_destroy, &c_res); igraph_vector_int_t c_vids_data; R_SEXP_to_igraph_vs(vids, &c_graph, &c_vids, &c_vids_data); c_mode = (igraph_neimode_t) Rf_asInteger(mode); IGRAPH_R_CHECK_BOOL(loops); c_loops = LOGICAL(loops)[0]; + if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } /* Call igraph */ - IGRAPH_R_CHECK(igraph_strength(&c_graph, c_res, c_vids, c_mode, c_loops, c_weights)); + IGRAPH_R_CHECK(igraph_strength(&c_graph, &c_res, c_vids, c_mode, c_loops, (Rf_isNull(weights) ? 0 : &c_weights))); /* Convert output */ + PROTECT(res=R_igraph_vector_to_SEXP(&c_res)); + igraph_vector_destroy(&c_res); + IGRAPH_FINALLY_CLEAN(1); igraph_vector_int_destroy(&c_vids_data); igraph_vs_destroy(&c_vids); r_result = res; @@ -4347,10 +4558,11 @@ SEXP R_igraph_centralization_eigenvector_centrality(SEXP graph, SEXP directed, S c_directed = LOGICAL(directed)[0]; IGRAPH_R_CHECK_BOOL(scale); c_scale = LOGICAL(scale)[0]; + R_SEXP_to_igraph_arpack_options(options, &c_options); IGRAPH_R_CHECK_BOOL(normalized); c_normalized = LOGICAL(normalized)[0]; /* Call igraph */ - IGRAPH_R_CHECK(igraph_centralization_eigenvector_centrality(&c_graph, &c_vector, &c_value, c_directed, c_scale, c_options, &c_centralization, &c_theoretical_max, c_normalized)); + IGRAPH_R_CHECK(igraph_centralization_eigenvector_centrality(&c_graph, &c_vector, &c_value, c_directed, c_scale, &c_options, &c_centralization, &c_theoretical_max, c_normalized)); /* Convert output */ PROTECT(r_result=NEW_LIST(5)); @@ -4360,6 +4572,7 @@ SEXP R_igraph_centralization_eigenvector_centrality(SEXP graph, SEXP directed, S IGRAPH_FINALLY_CLEAN(1); PROTECT(value=NEW_NUMERIC(1)); REAL(value)[0]=c_value; + PROTECT(options=R_igraph_arpack_options_to_SEXP(&c_options)); PROTECT(centralization=NEW_NUMERIC(1)); REAL(centralization)[0]=c_centralization; PROTECT(theoretical_max=NEW_NUMERIC(1)); @@ -4529,6 +4742,7 @@ SEXP R_igraph_joint_degree_matrix(SEXP graph, SEXP weights, SEXP max_out_degree, SEXP r_result; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); + if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } if (0 != igraph_matrix_init(&c_jdm, 0, 0)) { igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); } @@ -4538,7 +4752,7 @@ SEXP R_igraph_joint_degree_matrix(SEXP graph, SEXP weights, SEXP max_out_degree, IGRAPH_R_CHECK_INT(max_in_degree); c_max_in_degree = (igraph_integer_t) REAL(max_in_degree)[0]; /* Call igraph */ - IGRAPH_R_CHECK(igraph_joint_degree_matrix(&c_graph, c_weights, &c_jdm, c_max_out_degree, c_max_in_degree)); + IGRAPH_R_CHECK(igraph_joint_degree_matrix(&c_graph, (Rf_isNull(weights) ? 0 : &c_weights), &c_jdm, c_max_out_degree, c_max_in_degree)); /* Convert output */ PROTECT(jdm=R_igraph_matrix_to_SEXP(&c_jdm)); @@ -4569,6 +4783,7 @@ SEXP R_igraph_joint_degree_distribution(SEXP graph, SEXP weights, SEXP from_mode SEXP r_result; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); + if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } if (0 != igraph_matrix_init(&c_p, 0, 0)) { igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); } @@ -4584,7 +4799,7 @@ SEXP R_igraph_joint_degree_distribution(SEXP graph, SEXP weights, SEXP from_mode IGRAPH_R_CHECK_INT(max_to_degree); c_max_to_degree = (igraph_integer_t) REAL(max_to_degree)[0]; /* Call igraph */ - IGRAPH_R_CHECK(igraph_joint_degree_distribution(&c_graph, c_weights, &c_p, c_from_mode, c_to_mode, c_directed_neighbors, c_normalized, c_max_from_degree, c_max_to_degree)); + IGRAPH_R_CHECK(igraph_joint_degree_distribution(&c_graph, (Rf_isNull(weights) ? 0 : &c_weights), &c_p, c_from_mode, c_to_mode, c_directed_neighbors, c_normalized, c_max_from_degree, c_max_to_degree)); /* Convert output */ PROTECT(p=R_igraph_matrix_to_SEXP(&c_p)); @@ -4613,6 +4828,7 @@ SEXP R_igraph_joint_type_distribution(SEXP graph, SEXP weights, SEXP from_types, SEXP r_result; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); + if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } if (0 != igraph_matrix_init(&c_p, 0, 0)) { igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); } @@ -4626,7 +4842,7 @@ SEXP R_igraph_joint_type_distribution(SEXP graph, SEXP weights, SEXP from_types, IGRAPH_R_CHECK_BOOL(normalized); c_normalized = LOGICAL(normalized)[0]; /* Call igraph */ - IGRAPH_R_CHECK(igraph_joint_type_distribution(&c_graph, c_weights, &c_p, &c_from_types, &c_to_types, c_directed, c_normalized)); + IGRAPH_R_CHECK(igraph_joint_type_distribution(&c_graph, (Rf_isNull(weights) ? 0 : &c_weights), &c_p, &c_from_types, &c_to_types, c_directed, c_normalized)); /* Convert output */ PROTECT(p=R_igraph_matrix_to_SEXP(&c_p)); @@ -4690,13 +4906,20 @@ SEXP R_igraph_eccentricity(SEXP graph, SEXP vids, SEXP mode) { SEXP r_result; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); + if (0 != igraph_vector_init(&c_res, 0)) { + igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); + } + IGRAPH_FINALLY(igraph_vector_destroy, &c_res); igraph_vector_int_t c_vids_data; R_SEXP_to_igraph_vs(vids, &c_graph, &c_vids, &c_vids_data); c_mode = (igraph_neimode_t) Rf_asInteger(mode); /* Call igraph */ - IGRAPH_R_CHECK(igraph_eccentricity(&c_graph, c_res, c_vids, c_mode)); + IGRAPH_R_CHECK(igraph_eccentricity(&c_graph, &c_res, c_vids, c_mode)); /* Convert output */ + PROTECT(res=R_igraph_vector_to_SEXP(&c_res)); + igraph_vector_destroy(&c_res); + IGRAPH_FINALLY_CLEAN(1); igraph_vector_int_destroy(&c_vids_data); igraph_vs_destroy(&c_vids); r_result = res; @@ -4720,13 +4943,21 @@ SEXP R_igraph_eccentricity_dijkstra(SEXP graph, SEXP weights, SEXP vids, SEXP mo SEXP r_result; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); + if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } + if (0 != igraph_vector_init(&c_res, 0)) { + igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); + } + IGRAPH_FINALLY(igraph_vector_destroy, &c_res); igraph_vector_int_t c_vids_data; R_SEXP_to_igraph_vs(vids, &c_graph, &c_vids, &c_vids_data); c_mode = (igraph_neimode_t) Rf_asInteger(mode); /* Call igraph */ - IGRAPH_R_CHECK(igraph_eccentricity_dijkstra(&c_graph, c_weights, c_res, c_vids, c_mode)); + IGRAPH_R_CHECK(igraph_eccentricity_dijkstra(&c_graph, (Rf_isNull(weights) ? 0 : &c_weights), &c_res, c_vids, c_mode)); /* Convert output */ + PROTECT(res=R_igraph_vector_to_SEXP(&c_res)); + igraph_vector_destroy(&c_res); + IGRAPH_FINALLY_CLEAN(1); igraph_vector_int_destroy(&c_vids_data); igraph_vs_destroy(&c_vids); r_result = res; @@ -4780,13 +5011,14 @@ SEXP R_igraph_graph_center_dijkstra(SEXP graph, SEXP weights, SEXP mode) { SEXP r_result; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); + if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } if (0 != igraph_vector_int_init(&c_res, 0)) { igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_vector_int_destroy, &c_res); c_mode = (igraph_neimode_t) Rf_asInteger(mode); /* Call igraph */ - IGRAPH_R_CHECK(igraph_graph_center_dijkstra(&c_graph, c_weights, &c_res, c_mode)); + IGRAPH_R_CHECK(igraph_graph_center_dijkstra(&c_graph, (Rf_isNull(weights) ? 0 : &c_weights), &c_res, c_mode)); /* Convert output */ PROTECT(res=R_igraph_vector_int_to_SEXPp1(&c_res)); @@ -4838,9 +5070,10 @@ SEXP R_igraph_radius_dijkstra(SEXP graph, SEXP weights, SEXP mode) { SEXP r_result; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); + if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } c_mode = (igraph_neimode_t) Rf_asInteger(mode); /* Call igraph */ - IGRAPH_R_CHECK(igraph_radius_dijkstra(&c_graph, c_weights, &c_radius, c_mode)); + IGRAPH_R_CHECK(igraph_radius_dijkstra(&c_graph, (Rf_isNull(weights) ? 0 : &c_weights), &c_radius, c_mode)); /* Convert output */ PROTECT(radius=NEW_NUMERIC(1)); @@ -4922,6 +5155,7 @@ SEXP R_igraph_pseudo_diameter_dijkstra(SEXP graph, SEXP weights, SEXP start_vid, SEXP r_result, r_names; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); + if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } c_start_vid = (igraph_integer_t) REAL(start_vid)[0]; c_from=0; c_to=0; @@ -4930,7 +5164,7 @@ SEXP R_igraph_pseudo_diameter_dijkstra(SEXP graph, SEXP weights, SEXP start_vid, IGRAPH_R_CHECK_BOOL(unconnected); c_unconnected = LOGICAL(unconnected)[0]; /* Call igraph */ - IGRAPH_R_CHECK(igraph_pseudo_diameter_dijkstra(&c_graph, c_weights, &c_diameter, c_start_vid, &c_from, &c_to, c_directed, c_unconnected)); + IGRAPH_R_CHECK(igraph_pseudo_diameter_dijkstra(&c_graph, (Rf_isNull(weights) ? 0 : &c_weights), &c_diameter, c_start_vid, &c_from, &c_to, c_directed, c_unconnected)); /* Convert output */ PROTECT(r_result=NEW_LIST(3)); @@ -4968,12 +5202,20 @@ SEXP R_igraph_diversity(SEXP graph, SEXP weights, SEXP vids) { SEXP r_result; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); + if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } + if (0 != igraph_vector_init(&c_res, 0)) { + igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); + } + IGRAPH_FINALLY(igraph_vector_destroy, &c_res); igraph_vector_int_t c_vids_data; R_SEXP_to_igraph_vs(vids, &c_graph, &c_vids, &c_vids_data); /* Call igraph */ - IGRAPH_R_CHECK(igraph_diversity(&c_graph, c_weights, c_res, c_vids)); + IGRAPH_R_CHECK(igraph_diversity(&c_graph, (Rf_isNull(weights) ? 0 : &c_weights), &c_res, c_vids)); /* Convert output */ + PROTECT(res=R_igraph_vector_to_SEXP(&c_res)); + igraph_vector_destroy(&c_res); + IGRAPH_FINALLY_CLEAN(1); igraph_vector_int_destroy(&c_vids_data); igraph_vs_destroy(&c_vids); r_result = res; @@ -5001,6 +5243,7 @@ SEXP R_igraph_random_walk(SEXP graph, SEXP weights, SEXP start, SEXP mode, SEXP SEXP r_result, r_names; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); + if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } if (0 != igraph_vector_int_init(&c_vertices, 0)) { igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); } @@ -5015,7 +5258,7 @@ SEXP R_igraph_random_walk(SEXP graph, SEXP weights, SEXP start, SEXP mode, SEXP c_steps = (igraph_integer_t) REAL(steps)[0]; c_stuck = (igraph_random_walk_stuck_t) Rf_asInteger(stuck); /* Call igraph */ - IGRAPH_R_CHECK(igraph_random_walk(&c_graph, c_weights, &c_vertices, &c_edges, c_start, c_mode, c_steps, c_stuck)); + IGRAPH_R_CHECK(igraph_random_walk(&c_graph, (Rf_isNull(weights) ? 0 : &c_weights), &c_vertices, &c_edges, c_start, c_mode, c_steps, c_stuck)); /* Convert output */ PROTECT(r_result=NEW_LIST(2)); @@ -5054,6 +5297,7 @@ SEXP R_igraph_random_edge_walk(SEXP graph, SEXP weights, SEXP start, SEXP mode, SEXP r_result; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); + if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } if (0 != igraph_vector_int_init(&c_edgewalk, 0)) { igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); } @@ -5064,7 +5308,7 @@ SEXP R_igraph_random_edge_walk(SEXP graph, SEXP weights, SEXP start, SEXP mode, c_steps = (igraph_integer_t) REAL(steps)[0]; c_stuck = (igraph_random_walk_stuck_t) Rf_asInteger(stuck); /* Call igraph */ - IGRAPH_R_CHECK(igraph_random_edge_walk(&c_graph, c_weights, &c_edgewalk, c_start, c_mode, c_steps, c_stuck)); + IGRAPH_R_CHECK(igraph_random_edge_walk(&c_graph, (Rf_isNull(weights) ? 0 : &c_weights), &c_edgewalk, c_start, c_mode, c_steps, c_stuck)); /* Convert output */ PROTECT(edgewalk=R_igraph_vector_int_to_SEXPp1(&c_edgewalk)); @@ -5090,10 +5334,11 @@ SEXP R_igraph_global_efficiency(SEXP graph, SEXP weights, SEXP directed) { SEXP r_result; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); + if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } IGRAPH_R_CHECK_BOOL(directed); c_directed = LOGICAL(directed)[0]; /* Call igraph */ - IGRAPH_R_CHECK(igraph_global_efficiency(&c_graph, &c_res, c_weights, c_directed)); + IGRAPH_R_CHECK(igraph_global_efficiency(&c_graph, &c_res, (Rf_isNull(weights) ? 0 : &c_weights), c_directed)); /* Convert output */ PROTECT(res=NEW_NUMERIC(1)); @@ -5120,15 +5365,23 @@ SEXP R_igraph_local_efficiency(SEXP graph, SEXP vids, SEXP weights, SEXP directe SEXP r_result; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); + if (0 != igraph_vector_init(&c_res, 0)) { + igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); + } + IGRAPH_FINALLY(igraph_vector_destroy, &c_res); igraph_vector_int_t c_vids_data; R_SEXP_to_igraph_vs(vids, &c_graph, &c_vids, &c_vids_data); + if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } IGRAPH_R_CHECK_BOOL(directed); c_directed = LOGICAL(directed)[0]; c_mode = (igraph_neimode_t) Rf_asInteger(mode); /* Call igraph */ - IGRAPH_R_CHECK(igraph_local_efficiency(&c_graph, c_res, c_vids, c_weights, c_directed, c_mode)); + IGRAPH_R_CHECK(igraph_local_efficiency(&c_graph, &c_res, c_vids, (Rf_isNull(weights) ? 0 : &c_weights), c_directed, c_mode)); /* Convert output */ + PROTECT(res=R_igraph_vector_to_SEXP(&c_res)); + igraph_vector_destroy(&c_res); + IGRAPH_FINALLY_CLEAN(1); igraph_vector_int_destroy(&c_vids_data); igraph_vs_destroy(&c_vids); r_result = res; @@ -5152,11 +5405,12 @@ SEXP R_igraph_average_local_efficiency(SEXP graph, SEXP weights, SEXP directed, SEXP r_result; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); + if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } IGRAPH_R_CHECK_BOOL(directed); c_directed = LOGICAL(directed)[0]; c_mode = (igraph_neimode_t) Rf_asInteger(mode); /* Call igraph */ - IGRAPH_R_CHECK(igraph_average_local_efficiency(&c_graph, &c_res, c_weights, c_directed, c_mode)); + IGRAPH_R_CHECK(igraph_average_local_efficiency(&c_graph, &c_res, (Rf_isNull(weights) ? 0 : &c_weights), c_directed, c_mode)); /* Convert output */ PROTECT(res=NEW_NUMERIC(1)); @@ -5747,8 +6001,9 @@ SEXP R_igraph_get_laplacian(SEXP graph, SEXP mode, SEXP normalization, SEXP weig IGRAPH_FINALLY(igraph_matrix_destroy, &c_res); c_mode = (igraph_neimode_t) Rf_asInteger(mode); c_normalization = (igraph_laplacian_normalization_t) Rf_asInteger(normalization); + if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } /* Call igraph */ - IGRAPH_R_CHECK(igraph_get_laplacian(&c_graph, &c_res, c_mode, c_normalization, c_weights)); + IGRAPH_R_CHECK(igraph_get_laplacian(&c_graph, &c_res, c_mode, c_normalization, (Rf_isNull(weights) ? 0 : &c_weights))); /* Convert output */ PROTECT(res=R_igraph_matrix_to_SEXP(&c_res)); @@ -5781,8 +6036,9 @@ SEXP R_igraph_get_laplacian_sparse(SEXP graph, SEXP mode, SEXP normalization, SE IGRAPH_FINALLY(igraph_sparsemat_destroy, &c_sparseres); c_mode = (igraph_neimode_t) Rf_asInteger(mode); c_normalization = (igraph_laplacian_normalization_t) Rf_asInteger(normalization); + if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } /* Call igraph */ - IGRAPH_R_CHECK(igraph_get_laplacian_sparse(&c_graph, &c_sparseres, c_mode, c_normalization, c_weights)); + IGRAPH_R_CHECK(igraph_get_laplacian_sparse(&c_graph, &c_sparseres, c_mode, c_normalization, (Rf_isNull(weights) ? 0 : &c_weights))); /* Convert output */ PROTECT(sparseres=R_igraph_sparsemat_to_SEXP(&c_sparseres)); @@ -5924,18 +6180,39 @@ SEXP R_igraph_biconnected_components(SEXP graph) { /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); c_no=0; + if (0 != igraph_vector_int_list_init(&c_tree_edges, 0)) { + igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); + } + IGRAPH_FINALLY(igraph_vector_int_list_destroy, &c_tree_edges); + if (0 != igraph_vector_int_list_init(&c_component_edges, 0)) { + igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); + } + IGRAPH_FINALLY(igraph_vector_int_list_destroy, &c_component_edges); + if (0 != igraph_vector_int_list_init(&c_components, 0)) { + igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); + } + IGRAPH_FINALLY(igraph_vector_int_list_destroy, &c_components); if (0 != igraph_vector_int_init(&c_articulation_points, 0)) { igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_vector_int_destroy, &c_articulation_points); /* Call igraph */ - IGRAPH_R_CHECK(igraph_biconnected_components(&c_graph, &c_no, c_tree_edges, c_component_edges, c_components, &c_articulation_points)); + IGRAPH_R_CHECK(igraph_biconnected_components(&c_graph, &c_no, &c_tree_edges, &c_component_edges, &c_components, &c_articulation_points)); /* Convert output */ PROTECT(r_result=NEW_LIST(5)); PROTECT(r_names=NEW_CHARACTER(5)); PROTECT(no=NEW_NUMERIC(1)); REAL(no)[0]=(double) c_no; + PROTECT(tree_edges=R_igraph_vector_int_list_to_SEXPp1(&c_tree_edges)); + igraph_vector_int_list_destroy(&c_tree_edges); + IGRAPH_FINALLY_CLEAN(1); + PROTECT(component_edges=R_igraph_vector_int_list_to_SEXPp1(&c_component_edges)); + igraph_vector_int_list_destroy(&c_component_edges); + IGRAPH_FINALLY_CLEAN(1); + PROTECT(components=R_igraph_vector_int_list_to_SEXPp1(&c_components)); + igraph_vector_int_list_destroy(&c_components); + IGRAPH_FINALLY_CLEAN(1); PROTECT(articulation_points=R_igraph_vector_int_to_SEXPp1(&c_articulation_points)); igraph_vector_int_destroy(&c_articulation_points); IGRAPH_FINALLY_CLEAN(1); @@ -6023,15 +6300,21 @@ SEXP R_igraph_cliques(SEXP graph, SEXP min_size, SEXP max_size) { SEXP r_result; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); + if (0 != igraph_vector_int_list_init(&c_res, 0)) { + igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); + } + IGRAPH_FINALLY(igraph_vector_int_list_destroy, &c_res); IGRAPH_R_CHECK_INT(min_size); c_min_size = (igraph_integer_t) REAL(min_size)[0]; IGRAPH_R_CHECK_INT(max_size); c_max_size = (igraph_integer_t) REAL(max_size)[0]; /* Call igraph */ - IGRAPH_R_CHECK(igraph_cliques(&c_graph, c_res, c_min_size, c_max_size)); + IGRAPH_R_CHECK(igraph_cliques(&c_graph, &c_res, c_min_size, c_max_size)); /* Convert output */ - + PROTECT(res=R_igraph_vector_int_list_to_SEXPp1(&c_res)); + igraph_vector_int_list_destroy(&c_res); + IGRAPH_FINALLY_CLEAN(1); r_result = res; UNPROTECT(1); @@ -6085,11 +6368,17 @@ SEXP R_igraph_largest_cliques(SEXP graph) { SEXP r_result; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); + if (0 != igraph_vector_int_list_init(&c_res, 0)) { + igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); + } + IGRAPH_FINALLY(igraph_vector_int_list_destroy, &c_res); /* Call igraph */ - IGRAPH_R_CHECK(igraph_largest_cliques(&c_graph, c_res)); + IGRAPH_R_CHECK(igraph_largest_cliques(&c_graph, &c_res)); /* Convert output */ - + PROTECT(res=R_igraph_vector_int_list_to_SEXPp1(&c_res)); + igraph_vector_int_list_destroy(&c_res); + IGRAPH_FINALLY_CLEAN(1); r_result = res; UNPROTECT(1); @@ -6172,6 +6461,11 @@ SEXP R_igraph_weighted_cliques(SEXP graph, SEXP vertex_weights, SEXP min_weight, SEXP r_result; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); + if (!Rf_isNull(vertex_weights)) { R_SEXP_to_vector(vertex_weights, &c_vertex_weights); } + if (0 != igraph_vector_int_list_init(&c_res, 0)) { + igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); + } + IGRAPH_FINALLY(igraph_vector_int_list_destroy, &c_res); IGRAPH_R_CHECK_REAL(min_weight); c_min_weight = REAL(min_weight)[0]; IGRAPH_R_CHECK_REAL(max_weight); @@ -6179,10 +6473,12 @@ SEXP R_igraph_weighted_cliques(SEXP graph, SEXP vertex_weights, SEXP min_weight, IGRAPH_R_CHECK_BOOL(maximal); c_maximal = LOGICAL(maximal)[0]; /* Call igraph */ - IGRAPH_R_CHECK(igraph_weighted_cliques(&c_graph, c_vertex_weights, c_res, c_min_weight, c_max_weight, c_maximal)); + IGRAPH_R_CHECK(igraph_weighted_cliques(&c_graph, (Rf_isNull(vertex_weights) ? 0 : &c_vertex_weights), &c_res, c_min_weight, c_max_weight, c_maximal)); /* Convert output */ - + PROTECT(res=R_igraph_vector_int_list_to_SEXPp1(&c_res)); + igraph_vector_int_list_destroy(&c_res); + IGRAPH_FINALLY_CLEAN(1); r_result = res; UNPROTECT(1); @@ -6202,11 +6498,18 @@ SEXP R_igraph_largest_weighted_cliques(SEXP graph, SEXP vertex_weights) { SEXP r_result; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); + if (!Rf_isNull(vertex_weights)) { R_SEXP_to_vector(vertex_weights, &c_vertex_weights); } + if (0 != igraph_vector_int_list_init(&c_res, 0)) { + igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); + } + IGRAPH_FINALLY(igraph_vector_int_list_destroy, &c_res); /* Call igraph */ - IGRAPH_R_CHECK(igraph_largest_weighted_cliques(&c_graph, c_vertex_weights, c_res)); + IGRAPH_R_CHECK(igraph_largest_weighted_cliques(&c_graph, (Rf_isNull(vertex_weights) ? 0 : &c_vertex_weights), &c_res)); /* Convert output */ - + PROTECT(res=R_igraph_vector_int_list_to_SEXPp1(&c_res)); + igraph_vector_int_list_destroy(&c_res); + IGRAPH_FINALLY_CLEAN(1); r_result = res; UNPROTECT(1); @@ -6226,8 +6529,9 @@ SEXP R_igraph_weighted_clique_number(SEXP graph, SEXP vertex_weights) { SEXP r_result; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); + if (!Rf_isNull(vertex_weights)) { R_SEXP_to_vector(vertex_weights, &c_vertex_weights); } /* Call igraph */ - IGRAPH_R_CHECK(igraph_weighted_clique_number(&c_graph, c_vertex_weights, &c_res)); + IGRAPH_R_CHECK(igraph_weighted_clique_number(&c_graph, (Rf_isNull(vertex_weights) ? 0 : &c_vertex_weights), &c_res)); /* Convert output */ PROTECT(res=NEW_NUMERIC(1)); @@ -6400,8 +6704,9 @@ SEXP R_igraph_layout_drl(SEXP graph, SEXP res, SEXP use_seed, SEXP options, SEXP IGRAPH_R_CHECK_BOOL(use_seed); c_use_seed = LOGICAL(use_seed)[0]; R_SEXP_to_igraph_layout_drl_options(options, &c_options); + if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } /* Call igraph */ - IGRAPH_R_CHECK(igraph_layout_drl(&c_graph, &c_res, c_use_seed, &c_options, (Rf_isNull(weights) ? 0 : c_weights))); + IGRAPH_R_CHECK(igraph_layout_drl(&c_graph, &c_res, c_use_seed, &c_options, (Rf_isNull(weights) ? 0 : (Rf_isNull(weights) ? 0 : &c_weights)))); /* Convert output */ PROTECT(res=R_igraph_matrix_to_SEXP(&c_res)); @@ -6434,8 +6739,9 @@ SEXP R_igraph_layout_drl_3d(SEXP graph, SEXP res, SEXP use_seed, SEXP options, S IGRAPH_R_CHECK_BOOL(use_seed); c_use_seed = LOGICAL(use_seed)[0]; R_SEXP_to_igraph_layout_drl_options(options, &c_options); + if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } /* Call igraph */ - IGRAPH_R_CHECK(igraph_layout_drl_3d(&c_graph, &c_res, c_use_seed, &c_options, (Rf_isNull(weights) ? 0 : c_weights))); + IGRAPH_R_CHECK(igraph_layout_drl_3d(&c_graph, &c_res, c_use_seed, &c_options, (Rf_isNull(weights) ? 0 : (Rf_isNull(weights) ? 0 : &c_weights)))); /* Convert output */ PROTECT(res=R_igraph_matrix_to_SEXP(&c_res)); @@ -6489,8 +6795,9 @@ SEXP R_igraph_layout_sugiyama(SEXP graph, SEXP layers, SEXP hgap, SEXP vgap, SEX c_vgap = REAL(vgap)[0]; IGRAPH_R_CHECK_INT(maxiter); c_maxiter = (igraph_integer_t) REAL(maxiter)[0]; + if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } /* Call igraph */ - IGRAPH_R_CHECK(igraph_layout_sugiyama(&c_graph, &c_res, &c_extd_graph, &c_extd_to_orig_eids, (Rf_isNull(layers) ? 0 : &c_layers), c_hgap, c_vgap, c_maxiter, c_weights)); + IGRAPH_R_CHECK(igraph_layout_sugiyama(&c_graph, &c_res, &c_extd_graph, &c_extd_to_orig_eids, (Rf_isNull(layers) ? 0 : &c_layers), c_hgap, c_vgap, c_maxiter, (Rf_isNull(weights) ? 0 : &c_weights))); /* Convert output */ PROTECT(r_result=NEW_LIST(3)); @@ -7144,12 +7451,13 @@ SEXP R_igraph_modularity(SEXP graph, SEXP membership, SEXP weights, SEXP resolut R_SEXP_to_igraph(graph, &c_graph); R_SEXP_to_vector_int_copy(membership, &c_membership); IGRAPH_FINALLY(igraph_vector_int_destroy, &c_membership); + if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } IGRAPH_R_CHECK_REAL(resolution); c_resolution = REAL(resolution)[0]; IGRAPH_R_CHECK_BOOL(directed); c_directed = LOGICAL(directed)[0]; /* Call igraph */ - IGRAPH_R_CHECK(igraph_modularity(&c_graph, &c_membership, (Rf_isNull(weights) ? 0 : c_weights), c_resolution, c_directed, &c_modularity)); + IGRAPH_R_CHECK(igraph_modularity(&c_graph, &c_membership, (Rf_isNull(weights) ? 0 : (Rf_isNull(weights) ? 0 : &c_weights)), c_resolution, c_directed, &c_modularity)); /* Convert output */ igraph_vector_int_destroy(&c_membership); @@ -7177,6 +7485,7 @@ SEXP R_igraph_modularity_matrix(SEXP graph, SEXP weights, SEXP resolution, SEXP SEXP r_result; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); + if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } IGRAPH_R_CHECK_REAL(resolution); c_resolution = REAL(resolution)[0]; if (0 != igraph_matrix_init(&c_modmat, 0, 0)) { @@ -7186,7 +7495,7 @@ SEXP R_igraph_modularity_matrix(SEXP graph, SEXP weights, SEXP resolution, SEXP IGRAPH_R_CHECK_BOOL(directed); c_directed = LOGICAL(directed)[0]; /* Call igraph */ - IGRAPH_R_CHECK(igraph_modularity_matrix(&c_graph, (Rf_isNull(weights) ? 0 : c_weights), c_resolution, &c_modmat, c_directed)); + IGRAPH_R_CHECK(igraph_modularity_matrix(&c_graph, (Rf_isNull(weights) ? 0 : (Rf_isNull(weights) ? 0 : &c_weights)), c_resolution, &c_modmat, c_directed)); /* Convert output */ PROTECT(modmat=R_igraph_matrix_to_SEXP(&c_modmat)); @@ -7251,6 +7560,7 @@ SEXP R_igraph_community_label_propagation(SEXP graph, SEXP mode, SEXP weights, S } IGRAPH_FINALLY(igraph_vector_int_destroy, &c_membership); c_mode = (igraph_neimode_t) Rf_asInteger(mode); + if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } if (!Rf_isNull(initial)) { R_SEXP_to_vector_int_copy(initial, &c_initial); IGRAPH_FINALLY(igraph_vector_int_destroy, &c_initial); @@ -7262,7 +7572,7 @@ SEXP R_igraph_community_label_propagation(SEXP graph, SEXP mode, SEXP weights, S R_SEXP_to_vector_bool(fixed, &c_fixed); } /* Call igraph */ - IGRAPH_R_CHECK(igraph_community_label_propagation(&c_graph, &c_membership, c_mode, (Rf_isNull(weights) ? 0 : c_weights), (Rf_isNull(initial) ? 0 : &c_initial), (Rf_isNull(fixed) ? 0 : &c_fixed))); + IGRAPH_R_CHECK(igraph_community_label_propagation(&c_graph, &c_membership, c_mode, (Rf_isNull(weights) ? 0 : (Rf_isNull(weights) ? 0 : &c_weights)), (Rf_isNull(initial) ? 0 : &c_initial), (Rf_isNull(fixed) ? 0 : &c_fixed))); /* Convert output */ PROTECT(membership=R_igraph_vector_int_to_SEXP(&c_membership)); @@ -7294,6 +7604,7 @@ SEXP R_igraph_community_multilevel(SEXP graph, SEXP weights, SEXP resolution) { SEXP r_result, r_names; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); + if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } IGRAPH_R_CHECK_REAL(resolution); c_resolution = REAL(resolution)[0]; if (0 != igraph_vector_int_init(&c_membership, 0)) { @@ -7309,7 +7620,7 @@ SEXP R_igraph_community_multilevel(SEXP graph, SEXP weights, SEXP resolution) { } IGRAPH_FINALLY(igraph_vector_destroy, &c_modularity); /* Call igraph */ - IGRAPH_R_CHECK(igraph_community_multilevel(&c_graph, (Rf_isNull(weights) ? 0 : c_weights), c_resolution, &c_membership, &c_memberships, &c_modularity)); + IGRAPH_R_CHECK(igraph_community_multilevel(&c_graph, (Rf_isNull(weights) ? 0 : (Rf_isNull(weights) ? 0 : &c_weights)), c_resolution, &c_membership, &c_memberships, &c_modularity)); /* Convert output */ PROTECT(r_result=NEW_LIST(3)); @@ -7355,8 +7666,9 @@ SEXP R_igraph_community_optimal_modularity(SEXP graph, SEXP weights) { igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_vector_int_destroy, &c_membership); + if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } /* Call igraph */ - IGRAPH_R_CHECK(igraph_community_optimal_modularity(&c_graph, &c_modularity, &c_membership, (Rf_isNull(weights) ? 0 : c_weights))); + IGRAPH_R_CHECK(igraph_community_optimal_modularity(&c_graph, &c_modularity, &c_membership, (Rf_isNull(weights) ? 0 : (Rf_isNull(weights) ? 0 : &c_weights)))); /* Convert output */ PROTECT(r_result=NEW_LIST(2)); @@ -7398,6 +7710,8 @@ SEXP R_igraph_community_leiden(SEXP graph, SEXP weights, SEXP vertex_weights, SE SEXP r_result, r_names; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); + if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } + if (!Rf_isNull(vertex_weights)) { R_SEXP_to_vector(vertex_weights, &c_vertex_weights); } IGRAPH_R_CHECK_REAL(resolution); c_resolution = REAL(resolution)[0]; IGRAPH_R_CHECK_REAL(beta); @@ -7415,7 +7729,7 @@ SEXP R_igraph_community_leiden(SEXP graph, SEXP weights, SEXP vertex_weights, SE } c_nb_clusters=0; /* Call igraph */ - IGRAPH_R_CHECK(igraph_community_leiden(&c_graph, (Rf_isNull(weights) ? 0 : c_weights), (Rf_isNull(vertex_weights) ? 0 : c_vertex_weights), c_resolution, c_beta, c_start, c_n_iterations, &c_membership, &c_nb_clusters, &c_quality)); + IGRAPH_R_CHECK(igraph_community_leiden(&c_graph, (Rf_isNull(weights) ? 0 : (Rf_isNull(weights) ? 0 : &c_weights)), (Rf_isNull(vertex_weights) ? 0 : (Rf_isNull(vertex_weights) ? 0 : &c_vertex_weights)), c_resolution, c_beta, c_start, c_n_iterations, &c_membership, &c_nb_clusters, &c_quality)); /* Convert output */ PROTECT(r_result=NEW_LIST(3)); @@ -7502,6 +7816,8 @@ SEXP R_igraph_community_infomap(SEXP graph, SEXP e_weights, SEXP v_weights, SEXP SEXP r_result, r_names; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); + if (!Rf_isNull(e_weights)) { R_SEXP_to_vector(e_weights, &c_e_weights); } + if (!Rf_isNull(v_weights)) { R_SEXP_to_vector(v_weights, &c_v_weights); } IGRAPH_R_CHECK_INT(nb_trials); c_nb_trials = (igraph_integer_t) REAL(nb_trials)[0]; if (0 != igraph_vector_int_init(&c_membership, 0)) { @@ -7509,7 +7825,7 @@ SEXP R_igraph_community_infomap(SEXP graph, SEXP e_weights, SEXP v_weights, SEXP } IGRAPH_FINALLY(igraph_vector_int_destroy, &c_membership); /* Call igraph */ - IGRAPH_R_CHECK(igraph_community_infomap(&c_graph, c_e_weights, c_v_weights, c_nb_trials, &c_membership, &c_codelength)); + IGRAPH_R_CHECK(igraph_community_infomap(&c_graph, (Rf_isNull(e_weights) ? 0 : &c_e_weights), (Rf_isNull(v_weights) ? 0 : &c_v_weights), c_nb_trials, &c_membership, &c_codelength)); /* Convert output */ PROTECT(r_result=NEW_LIST(2)); @@ -7941,9 +8257,10 @@ SEXP R_igraph_get_adjacency_sparse(SEXP graph, SEXP type, SEXP weights, SEXP loo } IGRAPH_FINALLY(igraph_sparsemat_destroy, &c_sparsemat); c_type = (igraph_get_adjacency_t) Rf_asInteger(type); + if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } c_loops = (igraph_loops_t) Rf_asInteger(loops); /* Call igraph */ - IGRAPH_R_CHECK(igraph_get_adjacency_sparse(&c_graph, &c_sparsemat, c_type, c_weights, c_loops)); + IGRAPH_R_CHECK(igraph_get_adjacency_sparse(&c_graph, &c_sparsemat, c_type, (Rf_isNull(weights) ? 0 : &c_weights), c_loops)); /* Convert output */ PROTECT(sparsemat=R_igraph_sparsemat_to_SEXP(&c_sparsemat)); @@ -7975,8 +8292,9 @@ SEXP R_igraph_get_stochastic(SEXP graph, SEXP column_wise, SEXP weights) { IGRAPH_FINALLY(igraph_matrix_destroy, &c_res); IGRAPH_R_CHECK_BOOL(column_wise); c_column_wise = LOGICAL(column_wise)[0]; + if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } /* Call igraph */ - IGRAPH_R_CHECK(igraph_get_stochastic(&c_graph, &c_res, c_column_wise, c_weights)); + IGRAPH_R_CHECK(igraph_get_stochastic(&c_graph, &c_res, c_column_wise, (Rf_isNull(weights) ? 0 : &c_weights))); /* Convert output */ PROTECT(res=R_igraph_matrix_to_SEXP(&c_res)); @@ -8008,8 +8326,9 @@ SEXP R_igraph_get_stochastic_sparse(SEXP graph, SEXP column_wise, SEXP weights) IGRAPH_FINALLY(igraph_sparsemat_destroy, &c_sparsemat); IGRAPH_R_CHECK_BOOL(column_wise); c_column_wise = LOGICAL(column_wise)[0]; + if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } /* Call igraph */ - IGRAPH_R_CHECK(igraph_get_stochastic_sparse(&c_graph, &c_sparsemat, c_column_wise, c_weights)); + IGRAPH_R_CHECK(igraph_get_stochastic_sparse(&c_graph, &c_sparsemat, c_column_wise, (Rf_isNull(weights) ? 0 : &c_weights))); /* Convert output */ PROTECT(sparsemat=R_igraph_sparsemat_to_SEXP(&c_sparsemat)); @@ -8200,9 +8519,10 @@ SEXP R_igraph_local_scan_0(SEXP graph, SEXP weights, SEXP mode) { igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_vector_destroy, &c_res); + if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } c_mode = (igraph_neimode_t) Rf_asInteger(mode); /* Call igraph */ - IGRAPH_R_CHECK(igraph_local_scan_0(&c_graph, &c_res, c_weights, c_mode)); + IGRAPH_R_CHECK(igraph_local_scan_0(&c_graph, &c_res, (Rf_isNull(weights) ? 0 : &c_weights), c_mode)); /* Convert output */ PROTECT(res=R_igraph_vector_to_SEXP(&c_res)); @@ -8234,9 +8554,10 @@ SEXP R_igraph_local_scan_0_them(SEXP us, SEXP them, SEXP weights_them, SEXP mode igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_vector_destroy, &c_res); + if (!Rf_isNull(weights_them)) { R_SEXP_to_vector(weights_them, &c_weights_them); } c_mode = (igraph_neimode_t) Rf_asInteger(mode); /* Call igraph */ - IGRAPH_R_CHECK(igraph_local_scan_0_them(&c_us, &c_them, &c_res, c_weights_them, c_mode)); + IGRAPH_R_CHECK(igraph_local_scan_0_them(&c_us, &c_them, &c_res, (Rf_isNull(weights_them) ? 0 : &c_weights_them), c_mode)); /* Convert output */ PROTECT(res=R_igraph_vector_to_SEXP(&c_res)); @@ -8266,9 +8587,10 @@ SEXP R_igraph_local_scan_1_ecount(SEXP graph, SEXP weights, SEXP mode) { igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_vector_destroy, &c_res); + if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } c_mode = (igraph_neimode_t) Rf_asInteger(mode); /* Call igraph */ - IGRAPH_R_CHECK(igraph_local_scan_1_ecount(&c_graph, &c_res, c_weights, c_mode)); + IGRAPH_R_CHECK(igraph_local_scan_1_ecount(&c_graph, &c_res, (Rf_isNull(weights) ? 0 : &c_weights), c_mode)); /* Convert output */ PROTECT(res=R_igraph_vector_to_SEXP(&c_res)); @@ -8300,9 +8622,10 @@ SEXP R_igraph_local_scan_1_ecount_them(SEXP us, SEXP them, SEXP weights_them, SE igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_vector_destroy, &c_res); + if (!Rf_isNull(weights_them)) { R_SEXP_to_vector(weights_them, &c_weights_them); } c_mode = (igraph_neimode_t) Rf_asInteger(mode); /* Call igraph */ - IGRAPH_R_CHECK(igraph_local_scan_1_ecount_them(&c_us, &c_them, &c_res, c_weights_them, c_mode)); + IGRAPH_R_CHECK(igraph_local_scan_1_ecount_them(&c_us, &c_them, &c_res, (Rf_isNull(weights_them) ? 0 : &c_weights_them), c_mode)); /* Convert output */ PROTECT(res=R_igraph_vector_to_SEXP(&c_res)); @@ -8335,9 +8658,10 @@ SEXP R_igraph_local_scan_k_ecount(SEXP graph, SEXP k, SEXP weights, SEXP mode) { igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_vector_destroy, &c_res); + if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } c_mode = (igraph_neimode_t) Rf_asInteger(mode); /* Call igraph */ - IGRAPH_R_CHECK(igraph_local_scan_k_ecount(&c_graph, c_k, &c_res, c_weights, c_mode)); + IGRAPH_R_CHECK(igraph_local_scan_k_ecount(&c_graph, c_k, &c_res, (Rf_isNull(weights) ? 0 : &c_weights), c_mode)); /* Convert output */ PROTECT(res=R_igraph_vector_to_SEXP(&c_res)); @@ -8372,9 +8696,10 @@ SEXP R_igraph_local_scan_k_ecount_them(SEXP us, SEXP them, SEXP k, SEXP weights_ igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_vector_destroy, &c_res); + if (!Rf_isNull(weights_them)) { R_SEXP_to_vector(weights_them, &c_weights_them); } c_mode = (igraph_neimode_t) Rf_asInteger(mode); /* Call igraph */ - IGRAPH_R_CHECK(igraph_local_scan_k_ecount_them(&c_us, &c_them, c_k, &c_res, c_weights_them, c_mode)); + IGRAPH_R_CHECK(igraph_local_scan_k_ecount_them(&c_us, &c_them, c_k, &c_res, (Rf_isNull(weights_them) ? 0 : &c_weights_them), c_mode)); /* Convert output */ PROTECT(res=R_igraph_vector_to_SEXP(&c_res)); @@ -8404,13 +8729,18 @@ SEXP R_igraph_local_scan_neighborhood_ecount(SEXP graph, SEXP weights, SEXP neig igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_vector_destroy, &c_res); + if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } + R_igraph_SEXP_to_vector_int_list(neighborhoods, &c_neighborhoods); + IGRAPH_FINALLY(igraph_vector_int_list_destroy, &c_neighborhoods); /* Call igraph */ - IGRAPH_R_CHECK(igraph_local_scan_neighborhood_ecount(&c_graph, &c_res, c_weights, c_neighborhoods)); + IGRAPH_R_CHECK(igraph_local_scan_neighborhood_ecount(&c_graph, &c_res, (Rf_isNull(weights) ? 0 : &c_weights), &c_neighborhoods)); /* Convert output */ PROTECT(res=R_igraph_vector_to_SEXP(&c_res)); igraph_vector_destroy(&c_res); IGRAPH_FINALLY_CLEAN(1); + igraph_vector_int_list_destroy(&c_neighborhoods); + IGRAPH_FINALLY_CLEAN(1); r_result = res; UNPROTECT(1); @@ -8435,13 +8765,18 @@ SEXP R_igraph_local_scan_subset_ecount(SEXP graph, SEXP weights, SEXP subsets) { igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_vector_destroy, &c_res); + if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } + R_igraph_SEXP_to_vector_int_list(subsets, &c_subsets); + IGRAPH_FINALLY(igraph_vector_int_list_destroy, &c_subsets); /* Call igraph */ - IGRAPH_R_CHECK(igraph_local_scan_subset_ecount(&c_graph, &c_res, c_weights, c_subsets)); + IGRAPH_R_CHECK(igraph_local_scan_subset_ecount(&c_graph, &c_res, (Rf_isNull(weights) ? 0 : &c_weights), &c_subsets)); /* Convert output */ PROTECT(res=R_igraph_vector_to_SEXP(&c_res)); igraph_vector_destroy(&c_res); IGRAPH_FINALLY_CLEAN(1); + igraph_vector_int_list_destroy(&c_subsets); + IGRAPH_FINALLY_CLEAN(1); r_result = res; UNPROTECT(1); @@ -8584,8 +8919,9 @@ SEXP R_igraph_gomory_hu_tree(SEXP graph, SEXP capacity) { igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_vector_destroy, &c_flows); + if (!Rf_isNull(capacity)) { R_SEXP_to_vector(capacity, &c_capacity); } /* Call igraph */ - IGRAPH_R_CHECK(igraph_gomory_hu_tree(&c_graph, &c_tree, &c_flows, (Rf_isNull(capacity) ? 0 : c_capacity))); + IGRAPH_R_CHECK(igraph_gomory_hu_tree(&c_graph, &c_tree, &c_flows, (Rf_isNull(capacity) ? 0 : (Rf_isNull(capacity) ? 0 : &c_capacity)))); /* Convert output */ PROTECT(r_result=NEW_LIST(2)); @@ -8651,8 +8987,9 @@ SEXP R_igraph_maxflow(SEXP graph, SEXP source, SEXP target, SEXP capacity) { IGRAPH_FINALLY(igraph_vector_int_destroy, &c_partition2); c_source = (igraph_integer_t) REAL(source)[0]; c_target = (igraph_integer_t) REAL(target)[0]; + if (!Rf_isNull(capacity)) { R_SEXP_to_vector(capacity, &c_capacity); } /* Call igraph */ - IGRAPH_R_CHECK(igraph_maxflow(&c_graph, &c_value, &c_flow, &c_cut, &c_partition1, &c_partition2, c_source, c_target, (Rf_isNull(capacity) ? 0 : c_capacity), &c_stats)); + IGRAPH_R_CHECK(igraph_maxflow(&c_graph, &c_value, &c_flow, &c_cut, &c_partition1, &c_partition2, c_source, c_target, (Rf_isNull(capacity) ? 0 : (Rf_isNull(capacity) ? 0 : &c_capacity)), &c_stats)); /* Convert output */ PROTECT(r_result=NEW_LIST(6)); @@ -8707,9 +9044,15 @@ SEXP R_igraph_residual_graph(SEXP graph, SEXP capacity, SEXP flow) { SEXP r_result, r_names; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); + if (!Rf_isNull(capacity)) { R_SEXP_to_vector(capacity, &c_capacity); } + if (0 != igraph_vector_init(&c_residual_capacity, 0)) { + igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); + } + IGRAPH_FINALLY(igraph_vector_destroy, &c_residual_capacity); + residual_capacity=R_GlobalEnv; /* hack to have a non-NULL value */ R_SEXP_to_vector(flow, &c_flow); /* Call igraph */ - IGRAPH_R_CHECK(igraph_residual_graph(&c_graph, c_capacity, &c_residual, c_residual_capacity, &c_flow)); + IGRAPH_R_CHECK(igraph_residual_graph(&c_graph, (Rf_isNull(capacity) ? 0 : &c_capacity), &c_residual, (Rf_isNull(residual_capacity) ? 0 : &c_residual_capacity), &c_flow)); /* Convert output */ PROTECT(r_result=NEW_LIST(2)); @@ -8718,6 +9061,9 @@ SEXP R_igraph_residual_graph(SEXP graph, SEXP capacity, SEXP flow) { PROTECT(residual=R_igraph_to_SEXP(&c_residual)); IGRAPH_I_DESTROY(&c_residual); IGRAPH_FINALLY_CLEAN(1); + PROTECT(residual_capacity=R_igraph_0orvector_to_SEXP(&c_residual_capacity)); + igraph_vector_destroy(&c_residual_capacity); + IGRAPH_FINALLY_CLEAN(1); SET_VECTOR_ELT(r_result, 0, residual); SET_VECTOR_ELT(r_result, 1, residual_capacity); SET_STRING_ELT(r_names, 0, Rf_mkChar("residual")); @@ -8743,9 +9089,10 @@ SEXP R_igraph_reverse_residual_graph(SEXP graph, SEXP capacity, SEXP flow) { SEXP r_result; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); + if (!Rf_isNull(capacity)) { R_SEXP_to_vector(capacity, &c_capacity); } R_SEXP_to_vector(flow, &c_flow); /* Call igraph */ - IGRAPH_R_CHECK(igraph_reverse_residual_graph(&c_graph, c_capacity, &c_residual, &c_flow)); + IGRAPH_R_CHECK(igraph_reverse_residual_graph(&c_graph, (Rf_isNull(capacity) ? 0 : &c_capacity), &c_residual, &c_flow)); /* Convert output */ IGRAPH_FINALLY(igraph_destroy, &c_residual); @@ -8793,8 +9140,9 @@ SEXP R_igraph_st_mincut(SEXP graph, SEXP source, SEXP target, SEXP capacity) { IGRAPH_FINALLY(igraph_vector_int_destroy, &c_partition2); c_source = (igraph_integer_t) REAL(source)[0]; c_target = (igraph_integer_t) REAL(target)[0]; + if (!Rf_isNull(capacity)) { R_SEXP_to_vector(capacity, &c_capacity); } /* Call igraph */ - IGRAPH_R_CHECK(igraph_st_mincut(&c_graph, &c_value, &c_cut, &c_partition1, &c_partition2, c_source, c_target, (Rf_isNull(capacity) ? 0 : c_capacity))); + IGRAPH_R_CHECK(igraph_st_mincut(&c_graph, &c_value, &c_cut, &c_partition1, &c_partition2, c_source, c_target, (Rf_isNull(capacity) ? 0 : (Rf_isNull(capacity) ? 0 : &c_capacity)))); /* Convert output */ PROTECT(r_result=NEW_LIST(4)); @@ -8898,14 +9246,28 @@ SEXP R_igraph_all_st_cuts(SEXP graph, SEXP source, SEXP target) { SEXP r_result, r_names; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); + if (0 != igraph_vector_int_list_init(&c_cuts, 0)) { + igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); + } + IGRAPH_FINALLY(igraph_vector_int_list_destroy, &c_cuts); + if (0 != igraph_vector_int_list_init(&c_partition1s, 0)) { + igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); + } + IGRAPH_FINALLY(igraph_vector_int_list_destroy, &c_partition1s); c_source = (igraph_integer_t) REAL(source)[0]; c_target = (igraph_integer_t) REAL(target)[0]; /* Call igraph */ - IGRAPH_R_CHECK(igraph_all_st_cuts(&c_graph, c_cuts, c_partition1s, c_source, c_target)); + IGRAPH_R_CHECK(igraph_all_st_cuts(&c_graph, &c_cuts, &c_partition1s, c_source, c_target)); /* Convert output */ PROTECT(r_result=NEW_LIST(2)); PROTECT(r_names=NEW_CHARACTER(2)); + PROTECT(cuts=R_igraph_vector_int_list_to_SEXPp1(&c_cuts)); + igraph_vector_int_list_destroy(&c_cuts); + IGRAPH_FINALLY_CLEAN(1); + PROTECT(partition1s=R_igraph_vector_int_list_to_SEXPp1(&c_partition1s)); + igraph_vector_int_list_destroy(&c_partition1s); + IGRAPH_FINALLY_CLEAN(1); SET_VECTOR_ELT(r_result, 0, cuts); SET_VECTOR_ELT(r_result, 1, partition1s); SET_STRING_ELT(r_names, 0, Rf_mkChar("cuts")); @@ -8936,16 +9298,31 @@ SEXP R_igraph_all_st_mincuts(SEXP graph, SEXP source, SEXP target, SEXP capacity SEXP r_result, r_names; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); + if (0 != igraph_vector_int_list_init(&c_cuts, 0)) { + igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); + } + IGRAPH_FINALLY(igraph_vector_int_list_destroy, &c_cuts); + if (0 != igraph_vector_int_list_init(&c_partition1s, 0)) { + igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); + } + IGRAPH_FINALLY(igraph_vector_int_list_destroy, &c_partition1s); c_source = (igraph_integer_t) REAL(source)[0]; c_target = (igraph_integer_t) REAL(target)[0]; + if (!Rf_isNull(capacity)) { R_SEXP_to_vector(capacity, &c_capacity); } /* Call igraph */ - IGRAPH_R_CHECK(igraph_all_st_mincuts(&c_graph, &c_value, c_cuts, c_partition1s, c_source, c_target, (Rf_isNull(capacity) ? 0 : c_capacity))); + IGRAPH_R_CHECK(igraph_all_st_mincuts(&c_graph, &c_value, &c_cuts, &c_partition1s, c_source, c_target, (Rf_isNull(capacity) ? 0 : (Rf_isNull(capacity) ? 0 : &c_capacity)))); /* Convert output */ PROTECT(r_result=NEW_LIST(3)); PROTECT(r_names=NEW_CHARACTER(3)); PROTECT(value=NEW_NUMERIC(1)); REAL(value)[0]=c_value; + PROTECT(cuts=R_igraph_vector_int_list_to_SEXPp1(&c_cuts)); + igraph_vector_int_list_destroy(&c_cuts); + IGRAPH_FINALLY_CLEAN(1); + PROTECT(partition1s=R_igraph_vector_int_list_to_SEXPp1(&c_partition1s)); + igraph_vector_int_list_destroy(&c_partition1s); + IGRAPH_FINALLY_CLEAN(1); SET_VECTOR_ELT(r_result, 0, value); SET_VECTOR_ELT(r_result, 1, cuts); SET_VECTOR_ELT(r_result, 2, partition1s); @@ -8973,8 +9350,13 @@ SEXP R_igraph_even_tarjan_reduction(SEXP graph) { SEXP r_result, r_names; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); + if (0 != igraph_vector_init(&c_capacity, 0)) { + igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); + } + IGRAPH_FINALLY(igraph_vector_destroy, &c_capacity); + capacity=R_GlobalEnv; /* hack to have a non-NULL value */ /* Call igraph */ - IGRAPH_R_CHECK(igraph_even_tarjan_reduction(&c_graph, &c_graphbar, c_capacity)); + IGRAPH_R_CHECK(igraph_even_tarjan_reduction(&c_graph, &c_graphbar, (Rf_isNull(capacity) ? 0 : &c_capacity))); /* Convert output */ PROTECT(r_result=NEW_LIST(2)); @@ -8983,6 +9365,9 @@ SEXP R_igraph_even_tarjan_reduction(SEXP graph) { PROTECT(graphbar=R_igraph_to_SEXP(&c_graphbar)); IGRAPH_I_DESTROY(&c_graphbar); IGRAPH_FINALLY_CLEAN(1); + PROTECT(capacity=R_igraph_0orvector_to_SEXP(&c_capacity)); + igraph_vector_destroy(&c_capacity); + IGRAPH_FINALLY_CLEAN(1); SET_VECTOR_ELT(r_result, 0, graphbar); SET_VECTOR_ELT(r_result, 1, capacity); SET_STRING_ELT(r_names, 0, Rf_mkChar("graphbar")); @@ -9064,11 +9449,17 @@ SEXP R_igraph_all_minimal_st_separators(SEXP graph) { SEXP r_result; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); + if (0 != igraph_vector_int_list_init(&c_separators, 0)) { + igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); + } + IGRAPH_FINALLY(igraph_vector_int_list_destroy, &c_separators); /* Call igraph */ - IGRAPH_R_CHECK(igraph_all_minimal_st_separators(&c_graph, c_separators)); + IGRAPH_R_CHECK(igraph_all_minimal_st_separators(&c_graph, &c_separators)); /* Convert output */ - + PROTECT(separators=R_igraph_vector_int_list_to_SEXPp1(&c_separators)); + igraph_vector_int_list_destroy(&c_separators); + IGRAPH_FINALLY_CLEAN(1); r_result = separators; UNPROTECT(1); @@ -9087,11 +9478,17 @@ SEXP R_igraph_minimum_size_separators(SEXP graph) { SEXP r_result; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); + if (0 != igraph_vector_int_list_init(&c_separators, 0)) { + igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); + } + IGRAPH_FINALLY(igraph_vector_int_list_destroy, &c_separators); /* Call igraph */ - IGRAPH_R_CHECK(igraph_minimum_size_separators(&c_graph, c_separators)); + IGRAPH_R_CHECK(igraph_minimum_size_separators(&c_graph, &c_separators)); /* Convert output */ - + PROTECT(separators=R_igraph_vector_int_list_to_SEXPp1(&c_separators)); + igraph_vector_int_list_destroy(&c_separators); + IGRAPH_FINALLY_CLEAN(1); r_result = separators; UNPROTECT(1); @@ -9162,11 +9559,25 @@ SEXP R_igraph_automorphism_group(SEXP graph, SEXP colors) { SEXP r_result; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); + if (!Rf_isNull(colors)) { + R_SEXP_to_vector_int_copy(colors, &c_colors); + } else { + IGRAPH_R_CHECK(igraph_vector_int_init(&c_colors, 0)); + } + IGRAPH_FINALLY(igraph_vector_int_destroy, &c_colors); + if (0 != igraph_vector_int_list_init(&c_generators, 0)) { + igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); + } + IGRAPH_FINALLY(igraph_vector_int_list_destroy, &c_generators); /* Call igraph */ - IGRAPH_R_CHECK(igraph_automorphism_group(&c_graph, (Rf_isNull(colors) ? 0 : c_colors), c_generators)); + IGRAPH_R_CHECK(igraph_automorphism_group(&c_graph, (Rf_isNull(colors) ? 0 : (Rf_isNull(colors) ? 0 : &c_colors)), &c_generators)); /* Convert output */ - + igraph_vector_int_destroy(&c_colors); + IGRAPH_FINALLY_CLEAN(1); + PROTECT(generators=R_igraph_vector_int_list_to_SEXPp1(&c_generators)); + igraph_vector_int_list_destroy(&c_generators); + IGRAPH_FINALLY_CLEAN(1); r_result = generators; UNPROTECT(1); @@ -9186,10 +9597,18 @@ SEXP R_igraph_count_automorphisms(SEXP graph, SEXP colors) { SEXP r_result; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); + if (!Rf_isNull(colors)) { + R_SEXP_to_vector_int_copy(colors, &c_colors); + } else { + IGRAPH_R_CHECK(igraph_vector_int_init(&c_colors, 0)); + } + IGRAPH_FINALLY(igraph_vector_int_destroy, &c_colors); /* Call igraph */ - IGRAPH_R_CHECK(igraph_count_automorphisms(&c_graph, (Rf_isNull(colors) ? 0 : c_colors), &c_result)); + IGRAPH_R_CHECK(igraph_count_automorphisms(&c_graph, (Rf_isNull(colors) ? 0 : (Rf_isNull(colors) ? 0 : &c_colors)), &c_result)); /* Convert output */ + igraph_vector_int_destroy(&c_colors); + IGRAPH_FINALLY_CLEAN(1); PROTECT(result=NEW_NUMERIC(1)); REAL(result)[0]=c_result; r_result = result; @@ -9286,6 +9705,30 @@ SEXP R_igraph_isomorphic_vf2(SEXP graph1, SEXP graph2, SEXP vertex_color1, SEXP /* Convert input */ R_SEXP_to_igraph(graph1, &c_graph1); R_SEXP_to_igraph(graph2, &c_graph2); + if (!Rf_isNull(vertex_color1)) { + R_SEXP_to_vector_int_copy(vertex_color1, &c_vertex_color1); + } else { + IGRAPH_R_CHECK(igraph_vector_int_init(&c_vertex_color1, 0)); + } + IGRAPH_FINALLY(igraph_vector_int_destroy, &c_vertex_color1); + if (!Rf_isNull(vertex_color2)) { + R_SEXP_to_vector_int_copy(vertex_color2, &c_vertex_color2); + } else { + IGRAPH_R_CHECK(igraph_vector_int_init(&c_vertex_color2, 0)); + } + IGRAPH_FINALLY(igraph_vector_int_destroy, &c_vertex_color2); + if (!Rf_isNull(edge_color1)) { + R_SEXP_to_vector_int_copy(edge_color1, &c_edge_color1); + } else { + IGRAPH_R_CHECK(igraph_vector_int_init(&c_edge_color1, 0)); + } + IGRAPH_FINALLY(igraph_vector_int_destroy, &c_edge_color1); + if (!Rf_isNull(edge_color2)) { + R_SEXP_to_vector_int_copy(edge_color2, &c_edge_color2); + } else { + IGRAPH_R_CHECK(igraph_vector_int_init(&c_edge_color2, 0)); + } + IGRAPH_FINALLY(igraph_vector_int_destroy, &c_edge_color2); if (0 != igraph_vector_int_init(&c_map12, 0)) { igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); } @@ -9295,11 +9738,19 @@ SEXP R_igraph_isomorphic_vf2(SEXP graph1, SEXP graph2, SEXP vertex_color1, SEXP } IGRAPH_FINALLY(igraph_vector_int_destroy, &c_map21); /* Call igraph */ - IGRAPH_R_CHECK(igraph_isomorphic_vf2(&c_graph1, &c_graph2, (Rf_isNull(vertex_color1) ? 0 : c_vertex_color1), (Rf_isNull(vertex_color2) ? 0 : c_vertex_color2), (Rf_isNull(edge_color1) ? 0 : c_edge_color1), (Rf_isNull(edge_color2) ? 0 : c_edge_color2), &c_iso, &c_map12, &c_map21, 0, 0, 0)); + IGRAPH_R_CHECK(igraph_isomorphic_vf2(&c_graph1, &c_graph2, (Rf_isNull(vertex_color1) ? 0 : (Rf_isNull(vertex_color1) ? 0 : &c_vertex_color1)), (Rf_isNull(vertex_color2) ? 0 : (Rf_isNull(vertex_color2) ? 0 : &c_vertex_color2)), (Rf_isNull(edge_color1) ? 0 : (Rf_isNull(edge_color1) ? 0 : &c_edge_color1)), (Rf_isNull(edge_color2) ? 0 : (Rf_isNull(edge_color2) ? 0 : &c_edge_color2)), &c_iso, &c_map12, &c_map21, 0, 0, 0)); /* Convert output */ PROTECT(r_result=NEW_LIST(3)); PROTECT(r_names=NEW_CHARACTER(3)); + igraph_vector_int_destroy(&c_vertex_color1); + IGRAPH_FINALLY_CLEAN(1); + igraph_vector_int_destroy(&c_vertex_color2); + IGRAPH_FINALLY_CLEAN(1); + igraph_vector_int_destroy(&c_edge_color1); + IGRAPH_FINALLY_CLEAN(1); + igraph_vector_int_destroy(&c_edge_color2); + IGRAPH_FINALLY_CLEAN(1); PROTECT(iso=NEW_LOGICAL(1)); LOGICAL(iso)[0]=c_iso; PROTECT(map12=R_igraph_vector_int_to_SEXPp1(&c_map12)); @@ -9342,11 +9793,43 @@ SEXP R_igraph_count_isomorphisms_vf2(SEXP graph1, SEXP graph2, SEXP vertex_color /* Convert input */ R_SEXP_to_igraph(graph1, &c_graph1); R_SEXP_to_igraph(graph2, &c_graph2); + if (!Rf_isNull(vertex_color1)) { + R_SEXP_to_vector_int_copy(vertex_color1, &c_vertex_color1); + } else { + IGRAPH_R_CHECK(igraph_vector_int_init(&c_vertex_color1, 0)); + } + IGRAPH_FINALLY(igraph_vector_int_destroy, &c_vertex_color1); + if (!Rf_isNull(vertex_color2)) { + R_SEXP_to_vector_int_copy(vertex_color2, &c_vertex_color2); + } else { + IGRAPH_R_CHECK(igraph_vector_int_init(&c_vertex_color2, 0)); + } + IGRAPH_FINALLY(igraph_vector_int_destroy, &c_vertex_color2); + if (!Rf_isNull(edge_color1)) { + R_SEXP_to_vector_int_copy(edge_color1, &c_edge_color1); + } else { + IGRAPH_R_CHECK(igraph_vector_int_init(&c_edge_color1, 0)); + } + IGRAPH_FINALLY(igraph_vector_int_destroy, &c_edge_color1); + if (!Rf_isNull(edge_color2)) { + R_SEXP_to_vector_int_copy(edge_color2, &c_edge_color2); + } else { + IGRAPH_R_CHECK(igraph_vector_int_init(&c_edge_color2, 0)); + } + IGRAPH_FINALLY(igraph_vector_int_destroy, &c_edge_color2); c_count=0; /* Call igraph */ - IGRAPH_R_CHECK(igraph_count_isomorphisms_vf2(&c_graph1, &c_graph2, c_vertex_color1, c_vertex_color2, c_edge_color1, c_edge_color2, &c_count, 0, 0, 0)); + IGRAPH_R_CHECK(igraph_count_isomorphisms_vf2(&c_graph1, &c_graph2, (Rf_isNull(vertex_color1) ? 0 : &c_vertex_color1), (Rf_isNull(vertex_color2) ? 0 : &c_vertex_color2), (Rf_isNull(edge_color1) ? 0 : &c_edge_color1), (Rf_isNull(edge_color2) ? 0 : &c_edge_color2), &c_count, 0, 0, 0)); /* Convert output */ + igraph_vector_int_destroy(&c_vertex_color1); + IGRAPH_FINALLY_CLEAN(1); + igraph_vector_int_destroy(&c_vertex_color2); + IGRAPH_FINALLY_CLEAN(1); + igraph_vector_int_destroy(&c_edge_color1); + IGRAPH_FINALLY_CLEAN(1); + igraph_vector_int_destroy(&c_edge_color2); + IGRAPH_FINALLY_CLEAN(1); PROTECT(count=NEW_NUMERIC(1)); REAL(count)[0]=(double) c_count; r_result = count; @@ -9376,14 +9859,46 @@ SEXP R_igraph_get_isomorphisms_vf2(SEXP graph1, SEXP graph2, SEXP vertex_color1, /* Convert input */ R_SEXP_to_igraph(graph1, &c_graph1); R_SEXP_to_igraph(graph2, &c_graph2); + if (!Rf_isNull(vertex_color1)) { + R_SEXP_to_vector_int_copy(vertex_color1, &c_vertex_color1); + } else { + IGRAPH_R_CHECK(igraph_vector_int_init(&c_vertex_color1, 0)); + } + IGRAPH_FINALLY(igraph_vector_int_destroy, &c_vertex_color1); + if (!Rf_isNull(vertex_color2)) { + R_SEXP_to_vector_int_copy(vertex_color2, &c_vertex_color2); + } else { + IGRAPH_R_CHECK(igraph_vector_int_init(&c_vertex_color2, 0)); + } + IGRAPH_FINALLY(igraph_vector_int_destroy, &c_vertex_color2); + if (!Rf_isNull(edge_color1)) { + R_SEXP_to_vector_int_copy(edge_color1, &c_edge_color1); + } else { + IGRAPH_R_CHECK(igraph_vector_int_init(&c_edge_color1, 0)); + } + IGRAPH_FINALLY(igraph_vector_int_destroy, &c_edge_color1); + if (!Rf_isNull(edge_color2)) { + R_SEXP_to_vector_int_copy(edge_color2, &c_edge_color2); + } else { + IGRAPH_R_CHECK(igraph_vector_int_init(&c_edge_color2, 0)); + } + IGRAPH_FINALLY(igraph_vector_int_destroy, &c_edge_color2); if (0 != igraph_vector_int_list_init(&c_maps, 0)) { igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_vector_int_list_destroy, &c_maps); /* Call igraph */ - IGRAPH_R_CHECK(igraph_get_isomorphisms_vf2(&c_graph1, &c_graph2, c_vertex_color1, c_vertex_color2, c_edge_color1, c_edge_color2, &c_maps, 0, 0, 0)); + IGRAPH_R_CHECK(igraph_get_isomorphisms_vf2(&c_graph1, &c_graph2, (Rf_isNull(vertex_color1) ? 0 : &c_vertex_color1), (Rf_isNull(vertex_color2) ? 0 : &c_vertex_color2), (Rf_isNull(edge_color1) ? 0 : &c_edge_color1), (Rf_isNull(edge_color2) ? 0 : &c_edge_color2), &c_maps, 0, 0, 0)); /* Convert output */ + igraph_vector_int_destroy(&c_vertex_color1); + IGRAPH_FINALLY_CLEAN(1); + igraph_vector_int_destroy(&c_vertex_color2); + IGRAPH_FINALLY_CLEAN(1); + igraph_vector_int_destroy(&c_edge_color1); + IGRAPH_FINALLY_CLEAN(1); + igraph_vector_int_destroy(&c_edge_color2); + IGRAPH_FINALLY_CLEAN(1); PROTECT(maps=R_igraph_vector_int_list_to_SEXP(&c_maps)); igraph_vector_int_list_destroy(&c_maps); IGRAPH_FINALLY_CLEAN(1); @@ -9444,6 +9959,30 @@ SEXP R_igraph_subisomorphic_vf2(SEXP graph1, SEXP graph2, SEXP vertex_color1, SE /* Convert input */ R_SEXP_to_igraph(graph1, &c_graph1); R_SEXP_to_igraph(graph2, &c_graph2); + if (!Rf_isNull(vertex_color1)) { + R_SEXP_to_vector_int_copy(vertex_color1, &c_vertex_color1); + } else { + IGRAPH_R_CHECK(igraph_vector_int_init(&c_vertex_color1, 0)); + } + IGRAPH_FINALLY(igraph_vector_int_destroy, &c_vertex_color1); + if (!Rf_isNull(vertex_color2)) { + R_SEXP_to_vector_int_copy(vertex_color2, &c_vertex_color2); + } else { + IGRAPH_R_CHECK(igraph_vector_int_init(&c_vertex_color2, 0)); + } + IGRAPH_FINALLY(igraph_vector_int_destroy, &c_vertex_color2); + if (!Rf_isNull(edge_color1)) { + R_SEXP_to_vector_int_copy(edge_color1, &c_edge_color1); + } else { + IGRAPH_R_CHECK(igraph_vector_int_init(&c_edge_color1, 0)); + } + IGRAPH_FINALLY(igraph_vector_int_destroy, &c_edge_color1); + if (!Rf_isNull(edge_color2)) { + R_SEXP_to_vector_int_copy(edge_color2, &c_edge_color2); + } else { + IGRAPH_R_CHECK(igraph_vector_int_init(&c_edge_color2, 0)); + } + IGRAPH_FINALLY(igraph_vector_int_destroy, &c_edge_color2); if (0 != igraph_vector_int_init(&c_map12, 0)) { igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); } @@ -9453,11 +9992,19 @@ SEXP R_igraph_subisomorphic_vf2(SEXP graph1, SEXP graph2, SEXP vertex_color1, SE } IGRAPH_FINALLY(igraph_vector_int_destroy, &c_map21); /* Call igraph */ - IGRAPH_R_CHECK(igraph_subisomorphic_vf2(&c_graph1, &c_graph2, (Rf_isNull(vertex_color1) ? 0 : c_vertex_color1), (Rf_isNull(vertex_color2) ? 0 : c_vertex_color2), (Rf_isNull(edge_color1) ? 0 : c_edge_color1), (Rf_isNull(edge_color2) ? 0 : c_edge_color2), &c_iso, &c_map12, &c_map21, 0, 0, 0)); + IGRAPH_R_CHECK(igraph_subisomorphic_vf2(&c_graph1, &c_graph2, (Rf_isNull(vertex_color1) ? 0 : (Rf_isNull(vertex_color1) ? 0 : &c_vertex_color1)), (Rf_isNull(vertex_color2) ? 0 : (Rf_isNull(vertex_color2) ? 0 : &c_vertex_color2)), (Rf_isNull(edge_color1) ? 0 : (Rf_isNull(edge_color1) ? 0 : &c_edge_color1)), (Rf_isNull(edge_color2) ? 0 : (Rf_isNull(edge_color2) ? 0 : &c_edge_color2)), &c_iso, &c_map12, &c_map21, 0, 0, 0)); /* Convert output */ PROTECT(r_result=NEW_LIST(3)); PROTECT(r_names=NEW_CHARACTER(3)); + igraph_vector_int_destroy(&c_vertex_color1); + IGRAPH_FINALLY_CLEAN(1); + igraph_vector_int_destroy(&c_vertex_color2); + IGRAPH_FINALLY_CLEAN(1); + igraph_vector_int_destroy(&c_edge_color1); + IGRAPH_FINALLY_CLEAN(1); + igraph_vector_int_destroy(&c_edge_color2); + IGRAPH_FINALLY_CLEAN(1); PROTECT(iso=NEW_LOGICAL(1)); LOGICAL(iso)[0]=c_iso; PROTECT(map12=R_igraph_vector_int_to_SEXPp1(&c_map12)); @@ -9500,11 +10047,43 @@ SEXP R_igraph_count_subisomorphisms_vf2(SEXP graph1, SEXP graph2, SEXP vertex_co /* Convert input */ R_SEXP_to_igraph(graph1, &c_graph1); R_SEXP_to_igraph(graph2, &c_graph2); + if (!Rf_isNull(vertex_color1)) { + R_SEXP_to_vector_int_copy(vertex_color1, &c_vertex_color1); + } else { + IGRAPH_R_CHECK(igraph_vector_int_init(&c_vertex_color1, 0)); + } + IGRAPH_FINALLY(igraph_vector_int_destroy, &c_vertex_color1); + if (!Rf_isNull(vertex_color2)) { + R_SEXP_to_vector_int_copy(vertex_color2, &c_vertex_color2); + } else { + IGRAPH_R_CHECK(igraph_vector_int_init(&c_vertex_color2, 0)); + } + IGRAPH_FINALLY(igraph_vector_int_destroy, &c_vertex_color2); + if (!Rf_isNull(edge_color1)) { + R_SEXP_to_vector_int_copy(edge_color1, &c_edge_color1); + } else { + IGRAPH_R_CHECK(igraph_vector_int_init(&c_edge_color1, 0)); + } + IGRAPH_FINALLY(igraph_vector_int_destroy, &c_edge_color1); + if (!Rf_isNull(edge_color2)) { + R_SEXP_to_vector_int_copy(edge_color2, &c_edge_color2); + } else { + IGRAPH_R_CHECK(igraph_vector_int_init(&c_edge_color2, 0)); + } + IGRAPH_FINALLY(igraph_vector_int_destroy, &c_edge_color2); c_count=0; /* Call igraph */ - IGRAPH_R_CHECK(igraph_count_subisomorphisms_vf2(&c_graph1, &c_graph2, c_vertex_color1, c_vertex_color2, c_edge_color1, c_edge_color2, &c_count, 0, 0, 0)); + IGRAPH_R_CHECK(igraph_count_subisomorphisms_vf2(&c_graph1, &c_graph2, (Rf_isNull(vertex_color1) ? 0 : &c_vertex_color1), (Rf_isNull(vertex_color2) ? 0 : &c_vertex_color2), (Rf_isNull(edge_color1) ? 0 : &c_edge_color1), (Rf_isNull(edge_color2) ? 0 : &c_edge_color2), &c_count, 0, 0, 0)); /* Convert output */ + igraph_vector_int_destroy(&c_vertex_color1); + IGRAPH_FINALLY_CLEAN(1); + igraph_vector_int_destroy(&c_vertex_color2); + IGRAPH_FINALLY_CLEAN(1); + igraph_vector_int_destroy(&c_edge_color1); + IGRAPH_FINALLY_CLEAN(1); + igraph_vector_int_destroy(&c_edge_color2); + IGRAPH_FINALLY_CLEAN(1); PROTECT(count=NEW_NUMERIC(1)); REAL(count)[0]=(double) c_count; r_result = count; @@ -9534,14 +10113,46 @@ SEXP R_igraph_get_subisomorphisms_vf2(SEXP graph1, SEXP graph2, SEXP vertex_colo /* Convert input */ R_SEXP_to_igraph(graph1, &c_graph1); R_SEXP_to_igraph(graph2, &c_graph2); + if (!Rf_isNull(vertex_color1)) { + R_SEXP_to_vector_int_copy(vertex_color1, &c_vertex_color1); + } else { + IGRAPH_R_CHECK(igraph_vector_int_init(&c_vertex_color1, 0)); + } + IGRAPH_FINALLY(igraph_vector_int_destroy, &c_vertex_color1); + if (!Rf_isNull(vertex_color2)) { + R_SEXP_to_vector_int_copy(vertex_color2, &c_vertex_color2); + } else { + IGRAPH_R_CHECK(igraph_vector_int_init(&c_vertex_color2, 0)); + } + IGRAPH_FINALLY(igraph_vector_int_destroy, &c_vertex_color2); + if (!Rf_isNull(edge_color1)) { + R_SEXP_to_vector_int_copy(edge_color1, &c_edge_color1); + } else { + IGRAPH_R_CHECK(igraph_vector_int_init(&c_edge_color1, 0)); + } + IGRAPH_FINALLY(igraph_vector_int_destroy, &c_edge_color1); + if (!Rf_isNull(edge_color2)) { + R_SEXP_to_vector_int_copy(edge_color2, &c_edge_color2); + } else { + IGRAPH_R_CHECK(igraph_vector_int_init(&c_edge_color2, 0)); + } + IGRAPH_FINALLY(igraph_vector_int_destroy, &c_edge_color2); if (0 != igraph_vector_int_list_init(&c_maps, 0)) { igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_vector_int_list_destroy, &c_maps); /* Call igraph */ - IGRAPH_R_CHECK(igraph_get_subisomorphisms_vf2(&c_graph1, &c_graph2, c_vertex_color1, c_vertex_color2, c_edge_color1, c_edge_color2, &c_maps, 0, 0, 0)); + IGRAPH_R_CHECK(igraph_get_subisomorphisms_vf2(&c_graph1, &c_graph2, (Rf_isNull(vertex_color1) ? 0 : &c_vertex_color1), (Rf_isNull(vertex_color2) ? 0 : &c_vertex_color2), (Rf_isNull(edge_color1) ? 0 : &c_edge_color1), (Rf_isNull(edge_color2) ? 0 : &c_edge_color2), &c_maps, 0, 0, 0)); /* Convert output */ + igraph_vector_int_destroy(&c_vertex_color1); + IGRAPH_FINALLY_CLEAN(1); + igraph_vector_int_destroy(&c_vertex_color2); + IGRAPH_FINALLY_CLEAN(1); + igraph_vector_int_destroy(&c_edge_color1); + IGRAPH_FINALLY_CLEAN(1); + igraph_vector_int_destroy(&c_edge_color2); + IGRAPH_FINALLY_CLEAN(1); PROTECT(maps=R_igraph_vector_int_list_to_SEXP(&c_maps)); igraph_vector_int_list_destroy(&c_maps); IGRAPH_FINALLY_CLEAN(1); @@ -9564,14 +10175,22 @@ SEXP R_igraph_canonical_permutation(SEXP graph, SEXP colors) { SEXP r_result; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); + if (!Rf_isNull(colors)) { + R_SEXP_to_vector_int_copy(colors, &c_colors); + } else { + IGRAPH_R_CHECK(igraph_vector_int_init(&c_colors, 0)); + } + IGRAPH_FINALLY(igraph_vector_int_destroy, &c_colors); if (0 != igraph_vector_int_init(&c_labeling, 0)) { igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_vector_int_destroy, &c_labeling); /* Call igraph */ - IGRAPH_R_CHECK(igraph_canonical_permutation(&c_graph, (Rf_isNull(colors) ? 0 : c_colors), &c_labeling)); + IGRAPH_R_CHECK(igraph_canonical_permutation(&c_graph, (Rf_isNull(colors) ? 0 : (Rf_isNull(colors) ? 0 : &c_colors)), &c_labeling)); /* Convert output */ + igraph_vector_int_destroy(&c_colors); + IGRAPH_FINALLY_CLEAN(1); PROTECT(labeling=R_igraph_vector_int_to_SEXPp1(&c_labeling)); igraph_vector_int_destroy(&c_labeling); IGRAPH_FINALLY_CLEAN(1); @@ -9597,17 +10216,25 @@ SEXP R_igraph_canonical_permutation_bliss(SEXP graph, SEXP colors, SEXP sh) { SEXP r_result, r_names; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); + if (!Rf_isNull(colors)) { + R_SEXP_to_vector_int_copy(colors, &c_colors); + } else { + IGRAPH_R_CHECK(igraph_vector_int_init(&c_colors, 0)); + } + IGRAPH_FINALLY(igraph_vector_int_destroy, &c_colors); if (0 != igraph_vector_int_init(&c_labeling, 0)) { igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_vector_int_destroy, &c_labeling); c_sh = (igraph_bliss_sh_t) Rf_asInteger(sh); /* Call igraph */ - IGRAPH_R_CHECK(igraph_canonical_permutation_bliss(&c_graph, (Rf_isNull(colors) ? 0 : c_colors), &c_labeling, c_sh, &c_info)); + IGRAPH_R_CHECK(igraph_canonical_permutation_bliss(&c_graph, (Rf_isNull(colors) ? 0 : (Rf_isNull(colors) ? 0 : &c_colors)), &c_labeling, c_sh, &c_info)); /* Convert output */ PROTECT(r_result=NEW_LIST(2)); PROTECT(r_names=NEW_CHARACTER(2)); + igraph_vector_int_destroy(&c_colors); + IGRAPH_FINALLY_CLEAN(1); PROTECT(labeling=R_igraph_vector_int_to_SEXPp1(&c_labeling)); igraph_vector_int_destroy(&c_labeling); IGRAPH_FINALLY_CLEAN(1); @@ -9680,6 +10307,18 @@ SEXP R_igraph_isomorphic_bliss(SEXP graph1, SEXP graph2, SEXP colors1, SEXP colo /* Convert input */ R_SEXP_to_igraph(graph1, &c_graph1); R_SEXP_to_igraph(graph2, &c_graph2); + if (!Rf_isNull(colors1)) { + R_SEXP_to_vector_int_copy(colors1, &c_colors1); + } else { + IGRAPH_R_CHECK(igraph_vector_int_init(&c_colors1, 0)); + } + IGRAPH_FINALLY(igraph_vector_int_destroy, &c_colors1); + if (!Rf_isNull(colors2)) { + R_SEXP_to_vector_int_copy(colors2, &c_colors2); + } else { + IGRAPH_R_CHECK(igraph_vector_int_init(&c_colors2, 0)); + } + IGRAPH_FINALLY(igraph_vector_int_destroy, &c_colors2); if (0 != igraph_vector_int_init(&c_map12, 0)) { igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); } @@ -9690,11 +10329,15 @@ SEXP R_igraph_isomorphic_bliss(SEXP graph1, SEXP graph2, SEXP colors1, SEXP colo IGRAPH_FINALLY(igraph_vector_int_destroy, &c_map21); c_sh = (igraph_bliss_sh_t) Rf_asInteger(sh); /* Call igraph */ - IGRAPH_R_CHECK(igraph_isomorphic_bliss(&c_graph1, &c_graph2, (Rf_isNull(colors1) ? 0 : c_colors1), (Rf_isNull(colors2) ? 0 : c_colors2), &c_iso, &c_map12, &c_map21, c_sh, &c_info1, &c_info2)); + IGRAPH_R_CHECK(igraph_isomorphic_bliss(&c_graph1, &c_graph2, (Rf_isNull(colors1) ? 0 : (Rf_isNull(colors1) ? 0 : &c_colors1)), (Rf_isNull(colors2) ? 0 : (Rf_isNull(colors2) ? 0 : &c_colors2)), &c_iso, &c_map12, &c_map21, c_sh, &c_info1, &c_info2)); /* Convert output */ PROTECT(r_result=NEW_LIST(5)); PROTECT(r_names=NEW_CHARACTER(5)); + igraph_vector_int_destroy(&c_colors1); + IGRAPH_FINALLY_CLEAN(1); + igraph_vector_int_destroy(&c_colors2); + IGRAPH_FINALLY_CLEAN(1); PROTECT(iso=NEW_LOGICAL(1)); LOGICAL(iso)[0]=c_iso; PROTECT(map12=R_igraph_vector_int_to_SEXPp1(&c_map12)); @@ -9738,11 +10381,19 @@ SEXP R_igraph_count_automorphisms_bliss(SEXP graph, SEXP colors, SEXP sh) { SEXP r_result; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); + if (!Rf_isNull(colors)) { + R_SEXP_to_vector_int_copy(colors, &c_colors); + } else { + IGRAPH_R_CHECK(igraph_vector_int_init(&c_colors, 0)); + } + IGRAPH_FINALLY(igraph_vector_int_destroy, &c_colors); c_sh = (igraph_bliss_sh_t) Rf_asInteger(sh); /* Call igraph */ - IGRAPH_R_CHECK(igraph_count_automorphisms_bliss(&c_graph, (Rf_isNull(colors) ? 0 : c_colors), c_sh, &c_info)); + IGRAPH_R_CHECK(igraph_count_automorphisms_bliss(&c_graph, (Rf_isNull(colors) ? 0 : (Rf_isNull(colors) ? 0 : &c_colors)), c_sh, &c_info)); /* Convert output */ + igraph_vector_int_destroy(&c_colors); + IGRAPH_FINALLY_CLEAN(1); PROTECT(info=R_igraph_bliss_info_to_SEXP(&c_info)); if (c_info.group_size) { free(c_info.group_size); } r_result = info; @@ -9767,13 +10418,28 @@ SEXP R_igraph_automorphism_group_bliss(SEXP graph, SEXP colors, SEXP sh) { SEXP r_result, r_names; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); + if (!Rf_isNull(colors)) { + R_SEXP_to_vector_int_copy(colors, &c_colors); + } else { + IGRAPH_R_CHECK(igraph_vector_int_init(&c_colors, 0)); + } + IGRAPH_FINALLY(igraph_vector_int_destroy, &c_colors); + if (0 != igraph_vector_int_list_init(&c_generators, 0)) { + igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); + } + IGRAPH_FINALLY(igraph_vector_int_list_destroy, &c_generators); c_sh = (igraph_bliss_sh_t) Rf_asInteger(sh); /* Call igraph */ - IGRAPH_R_CHECK(igraph_automorphism_group_bliss(&c_graph, (Rf_isNull(colors) ? 0 : c_colors), c_generators, c_sh, &c_info)); + IGRAPH_R_CHECK(igraph_automorphism_group_bliss(&c_graph, (Rf_isNull(colors) ? 0 : (Rf_isNull(colors) ? 0 : &c_colors)), &c_generators, c_sh, &c_info)); /* Convert output */ PROTECT(r_result=NEW_LIST(2)); PROTECT(r_names=NEW_CHARACTER(2)); + igraph_vector_int_destroy(&c_colors); + IGRAPH_FINALLY_CLEAN(1); + PROTECT(generators=R_igraph_vector_int_list_to_SEXPp1(&c_generators)); + igraph_vector_int_list_destroy(&c_generators); + IGRAPH_FINALLY_CLEAN(1); PROTECT(info=R_igraph_bliss_info_to_SEXP(&c_info)); if (c_info.group_size) { free(c_info.group_size); } SET_VECTOR_ELT(r_result, 0, generators); @@ -9956,10 +10622,11 @@ SEXP R_igraph_maximum_bipartite_matching(SEXP graph, SEXP types, SEXP weights, S igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_vector_int_destroy, &c_matching); + if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } IGRAPH_R_CHECK_REAL(eps); c_eps = REAL(eps)[0]; /* Call igraph */ - IGRAPH_R_CHECK(igraph_maximum_bipartite_matching(&c_graph, (Rf_isNull(types) ? 0 : (Rf_isNull(types) ? 0 : &c_types)), &c_matching_size, &c_matching_weight, &c_matching, (Rf_isNull(weights) ? 0 : c_weights), c_eps)); + IGRAPH_R_CHECK(igraph_maximum_bipartite_matching(&c_graph, (Rf_isNull(types) ? 0 : (Rf_isNull(types) ? 0 : &c_types)), &c_matching_size, &c_matching_weight, &c_matching, (Rf_isNull(weights) ? 0 : (Rf_isNull(weights) ? 0 : &c_weights)), c_eps)); /* Convert output */ PROTECT(r_result=NEW_LIST(3)); @@ -9987,13 +10654,13 @@ SEXP R_igraph_maximum_bipartite_matching(SEXP graph, SEXP types, SEXP weights, S /*-------------------------------------------/ / igraph_eigen_adjacency / /-------------------------------------------*/ -SEXP R_igraph_eigen_adjacency(SEXP graph, SEXP algorithm, SEXP which, SEXP options, SEXP storage) { +SEXP R_igraph_eigen_adjacency(SEXP graph, SEXP algorithm, SEXP which, SEXP options) { /* Declarations */ igraph_t c_graph; igraph_eigen_algorithm_t c_algorithm; igraph_eigen_which_t c_which; igraph_arpack_options_t c_options; - igraph_arpack_storage_t c_storage; + igraph_vector_t c_values; igraph_matrix_t c_vectors; igraph_vector_complex_t c_cmplxvalues; @@ -10008,6 +10675,7 @@ SEXP R_igraph_eigen_adjacency(SEXP graph, SEXP algorithm, SEXP which, SEXP optio R_SEXP_to_igraph(graph, &c_graph); c_algorithm = (igraph_eigen_algorithm_t) Rf_asInteger(algorithm); R_SEXP_to_igraph_eigen_which(which, &c_which); + R_SEXP_to_igraph_arpack_options(options, &c_options); if (0 != igraph_vector_init(&c_values, 0)) { igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); } @@ -10027,11 +10695,12 @@ SEXP R_igraph_eigen_adjacency(SEXP graph, SEXP algorithm, SEXP which, SEXP optio IGRAPH_FINALLY(igraph_matrix_complex_destroy, &c_cmplxvectors); cmplxvectors=R_GlobalEnv; /* hack to have a non-NULL value */ /* Call igraph */ - IGRAPH_R_CHECK(igraph_eigen_adjacency(&c_graph, c_algorithm, &c_which, c_options, c_storage, &c_values, &c_vectors, (Rf_isNull(cmplxvalues) ? 0 : &c_cmplxvalues), (Rf_isNull(cmplxvectors) ? 0 : &c_cmplxvectors))); + IGRAPH_R_CHECK(igraph_eigen_adjacency(&c_graph, c_algorithm, &c_which, &c_options, 0, &c_values, &c_vectors, (Rf_isNull(cmplxvalues) ? 0 : &c_cmplxvalues), (Rf_isNull(cmplxvectors) ? 0 : &c_cmplxvectors))); /* Convert output */ - PROTECT(r_result=NEW_LIST(6)); - PROTECT(r_names=NEW_CHARACTER(6)); + PROTECT(r_result=NEW_LIST(5)); + PROTECT(r_names=NEW_CHARACTER(5)); + PROTECT(options=R_igraph_arpack_options_to_SEXP(&c_options)); PROTECT(values=R_igraph_vector_to_SEXP(&c_values)); igraph_vector_destroy(&c_values); IGRAPH_FINALLY_CLEAN(1); @@ -10045,19 +10714,17 @@ SEXP R_igraph_eigen_adjacency(SEXP graph, SEXP algorithm, SEXP which, SEXP optio igraph_matrix_complex_destroy(&c_cmplxvectors); IGRAPH_FINALLY_CLEAN(1); SET_VECTOR_ELT(r_result, 0, options); - SET_VECTOR_ELT(r_result, 1, storage); - SET_VECTOR_ELT(r_result, 2, values); - SET_VECTOR_ELT(r_result, 3, vectors); - SET_VECTOR_ELT(r_result, 4, cmplxvalues); - SET_VECTOR_ELT(r_result, 5, cmplxvectors); + SET_VECTOR_ELT(r_result, 1, values); + SET_VECTOR_ELT(r_result, 2, vectors); + SET_VECTOR_ELT(r_result, 3, cmplxvalues); + SET_VECTOR_ELT(r_result, 4, cmplxvectors); SET_STRING_ELT(r_names, 0, Rf_mkChar("options")); - SET_STRING_ELT(r_names, 1, Rf_mkChar("storage")); - SET_STRING_ELT(r_names, 2, Rf_mkChar("values")); - SET_STRING_ELT(r_names, 3, Rf_mkChar("vectors")); - SET_STRING_ELT(r_names, 4, Rf_mkChar("cmplxvalues")); - SET_STRING_ELT(r_names, 5, Rf_mkChar("cmplxvectors")); + SET_STRING_ELT(r_names, 1, Rf_mkChar("values")); + SET_STRING_ELT(r_names, 2, Rf_mkChar("vectors")); + SET_STRING_ELT(r_names, 3, Rf_mkChar("cmplxvalues")); + SET_STRING_ELT(r_names, 4, Rf_mkChar("cmplxvectors")); SET_NAMES(r_result, r_names); - UNPROTECT(7); + UNPROTECT(6); UNPROTECT(1); return(r_result); @@ -10372,16 +11039,23 @@ SEXP R_igraph_fundamental_cycles(SEXP graph, SEXP start, SEXP bfs_cutoff, SEXP w SEXP r_result; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); + if (0 != igraph_vector_int_list_init(&c_basis, 0)) { + igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); + } + IGRAPH_FINALLY(igraph_vector_int_list_destroy, &c_basis); if (!Rf_isNull(start)) { c_start = (igraph_integer_t) REAL(start)[0]; } IGRAPH_R_CHECK_INT(bfs_cutoff); c_bfs_cutoff = (igraph_integer_t) REAL(bfs_cutoff)[0]; + if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } /* Call igraph */ - IGRAPH_R_CHECK(igraph_fundamental_cycles(&c_graph, c_basis, (Rf_isNull(start) ? 0 : c_start), c_bfs_cutoff, c_weights)); + IGRAPH_R_CHECK(igraph_fundamental_cycles(&c_graph, &c_basis, (Rf_isNull(start) ? 0 : c_start), c_bfs_cutoff, (Rf_isNull(weights) ? 0 : &c_weights))); /* Convert output */ - + PROTECT(basis=R_igraph_vector_int_list_to_SEXPp1(&c_basis)); + igraph_vector_int_list_destroy(&c_basis); + IGRAPH_FINALLY_CLEAN(1); r_result = basis; UNPROTECT(1); @@ -10404,17 +11078,24 @@ SEXP R_igraph_minimum_cycle_basis(SEXP graph, SEXP bfs_cutoff, SEXP complete, SE SEXP r_result; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); + if (0 != igraph_vector_int_list_init(&c_basis, 0)) { + igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); + } + IGRAPH_FINALLY(igraph_vector_int_list_destroy, &c_basis); IGRAPH_R_CHECK_INT(bfs_cutoff); c_bfs_cutoff = (igraph_integer_t) REAL(bfs_cutoff)[0]; IGRAPH_R_CHECK_BOOL(complete); c_complete = LOGICAL(complete)[0]; IGRAPH_R_CHECK_BOOL(use_cycle_order); c_use_cycle_order = LOGICAL(use_cycle_order)[0]; + if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } /* Call igraph */ - IGRAPH_R_CHECK(igraph_minimum_cycle_basis(&c_graph, c_basis, c_bfs_cutoff, c_complete, c_use_cycle_order, c_weights)); + IGRAPH_R_CHECK(igraph_minimum_cycle_basis(&c_graph, &c_basis, c_bfs_cutoff, c_complete, c_use_cycle_order, (Rf_isNull(weights) ? 0 : &c_weights))); /* Convert output */ - + PROTECT(basis=R_igraph_vector_int_list_to_SEXPp1(&c_basis)); + igraph_vector_int_list_destroy(&c_basis); + IGRAPH_FINALLY_CLEAN(1); r_result = basis; UNPROTECT(1); @@ -10692,12 +11373,18 @@ SEXP R_igraph_vertex_coloring_greedy(SEXP graph, SEXP heuristic) { SEXP r_result; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); + if (0 != igraph_vector_int_init(&c_colors, 0)) { + igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); + } + IGRAPH_FINALLY(igraph_vector_int_destroy, &c_colors); c_heuristic = (igraph_coloring_greedy_t) Rf_asInteger(heuristic); /* Call igraph */ - IGRAPH_R_CHECK(igraph_vertex_coloring_greedy(&c_graph, c_colors, c_heuristic)); + IGRAPH_R_CHECK(igraph_vertex_coloring_greedy(&c_graph, &c_colors, c_heuristic)); /* Convert output */ - + PROTECT(colors=R_igraph_vector_int_to_SEXP(&c_colors)); + igraph_vector_int_destroy(&c_colors); + IGRAPH_FINALLY_CLEAN(1); r_result = colors; UNPROTECT(1); @@ -10721,11 +11408,12 @@ SEXP R_igraph_deterministic_optimal_imitation(SEXP graph, SEXP vid, SEXP optimal R_SEXP_to_igraph(graph, &c_graph); c_vid = (igraph_integer_t) REAL(vid)[0]; c_optimality = (igraph_optimal_t) Rf_asInteger(optimality); + R_SEXP_to_vector(quantities, &c_quantities); R_SEXP_to_vector_int_copy(strategies, &c_strategies); IGRAPH_FINALLY(igraph_vector_int_destroy, &c_strategies); c_mode = (igraph_neimode_t) Rf_asInteger(mode); /* Call igraph */ - IGRAPH_R_CHECK(igraph_deterministic_optimal_imitation(&c_graph, c_vid, c_optimality, c_quantities, &c_strategies, c_mode)); + IGRAPH_R_CHECK(igraph_deterministic_optimal_imitation(&c_graph, c_vid, c_optimality, &c_quantities, &c_strategies, c_mode)); /* Convert output */ PROTECT(strategies=R_igraph_vector_int_to_SEXP(&c_strategies)); @@ -10751,15 +11439,23 @@ SEXP R_igraph_moran_process(SEXP graph, SEXP weights, SEXP quantities, SEXP stra SEXP r_result, r_names; /* Convert input */ R_SEXP_to_igraph(graph, &c_graph); + if (!Rf_isNull(weights)) { R_SEXP_to_vector(weights, &c_weights); } + if (0 != R_SEXP_to_vector_copy(quantities, &c_quantities)) { + igraph_error("", __FILE__, __LINE__, IGRAPH_ENOMEM); + } + IGRAPH_FINALLY(igraph_vector_destroy, &c_quantities); R_SEXP_to_vector_int_copy(strategies, &c_strategies); IGRAPH_FINALLY(igraph_vector_int_destroy, &c_strategies); c_mode = (igraph_neimode_t) Rf_asInteger(mode); /* Call igraph */ - IGRAPH_R_CHECK(igraph_moran_process(&c_graph, c_weights, c_quantities, &c_strategies, c_mode)); + IGRAPH_R_CHECK(igraph_moran_process(&c_graph, (Rf_isNull(weights) ? 0 : &c_weights), &c_quantities, &c_strategies, c_mode)); /* Convert output */ PROTECT(r_result=NEW_LIST(2)); PROTECT(r_names=NEW_CHARACTER(2)); + PROTECT(quantities=R_igraph_vector_to_SEXP(&c_quantities)); + igraph_vector_destroy(&c_quantities); + IGRAPH_FINALLY_CLEAN(1); PROTECT(strategies=R_igraph_vector_int_to_SEXP(&c_strategies)); igraph_vector_int_destroy(&c_strategies); IGRAPH_FINALLY_CLEAN(1); @@ -10792,11 +11488,12 @@ SEXP R_igraph_roulette_wheel_imitation(SEXP graph, SEXP vid, SEXP is_local, SEXP c_vid = (igraph_integer_t) REAL(vid)[0]; IGRAPH_R_CHECK_BOOL(is_local); c_is_local = LOGICAL(is_local)[0]; + R_SEXP_to_vector(quantities, &c_quantities); R_SEXP_to_vector_int_copy(strategies, &c_strategies); IGRAPH_FINALLY(igraph_vector_int_destroy, &c_strategies); c_mode = (igraph_neimode_t) Rf_asInteger(mode); /* Call igraph */ - IGRAPH_R_CHECK(igraph_roulette_wheel_imitation(&c_graph, c_vid, c_is_local, c_quantities, &c_strategies, c_mode)); + IGRAPH_R_CHECK(igraph_roulette_wheel_imitation(&c_graph, c_vid, c_is_local, &c_quantities, &c_strategies, c_mode)); /* Convert output */ PROTECT(strategies=R_igraph_vector_int_to_SEXP(&c_strategies)); @@ -10825,11 +11522,12 @@ SEXP R_igraph_stochastic_imitation(SEXP graph, SEXP vid, SEXP algo, SEXP quantit R_SEXP_to_igraph(graph, &c_graph); c_vid = (igraph_integer_t) REAL(vid)[0]; c_algo = (igraph_imitate_algorithm_t) Rf_asInteger(algo); + R_SEXP_to_vector(quantities, &c_quantities); R_SEXP_to_vector_int_copy(strategies, &c_strategies); IGRAPH_FINALLY(igraph_vector_int_destroy, &c_strategies); c_mode = (igraph_neimode_t) Rf_asInteger(mode); /* Call igraph */ - IGRAPH_R_CHECK(igraph_stochastic_imitation(&c_graph, c_vid, c_algo, c_quantities, &c_strategies, c_mode)); + IGRAPH_R_CHECK(igraph_stochastic_imitation(&c_graph, c_vid, c_algo, &c_quantities, &c_strategies, c_mode)); /* Convert output */ PROTECT(strategies=R_igraph_vector_int_to_SEXP(&c_strategies)); @@ -10923,26 +11621,6 @@ SEXP R_igraph_vertex_path_from_edge_path(SEXP graph, SEXP start, SEXP edge_path, IGRAPH_FINALLY_CLEAN(1); r_result = vertex_path; - UNPROTECT(1); - return(r_result); -} - -/*-------------------------------------------/ -/ igraph_delete_vertices_idx / -/-------------------------------------------*/ -SEXP R_igraph_delete_vertices_idx(void) { - /* Declarations */ - igraph_error_t c_result; - SEXP r_result; - /* Convert input */ - - /* Call igraph */ - IGRAPH_R_CHECK(igraph_delete_vertices_idx()); - - /* Convert output */ - - - UNPROTECT(1); return(r_result); } diff --git a/src/rinterface.h b/src/rinterface.h index 2ef7b02705e..c4b7d6d14af 100644 --- a/src/rinterface.h +++ b/src/rinterface.h @@ -37,7 +37,7 @@ #include "uuid/uuid.h" -#define IGRAPH_I_DESTROY IGRAPH_I_ATTRIBUTE_DESTROY +#define IGRAPH_I_DESTROY igraph_i_attribute_destroy SEXP R_igraph_add_env(SEXP graph); diff --git a/src/rinterface_extra.c b/src/rinterface_extra.c index a3235466413..5573b115b0e 100644 --- a/src/rinterface_extra.c +++ b/src/rinterface_extra.c @@ -354,21 +354,21 @@ igraph_error_t R_igraph_attribute_init(igraph_t *graph, igraph_vector_ptr_t *att SET_VECTOR_ELT(gal, i, R_NilValue); switch (rec->type) { case IGRAPH_ATTRIBUTE_NUMERIC: - vec=(igraph_vector_t*) rec->value; + vec=(igraph_vector_t*) rec->value.as_vector; if (igraph_vector_size(vec) > 0) { SET_VECTOR_ELT(gal, i, NEW_NUMERIC(1)); REAL(VECTOR_ELT(gal, i))[0]=VECTOR(*vec)[0]; } break; case IGRAPH_ATTRIBUTE_BOOLEAN: - log=(igraph_vector_bool_t*) rec->value; + log=(igraph_vector_bool_t*) rec->value.as_vector_bool; if (igraph_vector_bool_size(log) > 0) { SET_VECTOR_ELT(gal, i, NEW_LOGICAL(1)); LOGICAL(VECTOR_ELT(gal, i))[0]=VECTOR(*log)[0]; } break; case IGRAPH_ATTRIBUTE_STRING: - strvec=(igraph_strvector_t*) rec->value; + strvec=(igraph_strvector_t*) rec->value.as_strvector; if (igraph_strvector_size(strvec) > 0) { SET_VECTOR_ELT(gal, i, NEW_CHARACTER(1)); SET_STRING_ELT(VECTOR_ELT(gal,i), 0, Rf_mkChar(igraph_strvector_get(strvec, 0))); @@ -433,13 +433,13 @@ SEXP R_igraph_attribute_add_vertices_append1(igraph_vector_ptr_t *nattr, switch (tmprec->type) { case IGRAPH_ATTRIBUTE_NUMERIC: - len = igraph_vector_size(tmprec->value); + len = igraph_vector_size(tmprec->value.as_vector); break; case IGRAPH_ATTRIBUTE_BOOLEAN: - len = igraph_vector_bool_size(tmprec->value); + len = igraph_vector_bool_size(tmprec->value.as_vector_bool); break; case IGRAPH_ATTRIBUTE_STRING: - len = igraph_strvector_size(tmprec->value); + len = igraph_strvector_size(tmprec->value.as_strvector); break; case IGRAPH_ATTRIBUTE_OBJECT: igraph_error("R objects not implemented yet", __FILE__, __LINE__, @@ -462,13 +462,13 @@ SEXP R_igraph_attribute_add_vertices_append1(igraph_vector_ptr_t *nattr, switch (tmprec->type) { case IGRAPH_ATTRIBUTE_NUMERIC: PROTECT(app=NEW_NUMERIC(nv)); - igraph_vector_copy_to(tmprec->value, REAL(app)); + igraph_vector_copy_to(tmprec->value.as_vector, REAL(app)); break; case IGRAPH_ATTRIBUTE_BOOLEAN: - PROTECT(app=R_igraph_vector_bool_to_SEXP(tmprec->value)); + PROTECT(app=R_igraph_vector_bool_to_SEXP(tmprec->value.as_vector_bool)); break; default: /* IGRAPH_ATTRIBUTE_STRING */ - PROTECT(app=R_igraph_strvector_to_SEXP(tmprec->value)); + PROTECT(app=R_igraph_strvector_to_SEXP(tmprec->value.as_strvector)); break; } @@ -768,13 +768,13 @@ SEXP R_igraph_attribute_add_edges_append1(igraph_vector_ptr_t *nattr, igraph_int switch(tmprec->type) { case IGRAPH_ATTRIBUTE_NUMERIC: - len = igraph_vector_size(tmprec->value); + len = igraph_vector_size(tmprec->value.as_vector); break; case IGRAPH_ATTRIBUTE_BOOLEAN: - len = igraph_vector_bool_size(tmprec->value); + len = igraph_vector_bool_size(tmprec->value.as_vector_bool); break; case IGRAPH_ATTRIBUTE_STRING: - len = igraph_strvector_size(tmprec->value); + len = igraph_strvector_size(tmprec->value.as_strvector); break; case IGRAPH_ATTRIBUTE_OBJECT: igraph_error("R objects not implemented yet", __FILE__, __LINE__, @@ -797,13 +797,13 @@ SEXP R_igraph_attribute_add_edges_append1(igraph_vector_ptr_t *nattr, igraph_int switch (tmprec->type) { case IGRAPH_ATTRIBUTE_NUMERIC: PROTECT(app=NEW_NUMERIC(ne)); - igraph_vector_copy_to(tmprec->value, REAL(app)); + igraph_vector_copy_to(tmprec->value.as_vector, REAL(app)); break; case IGRAPH_ATTRIBUTE_BOOLEAN: - PROTECT(app=R_igraph_vector_bool_to_SEXP(tmprec->value)); + PROTECT(app=R_igraph_vector_bool_to_SEXP(tmprec->value.as_vector_bool)); break; default: /* IGRAPH_ATTRIBUTE_STRING */ - PROTECT(app=R_igraph_strvector_to_SEXP(tmprec->value)); + PROTECT(app=R_igraph_strvector_to_SEXP(tmprec->value.as_strvector)); break; } @@ -1836,7 +1836,7 @@ igraph_error_t R_igraph_attribute_combine_vertices(const igraph_t *graph, /* Create the TODO list first */ PROTECT(names=GET_NAMES(val)); px++; - TODO=igraph_Calloc(valno, igraph_integer_t); + TODO=IGRAPH_CALLOC(valno, igraph_integer_t); if (!TODO) { UNPROTECT(px); IGRAPH_ERROR("Cannot combine edge attributes", @@ -2010,7 +2010,7 @@ igraph_error_t R_igraph_attribute_combine_edges(const igraph_t *graph, IGRAPH_ENOMEM); } IGRAPH_FINALLY(igraph_free, TODO); - funcs=igraph_Calloc(ealno, igraph_function_pointer_t); + funcs=IGRAPH_CALLOC(ealno, igraph_function_pointer_t); if (!funcs) { UNPROTECT(px); IGRAPH_ERROR("Cannot combine edge attributes", @@ -4209,10 +4209,10 @@ static igraph_error_t distances_johnson(const igraph_t *graph, } /* We simulate mode=IN by swapping to/from and transposing the result matrix. */ if (mode == IGRAPH_IN) { - IGRAPH_CHECK(igraph_distances_johnson(graph, res, to, from, weights)); + IGRAPH_CHECK(igraph_distances_johnson(graph, res, to, from, weights, mode)); IGRAPH_CHECK(igraph_matrix_transpose(res)); } else { - IGRAPH_CHECK(igraph_distances_johnson(graph, res, from, to, weights)); + IGRAPH_CHECK(igraph_distances_johnson(graph, res, from, to, weights, mode)); } return IGRAPH_SUCCESS; } diff --git a/src/vendor/cigraph/src/isomorphism/bliss.cc b/src/vendor/cigraph/src/isomorphism/bliss.cc index f57bb48bc21..3a90a052cb8 100644 --- a/src/vendor/cigraph/src/isomorphism/bliss.cc +++ b/src/vendor/cigraph/src/isomorphism/bliss.cc @@ -260,8 +260,7 @@ class AutCollector { */ igraph_error_t igraph_canonical_permutation( const igraph_t *graph, const igraph_vector_int_t *colors, - igraph_vector_int_t *labeling, igraph_bliss_sh_t sh, - igraph_bliss_info_t *info + igraph_vector_int_t *labeling ) { return igraph_canonical_permutation_bliss( graph, colors, labeling, IGRAPH_BLISS_FL, NULL diff --git a/tools/stimulus/functions-R.yaml b/tools/stimulus/functions-R.yaml index ca0ba7b512b..c84da92fd7c 100644 --- a/tools/stimulus/functions-R.yaml +++ b/tools/stimulus/functions-R.yaml @@ -30,8 +30,6 @@ igraph_delete_edges: igraph_delete_vertices: IGNORE: RR, RC -igraph_delete_vertices_idx: - igraph_vcount: igraph_ecount: @@ -424,8 +422,6 @@ igraph_edge_betweenness: igraph_edge_betweenness_cutoff: IGNORE: RR -igraph_edge_betweenness_subset: - igraph_harmonic_centrality: IGNORE: RR, RC, RInit # This is handled by igraph_harmonic_centrality_cutoff @@ -562,6 +558,13 @@ igraph_hub_and_authority_scores: # in the argument list. DEPS: weights ON graph, hub_vector ON graph V(graph), authority_vector ON graph V(graph) +igraph_edge_betweenness_subset: + # This is a temporary hack; we need to find a way to handle default values + # for dependencies. The problem is that the VERTEXINDEX type needs two + # dependencies: the graph and the vertex set, but we only have the graph + # in the argument list. + DEPS: eids ON graph, weights ON graph, res ON graph V(graph), sources ON graph, targets ON graph + igraph_unfold_tree: IGNORE: RR diff --git a/tools/stimulus/types-RC.yaml b/tools/stimulus/types-RC.yaml index c42e290b3c3..dd1375dbb00 100644 --- a/tools/stimulus/types-RC.yaml +++ b/tools/stimulus/types-RC.yaml @@ -231,7 +231,7 @@ VECTOR_INT_LIST: igraph_vector_int_list_destroy(&%C%); IGRAPH_FINALLY_CLEAN(1); -VERTEXSET_LIST: +VERTEX_INDICES_LIST: CALL: '&%C%' CTYPE: igraph_vector_int_list_t INCONV: @@ -252,7 +252,7 @@ VERTEXSET_LIST: igraph_vector_int_list_destroy(&%C%); IGRAPH_FINALLY_CLEAN(1); -EDGESET_LIST: +EDGE_INDICES_LIST: CALL: '&%C%' CTYPE: igraph_vector_int_list_t INCONV: @@ -304,7 +304,7 @@ ADJLIST: OUTCONV: IN: igraph_adjlist_destroy(&%C%); -EDGEWEIGHTS: +EDGE_WEIGHTS: CALL: '(Rf_isNull(%I%) ? 0 : &%C%)' CTYPE: igraph_vector_t INCONV: @@ -321,7 +321,7 @@ EDGEWEIGHTS: igraph_vector_destroy(&%C%); IGRAPH_FINALLY_CLEAN(1); -VERTEXWEIGHTS: +VERTEX_WEIGHTS: CALL: '(Rf_isNull(%I%) ? 0 : &%C%)' CTYPE: igraph_vector_t INCONV: @@ -338,7 +338,7 @@ VERTEXWEIGHTS: igraph_vector_destroy(&%C%); IGRAPH_FINALLY_CLEAN(1); -EDGE_CAPACITY: +EDGE_CAPACITIES: CALL: '(Rf_isNull(%I%) ? 0 : &%C%)' CTYPE: igraph_vector_t INCONV: @@ -448,7 +448,7 @@ VERTEX_ROOT: PROTECT(%I% = NEW_INTEGER(1)); INTEGER(%I%)[0] = %C% + 1; -VERTEX_QTY: +VERTEX_QTYS: CALL: '&%C%' CTYPE: igraph_vector_t INCONV: @@ -587,14 +587,14 @@ ATTRIBUTES: CTYPE: ~ HEADER: {} -ARPACKOPT: +ARPACK_OPTIONS: CALL: '&%C%' INCONV: INOUT: R_SEXP_to_igraph_arpack_options(%I%, &%C%); OUTCONV: INOUT: PROTECT(%I%=R_igraph_arpack_options_to_SEXP(&%C%)); -ARPACKSTORAGE: +ARPACK_STORAGE: CALL: '0' CTYPE: ~ HEADER: {} @@ -650,7 +650,7 @@ BIPARTITE_TYPES: igraph_vector_bool_destroy(&%C%); IGRAPH_FINALLY_CLEAN(1); -VERTEX_COLOR: +VERTEX_COLORS: CALL: IN: '(Rf_isNull(%I%) ? 0 : &%C%)' OUT: '&%C%' @@ -677,7 +677,7 @@ VERTEX_COLOR: igraph_vector_int_destroy(&%C%); IGRAPH_FINALLY_CLEAN(1); -EDGE_COLOR: +EDGE_COLORS: CALL: IN: '(Rf_isNull(%I%) ? 0 : &%C%)' OUT: '&%C%' diff --git a/tools/stimulus/types-RR.yaml b/tools/stimulus/types-RR.yaml index d39c49aaaf9..15584fb59fd 100644 --- a/tools/stimulus/types-RR.yaml +++ b/tools/stimulus/types-RR.yaml @@ -32,7 +32,7 @@ VECTOR: AsmDefaultCvec: strength(%I1%, weights=weights)/(vcount(%I1%)-1) INCONV: '%I% <- as.numeric(%I%)' -VERTEX_QTY: +VERTEX_QTYS: OUTCONV: OUT: |- if (igraph_opt("add.vertex.names") && is_named(%I1%)) { @@ -156,7 +156,7 @@ EDGE_SELECTOR: %I% <- create_es(%I1%, %I%) } -EDGEWEIGHTS: +EDGE_WEIGHTS: INCONV: |- if (is.null(%I%) && "weight" %in% edge_attr_names(%I1%)) { %I% <- E(%I1%)$weight @@ -167,7 +167,7 @@ EDGEWEIGHTS: %I% <- NULL } -VERTEXWEIGHTS: +VERTEX_WEIGHTS: INCONV: |- if (is.null(%I%) && "weight" %in% vertex_attr_names(%I1%)) { %I% <- V(%I1%)$weight @@ -178,7 +178,7 @@ VERTEXWEIGHTS: %I% <- NULL } -EDGE_CAPACITY: +EDGE_CAPACITIES: INCONV: |- if (is.null(%I%) && "capacity" %in% edge_attr_names(%I1%)) { %I% <- E(%I1%)$capacity @@ -198,7 +198,7 @@ BIPARTITE_TYPES: names(%I%) <- vertex_attr(%I1%, "name", %I2%) } -VERTEX_COLOR: +VERTEX_COLORS: INCONV: |- if (missing(%I%)) { if ("color" %in% vertex_attr_names(%I1%)) { @@ -217,7 +217,7 @@ VERTEX_COLOR: names(%I%) <- vertex_attr(%I1%, "name") } -EDGE_COLOR: +EDGE_COLORS: INCONV: |- if (missing(%I%)) { if ("color" %in% edge_attr_names(%I1%)) { @@ -245,14 +245,14 @@ ISOCOMPAT_FUNC: CALL: {} HEADER: ~ -VERTEXSET_LIST: +VERTEX_INDICES_LIST: OUTCONV: OUT: |- if (igraph_opt("return.vs.es")) { %I% <- lapply(%I%, unsafe_create_vs, graph = %I1%, verts = V(%I1%)) } -EDGESET_LIST: +EDGE_INDICES_LIST: OUTCONV: OUT: |- if (igraph_opt("return.vs.es")) { @@ -263,7 +263,7 @@ EDGESET_LIST: CALL: {} HEADER: ~ -ARPACKOPT: +ARPACK_OPTIONS: DEFAULT: ARPACK_DEFAULTS: arpack_defaults() INCONV: From 70d9ce1a770e06f6be7067760de31449c0c317ec Mon Sep 17 00:00:00 2001 From: Antonov548 Date: Fri, 12 Apr 2024 16:20:08 +0200 Subject: [PATCH 04/10] fix compilation --- R/aaa-auto.R | 2 +- src/cpp11.cpp | 23 +++++++++++--------- src/rinterface.c | 3 +++ src/vendor/cigraph/interfaces/functions.yaml | 2 +- 4 files changed, 18 insertions(+), 12 deletions(-) diff --git a/R/aaa-auto.R b/R/aaa-auto.R index 8338cfcdaf1..e7516ad3389 100644 --- a/R/aaa-auto.R +++ b/R/aaa-auto.R @@ -3516,7 +3516,7 @@ graph_count_impl <- function(n, directed=FALSE) { res } -adjacency_spectral_embedding_impl <- function(graph, no, weights=NULL, which=c("lm", "la", "sa"), scaled=TRUE, cvec=strength(graph, weights=weights)/(vcount(graph)-1), options=RPACK_DEFAULTS) { +adjacency_spectral_embedding_impl <- function(graph, no, weights=NULL, which=c("lm", "la", "sa"), scaled=TRUE, cvec=strength(graph, weights=weights)/(vcount(graph)-1), options=arpack_defaults()) { # Argument checks ensure_igraph(graph) no <- as.numeric(no) diff --git a/src/cpp11.cpp b/src/cpp11.cpp index 36a39cc39d8..c2292918fb8 100644 --- a/src/cpp11.cpp +++ b/src/cpp11.cpp @@ -48,7 +48,8 @@ extern SEXP R_igraph_assortativity_nominal(void *, void *, void *, void *); extern SEXP R_igraph_asymmetric_preference_game(void *, void *, void *, void *, void *, void *); extern SEXP R_igraph_atlas(void *); extern SEXP R_igraph_authority_score(void *, void *, void *, void *); -extern SEXP R_igraph_automorphism_group(void *, void *, void *); +extern SEXP R_igraph_automorphism_group(void *, void *); +extern SEXP R_igraph_automorphism_group_bliss(void *, void *, void *); extern SEXP R_igraph_average_local_efficiency(void *, void *, void *, void *); extern SEXP R_igraph_average_path_length_dijkstra(void *, void *, void *, void *); extern SEXP R_igraph_avg_nearest_neighbor_degree(void *, void *, void *, void *, void *); @@ -62,13 +63,14 @@ extern SEXP R_igraph_biadjacency(void *, void *, void *, void *); extern SEXP R_igraph_bibcoupling(void *, void *); extern SEXP R_igraph_biconnected_components(void *); extern SEXP R_igraph_bipartite_game(void *, void *, void *, void *, void *, void *, void *); -extern SEXP R_igraph_bipartite_game_gnm(void *, void *, void *, void *, void *); +extern SEXP R_igraph_bipartite_game_gnm(void *, void *, void *, void *, void *, void *); extern SEXP R_igraph_bipartite_game_gnp(void *, void *, void *, void *, void *); extern SEXP R_igraph_bipartite_projection(void *, void *, void *, void *); extern SEXP R_igraph_bipartite_projection_size(void *, void *); extern SEXP R_igraph_bridges(void *); extern SEXP R_igraph_callaway_traits_game(void *, void *, void *, void *, void *, void *); -extern SEXP R_igraph_canonical_permutation(void *, void *, void *); +extern SEXP R_igraph_canonical_permutation(void *, void *); +extern SEXP R_igraph_canonical_permutation_bliss(void *, void *, void *); extern SEXP R_igraph_centralization(void *, void *, void *); extern SEXP R_igraph_centralization_betweenness(void *, void *, void *); extern SEXP R_igraph_centralization_betweenness_tmax(void *, void *, void *); @@ -113,7 +115,8 @@ extern SEXP R_igraph_copy_to(void *); extern SEXP R_igraph_coreness(void *, void *); extern SEXP R_igraph_correlated_game(void *, void *, void *, void *); extern SEXP R_igraph_correlated_pair_game(void *, void *, void *, void *, void *); -extern SEXP R_igraph_count_automorphisms(void *, void *, void *); +extern SEXP R_igraph_count_automorphisms(void *, void *); +extern SEXP R_igraph_count_automorphisms_bliss(void *, void *, void *); extern SEXP R_igraph_count_isomorphisms_vf2(void *, void *, void *, void *, void *, void *); extern SEXP R_igraph_count_multiple(void *, void *); extern SEXP R_igraph_count_subisomorphisms_vf2(void *, void *, void *, void *, void *, void *); @@ -126,7 +129,7 @@ extern SEXP R_igraph_degree_correlation_vector(void *, void *, void *, void *, v extern SEXP R_igraph_degree_sequence_game(void *, void *, void *); extern SEXP R_igraph_delete_edges(void *, void *); extern SEXP R_igraph_delete_vertices(void *, void *); -extern SEXP R_igraph_delete_vertices_idx(void *, void *); +extern SEXP R_igraph_delete_vertices_map(void *, void *); extern SEXP R_igraph_density(void *, void *); extern SEXP R_igraph_deterministic_optimal_imitation(void *, void *, void *, void *, void *, void *); extern SEXP R_igraph_dfs(void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *); @@ -140,7 +143,7 @@ extern SEXP R_igraph_distances_cutoff(void *, void *, void *, void *, void *); extern SEXP R_igraph_distances_dijkstra(void *, void *, void *, void *, void *); extern SEXP R_igraph_distances_dijkstra_cutoff(void *, void *, void *, void *, void *, void *); extern SEXP R_igraph_distances_floyd_warshall(void *, void *, void *, void *, void *, void *); -extern SEXP R_igraph_distances_johnson(void *, void *, void *, void *); +extern SEXP R_igraph_distances_johnson(void *, void *, void *, void *, void *); extern SEXP R_igraph_diversity(void *, void *, void *); extern SEXP R_igraph_dominator_tree(void *, void *, void *); extern SEXP R_igraph_dot_product_game(void *, void *); @@ -153,7 +156,7 @@ extern SEXP R_igraph_edge_betweenness_subset(void *, void *, void *, void *, voi extern SEXP R_igraph_edge_connectivity(void *, void *); extern SEXP R_igraph_edge_disjoint_paths(void *, void *, void *); extern SEXP R_igraph_edges(void *, void *); -extern SEXP R_igraph_eigen_adjacency(void *, void *, void *, void *); +extern SEXP R_igraph_eigen_adjacency(void *, void *, void *, void *, void *); extern SEXP R_igraph_eigenvector_centrality(void *, void *, void *, void *, void *); extern SEXP R_igraph_empty(void *, void *); extern SEXP R_igraph_erdos_renyi_game(void *, void *, void *, void *, void *); @@ -396,11 +399,11 @@ extern SEXP R_igraph_sample_sphere_volume(void *, void *, void *, void *); extern SEXP R_igraph_sbm_game(void *, void *, void *, void *, void *); extern SEXP R_igraph_set_verbose(void *); extern SEXP R_igraph_shortest_paths(void *, void *, void *, void *, void *, void *); -extern SEXP R_igraph_similarity_dice(void *, void *, void *, void *); +extern SEXP R_igraph_similarity_dice(void *, void *, void *, void *, void *); extern SEXP R_igraph_similarity_dice_es(void *, void *, void *, void *); extern SEXP R_igraph_similarity_dice_pairs(void *, void *, void *, void *); extern SEXP R_igraph_similarity_inverse_log_weighted(void *, void *, void *); -extern SEXP R_igraph_similarity_jaccard(void *, void *, void *, void *); +extern SEXP R_igraph_similarity_jaccard(void *, void *, void *, void *, void *); extern SEXP R_igraph_similarity_jaccard_es(void *, void *, void *, void *); extern SEXP R_igraph_similarity_jaccard_pairs(void *, void *, void *, void *); extern SEXP R_igraph_simple_interconnected_islands_game(void *, void *, void *, void *); @@ -522,7 +525,7 @@ static const R_CallMethodDef CallEntries[] = { {"R_igraph_bibcoupling", (DL_FUNC) &R_igraph_bibcoupling, 2}, {"R_igraph_biconnected_components", (DL_FUNC) &R_igraph_biconnected_components, 1}, {"R_igraph_bipartite_game", (DL_FUNC) &R_igraph_bipartite_game, 7}, - {"R_igraph_bipartite_game_gnm", (DL_FUNC) &R_igraph_bipartite_game_gnm, 5}, + {"R_igraph_bipartite_game_gnm", (DL_FUNC) &R_igraph_bipartite_game_gnm, 6}, {"R_igraph_bipartite_game_gnp", (DL_FUNC) &R_igraph_bipartite_game_gnp, 5}, {"R_igraph_bipartite_projection", (DL_FUNC) &R_igraph_bipartite_projection, 4}, {"R_igraph_bipartite_projection_size", (DL_FUNC) &R_igraph_bipartite_projection_size, 2}, diff --git a/src/rinterface.c b/src/rinterface.c index 250ddd65bc9..595d8c3ad32 100644 --- a/src/rinterface.c +++ b/src/rinterface.c @@ -72,6 +72,7 @@ SEXP R_igraph_add_edges(SEXP graph, SEXP edges) { R_SEXP_to_igraph_copy(graph, &c_graph); IGRAPH_FINALLY(igraph_destroy, &c_graph); R_SEXP_to_vector_int_copy(edges, &c_edges); + IGRAPH_FINALLY(igraph_vector_int_destroy, &c_edges); /* Call igraph */ IGRAPH_R_CHECK(igraph_add_edges(&c_graph, &c_edges, 0)); @@ -79,6 +80,8 @@ SEXP R_igraph_add_edges(SEXP graph, SEXP edges) { PROTECT(graph=R_igraph_to_SEXP(&c_graph)); IGRAPH_I_DESTROY(&c_graph); IGRAPH_FINALLY_CLEAN(1); + igraph_vector_int_destroy(&c_edges); + IGRAPH_FINALLY_CLEAN(1); r_result = graph; UNPROTECT(1); diff --git a/src/vendor/cigraph/interfaces/functions.yaml b/src/vendor/cigraph/interfaces/functions.yaml index 0cfd446fe12..1eec57e43df 100644 --- a/src/vendor/cigraph/interfaces/functions.yaml +++ b/src/vendor/cigraph/interfaces/functions.yaml @@ -2402,7 +2402,7 @@ igraph_adjacency_spectral_embedding: EIGENWHICHPOS which=ASE, BOOLEAN scaled=True, OUT MATRIX X, OPTIONAL OUT MATRIX Y, OPTIONAL OUT VECTOR D, VECTOR cvec=AsmDefaultCvec, - INOUT ARPACK_OPTIONS options=RPACK_DEFAULTS + INOUT ARPACK_OPTIONS options=ARPACK_DEFAULTS DEPS: weights ON graph, cvec ON graph igraph_laplacian_spectral_embedding: From 761f21757886fd65a1778de4c913446692053300 Mon Sep 17 00:00:00 2001 From: Antonov548 Date: Fri, 12 Apr 2024 16:20:19 +0200 Subject: [PATCH 05/10] add multiple for `R_igraph_bipartite_game_gnm` --- R/games.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/games.R b/R/games.R index b76b6f1e624..df50b5ff560 100644 --- a/R/games.R +++ b/R/games.R @@ -1756,7 +1756,7 @@ sample_bipartite <- function(n1, n2, type = c("gnp", "gnm"), p, m, res$name <- "Bipartite Gnp random graph" res$p <- p } else if (type == "gnm") { - res <- .Call(R_igraph_bipartite_game_gnm, n1, n2, m, directed, mode) + res <- .Call(R_igraph_bipartite_game_gnm, n1, n2, m, directed, mode, multiple = FALSE) res <- set_vertex_attr(res$graph, "type", value = res$types) res$name <- "Bipartite Gnm random graph" res$m <- m From 65da7065ad4734363b2e29d23c5c5f07dcff1e2f Mon Sep 17 00:00:00 2001 From: Antonov548 Date: Fri, 12 Apr 2024 16:47:01 +0200 Subject: [PATCH 06/10] permute lose bliss info --- tests/testthat/test-canonical.permutation.R | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/testthat/test-canonical.permutation.R b/tests/testthat/test-canonical.permutation.R index a6d86155910..ed557d10d1a 100644 --- a/tests/testthat/test-canonical.permutation.R +++ b/tests/testthat/test-canonical.permutation.R @@ -1,12 +1,12 @@ test_that("canonical_permutation works", { g1 <- sample_gnm(10, 20) cp1 <- canonical_permutation(g1) - cf1 <- permute(g1, cp1$labeling) + cf1 <- permute(g1, cp1) ## Do the same with a random permutation of it g2 <- permute(g1, sample(vcount(g1))) cp2 <- canonical_permutation(g2) - cf2 <- permute(g2, cp2$labeling) + cf2 <- permute(g2, cp2) ## Check that they are the same el1 <- as_edgelist(cf1) From 733a30b9df5e079722a393a3a29de6dec5eb659b Mon Sep 17 00:00:00 2001 From: Antonov548 Date: Sat, 13 Apr 2024 11:27:27 +0200 Subject: [PATCH 07/10] update `ARPACK_STORAGE` --- R/aaa-auto.R | 4 ++-- src/cpp11.cpp | 4 ++-- tools/stimulus/types-RR.yaml | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/R/aaa-auto.R b/R/aaa-auto.R index e7516ad3389..f4387d64142 100644 --- a/R/aaa-auto.R +++ b/R/aaa-auto.R @@ -3567,7 +3567,7 @@ laplacian_spectral_embedding_impl <- function(graph, no, weights=NULL, which=c(" res } -eigen_adjacency_impl <- function(graph, algorithm=c("arpack", "auto", "lapack", "comp_auto", "comp_lapack", "comp_arpack"), which=list(), options=arpack_defaults(), storage) { +eigen_adjacency_impl <- function(graph, algorithm=c("arpack", "auto", "lapack", "comp_auto", "comp_lapack", "comp_arpack"), which=list(), options=arpack_defaults()) { # Argument checks ensure_igraph(graph) algorithm <- switch(igraph.match.arg(algorithm), "auto"=0L, "lapack"=1L, @@ -3579,7 +3579,7 @@ eigen_adjacency_impl <- function(graph, algorithm=c("arpack", "auto", "lapack", on.exit( .Call(R_igraph_finalizer) ) # Function call - res <- .Call(R_igraph_eigen_adjacency, graph, algorithm, which, options, storage) + res <- .Call(R_igraph_eigen_adjacency, graph, algorithm, which, options) res } diff --git a/src/cpp11.cpp b/src/cpp11.cpp index c2292918fb8..99d4cbbb5d9 100644 --- a/src/cpp11.cpp +++ b/src/cpp11.cpp @@ -156,7 +156,7 @@ extern SEXP R_igraph_edge_betweenness_subset(void *, void *, void *, void *, voi extern SEXP R_igraph_edge_connectivity(void *, void *); extern SEXP R_igraph_edge_disjoint_paths(void *, void *, void *); extern SEXP R_igraph_edges(void *, void *); -extern SEXP R_igraph_eigen_adjacency(void *, void *, void *, void *, void *); +extern SEXP R_igraph_eigen_adjacency(void *, void *, void *, void *); extern SEXP R_igraph_eigenvector_centrality(void *, void *, void *, void *, void *); extern SEXP R_igraph_empty(void *, void *); extern SEXP R_igraph_erdos_renyi_game(void *, void *, void *, void *, void *); @@ -618,7 +618,7 @@ static const R_CallMethodDef CallEntries[] = { {"R_igraph_edge_connectivity", (DL_FUNC) &R_igraph_edge_connectivity, 2}, {"R_igraph_edge_disjoint_paths", (DL_FUNC) &R_igraph_edge_disjoint_paths, 3}, {"R_igraph_edges", (DL_FUNC) &R_igraph_edges, 2}, - {"R_igraph_eigen_adjacency", (DL_FUNC) &R_igraph_eigen_adjacency, 5}, + {"R_igraph_eigen_adjacency", (DL_FUNC) &R_igraph_eigen_adjacency, 4}, {"R_igraph_eigenvector_centrality", (DL_FUNC) &R_igraph_eigenvector_centrality, 5}, {"R_igraph_empty", (DL_FUNC) &R_igraph_empty, 2}, {"R_igraph_erdos_renyi_game", (DL_FUNC) &R_igraph_erdos_renyi_game, 5}, diff --git a/tools/stimulus/types-RR.yaml b/tools/stimulus/types-RR.yaml index 15584fb59fd..1cb6ee60731 100644 --- a/tools/stimulus/types-RR.yaml +++ b/tools/stimulus/types-RR.yaml @@ -259,7 +259,7 @@ EDGE_INDICES_LIST: %I% <- lapply(%I%, unsafe_create_es, graph = %I1%, es = E(%I1%)) } -'ARPACKSTORAGE': +'ARPACK_STORAGE': CALL: {} HEADER: ~ From 937b16c5bc3542fe40b086957e2fdc629798850c Mon Sep 17 00:00:00 2001 From: Antonov548 Date: Tue, 16 Apr 2024 11:26:55 +0200 Subject: [PATCH 08/10] fix: attribute records list --- src/rinterface_extra.c | 42 +++++++++++++++++----------------- tests/testthat/test-topology.R | 10 ++++---- 2 files changed, 26 insertions(+), 26 deletions(-) diff --git a/src/rinterface_extra.c b/src/rinterface_extra.c index 52bc2724f63..41d3e17a8b7 100644 --- a/src/rinterface_extra.c +++ b/src/rinterface_extra.c @@ -315,7 +315,7 @@ void R_igraph_attribute_clean_preserve_list(void) { } } -igraph_error_t R_igraph_attribute_init(igraph_t *graph, igraph_vector_ptr_t *attr) { +igraph_error_t R_igraph_attribute_init(igraph_t *graph, const igraph_attribute_record_list_t *attr) { SEXP result, names, gal; int px = 0; @@ -341,12 +341,12 @@ igraph_error_t R_igraph_attribute_init(igraph_t *graph, igraph_vector_ptr_t *att graph->attr=result; /* Add graph attributes */ - igraph_integer_t attrno= attr==NULL ? 0 : igraph_vector_ptr_size(attr); + igraph_integer_t attrno= attr==NULL ? 0 : igraph_attribute_record_list_size(attr); SET_VECTOR_ELT(result, 1, NEW_LIST(attrno)); gal=VECTOR_ELT(result, 1); PROTECT(names=NEW_CHARACTER(attrno)); px++; for (igraph_integer_t i=0; itype) { @@ -477,7 +477,7 @@ SEXP R_igraph_attribute_add_vertices_append1(igraph_vector_ptr_t *nattr, } void R_igraph_attribute_add_vertices_append(SEXP val, igraph_integer_t nv, - igraph_vector_ptr_t *nattr) { + const igraph_attribute_record_list_t *nattr) { SEXP names; igraph_integer_t valno, nattrno; SEXP rep = R_NilValue; @@ -488,7 +488,7 @@ void R_igraph_attribute_add_vertices_append(SEXP val, igraph_integer_t nv, if (nattr==NULL) { nattrno=0; } else { - nattrno=igraph_vector_ptr_size(nattr); + nattrno=igraph_attribute_record_list_size(nattr); } for (igraph_integer_t i=0; iname); } if (l) { @@ -531,7 +531,7 @@ SEXP R_igraph_attribute_add_vertices_dup(SEXP attr) { } igraph_error_t R_igraph_attribute_add_vertices(igraph_t *graph, igraph_integer_t nv, - igraph_vector_ptr_t *nattr) { + const igraph_attribute_record_list_t *nattr) { SEXP attr=graph->attr; SEXP val, rep=0, names, newnames; igraph_vector_int_t news; @@ -547,7 +547,7 @@ igraph_error_t R_igraph_attribute_add_vertices(igraph_t *graph, igraph_integer_t if (nattr==NULL) { nattrno=0; } else { - nattrno=igraph_vector_ptr_size(nattr); + nattrno=igraph_attribute_record_list_size(nattr); } origlen=igraph_vcount(graph)-nv; @@ -556,7 +556,7 @@ igraph_error_t R_igraph_attribute_add_vertices(igraph_t *graph, igraph_integer_t if (igraph_vector_int_init(&news, 0)) Rf_error("Out of memory"); IGRAPH_FINALLY(igraph_vector_int_destroy, &news); for (igraph_integer_t i=0; iname; igraph_bool_t l=0; for (igraph_integer_t j=0; !l && jname)); } @@ -759,11 +759,11 @@ SEXP R_igraph_attribute_add_edges_dup(SEXP attr) { return newattr; } -SEXP R_igraph_attribute_add_edges_append1(igraph_vector_ptr_t *nattr, igraph_integer_t j, +SEXP R_igraph_attribute_add_edges_append1(const igraph_attribute_record_list_t *nattr, igraph_integer_t j, igraph_integer_t ne) { SEXP app = R_NilValue; - igraph_attribute_record_t *tmprec=VECTOR(*nattr)[j-1]; + igraph_attribute_record_t *tmprec=igraph_attribute_record_list_get_ptr(nattr, j-1); igraph_integer_t len = 0; switch(tmprec->type) { @@ -813,7 +813,7 @@ SEXP R_igraph_attribute_add_edges_append1(igraph_vector_ptr_t *nattr, igraph_int void R_igraph_attribute_add_edges_append(SEXP eal, const igraph_vector_int_t *edges, - igraph_vector_ptr_t *nattr) { + const igraph_attribute_record_list_t *nattr) { SEXP names; igraph_integer_t ealno; igraph_integer_t ne=igraph_vector_int_size(edges)/2, nattrno; @@ -825,7 +825,7 @@ void R_igraph_attribute_add_edges_append(SEXP eal, if (nattr==NULL) { nattrno=0; } else { - nattrno=igraph_vector_ptr_size(nattr); + nattrno=igraph_attribute_record_list_size(nattr); } for (igraph_integer_t i=0; iname); } if (l) { @@ -862,7 +862,7 @@ void R_igraph_attribute_add_edges_append(SEXP eal, } igraph_error_t R_igraph_attribute_add_edges(igraph_t *graph, const igraph_vector_int_t *edges, - igraph_vector_ptr_t *nattr) { + const igraph_attribute_record_list_t *nattr) { SEXP attr=graph->attr; SEXP eal, names, newnames; igraph_vector_int_t news; @@ -882,14 +882,14 @@ igraph_error_t R_igraph_attribute_add_edges(igraph_t *graph, const igraph_vector if (nattr==NULL) { nattrno=0; } else { - nattrno=igraph_vector_ptr_size(nattr); + nattrno=igraph_attribute_record_list_size(nattr); } origlen=igraph_ecount(graph)-ne; /* First add the new attributes, if any */ newattrs=0; for (igraph_integer_t i=0; iname; igraph_bool_t l=0; for (igraph_integer_t j=0; !l && jname)); } diff --git a/tests/testthat/test-topology.R b/tests/testthat/test-topology.R index 57101b07016..e0a5e0a584f 100644 --- a/tests/testthat/test-topology.R +++ b/tests/testthat/test-topology.R @@ -1,19 +1,19 @@ test_that("automorphisms works", { g <- make_ring(10) - expect_that(count_automorphisms(g)$group_size, equals("20")) + expect_that(count_automorphisms(g), equals(20)) g <- make_full_graph(4) - expect_that(count_automorphisms(g)$group_size, equals("24")) + expect_that(count_automorphisms(g), equals(24)) }) test_that("automorphisms works with colored graphs", { g <- make_full_graph(4) - expect_that(count_automorphisms(g, colors = c(1, 2, 1, 2))$group_size, equals("4")) + expect_that(count_automorphisms(g, colors = c(1, 2, 1, 2)), equals(4)) V(g)$color <- c(1, 2, 1, 2) - expect_that(count_automorphisms(g)$group_size, equals("4")) - expect_that(count_automorphisms(g, colors = NULL)$group_size, equals("24")) + expect_that(count_automorphisms(g), equals(4)) + expect_that(count_automorphisms(g, colors = NULL), equals(24)) }) From 622acfb92986766a0b848569c948a08b252b1a03 Mon Sep 17 00:00:00 2001 From: Antonov548 Date: Wed, 24 Apr 2024 17:36:46 +0200 Subject: [PATCH 09/10] fix return type --- src/rinterface_extra.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/rinterface_extra.c b/src/rinterface_extra.c index 41d3e17a8b7..14acbd3588a 100644 --- a/src/rinterface_extra.c +++ b/src/rinterface_extra.c @@ -2283,7 +2283,7 @@ void checkInterruptFn(void *dummy) { R_CheckUserInterrupt(); } -igraph_error_t R_igraph_interrupt_handler(void *data) { +igraph_bool_t R_igraph_interrupt_handler() { /* We need to call R_CheckUserInterrupt() regularly to enable interruptions. * However, if an interruption is pending, R_CheckUserInterrupt() will * longjmp back to the top level so we cannot clean up ourselves by calling @@ -2299,9 +2299,9 @@ igraph_error_t R_igraph_interrupt_handler(void *data) { */ if (R_ToplevelExec(checkInterruptFn, NULL) == FALSE) { IGRAPH_FINALLY_FREE(); - return IGRAPH_INTERRUPTED; + return 1; } - return IGRAPH_SUCCESS; + return 0; } igraph_error_t R_igraph_progress_handler(const char *message, double percent, @@ -6690,8 +6690,8 @@ SEXP R_igraph_spinglass_my_community(SEXP graph, SEXP weights, igraph_vector_int_t community; igraph_real_t cohesion; igraph_real_t adhesion; - igraph_integer_t inner_links; - igraph_integer_t outer_links; + igraph_real_t inner_links; + igraph_real_t outer_links; SEXP result, names; From e7c1af2b2a2b29ca622c5c102fa18e55c679cae7 Mon Sep 17 00:00:00 2001 From: Antonov548 Date: Thu, 25 Apr 2024 10:57:32 +0200 Subject: [PATCH 10/10] fix warning --- src/rinterface_extra.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rinterface_extra.c b/src/rinterface_extra.c index 14acbd3588a..2ac8eeb4ace 100644 --- a/src/rinterface_extra.c +++ b/src/rinterface_extra.c @@ -3325,7 +3325,7 @@ void R_igraph_SEXP_to_matrixlist(SEXP matrixlist, igraph_matrix_list_t *list) { igraph_error_t R_igraph_SEXP_to_strvector(SEXP rval, igraph_strvector_t *sv) { igraph_integer_t length = Rf_xlength(rval); - sv->stor_begin=(char**) R_alloc((size_t) length, sizeof(char*)); + sv->stor_begin=(const char**) R_alloc((size_t) length, sizeof(char*)); sv->stor_end=sv->stor_begin+length; sv->end=sv->stor_end; for (igraph_integer_t i=0; i