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
6 changes: 3 additions & 3 deletions .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,6 @@ jobs:
shell: julia --project=docs --color=yes {0}
run: |
using Documenter: DocMeta, doctest
using ScaleInvariantAnalysis
DocMeta.setdocmeta!(ScaleInvariantAnalysis, :DocTestSetup, :(using ScaleInvariantAnalysis); recursive=true)
doctest(ScaleInvariantAnalysis)
using MatrixCovers
DocMeta.setdocmeta!(MatrixCovers, :DocTestSetup, :(using MatrixCovers); recursive=true)
doctest(MatrixCovers)
12 changes: 6 additions & 6 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name = "ScaleInvariantAnalysis"
name = "MatrixCovers"
uuid = "727e6139-ff52-4636-a344-ed1d23e73ffc"
version = "1.0.0-DEV"
authors = ["Tim Holy <tim.holy@gmail.com> and contributors"]
Expand All @@ -16,11 +16,11 @@ SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"
Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d"

[extensions]
SIAIpopt = ["Ipopt", "JuMP"]
SIAJuMP = ["HiGHS", "JuMP"]
SIASparseArrays = "SparseArrays"
SIASparseArraysUnitful = ["SparseArrays", "Unitful"]
SIAUnitful = "Unitful"
MatrixCoversIpoptExt = ["Ipopt", "JuMP"]
MatrixCoversJuMPExt = ["HiGHS", "JuMP"]
MatrixCoversSparseArraysExt = "SparseArrays"
MatrixCoversSparseArraysUnitfulExt = ["SparseArrays", "Unitful"]
MatrixCoversUnitfulExt = "Unitful"

[compat]
Aqua = "0.8"
Expand Down
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
# ScaleInvariantAnalysis
# MatrixCovers

