# igraph Reference Manual

For using the igraph C library

# Chapter 4. About igraph graphs, the basic interface

## 1. The igraph data model

The igraph library can handle directed and undirected graphs. The igraph graphs are multisets of ordered (if directed) or unordered (if undirected) labeled pairs. The labels of the pairs plus the number of vertices always starts with zero and ends with the number of edges minus one. In addition to that a table of metadata is also attached to every graph, its most important entries are the number of vertices in the graph and whether the graph is directed or undirected.

Like the edges, the igraph vertices are also labeled by number between zero and the number of vertices minus one. So, to summarize, a directed graph can be imagined like this:

```  ( vertices: 6,
directed: yes,
{
(0,2),
(2,2),
(2,3),
(3,3),
(3,4),
(3,4),
(4,1)
}
)
```

Here the edges are ordered pairs or vertex ids, and the graph is a multiset of edges plus some meta-data.

An undirected graph is like this:

```  ( vertices: 6,
directed: no,
{
{0,2},
{2},
{2,3},
{3},
{3,4},
{3,4},
{4,1}
}
)
```

Here an edge is a set of one or two vertex ids, two for most of the time, except for loop edges. A graph is a multiset of edges plus meta data, just like in the directed case.

It is possible to convert a directed graph to an undirected one, see the `igraph_to_directed()` and `igraph_to_undirected()` functions.

Note that igraph has some limited support for graphs with multiple edges. The support means that multiple edges can be stored in igraph graphs, but for most functions (like `igraph_betweenness()`) it is not checked that they work well on graphs with multiple edges. To eliminate multiple edges from a graph, you can use `igraph_simplify()`.

## 2. The basic interface

This is the very minimal API in igraph. All the other functions use this minimal set for creating and manipulating graphs.

This is a very important principle since it makes possible to implement other data representations by implementing only this minimal set.

### 2.1. Graph Constructors and Destructors

#### 2.1.1. `igraph_empty` — Creates an empty graph with some vertices and no edges.

```int igraph_empty(igraph_t *graph, igraph_integer_t n, igraph_bool_t directed);
```

The most basic constructor, all the other constructors should call this to create a minimal graph object. Our use of the term "empty graph" in the above description should be distinguished from the mathematical definition of the empty or null graph. Strictly speaking, the empty or null graph in graph theory is the graph with no vertices and no edges. However by "empty graph" as used in `igraph` we mean a graph having zero or more vertices, but no edges.

Arguments:

`graph`:

Pointer to a not-yet initialized graph object.

`n`:

The number of vertices in the graph, a non-negative integer number is expected.

`directed`:

Boolean; whether the graph is directed or not. Supported values are:

 `IGRAPH_DIRECTED` The graph will be directed. `IGRAPH_UNDIRECTED` The graph will be undirected.

Returns:

 Error code: `IGRAPH_EINVAL`: invalid number of vertices.

Time complexity: O(|V|) for a graph with |V| vertices (and no edges).

Example 4.1.  File `examples/simple/igraph_empty.c`

```/* -*- mode: C -*-  */
/*
IGraph library.
Copyright (C) 2006-2012  Gabor Csardi <csardi.gabor@gmail.com>
334 Harvard st, Cambridge MA, 02139 USA

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc.,  51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA

*/

#include <igraph.h>

int main() {

igraph_t g;
int ret;

/* empty directed graph, zero vertices */
igraph_empty(&g, 0, 1);
if (igraph_vcount(&g) != 0) {
return 1;
}
if (igraph_ecount(&g) != 0) {
return 2;
}
igraph_destroy(&g);

/* empty undirected graph, zero vertices */
igraph_empty(&g, 0, 0);
if (igraph_vcount(&g) != 0) {
return 3;
}
if (igraph_ecount(&g) != 0) {
return 4;
}
igraph_destroy(&g);

/* empty directed graph, 20 vertices */
igraph_empty(&g, 20, 1);
if (igraph_vcount(&g) != 20) {
return 5;
}
if (igraph_ecount(&g) != 0) {
return 6;
}
igraph_destroy(&g);

/* empty undirected graph, 30 vertices */
igraph_empty(&g, 30, 0);
if (igraph_vcount(&g) != 30) {
return 7;
}
if (igraph_ecount(&g) != 0) {
return 8;
}
igraph_destroy(&g);

/* error: negative number of vertices */
igraph_set_error_handler(igraph_error_handler_ignore);
ret=igraph_empty(&g, -1, 0);
if (ret != IGRAPH_EINVAL) {
return 9;
}

return 0;
}
```

#### 2.1.2. `igraph_empty_attrs` — Creates an empty graph with some vertices, no edges and some graph attributes.

```int igraph_empty_attrs(igraph_t *graph, igraph_integer_t n, igraph_bool_t directed, void* attr);
```

Use this instead of `igraph_empty()` if you wish to add some graph attributes right after initialization. This function is currently not very interesting for the ordinary user. Just supply 0 here or use `igraph_empty()`.

Arguments:

`graph`:

Pointer to a not-yet initialized graph object.

`n`:

The number of vertices in the graph; a non-negative integer number is expected.

`directed`:

Boolean; whether the graph is directed or not. Supported values are:

 `IGRAPH_DIRECTED` Create a directed graph. `IGRAPH_UNDIRECTED` Create an undirected graph.

`attr`:

The attributes.

Returns:

 Error code: `IGRAPH_EINVAL`: invalid number of vertices.

Time complexity: O(|V|) for a graph with |V| vertices (and no edges).

#### 2.1.3. `igraph_copy` — Creates an exact (deep) copy of a graph.

```int igraph_copy(igraph_t *to, const igraph_t *from);
```

This function deeply copies a graph object to create an exact replica of it. The new replica should be destroyed by calling `igraph_destroy()` on it when not needed any more.

You can also create a shallow copy of a graph by simply using the standard assignment operator, but be careful and do not destroy a shallow replica. To avoid this mistake, creating shallow copies is not recommended.

Arguments:

 `to`: Pointer to an uninitialized graph object. `from`: Pointer to the graph object to copy.

Returns:

 Error code.

Time complexity: O(|V|+|E|) for a graph with |V| vertices and |E| edges.

Example 4.2.  File `examples/simple/igraph_copy.c`

