dummy-link

MappedArrays

Lazy in-place transformations of arrays

Readme

MappedArrays

Build Status

codecov.io

This package implements "lazy" in-place elementwise transformations of arrays for the Julia programming language. Explicitly, it provides a "view" M of an array A so that M[i] = f(A[i]) for a specified (but arbitrary) function f, without ever having to compute M explicitly (in the sense of allocating storage for M). The name of the package comes from the fact that M == map(f, A).

Usage

julia> using MappedArrays

julia> a = [1,4,9,16]
4-element Array{Int64,1}:
  1
  4
  9
 16

julia> b = mappedarray(sqrt, a)
4-element MappedArrays.ReadonlyMappedArray{Float64,1,Array{Int64,1},Base.#sqrt}:
 1.0
 2.0
 3.0
 4.0

julia> b[3]
3.0

Note that you can't set values in the array:

julia> b[3] = 2
ERROR: indexed assignment not defined for MappedArrays.ReadonlyMappedArray{Float64,1,Array{Int64,1},Base.#sqrt}
 in setindex!(::MappedArrays.ReadonlyMappedArray{Float64,1,Array{Int64,1},Base.#sqrt}, ::Int64, ::Int64) at ./abstractarray.jl:781
 in eval(::Module, ::Any) at ./boot.jl:231
 in macro expansion at ./REPL.jl:92 [inlined]
 in (::Base.REPL.##1#2{Base.REPL.REPLBackend})() at ./event.jl:46

unless you also supply the inverse function, using mappedarray((f, finv), A):

julia> c = mappedarray((sqrt, x->x*x), a)
4-element MappedArrays.MappedArray{Float64,1,Array{Int64,1},Base.#sqrt,##1#2}:
 1.0
 2.0
 3.0
 4.0

julia> c[3]
3.0

julia> c[3] = 2
2

julia> a
4-element Array{Int64,1}:
  1
  4
  4
 16

Naturally, the "backing" array a has to be able to represent any value that you set:

julia> c[3] = 2.2
ERROR: InexactError()
 in setindex!(::MappedArrays.MappedArray{Float64,1,Array{Int64,1},Base.#sqrt,##1#2}, ::Float64, ::Int64) at /home/tim/.julia/v0.5/MappedArrays/src/MappedArrays.jl:27
 in eval(::Module, ::Any) at ./boot.jl:231
 in macro expansion at ./REPL.jl:92 [inlined]
 in (::Base.REPL.##1#2{Base.REPL.REPLBackend})() at ./event.jl:46

because 2.2^2 = 4.84 is not representable as an Int. In contrast,

julia> a = [1.0, 4.0, 9.0, 16.0]
4-element Array{Float64,1}:
  1.0
  4.0
  9.0
 16.0

julia> c = mappedarray((sqrt, x->x*x), a)
4-element MappedArrays.MappedArray{Float64,1,Array{Float64,1},Base.#sqrt,##3#4}:
 1.0
 2.0
 3.0
 4.0

julia> c[3] = 2.2
2.2

julia> a
4-element Array{Float64,1}:
  1.0
  4.0
  4.84
 16.0

works without trouble.

So far our examples have all been one-dimensional, but this package also supports arbitrary-dimensional arrays:

julia> a = randn(3,5,2)
3×5×2 Array{Float64,3}:
[:, :, 1] =
  1.47716    0.323915   0.448389  -0.56426   2.67922
 -0.255123  -0.752548  -0.41303    0.306604  1.5196
  0.154179   0.425001  -1.95575   -0.982299  0.145111

[:, :, 2] =
 -0.799232  -0.301813  -0.457817  -0.115742  -1.22948
 -0.486558  -1.27959   -1.59661    1.05867    2.06828
 -0.315976  -0.188828  -0.567672   0.405086   1.06983

julia> b = mappedarray(abs, a)
3×5×2 MappedArrays.ReadonlyMappedArray{Float64,3,Array{Float64,3},Base.#abs}:
[:, :, 1] =
 1.47716   0.323915  0.448389  0.56426   2.67922
 0.255123  0.752548  0.41303   0.306604  1.5196
 0.154179  0.425001  1.95575   0.982299  0.145111

[:, :, 2] =
 0.799232  0.301813  0.457817  0.115742  1.22948
 0.486558  1.27959   1.59661   1.05867   2.06828
 0.315976  0.188828  0.567672  0.405086  1.06983

of_eltype

This package defines a convenience method, of_eltype, which "lazily-converts" arrays to a specific eltype. (It works simply by defining convert functions for both f and finv.)

Using of_eltype you can "convert" a series of arrays to a chosen element type:

julia> arrays = (rand(2,2), rand(Int,2,2), [0x01 0x03; 0x02 0x04])
(
[0.541018 0.223392; 0.341264 0.022014],

[2437062103055434647 4726011606246170825; -4226911569217925847 -8715663020460318733],

UInt8[0x01 0x03; 0x02 0x04])

julia> arraysT = map(A->of_eltype(Float64, A), arrays)
(
[0.541018 0.223392; 0.341264 0.022014],

[2.43706e18 4.72601e18; -4.22691e18 -8.71566e18],

[1.0 3.0; 2.0 4.0])

This construct is inferrable (type-stable), so it can be a useful means to "coerce" arrays to a common type. This can sometimes solve type-stability problems without requiring that one copy the data.

First Commit

06/21/2016

Last Touched

9 days ago

Commits

37 commits

Requires: