Beispiel #1
0
def sqp_ipm(func,
            x,
            bdry,
            args,
            maxiter=50,
            stepsize=1e-9,
            gradtol=1500,
            **kwargs):
    '''
    Does the SQP Algorithm and solves the quadratic problem with the quadratic
    interior point method (ipm_quadr)
    '''

    niter = 0
    n = len(x)
    p = len(bdry)

    #starting parameter
    y = numpy.ones(p)
    lam = numpy.ones(p)
    while (1):
        if (niter >= maxiter
                or numpy.linalg.norm(grad(func, x, stepsize)) <= gradtol):
            print('Stop of SQP Algorithm at Iteration=%d' % (niter))
            break

        niter = niter + 1
        print('ITERATON IN SQP =')
        print(niter)
        #set up matrices necessary for the ipm
        c = grad(func, x, stepsize)
        G = hessian(func, x)
        b = eval_c(x, bdry)
        A = numpy.zeros((p, n))
        for i in range(n):
            A[2 * i, i] = 1
            A[2 * i + 1, i] = -1

        #Call ipm quadr
        print('HESSEMATRIX= ')
        print(G)
        print('EIGENWERTE DER HESSEMATRIX')
        w, v = numpy.linalg.eig(G)
        print(w)
        (x, y, lam) = ipm_quadr(G, c, A, b, x, y, lam)
    fk = func(x)
    result = OptimizeResult(fun=fk, x=x, nit=niter)
    return result
Beispiel #2
0
def filter_meth(f, x, als, dx, s, ps, bdry, my):
    '''
    filters the stepsize according to Waechter/Biegler p. 31
    '''
    delta = 0.1
    stheta = 2.0
    sphi = 2.2
    thetamin = 10000
    eta = 0.02
    gammath = 0.1
    gammaph = 0.1

    gradphi = numpy.dot(grad(f, x, 1e-8), dx)
    xneu = x + als * dx
    sneu = s + als * ps
    phi_neu = f(xneu) - my * numpy.sum(numpy.log(sneu))
    phi = f(x) - my * numpy.sum(numpy.log(s))
    theta = numpy.linalg.norm(eval_c(x, bdry) - s)
    thetaneu = numpy.linalg.norm(eval_c(xneu, bdry) - sneu)

    if theta <= thetamin and gradphi < 0 and als * (
        (-1) * gradphi)**sphi < delta * theta**stheta:
        #armijo
        if phi_neu <= phi + eta * als * gradphi:
            # Case I
            print('CASE I')
            print(als)
            return xneu, sneu
    else:
        print('Case II')
        if thetaneu <= (1 -
                        gammath) * theta or phi_neu <= phi - gammaph * theta:
            return xneu, sneu
    print('FAILFAILFAILFAILFIAL')
    return 0, 0
Beispiel #3
0
def setup_F_ipm(f, A, x, z, s, my, bdry, stepsize=1e-9):
    '''
    Function to set up RHS for ipm (Nocedal p. 569)
    '''

    n = len(x)
    m = len(z)
    F = numpy.zeros(n + m + m)

    F[0:n] = numpy.subtract(grad(f, x, stepsize),
                            numpy.dot(numpy.transpose(A), z))
    F[n:n + m] = numpy.subtract(
        z, my * numpy.dot(numpy.diag(numpy.reciprocal(s)), numpy.ones(m)))
    F[n + m:n + m + m] = numpy.subtract(eval_c(x, bdry), s)

    return -1 * F
Beispiel #4
0
def setup_F_ipm_reduced(f, A, x, z, s, my, bdry, stepsize=1e-9):
    '''
    Function to set up RHS for ipm for the reduced system(Nocedal p. 571)
    '''
    n = len(x)
    m = len(bdry)
    F = numpy.zeros(n)
    sigma = numpy.dot(numpy.diag(numpy.reciprocal(s)), numpy.diag(z))

    F[0:n] = numpy.subtract(grad(f, x, stepsize),
                            numpy.dot(numpy.transpose(A), z))
    temp = numpy.dot(numpy.transpose(A), sigma)
    temp = numpy.dot(temp, numpy.diag(numpy.reciprocal(z)))
    temp2 = numpy.dot(numpy.transpose(A), sigma)
    F[0:n] = F[0:n] - my * numpy.dot(temp, numpy.ones(m)) + numpy.dot(
        temp2, eval_c(x, bdry))

    return -1 * F