```/* -*- mode: C -*-  */
/*
IGraph library.
Copyright (C) 2006-2012  Gabor Csardi <csardi.gabor@gmail.com>
334 Harvard street, Cambridge, MA 02139 USA

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc.,  51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA

*/

#include <igraph.h>

int main() {

igraph_t g1, g2;
igraph_vector_t v1, v2;

igraph_vector_init(&v1, 8);
VECTOR(v1)=0; VECTOR(v1)=1;
VECTOR(v1)=1; VECTOR(v1)=2;
VECTOR(v1)=2; VECTOR(v1)=3;
VECTOR(v1)=2; VECTOR(v1)=2;

igraph_create(&g1, &v1, 0, 0);
igraph_copy(&g2, &g1);

igraph_vector_init(&v2, 0);
igraph_get_edgelist(&g2, &v2, 0);
if (!igraph_vector_all_e(&v1, &v2)) {
return 1;
}

igraph_vector_destroy(&v1);
igraph_vector_destroy(&v2);
igraph_destroy(&g1);
igraph_destroy(&g2);

return 0;
}
```

#### 2.1.4. `igraph_destroy` — Frees the memory allocated for a graph object.

```int igraph_destroy(igraph_t *graph);
```

This function should be called for every graph object exactly once.

This function invalidates all iterators (of course), but the iterators of a graph should be destroyed before the graph itself anyway.

Arguments:

 `graph`: Pointer to the graph to free.

Returns:

 Error code.

Time complexity: operating system specific.

### 2.2. Basic Query Operations

#### 2.2.1. `igraph_vcount` — The number of vertices in a graph.

```igraph_integer_t igraph_vcount(const igraph_t *graph);
```

Arguments:

 `graph`: The graph.

Returns:

 Number of vertices.

Time complexity: O(1)

#### 2.2.2. `igraph_ecount` — The number of edges in a graph.

```igraph_integer_t igraph_ecount(const igraph_t *graph);
```

Arguments:

 `graph`: The graph.

Returns:

 Number of edges.

Time complexity: O(1)

#### 2.2.3. `igraph_edge` — Gives the head and tail vertices of an edge.

```int igraph_edge(const igraph_t *graph, igraph_integer_t eid,
igraph_integer_t *from, igraph_integer_t *to);
```

Arguments:

 `graph`: The graph object. `eid`: The edge id. `from`: Pointer to an igraph_integer_t. The tail of the edge will be placed here. `to`: Pointer to an igraph_integer_t. The head of the edge will be placed here.

Returns:

 Error code. The current implementation always returns with success.

See also:

 `igraph_get_eid()` for the opposite operation.

Added in version 0.2.

Time complexity: O(1).

#### 2.2.4. `igraph_get_eid` — Get the edge id from the end points of an edge.

```int igraph_get_eid(const igraph_t *graph, igraph_integer_t *eid,
igraph_integer_t pfrom, igraph_integer_t pto,
igraph_bool_t directed, igraph_bool_t error);
```

For undirected graphs `pfrom` and `pto` are exchangeable.

Arguments:

 `graph`: The graph object. `eid`: Pointer to an integer, the edge id will be stored here. `pfrom`: The starting point of the edge. `pto`: The end point of the edge. `directed`: Logical constant, whether to search for directed edges in a directed graph. Ignored for undirected graphs. `error`: Logical scalar, whether to report an error if the edge was not found. If it is false, then -1 will be assigned to `eid`.

Returns:

 Error code.

See also:

 `igraph_edge()` for the opposite operation.

Time complexity: O(log (d)), where d is smaller of the out-degree of `pfrom` and in-degree of `pto` if `directed` is true. If `directed` is false, then it is O(log(d)+log(d2)), where d is the same as before and d2 is the minimum of the out-degree of `pto` and the in-degree of `pfrom`.

Example 4.3.  File `examples/simple/igraph_get_eid.c`

```/* -*- mode: C -*-  */
/*
IGraph library.
Copyright (C) 2006-2012  Gabor Csardi <csardi.gabor@gmail.com>
334 Harvard st, Cambridge MA, 02139 USA

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc.,  51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA

*/

#include <igraph.h>

void print_vector(igraph_vector_t *v, FILE *f) {
long int i;
for (i=0; i<igraph_vector_size(v); i++) {
fprintf(f, " %li", (long int) VECTOR(*v)[i]);
}
fprintf(f, "\n");
}

int main() {
igraph_t g;
igraph_integer_t eid;
igraph_vector_t hist;
long int i;
int ret;

/* DIRECTED */

igraph_star(&g, 10, IGRAPH_STAR_OUT, 0);

igraph_vector_init(&hist, 9);

for (i=1; i<10; i++) {
igraph_get_eid(&g, &eid, 0, i, IGRAPH_DIRECTED, /*error=*/ 1);
VECTOR(hist)[ (long int) eid ] = 1;
}
print_vector(&hist, stdout);

igraph_vector_destroy(&hist);
igraph_destroy(&g);

/* UNDIRECTED */

igraph_star(&g, 10, IGRAPH_STAR_UNDIRECTED, 0);

igraph_vector_init(&hist, 9);

for (i=1; i<10; i++) {
igraph_get_eid(&g, &eid, 0, i, IGRAPH_UNDIRECTED, /*error=*/ 1);
VECTOR(hist)[ (long int) eid ] += 1;
igraph_get_eid(&g, &eid, i, 0, IGRAPH_DIRECTED, /*error=*/ 1);
VECTOR(hist)[ (long int) eid ] += 1;
}
print_vector(&hist, stdout);

igraph_vector_destroy(&hist);
igraph_destroy(&g);

/* NON-EXISTANT EDGE */

igraph_star(&g, 10, IGRAPH_STAR_UNDIRECTED, 0);

igraph_set_error_handler(igraph_error_handler_ignore);

ret=igraph_get_eid(&g, &eid, 5, 6, IGRAPH_UNDIRECTED, /*error=*/ 1);
if (ret != IGRAPH_EINVAL) {
return 1;
}

igraph_destroy(&g);

return 0;
}

/* Stress test */

/* int main() { */

/*   igraph_t g; */
/*   long int i, n; */
/*   igraph_integer_t from, to, eid; */

/*   igraph_barabasi_game(&g, 10000, 100, 0, 0, 1); */
/*   n=igraph_ecount(&g); */
/*   for (i=0; i<n; i++) { */
/*     igraph_edge(&g, i, &from, &to); */
/*     igraph_get_eid(&g, &eid, from, to, 1, 1); */
/*     igraph_get_eid(&g, &eid, to, from, 0, 1); */
/*     igraph_get_eid(&g, &eid, from, to, 0, 1); */
/*   } */
/*   igraph_destroy(&g); */

/*   igraph_barabasi_game(&g, 10000, 100, 0, 0, 0); */
/*   n=igraph_ecount(&g); */
/*   for (i=0; i<n; i++) { */
/*     igraph_edge(&g, i, &from, &to); */
/*     igraph_get_eid(&g, &eid, from, to, 0, 1); */
/*     igraph_get_eid(&g, &eid, to, from, 0, 1); */
/*   } */
/*   igraph_destroy(&g); */

/*   igraph_erdos_renyi_game(&g, IGRAPH_ERDOS_RENYI_GNP, */
/* 			  2000, 100.0/2000, 0, 0); */
/*   n=igraph_ecount(&g); */
/*   for (i=0; i<n; i++) { */
/*     igraph_edge(&g, i, &from, &to); */
/*     igraph_get_eid(&g, &eid, from, to, 0, 1); */
/*     igraph_get_eid(&g, &eid, to, from, 0, 1); */
/*   } */
/*   igraph_destroy(&g); */

/*   igraph_full(&g, 500, 0, 0); */
/*   n=igraph_ecount(&g); */
/*   for (i=0; i<n; i++) { */
/*     igraph_edge(&g, i, &from, &to); */
/*     igraph_get_eid(&g, &eid, from, to, 0, 1); */
/*   } */
/*   igraph_destroy(&g); */

/*   igraph_star(&g, 20000, IGRAPH_STAR_OUT, 0); */
/*   n=igraph_ecount(&g); */
/*   for (i=0; i<n; i++) { */
/*     igraph_edge(&g, i, &from, &to); */
/*     igraph_get_eid(&g, &eid, from, to, 0, 1); */
/*   } */
/*   igraph_destroy(&g); */

/*   igraph_star(&g, 20000, IGRAPH_STAR_IN, 0); */
/*   n=igraph_ecount(&g); */
/*   for (i=0; i<n; i++) { */
/*     igraph_edge(&g, i, &from, &to); */
/*     igraph_get_eid(&g, &eid, from, to, 0, 1); */
/*   } */
/*   igraph_destroy(&g); */

/*   igraph_star(&g, 2000000, IGRAPH_STAR_UNDIRECTED, 1999999); */
/*   n=igraph_ecount(&g); */
/*   for (i=0; i<n; i++) { */
/*     igraph_edge(&g, i, &from, &to); */
/*     igraph_get_eid(&g, &eid, from, to, 0, 1); */
/*     igraph_get_eid(&g, &eid, to, from, 0, 1); */
/*   } */
/*   igraph_destroy(&g); */

/*   return 0; */
/* } */
```

