Skip to content
Merged
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# News

## dev - unreleased
- **(breaking)** `neighbors`, `inneighbors`, and `outneighbors` now return an immutable `FrozenVector` instead of `Vector`
- Louvain community detection algorithm
- Graph views: `ReverseView` and `UndirectedView` for directed graphs
- New graph products: `strong_product`, `disjunctive_product`, `lexicographic_product`, `homomorphic_product`
Expand Down
1 change: 1 addition & 0 deletions src/Graphs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -478,6 +478,7 @@ and tutorials are available at the
Graphs
include("interface.jl")
include("utils.jl")
include("frozenvector.jl")
include("deprecations.jl")
include("core.jl")

Expand Down
5 changes: 3 additions & 2 deletions src/SimpleGraphs/SimpleGraphs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import Graphs:
AbstractGraph,
AbstractEdge,
AbstractEdgeIter,
FrozenVector,
src,
dst,
edgetype,
Expand Down Expand Up @@ -153,8 +154,8 @@ add_edge!(g::AbstractSimpleGraph, x) = add_edge!(g, edgetype(g)(x))
has_edge(g::AbstractSimpleGraph, x, y) = has_edge(g, edgetype(g)(x, y))
add_edge!(g::AbstractSimpleGraph, x, y) = add_edge!(g, edgetype(g)(x, y))

inneighbors(g::AbstractSimpleGraph, v::Integer) = badj(g, v)
outneighbors(g::AbstractSimpleGraph, v::Integer) = fadj(g, v)
inneighbors(g::AbstractSimpleGraph, v::Integer) = FrozenVector(badj(g, v))
outneighbors(g::AbstractSimpleGraph, v::Integer) = FrozenVector(fadj(g, v))

function issubset(g::T, h::T) where {T<:AbstractSimpleGraph}
nv(g) <= nv(h) || return false
Expand Down
18 changes: 10 additions & 8 deletions src/core.jl
Original file line number Diff line number Diff line change
Expand Up @@ -248,12 +248,13 @@ For directed graphs, the default is equivalent to [`outneighbors`](@ref);
use [`all_neighbors`](@ref) to list inbound and outbound neighbors.

### Implementation Notes
Returns a reference to the current graph's internal structures, not a copy.
Do not modify result. If the graph is modified, the behavior is undefined:
In some cases might return a reference to the current graph's internal structures,
not a copy. Do not modify result. If the graph is modified, the behavior is undefined:
the array behind this reference may be modified too, but this is not guaranteed.
If you need to modify the result use `collect` or `copy` to create a copy.

# Examples
```jldoctest
```jldoctest; filter = r"0-element Graphs\\.FrozenVector\\{Int64\\}|Int64\\[\\]"
julia> using Graphs

julia> g = DiGraph(3);
Expand All @@ -263,14 +264,14 @@ julia> add_edge!(g, 2, 3);
julia> add_edge!(g, 3, 1);

julia> neighbors(g, 1)
Int64[]
0-element Graphs.FrozenVector{Int64}

julia> neighbors(g, 2)
1-element Vector{Int64}:
1-element Graphs.FrozenVector{Int64}:
3

julia> neighbors(g, 3)
1-element Vector{Int64}:
1-element Graphs.FrozenVector{Int64}:
1
```
"""
Expand All @@ -284,9 +285,10 @@ For undirected graphs, this is equivalent to both [`outneighbors`](@ref)
and [`inneighbors`](@ref).

### Implementation Notes
Returns a reference to the current graph's internal structures, not a copy.
Do not modify result. If the graph is modified, the behavior is undefined:
In some cases might return a reference to the current graph's internal structures,
not a copy. Do not modify result. If the graph is modified, the behavior is undefined:
the array behind this reference may be modified too, but this is not guaranteed.
If you need to modify the result use `collect` or `copy` to create a copy.

# Examples
```jldoctest
Expand Down
25 changes: 25 additions & 0 deletions src/frozenvector.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
"""
FrozenVector(v::Vector) <: AbstractVector

A data structure that wraps a `Vector` but does not allow modifications.
"""
struct FrozenVector{T} <: AbstractVector{T}
wrapped::Vector{T}
end

