Perceive
cax.core.perceive.perceive
Perceive base module.
Perceive
Bases: Module
Base class for perception modules.
Subclasses implement neighborhood gathering or convolutional transforms that map a
state to a perception. Perceptions are PyTrees — commonly arrays shaped
(..., *spatial_dims, perception_size), or a dataclass of arrays — and the type
parameter names which one a subclass produces, so the perceive-update handoff is
checked instead of erased.
Source code in src/cax/core/perceive/perceive.py
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | |
__call__(state)
Process the current state to produce a perception.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
state
|
State
|
Current state. |
required |
Returns:
| Type | Description |
|---|---|
Perception
|
Perception derived from |
Source code in src/cax/core/perceive/perceive.py
16 17 18 19 20 21 22 23 24 25 26 | |
cax.core.perceive.neighborhood_perceive
Neighborhood perceive base module.
This module provides the shared pad-and-slice implementation for neighborhood-based perception. Both Moore and Von Neumann perceive modules inherit from this base class, differing only in which neighbor shifts they enumerate.
NeighborhoodPerceive
Bases: Perceive[Array, Array]
Base class for neighborhood-based perception using pad-and-slice.
Subclasses implement _get_shifts to define which neighbor offsets belong to the
neighborhood. This class handles padding, slicing, and optional reduction over
neighbors.
Source code in src/cax/core/perceive/neighborhood_perceive.py
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 | |
__init__(*, num_spatial_dims, radius, padding='CIRCULAR', include_center=True, reduce_fn=None)
Initialize neighborhood perceive.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
num_spatial_dims
|
int
|
Number of spatial dimensions. |
required |
radius
|
int
|
Neighborhood radius. |
required |
padding
|
str
|
Boundary condition mode. One of "CIRCULAR" (periodic/torus), "ZERO" (zero-padded), "REFLECT" (mirror), or "EDGE" (clamp to boundary). |
'CIRCULAR'
|
include_center
|
bool
|
Whether to include the center cell in the output. |
True
|
reduce_fn
|
Callable[..., Array] | None
|
Optional reduction function applied over the neighbor axis. If
None, neighbors are concatenated along the channel axis. If provided, it
is called as |
None
|
Source code in src/cax/core/perceive/neighborhood_perceive.py
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | |
__call__(state)
Apply neighborhood perception to the input state.
The input is assumed to have shape (..., *spatial_dims, channel_size).
When reduce_fn is None, neighbors are concatenated along the channel axis:
- With include_center=True: shape
(..., *spatial, channel_size * (N + 1))
- With include_center=False: shape (..., *spatial, channel_size * N)
where N is the number of neighbor shifts.
When reduce_fn is provided, neighbors are stacked and reduced:
- With include_center=True: shape (..., *spatial, 2 * channel_size)
- With include_center=False: shape (..., *spatial, channel_size)
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
state
|
Array
|
State of the cellular automaton. |
required |
Returns:
| Type | Description |
|---|---|
Array
|
Neighborhood perception. |
Source code in src/cax/core/perceive/neighborhood_perceive.py
77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 | |
cax.core.perceive.moore_perceive
Moore perceive module.
MoorePerceive
Bases: NeighborhoodPerceive
Moore perceive class.
This class implements perception based on the Moore neighborhood.
The Moore neighborhood includes all cells within Chebyshev distance radius of the
central cell — i.e., the full hypercube of side length 2 * radius + 1 excluding
the center.
Source code in src/cax/core/perceive/moore_perceive.py
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | |
__init__(*, num_spatial_dims, radius, padding='CIRCULAR', include_center=True, reduce_fn=None)
Initialize Moore perceive.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
num_spatial_dims
|
int
|
Number of spatial dimensions. |
required |
radius
|
int
|
Chebyshev distance defining the Moore neighborhood extent. |
required |
padding
|
str
|
Boundary condition mode. One of "CIRCULAR" (periodic/torus), "ZERO" (zero-padded), "REFLECT" (mirror), or "EDGE" (clamp to boundary). |
'CIRCULAR'
|
include_center
|
bool
|
Whether to include the center cell in the output. |
True
|
reduce_fn
|
Callable[..., Array] | None
|
Optional reduction function applied over the neighbor axis. If
None, neighbors are concatenated along the channel axis. If provided, it
is called as |
None
|
Source code in src/cax/core/perceive/moore_perceive.py
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | |
__call__(state)
Apply neighborhood perception to the input state.
The input is assumed to have shape (..., *spatial_dims, channel_size).
When reduce_fn is None, neighbors are concatenated along the channel axis:
- With include_center=True: shape
(..., *spatial, channel_size * (N + 1))
- With include_center=False: shape (..., *spatial, channel_size * N)
where N is the number of neighbor shifts.
When reduce_fn is provided, neighbors are stacked and reduced:
- With include_center=True: shape (..., *spatial, 2 * channel_size)
- With include_center=False: shape (..., *spatial, channel_size)
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
state
|
Array
|
State of the cellular automaton. |
required |
Returns:
| Type | Description |
|---|---|
Array
|
Neighborhood perception. |
Source code in src/cax/core/perceive/neighborhood_perceive.py
77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 | |
cax.core.perceive.von_neumann_perceive
Von Neumann perceive module.
VonNeumannPerceive
Bases: NeighborhoodPerceive
Von Neumann perceive class.
This class implements perception based on the Von Neumann neighborhood.
The Von Neumann neighborhood includes all cells within Manhattan distance radius
of the central cell.
Source code in src/cax/core/perceive/von_neumann_perceive.py
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | |
__init__(*, num_spatial_dims, radius, padding='CIRCULAR', include_center=True, reduce_fn=None)
Initialize Von Neumann perceive.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
num_spatial_dims
|
int
|
Number of spatial dimensions. |
required |
radius
|
int
|
Manhattan distance defining the Von Neumann neighborhood extent. |
required |
padding
|
str
|
Boundary condition mode. One of "CIRCULAR" (periodic/torus), "ZERO" (zero-padded), "REFLECT" (mirror), or "EDGE" (clamp to boundary). |
'CIRCULAR'
|
include_center
|
bool
|
Whether to include the center cell in the output. |
True
|
reduce_fn
|
Callable[..., Array] | None
|
Optional reduction function applied over the neighbor axis. If
None, neighbors are concatenated along the channel axis. If provided, it
is called as |
None
|
Source code in src/cax/core/perceive/von_neumann_perceive.py
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | |
__call__(state)
Apply neighborhood perception to the input state.
The input is assumed to have shape (..., *spatial_dims, channel_size).
When reduce_fn is None, neighbors are concatenated along the channel axis:
- With include_center=True: shape
(..., *spatial, channel_size * (N + 1))
- With include_center=False: shape (..., *spatial, channel_size * N)
where N is the number of neighbor shifts.
When reduce_fn is provided, neighbors are stacked and reduced:
- With include_center=True: shape (..., *spatial, 2 * channel_size)
- With include_center=False: shape (..., *spatial, channel_size)
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
state
|
Array
|
State of the cellular automaton. |
required |
Returns:
| Type | Description |
|---|---|
Array
|
Neighborhood perception. |
Source code in src/cax/core/perceive/neighborhood_perceive.py
77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 | |
cax.core.perceive.conv_perceive
Convolution perceive module.
ConvPerceive
Bases: Perceive[Array, Array]
Convolution perceive class.
Source code in src/cax/core/perceive/conv_perceive.py
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | |
__init__(*, channel_size, perception_size, kernel_size=(3, 3), padding='SAME', feature_group_count=1, use_bias=False, activation_fn=None, rngs)
Initialize convolution perceive.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
channel_size
|
int
|
Number of input channels. |
required |
perception_size
|
int
|
Number of output perception features. |
required |
kernel_size
|
int | tuple[int, ...]
|
Size of the convolutional kernel. |
(3, 3)
|
padding
|
str
|
Padding to use. |
'SAME'
|
feature_group_count
|
int
|
Number of feature groups. |
1
|
use_bias
|
bool
|
Whether to use bias in convolutional layers. |
False
|
activation_fn
|
Callable[[Array], Array] | None
|
Activation function to use. |
None
|
rngs
|
Rngs
|
rng key. |
required |
Source code in src/cax/core/perceive/conv_perceive.py
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | |
__call__(state)
Apply convolutional perception to the input state.
Inputs are expected to have shape (..., *spatial_dims, channel_size) where
spatial_dims is a tuple of num_spatial_dims dimensions and channel_size is
the number of channels. The output shape is
(..., *spatial_dims, perception_size). If activation_fn is provided, it is
applied element-wise to the convolution output. If activation_fn is None,
the convolution output is returned as is.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
state
|
Array
|
State of the cellular automaton. |
required |
Returns:
| Type | Description |
|---|---|
Array
|
The perceived state after applying convolutional layers. |
Source code in src/cax/core/perceive/conv_perceive.py
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | |
cax.core.perceive.kernels
Kernel utilities for perception modules.
Each function returns a small spatial kernel suitable for neighborhood aggregation or finite-difference style operations. Kernels use channel-last layout and a support of size 3 along each spatial dimension.
grad2_kernel takes a neighborhood, naming which of the surrounding cells contribute:
"von_neumann"--- the cells sharing a face, two per axis."moore"--- every cell in the surrounding block, diagonals included."hexagonal"--- a triangular lattice stored in a square array, whose axes are read as the basis vectors(1, 0)and(1/2, sqrt(3)/2)rather than as a Cartesian frame. Two opposite corners of the block are then not adjacent, leaving six neighbors that are all exactly one unit away. Two dimensions only.
HEX_BASIS = jnp.array([[1.0, 0.0], [0.5, math.sqrt(3.0) / 2.0]])
module-attribute
Rows are the lattice vectors a triangular lattice's array axes stand for.
identity_kernel(*, num_dims)
Create an identity kernel for the given number of dimensions.
The kernel has value 1 at the central position and 0 elsewhere.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
num_dims
|
int
|
Number of dimensions for the kernel. |
required |
Returns:
| Type | Description |
|---|---|
Array
|
Array with shape |
Source code in src/cax/core/perceive/kernels.py
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 | |
neighbors_kernel(*, num_dims)
Create a neighbors kernel for the given number of dimensions.
This kernel is 1 - identity_kernel, selecting all neighbors and excluding the
center.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
num_dims
|
int
|
Number of dimensions for the kernel. |
required |
Returns:
| Type | Description |
|---|---|
Array
|
Array with shape |
Source code in src/cax/core/perceive/kernels.py
88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 | |
grad_kernel(*, num_dims, normalize=True)
Create a gradient kernel for the given number of dimensions.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
num_dims
|
int
|
Number of dimensions for the kernel. |
required |
normalize
|
bool
|
Whether to L1-normalize each axis kernel. |
True
|
Returns:
| Type | Description |
|---|---|
Array
|
Array with shape |
Source code in src/cax/core/perceive/kernels.py
105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 | |
grad2_kernel(*, num_dims, neighborhood='von_neumann', normalize=True)
Create a second-order (Laplacian) kernel.
Each neighbor is weighted by the inverse square of its distance from the center, and the center takes whatever makes the kernel sum to zero, so that it annihilates a constant field.
The neighborhood decides how isotropic the result is. "von_neumann" is the
cheapest stencil, but its leading error favors the grid axes with four-fold symmetry
--- a bias a system asked to behave the same in every direction will find and use.
"moore" brings in the diagonals, which is the familiar
[[1, 2, 1], [2, -12, 2], [1, 2, 1]] up to the scale normalize removes; on a
quartic rotated by 45 degrees the von Neumann answer moves by 50% and this one by
20%.
"hexagonal" removes the question. Its six neighbors are all one unit away, so they
are weighted equally and no direction is singled out at all. Note that an array read
as a triangular lattice also has to be drawn as one --- see
cax.utils.hex_to_square.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
num_dims
|
int
|
Number of dimensions for the kernel. |
required |
neighborhood
|
Neighborhood
|
Which surrounding cells contribute. |
'von_neumann'
|
normalize
|
bool
|
Whether to L1-normalize the kernel. |
True
|
Returns:
| Type | Description |
|---|---|
Array
|
Array with shape |
Raises:
| Type | Description |
|---|---|
ValueError
|
If the neighborhood is unknown, or is hexagonal in other than two dimensions. |
Source code in src/cax/core/perceive/kernels.py
137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 | |