Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
10 changes: 5 additions & 5 deletions src/gram_covers.jl
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ function gramcover!(s::AbstractVector, a::AbstractVector, b::AbstractVector, sc:
_check_gramcover_ab(a, b, sc)
_check_gramcover_s(s, sc)
eachindex(w) == sc.rowax ||
throw(DimensionMismatch("`w` holds one weight per support row: eachindex(w) must be $(sc.rowax), got $(eachindex(w))"))
throw(DimensionMismatch("`w` holds one weight per support row: eachindex(w) must be $(string(sc.rowax)), got $(string(eachindex(w)))"))
m = zeros(typeof(_gc_term(a, w)), ncomponents(sc))
n = zeros(Int, ncomponents(sc))
for i in sc.rowax
Expand All @@ -223,7 +223,7 @@ function gramcover!(s::AbstractVector, a::AbstractVector, b::AbstractVector, sc:
_check_gramcover_ab(a, b, sc)
_check_gramcover_s(s, sc)
axes(W) == (sc.rowax, sc.rowax) ||
throw(DimensionMismatch("`W` couples support rows, so it must be square on the row axis: axes(W) must be $((sc.rowax, sc.rowax)), got $(axes(W))"))
throw(DimensionMismatch("`W` couples support rows, so it must be square on the row axis: axes(W) must be $(string((sc.rowax, sc.rowax))), got $(string(axes(W)))"))
ncomp = ncomponents(sc)

# Union-find over the component ids of `sc`: merge two of them whenever a
Expand Down Expand Up @@ -320,15 +320,15 @@ end

function _check_gramcover_ab(a::AbstractVector, b::AbstractVector, sc::SupportComponents)
eachindex(a) == sc.rowax ||
throw(DimensionMismatch("`a` holds one scale per support row: eachindex(a) must be $(sc.rowax), got $(eachindex(a))"))
throw(DimensionMismatch("`a` holds one scale per support row: eachindex(a) must be $(string(sc.rowax)), got $(string(eachindex(a)))"))
eachindex(b) == sc.colax ||
throw(DimensionMismatch("`b` holds one scale per support column: eachindex(b) must be $(sc.colax), got $(eachindex(b))"))
throw(DimensionMismatch("`b` holds one scale per support column: eachindex(b) must be $(string(sc.colax)), got $(string(eachindex(b)))"))
return nothing
end

function _check_gramcover_s(s::AbstractVector, sc::SupportComponents)
eachindex(s) == sc.colax ||
throw(DimensionMismatch("`s` holds one Gram scale per support column: eachindex(s) must be $(sc.colax), got $(eachindex(s))"))
throw(DimensionMismatch("`s` holds one Gram scale per support column: eachindex(s) must be $(string(sc.colax)), got $(string(eachindex(s)))"))
return nothing
end

Expand Down
16 changes: 8 additions & 8 deletions src/heuristic_covers.jl
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ function symcover!(a::AbstractVector, A::AbstractMatrix; kwargs...)
ax = axes(A, 1)
axes(A, 2) == ax || throw(ArgumentError("symcover! requires a square matrix"))
require_abs_symmetric(A, :symcover!)
eachindex(a) == ax || throw(DimensionMismatch("indices of `a` must match the indexing of `A`, got eachindex(a)=$(eachindex(a)), axes(A, 1)=$ax"))
eachindex(a) == ax || throw(DimensionMismatch("indices of `a` must match the indexing of `A`, got eachindex(a)=$(string(eachindex(a))), axes(A, 1)=$(string(ax))"))
unconstrained_min!(AbsLog{2}(), a, A)
boost_feasible!(a, A)
return tighten_cover!(a, A; kwargs...)
Expand Down Expand Up @@ -144,8 +144,8 @@ cover!(ϕ::AbstractCoverPenalty, a::AbstractVector, b::AbstractVector, A::Abstra
cover!(a, b, A; kwargs...)

function cover!(a::AbstractVector, b::AbstractVector, A::AbstractMatrix; kwargs...)
axes(A, 1) == eachindex(a) || throw(DimensionMismatch("indices of `a` must match row-indexing of `A`, got eachindex(a)=$(eachindex(a)), axes(A, 1)=$(axes(A, 1))"))
axes(A, 2) == eachindex(b) || throw(DimensionMismatch("indices of `b` must match column-indexing of `A`, got eachindex(b)=$(eachindex(b)), axes(A, 2)=$(axes(A, 2))"))
axes(A, 1) == eachindex(a) || throw(DimensionMismatch("indices of `a` must match row-indexing of `A`, got eachindex(a)=$(string(eachindex(a))), axes(A, 1)=$(string(axes(A, 1)))"))
axes(A, 2) == eachindex(b) || throw(DimensionMismatch("indices of `b` must match column-indexing of `A`, got eachindex(b)=$(string(eachindex(b))), axes(A, 2)=$(string(axes(A, 2)))"))
unconstrained_min!(AbsLog{2}(), a, b, A)
boost_feasible!(a, b, A)
tighten_cover!(a, b, A; kwargs...)
Expand Down Expand Up @@ -240,7 +240,7 @@ end
# This is the "rank-1 solution" described in manuscript section 5.2.
function unconstrained_min!(::AbsLog{2}, a::AbstractVector{T}, A::AbstractMatrix) where T
ax = eachindex(a)
axes(A) == (ax, ax) || throw(DimensionMismatch("`unconstrained_min!(ϕ, a, A)` requires a square matrix with matching axes to `a` (got axes(A)=$(axes(A)), axes(a)=$(axes(a))"))
axes(A) == (ax, ax) || throw(DimensionMismatch("`unconstrained_min!(ϕ, a, A)` requires a square matrix with matching axes to `a` (got axes(A)=$(string(axes(A))), axes(a)=$(string(axes(a)))"))
loga = fill!(similar(a), zero(T))
nza = zeros(Int, ax)
foreach_support_sym(A) do i, j, v
Expand All @@ -265,8 +265,8 @@ end

function unconstrained_min!(::AbsLog{2}, a::AbstractVector, b::AbstractVector, A::AbstractMatrix)
T = float(promote_type(eltype(a), eltype(b)))
axes(A, 1) == eachindex(a) || throw(DimensionMismatch("`unconstrained_min!(ϕ, a, b, A)` requires row indices of `A` to match `a`, got axes(A, 1)=$(axes(A, 1)), axes(a)=$(axes(a))"))
axes(A, 2) == eachindex(b) || throw(DimensionMismatch("`unconstrained_min!(ϕ, a, b, A)` requires column indices of `A` to match `b`, got axes(A, 2)=$(axes(A, 2)), axes(b)=$(axes(b))"))
axes(A, 1) == eachindex(a) || throw(DimensionMismatch("`unconstrained_min!(ϕ, a, b, A)` requires row indices of `A` to match `a`, got axes(A, 1)=$(string(axes(A, 1))), axes(a)=$(string(axes(a)))"))
axes(A, 2) == eachindex(b) || throw(DimensionMismatch("`unconstrained_min!(ϕ, a, b, A)` requires column indices of `A` to match `b`, got axes(A, 2)=$(string(axes(A, 2))), axes(b)=$(string(axes(b)))"))
loga = fill!(similar(a, T), zero(T))
logb = fill!(similar(b, T), zero(T))
nza = zeros(Int, axes(A, 1))
Expand Down Expand Up @@ -301,7 +301,7 @@ end
# a scale for it (see `boost_feasible_seq!`).
function init_feasible_diag!(a::AbstractVector{T}, A::AbstractMatrix) where T
ax = eachindex(a)
axes(A) == (ax, ax) || throw(DimensionMismatch("`init_feasible_diag!(a, A)` requires a square matrix with matching axes to `a` (got axes(A)=$(axes(A)), axes(a)=$(axes(a)))"))
axes(A) == (ax, ax) || throw(DimensionMismatch("`init_feasible_diag!(a, A)` requires a square matrix with matching axes to `a` (got axes(A)=$(string(axes(A))), axes(a)=$(string(axes(a))))"))
# A diagonal entry the traversal skips is zero, which is the "not yet resolved"
# value `boost_feasible_seq!` expects.
fill!(a, zero(T))
Expand Down Expand Up @@ -575,7 +575,7 @@ end
# initialization, a heuristic guaranteed to be O(n^2) seems reasonable.
function boost_feasible_seq!(a::AbstractVector{T}, A::AbstractMatrix) where T
ax = eachindex(a)
axes(A) == (ax, ax) || throw(DimensionMismatch("`boost_feasible_seq!(a, A)` requires a square matrix with matching axes to `a` (got axes(A)=$(axes(A)), axes(a)=$(axes(a)))"))
axes(A) == (ax, ax) || throw(DimensionMismatch("`boost_feasible_seq!(a, A)` requires a square matrix with matching axes to `a` (got axes(A)=$(string(axes(A))), axes(a)=$(string(axes(a))))"))
I = eltype(ax)

# The support gathered as off-diagonal pairs, ordered by increasing offset and
Expand Down
10 changes: 5 additions & 5 deletions src/initializers.jl
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ function initialize_symcover!(a::AbstractVector, A::AbstractMatrix;
ax = axes(A, 1)
axes(A, 2) == ax || throw(ArgumentError("initialize_symcover! requires a square matrix"))
require_abs_symmetric(A, :initialize_symcover!)
eachindex(a) == ax || throw(DimensionMismatch("indices of `a` must match the indexing of `A`, got eachindex(a)=$(eachindex(a)), axes(A, 1)=$ax"))
eachindex(a) == ax || throw(DimensionMismatch("indices of `a` must match the indexing of `A`, got eachindex(a)=$(string(eachindex(a))), axes(A, 1)=$(string(ax))"))
_initialize_symcover!(a, A, strategy, feasible; kwargs...) ||
throw(ArgumentError("strategy=:leaveout requires a support entry that can be dropped without emptying a row"))
return a
Expand Down Expand Up @@ -131,8 +131,8 @@ See also: [`initialize_cover`](@ref).
"""
function initialize_cover!(a::AbstractVector, b::AbstractVector, A::AbstractMatrix;
strategy::Symbol=:hardcover, feasible::Symbol=:inflate, kwargs...)
axes(A, 1) == eachindex(a) || throw(DimensionMismatch("indices of `a` must match row-indexing of `A`, got eachindex(a)=$(eachindex(a)), axes(A, 1)=$(axes(A, 1))"))
axes(A, 2) == eachindex(b) || throw(DimensionMismatch("indices of `b` must match column-indexing of `A`, got eachindex(b)=$(eachindex(b)), axes(A, 2)=$(axes(A, 2))"))
axes(A, 1) == eachindex(a) || throw(DimensionMismatch("indices of `a` must match row-indexing of `A`, got eachindex(a)=$(string(eachindex(a))), axes(A, 1)=$(string(axes(A, 1)))"))
axes(A, 2) == eachindex(b) || throw(DimensionMismatch("indices of `b` must match column-indexing of `A`, got eachindex(b)=$(string(eachindex(b))), axes(A, 2)=$(string(axes(A, 2)))"))
if strategy === :hardcover
cover!(a, b, A; kwargs...)
elseif strategy === :geomean
Expand Down Expand Up @@ -200,7 +200,7 @@ end
# which start was built.
function _reject_kwargs(strategy::Symbol, kwargs)
isempty(kwargs) && return nothing
throw(ArgumentError("strategy=:$strategy accepts no further keyword arguments, got $(join(keys(kwargs), ", "))"))
throw(ArgumentError("strategy=:$strategy accepts no further keyword arguments, got $(string(join(keys(kwargs), ", ")))"))
end

# Leave-one-out geometric mean. The geometric mean weights every nonzero entry equally, so
Expand Down Expand Up @@ -228,7 +228,7 @@ end
# would empty some row's support.
function _leaveout_logmean_init!(a::AbstractVector{T}, A::AbstractMatrix) where T
ax = eachindex(a)
axes(A) == (ax, ax) || throw(DimensionMismatch("`_leaveout_logmean_init!(a, A)` requires a square matrix with matching axes to `a` (got axes(A)=$(axes(A)), axes(a)=$(axes(a)))"))
axes(A) == (ax, ax) || throw(DimensionMismatch("`_leaveout_logmean_init!(a, A)` requires a square matrix with matching axes to `a` (got axes(A)=$(string(axes(A))), axes(a)=$(string(axes(a))))"))
nza = unconstrained_min!(AbsLog{2}(), a, A)
sum(nza) == 0 && return false
# One gather serves all three passes below: the two pair scans read the `j >= i`
Expand Down
8 changes: 4 additions & 4 deletions src/iscover.jl
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,9 @@ false
"""
function iscover(a::AbstractVector, b::AbstractVector, A::AbstractMatrix; rtol=0, atol=0)
eachindex(a) == axes(A, 1) ||
throw(DimensionMismatch("indices of `a` must match row-indexing of `A`, got eachindex(a)=$(eachindex(a)), axes(A, 1)=$(axes(A, 1))"))
throw(DimensionMismatch("indices of `a` must match row-indexing of `A`, got eachindex(a)=$(string(eachindex(a))), axes(A, 1)=$(string(axes(A, 1)))"))
eachindex(b) == axes(A, 2) ||
throw(DimensionMismatch("indices of `b` must match column-indexing of `A`, got eachindex(b)=$(eachindex(b)), axes(A, 2)=$(axes(A, 2))"))
throw(DimensionMismatch("indices of `b` must match column-indexing of `A`, got eachindex(b)=$(string(eachindex(b))), axes(A, 2)=$(string(axes(A, 2)))"))
_require_nonneg(a, "a")
_require_nonneg(b, "b")
# Zero entries of `A` are skipped by `foreach_support`, and need no check: they demand
Expand All @@ -57,7 +57,7 @@ end

function iscover(a::AbstractVector, A::AbstractMatrix; kwargs...)
axes(A, 1) == axes(A, 2) ||
throw(DimensionMismatch("iscover(a, A) requires a square matrix, got axes $(axes(A))"))
throw(DimensionMismatch("iscover(a, A) requires a square matrix, got axes $(string(axes(A)))"))
return iscover(a, a, A; kwargs...)
end

Expand All @@ -69,7 +69,7 @@ function _require_nonneg(x::AbstractVector, name::String)
# value, and `zero(Quantity{Float64})` is undefined. Also rejects NaN, which fails
# every comparison.
x[i] >= zero(x[i]) ||
throw(ArgumentError("iscover requires nonnegative scales, got $name[$i] = $(x[i])"))
throw(ArgumentError("iscover requires nonnegative scales, got $name[$(string(i))] = $(string(x[i]))"))
end
return nothing
end
20 changes: 10 additions & 10 deletions src/minimal_covers.jl
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ function symcover_min(ϕ::AbsLinear, A::AbstractMatrix; strategies=SYMCOVER_MIN_
built = [_initialize_symcover!(a, A, strategy, :inflate) for (a, strategy) in zip(starts, strategies)]
covers = [symcover_min!(ϕ, a, A) for (a, ok) in zip(starts, built) if ok]
isempty(covers) &&
throw(ArgumentError("symcover_min: no strategy in $strategies yields a starting cover of `A`"))
throw(ArgumentError("symcover_min: no strategy in $(string(strategies)) yields a starting cover of `A`"))
return covers[_multistart_select([cover_objective(ϕ, a, A) for a in covers])]
end

Expand Down Expand Up @@ -256,7 +256,7 @@ function _prepare_symcover_start!(a::AbstractVector, A::AbstractMatrix, fname=:s
ax = axes(A, 1)
axes(A, 2) == ax || throw(ArgumentError("$fname requires a square matrix"))
require_abs_symmetric(A, fname)
eachindex(a) == ax || throw(DimensionMismatch("indices of `a` must match the indexing of `A`, got eachindex(a)=$(eachindex(a)), axes(A, 1)=$ax"))
eachindex(a) == ax || throw(DimensionMismatch("indices of `a` must match the indexing of `A`, got eachindex(a)=$(string(eachindex(a))), axes(A, 1)=$(string(ax))"))
T = float(eltype(a))
supp = fill!(similar(a, Bool), false)
foreach_support_sym(A) do i, j, v
Expand All @@ -268,12 +268,12 @@ function _prepare_symcover_start!(a::AbstractVector, A::AbstractMatrix, fname=:s
end
foreach_support_sym(A) do i, j, v
(isfinite(a[i]) && a[i] > zero(a[i])) ||
throw(ArgumentError("symcover_min! requires a start with finite positive scale on every supported row, got a[$i] = $(a[i])"))
throw(ArgumentError("symcover_min! requires a start with finite positive scale on every supported row, got a[$(string(i))] = $(string(a[i]))"))
(isfinite(a[j]) && a[j] > zero(a[j])) ||
throw(ArgumentError("symcover_min! requires a start with finite positive scale on every supported row, got a[$j] = $(a[j])"))
throw(ArgumentError("symcover_min! requires a start with finite positive scale on every supported row, got a[$(string(j))] = $(string(a[j]))"))
lv, li, lj = log(T(v)), log(T(a[i])), log(T(a[j]))
lv - li - lj <= _start_slack(lv, li, lj) ||
throw(ArgumentError("symcover_min! requires a start that covers `A`, but a[$i]*a[$j] = $(a[i] * a[j]) < $v = abs(A[$i,$j]); see initialize_symcover"))
throw(ArgumentError("symcover_min! requires a start that covers `A`, but a[$(string(i))]*a[$(string(j))] = $(string(a[i] * a[j])) < $(string(v)) = abs(A[$(string(i)),$(string(j))]); see initialize_symcover"))
end
return inflate_feasible!(a, A)
end
Expand All @@ -283,8 +283,8 @@ end
# convention (imposed within each connected component of the support), so the
# refiners read it only up to the per-component row/column gauge.
function _prepare_cover_start!(a::AbstractVector, b::AbstractVector, A::AbstractMatrix)
axes(A, 1) == eachindex(a) || throw(DimensionMismatch("indices of `a` must match row-indexing of `A`, got eachindex(a)=$(eachindex(a)), axes(A, 1)=$(axes(A, 1))"))
axes(A, 2) == eachindex(b) || throw(DimensionMismatch("indices of `b` must match column-indexing of `A`, got eachindex(b)=$(eachindex(b)), axes(A, 2)=$(axes(A, 2))"))
axes(A, 1) == eachindex(a) || throw(DimensionMismatch("indices of `a` must match row-indexing of `A`, got eachindex(a)=$(string(eachindex(a))), axes(A, 1)=$(string(axes(A, 1)))"))
axes(A, 2) == eachindex(b) || throw(DimensionMismatch("indices of `b` must match column-indexing of `A`, got eachindex(b)=$(string(eachindex(b))), axes(A, 2)=$(string(axes(A, 2)))"))
T = float(promote_type(eltype(a), eltype(b)))
suppa = fill!(similar(a, Bool), false)
suppb = fill!(similar(b, Bool), false)
Expand All @@ -300,12 +300,12 @@ function _prepare_cover_start!(a::AbstractVector, b::AbstractVector, A::Abstract
end
foreach_support(A) do i, j, v
(isfinite(a[i]) && a[i] > zero(a[i])) ||
throw(ArgumentError("cover_min! requires a start with finite positive scale on every supported row, got a[$i] = $(a[i])"))
throw(ArgumentError("cover_min! requires a start with finite positive scale on every supported row, got a[$(string(i))] = $(string(a[i]))"))
(isfinite(b[j]) && b[j] > zero(b[j])) ||
throw(ArgumentError("cover_min! requires a start with finite positive scale on every supported column, got b[$j] = $(b[j])"))
throw(ArgumentError("cover_min! requires a start with finite positive scale on every supported column, got b[$(string(j))] = $(string(b[j]))"))
lv, li, lj = log(T(v)), log(T(a[i])), log(T(b[j]))
lv - li - lj <= _start_slack(lv, li, lj) ||
throw(ArgumentError("cover_min! requires a start that covers `A`, but a[$i]*b[$j] = $(a[i] * b[j]) < $v = abs(A[$i,$j]); see initialize_cover"))
throw(ArgumentError("cover_min! requires a start that covers `A`, but a[$(string(i))]*b[$(string(j))] = $(string(a[i] * b[j])) < $(string(v)) = abs(A[$(string(i)),$(string(j))]); see initialize_cover"))
end
_balance_cover!(a, b, A)
return inflate_feasible!(a, b, A)
Expand Down
4 changes: 2 additions & 2 deletions src/penalties.jl
Original file line number Diff line number Diff line change
Expand Up @@ -129,9 +129,9 @@ See also:
"""
function cover_objective(ϕ, a, b, A)
eachindex(a) == axes(A, 1) ||
throw(DimensionMismatch("indices of `a` must match row-indexing of `A`, got eachindex(a)=$(eachindex(a)), axes(A, 1)=$(axes(A, 1))"))
throw(DimensionMismatch("indices of `a` must match row-indexing of `A`, got eachindex(a)=$(string(eachindex(a))), axes(A, 1)=$(string(axes(A, 1)))"))
eachindex(b) == axes(A, 2) ||
throw(DimensionMismatch("indices of `b` must match column-indexing of `A`, got eachindex(b)=$(eachindex(b)), axes(A, 2)=$(axes(A, 2))"))
throw(DimensionMismatch("indices of `b` must match column-indexing of `A`, got eachindex(b)=$(string(eachindex(b))), axes(A, 2)=$(string(axes(A, 2)))"))
T = promote_type(objective_type(A), objective_type(a), objective_type(b))
s = Ref(zero(T))
nsupport = Ref(0)
Expand Down
Loading
Loading