Base.size(v::FrozenVector) = Base.size(v.wrapped)

Base.@propagate_inbounds Base.getindex(v::FrozenVector, i::Int) = Base.getindex(
v.wrapped, i
)

Base.IndexStyle(v::Type{FrozenVector{T}}) where {T} = Base.IndexStyle(Vector{T})

Base.iterate(v::FrozenVector) = Base.iterate(v.wrapped)
Base.iterate(v::FrozenVector, state) = Base.iterate(v.wrapped, state)

Base.similar(v::FrozenVector) = Base.similar(v.wrapped)
Base.similar(v::FrozenVector, T::Type) = Base.similar(v.wrapped, T)
Base.similar(v::FrozenVector, T::Type, dims::Base.Dims) = Base.similar(v.wrapped, T, dims)

Base.copy(v::FrozenVector) = Base.copy(v.wrapped)
14 changes: 8 additions & 6 deletions src/interface.jl
Original file line number Diff line number Diff line change
Expand Up @@ -281,9 +281,10 @@ has_edge(g, e) = has_edge(g, src(e), dst(e))
Return a list of all neighbors connected to vertex `v` by an incoming edge.

### Implementation Notes
Returns a reference to the current graph's internal structures, not a copy.
Do not modify result. If the graph is modified, the behavior is undefined:
In some cases might return a reference to the current graph's internal structures,
not a copy. Do not modify result. If the graph is modified, the behavior is undefined:
the array behind this reference may be modified too, but this is not guaranteed.
If you need to modify the result use `collect` or `copy` to create a copy.

# Examples
```jldoctest
Expand All @@ -292,7 +293,7 @@ julia> using Graphs
julia> g = SimpleDiGraph([0 1 0 0 0; 0 0 1 0 0; 1 0 0 1 0; 0 0 0 0 1; 0 0 0 1 0]);

julia> inneighbors(g, 4)
2-element Vector{Int64}:
2-element Graphs.FrozenVector{Int64}:
3
5
```
Expand All @@ -305,9 +306,10 @@ inneighbors(x, v) = _NI("inneighbors")
Return a list of all neighbors connected to vertex `v` by an outgoing edge.

# Implementation Notes
Returns a reference to the current graph's internal structures, not a copy.
Do not modify result. If the graph is modified, the behavior is undefined:
In some cases might return a reference to the current graph's internal structures,
not a copy. Do not modify result. If the graph is modified, the behavior is undefined:
the array behind this reference may be modified too, but this is not guaranteed.
If you need to modify the result use `collect` or `copy` to create a copy.

# Examples
```jldoctest
Expand All @@ -316,7 +318,7 @@ julia> using Graphs
julia> g = SimpleDiGraph([0 1 0 0 0; 0 0 1 0 0; 1 0 0 1 0; 0 0 0 0 1; 0 0 0 1 0]);

julia> outneighbors(g, 4)
1-element Vector{Int64}:
1-element Graphs.FrozenVector{Int64}:
5
```
"""
Expand Down
6 changes: 3 additions & 3 deletions src/wrappedGraphs/graphviews.jl
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ A graph view that wraps a directed graph and reverse the direction of every edge
constructing the view may lead to incorrect results.

# Examples
```jldoctest
```jldoctest; filter = r"0-element Graphs\\.FrozenVector\\{Int64\\}|Int64\\[\\]"
julia> using Graphs

julia> g = SimpleDiGraph(2);
Expand All @@ -19,10 +19,10 @@ julia> add_edge!(g, 1, 2);
julia> rg = ReverseView(g);

julia> neighbors(rg, 1)
Int64[]
0-element Graphs.FrozenVector{Int64}

julia> neighbors(rg, 2)
1-element Vector{Int64}:
1-element Graphs.FrozenVector{Int64}:
1
```
"""
Expand Down
Loading