Added in version 0.2.

#### 2.2.5. `igraph_get_eids` — Return edge ids based on the adjacent vertices.

```int igraph_get_eids(const igraph_t *graph, igraph_vector_t *eids,
const igraph_vector_t *pairs,
const igraph_vector_t *path,
igraph_bool_t directed, igraph_bool_t error);
```

This function operates in two modes. If the `pairs` argument is not a null pointer, but the `path` argument is, then it searches for the edge ids of all pairs of vertices given in `pairs`. The pairs of vertex ids are taken consecutively from the vector, i.e. ` VECTOR(pairs)` and ` VECTOR(pairs)` give the first pair, ` VECTOR(pairs)` and ` VECTOR(pairs)` the second pair, etc.

If the `pairs` argument is a null pointer, and `path` is not a null pointer, then the `path` is interpreted as a path given by vertex ids and the edges along the path are returned.

If neither `pairs` nor `path` are null pointers, then both are considered (first `pairs` and then `path`), and the results are concatenated.

If the `error` argument is true, then it is an error to give pairs of vertices that are not connected. Otherwise -1 is reported for not connected vertices.

If there are multiple edges in the graph, then these are ignored; i.e. for a given pair of vertex ids, always the same edge id is returned, even if the pair is given multiple time in `pairs` or in `path`. See `igraph_get_eids_multi()` for a similar function that works differently in case of multiple edges.

Arguments:

 `graph`: The input graph. `eids`: Pointer to an initialized vector, the result is stored here. It will be resized as needed. `pairs`: Vector giving pairs of vertices, or a null pointer. `path`: Vector giving vertex ids along a path, or a null pointer. `directed`: Logical scalar, whether to consider edge directions in directed graphs. This is ignored for undirected graphs. `error`: Logical scalar, whether it is an error to supply non-connected vertices. If false, then -1 is returned for non-connected pairs.

Returns:

 Error code.

Time complexity: O(n log(d)), where n is the number of queried edges and d is the average degree of the vertices.

See also:

 `igraph_get_eid()` for a single edge, `igraph_get_eids_multi()` for a version that handles multiple edges better (at a cost).

Example 4.4.  File `examples/simple/igraph_get_eids.c`

