From fd91c6a9ef5f308e9483c5cbdef483e9c742c449 Mon Sep 17 00:00:00 2001 From: Azzaare Date: Wed, 17 Mar 2021 22:38:52 +0900 Subject: [PATCH] Extended fold to both mutable and immutable vector folds. Add CI --- src/PatternFolds.jl | 4 ++-- src/common.jl | 26 ++++++++++++++++++++++++++ src/immutable_vector.jl | 22 +--------------------- src/vector.jl | 2 ++ test/vector.jl | 12 ++++++++++++ 5 files changed, 43 insertions(+), 23 deletions(-) diff --git a/src/PatternFolds.jl b/src/PatternFolds.jl index 97d3dc0..eb0f613 100644 --- a/src/PatternFolds.jl +++ b/src/PatternFolds.jl @@ -7,9 +7,9 @@ using Lazy export PatternFold export IVectorFold, VectorFold export Interval, IntervalsFold -export pattern, gap, folds, fold, check_pattern +export pattern, gap, folds, check_pattern export length -export unfold +export fold, unfold export value # includes diff --git a/src/common.jl b/src/common.jl index 68e2d99..e78d3fc 100644 --- a/src/common.jl +++ b/src/common.jl @@ -60,3 +60,29 @@ end Reset the *unfolded* pattern to the first fold. """ reset_pattern!(mvf) = set_fold!(mvf, 1) + +""" + fold(v::V, depth = 0) +returns a suitable `VectorFold`, which when unfolded gives the Vector V. +""" +function fold(v::V, depth = 0; kind = :mutable) where {T <: Real, V <: AbstractVector{T}} + l = length(v) + for i in 1:(l ÷ 2) + gap = v[i + 1] - v[1] + fold, r = divrem(l, i) + if r == 0 && check_pattern(v, i, gap, fold) + # return VectorFold(fold(v[1:i], depth + 1), gap, fold) + return make_vector_fold(v[1:i], gap, fold, kind) + end + end + if depth == 0 + @warn "No non-degenerate patterns have been found" v + return make_vector_fold(v, zero(T), 1, kind) + else + return v + end +end + +function make_vector_fold(pattern, gap, fold, kind = :mutable) + return make_vector_fold(pattern, gap, fold, Val(kind)) +end diff --git a/src/immutable_vector.jl b/src/immutable_vector.jl index f9c3a14..c96ce49 100644 --- a/src/immutable_vector.jl +++ b/src/immutable_vector.jl @@ -84,24 +84,4 @@ function check_pattern(v, i, gap, fold) return true end -""" - fold(v::V, depth = 0) -returns a suitable `VectorFold`, which when unfolded gives the Vector V. -""" -function fold(v::V, depth = 0) where {T <: Real, V <: AbstractVector{T}} - l = length(v) - for i in 1:(l ÷ 2) - gap = v[i + 1] - v[1] - fold, r = divrem(l, i) - if r == 0 && check_pattern(v, i, gap, fold) - # return VectorFold(fold(v[1:i], depth + 1), gap, fold) - return VectorFold(v[1:i], gap, fold) - end - end - if depth == 0 - @warn "No non-degenerate patterns have been found" v - return VectorFold(v, zero(T), 1) - else - return v - end -end \ No newline at end of file +make_vector_fold(pattern, gap, fold, ::Val{:immutable}) = IVectorFold(pattern, gap, fold) diff --git a/src/vector.jl b/src/vector.jl index 10d593f..9dd563d 100644 --- a/src/vector.jl +++ b/src/vector.jl @@ -93,3 +93,5 @@ function unfold(mvf::VectorFold; from=1, to=folds(mvf)) end return v end + +make_vector_fold(pattern, gap, fold, ::Val{:mutable}) = VectorFold(pattern, gap, fold) diff --git a/test/vector.jl b/test/vector.jl index 994f4b5..6a3991a 100644 --- a/test/vector.jl +++ b/test/vector.jl @@ -31,4 +31,16 @@ end @test isempty(IVectorFold(Vector(),1,1)) @test isempty(VectorFold(Vector(),1,1)) + + v1 = VectorFold([42,3,45,6],13,4) + w1 = unfold(v1) + v11 = fold(w1) + + @test unfold(v11) == w1 + + v2 = VectorFold([34,34,43,43],10,3) + w2 = unfold(v2) + v22 = fold(w2) + + @test unfold(v22) == w2 end