Beispiel #1
0
    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)
        '''
Beispiel #3
0
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
Beispiel #4
0
 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)
     
     '''
Beispiel #5
0
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
Beispiel #6
0
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
Beispiel #7
0
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
Beispiel #9
0
 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
Beispiel #10
0
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
Beispiel #11
0
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
Beispiel #12
0
    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
Beispiel #13
0
    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
Beispiel #14
0
    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
Beispiel #15
0
    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
Beispiel #16
0
    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
Beispiel #17
0
 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)
Beispiel #18
0
 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)
Beispiel #19
0
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
Beispiel #20
0
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
Beispiel #21
0
    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 
Beispiel #22
0
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
Beispiel #23
0
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)
Beispiel #24
0
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)
Beispiel #25
0
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
Beispiel #26
0
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)
Beispiel #27
0
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)
Beispiel #28
0
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)
Beispiel #29
0
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)
Beispiel #30
0
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
Beispiel #31
0
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)
Beispiel #33
0
    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)
Beispiel #34
0
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
Beispiel #35
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    
Beispiel #36
0
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
Beispiel #37
0
 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
Beispiel #38
0
 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
Beispiel #39
0
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
Beispiel #40
0
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)
Beispiel #42
0
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
Beispiel #43
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
Beispiel #44
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    
Beispiel #45
0
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
Beispiel #46
0
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__
Beispiel #47
0
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
Beispiel #48
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
Beispiel #49
0
 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)
Beispiel #50
0
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