About igraph releases and other things

Our efforts to bring the R interface of igraph closer to the recent developments of the C core continues: we have released R-igraph 1.3.0, which updates the C core of igraph within the R interface to version 0.9.7, which is now only one patch version behind the mainline C core. The update fixes lots of bugs compared to the previous release and adds quite a few new functions.

Due to the underlying changes in the C core of igraph between the 0.8 series and 0.9.7, there are some cases when we needed to make extra efforts in the R interface to keep things compatible with previous releases. For instance, igraph 0.9.7 now interprets zero cutoff in the closeness, betweenness and edge betweenness centrality functions literally, while igraph 0.8 interpreted zero as “no cutoff”. The R interface keeps the old behaviour in such cases but prints a deprecation warning; the old behaviour will be gone in igraph 1.4.0 or 2.0.0, whichever comes first.

A patch release of R/igraph is coming soon in the next few days, which will hopefully (finally) catch up with the 0.9 branch of the C core. We aim to let R/igraph stabilize for a few weeks now while we work on further improvements in the C core.

Even though we tried to do our best not to cause breaking changes for users of igraph from R, we may have made unintentional mistakes, so please keep on reporting issues in the Github issue tracker.

The C core is updated to 0.9.7, fixing a range of bugs and introducing a number of new functions.

`has_eulerian_path()`

and`has_eulerian_cycle()`

decides whether there is an Eulerian path or cycle in the graph.`eulerian_path()`

and`eulerian_cycle()`

returns the edges and vertices in an Eulerian path or cycle in the graph.`any_loop()`

checks whether a graph contains at least one loop edge.`is_tree()`

checks whether a graph is a tree and also finds a possible root`to_prufer()`

converts a tree graph into its Prufer sequence`make_from_prufer()`

creates a tree graph from its Prufer sequence`sample_tree()`

to sample labelled trees uniformly at random`sample_spanning_tree()`

to sample spanning trees of an undirected graph uniformly at random`automorphisms()`

and`canonical_permutation()`

now supports vertex colors`random_edge_walk()`

to record the edges traversed during a random walk`harmonic_centrality()`

calculates the harmonic centrality of vertices, optionally with a cutoff on path lengths`mean_distance()`

now supports edge weights and it can also return the number of unconnected vertex pairs when`details=TRUE`

is passed as an argument`greedy_vertex_coloring()`

finds vertex colorings based on a simple greedy algorithm.`bridges()`

finds the bridges (cut-edges) of a graph- The frame width of circle, rectangle and square vertex shapes can now be adjusted on plots with the
`frame.width`

vertex attribute or the`vertex.frame.width`

keyword argument, thanks to @simoncarrignon. See PR #500 for more details. `automorphism_group()`

returns a possible (not necessarily minimal) generating set of the automorphism group of a graph.`global_efficiency()`

calculates the global efficiency of the graph.`local_efficiency()`

calculates the local efficiency of each vertex in a graph.`average_local_efficiency()`

calculates the average local efficiency across the set of vertices in a graph.`rewire(each_edge(...))`

now supports rewiring only one endpoint of each edge.`realize_degseq()`

generates graphs from degree sequences in a deterministic manner. It is also available as`make_(degseq(..., deterministic=TRUE))`

.`clique_size_counts()`

counts cliques of different sizes without storing them all.`feedback_arc_set()`

finds a minimum-weight feedback arc set in a graph, either with an exact integer programming algorithm or with a linear-time approximation.`make_bipartite_graph()`

now handles vertices with names.`shortest_paths()`

now supports graphs with negative edge weights.`min_cut()`

now supports s-t mincuts even if`value.only=FALSE`

.`as.matrix()`

now supports converting an igraph graph to an adjacency or edge list matrix representation. See`as.matrix.igraph()`

for more details. This function was migrated from`intergraph`

; thanks to Michał Bojanowski.

`is_connected()`

now returns FALSE for the null graph- Calling
`length()`

on a graph now returns the number of vertices to make it consistent with indexing the graph with`[[`

. `diameter()`

now corrently returns infinity for disconnected graphs when`unconnected=FALSE`

. Previous versions returned the number of vertices plus one, which was clearly invalid for weighted graphs.`mean_distance()`

now correctly treats the path length between disconnected vertices as infinite when`unconnected=FALSE`

. Previous versions used the number of vertices plus one, adding a bias towards this number, even if the graph was weighted and the number of vertices plus one was not a path length that could safely have been considered as being longer than any “valid” path.`layout_with_sugiyama()`

now handles the case of exactly one extra virtual node correctly; fixes #85`bfs()`

and`dfs()`

callback functions now correctly receive 1-based vertex indices and ranks; it used to be zero-based in earlier versions- Accidentally returning a non-logical value from a
`bfs()`

or`dfs()`

callback does not crash R any more - Calling
`print()`

on a graph with a small`max.lines`

value (smaller than the number of lines needed to print the attribute list and the header) does not raise an error any more; fixes #179 `as_adjacency_matrix(edges=TRUE, sparse=TRUE)`

now consistently returns the last edge ID for each cell in the matrix instead of summing them.- Using the
`+`

and`-`

operators with a`path()`

object consisting of two vertices is now handled correctly; fixes #355 `topo_sort()`

now throws an error if the input graph is not acyclic instead of returning an incorrect partial ordering.- Weighted transitivity calculations (i.e.
`transitivity(mode="barrat")`

now throw an error for multigraphs; the implementation does not work correctly for multigraphs and earlier versions did not warn about this.

- The
`neimode`

argument of`bfs()`

and`dfs()`

was renamed to`mode`

for sake of consistency with other functions. The old argument name is deprecated and will be removed in 1.4.0. `bfs()`

and`dfs()`

callback functions now correctly receive 1-based vertex indices and ranks; it used to be zero-based in earlier versions. (This is actually a bugfix so it’s also mentioned in the “Fixed” section).`closeness()`

,`betweenness()`

and`edge_betweenness()`

now all take a`cutoff`

argument on their own.`estimate_closeness()`

,`estimate_betweenness()`

and`estimate_edge_betweenness()`

became aliases, with identical signature. They are*not*deprecated but their implementation might change in future versions to provide proper estimation schemes instead of a simple cutoff-based approximation. If you explicitly need cutoffs and you want your results to be reproducible with future versions, use`closeness()`

,`betweenness()`

and`edge_betweenness()`

in your code with a`cutoff`

argument.`closeness()`

now only considers*reachable*vertices during the calculation; in other words, closeness centrality is now calculated on a per-component basis for disconnected graphs. Earlier versions considered*all*vertices.

- Using
`cutoff=0`

for`closeness()`

,`betweenness()`

and`edge_betweenness()`

is deprecated; if you want exact scores, use a negative cutoff.`cutoff=0`

will be interpreted literally from igraph 1.4.0. `centr_degree_tmax()`

now prints a warning when it is invoked without an explicit`loops`

argument.`loops`

will be mandatory from igraph 1.4.0.- The
`nexus_list()`

,`nexus_info()`

,`nexus_get()`

and`nexus_search()`

functions now return an error informing the user that the Nexus graph repository has been taken offline (actually, several years ago). These functions will be removed in 1.4.0. - The
`edges`

argument of`as_adjacency_matrix()`

is deprecated; it will be removed in igraph 1.4.0.

- The deprecated
`page_rank_old()`

function and the deprecated`power`

method of`page_rank()`

were removed.