Beispiel #5
0
def ipm_error(f, x, A, c_x, z, s, my, text, stepsize=1e-9):
    a = numpy.subtract(grad(f, x, stepsize), numpy.dot(numpy.transpose(A), z))
    #print('INSIDE ERROR')
    #print('grad =')
    #print(numpy.linalg.norm(grad(f,x,stepsize)))

    #print('AT*z')
    #print(numpy.linalg.norm(numpy.dot(numpy.transpose(A), z)))
    #print('zusammen')
    #print(numpy.linalg.norm(a))
    b = numpy.subtract(numpy.dot(numpy.diag(s), z), my * numpy.ones(len(z)))
    #print('Sz-mye')
    #print(numpy.linalg.norm(b))
    c = numpy.linalg.norm(numpy.subtract(c_x, s))
    #print('C(x)-s')
    #print(c)
    text.write("%.4f %.4f %.4f" %
               (numpy.linalg.norm(a), numpy.linalg.norm(b), c))

    res = max(numpy.linalg.norm(a), numpy.linalg.norm(b), c)

    return res
Beispiel #6
0
def basicipm(
        func,
        x,
        args,
        reduced=False,
        maxiter=50,
        stepsize=1e-7,  # for Hesse Matrix/Gradient
        gradtol=1,
        **kwargs):
    '''
    Basic interior point method for nonconvex functions
    '''
    m = 2 * len(kwargs['bounds'].lb)
    bdry = numpy.zeros(m)
    for i in range(m / 2):
        bdry[2 * i] = kwargs['bounds'].lb[i]
        bdry[2 * i + 1] = kwargs['bounds'].ub[i]
    print(bdry)

    niter = 0
    n = len(x)
    #starting parameter
    z = numpy.ones(m)
    s = numpy.ones(m)
    my = 20.0
    delta_old = 0
    #textdummy = open("DUMMY3.txt", "a")
    gradtol = 0.000000001
    #setup A
    A = numpy.zeros((m, n))
    for i in range(n):
        A[2 * i, i] = 1.0
        A[2 * i + 1, i] = -1.0

    #c_x = eval_c(x, bdry)
    #temp = 20
    #while (numpy.linalg.norm(grad(func, x, stepsize))>gradtol and niter<maxiter) :
    while niter < 3:
        niter = niter + 1
        #print('NITER=')
        #print(niter)
        #error = ipm_error(func, x, A, c_x, z, s, my, textdummy)
        #erroralt = 0
        testit = 0
        #while (error > 30*my and testit<22) :
        while (testit < 22):
            testit = testit + 1
            #erroralt = error
            print('INERTIA CORRECTION....')
            delta, gamma = inertia_correction_ldl(setup_Jac_ipm,
                                                  func,
                                                  A,
                                                  x,
                                                  z,
                                                  s,
                                                  my,
                                                  delta_old,
                                                  a=1,
                                                  b=0.5)
            #delta =1
            print('INERTIA CORRETION Done')
            print('DELTA=')
            print(delta)
            print('WAITING FOR NEWTON...')
            if reduced:
                x, s, z = solve_ipm_newton(setup_F_ipm_reduced,
                                           setup_Jac_ipm_reduced,
                                           func,
                                           A,
                                           x,
                                           z,
                                           s,
                                           my,
                                           bdry,
                                           delta,
                                           delta_old,
                                           reduced=reduced,
                                           variant='gmres')
            else:
                x, s, z = solve_ipm_newton(setup_F_ipm,
                                           setup_Jac_ipm,
                                           func,
                                           A,
                                           x,
                                           z,
                                           s,
                                           my,
                                           bdry,
                                           delta,
                                           delta_old,
                                           reduced=reduced,
                                           variant='gmres')
            #error = ipm_error(func, x, A, c_x, z, s, my, textdummy)
            delta_old = delta
            wertwert = func(x)
        #my = my/2
        my = update_my(s, z)
        print(
            '#################################################################'
        )
        print('NEW MY IS')
        print(my)
    result = OptimizeResult(fun=func, x=x, nit=niter)
    print('gradient=')
    print(numpy.linalg.norm(grad(func, x, stepsize)))
    print('X=')
    print(x)
    print('S=')
    print(s)
    print('Z=')
    print(z)

    return result