```/* -*- mode: C -*-  */
/*
IGraph library.
Copyright (C) 2008-2012  Gabor Csardi <csardi.gabor@gmail.com>
334 Harvard st, Cambridge MA, 02139 USA

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc.,  51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA

*/

#include <igraph.h>
#include <stdlib.h>

void print_vector(igraph_vector_t *v, FILE *f) {
long int i;
for (i=0; i<igraph_vector_size(v); i++) {
fprintf(f, " %li", (long int) VECTOR(*v)[i]);
}
fprintf(f, "\n");
}

int check_simple() {

igraph_t g;
long int nodes=100;
long int edges=1000;
igraph_real_t p=3.0/nodes;
long int runs=10;
long int r, e, ecount;
igraph_vector_t eids, pairs, path;

srand(time(0));

igraph_vector_init(&pairs, edges*2);
igraph_vector_init(&path, 0);
igraph_vector_init(&eids, 0);

for (r=0; r<runs; r++) {
igraph_erdos_renyi_game(&g, IGRAPH_ERDOS_RENYI_GNP, nodes, p,
/*directed=*/ 0, /*loops=*/ 0);
ecount=igraph_ecount(&g);
for (e=0; e<edges; e++) {
long int edge=RNG_INTEGER(0, ecount-1);
VECTOR(pairs)[2*e] = IGRAPH_FROM(&g, edge);
VECTOR(pairs)[2*e+1] = IGRAPH_TO(&g, edge);
}
igraph_get_eids(&g, &eids, &pairs, /*path=*/ 0, 0, /*error=*/ 1);
for (e=0; e<edges; e++) {
long int edge=VECTOR(eids)[e];
long int from1=VECTOR(pairs)[2*e];
long int to1=VECTOR(pairs)[2*e+1];
long int from2=IGRAPH_FROM(&g, edge);
long int to2=IGRAPH_TO(&g, edge);
long int min1= from1 < to1 ? from1 : to1;
long int max1= from1 < to1 ? to1 : from1;
long int min2= from2 < to2 ? from2 : to2;
long int max2= from2 < to2 ? to2 : from2;
if (min1 != min2 || max1 != max2) {
return 11;
}
}

igraph_diameter(&g, /*res=*/ 0, /*from=*/ 0, /*to=*/ 0, &path,
IGRAPH_UNDIRECTED, /*unconn=*/ 1);
igraph_get_eids(&g, &eids, /*pairs=*/ 0, &path, 0, /*error=*/ 1);
for (e=0; e<igraph_vector_size(&path)-1; e++) {
long int edge=VECTOR(eids)[e];
long int from1=VECTOR(path)[e];
long int to1=VECTOR(path)[e+1];
long int from2=IGRAPH_FROM(&g, edge);
long int to2=IGRAPH_TO(&g, edge);
long int min1= from1 < to1 ? from1 : to1;
long int max1= from1 < to1 ? to1 : from1;
long int min2= from2 < to2 ? from2 : to2;
long int max2= from2 < to2 ? to2 : from2;
if (min1 != min2 || max1 != max2) {
return 12;
}
}

igraph_destroy(&g);
}

igraph_vector_destroy(&path);
igraph_vector_destroy(&pairs);
igraph_vector_destroy(&eids);

return 0;
}

int check_multi() {

igraph_t g;
igraph_vector_t vec;
igraph_vector_t eids, eids2;
int ret;
long int i;

igraph_real_t q1[] = { 0,1, 0,1 };
igraph_real_t q2[] = { 0,1, 0,1, 0,1 };
igraph_real_t q3[] = { 1,0, 3,4, 1,0, 0,1, 3,4, 0,1 };

igraph_vector_init(&eids, 0);

/*********************************/
igraph_small(&g, /*n=*/ 10, /*directed=*/ 1,
0,1, 0,1, 1,0, 1,2, 3,4, 3,4, 3,4, 3,5, 3,7,
9,8,
-1);

igraph_vector_view(&vec, q1, sizeof(q1) / sizeof(igraph_real_t));
igraph_get_eids_multi(&g, &eids, &vec, 0, /*directed=*/ 1, /*error=*/ 1);
igraph_vector_sort(&eids);
print_vector(&eids, stdout);

igraph_vector_view(&vec, q2, sizeof(q2) / sizeof(igraph_real_t));
igraph_get_eids_multi(&g, &eids, &vec, 0, /*directed=*/ 0, /*error=*/ 1);
igraph_vector_sort(&eids);
print_vector(&eids, stdout);

igraph_vector_view(&vec, q2, sizeof(q2) / sizeof(igraph_real_t));
igraph_set_error_handler(igraph_error_handler_ignore);
ret=igraph_get_eids_multi(&g, &eids, &vec, 0, /*directed=*/ 1, /*error=*/1);
if (ret != IGRAPH_EINVAL) { return 1; }
igraph_set_error_handler(igraph_error_handler_abort);

igraph_destroy(&g);
/*********************************/

/*********************************/
igraph_small(&g, /*n=*/10, /*directed=*/0,
0,1, 1,0, 0,1, 3,4, 3,4, 5,4, 9,8,
-1);

igraph_vector_view(&vec, q1, sizeof(q1) / sizeof(igraph_real_t));
igraph_get_eids_multi(&g, &eids, &vec, 0, /*directed=*/1, /*error=*/ 1);
igraph_vector_sort(&eids);
print_vector(&eids, stdout);

igraph_vector_view(&vec, q3, sizeof(q3) / sizeof(igraph_real_t));
igraph_set_error_handler(igraph_error_handler_ignore);
ret=igraph_get_eids_multi(&g, &eids, &vec, 0, /*directed=*/0, /*error=*/ 1);
if (ret != IGRAPH_EINVAL) { return 2; }
igraph_set_error_handler(igraph_error_handler_abort);

igraph_destroy(&g);

/*********************************/

igraph_vector_destroy(&eids);

/*********************************/
/* Speed tests */

#define NODES 10000
igraph_barabasi_game(&g, /*n=*/ NODES, /*power=*/ 1.0, /*m=*/ 3,
/*outseq=*/ 0, /*outpref=*/ 0, /*A=*/ 1,
/*directed=*/ 1, IGRAPH_BARABASI_BAG,
/*start_from=*/ 0);
igraph_simplify(&g, /*multiple=*/ 1, /*loops=*/ 0, /*edge_comb=*/ 0);

igraph_vector_init(&eids, NODES/2);
igraph_random_sample(&eids, 0, igraph_ecount(&g)-1, NODES/2);
igraph_vector_init(&vec, NODES);
for (i=0; i<NODES/2; i++) {
VECTOR(vec)[2*i]   = IGRAPH_FROM(&g, VECTOR(eids)[i]);
VECTOR(vec)[2*i+1] = IGRAPH_TO(&g, VECTOR(eids)[i]);
}
igraph_vector_init(&eids2, 0);
igraph_get_eids_multi(&g, &eids2, &vec, 0, /*directed=*/ 1, /*error=*/ 1);
if (!igraph_vector_all_e(&eids, &eids2)) {
return 3;
}

/**/

for (i=0; i<NODES/2; i++) {
VECTOR(vec)[2*i]   = IGRAPH_TO(&g, VECTOR(eids)[i]);
VECTOR(vec)[2*i+1] = IGRAPH_FROM(&g, VECTOR(eids)[i]);
}
igraph_get_eids_multi(&g, &eids2, &vec, 0, /*directed=*/ 0, /*error=*/ 1);
if (!igraph_vector_all_e(&eids, &eids2)) {
return 4;
}

igraph_vector_destroy(&eids);
igraph_vector_destroy(&eids2);
igraph_vector_destroy(&vec);
igraph_destroy(&g);

/*********************************/

return 0;
}

int main() {
int ret;

if ( (ret=check_simple()) != 0) { return ret; }
if ( (ret=check_multi()) != 0)  { return ret; }

return 0;
}
```

#### 2.2.6. `igraph_get_eids_multi` — Query edge ids based on their adjacent vertices, handle multiple edges.

```int igraph_get_eids_multi(const igraph_t *graph, igraph_vector_t *eids,
const igraph_vector_t *pairs,
const igraph_vector_t *path,
igraph_bool_t directed, igraph_bool_t error);
```

This function operates in two modes. If the `pairs` argument is not a null pointer, but the `path` argument is, then it searches for the edge ids of all pairs of vertices given in `pairs`. The pairs of vertex ids are taken consecutively from the vector, i.e. ` VECTOR(pairs)` and ` VECTOR(pairs)` give the first pair, ` VECTOR(pairs)` and ` VECTOR(pairs)` the second pair, etc.

If the `pairs` argument is a null pointer, and `path` is not a null pointer, then the `path` is interpreted as a path given by vertex ids and the edges along the path are returned.

