Beispiel #1
0
	static void barabasi_game(igraph_t *graph, int population, int param, bool isDirected) {
		vector<double> p (2*param+1, isDirected);
		vector<int> id;
		int i, j, from, to;
		igraph_empty(graph, population, isDirected);
		for (i = 0; i < 2*param+1; i++) {
			for (j = i+1; j < 2*param+1; j++) {
				from = j;
				to = i;
				igraph_add_edge (graph, from, to);
				p[to]++;
				if (!isDirected) p[from]++;
			}
		}
		int k = 0;
		for (i = 0; i < 2*param+1; i++)	k += p[i];
		fprintf (stderr, " awawa %lf\n", k/(double)(2*param+1));
		for (; i < population; i++) {
			Statistic::sample(p, param, id);
			p.push_back(isDirected);
			for (j = 0; j < param; j++) {
				from = i;
				to = id[j];
				igraph_add_edge (graph, from, to);
				p[to]++;
				if (!isDirected)	p[from]++;
			}
		}
		k = 0;
		for (i = 0; i < population; i++)	k += p[i];
	}
Beispiel #2
0
	static void SF2ER (igraph_t *graph, int N, int param, double alpha, bool isDirected) {

		int i, j, k, m;
		igraph_bool_t areconn;
		vector<int> p (N, 0); //quantidade de arestas PA
		int etot = 0, acc;
		igraph_empty(graph, N, isDirected);
		for (i = 0; i < 2*param+1; i++)
			for (j = i+1; j < 2*param+1; j++) {
				igraph_add_edge (graph, i, j);
				p[j]++;
				if (!isDirected)	p[i]++;
				etot += 1+(!isDirected);
			}
		for (; i < N; i++) {			
			for (m = param; m > 0; m--) {
				if (Statistic::unif() < alpha) { //ER
					do {
						j = rand()%(N-1);
						if (j >= i)	j++;
						igraph_are_connected(graph, i, j, &areconn);
						//printf ("er %d\n", (int)areconn);
					} while (areconn == 1);
					igraph_add_edge (graph, i, j);
				} else { //SF
					do {
						k = rand()%(etot-p[i]);
						//printf ("%d %d %d\n", k, etot, p[i]);
						acc = 0;
						for (j = 0; j < N; j++) {
							if (i == j)	continue;
							if (acc+p[j] >= k)	break;
							acc+=p[j];
						}
						igraph_are_connected(graph, i, j, &areconn);
						//printf ("sf %d %d %d\n",k, (int)areconn, etot);
					} while (areconn == 1);
					igraph_add_edge (graph, i, j);
					p[j]++;
					if (!isDirected)	p[i]++;
					etot += 1+(!isDirected);
				}
			}
		}
	}
Beispiel #3
0
void iterate(igraph_t *graph, double th)
{
    igraph_integer_t x, y, z = -1.0, xy;
    
    xy = rand() % (int) igraph_ecount(graph);
    igraph_edge(graph, xy, &x, &y);

    //flip increasing orientation with pr 1/2
    if(rand() % 2)
    {
        igraph_integer_t buffer = y;
        y = x;
        x = buffer;
    }

    igraph_vector_t degrees;
    igraph_vector_init(&degrees, 1); 
    all_degrees(graph, &degrees);


    double d_mean = get_d_mean(graph);
    double random = 1.0 * rand() / RAND_MAX;
    int w;
    double total = 0.0;
    double denom = get_denom(graph, &degrees, th, x, y); 

    for(w = 0; w < igraph_vector_size(&degrees); w++)
    {
        if(w != (int) x && w != (int) y)
        {
            total += f(VECTOR(degrees)[w], d_mean, th) / denom; 

            if(random < total)
            {
                z = (igraph_integer_t) w;
                break;
            }
        }
    }

    igraph_vector_destroy(&degrees);

    if(z > -.5)
    {
        igraph_es_t es;

        igraph_es_1(&es, xy);
        igraph_delete_edges(graph, es);
        igraph_es_destroy(&es);

        igraph_add_edge(graph, x, z);
    } 
}
int GraphRepresentation::buildIGraphTopology() {
    int source_vertex_id, destination_vertex_id;
    igraph_i_set_attribute_table(&igraph_cattribute_table);
    igraph_empty(&igraph, 0, true);
    //cout << "iGraph: number of nodes: " << dm->number_of_nodes << endl;
    //cout << "iGraph: number number_of_connections nodes: " << dm->number_of_connections << endl;
    for (int i = 0; i < dm->network_nodes.size(); i++) {
        NetworkNode *nn = dm->network_nodes[i];
        for (int j = 0; j < nn->connections.size(); j++) {
            NetworkConnection *nc = nn->connections[j];
            map <string, int>::iterator index_it;
            /*find that node - if exists*/
            index_it = reverse_node_index.find(nc->src_label);
            /*check if the source node exists in the reverse index*/
            if (index_it == reverse_node_index.end()) {
                /*it does not exist...add it*/
                source_vertex_id = igraph_vcount(&igraph);
                igraph_add_vertices(&igraph, 1, 0);
                reverse_node_index.insert(pair<string, int>(nc->src_label, source_vertex_id));
                igraph_cattribute_VAS_set(&igraph, "NODEID", source_vertex_id, nc->src_label.c_str());
                //cout << "added node " << nc->src_label << " in the igraph" << endl;
            } else {
                source_vertex_id = (*index_it).second;
            }
            index_it = reverse_node_index.find(nc->dst_label);
            /*check if the destination node exists in the reverse index*/
            if (index_it == reverse_node_index.end()) {
                /*it does not exist...add it*/
                destination_vertex_id = igraph_vcount(&igraph);
                igraph_add_vertices(&igraph, 1, 0);
                reverse_node_index.insert(pair<string, int>(nc->dst_label, destination_vertex_id));
                igraph_cattribute_VAS_set(&igraph, "NODEID", destination_vertex_id, nc->dst_label.c_str());
                //cout << "added node " << nc->dst_label << " in the igraph" << endl;
            } else {
                destination_vertex_id = (*index_it).second;
            }
            /*add an edge in the graph*/
            igraph_add_edge(&igraph, source_vertex_id, destination_vertex_id);
            igraph_cattribute_EAS_set(&igraph, "LID", igraph_ecount(&igraph) - 1, nc->LID.to_string().c_str());
            reverse_edge_index.insert(pair<string, int>(nc->LID.to_string(), igraph_ecount(&igraph) - 1));
        }
    }
    for (int i = 0; i < dm->network_nodes.size(); i++) {
        NetworkNode *nn = dm->network_nodes[i];
        igraph_cattribute_VAS_set(&igraph, "iLID", i, nn->iLid.to_string().c_str());
    }
}
Beispiel #5
0
int main() {
  igraph_t graph;
  igraph_t full, tree;
  igraph_hrg_t hrg;
  igraph_t dendrogram;
  // int i, j;
  // igraph_vector_t neis;

  igraph_rng_seed(igraph_rng_default(), 42);

  // We need attributes
  igraph_i_set_attribute_table(&igraph_cattribute_table);
  
  igraph_full(&full, 10, /*directed=*/ 0, /*loops=*/ 0);
  igraph_tree(&tree, 15, /*children=*/ 2, /*type=*/ IGRAPH_TREE_UNDIRECTED);
  igraph_disjoint_union(&graph, &full, &tree);
  igraph_add_edge(&graph, 0, 10);
  
  igraph_destroy(&full);
  igraph_destroy(&tree);

  // Fit
  igraph_hrg_init(&hrg, igraph_vcount(&graph));
  igraph_hrg_fit(&graph, &hrg, /*start=*/ 0, /*steps=*/ 0);

  // Create a graph from it
  igraph_hrg_dendrogram(&dendrogram, &hrg);

  // Print the tree, with labels
  // igraph_vector_init(&neis, 0);
  // for (i=0; i<igraph_vcount(&graph)-1; i++) {
  //   printf("Vertex # %2i, ", (int) (i+igraph_vcount(&graph)));
  //   igraph_neighbors(&dendrogram, &neis, i+igraph_vcount(&graph), IGRAPH_OUT);
  //   printf("left: # %2i, right: # %2i, ", (int) VECTOR(neis)[0], 
  // 	   (int) VECTOR(neis)[1]);
  //   printf("prob: %6.2g\n", 
  // 	   VAN(&dendrogram, "probability", i+igraph_vcount(&graph)));
  // }
  // igraph_vector_destroy(&neis);

  igraph_destroy(&dendrogram);
  igraph_hrg_destroy(&hrg);
  igraph_destroy(&graph);

  return 0;
}
Beispiel #6
0
igraph_vector_t *ggen_analyze_lowest_single_ancestor(igraph_t *g)
{
	unsigned long i,v,l,vid,r;
	int err = 0;
	igraph_vector_t toposort,itopo;
	igraph_vector_t *lsa;
	igraph_t tree;
	igraph_vs_t vs;
	igraph_vit_t vit;
	lca_metadata md;

	if(g == NULL)
		return NULL;

	err = igraph_vector_init(&toposort,igraph_vcount(g));
	if(err) return NULL;

	err = igraph_topological_sorting(g,&toposort,IGRAPH_OUT);
	if(err) goto d_tp;

	/* build a reverse index of the toposort */
	err = igraph_vector_init(&itopo,igraph_vcount(g));
	if(err) goto d_tp;

	for(i = 0; i < igraph_vcount(g); i++)
	{
		v = VECTOR(toposort)[i];
		VECTOR(itopo)[v] = i;
	}

	err = igraph_empty(&tree,1,IGRAPH_DIRECTED);
	if(err) goto d_i;

	lsa = calloc(1,sizeof(igraph_vector_t*));
	if(lsa == NULL) goto cleanup;

	err = igraph_vector_init(lsa,igraph_vcount(g));
	if(err) goto f_l;

	for(v = 1; v < igraph_vcount(g); v++)
	{
		vid = VECTOR(toposort)[v];

		tree_lca_metadata_init(&tree,&md);
		tree_lca_preprocessing(&tree,0,&md);

		/* iterate over parents of v in g
		 * The lsa of a node is the LCA of all its parents in our
		 * special tree.
		 */
		igraph_vs_adj(&vs, vid, IGRAPH_IN);
		igraph_vit_create(g,vs,&vit);
		l = VECTOR(itopo)[IGRAPH_VIT_GET(vit)];
		IGRAPH_VIT_NEXT(vit);

		for(vit;!IGRAPH_VIT_END(vit); IGRAPH_VIT_NEXT(vit))
		{
			tree_lca_query(&tree,l,VECTOR(itopo)[IGRAPH_VIT_GET(vit)],&r,&md);
			l = r;
		}

		igraph_vit_destroy(&vit);
		igraph_vs_destroy(&vs);
		tree_lca_metadata_free(&tree,&md);

		// update tree
		err = igraph_add_vertices(&tree,1,NULL);
		if(err) goto d_l;

		err = igraph_add_edge(&tree,l,v);
		if(err) goto d_l;

		VECTOR(*lsa)[vid] = VECTOR(toposort)[l];
	}
	goto cleanup;
d_l:
	igraph_vector_destroy(lsa);
f_l:
	free(lsa);
	lsa = NULL;
cleanup:
	igraph_destroy(&tree);
d_i:
	igraph_vector_destroy(&itopo);
d_tp:
	igraph_vector_destroy(&toposort);
	return lsa;
}
Beispiel #7
0
//resiliency function for use later when supporting resiliency inside TE 
void TEgraphMF::updateGraph(string &source, string &destination, string &net, bool update_op){
  igraph_vector_t v;
  igraph_es_t es;
  igraph_vector_t eids;
  int src_v = (*reverse_node_index.find(source)).second;
  int dst_v = (*reverse_node_index.find(destination)).second;
  string pairs[2];
  pairs[0]=source + "/" + destination;
  pairs[1]=destination + "/" + source;
     if(net != "e"){
      igraph_vector_init(&v, 2);
      igraph_vector_init(&eids,1);
      VECTOR(v)[0]=src_v;
      VECTOR(v)[1]=dst_v;
    } else {
      igraph_vector_init(&v, 4);
      igraph_vector_init(&eids,2);
      VECTOR(v)[0]=src_v;
      VECTOR(v)[1]=dst_v;
      VECTOR(v)[2]=dst_v;
      VECTOR(v)[3]=src_v;
    }
    if(update_op){
      if(rmv_edge_lid.find(pairs[0]) != rmv_edge_lid.end()){
	igraph_add_edge(&graph, src_v, dst_v);
	Bitvector *lid=new Bitvector();
	lid = (*rmv_edge_lid.find(pairs[0])).second;
	igraph_cattribute_EAS_set(&graph, "LID", igraph_ecount(&graph) - 1, lid->to_string().c_str());
	rmv_edge_lid.erase(pairs[0]);
	if((net=="e")&&(rmv_edge_lid.find(pairs[1]) != rmv_edge_lid.end())){
	  igraph_add_edge(&graph,dst_v , src_v);
	  Bitvector *lid=new Bitvector();
	  lid = (*rmv_edge_lid.find(pairs[1])).second;
	  igraph_cattribute_EAS_set(&graph, "LID", igraph_ecount(&graph) - 1, lid->to_string().c_str());
	  rmv_edge_lid.erase(pairs[1]);
	}
	cout<<"TM: Link Recovery: " << source << " - " << destination <<endl;
      }
    }else {
      if(net =="e"){
      if ((rmv_edge_lid.find(pairs[0]) != rmv_edge_lid.end()) || (rmv_edge_lid.find(pairs[1]) != rmv_edge_lid.end())){
	cout << "TM: Reported Edges are alreday disconnected" << endl;
      } else {
	igraph_es_pairs(&es, &v, true);
#if IGRAPH_V >= IGRAPH_V_0_6
	igraph_get_eids(&graph, &eids, &v, NULL, true, false);
# else 
	igraph_get_eids(&graph, &eids, &v, true);
#endif
	for (int j = 0; j <= igraph_vector_size(&eids) - 1; j++) {
	  Bitvector *lid = (*edge_LID.find(VECTOR(eids)[j])).second;
	  rmv_edge_lid.insert(pair<string, Bitvector *>(pairs[j],lid));
	}
	igraph_delete_edges(&graph, es);
      }
      } else if (net=="o"){
	if(rmv_edge_lid.find(pairs[0]) != rmv_edge_lid.end()){
	  cout << "TM: Reproted Edge is already disconnected" << endl;
	} else {
	    igraph_es_pairs(&es, &v, true);
#if IGRAPH_V >= IGRAPH_V_0_6
	    igraph_get_eids(&graph, &eids, &v,NULL, true, false);
# else 
	    igraph_get_eids(&graph, &eids, &v, true);
#endif
	    for (int j = 0; j <= igraph_vector_size(&eids) - 1; j++) {
	      Bitvector *lid = (*edge_LID.find(VECTOR(eids)[j])).second;
	      rmv_edge_lid.insert(pair<string, Bitvector *>(pairs[j],lid));
	    }
	    igraph_delete_edges(&graph, es);
	  }
	}
      }
    //mjreed MEMORY LEAK HERE
    reverse_edge_index.clear();
    edge_LID.clear();
    for (int i = 0; i < igraph_ecount(&graph); i++) {
      string LID = string(igraph_cattribute_EAS(&graph, "LID", i));
      reverse_edge_index.insert(pair<string, int>(LID, i));
      Bitvector* lid = new Bitvector(LID);
      edge_LID.insert(pair<int, Bitvector *>(i, lid));
      //cout << "edge " << i << " has LID  " << lid->to_string() << endl;
    }
} 
Beispiel #8
0
/*****************************************************************************
 * Main
 ****************************************************************************/
