104 lines
2.8 KiB
Julia
104 lines
2.8 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
|
|
#
|
|
# using gram[6, 2] or gram[7, 1] as the independent variable seems to stall
|
|
# convergence, even if its value comes from a known solution, like
|
|
#
|
|
# gram[6, 2] = 0.9936131705272925
|
|
#
|
|
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 = begin
|
|
const 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
|
|
#=
|
|
L, history = Engine.realize_gram_gradient(gram, guess, scaled_tol = 0.01)
|
|
L_pol, history_pol = Engine.realize_gram_newton(gram, L)
|
|
=#
|
|
L, success, history = Engine.realize_gram(gram, guess)
|
|
completed_gram = L'*Engine.Q*L
|
|
println("Completed Gram matrix:\n")
|
|
display(completed_gram)
|
|
#=
|
|
println("\nSteps: ", size(history.scaled_loss, 1), " + ", size(history_pol.scaled_loss, 1))
|
|
println("Loss: ", history_pol.scaled_loss[end], "\n")
|
|
=#
|
|
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)
|
|
=# |