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 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 logMinRoundAutoTest(repeats, roundMethod, digits, bringInPosition, getPosition, eps_position, eps_volume, eps_normals, eps_logMin): n = 0 logMinTrue = 0 logMinFalse = 0 logMinTriangleFalse = 0 while n < repeats: P = rP.getRandomNoncenteredPolarPolygon( math.floor(10 * random.random()) + 4) Q = rP.getRandomNoncenteredPolarPolygon( math.floor(10 * random.random()) + 4) K = rP.getCartesian(P) L = rP.getCartesian(Q) roundMethod(K, digits) roundMethod(L, digits) #because of roundig, convexity can be lost and support function can get negativ # because of rounding, two edges can be the same. # and then norm vector will be [] or something ? Because a type error ouccurs while (True): try: if not logMinTest(K, L, bringInPosition, eps_logMin): if pT.isConvex(K) and pT.isConvex(L) and pT.isConvexRun( K) and pT.isConvexRun(L): if M.norm(getPosition(K)) + M.norm( getPosition(L)) < eps_position: if math.fabs(rP.getVolume(K) - 1) + math.fabs( rP.getVolume(L) - 1) < eps_volume: # which bound is sufficient for a stable logMin calculation? a bound of 0.00003 seems to be always fulfilled... if pT.getWorsteNormalsDirection( K) < eps_normals: if len(K) == 3 or len(L) == 3: print('das darf nicht sein') print(K) print(L) pT.plotPoly(K, 'r') pT.plotPoly(L, 'g') logMinTriangleFalse += 1 else: print('logMin Gegenbeispiel') print(K) print(L) pT.plotPoly(K, 'r') pT.plotPoly(L, 'g') logMinFalse += 1 else: logMinTrue += 1 break except TypeError: break n = n + 1 print('done') print([logMinTrue, logMinFalse, logMinTriangleFalse])
def supportFunctionPolar(K_polar, u): angle = getAngle(u) neighbours = getPolarNeighbours(K_polar, angle) v = getCartesian([neighbours[1]])[0] w = getCartesian([neighbours[2]])[0] h_tilde = getMin(v, w, angle) divisor = M.norm(u) if divisor == 0: print('warum ist u als Normalenvektor so klein?') print(u) return h_tilde / mE.getMachEps() return h_tilde / M.norm(u)
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 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 getSumOuterNormal(polygon): coneVol = cV.getConeVol(polygon) normSum = 0 for v in coneVol: n = [v[0], v[1]] normSum = normSum + M.norm(n) return normSum
def preSolverPhi( params , cD ): v = cV.gamma( cD , params ) t = M.norm(v) n = len( cD ) if t >= 1 : return ( t ** ( 2 * n ) * cV.phi( params , cD ) ) else: return cV.phi( params , cD )
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 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 logMinAutoTest(repeats, bringInPosition, getPosition, eps_position, eps_volume, eps_normals, eps_logMin): n = 0 logMinTrue = 0 logMinFalse = 0 logMinTriangleFalse = 0 while n < repeats: P = rP.getRandomNoncenteredPolarPolygon(math.floor(3)) Q = rP.getRandomNoncenteredPolarPolygon(math.floor(4)) K = rP.getCartesian(P) L = rP.getCartesian(Q) if not logMinTest(K, L, bringInPosition, eps_logMin): if pT.isConvex(K) and pT.isConvex(L) and pT.isConvexRun( K) and pT.isConvexRun(L): if M.norm(getPosition(K)) + M.norm( getPosition(L)) < eps_position: if math.fabs(rP.getVolume(K) - 1) + math.fabs( rP.getVolume(L) - 1) < eps_volume: # which bound is sufficient for a stable logMin calculation? a bound of 0.00003 seems to be always fulfilled... if pT.getWorsteNormalsDirection(K) < eps_normals: if len(K) == 3 or len(L) == 3: print('das darf nicht sein') print(K) print(L) pT.plotPoly(K, 'r') pT.plotPoly(L, 'g') logMinTriangleFalse += 1 else: print('logMin Gegenbeispiel') print(K) print(L) pT.plotPoly(K, 'r') pT.plotPoly(L, 'g') logMinFalse += 1 else: logMinTrue += 1 n = n + 1 print('done') print([logMinTrue, logMinFalse, logMinTriangleFalse])
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 sigma(params, cD): n = len(cD) point = gamma(cD, params) touchedPoints = getConeVolIteratedVertices(cD, point) #result = M.dist( point , touchedPoints[ n-1 ]) ** 2 center = [0, 0] for point in touchedPoints: center = M.addScaleVek(center, 1.0 / n, point) result = M.norm(center)**2 + phi(params, cD) return result
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 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 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 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 polyFunctionalTest(repeats, edgeNumber, eps): turns = 0 while turns < repeats: P = rP.getRandomPolygon(edgeNumber) cD = cV.getConeVol(P) vertex = P[0] value_vertex = cV.polyFunctional(cD, vertex) grad_vertex = cV.gradPolyFunctional(cD, vertex) # getConeVol, polyFunctional oder gradPolyFunctional könnte falsch sein... if (value_vertex >= eps): print(' Fehler bei polyFunctionalTest , value zu hoch') print(P) print(value_vertex) if (M.norm(grad_vertex) >= eps): print(' Fehler bei polyFunctionalTest , grad zu hoch') print(P) print(grad_vertex) turns += 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
positions = x.get_trajectory2() latvecs = m.get_pwi_latvecs('md.in') positions.pop() #xyzpositions = [] #for i in positions: # xyz = [] # for j in range(nat): # xyz.append(latvecs @ i[j]) # xyzpositions.append(xyz) # getting Cl1-C2 bondlengths # must subtract 1 due to zero indexing Cl_ind = 1 - 1 C_ind = 2 - 1 distances = [] for k in range(len(positions)): # displacement = Cl_xyz_position - Carbon_xyz_position displacement = latvecs @ positions[k][Cl_ind] - latvecs @ positions[k][ C_ind] distance = m.norm(displacement) distances.append(distance) plt.scatter(d.Cl1, distances) plt.show()
def normalNormsPrint(coneVolume): for data in coneVolume: print(M.norm([data[0], data[1]]))
# by roating the molecule about the z axis x = md.Md('best.origin.crystal.works.pwi') pos = x.get_trajectory2()[0] rc1 = pos[0] rc11 = pos[10] rc4 = pos[3] rcl12 = pos[11] # these two R's should be identical # but due to OCD we will define both # R412: the distance from c4 to cl12 # R111: the distance from c1 to cl11 R412 = m.norm(rc4-rcl12) R111 = m.norm(rc1-rc11) sin=np.sin cos=np.cos #print("BEFORE!") #print(pos) # here rotate Cl12 by reassignment R=R412 pos[11] = rc4 + np.array([R*sin(theta_y), 0, R*cos(theta_y)]) # here rotate Cl11 by reassignment R=R111
y_sing = [] #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')
# must subtract 1 due to zero indexing Cl_ind= 1 -1 C_ind = 2 -1 C_ind2= 3 -1 angles = [] for k in range(len(positions)): # get positions of three atoms in xyz p1 = latvecs @ positions[k][Cl_ind] p2 = latvecs @ positions[k][C_ind] p3 = latvecs @ positions[k][C_ind2] # calculate the bond angle v1 = p2-p1 v2 = p3-p2 dot = v1@v2 costheta=dot/(m.norm(v1)*m.norm(v2)) angle = nu.arccos(costheta)*180/nu.pi-180+120 angles.append(angle) cqs = d.Cl1 abscqs= list(map(abs, d.Cl1)) a=angles[455:520] b=cqs[455:520] plt.scatter(b,a) plt.show()
def regulator(cD, params): return M.norm(F(cD, params)) #* M.norm(params)
def psi(cD , params): return M.norm( cV.f(cD,params))
def psi(cD, params): return M.norm(F(cD, params))
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 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
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))