From 3992a0a6ad61a4b35b5f099ca6b8b8811fa11957 Mon Sep 17 00:00:00 2001 From: domensta Date: Mon, 16 Feb 2015 11:26:50 +0100 Subject: [PATCH 01/32] Create ibex_NodeType.cpp NodeType associated to regular i-set --- ibex_NodeType.cpp | 310 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 310 insertions(+) create mode 100644 ibex_NodeType.cpp diff --git a/ibex_NodeType.cpp b/ibex_NodeType.cpp new file mode 100644 index 000000000..24918e1b0 --- /dev/null +++ b/ibex_NodeType.cpp @@ -0,0 +1,310 @@ +//============================================================================ +// I B E X +// File : ibex_NodeType.cpp +// Author : Gilles Chabert +// Copyright : Ecole des Mines de Nantes (France) +// License : See the LICENSE file +// Created : 18 Aug 2014 +//============================================================================ + +#include "ibex_NodeType.h" + +// =========== shortcuts ================== +#define IN __IBEX_IN__ +#define OUT __IBEX_OUT__ +#define UNK __IBEX_UNK__ +#define UNK_IN __IBEX_UNK_IN__ +#define UNK_OUT __IBEX_UNK_OUT__ +#define UNK_IN_OUT __IBEX_UNK_IN_OUT__ +#define IN_TMP __IBEX_IN_TMP__ +// ======================================== + +namespace ibex { +// relic from irregular set, need for SetBisect constructor +NodeType operator|(NodeType x, NodeType y) { + switch (x) { + case IN : { + switch(y) { + case IN : return IN; + case OUT : + case UNK_OUT: + case UNK_IN_OUT: return UNK_IN_OUT; + default : return UNK_IN; + } + } + break; + case OUT : { + switch(y) { + case OUT : return OUT; + case IN : + case UNK_IN: + case UNK_IN_OUT: return UNK_IN_OUT; + default : return UNK_OUT; + } + } + break; + case UNK : { + switch(y) { + case IN : + case UNK_IN: return UNK_IN; + case OUT : + case UNK_OUT: return UNK_OUT; + case UNK: return UNK; + default: return UNK_IN_OUT; + } + } + break; + case UNK_IN : { + switch(y) { + case IN : + case UNK_IN: + case UNK : return UNK_IN; + default: return UNK_IN_OUT; + } + } + break; + case UNK_OUT : { + switch(y) { + case OUT : + case UNK_OUT: + case UNK : return UNK_OUT; + default: return UNK_IN_OUT; + } + } + break; + default : + //Warning: IN_TMP not considered here. + return UNK_IN_OUT; + } +} + + + +// define operator or between two nodetype, assuming the two boxes associated are equal +NodeType uni(NodeType x,NodeType y) { + switch (x) { + case IN : { + return IN; + + } + break; + case OUT : { + return y; + } + break; + case UNK : { + switch(y) { + case IN : return IN; + case UNK_IN: return UNK_IN; + case OUT : return UNK; + case UNK : return UNK; + case UNK_OUT: return UNK_OUT; + default: return UNK_IN_OUT; + } + } + break; + case UNK_IN : { + switch(y) { + case IN : + case UNK_IN: + case UNK : return UNK_IN; + default: return UNK_IN_OUT; + } + } + break; + case UNK_OUT : { + switch(y) { + case OUT : + case UNK_OUT: + case UNK : return UNK_OUT; + default: return UNK_IN_OUT; + } + } + break; + default : + //Warning: IN_TMP not considered here. + return UNK_IN_OUT; + } + +} + +// define operator or between two nodetype, assuming box of nodetype y is subset of box of nodetype x; +NodeType uni_in(NodeType x, NodeType y) { + switch (x) { + case IN : { + switch(y) { + case IN : return IN; + case OUT : return IN; + case UNK : return IN; + case UNK_OUT: + case UNK_IN_OUT: return UNK_IN_OUT; + default : return UNK_IN; + } + } + break; + case OUT : { + switch(y) { + case OUT : return OUT; + case IN : return UNK; + case UNK : return UNK; + case UNK_IN: + case UNK_IN_OUT: return UNK_IN_OUT; + default : return UNK_OUT; + } + } + break; + case UNK : { + switch(y) { + return UNK; + } + } + break; + /*case UNK_IN : { + switch(y) { + case IN : + case UNK_IN: + case UNK : return UNK_IN; + default: return UNK_IN_OUT; + } + } + break; + case UNK_OUT : { + switch(y) { + case OUT : + case UNK_OUT: + case UNK : return UNK_OUT; + default: return UNK_IN_OUT; + } + } + break;*/ + default : + //Warning: IN_TMP not considered here. + return UNK_IN_OUT; + + } +} + +// define operator and between two nodetype, assuming the two boxes associated are equal +NodeType inte(NodeType x, NodeType y) { + switch (x) { + case IN : { + return y; + } + break; + case OUT : { + return OUT; + } + break; + case UNK : { + switch(y) { + case IN : return UNK; + case UNK_IN: return UNK_IN; + case OUT : return OUT; + case UNK : return UNK; + case UNK_OUT: return UNK_OUT; + default: return UNK_IN_OUT; + } + } + break; + case UNK_IN : { + switch(y) { + case IN : + case UNK_IN: + case UNK : return UNK_IN; + default: return UNK_IN_OUT; + } + } + break; + case UNK_OUT : { + switch(y) { + case OUT : + case UNK_OUT: + case UNK : return UNK_OUT; + default: return UNK_IN_OUT; + } + } + break; + default : + //Warning: IN_TMP not considered here. + return UNK_IN_OUT; + } +} + + +// define operator and between two nodetype, assuming box of nodetype y is subset of box of nodetype x; +NodeType inte_in(NodeType x, NodeType y) { + switch (x) { + case IN : { + switch(y) { + case IN : return IN; + case OUT : return UNK; + case UNK : return UNK; + case UNK_OUT: + case UNK_IN_OUT: return UNK_IN_OUT; + default : return UNK_IN; + } + } + break; + case OUT : { + switch(y) { + case OUT : return OUT; + case IN : return OUT; + case UNK : return OUT; + case UNK_IN: + case UNK_IN_OUT: return UNK_IN_OUT; + default : return UNK_OUT; + } + } + break; + case UNK : { + switch(y) { + case IN : return UNK; + case UNK_IN: return UNK_IN; + case OUT : return UNK; + case UNK_OUT: return UNK_OUT; + case UNK: return UNK; + default: return UNK_IN_OUT; + } + } + break; + case UNK_IN : { + switch(y) { + case IN : + case UNK_IN: + case UNK : return UNK_IN; + default: return UNK_IN_OUT; + } + } + break; + case UNK_OUT : { + switch(y) { + case OUT : + case UNK_OUT: + case UNK : return UNK_OUT; + default: return UNK_IN_OUT; + } + } + break; + default : + //Warning: IN_TMP not considered here. + return UNK_IN_OUT; + } +} + +bool certainly_contains_in(NodeType x) { + return x==IN || x==UNK_IN || x==UNK_IN_OUT; +} + +bool certainly_contains_out(NodeType x) { + return x==OUT || x==UNK_OUT || x==UNK_IN_OUT; +} + +bool possibly_contains_in(NodeType x) { + return x!=OUT; +} + +bool possibly_contains_out(NodeType x) { + return x!=IN; +} + +} // namespace ibex From 104e8443e036daeab6c3ed4efcd04f83ca20e4cc Mon Sep 17 00:00:00 2001 From: domensta Date: Mon, 16 Feb 2015 11:29:15 +0100 Subject: [PATCH 02/32] Create ibex_NodeType.h NodeType.h associated to regular i-set. --- ibex_NodeType.h | 92 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 ibex_NodeType.h diff --git a/ibex_NodeType.h b/ibex_NodeType.h new file mode 100644 index 000000000..7456e64f4 --- /dev/null +++ b/ibex_NodeType.h @@ -0,0 +1,92 @@ +//============================================================================ +// I B E X +// File : ibex_NodeType.h +// Author : Gilles Chabert +// Copyright : Ecole des Mines de Nantes (France) +// License : See the LICENSE file +// Created : 18 Aug 2014 +//============================================================================ + +#ifndef __IBEX_NODE_TYPE_H__ +#define __IBEX_NODE_TYPE_H__ + +namespace ibex { + +/** \ingroup iset */ +/*@{*/ + +/** + * \brief Status of a node in the representation of an i-set. + * + * __IBEX_IN__ : the node box is inside the set + * __IBEX_OUT__ : the node box is outside the set + * __IBEX_UNK__ : the node is of unknown status (typically, corresponds to a boundary box) + * __IBEX_UNK_IN : the subtree contains IN and UNK leaves + * __IBEX_UNK_OUT : the subtree contains OUT and UNK leaves + * __IBEX_UNK_IN_OUT : the subtree contains IN, OUT and UNK leaves + * __IBEX_IN_TMP__ : used by "inter" functions only. Means "inside the original set" (but not necessarily inside the intersection) + */ +typedef enum { __IBEX_IN__, + __IBEX_OUT__, + __IBEX_UNK__, + __IBEX_UNK_IN__, + __IBEX_UNK_OUT__, + __IBEX_UNK_IN_OUT__, + __IBEX_IN_TMP__ } NodeType; + +/** + * \brief Status of a union of two nodes. + * + * \note Status only useful for "sync" functions. So the IN_TMP status is ignored (and this makes no problem so far). + * + * Ex: __IBEX_IN__ | __IBEX_UNK__ gives __IBEX_IN_UNK__. + * + * \see SetBisect constructor. + */ +NodeType operator|(NodeType x, NodeType y); +/** + * \brief return value of union of two equal boxes + */ +NodeType uni(NodeType x,NodeType y); +/** + * \brief return value of union of two boxes, assuming the on associated to y is include in the one associated to x + */ +NodeType uni_in(NodeType x, NodeType y); +/** + * \brief return value of inter of two equal boxes + */ +NodeType inte(NodeType x, NodeType y); +/** + * \brief return value of inter of two boxes, assuming the on associated to y is include in the one associated to x + */ +NodeType inte_in(NodeType x, NodeType y); +/** + * \brief return value of inter of two boxes, assuming the on associated to y is include in the one associated to x + */ +bool possibly_contains_in(NodeType x); + +/** + * \brief False only if the subtree contains no outer point + */ +bool possibly_contains_out(NodeType x); + +/** + * \brief True only if the subtree contains inner points + */ +bool certainly_contains_in(NodeType x); + +/** + * \brief True only if the subtree contains outer points + */ +bool certainly_contains_out(NodeType x); + +/** + * \brief Convert the status to char + */ +char to_string(const NodeType& status); + +/*@}*/ + +} // namespace ibex + +#endif // __IBEX_NODE_TYPE_H__ From f276ae9a5ca9796c96489e2dc0d181737388d839 Mon Sep 17 00:00:00 2001 From: domensta Date: Mon, 16 Feb 2015 11:32:46 +0100 Subject: [PATCH 03/32] Create ibex_SetNode.cpp SetNode.cpp associated to regular i-set. --- ibex_SetNode.cpp | 56 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 ibex_SetNode.cpp diff --git a/ibex_SetNode.cpp b/ibex_SetNode.cpp new file mode 100644 index 000000000..35824f5f9 --- /dev/null +++ b/ibex_SetNode.cpp @@ -0,0 +1,56 @@ +//============================================================================ +// I B E X +// File : ibex_SetNode.cpp +// Author : Gilles Chabert +// Copyright : Ecole des Mines de Nantes (France) +// License : See the LICENSE file +// Created : 13 juil. 2014 +//============================================================================ + +#include "ibex_SetNode.h" +#include "ibex_SetLeaf.h" +#include "ibex_SetBisect.h" + #include + +using namespace std; + +// =========== shortcuts ================== +#define IN __IBEX_IN__ +#define OUT __IBEX_OUT__ +#define UNK __IBEX_UNK__ +#define UNK_IN __IBEX_UNK_IN__ +#define UNK_OUT __IBEX_UNK_OUT__ +#define UNK_IN_OUT __IBEX_UNK_IN_OUT__ +#define IN_TMP __IBEX_IN_TMP__ +// ======================================== + +namespace ibex { + + +char to_string(const NodeType& status) { + switch(status) { + case IN : return 'Y'; break; + case OUT : return 'N'; break; + default : return '?'; + } +} + +SetNode::SetNode(NodeType status) : status(status), father(NULL) { + +} + +SetNode::SetNode(NodeType status, SetNode *father): status(status), father(father) { + +} + +SetNode::~SetNode() { + +} + +/*void SetNode::inter(const SetNode* other) +{ + +}*/ + + +} // namespace ibex From f26cec98d3f2e43290f99c57db87af84d46ac7fc Mon Sep 17 00:00:00 2001 From: domensta Date: Mon, 16 Feb 2015 11:34:57 +0100 Subject: [PATCH 04/32] Create ibex_SetNode.h SetNode.h associated to regular i-set. A pointer on the father of the node has been added. --- ibex_SetNode.h | 159 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 159 insertions(+) create mode 100644 ibex_SetNode.h diff --git a/ibex_SetNode.h b/ibex_SetNode.h new file mode 100644 index 000000000..a6a289c83 --- /dev/null +++ b/ibex_SetNode.h @@ -0,0 +1,159 @@ +//============================================================================ +// I B E X +// File : ibex_SetNode.h +// Author : Gilles Chabert +// Copyright : Ecole des Mines de Nantes (France) +// License : See the LICENSE file +// Created : 13 juil. 2014 +//============================================================================ + +#ifndef __IBEX_SET_NODE_H__ +#define __IBEX_SET_NODE_H__ + +#include "ibex_IntervalVector.h" +#include "ibex_Sep.h" +#include "ibex_NodeType.h" +#include "ibex_BoolInterval.h" + +namespace ibex { + +/** + * \ingroup iset + * \brief Exception thrown by sync function. + * + * Thrown when the i-set is empty (<=> no set exists). + */ +class NoSet { + +}; +/** + * \ingroup iset + * \brief Exception thrown by sync function. + * + * use to compute regular cutting of a interval + */ +class vcut{ + int var; + double pt; +}; + +/** + * \brief Set node. + */ +class SetNode { + +public: + /** + * \brief Callback for "visit_leaves" + */ + typedef void (*leaf_func) (const IntervalVector&, BoolInterval); + + /** + * \brief Creates a node of given status + */ + SetNode(NodeType status); + + /** + * \brief Creates a node of given status and father + */ + SetNode(NodeType status,SetNode *father); + + + /** + * \brief Delete this. + */ + virtual ~SetNode(); + + /** + * \brief True iff this node is a leaf. + */ + virtual bool is_leaf() const=0; + + /** + * \brief Return a copy of the node. + */ + virtual SetNode * copy() const=0; + + + /** + * \brief Intersection or Union between a box of NodeType val and a regular setInterval. + * Box may not respect the regularity of the regular setInterval. + * The part of the set that intersect nodebox only is modify. + */ + virtual void operator_ir(const IntervalVector& box,const IntervalVector& nodebox, NodeType val, bool op, double eps)=0; + + /** + * \brief Call by operator_ir, create a subtree from a leaf with "fake leves" that are setbisect with left and right set to null + * should avoid to create leaf and eventually destruct it if it need to be cut i.e replace by a setbisect + * method abandonned, oddly slower than creating leaves and replace them by setbisect. + */ + virtual SetNode * fakeLeaf(const IntervalVector& box,const IntervalVector& subbox,NodeType val,bool op, double eps)=0; + + /** + * \brief Overloaded function, apply valout to the set outside of the box and valin to the inside, thus modify the whole set. + */ + virtual void operator_ir(const IntervalVector& box,const IntervalVector& subbox, NodeType valin,NodeType valout, bool op,double eps)=0; + + /** + * \brief Intersection between two setNode. + */ + virtual void oper(SetNode* other,bool op)=0; + + /** + * \brief Intersection between setnode and a status. + */ + virtual void inter(NodeType x_status)=0; + + /** + * \brief Union between setnode and a status. + */ + virtual void _union(NodeType x)=0; + + /** + * \brief Change value of branch if right and left got the same value IN, OUT or UNK. + */ + virtual void gather(bool go_up)=0; + /** + * \brief Delete the branch if left and right got the same value IN, OUT or UNK. + */ + virtual void cutDeadBranch()=0; + + /** + * \brief Check if fathers are initialized. + */ + virtual void checkFat()=0; + + /** + * \brief Contrat i-set w.r.t separator sep, split leaves until boxin and boxout returned by sep are disjoints, + * and then call operator_ir to contract on them + */ + virtual void cleave(const IntervalVector& box, Sep& sep,double eps)=0; + + /** + * \brief Visit the leaves of a tree with a callback "func" + */ + virtual void visit_leaves(leaf_func func, const IntervalVector& nodebox) const=0; + + /** + * \brief Display the structure on output stream "os" + */ + virtual void print(std::ostream& os, const IntervalVector& nodebox, int shift) const=0; + + /** + * \brief Set fathers of the nodes + */ + virtual void setFathers()=0; + + + + /** + * \brief The status of the node + */ + NodeType status; + SetNode * father; +}; + + +} // namespace ibex + +#endif // __IBEX_SET_NODE_H__ From 9f8352a8e96d4c7705f1feddf45a8bc9b50e2637 Mon Sep 17 00:00:00 2001 From: domensta Date: Mon, 16 Feb 2015 11:36:22 +0100 Subject: [PATCH 05/32] Create ibex_SetBisect.cpp SetBisect.cpp associated to regular i-set. --- ibex_SetBisect.cpp | 300 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 300 insertions(+) create mode 100644 ibex_SetBisect.cpp diff --git a/ibex_SetBisect.cpp b/ibex_SetBisect.cpp new file mode 100644 index 000000000..01e95bcee --- /dev/null +++ b/ibex_SetBisect.cpp @@ -0,0 +1,300 @@ +//============================================================================ +// I B E X +// File : ibex_SetBisect.cpp +// Author : Gilles Chabert +// Copyright : Ecole des Mines de Nantes (France) +// License : See the LICENSE file +// Created : 13 juil. 2014 +//============================================================================ + +#include "ibex_SetBisect.h" +#include "ibex_SetLeaf.h" +#include +#include + +using namespace std; + +// =========== shortcuts ================== +#define IN __IBEX_IN__ +#define OUT __IBEX_OUT__ +#define UNK __IBEX_UNK__ +#define UNK_IN __IBEX_UNK_IN__ +#define UNK_OUT __IBEX_UNK_OUT__ +#define UNK_IN_OUT __IBEX_UNK_IN_OUT__ +#define IN_TMP __IBEX_IN_TMP__ +// ======================================== + +namespace ibex { + +SetBisect::SetBisect(int var, double pt, SetNode* left, SetNode* right) : SetNode(UNK_IN_OUT,NULL), var(var), pt(pt), left(left), right(right) { + +} + +SetBisect::SetBisect(int var, double pt, SetNode* left, SetNode* right,SetNode* father) : SetNode(UNK_IN_OUT,father), var(var), pt(pt), left(left), right(right) { + +} + +SetBisect::SetBisect(int var, double pt) : SetNode(UNK_IN_OUT), var(var), pt(pt), left(NULL), right(NULL) { + +} + +SetBisect::~SetBisect() { + delete left; + delete right; +} + +bool SetBisect::is_leaf() const { + return false; +} + +SetNode * SetBisect::copy() const { + SetBisect * n = new SetBisect(this->var,this->pt,this->left->copy(),this->right->copy()); + n->left->father = n; + n->right->father = n; + return n; +} + + +void SetBisect::inter(NodeType x) { + + left->inter(x); // apply inter to left and right until reach the leaves + right->inter(x); +} + +void SetBisect::_union(NodeType x) { + left->_union(x); + right->_union(x); +} + +void SetBisect::oper(SetNode * node,bool op) { + if(node->is_leaf()) // apply status to leaves of the subtree which have this as root + { + if(op && node->status != IN) + { + left->inter(node->status); + right->inter(node->status); + } + else if(!op && node->status!= OUT) + { + left->_union(node->status); + right->_union(node->status); + } + } + else + { + SetBisect * other = (SetBisect*) node; // node is assume to be either a leaf or a bisect, able to cast node in bisect as it ain't a leaf + left->oper(other->left,op); + right->oper(other->right,op); + } +} + +void SetBisect::operator_ir(const IntervalVector& box,const IntervalVector& subbox, NodeType val,bool op, double eps) +{ + + if(box.is_subset(subbox)) // compute intersection of leaves of this root with val + { + if(op && val != IN) + this->inter(val); + else if(!op && val != OUT) + this->_union(val); + } + else + { + if(this->left_box(box).overlaps(subbox)) // need to apply function on left only if leftbox ovelaps subbox + left->operator_ir(this->left_box(box),subbox,val,op,eps); + if(this->right_box(box).overlaps(subbox)) // need to apply function on right only if rightbox overlaps subbox + right->operator_ir(this->right_box(box),subbox,val,op,eps); + } +} + +void SetBisect::operator_ir(const IntervalVector& box,const IntervalVector& subbox, NodeType valin,NodeType valout,bool op, double eps) +{ + + if(box.is_subset(subbox)) // apply valin on the leaves of this root + { + if(op && valin != IN) + this->inter(valin); + else if(!op && valin != OUT) + this->_union(valin); + } + else if(box.overlaps(subbox)) + { + if(this->left_box(box).overlaps(subbox)) + left->operator_ir(this->left_box(box),subbox,valin,valout,op,eps); + else { // leftbox is disjoint of subbox, apply valout on the leaves of this->left root + if(op && valout != IN) + left->inter(valout); + else if (!op && valout != OUT) + left->_union(valout);} + if(this->right_box(box).overlaps(subbox)) + right->operator_ir(this->right_box(box),subbox,valin,valout,op,eps); + else{ // rightbox is disjoint of subbox, apply valout on the leaves of this->right root + if(op && valout != IN) + right->inter(valout); + else if (!op && valout != OUT) + right->_union(valout);} + } + else{ // this is disjoint of subbox, apply valout on the leaves of this root + if(op && valout != IN) + this->inter(valout); + else if (!op && valout != OUT) + this->_union(valout);} +} + +// Uncomment this function and comment the one above to use fakeBranch method +/*void SetBisect::operator_ir(const IntervalVector& box,const IntervalVector& subbox, NodeType val,bool op, double eps) +{ + + if(left == NULL) + { + assert(right == NULL); + left = this->fakeLeaf(left_box(box),subbox,val,op,eps); + left->father = this; + right = this->fakeLeaf(right_box(box),subbox,val,op,eps); + right->father = this; + status = UNK_IN_OUT; + } + else + { + if(box.is_subset(subbox)) + { + if(op) + this->inter(val); + else + this->_union(val); + } + else + { + if(this->left_box(box).overlaps(subbox)) + left->operator_ir(this->left_box(box),subbox,val,op,eps); + else + return; + if(this->right_box(box).overlaps(subbox)) + right->operator_ir(this->right_box(box),subbox,val,op,eps); + else + return; + } + } +}*/ + +SetNode * SetBisect::fakeLeaf(const IntervalVector& box,const IntervalVector& subbox,NodeType val,bool op, double eps) { + //assert(left == NULL && right == NULL); + if(box.is_subset(subbox)) + if(op) + return new SetLeaf(inte(status,val)); + else + return new SetLeaf(uni(status,val)); + else if(box.overlaps(subbox)) + { + if(box.max_diam()<=eps) + return new SetLeaf(inte_in(status,val)); + else + { + int var = box.extr_diam_index(false); + double pt = box[var].mid(); + SetBisect * node = new SetBisect(var,pt,NULL,NULL); + node->status = status; + node->left = node->fakeLeaf(node->left_box(box),subbox,val,op,eps); + node->right = node->fakeLeaf(node->right_box(box),subbox,val,op,eps); + node->left->father = node; + node->right->father = node; + node->status = UNK_IN_OUT; + return node; + } + } + else + return new SetLeaf(status); +} +void SetBisect::cleave(const IntervalVector& box, Sep& sep, double eps) { + + IntervalVector box1(box); + IntervalVector box2(box); + + sep.separate(box1,box2); + if(box1.is_disjoint(box2)) // in and out are disjoint, can contract on box1 and box2 + { + if(!box1.is_empty()) + this->operator_ir(box,box1,IN,true,eps); + if(!box2.is_empty()) + this->operator_ir(box,box2,OUT,true,eps); + } + else // continu until box1 and box2 are disjoint + { + left->cleave(left_box(box),sep,eps); + right->cleave(right_box(box),sep,eps); + } +} +void SetBisect::gather(bool go_up) { + if(((left->is_leaf()&&right->is_leaf()) || go_up)&&left->status==right->status) // leaves are reached, or climbing up the tree toward the root + { + status = left->status; // this bisect get a leaf status IN OUT or UNK + if(father != NULL) // check if father is not the root of SetInterval + father->gather(true); + } + else if(!go_up) // go down the tree to reach the leaves + { + left->gather(false); + right->gather(false); + } +} + +void SetBisect::cutDeadBranch() { + if(left->status ==right->status && left->status < 3) // if status of left and right are equal and has got a leaf status, meaning all leaves have the same status + { + SetBisect* bfather = (SetBisect*) father; + if(bfather->left == this) + bfather->left = new SetLeaf(status,father); // this is now a leaf + else + bfather->right = new SetLeaf(status,father); // this is now a leaf + delete this; // delete former this which was a bisect + } + else // go down the tree until reach leaves or bisect that can be set a leaf + { + left->cutDeadBranch(); + right->cutDeadBranch(); + } +} + + +void SetBisect::checkFat() { + if(father == NULL) + cout<<"issue, invalid father"<checkFat(); + right->checkFat(); +} +void SetBisect::visit_leaves(leaf_func func, const IntervalVector& nodebox) const { + left->visit_leaves(func, left_box(nodebox)); + right->visit_leaves(func, right_box(nodebox)); +} + +void SetBisect::print(ostream& os, const IntervalVector& nodebox, int shift) const { + for (int i=0; iprint(os, left_box(nodebox), shift+2); + right->print(os, right_box(nodebox), shift+2); +} + +void SetBisect::setFathers() { + left->father = this; + right->father = this; + left->setFathers(); + right->setFathers(); +} + + +IntervalVector SetBisect::left_box(const IntervalVector& nodebox) const { + IntervalVector leftbox(nodebox); + assert (nodebox[var].contains(pt)); + leftbox[var] =Interval(nodebox[var].lb(),pt); + return leftbox; +} + +IntervalVector SetBisect::right_box(const IntervalVector& nodebox) const { + IntervalVector rightbox(nodebox); + assert (nodebox[var].contains(pt)); + rightbox[var]=Interval(pt,nodebox[var].ub()); + return rightbox; +} + + +} // namespace ibex From 96af337e278731d0feca5e792da17821ee6ffe15 Mon Sep 17 00:00:00 2001 From: domensta Date: Mon, 16 Feb 2015 11:37:30 +0100 Subject: [PATCH 06/32] Create ibex_SetBisect.h SetBisect.h associated to regular i-set. --- ibex_SetBisect.h | 118 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 ibex_SetBisect.h diff --git a/ibex_SetBisect.h b/ibex_SetBisect.h new file mode 100644 index 000000000..fb0073e38 --- /dev/null +++ b/ibex_SetBisect.h @@ -0,0 +1,118 @@ +//============================================================================ +// I B E X +// File : ibex_SetBisect.h +// Author : Gilles Chabert +// Copyright : Ecole des Mines de Nantes (France) +// License : See the LICENSE file +// Created : 13 juil. 2014 +//============================================================================ + +#ifndef __IBEX_SET_BISECT_H__ +#define __IBEX_SET_BISECT_H__ + +#include "ibex_SetNode.h" + +namespace ibex { + +/** + * \ingroup iset + * \brief Bisection node (i-set representation) + */ +class SetBisect : public SetNode { + +public: + + /** + * \brief Create a bisection node + * + * The variable of the nodebox is bisected at point "pt", resulting + * in two subnodes, left and right. + */ + SetBisect(int var, double pt, SetNode* left, SetNode* right); + + SetBisect(int var, double pt, SetNode* left, SetNode* right,SetNode* father); + + /** + * \brief Delete this + */ + virtual ~SetBisect(); + + /** \see SetNode */ + virtual bool is_leaf() const; + + /** \see SetNode */ + virtual SetNode * copy() const; + + /** \see SetNode */ + virtual void inter(NodeType x_status); + + /** \see SetNode */ + virtual void _union(NodeType x); + + /** \see SetNode */ + virtual void oper(SetNode * other,bool op); + + /** \see SetNode */ + virtual void operator_ir(const IntervalVector& box,const IntervalVector& nodebox, NodeType val,bool op, double eps); + + /** \see SetNode */ + virtual void operator_ir(const IntervalVector& box,const IntervalVector& subbox, NodeType valin,NodeType valout, bool op,double eps); + + /** \see SetNode */ + virtual SetNode * fakeLeaf(const IntervalVector& box,const IntervalVector& subbox,NodeType val,bool op, double eps); + + /** \see SetNode */ + virtual void cleave(const IntervalVector& box, Sep& sep, double eps); + + /** \see SetNode */ + virtual void gather(bool go_up); + + /** \see SetNode */ + virtual void cutDeadBranch(); + + /** \see SetNode */ + virtual void checkFat(); + + /** \see SetNode */ + virtual void visit_leaves(leaf_func func, const IntervalVector& nodebox) const; + + /** \see SetNode */ + virtual void print(std::ostream& os, const IntervalVector& nodebox, int shift) const; + + /** \see SetNode */ + virtual void setFathers(); + + + + + + /** + * \brief Rerturn left_box according to var, pt and nodebox + */ + IntervalVector left_box(const IntervalVector& nodebox) const; + + /** + * \brief Rerturn left_box according to var, pt and nodebox + */ + IntervalVector right_box(const IntervalVector& nodebox) const; + +//protected: + friend class SetNode; + friend class SetInterval; + + // partial initialization used by SetInterval::load only + SetBisect(int var, double pt); + + + int var; + double pt; + SetNode* left; + SetNode* right; + +private: + SetBisect(const SetBisect&); // forbidden +}; + +} // namespace ibex + +#endif // __IBEX_SET_BISECT_H__ From 739b052a3559f59461ed08aab1498bd9531c9bf0 Mon Sep 17 00:00:00 2001 From: domensta Date: Mon, 16 Feb 2015 11:39:03 +0100 Subject: [PATCH 07/32] Create ibex_SetLeaf.cpp SetLeaf.cpp associated to regular i-set. --- ibex_SetLeaf.cpp | 282 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 282 insertions(+) create mode 100644 ibex_SetLeaf.cpp diff --git a/ibex_SetLeaf.cpp b/ibex_SetLeaf.cpp new file mode 100644 index 000000000..441da0259 --- /dev/null +++ b/ibex_SetLeaf.cpp @@ -0,0 +1,282 @@ +//============================================================================ +// I B E X +// File : ibex_SetLeaf.cpp +// Author : Gilles Chabert +// Copyright : Ecole des Mines de Nantes (France) +// License : See the LICENSE file +// Created : 13 juil. 2014 +//============================================================================ + +#include "ibex_SetLeaf.h" +#include "ibex_SetBisect.h" + +using namespace std; + +// =========== shortcuts ================== +#define IN __IBEX_IN__ +#define OUT __IBEX_OUT__ +#define UNK __IBEX_UNK__ +#define UNK_IN __IBEX_UNK_IN__ +#define UNK_OUT __IBEX_UNK_OUT__ +#define UNK_IN_OUT __IBEX_UNK_IN_OUT__ +#define IN_TMP __IBEX_IN_TMP__ +// ======================================== + +namespace ibex { + +SetLeaf::SetLeaf(NodeType status) : SetNode(status) { + if (status>UNK && status!=IN_TMP) { + ibex_error("cannot set multiple status to SetLeaf"); + } +} + +SetLeaf::SetLeaf(NodeType status,SetNode* father): SetNode(status,father) { + +} + +SetLeaf::~SetLeaf() { + +} + +bool SetLeaf::is_leaf() const { + return true; +} + + SetNode * SetLeaf::copy() const { + return new SetLeaf(this->status); +} + +void SetLeaf::inter(NodeType x_status) { + status = inte(status,x_status); +} + +void SetLeaf::_union(NodeType x) { + status = uni(status,x); +} + +void SetLeaf::oper(SetNode * node,bool op) { + if(node->is_leaf()) // if node is leaf, apply its value to leaves of this + { + if(op) + status = inte(status,node->status); + else + status = uni(status,node->status); + } + else{ // if this is leaf and node isn't + SetBisect * bfather = (SetBisect*) father; + if(bfather->left == this) + { + bfather->left = node->copy(); // copy the structure of node + bfather->left->father = father; + if(op && status != IN) + bfather->left->inter(status); // apply status to leaves + else if(!op && status!= OUT) + bfather->left->_union(status); + } + else + { + bfather->right = node->copy(); + bfather->right->father = father; + if(op && status != IN) + bfather->right->inter(status); + else if(!op && status!= OUT) + bfather->right->_union(status); + } + delete this; // delete this as it is now a setBisect and no more a leaf + + } +} + +void SetLeaf::operator_ir(const IntervalVector& box,const IntervalVector& subbox, NodeType val, bool op,double eps) { + if(box.is_subset(subbox)) + { + if(op && val != IN) + status = inte(status,val); + else if(!op && val!=OUT) + status = uni(status,val); + } + else if(box.max_diam()>eps) + { + SetBisect * bfather = (SetBisect*) father; + int var = box.extr_diam_index(false); // indice of the maximal diameter + double pt = box[var].mid(); + SetLeaf * lnode = new SetLeaf(status,NULL); // create future right node + SetLeaf * rnode = new SetLeaf(status,NULL); // create future left node + if(bfather->left == this) // this is father->left + { + bfather->left = new SetBisect(var,pt,lnode,rnode,father); // create SetBisect to replace leaf + lnode->father = bfather->left; // set fathers + rnode->father = bfather->left; + bfather->left->operator_ir(box,subbox,val,op,eps); + } + else // this is father->right + { + bfather->right = new SetBisect(var,pt,lnode,rnode,father); + lnode->father = bfather->right; + rnode->father = bfather->right; + bfather->right->operator_ir(box,subbox,val,op,eps); + } + delete this; // delete former father->left or father->right + } + else // if leaf reach minimum precision, compute partial intersection or union + { + if(op) + status = inte_in(status,val); + else + status = uni_in(status,val); + } +} + +// Uncomment this function and comment the one above to use fakeBranch method +/*void SetLeaf::operator_ir(const IntervalVector& box,const IntervalVector& subbox, NodeType val, bool op,bool is_left,double eps) { + if(box.is_subset(subbox)) + { + if(op) + status = inte(status,val); + else + status = uni(status,val); + } + else if(box.overlaps(subbox)) + { + if(box.max_diam()>eps) + { + SetBisect * bfather = (SetBisect*) father; + int var = box.extr_diam_index(false); // indice of the maximal diameter + double pt = box[var].mid(); + if(bfather->left == this) + { + bfather->left = new SetBisect(var,pt,NULL,NULL,father); + bfather->left->status = status; // create new set bissect with nodetype IN OUT or UNK, that it will transmit this value to its left and right + bfather->left->operator_ir(box,subbox,val,op,eps); + } + else + { + bfather->right = new SetBisect(var,pt,NULL,NULL,father); + bfather->right->status = status; // create new set bissect with nodetype IN OUT or UNK, that it will transmit this value to its left and right + bfather->right->operator_ir(box,subbox,val,op,eps); + } + delete this; + } + else + if(op) + status = inte_in(status,val); + else + status = uni_in(status,val); + } + else + return; + +}*/ + +void SetLeaf::operator_ir(const IntervalVector& box,const IntervalVector& subbox, NodeType valin,NodeType valout, bool op,double eps) { + if(box.is_subset(subbox)) + { + if(op && valin!=IN) + status = inte(status,valin); + else if(!op && valin!=OUT) + status = uni(status,valin); + } + else if(box.max_diam()>eps) + { + SetBisect * bfather = (SetBisect*) father; + int var = box.extr_diam_index(false); // indice of the maximal diameter + double pt = box[var].mid(); + SetLeaf * lnode = new SetLeaf(status,NULL); // create future right node + SetLeaf * rnode = new SetLeaf(status,NULL); // create future left node + if(bfather->left == this) // this is father->left + { + bfather->left = new SetBisect(var,pt,lnode,rnode,father); // create SetBisect to replace leaf + lnode->father = bfather->left; // set fathers + rnode->father = bfather->left; + bfather->left->operator_ir(box,subbox,valin,valout,op,eps); + } + else // this is father->right + { + bfather->right = new SetBisect(var,pt,lnode,rnode,father); + lnode->father = bfather->right; + rnode->father = bfather->right; + bfather->right->operator_ir(box,subbox,valin,valout,op,eps); + } + delete this; // delete former father->left or father->right + } + else // if leaf reach minimum precision, compute partial intersection or union + { + if(op) + status = inte_in(status,UNK); + else + status = uni_in(status,UNK); + } +} + +SetNode * SetLeaf::fakeLeaf(const IntervalVector& box,const IntervalVector& subbox,NodeType val,bool op, double eps) { + assert(!this->is_leaf()); + return NULL; +} + +void SetLeaf::cleave(const IntervalVector& box, Sep& sep,double eps) { + + IntervalVector box1(box); + IntervalVector box2(box); + sep.separate(box1,box2); + if(box1.is_disjoint(box2)) // if box are disjoint, contract on box1 and box2 + { + if(!box1.is_empty()) + this->operator_ir(box,box1,IN,true,eps); + if(!box2.is_empty()) + this->operator_ir(box,box2,OUT,true,eps); + + } + else if(box.max_diam()>eps) + { + SetBisect * bfather = (SetBisect*) father; + int var = box.extr_diam_index(false); // indice of the maximal diameter + double pt = box[var].mid(); + SetLeaf * lnode = new SetLeaf(status,NULL); // create future right node + SetLeaf * rnode = new SetLeaf(status,NULL); // create future left node + if(bfather->left == this) // this is father->left + { + bfather->left = new SetBisect(var,pt,lnode,rnode,father); // create SetBisect to replace leaf + lnode->father = bfather->left; // set fathers + rnode->father = bfather->left; + bfather->left->cleave(box,sep,eps); + } + else // this is father->right + { + bfather->right = new SetBisect(var,pt,lnode,rnode,father); + lnode->father = bfather->right; + rnode->father = bfather->right; + bfather->right->cleave(box,sep,eps); + } + delete this; // delete former father->left or father->right + } + else + status = inte(status,UNK); + +} + +void SetLeaf::gather(bool go_up) { + return; // nothing to do +} + +void SetLeaf::cutDeadBranch() { + return; // nothing to do +} +void SetLeaf::checkFat() { + if (father == NULL) + cout<<"issue, invalid father"< Date: Mon, 16 Feb 2015 11:40:22 +0100 Subject: [PATCH 08/32] Create ibex_SetLeaf.h SetLeaf.h associated to regular i-set. --- ibex_SetLeaf.h | 90 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 ibex_SetLeaf.h diff --git a/ibex_SetLeaf.h b/ibex_SetLeaf.h new file mode 100644 index 000000000..b5007dc62 --- /dev/null +++ b/ibex_SetLeaf.h @@ -0,0 +1,90 @@ +//============================================================================ +// I B E X +// File : ibex_SetLeaf.h +// Author : Gilles Chabert +// Copyright : Ecole des Mines de Nantes (France) +// License : See the LICENSE file +// Created : 13 juil. 2014 +//============================================================================ + +#ifndef __IBEX_SET_LEAF_H__ +#define __IBEX_SET_LEAF_H__ + +#include "ibex_SetNode.h" + +namespace ibex { + +/** + * \ingroup iset + * \brief Leaf node (i-set representation) + */ +class SetLeaf : public SetNode { + +public: + /** + * \brief Creates a leaf of the given status + */ + SetLeaf(NodeType status); + + SetLeaf(NodeType status,SetNode* father); + + /** + * \brief Delete this. + */ + virtual ~SetLeaf(); + + /** \see SetNode */ + /** \see SetNode */ + virtual bool is_leaf() const; + + /** \see SetNode */ + virtual SetNode * copy() const; + + /** \see SetNode */ + virtual void inter(NodeType x_status); + + /** \see SetNode */ + virtual void _union(NodeType x); + + /** \see SetNode */ + virtual void oper(SetNode * other,bool op); + + /** \see SetNode */ + virtual void operator_ir(const IntervalVector& box,const IntervalVector& nodebox, NodeType val,bool op, double eps); + + /** \see SetNode */ + virtual void operator_ir(const IntervalVector& box,const IntervalVector& subbox, NodeType valin,NodeType valout, bool op,double eps); + + /** \see SetNode */ + virtual SetNode * fakeLeaf(const IntervalVector& box,const IntervalVector& subbox,NodeType val,bool op, double eps); + + /** \see SetNode */ + virtual void cleave(const IntervalVector& box, Sep& sep, double eps); + + /** \see SetNode */ + virtual void gather(bool go_up); + + /** \see SetNode */ + virtual void cutDeadBranch(); + + /** \see SetNode */ + virtual void checkFat(); + + /** \see SetNode */ + virtual void visit_leaves(leaf_func func, const IntervalVector& nodebox) const; + + /** \see SetNode */ + virtual void print(std::ostream& os, const IntervalVector& nodebox, int shift) const; + + /** \see SetNode */ + virtual void setFathers(); + + +private: + SetLeaf(const SetLeaf&); // forbidden + +}; + +} // namespace ibex + +#endif // __IBEX_SET_LEAF_H__ From 3ca7dfe20d8edb9c4d3db52d50d3039b37e363c3 Mon Sep 17 00:00:00 2001 From: domensta Date: Mon, 16 Feb 2015 11:41:53 +0100 Subject: [PATCH 09/32] Create ibex_SetInterval.cpp SetInterval.cpp associated to regular i-set. --- ibex_SetInterval.cpp | 348 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 348 insertions(+) create mode 100644 ibex_SetInterval.cpp diff --git a/ibex_SetInterval.cpp b/ibex_SetInterval.cpp new file mode 100644 index 000000000..691bc13b2 --- /dev/null +++ b/ibex_SetInterval.cpp @@ -0,0 +1,348 @@ +//============================================================================ +// I B E X +// File : ibex_Set.cpp +// Author : Gilles Chabert +// Copyright : Ecole des Mines de Nantes (France) +// License : See the LICENSE file +// Created : 13 juil. 2014 +//============================================================================ + +#include "ibex_SetInterval.h" +#include "ibex_SetLeaf.h" +#include "ibex_SetBisect.h" +#include "ibex_CellHeap.h" +#include "ibex_CellStack.h" +#include +#include + +using namespace std; + +namespace ibex { + +SetInterval::SetInterval(const IntervalVector& bounding_box, double eps, bool inner) : root(new SetLeaf(inner? __IBEX_IN__: __IBEX_UNK__)), eps(eps), bounding_box(bounding_box) { + +} + +SetInterval::SetInterval(const char* filename) : root(NULL), eps(-1), bounding_box(1) { + load(filename); +} + +SetInterval::SetInterval(const SetInterval& set) : eps(set.eps), bounding_box(set.bounding_box) +{ + root = set.root->copy(); + root->father = NULL; +} + + +bool SetInterval::is_empty() const { + return root==NULL; +} + +void SetInterval::cutRoot() +{ + NodeType stat = root->status; + delete root; + int var = bounding_box.extr_diam_index(false); + double pt = bounding_box[var].mid(); + SetBisect * broot = new SetBisect(var,pt,new SetLeaf(stat),new SetLeaf(stat)); + broot->left->father = broot; + broot->right->father = broot; + root = broot; + +} +void SetInterval::contract(Sep& sep) { + // case root is leaf create issue for SetLeaf recursive function that need the father + // root is redefined as SetBisect pointing on two leaves with value of the root + if(root->is_leaf()) + this->cutRoot(); + root->cleave(bounding_box, sep,eps); + this->gather(); + root->father = NULL; +} + +SetInterval& SetInterval::operator&=(const SetInterval& set) { + assert(bounding_box== set.bounding_box); // root must be the same as set interval are regular + // case root is leaf create issue for SetLeaf recursive function that need the father + // root is redefined as SetBisect pointing on two leaves with value of the root + if(root->is_leaf()) + this->cutRoot(); + root->oper(set.root,true); + this->gather(); + return *this; +} + +SetInterval& SetInterval::interBox(const IntervalVector& box,NodeType valin,NodeType valout) { + + // case root is leaf create issue for SetLeaf recursive function that need the father + // root is redefined as SetBisect pointing on two leaves with value of the root + if(root->is_leaf()) + this->cutRoot(); + cout<<"status of root: "<status<operator_ir(bounding_box,box,valin,valout,true,eps); + this->gather(); + return *this; +} + +SetInterval& SetInterval::unionBox(const IntervalVector& box,NodeType valin,NodeType valout) { + // case root is leaf create issue for SetLeaf recursive function that need the father + // root is redefined as SetBisect pointing on two leaves with value of the root + if(root->is_leaf()) + this->cutRoot(); + root->operator_ir(bounding_box,box,valin,valout,false,eps); + this->gather(); + return *this; +} + + +SetInterval& SetInterval::operator|=(const SetInterval& set) { + assert(bounding_box== set.bounding_box); // root must be the same as set interval are regular + // case root is leaf create issue for SetLeaf recursive function that need the father + // root is redefined as SetBisect pointing on two leaves with value of the root + if(root->is_leaf()) + this->cutRoot(); + root->oper(set.root,false); + this->gather(); + return *this; +} + +void SetInterval::gather() { + root->gather(false); + root->cutDeadBranch(); +} + +void SetInterval::checkFat() { + root->checkFat(); +} + +void SetInterval::save(const char* filename) { + std::stack s; + + s.push(root); + + fstream os; + os.open(filename, ios::out | ios::trunc | ios::binary); + + os.write((char*) &eps, sizeof(double)); + + int n=bounding_box.size(); + os.write((char*) &n, sizeof(int)); + + for (int i=0; iis_leaf()) { + int no_var=-1; // to store "-1" (means: leaf) + os.write((char*) &no_var, sizeof(int)); + os.write((char*) &node->status, sizeof(NodeType)); + } + else { + SetBisect* b=(SetBisect*) node; + os.write((char*) &b->var, sizeof(int)); + os.write((char*) &b->pt, sizeof(double)); + s.push(b->right); + s.push(b->left); + } + } + os.close(); +} + +void SetInterval::load(const char* filename) { + + std::ifstream is; + is.open(filename, ios::in | ios::binary); + + is.read((char*) &eps, sizeof(double)); + //cout << "eps=" << eps << endl; + + unsigned int n; + is.read((char*) &n, sizeof(int)); + //cout << "n=" << n << endl; + + bounding_box.resize(n); + + for (int i=0; i().dist; + } +}; +} + +double SetInterval::dist(const Vector& pt, bool inside) const { + CellHeapDist heap; + + //int count=0; // for stats + + Cell* root_cell =new Cell(bounding_box); + root_cell->add(); + root_cell->get().node = root; + root_cell->get().set_dist(bounding_box,pt); + //count++; + + heap.push(root_cell); + + double lb = POS_INFINITY; + + while (!heap.empty()) { + + Cell* c = heap.pop(); + + SetNode* node = c->get().node; + + assert(node!=NULL); + + if (node->status==(inside? __IBEX_IN__ : __IBEX_OUT__)) { + double d=c->get().dist; + if (dis_leaf() && ( (inside && possibly_contains_in(node->status)) + || (!inside && possibly_contains_out(node->status)))) { + SetBisect& b= *((SetBisect*) node); + + IntervalVector left=b.left_box(c->box); + IntervalVector right=b.right_box(c->box); + + std::pair p=c->bisect(left,right); + + p.first->get().set_dist(left,pt); + //count++; + if (p.first->get().dist<=lb) heap.push(p.first); + + p.second->get().set_dist(right,pt); + //count++; + if (p.second->get().dist<=lb) heap.push(p.second); + } + delete c; + } + //cout << " number of times a distance to a box has been computed: " << count << endl; + return ::sqrt(lb); +} + +SetInterval::~SetInterval() { + delete root; +} + +} // namespace ibex From 96dfb653aaf666779858768ec196294c51e4d190 Mon Sep 17 00:00:00 2001 From: domensta Date: Mon, 16 Feb 2015 11:43:13 +0100 Subject: [PATCH 10/32] Create ibex_SetInterval.h SetInterval.h associated to regular i-set. --- ibex_SetInterval.h | 162 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 162 insertions(+) create mode 100644 ibex_SetInterval.h diff --git a/ibex_SetInterval.h b/ibex_SetInterval.h new file mode 100644 index 000000000..ad3982e6c --- /dev/null +++ b/ibex_SetInterval.h @@ -0,0 +1,162 @@ +//============================================================================ +// I B E X +// File : ibex_Set.h +// Author : Gilles Chabert +// Copyright : Ecole des Mines de Nantes (France) +// License : See the LICENSE file +// Created : 13 juil. 2014 +//============================================================================ + +#ifndef __IBEX_SET_H__ +#define __IBEX_SET_H__ + +#include "ibex_SetNode.h" +#include "ibex_Sep.h" + +namespace ibex { + +/** + * \defgroup iset Set Interval + */ + +/** + * \ingroup iset + * \brief Set Interval + * + * See "Solving set-valued constraint satisfaction problem", Luc Jaulin, Computing. Volume 94, Issue 2, Page 297-311. + * + */ +class SetInterval { +public: + + /** + * \brief Creates a set interval from a simple box + * + * If x is the bounding box in argument, the set interval is either + * [empty, x] if inner==false or [x,x] if inner==false. + */ + SetInterval(const IntervalVector& bounding_box, double eps, bool inner=true); + + /** + * \brief Creates a copy of an existing setInterval + * + */ + SetInterval(const SetInterval& set); + + + /** + * \brief Loads a set from a data file. + * + * \see #save(). + */ + SetInterval(const char* filename); + + /* + * \brief Delete this + */ + ~SetInterval(); + + + /* + * \brief Replace the current root by a setbisect pointing on 2 leaves with the root status + */ + void cutRoot(); + + /** + * \brief i-Set Intersection + * + * In Jaulin's terminology, this operator is the "i-set extension of the intersection". + * + * If [x] designates this i-set and [y] the i-set in argument, then this will be replace by + * { x \cap y, x\in[x] and y\in[y] }. + */ + SetInterval& operator&=(const SetInterval& set); + + /** + * \brief i-Set Intersection + * + * Intersection of a setInterval with a box of interior value valin and exterior value valout. + * Computation is more efficient than create a setInterval contracted on the box, and then + * compute intersection of the two setInterval. + */ + SetInterval& interBox(const IntervalVector& box,NodeType valin,NodeType valout); + + /** + * \brief i-Set Intersection + * + * Union of a setInterval with a box of interior value valin and exterior value valout. + * Computation is more efficient than create a setInterval contracted on the box, and then + * compute intersection of the two setInterval. + */ + SetInterval& unionBox(const IntervalVector& box,NodeType valin,NodeType valout); + + /** + * \brief i-Set Union + * + * In Jaulin's terminology, this operator is the "i-set extension of the union". + * + * If [x] designates this i-set and [y] the i-set in argument, then this will be replace by + * { x \cup y, x\in[x] and y\in[y] }. + */ + SetInterval& operator|=(const SetInterval& set); + + /** + * \brief gather leaves that have the same value + */ + void gather(); + + /** + * \brief Check if fathers are initialized + */ + void checkFat(); + + /** + * \brief True if this i-set is empty + * + * \warning: an empty i-set is different from a i-set containing (and possibly only containing) the empty set. + */ + bool is_empty() const; + + /** + * \brief Contrat i-set w.r.t a separator sep + */ + void contract(Sep& sep); + + /** + * \brief Serialize the set and save it into a file + */ + void save(const char* filename); + + void visit_leaves(SetNode::leaf_func func) const; + + /** + * \brief Distance of the point "pt" wrt the set (if inside is true) + * of the complementary of the set (if inside is false). + */ + double dist(const Vector& pt, bool inside) const; + + + + + +protected: + + /** + * \brief Load the set from a file + */ + void load(const char* filename); + + friend std::ostream& operator<<(std::ostream& os, const SetInterval& set); + + SetNode* root; // NULL means no existing set (warning: different from empty set!) + + double eps; + + IntervalVector bounding_box; // not sure it is really necessary +}; + +std::ostream& operator<<(std::ostream& os, const SetInterval& set); + +} // namespace ibex + +#endif // __IBEX_SET_H__ From e50d56a3feb287e4a6922d194bde241606ee92dd Mon Sep 17 00:00:00 2001 From: domensta Date: Thu, 26 Feb 2015 11:13:56 +0100 Subject: [PATCH 11/32] Update ibex_NodeType.cpp --- src/set/ibex_NodeType.cpp | 215 +++++++++++++++++++++++++++++++++++++- 1 file changed, 214 insertions(+), 1 deletion(-) diff --git a/src/set/ibex_NodeType.cpp b/src/set/ibex_NodeType.cpp index d379266a0..24918e1b0 100644 --- a/src/set/ibex_NodeType.cpp +++ b/src/set/ibex_NodeType.cpp @@ -20,7 +20,7 @@ // ======================================== namespace ibex { - +// relic from irregular set, need for SetBisect constructor NodeType operator|(NodeType x, NodeType y) { switch (x) { case IN : { @@ -78,6 +78,219 @@ NodeType operator|(NodeType x, NodeType y) { } } + + +// define operator or between two nodetype, assuming the two boxes associated are equal +NodeType uni(NodeType x,NodeType y) { + switch (x) { + case IN : { + return IN; + + } + break; + case OUT : { + return y; + } + break; + case UNK : { + switch(y) { + case IN : return IN; + case UNK_IN: return UNK_IN; + case OUT : return UNK; + case UNK : return UNK; + case UNK_OUT: return UNK_OUT; + default: return UNK_IN_OUT; + } + } + break; + case UNK_IN : { + switch(y) { + case IN : + case UNK_IN: + case UNK : return UNK_IN; + default: return UNK_IN_OUT; + } + } + break; + case UNK_OUT : { + switch(y) { + case OUT : + case UNK_OUT: + case UNK : return UNK_OUT; + default: return UNK_IN_OUT; + } + } + break; + default : + //Warning: IN_TMP not considered here. + return UNK_IN_OUT; + } + +} + +// define operator or between two nodetype, assuming box of nodetype y is subset of box of nodetype x; +NodeType uni_in(NodeType x, NodeType y) { + switch (x) { + case IN : { + switch(y) { + case IN : return IN; + case OUT : return IN; + case UNK : return IN; + case UNK_OUT: + case UNK_IN_OUT: return UNK_IN_OUT; + default : return UNK_IN; + } + } + break; + case OUT : { + switch(y) { + case OUT : return OUT; + case IN : return UNK; + case UNK : return UNK; + case UNK_IN: + case UNK_IN_OUT: return UNK_IN_OUT; + default : return UNK_OUT; + } + } + break; + case UNK : { + switch(y) { + return UNK; + } + } + break; + /*case UNK_IN : { + switch(y) { + case IN : + case UNK_IN: + case UNK : return UNK_IN; + default: return UNK_IN_OUT; + } + } + break; + case UNK_OUT : { + switch(y) { + case OUT : + case UNK_OUT: + case UNK : return UNK_OUT; + default: return UNK_IN_OUT; + } + } + break;*/ + default : + //Warning: IN_TMP not considered here. + return UNK_IN_OUT; + + } +} + +// define operator and between two nodetype, assuming the two boxes associated are equal +NodeType inte(NodeType x, NodeType y) { + switch (x) { + case IN : { + return y; + } + break; + case OUT : { + return OUT; + } + break; + case UNK : { + switch(y) { + case IN : return UNK; + case UNK_IN: return UNK_IN; + case OUT : return OUT; + case UNK : return UNK; + case UNK_OUT: return UNK_OUT; + default: return UNK_IN_OUT; + } + } + break; + case UNK_IN : { + switch(y) { + case IN : + case UNK_IN: + case UNK : return UNK_IN; + default: return UNK_IN_OUT; + } + } + break; + case UNK_OUT : { + switch(y) { + case OUT : + case UNK_OUT: + case UNK : return UNK_OUT; + default: return UNK_IN_OUT; + } + } + break; + default : + //Warning: IN_TMP not considered here. + return UNK_IN_OUT; + } +} + + +// define operator and between two nodetype, assuming box of nodetype y is subset of box of nodetype x; +NodeType inte_in(NodeType x, NodeType y) { + switch (x) { + case IN : { + switch(y) { + case IN : return IN; + case OUT : return UNK; + case UNK : return UNK; + case UNK_OUT: + case UNK_IN_OUT: return UNK_IN_OUT; + default : return UNK_IN; + } + } + break; + case OUT : { + switch(y) { + case OUT : return OUT; + case IN : return OUT; + case UNK : return OUT; + case UNK_IN: + case UNK_IN_OUT: return UNK_IN_OUT; + default : return UNK_OUT; + } + } + break; + case UNK : { + switch(y) { + case IN : return UNK; + case UNK_IN: return UNK_IN; + case OUT : return UNK; + case UNK_OUT: return UNK_OUT; + case UNK: return UNK; + default: return UNK_IN_OUT; + } + } + break; + case UNK_IN : { + switch(y) { + case IN : + case UNK_IN: + case UNK : return UNK_IN; + default: return UNK_IN_OUT; + } + } + break; + case UNK_OUT : { + switch(y) { + case OUT : + case UNK_OUT: + case UNK : return UNK_OUT; + default: return UNK_IN_OUT; + } + } + break; + default : + //Warning: IN_TMP not considered here. + return UNK_IN_OUT; + } +} + bool certainly_contains_in(NodeType x) { return x==IN || x==UNK_IN || x==UNK_IN_OUT; } From fd74ea6bf977b051fcca1e7853e3f59df2bad85c Mon Sep 17 00:00:00 2001 From: domensta Date: Thu, 26 Feb 2015 11:14:42 +0100 Subject: [PATCH 12/32] Update ibex_NodeType.h --- src/set/ibex_NodeType.h | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/src/set/ibex_NodeType.h b/src/set/ibex_NodeType.h index 8d060ede1..7456e64f4 100644 --- a/src/set/ibex_NodeType.h +++ b/src/set/ibex_NodeType.h @@ -44,9 +44,24 @@ typedef enum { __IBEX_IN__, * \see SetBisect constructor. */ NodeType operator|(NodeType x, NodeType y); - /** - * \brief False only if the subtree contains no inner point + * \brief return value of union of two equal boxes + */ +NodeType uni(NodeType x,NodeType y); +/** + * \brief return value of union of two boxes, assuming the on associated to y is include in the one associated to x + */ +NodeType uni_in(NodeType x, NodeType y); +/** + * \brief return value of inter of two equal boxes + */ +NodeType inte(NodeType x, NodeType y); +/** + * \brief return value of inter of two boxes, assuming the on associated to y is include in the one associated to x + */ +NodeType inte_in(NodeType x, NodeType y); +/** + * \brief return value of inter of two boxes, assuming the on associated to y is include in the one associated to x */ bool possibly_contains_in(NodeType x); From fea8543af5300a3add75552cbd2d051f3c1fb097 Mon Sep 17 00:00:00 2001 From: domensta Date: Thu, 26 Feb 2015 11:15:21 +0100 Subject: [PATCH 13/32] Update ibex_SetBisect.cpp --- src/set/ibex_SetBisect.cpp | 289 ++++++++++++++++++++++++++----------- 1 file changed, 208 insertions(+), 81 deletions(-) diff --git a/src/set/ibex_SetBisect.cpp b/src/set/ibex_SetBisect.cpp index ead14b71d..01e95bcee 100644 --- a/src/set/ibex_SetBisect.cpp +++ b/src/set/ibex_SetBisect.cpp @@ -26,14 +26,15 @@ using namespace std; namespace ibex { -SetBisect::SetBisect(int var, double pt, SetNode* left, SetNode* right) : SetNode(left->status | right->status), var(var), pt(pt), left(left), right(right) { - // a bisectNode with two subnodes of same status IN or OUT should not exist - // (automatically compacted as a leaf node) but two subnodes IN_TMP can be - // created by a leaf with IN_TMP status (when it auto-splits in inter function) - assert(left->status>=UNK || left->status!=right->status); +SetBisect::SetBisect(int var, double pt, SetNode* left, SetNode* right) : SetNode(UNK_IN_OUT,NULL), var(var), pt(pt), left(left), right(right) { + } -SetBisect::SetBisect(int var, double pt) : SetNode(UNK), var(var), pt(pt), left(NULL), right(NULL) { +SetBisect::SetBisect(int var, double pt, SetNode* left, SetNode* right,SetNode* father) : SetNode(UNK_IN_OUT,father), var(var), pt(pt), left(left), right(right) { + +} + +SetBisect::SetBisect(int var, double pt) : SetNode(UNK_IN_OUT), var(var), pt(pt), left(NULL), right(NULL) { } @@ -43,87 +44,224 @@ SetBisect::~SetBisect() { } bool SetBisect::is_leaf() const { - return false; + return false; } -SetNode* SetBisect::sync(const IntervalVector& nodebox, const IntervalVector& x, NodeType x_status, double eps) { - assert(x_status<=UNK); +SetNode * SetBisect::copy() const { + SetBisect * n = new SetBisect(this->var,this->pt,this->left->copy(),this->right->copy()); + n->left->father = n; + n->right->father = n; + return n; +} - if (x_status==UNK) { - return this; - } - else if (nodebox.is_subset(x)) { - if (x_status==IN && !possibly_contains_in(status)) throw NoSet(); - if (x_status==OUT && !possibly_contains_out(status)) throw NoSet(); - - delete this; // warning: suicide - return new SetLeaf(x_status); - } else { - left = left->sync(left_box(nodebox), x, x_status, eps); - right = right->sync(right_box(nodebox), x, x_status, eps); - // status of children may have changed --> try merge - return try_merge(); - } + +void SetBisect::inter(NodeType x) { + + left->inter(x); // apply inter to left and right until reach the leaves + right->inter(x); } -SetNode* SetBisect::sync_rec(const IntervalVector& nodebox, Sep& sep, double eps) { - left = left->sync(left_box(nodebox), sep, eps); - right = right->sync(right_box(nodebox), sep, eps); - // status of children may have changed --> try merge - return try_merge(); +void SetBisect::_union(NodeType x) { + left->_union(x); + right->_union(x); } +void SetBisect::oper(SetNode * node,bool op) { + if(node->is_leaf()) // apply status to leaves of the subtree which have this as root + { + if(op && node->status != IN) + { + left->inter(node->status); + right->inter(node->status); + } + else if(!op && node->status!= OUT) + { + left->_union(node->status); + right->_union(node->status); + } + } + else + { + SetBisect * other = (SetBisect*) node; // node is assume to be either a leaf or a bisect, able to cast node in bisect as it ain't a leaf + left->oper(other->left,op); + right->oper(other->right,op); + } +} -SetNode* SetBisect::inter(const IntervalVector& nodebox, const IntervalVector& x, NodeType x_status, double eps) { - assert(x_status<=UNK); +void SetBisect::operator_ir(const IntervalVector& box,const IntervalVector& subbox, NodeType val,bool op, double eps) +{ - // no: keep subnodes informed that x_status is IN (their status can changed from IN_TMP to IN) - // if (x_status==IN) { - // return this; - // } + if(box.is_subset(subbox)) // compute intersection of leaves of this root with val + { + if(op && val != IN) + this->inter(val); + else if(!op && val != OUT) + this->_union(val); + } + else + { + if(this->left_box(box).overlaps(subbox)) // need to apply function on left only if leftbox ovelaps subbox + left->operator_ir(this->left_box(box),subbox,val,op,eps); + if(this->right_box(box).overlaps(subbox)) // need to apply function on right only if rightbox overlaps subbox + right->operator_ir(this->right_box(box),subbox,val,op,eps); + } +} - // in comment because certainly_contains_in does not take into account IN_TMP -// if (x_status==UNK && !certainly_contains_in(status)) { -// return this; -// } +void SetBisect::operator_ir(const IntervalVector& box,const IntervalVector& subbox, NodeType valin,NodeType valout,bool op, double eps) +{ - // certainly_contains_out in comment because does not take into account IN_TMP - if ((x_status==OUT /*|| !certainly_contains_out(status)*/) && nodebox.is_subset(x)) { - delete this; // warning: suicide - return new SetLeaf(x_status); // either OUT or UNK - } else { - left = left->inter(left_box(nodebox), x, x_status, eps); - right = right->inter(right_box(nodebox), x, x_status, eps); - // status of children may have changed --> try merge - return try_merge(); + if(box.is_subset(subbox)) // apply valin on the leaves of this root + { + if(op && valin != IN) + this->inter(valin); + else if(!op && valin != OUT) + this->_union(valin); + } + else if(box.overlaps(subbox)) + { + if(this->left_box(box).overlaps(subbox)) + left->operator_ir(this->left_box(box),subbox,valin,valout,op,eps); + else { // leftbox is disjoint of subbox, apply valout on the leaves of this->left root + if(op && valout != IN) + left->inter(valout); + else if (!op && valout != OUT) + left->_union(valout);} + if(this->right_box(box).overlaps(subbox)) + right->operator_ir(this->right_box(box),subbox,valin,valout,op,eps); + else{ // rightbox is disjoint of subbox, apply valout on the leaves of this->right root + if(op && valout != IN) + right->inter(valout); + else if (!op && valout != OUT) + right->_union(valout);} } + else{ // this is disjoint of subbox, apply valout on the leaves of this root + if(op && valout != IN) + this->inter(valout); + else if (!op && valout != OUT) + this->_union(valout);} } -SetNode* SetBisect::inter_rec(const IntervalVector& nodebox, Sep& sep, double eps) { - left = left->inter(left_box(nodebox), sep, eps); - right = right->inter(right_box(nodebox), sep, eps); - // status of children may have changed --> try merge - return try_merge(); +// Uncomment this function and comment the one above to use fakeBranch method +/*void SetBisect::operator_ir(const IntervalVector& box,const IntervalVector& subbox, NodeType val,bool op, double eps) +{ + + if(left == NULL) + { + assert(right == NULL); + left = this->fakeLeaf(left_box(box),subbox,val,op,eps); + left->father = this; + right = this->fakeLeaf(right_box(box),subbox,val,op,eps); + right->father = this; + status = UNK_IN_OUT; + } + else + { + if(box.is_subset(subbox)) + { + if(op) + this->inter(val); + else + this->_union(val); + } + else + { + if(this->left_box(box).overlaps(subbox)) + left->operator_ir(this->left_box(box),subbox,val,op,eps); + else + return; + if(this->right_box(box).overlaps(subbox)) + right->operator_ir(this->right_box(box),subbox,val,op,eps); + else + return; + } + } +}*/ + +SetNode * SetBisect::fakeLeaf(const IntervalVector& box,const IntervalVector& subbox,NodeType val,bool op, double eps) { + //assert(left == NULL && right == NULL); + if(box.is_subset(subbox)) + if(op) + return new SetLeaf(inte(status,val)); + else + return new SetLeaf(uni(status,val)); + else if(box.overlaps(subbox)) + { + if(box.max_diam()<=eps) + return new SetLeaf(inte_in(status,val)); + else + { + int var = box.extr_diam_index(false); + double pt = box[var].mid(); + SetBisect * node = new SetBisect(var,pt,NULL,NULL); + node->status = status; + node->left = node->fakeLeaf(node->left_box(box),subbox,val,op,eps); + node->right = node->fakeLeaf(node->right_box(box),subbox,val,op,eps); + node->left->father = node; + node->right->father = node; + node->status = UNK_IN_OUT; + return node; + } + } + else + return new SetLeaf(status); } +void SetBisect::cleave(const IntervalVector& box, Sep& sep, double eps) { -SetNode* SetBisect::union_(const IntervalVector& nodebox, const IntervalVector& x, NodeType x_status, double eps) { - assert(x_status<=UNK); + IntervalVector box1(box); + IntervalVector box2(box); - if (x_status>IN) { - return this; + sep.separate(box1,box2); + if(box1.is_disjoint(box2)) // in and out are disjoint, can contract on box1 and box2 + { + if(!box1.is_empty()) + this->operator_ir(box,box1,IN,true,eps); + if(!box2.is_empty()) + this->operator_ir(box,box2,OUT,true,eps); + } + else // continu until box1 and box2 are disjoint + { + left->cleave(left_box(box),sep,eps); + right->cleave(right_box(box),sep,eps); } +} +void SetBisect::gather(bool go_up) { + if(((left->is_leaf()&&right->is_leaf()) || go_up)&&left->status==right->status) // leaves are reached, or climbing up the tree toward the root + { + status = left->status; // this bisect get a leaf status IN OUT or UNK + if(father != NULL) // check if father is not the root of SetInterval + father->gather(true); + } + else if(!go_up) // go down the tree to reach the leaves + { + left->gather(false); + right->gather(false); + } +} - if (nodebox.is_subset(x)) { - delete this; // warning: suicide - return new SetLeaf(IN); - } else { - left = left->union_(left_box(nodebox), x, x_status, eps); - right = right->union_(right_box(nodebox), x, x_status, eps); - // status of children may have changed --> try merge - return try_merge(); +void SetBisect::cutDeadBranch() { + if(left->status ==right->status && left->status < 3) // if status of left and right are equal and has got a leaf status, meaning all leaves have the same status + { + SetBisect* bfather = (SetBisect*) father; + if(bfather->left == this) + bfather->left = new SetLeaf(status,father); // this is now a leaf + else + bfather->right = new SetLeaf(status,father); // this is now a leaf + delete this; // delete former this which was a bisect + } + else // go down the tree until reach leaves or bisect that can be set a leaf + { + left->cutDeadBranch(); + right->cutDeadBranch(); } } + +void SetBisect::checkFat() { + if(father == NULL) + cout<<"issue, invalid father"<checkFat(); + right->checkFat(); +} void SetBisect::visit_leaves(leaf_func func, const IntervalVector& nodebox) const { left->visit_leaves(func, left_box(nodebox)); right->visit_leaves(func, right_box(nodebox)); @@ -136,15 +274,13 @@ void SetBisect::print(ostream& os, const IntervalVector& nodebox, int shift) con right->print(os, right_box(nodebox), shift+2); } -void SetBisect::set_in_tmp() { - left->set_in_tmp(); - right->set_in_tmp(); +void SetBisect::setFathers() { + left->father = this; + right->father = this; + left->setFathers(); + right->setFathers(); } -void SetBisect::unset_in_tmp() { - left->unset_in_tmp(); - right->unset_in_tmp(); -} IntervalVector SetBisect::left_box(const IntervalVector& nodebox) const { IntervalVector leftbox(nodebox); @@ -160,14 +296,5 @@ IntervalVector SetBisect::right_box(const IntervalVector& nodebox) const { return rightbox; } -SetNode* SetBisect::try_merge() { - // the case left=right=UNK may happen. - if (left->status<=UNK && left->status==right->status) { - NodeType s=left->status; - delete this; - return new SetLeaf(s); - } else - return this; -} } // namespace ibex From 50a4181ed454c827d5d951748636c70a3908c498 Mon Sep 17 00:00:00 2001 From: domensta Date: Thu, 26 Feb 2015 11:15:56 +0100 Subject: [PATCH 14/32] Update ibex_SetBisect.h --- src/set/ibex_SetBisect.h | 44 ++++++++++++++++++++++++++++++++-------- 1 file changed, 35 insertions(+), 9 deletions(-) diff --git a/src/set/ibex_SetBisect.h b/src/set/ibex_SetBisect.h index e9b9eadd3..fb0073e38 100644 --- a/src/set/ibex_SetBisect.h +++ b/src/set/ibex_SetBisect.h @@ -30,6 +30,8 @@ class SetBisect : public SetNode { */ SetBisect(int var, double pt, SetNode* left, SetNode* right); + SetBisect(int var, double pt, SetNode* left, SetNode* right,SetNode* father); + /** * \brief Delete this */ @@ -39,19 +41,37 @@ class SetBisect : public SetNode { virtual bool is_leaf() const; /** \see SetNode */ - virtual SetNode* sync(const IntervalVector& nodebox, const IntervalVector& x, NodeType x_status, double eps); + virtual SetNode * copy() const; + + /** \see SetNode */ + virtual void inter(NodeType x_status); + + /** \see SetNode */ + virtual void _union(NodeType x); + + /** \see SetNode */ + virtual void oper(SetNode * other,bool op); + + /** \see SetNode */ + virtual void operator_ir(const IntervalVector& box,const IntervalVector& nodebox, NodeType val,bool op, double eps); + + /** \see SetNode */ + virtual void operator_ir(const IntervalVector& box,const IntervalVector& subbox, NodeType valin,NodeType valout, bool op,double eps); /** \see SetNode */ - virtual SetNode* inter(const IntervalVector& nodebox, const IntervalVector& x, NodeType x_status, double eps); + virtual SetNode * fakeLeaf(const IntervalVector& box,const IntervalVector& subbox,NodeType val,bool op, double eps); /** \see SetNode */ - virtual SetNode* sync_rec(const IntervalVector& nodebox, Sep& sep, double eps); + virtual void cleave(const IntervalVector& box, Sep& sep, double eps); /** \see SetNode */ - virtual SetNode* inter_rec(const IntervalVector& nodebox, Sep& sep, double eps); + virtual void gather(bool go_up); /** \see SetNode */ - virtual SetNode* union_(const IntervalVector& nodebox, const IntervalVector& x, NodeType x_status, double eps); + virtual void cutDeadBranch(); + + /** \see SetNode */ + virtual void checkFat(); /** \see SetNode */ virtual void visit_leaves(leaf_func func, const IntervalVector& nodebox) const; @@ -60,13 +80,20 @@ class SetBisect : public SetNode { virtual void print(std::ostream& os, const IntervalVector& nodebox, int shift) const; /** \see SetNode */ - virtual void set_in_tmp(); + virtual void setFathers(); + + - /** \see SetNode */ - virtual void unset_in_tmp(); + + /** + * \brief Rerturn left_box according to var, pt and nodebox + */ IntervalVector left_box(const IntervalVector& nodebox) const; + /** + * \brief Rerturn left_box according to var, pt and nodebox + */ IntervalVector right_box(const IntervalVector& nodebox) const; //protected: @@ -76,7 +103,6 @@ class SetBisect : public SetNode { // partial initialization used by SetInterval::load only SetBisect(int var, double pt); - SetNode* try_merge(); int var; double pt; From 9ab97091327df4682946a0aff41de0ef7fd0e4a1 Mon Sep 17 00:00:00 2001 From: domensta Date: Thu, 26 Feb 2015 11:16:44 +0100 Subject: [PATCH 15/32] Update ibex_SetInterval.cpp --- src/set/ibex_SetInterval.cpp | 88 +++++++++++++++++++++++++++++------- 1 file changed, 72 insertions(+), 16 deletions(-) diff --git a/src/set/ibex_SetInterval.cpp b/src/set/ibex_SetInterval.cpp index 0dc1c1d5f..691bc13b2 100644 --- a/src/set/ibex_SetInterval.cpp +++ b/src/set/ibex_SetInterval.cpp @@ -27,38 +27,93 @@ SetInterval::SetInterval(const char* filename) : root(NULL), eps(-1), bounding_b load(filename); } +SetInterval::SetInterval(const SetInterval& set) : eps(set.eps), bounding_box(set.bounding_box) +{ + root = set.root->copy(); + root->father = NULL; +} + + bool SetInterval::is_empty() const { return root==NULL; } -void SetInterval::sync(Sep& sep) { - try { - root = root->sync(bounding_box, sep, eps); - } catch(NoSet& e) { - delete root; - root = NULL; - throw e; - } -} +void SetInterval::cutRoot() +{ + NodeType stat = root->status; + delete root; + int var = bounding_box.extr_diam_index(false); + double pt = bounding_box[var].mid(); + SetBisect * broot = new SetBisect(var,pt,new SetLeaf(stat),new SetLeaf(stat)); + broot->left->father = broot; + broot->right->father = broot; + root = broot; +} void SetInterval::contract(Sep& sep) { - root->set_in_tmp(); - root = root->inter(bounding_box, sep, eps); - root->unset_in_tmp(); + // case root is leaf create issue for SetLeaf recursive function that need the father + // root is redefined as SetBisect pointing on two leaves with value of the root + if(root->is_leaf()) + this->cutRoot(); + root->cleave(bounding_box, sep,eps); + this->gather(); + root->father = NULL; } SetInterval& SetInterval::operator&=(const SetInterval& set) { - root->set_in_tmp(); - root = root->inter(bounding_box, set.root, set.bounding_box, eps); - root->unset_in_tmp(); + assert(bounding_box== set.bounding_box); // root must be the same as set interval are regular + // case root is leaf create issue for SetLeaf recursive function that need the father + // root is redefined as SetBisect pointing on two leaves with value of the root + if(root->is_leaf()) + this->cutRoot(); + root->oper(set.root,true); + this->gather(); return *this; } +SetInterval& SetInterval::interBox(const IntervalVector& box,NodeType valin,NodeType valout) { + + // case root is leaf create issue for SetLeaf recursive function that need the father + // root is redefined as SetBisect pointing on two leaves with value of the root + if(root->is_leaf()) + this->cutRoot(); + cout<<"status of root: "<status<operator_ir(bounding_box,box,valin,valout,true,eps); + this->gather(); + return *this; +} + +SetInterval& SetInterval::unionBox(const IntervalVector& box,NodeType valin,NodeType valout) { + // case root is leaf create issue for SetLeaf recursive function that need the father + // root is redefined as SetBisect pointing on two leaves with value of the root + if(root->is_leaf()) + this->cutRoot(); + root->operator_ir(bounding_box,box,valin,valout,false,eps); + this->gather(); + return *this; +} + + SetInterval& SetInterval::operator|=(const SetInterval& set) { - root = root->union_(bounding_box, set.root, set.bounding_box, eps); + assert(bounding_box== set.bounding_box); // root must be the same as set interval are regular + // case root is leaf create issue for SetLeaf recursive function that need the father + // root is redefined as SetBisect pointing on two leaves with value of the root + if(root->is_leaf()) + this->cutRoot(); + root->oper(set.root,false); + this->gather(); return *this; } +void SetInterval::gather() { + root->gather(false); + root->cutDeadBranch(); +} + +void SetInterval::checkFat() { + root->checkFat(); +} + void SetInterval::save(const char* filename) { std::stack s; @@ -175,6 +230,7 @@ void SetInterval::load(const char* filename) { } is.close(); + root->setFathers(); } void SetInterval::visit_leaves(SetNode::leaf_func func) const { From f55cdce05e609793e725a82efef53052824e8f85 Mon Sep 17 00:00:00 2001 From: domensta Date: Thu, 26 Feb 2015 11:17:35 +0100 Subject: [PATCH 16/32] Update ibex_SetInterval.h --- src/set/ibex_SetInterval.h | 51 ++++++++++++++++++++++++++++++++------ 1 file changed, 44 insertions(+), 7 deletions(-) diff --git a/src/set/ibex_SetInterval.h b/src/set/ibex_SetInterval.h index 120080c02..ad3982e6c 100644 --- a/src/set/ibex_SetInterval.h +++ b/src/set/ibex_SetInterval.h @@ -37,6 +37,12 @@ class SetInterval { */ SetInterval(const IntervalVector& bounding_box, double eps, bool inner=true); + /** + * \brief Creates a copy of an existing setInterval + * + */ + SetInterval(const SetInterval& set); + /** * \brief Loads a set from a data file. @@ -50,6 +56,12 @@ class SetInterval { */ ~SetInterval(); + + /* + * \brief Replace the current root by a setbisect pointing on 2 leaves with the root status + */ + void cutRoot(); + /** * \brief i-Set Intersection * @@ -60,6 +72,24 @@ class SetInterval { */ SetInterval& operator&=(const SetInterval& set); + /** + * \brief i-Set Intersection + * + * Intersection of a setInterval with a box of interior value valin and exterior value valout. + * Computation is more efficient than create a setInterval contracted on the box, and then + * compute intersection of the two setInterval. + */ + SetInterval& interBox(const IntervalVector& box,NodeType valin,NodeType valout); + + /** + * \brief i-Set Intersection + * + * Union of a setInterval with a box of interior value valin and exterior value valout. + * Computation is more efficient than create a setInterval contracted on the box, and then + * compute intersection of the two setInterval. + */ + SetInterval& unionBox(const IntervalVector& box,NodeType valin,NodeType valout); + /** * \brief i-Set Union * @@ -71,14 +101,14 @@ class SetInterval { SetInterval& operator|=(const SetInterval& set); /** - * \brief i-Set synchronization - * - * In Jaulin's terminology, this operator is the "intersection of i-sets" (squared symbol) - * - * If [x] designates this i-set and [y] the i-set in argument, then this will be replace by - * { x, x\in[x] and x\in[y] }. + * \brief gather leaves that have the same value */ - void sync(Sep& sep); + void gather(); + + /** + * \brief Check if fathers are initialized + */ + void checkFat(); /** * \brief True if this i-set is empty @@ -87,6 +117,9 @@ class SetInterval { */ bool is_empty() const; + /** + * \brief Contrat i-set w.r.t a separator sep + */ void contract(Sep& sep); /** @@ -102,6 +135,10 @@ class SetInterval { */ double dist(const Vector& pt, bool inside) const; + + + + protected: /** From 3af2afebbeacf8f5f9d9fa0d476f3043bb8b15b1 Mon Sep 17 00:00:00 2001 From: domensta Date: Thu, 26 Feb 2015 11:18:25 +0100 Subject: [PATCH 17/32] Update ibex_SetLeaf.cpp --- src/set/ibex_SetLeaf.cpp | 316 ++++++++++++++++++++++++++------------- 1 file changed, 215 insertions(+), 101 deletions(-) diff --git a/src/set/ibex_SetLeaf.cpp b/src/set/ibex_SetLeaf.cpp index f2386ee1a..441da0259 100644 --- a/src/set/ibex_SetLeaf.cpp +++ b/src/set/ibex_SetLeaf.cpp @@ -29,6 +29,11 @@ SetLeaf::SetLeaf(NodeType status) : SetNode(status) { ibex_error("cannot set multiple status to SetLeaf"); } } + +SetLeaf::SetLeaf(NodeType status,SetNode* father): SetNode(status,father) { + +} + SetLeaf::~SetLeaf() { } @@ -37,117 +42,231 @@ bool SetLeaf::is_leaf() const { return true; } -//SetNode* SetLeaf::sync(const IntervalVector& nodebox, const IntervalVector& x, NodeType xstatus, double eps, Mode mode) { -// switch (mode) { -// case SYNC: return sync(nodebox, x, xstatus, eps); -// case INTER: return inter(nodebox, x, xstatus, eps); -// case UNION: not_implemented("SetLeaf::sync with union"); return this; break; -// default : ibex_error("SetLeaf::sync: unknown mode"); return this; -// } -//} - -SetNode* SetLeaf::sync(const IntervalVector& nodebox, const IntervalVector& x, NodeType xstatus, double eps) { - //cout << nodebox << " " << to_string(status) << " sync " << x << " "; - assert(xstatus<=UNK); - - if (xstatus==UNK || status==xstatus) { - //cout << "this\n"; - return this; - } else if (nodebox.is_subset(x)) { - if (status!=UNK) throw NoSet(); - status=xstatus; - //cout << "this\n"; - return this; - } else { - if ((nodebox & x).is_flat()) { - //cout << "this\n"; - return this; + SetNode * SetLeaf::copy() const { + return new SetLeaf(this->status); +} + +void SetLeaf::inter(NodeType x_status) { + status = inte(status,x_status); +} + +void SetLeaf::_union(NodeType x) { + status = uni(status,x); +} + +void SetLeaf::oper(SetNode * node,bool op) { + if(node->is_leaf()) // if node is leaf, apply its value to leaves of this + { + if(op) + status = inte(status,node->status); + else + status = uni(status,node->status); + } + else{ // if this is leaf and node isn't + SetBisect * bfather = (SetBisect*) father; + if(bfather->left == this) + { + bfather->left = node->copy(); // copy the structure of node + bfather->left->father = father; + if(op && status != IN) + bfather->left->inter(status); // apply status to leaves + else if(!op && status!= OUT) + bfather->left->_union(status); } - SetNode* new_node=diff(nodebox, x, status, xstatus, eps); - delete this; // warning: suicide, don't move it before previous line - //cout << "gives "; new_node->print(cout,nodebox,0); - return new_node; + else + { + bfather->right = node->copy(); + bfather->right->father = father; + if(op && status != IN) + bfather->right->inter(status); + else if(!op && status!= OUT) + bfather->right->_union(status); + } + delete this; // delete this as it is now a setBisect and no more a leaf + } } -SetNode* SetLeaf::sync_rec(const IntervalVector& nodebox, Sep& sep, double eps) { - - if (status p=nodebox.bisect(var); - double pt=p.first[var].ub(); - assert(nodebox[var].interior_contains(pt)); - SetBisect* bis = new SetBisect(var, pt, new SetLeaf(UNK), new SetLeaf(UNK)); - delete this; - return bis->sync_rec(nodebox, sep, eps); +void SetLeaf::operator_ir(const IntervalVector& box,const IntervalVector& subbox, NodeType val, bool op,double eps) { + if(box.is_subset(subbox)) + { + if(op && val != IN) + status = inte(status,val); + else if(!op && val!=OUT) + status = uni(status,val); } + else if(box.max_diam()>eps) + { + SetBisect * bfather = (SetBisect*) father; + int var = box.extr_diam_index(false); // indice of the maximal diameter + double pt = box[var].mid(); + SetLeaf * lnode = new SetLeaf(status,NULL); // create future right node + SetLeaf * rnode = new SetLeaf(status,NULL); // create future left node + if(bfather->left == this) // this is father->left + { + bfather->left = new SetBisect(var,pt,lnode,rnode,father); // create SetBisect to replace leaf + lnode->father = bfather->left; // set fathers + rnode->father = bfather->left; + bfather->left->operator_ir(box,subbox,val,op,eps); + } + else // this is father->right + { + bfather->right = new SetBisect(var,pt,lnode,rnode,father); + lnode->father = bfather->right; + rnode->father = bfather->right; + bfather->right->operator_ir(box,subbox,val,op,eps); + } + delete this; // delete former father->left or father->right + } + else // if leaf reach minimum precision, compute partial intersection or union + { + if(op) + status = inte_in(status,val); + else + status = uni_in(status,val); + } } +// Uncomment this function and comment the one above to use fakeBranch method +/*void SetLeaf::operator_ir(const IntervalVector& box,const IntervalVector& subbox, NodeType val, bool op,bool is_left,double eps) { + if(box.is_subset(subbox)) + { + if(op) + status = inte(status,val); + else + status = uni(status,val); + } + else if(box.overlaps(subbox)) + { + if(box.max_diam()>eps) + { + SetBisect * bfather = (SetBisect*) father; + int var = box.extr_diam_index(false); // indice of the maximal diameter + double pt = box[var].mid(); + if(bfather->left == this) + { + bfather->left = new SetBisect(var,pt,NULL,NULL,father); + bfather->left->status = status; // create new set bissect with nodetype IN OUT or UNK, that it will transmit this value to its left and right + bfather->left->operator_ir(box,subbox,val,op,eps); + } + else + { + bfather->right = new SetBisect(var,pt,NULL,NULL,father); + bfather->right->status = status; // create new set bissect with nodetype IN OUT or UNK, that it will transmit this value to its left and right + bfather->right->operator_ir(box,subbox,val,op,eps); + } + delete this; + } + else + if(op) + status = inte_in(status,val); + else + status = uni_in(status,val); + } + else + return; +}*/ -SetNode* SetLeaf::inter(const IntervalVector& nodebox, const IntervalVector& x, NodeType xstatus, double eps) { - //cout << nodebox << " " << to_string(status) << " inter " << x << " "; - assert(xstatus<=UNK); - - if (statusprint(cout,nodebox,0); - return new_node; +void SetLeaf::operator_ir(const IntervalVector& box,const IntervalVector& subbox, NodeType valin,NodeType valout, bool op,double eps) { + if(box.is_subset(subbox)) + { + if(op && valin!=IN) + status = inte(status,valin); + else if(!op && valin!=OUT) + status = uni(status,valin); } + else if(box.max_diam()>eps) + { + SetBisect * bfather = (SetBisect*) father; + int var = box.extr_diam_index(false); // indice of the maximal diameter + double pt = box[var].mid(); + SetLeaf * lnode = new SetLeaf(status,NULL); // create future right node + SetLeaf * rnode = new SetLeaf(status,NULL); // create future left node + if(bfather->left == this) // this is father->left + { + bfather->left = new SetBisect(var,pt,lnode,rnode,father); // create SetBisect to replace leaf + lnode->father = bfather->left; // set fathers + rnode->father = bfather->left; + bfather->left->operator_ir(box,subbox,valin,valout,op,eps); + } + else // this is father->right + { + bfather->right = new SetBisect(var,pt,lnode,rnode,father); + lnode->father = bfather->right; + rnode->father = bfather->right; + bfather->right->operator_ir(box,subbox,valin,valout,op,eps); + } + delete this; // delete former father->left or father->right + } + else // if leaf reach minimum precision, compute partial intersection or union + { + if(op) + status = inte_in(status,UNK); + else + status = uni_in(status,UNK); + } } -SetNode* SetLeaf::inter_rec(const IntervalVector& nodebox, Sep& sep, double eps) { - - if (status p=nodebox.bisect(var); - double pt=p.first[var].ub(); - assert(nodebox[var].interior_contains(pt)); - SetBisect* bis = new SetBisect(var, pt, new SetLeaf(status), new SetLeaf(status)); - delete this; - return bis->inter_rec(nodebox, sep, eps); - } +SetNode * SetLeaf::fakeLeaf(const IntervalVector& box,const IntervalVector& subbox,NodeType val,bool op, double eps) { + assert(!this->is_leaf()); + return NULL; } -SetNode* SetLeaf::union_(const IntervalVector& nodebox, const IntervalVector& x, NodeType xstatus, double eps) { - //cout << nodebox << " " << to_string(status) << " union << x << " "; - assert(xstatus<=UNK); - - if (status==IN || xstatus>IN) { - //cout << "this\n"; - return this; - } else if (nodebox.is_subset(x)) { - status=IN; - //cout << "this\n"; - return this; - } else { - // status=(UNK | OUT), xstatus=(IN). - SetNode* new_node=diff(nodebox, x, status, IN, eps); - delete this; // warning: suicide, don't move it before previous line - //cout << "gives "; new_node->print(cout,nodebox,0); - return new_node; +void SetLeaf::cleave(const IntervalVector& box, Sep& sep,double eps) { + + IntervalVector box1(box); + IntervalVector box2(box); + sep.separate(box1,box2); + if(box1.is_disjoint(box2)) // if box are disjoint, contract on box1 and box2 + { + if(!box1.is_empty()) + this->operator_ir(box,box1,IN,true,eps); + if(!box2.is_empty()) + this->operator_ir(box,box2,OUT,true,eps); + } + else if(box.max_diam()>eps) + { + SetBisect * bfather = (SetBisect*) father; + int var = box.extr_diam_index(false); // indice of the maximal diameter + double pt = box[var].mid(); + SetLeaf * lnode = new SetLeaf(status,NULL); // create future right node + SetLeaf * rnode = new SetLeaf(status,NULL); // create future left node + if(bfather->left == this) // this is father->left + { + bfather->left = new SetBisect(var,pt,lnode,rnode,father); // create SetBisect to replace leaf + lnode->father = bfather->left; // set fathers + rnode->father = bfather->left; + bfather->left->cleave(box,sep,eps); + } + else // this is father->right + { + bfather->right = new SetBisect(var,pt,lnode,rnode,father); + lnode->father = bfather->right; + rnode->father = bfather->right; + bfather->right->cleave(box,sep,eps); + } + delete this; // delete former father->left or father->right + } + else + status = inte(status,UNK); + } +void SetLeaf::gather(bool go_up) { + return; // nothing to do +} + +void SetLeaf::cutDeadBranch() { + return; // nothing to do +} +void SetLeaf::checkFat() { + if (father == NULL) + cout<<"issue, invalid father"< Date: Thu, 26 Feb 2015 11:19:04 +0100 Subject: [PATCH 18/32] Update ibex_SetLeaf.h --- src/set/ibex_SetLeaf.h | 35 ++++++++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/src/set/ibex_SetLeaf.h b/src/set/ibex_SetLeaf.h index b66a2c443..b5007dc62 100644 --- a/src/set/ibex_SetLeaf.h +++ b/src/set/ibex_SetLeaf.h @@ -26,30 +26,49 @@ class SetLeaf : public SetNode { */ SetLeaf(NodeType status); + SetLeaf(NodeType status,SetNode* father); + /** * \brief Delete this. */ virtual ~SetLeaf(); /** \see SetNode */ + /** \see SetNode */ virtual bool is_leaf() const; - //virtual SetNode* sync(const IntervalVector& nodebox, const IntervalVector& x, NodeType x_status, double eps, Mode mode); + /** \see SetNode */ + virtual SetNode * copy() const; + + /** \see SetNode */ + virtual void inter(NodeType x_status); /** \see SetNode */ - virtual SetNode* sync(const IntervalVector& nodebox, const IntervalVector& x, NodeType x_status, double eps); + virtual void _union(NodeType x); /** \see SetNode */ - virtual SetNode* sync_rec(const IntervalVector& nodebox, Sep& sep, double eps); + virtual void oper(SetNode * other,bool op); /** \see SetNode */ - virtual SetNode* inter(const IntervalVector& nodebox, const IntervalVector& x, NodeType x_status, double eps); + virtual void operator_ir(const IntervalVector& box,const IntervalVector& nodebox, NodeType val,bool op, double eps); /** \see SetNode */ - virtual SetNode* inter_rec(const IntervalVector& nodebox, Sep& sep, double eps); + virtual void operator_ir(const IntervalVector& box,const IntervalVector& subbox, NodeType valin,NodeType valout, bool op,double eps); /** \see SetNode */ - virtual SetNode* union_(const IntervalVector& nodebox, const IntervalVector& x, NodeType x_status, double eps); + virtual SetNode * fakeLeaf(const IntervalVector& box,const IntervalVector& subbox,NodeType val,bool op, double eps); + + /** \see SetNode */ + virtual void cleave(const IntervalVector& box, Sep& sep, double eps); + + /** \see SetNode */ + virtual void gather(bool go_up); + + /** \see SetNode */ + virtual void cutDeadBranch(); + + /** \see SetNode */ + virtual void checkFat(); /** \see SetNode */ virtual void visit_leaves(leaf_func func, const IntervalVector& nodebox) const; @@ -58,10 +77,8 @@ class SetLeaf : public SetNode { virtual void print(std::ostream& os, const IntervalVector& nodebox, int shift) const; /** \see SetNode */ - virtual void set_in_tmp(); + virtual void setFathers(); - /** \see SetNode */ - virtual void unset_in_tmp(); private: SetLeaf(const SetLeaf&); // forbidden From fc55e9fecc01a19349df365fbf8f5159c8150bdc Mon Sep 17 00:00:00 2001 From: domensta Date: Thu, 26 Feb 2015 11:19:41 +0100 Subject: [PATCH 19/32] Update ibex_SetNode.cpp --- src/set/ibex_SetNode.cpp | 200 ++------------------------------------- 1 file changed, 6 insertions(+), 194 deletions(-) diff --git a/src/set/ibex_SetNode.cpp b/src/set/ibex_SetNode.cpp index df1e7926a..35824f5f9 100644 --- a/src/set/ibex_SetNode.cpp +++ b/src/set/ibex_SetNode.cpp @@ -26,117 +26,6 @@ using namespace std; namespace ibex { -SetNode* diff(const IntervalVector& x, const IntervalVector& y, NodeType x_status, NodeType y_status, double eps) { - - if (y.is_empty()) { - return new SetLeaf(x_status); - } - - const int nn=x.size(); - - typedef struct { - int var; - double pt; - bool y_left; // is the part that belongs to y on the left (=true) or right (=false) side? - } bisection; - - bisection *tmp = new bisection[2*nn]; // in the worst case, there is 2n bisections - Interval c1, c2; - int b=0; - - for (int var=0; varprint(cout,box,0); - SetNode* root2 = diff(box, box2, OUT, UNK, eps); - //cout << "set obtained with outer contraction:" << endl; root2->print(cout,box,0); - - // TODO: pb: sync fails - // check "false" (skip_other_maybe is an old parameter not used anymore) - root1->inter(box,root2,box,eps); //,false); - - delete root2; - - //cout << "final set:" << endl; root1->print(cout,box,0); - - return root1; -} char to_string(const NodeType& status) { switch(status) { @@ -146,99 +35,22 @@ char to_string(const NodeType& status) { } } -SetNode::SetNode(NodeType status) : status(status) { - -} - -SetNode::~SetNode() { - -} - -SetNode* SetNode::sync(const IntervalVector& nodebox, Sep& sep, double eps) { - // perform contraction - //cout << "=== contract with ctc_in =======" << endl; - - // we skip other UNK-box if this node is not a leaf. This makes no difference - // if we are in SYNC mode but if we are in INTER mode, this prevents from - // this node to be "absorbed" by a temporary UNK box resulting from contraction. - SetNode* this2 = this->sync(nodebox, contract_set(nodebox, sep, eps), nodebox, eps, !is_leaf()); - - //cout << " sep gives: "; this2->print(cout,nodebox,0); - //cout << endl; - +SetNode::SetNode(NodeType status) : status(status), father(NULL) { - SetNode* this3 = this2->sync_rec(nodebox, sep, eps); - - return this3; } -SetNode* SetNode::sync(const IntervalVector& nodebox, const SetNode* other, const IntervalVector& otherbox, double eps, bool skip_other_maybe) { - - if (nodebox.is_disjoint(otherbox)) - return this; - else if (other->is_leaf()) { - //if (other->statusstatus, eps); - //else - // return this; - } else { - - SetBisect* bisect_node = (SetBisect*) other; - SetNode* this2 = sync(nodebox, bisect_node->left, bisect_node->left_box(otherbox), eps, skip_other_maybe); - // warning: cannot use this anymore (use this2 instead) - return this2->sync(nodebox, bisect_node->right, bisect_node->right_box(otherbox), eps, skip_other_maybe); - } -} - -SetNode* SetNode::inter(const IntervalVector& nodebox, Sep& sep, double eps) { - // we skip other UNK-box if this node is not a leaf. This makes no difference - // if we are in SYNC mode but if we are in INTER mode, this prevents from - // this node to be "absorbed" by a temporary UNK box resulting from contraction. - SetNode* this2 = this->inter(nodebox, contract_set(nodebox, sep, eps), nodebox, eps); - //cout << " sep gives: "; this2->print(cout,nodebox,0); - - SetNode* this4 = this2->inter_rec(nodebox, sep, eps); +SetNode::SetNode(NodeType status, SetNode *father): status(status), father(father) { - return this4; } +SetNode::~SetNode() { -SetNode* SetNode::inter(const IntervalVector& nodebox, const SetNode* other, const IntervalVector& otherbox, double eps) { - - if (nodebox.is_disjoint(otherbox)) - return this; - else if (other->is_leaf()) { - // we consider IN_TMP to be "UNK" until the end. Otherwise, there - // would be problems when other->status==UNK. Indeed, if we set the status - // of this node to UNK, we lose information ("other" may be an intermediate - // node in the process, although it is a SetLeaf, and some sub-nodes of other - // could be IN. But once a node is UNK it cannot be set to IN anymore...). - // If we impose this node to be a leaf, it does not fix the problem (this node may also be an - // intermediate node in the process: consider a plain box (a leaf) to be - // contracted). - return inter(nodebox, otherbox, other->status, eps); - } else { - - SetBisect* bisect_node = (SetBisect*) other; - SetNode* this2 = inter(nodebox, bisect_node->left, bisect_node->left_box(otherbox), eps); - // warning: cannot use this anymore (use this2 instead) - return this2->inter(nodebox, bisect_node->right, bisect_node->right_box(otherbox), eps); - } } -SetNode* SetNode::union_(const IntervalVector& nodebox, const SetNode* other, const IntervalVector& otherbox, double eps) { +/*void SetNode::inter(const SetNode* other) +{ - if (nodebox.is_disjoint(otherbox)) - return this; - else if (other->is_leaf()) { - return union_(nodebox, otherbox, other->status, eps); - } else { +}*/ - SetBisect* bisect_node = (SetBisect*) other; - SetNode* this2 = union_(nodebox, bisect_node->left, bisect_node->left_box(otherbox), eps); - // warning: cannot use this anymore (use this2 instead) - return this2->union_(nodebox, bisect_node->right, bisect_node->right_box(otherbox), eps); - } -} } // namespace ibex From 6b1f809e2069c29abfa6aa4d31b18914001f6b95 Mon Sep 17 00:00:00 2001 From: domensta Date: Thu, 26 Feb 2015 11:20:12 +0100 Subject: [PATCH 20/32] Update ibex_SetNode.h --- src/set/ibex_SetNode.h | 107 ++++++++++++++++++++--------------------- 1 file changed, 51 insertions(+), 56 deletions(-) diff --git a/src/set/ibex_SetNode.h b/src/set/ibex_SetNode.h index 09dd5fbfa..a6a289c83 100644 --- a/src/set/ibex_SetNode.h +++ b/src/set/ibex_SetNode.h @@ -26,6 +26,16 @@ namespace ibex { class NoSet { }; +/** + * \ingroup iset + * \brief Exception thrown by sync function. + * + * use to compute regular cutting of a interval + */ +class vcut{ + int var; + double pt; +}; /** * \brief Set node. @@ -43,6 +53,12 @@ class SetNode { */ SetNode(NodeType status); + /** + * \brief Creates a node of given status and father + */ + SetNode(NodeType status,SetNode *father); + + /** * \brief Delete this. */ @@ -54,69 +70,64 @@ class SetNode { virtual bool is_leaf() const=0; /** - * \brief Synchronization with an i-set represented implicitly by a Sep + * \brief Return a copy of the node. */ - SetNode* sync(const IntervalVector& nodebox, Sep& sep, double eps); + virtual SetNode * copy() const=0; + /** - * \brief Synchronization with an explicit i-set "other" - * - * skip_other_maybe: don't consider UNK box of the other set. This is important - * because the other set may be a temporary set produced by - * the contract function (and the UNK box will be refined later) + * \brief Intersection or Union between a box of NodeType val and a regular setInterval. + * Box may not respect the regularity of the regular setInterval. + * The part of the set that intersect nodebox only is modify. */ - SetNode* sync(const IntervalVector& nodebox, const SetNode* other, const IntervalVector& otherbox, double eps, bool skip_other_maybe); + virtual void operator_ir(const IntervalVector& box,const IntervalVector& nodebox, NodeType val, bool op, double eps)=0; /** - * \brief Synchronization with an i-set reduced to a single box "x" of status "x_status". - * + * \brief Call by operator_ir, create a subtree from a leaf with "fake leves" that are setbisect with left and right set to null + * should avoid to create leaf and eventually destruct it if it need to be cut i.e replace by a setbisect + * method abandonned, oddly slower than creating leaves and replace them by setbisect. */ - virtual SetNode* sync(const IntervalVector& nodebox, const IntervalVector& x, NodeType x_status, double eps)=0; + virtual SetNode * fakeLeaf(const IntervalVector& box,const IntervalVector& subbox,NodeType val,bool op, double eps)=0; /** - * \brief Synchronization with a Sep (recursive call) - * - * Once the current "nodebox" has been synchronized with the two sets obtained by applying the inner and - * outer contraction, a recursive call is performed (where the Sep is applied on the sub-boxes). - * - * If this node is a leaf, it means it has to be bisected. + * \brief Overloaded function, apply valout to the set outside of the box and valin to the inside, thus modify the whole set. */ - virtual SetNode* sync_rec(const IntervalVector& nodebox, Sep& sep, double eps)=0; + virtual void operator_ir(const IntervalVector& box,const IntervalVector& subbox, NodeType valin,NodeType valout, bool op,double eps)=0; /** - * \brief Intersection with an i-set represented implicitly by a Sep + * \brief Intersection between two setNode. */ - SetNode* inter(const IntervalVector& nodebox, Sep& sep, double eps); + virtual void oper(SetNode* other,bool op)=0; /** - * \brief Intersection with an explicit i-set "other" + * \brief Intersection between setnode and a status. */ - SetNode* inter(const IntervalVector& nodebox, const SetNode* other, const IntervalVector& otherbox, double eps); + virtual void inter(NodeType x_status)=0; /** - * \brief Intersection with an i-set reduced to a single box "x" of status "x_status". + * \brief Union between setnode and a status. */ - virtual SetNode* inter(const IntervalVector& nodebox, const IntervalVector& x, NodeType x_status, double eps)=0; + virtual void _union(NodeType x)=0; /** - * \brief Intersection with a Sep (recursive call) - * - * Once the current "nodebox" has been intersected with the two sets obtained by applying the inner and - * outer contraction, a recursive call is performed (where the Sep is applied on the sub-boxes). - * - * If this node is a leaf, it means it has to be bisected. + * \brief Change value of branch if right and left got the same value IN, OUT or UNK. */ - virtual SetNode* inter_rec(const IntervalVector& nodebox, Sep& sep, double eps)=0; - + virtual void gather(bool go_up)=0; /** - * \brief Union with an explicit i-set "other" + * \brief Delete the branch if left and right got the same value IN, OUT or UNK. */ - SetNode* union_(const IntervalVector& nodebox, const SetNode* other, const IntervalVector& otherbox, double eps); + virtual void cutDeadBranch()=0; /** - * \brief Union with an i-set reduced to a single box "x" of status "x_status". + * \brief Check if fathers are initialized. */ - virtual SetNode* union_(const IntervalVector& nodebox, const IntervalVector& x, NodeType x_status, double eps)=0; + virtual void checkFat()=0; + + /** + * \brief Contrat i-set w.r.t separator sep, split leaves until boxin and boxout returned by sep are disjoints, + * and then call operator_ir to contract on them + */ + virtual void cleave(const IntervalVector& box, Sep& sep,double eps)=0; /** * \brief Visit the leaves of a tree with a callback "func" @@ -129,36 +140,20 @@ class SetNode { virtual void print(std::ostream& os, const IntervalVector& nodebox, int shift) const=0; /** - * Set all "IN" leaves to "IN_TMP". - * - * This function is useful for calculating set intersection only. - * It sets all the inner nodes of the original set to IN_TMP before. - * This allows to distinguish a node that is inside the original set (IN_TMP) - * from a node that is proven to be inside the intersection (IN). + * \brief Set fathers of the nodes */ - virtual void set_in_tmp()=0; + virtual void setFathers()=0; + - /** - * Set all "IN_TMP" leaves to "UNK" - * - * This function is useful for calculating set intersection only. - * Once the intersection is calculated, the nodes that was in the original - * set but that could not be proven to be inside the intersection - * have "UNK" status. - */ - virtual void unset_in_tmp()=0; /** * \brief The status of the node */ NodeType status; + SetNode * father; }; -SetNode* diff(const IntervalVector& x, const IntervalVector& y, NodeType x_status, NodeType y_status, double eps); - -SetNode* contract_set(const IntervalVector& x, Sep& sep, double eps); - } // namespace ibex #endif // __IBEX_SET_NODE_H__ From 2cadbdac6cb00ed6aed958abefb01c2ac746eba6 Mon Sep 17 00:00:00 2001 From: domensta Date: Thu, 26 Feb 2015 11:24:06 +0100 Subject: [PATCH 21/32] Delete ibex_NodeType.cpp --- ibex_NodeType.cpp | 310 ---------------------------------------------- 1 file changed, 310 deletions(-) delete mode 100644 ibex_NodeType.cpp diff --git a/ibex_NodeType.cpp b/ibex_NodeType.cpp deleted file mode 100644 index 24918e1b0..000000000 --- a/ibex_NodeType.cpp +++ /dev/null @@ -1,310 +0,0 @@ -//============================================================================ -// I B E X -// File : ibex_NodeType.cpp -// Author : Gilles Chabert -// Copyright : Ecole des Mines de Nantes (France) -// License : See the LICENSE file -// Created : 18 Aug 2014 -//============================================================================ - -#include "ibex_NodeType.h" - -// =========== shortcuts ================== -#define IN __IBEX_IN__ -#define OUT __IBEX_OUT__ -#define UNK __IBEX_UNK__ -#define UNK_IN __IBEX_UNK_IN__ -#define UNK_OUT __IBEX_UNK_OUT__ -#define UNK_IN_OUT __IBEX_UNK_IN_OUT__ -#define IN_TMP __IBEX_IN_TMP__ -// ======================================== - -namespace ibex { -// relic from irregular set, need for SetBisect constructor -NodeType operator|(NodeType x, NodeType y) { - switch (x) { - case IN : { - switch(y) { - case IN : return IN; - case OUT : - case UNK_OUT: - case UNK_IN_OUT: return UNK_IN_OUT; - default : return UNK_IN; - } - } - break; - case OUT : { - switch(y) { - case OUT : return OUT; - case IN : - case UNK_IN: - case UNK_IN_OUT: return UNK_IN_OUT; - default : return UNK_OUT; - } - } - break; - case UNK : { - switch(y) { - case IN : - case UNK_IN: return UNK_IN; - case OUT : - case UNK_OUT: return UNK_OUT; - case UNK: return UNK; - default: return UNK_IN_OUT; - } - } - break; - case UNK_IN : { - switch(y) { - case IN : - case UNK_IN: - case UNK : return UNK_IN; - default: return UNK_IN_OUT; - } - } - break; - case UNK_OUT : { - switch(y) { - case OUT : - case UNK_OUT: - case UNK : return UNK_OUT; - default: return UNK_IN_OUT; - } - } - break; - default : - //Warning: IN_TMP not considered here. - return UNK_IN_OUT; - } -} - - - -// define operator or between two nodetype, assuming the two boxes associated are equal -NodeType uni(NodeType x,NodeType y) { - switch (x) { - case IN : { - return IN; - - } - break; - case OUT : { - return y; - } - break; - case UNK : { - switch(y) { - case IN : return IN; - case UNK_IN: return UNK_IN; - case OUT : return UNK; - case UNK : return UNK; - case UNK_OUT: return UNK_OUT; - default: return UNK_IN_OUT; - } - } - break; - case UNK_IN : { - switch(y) { - case IN : - case UNK_IN: - case UNK : return UNK_IN; - default: return UNK_IN_OUT; - } - } - break; - case UNK_OUT : { - switch(y) { - case OUT : - case UNK_OUT: - case UNK : return UNK_OUT; - default: return UNK_IN_OUT; - } - } - break; - default : - //Warning: IN_TMP not considered here. - return UNK_IN_OUT; - } - -} - -// define operator or between two nodetype, assuming box of nodetype y is subset of box of nodetype x; -NodeType uni_in(NodeType x, NodeType y) { - switch (x) { - case IN : { - switch(y) { - case IN : return IN; - case OUT : return IN; - case UNK : return IN; - case UNK_OUT: - case UNK_IN_OUT: return UNK_IN_OUT; - default : return UNK_IN; - } - } - break; - case OUT : { - switch(y) { - case OUT : return OUT; - case IN : return UNK; - case UNK : return UNK; - case UNK_IN: - case UNK_IN_OUT: return UNK_IN_OUT; - default : return UNK_OUT; - } - } - break; - case UNK : { - switch(y) { - return UNK; - } - } - break; - /*case UNK_IN : { - switch(y) { - case IN : - case UNK_IN: - case UNK : return UNK_IN; - default: return UNK_IN_OUT; - } - } - break; - case UNK_OUT : { - switch(y) { - case OUT : - case UNK_OUT: - case UNK : return UNK_OUT; - default: return UNK_IN_OUT; - } - } - break;*/ - default : - //Warning: IN_TMP not considered here. - return UNK_IN_OUT; - - } -} - -// define operator and between two nodetype, assuming the two boxes associated are equal -NodeType inte(NodeType x, NodeType y) { - switch (x) { - case IN : { - return y; - } - break; - case OUT : { - return OUT; - } - break; - case UNK : { - switch(y) { - case IN : return UNK; - case UNK_IN: return UNK_IN; - case OUT : return OUT; - case UNK : return UNK; - case UNK_OUT: return UNK_OUT; - default: return UNK_IN_OUT; - } - } - break; - case UNK_IN : { - switch(y) { - case IN : - case UNK_IN: - case UNK : return UNK_IN; - default: return UNK_IN_OUT; - } - } - break; - case UNK_OUT : { - switch(y) { - case OUT : - case UNK_OUT: - case UNK : return UNK_OUT; - default: return UNK_IN_OUT; - } - } - break; - default : - //Warning: IN_TMP not considered here. - return UNK_IN_OUT; - } -} - - -// define operator and between two nodetype, assuming box of nodetype y is subset of box of nodetype x; -NodeType inte_in(NodeType x, NodeType y) { - switch (x) { - case IN : { - switch(y) { - case IN : return IN; - case OUT : return UNK; - case UNK : return UNK; - case UNK_OUT: - case UNK_IN_OUT: return UNK_IN_OUT; - default : return UNK_IN; - } - } - break; - case OUT : { - switch(y) { - case OUT : return OUT; - case IN : return OUT; - case UNK : return OUT; - case UNK_IN: - case UNK_IN_OUT: return UNK_IN_OUT; - default : return UNK_OUT; - } - } - break; - case UNK : { - switch(y) { - case IN : return UNK; - case UNK_IN: return UNK_IN; - case OUT : return UNK; - case UNK_OUT: return UNK_OUT; - case UNK: return UNK; - default: return UNK_IN_OUT; - } - } - break; - case UNK_IN : { - switch(y) { - case IN : - case UNK_IN: - case UNK : return UNK_IN; - default: return UNK_IN_OUT; - } - } - break; - case UNK_OUT : { - switch(y) { - case OUT : - case UNK_OUT: - case UNK : return UNK_OUT; - default: return UNK_IN_OUT; - } - } - break; - default : - //Warning: IN_TMP not considered here. - return UNK_IN_OUT; - } -} - -bool certainly_contains_in(NodeType x) { - return x==IN || x==UNK_IN || x==UNK_IN_OUT; -} - -bool certainly_contains_out(NodeType x) { - return x==OUT || x==UNK_OUT || x==UNK_IN_OUT; -} - -bool possibly_contains_in(NodeType x) { - return x!=OUT; -} - -bool possibly_contains_out(NodeType x) { - return x!=IN; -} - -} // namespace ibex From 82d8a90f010a8163a895caa3df71fc7d3870a638 Mon Sep 17 00:00:00 2001 From: domensta Date: Thu, 26 Feb 2015 11:24:15 +0100 Subject: [PATCH 22/32] Delete ibex_NodeType.h --- ibex_NodeType.h | 92 ------------------------------------------------- 1 file changed, 92 deletions(-) delete mode 100644 ibex_NodeType.h diff --git a/ibex_NodeType.h b/ibex_NodeType.h deleted file mode 100644 index 7456e64f4..000000000 --- a/ibex_NodeType.h +++ /dev/null @@ -1,92 +0,0 @@ -//============================================================================ -// I B E X -// File : ibex_NodeType.h -// Author : Gilles Chabert -// Copyright : Ecole des Mines de Nantes (France) -// License : See the LICENSE file -// Created : 18 Aug 2014 -//============================================================================ - -#ifndef __IBEX_NODE_TYPE_H__ -#define __IBEX_NODE_TYPE_H__ - -namespace ibex { - -/** \ingroup iset */ -/*@{*/ - -/** - * \brief Status of a node in the representation of an i-set. - * - * __IBEX_IN__ : the node box is inside the set - * __IBEX_OUT__ : the node box is outside the set - * __IBEX_UNK__ : the node is of unknown status (typically, corresponds to a boundary box) - * __IBEX_UNK_IN : the subtree contains IN and UNK leaves - * __IBEX_UNK_OUT : the subtree contains OUT and UNK leaves - * __IBEX_UNK_IN_OUT : the subtree contains IN, OUT and UNK leaves - * __IBEX_IN_TMP__ : used by "inter" functions only. Means "inside the original set" (but not necessarily inside the intersection) - */ -typedef enum { __IBEX_IN__, - __IBEX_OUT__, - __IBEX_UNK__, - __IBEX_UNK_IN__, - __IBEX_UNK_OUT__, - __IBEX_UNK_IN_OUT__, - __IBEX_IN_TMP__ } NodeType; - -/** - * \brief Status of a union of two nodes. - * - * \note Status only useful for "sync" functions. So the IN_TMP status is ignored (and this makes no problem so far). - * - * Ex: __IBEX_IN__ | __IBEX_UNK__ gives __IBEX_IN_UNK__. - * - * \see SetBisect constructor. - */ -NodeType operator|(NodeType x, NodeType y); -/** - * \brief return value of union of two equal boxes - */ -NodeType uni(NodeType x,NodeType y); -/** - * \brief return value of union of two boxes, assuming the on associated to y is include in the one associated to x - */ -NodeType uni_in(NodeType x, NodeType y); -/** - * \brief return value of inter of two equal boxes - */ -NodeType inte(NodeType x, NodeType y); -/** - * \brief return value of inter of two boxes, assuming the on associated to y is include in the one associated to x - */ -NodeType inte_in(NodeType x, NodeType y); -/** - * \brief return value of inter of two boxes, assuming the on associated to y is include in the one associated to x - */ -bool possibly_contains_in(NodeType x); - -/** - * \brief False only if the subtree contains no outer point - */ -bool possibly_contains_out(NodeType x); - -/** - * \brief True only if the subtree contains inner points - */ -bool certainly_contains_in(NodeType x); - -/** - * \brief True only if the subtree contains outer points - */ -bool certainly_contains_out(NodeType x); - -/** - * \brief Convert the status to char - */ -char to_string(const NodeType& status); - -/*@}*/ - -} // namespace ibex - -#endif // __IBEX_NODE_TYPE_H__ From 264aed34c7ba724ac587d4969c876a8197479a3f Mon Sep 17 00:00:00 2001 From: domensta Date: Thu, 26 Feb 2015 11:24:26 +0100 Subject: [PATCH 23/32] Delete ibex_SetBisect.cpp --- ibex_SetBisect.cpp | 300 --------------------------------------------- 1 file changed, 300 deletions(-) delete mode 100644 ibex_SetBisect.cpp diff --git a/ibex_SetBisect.cpp b/ibex_SetBisect.cpp deleted file mode 100644 index 01e95bcee..000000000 --- a/ibex_SetBisect.cpp +++ /dev/null @@ -1,300 +0,0 @@ -//============================================================================ -// I B E X -// File : ibex_SetBisect.cpp -// Author : Gilles Chabert -// Copyright : Ecole des Mines de Nantes (France) -// License : See the LICENSE file -// Created : 13 juil. 2014 -//============================================================================ - -#include "ibex_SetBisect.h" -#include "ibex_SetLeaf.h" -#include -#include - -using namespace std; - -// =========== shortcuts ================== -#define IN __IBEX_IN__ -#define OUT __IBEX_OUT__ -#define UNK __IBEX_UNK__ -#define UNK_IN __IBEX_UNK_IN__ -#define UNK_OUT __IBEX_UNK_OUT__ -#define UNK_IN_OUT __IBEX_UNK_IN_OUT__ -#define IN_TMP __IBEX_IN_TMP__ -// ======================================== - -namespace ibex { - -SetBisect::SetBisect(int var, double pt, SetNode* left, SetNode* right) : SetNode(UNK_IN_OUT,NULL), var(var), pt(pt), left(left), right(right) { - -} - -SetBisect::SetBisect(int var, double pt, SetNode* left, SetNode* right,SetNode* father) : SetNode(UNK_IN_OUT,father), var(var), pt(pt), left(left), right(right) { - -} - -SetBisect::SetBisect(int var, double pt) : SetNode(UNK_IN_OUT), var(var), pt(pt), left(NULL), right(NULL) { - -} - -SetBisect::~SetBisect() { - delete left; - delete right; -} - -bool SetBisect::is_leaf() const { - return false; -} - -SetNode * SetBisect::copy() const { - SetBisect * n = new SetBisect(this->var,this->pt,this->left->copy(),this->right->copy()); - n->left->father = n; - n->right->father = n; - return n; -} - - -void SetBisect::inter(NodeType x) { - - left->inter(x); // apply inter to left and right until reach the leaves - right->inter(x); -} - -void SetBisect::_union(NodeType x) { - left->_union(x); - right->_union(x); -} - -void SetBisect::oper(SetNode * node,bool op) { - if(node->is_leaf()) // apply status to leaves of the subtree which have this as root - { - if(op && node->status != IN) - { - left->inter(node->status); - right->inter(node->status); - } - else if(!op && node->status!= OUT) - { - left->_union(node->status); - right->_union(node->status); - } - } - else - { - SetBisect * other = (SetBisect*) node; // node is assume to be either a leaf or a bisect, able to cast node in bisect as it ain't a leaf - left->oper(other->left,op); - right->oper(other->right,op); - } -} - -void SetBisect::operator_ir(const IntervalVector& box,const IntervalVector& subbox, NodeType val,bool op, double eps) -{ - - if(box.is_subset(subbox)) // compute intersection of leaves of this root with val - { - if(op && val != IN) - this->inter(val); - else if(!op && val != OUT) - this->_union(val); - } - else - { - if(this->left_box(box).overlaps(subbox)) // need to apply function on left only if leftbox ovelaps subbox - left->operator_ir(this->left_box(box),subbox,val,op,eps); - if(this->right_box(box).overlaps(subbox)) // need to apply function on right only if rightbox overlaps subbox - right->operator_ir(this->right_box(box),subbox,val,op,eps); - } -} - -void SetBisect::operator_ir(const IntervalVector& box,const IntervalVector& subbox, NodeType valin,NodeType valout,bool op, double eps) -{ - - if(box.is_subset(subbox)) // apply valin on the leaves of this root - { - if(op && valin != IN) - this->inter(valin); - else if(!op && valin != OUT) - this->_union(valin); - } - else if(box.overlaps(subbox)) - { - if(this->left_box(box).overlaps(subbox)) - left->operator_ir(this->left_box(box),subbox,valin,valout,op,eps); - else { // leftbox is disjoint of subbox, apply valout on the leaves of this->left root - if(op && valout != IN) - left->inter(valout); - else if (!op && valout != OUT) - left->_union(valout);} - if(this->right_box(box).overlaps(subbox)) - right->operator_ir(this->right_box(box),subbox,valin,valout,op,eps); - else{ // rightbox is disjoint of subbox, apply valout on the leaves of this->right root - if(op && valout != IN) - right->inter(valout); - else if (!op && valout != OUT) - right->_union(valout);} - } - else{ // this is disjoint of subbox, apply valout on the leaves of this root - if(op && valout != IN) - this->inter(valout); - else if (!op && valout != OUT) - this->_union(valout);} -} - -// Uncomment this function and comment the one above to use fakeBranch method -/*void SetBisect::operator_ir(const IntervalVector& box,const IntervalVector& subbox, NodeType val,bool op, double eps) -{ - - if(left == NULL) - { - assert(right == NULL); - left = this->fakeLeaf(left_box(box),subbox,val,op,eps); - left->father = this; - right = this->fakeLeaf(right_box(box),subbox,val,op,eps); - right->father = this; - status = UNK_IN_OUT; - } - else - { - if(box.is_subset(subbox)) - { - if(op) - this->inter(val); - else - this->_union(val); - } - else - { - if(this->left_box(box).overlaps(subbox)) - left->operator_ir(this->left_box(box),subbox,val,op,eps); - else - return; - if(this->right_box(box).overlaps(subbox)) - right->operator_ir(this->right_box(box),subbox,val,op,eps); - else - return; - } - } -}*/ - -SetNode * SetBisect::fakeLeaf(const IntervalVector& box,const IntervalVector& subbox,NodeType val,bool op, double eps) { - //assert(left == NULL && right == NULL); - if(box.is_subset(subbox)) - if(op) - return new SetLeaf(inte(status,val)); - else - return new SetLeaf(uni(status,val)); - else if(box.overlaps(subbox)) - { - if(box.max_diam()<=eps) - return new SetLeaf(inte_in(status,val)); - else - { - int var = box.extr_diam_index(false); - double pt = box[var].mid(); - SetBisect * node = new SetBisect(var,pt,NULL,NULL); - node->status = status; - node->left = node->fakeLeaf(node->left_box(box),subbox,val,op,eps); - node->right = node->fakeLeaf(node->right_box(box),subbox,val,op,eps); - node->left->father = node; - node->right->father = node; - node->status = UNK_IN_OUT; - return node; - } - } - else - return new SetLeaf(status); -} -void SetBisect::cleave(const IntervalVector& box, Sep& sep, double eps) { - - IntervalVector box1(box); - IntervalVector box2(box); - - sep.separate(box1,box2); - if(box1.is_disjoint(box2)) // in and out are disjoint, can contract on box1 and box2 - { - if(!box1.is_empty()) - this->operator_ir(box,box1,IN,true,eps); - if(!box2.is_empty()) - this->operator_ir(box,box2,OUT,true,eps); - } - else // continu until box1 and box2 are disjoint - { - left->cleave(left_box(box),sep,eps); - right->cleave(right_box(box),sep,eps); - } -} -void SetBisect::gather(bool go_up) { - if(((left->is_leaf()&&right->is_leaf()) || go_up)&&left->status==right->status) // leaves are reached, or climbing up the tree toward the root - { - status = left->status; // this bisect get a leaf status IN OUT or UNK - if(father != NULL) // check if father is not the root of SetInterval - father->gather(true); - } - else if(!go_up) // go down the tree to reach the leaves - { - left->gather(false); - right->gather(false); - } -} - -void SetBisect::cutDeadBranch() { - if(left->status ==right->status && left->status < 3) // if status of left and right are equal and has got a leaf status, meaning all leaves have the same status - { - SetBisect* bfather = (SetBisect*) father; - if(bfather->left == this) - bfather->left = new SetLeaf(status,father); // this is now a leaf - else - bfather->right = new SetLeaf(status,father); // this is now a leaf - delete this; // delete former this which was a bisect - } - else // go down the tree until reach leaves or bisect that can be set a leaf - { - left->cutDeadBranch(); - right->cutDeadBranch(); - } -} - - -void SetBisect::checkFat() { - if(father == NULL) - cout<<"issue, invalid father"<checkFat(); - right->checkFat(); -} -void SetBisect::visit_leaves(leaf_func func, const IntervalVector& nodebox) const { - left->visit_leaves(func, left_box(nodebox)); - right->visit_leaves(func, right_box(nodebox)); -} - -void SetBisect::print(ostream& os, const IntervalVector& nodebox, int shift) const { - for (int i=0; iprint(os, left_box(nodebox), shift+2); - right->print(os, right_box(nodebox), shift+2); -} - -void SetBisect::setFathers() { - left->father = this; - right->father = this; - left->setFathers(); - right->setFathers(); -} - - -IntervalVector SetBisect::left_box(const IntervalVector& nodebox) const { - IntervalVector leftbox(nodebox); - assert (nodebox[var].contains(pt)); - leftbox[var] =Interval(nodebox[var].lb(),pt); - return leftbox; -} - -IntervalVector SetBisect::right_box(const IntervalVector& nodebox) const { - IntervalVector rightbox(nodebox); - assert (nodebox[var].contains(pt)); - rightbox[var]=Interval(pt,nodebox[var].ub()); - return rightbox; -} - - -} // namespace ibex From 6e6e0169cae7a7b011121ed44d6d550cbb539906 Mon Sep 17 00:00:00 2001 From: domensta Date: Thu, 26 Feb 2015 11:24:35 +0100 Subject: [PATCH 24/32] Delete ibex_SetBisect.h --- ibex_SetBisect.h | 118 ----------------------------------------------- 1 file changed, 118 deletions(-) delete mode 100644 ibex_SetBisect.h diff --git a/ibex_SetBisect.h b/ibex_SetBisect.h deleted file mode 100644 index fb0073e38..000000000 --- a/ibex_SetBisect.h +++ /dev/null @@ -1,118 +0,0 @@ -//============================================================================ -// I B E X -// File : ibex_SetBisect.h -// Author : Gilles Chabert -// Copyright : Ecole des Mines de Nantes (France) -// License : See the LICENSE file -// Created : 13 juil. 2014 -//============================================================================ - -#ifndef __IBEX_SET_BISECT_H__ -#define __IBEX_SET_BISECT_H__ - -#include "ibex_SetNode.h" - -namespace ibex { - -/** - * \ingroup iset - * \brief Bisection node (i-set representation) - */ -class SetBisect : public SetNode { - -public: - - /** - * \brief Create a bisection node - * - * The variable of the nodebox is bisected at point "pt", resulting - * in two subnodes, left and right. - */ - SetBisect(int var, double pt, SetNode* left, SetNode* right); - - SetBisect(int var, double pt, SetNode* left, SetNode* right,SetNode* father); - - /** - * \brief Delete this - */ - virtual ~SetBisect(); - - /** \see SetNode */ - virtual bool is_leaf() const; - - /** \see SetNode */ - virtual SetNode * copy() const; - - /** \see SetNode */ - virtual void inter(NodeType x_status); - - /** \see SetNode */ - virtual void _union(NodeType x); - - /** \see SetNode */ - virtual void oper(SetNode * other,bool op); - - /** \see SetNode */ - virtual void operator_ir(const IntervalVector& box,const IntervalVector& nodebox, NodeType val,bool op, double eps); - - /** \see SetNode */ - virtual void operator_ir(const IntervalVector& box,const IntervalVector& subbox, NodeType valin,NodeType valout, bool op,double eps); - - /** \see SetNode */ - virtual SetNode * fakeLeaf(const IntervalVector& box,const IntervalVector& subbox,NodeType val,bool op, double eps); - - /** \see SetNode */ - virtual void cleave(const IntervalVector& box, Sep& sep, double eps); - - /** \see SetNode */ - virtual void gather(bool go_up); - - /** \see SetNode */ - virtual void cutDeadBranch(); - - /** \see SetNode */ - virtual void checkFat(); - - /** \see SetNode */ - virtual void visit_leaves(leaf_func func, const IntervalVector& nodebox) const; - - /** \see SetNode */ - virtual void print(std::ostream& os, const IntervalVector& nodebox, int shift) const; - - /** \see SetNode */ - virtual void setFathers(); - - - - - - /** - * \brief Rerturn left_box according to var, pt and nodebox - */ - IntervalVector left_box(const IntervalVector& nodebox) const; - - /** - * \brief Rerturn left_box according to var, pt and nodebox - */ - IntervalVector right_box(const IntervalVector& nodebox) const; - -//protected: - friend class SetNode; - friend class SetInterval; - - // partial initialization used by SetInterval::load only - SetBisect(int var, double pt); - - - int var; - double pt; - SetNode* left; - SetNode* right; - -private: - SetBisect(const SetBisect&); // forbidden -}; - -} // namespace ibex - -#endif // __IBEX_SET_BISECT_H__ From a9b8ef1a6b8dd92fd13f7bd6ba1faa6f683320fe Mon Sep 17 00:00:00 2001 From: domensta Date: Thu, 26 Feb 2015 11:24:44 +0100 Subject: [PATCH 25/32] Delete ibex_SetInterval.cpp --- ibex_SetInterval.cpp | 348 ------------------------------------------- 1 file changed, 348 deletions(-) delete mode 100644 ibex_SetInterval.cpp diff --git a/ibex_SetInterval.cpp b/ibex_SetInterval.cpp deleted file mode 100644 index 691bc13b2..000000000 --- a/ibex_SetInterval.cpp +++ /dev/null @@ -1,348 +0,0 @@ -//============================================================================ -// I B E X -// File : ibex_Set.cpp -// Author : Gilles Chabert -// Copyright : Ecole des Mines de Nantes (France) -// License : See the LICENSE file -// Created : 13 juil. 2014 -//============================================================================ - -#include "ibex_SetInterval.h" -#include "ibex_SetLeaf.h" -#include "ibex_SetBisect.h" -#include "ibex_CellHeap.h" -#include "ibex_CellStack.h" -#include -#include - -using namespace std; - -namespace ibex { - -SetInterval::SetInterval(const IntervalVector& bounding_box, double eps, bool inner) : root(new SetLeaf(inner? __IBEX_IN__: __IBEX_UNK__)), eps(eps), bounding_box(bounding_box) { - -} - -SetInterval::SetInterval(const char* filename) : root(NULL), eps(-1), bounding_box(1) { - load(filename); -} - -SetInterval::SetInterval(const SetInterval& set) : eps(set.eps), bounding_box(set.bounding_box) -{ - root = set.root->copy(); - root->father = NULL; -} - - -bool SetInterval::is_empty() const { - return root==NULL; -} - -void SetInterval::cutRoot() -{ - NodeType stat = root->status; - delete root; - int var = bounding_box.extr_diam_index(false); - double pt = bounding_box[var].mid(); - SetBisect * broot = new SetBisect(var,pt,new SetLeaf(stat),new SetLeaf(stat)); - broot->left->father = broot; - broot->right->father = broot; - root = broot; - -} -void SetInterval::contract(Sep& sep) { - // case root is leaf create issue for SetLeaf recursive function that need the father - // root is redefined as SetBisect pointing on two leaves with value of the root - if(root->is_leaf()) - this->cutRoot(); - root->cleave(bounding_box, sep,eps); - this->gather(); - root->father = NULL; -} - -SetInterval& SetInterval::operator&=(const SetInterval& set) { - assert(bounding_box== set.bounding_box); // root must be the same as set interval are regular - // case root is leaf create issue for SetLeaf recursive function that need the father - // root is redefined as SetBisect pointing on two leaves with value of the root - if(root->is_leaf()) - this->cutRoot(); - root->oper(set.root,true); - this->gather(); - return *this; -} - -SetInterval& SetInterval::interBox(const IntervalVector& box,NodeType valin,NodeType valout) { - - // case root is leaf create issue for SetLeaf recursive function that need the father - // root is redefined as SetBisect pointing on two leaves with value of the root - if(root->is_leaf()) - this->cutRoot(); - cout<<"status of root: "<status<operator_ir(bounding_box,box,valin,valout,true,eps); - this->gather(); - return *this; -} - -SetInterval& SetInterval::unionBox(const IntervalVector& box,NodeType valin,NodeType valout) { - // case root is leaf create issue for SetLeaf recursive function that need the father - // root is redefined as SetBisect pointing on two leaves with value of the root - if(root->is_leaf()) - this->cutRoot(); - root->operator_ir(bounding_box,box,valin,valout,false,eps); - this->gather(); - return *this; -} - - -SetInterval& SetInterval::operator|=(const SetInterval& set) { - assert(bounding_box== set.bounding_box); // root must be the same as set interval are regular - // case root is leaf create issue for SetLeaf recursive function that need the father - // root is redefined as SetBisect pointing on two leaves with value of the root - if(root->is_leaf()) - this->cutRoot(); - root->oper(set.root,false); - this->gather(); - return *this; -} - -void SetInterval::gather() { - root->gather(false); - root->cutDeadBranch(); -} - -void SetInterval::checkFat() { - root->checkFat(); -} - -void SetInterval::save(const char* filename) { - std::stack s; - - s.push(root); - - fstream os; - os.open(filename, ios::out | ios::trunc | ios::binary); - - os.write((char*) &eps, sizeof(double)); - - int n=bounding_box.size(); - os.write((char*) &n, sizeof(int)); - - for (int i=0; iis_leaf()) { - int no_var=-1; // to store "-1" (means: leaf) - os.write((char*) &no_var, sizeof(int)); - os.write((char*) &node->status, sizeof(NodeType)); - } - else { - SetBisect* b=(SetBisect*) node; - os.write((char*) &b->var, sizeof(int)); - os.write((char*) &b->pt, sizeof(double)); - s.push(b->right); - s.push(b->left); - } - } - os.close(); -} - -void SetInterval::load(const char* filename) { - - std::ifstream is; - is.open(filename, ios::in | ios::binary); - - is.read((char*) &eps, sizeof(double)); - //cout << "eps=" << eps << endl; - - unsigned int n; - is.read((char*) &n, sizeof(int)); - //cout << "n=" << n << endl; - - bounding_box.resize(n); - - for (int i=0; i().dist; - } -}; -} - -double SetInterval::dist(const Vector& pt, bool inside) const { - CellHeapDist heap; - - //int count=0; // for stats - - Cell* root_cell =new Cell(bounding_box); - root_cell->add(); - root_cell->get().node = root; - root_cell->get().set_dist(bounding_box,pt); - //count++; - - heap.push(root_cell); - - double lb = POS_INFINITY; - - while (!heap.empty()) { - - Cell* c = heap.pop(); - - SetNode* node = c->get().node; - - assert(node!=NULL); - - if (node->status==(inside? __IBEX_IN__ : __IBEX_OUT__)) { - double d=c->get().dist; - if (dis_leaf() && ( (inside && possibly_contains_in(node->status)) - || (!inside && possibly_contains_out(node->status)))) { - SetBisect& b= *((SetBisect*) node); - - IntervalVector left=b.left_box(c->box); - IntervalVector right=b.right_box(c->box); - - std::pair p=c->bisect(left,right); - - p.first->get().set_dist(left,pt); - //count++; - if (p.first->get().dist<=lb) heap.push(p.first); - - p.second->get().set_dist(right,pt); - //count++; - if (p.second->get().dist<=lb) heap.push(p.second); - } - delete c; - } - //cout << " number of times a distance to a box has been computed: " << count << endl; - return ::sqrt(lb); -} - -SetInterval::~SetInterval() { - delete root; -} - -} // namespace ibex From 48d98c33626993f0968e71f3b31ccddc97965665 Mon Sep 17 00:00:00 2001 From: domensta Date: Thu, 26 Feb 2015 11:25:00 +0100 Subject: [PATCH 26/32] Delete ibex_SetInterval.h --- ibex_SetInterval.h | 162 --------------------------------------------- 1 file changed, 162 deletions(-) delete mode 100644 ibex_SetInterval.h diff --git a/ibex_SetInterval.h b/ibex_SetInterval.h deleted file mode 100644 index ad3982e6c..000000000 --- a/ibex_SetInterval.h +++ /dev/null @@ -1,162 +0,0 @@ -//============================================================================ -// I B E X -// File : ibex_Set.h -// Author : Gilles Chabert -// Copyright : Ecole des Mines de Nantes (France) -// License : See the LICENSE file -// Created : 13 juil. 2014 -//============================================================================ - -#ifndef __IBEX_SET_H__ -#define __IBEX_SET_H__ - -#include "ibex_SetNode.h" -#include "ibex_Sep.h" - -namespace ibex { - -/** - * \defgroup iset Set Interval - */ - -/** - * \ingroup iset - * \brief Set Interval - * - * See "Solving set-valued constraint satisfaction problem", Luc Jaulin, Computing. Volume 94, Issue 2, Page 297-311. - * - */ -class SetInterval { -public: - - /** - * \brief Creates a set interval from a simple box - * - * If x is the bounding box in argument, the set interval is either - * [empty, x] if inner==false or [x,x] if inner==false. - */ - SetInterval(const IntervalVector& bounding_box, double eps, bool inner=true); - - /** - * \brief Creates a copy of an existing setInterval - * - */ - SetInterval(const SetInterval& set); - - - /** - * \brief Loads a set from a data file. - * - * \see #save(). - */ - SetInterval(const char* filename); - - /* - * \brief Delete this - */ - ~SetInterval(); - - - /* - * \brief Replace the current root by a setbisect pointing on 2 leaves with the root status - */ - void cutRoot(); - - /** - * \brief i-Set Intersection - * - * In Jaulin's terminology, this operator is the "i-set extension of the intersection". - * - * If [x] designates this i-set and [y] the i-set in argument, then this will be replace by - * { x \cap y, x\in[x] and y\in[y] }. - */ - SetInterval& operator&=(const SetInterval& set); - - /** - * \brief i-Set Intersection - * - * Intersection of a setInterval with a box of interior value valin and exterior value valout. - * Computation is more efficient than create a setInterval contracted on the box, and then - * compute intersection of the two setInterval. - */ - SetInterval& interBox(const IntervalVector& box,NodeType valin,NodeType valout); - - /** - * \brief i-Set Intersection - * - * Union of a setInterval with a box of interior value valin and exterior value valout. - * Computation is more efficient than create a setInterval contracted on the box, and then - * compute intersection of the two setInterval. - */ - SetInterval& unionBox(const IntervalVector& box,NodeType valin,NodeType valout); - - /** - * \brief i-Set Union - * - * In Jaulin's terminology, this operator is the "i-set extension of the union". - * - * If [x] designates this i-set and [y] the i-set in argument, then this will be replace by - * { x \cup y, x\in[x] and y\in[y] }. - */ - SetInterval& operator|=(const SetInterval& set); - - /** - * \brief gather leaves that have the same value - */ - void gather(); - - /** - * \brief Check if fathers are initialized - */ - void checkFat(); - - /** - * \brief True if this i-set is empty - * - * \warning: an empty i-set is different from a i-set containing (and possibly only containing) the empty set. - */ - bool is_empty() const; - - /** - * \brief Contrat i-set w.r.t a separator sep - */ - void contract(Sep& sep); - - /** - * \brief Serialize the set and save it into a file - */ - void save(const char* filename); - - void visit_leaves(SetNode::leaf_func func) const; - - /** - * \brief Distance of the point "pt" wrt the set (if inside is true) - * of the complementary of the set (if inside is false). - */ - double dist(const Vector& pt, bool inside) const; - - - - - -protected: - - /** - * \brief Load the set from a file - */ - void load(const char* filename); - - friend std::ostream& operator<<(std::ostream& os, const SetInterval& set); - - SetNode* root; // NULL means no existing set (warning: different from empty set!) - - double eps; - - IntervalVector bounding_box; // not sure it is really necessary -}; - -std::ostream& operator<<(std::ostream& os, const SetInterval& set); - -} // namespace ibex - -#endif // __IBEX_SET_H__ From 763cbbfec354bcb76eb1efe6f50ba6520caf2757 Mon Sep 17 00:00:00 2001 From: domensta Date: Thu, 26 Feb 2015 11:25:10 +0100 Subject: [PATCH 27/32] Delete ibex_SetLeaf.cpp --- ibex_SetLeaf.cpp | 282 ----------------------------------------------- 1 file changed, 282 deletions(-) delete mode 100644 ibex_SetLeaf.cpp diff --git a/ibex_SetLeaf.cpp b/ibex_SetLeaf.cpp deleted file mode 100644 index 441da0259..000000000 --- a/ibex_SetLeaf.cpp +++ /dev/null @@ -1,282 +0,0 @@ -//============================================================================ -// I B E X -// File : ibex_SetLeaf.cpp -// Author : Gilles Chabert -// Copyright : Ecole des Mines de Nantes (France) -// License : See the LICENSE file -// Created : 13 juil. 2014 -//============================================================================ - -#include "ibex_SetLeaf.h" -#include "ibex_SetBisect.h" - -using namespace std; - -// =========== shortcuts ================== -#define IN __IBEX_IN__ -#define OUT __IBEX_OUT__ -#define UNK __IBEX_UNK__ -#define UNK_IN __IBEX_UNK_IN__ -#define UNK_OUT __IBEX_UNK_OUT__ -#define UNK_IN_OUT __IBEX_UNK_IN_OUT__ -#define IN_TMP __IBEX_IN_TMP__ -// ======================================== - -namespace ibex { - -SetLeaf::SetLeaf(NodeType status) : SetNode(status) { - if (status>UNK && status!=IN_TMP) { - ibex_error("cannot set multiple status to SetLeaf"); - } -} - -SetLeaf::SetLeaf(NodeType status,SetNode* father): SetNode(status,father) { - -} - -SetLeaf::~SetLeaf() { - -} - -bool SetLeaf::is_leaf() const { - return true; -} - - SetNode * SetLeaf::copy() const { - return new SetLeaf(this->status); -} - -void SetLeaf::inter(NodeType x_status) { - status = inte(status,x_status); -} - -void SetLeaf::_union(NodeType x) { - status = uni(status,x); -} - -void SetLeaf::oper(SetNode * node,bool op) { - if(node->is_leaf()) // if node is leaf, apply its value to leaves of this - { - if(op) - status = inte(status,node->status); - else - status = uni(status,node->status); - } - else{ // if this is leaf and node isn't - SetBisect * bfather = (SetBisect*) father; - if(bfather->left == this) - { - bfather->left = node->copy(); // copy the structure of node - bfather->left->father = father; - if(op && status != IN) - bfather->left->inter(status); // apply status to leaves - else if(!op && status!= OUT) - bfather->left->_union(status); - } - else - { - bfather->right = node->copy(); - bfather->right->father = father; - if(op && status != IN) - bfather->right->inter(status); - else if(!op && status!= OUT) - bfather->right->_union(status); - } - delete this; // delete this as it is now a setBisect and no more a leaf - - } -} - -void SetLeaf::operator_ir(const IntervalVector& box,const IntervalVector& subbox, NodeType val, bool op,double eps) { - if(box.is_subset(subbox)) - { - if(op && val != IN) - status = inte(status,val); - else if(!op && val!=OUT) - status = uni(status,val); - } - else if(box.max_diam()>eps) - { - SetBisect * bfather = (SetBisect*) father; - int var = box.extr_diam_index(false); // indice of the maximal diameter - double pt = box[var].mid(); - SetLeaf * lnode = new SetLeaf(status,NULL); // create future right node - SetLeaf * rnode = new SetLeaf(status,NULL); // create future left node - if(bfather->left == this) // this is father->left - { - bfather->left = new SetBisect(var,pt,lnode,rnode,father); // create SetBisect to replace leaf - lnode->father = bfather->left; // set fathers - rnode->father = bfather->left; - bfather->left->operator_ir(box,subbox,val,op,eps); - } - else // this is father->right - { - bfather->right = new SetBisect(var,pt,lnode,rnode,father); - lnode->father = bfather->right; - rnode->father = bfather->right; - bfather->right->operator_ir(box,subbox,val,op,eps); - } - delete this; // delete former father->left or father->right - } - else // if leaf reach minimum precision, compute partial intersection or union - { - if(op) - status = inte_in(status,val); - else - status = uni_in(status,val); - } -} - -// Uncomment this function and comment the one above to use fakeBranch method -/*void SetLeaf::operator_ir(const IntervalVector& box,const IntervalVector& subbox, NodeType val, bool op,bool is_left,double eps) { - if(box.is_subset(subbox)) - { - if(op) - status = inte(status,val); - else - status = uni(status,val); - } - else if(box.overlaps(subbox)) - { - if(box.max_diam()>eps) - { - SetBisect * bfather = (SetBisect*) father; - int var = box.extr_diam_index(false); // indice of the maximal diameter - double pt = box[var].mid(); - if(bfather->left == this) - { - bfather->left = new SetBisect(var,pt,NULL,NULL,father); - bfather->left->status = status; // create new set bissect with nodetype IN OUT or UNK, that it will transmit this value to its left and right - bfather->left->operator_ir(box,subbox,val,op,eps); - } - else - { - bfather->right = new SetBisect(var,pt,NULL,NULL,father); - bfather->right->status = status; // create new set bissect with nodetype IN OUT or UNK, that it will transmit this value to its left and right - bfather->right->operator_ir(box,subbox,val,op,eps); - } - delete this; - } - else - if(op) - status = inte_in(status,val); - else - status = uni_in(status,val); - } - else - return; - -}*/ - -void SetLeaf::operator_ir(const IntervalVector& box,const IntervalVector& subbox, NodeType valin,NodeType valout, bool op,double eps) { - if(box.is_subset(subbox)) - { - if(op && valin!=IN) - status = inte(status,valin); - else if(!op && valin!=OUT) - status = uni(status,valin); - } - else if(box.max_diam()>eps) - { - SetBisect * bfather = (SetBisect*) father; - int var = box.extr_diam_index(false); // indice of the maximal diameter - double pt = box[var].mid(); - SetLeaf * lnode = new SetLeaf(status,NULL); // create future right node - SetLeaf * rnode = new SetLeaf(status,NULL); // create future left node - if(bfather->left == this) // this is father->left - { - bfather->left = new SetBisect(var,pt,lnode,rnode,father); // create SetBisect to replace leaf - lnode->father = bfather->left; // set fathers - rnode->father = bfather->left; - bfather->left->operator_ir(box,subbox,valin,valout,op,eps); - } - else // this is father->right - { - bfather->right = new SetBisect(var,pt,lnode,rnode,father); - lnode->father = bfather->right; - rnode->father = bfather->right; - bfather->right->operator_ir(box,subbox,valin,valout,op,eps); - } - delete this; // delete former father->left or father->right - } - else // if leaf reach minimum precision, compute partial intersection or union - { - if(op) - status = inte_in(status,UNK); - else - status = uni_in(status,UNK); - } -} - -SetNode * SetLeaf::fakeLeaf(const IntervalVector& box,const IntervalVector& subbox,NodeType val,bool op, double eps) { - assert(!this->is_leaf()); - return NULL; -} - -void SetLeaf::cleave(const IntervalVector& box, Sep& sep,double eps) { - - IntervalVector box1(box); - IntervalVector box2(box); - sep.separate(box1,box2); - if(box1.is_disjoint(box2)) // if box are disjoint, contract on box1 and box2 - { - if(!box1.is_empty()) - this->operator_ir(box,box1,IN,true,eps); - if(!box2.is_empty()) - this->operator_ir(box,box2,OUT,true,eps); - - } - else if(box.max_diam()>eps) - { - SetBisect * bfather = (SetBisect*) father; - int var = box.extr_diam_index(false); // indice of the maximal diameter - double pt = box[var].mid(); - SetLeaf * lnode = new SetLeaf(status,NULL); // create future right node - SetLeaf * rnode = new SetLeaf(status,NULL); // create future left node - if(bfather->left == this) // this is father->left - { - bfather->left = new SetBisect(var,pt,lnode,rnode,father); // create SetBisect to replace leaf - lnode->father = bfather->left; // set fathers - rnode->father = bfather->left; - bfather->left->cleave(box,sep,eps); - } - else // this is father->right - { - bfather->right = new SetBisect(var,pt,lnode,rnode,father); - lnode->father = bfather->right; - rnode->father = bfather->right; - bfather->right->cleave(box,sep,eps); - } - delete this; // delete former father->left or father->right - } - else - status = inte(status,UNK); - -} - -void SetLeaf::gather(bool go_up) { - return; // nothing to do -} - -void SetLeaf::cutDeadBranch() { - return; // nothing to do -} -void SetLeaf::checkFat() { - if (father == NULL) - cout<<"issue, invalid father"< Date: Thu, 26 Feb 2015 11:25:23 +0100 Subject: [PATCH 28/32] Delete ibex_SetLeaf.h --- ibex_SetLeaf.h | 90 -------------------------------------------------- 1 file changed, 90 deletions(-) delete mode 100644 ibex_SetLeaf.h diff --git a/ibex_SetLeaf.h b/ibex_SetLeaf.h deleted file mode 100644 index b5007dc62..000000000 --- a/ibex_SetLeaf.h +++ /dev/null @@ -1,90 +0,0 @@ -//============================================================================ -// I B E X -// File : ibex_SetLeaf.h -// Author : Gilles Chabert -// Copyright : Ecole des Mines de Nantes (France) -// License : See the LICENSE file -// Created : 13 juil. 2014 -//============================================================================ - -#ifndef __IBEX_SET_LEAF_H__ -#define __IBEX_SET_LEAF_H__ - -#include "ibex_SetNode.h" - -namespace ibex { - -/** - * \ingroup iset - * \brief Leaf node (i-set representation) - */ -class SetLeaf : public SetNode { - -public: - /** - * \brief Creates a leaf of the given status - */ - SetLeaf(NodeType status); - - SetLeaf(NodeType status,SetNode* father); - - /** - * \brief Delete this. - */ - virtual ~SetLeaf(); - - /** \see SetNode */ - /** \see SetNode */ - virtual bool is_leaf() const; - - /** \see SetNode */ - virtual SetNode * copy() const; - - /** \see SetNode */ - virtual void inter(NodeType x_status); - - /** \see SetNode */ - virtual void _union(NodeType x); - - /** \see SetNode */ - virtual void oper(SetNode * other,bool op); - - /** \see SetNode */ - virtual void operator_ir(const IntervalVector& box,const IntervalVector& nodebox, NodeType val,bool op, double eps); - - /** \see SetNode */ - virtual void operator_ir(const IntervalVector& box,const IntervalVector& subbox, NodeType valin,NodeType valout, bool op,double eps); - - /** \see SetNode */ - virtual SetNode * fakeLeaf(const IntervalVector& box,const IntervalVector& subbox,NodeType val,bool op, double eps); - - /** \see SetNode */ - virtual void cleave(const IntervalVector& box, Sep& sep, double eps); - - /** \see SetNode */ - virtual void gather(bool go_up); - - /** \see SetNode */ - virtual void cutDeadBranch(); - - /** \see SetNode */ - virtual void checkFat(); - - /** \see SetNode */ - virtual void visit_leaves(leaf_func func, const IntervalVector& nodebox) const; - - /** \see SetNode */ - virtual void print(std::ostream& os, const IntervalVector& nodebox, int shift) const; - - /** \see SetNode */ - virtual void setFathers(); - - -private: - SetLeaf(const SetLeaf&); // forbidden - -}; - -} // namespace ibex - -#endif // __IBEX_SET_LEAF_H__ From cbe6ae627b94c166685b95bafff68b9234c516fe Mon Sep 17 00:00:00 2001 From: domensta Date: Thu, 26 Feb 2015 11:25:33 +0100 Subject: [PATCH 29/32] Delete ibex_SetNode.cpp --- ibex_SetNode.cpp | 56 ------------------------------------------------ 1 file changed, 56 deletions(-) delete mode 100644 ibex_SetNode.cpp diff --git a/ibex_SetNode.cpp b/ibex_SetNode.cpp deleted file mode 100644 index 35824f5f9..000000000 --- a/ibex_SetNode.cpp +++ /dev/null @@ -1,56 +0,0 @@ -//============================================================================ -// I B E X -// File : ibex_SetNode.cpp -// Author : Gilles Chabert -// Copyright : Ecole des Mines de Nantes (France) -// License : See the LICENSE file -// Created : 13 juil. 2014 -//============================================================================ - -#include "ibex_SetNode.h" -#include "ibex_SetLeaf.h" -#include "ibex_SetBisect.h" - #include - -using namespace std; - -// =========== shortcuts ================== -#define IN __IBEX_IN__ -#define OUT __IBEX_OUT__ -#define UNK __IBEX_UNK__ -#define UNK_IN __IBEX_UNK_IN__ -#define UNK_OUT __IBEX_UNK_OUT__ -#define UNK_IN_OUT __IBEX_UNK_IN_OUT__ -#define IN_TMP __IBEX_IN_TMP__ -// ======================================== - -namespace ibex { - - -char to_string(const NodeType& status) { - switch(status) { - case IN : return 'Y'; break; - case OUT : return 'N'; break; - default : return '?'; - } -} - -SetNode::SetNode(NodeType status) : status(status), father(NULL) { - -} - -SetNode::SetNode(NodeType status, SetNode *father): status(status), father(father) { - -} - -SetNode::~SetNode() { - -} - -/*void SetNode::inter(const SetNode* other) -{ - -}*/ - - -} // namespace ibex From fecf220f946499330930e9e7c2621dd9e5e56dd7 Mon Sep 17 00:00:00 2001 From: domensta Date: Thu, 26 Feb 2015 11:25:53 +0100 Subject: [PATCH 30/32] Delete ibex_SetNode.h --- ibex_SetNode.h | 159 ------------------------------------------------- 1 file changed, 159 deletions(-) delete mode 100644 ibex_SetNode.h diff --git a/ibex_SetNode.h b/ibex_SetNode.h deleted file mode 100644 index a6a289c83..000000000 --- a/ibex_SetNode.h +++ /dev/null @@ -1,159 +0,0 @@ -//============================================================================ -// I B E X -// File : ibex_SetNode.h -// Author : Gilles Chabert -// Copyright : Ecole des Mines de Nantes (France) -// License : See the LICENSE file -// Created : 13 juil. 2014 -//============================================================================ - -#ifndef __IBEX_SET_NODE_H__ -#define __IBEX_SET_NODE_H__ - -#include "ibex_IntervalVector.h" -#include "ibex_Sep.h" -#include "ibex_NodeType.h" -#include "ibex_BoolInterval.h" - -namespace ibex { - -/** - * \ingroup iset - * \brief Exception thrown by sync function. - * - * Thrown when the i-set is empty (<=> no set exists). - */ -class NoSet { - -}; -/** - * \ingroup iset - * \brief Exception thrown by sync function. - * - * use to compute regular cutting of a interval - */ -class vcut{ - int var; - double pt; -}; - -/** - * \brief Set node. - */ -class SetNode { - -public: - /** - * \brief Callback for "visit_leaves" - */ - typedef void (*leaf_func) (const IntervalVector&, BoolInterval); - - /** - * \brief Creates a node of given status - */ - SetNode(NodeType status); - - /** - * \brief Creates a node of given status and father - */ - SetNode(NodeType status,SetNode *father); - - - /** - * \brief Delete this. - */ - virtual ~SetNode(); - - /** - * \brief True iff this node is a leaf. - */ - virtual bool is_leaf() const=0; - - /** - * \brief Return a copy of the node. - */ - virtual SetNode * copy() const=0; - - - /** - * \brief Intersection or Union between a box of NodeType val and a regular setInterval. - * Box may not respect the regularity of the regular setInterval. - * The part of the set that intersect nodebox only is modify. - */ - virtual void operator_ir(const IntervalVector& box,const IntervalVector& nodebox, NodeType val, bool op, double eps)=0; - - /** - * \brief Call by operator_ir, create a subtree from a leaf with "fake leves" that are setbisect with left and right set to null - * should avoid to create leaf and eventually destruct it if it need to be cut i.e replace by a setbisect - * method abandonned, oddly slower than creating leaves and replace them by setbisect. - */ - virtual SetNode * fakeLeaf(const IntervalVector& box,const IntervalVector& subbox,NodeType val,bool op, double eps)=0; - - /** - * \brief Overloaded function, apply valout to the set outside of the box and valin to the inside, thus modify the whole set. - */ - virtual void operator_ir(const IntervalVector& box,const IntervalVector& subbox, NodeType valin,NodeType valout, bool op,double eps)=0; - - /** - * \brief Intersection between two setNode. - */ - virtual void oper(SetNode* other,bool op)=0; - - /** - * \brief Intersection between setnode and a status. - */ - virtual void inter(NodeType x_status)=0; - - /** - * \brief Union between setnode and a status. - */ - virtual void _union(NodeType x)=0; - - /** - * \brief Change value of branch if right and left got the same value IN, OUT or UNK. - */ - virtual void gather(bool go_up)=0; - /** - * \brief Delete the branch if left and right got the same value IN, OUT or UNK. - */ - virtual void cutDeadBranch()=0; - - /** - * \brief Check if fathers are initialized. - */ - virtual void checkFat()=0; - - /** - * \brief Contrat i-set w.r.t separator sep, split leaves until boxin and boxout returned by sep are disjoints, - * and then call operator_ir to contract on them - */ - virtual void cleave(const IntervalVector& box, Sep& sep,double eps)=0; - - /** - * \brief Visit the leaves of a tree with a callback "func" - */ - virtual void visit_leaves(leaf_func func, const IntervalVector& nodebox) const=0; - - /** - * \brief Display the structure on output stream "os" - */ - virtual void print(std::ostream& os, const IntervalVector& nodebox, int shift) const=0; - - /** - * \brief Set fathers of the nodes - */ - virtual void setFathers()=0; - - - - /** - * \brief The status of the node - */ - NodeType status; - SetNode * father; -}; - - -} // namespace ibex - -#endif // __IBEX_SET_NODE_H__ From f16b2f1f788b17dcfc71f9cc751049981e50f477 Mon Sep 17 00:00:00 2001 From: domensta Date: Fri, 6 Mar 2015 08:45:52 +0100 Subject: [PATCH 31/32] Update ibex_SetLeaf.cpp --- src/set/ibex_SetLeaf.cpp | 72 ++++++++++++++++++++++++++++++++++------ 1 file changed, 62 insertions(+), 10 deletions(-) diff --git a/src/set/ibex_SetLeaf.cpp b/src/set/ibex_SetLeaf.cpp index 441da0259..a424c6b73 100644 --- a/src/set/ibex_SetLeaf.cpp +++ b/src/set/ibex_SetLeaf.cpp @@ -213,19 +213,15 @@ SetNode * SetLeaf::fakeLeaf(const IntervalVector& box,const IntervalVector& subb return NULL; } -void SetLeaf::cleave(const IntervalVector& box, Sep& sep,double eps) { +void SetLeaf::cleave(const IntervalVector& box, Sep& sep, const double eps) { - IntervalVector box1(box); + /*IntervalVector box1(box); IntervalVector box2(box); sep.separate(box1,box2); - if(box1.is_disjoint(box2)) // if box are disjoint, contract on box1 and box2 - { - if(!box1.is_empty()) - this->operator_ir(box,box1,IN,true,eps); - if(!box2.is_empty()) - this->operator_ir(box,box2,OUT,true,eps); - - } + if(box1.is_empty()) + this->inter(OUT); + else if(box2.is_empty()) + this->_union(IN); else if(box.max_diam()>eps) { SetBisect * bfather = (SetBisect*) father; @@ -249,8 +245,59 @@ void SetLeaf::cleave(const IntervalVector& box, Sep& sep,double eps) { } delete this; // delete former father->left or father->right } + else + status = inte(status,UNK);*/ + + assert(status == UNK); + IntervalVector box1(box); + IntervalVector box2(box); + sep.separate(box1,box2); + if(box1.is_empty()) // all the box can be set to OUT + { + this->inter(OUT); + return; + } + else if(box2.is_empty())// all the box can be set to IN + { + this->_union(IN); + return; + } + else if(box.max_diam()>eps) + { + SetBisect * bfather = (SetBisect*) father; + IntervalVector* restout; + int nout = 0; + if(box1!=box) + nout=box.diff(box1,restout); + IntervalVector* restin; + int nin = 0; + if(box2!=box) + nin=box.diff(box2,restin); + + if(bfather->left == this) // this is father->left + { + for(int i = 0;ileft->operator_ir(box,restout[i],OUT,true,eps); // add in box + for(int i = 0;ileft->operator_ir(box,restin[i],IN,false,eps); // add out box + bfather->left->gatherTo(false,bfather->left); + if(!bfather->left->is_leaf()) + bfather->left->cleave(box,sep,eps); + } + else // this is father->right + { + for(int i = 0;iright->operator_ir(box,restout[i],OUT,true,eps); // add in box + for(int i = 0;iright->operator_ir(box,restin[i],IN,false,eps); // add out box + bfather->right->gatherTo(false,bfather->right); + if(!bfather->right->is_leaf()) + bfather->right->cleave(box,sep,eps); + } + } else status = inte(status,UNK); + } @@ -258,6 +305,10 @@ void SetLeaf::gather(bool go_up) { return; // nothing to do } +void SetLeaf::gatherTo(bool go_up,SetNode * branch) { + return; // nothing to do +} + void SetLeaf::cutDeadBranch() { return; // nothing to do } @@ -280,3 +331,4 @@ void SetLeaf::setFathers() { return; // nothing to do here } } // namespace ibex + From eecb92332b8520e56d056fabe215550e1c54bb38 Mon Sep 17 00:00:00 2001 From: domensta Date: Fri, 6 Mar 2015 08:46:23 +0100 Subject: [PATCH 32/32] Update ibex_SetBisect.cpp --- src/set/ibex_SetBisect.cpp | 66 ++++++++++++++++++++++++++++++++------ 1 file changed, 57 insertions(+), 9 deletions(-) diff --git a/src/set/ibex_SetBisect.cpp b/src/set/ibex_SetBisect.cpp index 01e95bcee..858147302 100644 --- a/src/set/ibex_SetBisect.cpp +++ b/src/set/ibex_SetBisect.cpp @@ -205,24 +205,57 @@ SetNode * SetBisect::fakeLeaf(const IntervalVector& box,const IntervalVector& su else return new SetLeaf(status); } -void SetBisect::cleave(const IntervalVector& box, Sep& sep, double eps) { +void SetBisect::cleave(const IntervalVector& box, Sep& sep, const double eps) { - IntervalVector box1(box); + /*IntervalVector box1(box); IntervalVector box2(box); sep.separate(box1,box2); - if(box1.is_disjoint(box2)) // in and out are disjoint, can contract on box1 and box2 - { - if(!box1.is_empty()) - this->operator_ir(box,box1,IN,true,eps); - if(!box2.is_empty()) - this->operator_ir(box,box2,OUT,true,eps); - } + if(box1.is_empty()) + this->inter(OUT); + else if(box2.is_empty()) + this->_union(IN); else // continu until box1 and box2 are disjoint { left->cleave(left_box(box),sep,eps); right->cleave(right_box(box),sep,eps); + }*/ + + status = UNK_IN_OUT; + IntervalVector box1(box); + IntervalVector box2(box); + + sep.separate(box1,box2); + if(box1.is_empty()) // all the box can be set to OUT + { + this->inter(OUT); + } + else if(box2.is_empty())// all the box can be set to IN + { + this->_union(IN); + } + else + { + + IntervalVector* restout; + int n=0; + if(box1!=box) + box.diff(box1,restout); + for(int i = 0;ioperator_ir(box,restout[i],OUT,true,eps); // add in box + IntervalVector* restin; + n = 0; + if(box2!= box) + n=box.diff(box2,restin); + for(int i = 0;ioperator_ir(box,restin[i],IN,false,eps); // add out box + this->gatherTo(false,this); + if(!left->is_leaf() || left->status == UNK )//&& left_box(box).max_diam()>eps) + left->cleave(left_box(box),sep,eps); + if(!right->is_leaf() || right->status == UNK )//&& right_box(box).max_diam()>eps) + right->cleave(right_box(box),sep,eps); } + } void SetBisect::gather(bool go_up) { if(((left->is_leaf()&&right->is_leaf()) || go_up)&&left->status==right->status) // leaves are reached, or climbing up the tree toward the root @@ -238,6 +271,20 @@ void SetBisect::gather(bool go_up) { } } +void SetBisect::gatherTo(bool go_up, SetNode * branch) { + if(((left->is_leaf()&&right->is_leaf()) || go_up)&&left->status==right->status) // leaves are reached, or climbing up the tree toward the root + { + status = left->status; // this bisect get a leaf status IN OUT or UNK + if(father != branch) // check if father is not the root of SetInterval + father->gather(true); + } + else if(!go_up) // go down the tree to reach the leaves + { + left->gather(false); + right->gather(false); + } +} + void SetBisect::cutDeadBranch() { if(left->status ==right->status && left->status < 3) // if status of left and right are equal and has got a leaf status, meaning all leaves have the same status { @@ -298,3 +345,4 @@ IntervalVector SetBisect::right_box(const IntervalVector& nodebox) const { } // namespace ibex +