def getBFGSApprox(cD, params_new, params_k, A_k): s_vector = M.subVek(params_new, params_k) y_vector = M.subVek(cV.gradPhiApprox(params_new, cD, 0.0001), cV.gradPhiApprox(params_k, cD, 0.0001)) # s_Matrix and y_Matix is a column, not a row, therefor copyTrans s_Matrix = M.Matrix([s_vector]).copyTrans() y_Matrix = M.Matrix([y_vector]).copyTrans() dividend = A_k.mult(s_Matrix) dividend = dividend.mult(dividend.copyTrans()) divisor = M.scal(s_vector, A_k.image(s_vector)) quotient = dividend quotient.scale(1.0 / divisor) rankOneMod = M.subMatrix(A_k, quotient) dividend2 = y_Matrix.mult(y_Matrix.copyTrans()) # here could be a division through zero. If this occurence, then I should just translate params_new a liiiitle bit... divisor2 = M.scal(y_vector, s_vector) quotient = dividend2 quotient.scale(1.0 / divisor2) rankTwoMod = M.addMatrix(rankOneMod, quotient) return rankTwoMod
def coneVolumeDescendBFGSApprox(cD, params_new, params_prev, crease, efficiency, beta_1, beta_2): A_k = M.idMatrix(2) n = 0 while (cV.phi(params_new, cD) > eps_descend): while (True): try: A_k = BFGS.getBFGSApprox(cD, params_new, params_prev, A_k) break except ZeroDivisionError: print('es geht nicht besser mit BFGSApprox') return params_new break antiGrad = M.scaleVek(-1, cV.gradPhiApprox(params_new, cD, 0.0001)) d = A_k.lgsSolve(antiGrad) d = M.scaleVek(1.0 / M.norm(d), d) alpha = sS.stepSizeArmijo(cD, params_new, d, crease, efficiency, beta_1, beta_2) d = M.scaleVek(alpha, d) params_prev = [params_new[0], params_new[1]] params_new = M.addVek(params_new, d) if (M.dist(params_new, params_prev) < minimalStep_BFGSApprox): print(' distance is lower than minimalStep of BFGSApprox ') break n = n + 1 return params_new
def scalGradNormedApprox( params , cD ): v = params w = cV.gradPhiApprox( params , cD , 0.001) result = M.scal( v , w ) result = result / ( M.norm( v ) * M.norm( w ) ) return result
def coneVolumeDescend(cD, start): result = start previous = [-1, -1] n = 0 print('gehe in while schleife ') while (cV.phi(result, cD) > eps_descend): if M.dist(previous, result) > 0.1: previous[0] = result[0] previous[1] = result[1] d = M.scaleVek(-1, cV.gradPhiApprox(result, cD, 0.0001)) # d = M.scaleVek( 1 / M.norm(d) , d ) alpha = sS.stepSize_posGrad(cD, result, d, n) result = M.addVek(result, M.scaleVek(alpha, d)) n = n + 1 else: print('versuche es mit BFGS und BFGSApprox, Start bei:') print(cV.gamma(cD, result)) result_2 = coneVolumeDescendBFGS(cD, result, previous, crease_test, efficiency_test, beta_1test, beta_2test) print('BFGS ist fertig mit:') print(cV.gamma(cD, result_2)) result_1 = coneVolumeDescendBFGSApprox(cD, result, previous, crease_test, efficiency_test, beta_1test, beta_2test) print('BFGS Approx ist fertig!') if cV.phi(result_1, cD) < cV.phi(result_2, cD): return result_1 else: return result_2 return result
polygon_test2 = [[2.673368179682499, 3.09152986544487], [1.2086453601351808, 4.28111986768648], [-1.1761317014903958, -0.022433820601322707], [-3.4952312190856785, -4.881491593765966], [0.789349380758395, -2.4687243187640626]] cD = cV.getConeVol(polygon_test2) params_now = [4.7, 1.6152821997297826] print(cV.gamma(cD, params_now)) print(cV.phi(params_now, cD)) d = [ -0.2083940408151545, -0.9780449497608644 ] # should come from a BFGS algorithm to test the efficiency of BFGS directions grad = M.scaleVek(1.0 / M.norm(cV.gradPhi(params_now, cD)), cV.gradPhi(params_now, cD)) grad_approx = cV.gradPhiApprox(params_now, cD, 0.00001) stepSize = 1 params_next = M.addVek(params_now, M.scaleVek(stepSize, d)) v.visiualizeLowValueOnGrid(0.001, 0.00001, cD, params_now, 0.02405, 0.024059, 0.02406) v.vizNiveauGradOnGrid(0.001, 0.00001, cD, params_now, d, 0.000001) v.vizNiveauGradOnGrid(0.001, 0.00001, cD, params_now, grad, 0.000001) v.vizNiveauGradOnGrid(0.001, 0.00001, cD, params_now, grad_approx, 0.000001) n = 0 diff = (1 * cV.phi(params_now, cD)) - (1 * cV.phi(params_next, cD)) d = [-1, 2] while (diff < 0): stepSize = stepSize * 0.5 params_next = M.addVek(params_now, M.scaleVek(stepSize, d)) diff = cV.phi(params_now, cD) - cV.phi(params_next, cD) if (n + 1) % 10 == 0: