Exemple #1
0
int check_ring_properties(const igraph_t *ring, igraph_bool_t directed,
			  igraph_bool_t mutual, igraph_bool_t circular) {

  igraph_bool_t res;

  /* Connected */
  igraph_is_connected(ring, &res, IGRAPH_WEAK); 
  if (!res) {
    printf("Not connected\n");
    return 1;
  }

  /* Simple */
  igraph_is_simple(ring, &res); 
  if (!res) {
    printf("Not simple\n");
    return 2;
  }
  
  /* Girth, for big enough circular graphs */
  if (circular && igraph_vcount(ring) > 2) { 
    igraph_integer_t girth;
    igraph_girth(ring, &girth, NULL);
    if (girth != igraph_vcount(ring)) { 
      printf("Wrong girth\n");
      return 3; 
    }
  }
   
  return 0;
}
Exemple #2
0
int main()

{
   igraph_t graph;
   FILE *instream;
   igraph_real_t diameter=0;
   igraph_bool_t res=1;

    instream=fopen("/home/cyborg/test3-2-3.txt","r");
	igraph_read_graph_edgelist(&graph,instream,6, 0);
   //igraph_diameter_dijkstra(&graph,NULL,&diameter,NULL,NULL,NULL,0,1);
    //igraph_diameter(&graph, &diameter, 0, 0, 0, IGRAPH_UNDIRECTED, 0);
    igraph_is_connected(&graph,&res,IGRAPH_WEAK);
   
   //igraph_shortest_paths(&graph, &res,0,1,IGRAPH_ALL);

    printf("Es conexa? : %d\n",res);
    
    
    igraph_destroy(&graph);
	fcloseall();
	return 0;
	}