If the `error` argument is true, then it is an error to give pairs of vertices that are not connected. Otherwise -1 is returned for not connected vertex pairs.

An error is triggered if both `pairs` and `path` are non-null pointers.

This function handles multiple edges properly, i.e. if the same pair is given multiple times and they are indeed connected by multiple edges, then each time a different edge id is reported.

Arguments:

 `graph`: The input graph. `eids`: Pointer to an initialized vector, the result is stored here. It will be resized as needed. `pairs`: Vector giving pairs of vertices, or a null pointer. `path`: Vector giving vertex ids along a path, or a null pointer. `directed`: Logical scalar, whether to consider edge directions in directed graphs. This is ignored for undirected graphs. `error`: Logical scalar, whether to report an error if non-connected vertices are specified. If false, then -1 is returned for non-connected vertex pairs.

Returns:

 Error code.

Time complexity: O(|E|+n log(d)), where |E| is the number of edges in the graph, n is the number of queried edges and d is the average degree of the vertices.

See also:

 `igraph_get_eid()` for a single edge, `igraph_get_eids()` for a faster version that does not handle multiple edges.

#### 2.2.7. `igraph_neighbors` — Adjacent vertices to a vertex.

```int igraph_neighbors(const igraph_t *graph, igraph_vector_t *neis, igraph_integer_t pnode,
igraph_neimode_t mode);
```

Arguments:

 `graph`: The graph to work on. `neis`: This vector will contain the result. The vector should be initialized beforehand and will be resized. Starting from igraph version 0.4 this vector is always sorted, the vertex ids are in increasing order. `pnode`: The id of the node for which the adjacent vertices are to be searched. `mode`: Defines the way adjacent vertices are searched in directed graphs. It can have the following values: `IGRAPH_OUT`, vertices reachable by an edge from the specified vertex are searched; `IGRAPH_IN`, vertices from which the specified vertex is reachable are searched; `IGRAPH_ALL`, both kinds of vertices are searched. This parameter is ignored for undirected graphs.

Returns:

 Error code: `IGRAPH_EINVVID`: invalid vertex id. `IGRAPH_EINVMODE`: invalid mode argument. `IGRAPH_ENOMEM`: not enough memory.

Time complexity: O(d), d is the number of adjacent vertices to the queried vertex.

Example 4.5.  File `examples/simple/igraph_neighbors.c`

```/* -*- mode: C -*-  */
/*
IGraph library.
Copyright (C) 2006-2012  Gabor Csardi <csardi.gabor@gmail.com>
334 Harvard st, Cambridge MA, 02139 USA

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc.,  51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA

*/

#include <igraph.h>

void print_vector(igraph_vector_t *v, FILE *f) {
long int i;
for (i=0; i<igraph_vector_size(v); i++) {
fprintf(f, " %li", (long int) VECTOR(*v)[i]);
}
fprintf(f, "\n");
}

int main() {

igraph_t g;
igraph_vector_t v;
int ret;

igraph_vector_init(&v, 8);
VECTOR(v)=0; VECTOR(v)=1;
VECTOR(v)=1; VECTOR(v)=2;
VECTOR(v)=2; VECTOR(v)=3;
VECTOR(v)=2; VECTOR(v)=2;
igraph_create(&g, &v, 0, 1);

igraph_neighbors(&g, &v, 2, IGRAPH_OUT);
igraph_vector_sort(&v);
print_vector(&v, stdout);

igraph_neighbors(&g, &v, 2, IGRAPH_IN);
igraph_vector_sort(&v);
print_vector(&v, stdout);

igraph_neighbors(&g, &v, 2, IGRAPH_ALL);
igraph_vector_sort(&v);
print_vector(&v, stdout);

/* Errors */
igraph_set_error_handler(igraph_error_handler_ignore);
ret=igraph_neighbors(&g, &v, 2, (igraph_neimode_t)0); /* conv for c++ */
if (ret != IGRAPH_EINVMODE) {
return 1;
}

ret=igraph_neighbors(&g, &v, 4, IGRAPH_ALL);
if (ret != IGRAPH_EINVVID) {
return 2;
}

igraph_vector_destroy(&v);
igraph_destroy(&g);
return 0;
}
```

#### 2.2.8. `igraph_incident` — Gives the incident edges of a vertex.

```int igraph_incident(const igraph_t *graph, igraph_vector_t *eids,
igraph_integer_t pnode, igraph_neimode_t mode);
```

Arguments:

 `graph`: The graph object. `eids`: An initialized vector_t object. It will be resized to hold the result. `pnode`: A vertex id. `mode`: Specifies what kind of edges to include for directed graphs. `IGRAPH_OUT` means only outgoing edges, `IGRAPH_IN` only incoming edges, `IGRAPH_ALL` both. This parameter is ignored for undirected graphs.

Returns:

 Error code. `IGRAPH_EINVVID`: invalid `pnode` argument, `IGRAPH_EINVMODE`: invalid `mode` argument.

Added in version 0.2.

Time complexity: O(d), the number of incident edges to `pnode`.

#### 2.2.9. `igraph_is_directed` — Is this a directed graph?

```igraph_bool_t igraph_is_directed(const igraph_t *graph);
```

Arguments:

 `graph`: The graph.

Returns:

 Logical value, ` TRUE` if the graph is directed, ` FALSE` otherwise.

Time complexity: O(1)

Example 4.6.  File `examples/simple/igraph_is_directed.c`

```/* -*- mode: C -*-  */
/*
IGraph library.
Copyright (C) 2006-2012  Gabor Csardi <csardi.gabor@gmail.com>
334 Harvard st, Cambridge MA, 02139 USA

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc.,  51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA

*/

#include <igraph.h>

int main() {

igraph_t g;

igraph_empty(&g, 0, 0);
if (igraph_is_directed(&g)) {
return 1;
}
igraph_destroy(&g);

igraph_empty(&g, 0, 1);
if (!igraph_is_directed(&g)) {
return 2;
}
igraph_destroy(&g);

return 0;
}
```

#### 2.2.10. `igraph_degree` — The degree of some vertices in a graph.

```int igraph_degree(const igraph_t *graph, igraph_vector_t *res,
const igraph_vs_t vids,
igraph_neimode_t mode, igraph_bool_t loops);
```

This function calculates the in-, out- or total degree of the specified vertices.

Arguments:

 `graph`: The graph. `res`: Vector, this will contain the result. It should be initialized and will be resized to be the appropriate size. `vids`: Vector, giving the vertex ids of which the degree will be calculated. `mode`: Defines the type of the degree. Valid modes are: `IGRAPH_OUT`, out-degree; `IGRAPH_IN`, in-degree; `IGRAPH_ALL`, total degree (sum of the in- and out-degree). This parameter is ignored for undirected graphs. `loops`: Boolean, gives whether the self-loops should be counted.

