Skip to content

Commit

Permalink
Fix deprecations and clean tests & CI (#19)
Browse files Browse the repository at this point in the history
* Fix deprecations

* Use separate test environment and test GLPK as well

* Use eachrow and eachcol

* Update CI

* Fix format

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
  • Loading branch information
devmotion and github-actions[bot] authored Dec 21, 2021
1 parent b1dba1c commit c67137b
Show file tree
Hide file tree
Showing 7 changed files with 71 additions and 46 deletions.
4 changes: 1 addition & 3 deletions .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,6 @@ jobs:
with:
python-version: '3.9'
architecture: ${{ matrix.arch }}
# Limitation of pip: https://pythonot.github.io/index.html#pip-installation
- run: python -m pip install cython numpy
- run: python -m pip install pot
- uses: julia-actions/setup-julia@v1
with:
Expand All @@ -63,7 +61,7 @@ jobs:
PYTHON: python
- uses: julia-actions/julia-processcoverage@v1
if: matrix.version == '1' && matrix.os == 'ubuntu-latest'
- uses: codecov/codecov-action@v1
- uses: codecov/codecov-action@v2
if: matrix.version == '1' && matrix.os == 'ubuntu-latest'
with:
file: lcov.info
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/CompatHelper.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ jobs:
- name: "Run CompatHelper"
run: |
import CompatHelper
CompatHelper.main(; subdirs=["", "docs"], bump_version=true)
CompatHelper.main(; subdirs=["", "docs", "test"], bump_version=true)
shell: julia --color=yes {0}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Expand Down
2 changes: 0 additions & 2 deletions .github/workflows/Documentation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@ jobs:
with:
python-version: '3.9'
architecture: ${{ matrix.arch }}
# Limitation of pip: https://pythonot.github.io/index.html#pip-installation
- run: python -m pip install cython numpy
- run: python -m pip install pot
- uses: julia-actions/setup-julia@latest
with:
Expand Down
14 changes: 2 additions & 12 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "ExactOptimalTransport"
uuid = "24df6009-d856-477c-ac5c-91f668376b31"
authors = ["JuliaOptimalTransport"]
version = "0.2.0"
version = "0.2.1"

[deps]
Distances = "b4f34e82-e78d-54a5-968a-f98e89d6e8f7"
Expand All @@ -18,19 +18,9 @@ StatsBase = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91"
Distances = "0.9.0, 0.10"
Distributions = "0.24, 0.25"
FillArrays = "0.12"
MathOptInterface = "0.9, 0.10"
MathOptInterface = "0.10"
PDMats = "0.10, 0.11"
QuadGK = "2"
StatsBase = "0.33.8"
julia = "1.6"

[extras]
HCubature = "19dc6840-f33b-545b-b366-655c7e3ffd49"
PythonOT = "3c485715-4278-42b2-9b5f-8f00e43c12ef"
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
SafeTestsets = "1bc83da4-3b8d-516f-aca4-4fe02f6d838f"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
Tulip = "6dd1b50a-3aae-11e9-10b5-ef983d2400fa"

[targets]
test = ["PythonOT", "Random", "SafeTestsets", "Test", "Tulip", "HCubature"]
10 changes: 5 additions & 5 deletions src/exact.jl
Original file line number Diff line number Diff line change
Expand Up @@ -71,21 +71,21 @@ function emd(μ, ν, C, model::MOI.ModelLike)

# add non-negativity constraints
for xi in x
MOI.add_constraint(model, MOI.SingleVariable(xi), MOI.GreaterThan(zero_T))
MOI.add_constraint(model, xi, MOI.GreaterThan(zero_T))
end

# add constraints for source
for (i, μi) in zip(axes(xmat, 1), μ) # eachrow(xmat) is not available on Julia 1.0
for (xrow, μi) in zip(eachrow(xmat), μ)
f = MOI.ScalarAffineFunction(
[MOI.ScalarAffineTerm(one(μi), xi) for xi in view(xmat, i, :)], zero(μi)
[MOI.ScalarAffineTerm(one(μi), xi) for xi in xrow], zero(μi)
)
MOI.add_constraint(model, f, MOI.EqualTo(μi))
end

# add constraints for target
for (i, νi) in zip(axes(xmat, 2), ν) # eachcol(xmat) is not available on Julia 1.0
for (xcol, νi) in zip(eachcol(xmat), ν)
f = MOI.ScalarAffineFunction(
[MOI.ScalarAffineTerm(one(νi), xi) for xi in view(xmat, :, i)], zero(νi)
[MOI.ScalarAffineTerm(one(νi), xi) for xi in xcol], zero(νi)
)
MOI.add_constraint(model, f, MOI.EqualTo(νi))
end
Expand Down
28 changes: 28 additions & 0 deletions test/Project.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
[deps]
Distances = "b4f34e82-e78d-54a5-968a-f98e89d6e8f7"
Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f"
FillArrays = "1a297f60-69ca-5386-bcde-b61e274b549b"
GLPK = "60bf3e95-4087-53dc-ae20-288a0d20c6a6"
HCubature = "19dc6840-f33b-545b-b366-655c7e3ffd49"
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
MathOptInterface = "b8f27783-ece8-5eb3-8dc8-9495eed66fee"
PDMats = "90014a1f-27ba-587c-ab20-58faa44d9150"
PythonOT = "3c485715-4278-42b2-9b5f-8f00e43c12ef"
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
SafeTestsets = "1bc83da4-3b8d-516f-aca4-4fe02f6d838f"
SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
Tulip = "6dd1b50a-3aae-11e9-10b5-ef983d2400fa"

[compat]
Distances = "0.9, 0.10"
Distributions = "0.24, 0.25"
FillArrays = "0.12"
GLPK = "0.15"
HCubature = "1.5"
MathOptInterface = "0.10"
PDMats = "0.10, 0.11"
PythonOT = "0.1"
SafeTestsets = "0.0.1"
Tulip = "0.9"
julia = "1.6"
57 changes: 34 additions & 23 deletions test/exact.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ using ExactOptimalTransport

using Distances
using FillArrays
using GLPK
using PythonOT: PythonOT
using Tulip
using MathOptInterface
Expand Down Expand Up @@ -32,30 +33,34 @@ Random.seed!(100)
pot_P = POT.emd(μ, ν, C)
pot_cost = POT.emd2(μ, ν, C)

# compute optimal transport map and cost with Tulip
lp = Tulip.Optimizer()
P = emd(μ, ν, C, lp)
@test size(C) == size(P)
@test MOI.get(lp, MOI.TerminationStatus()) == MOI.OPTIMAL
@test maximum(abs, P .- pot_P) < 1e-2

lp = Tulip.Optimizer()
cost = emd2(μ, ν, C, lp)
@test dot(C, P) cost atol = 1e-5
@test MOI.get(lp, MOI.TerminationStatus()) == MOI.OPTIMAL
@test cost pot_cost atol = 1e-5
# compute optimal transport map and cost with Tulip and GLPK
for T in (Tulip.Optimizer, GLPK.Optimizer)
lp = T()
P = emd(μ, ν, C, lp)
@test size(C) == size(P)
@test MOI.get(lp, MOI.TerminationStatus()) == MOI.OPTIMAL
@test maximum(abs, P .- pot_P) < 1e-2

lp = T()
cost = emd2(μ, ν, C, lp)
@test dot(C, P) cost atol = 1e-5
@test MOI.get(lp, MOI.TerminationStatus()) == MOI.OPTIMAL
@test cost pot_cost atol = 1e-5
end
end

@testset "pre-computed plan" begin
# create random cost matrix
C = pairwise(SqEuclidean(), rand(1, M), rand(1, N); dims=2)

# compute optimal transport map
P = emd(μ, ν, C, Tulip.Optimizer())
# compute optimal transport map with Tulip and GLPK
for T in (Tulip.Optimizer, GLPK.Optimizer)
P = emd(μ, ν, C, T())

# do not use μ and ν to ensure that provided map is used
cost = emd2(similar(μ), similar(ν), C, Tulip.Optimizer(); plan=P)
@test cost emd2(μ, ν, C, Tulip.Optimizer())
# do not use μ and ν to ensure that provided map is used
cost = emd2(similar(μ), similar(ν), C, T(); plan=P)
@test cost emd2(μ, ν, C, T())
end
end

# https://github.com/JuliaOptimalTransport/OptimalTransport.jl/issues/71
Expand Down Expand Up @@ -106,8 +111,10 @@ Random.seed!(100)
xs = rand(μ, m)
μdiscrete = fill(1 / m, m)
C = pairwise(Euclidean(), xs', (1:length(νprobs))'; dims=2)
c2 = emd2(μdiscrete, νprobs, C, Tulip.Optimizer())
@test c2 c rtol = 1e-1
for optimizer in (Tulip.Optimizer(), GLPK.Optimizer())
c2 = emd2(μdiscrete, νprobs, C, optimizer)
@test c2 c rtol = 1e-1
end
end

@testset "discrete case" begin
Expand Down Expand Up @@ -164,8 +171,10 @@ Random.seed!(100)
# DiscreteNonParametric sorts the support automatically, here we have to sort
# manually
C = pairwise(Euclidean(), μsupport', νsupport'; dims=2)
c2 = emd2(μprobs, νprobs, C, Tulip.Optimizer())
@test c2 c rtol = 1e-5
for optimizer in (Tulip.Optimizer(), GLPK.Optimizer())
c2 = emd2(μprobs, νprobs, C, optimizer)
@test c2 c rtol = 1e-5
end

# compare with POT
# disabled currently since https://github.com/PythonOT/POT/issues/169 causes bounds
Expand Down Expand Up @@ -222,8 +231,10 @@ Random.seed!(100)
μprobs = normalize!(pdf(μ, μsupp'), 1)
νprobs = normalize!(pdf(ν, νsupp'), 1)
C = pairwise(SqEuclidean(), μsupp', νsupp'; dims=2)
@test emd2(μprobs, νprobs, C, Tulip.Optimizer()) ot_cost(SqEuclidean(), μ, ν) rtol =
1e-3
for optimizer in (Tulip.Optimizer(), GLPK.Optimizer())
@test emd2(μprobs, νprobs, C, optimizer) ot_cost(SqEuclidean(), μ, ν) rtol =
1e-3
end

# Use hcubature integration to perform ``\\int c(x,T(x)) d\\mu``
T = ot_plan(SqEuclidean(), μ, ν)
Expand Down

2 comments on commit c67137b

@devmotion
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JuliaRegistrator
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Registration pull request created: JuliaRegistries/General/51010

After the above pull request is merged, it is recommended that a tag is created on this repository for the registered package version.

This will be done automatically if the Julia TagBot GitHub Action is installed, or can be done manually through the github interface, or via:

git tag -a v0.2.1 -m "<description of version>" c67137b3be1434da4bb8942a593bee5d4b675599
git push origin v0.2.1

Please sign in to comment.