Node* AddExactLNode::Ideal(PhaseGVN* phase, bool can_reshape) {
  Node* arg1 = in(1);
  Node* arg2 = in(2);

  const Type* type1 = phase->type(arg1);
  const Type* type2 = phase->type(arg2);

  if (type1 != Type::TOP && type1->singleton() &&
      type2 != Type::TOP && type2->singleton()) {
    jlong val1 = arg1->get_long();
    jlong val2 = arg2->get_long();
    jlong result = val1 + val2;
    // Hacker's Delight 2-12 Overflow if both arguments have the opposite sign of the result
    if ( (((val1 ^ result) & (val2 ^ result)) >= 0)) {
      Node* con_result = ConLNode::make(phase->C, result);
      return no_overflow(phase, con_result);
    }
    return NULL;
  }

  if (type1 == TypeLong::ZERO || type2 == TypeLong::ZERO) { // (Add 0 x) == x
    Node* add_result = new (phase->C) AddLNode(arg1, arg2);
    return no_overflow(phase, add_result);
  }

  if (type2->singleton()) {
    return NULL; // no change - keep constant on the right
  }

  if (type1->singleton()) {
    // Make it x + Constant - move constant to the right
    swap_edges(1, 2);
    return this;
  }

  if (arg2->is_Load()) {
    return NULL; // no change - keep load on the right
  }

  if (arg1->is_Load()) {
    // Make it x + Load - move load to the right
    swap_edges(1, 2);
    return this;
  }

  if (arg1->_idx > arg2->_idx) {
    // Sort the edges
    swap_edges(1, 2);
    return this;
  }

  return NULL;
}
Exemple #2
0
//**********************************************************************
//**********************************************************************
///a function that do a rewiring preserving the degree distribution
int rewiring_Pk(GRAPH* G,int num_rewires,gsl_rng * randgsl){
	
    printf("Rewiring preserving P(k)...\n");fflush(stdout);
    
	int i,pos_r,pos_s,r1,r2,s1,s2;
	
	for(i=0;i<num_rewires*G->E;++i){

		while(!choose_2_edges_random(G,&pos_r,&pos_s,randgsl)){} ///we try to find two edges avoiding selfedges and multipledges

		r1 = G->edge[pos_r].s;		/// the nodes first link are
		r2 = G->edge[pos_r].d;
		     
		s1 = G->edge[pos_s].s;		/// the nodes second link are
		s2 = G->edge[pos_s].d;
		
		swap_edges(G,s1,s2,r1,r2);	/// we swap the two links

		G->edge[pos_r].d = s2;		/// we modify the edge vector
		G->edge[pos_s].d = r2;
		
	}
	
	return 1;
}
//_________________________________________________________________________
double graph_molloy_hash::effective_K(int K, int quality) {
  if(K<3) return 0.0;
  long sum_K = 0;
  int *Kbuff = new int[K];
  bool *visited = new bool[n];
  int i;
  for(i=0; i<n; i++) visited[i] = false;
  for(int i=0; i<quality; i++) {
    // assert(verify());
    int f1,f2,t1,t2;
    int *f1t1, *f2t2;
    do {
      // Pick two random vertices
      do {
        f1 = pick_random_vertex();
        f2 = pick_random_vertex();
      } while(f1==f2);
      // Pick two random neighbours
      f1t1 = random_neighbour(f1);
      t1 = *f1t1;
      f2t2 = random_neighbour(f2);
      t2 = *f2t2;
      // test simplicity
    }
    while (t1==t2 || f1==t2 || f2==t1 || is_edge(f1,t2) || is_edge(f2,t1));
    // swap
    swap_edges(f1,t2,f2,t1);
    // assert(verify());
    sum_K += effective_isolated(deg[f1]>deg[t2] ? f1 : t2, K, Kbuff, visited);
    // assert(verify());
    sum_K += effective_isolated(deg[f2]>deg[t1] ? f2 : t1, K, Kbuff, visited);
    // assert(verify());
    // undo swap
    swap_edges(f1,t2,f2,t1);
    // assert(verify());
  }
  delete[] Kbuff;
  delete[] visited;
  return double(sum_K)/double(2*quality);
}
Exemple #4
0
//=============================================================================
//------------------------------Ideal------------------------------------------
// Check for power-of-2 multiply, then try the regular MulNode::Ideal
Node *MulINode::Ideal(PhaseGVN *phase, bool can_reshape) {
  // Swap constant to right
  jint con;
  if( in(1)->get_int( &con ) ) {
    swap_edges(1, 2);
    // Finish rest of method to use info in 'con'
  } else if( !in(2)->get_int( &con ) ) 
    return MulNode::Ideal(phase, can_reshape);
 
  // Now we have a constant Node on the right and the constant in con
  if( con == 0 ) return NULL;   // By zero is handled by Value call
  if( con == 1 ) return NULL;   // By one  is handled by Identity call

  // Check for negative constant; if so negate the final result
  bool sign_flip = false;
  if( con < 0 ) {
    con = -con;
    sign_flip = true;
  }

  // Get low bit; check for being the only bit
  Node *res = NULL;
  int bit1 = con & -con;        // Extract low bit
  if( bit1 == con ) {           // Found a power of 2?
    res = new (3) LShiftINode( in(1), phase->intcon(log2_intptr(bit1)) );
  } else {

    // Check for constant with 2 bits set
    int bit2 = con-bit1;
    bit2 = bit2 & -bit2;          // Extract 2nd bit
    if( bit2 + bit1 == con ) {    // Found all bits in con?
      Node *n1 = phase->transform( new (3) LShiftINode( in(1), phase->intcon(log2_intptr(bit1)) ) );
      Node *n2 = phase->transform( new (3) LShiftINode( in(1), phase->intcon(log2_intptr(bit2)) ) );
      res = new (3) AddINode( n2, n1 );

    // Sleezy: power-of-2 -1.  Next time be generic.
    } else if( is_power_of_2(con+1) ) {
      int temp = (int) (con + 1);
      Node *n1 = phase->transform( new (3) LShiftINode( in(1), phase->intcon(log2_intptr(temp)) ) );
      res = new (3) SubINode( n1, in(1) );
    } else {
      return MulNode::Ideal(phase, can_reshape);
    }
  }

  if( sign_flip ) {             // Need to negate result?
    res = phase->transform(res);// Transform, before making the zero con
    res = new (3) SubINode(phase->intcon(0),res);
  }

  return res;                   // Return final result
}
//=============================================================================
//------------------------------Idealize---------------------------------------
// MINs show up in range-check loop limit calculations.  Look for
// "MIN2(x+c0,MIN2(y,x+c1))".  Pick the smaller constant: "MIN2(x+c0,y)"
Node *MinINode::Ideal(PhaseGVN *phase, bool can_reshape) {
  Node *progress = NULL;
  // Force a right-spline graph
  Node *l = in(1);
  Node *r = in(2);
  // Transform  MinI1( MinI2(a,b), c)  into  MinI1( a, MinI2(b,c) )
  // to force a right-spline graph for the rest of MinINode::Ideal().
  if( l->Opcode() == Op_MinI ) {
    assert( l != l->in(1), "dead loop in MinINode::Ideal" );
    r = phase->transform(new (phase->C) MinINode(l->in(2),r));
    l = l->in(1);
    set_req(1, l);
    set_req(2, r);
    return this;
  }

  // Get left input & constant
  Node *x = l;
  int x_off = 0;
  if( x->Opcode() == Op_AddI && // Check for "x+c0" and collect constant
      x->in(2)->is_Con() ) {
    const Type *t = x->in(2)->bottom_type();
    if( t == Type::TOP ) return NULL;  // No progress
    x_off = t->is_int()->get_con();
    x = x->in(1);
  }

  // Scan a right-spline-tree for MINs
  Node *y = r;
  int y_off = 0;
  // Check final part of MIN tree
  if( y->Opcode() == Op_AddI && // Check for "y+c1" and collect constant
      y->in(2)->is_Con() ) {
    const Type *t = y->in(2)->bottom_type();
    if( t == Type::TOP ) return NULL;  // No progress
    y_off = t->is_int()->get_con();
    y = y->in(1);
  }
  if( x->_idx > y->_idx && r->Opcode() != Op_MinI ) {
    swap_edges(1, 2);
    return this;
  }


  if( r->Opcode() == Op_MinI ) {
    assert( r != r->in(2), "dead loop in MinINode::Ideal" );
    y = r->in(1);
    // Check final part of MIN tree
    if( y->Opcode() == Op_AddI &&// Check for "y+c1" and collect constant
        y->in(2)->is_Con() ) {
      const Type *t = y->in(2)->bottom_type();
      if( t == Type::TOP ) return NULL;  // No progress
      y_off = t->is_int()->get_con();
      y = y->in(1);
    }

    if( x->_idx > y->_idx )
      return new (phase->C) MinINode(r->in(1),phase->transform(new (phase->C) MinINode(l,r->in(2))));

    // See if covers: MIN2(x+c0,MIN2(y+c1,z))
    if( !phase->eqv(x,y) ) return NULL;
    // If (y == x) transform MIN2(x+c0, MIN2(x+c1,z)) into
    // MIN2(x+c0 or x+c1 which less, z).
    return new (phase->C) MinINode(phase->transform(new (phase->C) AddINode(x,phase->intcon(MIN2(x_off,y_off)))),r->in(2));
  } else {
    // See if covers: MIN2(x+c0,y+c1)
    if( !phase->eqv(x,y) ) return NULL;
    // If (y == x) transform MIN2(x+c0,x+c1) into x+c0 or x+c1 which less.
    return new (phase->C) AddINode(x,phase->intcon(MIN2(x_off,y_off)));
  }

}
//**********************************************************************
//**********************************************************************
int rewiring_PkkCbar_annealing(GRAPH* G,double B,double increment,double accmin,int rewires,gsl_rng* randgsl){
	
    
   	double Caim = G->Ccoef;  /// this is the clustering we want to achieve
	
	
 /***********************************************************************
	 we calculate the initial clustering of the random network
 ************************************************************************/
	
	double C  = clustering_coeff(G);
    
    double Cnew = C;
    
	printf("Caim %f Cinitial %f\n",Caim,C);
    
 /***********************************************************************
	       we do the rewiring preserving the P(k,k')
 ************************************************************************/	
    
    int* numEDGESwithK = countEDGESwithK(G); /// we count how many edges with and node of degree k are

	int **pos_edges_k = createPOSedgesK(G,numEDGESwithK);
	
	int s1,s2,r1,r2,kr1,kr2,ks1,ks2,pos_r,pos_s,j=0,l=0;					/// rewiring variables that will store the proposed rewiring
	
	double p,AH;
	
	int accepted=0,rewirestemp=0,pirem=0;					/// during the proces we count how many proposals rewirings are with AH>0, AH<o and AH=0
	double averAH = 0,averAHneg = 0,averAHpos = 0,oldacc=0;
	int numAH0 = 0,numAHneg = 0,numAHpos = 0;
	
    double H = fabs(C - Caim);                              /// initial energy
	
	
	/******** we start the rewiring *************/
	
	printf("Fixing the Clustering coefficient by an anneald rewiring preserving P(k,k')...\n");fflush(stdout);
	
	time_t start,end;										/// we will measure the time
	double dif;
	time (&start);
	
	FILE *ftemp = fopen("E_vs_T.dat","w");
	fprintf(ftemp,"#B\tEnergy\tacceptance\n");
	
    int i;
	for(i=1; oldacc>accmin || i<rewires*G->E+2 ;++i){
		
		
        /**** we propose a swap *********/			
		while(!choose_2_edges_random_pkk(G,&pos_r,&pos_s,numEDGESwithK,pos_edges_k,randgsl)){} /// we try to find two edges avoiding selfedges and multipledges
		
		r1 = G->edge[pos_r].s;		/// the nodes and its degree are
		r2 = G->edge[pos_r].d;
		
        kr1 = G->node[r1].k;
		kr2 = G->node[r2].k;
        
        s1 = G->edge[pos_s].s;
		s2 = G->edge[pos_s].d;
        
        ks1 = G->node[s1].k;
		ks2 = G->node[s2].k;
        
        /**** we calculate the increment of energy *********/
		AH = calc_AH_PkkCbar(G,s1,s2,r1,r2,C,&Cnew,Caim);	/// we calculate the increment of energy that would cause the rewiring
		
		averAH = averAH + fabs(AH);					    ///we also counbt the average AH of the proposals
		
		if(AH < 0.) {								    /// we count how many proposals have AH > 0
			
			numAHneg++;
			averAHneg = averAHneg + AH;
		}
		else if (AH > 0.) {							    /// we count how many proposals have AH < 0
			
			numAHpos++;
			averAHpos = averAHpos + AH;
			
		}
		else numAH0++;								/// we count how many proposals have AH = 0
		
		p =  gsl_rng_uniform(randgsl);				/// we throw a random number (0,1)
		
		/********** IF we acccept **************/
		
		if( p < exp(-B*AH) ){						
			
			
			swap_edges(G,s1,s2,r1,r2);			/// we make the proposed rewired
			
						
		    G->edge[pos_r].d = s2;						/// we modify the edge vector
            G->edge[pos_s].d = r2;
			
						
			if(kr2!=ks2){								///we modify the vector pos_edges_k
			
		    	if(kr2!=kr1){
		    		for(j=0;j<numEDGESwithK[kr2];++j){if(pos_edges_k[kr2][j]==pos_r){break;}}
		    	}
		    	if(ks2!=ks1){
		    		for(l=0;l<numEDGESwithK[ks2];++l){if(pos_edges_k[ks2][l]==pos_s){break;}}
		    	}
		    	
		    	
		    	if     (kr2!=kr1 && ks2==ks1)  pos_edges_k[kr2][j] = pos_s;    
		    	else if(ks2!=ks1 && kr2==kr1)  pos_edges_k[ks2][l] = pos_r;
		    	else if(kr2!=kr1 && ks2!=ks1){									/// in case the two other nodes have different degree we just swap the positions of the edges
		    		pos_edges_k[kr2][j] = pos_s;  
		    		pos_edges_k[ks2][l] = pos_r;
		    	}
		    	
		    	j=0;
		    	l=0;
		    	
		    }
		    	
				
			C = Cnew;	/// we update the clustering vector
			
			if(fabs(AH)>0.)	accepted++;					/// we count how many changes we accept
			
			H = H + AH;
		}
		
		/********** IF we reject **************/
		
		else {								
			
			Cnew = C;	/// we recover the old clustering vector
		}
		
		rewirestemp++;
		
		/********** we reduce the temperature and we check the acceptance **************/
		
		if(rewirestemp > rewires*G->E ) {	///we try to find the appropiate temperature in order to have the desire acceptation
			
			printf("acceptance rate = %f "                ,(double)accepted/(numAHneg+numAHpos));				/// the acceptance
			//printf("AH = %f "                 ,averAH/(numAHneg+numAHpos));							/// the average energy of the proposed swaps
			//printf("numAHneg = %f AHneg = %e ",(double)numAHneg/rewirestemp,averAHneg/numAHneg);	/// the proportion of negative energy swaps and the average
			//printf("numAHpos = %f AHpos = %e ",(double)numAHpos/rewirestemp,averAHpos/numAHpos);	/// the proportion of positive energy swaps and the average
			//printf("numAH0=%f "               ,(double)numAH0/rewirestemp);							/// the proportion of proposals that do not change the energy
			printf("Beta=%e Energy=%e\n"              ,B,H);												/// the temperature and the energy
			fflush(stdout);
			
			fprintf(ftemp,"%f\t%f\t%f\n",B,H,(double)accepted/(numAHneg+numAHpos));
			
			if( ((double)accepted/(numAHneg+numAHpos)) > oldacc && i > rewires*G->E + 2 ) pirem++;	/// in case we havethe acceptance has increased 10 times the rewiring proces
			if(pirem>30) break;
			
			oldacc		= ((double)accepted/(numAHneg+numAHpos));								/// we save the old acceptance in order to compare with the next one
			accepted    = 0;												/// we put to zero all the acceptance counters
			rewirestemp = 0;
			averAH      = 0; numAHneg = 0;averAHneg = 0;
			numAH0      = 0; numAHpos = 0;averAHpos = 0;
			
			B = B*increment;												/// we reduce the temperature
			
		}
		
					
	}
	
	
	time (&end);									///we count the rewiring time and take conclusions
	dif = difftime (end,start);
	printf ("You rewired the entire network %.2f times and it took %.2lf seconds to run.\n",(double)i/G->E, dif );
	
 /***********************************************************************
		we print the network and we free the memory	
 ************************************************************************/
	
    printf("Cfinal %f\n",C);
		
	fclose(ftemp);
	
    free(numEDGESwithK);
	for(i=1;i<G->max_k+1;++i){free(pos_edges_k[i]);}
    free(pos_edges_k);
	
	
	
	return 0;
	
}
Exemple #7
0
//------------------------------Ideal------------------------------------------
// We also canonicalize the Node, moving constants to the right input, 
// and flatten expressions (so that 1+x+2 becomes x+3).
Node *MulNode::Ideal(PhaseGVN *phase, bool can_reshape) {
  const Type *t1 = phase->type( in(1) );
  const Type *t2 = phase->type( in(2) );
  Node *progress = NULL;        // Progress flag
  // We are OK if right is a constant, or right is a load and
  // left is a non-constant.
  if( !(t2->singleton() ||
        (in(2)->is_Load() && !(t1->singleton() || in(1)->is_Load())) ) ) {
    if( t1->singleton() ||       // Left input is a constant?
        // Otherwise, sort inputs (commutativity) to help value numbering.
        (in(1)->_idx > in(2)->_idx) ) {
      swap_edges(1, 2);
      const Type *t = t1;
      t1 = t2;
      t2 = t;
      progress = this;            // Made progress
    }
  }

  // If the right input is a constant, and the left input is a product of a
  // constant, flatten the expression tree.
  uint op = Opcode();
  if( t2->singleton() &&        // Right input is a constant?
      op != Op_MulF &&          // Float & double cannot reassociate
      op != Op_MulD ) { 
    if( t2 == Type::TOP ) return NULL;
    Node *mul1 = in(1);
    if( mul1 == this ) {        // Check for dead cycle
      set_req(1, phase->C->top());
      return this;              // Make it trivially dead
    }
    if( mul1->Opcode() == mul_opcode() ) {  // Left input is a multiply?
      // Mul of a constant?
      const Type *t12 = phase->type( mul1->in(2) ); 
      if( t12->singleton() && t12 != Type::TOP) { // Left input is an add of a constant?
        // Compute new constant; check for overflow
        const Type *tcon01 = mul1->is_Mul()->mul_ring(t2,t12);
        if( tcon01->singleton() ) {
          // The Mul of the flattened expression
          set_req(1, mul1->in(1));
          set_req(2, phase->makecon( tcon01 ));
          t2 = tcon01;
          progress = this;      // Made progress
        }
      }
    }
    // If the right input is a constant, and the left input is an add of a 
    // constant, flatten the tree: (X+con1)*con0 ==> X*con0 + con1*con0
    const Node *add1 = in(1);
    if( add1->Opcode() == add_opcode() ) {      // Left input is an add?
      // Add of a constant?
      const Type *t12 = phase->type( add1->in(2) ); 
      if( t12->singleton() && t12 != Type::TOP ) { // Left input is an add of a constant?
        // Check if the add node is dead and self-referencing, 
        // to avoid infinite loop (no progress).
        if( add1->in(1) == add1 ) return progress;
        // Compute new constant; check for overflow
        const Type *tcon01 = mul_ring(t2,t12);
        if( tcon01->singleton() ) {
        
        // Convert (X+con1)*con0 into X*con0
          Node *mul = clone();    // mul = ()*con0
          mul->set_req(1,add1->in(1));  // mul = X*con0
          mul = phase->transform(mul);

          Node *add2 = add1->clone();
          add2->set_req(1, mul);        // X*con0 + con0*con1
          add2->set_req(2, phase->makecon(tcon01) );
          progress = add2;
        }
      }
    } // End of is left input an add
  } // End of is right input a Mul

  return progress;
}
Exemple #8
0
//**********************************************************************
//**********************************************************************
///a function that do a rewiring preserving the joint degree distribution P(k,k')
int rewiring_Pkk(GRAPH* G,int num_rewires,gsl_rng * randgsl){
	
    int* numEDGESwithK = countEDGESwithK(G); /// we count how many edges with and node of degree k are

	int **pos_edges_k = createPOSedgesK(G,numEDGESwithK);
	
	int i,s1,s2,r1,r2,kr1,kr2,ks1,ks2,pos_r,pos_s,j=0,l=0;					/// rewiring variables that will store the proposed rewiring
	
    /******** we start the rewiring *************/
	
	printf("Rewiring preserving P(k,k')...\n");fflush(stdout);
	

	for(i=1; i<num_rewires*G->E ;++i){
		
		
		while(!choose_2_edges_random_pkk(G,&pos_r,&pos_s,numEDGESwithK,pos_edges_k,randgsl)){} /// we try to find two edges avoiding selfedges and multipledges
		
		r1 = G->edge[pos_r].s;		/// the nodes and its degree are
		r2 = G->edge[pos_r].d;
		
        kr1 = G->node[r1].k;
		kr2 = G->node[r2].k;
        
        s1 = G->edge[pos_s].s;
		s2 = G->edge[pos_s].d;
        
        ks1 = G->node[s1].k;
		ks2 = G->node[s2].k;
		
		swap_edges(G,s1,s2,r1,r2);		/// we make the proposed rewired
		
		
		G->edge[pos_r].d = s2;			/// we modify the edge vector
		G->edge[pos_s].d = r2;
		
				
		if(kr2!=ks2){					///we modify the vector pos_edges_k
			
			if(kr2!=kr1){
				for(j=0;j<numEDGESwithK[kr2];++j){if(pos_edges_k[kr2][j]==pos_r){break;}}
			}
			if(ks2!=ks1){
				for(l=0;l<numEDGESwithK[ks2];++l){if(pos_edges_k[ks2][l]==pos_s){break;}}
			}
			
			
			if     (kr2!=kr1 && ks2==ks1)  pos_edges_k[kr2][j] = pos_s;    
			else if(ks2!=ks1 && kr2==kr1)  pos_edges_k[ks2][l] = pos_r;
			else if(kr2!=kr1 && ks2!=ks1){									/// in case the two other nodes have different degree we just swap the positions of the edges
				pos_edges_k[kr2][j] = pos_s;  
				pos_edges_k[ks2][l] = pos_r;
			}
			
			j=0;
			l=0;
			
		}
		
		
	}
    
	free(numEDGESwithK);
	for(i=1;i<G->max_k+1;++i){free(pos_edges_k[i]);}
    free(pos_edges_k);
	
	return 0;
}
Exemple #9
0
//**********************************************************************
//**********************************************************************
int rewiring_Cbar_annealing(GRAPH G,double B,double increment,double accmin,int rewires,gsl_rng* randgsl){
	
	
	double Caim = G.Ccoef;
    
 /***********************************************************************
	 we create a random network with the same degree sequence 
 ************************************************************************/
	
	rewiring_Pk(G,rewires,randgsl);
    
    double C  = clustering_coeff(G);
    
    double Cnew = C;
    
	printf("Caim %f Cinitial %f\n",Caim,C);
 /***********************************************************************
	       we do the rewiring preserving the C(k)
 ************************************************************************/	
	
	int s1,s2,r1,r2,pos_r,pos_s;						    /// rewiring variables that will store the proposed rewiring
	
	double p,AH;
	int accepted=0,rewirestemp=0,pirem=0;					/// during the proces we count how many proposals rewirings are with AH>0, AH<o and AH=0
	double averAH = 0,averAHneg = 0,averAHpos = 0,oldacc=0;
	int numAH0 = 0,numAHneg = 0,numAHpos = 0;
		
	double H = fabs(C - Caim);                              /// initial energy
	
		
	/******** we start the rewiring *************/
	
	printf("Annealed rewiring fixing the clustering coefficient...\n");fflush(stdout);
	
	time_t start,end;										/// we will measure the time
	double dif;
	time (&start);
	
	int i;	
	for(i=1; oldacc>accmin || i<rewires*G.E+2 ;++i){
		
					
		while(!choose_2_edges_random(G,&pos_r,&pos_s,randgsl)){} /// we try to find two edges avoiding selfedges and multipledges
		
		r1 = G.edge[pos_r].s;								/// the nodes are
		r2 = G.edge[pos_r].d; 
		
		s1 = G.edge[pos_s].s;
		s2 = G.edge[pos_s].d;
		
		AH = calc_AH_Cbar(G,s1,s2,r1,r2,C,&Cnew,Caim);	    /// we calculate the increment of energy that would cause the rewiring
		
		averAH = averAH + fabs(AH);							///we also counbt the average AH of the proposals
		
		if(AH < 0.) {										/// we count how many proposals have AH > 0
			
			numAHneg++;
			averAHneg = averAHneg + AH;
		}
		else if (AH > 0.) {									/// we count how many proposals have AH < 0
			
			numAHpos++;
			averAHpos = averAHpos + AH;
			
		}
		else numAH0++;										/// we count how many proposals have AH = 0
		
		p =  gsl_rng_uniform(randgsl);						/// we throw a random number (0,1)
		
		/********** IF we acccept **************/
		
		if( p < exp(-B*AH) ){						
			
			
			swap_edges(G,s1,s2,r1,r2);					    /// we make the proposed rewired
			
			G.edge[pos_r].d = s2;							/// we modify the edge vector
			G.edge[pos_s].d = r2;
			
			C = Cnew;
			
			if(fabs(AH)>0.)	accepted++;						/// we coubt how many changes we accept
			
			H = H + AH;
		}
		
		/********** IF we reject **************/
		
		else {								
			
			Cnew = C;
		}
		
		rewirestemp++;
		
		/********** we reduce the temperature and we check the acceptance **************/
		
		if(rewirestemp > rewires*G.E ) {	///we try to find the appropiate temperature in order to have the desire acceptation
			
			printf("acceptance rate = %f "                ,(double)accepted/(numAHneg+numAHpos));				/// the acceptance
			//printf("AH = %f "                 ,averAH/(numAHneg+numAHpos));							/// the average energy of the proposed swaps
			//printf("numAHneg = %f AHneg = %e ",(double)numAHneg/rewirestemp,averAHneg/numAHneg);	/// the proportion of negative energy swaps and the average
			//printf("numAHpos = %f AHpos = %e ",(double)numAHpos/rewirestemp,averAHpos/numAHpos);	/// the proportion of positive energy swaps and the average
			//printf("numAH0=%f "               ,(double)numAH0/rewirestemp);							/// the proportion of proposals that do not change the energy
			printf("Beta=%e Energy=%e\n"              ,B,H);												/// the temperature and the energy
			fflush(stdout);
			
			if( ((double)accepted/(numAHneg+numAHpos)) > oldacc && i > rewires*G.E + 2 ) pirem++;	/// in case we havethe acceptance has increased 10 times the rewiring proces
			if(pirem>30) break;
			
			oldacc		= ((double)accepted/(numAHneg+numAHpos));								/// we save the old acceptance in order to compare with the next one
			accepted    = 0;												/// we put to zero all the acceptance counters
			rewirestemp = 0;
			averAH      = 0; numAHneg = 0;averAHneg = 0;
			numAH0      = 0; numAHpos = 0;averAHpos = 0;
			
			B = B*increment;												/// we reduce the temperature
			
		}
		
					
	}
	
      

	time (&end);											///we count the rewiring time and take conclusions
	dif = difftime (end,start);
	printf ("You rewired the entire network %.2f times with %.2lf seconds.\n",(double)i/G.E, dif );
	printf("Cfinal %f\n",C);
    
 /***********************************************************************
		 we free the memory
 ************************************************************************/
	

	
	return 0;
	
}