Пример #1
0
    def _interval_(self, domain, dtype=float64):
        if self in domain.resolveSchedule:
            tmp = domain.get(self, None)
            if tmp is None:
                Tmp = getattr(domain, '_dictOfStochVars', {})
                tmp = Tmp.get(self, None)
                return None if tmp is None else (tile(
                    yield_stochastic(tmp, domain, self), (2, 1)), True)

            if isinstance(tmp, ndarray) or isscalar(
                    tmp):  # thus variable value is fixed for this calculation
                tmp = asarray(tmp, dtype)
                return tile(tmp, (2, 1)), True
            infinum, supremum = tmp

            #prev
            #return asarray(vstack((infinum, supremum)), dtype), True
            #new, works faster in CPython
            r = empty((2, asarray(infinum).size), dtype)
            r[0] = infinum
            r[1] = supremum
            return r, True
        else:
            S = surf({self: One}, Zero)
            return boundsurf(S, S, True, domain), True
Пример #2
0
 def _interval_(self, domain, dtype = float64):
     if 0 or self in domain.resolveSchedule:
         tmp = domain.get(self, None)
         if tmp is None: return None
         if isinstance(tmp, ndarray) or isscalar(tmp): # thus variable value is fixed for this calculation
             tmp = asarray(tmp, dtype)
             return tile(tmp, (2, 1)), True
         infinum, supremum = tmp
         
         #prev
         #return asarray(vstack((infinum, supremum)), dtype), True
         #new, works faster in CPython
         r = empty((2, asarray(infinum).size), dtype)
         r[0] = infinum
         r[1] = supremum
         return r, True
     else:
         S = surf({self: One}, Zero)
         return boundsurf(S, S, True, domain), True
Пример #3
0
 def to_linear(self):
     L = self.l.to_linear(self.domain, Greater)
     U = self.u.to_linear(self.domain, Less)
     return boundsurf(L, U, self.definiteRange, self.domain)
Пример #4
0
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
Пример #5
0
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    
Пример #6
0
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
Пример #7
0
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    
Пример #8
0
 def to_linear(self):
     L = self.l.to_linear(self.domain, Greater)
     U = self.u.to_linear(self.domain, Less)
     return boundsurf(L, U, self.definiteRange, self.domain)