1 /*
2    IGraph library.
3    Copyright (C) 2021  The igraph development team <igraph@igraph.org>
4 
5    This program is free software; you can redistribute it and/or modify
6    it under the terms of the GNU General Public License as published by
7    the Free Software Foundation; either version 2 of the License, or
8    (at your option) any later version.
9 
10    This program is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13    GNU General Public License for more details.
14 
15    You should have received a copy of the GNU General Public License
16    along with this program.  If not, see <https://www.gnu.org/licenses/>.
17 */
18 
19 #include <igraph.h>
20 #include "test_utilities.inc"
21 
init_vm(igraph_vector_t * type_dist,int v0,int v1,igraph_matrix_t * pref_matrix,int m00,int m10,int m01,int m11)22 void init_vm(igraph_vector_t *type_dist,
23              int v0, int v1,
24              igraph_matrix_t *pref_matrix,
25              int m00, int m10, int m01, int m11) {
26     igraph_vector_init_int_end(type_dist, -1, v0, v1, -1);
27     igraph_matrix_init(pref_matrix, 2, 2);
28     MATRIX(*pref_matrix, 0, 0) = m00;
29     MATRIX(*pref_matrix, 1, 0) = m10;
30     MATRIX(*pref_matrix, 0, 1) = m01;
31     MATRIX(*pref_matrix, 1, 1) = m11;
32 }
33 
34 #define DESTROY_GVM() do {               \
35     igraph_destroy(&g);                  \
36     igraph_vector_destroy(&type_dist);   \
37     igraph_matrix_destroy(&pref_matrix); \
38     } while(0)
39 
main()40 int main() {
41     igraph_t g;
42     igraph_vector_t type_dist, node_types;
43     igraph_matrix_t pref_matrix;
44     igraph_bool_t bipartite;
45 
46     igraph_rng_seed(igraph_rng_default(), 42);
47 
48     /*Zero matrix elements for only possible vertex type means no edges*/
49     init_vm(&type_dist, 1, 0, &pref_matrix, 0, 0, 0, 1);
50     IGRAPH_ASSERT(igraph_callaway_traits_game(&g, /*nodes*/ 20, /*types*/ 2, /*edges_per_step*/ 5, &type_dist, &pref_matrix, /*directed*/ 0, NULL) == IGRAPH_SUCCESS);
51     IGRAPH_ASSERT(igraph_ecount(&g) == 0);
52     IGRAPH_ASSERT(igraph_vcount(&g) == 20);
53     DESTROY_GVM();
54 
55     /*No vertices*/
56     init_vm(&type_dist, 1, 0, &pref_matrix, 0, 0, 0, 1);
57     IGRAPH_ASSERT(igraph_callaway_traits_game(&g, /*nodes*/ 0, /*types*/ 2, /*edges_per_step*/ 0, &type_dist, &pref_matrix, /*directed*/ 0, NULL) == IGRAPH_SUCCESS);
58     IGRAPH_ASSERT(igraph_vcount(&g) == 0);
59     IGRAPH_ASSERT(!igraph_is_directed(&g));
60     DESTROY_GVM();
61 
62     /*Two types with only cross terms makes a bipartite graph*/
63     init_vm(&type_dist, 2, 1, &pref_matrix, 0, 1, 1, 0);
64     igraph_vector_init(&node_types, 0);
65     IGRAPH_ASSERT(igraph_callaway_traits_game(&g, /*nodes*/ 20, /*types*/ 2, /*edges_per_step*/ 5, &type_dist, &pref_matrix, /*directed*/ 1, &node_types) == IGRAPH_SUCCESS);
66     igraph_is_bipartite(&g, &bipartite, NULL);
67     IGRAPH_ASSERT(bipartite);
68     IGRAPH_ASSERT(igraph_is_directed(&g));
69     IGRAPH_ASSERT(igraph_vector_size(&node_types) == igraph_vcount(&g));
70     IGRAPH_ASSERT(igraph_vector_min(&node_types) == 0);
71     IGRAPH_ASSERT(igraph_vector_max(&node_types) == 1);
72     igraph_vector_destroy(&node_types);
73     DESTROY_GVM();
74 
75     /*Automatically determined type_dist*/
76     init_vm(&type_dist, 0, 0, &pref_matrix, 0, 1, 1, 0);
77     igraph_vector_init(&node_types, 0);
78     IGRAPH_ASSERT(igraph_callaway_traits_game(&g, /*nodes*/ 20, /*types*/ 2, /*edges_per_step*/ 3, /*type_dist*/ NULL, &pref_matrix, /*directed*/ 0, &node_types) == IGRAPH_SUCCESS);
79     igraph_is_bipartite(&g, &bipartite, NULL);
80     IGRAPH_ASSERT(bipartite);
81     IGRAPH_ASSERT(!igraph_is_directed(&g));
82     IGRAPH_ASSERT(igraph_vector_size(&node_types) == igraph_vcount(&g));
83     IGRAPH_ASSERT(igraph_vector_min(&node_types) == 0);
84     IGRAPH_ASSERT(igraph_vector_max(&node_types) == 1);
85     igraph_vector_destroy(&node_types);
86     DESTROY_GVM();
87 
88     VERIFY_FINALLY_STACK();
89     igraph_set_error_handler(igraph_error_handler_ignore);
90 
91     /*Distribution of types should have at least one positive value*/
92     init_vm(&type_dist, 0, 0, &pref_matrix, 0, 1, 1, 0);
93     IGRAPH_ASSERT(igraph_callaway_traits_game(&g, /*nodes*/ 20, /* types*/ 2, /*edges_per_step*/ 5, &type_dist, &pref_matrix, /*directed*/ 0, NULL) == IGRAPH_EINVAL);
94     DESTROY_GVM();
95 
96     VERIFY_FINALLY_STACK();
97     return 0;
98 }
99