@@ -18,6 +18,8 @@ subs.(sys, x => 4, y => -2im)
18
18
subs .(sys, x => 1 , y => 3 )
19
19
subs .(sys, x => 4 , y => 3 )
20
20
21
+ # ----------- Standard Macaulay nullspace approach ---------------
22
+
21
23
# TODO : solve_system() removes complex-valued roots! How to compute all of them?
22
24
sols = solve_system (sys, column_maxdegree = 4 , print_level = 3 )
23
25
@@ -28,18 +30,66 @@ Z = nullspace(macaulay(sys, d_max))
28
30
include (" solvers.jl" )
29
31
big_clarabel = clarabel_optimizer (T = BigFloat)
30
32
31
- M = moment_matrix (Z, big_clarabel, 2 , T = BigFloat)
32
- res = atomic_measure (M, 1e-4 , ShiftNullspace ())
33
- # The solution seems off. We probably need to be more carefull with the rank checks:
33
+ ν = moment_matrix (Z, big_clarabel, 2 , T = BigFloat)
34
+ res = atomic_measure (ν, 1e-4 , ShiftNullspace ())
35
+ # The solution seems off. We probably need to be more carefull with the rank checks.
36
+
37
+ # ------------ Manual hyperparameter search -----------
38
+ # Hyperparameters:
39
+ # 1) d_max: degree of Macaulay to compute nullspace Z
40
+ # 2) d_m: degree of the PSD Moment matrix M to construct from Z (d_m <= d_max)
41
+ # 3) r: rank of the Moment M (used to retrieve the real-valued solutions)
42
+
43
+ # Let's try the moment-matrix approach:
44
+ d_max = 6
45
+ Z = nullspace (macaulay (sys, d_max))
46
+ d_m = 4
47
+ ν = moment_matrix (Z, big_clarabel, d_m, T = BigFloat)
48
+
49
+ # Manually inspect rank of Moment matrix via SVD:
50
+ M = value_matrix (ν)
51
+ M, S = svd (M)
52
+ round .(log10 .(S))
53
+
54
+ # Given the rank r, check for solutions:
55
+ r = 5
56
+ res = atomic_measure (ν, FixedRank (r), ShiftNullspace ())
57
+
58
+ # Results (Clarabel BigFloat):
59
+ # d_max = 4, d_m = 1: full rank
60
+ # d_max = 4, d_m = 2: rank is clearly 2, one approximate solution (3.899, 2.999)
61
+ # d_max = 4, d_m = 3: rank is clearly 6, no solutions...
62
+ # d_max = 5, d_m = 1: full rank
63
+ # d_max = 5, d_m = 2: rank is clearly 2, one approximate solution (4.163, 2.999)
64
+ # d_max = 5, d_m = 3: rank is clearly 6, no solutions...
65
+ # d_max = 5, d_m = 4: rank seems 7, 1 approximate solution (0.682, 3.000)
66
+ # d_max = 5, d_m = 5: difficult to find rank gap.
67
+ # If you choose rank = 7: 1 solution at (0.961, 3.000)
68
+ # If you choose rank = 10: 1 solution at (0.948, 2.999)
69
+ # d_max = 6, d_m = 1: full rank
70
+ # d_max = 6, d_m = 2: rank is clearly 2, one approximate solution (0.934, 3.000)
71
+ # d_max = 6, d_m = 3: rank is clearly 2, one wrong solution (1.548, 2.999)
72
+ # d_max = 6, d_m = 4: rank seems 7, 1 solution (0.995, 2.999)
73
+ # If you choose rank = 2: 1 solution (3.983, 2.999)
74
+ # If you choose rank = 3: 2 solutions (0.999, 2.999) and (4.000, 2.999)
75
+
76
+ # ---> Hyperparameters: 6, 4, 3 seem optimal.
77
+ # Observation: choosing the rank r = 3 based on the singular values of M does not seem an obvious choice...
78
+
79
+ # -------------- Cheat rank function --------------
80
+
81
+ d_max = 6
82
+ Z = nullspace (macaulay (sys, d_max))
83
+ d_m = 4
84
+ ν = moment_matrix (Z, big_clarabel, d_m, T = BigFloat)
34
85
35
86
# Let's cheat to find the correct rank:
36
87
expected (T = Float64) = [T[1 , 4 ], T[3 , 3 ]]
37
88
r = MacaulayMatrix. cheat_rank (
38
- M ,
89
+ ν ,
39
90
[x, y],
40
91
expected (BigFloat),
41
92
LeadingRelativeRankTol (1e-6 ),
42
93
)
43
-
44
- # Now try again:
45
- res = atomic_measure (M, FixedRank (r), ShiftNullspace ())
94
+ # Not possible to find correct rank...
95
+ # TODO : Why do we need to give the cheatrank function a rank check method?
0 commit comments