def convex_comb_dis_log(model,a,b):
    """convex_comb_dis_log -- add piecewise relation with a logarithmic number of binary variables
    using the convex combination formulation.
    Parameters:
        - model: a model where to include the piecewise linear relation
        - a[k]: x-coordinate of the k-th point in the piecewise linear relation
        - b[k]: y-coordinate of the k-th point in the piecewise linear relation
    Returns the model with the piecewise linear relation on added variables X, Y, and z.
    """
    K = len(a)-1
    G = int(math.ceil((math.log(K)/math.log(2))))     # number of required bits
    N = 1<<G                                          # number of required variables
    # print("K,G,N:",K,G,N
    wL,wR,z = {},{},{}
    for k in range(N):
        wL[k] = model.addVar(lb=0, ub=1, vtype="C")
        wR[k] = model.addVar(lb=0, ub=1, vtype="C")
    X = model.addVar(lb=a[0], ub=a[K], vtype="C")
    Y = model.addVar(lb=-model.infinity(), vtype="C")

    g = {}
    for j in range(G):
        g[j] = model.addVar(vtype="B")

    model.addCons(X == quicksum(a[k]*wL[k] + a[k+1]*wR[k] for k in range(K)))
    model.addCons(Y == quicksum(b[k]*wL[k] + b[k+1]*wR[k] for k in range(K)))
    model.addCons(quicksum(wL[k] + wR[k] for k in range(K)) == 1)

    # binary variables setup
    for j in range(G):
        ones = []
        zeros = []
        for k in range(K):
            if k & (1<<j):
                ones.append(k)
            else:
                zeros.append(k)
        model.addCons(quicksum(wL[k] + wR[k] for k in ones) <= g[j])
        model.addCons(quicksum(wL[k] + wR[k] for k in zeros) <= 1-g[j])

    return X,Y,wL,wR
def convex_comb_dis_log ( model , a , b ) : K = len ( a ) - 1 G = int ( math . ceil ( ( math . log ( K ) / math . log ( 2 ) ) ) ) N = 1 << G wL , wR , z = { } , { } , { } for k in range ( N ) : wL [ k ] = model . addVar ( lb = 0 , ub = 1 , vtype = "C" ) wR [ k ] = model . addVar ( lb = 0 , ub = 1 , vtype = "C" ) X = model . addVar ( lb = a [ 0 ] , ub = a [ K ] , vtype = "C" ) Y = model . addVar ( lb = - model . infinity ( ) , vtype = "C" ) g = { } for j in range ( G ) : g [ j ] = model . addVar ( vtype = "B" ) model . addCons ( X == quicksum ( a [ k ] * wL [ k ] + a [ k + 1 ] * wR [ k ] for k in range ( K ) ) ) model . addCons ( Y == quicksum ( b [ k ] * wL [ k ] + b [ k + 1 ] * wR [ k ] for k in range ( K ) ) ) model . addCons ( quicksum ( wL [ k ] + wR [ k ] for k in range ( K ) ) == 1 ) for j in range ( G ) : ones = [ ] zeros = [ ] for k in range ( K ) : if k & ( 1 << j ) : ones . append ( k ) else : zeros . append ( k ) model . addCons ( quicksum ( wL [ k ] + wR [ k ] for k in ones ) <= g [ j ] ) model . addCons ( quicksum ( wL [ k ] + wR [ k ] for k in zeros ) <= 1 - g [ j ] ) return X , Y , wL , wR
convex_comb_dis_log -- add piecewise relation with a logarithmic number of binary variables
    using the convex combination formulation.
    Parameters:
        - model: a model where to include the piecewise linear relation
        - a[k]: x-coordinate of the k-th point in the piecewise linear relation
        - b[k]: y-coordinate of the k-th point in the piecewise linear relation
    Returns the model with the piecewise linear relation on added variables X, Y, and z.