https://github.com/jw3126/reducewindows.jl
Apply reduce over sliding windows
https://github.com/jw3126/reducewindows.jl
arrays julia stencil
Last synced: about 1 year ago
JSON representation
Apply reduce over sliding windows
- Host: GitHub
- URL: https://github.com/jw3126/reducewindows.jl
- Owner: jw3126
- License: mit
- Created: 2023-04-23T22:10:25.000Z (about 3 years ago)
- Default Branch: main
- Last Pushed: 2023-10-21T18:09:03.000Z (over 2 years ago)
- Last Synced: 2025-04-10T05:05:29.758Z (about 1 year ago)
- Topics: arrays, julia, stencil
- Language: Julia
- Homepage:
- Size: 149 KB
- Stars: 6
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# ReduceWindows
[](https://github.com/jw3126/ReduceWindows.jl/actions/workflows/CI.yml?query=branch%3Amain)
[](https://codecov.io/gh/jw3126/ReduceWindows.jl)
Apply `reduce` over a sliding window.
# Usage
```julia
using ReduceWindows
x = [1,2,3,4,5]
reduce_window(+, x, (-1:1,))
# [3, 6, 9, 12, 9]
reduce_window(max, x, (-1:1,))
# [2, 3, 4, 5, 5]
reduce_window(min, x, (-3:0,))
# [1, 1, 1, 1, 2]
x = [1 2 3; 4 5 6]
reduce_window(*, x, (0:1,0:1))
# 40 180 18
# 20 30 6
```
# Speed
This package has very competitive performance, especially for large windows.
```julia
arr = randn(500,500)
window = (-50:50, -50:50)
using ImageFiltering: mapwindow
mapwindow(maximum, arr, window) # warmup
out1 = @showtime mapwindow(maximum, arr, window)
using ReduceWindows
reduce_window(max, arr, window) # warmup
out2 = @showtime reduce_window(max, arr, window)
@assert out1 == out2
```
```
mapwindow(maximum, arr, window): 2.075822 seconds (1.26 M allocations: 227.561 MiB, 0.76% gc time)
reduce_window(max, arr, window): 0.002320 seconds (14 allocations: 7.630 MiB)
```
Naively reducing a windows of size `k` over an array of size `n` is `O(k*n)`.
However the algorithm implemented here is `O(log(k)*n)` making it practical to reduce over large windows.
This packages also ships an `O(n)` algorithm, for extremly large windows or very costly ops.
```julia
arr = randn(500,500)
window = (-50:50, -50:50)
using ImageFiltering: mapwindow
using ReduceWindows
const OPCOUNT = Ref(0)
function mymax(x,y)
OPCOUNT[] += 1
max(x,y)
end
mapwindow(w->reduce(mymax, w), arr, window)
opcount_naive = OPCOUNT[]
OPCOUNT[] = 0
reduce_window(mymax, arr, window)
opcount_reduce_window = OPCOUNT[]
@show opcount_naive
@show opcount_reduce_window
```
```
opcount_naive = 2550010200
opcount_reduce_window = 4775000
```
# Alternatives
* [ImageFiltering.jl](https://github.com/JuliaImages/ImageFiltering.jl) much more features than this packge, but slow for large windows.
* [MeanFilters.jl](https://github.com/jw3126/MeanFilters.jl) fast, lightwight but very narrow usecase.
* [StaticKernels.jl](https://github.com/stev47/StaticKernels.jl) has very good performance for small windows.