def maximum(self, domain, domain_ind = slice(None)): c = self.c oovars = set(self.d.keys()) | set(self.d2.keys()) Vals = domain.values() n = np.asarray(Vals[0][0] if type(Vals) == list else next(iter(Vals))[0]).size active_domain_ind = type(domain_ind)==np.ndarray r = np.zeros(domain_ind.size if type(domain_ind)==np.ndarray else n) + c for k in oovars: l, u = domain[k][0][domain_ind], domain[k][1][domain_ind] d1, d2 = self.d.get(k, 0.0), self.d2.get(k, None) if active_domain_ind: if type(d1) == np.ndarray and d1.size != 1: d1 = d1[domain_ind] if type(d2) == np.ndarray and d2.size != 1: d2 = d2[domain_ind] if d2 is None: r += where(d1 < 0, l, u) * d1 continue rr = np.vstack(((d2 * l + d1)*l, (d2*u + d1)*u)) # rr.sort(axis=0) # r_min, r_max = rr r_max = nanmax(rr, axis=0) tops = -d1 / (2.0 * d2) ind_inside = logical_and(l < tops, tops < u) if any(ind_inside): top_vals = (d2*tops + d1) * tops ind_m = logical_and(ind_inside, r_max<top_vals) r_max = where(ind_m, top_vals, r_max) r += r_max return r
def exclude(self, domain, oovars, cmp): C = [] D, D2 = self.d.copy(), self.d2.copy() for k in oovars: l, u = domain.get(k, (None, None)) if l is None: continue # may be for fixed oovars d1, d2 = D.pop(k, 0.0), D2.pop(k, None) if d2 is None: C.append(where(cmp(d1, 0), l, u) * d1) continue #TODO: rework it as it was done in min/max rr = np.vstack(((d2 * l + d1) * l, (d2 * u + d1) * u)) rr.sort(axis=0) r_min, r_max = rr # check it _r = r_min if cmp == Greater else r_max #r_min = nanmin(rr, axis=0) tops = -d1 / (2.0 * d2) ind_inside = logical_and(l < tops, tops < u) if any(ind_inside): top_vals = (d2 * tops + d1) * tops ind_m = logical_and(ind_inside, cmp(_r, top_vals)) _r = where(ind_m, top_vals, _r) C.append(_r) c = self.c + PythonSum(C) return surf2(D2, D, c) '''
def get_pow_b2_coeffs(L, U, d_l, d_u, c_l, c_u, other): from overloads import get_inner_coeffs, get_outer_coeffs isInt = other == asarray(other, int) # L d = d_l ind = d > 0 l, u = where(ind, L, U), where(ind, U, L) # if not isInt: # point[logical_and(point)] koeffs_l = get_inner_coeffs(lambda x: x**other, lambda x: other * x**(other-1), \ d, l, u, d_l, d_u, c_l, c_u, pointCase='u', lineCase='l', feasLB = -inf if isInt else 0.0) # func, func_d, d, l, u, d_l, d_u, c_l, c_u, pointCase, lineCase # U d = d_u ind = d > 0 l, u = where(ind, L, U), where(ind, U, L) point = d*u + c_u # if not isInt: # point[logical_and(point)] f = point ** other df = d * other * point ** (other - 1) d2f = d**2 * other * (other - 1) * point ** (other - 2) koeffs_u = get_outer_coeffs(u, f, df, d2f) return koeffs_l, koeffs_u
def exclude(self, domain, oovars, cmp): C = [] D, D2 = self.d.copy(), self.d2.copy() for k in oovars: l, u = domain.get(k, (None, None)) if l is None: continue # may be for fixed oovars d1, d2 = D.pop(k, 0.0), D2.pop(k, None) if d2 is None: C.append(where(cmp(d1, 0), l, u) * d1) continue rr = np.vstack(((d2 * l + d1)*l, (d2*u + d1)*u)) rr.sort(axis=0) r_min, r_max = rr # check it _r = r_min if cmp == Greater else r_max #r_min = nanmin(rr, axis=0) tops = -d1 / (2.0 * d2) ind_inside = logical_and(l < tops, tops < u) if any(ind_inside): top_vals = (d2*tops + d1) * tops ind_m = logical_and(ind_inside, cmp(_r, top_vals)) _r = where(ind_m, top_vals, _r) C.append(_r) c = self.c + PythonSum(C) return surf2(D2, D, c) '''
def adjustBounds(R0, definiteRange, feasLB, feasUB): # adjust feasLB and feasUB r_l, r_u = R0 ind_L = r_l < feasLB ind_l = where(ind_L)[0] ind_U = r_u > feasUB ind_u = where(ind_U)[0] if ind_l.size != 0 or ind_u.size != 0: R0 = R0.copy() r_l, r_u = R0 if ind_l.size != 0: r_l[logical_and(ind_L, r_u >= feasLB)] = feasLB if definiteRange is not False: if type(definiteRange) != np.ndarray: definiteRange = np.empty_like(r_l, bool) definiteRange.fill(True) definiteRange[ind_l] = False if ind_u.size != 0: r_u[logical_and(ind_U, r_l <= feasUB)] = feasUB if definiteRange is not False: if type(definiteRange) != np.ndarray: definiteRange = np.empty_like(r_l, bool) definiteRange.fill(True) definiteRange[ind_u] = False return R0, definiteRange
def minimum(self, domain, domain_ind=slice(None)): #, reduceOnlyDomain = False): c = self.c oovars = set(self.d.keys()) | set(self.d2.keys()) n = getattr(domain, 'nPoints', 0) if n == 0: Vals = domain.values() n = np.asarray(Vals[0][0] if type(Vals) == list else next(iter(Vals))[0]).size active_domain_ind = type(domain_ind) == np.ndarray r = np.zeros(domain_ind.size if active_domain_ind else n) + c for k in oovars: l, u = domain[k][0][domain_ind], domain[k][1][domain_ind] d1, d2 = self.d.get(k, 0.0), self.d2.get(k, None) # if not reduceOnlyDomain and active_domain_ind: # if type(d1) == np.ndarray and d1.size != 1: # d1 = d1[domain_ind] # if type(d2) == np.ndarray and d2.size != 1: # d2 = d2[domain_ind] if d2 is None: r += where(d1 > 0, l, u) * d1 continue t1, t2 = (d2 * l + d1) * l, (d2 * u + d1) * u r_min = where(t1 < t2, t1, t2) tops = -d1 / (2.0 * d2) ind_inside = logical_and(l < tops, tops < u) ind_inside = logical_and(ind_inside, d2 > 0) # d2 may be a scalar if any(ind_inside): top_vals = (d2 * tops + d1) * tops # top_vals may be a scalar r_min = where(ind_inside, top_vals, r_min) r += r_min return r
def maximum(self, domain, domain_ind=slice(None)): c = self.c oovars = set(self.d.keys()) | set(self.d2.keys()) Vals = domain.values() n = np.asarray(Vals[0][0] if type(Vals) == list else next(iter(Vals))[0]).size active_domain_ind = type(domain_ind) == np.ndarray r = np.zeros(domain_ind.size if type(domain_ind) == np.ndarray else n) + c for k in oovars: l, u = domain[k][0][domain_ind], domain[k][1][domain_ind] d1, d2 = self.d.get(k, 0.0), self.d2.get(k, None) if active_domain_ind: if type(d1) == np.ndarray and d1.size != 1: d1 = d1[domain_ind] if type(d2) == np.ndarray and d2.size != 1: d2 = d2[domain_ind] if d2 is None: r += where(d1 < 0, l, u) * d1 continue rr = np.vstack(((d2 * l + d1) * l, (d2 * u + d1) * u)) # rr.sort(axis=0) # r_min, r_max = rr r_max = nanmax(rr, axis=0) tops = -d1 / (2.0 * d2) ind_inside = logical_and(l < tops, tops < u) if any(ind_inside): top_vals = (d2 * tops + d1) * tops ind_m = logical_and(ind_inside, r_max < top_vals) r_max = where(ind_m, top_vals, r_max) r += r_max return r
def split(*conditions): #Rest = np.ones_like(conditions[0]) # dtype bool #Temporary for PyPy: Rest = np.ones(conditions[0].shape, conditions[0].dtype) r = [] for c in conditions: tmp = logical_and(c, Rest) r.append(where(tmp)[0]) Rest &= logical_not(c) r.append(where(Rest)[0]) return r
def interval(domain, dtype): # TODO: # ia_surf_level = 2 ################ lb_ub, definiteRange = inp._interval(domain, dtype, ia_surf_level = 2) if isinstance(lb_ub, boundsurf): if is_abs: return lb_ub.abs() elif is_cosh: return defaultIntervalEngine(lb_ub, func, np.sinh, np.nan, 1, 0.0, 1.0) lb, ub = lb_ub#[0], lb_ub[1] ind1, ind2 = lb < 0.0, ub > 0.0 ind = logical_and(ind1, ind2) TMP = func(lb_ub) TMP.sort(axis=0) if any(ind): F0 = func(0.0) #TMP[0, atleast_1d(logical_and(ind, TMP[0] > F0))] = F0 # temporary for pypy: TMP[0, where(atleast_1d(logical_and(ind, TMP[0] > F0)))[0]] = F0 # TMP[atleast_1d(logical_and(ind, t_max < F0))] = F0 return TMP, definiteRange
def __div__(self, other, resolveSchedule=()): isBoundSurf = isinstance(other, boundsurf) assert isBoundSurf r = aux_mul_div_boundsurf((self, other), operator.truediv, resolveSchedule) # return r # ind_inf_z = logical_or(logical_or(R2[0]==0, R2[1]==0), logical_or(isinf(R1[0]), isinf(R1[1]))) #(R2[0]==0) | (R2[1]==0) | (isinf(R2[0])) | (isinf(R2[1])) | (isinf(R1[0])) | isinf(R1[1]) isBoundsurf = isinstance(r, boundsurf) rr = r.resolve()[0] if isBoundsurf else r #[0] # import pylab, numpy # xx = numpy.linspace(-1, 0, 1000) # t=r.l.d.keys()[0] # tmp=r # pylab.plot(xx, tmp.l.d2.get(t, 0.0)*xx**2+ tmp.l.d.get(t, 0.0)*xx+ tmp.l.c, 'r') # pylab.plot(xx, tmp.u.d2.get(t, 0.0)*xx**2+ tmp.u.d.get(t, 0.0)*xx+ tmp.u.c, 'b') # pylab.grid() # pylab.show() # nans may be from other computations from a level below, although ind_nan = logical_or(isnan(rr[0]), isnan(rr[1])) if not any(ind_nan) or not isBoundsurf: return r #if isBoundsurf else rr Ind_finite = where(logical_not(ind_nan))[0] r_finite = r.extract(Ind_finite) ind_nan = where(ind_nan)[0] R1 = self.resolve()[0] R2 = other.resolve()[0] lb1, ub1, lb2, ub2 = R1[0, ind_nan], R1[1, ind_nan], R2[0, ind_nan], R2[1, ind_nan] tmp = np.vstack((td(lb1, lb2), td(lb1, ub2), td(ub1, lb2), td(ub1, ub2))) R = np.vstack((nanmin(tmp, 0), nanmax(tmp, 0))) update_div_zero(lb1, ub1, lb2, ub2, R) b = boundsurf(surf({}, R[0]), surf({}, R[1]), False, self.domain) r = boundsurf_join((ind_nan, Ind_finite), (b, r_finite)) definiteRange = logical_and(self.definiteRange, other.definiteRange) r.definiteRange = definiteRange return r
def invert(self, ind=None): B = self.__class__ if ind is None: return B(-self.u, -self.l, self.definiteRange, self.domain) # if ind.dtype != bool: # bool_ind = np.zeros() assert ind.dtype == bool, 'unimplemented yet' ind_same, ind_invert = where(logical_not(ind))[0], where(ind)[0] l1, u1 = self.l.extract(ind_same), self.u.extract(ind_same) l2, u2 = self.l.extract(ind_invert), self.u.extract(ind_invert) b1 = B(l1, u1, False, self.domain) b2 = B(-u2, -l2, False, self.domain) b = boundsurf_join((ind_same, ind_invert), (b1, b2)) b.definiteRange = self.definiteRange # l, u = self.u.invert(ind), self.l.invert(ind) # if ind is None: return b
def exclude(self, domain, oovars, cmp): C = [] d = self.d.copy() for v in oovars: tmp = d.pop(v, 0.0) if any(tmp): D = domain[v] C.append(where(cmp(tmp, 0), D[0], D[1]) * tmp) c = self.c + PythonSum(C) return surf(d, c)
def exclude(self, domain, oovars, cmp): C = [] d = self.d.copy() for v in oovars: tmp = d.pop(v, 0.0) if any(tmp): D = domain[v] C.append(where(cmp(tmp, 0), D[0], D[1])*tmp) c = self.c + PythonSum(C) return surf(d, c)
def get_inv_b2_coeffs(ll, uu, dll, duu, c_l, c_u): ind_z = uu == ll dll, duu, c_l, c_u = duu, dll, c_u, c_l #L d = dll ind = d > 0 argmin = where(ind, uu, ll) min_val = argmin * d + c_l a = d**2 * min_val**-3 b = - d*(min_val+2*d*argmin) * min_val**-3 a[ind_z] = b[ind_z] = 0.0 ind_z2 = min_val == 0#logical_or(logical_not(isfinite(a)), logical_not(isfinite(b))) a[ind_z2] = b[ind_z2] = 0.0 #c = 1.0/min_val + d * argmin * min_val**-2 + d**2 * argmin ** 2 * min_val**-3 c = ((d * argmin / min_val + 1) * d * argmin / min_val + 1.0)/min_val c[logical_or(ind_z, ind_z2)] = 1.0/min_val[ind_z] #c[ind_z2] = 1.0/min_val[ind_z2]# - (a * argmin + b) * argmin koeffs_l = (a, b, c) #U ind = duu > 0 l, u = where(ind, ll, uu), where(ind, uu, ll) l2, u2 = l * duu + c_u, u * duu + c_u d = duu #inv_u2, inv_l2 = 1.0/u2, 1.0/l2 inv_l2 = 1.0/l2 u2_2 = u2 ** 2 a = (1.0/l2 - 1.0/u2 + d*(l-u)/u2_2) / (u-l)**2 b = -d/u2_2 - 2*a*u a[ind_z] = b[ind_z] = 0.0 ind_z2 = u2 == 0#logical_or(logical_not(isfinite(a)), logical_not(isfinite(b))) a[ind_z2] = b[ind_z2] = 0.0 c = inv_l2 - (a * l + b) * l # c[ind_z2] = inv_l2 koeffs_u = array((a, b, c)) return koeffs_l, koeffs_u
def nonnegative_interval(inp, func, deriv, domain, dtype, F0, shift=0.0): is_arccosh = func == np.arccosh is_sqrt = func == np.sqrt is_log = func in (np.log, np.log2, np.log10, np.log1p) ############################## assert is_arccosh or is_sqrt or is_log, 'unimplemented yet' # check for monotonity is required, sort or reverse of t_min_max has to be performed for monotonity != +1 ############################## lb_ub, definiteRange = inp._interval(domain, dtype, ia_surf_level=2) isBoundSurf = isinstance(lb_ub, boundsurf) if isBoundSurf: if is_sqrt or is_log: r, definiteRange = defaultIntervalEngine(lb_ub, func, deriv, monotonity=1, convexity=-1, feasLB=0.0) return r, r.definiteRange elif is_arccosh: r, definiteRange = defaultIntervalEngine(lb_ub, func, deriv, monotonity=1, convexity=-1, feasLB=1.0) return r, r.definiteRange lb_ub_resolved = lb_ub.resolve()[0] else: lb_ub_resolved = lb_ub lb, ub = lb_ub_resolved #[0], lb_ub_resolved[1] th = shift # 0.0 + shift = shift ind = lb < th if any(ind): lb_ub_resolved = lb_ub_resolved.copy() #lb_ub_resolved[0, logical_and(ind, ub >= th)] = th # for pypy: lb_ub_resolved[0, where(logical_and(ind, ub >= th))[0]] = th if definiteRange is not False: if type(definiteRange) != np.ndarray: definiteRange = np.empty_like(lb, bool) definiteRange.fill(True) definiteRange[ind] = False r = func(lb_ub_resolved) return r, definiteRange
def __div__(self, other, resolveSchedule=()): isBoundSurf = isinstance(other, boundsurf) assert isBoundSurf r = aux_mul_div_boundsurf((self, other), operator.truediv, resolveSchedule) # return r # ind_inf_z = logical_or(logical_or(R2[0]==0, R2[1]==0), logical_or(isinf(R1[0]), isinf(R1[1]))) #(R2[0]==0) | (R2[1]==0) | (isinf(R2[0])) | (isinf(R2[1])) | (isinf(R1[0])) | isinf(R1[1]) isBoundsurf = isinstance(r, boundsurf) rr = r.resolve()[0] if isBoundsurf else r#[0] # import pylab, numpy # xx = numpy.linspace(-1, 0, 1000) # t=r.l.d.keys()[0] # tmp=r # pylab.plot(xx, tmp.l.d2.get(t, 0.0)*xx**2+ tmp.l.d.get(t, 0.0)*xx+ tmp.l.c, 'r') # pylab.plot(xx, tmp.u.d2.get(t, 0.0)*xx**2+ tmp.u.d.get(t, 0.0)*xx+ tmp.u.c, 'b') # pylab.grid() # pylab.show() # nans may be from other computations from a level below, although ind_nan = logical_or(isnan(rr[0]), isnan(rr[1])) if not any(ind_nan) or not isBoundsurf: return r #if isBoundsurf else rr Ind_finite = where(logical_not(ind_nan))[0] r_finite = r.extract(Ind_finite) ind_nan = where(ind_nan)[0] R1 = self.resolve()[0] R2 = other.resolve()[0] lb1, ub1, lb2, ub2 = R1[0, ind_nan], R1[1, ind_nan], R2[0, ind_nan], R2[1, ind_nan] tmp = np.vstack((td(lb1, lb2), td(lb1, ub2), td(ub1, lb2), td(ub1, ub2))) R = np.vstack((nanmin(tmp, 0), nanmax(tmp, 0))) update_div_zero(lb1, ub1, lb2, ub2, R) b = boundsurf(surf({}, R[0]), surf({}, R[1]), False, self.domain) r = boundsurf_join((ind_nan, Ind_finite), (b, r_finite)) definiteRange = logical_and(self.definiteRange, other.definiteRange) r.definiteRange = definiteRange return r
def get_inv_b2_coeffs(ll, uu, dll, duu, c_l, c_u): ind_z = uu == ll dll, duu, c_l, c_u = duu, dll, c_u, c_l #L d = dll ind = d > 0 argmin = where(ind, uu, ll) min_val = argmin * d + c_l a = d**2 * min_val**-3 b = - d*(min_val+2*d*argmin) * min_val**-3 a[ind_z] = b[ind_z] = 0.0 ind_z2 = min_val == 0#logical_or(logical_not(isfinite(a)), logical_not(isfinite(b))) a[ind_z2] = b[ind_z2] = 0.0 #c = 1.0/min_val + d * argmin * min_val**-2 + d**2 * argmin ** 2 * min_val**-3 c = ((d * argmin / min_val + 1) * d * argmin / min_val + 1.0)/min_val c[logical_or(ind_z, ind_z2)] = 1.0/min_val[ind_z] #c[ind_z2] = 1.0/min_val[ind_z2]# - (a * argmin + b) * argmin koeffs_l = (a, b, c) #U ind = duu > 0 l, u = where(ind, ll, uu), where(ind, uu, ll) l2, u2 = l * duu + c_u, u * duu + c_u d = duu inv_u2, inv_l2 = 1.0/u2, 1.0/l2 u2_2 = u2 ** 2 a = (1.0/l2 - 1.0/u2 + d*(l-u)/u2_2) / (u-l)**2 b = -d/u2_2 - 2*a*u a[ind_z] = b[ind_z] = 0.0 ind_z2 = u2 == 0#logical_or(logical_not(isfinite(a)), logical_not(isfinite(b))) a[ind_z2] = b[ind_z2] = 0.0 c = inv_l2 - (a * l + b) * l # c[ind_z2] = inv_l2 koeffs_u = array((a, b, c)) return koeffs_l, koeffs_u
def boundsurf_join(inds, B): inds = [(ind if ind.dtype != bool else where(ind)[0]) for ind in inds] # B = [b for b in B if b is not None] L = surf_join(inds, [b.l for b in B]) U = surf_join(inds, [b.u for b in B]) #if self.l is not self.u else L definiteRange = True \ if PythonAll(np.array_equiv(True, b.definiteRange) for b in B)\ else Join(inds, [np.asarray(b.definiteRange) for b in B]) from boundsurf2 import boundsurf2 b = boundsurf if type(L) == type(U) == surf else boundsurf2 return b(L, U, definiteRange, B[0].domain)
def nonnegative_interval(inp, func, deriv, domain, dtype, F0, shift = 0.0): is_arccosh = func == np.arccosh is_sqrt = func == np.sqrt is_log = func in (np.log, np.log2, np.log10, np.log1p) ############################## assert is_arccosh or is_sqrt or is_log, 'unimplemented yet' # check for monotonity is required, sort or reverse of t_min_max has to be performed for monotonity != +1 ############################## lb_ub, definiteRange = inp._interval(domain, dtype, ia_surf_level = 2) isBoundSurf = isinstance(lb_ub, boundsurf) if isBoundSurf: if is_sqrt or is_log: r, definiteRange = defaultIntervalEngine(lb_ub, func, deriv, monotonity = 1, convexity = -1, feasLB = 0.0) return r, r.definiteRange elif is_arccosh: r, definiteRange = defaultIntervalEngine(lb_ub, func, deriv, monotonity = 1, convexity = -1, feasLB = 1.0) return r, r.definiteRange lb_ub_resolved = lb_ub.resolve()[0] else: lb_ub_resolved = lb_ub lb, ub = lb_ub_resolved#[0], lb_ub_resolved[1] th = shift # 0.0 + shift = shift ind = lb < th if any(ind): lb_ub_resolved = lb_ub_resolved.copy() #lb_ub_resolved[0, logical_and(ind, ub >= th)] = th # for pypy: lb_ub_resolved[0, where(logical_and(ind, ub >= th))[0]] = th if definiteRange is not False: if type(definiteRange) != np.ndarray: definiteRange = np.empty_like(lb, bool) definiteRange.fill(True) definiteRange[ind] = False r = func(lb_ub_resolved) return r, definiteRange
def adjust_ux_WithDiscreteDomain(Ux, v): if v.domain is bool or v.domain is 'bool': Ux[Ux != 1] = 0 else: d = v.domain if isPyPy: d2 = d.tolist() ind = atleast_1d([bisect_left(d2, val) for val in Ux]) ind2 = atleast_1d([bisect_right(d2, val) for val in Ux]) else: ind = searchsorted(d, Ux, 'left') ind2 = searchsorted(d, Ux, 'right') ind3 = where(ind!=ind2)[0] Tmp = d[ind[ind3]] #ind[ind==d.size] -= 1 ind[ind==0] = 1 Ux[:] = d[ind-1] if ind3.size: Ux[ind3] = asarray(Tmp, dtype=Ux.dtype)
def adjust_ux_WithDiscreteDomain(Ux, v): if v.domain is bool or v.domain is 'bool': Ux[Ux != 1] = 0 else: d = v.domain if isPyPy: d2 = d.tolist() ind = atleast_1d([bisect_left(d2, val) for val in Ux]) ind2 = atleast_1d([bisect_right(d2, val) for val in Ux]) else: ind = searchsorted(d, Ux, 'left') ind2 = searchsorted(d, Ux, 'right') ind3 = where(ind != ind2)[0] Tmp = d[ind[ind3]] #ind[ind==d.size] -= 1 ind[ind == 0] = 1 Ux[:] = d[ind - 1] if ind3.size: Ux[ind3] = asarray(Tmp, dtype=Ux.dtype)
def adjust_lx_WithDiscreteDomain(Lx, v): if v.domain is bool or v.domain is 'bool': Lx[Lx != 0] = 1 else: d = v.domain if isPyPy: d2 = d.tolist() ind = atleast_1d([bisect_left(d2, val) for val in Lx]) ind2 = atleast_1d([bisect_right(d2, val) for val in Lx]) else: ind = searchsorted(d, Lx, 'left') ind2 = searchsorted(d, Lx, 'right') ind3 = where(ind!=ind2)[0] Tmp = d[ind[ind3]] #if any(ind==d.size):print 'asdf' ind[ind==d.size] -= 1# Is it ever encountered? # ind[ind==d.size-1] -= 1 Lx[:] = d[ind] if ind3.size: Lx[ind3] = asarray(Tmp, dtype=Lx.dtype)
def adjust_lx_WithDiscreteDomain(Lx, v): if v.domain is bool or v.domain is 'bool': Lx[Lx != 0] = 1 else: d = v.domain if isPyPy: d2 = d.tolist() ind = atleast_1d([bisect_left(d2, val) for val in Lx]) ind2 = atleast_1d([bisect_right(d2, val) for val in Lx]) else: ind = searchsorted(d, Lx, 'left') ind2 = searchsorted(d, Lx, 'right') ind3 = where(ind != ind2)[0] Tmp = d[ind[ind3]] #if any(ind==d.size):print 'asdf' ind[ind == d.size] -= 1 # Is it ever encountered? # ind[ind==d.size-1] -= 1 Lx[:] = d[ind] if ind3.size: Lx[ind3] = asarray(Tmp, dtype=Lx.dtype)
def pow_b_interval(lb_ub, r1, other): definiteRange, domain = lb_ub.definiteRange, lb_ub.domain if type(lb_ub) == boundsurf2: lb_ub = lb_ub.to_linear() k = list(lb_ub.dep)[0] l, u = domain[k] d_l, d_u = lb_ub.l.d[k], lb_ub.u.d[k] c_l, c_u = lb_ub.l.c, lb_ub.u.c koeffs_l, koeffs_u = get_pow_b2_coeffs(l, u, d_l, d_u, c_l, c_u, other) #assert all(isfinite(koeffs_l)), all(isfinite(koeffs_u)) # L a, b, c = koeffs_l L = surf2({k: a}, {k: b}, c) # U a, b, c = koeffs_u U = surf2({k: a}, {k: b}, c) ######################### # from numpy import linspace # #l = 0.99 # print l, u # x = linspace(l, u, 10000) # import pylab # pylab.plot(x, pow(d_l*x+c_l, other), 'b', linewidth = 2) # pylab.plot(x, pow(d_u*x+c_u, other), 'r', linewidth = 2) # pylab.plot(x, koeffs_l[0]*x**2+koeffs_l[1]*x+koeffs_l[2], 'b', linewidth = 1) # pylab.plot(x, koeffs_u[0]*x**2+koeffs_u[1]*x+koeffs_u[2], 'r', linewidth = 1) # pylab.show() ######################### if not np.array_equal(other, asarray(other, int)): definiteRange = logical_and(definiteRange, c_l + d_l * where(d_l > 0, l, u) >= 0) r2 = boundsurf2(L, U, definiteRange, domain) R = merge_boundsurfs(r1, r2) return R, definiteRange
def pow_b_interval(lb_ub, r1, other): definiteRange, domain = lb_ub.definiteRange, lb_ub.domain if type(lb_ub) == boundsurf2: lb_ub = lb_ub.to_linear() k = list(lb_ub.dep)[0] l, u = domain[k] d_l, d_u = lb_ub.l.d[k], lb_ub.u.d[k] c_l, c_u = lb_ub.l.c, lb_ub.u.c koeffs_l, koeffs_u = get_pow_b2_coeffs(l, u, d_l, d_u, c_l, c_u, other) #assert all(isfinite(koeffs_l)), all(isfinite(koeffs_u)) # L a, b, c = koeffs_l L = surf2({k:a}, {k:b}, c) # U a, b, c = koeffs_u U = surf2({k:a}, {k:b}, c) ######################### # from numpy import linspace # #l = 0.99 # print l, u # x = linspace(l, u, 10000) # import pylab # pylab.plot(x, pow(d_l*x+c_l, other), 'b', linewidth = 2) # pylab.plot(x, pow(d_u*x+c_u, other), 'r', linewidth = 2) # pylab.plot(x, koeffs_l[0]*x**2+koeffs_l[1]*x+koeffs_l[2], 'b', linewidth = 1) # pylab.plot(x, koeffs_u[0]*x**2+koeffs_u[1]*x+koeffs_u[2], 'r', linewidth = 1) # pylab.show() ######################### if not np.array_equal(other, asarray(other, int)): definiteRange = logical_and(definiteRange, c_l+d_l*where(d_l>0, l, u)>=0) r2 = boundsurf2(L, U, definiteRange, domain) R = merge_boundsurfs(r1, r2) return R, definiteRange
def to_linear(self, domain, cmp): C = [] D, D2 = self.d, self.d2 new_D = D.copy() for k, d2 in D2.items(): l, u = domain[k] #[0], domain[k][1] #d1 = D.pop(k, 0.0) d1 = D.get(k, 0.0) vals1, vals2 = (d2 * l + d1) * l, (d2 * u + d1) * u ind = cmp(vals2, vals1) _r = where(ind, vals1, vals2) _argextr = where(ind, l, u) tops = -d1 / (2.0 * d2) ind_inside = logical_and(l < tops, tops < u) #TODO: rework it as it was done in min/max if any(ind_inside): #assert 0, 'unimplemented' #print('asdf') top_vals = (d2 * tops + d1) * tops ind_m = logical_and(ind_inside, cmp(_r, top_vals)) _r = where(ind_m, top_vals, _r) _argextr = where(ind_m, tops, _argextr) extr_val = (d2 * _argextr + d1) * _argextr tmp = d2 * (u + l) + d1 new_d1 = where(cmp(d2, 0), d1 + 2 * d2 * _argextr, tmp) new_extr_val = where(cmp(new_d1, 0), l, u) * new_d1 _r = extr_val - new_extr_val C.append(_r) new_D[k] = new_d1 c = self.c + PythonSum(C) # print '----' # print _argextr # print D2, D, self.c # print new_D, c return surf(new_D, c)
def to_linear(self, domain, cmp): C = [] D, D2 = self.d, self.d2 new_D = D.copy() for k, d2 in D2.items(): l, u = domain[k]#[0], domain[k][1] #d1 = D.pop(k, 0.0) d1 = D.get(k, 0.0) vals1, vals2 = (d2 * l + d1)*l, (d2*u + d1)*u ind = cmp(vals2, vals1) _r = where(ind, vals1, vals2) _argextr = where(ind, l, u) tops = -d1 / (2.0 * d2) ind_inside = logical_and(l < tops, tops < u) if any(ind_inside): #assert 0, 'unimplemented' #print('asdf') top_vals = (d2*tops + d1) * tops ind_m = logical_and(ind_inside, cmp(_r, top_vals)) _r = where(ind_m, top_vals, _r) _argextr = where(ind_m, tops, _argextr) extr_val = (d2 * _argextr + d1) * _argextr tmp = d2*(u+l) + d1 new_d1 = where(cmp(d2,0), d1 + 2 * d2 * _argextr, tmp) new_extr_val = where(cmp(new_d1, 0), l, u) * new_d1 _r = extr_val - new_extr_val C.append(_r) new_D[k] = new_d1 c = self.c + PythonSum(C) # print '----' # print _argextr # print D2, D, self.c # print new_D, c return surf(new_D, c)
def mul_fixed_interval(self, R2): if type(self) == boundsurf: Boundsurf = boundsurf else: from boundsurf2 import boundsurf2 Boundsurf = boundsurf2 domain = self.domain definiteRange = self.definiteRange assert R2.shape[0] == 2, 'bug or unimplemented yet' R2Positive = all(R2 >= 0) R2Negative = all(R2 <= 0) R1 = self.resolve()[0] selfPositive = all(R1 >= 0) selfNegative = all(R1 <= 0) SelfSameBounds = self.l is self.u # print('0', SelfSameBounds, selfPositive, selfNegative) if 1 and SelfSameBounds and (selfPositive or selfNegative): bound = self.l # equal to self.u # if selfPositive or selfNegative: rr = (bound * R2[0], bound * R2[1]) if selfPositive else (bound * R2[1], bound * R2[0]) elif selfPositive and R2Positive: rr = (self.l * R2[0], self.u * R2[1]) elif selfPositive and R2Negative: rr = (self.u * R2[0], self.l * R2[1]) elif selfNegative and R2Negative: rr = (self.u * R2[1], self.l * R2[0]) elif selfNegative and R2Positive: rr = (self.l * R2[1], self.u * R2[0]) elif R2Positive or R2Negative: lb1, ub1 = R1 ind_positive, ind_negative, ind_z = split(lb1 >= 0, ub1 <= 0) other_lb, other_ub = R2 if R2Positive else (-R2[1], -R2[0]) l, u = self.l, self.u tmp_l1 = other_lb[ind_positive] * l.extract(ind_positive) tmp_l2 = other_ub[ind_negative] * l.extract(ind_negative) tmp_u1 = other_ub[ind_positive] * u.extract(ind_positive) tmp_u2 = other_lb[ind_negative] * u.extract(ind_negative) # tmp_l3 = other_ub[ind_z] * l.extract(ind_z) # tmp_u3 = other_ub[ind_z] * u.extract(ind_z) l2, u2 = other_lb[ind_z], other_ub[ind_z] l1, u1 = lb1[ind_z], ub1[ind_z] Tmp = np.vstack((l1*l2, l1*u2, l2*u1, u1*u2)) tmp_l3 = surf({}, nanmin(Tmp, axis=0)) tmp_u3 = surf({}, nanmax(Tmp, axis=0)) tmp_l = surf_join((ind_positive, ind_negative, ind_z), (tmp_l1, tmp_l2, tmp_l3)) tmp_u = surf_join((ind_positive, ind_negative, ind_z), (tmp_u1, tmp_u2, tmp_u3)) # Inds, L, U = [], [], [] # if ind_positive.size: # tmp_l1 = other_lb[ind_positive] * l.extract(ind_positive) # tmp_u1 = other_ub[ind_positive] * u.extract(ind_positive) # Inds.append(ind_positive) # L.append(tmp_l1) # U.append(tmp_u1) # if ind_negative.size: # tmp_l2 = other_ub[ind_negative] * l.extract(ind_negative) # tmp_u2 = other_lb[ind_negative] * u.extract(ind_negative) # Inds.append(ind_negative) # L.append(tmp_l2) # U.append(tmp_u2) # if ind_z.size: # l2, u2 = other_lb[ind_z], other_ub[ind_z] # l1, u1 = lb1[ind_z], ub1[ind_z] # Tmp = np.vstack((l1*l2, l1*u2, l2*u1, u1*u2)) # tmp_l3 = surf({}, nanmin(Tmp, axis=0)) # tmp_u3 = surf({}, nanmax(Tmp, axis=0)) # Inds.append(ind_z) # L.append(tmp_l3) # U.append(tmp_u3) rr = (tmp_l, tmp_u) if R2Positive else (-tmp_u, -tmp_l) elif selfPositive or selfNegative: l, u = (self.l, self.u) if selfPositive else (-self.u, -self.l) lb1, ub1 = R1 other_lb, other_ub = R2 ind_other_positive, ind_other_negative, ind_z2 = split(other_lb >= 0, other_ub <= 0) Ind, Tmp_l, Tmp_u = [], [], [] if ind_other_positive.size: Ind.append(ind_other_positive) Tmp_l.append(other_lb[ind_other_positive] * l.extract(ind_other_positive)) Tmp_u.append(other_ub[ind_other_positive] * u.extract(ind_other_positive)) if ind_other_negative.size: Ind.append(ind_other_negative) Tmp_l.append(other_lb[ind_other_negative] * u.extract(ind_other_negative)) Tmp_u.append(other_ub[ind_other_negative] * l.extract(ind_other_negative)) # if 1: if ind_z2.size: uu = u.extract(ind_z2) Ind.append(ind_z2) Tmp_l.append(other_lb[ind_z2] * uu) Tmp_u.append(other_ub[ind_z2] * uu) # else: # l2, u2 = other_lb[ind_z2], other_ub[ind_z2] # l1, u1 = lb1[ind_z2], ub1[ind_z2] # Tmp = np.vstack((l1*l2, l1*u2, l2*u1, u1*u2)) # tmp_l3 = surf({}, nanmin(Tmp, axis=0)) # tmp_u3 = surf({}, nanmax(Tmp, axis=0)) tmp_l = surf_join(Ind, Tmp_l) tmp_u = surf_join(Ind, Tmp_u) rr = (tmp_l, tmp_u) if selfPositive else (-tmp_u, -tmp_l) else: # TODO: mb improve it lb1, ub1 = R1 lb2, ub2 = R2 l, u = self.l, self.u ind_other_positive, ind_other_negative, ind_z2 = Split(lb2 >= 0, ub2 <= 0) ind_positive, ind_negative, ind_z1 = Split(lb1 >= 0, ub1 <= 0) inds, lu = [], [] ind_Z = where(ind_z1)[0] if ind_Z.size: inds.append(ind_Z) l2, u2 = lb2[ind_Z], ub2[ind_Z] l1, u1 = lb1[ind_Z], ub1[ind_Z] Tmp = np.vstack((l1*l2, l1*u2, l2*u1, u1*u2)) tmp_l3 = surf({}, nanmin(Tmp, axis=0)) tmp_u3 = surf({}, nanmax(Tmp, axis=0)) lu.append((tmp_l3, tmp_u3)) ind_positive_all = logical_and(ind_positive, ind_other_positive) ind_Positive = where(ind_positive_all)[0] if ind_Positive.size: inds.append(ind_Positive) L = l.extract(ind_Positive) * lb2[ind_Positive] U = u.extract(ind_Positive) * ub2[ind_Positive] lu.append((L, U)) ind_negative_all = logical_and(ind_negative, ind_other_negative) ind_Negative = where(ind_negative_all)[0] if ind_Negative.size: inds.append(ind_Negative) U = l.extract(ind_Negative) * lb2[ind_Negative] L = u.extract(ind_Negative) * ub2[ind_Negative] lu.append((L, U)) ind = logical_and(ind_positive, ind_other_negative) Ind = where(ind)[0] if Ind.size: inds.append(Ind) L = u.extract(Ind) * lb2[Ind] U = l.extract(Ind) * ub2[Ind] lu.append((L, U)) ind = logical_and(ind_negative, ind_other_positive) Ind = where(ind)[0] if Ind.size: inds.append(Ind) L = l.extract(Ind) * ub2[Ind] U = u.extract(Ind) * lb2[Ind] lu.append((L, U)) ind = logical_and(ind_positive, ind_z2) Ind = where(ind)[0] if Ind.size: inds.append(Ind) uu = u.extract(Ind) L = uu * lb2[Ind] U = uu * ub2[Ind] lu.append((L, U)) ind = logical_and(ind_negative, ind_z2) Ind = where(ind)[0] if Ind.size: inds.append(Ind) ll = l.extract(Ind) L = ll * ub2[Ind] U = ll * lb2[Ind] lu.append((L, U)) # # ind = logical_and(ind_z1, ind_other_positive) # Ind = where(ind)[0] # if Ind.size: # print('8') # inds.append(Ind) # L = l.extract(Ind) * ub2[Ind] # U = u.extract(Ind) * ub2[Ind] # lu.append((L, U)) # # ind = logical_and(ind_z1, ind_other_negative) # Ind = where(ind)[0] # if Ind.size: # print('9') # inds.append(Ind) # L = u.extract(Ind) * lb2[Ind] # U = l.extract(Ind) * lb2[Ind] # lu.append((L, U)) # B = [Boundsurf(L, U, False, domain) for L, U in lu] rr = boundsurf_join(inds, B) rr.definiteRange = definiteRange R = Boundsurf(rr[0], rr[1], definiteRange, domain) if type(rr) == tuple else rr return R
def pow_const_interval(self, r, other, domain, dtype): lb_ub, definiteRange = self._interval(domain, dtype, ia_surf_level = 2) isBoundSurf = isinstance(lb_ub, boundsurf) # changes if 1 and isBoundSurf and other == 2 and lb_ub.level == 1 and len(lb_ub.l.d) == 1 and len(lb_ub.u.d) == 1: L, U = lb_ub.l, lb_ub.u if lb_ub.l is lb_ub.u: d, c = L.d, L.c s_l = surf2(dict((k, v**2) for k, v in d.items()), dict((k, 2*v*c) for k, v in d.items()), c**2) return boundsurf2(s_l, s_l, definiteRange, domain), definiteRange lb_ub_resolved = lb_ub.resolve()[0] lb, ub = lb_ub_resolved ind_positive, ind_negative, ind_z = split(lb >= 0, ub <= 0) #new m = lb.size if ind_negative.size: ind_negative_bool = ub <= 0 lb_ub = lb_ub.invert(ind_negative_bool) L, U = lb_ub.l, lb_ub.u d_l, d_u = L.d, U.d ind = logical_or(lb >= 0, ub <= 0) Ind_nonz = where(ind)[0] if Ind_nonz.size != 0: d_u2 = dict_reduce(d_u, Ind_nonz) c = U.c if type(U.c) != ndarray or U.c.size == 1 else U.c[Ind_nonz] s_u = surf2(dict((k, v**2) for k, v in d_u2.items()), dict((k, 2*v*c) for k, v in d_u2.items()), c**2) d_l2 = dict_reduce(d_l, Ind_nonz) c = L.c if type(L.c) != ndarray or L.c.size == 1 else L.c[Ind_nonz] s_l = surf2(dict((k, v**2) for k, v in d_l2.items()), dict((k, 2*v*c) for k, v in d_l2.items()), c**2) r_nz = boundsurf2(s_l, s_u, False, domain) if Ind_nonz.size == m: r_nz.definiteRange = definiteRange return r_nz, definiteRange r0, definiteRange0 = defaultIntervalEngine(lb_ub, r.fun, r.d, monotonity = np.nan, convexity = 1, criticalPoint = 0.0, criticalPointValue = 0.0, domain_ind = ind_z) if Ind_nonz.size == 0: return r0, definiteRange r = boundsurf_join((Ind_nonz, ind_z), (r_nz, r0)) #!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! r.definiteRange = definiteRange #################### return r, definiteRange #prev # L, U = lb_ub.l, lb_ub.u # d, c = L.d, L.c # s_l = surf2(dict((k, v**2) for k, v in d.items()), dict((k, 2*v*c) for k, v in d.items()), c**2) # # if lb_ub.l is lb_ub.u: # return boundsurf2(s_l, s_l, definiteRange, domain), definiteRange # # d, c = U.d, U.c # lb_ub_resolved = lb_ub.resolve()[0] # if all(lb_ub_resolved >= 0): # s_u = surf2(dict((k, v**2) for k, v in d.items()), dict((k, 2*v*c) for k, v in d.items()), c**2) # return boundsurf2(s_l, s_u, definiteRange, domain), definiteRange # elif all(lb_ub_resolved <= 0): # s_u = s_l # s_l = surf2(dict((k, v**2) for k, v in d.items()), dict((k, 2*v*c) for k, v in d.items()), c**2) # return boundsurf2(s_l, s_u, definiteRange, domain), definiteRange # changes end lb_ub_resolved = lb_ub.resolve()[0] if isBoundSurf else lb_ub arg_isNonNegative = all(lb_ub_resolved >= 0) arg_isNonPositive = all(lb_ub_resolved <= 0) #changes # !!!!!!!TODO: rdiv beyond arg_isNonNegative, arg_isNonPositive if 1 and other == -1 and (arg_isNonNegative or arg_isNonPositive) and isBoundSurf and len(lb_ub.dep)==1: return inv_b_interval(lb_ub, revert = arg_isNonPositive) # TODO: remove arg_isNonNegative if 1 and 0 < other < 1 and 1 and isBoundSurf and len(lb_ub.dep)==1: return pow_interval(r, self, other, domain, dtype) #changes end other_is_int = asarray(other, int) == other isOdd = other_is_int and other % 2 == 1 if isBoundSurf and not any(np.isinf(lb_ub_resolved)): #new # if arg_isNonNegative: # return defaultIntervalEngine(lb_ub, r.fun, r.d, # monotonity = 1, # convexity = 1 if other > 1.0 or other < 0 else -1) # # if other_is_int and other > 0 and other % 2 == 0: # return devided_interval(self, r, domain, dtype) #prev if arg_isNonNegative:# or (other_is_int and other > 0 and other % 2 == 0): return defaultIntervalEngine(lb_ub, r.fun, r.d, monotonity = 1 if other > 0 and arg_isNonNegative else -1 if arg_isNonNegative and other < 0 else np.nan, convexity = 1 if other > 1.0 or other < 0 else -1, criticalPoint = 0.0, criticalPointValue = 0.0) if other_is_int and other > 0 and other % 2 == 0: return defaultIntervalEngine(lb_ub, r.fun, r.d, monotonity = np.nan, convexity = 1, criticalPoint = 0.0, criticalPointValue = 0.0) feasLB = -inf if other_is_int else 0.0 if other > 0 or arg_isNonPositive: return devided_interval(self, r, domain, dtype, feasLB = feasLB) if other_is_int and other < 0:# and other % 2 != 0: lb, ub = lb_ub_resolved ind_positive, ind_negative, ind_z = split(lb >= 0, ub <= 0) B, inds = [], [] if ind_positive.size: inds.append(ind_positive) monotonity = -1 b = defaultIntervalEngine(lb_ub, r.fun, r.d, monotonity = monotonity, convexity = 1, domain_ind = ind_positive)[0] B.append(b) if ind_negative.size: inds.append(ind_negative) # TODO: fix it monotonity = -1 if isOdd else 1 convexity = -1 if isOdd else 1 b = defaultIntervalEngine(lb_ub, r.fun, r.d, monotonity = monotonity, convexity = convexity, domain_ind = ind_negative)[0] B.append(b) if ind_z.size: inds.append(ind_z) t = 1.0 / lb_ub_resolved[:, ind_z] t.sort(axis=0) update_negative_int_pow_inf_zero(lb_ub_resolved[0, ind_z], lb_ub_resolved[1, ind_z], t, other) b = boundsurf( surf({}, t[0]), surf({}, t[1]), definiteRange if type(definiteRange) == bool or definiteRange.size == 1 \ else definiteRange[ind_z], domain) B.append(b) r = boundsurf_join(inds, B) return r, r.definiteRange lb_ub = lb_ub_resolved lb, ub = lb_ub Tmp = lb_ub ** other # correct nan handling #Tmp.sort(axis = 0) ind = where(Tmp[0]>Tmp[1])[0] if ind.size: # PyPy doesn't work w/o this check Tmp[0, ind], Tmp[1, ind] = Tmp[1, ind], Tmp[0, ind] if not other_is_int or not isOdd: ind_z = logical_and(lb < 0, ub >= 0) assert type(ind_z) == np.ndarray if any(ind_z): Ind_z = where(ind_z)[0] if (not other_is_int and other > 0) or not isOdd: # print ind_z, type(ind_z), ind_z.shape # print Tmp Tmp[0, Ind_z] = 0.0 if other < 0: Tmp[1, Ind_z] = inf if not other_is_int: definiteRange = logical_and(definiteRange, logical_not(ind_z)) Tmp.sort(axis = 0) if other < 0 and other_is_int: update_negative_int_pow_inf_zero(lb, ub, Tmp, other) return Tmp, definiteRange
def aux_mul_div_boundsurf(Elems, op, resolveSchedule=()): _r = [] _resolved = [] changeSign = False indZ = False definiteRange = np.array(True) for elem in Elems: _R = elem.resolve()[0] lb, ub = _R ind_positive, ind_negative, ind_z = Split(lb >= 0, ub <= 0) not_ind_negative = logical_not(ind_negative) changeSign = logical_xor(changeSign, ind_negative) indZ = logical_or(indZ, ind_z) tmp1 = elem.extract(not_ind_negative) tmp2 = -elem.extract(ind_negative) Tmp = boundsurf_join((not_ind_negative, ind_negative), (tmp1, tmp2)) #.log() _r.append(Tmp) _resolved.append(_R) definiteRange = logical_and(definiteRange, elem.definiteRange) use_exp = True if op == operator.mul: if len(_r) == 2 and _r[0].level == _r[1].level == 1 and _r[0].b2equiv( _r[1]): rr = b2mult(_r[0], _r[1]) use_exp = False else: rr = PythonSum(elem.log() for elem in _r) #.exp() else: assert op == operator.truediv and len(Elems) == 2 if 1 and _r[1].level == 1 and _r[0].b2equiv(_r[1]): rr = b2div(_r[0], _r[1]) use_exp = False else: rr = (_r[0].log() - _r[1].log()) #.exp() changeSign = logical_and(changeSign, logical_not(indZ)) keepSign = logical_and(logical_not(changeSign), logical_not(indZ)) if use_exp: if len(resolveSchedule): rr = rr.exclude(resolveSchedule) if type(rr) == np.ndarray: #print('asdf') r = np.exp(rr) r[:, changeSign] = -r[:, changeSign][::-1] return r #, definiteRange # print len(rr.dep) rr = rr.exp() # print type(rr) # if type(rr) != boundsurf: # print(rr.l.d2, rr.l.d, rr.l.c, '----', rr.u.d2, rr.u.d, rr.u.c) _rr, _inds = [], [] if any(keepSign): _rr.append(rr.extract(keepSign)) _inds.append(keepSign) if any(changeSign): _rr.append(-rr.extract(changeSign)) _inds.append(changeSign) if any(indZ): assert len(Elems) == 2, 'unimplemented yet' lb1, ub1 = Elems[0].resolve()[0] # R1 other_lb, other_ub = Elems[1].resolve()[0] # R2 IndZ = where(indZ)[0] tmp_z = np.vstack( (op(lb1[IndZ], other_lb[IndZ]), op(ub1[IndZ], other_lb[IndZ]), op(lb1[IndZ], other_ub[IndZ]), op(ub1[IndZ], other_ub[IndZ]))) l_z, u_z = nanmin(tmp_z, 0), nanmax(tmp_z, 0) rr_z = boundsurf(surf({}, l_z), surf({}, u_z), True, Elems[0].domain) _rr.append(rr_z) _inds.append(indZ) rr = boundsurf_join(_inds, _rr) rr.definiteRange = definiteRange return rr
def render(self, domain, cmp): self.rendered = dict( (k, where(cmp(v, 0), domain[k][0], domain[k][1]) * v) for k, v in self.d.items()) self.resolved = PythonSum(self.rendered) + self.c self.isRendered = True
def render(self, domain, cmp): self.rendered = dict((k, where(cmp(v, 0), domain[k][0], domain[k][1])*v) for k, v in self.d.items()) self.resolved = PythonSum(self.rendered) + self.c self.isRendered = True
def b2div(Self, Other): # Self and Other must be nonnegative assert Other.level == 1 and Self.b2equiv(Other) DefiniteRange = Self.definiteRange & Other.definiteRange domain = Self.domain is_b2 = Self.level == 2 k = list(Self.dep)[0] L, U = Self.domain[k] # L if is_b2: h = Self.l.d2.get(k, 0.0) d1, d2 = Self.l.d[k], Other.u.d[k] c1, c2 = Self.l.c, Other.u.c ind_Z_l = d2 == 0.0 ind_z_l = where(ind_Z_l)[0] if ind_z_l.size: d_z_l = where(ind_Z_l, d1 / c2, 0.0) c_z_l = where(ind_Z_l, c1 / c2, 0.0) if is_b2: h_z_l = where(ind_Z_l, h / c2, 0.0) if is_b2: H1 = h / d2 a1 = (d1 - h * c2 / d2) / d2 else: a1 = d1 / d2 b1 = c1 - a1 * c2 ind_negative = b1<0 ind_b_negative_l = where(ind_negative)[0] ind_b_positive_l = where(logical_not(ind_negative))[0] b1[ind_b_negative_l] = -b1[ind_b_negative_l] d = {k: d2} c = c2 s_l = surf(d, c) # U if is_b2: h = Self.u.d2.get(k, 0.0) d1, d2 = Self.u.d[k], Other.l.d[k] c1, c2 = Self.u.c, Other.l.c ind_Z_u = d2 == 0.0 ind_z_u = where(ind_Z_u)[0] if ind_z_u.size: d_z_u = where(ind_Z_u, d1 / c2, 0.0) c_z_u = where(ind_Z_u, c1 / c2, 0.0) if is_b2: h_z_u = where(ind_Z_u, h / c2, 0.0) if is_b2: H2 = h / d2 a2 = (d1 - h * c2 / d2) / d2 else: a2 = d1 / d2 b2 = c1 - a2 * c2 ind_negative = b2<0 ind_b_negative_u = where(ind_negative)[0] ind_b_positive_u = where(logical_not(ind_negative))[0] b2[ind_b_negative_u] = -b2[ind_b_negative_u] d = {k: d2} c = c2 s_u = surf(d, c) tmp = boundsurf(s_l, s_u, DefiniteRange, domain) from Interval import inv_b_interval B = inv_b_interval(tmp, revert = False)[0] sl, su = B.l, B.u from boundsurf2 import boundsurf2, surf2 P = 1e11 sl2 = surf_join((ind_b_positive_l, ind_b_negative_l), \ (sl.extract(ind_b_positive_l), -su.extract(ind_b_negative_l)))*b1 ind_numericaly_unstable_l = P * np.abs(sl2.c + a1) < np.abs(sl2.c) + np.abs(a1) sl2 += a1 su2 = surf_join((ind_b_positive_u, ind_b_negative_u), \ (su.extract(ind_b_positive_u), -sl.extract(ind_b_negative_u)))*b2 ind_numericaly_unstable_u = P * np.abs(su2.c + a2) < np.abs(su2.c) + np.abs(a2) su2 += a2 if is_b2: ind_numericaly_unstable_l = logical_or(ind_numericaly_unstable_l, P*np.abs(sl2.d.get(k, 0.0) + H1) < np.abs(sl2.d.get(k, 0.0)) + np.abs(H1)) ind_numericaly_unstable_u = logical_or(ind_numericaly_unstable_u, P*np.abs(su2.d.get(k, 0.0) + H2) < np.abs(su2.d.get(k, 0.0)) + np.abs(H2)) sl2.d[k] = sl2.d.get(k, 0.0) + H1 su2.d[k] = su2.d.get(k, 0.0) + H2 if ind_z_l.size: ind_nz_l = where(logical_not(ind_Z_l))[0] sl2 = surf_join((ind_nz_l, ind_z_l), \ (sl.extract(ind_nz_l), surf2({k:0}, {k:d_z_l}, c_z_l))) if is_b2: sl2.d2[k] = sl2.d2.get(k, 0.0) + h_z_l if ind_z_u.size: ind_nz_u = where(logical_not(ind_Z_u))[0] su2 = surf_join((ind_nz_u, ind_z_u), \ (su.extract(ind_nz_u), surf2({k:0}, {k:d_z_u}, c_z_u))) if is_b2: su2.d2[k] = su2.d2.get(k, 0.0) + h_z_u r = boundsurf2(sl2, su2, DefiniteRange, domain) ind_numericaly_unstable = logical_or(ind_numericaly_unstable_l, ind_numericaly_unstable_u) if any(ind_numericaly_unstable): ind_numericaly_stable = logical_not(ind_numericaly_unstable) # print where(ind_numericaly_stable)[0].size, where(ind_numericaly_unstable)[0].size r2 = (Self.log() - Other.log()).exp() r = boundsurf_join((ind_numericaly_unstable, ind_numericaly_stable), \ (r2.extract(ind_numericaly_unstable), r.extract(ind_numericaly_stable))) return r
def iqg(Self, domain, dtype=float, lb=None, ub=None, UB=None): if type(domain) != ooPoint: domain = ooPoint(domain, skipArrayCast=True) domain.isMultiPoint = True domain.useSave = True r0 = Self.interval(domain, dtype, resetStoredIntervals=False) r0.lb, r0.ub = atleast_1d(r0.lb).copy(), atleast_1d( r0.ub).copy() # is copy required? # TODO: get rid of useSave domain.useSave = False # TODO: rework it with indexation of required data if lb is not None and ub is not None: ind = logical_or(logical_or(r0.ub < lb, r0.lb > ub), all(logical_and(r0.lb >= lb, r0.ub <= ub))) elif UB is not None: ind = r0.lb > UB else: ind = None useSlicing = False if ind is not None: if all(ind): return {}, r0 j = where(~ind)[0] #DOESN'T WORK FOR FIXED OOVARS AND DefiniteRange != TRUE YET if 0 and j.size < 0.85 * ind.size: # at least 15% of values to skip useSlicing = True tmp = [] for key, val in domain.storedIntervals.items(): Interval, definiteRange = val if type(definiteRange) not in (bool, bool_): definiteRange = definiteRange[j] tmp.append((key, (Interval[:, j], definiteRange))) _storedIntervals = dict(tmp) Tmp = [] for key, val in domain.storedSums.items(): # TODO: rework it R0, DefiniteRange0 = val.pop(-1) #R0, DefiniteRange0 = val[-1] R0 = R0[:, j] if type(DefiniteRange0) not in (bool, bool_): DefiniteRange0 = DefiniteRange0[j] tmp = [] for k, v in val.items(): # TODO: rework it # if k is (-1): continue v = v[:, j] tmp.append((k, v)) val = dict(tmp) val[-1] = (R0, DefiniteRange0) Tmp.append((key, val)) _storedSums = dict(Tmp) #domain.storedSums = dict(tmp) Tmp = [] for key, val in domain.items(): lb_, ub_ = val # TODO: rework it when lb, ub will be implemented as 2-dimensional Tmp.append((key, (lb_[j], ub_[j]))) dictOfFixedFuncs = domain.dictOfFixedFuncs domain2 = ooPoint(Tmp, skipArrayCast=True) domain2.storedSums = _storedSums domain2.storedIntervals = _storedIntervals domain2.dictOfFixedFuncs = dictOfFixedFuncs domain2._dictOfRedirectedFuncs = domain._dictOfRedirectedFuncs domain2.nPoints = domain.nPoints domain2.isMultiPoint = True domain = domain2 domain.useAsMutable = True r = {} Dep = (Self._getDep() if not Self.is_oovar else set([Self])).intersection( domain.keys()) for i, v in enumerate(Dep): domain.modificationVar = v r_l, r_u = _iqg(Self, domain, dtype, r0) if useSlicing and r_l is not r0: # r_l is r0 when array_equal(lb, ub) lf1, lf2, uf1, uf2 = r_l.lb, r_u.lb, r_l.ub, r_u.ub Lf1, Lf2, Uf1, Uf2 = Copy(r0.lb), Copy(r0.lb), Copy(r0.ub), Copy( r0.ub) Lf1[:, j], Lf2[:, j], Uf1[:, j], Uf2[:, j] = lf1, lf2, uf1, uf2 r_l.lb, r_u.lb, r_l.ub, r_u.ub = Lf1, Lf2, Uf1, Uf2 if type(r0.definiteRange) not in (bool, bool_): d1, d2 = r_l.definiteRange, r_u.definiteRange D1, D2 = atleast_1d(r0.definiteRange).copy(), atleast_1d( r0.definiteRange).copy() D1[j], D2[j] = d1, d2 r_l.definiteRange, r_u.definiteRange = D1, D2 r[v] = r_l, r_u if not Self.isUncycled: lf1, lf2, uf1, uf2 = r_l.lb, r_u.lb, r_l.ub, r_u.ub lf, uf = nanmin(vstack((lf1, lf2)), 0), nanmax(vstack((uf1, uf2)), 0) if i == 0: L, U = lf.copy(), uf.copy() else: L[L < lf] = lf[L < lf].copy() U[U > uf] = uf[U > uf].copy() if not Self.isUncycled: for R in r.values(): r1, r2 = R if type(r1.lb) != np.ndarray: r1.lb, r2.lb, r1.ub, r2.ub = atleast_1d(r1.lb), atleast_1d( r2.lb), atleast_1d(r1.ub), atleast_1d(r2.ub) r1.lb[r1.lb < L] = L[r1.lb < L] r2.lb[r2.lb < L] = L[r2.lb < L] r1.ub[r1.ub > U] = U[r1.ub > U] r2.ub[r2.ub > U] = U[r2.ub > U] r0.lb[r0.lb < L] = L[r0.lb < L] r0.ub[r0.ub > U] = U[r0.ub > U] # for more safety domain.useSave = True domain.useAsMutable = False domain.modificationVar = None domain.storedIntervals = {} return r, r0
def extract(self, ind): Ind = ind if ind.dtype != bool else where(ind)[0] definiteRange = self.definiteRange if type(self.definiteRange) == bool \ or self.definiteRange.size == 1 else self.definiteRange[ind] return boundsurf2(self.l.extract(Ind), self.u.extract(Ind), definiteRange, self.domain)
def aux_mul_div_boundsurf(Elems, op, resolveSchedule=()): _r = [] _resolved = [] changeSign = False indZ = False definiteRange = np.array(True) for elem in Elems: _R = elem.resolve()[0] lb, ub = _R ind_positive, ind_negative, ind_z = Split(lb >= 0, ub <= 0) not_ind_negative = logical_not(ind_negative) changeSign = logical_xor(changeSign, ind_negative) indZ = logical_or(indZ, ind_z) tmp1 = elem.extract(not_ind_negative) tmp2 = -elem.extract(ind_negative) Tmp = boundsurf_join((not_ind_negative, ind_negative), (tmp1, tmp2))#.log() _r.append(Tmp) _resolved.append(_R) definiteRange = logical_and(definiteRange, elem.definiteRange) use_exp = True if op == operator.mul: if len(_r) == 2 and _r[0].level == _r[1].level == 1 and _r[0].b2equiv(_r[1]): rr = b2mult(_r[0], _r[1]) use_exp = False else: rr = PythonSum(elem.log() for elem in _r)#.exp() else: assert op == operator.truediv and len(Elems) == 2 if 1 and _r[1].level == 1 and _r[0].b2equiv(_r[1]): rr = b2div(_r[0], _r[1]) use_exp = False else: rr = (_r[0].log() - _r[1].log())#.exp() changeSign = logical_and(changeSign, logical_not(indZ)) keepSign = logical_and(logical_not(changeSign), logical_not(indZ)) if use_exp: if len(resolveSchedule): rr = rr.exclude(resolveSchedule) if type(rr) == np.ndarray: #print('asdf') r = np.exp(rr) r[:, changeSign] = -r[:, changeSign][::-1] return r#, definiteRange # print len(rr.dep) rr = rr.exp() # print type(rr) # if type(rr) != boundsurf: # print(rr.l.d2, rr.l.d, rr.l.c, '----', rr.u.d2, rr.u.d, rr.u.c) _rr, _inds = [], [] if any(keepSign): _rr.append(rr.extract(keepSign)) _inds.append(keepSign) if any(changeSign): _rr.append(-rr.extract(changeSign)) _inds.append(changeSign) if any(indZ): assert len(Elems) == 2, 'unimplemented yet' lb1, ub1 = Elems[0].resolve()[0] # R1 other_lb, other_ub = Elems[1].resolve()[0] # R2 IndZ = where(indZ)[0] tmp_z = np.vstack(( op(lb1[IndZ], other_lb[IndZ]), op(ub1[IndZ], other_lb[IndZ]), op(lb1[IndZ], other_ub[IndZ]), op(ub1[IndZ], other_ub[IndZ]) )) l_z, u_z = nanmin(tmp_z, 0), nanmax(tmp_z, 0) rr_z = boundsurf(surf({}, l_z), surf({}, u_z), True, Elems[0].domain) _rr.append(rr_z) _inds.append(indZ) rr = boundsurf_join(_inds, _rr) rr.definiteRange = definiteRange return rr
def defaultIntervalEngine(arg_lb_ub, fun, deriv, monotonity, convexity, criticalPoint = np.nan, criticalPointValue = np.nan, feasLB = -inf, feasUB = inf, domain_ind = slice(None), R0 = None): #monotonity = nan assert type(monotonity) != bool and type(convexity) != bool, 'bug in defaultIntervalEngine' Ld2, Ud2 = getattr(arg_lb_ub.l,'d2', {}), getattr(arg_lb_ub.u,'d2', {}) # DEBUG!!!!!!!!!!!!!!!!! # if (len(Ld2) != 0 or len(Ud2) != 0): # arg_lb_ub = arg_lb_ub.to_linear() # Ld2, Ud2 = {}, {} # !! TODO: handle monotonity = nan with boundsurf2 #if (len(Ld2) != 0 or len(Ud2) != 0) and np.isnan(monotonity): if arg_lb_ub.level == 2 and np.isnan(monotonity): arg_lb_ub = arg_lb_ub.to_linear() Ld2, Ud2 = {}, {} L, U, domain, definiteRange = arg_lb_ub.l, arg_lb_ub.u, arg_lb_ub.domain, arg_lb_ub.definiteRange Ld, Ud = L.d, U.d if type(domain_ind) == np.ndarray: if domain_ind.dtype == bool: domain_ind = where(domain_ind)[0] Ld, Ud = dict_reduce(Ld, domain_ind), dict_reduce(Ud, domain_ind) Ld2, Ud2 = dict_reduce(Ld2, domain_ind), dict_reduce(Ud2, domain_ind) R0 = (arg_lb_ub.resolve()[0] if R0 is None else R0)[:, domain_ind] if type(definiteRange) != bool and definiteRange.size > 1: definiteRange = definiteRange[domain_ind] elif R0 is None: R0 = arg_lb_ub.resolve()[0] #R0 = arg_lb_ub.resolve(ind = domain_ind)[0] assert R0.shape[0]==2, 'unimplemented yet' if feasLB != -inf or feasUB != inf: R0, definiteRange = adjustBounds(R0, definiteRange, feasLB, feasUB) r_l, r_u = R0 R2 = fun(R0) ind_inf = where(np.logical_or(np.isinf(R2[0]), np.isinf(R2[1])))[0] koeffs = (R2[1] - R2[0]) / (r_u - r_l) koeffs[ind_inf] = 0.0 ind_eq = where(r_u == r_l)[0] if monotonity == 1: new_l_resolved, new_u_resolved = R2 U_dict, L_dict = Ud, Ld U2_dict, L2_dict = Ud2, Ld2 _argmin, _argmax = r_l, r_u elif monotonity == -1: new_u_resolved, new_l_resolved = R2 U_dict, L_dict = Ld, Ud U2_dict, L2_dict = Ld2, Ud2 _argmin, _argmax = r_u, r_l else: assert arg_lb_ub.level < 2, 'unimplemented' ind = R2[1] > R2[0] R2.sort(axis=0) new_l_resolved, new_u_resolved = R2 _argmin = where(ind, r_l, r_u) _argmax = where(ind, r_u, r_l) if criticalPoint is not np.nan: ind_c = logical_and(r_l < criticalPoint, r_u > criticalPoint) if convexity == 1: new_l_resolved[ind_c] = criticalPointValue _argmin[ind_c] = criticalPoint elif convexity == -1: new_u_resolved[ind_c] = criticalPointValue _argmax[ind_c] = criticalPoint Keys = set().union(set(Ld.keys()), set(Ud.keys())) L_dict = dict((k, where(ind, Ld.get(k, 0), Ud.get(k, 0))) for k in Keys) U_dict = dict((k, where(ind, Ud.get(k, 0), Ld.get(k, 0))) for k in Keys) if len(Ld2) != 0 or len(Ud2) != 0: L2_dict = dict((k, where(ind, Ld2.get(k, 0), Ud2.get(k, 0))) for k in Keys) U2_dict = dict((k, where(ind, Ud2.get(k, 0), Ld2.get(k, 0))) for k in Keys) else: L2_dict = U2_dict = {} if convexity == -1: tmp2 = deriv(_argmax.view(multiarray)).view(ndarray).flatten() tmp2[np.isinf(tmp2)] = 0.0 tmp2[ind_inf] = 0.0 d_new = dict((v, tmp2 * val) for v, val in U_dict.items()) if len(U2_dict) == 0: U_new = surf(d_new, 0.0) else: d2_new = dict((v, tmp2 * val) for v, val in U2_dict.items()) U_new = surf2(d2_new, d_new, 0.0) U_new.c = new_u_resolved - U_new.maximum(domain, domain_ind) ind_inf2 = np.isinf(new_u_resolved) if any(ind_inf2): U_new.c = where(ind_inf2, new_u_resolved, U_new.c) if len(L_dict) >= 1 or len(L2_dict) >= 1: if ind_eq.size: koeffs[ind_eq] = tmp2[ind_eq] d_new = dict((v, koeffs * val) for v, val in L_dict.items()) if len(L2_dict) == 0: L_new = surf(d_new, 0.0) else: d2_new = dict((v, koeffs * val) for v, val in L2_dict.items()) L_new = surf2(d2_new, d_new, 0.0) L_new.c = new_l_resolved - L_new.minimum(domain, domain_ind) if any(ind_inf2): L_new.c = where(ind_inf2, new_l_resolved, L_new.c) else: L_new = surf({}, new_l_resolved) elif convexity == 1: tmp2 = deriv(_argmin.view(multiarray)).view(ndarray).flatten() tmp2[np.isinf(tmp2)] = 0.0 tmp2[ind_inf] = 0.0 d_new = dict((v, tmp2 * val) for v, val in L_dict.items()) if len(L2_dict) == 0: L_new = surf(d_new, 0.0) else: d2_new = dict((v, tmp2 * val) for v, val in L2_dict.items()) L_new = surf2(d2_new, d_new, 0.0) L_new.c = new_l_resolved - L_new.minimum(domain, domain_ind) ind_inf2 = np.isinf(new_l_resolved) if any(ind_inf2): L_new.c = where(ind_inf2, new_l_resolved, L_new.c) if len(U_dict) >= 1 or len(U2_dict) >= 1: if ind_eq.size: koeffs[ind_eq] = tmp2[ind_eq] d_new = dict((v, koeffs * val) for v, val in U_dict.items()) if len(U2_dict) == 0: U_new = surf(d_new, 0.0) else: d2_new = dict((v, koeffs * val) for v, val in U2_dict.items()) U_new = surf2(d2_new, d_new, 0.0) U_new.c = new_u_resolved - U_new.maximum(domain, domain_ind) if any(ind_inf2): U_new.c = where(ind_inf2, new_u_resolved, U_new.c) else: U_new = surf({}, new_u_resolved) elif convexity == -101: if monotonity == 1: argvals = (_argmax, _argmin) vals = (new_u_resolved, new_l_resolved)[::-1] Attributes = ('maximum', 'minimum') elif monotonity == -1: argvals = (_argmin, _argmax) vals = (new_l_resolved, new_u_resolved) Attributes = ('minimum', 'maximum') else: assert 0 tmp2 = deriv(argvals[0].view(multiarray)).view(ndarray).flatten() ind_k = where((tmp2 > koeffs) if monotonity == 1 else (tmp2 < koeffs))[0] tmp2[ind_k] = koeffs[ind_k] tmp2[np.isinf(tmp2)] = 0.0 tmp2[ind_inf] = 0.0 d_new = dict((v, tmp2 * val) for v, val in U_dict.items()) if len(L2_dict) == 0: L_new = surf(d_new, 0.0) else: d2_new = dict((v, tmp2 * val) for v, val in U2_dict.items()) L_new = surf2(d2_new, d_new, 0.0) L_new.c = vals[0] - getattr(L_new, Attributes[0])(domain, domain_ind) # L_new.c = vals[0] - L_new.minimum(domain, domain_ind) # L_new.c = new_l_resolved - L_new.minimum(domain, domain_ind) ind_inf2 = np.isinf(vals[0]) if any(ind_inf2): L_new.c = where(ind_inf2, new_l_resolved, L_new.c) tmp2 = deriv(argvals[1].view(multiarray)).view(ndarray).flatten() ind_k = where((tmp2 > koeffs) if monotonity == 1 else (tmp2 < koeffs))[0] tmp2[ind_k] = koeffs[ind_k] tmp2[np.isinf(tmp2)] = 0.0 tmp2[ind_inf] = 0.0 d_new = dict((v, tmp2 * val) for v, val in L_dict.items()) # U_new = surf(d_new, 0.0) if len(L2_dict) == 0: U_new = surf(d_new, 0.0) else: d2_new = dict((v, koeffs * val) for v, val in L2_dict.items()) U_new = surf2(d2_new, d_new, 0.0) U_new.c = vals[1] - getattr(U_new, Attributes[1])(domain, domain_ind) # U_new.c = vals[1] - U_new.maximum(domain, domain_ind) # U_new.c = new_u_resolved - U_new.maximum(domain, domain_ind) ind_inf2 = np.isinf(vals[1]) if any(ind_inf2): U_new.c = where(ind_inf2, new_u_resolved, U_new.c) elif convexity == 9: # 1 0 -1 if monotonity == 1: argvals = (_argmin, _argmax) vals = (new_l_resolved, new_u_resolved) Attributes = ('minimum', 'maximum') elif monotonity == -1: argvals = (_argmax, _argmin) vals = (new_u_resolved, new_l_resolved)[::-1] Attributes = ('maximum','minimum') else: assert 0 tmp2 = deriv(argvals[0].view(multiarray)).view(ndarray).flatten() ind_k = where(tmp2 > koeffs)[0] tmp2[ind_k] = koeffs[ind_k] tmp2[np.isinf(tmp2)] = 0.0 tmp2[ind_inf] = 0.0 d_new = dict((v, tmp2 * val) for v, val in L_dict.items()) if len(L2_dict) == 0: L_new = surf(d_new, 0.0) else: d2_new = dict((v, tmp2 * val) for v, val in L2_dict.items()) L_new = surf2(d2_new, d_new, 0.0) L_new.c = vals[0] - getattr(L_new, Attributes[0])(domain, domain_ind) ind_inf2 = np.isinf(vals[0]) if any(ind_inf2): L_new.c = where(ind_inf2, vals[0], L_new.c) tmp2 = deriv(argvals[1].view(multiarray)).view(ndarray).flatten() ind_k = where(tmp2 > koeffs)[0] tmp2[ind_k] = koeffs[ind_k] tmp2[np.isinf(tmp2)] = 0.0 tmp2[ind_inf] = 0.0 d_new = dict((v, tmp2 * val) for v, val in U_dict.items()) if len(U2_dict) == 0: U_new = surf(d_new, 0.0) else: d2_new = dict((v, tmp2 * val) for v, val in U2_dict.items()) U_new = surf2(d2_new, d_new, 0.0) U_new.c = vals[1] - getattr(U_new, Attributes[1])(domain, domain_ind) ind_inf2 = np.isinf(vals[1]) if any(ind_inf2): U_new.c = where(ind_inf2, vals[1], U_new.c) else: # linear oofuns with convexity = 0 calculate their intervals in other funcs raise FuncDesignerException('bug in FD kernel') if type(L_new) == type(U_new) == surf: R = boundsurf(L_new, U_new, definiteRange, domain) else: R = boundsurf2(L_new, U_new, definiteRange, domain) if not np.all(definiteRange): ind1 = where(definiteRange)[0] r1 = R.extract(ind1) ind2 = where(logical_not(definiteRange))[0] r2 = boundsurf(surf({}, new_l_resolved[ind2]), surf({}, new_u_resolved[ind2]), definiteRange[ind2] if type(definiteRange)==ndarray and definiteRange.size != 1 else definiteRange, domain) R = boundsurf_join((ind1, ind2), (r1, r2)) return R, definiteRange
def pow_const_interval(self, r, other, domain, dtype): lb_ub, definiteRange = self._interval(domain, dtype, ia_surf_level = 2) isBoundSurf = isinstance(lb_ub, boundsurf) # changes if 1 and isBoundSurf and other == 2 and lb_ub.level == 1 and len(lb_ub.l.d) == 1 and len(lb_ub.u.d) == 1: L, U = lb_ub.l, lb_ub.u if lb_ub.l is lb_ub.u: d, c = L.d, L.c s_l = surf2(dict((k, v**2) for k, v in d.items()), dict((k, 2*v*c) for k, v in d.items()), c**2) return boundsurf2(s_l, s_l, definiteRange, domain), definiteRange lb_ub_resolved = lb_ub.resolve()[0] lb, ub = lb_ub_resolved ind_positive, ind_negative, ind_z = split(lb >= 0, ub <= 0) #new m = lb.size if ind_negative.size: ind_negative_bool = ub <= 0 lb_ub = lb_ub.invert(ind_negative_bool) L, U = lb_ub.l, lb_ub.u d_l, d_u = L.d, U.d ind = logical_or(lb >= 0, ub <= 0) Ind_nonz = where(ind)[0] if Ind_nonz.size != 0: d_u2 = dict_reduce(d_u, Ind_nonz) c = U.c if type(U.c) != ndarray or U.c.size == 1 else U.c[Ind_nonz] s_u = surf2(dict((k, v**2) for k, v in d_u2.items()), dict((k, 2*v*c) for k, v in d_u2.items()), c**2) d_l2 = dict_reduce(d_l, Ind_nonz) c = L.c if type(L.c) != ndarray or L.c.size == 1 else L.c[Ind_nonz] s_l = surf2(dict((k, v**2) for k, v in d_l2.items()), dict((k, 2*v*c) for k, v in d_l2.items()), c**2) r_nz = boundsurf2(s_l, s_u, False, domain) if Ind_nonz.size == m: r_nz.definiteRange = definiteRange return r_nz, definiteRange r0, definiteRange0 = defaultIntervalEngine(lb_ub, r.fun, r.d, monotonity = np.nan, convexity = 1, criticalPoint = 0.0, criticalPointValue = 0.0, domain_ind = ind_z) if Ind_nonz.size == 0: return r0, definiteRange r = boundsurf_join((Ind_nonz, ind_z), (r_nz, r0)) #!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! r.definiteRange = definiteRange #################### return r, definiteRange #prev # L, U = lb_ub.l, lb_ub.u # d, c = L.d, L.c # s_l = surf2(dict((k, v**2) for k, v in d.items()), dict((k, 2*v*c) for k, v in d.items()), c**2) # # if lb_ub.l is lb_ub.u: # return boundsurf2(s_l, s_l, definiteRange, domain), definiteRange # # d, c = U.d, U.c # lb_ub_resolved = lb_ub.resolve()[0] # if all(lb_ub_resolved >= 0): # s_u = surf2(dict((k, v**2) for k, v in d.items()), dict((k, 2*v*c) for k, v in d.items()), c**2) # return boundsurf2(s_l, s_u, definiteRange, domain), definiteRange # elif all(lb_ub_resolved <= 0): # s_u = s_l # s_l = surf2(dict((k, v**2) for k, v in d.items()), dict((k, 2*v*c) for k, v in d.items()), c**2) # return boundsurf2(s_l, s_u, definiteRange, domain), definiteRange # changes end lb_ub_resolved = lb_ub.resolve()[0] if isBoundSurf else lb_ub # TODO: implement SP if lb_ub_resolved.dtype == object: pWarn(''' interalg results for this stochastic problem with solver interalg can be incorrect yet''') arg_isNonNegative = lb_ub_resolved.dtype != object and all(lb_ub_resolved >= 0) arg_isNonPositive = lb_ub_resolved.dtype != object and all(lb_ub_resolved <= 0) #changes # !!!!!!!TODO: rdiv beyond arg_isNonNegative, arg_isNonPositive if 1 and other == -1 and (arg_isNonNegative or arg_isNonPositive) and isBoundSurf and len(lb_ub.dep)==1: return inv_b_interval(lb_ub, revert = arg_isNonPositive) # TODO: remove arg_isNonNegative if 1 and 0 < other < 1 and 1 and isBoundSurf and len(lb_ub.dep)==1: return pow_interval(r, self, other, domain, dtype) #changes end other_is_int = asarray(other, int) == other isOdd = other_is_int and other % 2 == 1 if isBoundSurf and not any(np.isinf(lb_ub_resolved)): #new # if arg_isNonNegative: # return defaultIntervalEngine(lb_ub, r.fun, r.d, # monotonity = 1, # convexity = 1 if other > 1.0 or other < 0 else -1) # # if other_is_int and other > 0 and other % 2 == 0: # return devided_interval(self, r, domain, dtype) #prev if arg_isNonNegative:# or (other_is_int and other > 0 and other % 2 == 0): return defaultIntervalEngine(lb_ub, r.fun, r.d, monotonity = 1 if other > 0 and arg_isNonNegative else -1 if arg_isNonNegative and other < 0 else np.nan, convexity = 1 if other > 1.0 or other < 0 else -1, criticalPoint = 0.0, criticalPointValue = 0.0) if other_is_int and other > 0 and other % 2 == 0: return defaultIntervalEngine(lb_ub, r.fun, r.d, monotonity = np.nan, convexity = 1, criticalPoint = 0.0, criticalPointValue = 0.0) feasLB = -inf if other_is_int else 0.0 if other > 0 or arg_isNonPositive: return devided_interval(self, r, domain, dtype, feasLB = feasLB) if other_is_int and other < 0:# and other % 2 != 0: lb, ub = lb_ub_resolved ind_positive, ind_negative, ind_z = split(lb >= 0, ub <= 0) B, inds = [], [] if ind_positive.size: inds.append(ind_positive) monotonity = -1 b = defaultIntervalEngine(lb_ub, r.fun, r.d, monotonity = monotonity, convexity = 1, domain_ind = ind_positive)[0] B.append(b) if ind_negative.size: inds.append(ind_negative) # TODO: fix it monotonity = -1 if isOdd else 1 convexity = -1 if isOdd else 1 b = defaultIntervalEngine(lb_ub, r.fun, r.d, monotonity = monotonity, convexity = convexity, domain_ind = ind_negative)[0] B.append(b) if ind_z.size: inds.append(ind_z) t = 1.0 / lb_ub_resolved[:, ind_z] t.sort(axis=0) update_negative_int_pow_inf_zero(lb_ub_resolved[0, ind_z], lb_ub_resolved[1, ind_z], t, other) b = boundsurf( surf({}, t[0]), surf({}, t[1]), definiteRange if type(definiteRange) == bool or definiteRange.size == 1 \ else definiteRange[ind_z], domain) B.append(b) r = boundsurf_join(inds, B) return r, r.definiteRange lb_ub = lb_ub_resolved lb, ub = lb_ub if lb_ub.dtype != object else (lb_ub[0, 0], lb_ub[1, 0]) Tmp = lb_ub ** other # correct nan handling #Tmp.sort(axis = 0) T = Tmp[0]>Tmp[1] if Tmp.dtype != object else Tmp[0].item() > Tmp[1].item() ind = where(T)[0] if ind.size: # PyPy doesn't work w/o this check Tmp[0, ind], Tmp[1, ind] = Tmp[1, ind], Tmp[0, ind] if not other_is_int or not isOdd: ind_z = logical_and(lb < 0, ub >= 0) assert type(ind_z) in (np.ndarray, bool, np.bool_) if any(ind_z): Ind_z = where(ind_z)[0] if (not other_is_int and other > 0) or not isOdd: # print ind_z, type(ind_z), ind_z.shape # print Tmp Tmp[0, Ind_z] = 0.0 if other < 0: Tmp[1, Ind_z] = inf if not other_is_int: definiteRange = logical_and(definiteRange, logical_not(ind_z)) Tmp.sort(axis = 0) if other < 0 and other_is_int: update_negative_int_pow_inf_zero(lb, ub, Tmp, other) return Tmp, definiteRange
def iqg(Self, domain, dtype = float, lb=None, ub=None, UB = None): if type(domain) != ooPoint: domain = ooPoint(domain, skipArrayCast=True) domain.isMultiPoint=True domain.useSave = True r0 = Self.interval(domain, dtype, resetStoredIntervals = False) r0.lb, r0.ub = atleast_1d(r0.lb).copy(), atleast_1d(r0.ub).copy() # is copy required? # TODO: get rid of useSave domain.useSave = False # TODO: rework it with indexation of required data if lb is not None and ub is not None: ind = logical_or(logical_or(r0.ub < lb, r0.lb > ub), all(logical_and(r0.lb >= lb, r0.ub <= ub))) elif UB is not None: ind = r0.lb > UB else: ind = None useSlicing = False if ind is not None: if all(ind): return {}, r0 j = where(~ind)[0] #DOESN'T WORK FOR FIXED OOVARS AND DefiniteRange != TRUE YET if 0 and j.size < 0.85*ind.size: # at least 15% of values to skip useSlicing = True tmp = [] for key, val in domain.storedIntervals.items(): Interval, definiteRange = val if type(definiteRange) not in (bool, bool_): definiteRange = definiteRange[j] tmp.append((key, (Interval[:, j], definiteRange))) _storedIntervals = dict(tmp) Tmp = [] for key, val in domain.storedSums.items(): # TODO: rework it R0, DefiniteRange0 = val.pop(-1) #R0, DefiniteRange0 = val[-1] R0 = R0[:, j] if type(DefiniteRange0) not in (bool, bool_): DefiniteRange0 = DefiniteRange0[j] tmp = [] for k,v in val.items(): # TODO: rework it # if k is (-1): continue v = v[:, j] tmp.append((k,v)) val = dict(tmp) val[-1] = (R0, DefiniteRange0) Tmp.append((key,val)) _storedSums = dict(Tmp) #domain.storedSums = dict(tmp) Tmp = [] for key, val in domain.items(): lb_,ub_ = val # TODO: rework it when lb, ub will be implemented as 2-dimensional Tmp.append((key, (lb_[j],ub_[j]))) dictOfFixedFuncs = domain.dictOfFixedFuncs domain2 = ooPoint(Tmp, skipArrayCast=True) domain2.storedSums = _storedSums domain2.storedIntervals = _storedIntervals domain2.dictOfFixedFuncs = dictOfFixedFuncs domain2.isMultiPoint=True domain = domain2 domain.useAsMutable = True r = {} Dep = (Self._getDep() if not Self.is_oovar else set([Self])).intersection(domain.keys()) for i, v in enumerate(Dep): domain.modificationVar = v r_l, r_u = _iqg(Self, domain, dtype, r0) if useSlicing and r_l is not r0:# r_l is r0 when array_equal(lb, ub) lf1, lf2, uf1, uf2 = r_l.lb, r_u.lb, r_l.ub, r_u.ub Lf1, Lf2, Uf1, Uf2 = Copy(r0.lb), Copy(r0.lb), Copy(r0.ub), Copy(r0.ub) Lf1[:, j], Lf2[:, j], Uf1[:, j], Uf2[:, j] = lf1, lf2, uf1, uf2 r_l.lb, r_u.lb, r_l.ub, r_u.ub = Lf1, Lf2, Uf1, Uf2 if type(r0.definiteRange) not in (bool, bool_): d1, d2 = r_l.definiteRange, r_u.definiteRange D1, D2 = atleast_1d(r0.definiteRange).copy(), atleast_1d(r0.definiteRange).copy() D1[j], D2[j] = d1, d2 r_l.definiteRange, r_u.definiteRange = D1, D2 r[v] = r_l, r_u if not Self.isUncycled: lf1, lf2, uf1, uf2 = r_l.lb, r_u.lb, r_l.ub, r_u.ub lf, uf = nanmin(vstack((lf1, lf2)), 0), nanmax(vstack((uf1, uf2)), 0) if i == 0: L, U = lf.copy(), uf.copy() else: L[L<lf] = lf[L<lf].copy() U[U>uf] = uf[U>uf].copy() if not Self.isUncycled: for R in r.values(): r1, r2 = R if type(r1.lb) != np.ndarray: r1.lb, r2.lb, r1.ub, r2.ub = atleast_1d(r1.lb), atleast_1d(r2.lb), atleast_1d(r1.ub), atleast_1d(r2.ub) r1.lb[r1.lb < L] = L[r1.lb < L] r2.lb[r2.lb < L] = L[r2.lb < L] r1.ub[r1.ub > U] = U[r1.ub > U] r2.ub[r2.ub > U] = U[r2.ub > U] r0.lb[r0.lb < L] = L[r0.lb < L] r0.ub[r0.ub > U] = U[r0.ub > U] # for more safety domain.useSave = True domain.useAsMutable = False domain.modificationVar = None domain.storedIntervals = {} return r, r0
class surf(object): isRendered = False __array_priority__ = 15 def __init__(self, d, c): self.d = d # dict of variables and linear coefficients on them (probably as multiarrays) self.c = np.asarray(c) # (multiarray of) constant(s) value = lambda self, point: self.c + PythonSum(point[k] * v for k, v in self.d.items()) # def invert(self, ind=None): # ind_is_None = ind is None # C = -self.c if ind_is_None else where(ind, -self.c, self.c) # D = dict((k, # (-v if ind_is_None else where(ind, -v, v))) \ # for k, v in self.d.items()) # if 'd2' not in self.__dict__: # return surf(D, C) # from boundsurf2 import surf2 # D2 = dict((k, # (-v if ind_is_None else where(ind, -v, v))) \ # for k, v in self.d2.items()) # return surf2(D2, D, C) # resolve = lambda self, domain, cmp: \ # self.c + PythonSum(where(cmp(v, 0), domain[k][0], domain[k][1])*v for k, v in self.d.items()) def exclude(self, domain, oovars, cmp): C = [] d = self.d.copy() for v in oovars: tmp = d.pop(v, 0.0) if any(tmp): D = domain[v] C.append(where(cmp(tmp, 0), D[0], D[1]) * tmp) c = self.c + PythonSum(C) return surf(d, c) # split = lambda self, inds: [extract(self, ind) for ind in inds] #self.resolve(domain, GREATER) minimum = lambda self, domain, domain_ind = None: \ self.c +\ (PythonSum(where(v > 0, domain[k][0], domain[k][1])*v for k, v in self.d.items()) if domain_ind is None else PythonSum(where(v > 0, domain[k][0][domain_ind], domain[k][1][domain_ind])*v for k, v in self.d.items())) #self.resolve(domain, LESS) maximum = lambda self, domain, domain_ind = None: \ self.c +\ (PythonSum(where(v < 0, domain[k][0], domain[k][1])*v for k, v in self.d.items()) if domain_ind is None else PythonSum(where(v < 0, domain[k][0][domain_ind], domain[k][1][domain_ind])*v for k, v in self.d.items())) def render(self, domain, cmp): self.rendered = dict( (k, where(cmp(v, 0), domain[k][0], domain[k][1]) * v) for k, v in self.d.items()) self.resolved = PythonSum(self.rendered) + self.c self.isRendered = True def extract(self, ind): # if ind.dtype == bool: # ind = where(ind)[0] d = dict((k, v if v.size == 1 else v[ind]) for k, v in self.d.items()) C = self.c c = C if C.size == 1 else C[ind] return surf(d, c) def __add__(self, other): if type(other) == surf: # if other.isRendered and not self.isRendered: # self, other = other, self S, O = self.d, other.d d = S.copy() d.update(O) for key in set(S.keys()) & set(O.keys()): d[key] = S[key] + O[key] return surf(d, self.c + other.c) elif isscalar(other) or type(other) == np.ndarray: return surf(self.d, self.c + other) elif isinstance(other, surf): # surf2 class instance return other + self else: assert 0, 'unimplemented yet' __sub__ = lambda self, other: self.__add__(-other) __neg__ = lambda self: surf(dict( (k, -v) for k, v in self.d.items()), -self.c) def __mul__(self, other): isArray = type(other) == np.ndarray if isscalar(other) or isArray: return surf(dict((k, v * other) for k, v in self.d.items()), self.c * other) else: assert 0, 'unimplemented yet' __rmul__ = __mul__
def b2div(Self, Other): # Self and Other must be nonnegative assert Other.level == 1 and Self.b2equiv(Other) DefiniteRange = Self.definiteRange & Other.definiteRange domain = Self.domain is_b2 = Self.level == 2 k = list(Self.dep)[0] L, U = Self.domain[k] # L if is_b2: h = Self.l.d2.get(k, 0.0) d1, d2 = Self.l.d[k], Other.u.d[k] c1, c2 = Self.l.c, Other.u.c ind_Z_l = d2 == 0.0 ind_z_l = where(ind_Z_l)[0] if ind_z_l.size: d_z_l = where(ind_Z_l, d1 / c2, 0.0) c_z_l = where(ind_Z_l, c1 / c2, 0.0) if is_b2: h_z_l = where(ind_Z_l, h / c2, 0.0) if is_b2: H1 = h / d2 a1 = (d1 - h * c2 / d2) / d2 else: a1 = d1 / d2 b1 = c1 - a1 * c2 ind_negative = b1 < 0 ind_b_negative_l = where(ind_negative)[0] ind_b_positive_l = where(logical_not(ind_negative))[0] b1[ind_b_negative_l] = -b1[ind_b_negative_l] d = {k: d2} c = c2 s_l = surf(d, c) # U if is_b2: h = Self.u.d2.get(k, 0.0) d1, d2 = Self.u.d[k], Other.l.d[k] c1, c2 = Self.u.c, Other.l.c ind_Z_u = d2 == 0.0 ind_z_u = where(ind_Z_u)[0] if ind_z_u.size: d_z_u = where(ind_Z_u, d1 / c2, 0.0) c_z_u = where(ind_Z_u, c1 / c2, 0.0) if is_b2: h_z_u = where(ind_Z_u, h / c2, 0.0) if is_b2: H2 = h / d2 a2 = (d1 - h * c2 / d2) / d2 else: a2 = d1 / d2 b2 = c1 - a2 * c2 ind_negative = b2 < 0 ind_b_negative_u = where(ind_negative)[0] ind_b_positive_u = where(logical_not(ind_negative))[0] b2[ind_b_negative_u] = -b2[ind_b_negative_u] d = {k: d2} c = c2 s_u = surf(d, c) tmp = boundsurf(s_l, s_u, DefiniteRange, domain) from Interval import inv_b_interval B = inv_b_interval(tmp, revert=False)[0] sl, su = B.l, B.u from boundsurf2 import boundsurf2, surf2 P = 1e11 sl2 = surf_join((ind_b_positive_l, ind_b_negative_l), \ (sl.extract(ind_b_positive_l), -su.extract(ind_b_negative_l)))*b1 ind_numericaly_unstable_l = P * np.abs(sl2.c + a1) < np.abs( sl2.c) + np.abs(a1) sl2 += a1 su2 = surf_join((ind_b_positive_u, ind_b_negative_u), \ (su.extract(ind_b_positive_u), -sl.extract(ind_b_negative_u)))*b2 ind_numericaly_unstable_u = P * np.abs(su2.c + a2) < np.abs( su2.c) + np.abs(a2) su2 += a2 if is_b2: ind_numericaly_unstable_l = logical_or( ind_numericaly_unstable_l, P * np.abs(sl2.d.get(k, 0.0) + H1) < np.abs(sl2.d.get(k, 0.0)) + np.abs(H1)) ind_numericaly_unstable_u = logical_or( ind_numericaly_unstable_u, P * np.abs(su2.d.get(k, 0.0) + H2) < np.abs(su2.d.get(k, 0.0)) + np.abs(H2)) sl2.d[k] = sl2.d.get(k, 0.0) + H1 su2.d[k] = su2.d.get(k, 0.0) + H2 if ind_z_l.size: ind_nz_l = where(logical_not(ind_Z_l))[0] sl2 = surf_join((ind_nz_l, ind_z_l), \ (sl.extract(ind_nz_l), surf2({k:0}, {k:d_z_l}, c_z_l))) if is_b2: sl2.d2[k] = sl2.d2.get(k, 0.0) + h_z_l if ind_z_u.size: ind_nz_u = where(logical_not(ind_Z_u))[0] su2 = surf_join((ind_nz_u, ind_z_u), \ (su.extract(ind_nz_u), surf2({k:0}, {k:d_z_u}, c_z_u))) if is_b2: su2.d2[k] = su2.d2.get(k, 0.0) + h_z_u r = boundsurf2(sl2, su2, DefiniteRange, domain) ind_numericaly_unstable = logical_or(ind_numericaly_unstable_l, ind_numericaly_unstable_u) if any(ind_numericaly_unstable): ind_numericaly_stable = logical_not(ind_numericaly_unstable) # print where(ind_numericaly_stable)[0].size, where(ind_numericaly_unstable)[0].size r2 = (Self.log() - Other.log()).exp() r = boundsurf_join((ind_numericaly_unstable, ind_numericaly_stable), \ (r2.extract(ind_numericaly_unstable), r.extract(ind_numericaly_stable))) return r
def mul_fixed_interval(self, R2): if type(self) == boundsurf: Boundsurf = boundsurf else: from boundsurf2 import boundsurf2 Boundsurf = boundsurf2 domain = self.domain definiteRange = self.definiteRange assert R2.shape[0] == 2, 'bug or unimplemented yet' R2Positive = all(R2 >= 0) R2Negative = all(R2 <= 0) R1 = self.resolve()[0] selfPositive = all(R1 >= 0) selfNegative = all(R1 <= 0) SelfSameBounds = self.l is self.u # print('0', SelfSameBounds, selfPositive, selfNegative) if 1 and SelfSameBounds and (selfPositive or selfNegative): bound = self.l # equal to self.u # if selfPositive or selfNegative: rr = (bound * R2[0], bound * R2[1]) if selfPositive else (bound * R2[1], bound * R2[0]) elif selfPositive and R2Positive: rr = (self.l * R2[0], self.u * R2[1]) elif selfPositive and R2Negative: rr = (self.u * R2[0], self.l * R2[1]) elif selfNegative and R2Negative: rr = (self.u * R2[1], self.l * R2[0]) elif selfNegative and R2Positive: rr = (self.l * R2[1], self.u * R2[0]) elif R2Positive or R2Negative: lb1, ub1 = R1 ind_positive, ind_negative, ind_z = split(lb1 >= 0, ub1 <= 0) other_lb, other_ub = R2 if R2Positive else (-R2[1], -R2[0]) l, u = self.l, self.u tmp_l1 = other_lb[ind_positive] * l.extract(ind_positive) tmp_l2 = other_ub[ind_negative] * l.extract(ind_negative) tmp_u1 = other_ub[ind_positive] * u.extract(ind_positive) tmp_u2 = other_lb[ind_negative] * u.extract(ind_negative) # tmp_l3 = other_ub[ind_z] * l.extract(ind_z) # tmp_u3 = other_ub[ind_z] * u.extract(ind_z) l2, u2 = other_lb[ind_z], other_ub[ind_z] l1, u1 = lb1[ind_z], ub1[ind_z] Tmp = np.vstack((l1 * l2, l1 * u2, l2 * u1, u1 * u2)) tmp_l3 = surf({}, nanmin(Tmp, axis=0)) tmp_u3 = surf({}, nanmax(Tmp, axis=0)) tmp_l = surf_join((ind_positive, ind_negative, ind_z), (tmp_l1, tmp_l2, tmp_l3)) tmp_u = surf_join((ind_positive, ind_negative, ind_z), (tmp_u1, tmp_u2, tmp_u3)) # Inds, L, U = [], [], [] # if ind_positive.size: # tmp_l1 = other_lb[ind_positive] * l.extract(ind_positive) # tmp_u1 = other_ub[ind_positive] * u.extract(ind_positive) # Inds.append(ind_positive) # L.append(tmp_l1) # U.append(tmp_u1) # if ind_negative.size: # tmp_l2 = other_ub[ind_negative] * l.extract(ind_negative) # tmp_u2 = other_lb[ind_negative] * u.extract(ind_negative) # Inds.append(ind_negative) # L.append(tmp_l2) # U.append(tmp_u2) # if ind_z.size: # l2, u2 = other_lb[ind_z], other_ub[ind_z] # l1, u1 = lb1[ind_z], ub1[ind_z] # Tmp = np.vstack((l1*l2, l1*u2, l2*u1, u1*u2)) # tmp_l3 = surf({}, nanmin(Tmp, axis=0)) # tmp_u3 = surf({}, nanmax(Tmp, axis=0)) # Inds.append(ind_z) # L.append(tmp_l3) # U.append(tmp_u3) rr = (tmp_l, tmp_u) if R2Positive else (-tmp_u, -tmp_l) elif selfPositive or selfNegative: l, u = (self.l, self.u) if selfPositive else (-self.u, -self.l) lb1, ub1 = R1 other_lb, other_ub = R2 ind_other_positive, ind_other_negative, ind_z2 = split( other_lb >= 0, other_ub <= 0) Ind, Tmp_l, Tmp_u = [], [], [] if ind_other_positive.size: Ind.append(ind_other_positive) Tmp_l.append(other_lb[ind_other_positive] * l.extract(ind_other_positive)) Tmp_u.append(other_ub[ind_other_positive] * u.extract(ind_other_positive)) if ind_other_negative.size: Ind.append(ind_other_negative) Tmp_l.append(other_lb[ind_other_negative] * u.extract(ind_other_negative)) Tmp_u.append(other_ub[ind_other_negative] * l.extract(ind_other_negative)) # if 1: if ind_z2.size: uu = u.extract(ind_z2) Ind.append(ind_z2) Tmp_l.append(other_lb[ind_z2] * uu) Tmp_u.append(other_ub[ind_z2] * uu) # else: # l2, u2 = other_lb[ind_z2], other_ub[ind_z2] # l1, u1 = lb1[ind_z2], ub1[ind_z2] # Tmp = np.vstack((l1*l2, l1*u2, l2*u1, u1*u2)) # tmp_l3 = surf({}, nanmin(Tmp, axis=0)) # tmp_u3 = surf({}, nanmax(Tmp, axis=0)) tmp_l = surf_join(Ind, Tmp_l) tmp_u = surf_join(Ind, Tmp_u) rr = (tmp_l, tmp_u) if selfPositive else (-tmp_u, -tmp_l) else: # TODO: mb improve it lb1, ub1 = R1 lb2, ub2 = R2 l, u = self.l, self.u ind_other_positive, ind_other_negative, ind_z2 = Split( lb2 >= 0, ub2 <= 0) ind_positive, ind_negative, ind_z1 = Split(lb1 >= 0, ub1 <= 0) inds, lu = [], [] ind_Z = where(ind_z1)[0] if ind_Z.size: inds.append(ind_Z) l2, u2 = lb2[ind_Z], ub2[ind_Z] l1, u1 = lb1[ind_Z], ub1[ind_Z] Tmp = np.vstack((l1 * l2, l1 * u2, l2 * u1, u1 * u2)) tmp_l3 = surf({}, nanmin(Tmp, axis=0)) tmp_u3 = surf({}, nanmax(Tmp, axis=0)) lu.append((tmp_l3, tmp_u3)) ind_positive_all = logical_and(ind_positive, ind_other_positive) ind_Positive = where(ind_positive_all)[0] if ind_Positive.size: inds.append(ind_Positive) L = l.extract(ind_Positive) * lb2[ind_Positive] U = u.extract(ind_Positive) * ub2[ind_Positive] lu.append((L, U)) ind_negative_all = logical_and(ind_negative, ind_other_negative) ind_Negative = where(ind_negative_all)[0] if ind_Negative.size: inds.append(ind_Negative) U = l.extract(ind_Negative) * lb2[ind_Negative] L = u.extract(ind_Negative) * ub2[ind_Negative] lu.append((L, U)) ind = logical_and(ind_positive, ind_other_negative) Ind = where(ind)[0] if Ind.size: inds.append(Ind) L = u.extract(Ind) * lb2[Ind] U = l.extract(Ind) * ub2[Ind] lu.append((L, U)) ind = logical_and(ind_negative, ind_other_positive) Ind = where(ind)[0] if Ind.size: inds.append(Ind) L = l.extract(Ind) * ub2[Ind] U = u.extract(Ind) * lb2[Ind] lu.append((L, U)) ind = logical_and(ind_positive, ind_z2) Ind = where(ind)[0] if Ind.size: inds.append(Ind) uu = u.extract(Ind) L = uu * lb2[Ind] U = uu * ub2[Ind] lu.append((L, U)) ind = logical_and(ind_negative, ind_z2) Ind = where(ind)[0] if Ind.size: inds.append(Ind) ll = l.extract(Ind) L = ll * ub2[Ind] U = ll * lb2[Ind] lu.append((L, U)) # # ind = logical_and(ind_z1, ind_other_positive) # Ind = where(ind)[0] # if Ind.size: # print('8') # inds.append(Ind) # L = l.extract(Ind) * ub2[Ind] # U = u.extract(Ind) * ub2[Ind] # lu.append((L, U)) # # ind = logical_and(ind_z1, ind_other_negative) # Ind = where(ind)[0] # if Ind.size: # print('9') # inds.append(Ind) # L = u.extract(Ind) * lb2[Ind] # U = l.extract(Ind) * lb2[Ind] # lu.append((L, U)) # B = [Boundsurf(L, U, False, domain) for L, U in lu] rr = boundsurf_join(inds, B) rr.definiteRange = definiteRange R = Boundsurf(rr[0], rr[1], definiteRange, domain) if type(rr) == tuple else rr return R