bool incremental_closure_opt_dense(opt_oct_mat_t *oo, int dim, int v, bool is_int){
	double *m = oo->mat;
	int n = 2*dim;
	int ii = 2*v + 1;
	int j;
	double *temp1, *temp2;
	temp1 = (double *)calloc(2*dim, sizeof(double));
  	temp2 = (double *)calloc(2*dim, sizeof(double));
	/******
		incremental Floyd-Warshall : v in end-point position 
	******/
	for(unsigned k = 0; k < n; k=k + 2){
		
		int v1 = 2*v;
		int v2 = 2*v + 1;
		int v1v2 = v2 + (((v1 + 1)*(v1 + 1))/2);
		int v2v1 = v1 + (((v2 + 1)*(v2 + 1))/2);
		int kk = (k^1);
		int br1 = k < v1 ? k : v1;
		int br2 = kk < v1 ? kk : v1;
		/*int v1v2 = v2 + (((v1 + 1)*(v1 + 1))/2);
		int v2v1 = v1 + (((v2 + 1)*(v2 + 1))/2);
		int v1k = k + (((v1 + 1)*(v1 + 1))/2);
		int v2k = k +  (((v2 + 1)*(v2 + 1))/2);
		int kv1 = v1 + (((k + 1)*(k + 1))/2);
		int kv2 = v2 +  (((k + 1)*(k + 1))/2);*/
		//m[n*2*v + (2*v + 1)] = min(m[n*2*v + (2*v + 1)], m[n*2*v + k] + m[n*k + 2*v + 1]);
		//m[v1v2] = min(m[v1v2], m[v1k] + m[kv2]);
		//m[n*(2*v + 1) + 2*v] = min(m[n*(2*v + 1) + 2*v], m[n*(2*v + 1) + k] + m[n*k + 2*v]);
		//m[v2v1] = min(m[v2v1], m[v2k] + m[kv1]);
		for(unsigned i = 2*v; i < 2*v + 2; i++){
			//double ik = m[n*i + k];
			int ind_ik, ind_ikk;
			if(k <=i){
				ind_ik = k + (((i + 1)*(i + 1))/2);
			}
			else{
				ind_ik = (i^1) + ((((k^1) + 1)*((k^1) + 1))/2);
			}
			
			if(kk <=i){
				ind_ikk = kk + (((i + 1)*(i + 1))/2);
			}
			else{
				ind_ikk = (i^1) + ((((kk^1) + 1)*((kk^1) + 1))/2);
			}
			double ik = m[ind_ik];
			double ikk = m[ind_ikk];
			v_double_type vik = v_set1_double(m[ind_ik]);
			v_double_type vikk = v_set1_double(m[ind_ikk]);
			//double ki = m[n*k + i];
			int ind_ki, ind_kki;
			if ( k <= i){
				ind_ki = (k^1) + ((((i^1) + 1)*((i^1) + 1))/2);
			}
			else{
				ind_ki = i + (((k + 1)*(k + 1))/2);
			}

			if ( kk <= i){
				ind_kki = (kk^1) + ((((i^1) + 1)*((i^1) + 1))/2);
			}
			else{
				ind_kki = i + (((kk + 1)*(kk + 1))/2);
			}
			
			//int ind_ki = i + (((k + 1)*(k + 1))/2);
			double ki = m[ind_ki];	
			double kki = m[ind_kki];
			/******* 
				v in first end-point position.
				This part is vectorized. 
			********/		
			for(j = 0; j <br1/v_length; j++){
				//double kj = m[n*k + j];
				int ind_kj = j*v_length + (((k + 1)*(k + 1))/2);
				v_double_type vkj = v_load_double(m+ind_kj);
				int ind_kkj = j*v_length + (((kk + 1)*(kk + 1))/2);
				v_double_type vkkj = v_load_double(m+ind_kkj);
				//double jk = m[n*j + k];
				//int ind_jk = k + (((j + 1)*(j + 1))/2);
				//double jk = m[ind_jk];
				//m[n*i + j] = min(m[n*i + j], ik + kj);
				int ind_ij = j*v_length + (((i + 1)*(i + 1))/2);
				v_double_type vij = v_load_double(m+ind_ij);
				v_double_type op1 = v_add_double(vik,vkj);
				v_double_type op2 = v_add_double(vikk,vkkj);
				v_double_type op3 = v_min_double(op1, op2);
				v_double_type res = v_min_double(vij,op3);
				v_store_double(m+ind_ij,res);
				//m[n*j + i] = min(m[n*j + i], jk + ki);
			}
			for(j = (br1/v_length)*v_length; j < br1; j++){
				int ind_kj = j + (((k + 1)*(k + 1))/2);
				double kj = m[ind_kj];
				int ind_kkj = j + (((kk + 1)*(kk + 1))/2);
				double kkj = m[ind_kkj];
				int ind_ij = j + (((i + 1)*(i + 1))/2);
				m[ind_ij] = min(m[ind_ij], ik + kj);
				m[ind_ij] = min(m[ind_ij], ikk + kkj);
			}
			for(; j < v1; j++){
				//double kj = m[n*k + j];
				int ind_kj = (k^1) + ((((j^1) + 1)*((j^1) + 1))/2);
				double kj = m[ind_kj];
				int ind_kkj = (kk^1) + ((((j^1) + 1)*((j^1) + 1))/2);
				double kkj = m[ind_kkj];
				//double jk = m[n*j + k];
				int ind_ij = j + (((i + 1)*(i + 1))/2);
				//m[n*i + j] = min(m[n*i + j], ik + kj);
				m[ind_ij] = min(m[ind_ij], ik + kj);
				m[ind_ij] = min(m[ind_ij], ikk + kkj);
				//m[n*j + i] = min(m[n*j + i], jk + ki);
			}
			/****** 
				v in second end-point position.
				This part is scalar. 
			*****/
			for(j= v1+2; j < k; j++ ){
				int ind_jk = (j^1) + ((((k^1) + 1)*((k^1) + 1))/2);
				double jk = m[ind_jk];
				int ind_jkk = (j^1) + ((((kk^1) + 1)*((kk^1) + 1))/2);
				double jkk = m[ind_jkk];
				int ind_ji = i + (((j + 1)*(j + 1))/2);
				m[ind_ji] = min(m[ind_ji], jk + ki);
				m[ind_ji] = min(m[ind_ji], jkk + kki);
			}
			
			for(; j < 2*dim; j++){
				int ind_jk = k + (((j + 1)*(j + 1))/2);
				double jk = m[ind_jk];
				int ind_jkk = kk + (((j + 1)*(j + 1))/2);
				double jkk = m[ind_jkk];
				int ind_ji = i + (((j + 1)*(j + 1))/2);
				m[ind_ji] = min(m[ind_ji], jk + ki);
				m[ind_ji] = min(m[ind_ji], jkk + kki);
			}
			
		}
		m[v1v2] = min(m[v1v2],m[opt_matpos2(v1,k)] + m[opt_matpos2(k,v2)]);
		m[v1v2] = min(m[v1v2],m[opt_matpos2(v1,kk)] + m[opt_matpos2(kk,v2)]);
		m[v2v1] = min(m[v2v1],m[opt_matpos2(v2,k)] + m[opt_matpos2(k,v1)]);
		m[v2v1] = min(m[v2v1],m[opt_matpos2(v2,kk)] + m[opt_matpos2(kk,v1)]);
		
	}
	
	int v1 = (2*v);
	int v2 = (2*v)^1;
	int vi = (((v1 + 1)*(v1 + 1))/2);
	int vvi = (((v2 + 1)*(v2 + 1))/2);
	int pos1 = v2 + vi;
	//int pos2 = opt_matpos2((2*k)^1, 2*k);
	int pos2 = v1 + vvi;
	int l = (v1 + 2);
	int mod = l%v_length;
	if(mod){
		l = l + (v_length - mod);
	}
	//variable v in pivot position
	for(int i = v1 + 2; i < n;i++){
		int ind1 = v2 + (((i+1)*(i+1))/2);
		int ind2 = v1 + (((i+1)*(i+1))/2);
		m[ind1] = min(m[ind1], m[ind2] + m[pos1] );
		temp2[i^1] = m[ind1];
	}
	for(int i = v1 + 2; i < n; i++){
		int ind1 = v2 + (((i+1)*(i+1))/2);
		int ind2 = v1 + (((i+1)*(i+1))/2);
		m[ind2] = min(m[ind2], m[ind1] + m[pos2] );
		temp1[i^1] = m[ind2];
	}

	for(int j = 0; j < v1; j++){
		//int ind3 = opt_matpos2((2*k)^1,j);
		int ind3 = j + vvi;
		//int ind4 = opt_matpos2( 2*k,j);
		int ind4 = j + vi;
		//result[n*((2*k)^1) + j] = min(result[n*((2*k)^1) + j], result[n*((2*k)^1) + 2*k] + result[n*(2*k) + j]);
		m[ind3] = min(m[ind3], m[pos2] + m[ind4]);
	}
	for(int j = 0; j < v1; j++){
		//int ind3 = opt_matpos2((2*k)^1,j);
		int ind3 = j + vvi;
		//int ind4 = opt_matpos2(2*k,j);
		int ind4 = j + vi;
		//result[n*2*k + j] = min(result[n*2*k + j], result[n*2*k + ((2*k)^1)] + result[n*((2*k)^1) + j]);
		m[ind4] = min(m[ind4], m[pos1] + m[ind3]);
	}


	//for(unsigned k = 2*v; k < 2*v + 2; k++){
		/******
			 incremental Floyd-Warshall : v in pivot position.
			 This is vectorized. 
		******/
		for(unsigned i = 0; i < v1; i++){
			int i2 = (i|1);
			int br = i2;
			int j;
			int ind_ik, ind_ikk;
			//ind_ik = (i^1) + ((((k^1) + 1)*((k^1) + 1))/2);
			ind_ik = (i^1) + vvi;
			//ind_ikk = (i^1) + ((((kk^1) + 1)*((kk^1) + 1))/2);
			ind_ikk = (i^1) + vi;
			//double ik = m[n*i + k];
			v_double_type ik = v_set1_double(m[ind_ik]);
			v_double_type ikk = v_set1_double(m[ind_ikk]);
			double ikd = m[ind_ik];
			double ikkd = m[ind_ikk];
			for(j = 0; j < br/v_length; j++){
				//int ind_kj = j + (((k + 1)*(k + 1))/2);
				int ind_kj = j*v_length + vi;
				//double kj = m[n*k + j];
				//double kj = m[ind_kj];
				v_double_type kj = v_load_double(m + ind_kj);
				//int ind_kkj = j + (((kk + 1)*(kk + 1))/2);
				int ind_kkj = j*v_length + vvi;
				//double kkj = m[ind_kkj];
				v_double_type kkj = v_load_double(m + ind_kkj);
				int ind_ij = j*v_length + (((i + 1)*(i + 1))/2);
				//m[n*i + j] = min(m[n*i + j], ik + kj);
				v_double_type ij = v_load_double(m + ind_ij);
				v_double_type op1 = v_add_double(ik,kj);
				v_double_type op2 = v_add_double(ikk,kkj);
				v_double_type op3 = v_min_double(op1,op2);
				v_double_type res = v_min_double(ij,op3);
				//m[ind_ij] = min(m[ind_ij], ik + kj);
				//m[ind_ij] = min(m[ind_ij], ikk + kkj);
				v_store_double(m + ind_ij,res);
			}
			for(j = (br/v_length)*v_length; j <= br; j++){
				//int ind_kj = j + (((k + 1)*(k + 1))/2);
				int ind_kj = j + vi;
				//double kj = m[n*k + j];
				double kj = m[ind_kj];
				//int ind_kkj = j + (((kk + 1)*(kk + 1))/2);
				int ind_kkj = j + vvi;
				double kkj = m[ind_kkj];
				int ind_ij = j + (((i + 1)*(i + 1))/2);
				//m[n*i + j] = min(m[n*i + j], ik + kj);
				m[ind_ij] = min(m[ind_ij], ikd + kj);
				m[ind_ij] = min(m[ind_ij], ikkd + kkj);
			}
		}


		for(unsigned i = 2*v + 2; i < n; i++){
			int i2 = (i|1);
			int br = v1;
			int j;
			int ind_ik, ind_ikk;
			ind_ik = v1 + (((i + 1)*(i + 1))/2);				
			ind_ikk = v2 + (((i + 1)*(i + 1))/2);				
			//double ik = m[n*i + k];
			v_double_type ik = v_set1_double(m[ind_ik]);
			v_double_type ikk = v_set1_double(m[ind_ikk]);
			double ikd = m[ind_ik];
			double ikkd = m[ind_ikk];
			int b = min(l,i2);
			for(j = 0; j < br/v_length; j++){
				//int ind_kj = j + (((k + 1)*(k + 1))/2);
				int ind_kj = j*v_length + vi;
				//double kj = m[n*k + j];
				//double kj = m[ind_kj];
				v_double_type kj = v_load_double(m + ind_kj);
				//int ind_kkj = j + (((kk + 1)*(kk + 1))/2);
				int ind_kkj = j*v_length + vvi;
				//double kkj = m[ind_kkj];
				v_double_type kkj = v_load_double(m + ind_kkj);
				int ind_ij = j*v_length + (((i + 1)*(i + 1))/2);
				//m[n*i + j] = min(m[n*i + j], ik + kj);
				v_double_type ij = v_load_double(m + ind_ij);
				v_double_type op1 = v_add_double(ik,kj);
				v_double_type op2 = v_add_double(ikk,kkj);
				v_double_type op3 = v_min_double(op1,op2);
				v_double_type res = v_min_double(ij,op3);
				//m[ind_ij] = min(m[ind_ij], ik + kj);
				//m[ind_ij] = min(m[ind_ij], ikk + kkj);
				v_store_double(m + ind_ij,res);
			}
			for(j = (br/v_length)*v_length; j <= br; j++){
				//int ind_kj = j + (((k + 1)*(k + 1))/2);
				int ind_kj = j + vi;
				//double kj = m[n*k + j];
				double kj = m[ind_kj];
				//int ind_kkj = j + (((kk + 1)*(kk + 1))/2);
				int ind_kkj = j + vvi;
				double kkj = m[ind_kkj];
				int ind_ij = j + (((i + 1)*(i + 1))/2);
				//m[n*i + j] = min(m[n*i + j], ik + kj);
				m[ind_ij] = min(m[ind_ij], ikd + kj);
				m[ind_ij] = min(m[ind_ij], ikkd + kkj);
			}

			for(j = v1 + 2; j <= b; j++){
				//double kj = m[n*k + j];
				double kj = temp2[j];
				//int ind_kkj = (kk^1) + ((((j^1) + 1)*((j^1) + 1))/2);
				//int ind_kkj = temp1[j];
				double kkj = temp1[j];
				//m[n*i + j] = min(m[n*i + j], ik + kj);
				int ind_ij = j + (((i + 1)*(i + 1))/2);
				m[ind_ij] = min(m[ind_ij], ikd + kj);
				m[ind_ij] = min(m[ind_ij], ikkd + kkj);
			}
			if(b < i2){
				for(j = b/v_length; j < i2/v_length; j++){
					v_double_type kj = v_load_double(temp2 + j*v_length);
					v_double_type kkj = v_load_double(temp1 + j*v_length);
					int ind_ij = j*v_length + (((i + 1)*(i + 1))/2);
					v_double_type ij = v_load_double(m + ind_ij);
					v_double_type op1 = v_add_double(ik,kj);
					v_double_type op2 = v_add_double(ikk,kkj);
					v_double_type op3 = v_min_double(op1,op2);
					v_double_type res = v_min_double(ij,op3);
					v_store_double(m + ind_ij,res);
				}
				for(j = (i2/v_length)*v_length; j <=i2; j++){
					//int ind_kj = (k^1) + ((((j^1) + 1)*((j^1) + 1))/2);
					//int ind_kj = v2 + ((((j^1) + 1)*((j^1) + 1))/2);
					//double kj = m[n*k + j];
					double kj = temp2[j];
					//int ind_kkj = (kk^1) + ((((j^1) + 1)*((j^1) + 1))/2);
					//int ind_kkj = v1 + ((((j^1) + 1)*((j^1) + 1))/2);
					double kkj = temp1[j];
					//m[n*i + j] = min(m[n*i + j], ik + kj);
					int ind_ij = j + (((i + 1)*(i + 1))/2);
					m[ind_ij] = min(m[ind_ij], ikd + kj);
					m[ind_ij] = min(m[ind_ij], ikkd + kkj);
				}
			}
		}
	
	oo->nni = 2*dim*(dim+1);
	bool res;	
	if(is_int){
		res = strengthning_int_dense(oo, temp1, n);
	}
	else{
        	res = strengthning_dense(oo, temp1, n);
	}
	
	return res;
}
Exemplo n.º 2
0
opt_oct_t* opt_oct_add_epsilon(ap_manager_t* man, opt_oct_t* o, ap_scalar_t* epsilon)
{
  opt_oct_internal_t* pr = opt_oct_init_from_manager(man,AP_FUNID_WIDENING,2);
  opt_oct_t* r = opt_oct_alloc_internal(pr,o->dim,o->intdim);
  opt_oct_mat_t * oo;
  oo = o->m ? o->m : o->closed;
  if (oo) {
    double *m = oo->mat;
    size_t i;
    /* compute max of finite bounds */
    pr->tmp[0] = 0;
    int size = 2*(o->dim)*(o->dim+1);
    r->m = opt_hmat_alloc(size);
    free_array_comp_list(r->m->acl);
    double *mm = r->m->mat;
    if(!oo->is_dense){
	r->m->is_dense = false;
	r->m->ti = false;
	r->m->acl = copy_array_comp_list(oo->acl);
	comp_list_t * cl = oo->acl->head;
	while(cl != NULL){
		unsigned short int * ca = to_sorted_array(cl,o->dim);
		unsigned short int comp_size = cl->size;
		for(int i = 0; i < 2*comp_size; i++){
			unsigned short int i1 = (i%2==0)? 2*ca[i/2] : 2*ca[i/2]+1;
			for(int j = 0; j < 2*comp_size; j++){
				unsigned short int j1 = (j%2==0) ? 2*ca[j/2] : 2*ca[j/2] + 1;
				if(j1 > (i1|1)){
					break;
				} 
				int ind = j1 + (((i1 + 1)*(i1 + 1))/2);
				if(m[ind]==INFINITY){
					continue;
				} 
				if(m[ind] >= 0){
					pr->tmp[0] = max(pr->tmp[0],m[ind]);
				}
				else{
					pr->tmp[1] = -1*m[ind];
					pr->tmp[0] = max(pr->tmp[0],pr->tmp[1]);
				}
			}
		}
		cl =cl->next; 
		free(ca);
		
	}
	 /* multiply by epsilon */
	 opt_bound_of_scalar(pr,&pr->tmp[1],epsilon,false,false);
	 pr->tmp[0] = pr->tmp[0]*pr->tmp[1];
	/* enlarge bounds */
	cl = oo->acl->head;
	while(cl != NULL){
		unsigned short int * ca = to_sorted_array(cl,o->dim);
		unsigned short int comp_size = cl->size;
		for(int i = 0; i < 2*comp_size; i++){
			unsigned short int i1 = (i%2==0)? 2*ca[i/2] : 2*ca[i/2]+1;
			for(int j = 0; j < 2*comp_size; j++){
				unsigned short int j1 = (j%2==0) ? 2*ca[j/2] : 2*ca[j/2] + 1;
				if(j1 > (i1|1)){
					break;
				} 
				int ind = j1 + (((i1 + 1)*(i1 + 1))/2);
				mm[ind] = m[ind] + pr->tmp[0];
			}
		}
		cl =cl->next; 
		free(ca);		
	}
	/*for(int i = 0; i < o->dim; i++){
		//if(find(oo->acl,i)==NULL){
			int i1 = 2*i;
			int i2 = i1+1;
			int ind1 = i1 + (((i1+1)*(i1+1))/2);
			mm[ind1] = pr->tmp[0];
			int ind2 = i2 + (((i2+1)*(i2+1))/2);
			mm[ind2] = pr->tmp[0];
			comp_list_t * cl1 = create_comp_list();
			insert_comp(cl1,i);
			insert_comp_list(oo->acl,cl1);
		//}
	}*/
    }
    else{
	    r->m->is_dense = true;
	    r->m->ti = true;
	    for (i=0;i<size;i++) {
	      if (m[i]==INFINITY){
		 continue;
	      }
	      if (m[i]>=0){ 
		 pr->tmp[0] = max(pr->tmp[0],m[i]);
	      }
	      else {
		pr->tmp[1] = -1*m[i];
		pr->tmp[0] = max(pr->tmp[0],pr->tmp[1]);
	      }
	    }
	    /* multiply by epsilon */
	    opt_bound_of_scalar(pr,&pr->tmp[1],epsilon,false,false);
	    pr->tmp[0] = pr->tmp[0]*pr->tmp[1];
	    /* enlarge bounds */
	    #if defined(VECTOR)
	  	v_double_type val = v_set1_double(pr->tmp[0]);
		for(i = 0; i < size/v_length; i++){
			v_double_type op1 = v_load_double(m + i*v_length);
			v_double_type op2 = v_add_double(val,op1);
			v_store_double(mm + i*v_length,op2);
		}  
	    #else
		for (i=0;i<(size/v_length)*v_length;i++){
	      		mm[i] = m[i] + pr->tmp[0];
	    	}
	    #endif
		for(i = (size/v_length)*v_length;i < size; i++){
			mm[i] = m[i] + pr->tmp[0];
		}
    }
     r->m->nni = oo->nni;
  }
 
  return r;
}