Skip to content

Commit

Permalink
Add union_cycles
Browse files Browse the repository at this point in the history
  • Loading branch information
Liozou committed Jun 30, 2022
1 parent 8f30749 commit 459c358
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 2 deletions.
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "PeriodicGraphs"
uuid = "18c5b727-b240-4874-878a-f2e242435bab"
authors = ["Lionel Zoubritzky [email protected]"]
version = "0.9.2"
version = "0.9.3"

[deps]
Graphs = "86223c79-3864-5bf0-83f7-82e725a168b6"
Expand Down
2 changes: 2 additions & 0 deletions docs/src/rings.md
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,8 @@ PeriodicGraphs.IterativeGaussianElimination
PeriodicGraphs.gaussian_elimination!
PeriodicGraphs.intersect_cycles!
PeriodicGraphs.intersect_cycles
PeriodicGraphs.union_cycles!
PeriodicGraphs.union_cycles
PeriodicGraphs.retrieve_track!
PeriodicGraphs.rings_around
PeriodicGraphs.EdgeDict
Expand Down
88 changes: 87 additions & 1 deletion src/algorithms/rings.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1119,6 +1119,14 @@ Symmetric difference between two sorted lists `a` and `b`.
Return the sorted list of elements belonging to `a` or to `b` but not to both.
Use [`PeriodicGraphs.symdiff_cycles!`](@ref) to provide a pre-allocated destination.
## Example
```jldoctest
julia> PeriodicGraphs.symdiff_cycles([3,4,5], [4,5,6])
2-element Vector{Int64}:
3
6
```
"""
symdiff_cycles(a, b) = symdiff_cycles!(Vector{Int}(undef, length(b) + length(a) - 1), a, b)

Expand Down Expand Up @@ -1282,7 +1290,8 @@ retrieve_track!(gauss::IterativeGaussianEliminationDecomposition) = retrieve_tra
Like [`PeriodicGraphs.intersect_cycles`](@ref) but stores the result in `c`.
`c` will be resized accordingly so its initial length does not matter.
`c` will be resized accordingly so its initial length does not matter as long as it is
at least as large as the resulting list.
"""
function intersect_cycles!(c::Vector{T}, a::Vector{T}, b::Vector{T}) where T
isempty(b) && (empty!(c); return c)
Expand All @@ -1301,6 +1310,7 @@ function intersect_cycles!(c::Vector{T}, a::Vector{T}, b::Vector{T}) where T
c[j] = xa
counter_b += 1
counter_b > lenb && @goto ret
xb = b[counter_b]
end
end
@label ret
Expand All @@ -1315,10 +1325,86 @@ Intersection between two sorted lists `a` and `b`.
Return the sorted list of elements belonging to both `a` and `b`.
Use [`PeriodicGraphs.intersect_cycles!`](@ref) to provide a pre-allocated destination.
## Example
```jldoctest
julia> PeriodicGraphs.intersect_cycles([3,4,5], [4,5,6])
2-element Vector{Int64}:
4
5
```
"""
intersect_cycles(a, b) = intersect_cycles!(Vector{Int}(undef, min(length(a), length(b))), a, b)


"""
union_cycles!(c::Vector{T}, a::Vector{T}, b::Vector{T}) where T
Like [`PeriodicGraphs.union_cycles`](@ref) but stores the result in `c`.
`c` will be resized accordingly so its initial length does not matter as long as it is
at least as large as the resulting list.
"""
function union_cycles!(c::Vector{T}, a::Vector{T}, b::Vector{T}) where T
lenb = length(b)
lena = length(a)
counter_a = 0
counter_b = 1
y = lenb == 0 ? typemax(Int) : (@inbounds b[1])
j = 1
@inbounds while counter_a < lena
counter_a += 1
x = a[counter_a]
while y < x
c[j] = y
j += 1
counter_b += 1
counter_b > lenb && @goto fillenda
y = b[counter_b]
end
c[j] = x
j += 1
if y == x
counter_b += 1
if counter_b > lenb
counter_a += 1
@goto fillenda
end
y = b[counter_b]
end
end
remaining_towriteb = lenb - counter_b + 1
remaining_towriteb > 0 && unsafe_copyto!(c, j, b, counter_b, remaining_towriteb)
@inbounds resize!(c, (j + remaining_towriteb - 1) % UInt)
return c

@label fillenda
remaining_towritea = lena - counter_a + 1
remaining_towritea > 0 && unsafe_copyto!(c, j, a, counter_a, remaining_towritea)
@inbounds resize!(c, (j + remaining_towritea - 1) % UInt)
return c
end

"""
union_cycles(a, b)
Union between two sorted lists `a` and `b`.
Return the sorted list of elements belonging to `a` or `b` or both.
Use [`PeriodicGraphs.union_cycles!`](@ref) to provide a pre-allocated destination.
## Example
```jldoctest
julia> PeriodicGraphs.union_cycles([3,4,5], [4,5,6])
4-element Vector{Int64}:
3
4
5
6
```
"""
union_cycles(a, b) = union_cycles!(Vector{Int}(undef, length(a) + length(b)), a, b)

# function retrieve_vcycle(ecycle, known_pairs)
# fst_pair = known_pairs[ecycle[1]]
# last_pair = known_pairs[ecycle[end]]
Expand Down
1 change: 1 addition & 0 deletions src/precompile.jl
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ function _precompile_()
@enforce Base.precompile(Tuple{typeof(PeriodicGraphs.unsafe_incr!),Ptr{SmallIntT}})
@enforce Base.precompile(Tuple{typeof(PeriodicGraphs.symdiff_cycles), Vector{Int}, Vector{Int}})
@enforce Base.precompile(Tuple{typeof(PeriodicGraphs.intersect_cycles), Vector{Int}, Vector{Int}})
@enforce Base.precompile(Tuple{typeof(PeriodicGraphs.union_cycles), Vector{Int}, Vector{Int}})
@enforce Base.precompile(Tuple{Type{PeriodicGraphs.IterativeGaussianEliminationLength}, Vector{Int}})
@enforce Base.precompile(Tuple{Type{PeriodicGraphs.IterativeGaussianElimination{Vector{Int32}}}, Vector{Int}})
@enforce Base.precompile(Tuple{Type{PeriodicGraphs.IterativeGaussianElimination{Vector{Vector{Int32}}}}, Vector{Int}})
Expand Down
3 changes: 3 additions & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -871,6 +871,9 @@ end

@test PeriodicGraphs.symdiff_cycles([3,4], [3,5,6]) == PeriodicGraphs.symdiff_cycles([4,5,6,7,8], [7,8]) == [4,5,6]
@test PeriodicGraphs.intersect_cycles([3,4], [3,5,6]) == PeriodicGraphs.intersect_cycles([2,3,5], [1,3]) == [3]
@test PeriodicGraphs.intersect_cycles([3,4,5], [4,5,6]) == PeriodicGraphs.intersect_cycles([4,5,7], [2,4,5,6]) == [4,5]
@test PeriodicGraphs.union_cycles([3,4], [4,5,6]) == PeriodicGraphs.union_cycles([4,5,6], [3,4]) == [3,4,5,6]
@test PeriodicGraphs.union_cycles([4,6], [3,5,6]) == PeriodicGraphs.union_cycles([3,5,6], [3,4,6]) == [3,4,5,6]

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

2 comments on commit 459c358

@Liozou
Copy link
Owner Author

@Liozou Liozou commented on 459c358 Jun 30, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JuliaRegistrator
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Registration pull request created: JuliaRegistries/General/63421

After the above pull request is merged, it is recommended that a tag is created on this repository for the registered package version.

This will be done automatically if the Julia TagBot GitHub Action is installed, or can be done manually through the github interface, or via:

git tag -a v0.9.3 -m "<description of version>" 459c358fdfb158789a2ef86b185652c4a364e211
git push origin v0.9.3

Please sign in to comment.