# Structured arrays for Julia

`StructuredArrays`

is a small Julia package which provides
multi-dimensional arrays behaving like regular arrays but whose elements have
the same given value or are computed by applying a given function to their
indices. The main advantage of such arrays is that they are very light in terms
of memory: their storage requirement is `O(1)`

whatever their size instead of
`O(n)`

for a usual array of `n`

elements.

Note that `StructuredArrays`

has a different purpose than
`StructArrays`

which is
designed for arrays whose elements are `struct`

.

## Uniform arrays

All elements of a uniform array have the same value. To build such an array, call:

`A = UniformArray(val, dims)`

which yields an array `A`

behaving as a read-only array of size `dims`

whose
values are all `val`

. The array dimensions may be specified as multiple
arguments.

Uniform arrays implement conventional linear indexing: `A[i]`

yields `val`

for
all linear indices `i`

in the range `1:length(A)`

.

Statements like `A[i] = val`

are however not implemented because uniform arrays
are considered as read-only. You may call `MutableUniformArray(val,dims)`

to
create a uniform array, say `B`

, whose element value can be changed:

`B = MutableUniformArray(val, dims)`

A statement like `B[i] = val`

is allowed to change the value of all the
elements of `B`

provided index `i`

represents all possible indices in `B`

.
Typically `B[:] = val`

or `B[1:end] = val`

are accepted but not `B[1] = val`

unless `B`

has a single element.

Apart from all values being the same, uniform arrays should behaves like ordinary Julia arrays.

## Fast uniform arrays

A fast uniform array is like an immutable uniform array but with the elements value being part of the signature so that this value is known at compile time. To build such an array, call:

`A = FastUniformArray(val, dims)`

## Structured arrays

The values of the elements of a structured array are computed on the fly as a function of their indices. To build such an array, call:

`A = StructuredArray(func, dims)`

which yields an array `A`

behaving as a read-only array of size `dims`

whose
entries are computed as a given function, here `func`

, of its indices: `A[i]`

yields `func(i)`

. The array dimensions may be specified as multiple arguments.

An optional leading argument `S`

may be used to specify another index style
than the default `IndexCartesian`

:

`A = StructuredArray(S, func, dims)`

where `S`

may be a sub-type of `IndexStyle`

or an instance of such a sub-type.
If `S`

is `IndexCartesian`

(the default), the function `func`

will be called
with `N`

integer arguments, `N`

being the number of dimensions. If `S`

is
`IndexLinear`

, the function `func`

will be called with a single integer
argument.

A structured array can be used to specify the location of structural non-zeros
in a sparse matrix. For instance, the structure of a lower triangular matrix of
size `m×n`

would be given by:

`StructuredArray((i,j) -> (i ≥ j), m, n)`

but with a constant small storage requirement whatever the size of the matrix.

Although the callable object `func`

may not be a *pure function*, its return
type shall be stable and structured arrays are considered as immutable in the
sense that a statement like `A[i] = val`

is not implemented. The type of the
elements of structured array is guessed by applying `func`

to the unit index.
The element type, say `T`

, may also be explicitely specified:

`StructuredArray{T}([S = IndexCartesian,] func, dims)`