def b2mult(Self, Other):
    assert Self.level == Other.level == 1 and Self.b2equiv(Other)
    lc = Self.l.c * Other.l.c
    uc = Self.u.c * Other.u.c
    if len(Self.dep):
        k = list(Self.dep)[0]
        ld = {
            k: Self.l.c * Other.l.d.get(k, 0.0) +
            Other.l.c * Self.l.d.get(k, 0.0)
        }
        ud = {
            k: Self.u.c * Other.u.d.get(k, 0.0) +
            Other.u.c * Self.u.d.get(k, 0.0)
        }
        ld2 = {k: Other.l.d.get(k, 0.0) * Self.l.d.get(k, 0.0)}
        ud2 = {k: Other.u.d.get(k, 0.0) * Self.u.d.get(k, 0.0)}
    else:
        assert len(Other.dep) == 0
        return boundsurf(surf({}, lc), surf({}, uc),
                         Self.definiteRange & Other.definiteRange, Self.domain)

    from boundsurf2 import surf2, boundsurf2
    ls, us = surf2(ld2, ld, lc), surf2(ud2, ud, uc)
    r = boundsurf2(ls, us, Self.definiteRange & Other.definiteRange,
                   Self.domain)
    return r
Beispiel #2
0
def inv_b_interval(B, revert):
    if type(B) == boundsurf2:
        B = B.to_linear()
        
    k = list(B.dep)[0]
    l, u = B.domain[k]
    d_l, d_u = B.l.d[k], B.u.d[k]
    c_l, c_u = B.l.c, B.u.c 
        
    if revert:
        d_l, d_u = -d_u, -d_l
        c_l, c_u = -c_u, -c_l

    koeffs_l, koeffs_u = get_inv_b2_coeffs(l, u, d_l, d_u, c_l, c_u)

#        ###########
#        from boundsurf2 import apply_quad_lin
#        a, b, c = koeffs_l
#        s_l = apply_quad_lin(a, b, c, B.l)
#        a, b, c = koeffs_u
#        s_u = apply_quad_lin(a, b, c, B.u)
#        ###########
#        print koeffs_l, koeffs_u
    if revert:
#            c_l, c_u = -c_u, -c_l
#            d_l, d_u = -d_u, -d_l
#            B = -B
        koeffs_l, koeffs_u = -array(koeffs_u), -array(koeffs_l)

    #############

    a, b, c = koeffs_l
    s_l = surf2({k:a}, {k:b}, c)
    a, b, c = koeffs_u
    s_u = surf2({k:a}, {k:b}, c)
    
#    ###############
#    if 0:
#        from numpy import linspace
#        x = linspace(l, u, 10000)
#        d_l, d_u = B.l.d[k], B.u.d[k]
#        c_l, c_u = B.l.c, B.u.c 
#        import pylab
#        if 1:
#            pylab.plot(x, 1.0/(d_l*x+c_l), 'r', linewidth = 2)
#            pylab.plot(x, koeffs_l[0]*x**2+koeffs_l[1]*x+koeffs_l[2], 'b', linewidth = 1)
#    #        else:
#            pylab.plot(x, 1.0/(d_u*x+c_u), 'b', linewidth = 2)
#            pylab.plot(x, koeffs_u[0]*x**2+koeffs_u[1]*x+koeffs_u[2], 'r', linewidth = 1)
#        pylab.grid()
#        pylab.show()
#    ###############

    return boundsurf2(s_l, s_u, B.definiteRange, B.domain), B.definiteRange
Beispiel #3
0
def inv_b_interval(B, revert):
    if type(B) == boundsurf2:
        B = B.to_linear()
        
    k = list(B.dep)[0]
    l, u = B.domain[k]
    d_l, d_u = B.l.d[k], B.u.d[k]
    c_l, c_u = B.l.c, B.u.c 
        
    if revert:
        d_l, d_u = -d_u, -d_l
        c_l, c_u = -c_u, -c_l

    koeffs_l, koeffs_u = get_inv_b2_coeffs(l, u, d_l, d_u, c_l, c_u)

#        ###########
#        from boundsurf2 import apply_quad_lin
#        a, b, c = koeffs_l
#        s_l = apply_quad_lin(a, b, c, B.l)
#        a, b, c = koeffs_u
#        s_u = apply_quad_lin(a, b, c, B.u)
#        ###########
#        print koeffs_l, koeffs_u
    if revert:
#            c_l, c_u = -c_u, -c_l
#            d_l, d_u = -d_u, -d_l
#            B = -B
        koeffs_l, koeffs_u = -array(koeffs_u), -array(koeffs_l)

    #############

    a, b, c = koeffs_l
    s_l = surf2({k:a}, {k:b}, c)
    a, b, c = koeffs_u
    s_u = surf2({k:a}, {k:b}, c)
    
