Exemplo n.º 1
0
def longpath2(A,
              b,
              c,
              gamma=0.001,
              c_form=0,
              w=10**(-8),
              max_it=500,
              info=0,
              ip=1):

    print('\n\tCOMPUTATION OF LPF ALGORITHM 2')

    # Algorithm in 4 steps:
    # 0..Input error checking
    # 1..Find the initial point with Mehrotra's method
    # 2..obtain the search direction
    # 3..find the largest step
    """ Input error checking & construction in a standard form """

    if not (isinstance(A, np.ndarray) or isinstance(b, np.ndarray)
            or isinstance(c, np.ndarray)):
        raise Exception('Inputs must be a numpy arrays')

    if c_form == 0:
        A, c = stdForm(A, c)
    r_A, c_A = A.shape
    if not np.linalg.matrix_rank(
            A) == r_A:  # Check full rank matrix:Remove ld rows:
        A = A[[
            i for i in range(r_A)
            if not np.array_equal(np.linalg.qr(A)[1][i, :], np.zeros(c_A))
        ], :]
        r_A = A.shape[0]  # Update no. of rows
    """ Initial points: Initial infeasible positive (x,y,s) and initial gap g """

    if ip == 0:
        (x, y, s) = sp(A, c, b)
    else:
        (x, y, s) = sp2(A, c, b)

    (x, y, s) = sp(A, c, b)
    g = np.dot(c, x) - np.dot(y, b)

    if info == 0:
        print('\nInitial primal-dual point:\nx = {} \nlambda = {} \ns = {}'.
              format(x, y, s))
        print('Dual initial g: {}.\n'.format("%10.3f" % g))

    # Check if (x, y, s) in neighborhood N_inf:
    mu = np.dot(x, s) / c_A
    if not (x * s > gamma * mu).all():
        print("Initial point is not in N")
    E = lambda a: (s + a * s1) * (x + a * x1) - (gamma * np.dot(
        (s + a * s1),
        (x + a * x1))) / c_A  # Function E: set of values in N_(gamma)

    #%%
    """ Search vector direction """
    '''Modified Newton's method with with normal equations: find the direction vector (y1, s1, x1)'''

    it = 0  # Num of iterations
    tm = term(it)  # Define tollerance tm = inf
    u = []  # Construct list of info elements
    u.append([it, g, x, s, b - np.dot(A, x), c - np.dot(A.T, y) - s])
    sig = []

    while tm > w:
        cp = min(0.1, 100 * np.dot(x, s) / c_A)  # sigma2

        if info == 0:
            print("\tIteration: {}\n".format(it), end='')
            print("Centering parameter sigma:{}.\n".format("%10.3f" % cp))

        X_inv = np.linalg.inv(np.diag(x))
        W1 = X_inv * np.diag(s)  # W1 = X^(-1)*S
        T = np.concatenate((np.zeros((r_A, r_A)), A), axis=1)
        U = np.concatenate((A.T, -W1), axis=1)
        V = np.concatenate((T, U), axis=0)

        rb = b - np.dot(A, x)
        rc = c - np.dot(A.T, y) - s
        rxs = -x * s + cp * (sum(x * s) / c_A) * np.ones(
            c_A)  # Newton step toward x*s = sigma*mi

        r = np.hstack((rb, rc - np.dot(X_inv, rxs)))
        o = np.linalg.solve(V, r)

        y1 = o[:r_A]
        x1 = o[r_A:c_A + r_A]
        s1 = np.dot(X_inv, rxs) - np.dot(W1, x1)

        if info == 0:
            print(
                'Search direction vectors: \n delta_x = {} \n delta_lambda = {} \n delta_s = {}.\n'
                .format(x1.round(decimals=3), y1.round(decimals=3),
                        s1.round(decimals=3)))
        """ Compute the largest step length & increment of the points and the iteration"""

        # We find the maximum alpha s. t the next iteration is in N_gamma
        v = np.arange(0, 1.000, 0.0001)
        i = len(v) - 1
        while i >= 0:
            if (E(v[i]) > 0).all():
                t = v[i]
                #                print('Largest step length:{}'.format("%10.3f"%t))
                break
            else:
                i -= 1

        # Update step
        x += t * x1  # Current x
        y += t * y1  # Current y
        s += t * s1  # Current s
        rb = b - np.dot(A, x)
        rc = c - np.dot(A.T, y) - s

        z = np.dot(c, x)  # Current opt. solution
        g = z - np.dot(y, b)  # Current gap
        it += 1
        u.append([it, g, x.copy(), s.copy(), rb.copy(), rc.copy()])
        sig.append([cp])

        # Termination elements
        m, n, q = term(it, b, c, rb, rc, z, g)
        tm = max(m, n, q)
        if it == max_it:
            raise TimeoutError("Iterations maxed out")
        if info == 0:
            print(
                '\nCurrent point:\n x = {} \n lambda = {} \n s = {}.\n'.format(
                    x.round(decimals=3), y.round(decimals=3),
                    s.round(decimals=3)))
            print('Dual next gap: {}.\n'.format("%10.3f" % g))

