def riesz_energy(points, s): num_points = len(points) if num_points < 2: return gmpy2.zero() if s == 1: energy = gmpy2.rec_sqrt(squared_distance(points[0], points[1])) for j in range(2, num_points): energy += gmpy2.rec_sqrt(squared_distance(points[0], points[j])) for i in range(1, num_points): for j in range(i + 1, num_points): energy += gmpy2.rec_sqrt(squared_distance(points[i], points[j])) elif s == 2: energy = 1 / squared_distance(points[0], points[1]) for j in range(2, num_points): energy += 1 / squared_distance(points[0], points[j]) for i in range(1, num_points): for j in range(i + 1, num_points): energy += 1 / squared_distance(points[i], points[j]) else: energy = squared_distance(points[0], points[1]) ** (-s/2) for j in range(2, num_points): energy += squared_distance(points[0], points[j]) ** (-s/2) for i in range(1, num_points): for j in range(i + 1, num_points): energy += squared_distance(points[i], points[j]) ** (-s/2) return energy
def riesz_force(points, s): point_indices = range(len(points)) dim_indices = range(len(points[0])) force = [[gmpy2.zero() for _ in dim_indices] for _ in point_indices] if s == 2: for i in point_indices: for j in point_indices: if i != j: dist, disp = squared_difference(points[i], points[j]) dist = 2 / gmpy2.square(dist) for k in dim_indices: force[i][k] += dist * disp[k] elif s == 1: for i in point_indices: for j in point_indices: if i != j: dist, disp = squared_difference(points[i], points[j]) dist = gmpy2.rec_sqrt(dist) / dist for k in dim_indices: force[i][k] += dist * disp[k] else: for i in point_indices: for j in point_indices: if i != j: dist, disp = squared_difference(points[i], points[j]) dist = s * dist**(-s / 2 - 1) for k in dim_indices: force[i][k] += dist * disp[k] return force
def rec_norm(v): norm_sq = gmpy2.square(v[0]) for i in range(1, len(v)): norm_sq += gmpy2.square(v[i]) return gmpy2.rec_sqrt(norm_sq)
def rec_norm(self): """Return the reciprocal of the Euclidean norm of this MPFRVector.""" return gmpy2.rec_sqrt(self.norm_squared())