Pads arrays of any dimension with various border options including constants, periodic, symmetric, mirror and smooth. Can control amount of padding applied to the left and right side of each dimension. Fully differentiable (compatible with Zygote.jl
Flux.jl
)
pad
eagerly allocates new bigger array while pad!
mutates original array in place. For pad!,
the effective border is set back by the padding amount when evaluating various border options. pad
is AD (automatic differentiation) compatible while pad!
requires Zygote.Buffer
for AD (see usage )
pad(array, border, pad_amount)
pad(array, border, left_pad_amount, right_pad_amount)
pad(array, border, pad_amounts_for_dims)
pad(array, border, left_pad_amount_for_dims, right_pad_amount_for_dims)
pad!(array, border, pad_amount)
pad!(array, border, left_pad_amount, right_pad_amount)
pad!(array, border, pad_amounts_for_dims)
pad!(array, border, left_pad_amount_for_dims, right_pad_amount_for_dims)
- any constant value
v
: a b c | v v :periodic
: a b c | a b:replicate
: a b c | c c:symmetric
: a b c | c b:mirror
: a b c | b a:smooth
: a b c | 2c-b (Maintains C1 continuity)
a = collect(reshape(1:16, 4, 4))
@test pad(a, -1, 1) == [
-1 -1 -1 -1 -1 -1
-1 1 5 9 13 -1
-1 2 6 10 14 -1
-1 3 7 11 15 -1
-1 4 8 12 16 -1
-1 -1 -1 -1 -1 -1
]
@test pad!(copy(a), -1, 1) == [
-1 -1 -1 -1
-1 6 10 -1
-1 7 11 -1
-1 -1 -1 -1
]
@test pad(a, -1, 1, 0) == [
-1 -1 -1 -1 -1
-1 1 5 9 13
-1 2 6 10 14
-1 3 7 11 15
-1 4 8 12 16
]
@test pad!(copy(a), -1, 1, 0) == [
-1 -1 -1 -1
-1 6 10 14
-1 7 11 15
-1 8 12 16
]
@test pad(a, -1, (0, 1), (1, 0)) == [
-1 1 5 9 13
-1 2 6 10 14
-1 3 7 11 15
-1 4 8 12 16
-1 -1 -1 -1 -1
]
@test pad!(copy(a), -1, (0, 1), (1, 0)) == [
-1 5 9 13
-1 6 10 14
-1 7 11 15
-1 -1 -1 -1
]
@test pad(a, :periodic, (1, 1), (0, 0)) == [
16 4 8 12 16
13 1 5 9 13
14 2 6 10 14
15 3 7 11 15
16 4 8 12 16
]
@test pad!(copy(a), :periodic, (1, 1), (0, 0)) == [
16 8 12 16
14 6 10 14
15 7 11 15
16 8 12 16
]
@test pad(a, :symmetric, 1) == [
1 1 5 9 13 13
1 1 5 9 13 13
2 2 6 10 14 14
3 3 7 11 15 15
4 4 8 12 16 16
4 4 8 12 16 16
]
@test pad!(copy(a), :symmetric, 1) == [
6 6 10 10
6 6 10 10
7 7 11 11
7 7 11 11
]
@test pad(a, :mirror, 1) == [
6 2 6 10 14 10
5 1 5 9 13 9
6 2 6 10 14 10
7 3 7 11 15 11
8 4 8 12 16 12
7 3 7 11 15 11
]
@test pad!(copy(a), :mirror, 1) == [
11 7 11 7
10 6 10 6
11 7 11 7
10 6 10 6
]
@test pad(a, :replicate, 1) == [
1 1 5 9 13 13
1 1 5 9 13 13
2 2 6 10 14 14
3 3 7 11 15 15
4 4 8 12 16 16
4 4 8 12 16 16
]
@test pad!(copy(a), :replicate, 1) == [
6 6 10 10
6 6 10 10
7 7 11 11
7 7 11 11
]
@test pad(a, :smooth, 1) == [
-4 0 4 8 12 16
-3 1 5 9 13 17
-2 2 6 10 14 18
-1 3 7 11 15 19
0 4 8 12 16 20
1 5 9 13 17 21
]
@test pad!(copy(a), :smooth, 1) == [
1 5 9 13
2 6 10 14
3 7 11 15
4 8 12 16
]
using Zygote
using Zygote: Buffer
@test withgradient(a) do a
a = pad(a, 0, 1)
sum(a)
end == (val=136, grad=([1.0 1.0 1.0 1.0; 1.0 1.0 1.0 1.0; 1.0 1.0 1.0 1.0; 1.0 1.0 1.0 1.0],))
@test withgradient(a) do a
a_ = Buffer(a)
a_ .= a
pad!(a_, 0, 1)
a = copy(a_)
sum(a)
end == (val=34, grad=([0.0 0.0 0.0 0.0; 0.0 1.0 1.0 0.0; 0.0 1.0 1.0 0.0; 0.0 0.0 0.0 0.0],))
Consider sponsoring this on Github if you found this repo helpful. Feel free to request features or contribute PRs :)
Paul Shen pxshen@alumni.stanford.edu