#%%

    print_boxed("Found optimal solution of the problem at\n x* = {}.\n\n".
                format(x.round(decimals=3)) +
                "Dual gap: {}\n".format("%2.2e" % g) +
                "Optimal cost: {}\n".format("%10.8E" % z) +
                "Number of iteration: {}".format(it))
    return x, s, u, sig
Exemplo n.º 2
0
u = []
q = []
p = []

v = []
w = []
k = []

for i in range(30):
    (A, b, c) = input_data(i)
    x.append(A.shape[0])
    y.append(A.shape[1])

    (A, c) = stdForm(A, c)
    (x1, y1, s1) = sp(A, c, b)
    (x2, y2, s2) = sp2(A, c, b)

    r1 = np.concatenate((np.dot(A, x1) - b, c - s1 - np.dot(A.T, y1)))
    r2 = np.concatenate((np.dot(A, x2) - b, c - s2 - np.dot(A.T, y2)))

    w1 = np.divide((np.dot(b, y1) - np.dot(c, x1)), A.shape[1])
    w2 = np.divide((np.dot(b, y2) - np.dot(c, x2)), A.shape[1])
    # Mehrotra's method
    u.append("%5.2e" % np.linalg.norm(r1))
    q.append("%5.2e" % w1)
    t = np.divide(np.linalg.norm(r1), w1)
    p.append(t)
    # STP1 method
    v.append("%5.2e" % np.linalg.norm(r2))
    w.append("%5.2e" % w2)
    m = np.divide(np.linalg.norm(r2), w2)