int main(int argc, char **argv) {

    srand ( time(NULL) );
       
    /******************************
     * Command Line Parser
     ******************************/
         
    bool mono_lib(false), print_gate(false), print_solns(false), print_sat(false), print_blif(false), print_verilog(false);
    int num_threads, budget;
    float remove_percent(0.6);
    vector<string> test_args;
    
    po::options_description optional_args("Usage: [options]");
    optional_args.add_options()
        ("circuit",         po::value<string>(),                                    "input circuit")
        ("tech_lib",        po::value<string>(),                                    "tech library")
        ("continue_file,c", po::value<string>(),                                    "input report to continue from")
        ("mono_lib,m",      po::value(&mono_lib)->zero_tokens(),                    "treat each gate as a nand")
        ("budget,b",        po::value<int>(&budget)->default_value(100000000),      "minisat conflict budget (-1 = unlimited)")
        ("remove_edges,e",  po::value<float>(&remove_percent)->default_value(0.6),  "edge percent to remove")
        ("print_graph",     po::value(&print_gate)->zero_tokens(),                  "print H graph")
        ("print_solns",     po::value(&print_solns)->zero_tokens(),                 "print isos")
        ("print_blif",      po::value(&print_blif)->zero_tokens(),                  "print G blif circuit")
        ("print_verilog",   po::value(&print_verilog)->zero_tokens(),               "print verilog circuits")
        ("test,t",          po::value< vector<string> >(&test_args),                 "Run test suite #: \n"
                                                                                    "  -99: Beta Testing \n"
                                                                                    "  -1: Mem Testing \n"
                                                                                    "   0: L0 [count, remove_percent] \n"
                                                                                    "   1: L1 [count, remove_percent] \n"
                                                                                    "   2: S1 - Random [min S1] \n"
                                                                                    "   3: S1 - Greedy [min S1] \n")
        ("num_threads,n",   po::value<int>(&num_threads)->default_value(1),         "Number of threads")
        ("wdir,w",          po::value<string>()->default_value("./wdir"),           "Output directory")
        ("help,h",                                                                  "produce help message")
    ;

    po::positional_options_description positional_args;
    positional_args.add("circuit", 1);
    positional_args.add("tech_lib", 1);
    positional_args.add("test", -1);
    po::variables_map vm;

    try {
        po::store(po::command_line_parser(argc, argv).options(optional_args).positional(positional_args).run(), vm);
        po::notify(vm);
    } catch(exception& e) {
        cerr << "error: " << e.what() << "\n";
        return 1;
    } catch(...) {
        cerr << "Exception of unknown type!\n";
    }

    if (vm.count("help")) {
        cout << optional_args << "\n";
        return 0;
    }

    string circuit_filename, circuit_name, tech_filename, tech_name, working_dir, report_filename;
   
    // input circuit
    if (vm.count("circuit") == 1) {
        circuit_filename = vm["circuit"].as<string>();
        circuit_name = circuit_filename.substr(circuit_filename.rfind('/')+1);
        circuit_name = circuit_name.substr(0, circuit_name.find('.'));
    } else {
        cout << optional_args << "\n";
        return 0;
    }

    // input tech lib
    if (vm.count("tech_lib")) {
        tech_filename = vm["tech_lib"].as<string>();
        tech_name = tech_filename.substr(tech_filename.rfind('/')+1);
        tech_name = tech_name.substr(0, tech_name.find('.'));
    } else {
        cout << optional_args << "\n";
        return 0;
    }

    cout << "Circuit : " << circuit_filename << "\n";
    cout << "Tech Lib: " << tech_filename << "\n";

   
    /******************************
     * Setup working dir
     ******************************/
    working_dir = vm["wdir"].as<string>();
    mkdir(working_dir.c_str(), S_IRWXU);
    cout << "WDIR    : " << working_dir << "\n";


    /******************************
     * Convert circuit using tech_lib
     ******************************/
    string outfile = working_dir + circuit_filename.substr(circuit_filename.rfind('/'));
    cout << "Outfile : " << outfile << "\n";
   // sis_convert(circuit_filename, tech_filename, outfile);
cout << "I'm here!\n";
    circuit_filename = outfile;
    // copy tech_lib
    if ( tech_filename != string(working_dir + tech_filename.substr(tech_filename.rfind('/')) ) ) {
        ifstream src( tech_filename.c_str() );
        ofstream dst( string(working_dir + tech_filename.substr(tech_filename.rfind('/')) ).c_str() );
        dst << src.rdbuf();
        dst.close();
    }

   
    /******************************
     * Load circuit
     ******************************/
    Circuit circuit;
    load_circuit(&circuit, circuit_filename, mono_lib);
    
    Security *security;
    Circuit G, H;
    G.copy(&circuit);
    G.remove_io();

    circuit.save( working_dir + "/circuit.gml" );
    G.save( working_dir + "/G_circuit.gml" );


    /****************************************************************
     * print G
     ****************************************************************/
    if ( test_args.size() > 0 && -1 == atoi(test_args[0].c_str())) {
         G.print();
    }


    /****************************************************************
     * L0
     ****************************************************************/
    if ( test_args.size() > 0 && 0 == atoi(test_args[0].c_str())) {

        int max_count(2);
        if (test_args.size() == 2)
            max_count = atoi(test_args[1].c_str());

        H.copy(&G);
        H.rand_del_edges(remove_percent);
        H.save( working_dir + "/H_circuit.gml" );

        security = new Security(&G, &H);
        security->setConfBudget(budget);

        cout << "Rand L0: |V(G)| = "  << (int) igraph_vcount(&G);
        cout << ", |E(G)| = "         << (int) igraph_ecount(&G);
        cout << ", |V(H)| = "         << (int) igraph_vcount(&H);
        cout << ", |E(H)| = "         << (int) igraph_ecount(&H) << "\n";
        
        cout << " " << boolalpha << security->L0(max_count, false) << endl;
    }



    /****************************************************************
     * L1
     ****************************************************************/
    if ( test_args.size() > 0 && 1 == atoi(test_args[0].c_str())) {

        int max_L1(2);
        if (test_args.size() == 2)
            max_L1 = atoi(test_args[1].c_str());

        H.copy(&G);
        H.rand_del_edges(remove_percent);
        
        if (vm.count("continue_file")) {
            H.rand_del_edges((float) 1.0);
            string filename = vm["continue_file"].as<string>();
            ifstream file;
            try {
                file.open(filename.c_str());
                
                while (file.good()) {
                    string line;
                    int L0, L1;
                    Edge edge;

                    getline(file, line);
                    if (parse(line, &G, L1, L0, edge)) {
                        if (L1 >= max_L1) {
                            H.add_edge(edge);
                            cout << "L1 = " << max_L1 << ", +<" << edge.first << "," << edge.second << ">" << endl;
                        }
                    }
                }
            } catch(...) {}
        }

        H.save( working_dir + "/H_circuit.gml" );

        security = new Security(&G, &H);
        security->setConfBudget(budget);

        cout << "Rand L1: |V(G)| = "  << (int) igraph_vcount(&G);
        cout << ", |E(G)| = "         << (int) igraph_ecount(&G);
        cout << ", |V(H)| = "         << (int) igraph_vcount(&H);
        cout << ", |E(H)| = "         << (int) igraph_ecount(&H) << "\n";
        
        cout << " " << boolalpha << security->L1(max_L1, false) << endl;
    }



    /****************************************************************
     * #L1
     ****************************************************************/
    if ( test_args.size() == 1 && 2 == atoi(test_args[0].c_str())) {

        int max_L1(2);
        if (test_args.size() == 2)
            max_L1 = atoi(test_args[1].c_str());

        H.copy(&G);
        H.rand_del_edges(remove_percent);

        if (vm.count("continue_file")) {
            H.rand_del_edges((float) 1.0);
            string filename = vm["continue_file"].as<string>();
            ifstream file;
            try {
                file.open(filename.c_str());
                
                while (file.good()) {
                    string line;
                    int L0, L1;
                    Edge edge;

                    getline(file, line);
                    if (parse(line, &G, L1, L0, edge)) {
                        H.add_edge(edge);
                        max_L1 = L1;
                        cout << "L1 = " << max_L1 << ", +<" << edge.first << "," << edge.second << ">" << endl;
                    }
                }
            } catch(...) {}
        }

        H.save( working_dir + "/H_circuit.gml" );

        security = new Security(&G, &H);
        security->setConfBudget(budget);

        cout << "Rand L1: |V(G)| = "  << (int) igraph_vcount(&G);
        cout << ", |E(G)| = "         << (int) igraph_ecount(&G);
        cout << ", |V(H)| = "         << (int) igraph_vcount(&H);
        cout << ", |E(H)| = "         << (int) igraph_ecount(&H) << "\n";
        cout << " " << security->L1(false);
    }



    /****************************************************************
     * S1_rand
     ****************************************************************/
    if ( test_args.size() == 1 && 3 == atoi(test_args[0].c_str())) {

        int max_L1 = G.max_L1();
        H.copy(&G);
        H.rand_del_edges((float) 1.0);

        security = new Security(&G, &H);
        security->setConfBudget(budget);

        string output;
        output = "S1_rand ("  + G.get_name() + ")";
        output = report(output, &G, &H, max_L1);
        cout << output;

        security->S1_rand(num_threads);
    }



    /****************************************************************
     * S1_greedy
     ****************************************************************/
    if ( test_args.size() >= 1 && 4 == atoi(test_args[0].c_str())) {

        int min_L1(2), max_L1 = G.max_L1();
        H.copy(&G);
        H.rand_del_edges((float) 1.0);
        bool done(false);
        
        if ( test_args.size() == 3 ) {
            min_L1 = atoi(test_args[1].c_str());
            max_L1 = atoi(test_args[2].c_str());
        } else if ( test_args.size() == 2 )
            min_L1 = atoi(test_args[1].c_str());

        if (vm.count("continue_file")) {
            string filename = vm["continue_file"].as<string>();
            ifstream file;
		
		for (int eid = 0; eid < igraph_ecount(&G); eid++)
			SETEAS(&G, "style", eid, "invis");

            try {
                file.open(filename.c_str());
                
//		int last_sec;
//		Edge prev_edge;
//		bool first = true;
                while (file.good()) {
                    string line;
                    int L0, L1;
                    Edge edge;

                    getline(file, line);
		    
		
                    if (parse(line, &G, L1, L0, edge)) {
                        if (L1 < min_L1) {
                            done = true;
                            break;
                        }

//			if (first) { last_sec = L1; first = false; prev_edge = edge;}
//			else
//			{
//				if (last_sec != L1)
//				{

					
//					H.del_edge(prev_edge);
//					string gmlfilename;
//					char num[3];
//					sprintf(num, "%d", last_sec);		
//					gmlfilename = working_dir + "/H_circuit_" + num + ".gml";
//					string gvfilename = working_dir + "/H_circuit_" + num + ".gv";
//					string psfilename = working_dir + "/H_circuit_" + num + ".ps";					
					//H.save( gmlfilename );
//					G.save( gmlfilename );

//					H.add_edge(prev_edge);
//					string command = "gml2gv -o" + gvfilename + " " + gmlfilename;
//					system(command.c_str());
//					command = "dot -Tps -Nstyle=filled -Ncolorscheme=accent8 -Nshape=circle -Nlabel=\"\" -o " + psfilename + " " + gvfilename;
//					system(command.c_str());
//					last_sec = L1;
//				}
//				prev_edge = edge;
//				int eid;
//				igraph_get_eid(&G, &eid, edge.first, edge.second, true, false);
//				SETEAS(&G, "style", eid, "solid");

//			}
			
				
                        H.add_edge(edge);
                        max_L1 = L1;
                        cout << "L1 = " << max_L1 << ", +<" << edge.first << "," << edge.second << ">" << endl;
                    }
                }
//		return 0;
            } catch(...) {}
        }

        if ( test_args.size() == 3 ) {
            min_L1 = atoi(test_args[1].c_str());
            max_L1 = atoi(test_args[2].c_str());
        } else if ( test_args.size() == 2 )
            min_L1 = atoi(test_args[1].c_str());

        security = new Security(&G, &H);
        security->setConfBudget(budget);
	
        string output;
        output = "S1_greedy ("  + G.get_name() + ")";
        output = report(output, &G, &H, max_L1);
        cout << output;

        fstream report;
        if (!done)
	{
		clock_t tic = clock();
            security->S1_greedy(num_threads, min_L1, max_L1);
		clock_t toc = clock();
          cout << endl << "Heuristic took: ";
          cout << (double) (toc-tic)/CLOCKS_PER_SEC << endl;
	}

    }


    /****************************************************************
     * k-isomorphism
     ****************************************************************/
    if ( test_args.size() >= 1 && 10 == atoi(test_args[0].c_str())) {

        int min_L1(2), max_L1 = G.max_L1();

	if ( test_args.size() == 3 ) {
            min_L1 = atoi(test_args[1].c_str());
            max_L1 = atoi(test_args[2].c_str());
        } else if ( test_args.size() == 2 )
            min_L1 = atoi(test_args[1].c_str());

	igraph_vector_t match_vert;
	igraph_vector_init(&match_vert, 0);
	for (int i = 0; i < igraph_vcount(&G); i++)
	{
			int color = VAN(&G, "colour", i);
			if (igraph_vector_size(&match_vert) < color + 1)
				for (int j = igraph_vector_size(&match_vert); j <= color; j++)
				{
					igraph_vector_push_back(&match_vert, 0);
				}
			VECTOR(match_vert)[color]++;
	}

	igraph_t temp;
//	igraph_copy(&temp, &G);
//	igraph_destroy(&G);
//	for (min_L1 = max_L1; min_L1 >= 1; min_L1--) {
//		igraph_copy(&G, &temp);
	int count = 0;
	for (int i = 0; i < igraph_vector_size(&match_vert); i++)
	{
		int n = ((int) VECTOR(match_vert)[i]) % min_L1; if (n == 0) continue;
		for (int j = 0; j < min_L1 - n; j++)
		{ count++;
			igraph_add_vertices(&G, 1, 0);
			SETVAN(&G, "colour", igraph_vcount(&G) - 1, i);
		}
	}
	
cout << count << " "; cout.flush();
        H.copy(&G);
        H.rand_del_edges((float) 1.0);
        bool done(false);
        
        security = new Security(&G, &H);
        security->setConfBudget(budget);
	
        string output;
        output = "S1_greedy ("  + G.get_name() + ")";
        output = report(output, &G, &H, max_L1);
//        cout << output;

        fstream report;
        if (!done)
	{
		clock_t tic = clock();
            security->kiso(min_L1, max_L1);
		clock_t toc = clock();
  //        cout << endl << "Heuristic took: ";
   //       cout << (double) (toc-tic)/CLOCKS_PER_SEC << endl;
	} //igraph_destroy(&G);}

    }

/****************************************************************
     * Tree test
     ****************************************************************/
    if ( test_args.size() >= 1 && 7 == atoi(test_args[0].c_str())) {

        int min_L1(2), max_L1 = G.max_L1();

	//G.erase();
	igraph_vs_t vs;
	igraph_vs_all(&vs);

	igraph_delete_vertices(&G, vs);
	const int depth = 7;
	igraph_add_vertices(&G, pow(2,depth)-1, 0);
	for (int i=0; i < pow(2,depth-1); i++)
	{
		int level = floor(log(i+1)/log(2));
		igraph_add_edge(&G,i,pow(2,level+1) + (i-pow(2,level))*2 - 1);
		igraph_add_edge(&G,i,pow(2,level+1) + (i-pow(2,level))*2);
	}	

	for (int i=0; i < igraph_vcount(&G); i++)
	{
		SETVAN(&G, "colour", i, 0);
		SETVAS(&G, "type", i, "invf101");
		string label = "label";
		SETVAS(&G, "label", i, label.c_str());
	}

        H.copy(&G);
	for (int i=0; i < igraph_vcount(&H); i++)
	{
		SETVAN(&H, "colour", i, 0);
	}

        H.rand_del_edges((float) 1.0);
        
        if ( test_args.size() == 3 ) {
            min_L1 = atoi(test_args[1].c_str());
            max_L1 = atoi(test_args[2].c_str());
        } else if ( test_args.size() == 2 )
            min_L1 = atoi(test_args[1].c_str());


        if ( test_args.size() == 3 ) {
            min_L1 = atoi(test_args[1].c_str());
            max_L1 = atoi(test_args[2].c_str());
        } else if ( test_args.size() == 2 )
            min_L1 = atoi(test_args[1].c_str());

	cout << "I'm here!"; cout.flush();
        security = new Security(&G, &H);
        security->setConfBudget(budget);
	
        string output;
	cout << "I'm here!";
        output = "S1_greedy ("  + G.get_name() + ")";
	cout << "I'm here!";
        output = report(output, &G, &H, max_L1);
        cout << output;

	cout << "I'm here!";
        security->S1_greedy(num_threads, min_L1, max_L1);

    }

/****************************************************************
     * Compute security level G if no wires are lifted
     ****************************************************************/
    if ( test_args.size() >= 1 && 5 == atoi(test_args[0].c_str())) {

        H.copy(&G);
        security = new Security(&G, &H);
        security->setConfBudget(budget);
   H.rand_del_edges((float) 0.0);

//	security->clean_solutions();

        string output;
        output = "Security of circuit ("  + G.get_name() + ") if no wires are lifted: ";
        cout << output;
        
        security->S1_self();

    }



/****************************************************************
     * Solve LIFT(G, k, eta)
     ****************************************************************/

if ( test_args.size() >= 1 && 6 == atoi(test_args[0].c_str())) {

        int min_L1(2), max_L1 = G.max_L1(), eta = igraph_ecount(&G);
	H.copy(&G);
//        H.rand_del_edges((float) 1.0);
        
        if ( test_args.size() == 3 ) {
            min_L1 = atoi(test_args[1].c_str());
            eta = atoi(test_args[2].c_str());
        } else if ( test_args.size() == 2 )
            min_L1 = atoi(test_args[1].c_str());

        security = new Security(&G, &H);
        security->setConfBudget(budget);
	
    
	clock_t tic = clock();
	security->rSAT(min_L1, max_L1, eta);
	clock_t toc = clock();
	cout << endl << "SAT took: ";
	cout << (double) (toc-tic)/CLOCKS_PER_SEC << endl;

    }

/****************************************************************
     * Solve LIFT(G, k, eta, u)
     ****************************************************************/

if ( test_args.size() >= 1 && 8 == atoi(test_args[0].c_str())) {

        int min_L1(2), max_L1 = G.max_L1(), eta = igraph_ecount(&G), u;
	H.copy(&G);
//        H.rand_del_edges((float) 1.0);
        
        if ( test_args.size() == 4 ) {
		u = atoi(test_args[1].c_str());
            min_L1 = atoi(test_args[2].c_str());
            eta = atoi(test_args[3].c_str());
        } else if ( test_args.size() == 3 )
	{
		u = atoi(test_args[1].c_str());
            min_L1 = atoi(test_args[2].c_str());
} 
else if ( test_args.size() == 2 )
		u = atoi(test_args[1].c_str());

        security = new Security(&G, &H);
        security->setConfBudget(budget);
	
    
	clock_t tic = clock();
	security->rSAT(min_L1, max_L1, eta, u, true);
	clock_t toc = clock();
	cout << endl << "SAT took: ";
	cout << (double) (toc-tic)/CLOCKS_PER_SEC << endl;

    }

/****************************************************************
     * Solve LIFT(G, k, eta, u)
     ****************************************************************/

if ( test_args.size() >= 1 && 9 == atoi(test_args[0].c_str())) {

        int min_L1(2), max_L1 = G.max_L1(), eta = igraph_ecount(&G), u;
	H.copy(&G);
//        H.rand_del_edges((float) 1.0);
        
        if ( test_args.size() == 4 ) {
		u = atoi(test_args[1].c_str());
            min_L1 = atoi(test_args[2].c_str());
            eta = atoi(test_args[3].c_str());
        } else if ( test_args.size() == 3 )
	{
		u = atoi(test_args[1].c_str());
            min_L1 = atoi(test_args[2].c_str());
} 
else if ( test_args.size() == 2 )
		u = atoi(test_args[1].c_str());

        security = new Security(&G, &H);
        security->setConfBudget(budget);
	
    
	clock_t tic = clock();
	security->rSAT(min_L1,max_L1, eta, u);
	clock_t toc = clock();
	cout << endl << "SAT took: ";
	cout << (double) (toc-tic)/CLOCKS_PER_SEC << endl;

    }

/****************************************************************
     * simulated annealing
     ****************************************************************/


if ( test_args.size() >= 1 && 10 == atoi(test_args[0].c_str())) {
    const double MAX_TEMP = 100000.0;
    const int MAX_ITERATIONS = 2000;
    const double TEMP_CHANGE = 0.98;
    int no_of_edges = 20;
    int min_L1(2), max_L1 = G.max_L1();
    H.copy(&G);
    H.rand_del_edges(igraph_ecount(&G) - no_of_edges);
    security = new Security(&G, &H);
    security->setConfBudget(budget);
    int current_k_security = security->L1(); 
    int best_k_security = current_k_security;
    delete security;
    double temperature = MAX_TEMP;
    srand( time(NULL));

    for (int iter = 0; iter < MAX_ITERATIONS; iter++) {
        bool done(false);
        
        // H.rand_del_edges(1);
        vector<Edge> unlifted_edge_list;
        for (int eid = 0; eid < igraph_ecount(&H); eid++) {
            Edge edge = H.get_edge(eid);
            unlifted_edge_list.push_back(edge);
        }
        random_shuffle(unlifted_edge_list.begin(), unlifted_edge_list.end());
        H.del_edge(unlifted_edge_list[0]);

 
        vector<Edge> edge_list;
        for (int eid = 0; eid < igraph_ecount(&G); eid++) {
            Edge edge = G.get_edge(eid);
            if (!H.test_edge(edge)) edge_list.push_back(edge);
        }
        random_shuffle(edge_list.begin(), edge_list.end());
        H.add_edge(edge_list[0]);

        security = new Security(&G, &H);
        security->setConfBudget(budget);
	
        int new_k_security = security->L1();
        if (new_k_security >= current_k_security) { 
            current_k_security = new_k_security;
            if (current_k_security >= best_k_security) best_k_security = current_k_security;
        }
        else {
            if (exp((new_k_security-current_k_security)/temperature) >= ((double) rand())/ RAND_MAX);
            else {
                H.add_edge(unlifted_edge_list[0]);
                H.add_edge(edge_list[0]);
            }
        }
        temperature *= TEMP_CHANGE;
        if ((iter + 1 )% 10 == 0) cout << " > iteration " << iter + 1 << ", temp=" << temperature << ", best=" << best_k_security << endl;             
    }
}



    /****************************************************************
     * L1(label)
     ****************************************************************/
    if ( test_args.size() >= 1 && 5 == atoi(test_args[0].c_str())) {

        string label = "";
        if (test_args.size() == 2)
            label = test_args[1];

        int max_L1(2);
        H.copy(&G);
        H.rand_del_edges(remove_percent);
        
        if (vm.count("continue_file")) {
            H.rand_del_edges((float) 1.0);
            string filename = vm["continue_file"].as<string>();
            ifstream file;
            try {
                file.open(filename.c_str());
                
                while (file.good()) {
                    string line;
                    int L0, L1;
                    Edge edge;

                    getline(file, line);
                    if (parse(line, &G, L1, L0, edge)) {
                        H.add_edge(edge);
                        max_L1 = L1;
                        cout << "L1 = " << max_L1 << ", +<" << edge.first << "," << edge.second << ">" << endl;
                    }
                }
            } catch(...) {}
        }

        H.save( working_dir + "/H_circuit.gml" );

        security = new Security(&G, &H);
        security->setConfBudget(budget);

        security->L1(label);       
    }


    if ( test_args.size() >= 1 && atoi(test_args[0].c_str()) >= 0) {
        H.save( working_dir + "/H_circuit.gml" );
        delete security;
    }

    if (print_gate)
        G.print();

    if (print_blif)
        print_file(circuit_filename);
        
    if (print_solns)
        security->print_solutions();

    if (print_verilog)
        security->print_solutions();


    printf("\n\ndone 0 \n");
    return 0;
}
int main() {
  igraph_t g;
  igraph_vector_t weights;

  igraph_rng_seed(igraph_rng_default(), 42);

  /* Two triangles connected by one edge */
  printf("# Two triangles connected by one edge\n");
  igraph_small(&g, 0, IGRAPH_UNDIRECTED,
                      0, 1, 1, 2, 2, 0,
                      3, 4, 4, 5, 5, 3,
                      0, 5,
                      -1);
  infomap_test(&g);
  igraph_destroy(&g);
  //return 0;

  /* Two 4-cliques with one commun vertex (vertex 3) */
  printf("# Two 4-cliques (0123 and 4567) connected by two edges (0-4 and 1-5)\n");
  igraph_small(&g, 0, IGRAPH_UNDIRECTED,
                      0, 1,  0, 2,  0, 3,  1, 2,  1, 3,  2, 3, // 4-clique 0,1,2,3
                      7, 4,  7, 5,  7, 6,  4, 5,  4, 6,  5, 6, // 4-clique 4,5,6,7
                      0, 4,  1, 5, //8, 0, 8, 4,
                      -1);
  infomap_test(&g);

  printf("# Two 4-cliques (0123 and 4567) connected by two edges (0-4 and 1-5)\n");
  igraph_add_edge(&g, 0, 4);
  igraph_add_edge(&g, 1, 5);
  infomap_test(&g);
  igraph_destroy(&g);
  
  /* Zachary Karate club -- this is just a quick smoke test */
  printf("# Zachary Karate club\n");
  igraph_small(&g, 0, IGRAPH_UNDIRECTED,
               0,  1,  0,  2,  0,  3,  0,  4,  0,  5, //0,  5, 0,  5, 0,  5,
               0,  6,  0,  7,  0,  8,  0, 10,  0, 11,
               0, 12,  0, 13,  0, 17,  0, 19,  0, 21,
               0, 31,  1,  2,  1,  3,  1,  7,  1, 13,
               1, 17,  1, 19,  1, 21,  1, 30,  2,  3,
               2,  7,  2,  8,  2,  9,  2, 13,  2, 27,
               2, 28,  2, 32,  3,  7,  3, 12,  3, 13,
               4,  6,  4, 10,  5,  6,  5, 10,  5, 16,
               6, 16,  8, 30,  8, 32,  8, 33,  9, 33,
               13, 33, 14, 32, 14, 33, 15, 32, 15, 33,
               18, 32, 18, 33, 19, 33, 20, 32, 20, 33,
               22, 32, 22, 33, 23, 25, 23, 27, 23, 29,
               23, 32, 23, 33, 24, 25, 24, 27, 24, 31,
               25, 31, 26, 29, 26, 33, 27, 33, 28, 31,
               28, 33, 29, 32, 29, 33, 30, 32, 30, 33,
               31, 32, 31, 33, 32, 33,
               -1);
  infomap_test(&g);
  igraph_destroy(&g);
  
  /* Flow.net that come in infomap_dir.tgz  */
  printf("# Flow (from infomap_dir.tgz)\n");
  igraph_small(&g, 0, IGRAPH_DIRECTED,
              0, 1,     1, 2,    2, 3,    3, 0,    1, 4,
              4, 5,     5, 6,    6, 7,    7, 4,    5, 8,
              8, 9,     9, 10,  10, 11,  11, 8,    9, 12,
              12, 13,  13, 14,  14, 15,  15, 12,  13, 0,
               -1);
  infomap_test(&g);
  igraph_destroy(&g);

  /* MultiphysChemBioEco40W_weighted_dir.net */
  printf("# MultiphysChemBioEco40W_weighted_dir.net (from infomap_dir.tgz)\n");
  igraph_small(&g, 0, IGRAPH_DIRECTED,
          1, 0,  2, 0,  3, 0,  4, 0,  5, 0,  6, 0,  7, 0,
          8, 0,  9, 0,  16, 0,  18, 0,  0, 1,  2, 1,  3, 1,
          5, 1,  6, 1,  7, 1,  9, 1,  10, 1,  16, 1,  18, 1,
          0, 2,  3, 2,  4, 2,  5, 2,  6, 2,  7, 2,  0, 3,
          1, 3,  2, 3,  4, 3,  5, 3,  6, 3,  7, 3,  8, 3,
          9, 3,  10, 3,  11, 3,  13, 3,  14, 3,  16, 3,  17, 3,
          18, 3,  19, 3,  26, 3,  30, 3,  1, 4,  3, 4,  5, 4,
          6, 4,  13, 4,  18, 4,  0, 5,  1, 5,  2, 5,  3, 5,
          6, 5,  7, 5,  9, 5,  1, 6,  3, 6,  7, 6,  9, 6,
          16, 6,  0, 7,  1, 7,  2, 7,  3, 7,  5, 7,  6, 7,
          9, 7,  3, 8,  5, 8,  3, 9,  7, 9,  12, 10,  13, 10,
          14, 10,  15, 10,  16, 10,  17, 10,  18, 10,  19, 10,
          21, 10,  3, 11,  18, 11,  10, 12,  14, 12,  16, 12,
          17, 12,  18, 12,  3, 13,  10, 13,  14, 13,  16, 13,
          10, 14,  12, 14,  13, 14,  15, 14,  16, 14,  17, 14,
          18, 14,  10, 15,  14, 15,  18, 15,  0, 16,  2, 16,
          3, 16,  6, 16,  10, 16,  12, 16,  13, 16,  14, 16,
          17, 16,  18, 16,  10, 17,  12, 17,  14, 17,  18, 17,
          3, 18,  10, 18,  12, 18,  14, 18,  15, 18,  16, 18,
          17, 18,  19, 18,  21, 18,  11, 19,  16, 19,  17, 19,
          16, 20,  18, 20,  21, 20,  22, 20,  23, 20,  24, 20,
          25, 20,  26, 20,  27, 20,  28, 20,  29, 20,  3, 21,
          14, 21,  18, 21,  20, 21,  22, 21,  23, 21,  24, 21,
          25, 21,  26, 21,  27, 21,  28, 21,  29, 21,  35, 21,
          36, 21,  38, 21,  18, 22,  20, 22,  21, 22,  23, 22,
          24, 22,  25, 22,  26, 22,  27, 22,  29, 22,  3, 23,
          20, 23,  21, 23,  22, 23,  24, 23,  25, 23,  26, 23,
          27, 23,  28, 23,  29, 23,  35, 23,  38, 23,  39, 23,
          20, 24,  21, 24,  23, 24,  25, 24,  26, 24,  27, 24,
          28, 24,  29, 24,  9, 25,  20, 25,  21, 25,  22, 25,
          23, 25,  24, 25,  26, 25,  27, 25,  28, 25,  29, 25,
          18, 26,  20, 26,  21, 26,  22, 26,  23, 26,  25, 26,
          27, 26,  28, 26,  29, 26,  30, 26,  32, 26,  35, 26,
          36, 26,  38, 26,  39, 26,  3, 27,  14, 27,  20, 27,
          21, 27,  22, 27,  23, 27,  24, 27,  25, 27,  26, 27,
          28, 27,  29, 27,  38, 27,  3, 28,  18, 28,  20, 28,
          21, 28,  23, 28,  24, 28,  25, 28,  26, 28,  27, 28,
          29, 28,  35, 28,  14, 29,  16, 29,  18, 29,  20, 29,
          21, 29,  22, 29,  23, 29,  24, 29,  25, 29,  26, 29,
          27, 29,  28, 29,  31, 30,  32, 30,  33, 30,  34, 30,
          35, 30,  36, 30,  38, 30,  39, 30,  30, 31,  32, 31,
          34, 31,  36, 31,  30, 32,  34, 32,  35, 32,  36, 32,
          30, 33,  32, 33,  34, 33,  35, 33,  36, 33,  38, 33,
          30, 34,  31, 34,  32, 34,  33, 34,  35, 34,  36, 34,
          38, 34,  39, 34,  26, 35,  30, 35,  32, 35,  33, 35,
          34, 35,  36, 35,  38, 35,  39, 35,  30, 36,  34, 36,
          35, 36,  38, 36,  39, 36,  34, 37,  26, 38,  30, 38,
          32, 38,  33, 38,  34, 38,  35, 38,  36, 38,  39, 38,
          26, 39,  30, 39,  33, 39,  34, 39,  35, 39,  36, 39,
          38, 39,
          -1);
  igraph_vector_init_real(&weights, 306,
          5.0,  3.0,  130.0,  4.0,  15.0,  9.0,
          7.0,  1.0,  1.0,  3.0,  1.0,  1.0,
          1.0,  34.0,  38.0,  2.0,  23.0,  1.0,
          1.0,  3.0,  2.0,  2.0,  16.0,  1.0,
          3.0,  1.0,  3.0,  63.0,  92.0,  72.0,
          25.0,  447.0,  121.0,  65.0,  4.0,  16.0,
          35.0,  1.0,  19.0,  1.0,  78.0,  1.0,
          45.0,  1.0,  3.0,  1.0,  1.0,  25.0,
          1.0,  3.0,  1.0,  1.0,  3.0,  36.0,
          19.0,  136.0,  41.0,  96.0,  1.0,  7.0,
          26.0,  1.0,  2.0,  2.0,  3.0,  2.0,  2.0,
          23.0,  52.0,  4.0,  1.0,  2.0,  1.0,  3.0,
          1.0,  11.0,  2.0,  17.0,  1.0,  5.0,  18.0,
          86.0,  5.0,  1.0,  1.0,  1.0,  6.0,  1.0,
          2.0,  2.0,  20.0,  4.0,  5.0,  1.0,  5.0,
          12.0,  4.0,  1.0,  1.0,  4.0,  9.0,  40.0,
          2.0,  1.0,  4.0,  1.0,  1.0,  48.0,  2.0,
          18.0,  1.0,  7.0,  2.0,  2.0,  53.0,  25.0,
          9.0,  1.0,  23.0,  8.0,  62.0,  29.0,  35.0,
          4.0,  34.0,  35.0,  3.0,  1.0,  24.0,  1.0,
          6.0,  2.0,  2.0,  22.0,  7.0,  2.0,  5.0,
          14.0,  3.0,  28.0,  14.0,  20.0,  3.0,  1.0,
          5.0,  77.0,  20.0,  25.0,  35.0,  55.0,  35.0,
          115.0,  68.0,  105.0,  2.0,  2.0,  2.0,  4.0,
          2.0,  17.0,  12.0,  3.0,  3.0,  11.0,  10.0,
          7.0,  2.0,  12.0,  31.0,  11.0,  5.0,  11.0,
          65.0,  39.0,  17.0,  26.0,  3.0,  4.0,  2.0,
          3.0,  6.0,  4.0,  8.0,  1.0,  7.0,  7.0,
          6.0,  1.0,  39.0,  42.0,  9.0,  6.0,  9.0,
          5.0,  45.0,  43.0,  26.0,  1.0,  2.0,  6.0,
          2.0,  15.0,  3.0,  9.0,  2.0,  1.0,  1.0,
          1.0,  4.0,  2.0,  9.0,  2.0,  1.0,  2.0,
          28.0,  80.0,  10.0,  18.0,  13.0,  17.0,
          28.0,  40.0,  76.0,  1.0,  2.0,  1.0,  11.0,
          37.0,  5.0,  11.0,  14.0,  4.0,  14.0,  10.0,
          1.0,  1.0,  1.0,  1.0,  41.0,  121.0,  6.0,
          21.0,  12.0,  30.0,  6.0,  141.0,  43.0,  2.0,
          12.0,  6.0,  35.0,  10.0,  7.0,  2.0,  12.0,
          6.0,  2.0,  11.0,  1.0,  7.0,  6.0,  5.0,  3.0,
          1.0,  2.0,  1.0,  1.0,  1.0,  1.0,  67.0,  9.0,
          9.0,  11.0,  10.0,  21.0,  7.0,  12.0,  9.0,
          16.0,  7.0,  4.0,  11.0,  17.0,  37.0,  32.0,
          9.0,  2.0,  2.0,  5.0,  4.0,  2.0,  7.0,  3.0,
          3.0,  5.0,  8.0,  14.0,  3.0,  38.0,  3.0,  9.0,
          2.0,  8.0,  21.0,  18.0,  58.0);
  infomap_weighted_test(&g, &weights);
  igraph_vector_destroy(&weights);
  igraph_destroy(&g);
  
   /* Two triangles connected by one edge */
  printf("# Wiktionary english verbs (synonymy 2008)\n");
  FILE *wikt = fopen("wikti_en_V_syn.elist", "r");
  igraph_read_graph_edgelist(&g, wikt, 0, 0);
  fclose(wikt);
  gsumary(&g);
  infomap_test(&g);
  igraph_destroy(&g);
  
#ifdef __APPLE__
  return 0;
#else
  return 77;
#endif
}
Beispiel #10
0
int main() {
  
  igraph_t g, g2;
  FILE *ifile;
  igraph_vector_t gtypes, vtypes, etypes;
  igraph_strvector_t gnames, vnames, enames;
  long int i;
  igraph_vector_t y;
  igraph_strvector_t id;
  char str[20];

  /* turn on attribute handling */
  igraph_i_set_attribute_table(&igraph_cattribute_table);
  
  ifile=fopen("LINKS.NET", "r");
  if (ifile==0) {
    return 10;
  }
  igraph_read_graph_pajek(&g, ifile);
  fclose(ifile);

  igraph_vector_init(&gtypes, 0);
  igraph_vector_init(&vtypes, 0);
  igraph_vector_init(&etypes, 0);
  igraph_strvector_init(&gnames, 0);
  igraph_strvector_init(&vnames, 0);
  igraph_strvector_init(&enames, 0);
  
  igraph_cattribute_list(&g, &gnames, &gtypes, &vnames, &vtypes, 
			 &enames, &etypes);
  
  /* List attribute names and types */
  printf("Graph attributes: ");
  for (i=0; i<igraph_strvector_size(&gnames); i++) {
    printf("%s (%i) ", STR(gnames, i), (int)VECTOR(gtypes)[i]);
  }
  printf("\n");
  printf("Vertex attributes: ");
  for (i=0; i<igraph_strvector_size(&vnames); i++) {
    printf("%s (%i) ", STR(vnames, i), (int)VECTOR(vtypes)[i]);
  }
  printf("\n");
  printf("Edge attributes: ");
  for (i=0; i<igraph_strvector_size(&enames); i++) {
    printf("%s (%i) ", STR(enames, i), (int)VECTOR(etypes)[i]);
  }
  printf("\n");

  print_attributes(&g);

  /* Copying a graph */
  igraph_copy(&g2, &g);
  print_attributes(&g2);
  igraph_destroy(&g2);
  
  /* Adding vertices */
  igraph_add_vertices(&g, 3, 0);
  print_attributes(&g);

  /* Adding edges */
  igraph_add_edge(&g, 1, 1);
  igraph_add_edge(&g, 2, 5);
  igraph_add_edge(&g, 3, 6);
  print_attributes(&g);

  /* Deleting vertices */
  igraph_delete_vertices(&g, igraph_vss_1(1));
  igraph_delete_vertices(&g, igraph_vss_1(4));
  print_attributes(&g);

  /* Deleting edges */
  igraph_delete_edges(&g, igraph_ess_1(igraph_ecount(&g)-1));
  igraph_delete_edges(&g, igraph_ess_1(0));
  print_attributes(&g);

  /* Set graph attributes */
  SETGAN(&g, "id", 10);
  if (GAN(&g, "id") != 10) {
    return 11;
  }
  SETGAS(&g, "name", "toy");
  if (strcmp(GAS(&g, "name"), "toy")) {
    return 12;
  }
  
  /* Delete graph attributes */
  DELGA(&g, "id");
  DELGA(&g, "name");
  igraph_cattribute_list(&g, &gnames, 0,0,0,0,0);
  if (igraph_strvector_size(&gnames) != 0) {
    return 14;
  }  

  /* Delete vertex attributes */
  DELVA(&g, "x");
  DELVA(&g, "shape");
  DELVA(&g, "xfact");
  DELVA(&g, "yfact");
  igraph_cattribute_list(&g, 0,0, &vnames, 0,0,0);  
  if (igraph_strvector_size(&vnames) != 2) {
    return 15;
  }
  
  /* Delete edge attributes */
  igraph_cattribute_list(&g, 0,0,0,0,&enames,0);
  i=igraph_strvector_size(&enames);
  DELEA(&g, "hook1");
  DELEA(&g, "hook2"); 
  DELEA(&g, "label");
  igraph_cattribute_list(&g, 0,0,0,0,&enames,0);
  if (igraph_strvector_size(&enames) != i-3) {
    return 16;
  }
  
  /* Set vertex attributes */
  SETVAN(&g, "y", 0, -1);
  SETVAN(&g, "y", 1, 2.1);
  if (VAN(&g, "y", 0) != -1 || 
      VAN(&g, "y", 1) != 2.1) {
    return 17;
  }
  SETVAS(&g, "id", 0, "foo");
  SETVAS(&g, "id", 1, "bar");
  if (strcmp(VAS(&g, "id", 0), "foo") ||
      strcmp(VAS(&g, "id", 1), "bar")) {
    return 18;
  }

  /* Set edge attributes */
  SETEAN(&g, "weight", 2, 100.0);
  SETEAN(&g, "weight", 0, -100.1);
  if (EAN(&g, "weight", 2) != 100.0 ||
      EAN(&g, "weight", 0) != -100.1) {
    return 19;
  }
  SETEAS(&g, "color", 2, "RED");
  SETEAS(&g, "color", 0, "Blue");
  if (strcmp(EAS(&g, "color", 2), "RED") ||
      strcmp(EAS(&g, "color", 0), "Blue")) {
    return 20;
  }      

  /* Set vector attributes as vector */
  igraph_vector_init(&y, igraph_vcount(&g));
  igraph_vector_fill(&y, 1.23);
  SETVANV(&g, "y", &y);
  igraph_vector_destroy(&y);
  for (i=0; i<igraph_vcount(&g); i++) {    
    if (VAN(&g, "y", i) != 1.23) {
      return 21;
    }
  }
  igraph_vector_init_seq(&y, 0, igraph_vcount(&g)-1);
  SETVANV(&g, "foobar", &y);
  igraph_vector_destroy(&y);
  for (i=0; i<igraph_vcount(&g); i++) {
    if (VAN(&g, "foobar", i) != i) {
      return 22;
    }
  }  
  
  igraph_strvector_init(&id, igraph_vcount(&g));
  for (i=0; i<igraph_vcount(&g); i++) {
    snprintf(str, sizeof(str)-1, "%li", i);
    igraph_strvector_set(&id, i, str);
  }
  SETVASV(&g, "foo", &id);
  igraph_strvector_destroy(&id);
  for (i=0; i<igraph_vcount(&g); i++) {
    printf("%s ", VAS(&g, "foo", i));
  }
  printf("\n");
  igraph_strvector_init(&id, igraph_vcount(&g));
  for (i=0; i<igraph_vcount(&g); i++) {
    snprintf(str, sizeof(str)-1, "%li", i);
    igraph_strvector_set(&id, i, str);
  }
  SETVASV(&g, "id", &id);
  igraph_strvector_destroy(&id);
  for (i=0; i<igraph_vcount(&g); i++) {
    printf("%s ", VAS(&g, "id", i));
  }
  printf("\n");  
  
  /* Set edge attributes as vector */
  igraph_vector_init(&y, igraph_ecount(&g));
  igraph_vector_fill(&y, 12.3);
  SETEANV(&g, "weight", &y);
  igraph_vector_destroy(&y);
  for (i=0; i<igraph_ecount(&g); i++) {    
    if (EAN(&g, "weight", i) != 12.3) {
      return 23;
    }
  }
  igraph_vector_init_seq(&y, 0, igraph_ecount(&g)-1);
  SETEANV(&g, "foobar", &y);
  igraph_vector_destroy(&y);
  for (i=0; i<igraph_ecount(&g); i++) {
    if (VAN(&g, "foobar", i) != i) {
      return 24;
    }
  }  
  
  igraph_strvector_init(&id, igraph_ecount(&g));
  for (i=0; i<igraph_ecount(&g); i++) {
    snprintf(str, sizeof(str)-1, "%li", i);
    igraph_strvector_set(&id, i, str);
  }
  SETEASV(&g, "foo", &id);
  igraph_strvector_destroy(&id);
  for (i=0; i<igraph_ecount(&g); i++) {
    printf("%s ", EAS(&g, "foo", i));
  }
  printf("\n");
  igraph_strvector_init(&id, igraph_ecount(&g));
  for (i=0; i<igraph_ecount(&g); i++) {
    snprintf(str, sizeof(str)-1, "%li", i);
    igraph_strvector_set(&id, i, str);
  }
  SETEASV(&g, "color", &id);
  igraph_strvector_destroy(&id);
  for (i=0; i<igraph_ecount(&g); i++) {
    printf("%s ", EAS(&g, "color", i));
  }
  printf("\n");    

  /* Delete all remaining attributes */
  DELALL(&g);
  igraph_cattribute_list(&g, &gnames, &gtypes, &vnames, &vtypes, &enames, &etypes);
  if (igraph_strvector_size(&gnames) != 0 ||
      igraph_strvector_size(&vnames) != 0 ||
      igraph_strvector_size(&enames) != 0) {
    return 25;
  }

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

  igraph_destroy(&g);

  return 0;
}
Beispiel #11
0
void Graph::addEdge(int i, int j) {
  if (not areConnected(i,j))
    igraph_add_edge(graph, i, j);
}
Beispiel #12
0
static void
rvine_trees_to_vine(dml_vine_t *vine, igraph_t **trees)
{
    size_t n = vine->dim;
    size_t *order_inv;
    gsl_vector_short *B;
    igraph_integer_t Cea, Ceb;
    size_t x = 0, x_hat = 0, x_hat_hat = 0; // Initialized to avoid GCC warnings.
    dml_copula_t *copula = NULL; // Initialized to avoid GCC warnings.
    igraph_integer_t e; // Edge id.
    igraph_integer_t a, b, aa, ab, ba, bb; // Vertex id.
    igraph_t **last_trees = NULL;
    igraph_t *graph = NULL;
    gsl_vector_short *Ue, *Ua, *Ub;

    // Set the number of trees of the vines.
    vine->trees = n - 1;
    while (trees[vine->trees - 1] == NULL) vine->trees--;

    // Nothing to do for vines without trees.
    if (vine->trees == 0) return;

    // Selecting a structure for the trees that were truncated.
    // Is this really necessary? Think a better solution.
    if (vine->trees != n - 1) {
        igraph_i_set_attribute_table(&igraph_cattribute_table);
        last_trees = g_malloc_n(n - 1 - vine->trees, sizeof(igraph_t *));
        graph = g_malloc(sizeof(igraph_t));

        for (size_t k = vine->trees; k < n - 1; k++) { // Tree index.
            igraph_empty(graph, n - k, IGRAPH_UNDIRECTED);

            // Adding all "possible" edges.
            for (a = 0; a < igraph_vcount(graph) - 1; a++) {
                for (b = a + 1; b < igraph_vcount(graph); b++) {
                    // Checking the proximity condition.
                    igraph_edge(k <= vine->trees ? trees[k - 1] : last_trees[k - 1 - vine->trees], a, &aa, &ab);
                    igraph_edge(k <= vine->trees ? trees[k - 1] : last_trees[k - 1 - vine->trees], b, &ba, &bb);
                    if (aa == ba || aa == bb || ab == ba || ab == bb) {
                        igraph_add_edge(graph, a, b);
                        igraph_get_eid(graph, &e, a, b, IGRAPH_UNDIRECTED, 1);

                        // Variables "connected" by this edge and conditioned set.
                        Ua = EAP(k <= vine->trees ? trees[k - 1] : last_trees[k - 1 - vine->trees], "Ue", a);
                        Ub = EAP(k <= vine->trees ? trees[k - 1] : last_trees[k - 1 - vine->trees], "Ue", b);
                        Ue = gsl_vector_short_calloc(n);
                        for (size_t i = 0; i < n; i++) {
                            gsl_vector_short_set(Ue, i,
                                    gsl_vector_short_get(Ua, i)
                                            | gsl_vector_short_get(Ub, i));
                            if (gsl_vector_short_get(Ua, i)
                                    && !gsl_vector_short_get(Ub, i)) {
                                SETEAN(graph, "Cea", e, i + 1);
                            }
                            if (gsl_vector_short_get(Ub, i)
                                    && !gsl_vector_short_get(Ua, i)) {
                                SETEAN(graph, "Ceb", e, i + 1);
                            }
                        }
                        SETEAP(graph, "Ue", e, Ue);
                    }
                }
            }

            // Compute the minimum weight spanning tree.
            last_trees[k - vine->trees] = g_malloc(sizeof(igraph_t));
            igraph_minimum_spanning_tree_unweighted(graph, last_trees[k - vine->trees]);

            igraph_destroy(graph);
        }
    }

    order_inv = g_malloc0_n(n, sizeof(size_t));
    B = gsl_vector_short_calloc(n);

    // for loop in line 2.
    for (size_t i = 0; i < n - 1; i++) {
        if (trees[n - i - 2] == NULL) {
            for (e = 0; e < igraph_ecount(last_trees[n - i - 2 - vine->trees]); e++) {
                x = EAN(last_trees[n - i - 2 - vine->trees], "Cea", e);
                x_hat = EAN(last_trees[n - i - 2 - vine->trees], "Ceb", e);
                if (!gsl_vector_short_get(B, x - 1)
                        && !gsl_vector_short_get(B, x_hat - 1)) {
                    x_hat = 0;
                    copula = NULL;
                    break;
                }
            }
        } else {
            for (e = 0; e < igraph_ecount(trees[n - i - 2]); e++) {
                x = EAN(trees[n - i - 2], "Cea", e);
                x_hat = EAN(trees[n - i - 2], "Ceb", e);
                if (!gsl_vector_short_get(B, x - 1)
                        && !gsl_vector_short_get(B, x_hat - 1)) {
                    copula = EAP(trees[n - i - 2], "copula", e);
                    break;
                }
            }
        }

        // Line 4.
        gsl_vector_short_set(B, x - 1, 1);
        vine->order[n - i - 1] = x - 1;
        order_inv[x - 1] = n - i;
        vine->matrix[i][i] = x;
        vine->matrix[i + 1][i] = x_hat;
        vine->copulas[i + 1][i] = copula;

        // for loop in line 5.
        for (size_t k = i + 2; k < n; k++) {
            if (trees[n - k - 1] != NULL) {
                for (e = 0; e < igraph_ecount(trees[n - k - 1]); e++) {
                    Cea = EAN(trees[n - k - 1], "Cea", e);
                    Ceb = EAN(trees[n - k - 1], "Ceb", e);
                    if (x == Cea) {
                        x_hat_hat = Ceb;
                        if (!gsl_vector_short_get(B, x_hat_hat - 1)) {
                            // The pseudocode of the algorithm does not included
                            // this check. Invalid matrices were generated when
                            // x_hat_hat is set to an index already assigned
                            // to a diagonal entry.
                            copula = EAP(trees[n - k - 1], "copula", e);
                            break;
                        }
                    } else if (x == Ceb) {
                        x_hat_hat = Cea;
                        if (!gsl_vector_short_get(B, x_hat_hat - 1)) {
                            // Ibdem to the previous comment.
                            copula = EAP(trees[n - k - 1], "copula", e);
                            break;
                        }
                    }
                }
                vine->matrix[k][i] = x_hat_hat;
                vine->copulas[k][i] = copula;
            }
        }
    }

    for (size_t i = 0; i < n; i++) {
        if (!gsl_vector_short_get(B, i)) {
            vine->matrix[n - 1][n - 1] = i + 1;
            vine->order[0] = i;
            order_inv[i] = 1;
            break;
        }
    }
    // Reorder the variables. The simulation algorithm assumes that the
    // diagonal entries of the R-vine matrix are ordered from n to 1.
    for (size_t i = 0; i < n; i++) {
        for (size_t j = 0; j <= i; j++) {
            if (vine->matrix[i][j] > 0) {
                vine->matrix[i][j] = order_inv[vine->matrix[i][j] - 1];
            }
        }
    }

    if (vine->trees != n - 1) {
        for (size_t i = 0; i < n - 1 - vine->trees; i++) {
            for (e = 0; e < igraph_ecount(last_trees[i]); e++) {
                Ue = EAP(last_trees[i], "Ue", e);
                gsl_vector_short_free(Ue);
            }
            DELEA(last_trees[i], "Ue");
            igraph_destroy(last_trees[i]);
            g_free(last_trees[i]);
        }
        g_free(last_trees);
        g_free(graph);
    }
    g_free(order_inv);
    gsl_vector_short_free(B);
}
Beispiel #13
0
static void
fit_rvine_trees(igraph_t **trees,
                const gsl_matrix *data,
                const dml_vine_weight_t weight,
                const dml_vine_trunc_t trunc,
                const dml_copula_indeptest_t indeptest,
                const double indeptest_level,
                const dml_copula_type_t *types,
                const size_t types_size,
                const dml_copula_select_t select,
                const gsl_rng *rng)
{
    size_t m, n;
    igraph_t *graph;
    igraph_vector_t *graph_weight;
    dml_copula_t *copula;
    gsl_vector *x;
    igraph_integer_t e; // Edge id.
    igraph_integer_t a, aa, ab, b, ba, bb; // Vertex id.
    gsl_vector *u = NULL, *v = NULL;
    igraph_integer_t Cea, Ceb;
    gsl_vector_short *Ue, *Ua, *Ub;
    size_t k;
    dml_measure_t *measure;
    double tree_aic, copula_aic;
    gsl_permutation *perm, *rank, *u_rank = NULL, *v_rank = NULL;

    igraph_i_set_attribute_table(&igraph_cattribute_table);

    m = data->size1;
    n = data->size2;
    graph = g_malloc(sizeof(igraph_t));
    graph_weight = g_malloc(sizeof(igraph_vector_t));
    perm = gsl_permutation_alloc(m);

    for (k = 0; k < n - 1; k++) { // Tree index.
        if (k == 0) {
            igraph_full(graph, n, IGRAPH_UNDIRECTED, IGRAPH_NO_LOOPS);

            // Assign the observations to the nodes.
            for (size_t i = 0; i < n; i++) { // Variable and node index.
                x = gsl_vector_alloc(m);
                gsl_matrix_get_col(x, data, i);

                // Results of the h-function of the copula assigned to the
                // edge that corresponds to this vertex in the previous tree.
                // h for the h-function with its arguments in order and
                // hrev for the h-function with its arguments reversed. In the
                // first tree both are equal to the observations of the
                // corresponding variable, in the rest of the trees they differ.
                SETVAP(graph, "h", i, x);
                SETVAP(graph, "hrev", i, x);
                gsl_sort_vector_index(perm, x);
                rank = gsl_permutation_alloc(m);
                gsl_permutation_inverse(rank, perm);
                // Ranks of the h and hrev vectors.
                SETVAP(graph, "hrank", i, rank);
                SETVAP(graph, "hrevrank", i, rank);
            }

            for (e = 0; e < igraph_ecount(graph); e++) {
                igraph_edge(graph, e, &a, &b);

                // Variables "connected" by this edge.
                Ue = gsl_vector_short_calloc(n);
                gsl_vector_short_set(Ue, a, 1);
                gsl_vector_short_set(Ue, b, 1);
                SETEAP(graph, "Ue", e, Ue);

                // Conditioned set.
                SETEAN(graph, "Cea", e, a + 1);
                SETEAN(graph, "Ceb", e, b + 1);
                Cea = EAN(graph, "Cea", e);
                Ceb = EAN(graph, "Ceb", e);

                // Calculate the weight of the edge.
                u = VAP(graph, "h", a);
                v = VAP(graph, "h", b);
                u_rank = VAP(graph, "hrank", a);
                v_rank = VAP(graph, "hrank", b);
                // The conditioned set is ordered to make the order of the
                // arguments in the bivariate copulas unique as suggested in
                // Czado, C. (2010) Pair-Copula Constructions of Multivariate
                // Copulas. In Jaworski, P. and Durante, F. and Hardle, W. K.
                // and Rychlik, T. (eds.) Copula Theory and Its Applications,
                // Springer-Verlag, 93-109.
                if (Cea < Ceb) {
                    rvine_set_weight(graph, weight, e, u, v, u_rank, v_rank);
                } else {
                    rvine_set_weight(graph, weight, e, v, u, v_rank, u_rank);
                }
            }
        } else {
            igraph_empty(graph, n - k, IGRAPH_UNDIRECTED);

            // Adding all "possible" edges.
            for (a = 0; a < igraph_vcount(graph) - 1; a++) {
                for (b = a + 1; b < igraph_vcount(graph); b++) {
                    igraph_edge(trees[k - 1], a, &aa, &ab);
                    igraph_edge(trees[k - 1], b, &ba, &bb);

                    // Checking the proximity condition.
                    if (aa == ba || aa == bb || ab == ba || ab == bb) {
                        igraph_add_edge(graph, a, b);
                        igraph_get_eid(graph, &e, a, b, IGRAPH_UNDIRECTED, 1);

                        // Variables "connected" by this edge and conditioned set.
                        Ua = EAP(trees[k - 1], "Ue", a);
                        Ub = EAP(trees[k - 1], "Ue", b);
                        Ue = gsl_vector_short_calloc(n);
                        for (size_t i = 0; i < n; i++) {
                            gsl_vector_short_set(Ue, i,
                                    gsl_vector_short_get(Ua, i)
                                            | gsl_vector_short_get(Ub, i));
                            if (gsl_vector_short_get(Ua, i)
                                    && !gsl_vector_short_get(Ub, i)) {
                                SETEAN(graph, "Cea", e, i + 1);
                            }
                            if (gsl_vector_short_get(Ub, i)
                                    && !gsl_vector_short_get(Ua, i)) {
                                SETEAN(graph, "Ceb", e, i + 1);
                            }
                        }
                        SETEAP(graph, "Ue", e, Ue);
                    }
                }
            }

            // Compute pseudo-observations and edge weights.
            for (a = 0; a < igraph_vcount(graph); a++) {
                // See the comment in the code for the first tree.
                SETVAP(graph, "h", a, NULL);
                SETVAP(graph, "hrev", a, NULL);
                SETVAP(graph, "hrank", a, NULL);
                SETVAP(graph, "hrevrank", a, NULL);
            }
            for (e = 0; e < igraph_ecount(graph); e++) {
                igraph_edge(graph, e, &a, &b);
                Cea = EAN(graph, "Cea", e);
                Ceb = EAN(graph, "Ceb", e);

                // Assign u and u_rank.
                if ((Cea == EAN(trees[k - 1], "Cea", a)
                        && (EAN(trees[k - 1], "Cea", a)
                                < EAN(trees[k - 1], "Ceb", a)))
                        || (Cea != EAN(trees[k - 1], "Cea", a)
                                && (EAN(trees[k - 1], "Cea", a)
                                        > EAN(trees[k - 1], "Ceb", a)))) {
                    u = VAP(graph, "h", a);
                    if (u == NULL) {
                        copula = EAP(trees[k - 1], "copula", a);
                        measure = EAP(trees[k - 1], "measure", a);
                        u = gsl_vector_alloc(m);
                        dml_copula_h(copula, measure->x, measure->y, u);
                        SETVAP(graph, "h", a, u);
                        gsl_sort_vector_index(perm, u);
                        rank = gsl_permutation_alloc(m);
                        gsl_permutation_inverse(rank, perm);
                        SETVAP(graph, "hrank", a, rank);
                    }
                    u_rank = VAP(graph, "hrank", a);
                }
                if ((Cea == EAN(trees[k - 1], "Cea", a)
                        && (EAN(trees[k - 1], "Cea", a)
                                > EAN(trees[k - 1], "Ceb", a)))
                        || (Cea != EAN(trees[k - 1], "Cea", a)
                                && (EAN(trees[k - 1], "Cea", a)
                                        < EAN(trees[k - 1], "Ceb", a)))) {
                    u = VAP(graph, "hrev", a);
                    if (u == NULL) {
                        copula = EAP(trees[k - 1], "copula", a);
                        measure = EAP(trees[k - 1], "measure", a);
                        u = gsl_vector_alloc(m);
                        dml_copula_h(copula, measure->y, measure->x, u);
                        SETVAP(graph, "hrev", a, u);
                        gsl_sort_vector_index(perm, u);
                        rank = gsl_permutation_alloc(m);
                        gsl_permutation_inverse(rank, perm);
                        SETVAP(graph, "hrevrank", a, rank);
                    }
                    u_rank = VAP(graph, "hrevrank", a);
                }

                // Assign v and v_rank.
                if ((Ceb == EAN(trees[k - 1], "Cea", b)
                        && (EAN(trees[k - 1], "Cea", b)
                                < EAN(trees[k - 1], "Ceb", b)))
                        || (Ceb != EAN(trees[k - 1], "Cea", b)
                                && (EAN(trees[k - 1], "Cea", b)
                                        > EAN(trees[k - 1], "Ceb", b)))) {
                    v = VAP(graph, "h", b);
                    if (v == NULL) {
                        copula = EAP(trees[k - 1], "copula", b);
                        measure = EAP(trees[k - 1], "measure", b);
                        v = gsl_vector_alloc(m);
                        dml_copula_h(copula, measure->x, measure->y, v);
                        SETVAP(graph, "h", b, v);
                        gsl_sort_vector_index(perm, v);
                        rank = gsl_permutation_alloc(m);
                        gsl_permutation_inverse(rank, perm);
                        SETVAP(graph, "hrank", b, rank);
                    }
                    v_rank = VAP(graph, "hrank", b);

                }
                if ((Ceb == EAN(trees[k - 1], "Cea", b)
                        && (EAN(trees[k - 1], "Cea", b)
                                > EAN(trees[k - 1], "Ceb", b)))
                        || (Ceb != EAN(trees[k - 1], "Cea", b)
                                && (EAN(trees[k - 1], "Cea", b)
                                        < EAN(trees[k - 1], "Ceb", b)))) {
                    v = VAP(graph, "hrev", b);
                    if (v == NULL) {
                        copula = EAP(trees[k - 1], "copula", b);
                        measure = EAP(trees[k - 1], "measure", b);
                        v = gsl_vector_alloc(m);
                        dml_copula_h(copula, measure->y, measure->x, v);
                        SETVAP(graph, "hrev", b, v);
                        gsl_sort_vector_index(perm, v);
                        rank = gsl_permutation_alloc(m);
                        gsl_permutation_inverse(rank, perm);
                        SETVAP(graph, "hrevrank", b, rank);
                    }
                    v_rank = VAP(graph, "hrevrank", b);
                }

                // Set the weight of the edge. The arguments are ordered here.
                // The order determines the x and y fields of measure.
                if (Cea < Ceb) {
                    rvine_set_weight(graph, weight, e, u, v, u_rank, v_rank);
                } else {
                    rvine_set_weight(graph, weight, e, v, u, v_rank, u_rank);
                }
            }
        }

        // Compute the minimum weight spanning tree.
        trees[k] = g_malloc(sizeof(igraph_t));
        igraph_vector_init(graph_weight, igraph_ecount(graph));
        EANV(graph, "weight", graph_weight);
        igraph_minimum_spanning_tree_prim(graph, trees[k], graph_weight);
        igraph_vector_destroy(graph_weight);

        tree_aic = 0;
        for (e = 0; e < igraph_ecount(trees[k]); e++) {
            igraph_edge(trees[k], e, &a, &b);
            Cea = EAN(trees[k], "Cea", e);
            Ceb = EAN(trees[k], "Ceb", e);
            measure = EAP(trees[k], "measure", e);

            // Assign a bivariate copula to the edge.
            if (Cea < Ceb) {
                copula = dml_copula_select(measure->x, measure->y, measure,
                                           indeptest, indeptest_level, types,
                                           types_size, select, rng);
                // Get information for the truncation of the vine.
                if (trunc == DML_VINE_TRUNC_AIC) {
                    dml_copula_aic(copula, measure->x, measure->y, &copula_aic);
                    tree_aic += copula_aic;
                }
            } else {
                copula = dml_copula_select(measure->y, measure->x, measure,
                                           indeptest, indeptest_level, types,
                                           types_size, select, rng);
                // Get information for the truncation of the vine.
                if (trunc == DML_VINE_TRUNC_AIC) {
                    dml_copula_aic(copula, measure->y, measure->x, &copula_aic);
                    tree_aic += copula_aic;
                }
            }
            SETEAP(trees[k], "copula", e, copula);
        }

        igraph_destroy(graph);

        // Check if the vine should be truncated.
        if (trunc == DML_VINE_TRUNC_AIC && tree_aic >= 0) {
            // Free the memory used for the last tree.
            rvine_tree_cleanup(trees[k]);
            for (e = 0; e < igraph_ecount(trees[k]); e++) {
                copula = EAP(trees[k], "copula", e);
                dml_copula_free(copula);
            }
            igraph_destroy(trees[k]);
            g_free(trees[k]);
            trees[k] = NULL;
            break;
        }

        if (k > 0) rvine_tree_cleanup(trees[k - 1]);
    }

    // Cleanup the last tree if the vine was completely estimated.
    // If the vine was truncated, the last tree will be freed in
    // the function vine_fit_rvine, because the rvine_trees_to_vine
    // function needs some attributes of its edges.
    if (k == n - 1) {
        rvine_tree_cleanup(trees[n - 2]);
    }

    g_free(graph_weight);
    g_free(graph);
    gsl_permutation_free(perm);
}