Vous avez reçu un message "Your GitLab account has been locked ..." ? Pas d'inquiétude : lisez cet article https://docs.gricad-pages.univ-grenoble-alpes.fr/help/unlock/

Commit 1339e315 authored by Akshay Mambakam's avatar Akshay Mambakam
Browse files

[CHAR_CLASSIFY] All the code needed for experimentation.

parent d9832aad
Pipeline #42875 canceled with stages
......@@ -75,6 +75,7 @@ from ParetoLib.Geometry.Segment import Segment
from ParetoLib.Geometry.Point import greater, greater_equal, less, less_equal, equal, add, subtract, div, mult, distance, dim, \
incomparables, select, subt, int_to_bin_tuple, minimum, maximum#, r
from ParetoLib._py3k import red
from ParetoLib.Search.CommonSearch import EPS
class Rectangle(object):
......@@ -101,13 +102,20 @@ class Rectangle(object):
# Volume (self.vol) is calculated on demand the first time is accessed, and cached afterwards.
# Using 'None' for indicating that attribute vol is outdated (e.g., user changes min_corner or max_corners).
self.vol = None
self.nInf = None
self.snInf = None
self.sigVol = None
# Vertices are also cached.
self.vertx = None
self.privilege = 1
assert greater_equal(self.max_corner, self.min_corner) or incomparables(self.min_corner, self.max_corner)
def reset(self):
self.vol = None
self.nInf = None
self.snInf = None
self.sigVol = None
self.vertx = None
def __setattr__(self, name, value):
......@@ -330,6 +338,112 @@ class Rectangle(object):
self.vol = self._volume()
return self.vol
def adjustedVolume(self):
return self.volume() / (1 + self.privilege)
def adjustedNormInf(self):
return self.normInf() / (1 + self.privilege)
def _normInf(self):
# type: (Rectangle) -> float
diagonal_length = self.diag_vector()
normIf = 0
for i in diagonal_length:
if normIf < abs(i):
normIf = abs(i)
return normIf
def significantVolume(self):
# type: (Rectangle) -> float
"""
Volume of the Rectangle.
Args:
self (Rectangle): The Rectangle.
Returns:
float: Volume of the Rectangle.
Example:
>>> x = (0,0,0)
>>> y = (2,2,2)
>>> r = Rectangle(x,y)
>>> r.volume()
>>> 8.0
"""
# Recalculate volume if it is outdated
if self.sigVol is None:
self.sigVol = self._significantVolume()
return self.sigVol
def _significantVolume(self):
# type: (Rectangle) -> float
diagonal_length = self.diag_vector()
sigVol = 1
insigVol = 1
for i in diagonal_length:
if abs(i) > EPS:
sigVol *= abs(i)
else:
insigVol *= abs(i)
return sigVol
def _scaledNormInf(self, xspace):
diagonal_length = self.diag_vector()
scale_list = xspace.diag_vector()
snormIf = 0
for i in range(len(diagonal_length)):
scaled_dim = diagonal_length[i] / scale_list[i]
if snormIf < abs(scaled_dim):
snormIf = abs(scaled_dim)
return snormIf
def scaledNormInf(self, xspace):
# type: (Rectangle) -> float
"""
Volume of the Rectangle.
Args:
self (Rectangle): The Rectangle.
Returns:
float: Volume of the Rectangle.
Example:
>>> x = (0,0,0)
>>> y = (2,2,2)
>>> r = Rectangle(x,y)
>>> r.scaledNormInf()
>>> 1
"""
# Recalculate volume if it is outdated
if self.snInf is None:
self.snInf = self._scaledNormInf(xspace)
return self.snInf
def normInf(self):
# type: (Rectangle) -> float
"""
Volume of the Rectangle.
Args:
self (Rectangle): The Rectangle.
Returns:
float: Volume of the Rectangle.
Example:
>>> x = (0,0,0)
>>> y = (2,2,2)
>>> r = Rectangle(x,y)
>>> r.volume()
>>> 8.0
"""
# Recalculate volume if it is outdated
if self.nInf is None:
self.nInf = self._normInf()
return self.nInf
def num_vertices(self):
# type: (Rectangle) -> int
"""
......@@ -1133,7 +1247,7 @@ class Rectangle(object):
alpha=opacity
)
def plot_3D(self, c='red', xaxe=0, yaxe=1, zaxe=2, opacity=1.0):
def plot_3D(self, c='red', xaxe=0, yaxe=1, zaxe=2, opacity=1.0, clipBox=None):
# type: (Rectangle, str, int, int, int, float) -> Poly3DCollection
"""
Function that creates a graphical representation of the rectangle in 3D.
......@@ -1154,6 +1268,24 @@ class Rectangle(object):
minc = (self.min_corner[xaxe], self.min_corner[yaxe], self.min_corner[zaxe],)
maxc = (self.max_corner[xaxe], self.max_corner[yaxe], self.max_corner[zaxe],)
if not (clipBox is None):
clipminc = (clipBox.min_corner[xaxe], clipBox.min_corner[yaxe], clipBox.min_corner[zaxe],)
clipmaxc = (clipBox.max_corner[xaxe], clipBox.max_corner[yaxe], clipBox.max_corner[zaxe],)
a = [self.min_corner[xaxe], self.min_corner[yaxe], self.min_corner[zaxe]]
b = [self.max_corner[xaxe], self.max_corner[yaxe], self.max_corner[zaxe]]
for i in range(len(a)):
if a[i] < clipminc[i]:
a[i] = clipminc[i]
elif a[i] > clipmaxc[i]:
a[i] = clipmaxc[i]
for i in range(len(b)):
if b[i] < clipminc[i]:
b[i] = clipminc[i]
elif b[i] > clipmaxc[i]:
b[i] = clipmaxc[i]
minc = (a[0], a[1], a[2],)
maxc = (b[0], b[1], b[2],)
rect = Rectangle(minc, maxc)
# sorted(vertices) =
......@@ -1340,6 +1472,88 @@ def incomp(d, opt=True):
return incomp_expanded(d)
'''
NOTE:
0 -> a
1 -> b
2 -> c
3 -> (a+b)
4 -> (b+c)
5 -> (a+b+c)
'''
def incomp_segmentNegRemoveDown(d):
if d > 0:
return incomp_segmentNegRemoveDownE(d)
else:
return []
def incomp_segmentNegRemoveDownE(d):
if(d == 0):
return []
else:
elist = ["0" + i for i in incomp_segmentNegRemoveDownE(d-1)]
elist += ["1" + ('3')*(d-1)]
return elist
def incomp_segmentNegRemoveUp(d):
if d > 0:
return incomp_segmentNegRemoveUpE(d)
else:
return []
def incomp_segmentNegRemoveUpE(d):
if(d == 0):
return []
else:
elist = ["1" + i for i in incomp_segmentNegRemoveUpE(d-1)]
elist += ["0" + ('3')*(d-1)]
return elist
def incomp_segmentpos(d):
if d > 0:
return incomp_segmentposE(d)
else:
return []
def incomp_segmentposE(d):
if (d == 0):
return []
else:
elist1 = ["1" + i for i in incomp_segmentposE(d-1)]
elistDown = ["0" + ('5')*(d-1)]
elistUp = ["2" + ('5')*(d-1)]
return elistDown+elistUp+elist1
def incomp_segment(d):
if d > 0:
return incomp_segmentE(d)
else:
return []
def incomp_segmentE(d):
if (d == 1):
return []
else:
elist = ["0" + i for i in incomp_segmentC(d-1)] + ["2" + i for i in incomp_segmentA(d-1)]
elist += ["1" + i for i in incomp_segmentE(d-1)]
return elist
def incomp_segmentA(d):
if (d == 1):
return ["0"]
else:
alist = ["0" + ('5')*(d-1)]
alist += ["4" + i for i in incomp_segmentA(d-1)]
return alist
def incomp_segmentC(d):
if (d == 1):
return ["2"]
else:
clist = ["2" + ('5')*(d-1)]
clist += ["3" + i for i in incomp_segmentC(d-1)]
return clist
def incomp_expanded(d):
# type: (int) -> list
alphaprime = (range(2),) * d
......@@ -1381,6 +1595,28 @@ def E(d):
#################
# Cube generators
#################
def intercpoint(i, alphai, yspace, xspace):
# type: (int, int, tuple, Rectangle) -> Rectangle
result_xspace = Rectangle(xspace.min_corner, xspace.max_corner)
if alphai == '0':
# result_xspace.min_corner = subt(i, xspace.min_corner, xspace.min_corner)
result_xspace.max_corner = subt(i, xspace.max_corner, yspace.min_corner)
elif alphai == '1':
result_xspace.min_corner = subt(i, xspace.min_corner, yspace.min_corner)
result_xspace.max_corner = subt(i, xspace.max_corner, yspace.max_corner)
elif alphai == '2':
result_xspace.min_corner = subt(i, xspace.min_corner, yspace.max_corner)
# result_xspace.max_corner = subt(i, xspace.max_corner, xspace.max_corner)
elif alphai == '3':
# result_xspace.min_corner = subt(i, xspace.min_corner, xspace.min_corner)
result_xspace.max_corner = subt(i, xspace.max_corner, yspace.max_corner)
elif alphai == '4':
result_xspace.min_corner = subt(i, xspace.min_corner, yspace.min_corner)
# result_xspace.max_corner = subt(i, xspace.max_corner, xspace.max_corner)
# elif alpha == '5': # Nothing to be done here.
# result_xspace.min_corner = subt(i, xspace.min_corner, xspace.min_corner)
# result_xspace.max_corner = subt(i, xspace.max_corner, xspace.max_corner)
return result_xspace
def cpoint(i, alphai, ypoint, xspace):
# type: (int, int, tuple, Rectangle) -> Rectangle
......@@ -1393,6 +1629,11 @@ def cpoint(i, alphai, ypoint, xspace):
result_xspace.min_corner = subt(i, xspace.min_corner, ypoint)
return result_xspace
def intercrect(i, alphai, yrectangle, xspace):
# type: (int, int, Rectangle, Rectangle) -> Rectangle
result_xspace = Rectangle(xspace.min_corner, xspace.max_corner)
result_xspace = intercpoint(i, alphai, yrectangle, xspace)
return result_xspace
def crect(i, alphai, yrectangle, xspace):
# type: (int, int, Rectangle, Rectangle) -> Rectangle
......@@ -1417,6 +1658,22 @@ def bpoint(alpha, ypoint, xspace):
temp = cpoint(i, alphai, ypoint, temp)
return temp
def interbrect(alpha, yrectangle, xspace):
# type: (tuple, Rectangle, Rectangle) -> Rectangle
assert (dim(yrectangle.min_corner) == dim(yrectangle.max_corner)), \
'xrectangle.min_corner and xrectangle.max_corner do not share the same dimension'
assert (dim(xspace.min_corner) == dim(xspace.max_corner)), \
'xspace.min_corner and xspace.max_corner do not share the same dimension'
assert (dim(alpha) == dim(yrectangle.min_corner)), \
'alpha and xrectangle.min_corner do not share the same dimension'
assert (dim(xspace.min_corner) == dim(yrectangle.min_corner)), \
'xspace.min_corner and xrectangle.min_corner do not share the same dimension'
# assert (dim(xspace.max_corner) == dim(yrectangle.max_corner)), \
# 'xspace.max_corner and yrectangle.max_corner do not share the same dimension'
temp = Rectangle(xspace.min_corner, xspace.max_corner)
for i, alphai in enumerate(alpha):
temp = intercrect(i, alphai, yrectangle, temp)
return temp
def brect(alpha, yrectangle, xspace):
# type: (tuple, Rectangle, Rectangle) -> Rectangle
......@@ -1435,6 +1692,17 @@ def brect(alpha, yrectangle, xspace):
temp = crect(i, alphai, yrectangle, temp)
return temp
def interirect(alphaincomp, yrectangle, xspace):
# type: (list, Rectangle, Rectangle) -> list
assert (dim(yrectangle.min_corner) == dim(yrectangle.max_corner)), \
'xrectangle.min_corner and xrectangle.max_corner do not share the same dimension'
assert (dim(xspace.min_corner) == dim(xspace.max_corner)), \
'xspace.min_corner and xspace.max_corner do not share the same dimension'
# assert (dim(alphaincomp_list) == dim(yrectangle.min_corner)), \
# 'alphaincomp_list and yrectangle.min_corner do not share the same dimension'
# assert (dim(alphaincomp_list) == dim(yrectangle.max_corner)), \
# 'alphaincomp_list and yrectangle.max_corner do not share the same dimension'
return [interbrect(alphaincomp_i, yrectangle, xspace) for alphaincomp_i in alphaincomp]
def irect(alphaincomp, yrectangle, xspace):
# type: (list, Rectangle, Rectangle) -> list
......
......@@ -18,7 +18,7 @@ Pareto point is located.
import math
from ParetoLib.Geometry.Point import maxi, mini, greater_equal, less_equal, div, add, r
from ParetoLib.Geometry.Point import maxi, mini, greater_equal, less_equal, div, mult, add, r
import ParetoLib.Geometry.Point as Point
......@@ -215,6 +215,27 @@ class Segment (object):
diagonal = self.diag()
return Point.norm(diagonal)
def center_eps(self, eps):
# type: (Segment) -> tuple
"""
off by eps from the center of the Segment.
Args:
self (Segment): The Segment, eps: a float value.
Returns:
tuple: eps-center of the Segment.
Example:
>>> x = (0,0)
>>> y = (1,1)
>>> s = Segment(x,y)
>>> s.center_eps(0.01)
>>> (0.51,0.51)
"""
offset = mult(self.diag(), eps)
return add(self.center(), offset)
def center(self):
# type: (Segment) -> tuple
"""
......@@ -245,14 +266,14 @@ class Segment (object):
self (Segment): The Segment.
Returns:
tuple: Center of the Segment.
tuple: rounded center of the Segment.
Example:
>>> x = (0,0)
>>> y = (1,1)
>>> y = (3,3)
>>> s = Segment(x,y)
>>> s.center()
>>> (0.5,0.5)
>>> s.center_round()
>>> (1, 1)
"""
offset = div(self.diag(), 2.0)
offset = (math.floor(offset[0]), math.floor(offset[1]))
......
......@@ -3,6 +3,7 @@ import io, os
import ParetoLib.Oracle as RootOracle
from ParetoLib.Oracle.Oracle import Oracle
from ParetoLib.Oracle.OracleSTLe import OracleSTLeLib
from ParetoLib.Oracle.OracleEpsSTLe import OracleEpsSTLe
from ParetoLib.Search.Search import SearchIntersection2D, SearchIntersection3D, Search2D, EPS, DELTA, STEPS
......@@ -63,7 +64,7 @@ class OracleFnFp3D(Oracle):
temp_file = open(template_file1, 'r')
temp_string = temp_file.read()
temp_string = temp_string.replace('num_fn',str(point[0]))
# temp_string = temp_string.replace('num_fn',str(point[0]))
temp_file.close()
temp_file = open(scratch_file1, 'w')
temp_file.write(temp_string)
......@@ -71,7 +72,7 @@ class OracleFnFp3D(Oracle):
temp_file = open(template_file2, 'r')
temp_string = temp_file.read()
temp_string = temp_string.replace('num_fp',str(point[1]))
# temp_string = temp_string.replace('num_fp',str(point[1]))
temp_file.close()
temp_file = open(scratch_file2, 'w')
temp_file.write(temp_string)
......@@ -84,10 +85,10 @@ class OracleFnFp3D(Oracle):
min_x, min_y, min_z = self.min_tuple
max_x, max_y, max_z = self.max_tuple
orac1 = OracleSTLeLib()
orac1 = OracleEpsSTLe(boundOnCount=int(point[0]), intvlEpsilon=1)
orac1.from_file(nfile1, human_readable)
orac2 = OracleSTLeLib()
orac2 = OracleEpsSTLe(boundOnCount=int(point[1]), intvlEpsilon=10)
orac2.from_file(nfile2, human_readable)
output_intersect = SearchIntersection3D(oracle1=orac1, oracle2=orac2,
......@@ -98,7 +99,7 @@ class OracleFnFp3D(Oracle):
max_cornery=max_y,
max_cornerz=max_z,
epsilon=EPS,
delta=0.01,
delta=0.001,
max_step=STEPS,
blocking=False,
sleep=0,
......
import ParetoLib.Oracle as RootOracle
from ParetoLib.Oracle.Oracle import Oracle
import math
class OracleVolTest(Oracle):
def __init__(self,lineIntercept=0, numPoints=7):
# type: (OracleVolTest) -> None
"""
An OracleVolTest is a set of Conditions.
"""
# super(OracleVolTest, self).__init__()
Oracle.__init__(self)
self.lineIntercept = lineIntercept
self.numPoints = numPoints
def member(self, point):
# type: (OracleVolTest, tuple) -> bool
"""
See Oracle.member().
A point belongs to the Oracle if it satisfies all the conditions.
"""
lineIntercept = self.lineIntercept
if lineIntercept != 0:
return point[0] + point[1] < lineIntercept
discretize = math.floor(point[0]*self.numPoints)
return point[1] > (1-1*discretize/self.numPoints)
def dim(self):
# type: (OracleVolTest) -> int
"""
See Oracle.dim().
"""
return 3
def membership(self):
# type: (OracleVolTest) -> callable
"""
See Oracle.membership().
"""
return lambda point: self.member(point)
\ No newline at end of file
......@@ -23,6 +23,7 @@ actions on Evolutionary Computation, 2018.
from ParetoLib.Geometry.Point import add, subtract, less_equal, div
from ParetoLib.Geometry.Segment import Segment
import copy
# EPS = sys.float_info.epsilon
# DELTA = sys.float_info.epsilon
......@@ -66,6 +67,29 @@ def binary_search(x,
dist = y.norm()
return y, i
def intersection_empty_constrained(x, member1, member2, list_constraints):
low_allowed = True
high_allowed = True
for constraint in list_constraints:
left_sum = 0
for i in range(len(x.low)):
left_sum += x.low[i]*constraint[i]
if left_sum > constraint[-1]:
low_allowed = False
break
left_sum = 0
for i in range(len(x.high)):
left_sum += x.high[i]*constraint[i]
if left_sum > constraint[-1]:
high_allowed = False
break
if(low_allowed and (not member2(x.low))):
return True
if(high_allowed and (not member1(x.high))):
return True
return False
def intersection_empty(x, member1, member2):
if (not member1(x.high)) or (not member2(x.low)):
# The cube doesn't contain an intersection.
......@@ -73,6 +97,106 @@ def intersection_empty(x, member1, member2):
else:
return False
def intersection_expansion_search(x,
member1, member2,
error, to_expand):
# type: (Segment, callable, callable, tuple) -> (Segment, int)
# member1 is the function whose truth value increases with x.
# member2 is the function whose truth value decreases with x.
# Try to find an intersection or a proof that there doesn't exist an intersection on the given segment.
i = 0
y = x
intersect_indicator = -1
if member1(y.low) and member2(y.high):
# All the cube belongs to B1
intersect_indicator = 2
elif (not member1(y.high)) or (not member2(y.low)):
# All the cube belongs to B0
y.low = x.high
y.high = x.high
intersect_indicator = -3
else:
# We don't know. We search for a point in the diagonal
# dist = subtract(y.high, y.low)
dist = y.norm()
# while not less_equal(dist, error):
while dist > error[0]:
i += 2
# yval = div(add(y.low, y.high), 2.0)
yval = y.center()
# We need a oracle() for guiding the search
result1 = member1(yval)
result2 = member2(yval)
if result1 and result2:
# assign
z = copy.deepcopy(y)
y.low = yval
y.high = yval
intersect_indicator = 1
break
elif not (result1 or result2):
# assign
z = copy.deepcopy(y)
y.low = yval
y.high = yval
intersect_indicator = -2
break
elif result1 and (not result2):
y.high = yval
else: # (not result1) and (result2)
y.low = yval
# dist = subtract(y.high, y.low)
dist = y.norm()
yIn = copy.deepcopy(y)
yCover = copy.deepcopy(y)
# Expansion step here.
if intersect_indicator == -2 and to_expand:
eps_minus = z.center_eps(-error[0]/2)
eps_plus = z.center_eps( error[0]/2)
if not member2(eps_minus):
# Try to expand on the lower side.
zgrek1 = copy.deepcopy(z)
zgrek1.high = eps_minus
flip_member2 = lambda point: not member2(point)
ygrek, i1 = binary_search(zgrek1, flip_member2, error)
i += i1
yCover.low = ygrek.low
yIn.low = ygrek.high
if not member1(eps_plus):
# Try to expand on the upper side.
zgrek2 = copy.deepcopy(z)
zgrek2.low = eps_plus
ygrek, i2 = binary_search(zgrek2