Exemplo n.º 3
0
def longpathPC(A,
               b,
               c,
               gamma=0.001,
               c_form=0,
               w=10**(-8),
               max_it=500,
               info=0,
               ip=0):

    print('\n\tLPF predictor-corrector')

    # Algorithm in 4 steps:
    # 0..Input error checking
    # 1..Find the initial point with Mehrotra's method
    # 2..Predictor step
    # 3..Corrector step
    """ Input error checking & construction in a standard form """

    if not (isinstance(A, np.ndarray) or isinstance(b, np.ndarray)
            or isinstance(c, np.ndarray)):
        info = 1
        raise Exception('Inputs must be a numpy arrays: INFO {}'.format(info))

    if c_form == 0:  # Construction in a standard form [A | I]
        A, c = stdForm(A, c)
    r_A, c_A = A.shape
    if not np.linalg.matrix_rank(A) == r_A:  # Remove ld rows:
        A = A[[
            i for i in range(r_A)
            if not np.array_equal(np.linalg.qr(A)[1][i, :], np.zeros(c_A))
        ], :]
        r_A = A.shape[0]  # Update no. of rows
    """ Initial points: Initial infeasible positive (x,y,s) and initial gap g """

    if ip == 0:
        (x, y, s) = sp(A, c, b)
    else:
        (x, y, s) = sp2(A, c, b)
    g = np.dot(c, x) - np.dot(y, b)

    if info == 0:

        print('\nInitial primal-dual point:\nx = {} \nlambda = {} \ns = {}'.
              format(x, y, s))
        print('Dual initial gap: {}.\n'.format("%10.3f" % g))

    # Check if (x, y, s) in neighborhood N_inf and define E:
    if not (x * s > gamma * np.dot(x, s) / c_A).all():
        print("Initial point is not in N")
    E = lambda a: (s + a * s1) * (x + a * x1) - (gamma * np.dot(
        (s + a * s1),
        (x + a * x1))) / c_A  # Function E: set of values in N_(gamma)

    #%%
    """ Predictor step """
    '''Pure Newton's method with with normal equations: find the direction vector (y1, s1, x1)'''

    it = 0  # Num of iterations
    tm = term(it)  # Define tollerance tm = inf
    u = []  # Construct list of info elements
    u.append([it, g, x, s, b - np.dot(A, x), c - np.dot(A.T, y) - s])
    sig = []

    while tm > w:

        if info == 0:
            print("\tIteration: {}\n".format(it + 1))

        # Choose cp = 0 and compute the direction with augmented system
        (x1, y1, s1, rb, rc) = augm(A, b, c, x, y, s, 0)

        # Find the maximum alpha s.t the next iteration is in N_gamma
        v = np.arange(0, 1.0000, 0.0001)
        i = len(v) - 1
        while i >= 0:
            if (E(v[i]) > 0).all():
                t = v[i]
                #            print('Largest step length:{}'.format("%10.3f"%t))
                break
            else:
                i -= 1
        mi = np.dot(x, s) / c_A  # Duality measure
        mi_aff = np.dot(
            x + t * x1,
            s + t * s1) / c_A  # Average value of the incremented vectors
        Sigma = (mi_aff / mi)**3
        """ Corrector step: compute (x_k+1, lambda_k+1, s_k+1) """

        (x1, y1, s1, rb, rc) = augm(A, b, c, x, y, s, Sigma)

        if info == 0:
            print(
                'Search direction vectors: \n delta_x = {} \n delta_lambda = {} \n delta_s = {}.\n'
                .format(x1.round(decimals=3), x1.round(decimals=3),
                        s1.round(decimals=3)))

        # Update
        x += t * x1  # Current x
        y += t * y1  # Current y
        s += t * s1  # Current s
        z = np.dot(c, x)  # Current optimal solution
        g = z - np.dot(y, b)  # Current gap
        it += 1
        u.append([it, g, x.copy(), s.copy(), rb.copy(), rc.copy()])
        sig.append(Sigma)

        # Termination elements
        tm = term(it, b, c, rb, rc, z, g)

        if it == max_it:
            raise TimeoutError("Iterations maxed out")

        if info == 0:
            print(
                '\nCurrent primal-dual point:\n x = {} \n lambda = {} \n s = {}.\n'
                .format(x.round(decimals=3), y.round(decimals=3),
                        s.round(decimals=3)))
            print('Dual next gap: {}.\n'.format("%10.3f" % g))

#%%

    print_boxed("Found optimal solution of the problem at\n x* = {}.\n\n".
                format(x.round(decimals=3)) +
                "Dual gap: {}\n".format("%2.2e" % g) +
                "Optimal cost: {}\n".format("%10.3f" % z) +
                "Number of iteration: {}".format(it))

    return x, s, u, sig
