def b2mult(Self, Other): assert Self.level == Other.level == 1 and Self.b2equiv(Other) lc = Self.l.c * Other.l.c uc = Self.u.c * Other.u.c if len(Self.dep): k = list(Self.dep)[0] ld = { k: Self.l.c * Other.l.d.get(k, 0.0) + Other.l.c * Self.l.d.get(k, 0.0) } ud = { k: Self.u.c * Other.u.d.get(k, 0.0) + Other.u.c * Self.u.d.get(k, 0.0) } ld2 = {k: Other.l.d.get(k, 0.0) * Self.l.d.get(k, 0.0)} ud2 = {k: Other.u.d.get(k, 0.0) * Self.u.d.get(k, 0.0)} else: assert len(Other.dep) == 0 return boundsurf(surf({}, lc), surf({}, uc), Self.definiteRange & Other.definiteRange, Self.domain) from boundsurf2 import surf2, boundsurf2 ls, us = surf2(ld2, ld, lc), surf2(ud2, ud, uc) r = boundsurf2(ls, us, Self.definiteRange & Other.definiteRange, Self.domain) return r
def inv_b_interval(B, revert): if type(B) == boundsurf2: B = B.to_linear() k = list(B.dep)[0] l, u = B.domain[k] d_l, d_u = B.l.d[k], B.u.d[k] c_l, c_u = B.l.c, B.u.c if revert: d_l, d_u = -d_u, -d_l c_l, c_u = -c_u, -c_l koeffs_l, koeffs_u = get_inv_b2_coeffs(l, u, d_l, d_u, c_l, c_u) # ########### # from boundsurf2 import apply_quad_lin # a, b, c = koeffs_l # s_l = apply_quad_lin(a, b, c, B.l) # a, b, c = koeffs_u # s_u = apply_quad_lin(a, b, c, B.u) # ########### # print koeffs_l, koeffs_u if revert: # c_l, c_u = -c_u, -c_l # d_l, d_u = -d_u, -d_l # B = -B koeffs_l, koeffs_u = -array(koeffs_u), -array(koeffs_l) ############# a, b, c = koeffs_l s_l = surf2({k:a}, {k:b}, c) a, b, c = koeffs_u s_u = surf2({k:a}, {k:b}, c) # ############### # if 0: # from numpy import linspace # x = linspace(l, u, 10000) # d_l, d_u = B.l.d[k], B.u.d[k] # c_l, c_u = B.l.c, B.u.c # import pylab # if 1: # pylab.plot(x, 1.0/(d_l*x+c_l), 'r', linewidth = 2) # pylab.plot(x, koeffs_l[0]*x**2+koeffs_l[1]*x+koeffs_l[2], 'b', linewidth = 1) # # else: # pylab.plot(x, 1.0/(d_u*x+c_u), 'b', linewidth = 2) # pylab.plot(x, koeffs_u[0]*x**2+koeffs_u[1]*x+koeffs_u[2], 'r', linewidth = 1) # pylab.grid() # pylab.show() # ############### return boundsurf2(s_l, s_u, B.definiteRange, B.domain), B.definiteRange
def inv_b_interval(B, revert): if type(B) == boundsurf2: B = B.to_linear() k = list(B.dep)[0] l, u = B.domain[k] d_l, d_u = B.l.d[k], B.u.d[k] c_l, c_u = B.l.c, B.u.c if revert: d_l, d_u = -d_u, -d_l c_l, c_u = -c_u, -c_l koeffs_l, koeffs_u = get_inv_b2_coeffs(l, u, d_l, d_u, c_l, c_u) # ########### # from boundsurf2 import apply_quad_lin # a, b, c = koeffs_l # s_l = apply_quad_lin(a, b, c, B.l) # a, b, c = koeffs_u # s_u = apply_quad_lin(a, b, c, B.u) # ########### # print koeffs_l, koeffs_u if revert: # c_l, c_u = -c_u, -c_l # d_l, d_u = -d_u, -d_l # B = -B koeffs_l, koeffs_u = -array(koeffs_u), -array(koeffs_l) ############# a, b, c = koeffs_l s_l = surf2({k:a}, {k:b}, c) a, b, c = koeffs_u s_u = surf2({k:a}, {k:b}, c) # ############### # if 0: # from numpy import linspace # x = linspace(l, u, 10000) # d_l, d_u = B.l.d[k], B.u.d[k] # c_l, c_u = B.l.c, B.u.c # import pylab # if 1: # pylab.plot(x, 1.0/(d_l*x+c_l), 'r', linewidth = 2) # pylab.plot(x, koeffs_l[0]*x**2+koeffs_l[1]*x+koeffs_l[2], 'b', linewidth = 1) # # else: # pylab.plot(x, 1.0/(d_u*x+c_u), 'b', linewidth = 2) # pylab.plot(x, koeffs_u[0]*x**2+koeffs_u[1]*x+koeffs_u[2], 'r', linewidth = 1) # pylab.grid() # pylab.show() # ############### return boundsurf2(s_l, s_u, B.definiteRange, B.domain), B.definiteRange
def b2mult_direct(Self, Other): assert Self.level == Other.level == 1 and Self.b2equiv(Other) and Self.l is Self.u and Other.l is Other.u k = list(Self.dep)[0] s, o = Self.l, Other.l # = Self.u, Other.u ld = {k: s.c * o.d.get(k, 0.0) + o.c * s.d.get(k, 0.0)} ld2 = {k: o.d.get(k, 0.0) * s.d.get(k, 0.0)} lc = s.c * o.c from boundsurf2 import surf2, boundsurf2 ls = surf2(ld2, ld, lc) r = boundsurf2(ls, ls, Self.definiteRange & Other.definiteRange, Self.domain) return r
def b2mult_direct(Self, Other): assert Self.level == Other.level == 1 and Self.b2equiv( Other) and Self.l is Self.u and Other.l is Other.u k = list(Self.dep)[0] s, o = Self.l, Other.l # = Self.u, Other.u ld = {k: s.c * o.d.get(k, 0.0) + o.c * s.d.get(k, 0.0)} ld2 = {k: o.d.get(k, 0.0) * s.d.get(k, 0.0)} lc = s.c * o.c from boundsurf2 import surf2, boundsurf2 ls = surf2(ld2, ld, lc) r = boundsurf2(ls, ls, Self.definiteRange & Other.definiteRange, Self.domain) return r
def b2mult(Self, Other): assert Self.level == Other.level == 1 and Self.b2equiv(Other) k = list(Self.dep)[0] ld = {k: Self.l.c*Other.l.d.get(k, 0.0) + Other.l.c*Self.l.d.get(k, 0.0)} ud = {k: Self.u.c*Other.u.d.get(k, 0.0) + Other.u.c*Self.u.d.get(k, 0.0)} ld2 = {k: Other.l.d.get(k, 0.0) * Self.l.d.get(k, 0.0)} ud2 = {k: Other.u.d.get(k, 0.0) * Self.u.d.get(k, 0.0)} lc = Self.l.c * Other.l.c uc = Self.u.c * Other.u.c from boundsurf2 import surf2, boundsurf2 ls, us = surf2(ld2, ld, lc), surf2(ud2, ud, uc) r = boundsurf2(ls, us, Self.definiteRange & Other.definiteRange, Self.domain) return r
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 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 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 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 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 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