Example #1
0
void Function::hansen_matrix(const IntervalVector& box, IntervalMatrix& H) const {
	int n=nb_var();
	int m=expr().dim.vec_size();

	assert(H.nb_cols()==n);
	assert(box.size()==n);
	assert(expr().dim.is_vector());
	assert(H.nb_rows()==m);

	IntervalVector x=box.mid();
	IntervalMatrix J(m,n);

	// test!
//	int tab[box.size()];
//	box.sort_indices(false,tab);
//	int var;

	for (int var=0; var<n; var++) {
		//var=tab[i];
		x[var]=box[var];
		jacobian(x,J);
		H.set_col(var,J.col(var));
	}

}
Example #2
0
int LSmear::var_to_bisect(IntervalMatrix& J, const IntervalVector& box) const {
  int lvar = -1; 
 
	//Linearization
	LPSolver::Status_Sol stat = LPSolver::UNKNOWN;

	Vector dual_solution(1);

	if (lsmode==LSMEAR_MG) { //compute the Jacobian in the midpoint
		IntervalMatrix J2(sys.f_ctrs.image_dim(), sys.nb_var);
		IntervalVector box2(IntervalVector(box.mid()).inflate(1e-8));
		//		IntervalVector box2(IntervalVector(box.random()));
		box2 &= box;

		sys.f_ctrs.jacobian(box2,J2);
		stat = getdual(J2, box, dual_solution);

	} else if (lsmode==LSMEAR) {
		stat = getdual(J, box, dual_solution);
	}


	if (stat == LPSolver::OPTIMAL) {
		double max_Lmagn = 0.0;
		int k=0;

		for (int j=0; j<nbvars; j++) {
			Interval lsmear=Interval(0.0);
			if ((!too_small(box,j)) && (box[j].mag() <1 ||  box[j].diam()/ box[j].mag() >= prec(j))){
				lsmear=dual_solution[j];

				for (int i=0; i<sys.f_ctrs.image_dim(); i++){
					lsmear += dual_solution[sys.nb_var+i] * J[i][j];
				}
			}

			lsmear*=(box[j].diam());

			if (lsmear.mag() > 1e-10  && (j!=goal_var() || mylinearsolver->get_obj_value().mid() > box[goal_var()].lb() )) {
				k++;
				if (lsmear.mag() > max_Lmagn) {
					max_Lmagn = lsmear.mag();
					lvar = j;
				}
			}
		}

		if (k==1 && lvar==goal_var()) { lvar=-1; }
	}
	if (lvar==-1) {
	  //	  std::cout << "ssr " << std::endl;
	  lvar=SmearSumRelative::var_to_bisect(J, box);
	}
	//	std::cout << "lsmear " << lvar << std::endl;
	return lvar;
}
Example #3
0
Interval centeredFormEval(const Function& function, const IntervalVector& arg) {
	/*Interval natural_extension = function.eval(arg);
	Interval centered_form = function.eval(arg.mid()) + function.gradient(arg) * (arg - arg.mid());*/
	IntervalVector new_arg_ub(arg);
	IntervalVector new_arg_lb(arg);
	IntervalVector grad = function.gradient(arg);
	for(int i = 0; i < arg.size(); ++i) {
		if(grad[i].lb() > 0) {
			new_arg_ub[i] = arg[i].ub();
			new_arg_lb[i] = arg[i].lb();
		} else if(grad[i].ub() < 0) {
			new_arg_ub[i] = arg[i].lb();
			new_arg_lb[i] = arg[i].ub();
		}
	}
	Interval natural_extension = function.eval(arg);
	Interval centered_form = function.eval(arg.mid()) + grad * (arg - arg.mid());
	Interval ub_form = function.eval(arg.ub()) + grad * (arg - arg.ub());
	Interval lb_form = function.eval(arg.lb()) + grad * (arg - arg.lb());
	Interval res = natural_extension & centered_form & ub_form & lb_form;
	res &= Interval(function.eval(new_arg_lb).lb(), function.eval(new_arg_ub).ub());
	return res;
}
Example #4
0
void hansen_bliek(const IntervalMatrix& A, const IntervalVector& B, IntervalVector& x) {
	int n=A.nb_rows();
	assert(n == A.nb_cols()); // throw NotSquareMatrixException();
	assert(n == x.size() && n == B.size());

	Matrix Id(n,n);
	for (int i=0; i<n; i++)
		for (int j=0; j<n; j++) {
			Id[i][j]   = i==j;
		}

	IntervalMatrix radA(A-Id);
	Matrix InfA(Id-abs(radA.lb()));
	Matrix M(n,n);

	real_inverse(InfA, M);  // may throw SingularMatrixException...

	for (int i=0; i<n; i++)
		for (int j=0; j<n; j++)
			if (! (M[i][j]>=0.0)) throw NotInversePositiveMatrixException();

	Vector b(B.mid());
	Vector delta = (B.ub())-b;

	Vector xstar = M * (abs(b)+delta);

	double xtildek, xutildek, nuk, max, min;

	for (int k=0; k<n; k++) {
		xtildek = (b[k]>=0) ? xstar[k] : xstar[k] + 2*M[k][k]*b[k];
		xutildek = (b[k]<=0) ? -xstar[k] : -xstar[k] + 2*M[k][k]*b[k];

		nuk = 1/(2*M[k][k]-1);
		max = nuk*xutildek;
		if (max < 0) max = 0;

		min = nuk*xtildek;
		if (min > 0) min = 0;

		/* compute bounds of x(k) */
		if (xtildek >= max) {
			if (xutildek <= min) x[k] = Interval(xutildek,xtildek);
			else x[k] = Interval(max,xtildek);
		} else {
			if (xutildek <= min) x[k] = Interval(xutildek,min);
			else { x.set_empty(); return; }
		}
	}
}
BoolInterval PdcHansenFeasibility::test(const IntervalVector& box) {

	int n=f.nb_var();
	int m=f.image_dim();
	IntervalVector mid=box.mid();

	/* Determine the "most influencing" variable thanks to
	 * the pivoting of Gauss elimination */
	// ==============================================================
	Matrix A=f.jacobian(mid).mid();
	Matrix LU(m,n);
	int pr[m];
	int pc[n]; // the interesting output: the variables permutation

	try {
		real_LU(A,LU,pr,pc);
	} catch(SingularMatrixException&) {
		// means in particular that we could not extract an
		// invertible m*m submatrix
		return MAYBE;
	}
	// ==============================================================


	PartialFnc pf(f,pc,m,mid);

	IntervalVector box2(pf.chop(box));
	IntervalVector savebox(box2);

	if (inflating) {
		if (inflating_newton(pf,box2)) {
			_solution = pf.extend(box2);
			return YES;
		}
	}
	else {
		try {
			newton(pf,box2);
			if (box2.is_strict_subset(savebox)) {
				_solution = pf.extend(box2);
				return YES;
			}
		} catch (EmptyBoxException& ) {	}
	}

	_solution.set_empty();
	return MAYBE;

}
Example #6
0
		void contract(IntervalVector& box) {
			box=box.mid()+0.5*Interval(-1,1)*box.rad();
		}