Exemplo n.º 4
0
def mehrotra(A, b, c, c_form=0, w=10**(-8), max_it=500, info=0, ip=1):

    print('\n\tCOMPUTATION OF MEHROTRA ALGORITHM\n')

    # Algorithm in 4 steps:
    # 0..Input error checking
    # 1..Find the initial point with Mehrotra's method
    # 2..Predictor step
    # 3..Centering step
    # 4..Corrector step
    """ Input error checking & construction in a standard form """

    if not (isinstance(A, np.ndarray) or isinstance(b, np.ndarray)
            or isinstance(c, np.ndarray)):
        raise Exception('Inputs must be a numpy arrays')

    if c_form == 0:
        A, c = stdForm(A, c)
    r_A, c_A = A.shape
    if not np.linalg.matrix_rank(
            A) == r_A:  # Check full rank matrix:Remove ld rows:
        A = A[[
            i for i in range(r_A)
            if not np.array_equal(np.linalg.qr(A)[1][i, :], np.zeros(c_A))
        ], :]
        r_A = A.shape[0]  # Update no. of rows
    """ Initial points: Initial infeasible positive (x,y,s) and initial gap g """

    if ip == 0:
        (x, y, s) = sp(A, c, b)  # MIP
    else:
        (x, y, s) = sp2(A, c, b)  # STP1

    g = np.dot(c, x) - np.dot(y, b)

    if info == 0:

        print('\nInitial primal-dual point:\nx = {} \nlambda = {} \ns = {}'.
              format(x, y, s))
        print('Dual initial g: {}.\n'.format("%10.3f" % g))

    #%%
    """ Predictor step: compute affine direction """
    '''
    Compute affine scaling direction solving Qs = R with system D^2 = S^{-1}*X 
    with Q a large sparse matrix 
    and R = [rb, rc, - x_0*s_0]
    '''

    it = 0  # Num of iterations
    tm = term(it)  # Tollerance in the cycle

    u = []  # Construct list of info elements
    sig = []
    u.append([it, g, x, s, b - np.dot(A, x), c - np.dot(A.T, y) - s])

    while tm > w:
        """ Pure Newton's method with with normal equations: find the direction vector (y1, s1, x1)"""

        S_inv = np.linalg.inv(np.diag(s))  # S^{-1}
        W1 = np.dot(S_inv, np.diag(x))  # W1 = D = S^(-1)*X
        W2 = np.dot(A, W1)  # W2      A*S^(-1)*X
        W = np.dot(W2, A.T)
        L = np.linalg.cholesky(W)
        L_inv = np.linalg.inv(L)

        # RHS of the system, including the minus
        rb = b - np.dot(A, x)
        rc = c - np.dot(A.T, y) - s
        rxs = -x * s

        B = rb + np.dot(W2, rc) - np.dot(np.dot(A, S_inv),
                                         rxs)  #RHS of normal equation form
        z = np.dot(L_inv, B)

        # SEARCH DIRECTION affine:
        y1 = np.dot(L_inv.T, z)
        s1 = rc - np.dot(A.T, y1)
        x1 = np.dot(S_inv, rxs) - np.dot(W1, s1)

        if info == 0:

            print("\n\tIteration: {}\n".format(it), end='')
            print(
                "\nPREDICTOR STEP:\nAffine direction:\n({}, {}, {})\n".format(
                    x1, y1, s1))

        #%%
        """ Centering step: compute search direction """
        '''
        Find alfa1_affine and alfa2_affine : maximum steplength along affine-scaling direction
        Find the minimum( x_{i}/x1_{i} , 1) and the minimum( s_{i}/s1_{i} , 1)
        '''

        h = min([(-x[i] / x1[i], i) for i in range(c_A) if x1[i] < 0],
                default=[0])[0]
        k = min([(-s[i] / s1[i], i) for i in range(c_A) if s1[i] < 0],
                default=[0])[0]

        alfa1 = min(h, 1)
        alfa2 = min(k, 1)

        # Set the centering parameter to Sigma = (mi_aff/mi)^{3}
        mi = np.dot(x, s) / c_A  # Duality measure
        mi_af = np.dot(
            x + alfa1 * x1,
            s + alfa2 * s1) / c_A  # Average value of the incremented vectors
        Sigma = (mi_af / mi)**(3)

        # SECOND SEARCH DIRECTION
        Rxs = -x1 * s1 + Sigma * mi * np.ones(
            (c_A))  # RHS of the New system, including minus

        Rb = -np.dot(np.dot(A, S_inv), Rxs)  # RHS of New normal equation form
        z = np.dot(L_inv, Rb)

        # SEARCH DIRECTION centering-orrector:
        y2 = np.dot(L_inv.T, z)
        s2 = -np.dot(A.T, y2)
        x2 = np.dot(S_inv, Rxs) - np.dot(W1, s2)

        if info == 0:

            print("Cc direction:\n({}, {}, {})\n".format(x2, y2, s2))

        #%%
        """ Corrector step: compute (x_k+1, lambda_k+1, s_k+1) """

        # The steplength without eta_k
        x2 += x1
        s2 += s1
        y2 += y1
        H = min([(-x[i] / x2[i], i) for i in range(c_A) if x2[i] < 0],
                default=[0])[0]
        K = min([(-s[i] / s2[i], i) for i in range(c_A) if s2[i] < 0],
                default=[0])[0]
        Alfa1 = min(0.99 * H, 1)
        Alfa2 = min(0.99 * K, 1)

        # Update
        x += Alfa1 * x2  # Current x
        y += Alfa2 * y2  # Current y
        s += Alfa2 * s2  # Current s
        z = np.dot(c, x)  # Current optimal solution
        g = z - np.dot(y, b)  # Current gap
        it += 1
        u.append([it, g, x.copy(), s.copy(), rb.copy(), rc.copy()])
        sig.append([Sigma])

        # Termination elements
        tm = term(it, b, c, rb, rc, z, g)

        if it == max_it:
            raise TimeoutError("Iterations maxed out")

        if info == 0:
            print('CORRECTOR STEP:\nCurrent primal-dual point: \n x = ', x,
                  '\nlambda = ', y, '\n s = ', s)
            print('Current g: {}\n'.format("%.3f" % g))