<!--- [![Stable](https://img.shields.io/badge/docs-stable-blue.svg)](https://HolyLab.github.io/ScaleInvariantAnalysis.jl/stable/) --->
[![Dev](https://img.shields.io/badge/docs-dev-blue.svg)](https://HolyLab.github.io/ScaleInvariantAnalysis.jl/dev/)
[![Build Status](https://github.com/HolyLab/ScaleInvariantAnalysis.jl/actions/workflows/CI.yml/badge.svg?branch=main)](https://github.com/HolyLab/ScaleInvariantAnalysis.jl/actions/workflows/CI.yml?query=branch%3Amain)
[![Coverage](https://codecov.io/gh/HolyLab/ScaleInvariantAnalysis.jl/branch/main/graph/badge.svg)](https://codecov.io/gh/HolyLab/ScaleInvariantAnalysis.jl)
<!--- [![Stable](https://img.shields.io/badge/docs-stable-blue.svg)](https://HolyLab.github.io/MatrixCovers.jl/stable/) --->
[![Dev](https://img.shields.io/badge/docs-dev-blue.svg)](https://HolyLab.github.io/MatrixCovers.jl/dev/)
[![Build Status](https://github.com/HolyLab/MatrixCovers.jl/actions/workflows/CI.yml/badge.svg?branch=main)](https://github.com/HolyLab/MatrixCovers.jl/actions/workflows/CI.yml?query=branch%3Amain)
[![Coverage](https://codecov.io/gh/HolyLab/MatrixCovers.jl/branch/main/graph/badge.svg)](https://codecov.io/gh/HolyLab/MatrixCovers.jl)
[![Aqua QA](https://juliatesting.github.io/Aqua.jl/dev/assets/badge.svg)](https://github.com/JuliaTesting/Aqua.jl)

This package computes **covers** of matrices: non-negative vectors `a` (and `b`)
Expand All @@ -19,5 +19,5 @@ rather than forbid it. Objective-minimal hard covers (`symcover_min`,
squared-log-excess penalty is solved natively, with no external solver, while
the other penalties are available when JuMP and HiGHS (or Ipopt) are loaded.

See the [documentation](https://HolyLab.github.io/ScaleInvariantAnalysis.jl/dev/)
See the [documentation](https://HolyLab.github.io/MatrixCovers.jl/dev/)
for motivation, examples, and a full API reference.
2 changes: 1 addition & 1 deletion bench/Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ HiGHS = "87dc4568-4c63-4d18-b0c0-bb2238e4078b"
Ipopt = "b6b21f68-93f8-5de0-b562-5493be1d77c9"
JuMP = "4076af6c-e467-56ae-b986-b466b2749572"
Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7"
ScaleInvariantAnalysis = "727e6139-ff52-4636-a344-ed1d23e73ffc"
MatrixCovers = "727e6139-ff52-4636-a344-ed1d23e73ffc"
SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"
StableRNGs = "860ef19b-820b-49d6-a774-d7a799459cd3"
Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"
Expand Down
4 changes: 2 additions & 2 deletions bench/sizesweep.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
# julia --project=bench bench/sizesweep.jl
# First use (creates bench/Manifest*.toml, which is gitignored):
# julia --project=bench -e 'using Pkg; Pkg.develop(path="."); Pkg.instantiate()'
using ScaleInvariantAnalysis, SparseArrays
using JuMP, HiGHS, Ipopt # triggers the SIAJuMP and SIAIpopt solver extensions
using MatrixCovers, SparseArrays
using JuMP, HiGHS, Ipopt # triggers the MatrixCoversJuMPExt and MatrixCoversIpoptExt solver extensions
using StableRNGs: StableRNG
using Statistics: median
using Printf
Expand Down
2 changes: 1 addition & 1 deletion docs/Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
HiGHS = "87dc4568-4c63-4d18-b0c0-bb2238e4078b"
JuMP = "4076af6c-e467-56ae-b986-b466b2749572"
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
ScaleInvariantAnalysis = "727e6139-ff52-4636-a344-ed1d23e73ffc"
MatrixCovers = "727e6139-ff52-4636-a344-ed1d23e73ffc"
Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d"

[compat]
Expand Down
12 changes: 6 additions & 6 deletions docs/make.jl
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
using ScaleInvariantAnalysis
using MatrixCovers
using Documenter
using JuMP, HiGHS
using Unitful # loaded here so the doctests' own `using` cannot emit precompilation output

DocMeta.setdocmeta!(ScaleInvariantAnalysis, :DocTestSetup, :(using ScaleInvariantAnalysis); recursive=true)
DocMeta.setdocmeta!(MatrixCovers, :DocTestSetup, :(using MatrixCovers); recursive=true)

makedocs(;
modules=[ScaleInvariantAnalysis],
modules=[MatrixCovers],
authors="Tim Holy <tim.holy@gmail.com> and contributors",
sitename="ScaleInvariantAnalysis.jl",
sitename="MatrixCovers.jl",
format=Documenter.HTML(;
canonical="https://HolyLab.github.io/ScaleInvariantAnalysis.jl",
canonical="https://HolyLab.github.io/MatrixCovers.jl",
edit_link="main",
assets=String[],
),
Expand All @@ -21,6 +21,6 @@ makedocs(;
)

deploydocs(;
repo="github.com/HolyLab/ScaleInvariantAnalysis.jl",
repo="github.com/HolyLab/MatrixCovers.jl",
devbranch="main",
)
20 changes: 10 additions & 10 deletions docs/src/index.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
```@meta
CurrentModule = ScaleInvariantAnalysis
CurrentModule = MatrixCovers
```

# ScaleInvariantAnalysis
# MatrixCovers

This package computes *covers* of matrices. Given a matrix `A`, a cover (more
specifically, a *hard cover*) is a matrix `C` that can be defined as
Expand Down Expand Up @@ -41,7 +41,7 @@ Newtons. Loading [Unitful](https://github.com/PainterQubits/Unitful.jl) lets
the matrix carry those units itself:

```jldoctest coverunits
julia> using ScaleInvariantAnalysis, Unitful
julia> using MatrixCovers, Unitful

julia> L, V, F = u"m", u"m/s", u"N"; # length, velocity, force

Expand Down Expand Up @@ -112,7 +112,7 @@ which the solvers minimize. Two penalty families are provided:
[`cover_objective`](@ref) evaluates either penalty for a given cover:

```jldoctest quality; filter = r"(\d+\.\d{6})\d+" => s"\1"
julia> using ScaleInvariantAnalysis
julia> using MatrixCovers

julia> A = [4.0 2.0; 2.0 16.0];

Expand Down Expand Up @@ -186,7 +186,7 @@ penalty they are solved natively (no external solver) by penalty-continuation
with a damped semismooth Newton iteration:

```jldoctest qmin; filter = r"(\d+\.\d{6})\d+" => s"\1"
julia> using ScaleInvariantAnalysis
julia> using MatrixCovers

julia> A = [1 2 3; 6 5 4];

Expand Down Expand Up @@ -219,7 +219,7 @@ faster than a general-purpose convex solver. The other penalties — `AbsLog{1}

```julia
using JuMP, HiGHS # HiGHS for AbsLog penalties
using ScaleInvariantAnalysis
using MatrixCovers

a = symcover_min(AbsLog{1}(), A) # L1-minimal symmetric hard cover
a, b = cover_min(AbsLog{1}(), A) # L1-minimal general hard cover
Expand Down Expand Up @@ -293,7 +293,7 @@ For finer control, you can run these manually:

```julia
using JuMP, Ipopt # Ipopt for the AbsLinear penalties
using ScaleInvariantAnalysis
using MatrixCovers

a = symcover_min(AbsLinear{2}(), A) # multistart over the whole menu
a = symcover_min(AbsLinear{2}(), A; strategies=(:geomean,)) # or commit to one start
Expand Down Expand Up @@ -323,7 +323,7 @@ That quantity can be estimated from the magnitudes of `A` and `b` alone, without
forming `x` at all:

```jldoctest roundoff
julia> using ScaleInvariantAnalysis, LinearAlgebra
julia> using MatrixCovers, LinearAlgebra

julia> A = [1e6 1e3; 1e3 4.0];

Expand Down Expand Up @@ -410,12 +410,12 @@ true
## Index of available tools

```@index
Modules = [ScaleInvariantAnalysis]
Modules = [MatrixCovers]
```

## Reference documentation

```@autodocs
Modules = [ScaleInvariantAnalysis]
Modules = [MatrixCovers]
Private = false
```
40 changes: 20 additions & 20 deletions ext/SIAIpopt.jl → ext/MatrixCoversIpoptExt.jl
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
module SIAIpopt
module MatrixCoversIpoptExt

using JuMP: JuMP, @variable, @objective, @constraint, @NLobjective, @NLconstraint
using Ipopt: Ipopt
using ScaleInvariantAnalysis
using ScaleInvariantAnalysis: AbsLinear
using MatrixCovers
using MatrixCovers: AbsLinear

# The models are built over 1-based positions 1:n; `pr`/`pc` map each position to the
# corresponding axis index of `A`, and results are scattered back onto vectors
Expand Down Expand Up @@ -34,8 +34,8 @@ end
# Variables: α[i] = log(a[i]); constraint: α[i]+α[j] ≥ log|A[i,j]|.
# ============================================================

function ScaleInvariantAnalysis.symcover_min!(::AbsLinear{2}, a::AbstractVector, A)
ScaleInvariantAnalysis._prepare_symcover_start!(a, A)
function MatrixCovers.symcover_min!(::AbsLinear{2}, a::AbstractVector, A)
MatrixCovers._prepare_symcover_start!(a, A)
axr = axes(A, 1)
T = float(real(eltype(A)))
pr = collect(axr)
Expand Down Expand Up @@ -63,8 +63,8 @@ function ScaleInvariantAnalysis.symcover_min!(::AbsLinear{2}, a::AbstractVector,
return a
end

function ScaleInvariantAnalysis.symcover_min!(::AbsLinear{1}, a::AbstractVector, A)
ScaleInvariantAnalysis._prepare_symcover_start!(a, A)
function MatrixCovers.symcover_min!(::AbsLinear{1}, a::AbstractVector, A)
MatrixCovers._prepare_symcover_start!(a, A)
axr = axes(A, 1)
T = float(real(eltype(A)))
pr = collect(axr)
Expand Down Expand Up @@ -108,8 +108,8 @@ end
# would be arbitrary.
# ============================================================

function ScaleInvariantAnalysis.cover_min!(::AbsLinear{2}, a::AbstractVector, b::AbstractVector, A)
ScaleInvariantAnalysis._prepare_cover_start!(a, b, A)
function MatrixCovers.cover_min!(::AbsLinear{2}, a::AbstractVector, b::AbstractVector, A)
MatrixCovers._prepare_cover_start!(a, b, A)
axr, axc = axes(A, 1), axes(A, 2)
T = float(real(eltype(A)))
pr, pc = collect(axr), collect(axc)
Expand Down Expand Up @@ -143,8 +143,8 @@ function ScaleInvariantAnalysis.cover_min!(::AbsLinear{2}, a::AbstractVector, b:
return a, b
end

function ScaleInvariantAnalysis.cover_min!(::AbsLinear{1}, a::AbstractVector, b::AbstractVector, A)
ScaleInvariantAnalysis._prepare_cover_start!(a, b, A)
function MatrixCovers.cover_min!(::AbsLinear{1}, a::AbstractVector, b::AbstractVector, A)
MatrixCovers._prepare_cover_start!(a, b, A)
axr, axc = axes(A, 1), axes(A, 2)
T = float(real(eltype(A)))
pr, pc = collect(axr), collect(axc)
Expand Down Expand Up @@ -190,8 +190,8 @@ end
# driver over these kernels is native; see soft_symcover_min.
# ============================================================

function ScaleInvariantAnalysis.soft_symcover_min!(::AbsLinear{2}, a::AbstractVector, A)
ScaleInvariantAnalysis._prepare_soft_symcover_start!(a, A)
function MatrixCovers.soft_symcover_min!(::AbsLinear{2}, a::AbstractVector, A)
MatrixCovers._prepare_soft_symcover_start!(a, A)
axr = axes(A, 1)
T = float(real(eltype(A)))
pr = collect(axr)
Expand All @@ -217,8 +217,8 @@ function ScaleInvariantAnalysis.soft_symcover_min!(::AbsLinear{2}, a::AbstractVe
return a
end

function ScaleInvariantAnalysis.soft_symcover_min!(::AbsLinear{1}, a::AbstractVector, A)
ScaleInvariantAnalysis._prepare_soft_symcover_start!(a, A)
function MatrixCovers.soft_symcover_min!(::AbsLinear{1}, a::AbstractVector, A)
MatrixCovers._prepare_soft_symcover_start!(a, A)
axr = axes(A, 1)
T = float(real(eltype(A)))
pr = collect(axr)
Expand Down Expand Up @@ -256,8 +256,8 @@ end
# scales, so the count of zeros enters the objective as a constant, matching cover_objective.
# ============================================================

function ScaleInvariantAnalysis.soft_cover_min!(::AbsLinear{2}, a::AbstractVector, b::AbstractVector, A)
ScaleInvariantAnalysis._prepare_soft_cover_start!(a, b, A)
function MatrixCovers.soft_cover_min!(::AbsLinear{2}, a::AbstractVector, b::AbstractVector, A)
MatrixCovers._prepare_soft_cover_start!(a, b, A)
axr, axc = axes(A, 1), axes(A, 2)
T = float(real(eltype(A)))
pr, pc = collect(axr), collect(axc)
Expand Down Expand Up @@ -289,8 +289,8 @@ function ScaleInvariantAnalysis.soft_cover_min!(::AbsLinear{2}, a::AbstractVecto
return a, b
end

function ScaleInvariantAnalysis.soft_cover_min!(::AbsLinear{1}, a::AbstractVector, b::AbstractVector, A)
ScaleInvariantAnalysis._prepare_soft_cover_start!(a, b, A)
function MatrixCovers.soft_cover_min!(::AbsLinear{1}, a::AbstractVector, b::AbstractVector, A)
MatrixCovers._prepare_soft_cover_start!(a, b, A)
axr, axc = axes(A, 1), axes(A, 2)
T = float(real(eltype(A)))
pr, pc = collect(axr), collect(axc)
Expand Down Expand Up @@ -327,4 +327,4 @@ function ScaleInvariantAnalysis.soft_cover_min!(::AbsLinear{1}, a::AbstractVecto
return a, b
end

end # module SIAIpopt
end # module MatrixCoversIpoptExt
22 changes: 11 additions & 11 deletions ext/SIAJuMP.jl → ext/MatrixCoversJuMPExt.jl
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
module SIAJuMP
module MatrixCoversJuMPExt

using JuMP: JuMP, @variable, @objective, @constraint
using HiGHS: HiGHS
using ScaleInvariantAnalysis
using ScaleInvariantAnalysis: AbsLog
using MatrixCovers
using MatrixCovers: AbsLog
using LinearAlgebra: dot

# The models are built over 1-based positions 1:n; `pr`/`pc` map each position to
Expand All @@ -14,7 +14,7 @@ using LinearAlgebra: dot

# Exact reference for the native `symcover_min(::AbsLog{2})`: same QP, solved by
# HiGHS. Not exported; used by the test suite to cross-check the native solver.
function ScaleInvariantAnalysis.symcover_min_jump(::AbsLog{2}, A)
function MatrixCovers.symcover_min_jump(::AbsLog{2}, A)
axr = axes(A, 1)
axes(A, 2) == axr || throw(ArgumentError("symcover_min_jump requires a square matrix"))
T = float(real(eltype(A)))
Expand All @@ -38,10 +38,10 @@ function ScaleInvariantAnalysis.symcover_min_jump(::AbsLog{2}, A)
return a
end

ScaleInvariantAnalysis.symcover_min(::AbsLog{1}, A) = _symcover_min_abslog1(A, nothing)
MatrixCovers.symcover_min(::AbsLog{1}, A) = _symcover_min_abslog1(A, nothing)

function ScaleInvariantAnalysis.symcover_min!(::AbsLog{1}, a::AbstractVector, A)
ScaleInvariantAnalysis._prepare_symcover_start!(a, A)
function MatrixCovers.symcover_min!(::AbsLog{1}, a::AbstractVector, A)
MatrixCovers._prepare_symcover_start!(a, A)
a .= _symcover_min_abslog1(A, a)
return a
end
Expand Down Expand Up @@ -114,7 +114,7 @@ function _symcover_min_abslog1(A, start)
return a
end

function ScaleInvariantAnalysis.cover_min_jump(::AbsLog{2}, A)
function MatrixCovers.cover_min_jump(::AbsLog{2}, A)
axr = axes(A, 1)
axc = axes(A, 2)
T = float(real(eltype(A)))
Expand Down Expand Up @@ -146,10 +146,10 @@ function ScaleInvariantAnalysis.cover_min_jump(::AbsLog{2}, A)
return a, b
end

ScaleInvariantAnalysis.cover_min(::AbsLog{1}, A) = _cover_min_abslog1(A, nothing)
MatrixCovers.cover_min(::AbsLog{1}, A) = _cover_min_abslog1(A, nothing)

function ScaleInvariantAnalysis.cover_min!(::AbsLog{1}, a::AbstractVector, b::AbstractVector, A)
ScaleInvariantAnalysis._prepare_cover_start!(a, b, A)
function MatrixCovers.cover_min!(::AbsLog{1}, a::AbstractVector, b::AbstractVector, A)
MatrixCovers._prepare_cover_start!(a, b, A)
anew, bnew = _cover_min_abslog1(A, (a, b))
a .= anew
b .= bnew
Expand Down
Loading
Loading