def getBFGS(cD, params_new, params_k, A_k): s_vector = M.subVek(params_new, params_k) y_vector = M.subVek(cV.gradPhi(params_new, cD), cV.gradPhi(params_k, cD)) # 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 #print( 'vectors are') #print(y_vector) #print( s_vector) #print( cV.gradPhi(params_new , cD)) quotient.scale(1.0 / divisor2) rankTwoMod = M.addMatrix(rankOneMod, quotient) return rankTwoMod
def vizLowValue( cD , n , first_bound, second_bound , third_bound): grid = pS.getGrid(n) x_1 = [] y_1 = [] x_2 = [] y_2 = [] x_3 = [] y_3 = [] b = 0 d = 0 for point in grid: while (True): try: value = cV.phi(point, cD) if value <= first_bound: x_1.append(point[0]) y_1.append(point[1]) else: if value <= second_bound: x_2.append(point[0]) y_2.append(point[1]) else: if value <= third_bound: x_3.append(point[0]) y_3.append(point[1]) if point[0] > b: b = point[0] if point[1] > d: d = point[1] break except ZeroDivisionError: # print('zero division at',pair) break mp.plot(x_1 , y_1 , 'go') mp.plot(x_2 , y_2 , 'yo') mp.plot(x_3, y_3, 'ro') mp.axis( [ 0, b, 0, d ] ) # print(vertices) mp.show() if len(x_1) > 0 : params = [ x_1[0] , y_1[0] ] vertex = cV.gamma(cD, params) print( ' Point near to result , gamma params , phi-value , gradient ') print(vertex) print( params) print( cV.phi( params , cD ) ) print( cV.gradPhi( params , cD) ) if len(x_1) > 1 : lastIndex = len( x_1 ) - 1 params = [x_1[lastIndex],y_1[lastIndex]] print(' ANOTHER one is ') vertex = cV.gamma(cD, params) print(vertex) print(params) print(cV.phi(params, cD)) print(cV.gradPhi(params, cD))
def getPositiveGrad( grid , cD ): result = [] gradNorm_result = math.inf for point in grid: while (True): try: scal_point = M.scal(cV.gradPhi( point , cD ), point) gradNorm_point = M.norm(cV.gradPhi(point, cD)) if scal_point >= 0 and gradNorm_point < gradNorm_result: result = point gradNorm_result = gradNorm_point break except ZeroDivisionError: # print('zero division at',pair) break return result
def coneVolumeDescendArmijo(cD, start, crease, efficiency, beta_1, beta_2): result = start n = 0 previous = [-1, -1] print('gehe in while schleife ') while (cV.phi(result, cD) > eps_descend): if M.dist(previous, result) > minimalStep_descendArmijo: previous[0] = result[0] previous[1] = result[1] d = M.scaleVek(-1, cV.gradPhi(result, cD)) #d = M.scaleVek( 1 / M.norm(d) , d ) alpha = sS.stepSizeArmijo(cD, result, d, crease, efficiency, beta_1, beta_2) result = M.addVek(result, M.scaleVek(alpha, d)) else: print('versuche es mit BFGS und BFGSApprox') result_1 = coneVolumeDescendBFGSApprox(cD, result, previous, crease, efficiency, beta_1, beta_2) result_2 = coneVolumeDescendBFGS(cD, result, previous, crease, efficiency, beta_1, beta_2) if cV.phi(result_1, cD) < cV.phi(result_2, cD): return result_1 else: return result_2 n = n + 1 return result
def powellFunction_1(cD, params, d, step): dividend = cV.phi(M.addScaleVek(params, step, d), cD) - cV.phi(params, cD) divisor = step * M.scal(cV.gradPhi(params, cD), d) if (step <= eps): return 1 return dividend / divisor
def scalGradNormed( params , cD ): v = params w = cV.gradPhi( params , cD ) result = M.scal( w , v ) norm_1 = M.norm( v ) norm_2 = M.norm( w ) #if norm_2 * norm_1 == 0: # return 0 return result / ( norm_1 * norm_2 )
def vizLowGrad( cD , n , first_bound, second_bound , third_bound): grid = pS.getGrid(n) x_1 = [] y_1 = [] x_2 = [] y_2 = [] x_3 = [] y_3 = [] b = 0 d = 0 for point in grid: while (True): try: value = M.norm(cV.gradPhi(point, cD)) if value <= first_bound: x_1.append(point[0]) y_1.append(point[1]) else: if value <= second_bound: x_2.append(point[0]) y_2.append(point[1]) else: if value <= third_bound: x_3.append(point[0]) y_3.append(point[1]) if point[0] > b: b = point[0] if point[1] > d: d = point[1] break except ZeroDivisionError: # print('zero division at',pair) break mp.plot(x_1 , y_1 , 'go') mp.plot(x_2 , y_2 , 'yo') mp.plot(x_3, y_3, 'ro') mp.axis( [ 0, b, 0, d ] ) # print(vertices) mp.show()
def coneVolumeDescendBFGS(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): # ICH VERÄNDERE HIER MEIN CREASE... crease = 0.000001 #cV.phi( params_new , cD) * 0.00000001 while (True): try: A_k = BFGS.getBFGS(cD, params_new, params_prev, A_k) break except ZeroDivisionError: print('es geht nicht besser') return params_new break antiGrad = M.scaleVek(-1, cV.gradPhi(params_new, cD)) d = A_k.lgsSolve(antiGrad) d = M.scaleVek(1.0 / M.norm(d), d) alpha = sS.stepSize_posGrad( cD, params_new, d, n) # 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_BFGS): print(' distance is lower than minimalStep of BFGS ') break n = n + 1 return params_new
def powellFunction_2(cD, params, d, step): v = cV.gradPhi(M.addScaleVek(params, step, d)) dividend = M.scal(v, d) divisor = M.scal(cV.gradPhi(params, cD), d) return dividend / divisor
def stepSizeArmijo(cD, point, d, crease, efficiency, beta_1, beta_2): result = -efficiency * (M.scal(cV.gradPhi(point, cD), d) / (M.norm(d)**2)) while notEfficient(cD, point, d, result, crease): result = beta_2 * result return result
def notEfficient(cD, point, d, stepSize, crease): v = M.addVek(point, M.scaleVek(stepSize, d)) upper_bound = cV.phi(point, cD) + crease * stepSize * M.scal( cV.gradPhi(point, cD), d) / M.norm(d) return cV.phi(v, cD) > upper_bound
def scalAbsGrad( params , cD ): return math.fabs(M.scal( cV.gradPhi( params , cD ) , params ))
def scalGrad( params , cD ): return M.scal( cV.gradPhi( params , cD ) , params )
import vizualization as v 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))