00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "ne_sys.h"
00024 #include <string.h>
00025
00026
00027 ne_sys_t * ne_sys_alloc (ne_bool_t directed, ne_int_t nodes, ne_int_t nodeStates,
00028 ne_int_t edgeStates, ne_bool_t dynNodeVary, ne_bool_t dynEdgeVary,
00029 ne_bool_t dynNodeParamsVary, ne_bool_t dynEdgeParamsVary)
00030 {
00031 ne_sys_t *sys;
00032 igraph_t G;
00033 igraph_empty(&G, (igraph_integer_t)nodes, (igraph_bool_t)directed);
00034 sys = ne_sys_alloc_from_igraph(&G, nodeStates, edgeStates, dynNodeVary, dynEdgeVary,
00035 dynNodeParamsVary, dynEdgeParamsVary);
00036 igraph_destroy(&G);
00037 return sys;
00038 }
00039
00040
00041 ne_sys_t * ne_sys_alloc_from_igraph (igraph_t *G, ne_int_t nodeStates, ne_int_t edgeStates,
00042 ne_bool_t dynNodeVary, ne_bool_t dynEdgeVary,
00043 ne_bool_t dynNodeParamsVary, ne_bool_t dynEdgeParamsVary)
00044 {
00045 ne_sys_t *sys = NULL;
00046
00047 if ((sys = (ne_sys_t *)malloc(sizeof(ne_sys_t))) == NULL) {
00048 ne_error("ne_sys_alloc_from_igraph: Could not allocate memory for ne_sys.");
00049 return NULL;
00050 }
00051
00052 sys->graph = (igraph_t *)malloc(sizeof(igraph_t));
00053 if (sys->graph == NULL) {
00054 ne_error("ne_sys_alloc_from_igraph: Could not allocate memory for ne_sys.graph.");
00055 free(sys);
00056 return NULL;
00057 }
00058 igraph_copy(sys->graph, G);
00059
00060 sys->nodeStates = nodeStates;
00061 sys->edgeStates = edgeStates;
00062 sys->nodeDynVary = dynNodeVary;
00063 sys->edgeDynVary = dynEdgeVary;
00064 sys->nodeDynParamsVary = dynNodeParamsVary;
00065 sys->edgeDynParamsVary = dynEdgeParamsVary;
00066
00067 if ((sys->nodeParams = (ne_param_t *)calloc(NE_NODE_PARAMS * igraph_vcount(G), sizeof(ne_param_t))) == NULL) {
00068 ne_error("ne_sys_alloc_from_igraph: Could not allocate memory for ne_sys.nodeParams.");
00069 igraph_destroy(sys->graph);
00070 free(sys);
00071 return NULL;
00072 }
00073
00074 if ((sys->edgeParams = (ne_param_t *)calloc(NE_EDGE_PARAMS * igraph_ecount(G),
00075 sizeof(ne_param_t))) == NULL) {
00076 ne_error("ne_sys_alloc_from_igraph: Could not allocate memory for ne_sys.edgeParams.");
00077 igraph_destroy(sys->graph);
00078 free(sys->nodeParams);
00079 free(sys);
00080 return NULL;
00081 }
00082
00083 if (dynNodeVary == TRUE) {
00084 if ((sys->nodeDyn = (ne_dyn_node_t **)malloc(sizeof(ne_dyn_node_t *) * igraph_vcount(G))) == NULL) {
00085 ne_error("ne_sys_alloc_from_igraph: Could not allocate memory for ne_sys.nodeDyn.");
00086 igraph_destroy(sys->graph);
00087 free(sys->nodeParams);
00088 free(sys->edgeParams);
00089 free(sys);
00090 return NULL;
00091 }
00092 }
00093 else {
00094 if ((sys->nodeDyn = (ne_dyn_node_t **)malloc(sizeof(ne_dyn_node_t *))) == NULL) {
00095 ne_error("ne_sys_alloc_from_igraph: Could not allocate memory for ne_sys.nodeDyn.");
00096 igraph_destroy(sys->graph);
00097 free(sys->nodeParams);
00098 free(sys->edgeParams);
00099 free(sys);
00100 return NULL;
00101 }
00102 }
00103
00104 if (dynEdgeVary == TRUE) {
00105 if ((sys->edgeDyn = (ne_dyn_edge_t **)malloc(sizeof(ne_dyn_edge_t *) *
00106 igraph_ecount(G))) == NULL) {
00107 ne_error("ne_sys_alloc_from_igraph: Could not allocate memory for ne_sys.edgeDyn.");
00108 igraph_destroy(sys->graph);
00109 free(sys->nodeParams);
00110 free(sys->edgeParams);
00111 free(sys->nodeDyn);
00112 free(sys);
00113 return NULL;
00114 }
00115 }
00116 else {
00117 if ((sys->edgeDyn = (ne_dyn_edge_t **)malloc(sizeof(ne_dyn_edge_t *))) == NULL) {
00118 ne_error("ne_sys_alloc_from_igraph: Could not allocate memory for ne_sys.edgeDyn.");
00119 igraph_destroy(sys->graph);
00120 free(sys->nodeParams);
00121 free(sys->edgeParams);
00122 free(sys->nodeDyn);
00123 free(sys);
00124 return NULL;
00125 }
00126 }
00127
00128 if (dynNodeParamsVary == TRUE) {
00129 if ((sys->nodeDynParams = (ne_dyn_param_t *)calloc(igraph_vcount(G) * NE_DYN_PARAMS,
00130 sizeof(ne_dyn_param_t))) == NULL) {
00131 ne_error("ne_sys_alloc_from_igraph: Could not allocate memory for ne_sys.nodeDynParams.");
00132 igraph_destroy(sys->graph);
00133 free(sys->nodeParams);
00134 free(sys->edgeParams);
00135 free(sys->nodeDyn);
00136 free(sys->edgeDyn);
00137 free(sys);
00138 return NULL;
00139 }
00140 }
00141 else {
00142 if ((sys->nodeDynParams = (ne_dyn_param_t *)calloc(NE_DYN_PARAMS,
00143 sizeof(ne_dyn_param_t))) == NULL) {
00144 ne_error("ne_sys_alloc_from_igraph: Could not allocate memory for ne_sys.nodeDynParams.");
00145 igraph_destroy(sys->graph);
00146 free(sys->nodeParams);
00147 free(sys->edgeParams);
00148 free(sys->nodeDyn);
00149 free(sys->edgeDyn);
00150 free(sys);
00151 return NULL;
00152 }
00153 }
00154
00155 if (dynEdgeParamsVary == TRUE) {
00156 if ((sys->edgeDynParams = (ne_dyn_param_t *)calloc(NE_DYN_PARAMS * igraph_ecount(G),
00157 sizeof(ne_dyn_param_t))) == NULL) {
00158 ne_error("ne_sys_alloc_from_igraph: Could not allocate memory for ne_sys.edgeDynParams.");
00159 igraph_destroy(sys->graph);
00160 free(sys->nodeParams);
00161 free(sys->edgeParams);
00162 free(sys->nodeDyn);
00163 free(sys->edgeDyn);
00164 free(sys->nodeDynParams);
00165 free(sys);
00166 return NULL;
00167 }
00168 }
00169 else {
00170 if ((sys->edgeDynParams = (ne_dyn_param_t *)calloc(NE_DYN_PARAMS,
00171 sizeof(ne_dyn_param_t))) == NULL) {
00172 ne_error("ne_sys_alloc_from_igraph: Could not allocate memory for ne_sys.edgeDynParams.");
00173 igraph_destroy(sys->graph);
00174 free(sys->nodeParams);
00175 free(sys->edgeParams);
00176 free(sys->nodeDyn);
00177 free(sys->edgeDyn);
00178 free(sys->nodeDynParams);
00179 free(sys);
00180 return NULL;
00181 }
00182 }
00183
00184 return sys;
00185 }
00186
00187
00188 ne_sys_t * ne_sys_clone (ne_sys_t *from)
00189 {
00190 ne_sys_t *to;
00191
00192
00193 to = ne_sys_alloc_from_igraph(from->graph, from->nodeStates, from->edgeStates,
00194 from->nodeDynVary, from->edgeDynVary, from->nodeDynParamsVary,
00195 from->edgeDynParamsVary);
00196
00197 if (to == NULL) {
00198 ne_error("ne_sys_copy: Could not copy system.");
00199 return NULL;
00200 }
00201
00202
00203 memcpy(to->nodeParams, from->nodeParams, sizeof(ne_param_t) * igraph_vcount(from->graph) * NE_NODE_PARAMS);
00204 memcpy(to->edgeParams, from->edgeParams, sizeof(ne_param_t) * igraph_ecount(from->graph) * NE_EDGE_PARAMS);
00205
00206 if (from->nodeDynVary == TRUE) {
00207 memcpy(to->nodeDyn, from->nodeDyn, sizeof(ne_dyn_node_t) * igraph_vcount(from->graph));
00208 }
00209 else {
00210 to->nodeDyn[0] = from->nodeDyn[0];
00211 }
00212
00213 if (from->edgeDynVary == TRUE) {
00214 memcpy(to->edgeDyn, from->edgeDyn, sizeof(ne_dyn_edge_t) * igraph_ecount(from->graph));
00215 }
00216 else {
00217 to->edgeDyn[0] = from->edgeDyn[0];
00218 }
00219
00220 if (from->nodeDynParamsVary == TRUE) {
00221 memcpy(to->nodeDynParams, from->nodeDynParams, sizeof(ne_dyn_param_t) *
00222 igraph_vcount(from->graph) * NE_DYN_PARAMS);
00223 }
00224 else {
00225 memcpy(to->nodeDynParams, from->nodeDynParams, sizeof(ne_dyn_param_t) * NE_DYN_PARAMS);
00226 }
00227
00228 if (from->edgeDynParamsVary == TRUE) {
00229 memcpy(to->edgeDynParams, from->edgeDynParams, sizeof(ne_dyn_param_t) *
00230 igraph_ecount(from->graph) * NE_DYN_PARAMS);
00231 }
00232 else {
00233 memcpy(to->edgeDynParams, from->edgeDynParams, sizeof(ne_dyn_param_t) * NE_DYN_PARAMS);
00234 }
00235
00236 return to;
00237 }
00238
00239
00240 void ne_sys_free (ne_sys_t *sys)
00241 {
00242 igraph_destroy(sys->graph);
00243 free(sys->nodeParams);
00244 free(sys->edgeParams);
00245 free(sys->nodeDyn);
00246 free(sys->edgeDyn);
00247 free(sys->nodeDynParams);
00248 free(sys->edgeDynParams);
00249 free(sys);
00250 }
00251
00252
00253 igraph_t * ne_sys_igraph (ne_sys_t *sys)
00254 {
00255 return sys->graph;
00256 }
00257
00258
00259 ne_bool_t ne_sys_directed (ne_sys_t *sys)
00260 {
00261 return (ne_bool_t)igraph_is_directed(sys->graph);
00262 }
00263
00264
00265 ne_int_t ne_sys_node_states (ne_sys_t *sys)
00266 {
00267 return sys->nodeStates;
00268 }
00269
00270 ne_int_t ne_sys_edge_states (ne_sys_t *sys)
00271 {
00272 return sys->edgeStates;
00273 }
00274
00275
00276 ne_int_t ne_sys_nodes (ne_sys_t *sys)
00277 {
00278 return (ne_int_t)igraph_vcount(sys->graph);
00279 }
00280
00281
00282 ne_int_t ne_sys_edges (ne_sys_t *sys)
00283 {
00284 return (ne_int_t)igraph_ecount(sys->graph);
00285 }
00286
00287
00288
00289 ne_bool_t ne_sys_dyn_node_vary (ne_sys_t *sys)
00290 {
00291 return sys->nodeDynVary;
00292 }
00293
00294
00295 ne_bool_t ne_sys_dyn_edge_vary (ne_sys_t *sys)
00296 {
00297 return sys->edgeDynVary;
00298 }
00299
00300
00301 ne_bool_t ne_sys_dyn_node_param_vary (ne_sys_t *sys)
00302 {
00303 return sys->nodeDynParamsVary;
00304 }
00305
00306
00307 ne_bool_t ne_sys_dyn_edge_param_vary (ne_sys_t *sys)
00308 {
00309 return sys->edgeDynParamsVary;
00310 }
00311
00312
00313 ne_bool_t ne_sys_edge_exists (ne_sys_t *sys, ne_int_t startNode, ne_int_t endNode)
00314 {
00315 igraph_integer_t i;
00316 igraph_vector_t adjV;
00317 igraph_vector_init(&adjV, 0);
00318
00319
00320 if (!igraph_is_directed(sys->graph)) {
00321
00322 igraph_neighbors(sys->graph, &adjV, (igraph_integer_t)startNode, IGRAPH_ALL);
00323 }
00324 else {
00325
00326 igraph_neighbors(sys->graph, &adjV, (igraph_integer_t)startNode, IGRAPH_OUT);
00327 }
00328
00329
00330 for (i=0; i<igraph_vector_size(&adjV); i++) {
00331
00332 if (VECTOR(adjV)[(int)i] == (igraph_integer_t)endNode) {
00333
00334 return TRUE;
00335 }
00336 }
00337
00338 igraph_vector_destroy(&adjV);
00339
00340
00341 return FALSE;
00342 }
00343
00344
00345 ne_err_code_t ne_sys_add_node (ne_sys_t *sys, ne_dyn_node_t *dyn, ne_dyn_param_t *params)
00346 {
00347 ne_param_t *newNodeParams;
00348 ne_dyn_param_t *newNodeDynParams;
00349 ne_dyn_node_t **newNodeDyn;
00350 ne_int_t nodes;
00351 nodes = (ne_int_t)igraph_vcount(sys->graph);
00352
00353
00354 if ((newNodeParams = (ne_param_t *)calloc(NE_NODE_PARAMS * (nodes + 1),
00355 sizeof(ne_param_t))) == NULL) {
00356 ne_error("ne_sys_add_node: Could not allocate memory for ne_sys.nodeParams.");
00357 return NE_MEM_ALLOC_ERROR;
00358 }
00359 if (sys->nodeDynParamsVary == TRUE) {
00360 if ((newNodeDynParams = (ne_dyn_param_t *)calloc(NE_DYN_PARAMS * (nodes + 1),
00361 sizeof(ne_dyn_param_t))) == NULL) {
00362 ne_error("ne_sys_add_node: Could not allocate memory for ne_sys.nodeDynParams.");
00363 free(newNodeParams);
00364 return NE_MEM_ALLOC_ERROR;
00365 }
00366 memcpy(newNodeDynParams, sys->nodeDynParams, sizeof(ne_dyn_param_t) * NE_DYN_PARAMS * nodes);
00367 free(sys->nodeDynParams);
00368 sys->nodeDynParams = newNodeDynParams;
00369 }
00370 if (sys->nodeDynVary == TRUE) {
00371 if ((newNodeDyn = (ne_dyn_node_t **)calloc(nodes+1, sizeof(ne_dyn_node_t *))) == NULL) {
00372 ne_error("ne_sys_add_node: Could not allocate memory for ne_sys.nodeDyn.");
00373 free(newNodeParams);
00374 if (sys->nodeDynParamsVary == TRUE)
00375 free(newNodeDynParams);
00376 return NE_MEM_ALLOC_ERROR;
00377 }
00378
00379 memcpy(newNodeDyn, sys->nodeDyn, sizeof(ne_dyn_node_t *) * nodes);
00380 free(sys->nodeDyn);
00381 sys->nodeDyn = newNodeDyn;
00382 }
00383
00384
00385 memcpy(newNodeParams, sys->nodeParams, sizeof(ne_param_t) * NE_NODE_PARAMS * nodes);
00386 free(sys->nodeParams);
00387 sys->nodeParams = newNodeParams;
00388
00389
00390 igraph_add_vertices(sys->graph, (igraph_integer_t)1, 0);
00391
00392 ne_sys_set_dyn_node(sys, nodes, dyn);
00393 ne_sys_set_dyn_node_params(sys, nodes, params);
00394
00395 return NE_SUCCESS;
00396 }
00397
00398
00399 ne_err_code_t ne_sys_add_edge (ne_sys_t *sys, ne_int_t startNode, ne_int_t endNode,
00400 ne_dyn_edge_t *dyn, ne_dyn_param_t *params)
00401 {
00402 ne_param_t *newEdgeParams;
00403 ne_dyn_param_t *newEdgeDynParams;
00404 ne_dyn_edge_t **newEdgeDyn;
00405 ne_int_t edges;
00406 edges = (ne_int_t)igraph_ecount(sys->graph);
00407
00408 if (ne_sys_edge_exists(sys, startNode, endNode)) {
00409 ne_error("ne_sys_add_edge: Edge (%i, %i) already exists.", startNode, endNode);
00410 return NE_FAILURE;
00411 }
00412
00413
00414 if ((newEdgeParams = (ne_param_t *)calloc(NE_EDGE_PARAMS * (edges + 1),
00415 sizeof(ne_param_t))) == NULL) {
00416 ne_error("ne_sys_add_edge: Could not allocate memory for ne_sys.edgeParams.");
00417 return NE_MEM_ALLOC_ERROR;
00418 }
00419 if (sys->edgeDynParamsVary == TRUE) {
00420 if ((newEdgeDynParams = (ne_dyn_param_t *)calloc(NE_DYN_PARAMS * (edges + 1),
00421 sizeof(ne_dyn_param_t))) == NULL) {
00422 ne_error("ne_sys_add_edge: Could not allocate memory for ne_sys.edgeDynParams.");
00423 free(newEdgeParams);
00424 return NE_MEM_ALLOC_ERROR;
00425 }
00426 memcpy(newEdgeDynParams, sys->edgeDynParams, sizeof(ne_dyn_param_t) * NE_DYN_PARAMS * edges);
00427 free(sys->edgeDynParams);
00428 sys->edgeDynParams = newEdgeDynParams;
00429 }
00430 if (sys->edgeDynVary == TRUE) {
00431 if ((newEdgeDyn = (ne_dyn_edge_t **)calloc(edges+1, sizeof(ne_dyn_edge_t *))) == NULL) {
00432 ne_error("ne_sys_add_edge: Could not allocate memory for ne_sys.edgeDyn.");
00433 free(newEdgeParams);
00434 if (sys->edgeDynParamsVary == TRUE)
00435 free(newEdgeDynParams);
00436 return NE_MEM_ALLOC_ERROR;
00437 }
00438
00439 memcpy(newEdgeDyn, sys->edgeDyn, sizeof(ne_dyn_edge_t *) * edges);
00440 free(sys->edgeDyn);
00441 sys->edgeDyn = newEdgeDyn;
00442 }
00443
00444
00445 memcpy(newEdgeParams, sys->edgeParams, sizeof(ne_param_t) * NE_EDGE_PARAMS * edges);
00446 free(sys->edgeParams);
00447 sys->edgeParams = newEdgeParams;
00448
00449
00450 igraph_add_edge(sys->graph, (igraph_integer_t)startNode, (igraph_integer_t)endNode);
00451
00452 ne_sys_set_dyn_edge(sys, startNode, endNode, dyn);
00453 ne_sys_set_dyn_edge_params(sys, startNode, endNode, params);
00454
00455 return NE_SUCCESS;
00456 }
00457
00458
00459 ne_err_code_t ne_sys_del_node (ne_sys_t *sys, ne_int_t node)
00460 {
00461 ne_param_t *newNodeParams;
00462 ne_dyn_param_t *newNodeDynParams;
00463 ne_dyn_node_t **newNodeDyn;
00464 igraph_es_t esDel;
00465 igraph_eit_t eitDel;
00466 ne_int_t nodes;
00467 nodes = (ne_int_t)igraph_vcount(sys->graph);
00468
00469 if (nodes == 1) {
00470 ne_error("ne_sys_del_node: Cannot delete node when only 1 left.");
00471 return NE_FAILURE;
00472 }
00473
00474
00475
00476 igraph_es_adj(&esDel, (igraph_integer_t)node, IGRAPH_ALL);
00477 igraph_eit_create(sys->graph, esDel, &eitDel);
00478 while (!IGRAPH_EIT_END(eitDel)) {
00479 ne_sys_del_eid(sys, (ne_int_t)IGRAPH_EIT_GET(eitDel));
00480 IGRAPH_EIT_NEXT(eitDel);
00481 }
00482
00483
00484 if ((newNodeParams = (ne_param_t *)calloc(NE_NODE_PARAMS * (nodes - 1),
00485 sizeof(ne_param_t))) == NULL) {
00486 ne_error("ne_sys_del_node: Could not allocate memory for ne_sys.nodeParams.");
00487 return NE_MEM_ALLOC_ERROR;
00488 }
00489
00490 if (sys->nodeDynParamsVary == TRUE) {
00491 if ((newNodeDynParams = (ne_dyn_param_t *)calloc(NE_DYN_PARAMS * (nodes - 1),
00492 sizeof(ne_dyn_param_t))) == NULL) {
00493 ne_error("ne_sys_del_node: Could not allocate memory for ne_sys.nodeDynParams.");
00494 free(newNodeParams);
00495 return NE_MEM_ALLOC_ERROR;
00496 }
00497 memcpy(newNodeDynParams, sys->nodeDynParams, sizeof(ne_dyn_param_t) * NE_DYN_PARAMS * node);
00498 memcpy(&newNodeDynParams[node], &sys->nodeDynParams[node+1], sizeof(ne_dyn_param_t) * NE_DYN_PARAMS * (nodes-1-node));
00499 free(sys->nodeDynParams);
00500 sys->nodeDynParams = newNodeDynParams;
00501 }
00502 if (sys->nodeDynVary == TRUE) {
00503 if ((newNodeDyn = (ne_dyn_node_t **)calloc(nodes-1, sizeof(ne_dyn_node_t *))) == NULL) {
00504 ne_error("ne_sys_del_node: Could not allocate memory for ne_sys.nodeDyn.");
00505 free(newNodeParams);
00506 if (sys->nodeDynParamsVary == TRUE)
00507 free(newNodeDynParams);
00508 return NE_MEM_ALLOC_ERROR;
00509 }
00510 memcpy(newNodeDyn, sys->nodeDyn, sizeof(ne_dyn_node_t *) * node);
00511 memcpy(&newNodeDyn[node], &sys->nodeDyn[node+1], sizeof(ne_dyn_node_t *) * (nodes-1-node));
00512 free(sys->nodeDyn);
00513 sys->nodeDyn = newNodeDyn;
00514 }
00515
00516
00517 memcpy(newNodeParams, sys->nodeParams, sizeof(ne_param_t) * NE_NODE_PARAMS * node);
00518 memcpy(&newNodeParams[node], &sys->nodeParams[node+1], sizeof(ne_param_t) * NE_NODE_PARAMS * (nodes-1-node));
00519
00520
00521 free(sys->nodeParams);
00522 sys->nodeParams = newNodeParams;
00523
00524
00525 igraph_delete_vertices(sys->graph, igraph_vss_1((igraph_integer_t)node));
00526
00527 return NE_SUCCESS;
00528 }
00529
00530
00531 ne_err_code_t ne_sys_del_edge (ne_sys_t *sys, ne_int_t startNode, ne_int_t endNode)
00532 {
00533 igraph_integer_t eidDel;
00534
00535
00536 igraph_get_eid(sys->graph, &eidDel, (igraph_integer_t)startNode, (igraph_integer_t)endNode,
00537 igraph_is_directed(sys->graph));
00538
00539 return ne_sys_del_eid(sys, (ne_int_t)eidDel);
00540 }
00541
00542
00543 ne_err_code_t ne_sys_del_eid (ne_sys_t *sys, ne_int_t eid)
00544 {
00545 ne_param_t *newEdgeParams;
00546 ne_dyn_param_t *newEdgeDynParams;
00547 ne_dyn_edge_t **newEdgeDyn;
00548 ne_int_t edges;
00549 edges = (ne_int_t)igraph_ecount(sys->graph);
00550
00551
00552 if ((newEdgeParams = (ne_param_t *)calloc(NE_EDGE_PARAMS * (edges - 1),
00553 sizeof(ne_param_t))) == NULL) {
00554 ne_error("ne_sys_del_edge: Could not allocate memory for ne_sys.edgeParams.");
00555 return NE_MEM_ALLOC_ERROR;
00556 }
00557 if (sys->edgeDynParamsVary == TRUE) {
00558 if ((newEdgeDynParams = (ne_dyn_param_t *)calloc(NE_DYN_PARAMS * (edges - 1),
00559 sizeof(ne_dyn_param_t))) == NULL) {
00560 ne_error("ne_sys_del_edge: Could not allocate memory for ne_sys.edgeDynParams.");
00561 free(newEdgeParams);
00562 return NE_MEM_ALLOC_ERROR;
00563 }
00564 memcpy(newEdgeDynParams, sys->edgeDynParams, sizeof(ne_dyn_param_t) * NE_DYN_PARAMS * eid);
00565 memcpy(&newEdgeDynParams[eid], &sys->edgeDynParams[eid+1], sizeof(ne_dyn_param_t) * NE_DYN_PARAMS * (edges-1-eid));
00566 free(sys->edgeDynParams);
00567 sys->edgeDynParams = newEdgeDynParams;
00568
00569 }
00570 if (sys->edgeDynVary == TRUE) {
00571 if ((newEdgeDyn = (ne_dyn_edge_t **)calloc(edges-1, sizeof(ne_dyn_edge_t *))) == NULL) {
00572 ne_error("ne_sys_del_edge: Could not allocate memory for ne_sys.edgeDyn.");
00573 free(newEdgeParams);
00574 if (sys->edgeDynParamsVary == TRUE)
00575 free(newEdgeDynParams);
00576 return NE_MEM_ALLOC_ERROR;
00577 }
00578 memcpy(newEdgeDyn, sys->edgeDyn, sizeof(ne_dyn_edge_t *) * eid);
00579 memcpy(&newEdgeDyn[eid], &sys->edgeDyn[eid+1], sizeof(ne_dyn_edge_t *) * (edges-1-eid));
00580 free(sys->edgeDyn);
00581 sys->edgeDyn = newEdgeDyn;
00582 }
00583
00584
00585 memcpy(newEdgeParams, sys->edgeParams, sizeof(ne_param_t) * NE_EDGE_PARAMS * eid);
00586 memcpy(&newEdgeParams[eid], &sys->edgeParams[eid+1], sizeof(ne_param_t) * NE_EDGE_PARAMS * (edges-1-eid));
00587
00588
00589 free(sys->edgeParams);
00590 sys->edgeParams = newEdgeParams;
00591
00592
00593 igraph_delete_edges(sys->graph, igraph_ess_1((igraph_integer_t)eid));
00594
00595 return NE_SUCCESS;
00596 }
00597
00598
00599 ne_param_t ne_sys_node_param (ne_sys_t *sys, ne_int_t node, ne_int_t param)
00600 {
00601 return sys->nodeParams[(node * NE_NODE_PARAMS) + param];
00602 }
00603
00604
00605 ne_param_t ne_sys_edge_param (ne_sys_t *sys, ne_int_t startNode, ne_int_t endNode, ne_int_t param)
00606 {
00607 igraph_integer_t eid;
00608
00609 igraph_get_eid(sys->graph, &eid, (igraph_integer_t)startNode, (igraph_integer_t)endNode, igraph_is_directed(sys->graph));
00610 return sys->edgeParams[((ne_int_t)eid * NE_EDGE_PARAMS) + param];
00611 }
00612
00613
00614 ne_param_t ne_sys_eid_param (ne_sys_t *sys, ne_int_t eid, ne_int_t param)
00615 {
00616 return sys->edgeParams[(eid * NE_EDGE_PARAMS) + param];
00617 }
00618
00619
00620 ne_err_code_t ne_sys_set_node_param (ne_sys_t *sys, ne_int_t node, ne_int_t param, ne_param_t value)
00621 {
00622 sys->nodeParams[(node * NE_NODE_PARAMS) + param] = value;
00623 return NE_SUCCESS;
00624
00625 }
00626
00627
00628 ne_err_code_t ne_sys_set_edge_param (ne_sys_t *sys, ne_int_t startNode, ne_int_t endNode,
00629 ne_int_t param, ne_param_t value)
00630 {
00631 igraph_integer_t eid;
00632
00633 igraph_get_eid(sys->graph, &eid, (igraph_integer_t)startNode, (igraph_integer_t)endNode, igraph_is_directed(sys->graph));
00634 sys->edgeParams[((ne_int_t)eid * NE_EDGE_PARAMS) + param] = value;
00635 return NE_SUCCESS;
00636 }
00637
00638
00639 ne_err_code_t ne_sys_set_eid_param (ne_sys_t *sys, ne_int_t eid, ne_int_t param,
00640 ne_param_t value)
00641 {
00642 sys->edgeParams[(eid * NE_EDGE_PARAMS) + param] = value;
00643 return NE_SUCCESS;
00644 }
00645
00646
00647 ne_dyn_node_t * ne_sys_dyn_node (ne_sys_t *sys, ne_int_t node)
00648 {
00649 if (sys->nodeDynVary == TRUE) {
00650 return sys->nodeDyn[node];
00651 }
00652 else {
00653 return sys->nodeDyn[0];
00654 }
00655 }
00656
00657
00658 ne_dyn_edge_t * ne_sys_dyn_edge (ne_sys_t *sys, ne_int_t startNode, ne_int_t endNode)
00659 {
00660 igraph_integer_t eid;
00661
00662 if (sys->edgeDynVary == TRUE) {
00663
00664 igraph_get_eid(sys->graph, &eid, (igraph_integer_t)startNode, (igraph_integer_t)endNode, igraph_is_directed(sys->graph));
00665 return sys->edgeDyn[(ne_int_t)eid];
00666 }
00667 else {
00668 return sys->edgeDyn[0];
00669 }
00670 }
00671
00672
00673 ne_dyn_edge_t * ne_sys_dyn_eid (ne_sys_t *sys, ne_int_t eid)
00674 {
00675 if (sys->edgeDynVary == TRUE) {
00676 return sys->edgeDyn[eid];
00677 }
00678 else {
00679 return sys->edgeDyn[0];
00680 }
00681 }
00682
00683
00684 ne_err_code_t ne_sys_set_dyn_node (ne_sys_t *sys, ne_int_t node, ne_dyn_node_t *nodeDyn)
00685 {
00686 if (sys->nodeDynVary == TRUE) {
00687 sys->nodeDyn[node] = nodeDyn;
00688 }
00689 else {
00690 sys->nodeDyn[0] = nodeDyn;
00691 }
00692
00693 return NE_SUCCESS;
00694 }
00695
00696
00697 ne_err_code_t ne_sys_set_dyn_edge (ne_sys_t *sys, ne_int_t startNode, ne_int_t endNode,
00698 ne_dyn_edge_t *edgeDyn)
00699 {
00700 igraph_integer_t eid;
00701
00702 if (sys->edgeDynVary == TRUE) {
00703
00704 igraph_get_eid(sys->graph, &eid, (igraph_integer_t)startNode, (igraph_integer_t)endNode, igraph_is_directed(sys->graph));
00705 sys->edgeDyn[(ne_int_t)eid] = edgeDyn;
00706 }
00707 else {
00708 sys->edgeDyn[0] = edgeDyn;
00709 }
00710
00711 return NE_SUCCESS;
00712 }
00713
00714
00715 ne_err_code_t ne_sys_set_dyn_eid (ne_sys_t *sys, ne_int_t eid, ne_dyn_edge_t *edgeDyn)
00716 {
00717 if (sys->edgeDynVary == TRUE) {
00718 sys->edgeDyn[eid] = edgeDyn;
00719 }
00720 else {
00721 sys->edgeDyn[0] = edgeDyn;
00722 }
00723
00724 return NE_SUCCESS;
00725 }
00726
00727
00728 ne_dyn_param_t ne_sys_dyn_node_param (ne_sys_t *sys, ne_int_t node, ne_int_t param)
00729 {
00730 if (sys->nodeDynParamsVary == TRUE) {
00731 return sys->nodeDynParams[(node * NE_DYN_PARAMS) + param];
00732 }
00733 else {
00734 return sys->nodeDynParams[param];
00735 }
00736 }
00737
00738
00739 ne_dyn_param_t * ne_sys_dyn_node_params (ne_sys_t *sys, ne_int_t node)
00740 {
00741 if (sys->nodeDynParamsVary == TRUE) {
00742 return &sys->nodeDynParams[node * NE_DYN_PARAMS];
00743 }
00744 else {
00745 return sys->nodeDynParams;
00746 }
00747 }
00748
00749
00750 ne_dyn_param_t ne_sys_dyn_edge_param (ne_sys_t *sys, ne_int_t startNode, ne_int_t endNode,
00751 ne_int_t param)
00752 {
00753 igraph_integer_t eid;
00754
00755 if (sys->edgeDynParamsVary == TRUE) {
00756
00757 igraph_get_eid(sys->graph, &eid, (igraph_integer_t)startNode, (igraph_integer_t)endNode, igraph_is_directed(sys->graph));
00758 return sys->edgeDynParams[((ne_int_t)eid * NE_DYN_PARAMS) + param];
00759 }
00760 else {
00761 return sys->edgeDynParams[param];
00762 }
00763 }
00764
00765
00766 ne_dyn_param_t ne_sys_dyn_eid_param (ne_sys_t *sys, ne_int_t eid, ne_int_t param)
00767 {
00768 if (sys->edgeDynParamsVary == TRUE) {
00769 return sys->edgeDynParams[(eid * NE_DYN_PARAMS) + param];
00770 }
00771 else {
00772 return sys->edgeDynParams[param];
00773 }
00774 }
00775
00776
00777 ne_dyn_param_t * ne_sys_dyn_edge_params (ne_sys_t *sys, ne_int_t startNode, ne_int_t endNode)
00778 {
00779 igraph_integer_t eid;
00780
00781 if (sys->edgeDynParamsVary == TRUE) {
00782
00783 igraph_get_eid(sys->graph, &eid, (igraph_integer_t)startNode, (igraph_integer_t)endNode, igraph_is_directed(sys->graph));
00784 return &sys->edgeDynParams[(ne_int_t)eid * NE_DYN_PARAMS];
00785 }
00786 else {
00787 return sys->edgeDynParams;
00788 }
00789 }
00790
00791
00792 ne_dyn_param_t * ne_sys_dyn_eid_params (ne_sys_t *sys, ne_int_t eid)
00793 {
00794 if (sys->edgeDynParamsVary == TRUE) {
00795 return &sys->edgeDynParams[eid * NE_DYN_PARAMS];
00796 }
00797 else {
00798 return sys->edgeDynParams;
00799 }
00800 }
00801
00802
00803 ne_err_code_t ne_sys_set_dyn_node_param (ne_sys_t *sys, ne_int_t node, ne_int_t param,
00804 ne_dyn_param_t value)
00805 {
00806 if (sys->nodeDynParamsVary == TRUE) {
00807 sys->nodeDynParams[(node * NE_DYN_PARAMS) + param] = value;
00808 }
00809 else {
00810 sys->nodeDynParams[param] = value;
00811 }
00812
00813 return NE_SUCCESS;
00814 }
00815
00816
00817 ne_err_code_t ne_sys_set_dyn_edge_param (ne_sys_t *sys, ne_int_t startNode, ne_int_t endNode,
00818 ne_int_t param, ne_dyn_param_t value)
00819 {
00820 igraph_integer_t eid;
00821
00822 if (sys->edgeDynParamsVary == TRUE) {
00823
00824 igraph_get_eid(sys->graph, &eid, (igraph_integer_t)startNode, (igraph_integer_t)endNode, igraph_is_directed(sys->graph));
00825 sys->edgeDynParams[((ne_int_t)eid * NE_DYN_PARAMS) + param] = value;
00826 }
00827 else {
00828 sys->edgeDynParams[param] = value;
00829 }
00830
00831 return NE_SUCCESS;
00832 }
00833
00834
00835 ne_err_code_t ne_sys_set_dyn_eid_param (ne_sys_t *sys, ne_int_t eid, ne_int_t param,
00836 ne_dyn_param_t value)
00837 {
00838 if (sys->edgeDynParamsVary == TRUE) {
00839 sys->edgeDynParams[(eid * NE_DYN_PARAMS) + param] = value;
00840 }
00841 else {
00842 sys->edgeDynParams[param] = value;
00843 }
00844
00845 return NE_SUCCESS;
00846 }
00847
00848
00849 ne_err_code_t ne_sys_set_dyn_node_params (ne_sys_t *sys, ne_int_t node, ne_dyn_param_t *params)
00850 {
00851 if (sys->nodeDynParamsVary == TRUE) {
00852 memcpy(&sys->nodeDynParams[node*NE_DYN_PARAMS], params, sizeof(ne_dyn_param_t) * NE_DYN_PARAMS);
00853 }
00854 else {
00855 memcpy(sys->nodeDynParams, params, sizeof(ne_dyn_param_t) * NE_DYN_PARAMS);
00856 }
00857 return NE_SUCCESS;
00858 }
00859
00860
00861 ne_err_code_t ne_sys_set_dyn_edge_params (ne_sys_t *sys, ne_int_t startNode, ne_int_t endNode,
00862 ne_dyn_param_t *params)
00863 {
00864 igraph_integer_t eid;
00865
00866 if (sys->edgeDynParamsVary == TRUE) {
00867
00868 igraph_get_eid(sys->graph, &eid, (igraph_integer_t)startNode, (igraph_integer_t)endNode,
00869 igraph_is_directed(sys->graph));
00870 return ne_sys_set_dyn_eid_params(sys, (ne_int_t)eid, params);
00871 }
00872 else {
00873 memcpy(sys->edgeDynParams, params, sizeof(ne_dyn_param_t) * NE_DYN_PARAMS);
00874 }
00875
00876 return NE_SUCCESS;
00877 }
00878
00879
00880 ne_err_code_t ne_sys_set_dyn_eid_params (ne_sys_t *sys, ne_int_t eid, ne_dyn_param_t *params)
00881 {
00882 if (sys->edgeDynParamsVary == TRUE) {
00883 memcpy(&sys->edgeDynParams[eid*NE_DYN_PARAMS], params, sizeof(ne_dyn_param_t) * NE_DYN_PARAMS);
00884 }
00885 else {
00886 memcpy(sys->edgeDynParams, params, sizeof(ne_dyn_param_t) * NE_DYN_PARAMS);
00887 }
00888 return NE_SUCCESS;
00889 }
00890
00891
00892 ne_err_code_t ne_sys_to_GML (ne_sys_t *sys, FILE *file)
00893 {
00894 int i, j;
00895 char paramBuf[100];
00896 igraph_t *G;
00897
00898 G = sys->graph;
00899
00900
00901 DELALL(G);
00902
00903
00904 SETVAN(G, "neNodeStates", 0, sys->nodeStates);
00905 SETVAN(G, "neEdgeStates", 0, sys->edgeStates);
00906 SETVAN(G, "neNodeDynVary", 0, sys->nodeDynVary);
00907 SETVAN(G, "neEdgeDynVary", 0, sys->edgeDynVary);
00908 SETVAN(G, "neNodeDynParamsVary", 0, sys->nodeDynParamsVary);
00909 SETVAN(G, "neEdgeDynParamsVary", 0, sys->edgeDynParamsVary);
00910
00911
00912 for (i=0; i<ne_sys_nodes(sys); i++) {
00913 for (j=0; j<NE_NODE_PARAMS; j++) {
00914 sprintf(paramBuf, "neNodeParam%i", j);
00915 SETVAN(G, paramBuf, i, ne_sys_node_param(sys, i, j));
00916 }
00917 }
00918
00919
00920 if (ne_sys_dyn_node_param_vary(sys)) {
00921 for (i=0; i<ne_sys_nodes(sys); i++) {
00922 for (j=0; j<NE_DYN_PARAMS; j++) {
00923 sprintf(paramBuf, "neNodeDynParam%i", j);
00924 SETVAN(G, paramBuf, i, ne_sys_dyn_node_param(sys, i, j));
00925 }
00926 }
00927 }
00928 else {
00929 for (j=0; j<NE_DYN_PARAMS; j++) {
00930 sprintf(paramBuf, "neNodeDynParam%i", j);
00931 SETVAN(G, paramBuf, 0, ne_sys_dyn_node_param(sys, 0, j));
00932 }
00933 }
00934
00935
00936 if (ne_sys_dyn_node_vary(sys)) {
00937 for (i=0; i<ne_sys_nodes(sys); i++) {
00938 SETVAS(G, "neNodeDyn", i, ne_sys_dyn_node(sys, i)->name);
00939 }
00940 }
00941 else {
00942 SETVAS(G, "neNodeDyn", 0, ne_sys_dyn_node(sys, 0)->name);
00943 }
00944
00945
00946 for (i=0; i<ne_sys_edges(sys); i++) {
00947 for (j=0; j<NE_EDGE_PARAMS; j++) {
00948 sprintf(paramBuf, "neEdgeParam%i", j);
00949 SETEAN(G, paramBuf, i, ne_sys_eid_param(sys, i, j));
00950 }
00951 }
00952
00953
00954 if (ne_sys_dyn_edge_param_vary(sys)) {
00955 for (i=0; i<ne_sys_edges(sys); i++) {
00956 for (j=0; j<NE_DYN_PARAMS; j++) {
00957 sprintf(paramBuf, "neEdgeDynParam%i", j);
00958 SETEAN(G, paramBuf, i, ne_sys_dyn_eid_param(sys, i, j));
00959 }
00960 }
00961 }
00962 else {
00963 if (ne_sys_edges(sys) > 0) {
00964 for (j=0; j<NE_DYN_PARAMS; j++) {
00965 sprintf(paramBuf, "neEdgeDynParam%i", j);
00966 SETEAN(G, paramBuf, 0, ne_sys_dyn_eid_param(sys, 0, j));
00967 }
00968 }
00969 }
00970
00971
00972 if (ne_sys_dyn_edge_vary(sys)) {
00973 for (i=0; i<ne_sys_edges(sys); i++) {
00974 SETEAS(G, "neEdgeDyn", i, ne_sys_dyn_eid(sys, i)->name);
00975 }
00976 }
00977 else {
00978 if (ne_sys_edges(sys) > 0) {
00979 SETEAS(G, "neEdgeDyn", 0, ne_sys_dyn_eid(sys, 0)->name);
00980 }
00981 }
00982
00983
00984 igraph_write_graph_gml(G, file, NULL, "NetEvo");
00985
00986
00987 DELALL(G);
00988
00989 return NE_SUCCESS;
00990 }
00991
00992
00993 ne_sys_t * ne_sys_from_GML (FILE *file)
00994 {
00995 int i, j;
00996 char paramBuf[100];
00997 igraph_t G;
00998 ne_sys_t *sys;
00999
01000
01001 igraph_read_graph_gml(&G, file);
01002
01003
01004 sys = ne_sys_alloc_from_igraph(&G,
01005 (ne_int_t)VAN(&G, "neNodeStates", 0),
01006 (ne_int_t)VAN(&G, "neEdgeStates", 0),
01007 (ne_bool_t)VAN(&G, "neNodeDynVary", 0),
01008 (ne_bool_t)VAN(&G, "neEdgeDynVary", 0),
01009 (ne_bool_t)VAN(&G, "neNodeDynParamsVary", 0),
01010 (ne_bool_t)VAN(&G, "neEdgeDynParamsVary", 0));
01011
01012
01013 for (i=0; i<ne_sys_nodes(sys); i++) {
01014 for (j=0; j<NE_NODE_PARAMS; j++) {
01015 sprintf(paramBuf, "neNodeParam%i", j);
01016 ne_sys_set_node_param(sys, i, j, (ne_param_t)VAN(&G, paramBuf, i));
01017 }
01018 }
01019
01020
01021 if (ne_sys_dyn_node_param_vary(sys)) {
01022 for (i=0; i<ne_sys_nodes(sys); i++) {
01023 for (j=0; j<NE_DYN_PARAMS; j++) {
01024 sprintf(paramBuf, "neNodeDynParam%i", j);
01025 ne_sys_set_dyn_node_param(sys, i, j, (ne_dyn_param_t)VAN(&G, paramBuf, i));
01026 }
01027 }
01028 }
01029 else {
01030 for (j=0; j<NE_DYN_PARAMS; j++) {
01031 sprintf(paramBuf, "neNodeDynParam%i", j);
01032 ne_sys_set_dyn_node_param(sys, 0, j, (ne_dyn_param_t)VAN(&G, paramBuf, 0));
01033 }
01034 }
01035
01036
01037 if (ne_sys_dyn_node_vary(sys)) {
01038 for (i=0; i<ne_sys_nodes(sys); i++) {
01039 ne_sys_set_dyn_node(sys, i, ne_dyn_find_node_dyn(VAS(&G, "neNodeDyn", i)));
01040 }
01041 }
01042 else {
01043 ne_sys_set_dyn_node(sys, 0, ne_dyn_find_node_dyn(VAS(&G, "neNodeDyn", 0)));
01044 }
01045
01046
01047 for (i=0; i<ne_sys_edges(sys); i++) {
01048 for (j=0; j<NE_EDGE_PARAMS; j++) {
01049 sprintf(paramBuf, "neEdgeParam%i", j);
01050 ne_sys_set_eid_param(sys, i, j, (ne_param_t)EAN(&G, paramBuf, i));
01051 }
01052 }
01053
01054
01055 if (ne_sys_dyn_edge_param_vary(sys)) {
01056 for (i=0; i<ne_sys_edges(sys); i++) {
01057 for (j=0; j<NE_DYN_PARAMS; j++) {
01058 sprintf(paramBuf, "neEdgeDynParam%i", j);
01059 ne_sys_set_dyn_eid_param(sys, i, j, (ne_dyn_param_t)EAN(&G, paramBuf, i));
01060 }
01061 }
01062 }
01063 else {
01064 if (ne_sys_edges(sys) > 0) {
01065 for (j=0; j<NE_DYN_PARAMS; j++) {
01066 sprintf(paramBuf, "neEdgeDynParam%i", j);
01067 ne_sys_set_dyn_eid_param(sys, 0, j, (ne_dyn_param_t)EAN(&G, paramBuf, 0));
01068 }
01069 }
01070 }
01071
01072
01073 if (ne_sys_dyn_edge_vary(sys)) {
01074 for (i=0; i<ne_sys_edges(sys); i++) {
01075 ne_sys_set_dyn_eid(sys, i, ne_dyn_find_edge_dyn(EAS(&G, "neEdgeDyn", i)));
01076 }
01077 }
01078 else {
01079 if (ne_sys_edges(sys) > 0) {
01080 ne_sys_set_dyn_eid(sys, 0, ne_dyn_find_edge_dyn(EAS(&G, "neEdgeDyn", 0)));
01081 }
01082 }
01083
01084
01085 igraph_destroy(&G);
01086 DELALL(sys->graph);
01087
01088 return sys;
01089 }
01090
01091
01092 void ne_sys_print(ne_sys_t *sys)
01093 {
01094
01095 ne_log("ne_sys_print: Not yet implemented.");
01096 }
01097
01098
01099 gsl_matrix * ne_sys_adj_to_gsl_matrix_alloc (ne_sys_t *sys)
01100 {
01101 gsl_matrix *M;
01102 ne_int_t i, j;
01103
01104 M = gsl_matrix_calloc((size_t)ne_sys_nodes(sys), (size_t)ne_sys_nodes(sys));
01105
01106 for (i=0; i<ne_sys_nodes(sys); i++) {
01107 for (j=0; j<ne_sys_nodes(sys); j++) {
01108 if (ne_sys_edge_exists(sys, i, j) == TRUE)
01109 gsl_matrix_set(M, (size_t)i, (size_t)j, 1.0);
01110 }
01111 }
01112
01113 return M;
01114 }
01115
01116
01117 gsl_matrix * ne_sys_laplacian_to_gsl_matrix_alloc (ne_sys_t *sys)
01118 {
01119 gsl_matrix *L;
01120 igraph_matrix_t igraphL;
01121 ne_int_t i, j;
01122
01123 L = gsl_matrix_calloc((size_t)ne_sys_nodes(sys), (size_t)ne_sys_nodes(sys));
01124
01125 igraph_matrix_init(&igraphL, 0, 0);
01126
01127
01128 igraph_laplacian(sys->graph, &igraphL, FALSE);
01129
01130
01131 for (i=0; i<igraph_vcount(sys->graph); i++) {
01132 for (j=0; j<igraph_vcount(sys->graph); j++) {
01133 gsl_matrix_set(L, i, j, MATRIX(igraphL,i,j));
01134 }
01135 }
01136
01137 igraph_matrix_destroy(&igraphL);
01138
01139 return L;
01140 }
01141