Returns:

 Error code: `IGRAPH_EINVVID`: invalid vertex id. `IGRAPH_EINVMODE`: invalid mode argument.

Time complexity: O(v) if loops is TRUE, and O(v*d) otherwise. v is the number of vertices for which the degree will be calculated, and d is their (average) degree.

See also:

 `igraph_strength()` for the version that takes into account edge weights.

Example 4.7.  File `examples/simple/igraph_degree.c`

```/* -*- mode: C -*-  */
/*
IGraph library.
Copyright (C) 2006-2012  Gabor Csardi <csardi.gabor@gmail.com>
334 Harvard street, Cambridge, MA 02139 USA

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc.,  51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA

*/

#include <igraph.h>

void print_vector(igraph_vector_t *v, FILE *f) {
long int i;
for (i=0; i<igraph_vector_size(v); i++) {
fprintf(f, " %li", (long int) VECTOR(*v)[i]);
}
fprintf(f, "\n");
}

int main() {

igraph_t g;
igraph_vector_t v, seq;
int ret;
igraph_integer_t mdeg, nedges;
long int i;
long int ndeg;

/* Create graph */
igraph_vector_init(&v, 8);
VECTOR(v)=0; VECTOR(v)=1;
VECTOR(v)=1; VECTOR(v)=2;
VECTOR(v)=2; VECTOR(v)=3;
VECTOR(v)=2; VECTOR(v)=2;
igraph_create(&g, &v, 0, IGRAPH_DIRECTED);

igraph_degree(&g, &v, igraph_vss_all(), IGRAPH_OUT, IGRAPH_NO_LOOPS);
print_vector(&v, stdout);

igraph_degree(&g, &v, igraph_vss_all(), IGRAPH_OUT, IGRAPH_LOOPS);
print_vector(&v, stdout);

igraph_degree(&g, &v, igraph_vss_all(), IGRAPH_IN, IGRAPH_NO_LOOPS);
print_vector(&v, stdout);

igraph_degree(&g, &v, igraph_vss_all(), IGRAPH_IN, IGRAPH_LOOPS);
print_vector(&v, stdout);

igraph_degree(&g, &v, igraph_vss_all(), IGRAPH_ALL, IGRAPH_NO_LOOPS);
print_vector(&v, stdout);

igraph_degree(&g, &v, igraph_vss_all(), IGRAPH_ALL, IGRAPH_LOOPS);
print_vector(&v, stdout);

igraph_set_error_handler(igraph_error_handler_ignore);

/* Consistency check of the handshaking lemma. */
/* If d is the sum of all vertex degrees, then d = 2|E|. */
ndeg = 0;
nedges = igraph_ecount(&g);
for (i = 0; i < igraph_vector_size(&v); i++) {
ndeg += (long int) VECTOR(v)[i];
}
if (ndeg != 2*nedges) {
return 1;
}

igraph_destroy(&g);

igraph_vector_resize(&v, 8);
VECTOR(v)=0; VECTOR(v)=1;
VECTOR(v)=1; VECTOR(v)=2;
VECTOR(v)=2; VECTOR(v)=3;
VECTOR(v)=2; VECTOR(v)=2;
igraph_create(&g, &v, 0, IGRAPH_UNDIRECTED);

igraph_degree(&g, &v, igraph_vss_all(), IGRAPH_OUT, IGRAPH_NO_LOOPS);
print_vector(&v, stdout);

igraph_degree(&g, &v, igraph_vss_all(), IGRAPH_OUT, IGRAPH_LOOPS);
print_vector(&v, stdout);

igraph_degree(&g, &v, igraph_vss_all(), IGRAPH_IN, IGRAPH_NO_LOOPS);
print_vector(&v, stdout);

igraph_degree(&g, &v, igraph_vss_all(), IGRAPH_IN, IGRAPH_LOOPS);
print_vector(&v, stdout);

igraph_degree(&g, &v, igraph_vss_all(), IGRAPH_ALL, IGRAPH_NO_LOOPS);
print_vector(&v, stdout);

igraph_degree(&g, &v, igraph_vss_all(), IGRAPH_ALL, IGRAPH_LOOPS);
print_vector(&v, stdout);

/* Consistency check of the handshaking lemma. */
/* If d is the sum of all vertex degrees, then d = 2|E|. */
ndeg = 0;
nedges = igraph_ecount(&g);
for (i = 0; i < igraph_vector_size(&v); i++) {
ndeg += (long int) VECTOR(v)[i];
}
if (ndeg != 2*nedges) {
return 2;
}

/* Degree of the same vertex multiple times */

igraph_vector_init(&seq, 3);
VECTOR(seq)=2; VECTOR(seq)=0; VECTOR(seq)=2;
igraph_degree(&g, &v, igraph_vss_vector(&seq), IGRAPH_ALL, IGRAPH_LOOPS);
print_vector(&v, stdout);

/* Errors */
ret=igraph_degree(&g, &v, igraph_vss_vector(&seq), (igraph_neimode_t)0,
IGRAPH_LOOPS);
if (ret != IGRAPH_EINVMODE) {
return 3;
}

VECTOR(seq)=4;
ret=igraph_degree(&g, &v, igraph_vss_vector(&seq), IGRAPH_ALL, IGRAPH_LOOPS);
if (ret != IGRAPH_EINVVID) {
return 4;
}

igraph_destroy(&g);
igraph_vector_destroy(&seq);

/* Maximum degree */

igraph_ring(&g, 10, 0 /*undirected*/, 0 /*undirected*/, 0/*uncircular*/);
igraph_maxdegree(&g, &mdeg, igraph_vss_all(), IGRAPH_ALL, IGRAPH_LOOPS);
if (mdeg != 2) {
return 5;
}
/* Consistency check of the handshaking lemma. */
/* If d is the sum of all vertex degrees, then d = 2|E|. */
igraph_degree(&g, &v, igraph_vss_all(), IGRAPH_ALL, IGRAPH_LOOPS);
ndeg = 0;
nedges = igraph_ecount(&g);
for (i = 0; i < igraph_vector_size(&v); i++) {
ndeg += (long int) VECTOR(v)[i];
}
if (ndeg != 2*nedges) {
return 6;
}
igraph_destroy(&g);

igraph_full(&g, 10, 0 /*undirected*/, 0/*no loops*/);
igraph_maxdegree(&g, &mdeg, igraph_vss_all(), IGRAPH_ALL, IGRAPH_LOOPS);
if (mdeg != 9) {
return 7;
}
/* Consistency check of the handshaking lemma. */
/* If d is the sum of all vertex degrees, then d = 2|E|. */
igraph_degree(&g, &v, igraph_vss_all(), IGRAPH_ALL, IGRAPH_LOOPS);
ndeg = 0;
nedges = igraph_ecount(&g);
for (i = 0; i < igraph_vector_size(&v); i++) {
ndeg += (long int) VECTOR(v)[i];
}
if (ndeg != 2*nedges) {
return 8;
}
igraph_destroy(&g);

igraph_star(&g, 10, IGRAPH_STAR_OUT, 0);
igraph_maxdegree(&g, &mdeg, igraph_vss_all(), IGRAPH_OUT, IGRAPH_LOOPS);
if (mdeg != 9) {
return 9;
}
igraph_maxdegree(&g, &mdeg, igraph_vss_all(), IGRAPH_IN, IGRAPH_LOOPS);
if (mdeg != 1) {
return 10;
}
igraph_maxdegree(&g, &mdeg, igraph_vss_all(), IGRAPH_ALL, IGRAPH_LOOPS);
if (mdeg != 9) {
return 11;
}
/* Consistency check of the handshaking lemma. */
/* If d is the sum of all vertex degrees, then d = 2|E|. */
igraph_degree(&g, &v, igraph_vss_all(), IGRAPH_ALL, IGRAPH_LOOPS);
ndeg = 0;
nedges = igraph_ecount(&g);
for (i = 0; i < igraph_vector_size(&v); i++) {
ndeg += (long int) VECTOR(v)[i];
}
if (ndeg != 2*nedges) {
return 12;
}
igraph_destroy(&g);

igraph_vector_destroy(&v);

return 0;
}
```

