@@ -352,14 +352,22 @@ function _explore_one_component!(expected, encountered, visited, graph::Periodic
352352 end
353353 vec:: Vector{SVector{N,Int}} = collect (recordedperiodicities)
354354 catenationmat, d = normal_basis (vec)
355+ detmat = Int (det (catenationmat))
356+ if detmat < 0 && N ≥ 2
357+ # Swap the two first columns to make the determinant positive.
358+ # This is not crucial to the algorithm, but it yields simpler offsets in the end.
359+ for i in 1 : N
360+ catenationmat[i,1 ], catenationmat[i,2 ] = catenationmat[i,2 ], catenationmat[i,1 ]
361+ end
362+ end
355363 invmcatenationmat = inv (SMatrix {N,N,Rational{Int},N*N} (catenationmat))
356364 for (j, (src, (dst, ofs))) in enumerate (newedges)
357365 newedges[j] = PeriodicEdge {N} (src, dst, Int .(invmcatenationmat* ofs))
358366 end
359367
360368 idx = minimum (keys (component))
361369 @assert expected[idx] == 0
362- expected[idx] = Int ( det (catenationmat) )
370+ expected[idx] = abs (detmat )
363371 encountered[idx] = (PeriodicGraph {N} (length (Q), newedges), [OffsetVertexIterator (nullofs, Q)], catenationmat, d)
364372 idx
365373end
@@ -431,8 +439,18 @@ function split_connected_components(graph::PeriodicGraph{N}) where N
431439 refmap = first (vmaps). nlist
432440 invmat = inv (SMatrix {N,N,Rational{Int},N*N} (mat))
433441 dumb_indices = findall (i -> begin onei = zeros (Int, N); onei[i] = 1 ; mat * onei == onei end , 1 : N)
434- for h in 1 : 1000
435- x = reverse_hash_position (h, Val {N} ())
442+ h = 0
443+ MAXh = 1000
444+ oneaxes = ntuple (i -> SVector {N,Int} (ntuple (j -> Int (j == i), Val (N))), Val (N))
445+ while true
446+ h += 1
447+ x = if h ≤ MAXh
448+ reverse_hash_position (h, Val {N} ())
449+ else
450+ hh = h - MAXh
451+ u, v = fldmod1 (hh, N)
452+ NtoZ (u)* oneaxes[v]
453+ end
436454 all (i -> iszero (x[i]), dumb_indices) || continue
437455 attempt_x = true
438456 for ofsvmap in vmaps
@@ -459,7 +477,7 @@ function split_connected_components(graph::PeriodicGraph{N}) where N
459477 length (vmaps) == ex && break
460478 end
461479 end
462- length (vmaps) < ex && error ( " Could not complete the splitting of connected components " )
480+ @assert length (vmaps) == ex
463481 end
464482 encountered[keep]
465483end
0 commit comments