#%%

    print_boxed(
        "Found optimal solution of the standard problem at\n x* = {}.\n\n".
        format(x) + "Dual gap: {}\n".format("%2.2e" % g) +
        "Optimal cost: {}\n".format("%10.3f" % z) +
        "Number of iteration: {}".format(it))

    return x, s, u, sig
Exemplo n.º 5
0
def affine(A, b, c, c_form = 0, w = 10**(-8), max_it = 500, info = 0, ip = 0):
        
    print('\n\tCOMPUTATION OF PRIMAL-DUAL AFFINE SCALING ALGORITHM')
    
    # Algorithm in 4 steps:  
    # 0..Input error checking
    # 1..Find the initial point with Mehrotra's method 
    # 2..obtain the search direction
    # 3..find the largest step   
        
    """ Input error checking & construction in a standard form """
        
    if not (isinstance(A, np.ndarray) or isinstance(b, np.ndarray) or isinstance(c, np.ndarray)):
       raise Exception('Inputs must be a numpy arrays')
        
    if c_form == 0:
        A, c = stdForm(A, c)    
    r_A, c_A = A.shape
    if not np.linalg.matrix_rank(A) == r_A: # Check full rank matrix: Remove ld rows
        A = A[[i for i in range(r_A) if not np.array_equal(np.linalg.qr(A)[1][i, :], np.zeros(c_A))], :]
        r_A = A.shape[0]  # Update no. of rows
    
    """ Initial points: Initial infeasible positive (x,y,s) and initial gap g """
    
    if ip == 0:
        (x, y, s) = sp(A, c, b)
    else:
        (x, y, s) = sp2(A, c, b)        
    g = np.dot(c,x) - np.dot(y,b)    
    
    if info == 0:
        print('\nInitial primal-dual point:\n x = {} \n lambda = {} \n s = {}.\n'.format(x, y, s))    
        print('Dual initial gap: {}.\n'.format("%10.3f"%g))      
    
   #%%
        
    """ Search vector direction """
    
    it = 0        # Num of iterations
    tm = term(it) # Tollerance in the cycle
    
    u = [] # Construct list of info elements 
    u.append([it, g, x, s, b - np.dot(A,x), c - np.dot(A.T, y) - s])
    
    while tm > w:               
        
        """ Pure Newton's method with with normal equations: find the direction vector (y1, s1, x1)"""
        
        S_inv = np.linalg.inv(np.diag(s))           
        W1 = S_inv*np.diag(x)                       # W1 = D = S^(-1)*X    
        W2 = np.dot(A, W1)                          # W      A*S^(-1)*X
        W  = np.dot(W2, A.T)
        L = np.linalg.cholesky(W)                   # CHOLESKY for A* D^2 *A^T
        L_inv = np.linalg.inv(L) 
        
        # RHS of the system        
        rb = b - np.dot(A, x)
        rc = c - np.dot(A.T, y) - s
        rxs = - x*s  # Newton step toward x*s = 0
        
        B = rb + np.dot(W2, rc) - np.dot(np.dot(A, S_inv), rxs) #RHS of normal equation form
        z = np.dot(L_inv, B)
        
        # SEARCH DIRECTION:        
        y1 = np.dot(L_inv.T, z)
        s1 = rc - np.dot(A.T, y1)
        x1 = np.dot(S_inv, rxs) - np.dot(W1,s1)
        
        if info == 0:
            print("\tIteration: {}\n".format(it))
            print('Search direction vectors: \n delta_x = {} \n delta_lambda = {} \n delta_s = {}.\n'.format(x1.round(decimals = 3),y1.round(decimals = 3),s1.round(decimals = 3)))
        
        """ Compute the largest step length & increment of the points and the iteration"""
        
        # Largest step length T such that (x, s) + T (x1, s1) is positive
        m = min([(-x[i] / x1[i], i) for i in range(c_A) if x1[i] < 0], default = [1])[0] 
        n = min([(-s[i] / s1[i], i) for i in range(c_A) if s1[i] < 0], default = [1])[0] 
        T = (0.9)*min(m, n) 

        # Update step
        x += min(T,1)*x1            # Current x
        y += min(T,1)*y1            # Current y
        s += min(T,1)*s1            # Current s  
        rb = b - np.dot(A, x)
        rc = c - np.dot(A.T, y) - s
        z = np.dot(c, x)            # Current optimal solution
        g = np.abs(z - np.dot(y, b))# Current gap 
        it += 1
        u.append([it, g.copy(), x.copy(), s.copy(), rb.copy(), rc.copy()])       
                
        # Termination elements
        m, n, q = term(it, b, c, rb, rc, z, g)
        tm = max(m, n, q)
        if it == max_it:
            raise TimeoutError("Iterations maxed out") 
        
        if info == 0:
            print('Current point:\n x = {} \n lambda = {} \n s = {}.\n'.format(x, y, s))
            print('Dual next gap: {}.\n'.format("%10.3f"%g))
        