### 2.3. Adding and Deleting Vertices and Edges

#### 2.3.1. `igraph_add_edge` — Adds a single edge to a graph.

```int igraph_add_edge(igraph_t *graph, igraph_integer_t from, igraph_integer_t to);
```

For directed graphs the edge points from `from` to `to`.

Note that if you want to add many edges to a big graph, then it is inefficient to add them one by one, it is better to collect them into a vector and add all of them via a single `igraph_add_edges()` call.

Arguments:

 `igraph`: The graph. `from`: The id of the first vertex of the edge. `to`: The id of the second vertex of the edge.

Returns:

 Error code.

See also:

 `igraph_add_edges()` to add many edges, `igraph_delete_edges()` to remove edges and `igraph_add_vertices()` to add vertices.

Time complexity: O(|V|+|E|), the number of edges plus the number of vertices.

#### 2.3.2. `igraph_add_edges` — Adds edges to a graph object.

```int igraph_add_edges(igraph_t *graph, const igraph_vector_t *edges,
void *attr);
```

The edges are given in a vector, the first two elements define the first edge (the order is ` from` , ` to` for directed graphs). The vector should contain even number of integer numbers between zero and the number of vertices in the graph minus one (inclusive). If you also want to add new vertices, call igraph_add_vertices() first.

Arguments:

 `graph`: The graph to which the edges will be added. `edges`: The edges themselves. `attr`: The attributes of the new edges, only used by high level interfaces currently, you can supply 0 here.

Returns:

 Error code: `IGRAPH_EINVEVECTOR`: invalid (odd) edges vector length, `IGRAPH_EINVVID`: invalid vertex id in edges vector.

This function invalidates all iterators.

Time complexity: O(|V|+|E|) where |V| is the number of vertices and |E| is the number of edges in the new, extended graph.

Example 4.8.  File `examples/simple/igraph_add_edges.c`

```/* -*- mode: C -*-  */
/*
IGraph library.
Copyright (C) 2006-2012  Gabor Csardi <csardi.gabor@gmail.com>
334 Harvard street, Cambridge, MA 02139 USA

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc.,  51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA

*/

#include <igraph.h>

void print_vector(igraph_vector_t *v, FILE *f) {
long int i;
for (i=0; i<igraph_vector_size(v); i++) {
fprintf(f, " %li", (long int) VECTOR(*v)[i]);
}
fprintf(f, "\n");
}

int main() {

igraph_t g;
igraph_vector_t v;
int ret;

/* Create graph */
igraph_vector_init(&v, 8);
VECTOR(v)=0; VECTOR(v)=1;
VECTOR(v)=1; VECTOR(v)=2;
VECTOR(v)=2; VECTOR(v)=3;
VECTOR(v)=2; VECTOR(v)=2;
igraph_create(&g, &v, 0, 1);

/* Add edges */
igraph_vector_resize(&v, 4);
VECTOR(v)=2; VECTOR(v)=1;
VECTOR(v)=3; VECTOR(v)=3;
igraph_add_edges(&g, &v, 0);

/* Check result */
igraph_get_edgelist(&g, &v, 0);
igraph_vector_sort(&v);
print_vector(&v, stdout);

/* Error, vector length */
igraph_set_error_handler(igraph_error_handler_ignore);
igraph_vector_resize(&v, 3);
VECTOR(v)=0; VECTOR(v)=1;
VECTOR(v)=2;
ret=igraph_add_edges(&g, &v, 0);
if (ret != IGRAPH_EINVEVECTOR) {
return 1;
}

/* Check result */
igraph_get_edgelist(&g, &v, 0);
igraph_vector_sort(&v);
print_vector(&v, stdout);

/* Error, vector ids */
igraph_vector_resize(&v, 4);
VECTOR(v)=0; VECTOR(v)=1;
VECTOR(v)=2; VECTOR(v)=4;
ret=igraph_add_edges(&g, &v, 0);
if (ret != IGRAPH_EINVVID) {
return 2;
}

/* Check result */
igraph_get_edgelist(&g, &v, 0);
igraph_vector_sort(&v);
print_vector(&v, stdout);

igraph_vector_destroy(&v);
igraph_destroy(&g);

return 0;
}
```

#### 2.3.3. `igraph_add_vertices` — Adds vertices to a graph.

```int igraph_add_vertices(igraph_t *graph, igraph_integer_t nv, void *attr);
```

This function invalidates all iterators.

Arguments:

 `graph`: The graph object to extend. `nv`: Non-negative integer giving the number of vertices to add. `attr`: The attributes of the new vertices, only used by high level interfaces, you can supply 0 here.

Returns:

 Error code: `IGRAPH_EINVAL`: invalid number of new vertices.

Time complexity: O(|V|) where |V| is the number of vertices in the new, extended graph.

Example 4.9.  File `examples/simple/igraph_add_vertices.c`

