def gradPhiApprox(params, cD, h): e_1 = [1, 0] e_2 = [0, 1] point_diff1 = M.addVek(params, M.scaleVek(h, e_1)) quotient_diff1 = phi(point_diff1, cD) / h - phi(params, cD) / h point_diff2 = M.addVek(params, M.scaleVek(h, e_2)) quotient_diff2 = phi(point_diff2, cD) / h - phi(params, cD) / h return [quotient_diff1, quotient_diff2]
def stepSize_posGrad(cD, point, d, n): alpha = 0.5 nextPoint = M.addVek(point, M.scaleVek(alpha, d)) while (cV.phi(point, cD) + eps < cV.phi( nextPoint, cD)): #or pS.scalGrad( cD , nextPoint ) < 0 ): alpha = alpha * 0.5 nextPoint = M.addVek(point, M.scaleVek(alpha, d)) if n % 300 == 0: print(alpha) if alpha < eps == 1: return 0 return alpha
def diffConeVolIteratorApprox(params, cD, h): e_1 = [1, 0] e_2 = [0, 1] point_diff1 = M.addVek(params, M.scaleVek(h, e_1)) quotient_diff1 = M.subVek(coneVolIterator(cD, point_diff1), coneVolIterator(cD, params)) quotient_diff1 = M.scaleVek(1.0 / h, quotient_diff1) point_diff2 = M.addVek(params, M.scaleVek(h, e_2)) quotient_diff2 = M.subVek(coneVolIterator(cD, point_diff2), coneVolIterator(cD, params)) quotient_diff2 = M.scaleVek(1.0 / h, quotient_diff2) return M.Matrix([quotient_diff1, quotient_diff2]).copyTrans()
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 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 gamma(coneData, params): # d_0 und d_1 verdrehen? d_0 = [-coneData[0][1], coneData[0][0]] d_1 = [coneData[1][1], -coneData[1][0]] v = M.scaleVek(params[0], d_0) w = M.scaleVek(params[1], d_1) return M.addVek(v, w)
def hMethodConeVolIteratorCheck(cD, point, eps, h): while (True): try: vektor = cV.coneVolIterator(cD, point) break except ZeroDivisionError: return True break diff = cV.diffConeVolumeIterator(cD, point) e_1 = [1, 0] e_2 = [0, 1] diff_1 = diff.image(e_1) diff_2 = diff.image(e_2) point_diff11 = M.addVek(point, M.scaleVek(h, e_1)) point_diff12 = M.subVek(point, M.scaleVek(h, e_1)) quotient_diff1 = M.subVek( M.scaleVek(1 / (2 * h), cV.coneVolIterator(cD, point_diff11)), M.scaleVek(1 / (2 * h), cV.coneVolIterator(cD, point_diff12))) point_diff21 = M.addVek(point, M.scaleVek(h, e_2)) point_diff22 = M.subVek(point, M.scaleVek(h, e_2)) quotient_diff2 = M.subVek( M.scaleVek(1 / (2 * h), cV.coneVolIterator(cD, point_diff21)), M.scaleVek(1 / (2 * h), cV.coneVolIterator(cD, point_diff22))) difference_1 = M.dist(quotient_diff1, diff_1) difference_2 = M.dist(quotient_diff2, diff_2) print(' the differences equals') print(diff_1) print(quotient_diff1) print(diff_2) print(quotient_diff2) if difference_1 >= eps or difference_2 >= eps: print(' the differences equals') print(difference_1) print(difference_2) return False return True
def hMethodPolyFunctionalCheck(cD, point, eps, h): while (True): try: value = cV.polyFunctional(cD, point) break except ZeroDivisionError: return True break e_1 = [1, 0] e_2 = [0, 1] grad_point = cV.gradPolyFunctional(cD, point) # diff is a row, grad is a column... diff = M.Matrix([grad_point]) diff_1 = diff.image(e_1)[0] diff_2 = diff.image(e_2)[0] pointTrans_1 = M.addVek(point, M.scaleVek(h, e_1)) pointTrans_2 = M.addVek(point, M.scaleVek(h, e_2)) diffQuotient_1 = cV.polyFunctional(cD, pointTrans_1) / h substraction_1 = cV.polyFunctional(cD, point) / h diffQuotient_1 = diffQuotient_1 - substraction_1 diffQuotient_2 = cV.polyFunctional(cD, pointTrans_2) / h substraction_2 = cV.polyFunctional(cD, point) / h diffQuotient_2 = diffQuotient_2 - substraction_2 dist_1 = math.fabs(diff_1 - diffQuotient_1) dist_2 = math.fabs(diff_2 - diffQuotient_2) if dist_1 > eps or dist_2 > eps: print(' difference equals ') print(dist_1) print(dist_2) print(' calculated diff and approximated diff:') diff.list() print([diffQuotient_1, diffQuotient_2]) return False return True
def vizNiveauGradOnGrid( size , stepSize , cD , param , grad , eps): grid = [] value_param = cV.phi( param , cD ) n = math.floor(size * 1.0/stepSize) for i in range(n): for j in range(n): grid.append( [ i * stepSize - size / 2.0 + param[0], j *stepSize - size / 2.0 + param[1]]) print('grid ist fertig') x_1 = [] y_1 = [] for point in grid: while(True): try: value= cV.phi(point , cD ) if math.fabs(value - value_param) < eps: x_1.append(point[0]) y_1.append([point[1]]) break except ZeroDivisionError: break d= M.scaleVek( 1.0 / M.norm(grad) , grad ) x_d = [] y_d = [] stepBound = 0.71 * size step = - stepBound while( step <= stepBound ): point = M.addVek( param , M.scaleVek( step , d ) ) x_d.append( point[0] ) y_d.append( point[1] ) step = step + stepSize a_x = param[0] - size / 2.0 b_x = param[0] + size / 2.0 + 5 a_y = param[1] - size / 2.0 b_y = param[1] + size / 2.0 + 5 mp.plot( x_1 , y_1 , 'go') mp.plot( x_d , y_d , 'yo') mp.plot([param[0]], [param[1]], 'wo') mp.axes( [a_x , b_x , a_y , b_y]) #print('here comes minimal point, gamma , value, gradient:') #print( point_min ) #print( cV.gamma( cD , point_min )) #print( cV.phi( point_min , cD )) #print( cV.gradPhi( point_min , cD)) mp.show()
def nextVertex(u, volume, point): orth = [] # gegen uhrzeigersinn um 90 grad drehen orth.append(-u[1]) orth.append(u[0]) # assumes that 0 lies in K (i.e. point is not orthogonal) d = M.scaleVek(2 * volume / M.scal(point, u), orth) temp = M.addVek(point, d) point[0] = temp[0] point[1] = temp[1]
def getDistOrderedGrid( steps , stepSize ): grid = [] n = math.floor( steps / stepSize ) #range( n ) = [ 0 , 1 , ... , n - 1 ], so ... for k in range( n + 1): diagonalStart = [ k * stepSize , 0 ] grid.append(diagonalStart) for l in range(k): diagonalStart = M.addVek( diagonalStart , [ - stepSize , stepSize ] ) grid.append( diagonalStart ) return grid
def hMethodNextVertexCheck(u, V, point, eps, h): nextVektor = cV.getNextVertex(u, V, point) while (True): try: nextVektor = cV.getNextVertex(u, V, point) break except ZeroDivisionError: return True break diff = cV.diffGetNextVertex(u, V, point) e_1 = [1, 0] e_2 = [0, 1] diff_1 = diff.image(e_1) diff_2 = diff.image(e_2) point_diff1 = M.addVek(point, M.scaleVek(h, e_1)) quotient_diff1 = M.subVek( M.scaleVek(1 / h, cV.getNextVertex(u, V, point_diff1)), M.scaleVek(1 / h, cV.getNextVertex(u, V, point))) point_diff2 = M.addVek(point, M.scaleVek(h, e_2)) quotient_diff2 = M.subVek( M.scaleVek(1 / h, cV.getNextVertex(u, V, point_diff2)), M.scaleVek(1 / h, cV.getNextVertex(u, V, point))) difference_1 = M.dist(quotient_diff1, diff_1) difference_2 = M.dist(quotient_diff2, diff_2) print(' the differences equals') print(difference_1) print(difference_2) if difference_1 >= eps or difference_2 >= eps: print(' the differences euqal') print(difference_1) print(difference_2) return False return True
def gradPolyFunctionalTest_random(repeats, edgeNumber, eps, h, delta, nearby_option): n = 1 if not nearby_option: while n <= repeats: P = rP.getRandomPolygon(edgeNumber) cD_test = cV.getConeVol(P) point_test = [random.random() * 10, random.random() * 10] # could be improved by making delta smaller if check is false ... orby setting point_test in the near of an vertex... check = hMethodPolyFunctionalCheck(cD_test, point_test, eps, h) if not check: print( ' gradPolyFunctionalTest failed with polytop , point_test , value : ' ) print(P) print(point_test) print(cV.polyFunctional(cD_test, point_test)) n = n + 1 else: while n <= repeats: P = rP.getRandomPolygon(edgeNumber) cD_test = cV.getConeVol(P) point_test = [random.random(), random.random()] norm = M.norm(point_test) point_test = M.scaleVek(delta / norm, point_test) print(' here is the translation') print(point_test) point_test = M.addVek(point_test, P[0]) # could be improved by making delta smaller if check is false ... orby setting point_test in the near of an vertex... check = hMethodPolyFunctionalCheck(cD_test, point_test, eps, h) if not check: print( ' gradPolyFunctionalTest failed with polytop , point_test , value : ' ) print(P) print(point_test) print(cV.polyFunctional(cD_test, point_test)) n = n + 1
def transGridMid( orderedGrid , newMidPoint): length = len(orderedGrid) start = orderedGrid[0] end_leftup = orderedGrid[ length -1 ] end_rightdown = [ end_leftup[1] , start[1] ] midOfGrid = M.getMidPoint( end_leftup , end_rightdown ) translation = M.subVek( newMidPoint , midOfGrid ) i = 0 # delete every point in orderedGrid, that is not in first (postive) quadrant. Because of 'index out of bounce' error, i and length may have to be reduced while i < length: orderedGrid[i] = M.addVek( orderedGrid[i] , translation ) if orderedGrid[i][0] < 0 or orderedGrid[i][1] < 0: orderedGrid.pop(i) i = i - 1 length = length - 1 i = i + 1
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
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
[-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: print(diff)
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