Example #7
0
Optimizer::Status Optimizer::optimize(const IntervalVector& init_box, double obj_init_bound) {
	loup=obj_init_bound;
	pseudo_loup=obj_init_bound;
	buffer.contract(loup);

	uplo=NEG_INFINITY;
	uplo_of_epsboxes=POS_INFINITY;

	nb_cells=0;
	nb_simplex=0;
	diam_simplex=0;
	nb_rand=0;
	diam_rand=0;

	buffer.flush();

	Cell* root=new Cell(IntervalVector(n+1));

	write_ext_box(init_box,root->box);

	// add data required by the bisector
	bsc.add_backtrackable(*root);

	// add data "pu" and "pf" (if required)
	buffer.cost2().add_backtrackable(*root);

	// add data required by optimizer + Fritz John contractor
	root->add<EntailedCtr>();
	//root->add<Multipliers>();
	entailed=&root->get<EntailedCtr>();
	entailed->init_root(user_sys,sys);

	loup_changed=false;
	initial_loup=obj_init_bound;
	loup_point=init_box.mid();
	time=0;
	Timer::start();
	handle_cell(*root,init_box);

	update_uplo();

	try {
		while (!buffer.empty()) {
		  //			if (trace >= 2) cout << " buffer " << buffer << endl;
		  if (trace >= 2) buffer.print(cout);
			//		  cout << "buffer size "  << buffer.size() << " " << buffer2.size() << endl;
			// removes from the heap buffer, the cells already chosen in the other buffer

			if (buffer.empty()) {
				//cout << " buffer empty " << buffer.empty() << " " << buffer2.empty() << endl;
				// this update is only necessary when buffer was not
				// initially empty
				update_uplo();
				break;
			}

			loup_changed=false;
			Cell *c;

			// random choice between the 2 buffers corresponding to two criteria implemented in two heaps)
			// critpr chances over 100 to choose the second heap (see CellDoubleHeap)
			c=buffer.top();

			try {
				pair<IntervalVector,IntervalVector> boxes=bsc.bisect(*c);

				pair<Cell*,Cell*> new_cells=c->bisect(boxes.first,boxes.second);

				buffer.pop();
				delete c; // deletes the cell.

				handle_cell(*new_cells.first, init_box);
				handle_cell(*new_cells.second, init_box);

				if (uplo_of_epsboxes == NEG_INFINITY) {
					cout << " possible infinite minimum " << endl;
					break;
				}
				if (loup_changed) {
					// In case of a new upper bound (loup_changed == true), all the boxes
					// with a lower bound greater than (loup - goal_prec) are removed and deleted.
					// Note: if contraction was before bisection, we could have the problem
					// that the current cell is removed by contractHeap. See comments in
					// older version of the code (before revision 284).

					double ymax=compute_ymax();

					buffer.contract(ymax);
					//cout << " now buffer is contracted and min=" << buffer.minimum() << endl;


					if (ymax <= NEG_INFINITY) {
						if (trace) cout << " infinite value for the minimum " << endl;
						break;
					}
					if (trace) cout << setprecision(12) << "ymax=" << ymax << " uplo= " <<  uplo<< endl;
				}
				update_uplo();
				time_limit_check();

			}
			catch (NoBisectableVariableException& ) {
				update_uplo_of_epsboxes((c->box)[ext_sys.goal_var()].lb());
				buffer.pop();
				delete c; // deletes the cell.

				update_uplo(); // the heap has changed -> recalculate the uplo

			}
		}
	}
	catch (TimeOutException& ) {
		return TIME_OUT;
	}

	Timer::stop();
	time+= Timer::VIRTUAL_TIMELAPSE();

	if (uplo_of_epsboxes == POS_INFINITY && (loup==POS_INFINITY || (loup==initial_loup && goal_abs_prec==0 && goal_rel_prec==0)))
		return INFEASIBLE;
	else if (loup==initial_loup)
		return NO_FEASIBLE_FOUND;
	else if (uplo_of_epsboxes == NEG_INFINITY)
		return UNBOUNDED_OBJ;
	else
		return SUCCESS;
}
Example #8
0
/// Processes the data using contractors and bissections. Classifies the boxes in outside (grey), back_in(yellow) and unsafe (red)
void Sivia::do_Sivia(Ctc& tubeConstraints, Data &data, Function gdot, bool calcInner){

    QTime tSivia;
    tSivia.start();

    if (calcInner)                  //inner approximation calculation
    {
        int count=0;
        while (!data.boxes.empty()) {
            IntervalVector currentBox = data.boxes.front();                 //start from the first one
            data.boxes.pop_front();                                         //once it has been copied remove the first box

            IntervalVector auxBox=currentBox;                               //store it in aux variable to compare later

            tubeConstraints.contract(currentBox);                           //contract the current box using the previously calculated constraints
            if (currentBox!=auxBox){                                        //if the box has been contracted
                IntervalVector* removedByContractorInner;
                int setDiff=auxBox.diff(currentBox, removedByContractorInner);   //set difference between the contracted box and the original box
                for (int i = 0; i < setDiff; ++i) {

                    bool testInside=true;
                    IntervalVector gg=data.g->eval_vector(removedByContractorInner[i]);

                    for(int j = 0; j<gg.size(); j++){
                        testInside = testInside && (gg[j].ub()<=0);
                    }
                    if (testInside) {
                        data.boxesInside.append(removedByContractorInner[i]);
                    }
                }
                delete[] removedByContractorInner;
            }

            if(data.realTimeDraw){                                          //draw the boxes processing in real time
                draw_update(data, auxBox, currentBox);
            }


            bool allBoxesLessEpsilon=true;                                                                              //check if all the boxes are smaler than epsilon
            for (int i=0;(i<(currentBox.size()-1));i++){
                allBoxesLessEpsilon = (allBoxesLessEpsilon && ((currentBox.diam()[i])<=data.epsilons[i]));
            }
            allBoxesLessEpsilon = (allBoxesLessEpsilon && ((currentBox[currentBox.size()-1].diam())<=data.dt));         //check the time box also


            bool boxesLessEpsilon=false;                                                                                //check if at least one box is smaller than epsilon
            for (int i=0;(i<(currentBox.size()-1));i++){
                boxesLessEpsilon = boxesLessEpsilon||((currentBox[i].diam())<=data.epsilons[i]);
            }
            boxesLessEpsilon = boxesLessEpsilon&&((currentBox[currentBox.size()-1].diam())<=data.dt);                   //check time box

            if (allBoxesLessEpsilon) {                                                          //if allBoxesLessEpsilon = true the box is unsafe and I continue my loop
                (data.boxesInsideUnsafe).push_back(currentBox);
                count++;
                if (count >=data.maxNumUnsafeBoxes && data.maxNumUnsafeBoxesActivated){         //If I have more boxes than nbPerhaps I stop the loop and I display the results
                    break;
                }
            }
            else {                                                                              //Otherwise we bissect following the widest diameter
                double l = 0;
                double l_temp = 0;
                int v = -1;
                for(int i = 0; i<currentBox.size()-1; i++){                                     //test that the diameter of the boxes doesnt depend on time
                    if(currentBox[i].is_bisectable()||!(currentBox[i].is_degenerated())){
                        l_temp = currentBox[i].diam();
                        if(l_temp>=data.epsilons[i] && l_temp/(data.epsilons[i]) > l){
                            l = l_temp/(data.epsilons[i]);
                            v = i;
                        }
                    }
                }

                l_temp = currentBox[currentBox.size()-1].diam();                                //test the time interval
                if(l_temp>=data.dt && l_temp/(data.dt) > l){
                    v = currentBox.size()-1;
                }
                if(v != -1 && currentBox[v].is_bisectable()){                                   // then the test interval of the state variables, and then it bisects the interval which has the largest diameter
                    pair<IntervalVector,IntervalVector> boxes=currentBox.bisect(v, 0.5);
                    (data.boxes).push_back(boxes.first);
                    (data.boxes).push_back(boxes.second);
                }
                else{
                    if (data.myDebug){
                        std::cout<<"Cannot be bisected \n";
                    }
                }
            }
        }
    }


    else                            //outer approximation
    {
        int count=0;
        //process all the boxes in data
        while (!data.boxes.empty()) {
            IntervalVector currentBox = data.boxes.front();                 //start from the first one
            data.boxes.pop_front();                                         //once it has been copied remove the first box

            IntervalVector auxBox=currentBox;                               //store it in aux variable to compare later

            tubeConstraints.contract(currentBox);                           //contract the current box using the previously calculated constraints
            if (currentBox!=auxBox){                                        //if the box has been contracted
                IntervalVector* removedByContractor;
                int setDiff=auxBox.diff(currentBox, removedByContractor);   //set difference between the contracted box and the original box
                for (int i = 0; i < setDiff; ++i) {
                    data.boxesOutside.push_back(removedByContractor[i]);    //add the areas removed by the contractor to the outside set
                }
                delete[] removedByContractor;
            }

            if(data.realTimeDraw){                                          //draw the boxes processing in real time
                draw_update(data, auxBox, currentBox);
            }


            bool allBoxesLessEpsilon=true;                                                                              //check if all the boxes are smaler than epsilon
            for (int i=0;(i<(currentBox.size()-1));i++){
                allBoxesLessEpsilon = (allBoxesLessEpsilon && ((currentBox.diam()[i])<=data.epsilons[i]));
            }
            allBoxesLessEpsilon = (allBoxesLessEpsilon && ((currentBox[currentBox.size()-1].diam())<=data.dt));         //check the time box also

            bool boxesLessEpsilon=false;                                                                                //check if at least one box is smaller than epsilon
            for (int i=0;(i<(currentBox.size()-1));i++){
                boxesLessEpsilon = boxesLessEpsilon||((currentBox[i].diam())<=data.epsilons[i]);
            }
            boxesLessEpsilon = boxesLessEpsilon&&((currentBox[currentBox.size()-1].diam())<=data.dt);                   //check time box

            if (boxesLessEpsilon && !allBoxesLessEpsilon){
                IntervalVector xnext = currentBox.subvector(0, data.numVarF-1).mid();   //using the middle point of the box calculate the future positions using euler method
                IntervalVector x = currentBox.mid();
                bool testBackIn;
                for (int i = 0;i<data.numFuturePos;i++){                                // Euler method: x(n+1)=x(n)+dt*fx
                    x[data.numVarF]= x[data.numVarF].mid();
                    testBackIn = true;
                    xnext=xnext+(data.dt)*data.f->eval_vector(x);
                    x.put(0, xnext);
                    x[data.numVarF] = x[data.numVarF]+(data.dt);
                    IntervalVector gg=data.g->eval_vector(x);
                    for(int j = 0; j<gg.size(); j++){
                        testBackIn = testBackIn && (gg[j].ub()<0);                      //test if it comes back to the bubble

                    }
                    if(testBackIn == true){
                        break;
                    }
                }

                if(testBackIn == true && data.enableBackIn){                                                 //If my box was back in the bubble after integration, I store it in boxesbackin
                    (data.boxesBackIn).append(currentBox);

                    continue;
                }
            }


            if (allBoxesLessEpsilon) {                                                          //if allBoxesLessEpsilon = true the box is unsafe and I continue my loop
                (data.boxesUnsafe).push_back(currentBox);
                count++;
                if (count >=data.maxNumUnsafeBoxes && data.maxNumUnsafeBoxesActivated){         //If I have more boxes than nbPerhaps I stop the loop and I display the results
                    break;
                }
            }
            else {                                                                              //Otherwise we bissect following the widest diameter
                double l = 0;
                double l_temp = 0;
                int v = -1;
                for(int i = 0; i<currentBox.size()-1; i++){                                     //test that the diameter of the boxes doesnt depend on time
                    if(currentBox[i].is_bisectable()||!(currentBox[i].is_degenerated())){
                        l_temp = currentBox[i].diam();
                        if(l_temp>=data.epsilons[i] && l_temp/(data.epsilons[i]) > l){
                            l = l_temp/(data.epsilons[i]);
                            v = i;
                        }
                    }
                }

                l_temp = currentBox[currentBox.size()-1].diam();                                //test the time interval
                if(l_temp>=data.dt && l_temp/(data.dt) > l){
                    v = currentBox.size()-1;
                }
                if(v != -1 && currentBox[v].is_bisectable()){                                   // then the test interval of the state variables, and then it bisects the interval which has the largest diameter
                    pair<IntervalVector,IntervalVector> boxes=currentBox.bisect(v, 0.5);
                    (data.boxes).push_back(boxes.first);
                    (data.boxes).push_back(boxes.second);
                }
                else{
                    if (data.myDebug){
                        std::cout<<"Can not be bisected \n";
                    }
                }
            }
        }


        double maxGValues[data.numVarG-1];                              //init vector to store the max values of G

        for (int i = 0; i < data.numVarG-1; ++i) {
            maxGValues[i]=0; }


        for(int i=0; i<data.boxesUnsafe.size();i++) {                   //process unsafe boxes

            IntervalVector currentBox=data.boxesUnsafe.at(i);
            IntervalVector nextBox = currentBox.subvector(0, data.numVarF-1);

            if (data.intMethod==0){                                     //Guaranteed integration

                // State variables
                Variable y(data.numVarF);

                // Initial conditions
                IntervalVector yinit(data.numVarF);

                for (int i = 0; i < data.numVarF; ++i) {
                    yinit[i] = currentBox[i];
                    cout<<currentBox[i]<<endl;
                }

                // system fn has to be re entered here, cannot be loaded directly from text file

                //pendulum
                Function ydot = Function (y,Return (y[1], -sin(y[0])-0.15*y[1]));

                //non holonomic
                //                Interval t = currentBox[data.numVarF];
                //                Interval xd = 7*t;
                //                Interval xdd = 7;
                //                Interval yd = sin(0.1*t);
                //                Interval ydd = 0.1*cos(0.1*t);
                //                Interval xdiff = (xd-y[0]+xdd);
                //                Interval ydiff = (yd-y[1]+ydd);
                //                Interval norm =  ( sqrt((xdiff)^2 +(ydiff)^2) );

                //                Function ydot = Function (y,Return (( sqrt((xd-y[0]+xdd)*(xd-y[0]+xdd) +((yd-y[1]+ydd))*(yd-y[1]+ydd)) )*cos(y[2]), ( sqrt(((xd-y[0]+xdd))*(xd-y[0]+xdd) +((yd-y[1]+ydd))*(yd-y[1]+ydd)) )*sin(y[2]), 10*(cos(y[2])*((yd-y[1]+ydd))-sin(y[2])*((xd-y[0]+xdd)))/( sqrt(((xd-y[0]+xdd))*(xd-y[0]+xdd) +((yd-y[1]+ydd))*(yd-y[1]+ydd)) )));           // Ivp contruction (initial time is 0.0)

                QTime t1;
                t1.start();

                ivp_ode problem = ivp_ode (ydot, 0.0 , yinit);

                // Simulation construction and run
                simulation simu = simulation (&problem,data.dt*data.numFuturePos, __METH__, __PREC__);          //uses Runge-kutta4 method
                data.boxesUnsafeFuture.append(simu.run_simulation());                                           //modified ibex_simulation.h to make it return a list with all the solutions, not just the last one

                double timeSiviaCalculations1=t1.elapsed()/1000.0;
                double timeSiviaCalculationsTotal=tSivia.elapsed()/1000.0;
                cout<<endl<<"Unsafe # "<<i<<"  , Box time = "<<timeSiviaCalculations1<<" , Total elapsed time = "<<timeSiviaCalculationsTotal<<endl;
            }

            if (data.intMethod==1){                                     //euler method

                for (int i = 0;i<data.numFuturePos;i++){

                    IntervalVector gdotValue=gdot.eval_vector(currentBox);                                      //evaluate the g and gdot functions to inspect the constraints
                    IntervalVector gValue=data.g->eval_vector(currentBox);

                    if (data.myDebug){
                        cout<<"box = "<<currentBox<<endl;

                        for(int j = 0; j<gValue.size(); j++){
                            cout<<"gdot"<<j<<" = "<<gdotValue<<"  /  "<<(gdotValue[j].lb()>0) <<endl;                       //gdot i values
                        }
                    }

                    for(int j = 0; j<gValue.size(); j++){
                        if (data.myDebug){
                            cout<<"g"<<j<<" = "<<gValue[j]<<"  /  "<<((gValue[j].ub()>0)&&(gValue[j].lb()<0)) <<endl;}      //print gi values

                        if((gValue[j].ub()>maxGValues[j])&&(gValue[j].ub()<999999)){                                        //check max values for each gi, ignore if system goes to infinity
                            maxGValues[j]=gValue[j].ub();}
                    }

                    nextBox=nextBox+(data.dt)*data.f->eval_vector(currentBox);              //euler method
                    data.boxesUnsafeFuture.append(nextBox);

                    currentBox.put(0, nextBox);
                    currentBox[data.numVarF] = currentBox[data.numVarF]+(data.dt);          //increase time for the next step
                }
            }
        }


        for(int i=0; i<data.boxesBackIn.size();i++){                                        //process back_in boxes

            IntervalVector currentBox=data.boxesBackIn.at(i);
            IntervalVector nextBox = currentBox.subvector(0, data.numVarF-1);

            if (data.intMethod==0){                 //guaranteed integration                                                       //Guaranteed integration

                // State variables
                Variable y(data.numVarF);

                // Initial conditions
                IntervalVector yinit(data.numVarF);

                for (int i = 0; i < data.numVarF; ++i) {
                    yinit[i] = currentBox[i];
                    cout<<currentBox[i]<<endl;
                }

                QTime t2;
                t2.start();

                // system fn has to be re entered here, cannot be loaded directly from text file

                //pendulum
                Function ydot = Function (y,Return (y[1], -sin(y[0])-0.15*y[1]));

                //non holonomic
                //                Interval t = currentBox[data.numVarF];
                //                Interval xd = 7*t;
                //                Interval xdd = 7;
                //                Interval yd = sin(0.1*t);
                //                Interval ydd = 0.1*cos(0.1*t);
                //                Interval xdiff = (xd-y[0]+xdd);
                //                Interval ydiff = (yd-y[1]+ydd);
                //                Interval norm =  ( sqrt((xdiff)^2 +(ydiff)^2) );

                //                Function ydot = Function (y,Return (( sqrt((xd-y[0]+xdd)*(xd-y[0]+xdd) +((yd-y[1]+ydd))*(yd-y[1]+ydd)) )*cos(y[2]), ( sqrt(((xd-y[0]+xdd))*(xd-y[0]+xdd) +((yd-y[1]+ydd))*(yd-y[1]+ydd)) )*sin(y[2]), 10*(cos(y[2])*((yd-y[1]+ydd))-sin(y[2])*((xd-y[0]+xdd)))/( sqrt(((xd-y[0]+xdd))*(xd-y[0]+xdd) +((yd-y[1]+ydd))*(yd-y[1]+ydd)) )));           // Ivp contruction (initial time is 0.0)


                ivp_ode problem = ivp_ode (ydot, currentBox[data.numVarF].lb() , yinit);

                // Simulation construction and run
                simulation simu = simulation (&problem,data.dt*data.numFuturePos, __METH__, __PREC__);          //uses Runge-kutta4 method
                data.boxesUnsafeFuture.append(simu.run_simulation());                       //modified ibex_simulation.h to make it return a list with all the solutions, not just the last one

                double timeSiviaCalculations2=t2.elapsed()/1000.0;
                double timeSiviaCalculationsTotal=tSivia.elapsed()/1000.0;

                cout<<endl<<"Back_in # "<<i<<"  , Box time = "<<timeSiviaCalculations2<<" , Total elapsed time = "<<timeSiviaCalculationsTotal<<endl;
            }

            for (int i = 0;i<data.numFuturePos;i++){                                        //euler method

                if (data.intMethod==1){
                    IntervalVector gdotValue=gdot.eval_vector(currentBox);                  //evaluate the g and gdot functions to inspect the constraints
                    IntervalVector gValue=data.g->eval_vector(currentBox);

                    if (data.myDebug){
                        cout<<"box = "<<currentBox<<endl;

                        for(int j = 0; j<gValue.size(); j++){
                            cout<<"gdot"<<j<<" = "<<gdotValue<<"  /  "<<(gdotValue[j].lb()>0) <<endl;               //gdoti values
                        }
                    }

                    bool testBackIn= true;
                    for(int j = 0; j<gValue.size(); j++){
                        if (data.myDebug){
                            cout<<"g"<<j<<" = "<<gValue[j]<<"  /  "<<((gValue[j].ub()>0)&&(gValue[j].lb()<0)) <<endl;}          //print gi values

                        testBackIn = testBackIn && (gValue[j].ub()<0);                                              //test if it comes back to the bubble

                        if((gValue[j].ub()>maxGValues[j])&&(gValue[j].ub()<999999)){                                //check max values for each gi, ignore if system goes to infinity
                            maxGValues[j]=gValue[j].ub();
                        }
                    }


                    nextBox=nextBox+(data.dt)*data.f->eval_vector(currentBox);                                      // euler method
                    if (!testBackIn){
                        data.boxesBackInFuture.append(nextBox);
                    }
                    currentBox.put(0, nextBox);
                    currentBox[data.numVarF] = currentBox[data.numVarF]+(data.dt);                                  //increase time for the next step
                }
            }
        }


        if (data.myDebug){
            for (int i = 0; i < data.numVarG-1; ++i) {
                cout<<"Max G"<<i<<" = "<<maxGValues[i]<<endl;}
        }
    }
}
int LinearizerDuality::linearize(const IntervalVector& box, LPSolver& lp_solver, BoxProperties& prop)  {
	// ========= get active constraints ===========
	/* Using system cache seems not interesting. */
	//BxpSystemCache* cache=(BxpSystemCache*) prop[BxpSystemCache::get_id(sys)];
	BxpSystemCache* cache=NULL;
	//--------------------------------------------------------------------------

	BitSet* active;

	if (cache!=NULL) {
		active = &cache->active_ctrs();
	} else {
		active = new BitSet(sys.active_ctrs(box));
	}
	// ============================================

	size_t n = sys.nb_var;
	size_t m = sys.f_ctrs.image_dim();
	size_t n_total = n +  m*n;

	int nb_ctr=0; // number of inequalities added in the LP solver

//	BxpLinearRelaxArgMin* argmin=(BxpLinearRelaxArgMin*) prop[BxpLinearRelaxArgMin::get_id(sys)];
//
//	if (argmin && argmin->argmin()) {
//		pt=*argmin->argmin();
//	} else
		pt=box.mid();

	if (!active->empty()) {

		//IntervalMatrix J=cache? cache->active_ctrs_jacobian() : sys.f_ctrs.jacobian(box,active);
		//IntervalMatrix J=sys.f_ctrs.jacobian(box,*active);
		IntervalMatrix J(active->size(),n); // derivatives over the box
		sys.f_ctrs.hansen_matrix(box,pt,J,*active);

		if (J.is_empty()) {
			if (cache==NULL) delete active;
			return -1;
		}

		// the evaluation of the constraints in the point
		IntervalVector gx(sys.f_ctrs.eval_vector(pt,*active));
		if (gx.is_empty()) {
			if (cache==NULL) delete active;
			return 0;
		}


		int i=0; // counter of active constraints
		for (BitSet::iterator c=active->begin(); c!=active->end(); ++c, i++)  {

			if (!sys.f_ctrs.deriv_calculator().is_linear[c]) {
				for (size_t j=0; j<n; j++) {
					Vector row(n_total,0.0);
					row[j]=1;
					row[n + c*n +j]=1;

					double rhs = pt[j] - lp_solver.get_epsilon();

					lp_solver.add_constraint(row, LEQ, rhs);
					nb_ctr++;
				}
			}

			Vector row(n_total,0.0);
			row.put(0,J[i].lb());

			IntervalVector gl(J[i].lb());

			Vector diam_correctly_rounded = (IntervalVector(J[i].ub())-gl).lb();

			for (size_t j=0; j<n; j++) {
				if (diam_correctly_rounded[j]<0)
					ibex_error("negative diameter");
			}

			row.put(n + c*n,-diam_correctly_rounded);

			double rhs = (-gx[i] + (gl*pt)).lb()- lp_solver.get_epsilon();

			lp_solver.add_constraint(row, LEQ, rhs);
			nb_ctr++;
		}
	}

	if (cache==NULL) delete active;
	return nb_ctr;
}
Example #10
0
bool inflating_newton(const Fnc& f, const VarSet* vars, const IntervalVector& full_box, IntervalVector& box_existence, IntervalVector& box_unicity, int k_max, double mu_max, double delta, double chi) {
	int n=vars ? vars->nb_var : f.nb_var();
	assert(f.image_dim()==n);
	assert(full_box.size()==f.nb_var());

	if (full_box.is_empty()) {
		box_existence.set_empty();
		box_unicity.set_empty();
		return false;
	}

	int k=0;
	bool success=false;

	IntervalVector mid(n);       // Midpoint of the current box
	IntervalVector Fmid(n);      // Evaluation of f at the midpoint
	IntervalMatrix J(n, n);	     // Hansen matrix of f % variables

	// Following variables are introduced just to use a
	// centered-form on parameters when evaluating Fmid
	IntervalVector* p=NULL;      // Parameter box
	IntervalVector* midp=NULL;   // Parameter box midpoint
	// -------------------------------------------------

	IntervalMatrix* Jp=NULL;     // Jacobian % parameters
//
	if (vars) {
		p=new IntervalVector(vars->param_box(full_box));
		midp=new IntervalVector(p->mid());
		Jp=new IntervalMatrix(n,vars->nb_param);
	}

	IntervalVector y(n);
	IntervalVector y1(n);

	IntervalVector box = vars ? vars->var_box(full_box) : full_box;
	IntervalVector& full_mid = vars ? *new IntervalVector(full_box) : mid;

	// Warning: box_existence is used to store the full box of the
	// current iteration (that is, param_box x box)
	// It will eventually (at return) be the
	// existence box in case of success. Nothing is proven inside
	// box_existence until success==true in the loop (note: inflation
	// stops when success is true and existence is thus preserved
	// until the end)
	box_existence = full_box;

	// Just to quickly initialize the domains of parameters
	box_unicity = full_box;

	y1 = box.mid();

	while (k<k_max) {

		//cout << "current box=" << box << endl << endl;

		if (vars)
			f.hansen_matrix(box_existence, J, *Jp, *vars);
		else
			f.hansen_matrix(box_existence, J);

		if (J.is_empty()) break;

		mid = box.mid();

		if (vars) vars->set_var_box(full_mid, mid);

		Fmid=f.eval_vector(full_mid);

		// Use the jacobian % parameters to calculate
		// a mean-value form for Fmid
		if (vars) {
			Fmid &= f.eval_vector(vars->full_box(mid,*midp))+(*Jp)*(*p-*midp);
		}

		y = mid-box;
		//if (y==y1) break; <--- allowed in Newton inflation
		y1=y;

		try {
			precond(J, Fmid);
		} catch(LinearException&) {
			break; // should be false
		}
		// Note: giving mu_max to gauss-seidel (GS) is slightly different from checking the condition "mu<mu_max" in the
		// Newton procedure itself. If GS transforms x0 to x1 in n iterations, and then x1 to x2 in n other iterations
		// it is possible that each of these 2n iterations satisfies mu<mu_max, whereas the two global Newton iterations
		// do not, i.e., d(x2,x1) > mu_max d(x1,x0).
		if (!inflating_gauss_seidel(J, Fmid, y, 1e-12, mu_max)) {// TODO: replace hardcoded value 1e-12
			// when k~kmax, "divergence" may also mean "cannot contract more" (d/dold~1)
			break;
		}

		IntervalVector box2=mid-y;

		if (box2.is_subset(box)) {

			assert(!box2.is_empty());

			if (!success) { // to get the largest unicity box, we do this
				            // only when the first contraction occurs

				if (vars) vars->set_var_box(box_unicity,box);
				else box_unicity = box;

				//=================================================
				// We now try to enlarge the unicity box as possible
				// =================================================
//				IntervalVector box2copy=box2;
//
//				bool inflate_ok=true;
//
//				while (inflate_ok) {
//
//					box2copy.inflate(delta,0.0);
//
//					// box_existence is also used inside this iteration
//					// to store the "full box"
//					if (vars) vars->set_var_box(box_existence,box2copy);
//					else box_existence = box2copy;
//
//					newton(f,vars,box_existence,0.0,default_gauss_seidel_ratio);
//
//					if (vars) {
//						if (vars->var_box(box_existence).is_interior_subset(box2))
//							vars->set_var_box(box_unicity,box2copy);
//						else inflate_ok=false;
//					} else {
//						if (box_existence.is_interior_subset(box2))
//							box_unicity = box2copy;
//						else inflate_ok=false;
//					}
//				}

			}
			success=true;  // we don't return now, to let the box being contracted more
		}

		box = success? box2 : box2.inflate(delta,chi);

		k++;

		// we update box_existence inside the loop because
		// the Jacobian has to be recalculated on the current
		// full box at each iteration
		if (vars) vars->set_var_box(box_existence,box);
		else box_existence = box;

	}

	if (vars) {
		delete p;
		delete midp;
		delete Jp;
		delete &full_mid;
	}

	if (!success) {
		box_existence.set_empty();
		box_unicity.set_empty();
	}
	return success;
}
Example #11
0
  LPSolver::Status_Sol LSmear::getdual(IntervalMatrix& J, const IntervalVector& box, Vector& dual) const {
  
    int  _goal_var = goal_var();
    bool minimize=true;
    if (_goal_var == -1){
      _goal_var = RNG::rand()%box.size();
      minimize=RNG::rand()%2;
    }
     
	// The linear system is created
	mylinearsolver->clean_ctrs();
	mylinearsolver->set_bounds(box);
	mylinearsolver->set_bounds_var(_goal_var, Interval(-1e10,1e10));

	int nb_lctrs[sys.f_ctrs.image_dim()]; /* number of linear constraints generated by nonlinear constraint*/

	for (int i=0; i<sys.f_ctrs.image_dim(); i++) {
	  
		Vector row1(sys.nb_var);
		Interval ev(0.0);
		for (int j=0; j<sys.nb_var; j++) {
			row1[j] = J[i][j].mid();
			ev -= Interval(row1[j])*box[j].mid();
		}
		ev+= sys.f_ctrs.eval(i,box.mid()).mid();

		nb_lctrs[i]=1;
		if (i!=goal_ctr()) {
		  if (sys.ops[i] == LEQ || sys.ops[i] == LT){
		    mylinearsolver->add_constraint( row1, sys.ops[i], (-ev).ub());
		  }
		  else if (sys.ops[i] == GEQ || sys.ops[i] == GT)
				mylinearsolver->add_constraint( row1, sys.ops[i], (-ev).lb());
		  else { //op=EQ
				mylinearsolver->add_constraint( row1, LT, (-ev).ub());
				mylinearsolver->add_constraint( row1, GT, (-ev).lb());
				nb_lctrs[i]=2;
		  }
		}
		else if (goal_to_consider(J,i)) 
		  mylinearsolver->add_constraint( row1, LEQ, (-ev).ub());
		else // the goal is equal to a variable : the goal constraint is useless.
		  nb_lctrs[i]=0;
		  
		
	}


	//the linear system is solved
	LPSolver::Status_Sol stat=LPSolver::UNKNOWN;
	try {
		mylinearsolver->set_obj_var(_goal_var, (minimize)? 1.0:-1.0);

		stat = mylinearsolver->solve();

		if (stat == LPSolver::OPTIMAL) {
			// the dual solution : used to compute the bound
			dual.resize(mylinearsolver->get_nb_rows());
			dual = mylinearsolver->get_dual_sol();
			int k=0; //number of multipliers != 0
			int ii=0;


			for (int i=0; i<sys.f_ctrs.image_dim(); i++) {
				if (nb_lctrs[i]==2) {
					dual[sys.nb_var+i]=dual[sys.nb_var+ii]+dual[sys.nb_var+ii+1]; ii+=2;
				} else {
					dual[sys.nb_var+i]=dual[sys.nb_var+ii]; ii++;
				}

				if (std::abs(dual[sys.nb_var+i])>1e-10) k++;
			}

			if(k<2) { stat = LPSolver::UNKNOWN; }
		}
	} catch (LPException&) {
		stat = LPSolver::UNKNOWN;
	}

	return stat;
}
Example #12
0
/// Processes the data using contractors and bissections. Classifies the boxes in outside (grey), back_in(yellow) and unsafe (red)
void Sivia::do_Sivia(Ctc& tubeConstraints, Data &data, Function gdot, bool calcInner) {

    QTime tSivia;
    tSivia.start();

    if (calcInner)                  //inner approximation calculation
    {
        int count=0;
        while (!data.boxes.empty()) {
            IntervalVector currentBox = data.boxes.front();                 //start from the first one
            data.boxes.pop_front();                                         //once it has been copied remove the first box

            IntervalVector auxBox=currentBox;                               //store it in aux variable to compare later

            tubeConstraints.contract(currentBox);                           //contract the current box using the previously calculated constraints
            if (currentBox!=auxBox){                                        //if the box has been contracted
                IntervalVector* removedByContractorInner;
                int setDiff=auxBox.diff(currentBox, removedByContractorInner);   //set difference between the contracted box and the original box
                for (int i = 0; i < setDiff; ++i) {
                    //data.boxesOutside.push_back(removedByContractor[i]);    //add the areas removed by the contractor to the outside set


                    bool testInside=true;
                    IntervalVector gg=data.g->eval_vector(removedByContractorInner[i]);

                    for(int j = 0; j<gg.size(); j++){
                        testInside = testInside && (gg[j].ub()<=0);
                    }
                    if (testInside) {
                        data.boxesInside.append(removedByContractorInner[i]);
                    }

                }
                delete[] removedByContractorInner;

            }

            if(data.realTimeDraw){                                          //draw the boxes processing in real time
                draw_update(data, auxBox, currentBox);
            }


            bool allBoxesLessEpsilon=true;                                                                              //check if all the boxes are smaler than epsilon
            for (int i=0;(i<(currentBox.size()-1));i++){
                allBoxesLessEpsilon = (allBoxesLessEpsilon && ((currentBox.diam()[i])<=data.epsilons[i]));
            }
            allBoxesLessEpsilon = (allBoxesLessEpsilon && ((currentBox[currentBox.size()-1].diam())<=data.dt));         //check the time box also


            bool boxesLessEpsilon=false;                                                                                //check if at least one box is smaller than epsilon
            for (int i=0;(i<(currentBox.size()-1));i++){
                boxesLessEpsilon = boxesLessEpsilon||((currentBox[i].diam())<=data.epsilons[i]);
            }
            boxesLessEpsilon = boxesLessEpsilon&&((currentBox[currentBox.size()-1].diam())<=data.dt);                   //check time box



            if (boxesLessEpsilon && !allBoxesLessEpsilon){
                IntervalVector xnext = currentBox.subvector(0, data.numVarF-1).mid();   //using the middle point of the box calculate the future positions using euler method
                IntervalVector x = currentBox.mid();
                bool testBackIn;
                for (int i = 0;i<data.numFuturePos;i++){                                // Euler method: x(n+1)=x(n)+dt*fx
                    x[data.numVarF]= x[data.numVarF].mid();
                    testBackIn = true;
                    xnext=xnext+(data.dt)*data.f->eval_vector(x);
                    x.put(0, xnext);
                    x[data.numVarF] = x[data.numVarF]+(data.dt);
                    IntervalVector gg=data.g->eval_vector(x);
                    for(int j = 0; j<gg.size(); j++){
                        testBackIn = testBackIn && (gg[j].ub()<0);                      //test if it comes back to the bubble

                    }
                    if(testBackIn == true){                                             //If so we calculate the max deviation
                        break;
                    }
                }

                if(testBackIn == true){                                                 //If my box was back in the bubble after integration, I store it in boxesbackin
                    (data.boxesInsideBackIn).append(currentBox);

                    continue;
                }
            }


            if (allBoxesLessEpsilon) {                                                          //if allBoxesLessEpsilon = true the box is unsafe and I continue my loop
                (data.boxesInsideUnsafe).push_back(currentBox);
                count++;
                if (count >=data.maxNumUnsafeBoxes && data.maxNumUnsafeBoxesActivated){         //If I have more boxes than nbPerhaps I stop the loop and I display the results
                    break;
                }
            }
            else {                                                                              //Otherwise we bissect following the widest diameter
                double l = 0;
                double l_temp = 0;
                int v = -1;
                for(int i = 0; i<currentBox.size()-1; i++){                                     //test that the diameter of the boxes doesnt depend on time
                    if(currentBox[i].is_bisectable()||!(currentBox[i].is_degenerated())){
                        l_temp = currentBox[i].diam();
                        if(l_temp>=data.epsilons[i] && l_temp/(data.epsilons[i]) > l){
                            l = l_temp/(data.epsilons[i]);
                            v = i;
                        }
                    }
                }

                l_temp = currentBox[currentBox.size()-1].diam();                                //test the time interval
                if(l_temp>=data.dt && l_temp/(data.dt) > l){
                    v = currentBox.size()-1;
                }
                if(v != -1 && currentBox[v].is_bisectable()){                                   // then the test interval of the state variables, and then it bisects the interval which has the largest diameter
                    pair<IntervalVector,IntervalVector> boxes=currentBox.bisect(v, 0.5);
                    (data.boxes).push_back(boxes.first);
                    (data.boxes).push_back(boxes.second);
                }
                else{
                    if (data.myDebug){
                        std::cout<<"Cannot be bisected \n";
                    }
                }
            }
        }

    }


    else                            //outer approximation
    {
        int count=0;
        //SIVIA
        //process all the boxes in data
        while (!data.boxes.empty()) {
            IntervalVector currentBox = data.boxes.front();                 //start from the first one
            data.boxes.pop_front();                                         //once it has been copied remove the first box

            IntervalVector auxBox=currentBox;                               //store it in aux variable to compare later

            tubeConstraints.contract(currentBox);                           //contract the current box using the previously calculated constraints
            if (currentBox!=auxBox){                                        //if the box has been contracted
                IntervalVector* removedByContractor;
                int setDiff=auxBox.diff(currentBox, removedByContractor);   //set difference between the contracted box and the original box
                for (int i = 0; i < setDiff; ++i) {
                    data.boxesOutside.push_back(removedByContractor[i]);    //add the areas removed by the contractor to the outside set
                }
                delete[] removedByContractor;
            }

            if(data.realTimeDraw){                                          //draw the boxes processing in real time
                draw_update(data, auxBox, currentBox);
            }


            bool allBoxesLessEpsilon=true;                                                                              //check if all the boxes are smaler than epsilon
            for (int i=0;(i<(currentBox.size()-1));i++){
                allBoxesLessEpsilon = (allBoxesLessEpsilon && ((currentBox.diam()[i])<=data.epsilons[i]));
            }
            allBoxesLessEpsilon = (allBoxesLessEpsilon && ((currentBox[currentBox.size()-1].diam())<=data.dt));         //check the time box also


            bool boxesLessEpsilon=false;                                                                                //check if at least one box is smaller than epsilon
            for (int i=0;(i<(currentBox.size()-1));i++){
                boxesLessEpsilon = boxesLessEpsilon||((currentBox[i].diam())<=data.epsilons[i]);
            }
            boxesLessEpsilon = boxesLessEpsilon&&((currentBox[currentBox.size()-1].diam())<=data.dt);                   //check time box


            if (boxesLessEpsilon && !allBoxesLessEpsilon){
                IntervalVector xnext = currentBox.subvector(0, data.numVarF-1).mid();   //using the middle point of the box calculate the future positions using euler method
                IntervalVector x = currentBox.mid();
                bool testBackIn;
                for (int i = 0;i<data.numFuturePos;i++){                                // Euler method: x(n+1)=x(n)+dt*fx
                    x[data.numVarF]= x[data.numVarF].mid();
                    testBackIn = true;
                    xnext=xnext+(data.dt)*data.f->eval_vector(x);
                    x.put(0, xnext);
                    x[data.numVarF] = x[data.numVarF]+(data.dt);
                    IntervalVector gg=data.g->eval_vector(x);
                    for(int j = 0; j<gg.size(); j++){
                        testBackIn = testBackIn && (gg[j].ub()<0);                      //test if it comes back to the bubble

                    }
                    if(testBackIn == true){                                             //If so we calculate the max deviation
                        break;
                    }
                }

                //                if(testBackIn == true){                                                 //If my box was back in the bubble after integration, I store it in boxesbackin
                //                    (data.boxesBackIn).append(currentBox);
                //                    continue;
                //                }
            }


            if (allBoxesLessEpsilon) {                                                          //if allBoxesLessEpsilon = true the box is unsafe and I continue my loop
                (data.boxesUnsafe).push_back(currentBox);
                count++;
                if (count >=data.maxNumUnsafeBoxes && data.maxNumUnsafeBoxesActivated){         //If I have more boxes than nbPerhaps I stop the loop and I display the results
                    break;
                }
            }
            else {                                                                              //Otherwise we bissect following the widest diameter
                double l = 0;
                double l_temp = 0;
                int v = -1;
                for(int i = 0; i<currentBox.size()-1; i++){                                     //test that the diameter of the boxes doesnt depend on time
                    if(currentBox[i].is_bisectable()||!(currentBox[i].is_degenerated())){
                        l_temp = currentBox[i].diam();
                        if(l_temp>=data.epsilons[i] && l_temp/(data.epsilons[i]) > l){
                            l = l_temp/(data.epsilons[i]);
                            v = i;
                        }
                    }
                }

                l_temp = currentBox[currentBox.size()-1].diam();                                //test the time interval
                if(l_temp>=data.dt && l_temp/(data.dt) > l){
                    v = currentBox.size()-1;
                }
                if(v != -1 && currentBox[v].is_bisectable()){                                   // then the test interval of the state variables, and then it bisects the interval which has the largest diameter
                    pair<IntervalVector,IntervalVector> boxes=currentBox.bisect(v, 0.5);
                    (data.boxes).push_back(boxes.first);
                    (data.boxes).push_back(boxes.second);
                }
                else{
                    if (data.myDebug){
                        std::cout<<"Cannot be bisected \n";
                    }
                }
            }
        }




        for(int i=0; i<data.boxesUnsafe.size();i++) {                   //process unsafe boxes

            IntervalVector currentBox=data.boxesUnsafe.at(i);
            IntervalVector nextBox = currentBox.subvector(0, data.numVarF-1);

            if (data.intMethod==0){                                     //Guaranteed integration

                // State variables
                Variable y(data.numVarF);

                // Initial conditions
                IntervalVector yinit(data.numVarF);

                for (int i = 0; i < data.numVarF; ++i) {
                    yinit[i] = currentBox[i];
                    cout<<currentBox[i]<<endl;
                }

                Interval t = currentBox[data.numVarF];
                Interval xd = 7*t;
                Interval xdd = 7;
                Interval yd = sin(0.1*t);
                Interval ydd = 0.1*cos(0.1*t);
                //                Interval xdiff = (xd-y[0]+xdd);
                //                Interval ydiff = (yd-y[1]+ydd);
                //                Interval norm =  (sqrt((xdiff)^2 +(ydiff)^2));


                // system fn has to be re entered here, cannot be loaded directly from text file
                //pendulum
                Function ydot = Function (y,Return (y[1],-1*sin(y[0])-0.15*y[1]));                               // Ivp contruction (initial time is 0.0)



                //non holonomic
                //                Function ydot = Function (y, Return ((sqrt(((xd-y[0]+xdd)*(xd-y[0]+xdd)) +((yd-y[1]+ydd)*(yd-y[1]+ydd))))*cos(y[2]), (sqrt(((xd-y[0]+xdd)*(xd-y[0]+xdd)) +((yd-y[1]+ydd)*(yd-y[1]+ydd))))*sin(y[2]),10*(cos(y[2])*((yd-y[1]+ydd))-sin(y[2])*((xd-y[0]+xdd)))/(sqrt(((xd-y[0]+xdd)*(xd-y[0]+xdd)) +((yd-y[1]+ydd)*(yd-y[1]+ydd))))));                               // Ivp contruction (initial time is 0.0)

                QTime t1;
                t1.start();

                ivp_ode problem = ivp_ode (ydot,0.0 , yinit);

                // Simulation construction and run
                simulation simu = simulation (&problem,data.dt*data.numFuturePos, __METH__, __PREC__);          //uses Runge-kutta4 method
                data.boxesUnsafeFuture.append(simu.run_simulation());                                           //modified ibex_simulation.h to make it return a list with all the solutions, not just the last one

                double timeSiviaCalculations1=t1.elapsed()/1000.0;
                double timeSiviaCalculationsTotal=tSivia.elapsed()/1000.0;
                cout<<endl<<"Unsafe # "<<i<<"  , Box time = "<<timeSiviaCalculations1<<" , Total elapsed time = "<<timeSiviaCalculationsTotal<<endl;
            }

            if (data.intMethod==1){                                     //euler method

                for (int i = 0;i<data.numFuturePos;i++){

                    IntervalVector gdotValue=gdot.eval_vector(currentBox);                                      //evaluate the g and gdot functions to inspect the constraints
                    IntervalVector gValue=data.g->eval_vector(currentBox);

                    if (data.myDebug){
                        cout<<"box = "<<currentBox<<endl;

                        for(int j = 0; j<gValue.size(); j++){
                            cout<<"gdot"<<j<<" = "<<gdotValue<<"  /  "<<(gdotValue[j].lb()>0) <<endl;                       //gdot i values
                        }
                    }


                    nextBox=nextBox+(data.dt)*data.f->eval_vector(currentBox);              //euler method
                    data.boxesUnsafeFuture.append(nextBox);

                    currentBox.put(0, nextBox);
                    currentBox[data.numVarF] = currentBox[data.numVarF]+(data.dt);          //increase time for the next step
                }
            }
            if (data.intMethod==2){                                     //vertex unsafe


                //check derivative of the unsafe boxes of outer g wrt the inner g
                //                Function g_inner("g_inner.txt");

                //                Function dg_inner(g_inner, Function::DIFF);                                     //  d/dx(gi)(x,t)
                //                Variable x(data.numVarF),t;                                         //we have x[] and t as variables for our fns

                //                // initialize auxMat and auxVector to the correct sizes and fill with zeros
                //                IntervalMatrix auxMat(data.numVarF+1, data.numVarF,Interval::ZERO);
                //                IntervalVector auxVector(data.numVarF+1,Interval::ZERO);

                //                //put 1 in the diagonal of auxMat
                //                for (int i=0; i<data.numVarF; i++){
                //                    auxMat[i][i]=1;}

                //                auxVector[data.numVarF]=1;

                //                Function f=("f.txt");
                //                Function gdot_inner(x,t,dg_inner(x,t)*(auxMat*transpose(f(x,t))+auxVector));

                //                cout<<"gdot: "<<gdot_inner<<endl;
                //                IntervalVector gdot_inner_Result=gdot_inner.eval_vector(currentBox);

                //                bool testNegative=true;

                //                for(int j = 0; j<gdot_inner_Result.size(); j++){
                //                    testNegative = testNegative && (gdot_inner_Result[j].ub()<0);
                //                }
                //                if (testNegative) {
                //                    data.boxesOuterGSafeForInnerG.append(currentBox);
                //                    cout<<"Safe for inner G: "<<currentBox<<" result: "<<gdot_inner_Result<<endl;
                //                }
                //                else{
                //                    data.boxesOuterGUnsafeForInnerG.append(currentBox);
                //                    cout<<"Unsafe for inner G: "<<currentBox<<" result: "<<gdot_inner_Result<<endl;
                //                }


                //system
                double x_k_lb[currentBox.size()], x_k_ub[currentBox.size()];
                for (int j = 0; j < currentBox.size(); ++j) {
                    x_k_ub[j]=currentBox[j].ub();
                    x_k_lb[j]=currentBox[j].lb();
                }

                int numVar=currentBox.size()-1;
                int numSamples=data.dt*data.numFuturePos*1000;
                double x_k_uu[numVar][numSamples];
                double x_k_ul[numVar][numSamples];
                double x_k_lu[numVar][numSamples];
                double x_k_ll[numVar][numSamples];


                x_k_uu[0][0]=x_k_ub[0];
                x_k_ll[0][0]=x_k_lb[0];
                x_k_lu[0][0]=x_k_lb[0];
                x_k_ul[0][0]=x_k_ub[0];

                x_k_uu[1][0]=x_k_ub[1];
                x_k_ll[1][0]=x_k_lb[1];
                x_k_lu[1][0]=x_k_ub[1];
                x_k_ul[1][0]=x_k_lb[1];

                double g_outer_uu, g_outer_lu, g_outer_ul, g_outer_ll, g_inner_uu, g_inner_lu, g_inner_ul, g_inner_ll;
                bool unsafeBox=false;
                bool safeBox=false;


                //pendulum system
                for (int j = 1; j < data.dt*data.numFuturePos*1000; ++j) {
                    x_k_uu[1][j]=data.dt/10.0*(-sin(x_k_uu[0][j-1])-0.15*x_k_uu[1][j-1])+x_k_uu[1][j-1];
                    x_k_ll[1][j]=data.dt/10.0*(-sin(x_k_ll[0][j-1])-0.15*x_k_ll[1][j-1])+x_k_ll[1][j-1];
                    x_k_lu[1][j]=data.dt/10.0*(-sin(x_k_lu[0][j-1])-0.15*x_k_lu[1][j-1])+x_k_lu[1][j-1];
                    x_k_ul[1][j]=data.dt/10.0*(-sin(x_k_ul[0][j-1])-0.15*x_k_ul[1][j-1])+x_k_ul[1][j-1];

                    x_k_uu[0][j]=(x_k_uu[1][j-1])*(data.dt/10.0)+x_k_uu[0][j-1];
                    x_k_ll[0][j]=(x_k_ll[1][j-1])*(data.dt/10.0)+x_k_uu[0][j-1];
                    x_k_lu[0][j]=(x_k_lu[1][j-1])*(data.dt/10.0)+x_k_uu[0][j-1];
                    x_k_ul[0][j]=(x_k_ul[1][j-1])*(data.dt/10.0)+x_k_uu[0][j-1];

                    //add discretized sys

                    //check if they leave the outer g
                    g_outer_uu= (x_k_uu[0][j]*x_k_uu[0][j])+(x_k_uu[1][j]*x_k_uu[1][j])-1;
                    g_outer_lu= (x_k_lu[0][j]*x_k_lu[0][j])+(x_k_lu[1][j]*x_k_lu[1][j])-1;
                    g_outer_ul= (x_k_ul[0][j]*x_k_ul[0][j])+(x_k_ul[1][j]*x_k_ul[1][j])-1;
                    g_outer_ll= (x_k_ll[0][j]*x_k_ll[0][j])+(x_k_ll[1][j]*x_k_ll[1][j])-1;

                    //check if the trajectories reenter the inner g
                    if (data.ellipseInner) {
                        g_inner_uu= (x_k_uu[0][j]*x_k_uu[0][j])/0.81+(x_k_uu[1][j]*x_k_uu[1][j])/(0.4*0.4)-1;
                        g_inner_lu= (x_k_lu[0][j]*x_k_lu[0][j])/0.81+(x_k_lu[1][j]*x_k_lu[1][j])/(0.4*0.4)-1;
                        g_inner_ul= (x_k_ul[0][j]*x_k_ul[0][j])/0.81+(x_k_ul[1][j]*x_k_ul[1][j])/(0.4*0.4)-1;
                        g_inner_ll= (x_k_ll[0][j]*x_k_ll[0][j])/0.81+(x_k_ll[1][j]*x_k_ll[1][j])/(0.4*0.4)-1;

                    }
                    else{
                        g_inner_uu= (x_k_uu[0][j]*x_k_uu[0][j])/(0.99*0.99)+(x_k_uu[1][j]*x_k_uu[1][j])/(0.96*0.96)-1;
                        g_inner_lu= (x_k_lu[0][j]*x_k_lu[0][j])/(0.99*0.99)+(x_k_lu[1][j]*x_k_lu[1][j])/(0.96*0.96)-1;
                        g_inner_ul= (x_k_ul[0][j]*x_k_ul[0][j])/(0.99*0.99)+(x_k_ul[1][j]*x_k_ul[1][j])/(0.96*0.96)-1;
                        g_inner_ll= (x_k_ll[0][j]*x_k_ll[0][j])/(0.99*0.99)+(x_k_ll[1][j]*x_k_ll[1][j])/(0.96*0.96)-1;

                    }


                    double myFutureBox[j][2][2];


                    double myMaxPos= qMax(qMax(qMax(x_k_uu[0][j],x_k_ll[0][j]),x_k_lu[0][j]),x_k_ul[0][j]);
                    double myMinPos= qMin(qMin(qMin(x_k_uu[0][j],x_k_ll[0][j]),x_k_lu[0][j]),x_k_ul[0][j]);

                    double myMaxVel= qMax(qMax(qMax(x_k_uu[1][j],x_k_ll[1][j]),x_k_lu[1][j]),x_k_ul[1][j]);
                    double myMinVel= qMin(qMin(qMin(x_k_uu[1][j],x_k_ll[1][j]),x_k_lu[1][j]),x_k_ul[1][j]);

                    myFutureBox[j][0][0]=myMinPos;
                    myFutureBox[j][0][1]=myMaxPos;

                    myFutureBox[j][1][0]=myMinVel;
                    myFutureBox[j][1][1]=myMaxVel;

                    IntervalVector BoxFuture(data.numVarG, myFutureBox[j]);
                    data.boxesVertexFuture.append(BoxFuture);

                    if (true &&(g_outer_uu>=0 || g_outer_lu>=0 || g_outer_ul>=0 || g_outer_ll>=0)){
                        unsafeBox=true;
                        data.boxesUnsafeOuterG.append(currentBox);
                        double myUnsafeFutureBox[j][2][2];
                        for (int k = 0; k < j; ++k) {

                            myMaxPos= qMax(qMax(qMax(x_k_uu[0][j],x_k_ll[0][j]),x_k_lu[0][j]),x_k_ul[0][j]);
                            myMinPos= qMin(qMin(qMin(x_k_uu[0][j],x_k_ll[0][j]),x_k_lu[0][j]),x_k_ul[0][j]);

                            myMaxVel= qMax(qMax(qMax(x_k_uu[1][j],x_k_ll[1][j]),x_k_lu[1][j]),x_k_ul[1][j]);
                            myMinVel= qMin(qMin(qMin(x_k_uu[1][j],x_k_ll[1][j]),x_k_lu[1][j]),x_k_ul[1][j]);

                            myUnsafeFutureBox[j][0][0]=myMinPos;
                            myUnsafeFutureBox[j][0][1]=myMaxPos;

                            myUnsafeFutureBox[j][1][0]=myMinVel;
                            myUnsafeFutureBox[j][1][1]=myMaxVel;

                            IntervalVector BoxUnsafeFuture(data.numVarG, myUnsafeFutureBox[k]);
                            data.boxesUnsafeOuterGFuture.append(BoxUnsafeFuture);
                            //                            cout<<"Unsafe vertex box "<<BoxUnsafeFuture<<endl;
                        }
                        break;
                    }

                    if (j>20 && g_inner_uu<0 && g_inner_lu<0 && g_inner_ul<0 && g_inner_ll<0){
                        safeBox=true;
                        //data.boxesUnsafeOuterG.append(currentBox);
                        double mySafeFutureBox[j][2][2];

                        for (int k = 0; k < j; ++k) {

                            myMaxPos= qMax(qMax(qMax(x_k_uu[0][j],x_k_ll[0][j]),x_k_lu[0][j]),x_k_ul[0][j]);
                            myMinPos= qMin(qMin(qMin(x_k_uu[0][j],x_k_ll[0][j]),x_k_lu[0][j]),x_k_ul[0][j]);

                            myMaxVel= qMax(qMax(qMax(x_k_uu[1][j],x_k_ll[1][j]),x_k_lu[1][j]),x_k_ul[1][j]);
                            myMinVel= qMin(qMin(qMin(x_k_uu[1][j],x_k_ll[1][j]),x_k_lu[1][j]),x_k_ul[1][j]);

                            mySafeFutureBox[j][0][0]=myMinPos;
                            mySafeFutureBox[j][0][1]=myMaxPos;

                            mySafeFutureBox[j][1][0]=myMinVel;
                            mySafeFutureBox[j][1][1]=myMaxVel;

                            IntervalVector BoxSafeFuture(data.numVarG, mySafeFutureBox[k]);
                            data.boxesGuaranteedIntegrationUnsafe.append(BoxSafeFuture);
                            //                            cout<<"Safe vertex box "<<BoxSafeFuture<<endl;
                        }
                        break;
                    }
                }
                if (unsafeBox==false && safeBox==true){
                    data.boxesUncertain.append(currentBox);
                }

            }
        }



        for (int i = 0; i < data.boxesUncertain.size(); ++i) {                              //process uncertain boxes

            IntervalVector uncertainBox=data.boxesUncertain.at(i);
            Variable y(data.numVarF);

            // Initial conditions
            IntervalVector yinit(data.numVarF);

            for (int j = 0; j < data.numVarF; ++j) {
                yinit[j] = uncertainBox[j];
                cout<<uncertainBox[j]<<endl;
            }

            Function ydot = Function (y,Return (y[1],-1*sin(y[0])-0.15*y[1]));                               // Ivp contruction (initial time is 0.0)

            QTime t1;
            t1.start();

            ivp_ode problem = ivp_ode (ydot, 0.0 , yinit);

            // Simulation construction and run
            int prevSize=data.boxesUncertainFuture.size();
            simulation simu = simulation (&problem,data.dt*data.numFuturePos, __METH__, __PREC__);          //uses Runge-kutta4 method
            data.boxesUncertainFuture.append(simu.run_simulation());                                           //modified ibex_simulation.h to make it return a list with all the solutions, not just the last one

            int afterSize=data.boxesUncertainFuture.size();
            for (int k = 0; k < (afterSize-prevSize); ++k) {
                data.boxesUncertainFutureIndex.append(i);
            }
            double timeSiviaCalculations1=t1.elapsed()/1000.0;
            double timeSiviaCalculationsTotal=tSivia.elapsed()/1000.0;
            cout<<endl<<"Unsafe # "<<i<<"  , Box time = "<<timeSiviaCalculations1<<" , Total elapsed time = "<<timeSiviaCalculationsTotal<<endl;

        }
        for (int j = 0; j < data.boxesUncertainFuture.size(); ++j) {
            IntervalVector myBox=data.boxesUncertainFuture.at(j);
            bool testInsideOuterG = true;
            Function g_outer("g_outer.txt");
            IntervalVector gg=g_outer.eval_vector(myBox);
            for(int j = 0; j<gg.size(); j++){
                testInsideOuterG = (testInsideOuterG && (gg[j].ub()<0));
            }
            if (testInsideOuterG==false){
                data.boxesUnsafeOuterGFuture.append(myBox);
                data.boxesUnsafeOuterG.append(data.boxesUncertain.at(data.boxesUncertainFutureIndex.at(j)));
            }
            else{
                data.boxesSafeOuterGFuture.append(myBox);
            }
        }
    }
}
BoolInterval PdcHansenFeasibility::test(const IntervalVector& box) {

	int n=f.nb_var();
	int m=f.image_dim();
	IntervalVector mid=box.mid();

	/* Determine the "most influencing" variable thanks to
	 * the pivoting of Gauss elimination */
	// ==============================================================
	Matrix A=f.jacobian(mid).mid();
	Matrix LU(m,n);
	int *pr = new int[m];
	int *pc = new int[n]; // the interesting output: the variables permutation
	BoolInterval res=MAYBE;

	try {
		real_LU(A,LU,pr,pc);
	} catch(SingularMatrixException&) {
		// means in particular that we could not extract an
		// invertible m*m submatrix
		delete [] pr;
		delete [] pc;
		return MAYBE;
	}
	// ==============================================================


//	PartialFnc pf(f,pc,m,mid);

	BitSet _vars=BitSet::empty(n);
	for (int i=0; i<m; i++) _vars.add(pc[i]);
	VarSet vars(f.nb_var(),_vars);

	IntervalVector box2(box);

	// fix parameters to their midpoint
	vars.set_param_box(box2, vars.param_box(box).mid());

	IntervalVector savebox(box2);

	if (inflating) {
		if (inflating_newton(f,vars,box2)) {
			_solution = box2;
			res = YES;
		} else {
			_solution.set_empty();
		}
	}
	else {
		// ****** TODO **********
			newton(f,vars,box2);

			if (box2.is_empty()) {
				_solution.set_empty();
			} else if (box2.is_strict_subset(savebox)) {
				_solution = box2;
				res = YES;
			}
	}

	delete [] pr;
	delete [] pc;
	return res;

}
Example #14
0
void Optimizer::optimize(const IntervalVector& init_box) {

	buffer.flush();

	Cell* root=new Cell(IntervalVector(n+1));

	write_ext_box(init_box,root->box);

	// add data required by the bisector
	bsc.add_backtrackable(*root);

	// add data required by optimizer + Fritz John contractor
	root->add<EntailedCtr>();
	//root->add<Multipliers>();
	entailed=&root->get<EntailedCtr>();
	entailed->init_root(user_sys,sys);

	loup_changed=false;
	loup_point=init_box.mid();
	time=0;
	Timer::start();
	handle_cell(*root,init_box);

	try {
		while (!buffer.empty()) {
			loup_changed=false;
			if (trace >= 2) cout << ((CellBuffer&) buffer) << endl;

			Cell* c=buffer.top();

			//	    cout << " box before bisection " <<  c->box << endl;

			try {
				pair<IntervalVector,IntervalVector> boxes=bsc.bisect(*c);

				pair<Cell*,Cell*> new_cells=c->bisect(boxes.first,boxes.second);

				delete buffer.pop();
				handle_cell(*new_cells.first, init_box);
				handle_cell(*new_cells.second, init_box);

				if (uplo_of_epsboxes == NEG_INFINITY) {
					cout << " possible infinite minimum " << endl;
					break;
				}
				if (loup_changed ) {
					// In case of a new upper bound (loup_changed == true), all the boxes
					// with a lower bound greater than (loup - goal_prec) are removed and deleted.
					// Note: if contraction was before bisection, we could have the problem
					// that the current cell is removed by contract_heap. See comments in
					// older version of the code (before revision 284).

					double ymax= compute_ymax();
					buffer.contract_heap(ymax);
					if (ymax <=NEG_INFINITY) {
						if (trace) cout << " infinite value for the minimum " << endl;
						break;
					}
					if (trace) cout << setprecision(12) << "ymax=" << ymax << " uplo= " <<  uplo<< endl;
				}
				update_uplo();
				time_limit_check();

			}
			catch (NoBisectableVariableException& ) {
				bool bb=false;
				for (int i=0;(!bb)&&( i<(c->box).size()); i++) {
					if (i!=ext_sys.goal_var())  // skip goal variable
						bb=bb||(c->box)[i].is_unbounded();
				}
				if (!bb) {
					// rem4: this case can append if the interval [1.79769e+308,inf] is in c.box.
					// It is only numerical degenerated case
					update_uplo_of_epsboxes ((c->box)[ext_sys.goal_var()].lb());
				}
				delete buffer.pop();
			}
		}
	}
	catch (TimeOutException& ) {
		return;
	}

	Timer::stop();
	time+= Timer::VIRTUAL_TIMELAPSE();
}