#    ###############
#    if 0:
#        from numpy import linspace
#        x = linspace(l, u, 10000)
#        d_l, d_u = B.l.d[k], B.u.d[k]
#        c_l, c_u = B.l.c, B.u.c 
#        import pylab
#        if 1:
#            pylab.plot(x, 1.0/(d_l*x+c_l), 'r', linewidth = 2)
#            pylab.plot(x, koeffs_l[0]*x**2+koeffs_l[1]*x+koeffs_l[2], 'b', linewidth = 1)
#    #        else:
#            pylab.plot(x, 1.0/(d_u*x+c_u), 'b', linewidth = 2)
#            pylab.plot(x, koeffs_u[0]*x**2+koeffs_u[1]*x+koeffs_u[2], 'r', linewidth = 1)
#        pylab.grid()
#        pylab.show()
#    ###############

    return boundsurf2(s_l, s_u, B.definiteRange, B.domain), B.definiteRange
Beispiel #4
0
def b2mult(Self, Other):
    assert Self.level == Other.level == 1 and Self.b2equiv(Other)
    k = list(Self.dep)[0]
    ld = {k: Self.l.c*Other.l.d.get(k, 0.0) + Other.l.c*Self.l.d.get(k, 0.0)}
    ud = {k: Self.u.c*Other.u.d.get(k, 0.0) + Other.u.c*Self.u.d.get(k, 0.0)}
    ld2 = {k: Other.l.d.get(k, 0.0) * Self.l.d.get(k, 0.0)}
    ud2 = {k: Other.u.d.get(k, 0.0) * Self.u.d.get(k, 0.0)}
    lc = Self.l.c * Other.l.c
    uc = Self.u.c * Other.u.c
    from boundsurf2 import surf2, boundsurf2
    ls, us = surf2(ld2, ld, lc), surf2(ud2, ud, uc)
    r = boundsurf2(ls, us, Self.definiteRange & Other.definiteRange, Self.domain)
    return r
Beispiel #5
0
def b2mult_direct(Self, Other):
    assert Self.level == Other.level == 1 and Self.b2equiv(Other) and Self.l is Self.u and Other.l is Other.u
    k = list(Self.dep)[0]
    s, o = Self.l, Other.l # = Self.u, Other.u 
    ld = {k: s.c * o.d.get(k, 0.0) + o.c * s.d.get(k, 0.0)}
    ld2 = {k: o.d.get(k, 0.0) * s.d.get(k, 0.0)}
    lc = s.c * o.c
    from boundsurf2 import surf2, boundsurf2
    ls = surf2(ld2, ld, lc)
    r = boundsurf2(ls, ls, Self.definiteRange & Other.definiteRange, Self.domain)
    return r
Beispiel #6
0
def b2mult_direct(Self, Other):
    assert Self.level == Other.level == 1 and Self.b2equiv(
        Other) and Self.l is Self.u and Other.l is Other.u
    k = list(Self.dep)[0]
    s, o = Self.l, Other.l  # = Self.u, Other.u
    ld = {k: s.c * o.d.get(k, 0.0) + o.c * s.d.get(k, 0.0)}
    ld2 = {k: o.d.get(k, 0.0) * s.d.get(k, 0.0)}
    lc = s.c * o.c
    from boundsurf2 import surf2, boundsurf2
    ls = surf2(ld2, ld, lc)
    r = boundsurf2(ls, ls, Self.definiteRange & Other.definiteRange,
                   Self.domain)
    return r
Beispiel #7
0
def surf_join(inds, S):
    c = Join(inds, [s.c for s in S]) # list, not iterator!
    
    keys = set.union(*[set(s.d.keys()) for s in S])
    d = dict((k, Join(inds, [s.d.get(k, arrZero) for s in S])) for k in keys)
    
    keys = set.union(*[set(getattr(s,'d2', {}).keys()) for s in S])
    if len(keys) == 0:
        return surf(d, c)
        
    d2 = dict((k, Join(inds, [getattr(s, 'd2', {}).get(k, arrZero) for s in S])) for k in keys)
    from boundsurf2 import surf2
    return surf2(d2, d, c)
Beispiel #8
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 #9
0
def surf_join(inds, S):
    c = Join(inds, [s.c for s in S])  # list, not iterator!

    keys = set.union(*[set(s.d.keys()) for s in S])
    d = dict((k, Join(inds, [s.d.get(k, arrZero) for s in S])) for k in keys)

    keys = set.union(*[set(getattr(s, 'd2', {}).keys()) for s in S])
    if len(keys) == 0:
        return surf(d, c)

    d2 = dict((k, Join(inds, [getattr(s, 'd2', {}).get(k, arrZero)
                              for s in S])) for k in keys)
    from boundsurf2 import surf2
    return surf2(d2, d, c)
Beispiel #10
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 #11
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 #12
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 #13
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 #14
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 #15
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 #16
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