def arrayPolyFunctional1(coneData, point, param): result = [] for i in param: result.append(polyFunctional(coneData, M.scaleVek(i, point))) if polyFunctional(coneData, M.scaleVek(i, point)) < eps_graph: print(i) 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 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 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 arrayPolyFunctional1(coneData, point, param): result = [] for i in param: result.append(polyFunctional(coneData, M.scaleVek(i, point))) if polyFunctional(coneData, M.scaleVek(i, point)) < eps_graph: print("I had to print something but it was deleted...") return result
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 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 supportTest(repeats): tooSmall = 0 tooSmall2 = 0 tooSmall3 = 3 tooBig = 0 easyFail = 0 n = 0 while (n < repeats): containsPoint_eps = 0 P = rP.getRandomPolygon(3) Q = rP.getRandomPolygon(4) cD_P = cV.getConeVol(P) for i in range(len(P)): print(len(P)) u = [cD_P[i - 1][0], cD_P[i - 1][1]] alpha = rP.supportFunctionCartesianCentered(Q, u) beta = rP.supportFunctionCartesianCentered2(Q, u) gamma = 1 #trySupport( Q , u , 0.0000001) if math.fabs( M.scal(u, P[i - 1]) - rP.supportFunctionCartesianCentered2(P, u)) > 1: easyFail += 1 if not (containsPoint(Q, M.scaleVek(alpha - math.exp(-15), u))): tooBig += 1 if (containsPoint(Q, M.scaleVek(alpha + 0.01, u))): #plotPoly( P , 'r' ) #plotPoly( Q , 'y') tooSmall += 1 if (containsPoint(Q, M.scaleVek(beta + 0.01, u))): #plotPoly( P , 'r' ) #plotPoly( Q , 'y') tooSmall2 += 1 if (containsPoint(Q, M.scaleVek(gamma + 0.01, u))): #plotPoly( P , 'r' ) #plotPoly( Q , 'y') tooSmall3 += 1 n += 1 print([easyFail, tooBig, tooSmall, tooSmall2, tooSmall3])
def preSolverPlot( cD , params ): x = cV.domain( 0.22 , 0.223 , 0.0001 ) v = cV.gamma( cD , params ) for x_value in x: stretchedParams = M.scaleVek( x_value , v ) y_value = preSolverPhi( stretchedParams , cD ) mp.plot( x_value , y_value , 'ro' ) mp.show()
def makeUnitVolume(orderedPolytop): coneVolume = cV.getConeVol(orderedPolytop) volume = 0 for data in coneVolume: volume = volume + data[2] for i in range(len(orderedPolytop)): orderedPolytop[i - 1] = M.scaleVek(1.0 / math.sqrt(volume), orderedPolytop[i - 1])
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 supportRationalTest(repeats): containsPoint_eps = 0 tooSmall = 0 tooSmall2 = 0 tooBig = 0 easyFail = 0 n = 0 while (n < repeats): P = rRP.getRandomRationalPolygon(3, 3) Q = rRP.getRandomRationalPolygon(4, 3) #rP.supportFunctionCartesianCenteredRational() for i in range(len(P)): u = [ P[i % len(P)][1] - P[i - 1][1], P[i % len(P)][0] - P[i - 1][0] ] alpha = rP.supportFunctionCartesianCenteredRational( Q, u) / (u[0] * u[0] + u[1] * u[1]) beta = rP.supportFunctionCartesianCenteredRational( Q, u) / (u[0] * u[0] + u[1] * u[1]) #pos_diff = M.scal( u , P[ i - 1 ]) - rP.supportFunctionCartesianCentered2( P , u) #if pos_diff > 0.1 or - pos_diff > 0.1: # easyFail += 1 if not (containsPoint(Q, M.scaleVek(alpha - f.Fraction(1, 10), u))): tooBig += 1 if (containsPoint(Q, M.scaleVek(alpha + f.Fraction(1, 1000), u))): #plotPoly( P , 'r' ) #plotPoly( Q , 'y') tooSmall += 1 if (containsPoint(Q, M.scaleVek(beta + f.Fraction(1, 1000), u))): #plotPoly( P , 'r' ) #plotPoly( Q , 'y') tooSmall2 += 1 n += 1 print([easyFail, tooBig, tooSmall, tooSmall2])
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 gradPolyFunctional(coneData, point): B = M.idMatrix(2) A = gradConeVolumeIterator(coneData, point) A.scale(-1) B.add(A) b = M.subVek(point, getConeVolIterator(coneData, point)) b = M.scaleVek(2, b) result = B.image(b) 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
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 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 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 vizualizeSupportRational(rationalPolygon, rationalDirection): P = rationalPolygon u = rationalDirection norm_squared = u[0] * u[0] + u[1] * u[1] alpha = rP.supportFunctionCartesianCenteredRational(P, u) / norm_squared p = M.scaleVek(alpha, u) # make p and polygon coordinates to float numbers for point in P: point[0] += 0.0 point[1] += 0.0 p[0] += 0.0 p[1] += 0.0 x = [] y = [] support_x = [] support_y = [] supportLineDirection = [-p[1], p[0]] for v in P: x.append(v[0]) y.append(v[1]) for i in range(100): point_pos = M.addScaleVek(p, i / 10.0, supportLineDirection) point_neg = M.addScaleVek(p, -i / 10.0, supportLineDirection) support_x.append(point_pos[0]) support_y.append(point_pos[1]) support_x.append(point_neg[0]) support_y.append(point_neg[1]) # make a line between last point and first point x.append(P[0][0]) y.append(P[0][1]) #x.append( 0 ) #y.append( 0 ) mp.plot(x, y, 'r' + '--') mp.plot(x, y, 'r' + 'o') mp.plot(p[0], p[1], 'ro') mp.plot(support_x, support_y, 'bo') mp.axis(getPolyDomain(P)) mp.show()
def getConeVol(vertices): result = [] n = len(vertices) for i in range(n): v = M.subVek(vertices[i], vertices[(i - 1 + n) % n]) u_tilde = getClockRotation(v) divisor = M.norm(v) if u_tilde[0] == 0 and u_tilde[1] == 0: divisor = mE.getMachEps() u = M.scaleVek(1.0 / divisor, u_tilde) height = M.scal(u, vertices[i - 1]) if height < 0: print('height is negativ at ') print(i) facetVolume = M.norm(v) coneVolume = 0.5 * height * facetVolume result.append([u[0], u[1], coneVolume]) return result
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 trySupport(Q, u, eps): alternative = 1 exp = 0 if containsPoint(Q, u): while containsPoint(Q, M.scaleVek( alternative + eps, u)) or not containsPoint(Q, M.scaleVek(alternative - eps, u)): if containsPoint(Q, M.scaleVek(alternative + 10**exp, u)): alternative += 10**exp else: exp -= 1 else: while containsPoint(Q, M.scaleVek( alternative + eps, u)) or not containsPoint(Q, M.scaleVek(alternative - eps, u)): if not containsPoint(Q, M.scaleVek(alternative + 10**exp, u)): alternative -= 10**exp else: exp -= 1 return alternative
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)) diff = cV.phi(params_now, cD) - cV.phi(params_next, cD)
def gradPhi(params, cD): A = gradGamma(cD, params) v = gradPolyFunctional(cD, gamma(cD, params)) return M.scaleVek(1, A.image(v))
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
#cD_test = cV.getConeVol( [[1,0],[0,1],[-1,0],[0,-1]]) #cD_test = cV.getConeVol( [[1,1],[-1,1],[-1,-1],[1,-1]]) P = [[1, 1], [-1, 1], [-1, -1], [2, -1]] cD_test = cV.getConeVol(P) for i in range(x_shape[0]): for j in range(x_shape[1]): point = [X[i][j], Y[i][j]] try: v = M.subVek(cV.getConeVolIterator(cD_test, point), point) if v[0]**2 + v[1]**2 < 0: v = [0, 0] x_sing.append(point[0]) y_sing.append(point[1]) else: if (M.norm(v) != 0): v = M.scaleVek(density / M.norm(v), v) else: v = [0, 0] x_fix.append(point[0]) y_fix.append(point[1]) except ZeroDivisionError: #print(point) x_sing.append(point[0]) y_sing.append(point[1]) v = [0, 0] U[i, j] = v[0] V[i, j] = v[1] fig, ax = plt.subplots() ax.quiver(X, Y, U, V, units='xy', scale=2, color='red')