def containsPoint(orderedCartesianVertices, point): if (len(orderedCartesianVertices) == 1): if (M.norm(M.subVek(point, orderedCartesianVertices[1])) <= test_eps): return True else: return False if (len(orderedCartesianVertices) == 2): d = M.subVek(orderedCartesianVertices[0], orderedCartesianVertices[1]) normal = [d[1], -d[0]] if (math.fabs( M.scal(point, normal) - M.scal(orderedCartesianVertices[1], normal)) <= containsPoint_eps): return True else: return False i = 0 n = len(orderedCartesianVertices) for v in orderedCartesianVertices: w = orderedCartesianVertices[(i + 1) % n] d = M.subVek(w, v) normal = [d[1], -d[0]] if (M.scal(normal, point) - containsPoint_eps > M.scal(normal, v)): return False i = i + 1 return True
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 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 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 getWorsteNormalsDirection(polygon): n = len(polygon) result = 0 cD = cV.getConeVol(polygon) for i in range(n): u = [cD[i % n][0], cD[i % n][1]] v = polygon[i - 1] w = polygon[i % n] diff = math.fabs(M.scal(v, u) - M.scal(w, u)) if diff > result: result = diff return result
def makeNormalsTest(polygon, eps_norm, eps_direction): n = len(polygon) cD = cV.getConeVol(polygon) for i in range(n): u = [cD[i % n][0], cD[i % n][1]] if math.fabs(M.norm(u) - 1) > eps_norm: return False v = polygon[i - 1] w = polygon[i % n] diff = math.fabs(M.scal(v, u) - M.scal(w, u)) if diff > eps_direction: return False return True
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 diffGetNextVertex(u, volume, point): B = M.Matrix([[-u[1]], [u[0]]]) A = M.Matrix([[-u[0], -u[1]]]) C = B.mult(A) c = M.scal(point, u) c = 2 * volume / (c**2) C.scale(c) # Matrix.plus oder Matrix.add verwenden? C.add(M.idMatrix(2)) return C
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 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 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 getPseudoConeVolRational(polygonRational): result = [] P = polygonRational n = len(P) for i in range(n): v = M.subVek(P[i], P[(i - 1 + n) % n]) u = getClockRotation(v) # this equals 1/2 * determinant, since norm of u is the same as norm of v, both get cancelled volume = f.Fraction(1, 2) * M.scal(u, P[i - 1]) if volume < 0: print('volume is negativ at ') print(i) result.append([u[0], u[1], volume]) return result
def supportFunctionCartesianCenteredRational(K_cartesianCenteredRational, u_Rational): P = K_cartesianCenteredRational n = len(P) result = -math.inf # luckily, norm of u_i cancels in the fraction of the logMin product inequality... # hier muss ich noch dran arbeiten... for v in P: # I do not need a special rational support function, do I? value = M.scal(v, u_Rational) if value > result: result = value return result
def supportFunctionCartesianCentered2(K_cartesianCentered, u): if math.fabs(M.norm(u) - 1) > 0.0001: print( ' u is not normed for support function, result needs to be divided by norm ' ) return [] P = K_cartesianCentered result = -math.inf for v in P: # I do not need a special rational support function, do I? value = M.scal(v, u) if value > result: result = value return result
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 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 )
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