This microsite is associated to the paper
A new interval arithmetic to generate the complementary of contractors
Contractor algebra is used to characterize a set defined as a composition of sets defined by inequalities. It mainly uses interval methods combined with constraint propagation.
This algebra includes the classical operations we have for sets such as the intersection, the union and the inversion. Now, it does not include the complement operator.
The reason for this is probably related to the interval arithmetic itself.
In this work, we show that it we change the arithmetic used for intervals adding a single flag, similar to not a number, we are able to include easily the complement in the algebra of contractors
from codac import * from vibes import * X0=IntervalVector([[-10,10],[-10,10]]) f = Function("x1","x2","x2+sqrt(x1+x2)") S=SepFwdBwd(f,sqr(Interval(1,2))) vibes.beginDrawing() SIVIA(X0,S,0.01)
from vibes import * from mybox import * def sqrti(x,ix): y=sqrt(x) iy=(x.lb<0)|ix return y,iy def sqrtirev(x,ix,y,iy): r,ir=Interval(1,0),False if y.is_empty(): return r,ir r=sqr(y) if (iy==True) : r,ir=r|Interval(-oo,0),True return r&x,ir&ix def addi(x,ix,y,iy): z=x+y iz=ix|iy return z,iz def addirev(z,iz,x,ix,y,iy): if not(iz): x=x&(z-y) y=y&(z-x) return x,ix,y,iy def ininterval(x,ix,y,outer): if outer: x=x&y; ix=False else: xa=x&Interval(-oo,y.lb) xb=x&Interval(y.ub,oo) x=xa|xb ix=ix&True return x,ix def S1(x,y,outer): #y+sqrt(x) in [1,2] ix,iy=False,False a,ia=sqrti(x,ix) z,iz=addi(a,ia,y,iy) z,iz=ininterval(z,iz,Interval(1,2),outer) a,ia,y,iy=addirev(z,iz,a,ia,y,iy) x,ix=sqrtirev(x,ix,a,ia) return x,y def S(x,y,outer): #y+sqrt(x+y) in [1,2] Y=Interval(1,2) ix,iy=False,False b,ib=addi(x,ix,y,iy) a,ia=sqrti(b,ib) z,iz=addi(a,ia,y,iy) z,iz=ininterval(z,iz,Y,outer) a,ia,y,iy=addirev(z,iz,a,ia,y,iy) b,ib=sqrtirev(b,ib,a,ia) x,ix,y,iy=addirev(b,ib,x,ix,y,iy) return x,y def sivia(X): if (X.width()<0.1): return vibes.drawBox(X.x.lb, X.x.ub,X.y.lb, X.y.ub, 'blue[cyan]') X.x,X.y = S(X.x,X.y,True) vibes.drawBox(X.x.lb, X.x.ub,X.y.lb, X.y.ub, 'red[magenta]') X.x,X.y = S(X.x,X.y,False) vibes.drawBox(X.x.lb, X.x.ub,X.y.lb, X.y.ub, '[yellow]') sivia(X.left()) sivia(X.right()) vibes.beginDrawing() vibes.newFigure('Result') vibes.setFigureProperties({'x': 0, 'y': 0, 'width': 1600, 'height': 1000}) X=Box(Interval(-10,10),Interval(-10,10)) sivia(X) vibes.endDrawing()
import math from myinterval import * class Box: def __init__(X,a,b): X.x,X.y = a,b def __repr__(X): return "[%f, %f] X [%f, %f]"%(X.x.lb, X.x.ub,X.y.lb, X.y.ub) def width(X): if X.x.is_empty() | X.y.is_empty(): return -oo else: return max(X.x.width(),X.y.width()) def left(X): if X.x.width()>X.y.width(): return Box(X.x.left(),X.y) else: return Box(X.x,X.y.left()) def right(X): if X.x.width()>X.y.width(): return Box(X.x.right(),X.y) else: return Box(X.x,X.y.right()) if __name__ == '__main__': a = Interval(2,4) b = Interval(4,8) X=Box(a,b) print ("X = ",X) print ("X.left() = ",X.left()) print ("X.right() = ",X.right())
import math oo= float('inf') nan=float('nan') class Interval: def __init__(x,a,b): if a>b: x.lb,x.ub = nan,nan else: x.lb,x.ub = a,b def is_empty(x): return math.isnan(x.lb) def __add__(x,y): return Interval(x.lb+y.lb, x.ub+y.ub) def __sub__(x, y): return Interval(x.lb-y.ub, x.ub-y.lb) def __mul__(x, y): L=[x.lb*y.lb,x.lb*y.ub,x.ub*y.lb,x.ub*y.ub] return Interval(min(L),max(L)) def __rmul__(x, y): return x*Interval(y,y) def __contains__(x, a): return (x.lb<=a<=x.ub) def __truediv__(x, y): if 0 in y: return Interval(-oo, oo) else: return x*Interval(1./y.ub, 1./y.lb) def __and__(x,y): if (x.is_empty() or y.is_empty()): return Interval(1,0) else: return Interval(max(x.lb,y.lb),min(x.ub,y.ub)) def __or__(x,y): if x.is_empty(): return y elif y.is_empty(): return x else: return Interval(min(x.lb,y.lb),max(x.ub,y.ub)) def __repr__(x): return '[{}, {}]'.format(x.lb, x.ub) def width(x): return x.ub-x.lb def left(x): return Interval(x.lb,0.5*(x.lb+x.ub)) def right(x): return Interval(0.5*(x.lb+x.ub),x.ub) def sqr(x): L=[x.lb**2,x.ub**2] if 0 in x: return Interval(0,max(L)) else: return Interval(min(L),max(L)) def sqrt(x): x=x&Interval(0,oo) return Interval(math.sqrt(x.lb),math.sqrt(x.ub)) def mini(x,y): return Interval(min(x.lb,y.lb),min(x.ub,y.ub)) def maxi(x,y): return Interval(max(x.lb,y.lb),max(x.ub,y.ub)) def exp(x): return Interval(math.exp(x.lb), math.exp(x.ub)) def log(x): if x.ub<=0: return Interval(1,0) elif 0 in x: return Interval(-oo,math.log(x.ub)) else: return Interval(math.log(x.lb), math.log(x.ub)) def subset(x,y): if x.is_empty(): return True else: return (x.lb in y) and (x.ub in y) def disjoint(x,y): return (x&y).is_empty() if __name__ == '__main__': x = Interval(-2, 2) print("x = ",x) print("sqr(x)+2*x - exp(x) = ",sqr(x)+2*x - exp(x)) print("sqrt(Interval(4,9)) = ",sqrt(Interval(4,9))) print("sqrt(Interval(-9,-3)) = ",sqrt(Interval(-9,-3))) print("sqrt(Interval(-9,4)) = ",sqrt(Interval(-9,4))) x = Interval(-1, 3) print("x = ",x) y = Interval(3, 4) print("y = ",y) print("subset(x,y) = ",subset(x,y)) print("disjoint(x,y) = ",disjoint(x,y))