scran
C++ library for basic single-cell RNA-seq analyses
Loading...
Searching...
No Matches
igraph_utils.hpp
Go to the documentation of this file.
1#ifndef SCRAN_IGRAPH_UTILS_HPP
2#define SCRAN_IGRAPH_UTILS_HPP
3
4#include "../utils/macros.hpp"
5
6#include "igraph.h"
7
14namespace scran {
15
20namespace igraph {
21
25struct RNGScope {
26 RNGScope(int seed) : previous(igraph_rng_default()) {
27 if (igraph_rng_init(&rng, &igraph_rngtype_mt19937)) {
28 throw std::runtime_error("failed to initialize an instance of igraph's RNG");
29 }
30
31 if (igraph_rng_seed(&rng, seed)) {
32 igraph_rng_destroy(&rng);
33 throw std::runtime_error("failed to set the seed on igraph's RNG");
34 }
35
36 igraph_rng_set_default(&rng);
37 }
38
39 // Just deleting the methods here, because the RNGScope
40 // is strictly internal and we don't do any of these.
41 RNGScope(const RNGScope& other) = delete;
42 RNGScope& operator=(const RNGScope& other) = delete;
43 RNGScope(RNGScope&& other) = delete;
44 RNGScope& operator=(RNGScope&& other) = delete;
45
46 ~RNGScope() {
47 if (active) {
48 igraph_rng_set_default(previous);
49 igraph_rng_destroy(&rng);
50 }
51 }
52
53 igraph_rng_t* previous;
54 igraph_rng_t rng;
55 bool active = true;
56};
57
58/*****************************************************
59 *****************************************************/
60
61template<class Overlord>
62struct Vector_ {
63private:
64 static void try_copy(typename Overlord::Vector& dest, const typename Overlord::Vector& source, bool source_active) {
65 if (source_active) {
66 if (Overlord::copy(dest, source)) {
67 throw std::runtime_error("failed to copy igraph vector of size " + std::to_string(Overlord::size(source)));
68 }
69 }
70 }
71
72 static void try_destroy(typename Overlord::Vector& vector, bool active) {
73 if (active) {
74 Overlord::destroy(vector);
75 }
76 }
77
78public:
79 Vector_(size_t size = 0) {
80 if (Overlord::initialize(vector, size)) {
81 throw std::runtime_error("failed to initialize igraph vector of size " + std::to_string(size));
82 }
83 }
84
85 // Just deleting the methods here, because the Vector_
86 // is strictly internal and we don't do any of these.
87 Vector_(const Vector_& other) = delete;
88 Vector_& operator=(const Vector_& other) = delete;
89 Vector_(Vector_&& other) = delete;
90 Vector_& operator=(Vector_&& other) = delete;
91
92 ~Vector_() {
93 try_destroy(vector, active);
94 }
95
96 typename Overlord::Vector vector;
97 bool active = true;
98};
99
100struct IntegerVectorOverlord {
101 typedef igraph_vector_int_t Vector;
102
103 static igraph_error_t copy(igraph_vector_int_t& dest, const igraph_vector_int_t& source) {
104 return igraph_vector_int_init_copy(&dest, &source);
105 }
106
107 static void destroy(igraph_vector_int_t& x) {
108 return igraph_vector_int_destroy(&x);
109 }
110
111 static igraph_integer_t size(igraph_vector_int_t& x) {
112 return igraph_vector_int_size(&x);
113 }
114
115 static igraph_error_t initialize(igraph_vector_int_t& x, size_t size) {
116 return igraph_vector_int_init(&x, size);
117 }
118};
119
120using IntegerVector = Vector_<IntegerVectorOverlord>;
121
122struct RealVectorOverlord {
123 typedef igraph_vector_t Vector;
124
125 static igraph_error_t copy(igraph_vector_t& dest, const igraph_vector_t& source) {
126 return igraph_vector_init_copy(&dest, &source);
127 }
128
129 static void destroy(igraph_vector_t& x) {
130 return igraph_vector_destroy(&x);
131 }
132
133 static igraph_integer_t size(igraph_vector_t& x) {
134 return igraph_vector_size(&x);
135 }
136
137 static igraph_error_t initialize(igraph_vector_t& x, size_t size) {
138 return igraph_vector_init(&x, size);
139 }
140};
141
142using RealVector = Vector_<RealVectorOverlord>;
143
144/*****************************************************
145 *****************************************************/
146
147struct IntegerMatrix {
148 IntegerMatrix(size_t nrows = 0, size_t ncols = 0) {
149 if (igraph_matrix_int_init(&matrix, nrows, ncols)) {
150 throw std::runtime_error("failed to initialize igraph " + std::to_string(nrows) + "x" + std::to_string(ncols) + " matrix");
151 }
152 }
153
154 // Just deleting the methods here, because the Matrix
155 // is strictly internal and we don't do any of these.
156 IntegerMatrix(const IntegerMatrix& other) = delete;
157 IntegerMatrix& operator=(const IntegerMatrix& other) = delete;
158 IntegerMatrix(IntegerMatrix&& other) = delete;
159 IntegerMatrix& operator=(IntegerMatrix&& other) = delete;
160
161 ~IntegerMatrix() {
162 if (active) {
163 igraph_matrix_int_destroy(&matrix);
164 }
165 }
166
167 igraph_matrix_int_t matrix;
168 bool active = true;
169};
174/*****************************************************
175 *****************************************************/
176
180struct Graph {
181private:
182 static void try_copy(igraph_t& dest, const igraph_t& source, bool source_active) {
183 if (source_active) {
184 if (igraph_copy(&dest, &source)) {
185 throw std::runtime_error("failed to copy igraph's graph");
186 }
187 }
188 }
189
190 static void try_destroy(igraph_t& graph, bool active) {
191 if (active) {
192 igraph_destroy(&graph);
193 }
194 }
195
196public:
200 Graph() : active(false) {}
201
202 Graph(const IntegerVector& edges, size_t nvertices, bool directed) : Graph(&(edges.vector), nvertices, directed) {}
203
204 Graph(const igraph_vector_int_t* edges, size_t nvertices, bool directed) {
205 if (igraph_create(&graph, edges, nvertices, directed)) {
206 throw std::runtime_error("failed to initialize igraph's graph object");
207 }
208 }
209
210 Graph(const Graph& other) : active(other.active) {
211 try_copy(graph, other.graph, other.active);
212 }
213
214 Graph& operator=(const Graph& other) {
215 if (this != &other) {
216 try_destroy(graph, active);
217 try_copy(graph, other.graph, other.active);
218 active = other.active;
219 }
220 return *this;
221 }
222
223 // See https://docs.microsoft.com/en-us/cpp/cpp/move-constructors-and-move-assignment-operators-cpp?view=msvc-170
224 Graph(Graph&& other) : graph(std::move(other.graph)), active(other.active) {
225 other.active = false;
226 }
227
228 Graph& operator=(Graph&& other) {
229 if (this != &other) {
230 try_destroy(graph, active);
231 graph = std::move(other.graph);
232 active = other.active;
233 other.active = false;
234 }
235 return *this;
236 }
237
238 ~Graph() {
239 try_destroy(graph, active);
240 }
241
242 bool active = true;
243
244 igraph_t graph;
256 const igraph_t* get_graph() const {
257 return &graph;
258 }
259};
260
261}
262
263}
264
265#endif
Functions for single-cell RNA-seq analyses.
Definition AggregateAcrossCells.hpp:18
Wrapper around the igraph_t class from igraph.
Definition igraph_utils.hpp:180
const igraph_t * get_graph() const
Definition igraph_utils.hpp:256