• Main Page
  • Data Structures
  • Files
  • File List
  • Globals

ne_sys.c

00001 /*===========================================================================
00002  NetEvo Foundation Library
00003  Copyright (C) 2009, 2010 Thomas E. Gorochowski <tgorochowski@me.com>
00004  Bristol Centre for Complexity Sciences, University of Bristol, Bristol, UK
00005  ---------------------------------------------------------------------------- 
00006  NetEvo is a computing framework designed to allow researchers to investigate 
00007  evolutionary aspects of dynamical complex networks. By providing tools to 
00008  easily integrate each of these factors in a coherent way, it is hoped a 
00009  greater understanding can be gained of key attributes and features displayed 
00010  by complex systems.
00011  
00012  NetEvo is open-source software released under the Open Source Initiative 
00013  (OSI) approved Non-Profit Open Software License ("Non-Profit OSL") 3.0. 
00014  Detailed information about this licence can be found in the COPYING file 
00015  included as part of the source distribution.
00016  
00017  This library is distributed in the hope that it will be useful, but
00018  WITHOUT ANY WARRANTY; without even the implied warranty of
00019  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
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    /* Initialise the copy with details of the graph */
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    /* Bulk copy the arrays of dynamic data */
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    /* Decide which edges to extract from graph */
00320    if (!igraph_is_directed(sys->graph)) {
00321       /* Only consider inward and outward edges */
00322       igraph_neighbors(sys->graph, &adjV, (igraph_integer_t)startNode, IGRAPH_ALL);
00323    }
00324    else {   
00325       /* Only consider outward edges */
00326       igraph_neighbors(sys->graph, &adjV, (igraph_integer_t)startNode, IGRAPH_OUT);
00327    }
00328    
00329    /* Check each adjacent edge */
00330    for (i=0; i<igraph_vector_size(&adjV); i++) {
00331       /* Check to see if correct edge found */
00332       if (VECTOR(adjV)[(int)i] == (igraph_integer_t)endNode) {
00333          /* Found the edge, stop searching and return success */
00334          return TRUE;
00335       }
00336    }
00337    
00338    igraph_vector_destroy(&adjV);
00339    
00340    /* Could not find an edge */
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    /* Allocate memory for new parameter arrays */
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       /* Bulk copy the node dynamics */
00379       memcpy(newNodeDyn, sys->nodeDyn, sizeof(ne_dyn_node_t *) * nodes);
00380       free(sys->nodeDyn);
00381       sys->nodeDyn = newNodeDyn;
00382    }
00383    
00384    /* Bulk copy the parameters */
00385    memcpy(newNodeParams, sys->nodeParams, sizeof(ne_param_t) * NE_NODE_PARAMS * nodes);
00386    free(sys->nodeParams);
00387    sys->nodeParams = newNodeParams;
00388 
00389    /* Update the graph */
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    /* Allocate memory for new parameter arrays */
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       /* Bulk copy the edge dynamics */
00439       memcpy(newEdgeDyn, sys->edgeDyn, sizeof(ne_dyn_edge_t *) * edges);
00440       free(sys->edgeDyn);
00441       sys->edgeDyn = newEdgeDyn;
00442    }
00443    
00444    /* Bulk copy the parameters */
00445    memcpy(newEdgeParams, sys->edgeParams, sizeof(ne_param_t) * NE_EDGE_PARAMS * edges);
00446    free(sys->edgeParams);
00447    sys->edgeParams = newEdgeParams;
00448    
00449    /* Update the graph */
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    /* Cycle through each connected edge and remove */
00475    /* This will be slow as it requires reallocation of memory at each step */
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    /* Allocate memory for new parameter arrays */
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    /* Bulk copy removing the element that is removed */
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    /* Swap arrays and free old ones */
00521    free(sys->nodeParams);
00522    sys->nodeParams = newNodeParams;
00523 
00524    /* Remove node from graph */
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    /* Edge ID required to calculate indexes that need to be copied */
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    /* Allocate memory for new parameter arrays */
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    /* Bulk copy removing the element that is removed */
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    /* Swap arrays and free old ones */
00589    free(sys->edgeParams);
00590    sys->edgeParams = newEdgeParams;
00591    
00592    /* Remove edge from graph */
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    /* Find the edge ID used for the index in the parameters array */
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    /* Find the edge ID used for the index in the parameters array */
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       /* Find the edge ID used for the index in the parameters array */
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       /* Find the edge ID used for the index in the parameters array */
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       /* Find the edge ID used for the index in the parameters array */
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       /* Find the edge ID used for the index in the parameters array */
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       /* Find the edge ID used for the index in the parameters array */
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       /* Find the edge ID used for the index in the parameters array */
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    /* Remove all current attributes (none should exist) */
00901    DELALL(G);
00902    
00903    /* Set system level attributes */
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    /* Set all node parameters */
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    /* Set node dynamics parameters */
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    /* Set node dynamics */
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    /* Set all edge parameters */
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    /* Set edge dynamics parameters */
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    /* Set edge dynamics */
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    /* Save to file */
00984    igraph_write_graph_gml(G, file, NULL, "NetEvo");   
00985    
00986    /* Remove all attributes */
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    /* Read the graph */
01001    igraph_read_graph_gml(&G, file);
01002    
01003    /* Generate a new system from this attributed file */
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    /* Load node parameters */
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    /* Set node dynamics parameters */
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    /* Set node dynamics */
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    /* Load edge parameters */
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    /* Load edge dynamics parameters */
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    /* Load edge dynamics */
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    /* Free memory and free any current attributes */
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    /* TODO: ne_sys_print */
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    /* Find the degree of all nodes */
01128    igraph_laplacian(sys->graph, &igraphL, FALSE);
01129    
01130    /* Might be quicker to query the igraph structure directly for each element */
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 

Generated on Thu Aug 26 2010 11:04:25 for NetEvo by  doxygen 1.7.1