dyna3/engine-proto/gram-test/overlapping-pyramids.jl
2024-07-18 01:12:49 -07:00

90 lines
2.4 KiB
Julia

include("Engine.jl")
using SparseArrays
using AbstractAlgebra
using PolynomialRoots
using Random
# initialize the partial gram matrix for an arrangement of seven spheres in
# which spheres 1 through 5 are mutually tangent, and spheres 3 through 7 are
# also mutually tangent
J = Int64[]
K = Int64[]
values = BigFloat[]
for j in 1:7
for k in 1:7
if (j <= 5 && k <= 5) || (j >= 3 && k >= 3)
push!(J, j)
push!(K, k)
push!(values, j == k ? 1 : -1)
end
end
end
gram = sparse(J, K, values)
# set the independent variable
indep_val = -9//5
gram[6, 1] = BigFloat(indep_val)
gram[1, 6] = gram[6, 1]
# in this initial guess, the mutual tangency condition is satisfied for spheres
# 1 through 5
Random.seed!(50793)
guess = let
a = sqrt(BigFloat(3)/2)
hcat(
sqrt(1/BigFloat(2)) * BigFloat[
1 1 -1 -1 0
1 -1 1 -1 0
1 -1 -1 1 0
0.5 0.5 0.5 0.5 1+a
0.5 0.5 0.5 0.5 1-a
] + 0.2*Engine.rand_on_shell(fill(BigFloat(-1), 5)),
Engine.rand_on_shell(fill(BigFloat(-1), 2))
)
end
# complete the gram matrix using Newton's method with backtracking
L, success, history = Engine.realize_gram(gram, guess)
completed_gram = L'*Engine.Q*L
println("Completed Gram matrix:\n")
display(completed_gram)
if success
println("\nTarget accuracy achieved!")
else
println("\nFailed to reach target accuracy")
end
println("Steps: ", size(history.scaled_loss, 1))
println("Loss: ", history.scaled_loss[end], "\n")
# === algebraic check ===
#=
R, gens = polynomial_ring(AbstractAlgebra.Rationals{BigInt}(), ["x", "t", "t", "t"])
x = gens[1]
t = gens[2:4]
S, u = polynomial_ring(AbstractAlgebra.Rationals{BigInt}(), "u")
M = matrix_space(R, 7, 7)
gram_symb = M(R[
1 -1 -1 -1 -1 t[1] t[2];
-1 1 -1 -1 -1 x t[3]
-1 -1 1 -1 -1 -1 -1;
-1 -1 -1 1 -1 -1 -1;
-1 -1 -1 -1 1 -1 -1;
t[1] x -1 -1 -1 1 -1;
t[2] t[3] -1 -1 -1 -1 1
])
rank_constraints = det.([
gram_symb[1:6, 1:6],
gram_symb[2:7, 2:7],
gram_symb[[1, 3, 4, 5, 6, 7], [1, 3, 4, 5, 6, 7]]
])
# solve for x and t
x_constraint = 25//16 * to_univariate(S, evaluate(rank_constraints[1], [2], [indep_val]))
t_constraint = 25//16 * to_univariate(S, evaluate(rank_constraints[3], [2], [indep_val]))
x_vals = PolynomialRoots.roots(x_constraint.coeffs)
t_vals = PolynomialRoots.roots(t_constraint.coeffs)
=#