Skip to content
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,27 +32,25 @@ jobs:
test:
needs: pre_job
if: needs.pre_job.outputs.should_skip != 'true'
name: Julia ${{ matrix.version }} - ${{ matrix.os }} - ${{ matrix.arch }} - ${{ github.event_name }}
name: Julia ${{ matrix.version }} - ${{ matrix.os }} - ${{ github.event_name }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
version:
- 'min'
- 'lts'
- '1'
- 'pre'
os:
- ubuntu-latest
- macOS-latest
- windows-latest
arch:
- x64
steps:
- uses: actions/checkout@v4
- uses: julia-actions/setup-julia@v2
with:
version: ${{ matrix.version }}
arch: ${{ matrix.arch }}
- uses: julia-actions/cache@v2
- uses: julia-actions/julia-buildpkg@v1
- uses: julia-actions/julia-runtest@v1
Expand Down
17 changes: 7 additions & 10 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
name = "FillArrays"
uuid = "1a297f60-69ca-5386-bcde-b61e274b549b"
version = "1.14.0"
version = "1.15.0"

[deps]
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
PDMats = "90014a1f-27ba-587c-ab20-58faa44d9150"
SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"
Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"

[weakdeps]
PDMats = "90014a1f-27ba-587c-ab20-58faa44d9150"
Expand All @@ -22,16 +19,16 @@ FillArraysStatisticsExt = "Statistics"
Aqua = "0.8"
Documenter = "1"
Infinities = "0.1"
LinearAlgebra = "1.6"
LinearAlgebra = "1"
PDMats = "0.11.17"
Quaternions = "0.7"
Random = "1.6"
Random = "1"
ReverseDiff = "1"
SparseArrays = "1.6"
SparseArrays = "1"
StaticArrays = "1"
Statistics = "1.6"
Test = "1.6"
julia = "1.6"
Statistics = "1"
Test = "1"
julia = "1.10"

[extras]
Aqua = "4c88cf16-eb10-579e-8560-4a9242c79595"
Expand Down
7 changes: 1 addition & 6 deletions ext/FillArraysSparseArraysExt.jl
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,6 @@ end
@deprecate kron(E1::RectDiagonalFill, E2::RectDiagonalFill) kron(sparse(E1), sparse(E2))

# Ambiguity. see #178
if VERSION >= v"1.8"
dot(x::AbstractFillVector, y::SparseVectorUnion) = _fill_dot(x, y)
else
dot(x::AbstractFillVector{<:Number}, y::SparseVectorUnion{<:Number}) = _fill_dot(x, y)
end

dot(x::AbstractFillVector, y::SparseVectorUnion) = _fill_dot(x, y)

end # module
55 changes: 15 additions & 40 deletions src/FillArrays.jl
Original file line number Diff line number Diff line change
Expand Up @@ -48,18 +48,18 @@ Base.@propagate_inbounds getindex(F::AbstractFill{T, N}, kj::Vararg{Integer, N})

@inline function setindex!(F::AbstractFill, v, k::Integer)
@boundscheck checkbounds(F, k)
v == getindex_value(F) || throw(ArgumentError("Cannot setindex! to $v for an AbstractFill with value $(getindex_value(F))."))
v == getindex_value(F) || throw(ArgumentError(LazyString("Cannot setindex! to ", v, " for an AbstractFill with value ", getindex_value(F), ".")))
F
end

@inline function setindex!(F::AbstractFill{T, N}, v, kj::Vararg{Integer, N}) where {T, N}
@boundscheck checkbounds(F, kj...)
v == getindex_value(F) || throw(ArgumentError("Cannot setindex! to $v for an AbstractFill with value $(getindex_value(F))."))
v == getindex_value(F) || throw(ArgumentError(LazyString("Cannot setindex! to ", v, " for an AbstractFill with value ", getindex_value(F), ".")))
F
end

@inline function fill!(F::AbstractFill, v)
v == getindex_value(F) || throw(ArgumentError("Cannot fill! with $v an AbstractFill with value $(getindex_value(F))."))
v == getindex_value(F) || throw(ArgumentError(LazyString("Cannot fill! with ", v, " an AbstractFill with value ", getindex_value(F), ".")))
F
end

Expand All @@ -72,18 +72,10 @@ ishermitian(F::AbstractFillMatrix) = axes(F,1) == axes(F,2) && (isempty(F) || is
Base.IteratorSize(::Type{<:AbstractFill{T,N,Axes}}) where {T,N,Axes} = _IteratorSize(Axes)
_IteratorSize(::Type{Tuple{}}) = Base.HasShape{0}()
_IteratorSize(::Type{Tuple{T}}) where {T} = Base.IteratorSize(T)
# Julia Base has an optimized any for Tuples on versions >= v1.9
# On lower versions, a recursive implementation helps with type-inference
if VERSION >= v"1.9.0-beta3"
_any(f, t::Tuple) = any(f, t)
else
_any(f, ::Tuple{}) = false
_any(f, t::Tuple) = f(t[1]) || _any(f, Base.tail(t))
end
function _IteratorSize(::Type{T}) where {T<:Tuple}
N = fieldcount(T)
s = ntuple(i-> Base.IteratorSize(fieldtype(T, i)), N)
_any(x -> x isa Base.IsInfinite, s) ? Base.IsInfinite() : Base.HasShape{N}()
any(x -> x isa Base.IsInfinite, s) ? Base.IsInfinite() : Base.HasShape{N}()
end


Expand Down Expand Up @@ -190,7 +182,7 @@ function unique_value(arr::AbstractArray)
val = first(arr)
for x in arr
if x !== val
error("Input array contains both $x and $val. Cannot convert to Fill")
error(LazyString("Input array contains both ", x, " and ", val, ". Cannot convert to Fill"))
end
end
return val
Expand Down Expand Up @@ -263,12 +255,9 @@ end

svdvals!(a::AbstractFillMatrix) = [getindex_value(a)*sqrt(prod(size(a))); Zeros(min(size(a)...)-1)]

@noinline function _throw_dmrs(n, str, dims)
throw(DimensionMismatch("parent has $n elements, which is incompatible with $str $dims"))
end
function fill_reshape(parent, dims::Integer...)
n = length(parent)
prod(dims) == n || _throw_dmrs(n, "size", dims)
prod(dims) == n || throw(DimensionMismatch(LazyString("parent has ", n, " elements, which is incompatible with ", str, " ", dims)))
fillsimilar(parent, dims...)
end

Expand Down Expand Up @@ -347,10 +336,10 @@ for (AbsTyp, Typ, funcs, func) in ((:AbstractZeros, :Zeros, :zeros, :zero), (:Ab
convert(::Type{$Typ{T,N}}, A::$AbsTyp{V,N,Axes}) where {T,V,N,Axes} = convert($Typ{T,N,Axes}, A)
convert(::Type{$Typ{T}}, A::$AbsTyp{V,N,Axes}) where {T,V,N,Axes} = convert($Typ{T,N,Axes}, A)
function convert(::Type{Typ}, A::AbstractFill{V,N}) where {T,V,N,Axes,Typ<:$AbsTyp{T,N,Axes}}
axes(A) isa Axes || throw(ArgumentError("cannot convert, as axes of array are not $Axes"))
axes(A) isa Axes || throw(ArgumentError(LazyString("cannot convert, as axes of array are not ", Axes)))
val = getindex_value(A)
y = convert(T, val)
y == $func(T) || throw(ArgumentError(string("cannot convert an array containinig $val to ", $Typ)))
y == $func(T) || throw(ArgumentError(LazyString("cannot convert an array containinig ", val, " to ", Typ)))
Typ(axes(A))
end
function convert(::Type{$Typ{T,N}}, A::AbstractFill{<:Any,N}) where {T,N}
Expand Down Expand Up @@ -389,7 +378,7 @@ fillsimilar(a::AbstractFill, axes...) = Fill(getindex_value(a), axes...)
# functions
function Base.sqrt(a::AbstractFillMatrix{<:Union{Real, Complex}})
Base.require_one_based_indexing(a)
size(a,1) == size(a,2) || throw(DimensionMismatch("matrix is not square: dimensions are $(size(a))"))
size(a,1) == size(a,2) || throw(DimensionMismatch(LazyString("matrix is not square: dimensions are ", size(a))))
_sqrt(a)
end
_sqrt(a::AbstractZerosMatrix) = float(a)
Expand All @@ -401,7 +390,7 @@ function _sqrt(a::AbstractFillMatrix)
end
function Base.cbrt(a::AbstractFillMatrix{<:Real})
Base.require_one_based_indexing(a)
size(a,1) == size(a,2) || throw(DimensionMismatch("matrix is not square: dimensions are $(size(a))"))
size(a,1) == size(a,2) || throw(DimensionMismatch(LazyString("matrix is not square: dimensions are ", size(a))))
_cbrt(a)
end
_cbrt(a::AbstractZerosMatrix) = float(a)
Expand Down Expand Up @@ -460,7 +449,7 @@ function setindex!(rd::RectDiagonal, v, i::Integer, j::Integer)
if i == j
@inbounds rd.diag[i] = v
elseif !iszero(v)
throw(ArgumentError("cannot set off-diagonal entry ($i, $j) to a nonzero value ($v)"))
throw(ArgumentError(LazyString("cannot set off-diagonal entry (", i, ", ", j, ") to a nonzero value (", v, ")")))
end
return v
end
Expand Down Expand Up @@ -738,12 +727,6 @@ include("fillalgebra.jl")
include("fillbroadcast.jl")
include("trues.jl")

if !isdefined(Base, :get_extension)
include("../ext/FillArraysPDMatsExt.jl")
include("../ext/FillArraysSparseArraysExt.jl")
include("../ext/FillArraysStatisticsExt.jl")
end

##
# print
##
Expand All @@ -752,15 +735,9 @@ Base.replace_in_print_matrix(::AbstractZeros, ::Integer, ::Integer, s::AbstractS

# following support blocked fill array printing via
# BlockArrays.jl
if VERSION < v"1.8-"
axes_print_matrix_row(lay, io, X, A, i, cols, sep) =
Base.invoke(Base.print_matrix_row, Tuple{IO,AbstractVecOrMat,Vector,Integer,AbstractVector,AbstractString},
io, X, A, i, cols, sep)
else
axes_print_matrix_row(lay, io, X, A, i, cols, sep, idxlast::Integer=last(axes(X, 2))) =
Base.invoke(Base.print_matrix_row, Tuple{IO,AbstractVecOrMat,Vector,Integer,AbstractVector,AbstractString,Integer},
axes_print_matrix_row(lay, io, X, A, i, cols, sep, idxlast::Integer=last(axes(X, 2))) =
Base.invoke(Base.print_matrix_row, Tuple{IO,AbstractVecOrMat,Vector,Integer,AbstractVector,AbstractString,Integer},
io, X, A, i, cols, sep, idxlast)
end

Base.print_matrix_row(io::IO,
X::Union{AbstractFillVector,
Expand Down Expand Up @@ -871,11 +848,9 @@ end
function _repeat(A; inner=ntuple(x->1, ndims(A)), outer=ntuple(x->1, ndims(A)))
Base.require_one_based_indexing(A)
length(inner) >= ndims(A) ||
throw(ArgumentError("number of inner repetitions $(length(inner)) cannot be "*
"less than number of dimensions of input array $(ndims(A))"))
throw(ArgumentError(LazyString("number of inner repetitions ", length(inner), " cannot be less than number of dimensions of input array ", ndims(A))))
length(outer) >= ndims(A) ||
throw(ArgumentError("number of outer repetitions $(length(outer)) cannot be "*
"less than number of dimensions of input array $(ndims(A))"))
throw(ArgumentError(LazyString("number of outer repetitions ", length(outer), " cannot be less than number of dimensions of input array ", ndims(A))))
sz = _repeat_size(size(A), Tuple(inner), Tuple(outer))
fillsimilar(A, sz)
end
Expand Down
42 changes: 21 additions & 21 deletions src/fillalgebra.jl
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ end
function mult_axes(a, b)
Base.require_one_based_indexing(a, b)
size(a, 2) ≠ size(b, 1) &&
throw(DimensionMismatch("A has dimensions $(size(a)) but B has dimensions $(size(b))"))
throw(DimensionMismatch(LazyString("A has dimensions ", size(a), " but B has dimensions ", size(b))))
return (axes(a, 1), axes(b)[2:end]...)
end

Expand Down Expand Up @@ -115,11 +115,11 @@ function *(F::AbstractFillMatrix, v::AbstractVector)
end

function lmul_diag(a::Diagonal, b)
size(a,2) == size(b,1) || throw(DimensionMismatch("A has dimensions $(size(a)) but B has dimensions $(size(b))"))
size(a,2) == size(b,1) || throw(DimensionMismatch(LazyString("A has dimensions ", size(a), " but B has dimensions ", size(b))))
parent(a) .* b # use special broadcast
end
function rmul_diag(a, b::Diagonal)
size(a,2) == size(b,1) || throw(DimensionMismatch("A has dimensions $(size(a)) but B has dimensions $(size(b))"))
size(a,2) == size(b,1) || throw(DimensionMismatch(LazyString("A has dimensions ", size(a), " but B has dimensions ", size(b))))
a .* permutedims(parent(b)) # use special broadcast
end

Expand All @@ -132,26 +132,26 @@ end
@noinline function check_matmul_sizes(A::AbstractMatrix, x::AbstractVector)
Base.require_one_based_indexing(A, x)
size(A,2) == size(x,1) ||
throw(DimensionMismatch("second dimension of A, $(size(A,2)) does not match length of x $(length(x))"))
throw(DimensionMismatch(LazyString("second dimension of A, ", size(A,2), ", does not match length of x, ", length(x))))
end
@noinline function check_matmul_sizes(A::AbstractMatrix, B::AbstractMatrix)
Base.require_one_based_indexing(A, B)
size(A,2) == size(B,1) ||
throw(DimensionMismatch("second dimension of A, $(size(A,2)) does not match first dimension of B, $(size(B,1))"))
throw(DimensionMismatch(LazyString("second dimension of A, ", size(A,2), ", does not match first dimension of B, ", size(B,1))))
end
@noinline function check_matmul_sizes(y::AbstractVector, A::AbstractMatrix, x::AbstractVector)
Base.require_one_based_indexing(A, x, y)
size(A,2) == size(x,1) ||
throw(DimensionMismatch("second dimension of A, $(size(A,2)) does not match length of x $(length(x))"))
throw(DimensionMismatch(LazyString("second dimension of A, ", size(A,2), ", does not match length of x, ", length(x))))
size(y,1) == size(A,1) ||
throw(DimensionMismatch("first dimension of A, $(size(A,1)) does not match length of y $(length(y))"))
throw(DimensionMismatch(LazyString("first dimension of A, ", size(A,1), ", does not match length of y, ", length(y))))
end
@noinline function check_matmul_sizes(C::AbstractMatrix, A::AbstractMatrix, B::AbstractMatrix)
Base.require_one_based_indexing(A, B, C)
size(A,2) == size(B,1) ||
throw(DimensionMismatch("second dimension of A, $(size(A,2)) does not match first dimension of B, $(size(B,1))"))
throw(DimensionMismatch(LazyString("second dimension of A, ", size(A,2), ", does not match first dimension of B, ", size(B,1))))
size(C,1) == size(A,1) && size(C,2) == size(B,2) ||
throw(DimensionMismatch("A has size $(size(A)), B has size $(size(B)), C has size $(size(C))"))
throw(DimensionMismatch(LazyString("A has size ", size(A), ", B has size ", size(B), ", C has size ", size(C))))
end

function mul!(y::AbstractVector, A::AbstractFillMatrix, b::AbstractFillVector, alpha::Number, beta::Number)
Expand Down Expand Up @@ -314,7 +314,7 @@ end
function _adjvec_mul_zeros(a, b)
la, lb = length(a), length(b)
if la ≠ lb
throw(DimensionMismatch("dot product arguments have lengths $la and $lb"))
throw(DimensionMismatch(LazyString("dot product arguments have lengths ", la, " and ", lb)))
end
# ensure that all the elements of `a` are of the same size,
# so that ∑ᵢaᵢbᵢ = b₁∑ᵢaᵢ makes sense
Expand All @@ -324,7 +324,7 @@ function _adjvec_mul_zeros(a, b)
end
a1 = a[1]
sza1 = size(a1)
all(x -> size(x) == sza1, a) || throw(DimensionMismatch("not all elements of A are of size $sza1"))
all(x -> size(x) == sza1, a) || throw(DimensionMismatch(LazyString("not all elements of A are of size ", sza1)))
# we replace b₁∑ᵢaᵢ by b₁a₁, as we know that b₁ is zero.
# Each term in the summation is zero, so the sum is equal to the first term
return a1 * b[1]
Expand Down Expand Up @@ -365,7 +365,7 @@ end
*(a::TransposeAbsVec{<:Any,<:AbstractZerosVector}, D::Diagonal) = transpose(D*transpose(a))
function _triple_zeromul(x, D::Diagonal, y)
if !(length(x) == length(D.diag) == length(y))
throw(DimensionMismatch("x has length $(length(x)), D has size $(size(D)), and y has $(length(y))"))
throw(DimensionMismatch(LazyString("x has length ", length(x), ", D has size ", size(D), ", and y has ", length(y))))
end
zero(promote_type(eltype(x), eltype(D), eltype(y)))
end
Expand All @@ -381,7 +381,7 @@ end
function *(a::Transpose{T, <:AbstractVector}, b::AbstractZerosVector{T}) where T<:Real
la, lb = length(a), length(b)
if la ≠ lb
throw(DimensionMismatch("dot product arguments have lengths $la and $lb"))
throw(DimensionMismatch(LazyString("dot product arguments have lengths ", la, " and ", lb)))
end
return zero(T)
end
Expand All @@ -391,12 +391,12 @@ end
# infinite cases should be supported in InfiniteArrays.jl
# type issues of Bool dot are ignored at present.
function _fill_dot(a::AbstractFillVector{T}, b::AbstractVector{V}) where {T,V}
axes(a) == axes(b) || throw(DimensionMismatch("dot product arguments have lengths $(length(a)) and $(length(b))"))
axes(a) == axes(b) || throw(DimensionMismatch(LazyString("dot product arguments have lengths ", length(a), " and ", length(b))))
dot(getindex_value(a), sum(b))
end

function _fill_dot_rev(a::AbstractVector{T}, b::AbstractFillVector{V}) where {T,V}
axes(a) == axes(b) || throw(DimensionMismatch("dot product arguments have lengths $(length(a)) and $(length(b))"))
axes(a) == axes(b) || throw(DimensionMismatch(LazyString("dot product arguments have lengths ", length(a), " and ", length(b))))
dot(sum(a), getindex_value(b))
end

Expand All @@ -406,21 +406,21 @@ dot(a::AbstractVector, b::AbstractFillVector) = _fill_dot_rev(a, b)

function dot(u::AbstractVector, E::Eye, v::AbstractVector)
length(u) == size(E,1) && length(v) == size(E,2) ||
throw(DimensionMismatch("dot product arguments have dimensions $(length(u))×$(size(E))×$(length(v))"))
throw(DimensionMismatch(LazyString("dot product arguments have dimensions ", length(u), "×", size(E), "×", length(v))))
d = dot(u,v)
T = typeof(one(eltype(E)) * d)
convert(T, d)
end

function dot(u::AbstractVector, D::Diagonal{<:Any,<:Fill}, v::AbstractVector)
length(u) == size(D,1) && length(v) == size(D,2) ||
throw(DimensionMismatch("dot product arguments have dimensions $(length(u))×$(size(D))×$(length(v))"))
throw(DimensionMismatch(LazyString("dot product arguments have dimensions ", length(u), "×", size(D), "×", length(v))))
D.diag.value*dot(u, v)
end

function dot(u::AbstractVector{T}, D::Diagonal{U,<:Zeros}, v::AbstractVector{V}) where {T,U,V}
length(u) == size(D,1) && length(v) == size(D,2) ||
throw(DimensionMismatch("dot product arguments have dimensions $(length(u))×$(size(D))×$(length(v))"))
throw(DimensionMismatch(LazyString("dot product arguments have dimensions ", length(u), "×", size(D), "×", length(v))))
zero(promote_type(T,U,V))
end

Expand Down Expand Up @@ -510,21 +510,21 @@ function lmul!(x::Number, z::AbstractFill)
λ = getindex_value(z)
# Following check ensures consistency w/ lmul!(x, Array(z))
# for, e.g., lmul!(NaN, z)
x*λ == λ || throw(ArgumentError("Cannot scale by $x"))
x*λ == λ || throw(ArgumentError(LazyString("Cannot scale by ", x)))
z
end

function rmul!(z::AbstractFill, x::Number)
λ = getindex_value(z)
# Following check ensures consistency w/ lmul!(x, Array(z))
# for, e.g., lmul!(NaN, z)
λ*x == λ || throw(ArgumentError("Cannot scale by $x"))
λ*x == λ || throw(ArgumentError(LazyString("Cannot scale by ", x)))
z
end

fillzero(::Type{Fill{T,N,AXIS}}, n, m) where {T,N,AXIS} = Fill{T,N,AXIS}(zero(T), (n, m))
fillzero(::Type{<:AbstractZeros{T,N,AXIS}}, n, m) where {T,N,AXIS} = Zeros{T,N,AXIS}((n, m))
fillzero(::Type{F}, n, m) where F = throw(ArgumentError("Cannot create a zero array of type $F"))
fillzero(::Type{F}, n, m) where F = throw(ArgumentError(LazyString("Cannot create a zero array of type ", F)))

diagzero(D::Diagonal{F}, i, j) where F<:AbstractFill = fillzero(F, axes(D.diag[i], 1), axes(D.diag[j], 2))

Expand Down
Loading
Loading