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 mpf_to_mpfr(f): assert isinstance(f, MPF) if f.isNaN(): return gmpy2.nan() elif f.isInfinite(): if f.isPositive(): return gmpy2.inf(1) else: return gmpy2.inf(-1) elif f.isZero(): if f.isPositive(): return gmpy2.zero(1) else: return gmpy2.zero(-1) else: return gmpy2.mpfr(f.to_python_string())
def squared_distance(v, w): assert len(v) == len(w) if len(v) == 0: return gmpy2.zero() else: dist = gmpy2.square(v[0] - w[0]) for i in range(1, len(v)): dist += gmpy2.square(v[i] - w[i]) return dist
def double_matrix_multiply(a, b): m = len(a) n = len(a[0]) c = [[gmpy2.zero() for _ in range(n)] for _ in range(m)] for i in range(m): for j in range(n): for k in range(m): for l in range(n): c[i][j] += a[i][j][k][l] * b[k][l] return c
def squared_difference(v, w): assert len(v) == len(w) if len(v) == 0: return gmpy2.zero(), () else: diff = tuple(v[i] - w[i] for i in range(len(v))) dist = gmpy2.square(diff[0]) for i in range(1, len(v)): dist += gmpy2.square(diff[i]) return dist, diff
def mvmul(mat, vec): m = len(mat) n_set = set(map(len, mat)) assert len(n_set) == 1 n, = n_set assert len(vec) == n ans = [gmpy2.zero() for _ in range(m)] for i in range(m): for j in range(n): ans[i] += mat[i][j] * vec[j] return tuple(ans)
def centroid(points): dim_set = set(map(len, points)) assert len(dim_set) == 1 dim, = dim_set cent = [gmpy2.zero() for _ in range(dim)] for point in points: for i in range(dim): cent[i] += point[i] num_points = len(points) for i in range(dim): cent[i] /= num_points return tuple(cent)
def icosahedron_vertices(): zero = gmpy2.zero() one = gmpy2.mpfr(1) phi = (gmpy2.sqrt(5) + 1) / 2 return ( (+one, +phi, zero), (+one, -phi, zero), (-one, +phi, zero), (-one, -phi, zero), (zero, +one, +phi), (zero, +one, -phi), (zero, -one, +phi), (zero, -one, -phi), (+phi, zero, +one), (+phi, zero, -one), (-phi, zero, +one), (-phi, zero, -one))
def full_icosahedral_group(): zero = gmpy2.zero() one = gmpy2.mpfr(1) half = one / 2 psi = (gmpy2.sqrt(5) - 1) / 4 phi = (gmpy2.sqrt(5) + 1) / 4 return ( ((+one, zero, zero), (zero, +one, zero), (zero, zero, +one)), ((+one, zero, zero), (zero, +one, zero), (zero, zero, -one)), ((+one, zero, zero), (zero, -one, zero), (zero, zero, +one)), ((+one, zero, zero), (zero, -one, zero), (zero, zero, -one)), ((-one, zero, zero), (zero, +one, zero), (zero, zero, +one)), ((-one, zero, zero), (zero, +one, zero), (zero, zero, -one)), ((-one, zero, zero), (zero, -one, zero), (zero, zero, +one)), ((-one, zero, zero), (zero, -one, zero), (zero, zero, -one)), ((zero, +one, zero), (zero, zero, +one), (+one, zero, zero)), ((zero, +one, zero), (zero, zero, +one), (-one, zero, zero)), ((zero, +one, zero), (zero, zero, -one), (+one, zero, zero)), ((zero, +one, zero), (zero, zero, -one), (-one, zero, zero)), ((zero, -one, zero), (zero, zero, +one), (+one, zero, zero)), ((zero, -one, zero), (zero, zero, +one), (-one, zero, zero)), ((zero, -one, zero), (zero, zero, -one), (+one, zero, zero)), ((zero, -one, zero), (zero, zero, -one), (-one, zero, zero)), ((zero, zero, +one), (+one, zero, zero), (zero, +one, zero)), ((zero, zero, +one), (+one, zero, zero), (zero, -one, zero)), ((zero, zero, +one), (-one, zero, zero), (zero, +one, zero)), ((zero, zero, +one), (-one, zero, zero), (zero, -one, zero)), ((zero, zero, -one), (+one, zero, zero), (zero, +one, zero)), ((zero, zero, -one), (+one, zero, zero), (zero, -one, zero)), ((zero, zero, -one), (-one, zero, zero), (zero, +one, zero)), ((zero, zero, -one), (-one, zero, zero), (zero, -one, zero)), ((+half, +psi, +phi), (+psi, +phi, -half), (+phi, -half, -psi)), ((+half, +psi, +phi), (+psi, +phi, -half), (-phi, +half, +psi)), ((+half, +psi, +phi), (-psi, -phi, +half), (+phi, -half, -psi)), ((+half, +psi, +phi), (-psi, -phi, +half), (-phi, +half, +psi)), ((+half, +psi, -phi), (+psi, +phi, +half), (+phi, -half, +psi)), ((+half, +psi, -phi), (+psi, +phi, +half), (-phi, +half, -psi)), ((+half, +psi, -phi), (-psi, -phi, -half), (+phi, -half, +psi)), ((+half, +psi, -phi), (-psi, -phi, -half), (-phi, +half, -psi)), ((+half, -psi, +phi), (+psi, -phi, -half), (+phi, +half, -psi)), ((+half, -psi, +phi), (+psi, -phi, -half), (-phi, -half, +psi)), ((+half, -psi, +phi), (-psi, +phi, +half), (+phi, +half, -psi)), ((+half, -psi, +phi), (-psi, +phi, +half), (-phi, -half, +psi)), ((+half, -psi, -phi), (+psi, -phi, +half), (+phi, +half, +psi)), ((+half, -psi, -phi), (+psi, -phi, +half), (-phi, -half, -psi)), ((+half, -psi, -phi), (-psi, +phi, -half), (+phi, +half, +psi)), ((+half, -psi, -phi), (-psi, +phi, -half), (-phi, -half, -psi)), ((-half, +psi, +phi), (+psi, -phi, +half), (+phi, +half, +psi)), ((-half, +psi, +phi), (+psi, -phi, +half), (-phi, -half, -psi)), ((-half, +psi, +phi), (-psi, +phi, -half), (+phi, +half, +psi)), ((-half, +psi, +phi), (-psi, +phi, -half), (-phi, -half, -psi)), ((-half, +psi, -phi), (+psi, -phi, -half), (+phi, +half, -psi)), ((-half, +psi, -phi), (+psi, -phi, -half), (-phi, -half, +psi)), ((-half, +psi, -phi), (-psi, +phi, +half), (+phi, +half, -psi)), ((-half, +psi, -phi), (-psi, +phi, +half), (-phi, -half, +psi)), ((-half, -psi, +phi), (+psi, +phi, +half), (+phi, -half, +psi)), ((-half, -psi, +phi), (+psi, +phi, +half), (-phi, +half, -psi)), ((-half, -psi, +phi), (-psi, -phi, -half), (+phi, -half, +psi)), ((-half, -psi, +phi), (-psi, -phi, -half), (-phi, +half, -psi)), ((-half, -psi, -phi), (+psi, +phi, -half), (+phi, -half, -psi)), ((-half, -psi, -phi), (+psi, +phi, -half), (-phi, +half, +psi)), ((-half, -psi, -phi), (-psi, -phi, +half), (+phi, -half, -psi)), ((-half, -psi, -phi), (-psi, -phi, +half), (-phi, +half, +psi)), ((+phi, +half, +psi), (+half, -psi, -phi), (+psi, -phi, +half)), ((+phi, +half, +psi), (+half, -psi, -phi), (-psi, +phi, -half)), ((+phi, +half, +psi), (-half, +psi, +phi), (+psi, -phi, +half)), ((+phi, +half, +psi), (-half, +psi, +phi), (-psi, +phi, -half)), ((+phi, +half, -psi), (+half, -psi, +phi), (+psi, -phi, -half)), ((+phi, +half, -psi), (+half, -psi, +phi), (-psi, +phi, +half)), ((+phi, +half, -psi), (-half, +psi, -phi), (+psi, -phi, -half)), ((+phi, +half, -psi), (-half, +psi, -phi), (-psi, +phi, +half)), ((+phi, -half, +psi), (+half, +psi, -phi), (+psi, +phi, +half)), ((+phi, -half, +psi), (+half, +psi, -phi), (-psi, -phi, -half)), ((+phi, -half, +psi), (-half, -psi, +phi), (+psi, +phi, +half)), ((+phi, -half, +psi), (-half, -psi, +phi), (-psi, -phi, -half)), ((+phi, -half, -psi), (+half, +psi, +phi), (+psi, +phi, -half)), ((+phi, -half, -psi), (+half, +psi, +phi), (-psi, -phi, +half)), ((+phi, -half, -psi), (-half, -psi, -phi), (+psi, +phi, -half)), ((+phi, -half, -psi), (-half, -psi, -phi), (-psi, -phi, +half)), ((-phi, +half, +psi), (+half, +psi, +phi), (+psi, +phi, -half)), ((-phi, +half, +psi), (+half, +psi, +phi), (-psi, -phi, +half)), ((-phi, +half, +psi), (-half, -psi, -phi), (+psi, +phi, -half)), ((-phi, +half, +psi), (-half, -psi, -phi), (-psi, -phi, +half)), ((-phi, +half, -psi), (+half, +psi, -phi), (+psi, +phi, +half)), ((-phi, +half, -psi), (+half, +psi, -phi), (-psi, -phi, -half)), ((-phi, +half, -psi), (-half, -psi, +phi), (+psi, +phi, +half)), ((-phi, +half, -psi), (-half, -psi, +phi), (-psi, -phi, -half)), ((-phi, -half, +psi), (+half, -psi, +phi), (+psi, -phi, -half)), ((-phi, -half, +psi), (+half, -psi, +phi), (-psi, +phi, +half)), ((-phi, -half, +psi), (-half, +psi, -phi), (+psi, -phi, -half)), ((-phi, -half, +psi), (-half, +psi, -phi), (-psi, +phi, +half)), ((-phi, -half, -psi), (+half, -psi, -phi), (+psi, -phi, +half)), ((-phi, -half, -psi), (+half, -psi, -phi), (-psi, +phi, -half)), ((-phi, -half, -psi), (-half, +psi, +phi), (+psi, -phi, +half)), ((-phi, -half, -psi), (-half, +psi, +phi), (-psi, +phi, -half)), ((+psi, +phi, +half), (+phi, -half, +psi), (+half, +psi, -phi)), ((+psi, +phi, +half), (+phi, -half, +psi), (-half, -psi, +phi)), ((+psi, +phi, +half), (-phi, +half, -psi), (+half, +psi, -phi)), ((+psi, +phi, +half), (-phi, +half, -psi), (-half, -psi, +phi)), ((+psi, +phi, -half), (+phi, -half, -psi), (+half, +psi, +phi)), ((+psi, +phi, -half), (+phi, -half, -psi), (-half, -psi, -phi)), ((+psi, +phi, -half), (-phi, +half, +psi), (+half, +psi, +phi)), ((+psi, +phi, -half), (-phi, +half, +psi), (-half, -psi, -phi)), ((+psi, -phi, +half), (+phi, +half, +psi), (+half, -psi, -phi)), ((+psi, -phi, +half), (+phi, +half, +psi), (-half, +psi, +phi)), ((+psi, -phi, +half), (-phi, -half, -psi), (+half, -psi, -phi)), ((+psi, -phi, +half), (-phi, -half, -psi), (-half, +psi, +phi)), ((+psi, -phi, -half), (+phi, +half, -psi), (+half, -psi, +phi)), ((+psi, -phi, -half), (+phi, +half, -psi), (-half, +psi, -phi)), ((+psi, -phi, -half), (-phi, -half, +psi), (+half, -psi, +phi)), ((+psi, -phi, -half), (-phi, -half, +psi), (-half, +psi, -phi)), ((-psi, +phi, +half), (+phi, +half, -psi), (+half, -psi, +phi)), ((-psi, +phi, +half), (+phi, +half, -psi), (-half, +psi, -phi)), ((-psi, +phi, +half), (-phi, -half, +psi), (+half, -psi, +phi)), ((-psi, +phi, +half), (-phi, -half, +psi), (-half, +psi, -phi)), ((-psi, +phi, -half), (+phi, +half, +psi), (+half, -psi, -phi)), ((-psi, +phi, -half), (+phi, +half, +psi), (-half, +psi, +phi)), ((-psi, +phi, -half), (-phi, -half, -psi), (+half, -psi, -phi)), ((-psi, +phi, -half), (-phi, -half, -psi), (-half, +psi, +phi)), ((-psi, -phi, +half), (+phi, -half, -psi), (+half, +psi, +phi)), ((-psi, -phi, +half), (+phi, -half, -psi), (-half, -psi, -phi)), ((-psi, -phi, +half), (-phi, +half, +psi), (+half, +psi, +phi)), ((-psi, -phi, +half), (-phi, +half, +psi), (-half, -psi, -phi)), ((-psi, -phi, -half), (+phi, -half, +psi), (+half, +psi, -phi)), ((-psi, -phi, -half), (+phi, -half, +psi), (-half, -psi, +phi)), ((-psi, -phi, -half), (-phi, +half, -psi), (+half, +psi, -phi)), ((-psi, -phi, -half), (-phi, +half, -psi), (-half, -psi, +phi)))