```/* -*- mode: C -*-  */
/*
IGraph library.
Copyright (C) 2006-2012  Gabor Csardi <csardi.gabor@gmail.com>
334 Harvard street, Cambridge, MA 02139 USA

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc.,  51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA

*/

#include <igraph.h>

int main() {

igraph_t g1;
igraph_vector_t v1;
int ret;

/* Create a graph */
igraph_vector_init(&v1, 8);
VECTOR(v1)=0; VECTOR(v1)=1;
VECTOR(v1)=1; VECTOR(v1)=2;
VECTOR(v1)=2; VECTOR(v1)=3;
VECTOR(v1)=2; VECTOR(v1)=2;
igraph_create(&g1, &v1, 0, 0);
igraph_vector_destroy(&v1);

/* Add more vertices */
igraph_add_vertices(&g1, 10, 0);
if (igraph_vcount(&g1) != 14) {
return 1;
}

/* Add more vertices */
igraph_add_vertices(&g1, 0, 0);
if (igraph_vcount(&g1) != 14) {
return 2;
}

/* Error */
igraph_set_error_handler(igraph_error_handler_ignore);
ret=igraph_add_vertices(&g1, -1, 0);
if (ret != IGRAPH_EINVAL) {
return 3;
}

igraph_destroy(&g1);

return 0;
}
```

#### 2.3.4. `igraph_delete_edges` — Removes edges from a graph.

```int igraph_delete_edges(igraph_t *graph, igraph_es_t edges);
```

The edges to remove are given as an edge selector.

This function cannot remove vertices, they will be kept, even if they lose all their edges.

This function invalidates all iterators.

Arguments:

 `graph`: The graph to work on. `edges`: The edges to remove.

Returns:

 Error code.

Time complexity: O(|V|+|E|) where |V| and |E| are the number of vertices and edges in the original graph, respectively.

Example 4.10.  File `examples/simple/igraph_delete_edges.c`

```/* -*- mode: C -*-  */
/*
IGraph library.
Copyright (C) 2006-2012  Gabor Csardi <csardi.gabor@gmail.com>
334 Harvard street, Cambridge, MA 02139 USA

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc.,  51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA

*/

#include <igraph.h>

int main() {

igraph_t g;
igraph_vector_t v;
int ret;
igraph_es_t es;

igraph_vector_init(&v, 8);
VECTOR(v)=0; VECTOR(v)=1;
VECTOR(v)=1; VECTOR(v)=2;
VECTOR(v)=2; VECTOR(v)=3;
VECTOR(v)=2; VECTOR(v)=2;
igraph_create(&g, &v, 0, 0);

igraph_es_pairs_small(&es, IGRAPH_DIRECTED, 3,2, -1);
igraph_delete_edges(&g, es);
if (igraph_ecount(&g) != 3) {
return 1;
}

/* error test, no such edge to delete */
igraph_set_error_handler(igraph_error_handler_ignore);
ret=igraph_delete_edges(&g, es);
if (ret != IGRAPH_EINVAL) {
printf("Error code: %i\n", ret);
return 2;
}
if (igraph_ecount(&g) != 3) {
return 3;
}

/* error test, invalid vertex id */
igraph_es_destroy(&es);
igraph_es_pairs_small(&es, IGRAPH_DIRECTED, 10,2, -1);
ret=igraph_delete_edges(&g, es);
if (ret != IGRAPH_EINVVID) {
return 4;
}
if (igraph_ecount(&g) != 3) {
return 5;
}

/* error test, invalid (odd) length */
igraph_es_destroy(&es);
igraph_es_pairs_small(&es, IGRAPH_DIRECTED, 0,1,2, -1);
ret=igraph_delete_edges(&g, es);
if (ret != IGRAPH_EINVAL) {
return 6;
}
if (igraph_ecount(&g) != 3) {
return 7;
}

igraph_es_destroy(&es);
igraph_vector_destroy(&v);
igraph_destroy(&g);

return 0;
}
```

#### 2.3.5. `igraph_delete_vertices` — Removes vertices (with all their edges) from the graph.

```int igraph_delete_vertices(igraph_t *graph, const igraph_vs_t vertices);
```

This function changes the ids of the vertices (except in some very special cases, but these should not be relied on anyway).

This function invalidates all iterators.

Arguments:

 `graph`: The graph to work on. `vertices`: The ids of the vertices to remove in a vector. The vector may contain the same id more than once.

Returns:

 Error code: `IGRAPH_EINVVID`: invalid vertex id.

Time complexity: O(|V|+|E|), |V| and |E| are the number of vertices and edges in the original graph.

Example 4.11.  File `examples/simple/igraph_delete_vertices.c`

```/* -*- mode: C -*-  */
/*
IGraph library.
Copyright (C) 2006-2012  Gabor Csardi <csardi.gabor@gmail.com>
334 Harvard street, Cambridge, MA 02139 USA

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc.,  51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA

*/

#include <igraph.h>

int main() {

igraph_t g;
igraph_vector_t v;
int ret;

/* without edges */
igraph_empty(&g, 5, IGRAPH_DIRECTED);
igraph_add_vertices(&g, 2, 0);
igraph_add_vertices(&g, 3, 0);
igraph_add_vertices(&g, 1, 0);
igraph_add_vertices(&g, 4, 0);
if (igraph_vcount(&g) != 15)  {
return 1;
}
igraph_delete_vertices(&g, igraph_vss_1(2));
if (igraph_vcount(&g) != 14)  {
return 2;
}
igraph_destroy(&g);

igraph_vector_init(&v, 8);
VECTOR(v)=0; VECTOR(v)=1;
VECTOR(v)=1; VECTOR(v)=2;
VECTOR(v)=2; VECTOR(v)=3;
VECTOR(v)=2; VECTOR(v)=2;
igraph_create(&g, &v, 0, 0);
igraph_vector_destroy(&v);

/* resize vector */
igraph_delete_vertices(&g, igraph_vss_1(2));
if (igraph_vcount(&g) != 3) {
return 3;
}
if (igraph_ecount(&g) != 1) {
return 4;
}

/* error test */
igraph_set_error_handler(igraph_error_handler_ignore);
ret=igraph_delete_vertices(&g, igraph_vss_1(3));
if (ret != IGRAPH_EINVVID) {
return 5;
}

igraph_destroy(&g);

return 0;
}
```

### 2.4. Deprecated functions

#### 2.4.1. `igraph_adjacent` — Gives the incident edges of a vertex.

```int igraph_adjacent(const igraph_t *graph, igraph_vector_t *eids,
igraph_integer_t pnode, igraph_neimode_t mode);
```

This function was superseded by `igraph_incident()` in igraph 0.6. Please use `igraph_incident()` instead of this function.

Added in version 0.2, deprecated in version 0.6.