Beispiel #7
0
def solve_ipm_newton(F,
                     DF,
                     f,
                     A,
                     x,
                     z,
                     s,
                     my,
                     bdry,
                     delta,
                     delta_old,
                     reduced=False,
                     variant='standard',
                     stepsize=1e-9):
    '''
    solves the nonlinear system (Nocedal p. 569) with a naiv Newton method
    delta is the factor of the identity matrix that is added on DF to ensure
    the matrix is positiv definit
    variant for netwon can be:
    - 'standard': naiv computation of DF^-1*f

    - 'ldl': computes the LDL' ecomposation and solves the system via Vorwaerts/
             Rueckwaertseinsetzen

    - 'gmres': uses the scipy generalized minimal residual iteration
    
    '''
    n = len(x)
    m = len(z)
    tol = 0.00000000000001
    maxit = 1  #7#20#300
    nit = 0
    fval = F(f, A, x, z, s, my, bdry)

    text = open("AuswertungIPM.txt", "a")
    #text.write("error1 error2 error3 NewtonIter delta meritwert error Fval gradMerit my\r\n")
    dummy = 1
    while (1):

        merwertneu = f(x)
        ####################TEXTFILE#####################################
        c_x = eval_c(x, bdry)
        error = ipm_error(f, x, A, c_x, z, s, my, text)
        merwert = merwertneu
        print('MERITWERT IN NEWTON=')
        print(merwert)
        text.write("%d %.4f %.4f %.4f %.4f %.4f %.4f\r\n" %
                   (nit, delta, merwert, error, numpy.linalg.norm(fval),
                    numpy.linalg.norm(grad(f, x, stepsize)), my))

        #################################################################
        #print('FVAL IN NEWTON')
        #print(fval)
        #fval  = F(f, A, x, z, s, my, bdry)
        if numpy.linalg.norm(fval) < tol or nit >= maxit:
            break

        nit = nit + 1
        print('Newton Iteration =')
        print(nit)
        dfval = DF(f, A, x, z, s, delta=delta)
        if variant == 'standard':
            dx_ges = numpy.dot(numpy.linalg.inv(dfval), fval)
        elif variant == 'ldl':
            lu, d, per = scipy.linalg.ldl(dfval)
            dx_ges = solve_ldlxb(lu, d, per, fval)
        elif variant == 'gmres':
            dfvals = scipy.sparse.csr_matrix(dfval)
            dx_ges, exitcode = scipy.sparse.linalg.gmres(dfvals, fval)

        if reduced:
            sigma = numpy.dot(numpy.diag(numpy.reciprocal(s)), numpy.diag(z))
            siginv = numpy.dot(numpy.diag(numpy.reciprocal(z)), numpy.diag(s))

            temp = numpy.dot(sigma, numpy.diag(numpy.reciprocal(z)))
            temp2 = numpy.dot(sigma, A)

            pz = my * numpy.dot(temp, numpy.ones(m)) - numpy.dot(
                temp2, dx_ges) - numpy.dot(sigma, eval_c(x, bdry))
            ps = my * numpy.dot(numpy.diag(numpy.reciprocal(z)), numpy.ones(m))
            ps = ps - numpy.dot(siginv, pz) - s

            als, alz = get_alphas(s, z, ps, pz)
            #x,s= filter_meth(f, x , als, dx_ges, s, ps, bdry, my)

            #if dummy and merwertneu<0.31 :
            #    dummy = 0

            if (1):  #(my==20.0) :
                x = x + als * dx_ges
                s = s + als * ps
                z = z + alz * pz
            else:
                print('SCHRITTWEITE ANPASSEN!!!!!!!!!')
                for i in range(10):
                    x = x + (als / (i + 1)) * dx_ges
                    s = s + (als / (i + 1)) * ps
                    z = z + (alz / (i + 1)) * pz
                    merwertneu = f(x)
                    if merwertneu < merwert:
                        break

            fval = F(f, A, x, z, s, my, bdry)
        else:
            ps = dx_ges[n:n + m]
            pz = dx_ges[n + m:n + m + m]
            als, alz = get_alphas(s, z, ps, pz)
            x = x + als * dx_ges[0:n]
            s = s + als * ps
            z = z + alz * pz

        fvalt = fval
        fval = F(f, A, x, z, s, my, bdry)
        #tei   = 2
        #prevent the solution to get worse
        #while numpy.linalg.norm(fval)-numpy.linalg.norm(fvalt)>10 :
        #    print('WERT HAETTE SICH VERSCHLECHTERT')
        #    x = x - (als/tei) * dx_ges[0:n]
        #    s = s - (als/tei) * ps
        #    z = z + (alz/tei) * pz
        #    tei = tei*2
    return x, s, z