Skip to content

Commit

Permalink
Merge pull request #9 from cesaraustralia/docs
Browse files Browse the repository at this point in the history
update docs
  • Loading branch information
rafaqz authored Dec 16, 2019
2 parents 7097970 + 114a39e commit d2041af
Show file tree
Hide file tree
Showing 12 changed files with 94 additions and 49 deletions.
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "DynamicGrids"
uuid = "a5dba43e-3abc-5203-bfc5-584ca68d3f5b"
authors = ["Rafael Schouten <[email protected]>"]
version = "0.2.0"
version = "0.2.1"

[deps]
Colors = "5ae59095-9a9b-59fe-a467-6f913c188581"
Expand Down
1 change: 1 addition & 0 deletions docs/make.jl
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Documenter, DynamicGrids
using DynamicGrids: @Output, @Graphic, @Image, applyinteraction, applyinteraction!

makedocs(
modules = [DynamicGrids],
Expand Down
41 changes: 39 additions & 2 deletions docs/src/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ init = round.(Int8, max.(0.0, rand(-2.0:0.1:1.0, 70,70)))
model = Ruleset(Life())
# Use an output that shows the cellular automata as blocks in the REPL
output = REPLOutput{:block}(init; fps=100)
output = REPLOutput(init; fps=100)
sim!(output, model, init; tstop=5)
sim!(output, model, init; tspan=(1, 5))
```

More life-like examples:
Expand Down Expand Up @@ -59,15 +59,28 @@ Rules define simulation behaviour. They hold data relevant to the simulation,
and trigger dispatch of particular [`applyrule`](@ref) or [`applyrule!`](@ref) methods.
Rules can be chained together arbitrarily to make composite simulations.


### Types and Constructors

```@docs
Ruleset
Rule
CellRule
NeighborhoodRule
PartialRule
PartialNeighborhoodRule
Life
Chain
```

`Interaction` rules specify interactions between multiple dynamic grids.

```@docs
Interaction
NeighborhoodInteraction
CellInteraction
PartialInteraction
PartialNeighborhoodInteraction
```

## Neighborhoods
Expand All @@ -79,6 +92,7 @@ and how they are combined to update the value of the current cell.

```@docs
Neighborhood
AbstractRadialNeighborhood
RadialNeighborhood
AbstractCustomNeighborhood
CustomNeighborhood
Expand All @@ -93,17 +107,40 @@ LayeredCustomNeighborhood
```@docs
Output
ArrayOutput
GraphicOutput
REPLOutput
ImageOutput
```


Dynamic grids uses [Mixers.jl](https://github.com/rafaqz/Mixers.jl) mixins
to simplify specifying custom outputs with the required fields.

```@docs
@Output
@Graphic
@Image
```

### Frame processors

```@docs
FrameProcessor
SingleFrameProcessor
ColorProcessor
MultiFrameProcessor
ThreeColorProcessor
LayoutProcessor
Greyscale
```

### Internal data handling

```@docs
SimData
MultiSimData
```

## Overflow

```@docs
Expand Down
13 changes: 8 additions & 5 deletions src/DynamicGrids.jl
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module DynamicGrids
# Use the README as the module docs
@doc let
@doc let
path = joinpath(dirname(@__DIR__), "README.md")
include_dependency(path)
# Use [`XX`](@ref) in the docs but not the readme
Expand Down Expand Up @@ -50,15 +50,18 @@ export AbstractRuleset, Ruleset, MultiRuleset

export Life

export Neighborhood, AbstractRadialNeighborhood, RadialNeighborhood,
AbstractCustomNeighborhood, CustomNeighborhood, LayeredCustomNeighborhood,
export Neighborhood, AbstractRadialNeighborhood, RadialNeighborhood,
AbstractCustomNeighborhood, CustomNeighborhood, LayeredCustomNeighborhood,
VonNeumannNeighborhood

export RemoveOverflow, WrapOverflow
export Overflow, RemoveOverflow, WrapOverflow

export Output, GraphicOutput, ImageOutput, ArrayOutput, REPLOutput

export FrameProcessor, ColorProcessor, Greyscale, Grayscale
export FrameProcessor, SingleFrameProcessor, ColorProcessor,
MultiFrameProcessor, ThreeColorProcessor, LayoutProcessor

export Greyscale, Grayscale

export CharStyle, Block, Braile

Expand Down
5 changes: 3 additions & 2 deletions src/framework.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ Runs the whole simulation, passing the destination aray to
the passed in output for each time-step.
### Arguments
- `output`: An [AbstractOutput](@ref) to store frames or display them on the screen.
- `ruleset`: A Rule() containing one ore more [`AbstractRule`](@ref). These will each be run in sequence.
- `output`: An [Output](@ref) to store frames or display them on the screen.
- `ruleset`: A Rule() containing one ore more [`Rule`](@ref). These will each be run in sequence.
### Keyword Arguments
- `init`: the initialisation array. If `nothing`, the Ruleset must contain an `init` array.
Expand Down Expand Up @@ -95,6 +95,7 @@ simloop!(output, data, fspan) = begin
data = updatetime(data, f) |> precalcrules
# Run the ruleset and setup data for the next iteration
data = sequencerules!(data)
println(typeof(data))
# Save/do something with the the current frame
storeframe!(output, data)
isasync(output) && yield()
Expand Down
17 changes: 13 additions & 4 deletions src/interactions.jl
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""
Rules that involved the interaction between
two grids
Rules that involved the interaction between two grids
Applied using [`applyinteraction](@ref) and [`applyinteraction!](@ref).
"""
abstract type Interaction{Keys} <: Rule end

Expand All @@ -10,19 +11,27 @@ Base.keys(::Interaction{Keys}) where Keys = Keys
ConstructionBase.constructorof(::Type{T}) where T<:Interaction{Keys} where Keys =
T{Keys}

"""
Cell by cell interaction, analogous to [`CellRule`](@ref).
"""
abstract type CellInteraction{Keys} <: Interaction{Keys} end

"""
Rules that conditionally apply to particular cells, but may not write
to every cell in the grid. Analogous to [`PartialRule`](@ref).
"""
abstract type PartialInteraction{Keys} <: Interaction{Keys} end

"""
Interactions that use a neighborhood and write to the current cell.
Interactions that use a neighborhood and write to the current cell,
analagous to [`NeighborhoodRule`](@ref).
"""
abstract type NeighborhoodInteraction{Keys} <: Interaction{Keys} end

neighborhood(interaction::NeighborhoodInteraction) = interaction.neighborhood

"""
Interactions that write to a neighborhood.
Interactions that write to a neighborhood, analogous to [`PartialNeighborhoodRule`](@ref).
"""
abstract type PartialNeighborhoodInteraction{Keys} <: PartialInteraction{Keys} end

Expand Down
3 changes: 2 additions & 1 deletion src/interface.jl
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
"""
applyrule(rule::Rule, data, state, index)
applyrule(rule::Rule, data, state, index, [buffer])
Updates cell values based on their current state and the state of other cells
as defined in the Rule.
Expand All @@ -9,6 +9,7 @@ as defined in the Rule.
- `data` : [`FrameData`](@ref)
- `state`: the value of the current cell
- `index`: a (row, column) tuple of Int for the current cell coordinates - `t`: the current time step
- `buffer`: a neighborhood burrer array passed to [`NeighborhoodRule`].
Returns a value to be written to the current cell.
"""
Expand Down
35 changes: 14 additions & 21 deletions src/life.jl
Original file line number Diff line number Diff line change
@@ -1,23 +1,7 @@
"""
Rule for game-of-life style cellular automata.
$(FIELDDOCTABLE)
"""
@description @limits @flattenable @default_kw struct Life{R,N,B,S} <: NeighborhoodRule{R}
neighborhood::N | RadialNeighborhood{1}() | false | nothing | "Any Neighborhood"
b::B | (3, 3) | true | (0, 8) | "Array, Tuple or Iterable of integers to match neighbors when cell is empty"
s::S | (2, 3) | true | (0, 8) | "Array, Tuple or Iterable of integers to match neighbors cell is full"
end

Life(neighborhood::N, b::B, s::S) where {N,B,S} =
Life{radius(neighborhood),N,B,S}(neighborhood, b, s)

"""
rule(rule::Life, state)
Rule for game-of-life style cellular automata. This is a demonstration of
Cellular Automata more than a seriously optimised game of life rule.
Cells becomes active if it is empty and the number of neightbors is a number in
the b array, and remains active the cell is active and the number of neightbors is
in the s array.
Expand All @@ -29,24 +13,33 @@ Returns: boolean
```julia
# Life.
init = round.(Int64, max.(0.0, rand(-3.0:0.1:1.0, 300,300)))
output = REPLOutput{:block}(init; fps=10, color=:red)
sim!(output, rule, init; time=1000)
output = REPLOutput(init; fps=10, color=:red)
sim!(output, rule, init; tspan=(1, 1000)
# Dimoeba
init = rand(0:1, 400, 300)
init[:, 100:200] .= 0
output = REPLOutput{:braile}(init; fps=25, color=:blue)
sim!(output, Ruleset(Life(b=(3,5,6,7,8), s=(5,6,7,8))), init; time=1000)
sim!(output, Ruleset(Life(b=(3,5,6,7,8), s=(5,6,7,8))), init; tspan=(1, 1000))
# Replicator
init = fill(1, 300,300)
init[:, 100:200] .= 0
init[10, :] .= 0
output = REPLOutput{:block}(init; fps=60, color=:yellow)
sim!(output, Ruleset(Life(b=(1,3,5,7), s=(1,3,5,7))), init; time=1000)
output = REPLOutput(init; fps=60, color=:yellow)
sim!(output, Ruleset(Life(b=(1,3,5,7), s=(1,3,5,7))), init; tspan=(1, 1000))
```
$(FIELDDOCTABLE)
"""
@description @limits @flattenable @default_kw struct Life{R,N,B,S} <: NeighborhoodRule{R}
neighborhood::N | RadialNeighborhood{1}() | false | nothing | "Any Neighborhood"
b::B | (3, 3) | true | (0, 8) | "Array, Tuple or Iterable of integers to match neighbors when cell is empty"
s::S | (2, 3) | true | (0, 8) | "Array, Tuple or Iterable of integers to match neighbors cell is full"
end
Life(neighborhood::N, b::B, s::S) where {N,B,S} =
Life{radius(neighborhood),N,B,S}(neighborhood, b, s)

applyrule(rule::Life, data, state, index, buf) = begin
# Sum neighborhood
cc = neighbors(rule.neighborhood, rule, buf, state)
Expand Down
18 changes: 9 additions & 9 deletions src/outputs/image.jl
Original file line number Diff line number Diff line change
Expand Up @@ -63,12 +63,12 @@ Frame processors convert a frame of the grid simulation into an RGB24 image for
abstract type FrameProcessor end

"""
Processors for converting one frame of a single grid model to an image.
Processors that convert one frame of a single grid model to an image.
"""
abstract type SingleFrameProcessor <: FrameProcessor end

"""
Processors for converting frames from multiple grids to a single image.
Processors that convert frames from multiple grids to a single image.
"""
abstract type MultiFrameProcessor <: FrameProcessor end

Expand Down Expand Up @@ -141,9 +141,9 @@ struct Blue <: BandColor end


"""
ThreeColor(; colors=(Red(), Green(), Blue()), zerocolor=nothing, maskcolor=nothing)
ThreeColorProcessor(; colors=(Red(), Green(), Blue()), zerocolor=nothing, maskcolor=nothing)
ThreeColor processor. Assigns `Red()`, `Blue()`, `Green()` or `nothing` to
Assigns `Red()`, `Blue()`, `Green()` or `nothing` to
any number of dynamic grids in any order. Duplicate colors will be summed.
The final color sums are combined into a composite color image for display.
Expand All @@ -152,17 +152,17 @@ The final color sums are combined into a composite color image for display.
- `zerocolor`: an `RGB24` color to use when values are zero, or `nothing` to ignore.
- `maskcolor`: an `RGB24` color to use when cells are masked, or `nothing` to ignore.
"""
@default_kw struct ThreeColor{C<:Tuple,Z,M} <: MultiFrameProcessor
@default_kw struct ThreeColorProcessor{C<:Tuple,Z,M} <: MultiFrameProcessor
colors::C | (Red(), Green(), Blue())
zerocolor::Z | nothing
maskcolor::M | nothing
end

colors(processor::ThreeColor) = processor.colors
zerocolor(processor::ThreeColor) = processor.zerocolor
maskcolor(processor::ThreeColor) = processor.maskcolor
colors(processor::ThreeColorProcessor) = processor.colors
zerocolor(processor::ThreeColorProcessor) = processor.zerocolor
maskcolor(processor::ThreeColorProcessor) = processor.maskcolor

frametoimage(p::ThreeColor, minvals::Tuple, maxvals::Tuple, ruleset, bands::NamedTuple, t) = begin
frametoimage(p::ThreeColorProcessor, minvals::Tuple, maxvals::Tuple, ruleset, bands::NamedTuple, t) = begin
img = fill(RGB24(0), size(first(bands)))
ncols = length(colors(p))
nbands = length(bands)
Expand Down
2 changes: 1 addition & 1 deletion src/outputs/output.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ many cases can be used interchangeably.
"""
abstract type Output{T} <: AbstractVector{T} end

"Generic ouput constructor. Converts init array to vector of frames."
# Generic ouput constructor. Converts init array to vector of frames.
(::Type{F})(init::AbstractMatrix; kwargs...) where F <: Output =
F(; frames=[deepcopy(init)], kwargs...)
(::Type{F})(init::NamedTuple; kwargs...) where F <: Output =
Expand Down
4 changes: 2 additions & 2 deletions src/outputs/repl.jl
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ simulation frames.
- `store::Bool`: store frames or not
- `color`: a color from Crayons.jl
- `cutoff::Real`: the cutoff point to display a full or empty cell. Default is `0.5`
- `style::CharStyle`: `Block()` or `Braile()` style printing. `Braile` uses 1/4 the screen space.
To choose the display type can pass `:braile` or `:block` to the constructor:
```julia
REPLOutput{:block}(init)
REPLOutput(init)
```
The default option is `:block`.
"""
Expand Down
2 changes: 1 addition & 1 deletion test/multi.jl
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ sim!(output, ruleset; init=init, tspan=(1, 20))

# Color processor runs
@Image @Graphic @Output mutable struct TestImageOutput{} <: ImageOutput{T} end
processor=DynamicGrids.ThreeColor(colors=(DynamicGrids.Blue(), DynamicGrids.Red()))
processor=DynamicGrids.ThreeColorProcessor(colors=(DynamicGrids.Blue(), DynamicGrids.Red()))
imageoutput = TestImageOutput(init; processor=processor, minval=(0, 0), maxval=(1000, 100), store=true)
DynamicGrids.showframe(::TestImageOutput, ::AbstractSimData, args...) = nothing
sim!(imageoutput, ruleset; init=init, tspan=(1, 20))
Expand Down

3 comments on commit d2041af

@rafaqz
Copy link
Member Author

@rafaqz rafaqz commented on d2041af Dec 16, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rafaqz
Copy link
Member Author

@rafaqz rafaqz commented on d2041af Dec 16, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JuliaRegistrator
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Registration pull request created: JuliaRegistries/General/6814

After the above pull request is merged, it is recommended that a tag is created on this repository for the registered package version.

This will be done automatically if Julia TagBot is installed, or can be done manually through the github interface, or via:

git tag -a v0.2.1 -m "<description of version>" d2041af359ab644150026ca8f3e9c050eb99f266
git push origin v0.2.1

Please sign in to comment.