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
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
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
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
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