Add a canonical form for lattices#6102
Conversation
|
@simonbrandhorst here is an initial version of this algorithm |
| matrix2 = [2,1,1,-1,-1,1,-1,1,-1,-1,2,0,-1,-1,1,-1,1,-1,0,4,-2,1,2,-2,-1,-1,0,4,1,-2,2,1,2,1,4,1,-1,0,0,1,4,-2,1,-2,-1,4,-1,2,1,4,0,-1,4,1,4] | ||
| G1 = create_gram(matrix1) | ||
| G2 = create_gram(matrix2) | ||
| U = hnf_with_transform(matrix(ZZ,n,n,rand(0:1,n^2)))[2]; |
There was a problem hiding this comment.
the ; here and in the following lines is not necessary
| return transpose(U_inv)*A*U_inv | ||
| end | ||
|
|
||
| function _get_edge_labeled_graph(cv_set, gram) |
| max_w = w | ||
| end | ||
| add_edge!(res_graph, i, j) | ||
| merge!(weightDict, Dict((i, j) => w)) |
There was a problem hiding this comment.
it looks like you are merging with a new dict instead of adding entries to the already existing dict (which would be a bit more performant.
This would look like
| merge!(weightDict, Dict((i, j) => w)) | |
| weightDict[(i, j)] = w |
The difference would just be in the handling of duplicate keys. Do you want to update a value in case the key is already there, or do you want to keep the original value? In the former case, you can apply the above suggestion.
There was a problem hiding this comment.
This same pattern occurrs also a few more times.
| for i = 1:p | ||
| for j = i+1:p | ||
|
|
||
| w = (cv_set[i]*gram*transpose(cv_set[j]))[1] | ||
| if w>max_w | ||
| max_w = w | ||
| end |
There was a problem hiding this comment.
This should be considered a hot loop. Suppose that p=10000. Then the inner part is called p(p-1)/2= 49995000 times.
Some suggestions:
- move
cv_set[i]*gramto the outer loop on i. There is no dependence on j - use inplace operations such as transpose! and mul! with preallocated vectors
- you can detect overflow before hand using the Cauchy-Schwarz inequality. If
n= max(v*g*transpose(v))and n^2 fits in Int, then we are fine. If this is the case (and it will be the case in almost all use cases), convert toVector{Int}if and the matrix toMatrix{Int}. Then you can useLinearAlgebra.mul!which should be the fastest matrix vector multiplication with overflow that we have in julia. Be careful though, it does not support alialising on the first argument. - Is there a way to label the edge directly, instead of collecting all labels beforehand?
Otherwise we are creating 49995000 dict entries. But I do not know enough of the internals of how labels work to judge if this makes sense.
There was a problem hiding this comment.
Is there a way to label the edge directly, instead of collecting all labels beforehand?
Otherwise we are creating 49995000 dict entries. But I do not know enough of the internals of how labels work to judge if this makes sense.
There is option to use label!() with a newly made Dict with 1 edge. But the problem is, it looks that if you add more edges, the graph object don't merge them inside. Instead, it stores all the dictionaries as is and as Dict uses a lot of memory by default => it results in enourmous memory usage for big graphs. That's why I collect here all edges in one big dictionary.
| a = 1+max_w | ||
| b = a + 1 | ||
| for i = 1:p | ||
| add_edge!(res_graph, i, p+2) | ||
| merge!(weightDict, Dict((i, p+2) => a)) | ||
| end | ||
| add_edge!(res_graph, p+1, p+2) | ||
| merge!(weightDict, Dict((p+1, p+2) => b)) |
There was a problem hiding this comment.
Can you explain what happens here?
There was a problem hiding this comment.
Yes, here I follows the paper and it looks, that we need 2 more vertices to preserve automorphisms of graphs correctly. So, basically another step to not lose isomorphism/not get "new" isom. of resulting forms
| for i = 1:p | ||
| for j = i+1:p |
There was a problem hiding this comment.
What about the squared length of the vector, i.e. cv_set[i]*gram*transpose(cv_set[i])? This should be relevant as well.
Co-authored-by: Lars Göttgens <lars.goettgens@gmail.com>
Co-authored-by: Lars Göttgens <lars.goettgens@gmail.com>
Co-authored-by: Lars Göttgens <lars.goettgens@gmail.com>
Co-authored-by: Lars Göttgens <lars.goettgens@gmail.com>
Co-authored-by: Lars Göttgens <lars.goettgens@gmail.com>
Co-authored-by: Lars Göttgens <lars.goettgens@gmail.com>
Co-authored-by: Lars Göttgens <lars.goettgens@gmail.com>
Co-authored-by: Lars Göttgens <lars.goettgens@gmail.com>
Co-authored-by: Simon Brandhorst <brandhorst@math.uni-sb.de>
Added function to get canonical form of lattice following ideas of Sikirić, Haensch, Voight and van Woerden [SHVW20]