Exemple #3
0
int check_lattice_properties(const igraph_t *lattice,
			     const igraph_vector_t *dim, 
			     igraph_bool_t directed, 
			     igraph_bool_t mutual, 
			     igraph_bool_t circular) {
  igraph_bool_t res;

  /* Connected */
  igraph_is_connected(lattice, &res, IGRAPH_WEAK); 
  if (!res) {
    printf("Not connected\n");
    return 1;
  }

  /* Simple */
  igraph_is_simple(lattice, &res); 
  if (!res) {
    printf("Not simple\n");
    return 2;
  }

  return 0;
}
Exemple #4
0
int igraph_i_community_spinglass_negative(const igraph_t *graph,
					  const igraph_vector_t *weights,
					  igraph_real_t *modularity,
					  igraph_real_t *temperature,
					  igraph_vector_t *membership, 
					  igraph_vector_t *csize,
					  igraph_integer_t spins,
					  igraph_bool_t parupdate,
					  igraph_real_t starttemp,
					  igraph_real_t stoptemp,
					  igraph_real_t coolfact,
					  igraph_spincomm_update_t update_rule,
					  igraph_real_t gamma,
/* 					  igraph_matrix_t *adhesion, */
/* 					  igraph_matrix_t *normalised_adhesion, */
/* 					  igraph_real_t *polarization, */
					  igraph_real_t gamma_minus) {

  unsigned long changes, runs;
  igraph_bool_t use_weights=0;
  bool zeroT;
  double kT, acc;
  ClusterList<NNode*> *cl_cur;
  network *net;
  PottsModelN *pm;
  igraph_real_t d_n;
  igraph_real_t d_p;

  /* Check arguments */

  if (parupdate) {
    IGRAPH_ERROR("Parallel spin update not implemented with "
		 "negative gamma", IGRAPH_UNIMPLEMENTED);
  }

  if (spins < 2 || spins > 500) {
    IGRAPH_ERROR("Invalid number of spins", IGRAPH_EINVAL);
  }
  if (update_rule != IGRAPH_SPINCOMM_UPDATE_SIMPLE &&
      update_rule != IGRAPH_SPINCOMM_UPDATE_CONFIG) {
    IGRAPH_ERROR("Invalid update rule", IGRAPH_EINVAL);
  }
  if (weights) {
    if (igraph_vector_size(weights) != igraph_ecount(graph)) {
      IGRAPH_ERROR("Invalid weight vector length", IGRAPH_EINVAL);
    }
    use_weights=1;
  }
  if (coolfact < 0 || coolfact>=1.0) {
    IGRAPH_ERROR("Invalid cooling factor", IGRAPH_EINVAL);
  }
  if (gamma < 0.0) {
    IGRAPH_ERROR("Invalid gamma value", IGRAPH_EINVAL);
  }
  if (starttemp/stoptemp<1.0) {
    IGRAPH_ERROR("starttemp should be larger in absolute value than stoptemp",
		 IGRAPH_EINVAL);
  }
  
  /* Check whether we have a single component */
  igraph_bool_t conn;
  IGRAPH_CHECK(igraph_is_connected(graph, &conn, IGRAPH_WEAK));
  if (!conn) {
    IGRAPH_ERROR("Cannot work with unconnected graph", IGRAPH_EINVAL);
  }
  
  igraph_vector_minmax(weights, &d_n, &d_p);
  if (d_n > 0) { d_n=0; }
  if (d_p < 0) { d_p=0; }
  d_n = -d_n;

  net = new network;
  net->node_list   =new DL_Indexed_List<NNode*>();
  net->link_list   =new DL_Indexed_List<NLink*>();
  net->cluster_list=new DL_Indexed_List<ClusterList<NNode*>*>();

  /* Transform the igraph_t */
  IGRAPH_CHECK(igraph_i_read_network(graph, weights,
				     net, use_weights, 0));
	
  bool directed = igraph_is_directed(graph);
  
  pm=new PottsModelN(net,(unsigned int)spins, directed);

  /* initialize the random number generator */
  RNG_BEGIN();
  
  if ((stoptemp==0.0) && (starttemp==0.0)) zeroT=true; else zeroT=false;

  //Begin at a high enough temperature
  kT=pm->FindStartTemp(gamma, gamma_minus, starttemp);

  /* assign random initial configuration */
  pm->assign_initial_conf(true);

  runs=0;
  changes=1;
  acc = 0;
	while (changes>0 && (kT/stoptemp>1.0 || (zeroT && runs<150))) 
	{
		
		IGRAPH_ALLOW_INTERRUPTION(); /* This is not clean.... */
		
		runs++;
		kT = kT*coolfact; 
		acc=pm->HeatBathLookup(gamma, gamma_minus, kT, 50);
		if (acc<(1.0-1.0/double(spins))*0.001)
			changes=0; 
		else 
			changes=1;
		
	} /* while loop */

  /* These are needed, otherwise 'modularity' is not calculated */
  igraph_matrix_t adhesion, normalized_adhesion;
  igraph_real_t polarization;
  IGRAPH_MATRIX_INIT_FINALLY(&adhesion, 0, 0);
  IGRAPH_MATRIX_INIT_FINALLY(&normalized_adhesion, 0, 0);
  pm->WriteClusters(modularity, temperature, csize, membership, 
		    &adhesion, &normalized_adhesion, &polarization, 
		    kT, d_p, d_n, gamma, gamma_minus);
  igraph_matrix_destroy(&normalized_adhesion);
  igraph_matrix_destroy(&adhesion);
  IGRAPH_FINALLY_CLEAN(2);

  while (net->link_list->Size()) delete net->link_list->Pop();
  while (net->node_list->Size()) delete net->node_list->Pop();
  while (net->cluster_list->Size())
    {
      cl_cur=net->cluster_list->Pop();
      while (cl_cur->Size()) cl_cur->Pop();
      delete cl_cur;
    }
  
  RNG_END();

  return 0;
}
Exemple #5
0
int igraph_community_spinglass_single(const igraph_t *graph,
				      const igraph_vector_t *weights,
				      igraph_integer_t vertex,
				      igraph_vector_t *community,
				      igraph_real_t *cohesion,
				      igraph_real_t *adhesion,
				      igraph_integer_t *inner_links,
				      igraph_integer_t *outer_links,
				      igraph_integer_t spins,
				      igraph_spincomm_update_t update_rule,
				      igraph_real_t gamma) {

  igraph_bool_t use_weights=0;
  double prob;
  ClusterList<NNode*> *cl_cur;
  network *net;
  PottsModel *pm;
  char startnode[255];

  /* Check arguments */

  if (spins < 2 || spins > 500) {
    IGRAPH_ERROR("Invalid number of spins", IGRAPH_EINVAL);
  }
  if (update_rule != IGRAPH_SPINCOMM_UPDATE_SIMPLE &&
      update_rule != IGRAPH_SPINCOMM_UPDATE_CONFIG) {
    IGRAPH_ERROR("Invalid update rule", IGRAPH_EINVAL);
  }
  if (weights) {
    if (igraph_vector_size(weights) != igraph_ecount(graph)) {
      IGRAPH_ERROR("Invalid weight vector length", IGRAPH_EINVAL);
    }
    use_weights=1;
  }
  if (gamma < 0.0) {
    IGRAPH_ERROR("Invalid gamme value", IGRAPH_EINVAL);
  }
  if (vertex < 0 || vertex > igraph_vcount(graph)) {
    IGRAPH_ERROR("Invalid vertex id", IGRAPH_EINVAL);
  }
  
  /* Check whether we have a single component */
  igraph_bool_t conn;
  IGRAPH_CHECK(igraph_is_connected(graph, &conn, IGRAPH_WEAK));
  if (!conn) {
    IGRAPH_ERROR("Cannot work with unconnected graph", IGRAPH_EINVAL);
  }

  net = new network;
  net->node_list   =new DL_Indexed_List<NNode*>();
  net->link_list   =new DL_Indexed_List<NLink*>();
  net->cluster_list=new DL_Indexed_List<ClusterList<NNode*>*>();

  /* Transform the igraph_t */
  IGRAPH_CHECK(igraph_i_read_network(graph, weights,
				     net, use_weights, 0));

  prob=2.0*net->sum_weights/double(net->node_list->Size())
    /double(net->node_list->Size()-1);

  pm=new PottsModel(net,(unsigned int)spins,update_rule);

  /* initialize the random number generator */
  RNG_BEGIN();

  /* to be exected, if we want to find the community around a particular node*/
  /* the initial conf is needed, because otherwise, 
     the degree of the nodes is not in the weight property, stupid!!! */
  pm->assign_initial_conf(-1);
  snprintf(startnode, 255, "%li", (long int)vertex+1);
  pm->FindCommunityFromStart(gamma, prob, startnode, community,
			     cohesion, adhesion, inner_links, outer_links);
  
  while (net->link_list->Size()) delete net->link_list->Pop();
  while (net->node_list->Size()) delete net->node_list->Pop();
  while (net->cluster_list->Size())
    {
      cl_cur=net->cluster_list->Pop();
      while (cl_cur->Size()) cl_cur->Pop();
      delete cl_cur;
    }
  delete net->link_list;
  delete net->node_list;
  delete net->cluster_list;
  
  RNG_END();

  delete net;
  delete pm;

  return 0;
}
Exemple #6
0
int igraph_i_community_spinglass_orig(const igraph_t *graph,
				      const igraph_vector_t *weights,
				      igraph_real_t *modularity,
				      igraph_real_t *temperature,
				      igraph_vector_t *membership, 
				      igraph_vector_t *csize, 
				      igraph_integer_t spins,
				      igraph_bool_t parupdate,
				      igraph_real_t starttemp,
				      igraph_real_t stoptemp,
				      igraph_real_t coolfact,
				      igraph_spincomm_update_t update_rule,
				      igraph_real_t gamma) {

  unsigned long changes, runs;
  igraph_bool_t use_weights=0;
  bool zeroT;
  double kT, acc, prob;
  ClusterList<NNode*> *cl_cur;
  network *net;
  PottsModel *pm;

  /* Check arguments */

  if (spins < 2 || spins > 500) {
    IGRAPH_ERROR("Invalid number of spins", IGRAPH_EINVAL);
  }
  if (update_rule != IGRAPH_SPINCOMM_UPDATE_SIMPLE &&
      update_rule != IGRAPH_SPINCOMM_UPDATE_CONFIG) {
    IGRAPH_ERROR("Invalid update rule", IGRAPH_EINVAL);
  }
  if (weights) {
    if (igraph_vector_size(weights) != igraph_ecount(graph)) {
      IGRAPH_ERROR("Invalid weight vector length", IGRAPH_EINVAL);
    }
    use_weights=1;
  }
  if (coolfact < 0 || coolfact>=1.0) {
    IGRAPH_ERROR("Invalid cooling factor", IGRAPH_EINVAL);
  }
  if (gamma < 0.0) {
    IGRAPH_ERROR("Invalid gamme value", IGRAPH_EINVAL);
  }
  if (starttemp/stoptemp<1.0) {
    IGRAPH_ERROR("starttemp should be larger in absolute value than stoptemp",
		 IGRAPH_EINVAL);
  }
  
  /* Check whether we have a single component */
  igraph_bool_t conn;
  IGRAPH_CHECK(igraph_is_connected(graph, &conn, IGRAPH_WEAK));
  if (!conn) {
    IGRAPH_ERROR("Cannot work with unconnected graph", IGRAPH_EINVAL);
  }

  net = new network;
  net->node_list   =new DL_Indexed_List<NNode*>();
  net->link_list   =new DL_Indexed_List<NLink*>();
  net->cluster_list=new DL_Indexed_List<ClusterList<NNode*>*>();

  /* Transform the igraph_t */
  IGRAPH_CHECK(igraph_i_read_network(graph, weights,
				     net, use_weights, 0));

  prob=2.0*net->sum_weights/double(net->node_list->Size())
    /double(net->node_list->Size()-1);

  pm=new PottsModel(net,(unsigned int)spins,update_rule);

  /* initialize the random number generator */
  RNG_BEGIN();
  
  if ((stoptemp==0.0) && (starttemp==0.0)) zeroT=true; else zeroT=false;
  if (!zeroT) kT=pm->FindStartTemp(gamma, prob, starttemp); else kT=stoptemp;
  /* assign random initial configuration */
  pm->assign_initial_conf(-1);
  runs=0;
  changes=1;

  while (changes>0 && (kT/stoptemp>1.0 || (zeroT && runs<150))) {

    IGRAPH_ALLOW_INTERRUPTION(); /* This is not clean.... */
    
    runs++;
    if (!zeroT) {
      kT*=coolfact;
      if (parupdate) { 
	changes=pm->HeatBathParallelLookup(gamma, prob, kT, 50);
      } else {
	acc=pm->HeatBathLookup(gamma, prob, kT, 50);
	if (acc<(1.0-1.0/double(spins))*0.01) {
	  changes=0; 
	} else { 
	  changes=1;
	}
      }
    } else {
      if (parupdate) { 
	changes=pm->HeatBathParallelLookupZeroTemp(gamma, prob, 50);
      } else {
	acc=pm->HeatBathLookupZeroTemp(gamma, prob, 50);
	/* less than 1 percent acceptance ratio */
	if (acc<(1.0-1.0/double(spins))*0.01) {
	  changes=0; 
	} else { 
	  changes=1;
	}
      }
    }
  } /* while loop */

  pm->WriteClusters(modularity, temperature, csize, membership, kT, gamma);

  while (net->link_list->Size()) delete net->link_list->Pop();
  while (net->node_list->Size()) delete net->node_list->Pop();
  while (net->cluster_list->Size())
    {
      cl_cur=net->cluster_list->Pop();
      while (cl_cur->Size()) cl_cur->Pop();
      delete cl_cur;
    }
  delete net->link_list;
  delete net->node_list;
  delete net->cluster_list;
  
  RNG_END();
  
  delete net;
  delete pm;

  return 0;
}
Exemple #7
0
static GError* _tgengraph_parseGraphProperties(TGenGraph* g) {
    TGEN_ASSERT(g);
    gint result = 0;

    tgen_debug("checking graph properties...");

    /* IGRAPH_WEAK means the undirected version of the graph is connected
     * IGRAPH_STRONG means a vertex can reach all others via a directed path */
    result = igraph_is_connected(g->graph, &(g->isConnected), IGRAPH_WEAK);
    if(result != IGRAPH_SUCCESS) {
        return g_error_new(G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
                "igraph_is_connected return non-success code %i", result);
    }

    igraph_integer_t clusterCount;
    result = igraph_clusters(g->graph, NULL, NULL, &(g->clusterCount), IGRAPH_WEAK);
    if(result != IGRAPH_SUCCESS) {
        return g_error_new(G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
                "igraph_clusters return non-success code %i", result);
    }

    /* it must be connected */
    if(!g->isConnected || g->clusterCount > 1) {
        return g_error_new(G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
                "graph must be but is not connected");
    }

    g->isDirected = igraph_is_directed(g->graph);

    tgen_debug("checking graph attributes...");

    /* now check list of all attributes */
    igraph_strvector_t gnames, vnames, enames;
    igraph_vector_t gtypes, vtypes, etypes;
    igraph_strvector_init(&gnames, 25);
    igraph_vector_init(&gtypes, 25);
    igraph_strvector_init(&vnames, 25);
    igraph_vector_init(&vtypes, 25);
    igraph_strvector_init(&enames, 25);
    igraph_vector_init(&etypes, 25);

    result = igraph_cattribute_list(g->graph, &gnames, &gtypes, &vnames, &vtypes, &enames, &etypes);
    if(result != IGRAPH_SUCCESS) {
        return g_error_new(G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE,
                "igraph_cattribute_list return non-success code %i", result);
    }

    gint i = 0;
    for(i = 0; i < igraph_strvector_size(&gnames); i++) {
        gchar* name = NULL;
        igraph_strvector_get(&gnames, (glong) i, &name);

        tgen_debug("found graph attribute '%s'", name);
    }
    for(i = 0; i < igraph_strvector_size(&vnames); i++) {
        gchar* name = NULL;
        igraph_strvector_get(&vnames, (glong) i, &name);

        tgen_debug("found vertex attribute '%s'", name);
        g->knownAttributes |= _tgengraph_vertexAttributeToFlag(name);
    }
    for(i = 0; i < igraph_strvector_size(&enames); i++) {
        gchar* name = NULL;
        igraph_strvector_get(&enames, (glong) i, &name);

        tgen_debug("found edge attribute '%s'", name);
        g->knownAttributes |= _tgengraph_edgeAttributeToFlag(name);
    }

    igraph_strvector_destroy(&gnames);
    igraph_vector_destroy(&gtypes);
    igraph_strvector_destroy(&vnames);
    igraph_vector_destroy(&vtypes);
    igraph_strvector_destroy(&enames);
    igraph_vector_destroy(&etypes);

    tgen_info("successfully verified graph properties and attributes");

    return NULL;
}
Exemple #8
0
int main(int argc, char* argv[])
{
    if (argc != 9)
    {
        cout << "Usage: ./release/fixating <Update Rule: \"Bd\", \"dB\"> <integer: population size> <\"directed\" or \"undirected\"> <double: fitness of mutant> <category of graph: \"complete\", \"ER\", \"BB\", \"WS\", \"geo\", or \"custom\" > <secondary parameter for the category of graph: \"GNM\" or \"GNP\" for Erdos Reny, double power of preference for Barabasi, int dimension for small world, bool periodic for geometric, , adjacency matrix for custom> <tertiary parameter for the category of graph: probability for every edge in Erdos-Reny GNP and geometric, number of edges for Erdos-Reny GNM, m for barabasi, probability of rewiring for small world, 0 for custom> <output: \"probability\", \"conditional\", \"unconditional\", or \"all\">" << endl;
        return -1;
    }
    //   ---------- If you want to stop time, uncomment all comments with //CLOCK//
    //CLOCK//
    std::clock_t start;
    //CLOCK//
    double bt = 0;
    //CLOCK//
    double st = 0;
    //counting variable for the graph generators
    int counts = 0;
    const unsigned int popSize = atoi(argv[2]);
    if (popSize > 23)
    {
        cout << "Code only possible for population size up to 23... aborting..." << endl;
        return -1;
    }
    const unsigned int numStates = 1 << popSize;

    string update = argv[1];
    if (update != "dB" && update != "Bd")
    {
        cout << "Only \"Bd\" or \"dB\" possible for update rule!... aborting..." << endl;
        return -1;
    }

    float fitnessMutants = atof(argv[4]);
    string direction = argv[3];
    string category = argv[5];
    igraph_t graph;
    int admat[popSize * popSize];

    string output = argv[8];
    if (output != "probability" && output != "conditional" && output != "unconditional" && output != "all")
    {
        cout << "Only \"probability\", \"unconditional\", \"conditional\" or \"all\" possible for output!... aborting..." << endl;
        return -1;
    }



    // ----------   Code snippet for fully connected graph   ----------
    if (category == "complete")
    {
        if (direction == "undirected")
        {
            igraph_full(&graph, popSize, false, false);
        }
        else if (direction == "directed")
        {
            igraph_full(&graph, popSize, true, false);
        }
        else
        {
            cout << "Only \"directed\" and \"undirected\" possible for direction of graph!... aborting..." << endl;
            return -1;
        }
    }


    // ----------   Code snippet for random graph   ----------
    else if (category == "ER")
    {
        string gn = argv[6];

        igraph_rng_seed(igraph_rng_default(), std::clock());
        igraph_bool_t isConnected = 0;

        if (direction == "directed")
        {
            while ((isConnected == 0) & (counts < maxcount))
            {
                if (gn == "GNP")
                {
                    double edgeprob = atof(argv[7]);
                    if ((edgeprob > 1) || (edgeprob < 0))
                    {
                        cout << "probabilities larger than 1 or smaller than 0 ...aborting..." << endl;
                        return -1;
                    }
                    igraph_erdos_renyi_game(&graph, IGRAPH_ERDOS_RENYI_GNP,
                                            popSize, edgeprob,
                                            true, false);
                }
                else if (gn == "GNM")
                {
                    int edgenumber = atoi(argv[7]);
                    if ((edgenumber < 1) || (edgenumber > popSize*(popSize-1)))
                    {
                        cout << "number of edges must be greater than 1 and smaller than N*(N-1) ...aborting..." << endl;
                        return -1;
                    }

                    igraph_erdos_renyi_game(&graph, IGRAPH_ERDOS_RENYI_GNM,
                                            popSize, edgenumber,
                                            true, false);
                }
                else
                {
                    cout << "Only \"GNM\" and \"GNP\" possible ... aborting..." << endl;
                }
                igraph_is_connected(&graph, &isConnected, IGRAPH_STRONG);

                counts++;
            }
            if (counts == maxcount)
            {
                cout << "Probability or number of edges too low... Did not find a connected graph after "<< maxcount <<" attempts... aborting..." << endl;
                return -1;
            }
        }
        else if (direction == "undirected")
        {
            int counts = 0;
            while ((isConnected == 0) & (counts < maxcount))
            {
                if (gn == "GNP")
                {
                    double edgeprob = atof(argv[7]);
                    if ((edgeprob > 1) || (edgeprob < 0))
                    {
                        cout << "probabilities larger than 1 or smaller than 0 ...aborting..." << endl;
                        return -1;
                    }
                    igraph_erdos_renyi_game(&graph, IGRAPH_ERDOS_RENYI_GNP,
                                            popSize, edgeprob,
                                            false, false);
                }
                else if (gn == "GNM")
                {
                    int edgenumber = atoi(argv[7]);
                    if ((edgenumber < 1) || (edgenumber > popSize*(popSize-1)/2))
                    {
                        cout << "number of edges must be greater than 1 and smaller than N*(N-1)/2 ...aborting..." << endl;
                        return -1;
                    }
                    igraph_erdos_renyi_game(&graph, IGRAPH_ERDOS_RENYI_GNM,
                                            popSize, edgenumber,
                                            false, false);
                }
                else
                {
                    cout << "Only \"GNM\" and \"GNP\" possible ... aborting..." << endl;
                }
                igraph_is_connected(&graph, &isConnected, IGRAPH_STRONG);
                counts++;
            }
            if (counts == maxcount)
            {
                cout << "Probability or number of edges too low... Did not find a connected graph after "<< maxcount <<" attempts... aborting..." << endl;
                return -1;
            }
        }
        else
        {
            cout << "Only \"directed\" and \"undirected\" possible for direction of graph!... aborting..." << endl;
            return -1;
        }
    }

//---------------------------- Code snippet for small world network --------------------------------//
    else if (category == "WS")
    {
        igraph_rng_seed(igraph_rng_default(), std::clock());
        igraph_bool_t isConnected = 0;

        double edgeprob = atof(argv[7]);
        if ((edgeprob > 1) || (edgeprob < 0))
        {
            cout << "probabilities larger than 1 or smaller than 0 ...aborting..." << endl;
            return -1;
        }

        int dim = atoi(argv[6]);
        int latSize = pow(popSize,1/double(dim));

        if (direction == "directed")
        {
            while ((isConnected == 0) & (counts < maxcount))
            {
                igraph_watts_strogatz_game(&graph, dim,
                                           latSize, 1,
                                           edgeprob, 0,
                                           0);
                igraph_is_connected(&graph, &isConnected, IGRAPH_STRONG);
                counts++;
            }
        }
        else if (direction == "undirected")
        {
            while ((isConnected == 0) & (counts < maxcount))
            {
                igraph_watts_strogatz_game(&graph, dim,
                                           latSize, 1,
                                           edgeprob, 0,
                                           0);
                igraph_is_connected(&graph, &isConnected, IGRAPH_STRONG);
                counts++;
            }
        }
        else
        {
            cout << "Only \"directed\" and \"undirected\" possible for direction of graph!... aborting..." << endl;
            return -1;
        }
        if (counts == maxcount)
        {
            cout << "Did not find a connected graph after "<< maxcount <<" attempts... aborting..." << endl;
            return -1;
        }
    }

//---------------------------- Code snippet for geometric generator --------------------------------//
    else if(category == "geo")
    {
        igraph_rng_seed(igraph_rng_default(), std::clock());
        igraph_bool_t isConnected = 0;
        double edgeprob = atof(argv[7]);
        if ((edgeprob > 1) || (edgeprob < 0))
        {
            cout << "probabilities larger than 1 or smaller than 0 ...aborting..." << endl;
            return -1;
        }
        bool torus = (atoi(argv[6]) == 1);
        double radius = sqrt(edgeprob/3.14);
        if (direction == "directed")
        {
            while ((isConnected == 0) & (counts < maxcount))
            {
                igraph_grg_game(&graph, popSize,
                                radius, torus,
                                0, 0);
                igraph_is_connected(&graph, &isConnected, IGRAPH_STRONG);
                counts++;
            }
        }
        else if (direction == "undirected")
        {
            while ((isConnected == 0) & (counts < maxcount))
            {
                igraph_grg_game(&graph, popSize,
                                radius, torus,
                                0, 0);
                igraph_is_connected(&graph, &isConnected, IGRAPH_STRONG);
                counts++;
            }
        }
        else
        {
            cout << "Only \"directed\" and \"undirected\" possible for direction of graph!... aborting..." << endl;
            return -1;
        }
        if (counts == maxcount)
        {
            cout << "Probability or number of edges too low... Did not find a connected graph after "<< maxcount <<" attempts... aborting..." << endl;
            return -1;
        }
    }
//---------------------------- Code snippet for barabasi generator --------------------------------//
    else if(category == "BB")
    {
        double power = atof(argv[6]);
        int m = atoi(argv[7]);

        igraph_rng_seed(igraph_rng_default(), std::clock());
        igraph_bool_t isConnected = 0;
        if (direction == "directed")
        {
            cout << "directed Barabasi-Albert never creates connected graphs, use undirected instead! aborting..." << endl;
            return -1;

        }
        else if (direction == "undirected")
        {
            while ((isConnected == 0) & (counts < maxcount))
            {
                igraph_barabasi_game(&graph, popSize,
                                     power,
                                     m,
                                     0,
                                     0,
                                     1.0,
                                     false,
                                     IGRAPH_BARABASI_PSUMTREE,
                                     0);
                igraph_is_connected(&graph, &isConnected, IGRAPH_STRONG);
                counts++;
            }
        }
        else
        {
            cout << "Only \"directed\" and \"undirected\" possible for direction of graph!... aborting..." << endl;
            return -1;
        }
        if (counts == maxcount)
        {
            cout << "Did not find a connected graph after "<< maxcount <<" attempts... aborting..." << endl;
            return -1;
        }
    }
    // ----------   Code snippet for custom graph   ----------
    else if(category == "custom")
    {
        std::string admats = argv[6];
        if (admats.size() != popSize*popSize)
        {
            cout << "adjacency matrix has the wrong size... aborting..." << endl;
            return -1;
        }
        std::vector<int> ints;
        std::transform(std::begin(admats), std::end(admats), std::back_inserter(ints),
                       [](char c)
        {
            return c - '0';
        }
                      );
        std::copy(ints.begin(), ints.end(), admat);
    }

    else
    {
        cout << "Only \"complete\", \"ER\", \"BB\", \"WS\", or \"geo\" as categories... aborting..." << endl;
        return -1;
    }


    // ----------   Here the adjacency matrix gets copied into an array  ----------

    if(category!="custom")
    {
        igraph_matrix_t admatv;
        igraph_matrix_init(&admatv, 0,0);
        igraph_get_adjacency( &graph, &admatv,IGRAPH_GET_ADJACENCY_BOTH,false);
        for(unsigned int i = 0 ; i < popSize ; i++)
        {
            for(unsigned int k = 0 ; k < popSize ; k++)
            {
                admat[ i*popSize + k] = MATRIX(admatv,i,k );
            }
        }

        igraph_destroy(&graph);
        igraph_matrix_destroy(&admatv);
    }
    for (unsigned int i=0; i<popSize; i++) {

        for (unsigned int j=0; j<popSize; j++) {
            // If you want to print the adjacency matrix:
            cout<<admat[i * popSize + j]<<" ";
        }
    }
    cout<<endl;
    t_vectorFP data;
    t_vectorInt row;
    t_vectorInt col;
    data.reserve(popSize * numStates);
    row.reserve(popSize * numStates);
    col.reserve(popSize * numStates);

    //CLOCK//
    start = std::clock();
    createTransitionMatrix(popSize, numStates, fitnessMutants, update, admat, data, row, col);


    std::vector<T> tripletList;
    tripletList.reserve(popSize * numStates);

    for( unsigned int j = 0 ; j < data.size() ; j++)
    {
        tripletList.push_back(T(col.at(j),row.at(j),data.at(j)));
    }

    SpMat mat(numStates,numStates);
    mat.setFromTriplets(tripletList.begin(), tripletList.end());

    // Stopping time after creating transition matrix
    //CLOCK//
    bt = ( std::clock() - start ) / (double) CLOCKS_PER_SEC;

    //for (int i = 0; i<data.size(); i++)
    //    cout<<"unconditional: transition prob from state "<<row[i]<<" to state "<<col[i]<<" is "<<data[i]<<endl;
    string s1;



    /*   ----------   No distinguishing between "probability", "unconditional" time, and "conditional" time   ----------    */

    float * fixProbAllStates = static_cast<float*> (malloc(numStates * sizeof(float)));
    fixProb(mat, popSize, numStates, fixProbAllStates);

    // Stopping time after solving fixation probabilities
    //CLOCK//
    st = ( std::clock() - start) / (double) CLOCKS_PER_SEC - bt;

    float probOne = 0.0;
    for(unsigned int i = 0; i < popSize; i++)
    {
        int j = 1 << i;

        probOne = probOne + fixProbAllStates[j];

    }
    probOne = probOne / (float)(popSize);

    cout << "fixation probability:" << probOne << endl;
    /*   ----------   Printing the fixation probability starting from all states   ----------    */
    /*
    for(unsigned int i = 0; i < numStates; i++)
    {
        bitset<23> b1(i);
        s1 =  b1.to_string();
        cout<<"fixation probability in state ";
        cout<< s1.substr(23-popSize,popSize);
        cout <<" is "<<fixProbAllStates[i]<<endl;
    }
    */
    if((output == "unconditional")||(output == "all"))
    {
        float * uncondFixTimeAllStates = static_cast<float*> (malloc(numStates * sizeof(float)));
        // Stopping the time for solving for unconditional fixation time
        //CLOCK// start = std::clock();
        //CLOCK// bt = ( std::clock() - start ) / (double) CLOCKS_PER_SEC;
        time(mat, popSize, numStates, uncondFixTimeAllStates);
        //CLOCK//

        float avUncondTime = 0.0;
        for(unsigned int i = 0 ; i < popSize ; i++)
        {
            int j = 1 << i;
            avUncondTime = avUncondTime + uncondFixTimeAllStates[j];
        }
        avUncondTime = avUncondTime / (float)(popSize);

        free(uncondFixTimeAllStates);

        cout<< "unconditional fixation time:" << avUncondTime << endl;
    }
    /*   ----------   Printing the average unconditional fixation time starting from all states   ----------    */

    //for(unsigned int i = 0; i < numStates; i++)
    //{
    //    bitset<23> b1(i);
    //    s1 =  b1.to_string();
    //cout<<"Unconditional fixation time in state ";
    //cout<< s1.substr (23-popSize,popSize);
    //cout <<" is "<<uncondFixTimeAllStates[i]<<endl;
    //}

    //float * fixProbAllStates = (float*) malloc(numStates * sizeof(float));
    //fixProb(mat, popSize, numStates, fixProbAllStates);
    if((output == "conditional")||(output == "all"))
    {
        createConditionalTransitionMatrix(popSize, numStates, fixProbAllStates, data, row, col);

        std::vector<T> tripletListCond;
        tripletListCond.reserve(popSize * numStates);

        for( unsigned int j = 0 ; j < data.size() ; j++)
        {
            tripletListCond.push_back(T(col.at(j),row.at(j),data.at(j)));
        }

        SpMat conditionalMatrix(numStates,numStates);
        conditionalMatrix.setFromTriplets(tripletListCond.begin(), tripletListCond.end());


        float * condFixTimeAllStates = static_cast<float*> (malloc(numStates * sizeof(float)));
        time(conditionalMatrix, popSize, numStates, condFixTimeAllStates);


        float avCondTime = 0.0;
        for(unsigned int i = 0 ; i < popSize ; i++)
        {
            int j = 1 << i;
            avCondTime = avCondTime + condFixTimeAllStates[j];
        }
        avCondTime = avCondTime / (float)(popSize);

        free(condFixTimeAllStates);
        cout << "conditional fixation time:" << avCondTime << endl;
    }

    free(fixProbAllStates);
    /*   ----------   Printing the average conditional fixation time starting from all states   ----------    */

    //for(unsigned int i = 0; i < numStates; i++)
    //{
    //bitset<23> b1(i);
    //s1 =  b1.to_string();
    //cout<<"Conditional fixation time in state ";
    //cout<< s1.substr (23-popSize,popSize);
    //cout <<" is "<<condFixTimeAllStates[i]<<endl;
    //}

    st = ( std::clock() - start) / (double) CLOCKS_PER_SEC - bt;
    //CLOCK//
    cout<<"building time: "<< bt <<'\n';
    //CLOCK//
    cout<<"solving time: "<< st << "\n\n";

}
Exemple #9
0
bool Graph::isConnected() {
  igraph_bool_t res;
  igraph_is_connected(graph, &res, IGRAPH_STRONG);
  return bool(res);
}
Exemple #10
0
int igraph_layout_fruchterman_reingold_3d(const igraph_t *graph, 
					  igraph_matrix_t *res,
					  igraph_bool_t use_seed,
					  igraph_integer_t niter,
					  igraph_real_t start_temp,
					  const igraph_vector_t *weight, 
					  const igraph_vector_t *minx,
					  const igraph_vector_t *maxx,
					  const igraph_vector_t *miny,
					  const igraph_vector_t *maxy,
					  const igraph_vector_t *minz,
					  const igraph_vector_t *maxz) {

  igraph_integer_t no_nodes=igraph_vcount(graph);
  igraph_integer_t no_edges=igraph_ecount(graph);
  igraph_integer_t i;
  igraph_vector_float_t dispx, dispy, dispz;
  igraph_real_t temp=start_temp;
  igraph_real_t difftemp=start_temp / niter;
  float width=sqrtf(no_nodes), height=width, depth=width;
  igraph_bool_t conn=1;
  float C;

  if (niter < 0) {
    IGRAPH_ERROR("Number of iterations must be non-negative in "
		 "Fruchterman-Reingold layout", IGRAPH_EINVAL);
  }

  if (use_seed && (igraph_matrix_nrow(res) != no_nodes ||
		   igraph_matrix_ncol(res) != 3)) {
    IGRAPH_ERROR("Invalid start position matrix size in "
		 "Fruchterman-Reingold layout", IGRAPH_EINVAL);
  }

  if (weight && igraph_vector_size(weight) != igraph_ecount(graph)) {
    IGRAPH_ERROR("Invalid weight vector length", IGRAPH_EINVAL);
  }

  if (minx && igraph_vector_size(minx) != no_nodes) {
    IGRAPH_ERROR("Invalid minx vector length", IGRAPH_EINVAL);
  }
  if (maxx && igraph_vector_size(maxx) != no_nodes) {
    IGRAPH_ERROR("Invalid maxx vector length", IGRAPH_EINVAL);
  }
  if (minx && maxx && !igraph_vector_all_le(minx, maxx)) {
    IGRAPH_ERROR("minx must not be greater than maxx", IGRAPH_EINVAL);
  }
  if (miny && igraph_vector_size(miny) != no_nodes) {
    IGRAPH_ERROR("Invalid miny vector length", IGRAPH_EINVAL);
  }
  if (maxy && igraph_vector_size(maxy) != no_nodes) {
    IGRAPH_ERROR("Invalid maxy vector length", IGRAPH_EINVAL);
  }
  if (miny && maxy && !igraph_vector_all_le(miny, maxy)) {
    IGRAPH_ERROR("miny must not be greater than maxy", IGRAPH_EINVAL);
  }
  if (minz && igraph_vector_size(minz) != no_nodes) {
    IGRAPH_ERROR("Invalid minz vector length", IGRAPH_EINVAL);
  }
  if (maxz && igraph_vector_size(maxz) != no_nodes) {
    IGRAPH_ERROR("Invalid maxz vector length", IGRAPH_EINVAL);
  }
  if (minz && maxz && !igraph_vector_all_le(minz, maxz)) {
    IGRAPH_ERROR("minz must not be greater than maxz", IGRAPH_EINVAL);
  }

  igraph_is_connected(graph, &conn, IGRAPH_WEAK);
  if (!conn) { C = no_nodes * sqrtf(no_nodes); }

  RNG_BEGIN();

  if (!use_seed) {
    IGRAPH_CHECK(igraph_matrix_resize(res, no_nodes, 3));
    for (i=0; i<no_nodes; i++) {
      igraph_real_t x1=minx ? VECTOR(*minx)[i] : -width/2;
      igraph_real_t x2=maxx ? VECTOR(*maxx)[i] :  width/2;
      igraph_real_t y1=miny ? VECTOR(*miny)[i] : -height/2;
      igraph_real_t y2=maxy ? VECTOR(*maxy)[i] :  height/2;
      igraph_real_t z1=minz ? VECTOR(*minz)[i] : -depth/2;
      igraph_real_t z2=maxz ? VECTOR(*maxz)[i] :  depth/2;
      MATRIX(*res, i, 0) = RNG_UNIF(x1, x2);
      MATRIX(*res, i, 1) = RNG_UNIF(y1, y2);
      MATRIX(*res, i, 2) = RNG_UNIF(z1, z2);
    }
  }

  IGRAPH_CHECK(igraph_vector_float_init(&dispx, no_nodes));
  IGRAPH_FINALLY(igraph_vector_float_destroy, &dispx);
  IGRAPH_CHECK(igraph_vector_float_init(&dispy, no_nodes));
  IGRAPH_FINALLY(igraph_vector_float_destroy, &dispy);
  IGRAPH_CHECK(igraph_vector_float_init(&dispz, no_nodes));
  IGRAPH_FINALLY(igraph_vector_float_destroy, &dispz);

  for (i=0; i<niter; i++) {
    igraph_integer_t v, u, e;
    
    /* calculate repulsive forces, we have a special version
       for unconnected graphs */
    igraph_vector_float_null(&dispx);
    igraph_vector_float_null(&dispy);
    igraph_vector_float_null(&dispz);
    if (conn) {
      for (v=0; v<no_nodes; v++) {
	for (u=v+1; u<no_nodes; u++) {
	  float dx=MATRIX(*res, v, 0) - MATRIX(*res, u, 0);
	  float dy=MATRIX(*res, v, 1) - MATRIX(*res, u, 1);
	  float dz=MATRIX(*res, v, 2) - MATRIX(*res, u, 2);
	  float dlen=dx * dx + dy * dy + dz * dz;

          if (dlen == 0) {
            dx = RNG_UNIF01() * 1e-9;
            dy = RNG_UNIF01() * 1e-9;
            dz = RNG_UNIF01() * 1e-9;
            dlen = dx * dx + dy * dy + dz * dz;
          }

	  VECTOR(dispx)[v] += dx/dlen;
	  VECTOR(dispy)[v] += dy/dlen;
	  VECTOR(dispz)[v] += dz/dlen;
	  VECTOR(dispx)[u] -= dx/dlen;
	  VECTOR(dispy)[u] -= dy/dlen;
	  VECTOR(dispz)[u] -= dz/dlen;
	}
      }
    } else {
      for (v=0; v<no_nodes; v++) {
	for (u=v+1; u<no_nodes; u++) {
	  float dx=MATRIX(*res, v, 0) - MATRIX(*res, u, 0);
	  float dy=MATRIX(*res, v, 1) - MATRIX(*res, u, 1);
	  float dz=MATRIX(*res, v, 2) - MATRIX(*res, u, 2);
	  float dlen, rdlen;

	  dlen=dx * dx + dy * dy + dz * dz;
          if (dlen == 0) {
            dx = RNG_UNIF01() * 1e-9;
            dy = RNG_UNIF01() * 1e-9;
            dz = RNG_UNIF01() * 1e-9;
            dlen = dx * dx + dy * dy + dz * dz;
          }

	  rdlen=sqrt(dlen);

	  VECTOR(dispx)[v] += dx * (C-dlen * rdlen) / (dlen*C);
	  VECTOR(dispy)[v] += dy * (C-dlen * rdlen) / (dlen*C);
	  VECTOR(dispy)[v] += dz * (C-dlen * rdlen) / (dlen*C);
	  VECTOR(dispx)[u] -= dx * (C-dlen * rdlen) / (dlen*C);
	  VECTOR(dispy)[u] -= dy * (C-dlen * rdlen) / (dlen*C);
	  VECTOR(dispz)[u] -= dz * (C-dlen * rdlen) / (dlen*C);
	}
      }
    }

    /* calculate attractive forces */
    for (e=0; e<no_edges; e++) {
      /* each edges is an ordered pair of vertices v and u */
      igraph_integer_t v=IGRAPH_FROM(graph, e);
      igraph_integer_t u=IGRAPH_TO(graph, e);
      igraph_real_t dx=MATRIX(*res, v, 0) - MATRIX(*res, u, 0);
      igraph_real_t dy=MATRIX(*res, v, 1) - MATRIX(*res, u, 1);
      igraph_real_t dz=MATRIX(*res, v, 2) - MATRIX(*res, u, 2);
      igraph_real_t w=weight ? VECTOR(*weight)[e] : 1.0;
      igraph_real_t dlen=sqrt(dx * dx + dy * dy + dz * dz) * w;
      VECTOR(dispx)[v] -= (dx * dlen);
      VECTOR(dispy)[v] -= (dy * dlen);
      VECTOR(dispz)[v] -= (dz * dlen);
      VECTOR(dispx)[u] += (dx * dlen);
      VECTOR(dispy)[u] += (dy * dlen);
      VECTOR(dispz)[u] += (dz * dlen);
    }
    
    /* limit max displacement to temperature t and prevent from
       displacement outside frame */
    for (v=0; v<no_nodes; v++) {
      igraph_real_t dx=VECTOR(dispx)[v] + RNG_UNIF01() * 1e-9;
      igraph_real_t dy=VECTOR(dispy)[v] + RNG_UNIF01() * 1e-9;
      igraph_real_t dz=VECTOR(dispz)[v] + RNG_UNIF01() * 1e-9;
      igraph_real_t displen=sqrt(dx * dx + dy * dy + dz * dz);
      igraph_real_t mx=fabs(dx) < temp ? dx : temp;
      igraph_real_t my=fabs(dy) < temp ? dy : temp;
      igraph_real_t mz=fabs(dz) < temp ? dz : temp;
      if (displen > 0) {
        MATRIX(*res, v, 0) += (dx / displen) * mx;
        MATRIX(*res, v, 1) += (dy / displen) * my;
        MATRIX(*res, v, 2) += (dz / displen) * mz;
      }
      if (minx && MATRIX(*res, v, 0) < VECTOR(*minx)[v]) { 
	MATRIX(*res, v, 0) = VECTOR(*minx)[v]; 
      }
      if (maxx && MATRIX(*res, v, 0) > VECTOR(*maxx)[v]) {
	MATRIX(*res, v, 0) = VECTOR(*maxx)[v];
      }
      if (miny && MATRIX(*res, v, 1) < VECTOR(*miny)[v]) {
	MATRIX(*res, v, 1) = VECTOR(*miny)[v];
      }
      if (maxy && MATRIX(*res, v, 1) > VECTOR(*maxy)[v]) {
	MATRIX(*res, v, 1) = VECTOR(*maxy)[v];
      }
      if (minz && MATRIX(*res, v, 2) < VECTOR(*minz)[v]) {
	MATRIX(*res, v, 2) = VECTOR(*minz)[v];
      }
      if (maxz && MATRIX(*res, v, 2) > VECTOR(*maxz)[v]) {
	MATRIX(*res, v, 2) = VECTOR(*maxz)[v];
      }
    }

    temp -= difftemp;
  }

  RNG_END();

  igraph_vector_float_destroy(&dispx);
  igraph_vector_float_destroy(&dispy);
  igraph_vector_float_destroy(&dispz);
  IGRAPH_FINALLY_CLEAN(3);
  
  return 0;
}
Exemple #11
0
int igraph_layout_i_fr(const igraph_t *graph,
		       igraph_matrix_t *res,
		       igraph_bool_t use_seed,
		       igraph_integer_t niter,
		       igraph_real_t start_temp,
		       const igraph_vector_t *weight,
		       const igraph_vector_t *minx,
		       const igraph_vector_t *maxx,
		       const igraph_vector_t *miny,
		       const igraph_vector_t *maxy) {

  igraph_integer_t no_nodes=igraph_vcount(graph);
  igraph_integer_t no_edges=igraph_ecount(graph);
  igraph_integer_t i;
  igraph_vector_float_t dispx, dispy;
  igraph_real_t temp=start_temp;
  igraph_real_t difftemp=start_temp / niter;
  float width=sqrtf(no_nodes), height=width;
  igraph_bool_t conn=1;
  float C;

  igraph_is_connected(graph, &conn, IGRAPH_WEAK);
  if (!conn) { C = no_nodes * sqrtf(no_nodes); }

  RNG_BEGIN();

  if (!use_seed) {
    IGRAPH_CHECK(igraph_matrix_resize(res, no_nodes, 2));
    for (i=0; i<no_nodes; i++) {
      igraph_real_t x1=minx ? VECTOR(*minx)[i] : -width/2;
      igraph_real_t x2=maxx ? VECTOR(*maxx)[i] :  width/2;
      igraph_real_t y1=miny ? VECTOR(*miny)[i] : -height/2;
      igraph_real_t y2=maxy ? VECTOR(*maxy)[i] :  height/2;
      if (!igraph_finite(x1)) { x1 = -sqrt(no_nodes)/2; }
      if (!igraph_finite(x2)) { x2 =  sqrt(no_nodes)/2; }
      if (!igraph_finite(y1)) { y1 = -sqrt(no_nodes)/2; }
      if (!igraph_finite(y2)) { y2 =  sqrt(no_nodes)/2; }
      MATRIX(*res, i, 0) = RNG_UNIF(x1, x2);
      MATRIX(*res, i, 1) = RNG_UNIF(y1, y2);
    }
  }

  IGRAPH_CHECK(igraph_vector_float_init(&dispx, no_nodes));
  IGRAPH_FINALLY(igraph_vector_float_destroy, &dispx);
  IGRAPH_CHECK(igraph_vector_float_init(&dispy, no_nodes));
  IGRAPH_FINALLY(igraph_vector_float_destroy, &dispy);

  for (i=0; i<niter; i++) {
    igraph_integer_t v, u, e;

    /* calculate repulsive forces, we have a special version
       for unconnected graphs */
    igraph_vector_float_null(&dispx);
    igraph_vector_float_null(&dispy);
    if (conn) {
      for (v=0; v<no_nodes; v++) {
	for (u=v+1; u<no_nodes; u++) {
	  float dx=MATRIX(*res, v, 0) - MATRIX(*res, u, 0);
	  float dy=MATRIX(*res, v, 1) - MATRIX(*res, u, 1);
	  float dlen=dx * dx + dy * dy;

          if (dlen == 0) {
            dx = RNG_UNIF01() * 1e-9;
            dy = RNG_UNIF01() * 1e-9;
            dlen = dx * dx + dy * dy;
          }

	  VECTOR(dispx)[v] += dx/dlen;
	  VECTOR(dispy)[v] += dy/dlen;
	  VECTOR(dispx)[u] -= dx/dlen;
	  VECTOR(dispy)[u] -= dy/dlen;
	}
      }
    } else {
      for (v=0; v<no_nodes; v++) {
	for (u=v+1; u<no_nodes; u++) {
	  float dx=MATRIX(*res, v, 0) - MATRIX(*res, u, 0);
	  float dy=MATRIX(*res, v, 1) - MATRIX(*res, u, 1);
	  float dlen, rdlen;

	  dlen=dx * dx + dy * dy;
          if (dlen == 0) {
            dx = RNG_UNIF(0, 1e-6);
            dy = RNG_UNIF(0, 1e-6);
            dlen = dx * dx + dy * dy;
          }

	  rdlen=sqrt(dlen);

	  VECTOR(dispx)[v] += dx * (C-dlen * rdlen) / (dlen*C);
	  VECTOR(dispy)[v] += dy * (C-dlen * rdlen) / (dlen*C);
	  VECTOR(dispx)[u] -= dx * (C-dlen * rdlen) / (dlen*C);
	  VECTOR(dispy)[u] -= dy * (C-dlen * rdlen) / (dlen*C);
	}
      }
    }

    /* calculate attractive forces */
    for (e=0; e<no_edges; e++) {
      /* each edges is an ordered pair of vertices v and u */
      igraph_integer_t v=IGRAPH_FROM(graph, e);
      igraph_integer_t u=IGRAPH_TO(graph, e);
      igraph_real_t dx=MATRIX(*res, v, 0) - MATRIX(*res, u, 0);
      igraph_real_t dy=MATRIX(*res, v, 1) - MATRIX(*res, u, 1);
      igraph_real_t w=weight ? VECTOR(*weight)[e] : 1.0;
      igraph_real_t dlen=sqrt(dx * dx + dy * dy) * w;
      VECTOR(dispx)[v] -= (dx * dlen);
      VECTOR(dispy)[v] -= (dy * dlen);
      VECTOR(dispx)[u] += (dx * dlen);
      VECTOR(dispy)[u] += (dy * dlen);
    }

    /* limit max displacement to temperature t and prevent from
       displacement outside frame */
    for (v=0; v<no_nodes; v++) {
      igraph_real_t dx=VECTOR(dispx)[v] + RNG_UNIF01() * 1e-9;
      igraph_real_t dy=VECTOR(dispy)[v] + RNG_UNIF01() * 1e-9;
      igraph_real_t displen=sqrt(dx * dx + dy * dy);
      igraph_real_t mx=fabs(dx) < temp ? dx : temp;
      igraph_real_t my=fabs(dy) < temp ? dy : temp;
      if (displen > 0) {
        MATRIX(*res, v, 0) += (dx / displen) * mx;
        MATRIX(*res, v, 1) += (dy / displen) * my;
      }
      if (minx && MATRIX(*res, v, 0) < VECTOR(*minx)[v]) {
	MATRIX(*res, v, 0) = VECTOR(*minx)[v];
      }
      if (maxx && MATRIX(*res, v, 0) > VECTOR(*maxx)[v]) {
	MATRIX(*res, v, 0) = VECTOR(*maxx)[v];
      }
      if (miny && MATRIX(*res, v, 1) < VECTOR(*miny)[v]) {
	MATRIX(*res, v, 1) = VECTOR(*miny)[v];
      }
      if (maxy && MATRIX(*res, v, 1) > VECTOR(*maxy)[v]) {
	MATRIX(*res, v, 1) = VECTOR(*maxy)[v];
      }
    }

    temp -= difftemp;
  }

  RNG_END();

  igraph_vector_float_destroy(&dispx);
  igraph_vector_float_destroy(&dispy);
  IGRAPH_FINALLY_CLEAN(2);
  
  return 0;
}
int main() {
  igraph_t g;
  igraph_vector_t tdist;
  igraph_matrix_t pmat;
  igraph_bool_t conn;
  igraph_vector_bool_t bs;
  int i, ret;
  
  /* Symmetric preference game */
  igraph_vector_bool_init(&bs, 0);

  igraph_vector_init_real(&tdist, 3, 1.0, 1.0, 1.0);

  igraph_matrix_init(&pmat, 3, 3);
  for (i=0; i<3; i++) MATRIX(pmat, i, i) = 0.2;

  /* undirected, no loops */
  IGRAPH_CHECK(igraph_preference_game(&g, 1000, 3, &tdist, /*fixed_sizes=*/ 0,
				      &pmat, 0, 0, 0));
  if (igraph_vcount(&g) != 1000) return 18;
  if (igraph_is_directed(&g)) return 2;
  igraph_is_connected(&g, &conn, IGRAPH_STRONG);
  if (conn) return 3;
  igraph_is_loop(&g, &bs, igraph_ess_all(IGRAPH_EDGEORDER_ID));
  if (igraph_vector_bool_sum(&bs)) return 4;
  igraph_is_multiple(&g, &bs, igraph_ess_all(IGRAPH_EDGEORDER_ID));
  if (igraph_vector_bool_sum(&bs)) return 5;
  igraph_destroy(&g);

  for (i=0; i<2; i++) MATRIX(pmat, i, i+1) = 0.1;

  /* directed, no loops */
  IGRAPH_CHECK(igraph_preference_game(&g, 1000, 3, &tdist, /*fixed_sizes=*/0, 
				      &pmat, 0, 1, 0));
  if (igraph_vcount(&g) != 1000) return 17;
  if (!igraph_is_directed(&g)) return 6;
  igraph_is_loop(&g, &bs, igraph_ess_all(IGRAPH_EDGEORDER_ID));
  if (igraph_vector_bool_sum(&bs)) return 7;
  igraph_is_multiple(&g, &bs, igraph_ess_all(IGRAPH_EDGEORDER_ID));
  if (igraph_vector_bool_sum(&bs)) return 8;
  igraph_destroy(&g);

  /* undirected, loops */
  for (i=0; i<3; i++) MATRIX(pmat, i, i) = 1.0;
  IGRAPH_CHECK(igraph_preference_game(&g, 100, 3, &tdist, /*fixed_sizes=*/ 0,
				      &pmat, 0, 0, 1));
  if (igraph_vcount(&g) != 100) return 16;
  if (igraph_ecount(&g) < 1395) return 20;
  if (igraph_is_directed(&g)) return 9;
  igraph_is_loop(&g, &bs, igraph_ess_all(IGRAPH_EDGEORDER_ID));
  if (igraph_vector_bool_sum(&bs) == 0) return 10;
  igraph_is_multiple(&g, &bs, igraph_ess_all(IGRAPH_EDGEORDER_ID));
  if (igraph_vector_bool_sum(&bs)) return 11;
  igraph_destroy(&g);

  /* directed, loops */
  IGRAPH_CHECK(igraph_preference_game(&g, 100, 3, &tdist, /*fixed_sizes=*/ 0,
				      &pmat, 0, 1, 1));
  if (igraph_vcount(&g) != 100) return 15;
  if (igraph_ecount(&g) < 2700) return 19;
  if (!igraph_is_directed(&g)) return 12;
  igraph_is_loop(&g, &bs, igraph_ess_all(IGRAPH_EDGEORDER_ID));
  if (igraph_vector_bool_sum(&bs) == 0) return 13;
  igraph_is_multiple(&g, &bs, igraph_ess_all(IGRAPH_EDGEORDER_ID));
  if (igraph_vector_bool_sum(&bs)) return 14;
  igraph_destroy(&g);

  /* Asymmetric preference game */

  /* directed, no loops */
  igraph_matrix_resize(&pmat, 2, 2);
  MATRIX(pmat, 0, 0) = 1; MATRIX(pmat, 0, 1) = 1;
  MATRIX(pmat, 1, 0) = 1; MATRIX(pmat, 1, 1) = 1;
  IGRAPH_CHECK(igraph_asymmetric_preference_game(&g, 100, 2, 0, &pmat, 0, 0, 0));
  if (igraph_vcount(&g) != 100) return 21;
  if (igraph_ecount(&g) != 9900) return 22;
  if (!igraph_is_directed(&g)) return 23;
  igraph_is_loop(&g, &bs, igraph_ess_all(IGRAPH_EDGEORDER_ID));
  if (igraph_vector_bool_sum(&bs)) return 24;
  igraph_is_multiple(&g, &bs, igraph_ess_all(IGRAPH_EDGEORDER_ID));
  if (igraph_vector_bool_sum(&bs)) return 25;
  igraph_destroy(&g);

  /* directed, loops */
  igraph_matrix_resize(&pmat, 2, 2);
  MATRIX(pmat, 0, 0) = 1; MATRIX(pmat, 0, 1) = 1;
  MATRIX(pmat, 1, 0) = 1; MATRIX(pmat, 1, 1) = 1;
  IGRAPH_CHECK(igraph_asymmetric_preference_game(&g, 100, 2, 0, &pmat, 0, 0, 1));
  if (igraph_vcount(&g) != 100) return 26;
  if (igraph_ecount(&g) != 10000) return 27;
  if (!igraph_is_directed(&g)) return 28;
  igraph_is_loop(&g, &bs, igraph_ess_all(IGRAPH_EDGEORDER_ID));
  if (igraph_vector_bool_sum(&bs) != 100) return 29;
  igraph_is_multiple(&g, &bs, igraph_ess_all(IGRAPH_EDGEORDER_ID));
  if (igraph_vector_bool_sum(&bs)) return 30;
  igraph_destroy(&g);

  igraph_vector_destroy(&tdist);
  igraph_matrix_destroy(&pmat);
  igraph_vector_bool_destroy(&bs);

  assert(IGRAPH_FINALLY_STACK_EMPTY);

  return 0;
}