#%%
        
    print_boxed("Found optimal solution of the problem at\n x* = {}.\n".format(x) +
                "Dual gap: {}\n".format("%10.6f"%g) +
                "Optimal cost: {}\n".format("%.8E" %z) +
                "Number of iterations: {}".format(it))
    return x, s, u
Exemplo n.º 6
0
def mehrotra2(A, b, c, c_form=0, w=10**(-8), max_it=500, info=0, ip=0):

    print('\n\tCOMPUTATION OF MEHROTRA ALGORITHMwith Augmented system\n')

    # Algorithm in 4 steps:
    # 0..Input error checking
    # 1..Find the initial point with Mehrotra's method
    # 2..Predictor step
    # 3..Centering step
    # 4..Corrector step
    """ Input error checking & construction in a standard form """

    if not (isinstance(A, np.ndarray) or isinstance(b, np.ndarray)
            or isinstance(c, np.ndarray)):
        raise Exception('Inputs must be a numpy arrays')

    if c_form == 0:
        A, c = stdForm(A, c)
    r_A, c_A = A.shape
    if not np.linalg.matrix_rank(
            A) == r_A:  # Check full rank matrix:Remove ld rows:
        A = A[[
            i for i in range(r_A)
            if not np.array_equal(np.linalg.qr(A)[1][i, :], np.zeros(c_A))
        ], :]
        r_A = A.shape[0]  # Update no. of rows
    """ Initial points: Initial infeasible positive (x,y,s) and initial gap g """

    if ip == 0:
        (x, y, s) = sp(A, c, b)
    else:
        (x, y, s) = sp2(A, c, b)
    g = np.dot(c, x) - np.dot(y, b)
    if info == 0:

        print('\nInitial primal-dual point:\nx = {} \nlambda = {} \ns = {}'.
              format(x, y, s))
        print('Dual initial g: {}.\n'.format("%10.3f" % g))

    #%%
    """ Predictor step: compute affine direction """
    '''
    Compute affine scaling direction solving Qs = R with an augmented system D^2 = S^{-1}*X 
    with Q a large sparse matrix 
    and R = [rb, rc, - x_0*s_0]
    '''

    it = 0  # Num of iterations
    tm = term(it)  # Tollerance in the cycle

    u = []  # Construct list of info elements
    sig = []
    u.append([it, g, x, s, b - np.dot(A, x), c - np.dot(A.T, y) - s])

    while tm > w:
        if info == 0:
            print("\n\tIteration: {}\n".format(it), end='')

        X_inv = np.linalg.inv(np.diag(x))
        W1 = X_inv * np.diag(s)  # W1 = X^(-1)*S
        T = np.concatenate((np.zeros((r_A, r_A)), A), axis=1)
        U = np.concatenate((A.T, -W1), axis=1)
        V = np.concatenate((T, U), axis=0)

        # RHS of the system, including the minus

        rb = b - np.dot(A, x)
        rc = c - np.dot(A.T, y) - s
        rxs = -x * s

        r = np.hstack((rb, rc - np.dot(X_inv, rxs)))
        o = np.linalg.solve(V, r)

        # SEARCH DIRECTION affine:
        y1 = o[:r_A]
        x1 = o[r_A:c_A + r_A]
        s1 = np.dot(X_inv, rxs) - np.dot(W1, x1)
        if info == 0:

            print(
                "\nPREDICTOR STEP:\nAffine direction:\n({}, {}, {})\n".format(
                    x1, y1, s1))

        #%%
        """ Centering step: compute search direction """

        # Find alfa1_affine and alfa2_affine : maximum steplength along affine-scaling direction
        # Find the minimum( x_{i}/x1_{i} , 1) and the minimum( s_{i}/s1_{i} , 1)

        h = min([(-x[i] / x1[i], i) for i in range(c_A) if x1[i] < 0],
                default=[0])[0]
        k = min([(-s[i] / s1[i], i) for i in range(c_A) if s1[i] < 0],
                default=[0])[0]

        alfa1 = min(h, 1)
        alfa2 = min(k, 1)

        # Set the centering parameter to Sigma = (mi_aff/mi)^{3}
        mi = np.dot(x, s) / c_A  # Duality measure
        mi_af = np.dot(
            x + alfa1 * x1,
            s + alfa2 * s1) / c_A  # Average value of the incremented vectors
        Sigma = (mi_af / mi)**(3)

        # SECOND SEARCH DIRECTION
        Rxs = -x1 * s1 + Sigma * mi * np.ones(
            (c_A))  # RHS of the New system, including minus

        r = np.hstack((np.zeros(r_A), -np.dot(X_inv, Rxs)))
        o = np.linalg.solve(V, r)

        # SEARCH DIRECTION centering-corrector:
        y2 = o[:r_A]
        x2 = o[r_A:c_A + r_A]
        s2 = np.dot(X_inv, Rxs) - np.dot(W1, x2)
        if info == 0:

            print("\nPREDICTOR STEP:\nCC direction:\n({}, {}, {})\n".format(
                x2, y2, s2))

        #%%
        """ Corrector step: compute (x_k+1, lambda_k+1, s_k+1) """

        # The steplength without eta_k
        x2 += x1
        s2 += s1
        y2 += y1
        H = min([(-x[i] / x2[i], i) for i in range(c_A) if x2[i] < 0],
                default=[0])[0]
        K = min([(-s[i] / s2[i], i) for i in range(c_A) if s2[i] < 0],
                default=[0])[0]
        Alfa1 = min(0.99 * H, 1)
        Alfa2 = min(0.99 * K, 1)

        # Compute the final update , using sol2 and Alfa_i

        x += Alfa1 * x2
        y += Alfa2 * y2
        s += Alfa2 * s2
        it += 1
        if it == max_it:
            return x, s, u, sig
            raise TimeoutError("Iterations maxed out")

        # Dual gap c^{T}*x - b^{T}*y = x*s
        z = np.dot(c, x)
        g = np.dot(x, s)
        g1 = z - np.dot(y, b)

        u.append([it, g, x.copy(), s.copy(), rb.copy(), rc.copy()])
        sig.append([Sigma])
        # Termination elements
        m, n, q = term(it, b, c, rb, rc, z, g)
        tm = max(m, n, q)
        if info == 0:

            print('Tollerance: {}.\n'.format("%10.3f" % tm))

            print('CORRECTOR STEP:\nCurrent primal-dual point: \n x = ', x,
                  '\nlambda = ', y, '\n s = ', s)
            print('Current g: {}\nCurrent g1: {}\n'.format(
                "%.3f" % g, "%.3f" % g1))

    print_boxed(
        "Found optimal solution of the standard problem at\n x* = {}.\n\n".
        format(x) + "Dual gap: {}\n".format("%2.2e" % g) +
        "Optimal cost: {}\n".format("%2.8E" % z) +
        "Number of iteration: {}".format(it))

    return x, s, u, sig