Skip to content

Commit 459c358

Browse files
committed
Add union_cycles
1 parent 8f30749 commit 459c358

File tree

5 files changed

+94
-2
lines changed

5 files changed

+94
-2
lines changed

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name = "PeriodicGraphs"
22
uuid = "18c5b727-b240-4874-878a-f2e242435bab"
33
authors = ["Lionel Zoubritzky [email protected]"]
4-
version = "0.9.2"
4+
version = "0.9.3"
55

66
[deps]
77
Graphs = "86223c79-3864-5bf0-83f7-82e725a168b6"

docs/src/rings.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,8 @@ PeriodicGraphs.IterativeGaussianElimination
172172
PeriodicGraphs.gaussian_elimination!
173173
PeriodicGraphs.intersect_cycles!
174174
PeriodicGraphs.intersect_cycles
175+
PeriodicGraphs.union_cycles!
176+
PeriodicGraphs.union_cycles
175177
PeriodicGraphs.retrieve_track!
176178
PeriodicGraphs.rings_around
177179
PeriodicGraphs.EdgeDict

src/algorithms/rings.jl

Lines changed: 87 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1119,6 +1119,14 @@ Symmetric difference between two sorted lists `a` and `b`.
11191119
Return the sorted list of elements belonging to `a` or to `b` but not to both.
11201120
11211121
Use [`PeriodicGraphs.symdiff_cycles!`](@ref) to provide a pre-allocated destination.
1122+
1123+
## Example
1124+
```jldoctest
1125+
julia> PeriodicGraphs.symdiff_cycles([3,4,5], [4,5,6])
1126+
2-element Vector{Int64}:
1127+
3
1128+
6
1129+
```
11221130
"""
11231131
symdiff_cycles(a, b) = symdiff_cycles!(Vector{Int}(undef, length(b) + length(a) - 1), a, b)
11241132

@@ -1282,7 +1290,8 @@ retrieve_track!(gauss::IterativeGaussianEliminationDecomposition) = retrieve_tra
12821290
12831291
Like [`PeriodicGraphs.intersect_cycles`](@ref) but stores the result in `c`.
12841292
1285-
`c` will be resized accordingly so its initial length does not matter.
1293+
`c` will be resized accordingly so its initial length does not matter as long as it is
1294+
at least as large as the resulting list.
12861295
"""
12871296
function intersect_cycles!(c::Vector{T}, a::Vector{T}, b::Vector{T}) where T
12881297
isempty(b) && (empty!(c); return c)
@@ -1301,6 +1310,7 @@ function intersect_cycles!(c::Vector{T}, a::Vector{T}, b::Vector{T}) where T
13011310
c[j] = xa
13021311
counter_b += 1
13031312
counter_b > lenb && @goto ret
1313+
xb = b[counter_b]
13041314
end
13051315
end
13061316
@label ret
@@ -1315,10 +1325,86 @@ Intersection between two sorted lists `a` and `b`.
13151325
Return the sorted list of elements belonging to both `a` and `b`.
13161326
13171327
Use [`PeriodicGraphs.intersect_cycles!`](@ref) to provide a pre-allocated destination.
1328+
1329+
## Example
1330+
```jldoctest
1331+
julia> PeriodicGraphs.intersect_cycles([3,4,5], [4,5,6])
1332+
2-element Vector{Int64}:
1333+
4
1334+
5
1335+
```
13181336
"""
13191337
intersect_cycles(a, b) = intersect_cycles!(Vector{Int}(undef, min(length(a), length(b))), a, b)
13201338

13211339

1340+
"""
1341+
union_cycles!(c::Vector{T}, a::Vector{T}, b::Vector{T}) where T
1342+
1343+
Like [`PeriodicGraphs.union_cycles`](@ref) but stores the result in `c`.
1344+
1345+
`c` will be resized accordingly so its initial length does not matter as long as it is
1346+
at least as large as the resulting list.
1347+
"""
1348+
function union_cycles!(c::Vector{T}, a::Vector{T}, b::Vector{T}) where T
1349+
lenb = length(b)
1350+
lena = length(a)
1351+
counter_a = 0
1352+
counter_b = 1
1353+
y = lenb == 0 ? typemax(Int) : (@inbounds b[1])
1354+
j = 1
1355+
@inbounds while counter_a < lena
1356+
counter_a += 1
1357+
x = a[counter_a]
1358+
while y < x
1359+
c[j] = y
1360+
j += 1
1361+
counter_b += 1
1362+
counter_b > lenb && @goto fillenda
1363+
y = b[counter_b]
1364+
end
1365+
c[j] = x
1366+
j += 1
1367+
if y == x
1368+
counter_b += 1
1369+
if counter_b > lenb
1370+
counter_a += 1
1371+
@goto fillenda
1372+
end
1373+
y = b[counter_b]
1374+
end
1375+
end
1376+
remaining_towriteb = lenb - counter_b + 1
1377+
remaining_towriteb > 0 && unsafe_copyto!(c, j, b, counter_b, remaining_towriteb)
1378+
@inbounds resize!(c, (j + remaining_towriteb - 1) % UInt)
1379+
return c
1380+
1381+
@label fillenda
1382+
remaining_towritea = lena - counter_a + 1
1383+
remaining_towritea > 0 && unsafe_copyto!(c, j, a, counter_a, remaining_towritea)
1384+
@inbounds resize!(c, (j + remaining_towritea - 1) % UInt)
1385+
return c
1386+
end
1387+
1388+
"""
1389+
union_cycles(a, b)
1390+
1391+
Union between two sorted lists `a` and `b`.
1392+
Return the sorted list of elements belonging to `a` or `b` or both.
1393+
1394+
Use [`PeriodicGraphs.union_cycles!`](@ref) to provide a pre-allocated destination.
1395+
1396+
## Example
1397+
```jldoctest
1398+
julia> PeriodicGraphs.union_cycles([3,4,5], [4,5,6])
1399+
4-element Vector{Int64}:
1400+
3
1401+
4
1402+
5
1403+
6
1404+
```
1405+
"""
1406+
union_cycles(a, b) = union_cycles!(Vector{Int}(undef, length(a) + length(b)), a, b)
1407+
13221408
# function retrieve_vcycle(ecycle, known_pairs)
13231409
# fst_pair = known_pairs[ecycle[1]]
13241410
# last_pair = known_pairs[ecycle[end]]

src/precompile.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ function _precompile_()
5252
@enforce Base.precompile(Tuple{typeof(PeriodicGraphs.unsafe_incr!),Ptr{SmallIntT}})
5353
@enforce Base.precompile(Tuple{typeof(PeriodicGraphs.symdiff_cycles), Vector{Int}, Vector{Int}})
5454
@enforce Base.precompile(Tuple{typeof(PeriodicGraphs.intersect_cycles), Vector{Int}, Vector{Int}})
55+
@enforce Base.precompile(Tuple{typeof(PeriodicGraphs.union_cycles), Vector{Int}, Vector{Int}})
5556
@enforce Base.precompile(Tuple{Type{PeriodicGraphs.IterativeGaussianEliminationLength}, Vector{Int}})
5657
@enforce Base.precompile(Tuple{Type{PeriodicGraphs.IterativeGaussianElimination{Vector{Int32}}}, Vector{Int}})
5758
@enforce Base.precompile(Tuple{Type{PeriodicGraphs.IterativeGaussianElimination{Vector{Vector{Int32}}}}, Vector{Int}})

test/runtests.jl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -871,6 +871,9 @@ end
871871

872872
@test PeriodicGraphs.symdiff_cycles([3,4], [3,5,6]) == PeriodicGraphs.symdiff_cycles([4,5,6,7,8], [7,8]) == [4,5,6]
873873
@test PeriodicGraphs.intersect_cycles([3,4], [3,5,6]) == PeriodicGraphs.intersect_cycles([2,3,5], [1,3]) == [3]
874+
@test PeriodicGraphs.intersect_cycles([3,4,5], [4,5,6]) == PeriodicGraphs.intersect_cycles([4,5,7], [2,4,5,6]) == [4,5]
875+
@test PeriodicGraphs.union_cycles([3,4], [4,5,6]) == PeriodicGraphs.union_cycles([4,5,6], [3,4]) == [3,4,5,6]
876+
@test PeriodicGraphs.union_cycles([4,6], [3,5,6]) == PeriodicGraphs.union_cycles([3,5,6], [3,4,6]) == [3,4,5,6]
874877

875878
gausslengths = PeriodicGraphs.IterativeGaussianEliminationLength([3, 4, 7])
876879
@test !PeriodicGraphs.gaussian_elimination!(gausslengths, [3, 6])

0 commit comments

Comments
 (0)