Skip to content

JuliaArrays/FillArrays.jl

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

FillArrays.jl

Stable Dev Build Status codecov deps version pkgeval Aqua

Julia package to lazily represent matrices filled with a single entry, as well as identity matrices. This package exports the following types: Eye, Fill, Ones, Zeros, Trues, Falses, and OneElement.

The primary purpose of this package is to present a unified way of constructing matrices. For example, to construct a 5-by-5 BandedMatrix of all zeros with bandwidths (1,2), one would use

julia> BandedMatrix(Zeros(5,5), (1, 2))

Usage

Here are the matrix types:

julia> Zeros(5, 6)
5×6 Zeros{Float64}

julia> Zeros{Int}(2, 3)
2×3 Zeros{Int64}

julia> Zeros(Int, 2, 3) # can also specify the type as an argument
2×3 Zeros{Int64}

julia> Ones{Int}(5)
5-element Ones{Int64}

julia> Eye{Int}(5)
 5×5 Diagonal{Int64,Ones{Int64,1,Tuple{Base.OneTo{Int64}}}}:
  1        
    1      
      1    
        1  
          1

julia> Fill(7.0f0, 3, 2)
3×2 Fill{Float32}: entries equal to 7.0

julia> Trues(2, 3)
2×3 Ones{Bool}

julia> Falses(2)
2-element Zeros{Bool}

julia> OneElement(3.0, (2,1), (5,6))
5×6 OneElement{Float64, 2, Tuple{Int64, Int64}, Tuple{Base.OneTo{Int64}, Base.OneTo{Int64}}}:
                       
 3.0                    
                       
                       
                       

They support conversion to other matrix types like Array, SparseVector, SparseMatrix, and Diagonal:

julia> Matrix(Zeros(5, 5))
5×5 Array{Float64,2}:
 0.0  0.0  0.0  0.0  0.0
 0.0  0.0  0.0  0.0  0.0
 0.0  0.0  0.0  0.0  0.0
 0.0  0.0  0.0  0.0  0.0
 0.0  0.0  0.0  0.0  0.0

julia> SparseMatrixCSC(Zeros(5, 5))
5×5 SparseMatrixCSC{Float64,Int64} with 0 stored entries

julia> Array(Fill(7, (2,3)))
2×3 Array{Int64,2}:
 7  7  7
 7  7  7

There is also support for offset index ranges, and the type includes the axes:

julia> Ones((-3:2, 1:2))
6×2 Ones{Float64,2,Tuple{UnitRange{Int64},UnitRange{Int64}}} with indices -3:2×1:2

julia> Fill(7, ((0:2), (-1:0)))
3×2 Fill{Int64,2,Tuple{UnitRange{Int64},UnitRange{Int64}}} with indices 0:2×-1:0: entries equal to 7

julia> typeof(Zeros(5,6))
Zeros{Float64,2,Tuple{Base.OneTo{Int64},Base.OneTo{Int64}}}

These types have methods that perform many operations efficiently, including elementary algebra operations like multiplication and addition, as well as linear algebra methods like norm, adjoint, transpose and vec.

Warning!

Broadcasting operations and map, mapreduce are also done efficiently, by evaluating the function being applied only once:

julia> map(sqrt, Fill(4, 2,5))  # one evaluation, not 10, to save time
2×5 Fill{Float64}: entries equal to 2.0

julia> println.(Fill(pi, 10))
π
10-element Fill{Nothing}: entries equal to nothing

Notice that this will only match the behaviour of a dense matrix from fill if the function is pure. And that this shortcut is taken before any other fused broadcast:

julia> map(_ -> rand(), Fill("pi", 2,5))  # not a pure function!
2×5 Fill{Float64}: entries equal to 0.7201617100284206

julia> map(_ -> rand(), fill("4", 2,5))  # 10 evaluations, different answer!
2×5 Matrix{Float64}:
 0.43675   0.270809  0.56536   0.0948089  0.24655
 0.959363  0.79598   0.238662  0.401909   0.317716

julia> ones(1,5) .+ (_ -> rand()).(Fill("vec", 2))  # Fill broadcast is done first
2×5 Matrix{Float64}:
 1.51796  1.51796  1.51796  1.51796  1.51796
 1.51796  1.51796  1.51796  1.51796  1.51796

julia> ones(1,5) .+ (_ -> rand()).(fill("vec", 2))  # fused, 10 evaluations
2×5 Matrix{Float64}:
 1.51337  1.17578  1.19815  1.43035  1.2987
 1.30253  1.21909  1.61755  1.02645  1.77681