Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ jobs:
fail-fast: false
matrix:
version:
- "^1.6.0-0"
- "^1.7.0-0"
- 'nightly'
os:
- ubuntu-latest
Expand Down
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Lazy = "50d2b5c4-7a5e-59d5-8109-a42b560f39c0"

[compat]
Lazy = "0.15"
julia = "1.6"
julia = "1.7"

[extras]
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
Expand Down
28 changes: 20 additions & 8 deletions src/PatternFolds.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,31 @@ module PatternFolds
using Lazy

# exports
export PatternFold
export IVectorFold, VectorFold
export Interval, IntervalsFold
export pattern, gap, folds, check_pattern
export Interval
export IntervalsFold
export IVectorFold
export VectorFold

export a_isless
export a_ismore
export b_isless
export b_ismore
export check_pattern
export closed
export fold
export folds
export gap
export length
export fold, unfold
export value, closed, opened
export a_isless, b_isless, a_ismore, b_ismore
export make_vector_fold
export opened
export pattern
export unfold
export value

# includes
include("intervals.jl")
include("common.jl")
include("immutable_vector.jl")
include("vector.jl")
include("intervals.jl")

end
32 changes: 27 additions & 5 deletions src/common.jl
Original file line number Diff line number Diff line change
@@ -1,12 +1,26 @@
"""
PatternFold{T, P}
An abstract stype used as an interface for folded patterns such as `VectorFold`.
AbstractVectorFold{T, P}
An abstract type used as an interface for folded vectors such as `VectorFold`.
To implement the interface and inherit from it, a new structure must define three fields:
- `pattern::P`. Note that both `length(::P)` and `rand(::P)` methods must be available
- `gap::T`
- `folds::int`
"""
abstract type PatternFold{T, P} end
abstract type AbstractVectorFold{T} <: AbstractVector{T} end

"""
PatternFold{T, P}
A `Union` type used as an interface for folded patterns such as `VectorFold`.
To implement the interface and inherit from it, a new structure `MyFold{T[,P]}` must define three fields:
- `pattern::P`. Note that both `length(::P)` and `rand(::P)` methods must be available
- `gap::T`S
- `folds::int`
Finally one can redefine PatternFold{T}
```julia
PatternFold{T} = Union{AbstractVectorFold{T}, IntervalsFold{T}, MyFold{T[,P]}}
```
"""
PatternFold{T} = Union{AbstractVectorFold{T}, IntervalsFold{T}}

"""
pattern(<:PatternFold)
Expand All @@ -29,7 +43,6 @@ folds(pf) = pf.folds
# Forwards isempty, ndims
@forward PatternFold.pattern Base.isempty, Base.ndims

# TODO - look if another name is more appropriate
"""
pattern_length(pf<:PatternFold)
Return the length of the basic pattern of `pf`.
Expand All @@ -41,11 +54,12 @@ pattern_length(pf) = length(pattern(pf))
Return the length of `pf` if unfolded.
"""
Base.length(pf::PatternFold) = pattern_length(pf) * folds(pf)
Base.size(pf::PatternFold) = (length(pf),)

"""
eltype(pf<: PatternFolds)
"""
Base.eltype(::Type{<:PatternFold{T,P}}) where {T,P} = T
Base.eltype(::Type{<:PatternFold{T}}) where {T} = T

"""
rand(pf<:PatternFold)
Expand Down Expand Up @@ -83,6 +97,14 @@ function fold(v::V, depth = 0; kind = :mutable) where {T <: Real, V <: AbstractV
end
end

"""
make_vector_fold(pattern, gap, fold, kind = :mutable)
A dispatcher to construct a folded vector. The `kind` of vector can be set to either `:mutable` (default) or `:immutable`. The default is faster in most cases but it depends on the `pattern`, `gap`, and `fold` parameters. For critical code, it is recommended to benchmark both options.
"""
function make_vector_fold(pattern, gap, fold, kind = :mutable)
return make_vector_fold(pattern, gap, fold, Val(kind))
end

function Base.print_array(io::IO, X::AbstractVectorFold)
print(io, "\tPattern: $(pattern(X))\n\tGap: $(gap(X))\n\tFolds: $(folds(X))")
end
2 changes: 1 addition & 1 deletion src/immutable_vector.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
VectorFold{T,V <: AbstractVector{T}}
A folded vector structure that extends the methods of AbstractVector to a folded structure.
"""
struct IVectorFold{T,V <: AbstractVector{T}} <: PatternFold{T,V}
struct IVectorFold{T,V <: AbstractVector{T}} <: AbstractVectorFold{T}
pattern::V
gap::T
folds::Int
Expand Down
2 changes: 1 addition & 1 deletion src/intervals.jl
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ Base.isempty(i::Interval) = size(i) == 0 && (opened(i, :a) || opened(i, :b))
Base.ndims(::Interval) = 1
Base.rand(i::Interval) = rand() * size(i) + value(i, :a)

mutable struct IntervalsFold{T <: Real} <: PatternFold{T, Interval{T}}
mutable struct IntervalsFold{T <: Real} #<: PatternFold{T, Interval{T}}
pattern::Interval{T}
gap::T
folds::Int
Expand Down
10 changes: 5 additions & 5 deletions src/vector.jl
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
"""
MVectorFold{T,V <: AbstractVector{T}}
A mutable structure for folded vector that extends the methods of AbstractVector. Compared to `VectorFold`, this tructure is about 20% faster using iterators. Unfolding is twice slower though.
Note that this structure keep an active pointer to the `current` *unfolded* pattern. However, its external behavior is similar to `VectorFold`.
VectorFold{T,V <: AbstractVector{T}}
A mutable structure for folded vector that extends the methods of AbstractVector. Compared to `IVectorFold`, this tructure is about 20% faster using iterators.
Note that this structure keep an active pointer to the `current` *unfolded* pattern. However, its external behavior is similar to `IVectorFold`.
"""
mutable struct VectorFold{T,V <: AbstractVector{T}} <: PatternFold{T,V}
mutable struct VectorFold{T,V <: AbstractVector{T}} <: AbstractVectorFold{T}
pattern::V
gap::T
folds::Int
Expand All @@ -22,7 +22,7 @@ end
pattern(mvf::VectorFold, index) = pattern(mvf)[index]

"""
set_fold!(mvf::MVectorFold, new_fold = mvf.current + 1)
set_fold!(mvf::VectorFold, new_fold = mvf.current + 1)
Set the *unfolded* pattern to `new_fold`. By default move the next *fold* after `current`.
"""
function set_fold!(mvf, new_fold = mvf.current + 1)
Expand Down
12 changes: 6 additions & 6 deletions test/vector.jl
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
@testset "VectorFold" begin
vf_dict = Dict([
IVectorFold([1,2], 10, 5) => Dict(
make_vector_fold([1,2], 10, 5, :immutable) => Dict(
:pattern => [1,2],
:gap => 10,
:folds => 5,
:length => 10,
:unfold => [1,2,11,12,21,22,31,32,41,42],
:reverse => reverse([1,2,11,12,21,22,31,32,41,42]),
),
VectorFold([1,2], 10, 5) => Dict(
make_vector_fold([1,2], 10, 5, :mutable) => Dict(
:pattern => [1,2],
:gap => 10,
:folds => 5,
Expand All @@ -29,16 +29,16 @@
@test collect(vf) == [i for i in vf] == unfold(vf)
@test collect(Iterators.reverse(vf)) == reverse(collect(vf)) == results[:reverse]
end
@test isempty(IVectorFold(Vector(),1,1))
@test isempty(VectorFold(Vector(),1,1))
@test isempty(make_vector_fold(Vector(),1,1,:immutable))
@test isempty(make_vector_fold(Vector(),1,1))

v1 = VectorFold([42,3,45,6],13,4)
v1 = make_vector_fold([42,3,45,6],13,4)
w1 = unfold(v1)
v11 = fold(w1)

@test unfold(v11) == w1

v2 = VectorFold([34,34,43,43],10,3)
v2 = make_vector_fold([34,34,43,43],10,3)
w2 = unfold(v2)
v22 = fold(w2)

Expand Down