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
26 changes: 26 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,32 @@ julia> a4[i,i]
12 15 18 22 25
```

## Known Limitations

**Iterated indexing for mutation does not work** when the map is non-trivial.
For a `PeriodicArray` whose elements are themselves mutable (e.g. an array of matrices), writing

```julia
x[out_of_bounds_index][i, j] = value
```

silently does nothing to `x`. The reason is that `x[out_of_bounds_index]` applies the map and returns a *new, transformed copy* of the element; the subsequent assignment mutates only that temporary object, not the underlying data.

For in-bounds indices the element is returned by reference and mutation works as expected.
As a workaround, operate directly on the underlying data:

```julia
parent(x)[mod_index][i, j] = value # bypasses the map entirely
```

or set the whole element at once (which goes through `setindex!` on `x` and correctly applies the inverse map):

```julia
tmp = copy(x[out_of_bounds_index])
tmp[i, j] = value
x[out_of_bounds_index] = tmp
```

## License

PeriodicArrays.jl is licensed under the [MIT License](LICENSE). By using or interacting with this software in any way, you agree to the license of this software.
102 changes: 102 additions & 0 deletions test/test_basics.jl
Original file line number Diff line number Diff line change
Expand Up @@ -339,12 +339,34 @@ end
end
end

@testset "AbstractVector shifts" begin
a = PeriodicVector([1, 2, 3, 4, 5])
@test circshift(a, [2]) == circshift(a, 2)
@test circshift(a, [-1]) == circshift(a, -1)

b = PeriodicMatrix([1 2 3; 4 5 6])
for s in ((0, 0), (1, 0), (0, 1), (1, 2))
cs = circshift(b, collect(s))
@test all(cs[i, j] == b[i - s[1], j - s[2]] for i in -5:5, j in -5:5)
end
end

@testset "circshift! 3-arg" begin
a = PeriodicVector([1, 2, 3, 4, 5])
dest = similar(a)
circshift!(dest, a, 2)
@test dest == circshift(a, 2)
@test parent(a) == [1, 2, 3, 4, 5]

# empty tuple: no shift
dest2 = similar(a)
circshift!(dest2, a, ())
@test dest2 == a

# AbstractVector shifts
dest3 = similar(a)
circshift!(dest3, a, [2])
@test dest3 == circshift(a, 2)
end

@testset "circshift! in-place" begin
Expand All @@ -353,6 +375,86 @@ end
circshift!(a, 2)
@test a == expected
end

@testset "circshift! 2D in-place" begin
b = PeriodicMatrix([1 2 3; 4 5 6])
expected = circshift(b, (1, 2))
circshift!(b, (1, 2))
@test b == expected
end
end

@testset "reverse" begin
@testset "1D" begin
a = PeriodicVector([1, 2, 3, 4, 5])
ra = reverse(a)
@test parent(ra) == [5, 4, 3, 2, 1]
@test ra[1] == a[5]
@test ra[3] == a[3]
# periodic: ra[i] == a[n+1-i] for all i
@test all(ra[i] == a[6 - i] for i in -20:20)
end

@testset "2D full" begin
b_arr = [1 2 3; 4 5 6]
b = PeriodicMatrix(b_arr)
rb = reverse(b)
@test parent(rb) == reverse(b_arr)
@test all(rb[i, j] == b[3 - i, 4 - j] for i in -5:5, j in -5:5)
end

@testset "2D partial" begin
b_arr = [1 2 3; 4 5 6]
b = PeriodicMatrix(b_arr)

rb1 = reverse(b; dims = 1)
@test parent(rb1) == reverse(b_arr; dims = 1)
@test all(rb1[i, j] == b[3 - i, j] for i in -5:5, j in -5:5)

rb2 = reverse(b; dims = 2)
@test parent(rb2) == reverse(b_arr; dims = 2)
@test all(rb2[i, j] == b[i, 4 - j] for i in -5:5, j in -5:5)
end
end

@testset "repeat" begin
@testset "1D" begin
a = PeriodicVector([1, 2, 3])

# outer as scalar — identity map tiles data unchanged
ar = repeat(a; outer = 2)
@test parent(ar) == [1, 2, 3, 1, 2, 3]
@test length(ar) == 6

# outer as tuple
ar2 = repeat(a; outer = (2,))
@test parent(ar2) == parent(ar)

# inner repetition
ai = repeat(a; inner = 2)
@test parent(ai) == [1, 1, 2, 2, 3, 3]
@test length(ai) == 6

# combined inner + outer
aio = repeat(a; inner = 2, outer = 3)
@test length(aio) == 18
@test parent(aio) == repeat(parent(ai); outer = 3)
end

@testset "2D" begin
b_arr = [1 2; 3 4; 5 6]
b = PeriodicMatrix(b_arr)

# outer repetition
br = repeat(b; outer = (2, 3))
@test size(br) == (6, 6)
@test parent(br) == repeat(b_arr; outer = (2, 3))

# inner repetition
bi = repeat(b; inner = (1, 2))
@test parent(bi) == repeat(b_arr; inner = (1, 2))
@test size(bi) == (3, 4)
end
end

@testset "offset indices" begin
Expand Down
Loading