Skip to content

Commit

Permalink
Merge pull request #46 from focusenergy/julia-1-update
Browse files Browse the repository at this point in the history
Julia 1.0 compatibility updates.
  • Loading branch information
rdeits authored Jan 6, 2019
2 parents b4ae998 + bb04ba7 commit e0c4060
Show file tree
Hide file tree
Showing 12 changed files with 86 additions and 92 deletions.
17 changes: 3 additions & 14 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ language: julia
os:
- linux
julia:
- 0.6
- 1.0
- nightly
notifications:
email: false
Expand All @@ -15,20 +15,9 @@ matrix:
allow_failures:
- julia: nightly
branches:
only:
only:
- master

## uncomment and modify the following lines to manually install system packages
#addons:
# apt: # apt-get for linux
# packages:
# - gfortran
#before_script: # homebrew for mac
# - if [ $TRAVIS_OS_NAME = osx ]; then brew install gcc; fi

## uncomment the following lines to override the default test script
#script:
# - julia -e 'Pkg.clone(pwd()); Pkg.build("ConditionalJuMP"); Pkg.test("ConditionalJuMP"; coverage=true)'
after_success:
# push coverage results to Codecov
- julia -e 'cd(Pkg.dir("ConditionalJuMP")); Pkg.add("Coverage"); using Coverage; Codecov.submit(Codecov.process_folder())'
- julia -e 'import Pkg; Pkg.add("Coverage"); using Coverage; Codecov.submit(Codecov.process_folder())'
5 changes: 3 additions & 2 deletions REQUIRE
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
julia 0.6
JuMP 0.16 0.19
julia 1.0
IntervalArithmetic 0.9
JuMP 0.16 0.19
Nullables
52 changes: 24 additions & 28 deletions appveyor.yml
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
environment:
matrix:
- JULIA_URL: "https://julialang-s3.julialang.org/bin/winnt/x86/0.6/julia-0.6-latest-win32.exe"
- JULIA_URL: "https://julialang-s3.julialang.org/bin/winnt/x64/0.6/julia-0.6-latest-win64.exe"
- JULIA_URL: "https://julialangnightlies-s3.julialang.org/bin/winnt/x86/julia-latest-win32.exe"
- JULIA_URL: "https://julialangnightlies-s3.julialang.org/bin/winnt/x64/julia-latest-win64.exe"

## uncomment the following lines to allow failures on nightly julia
## (tests will run but not make your overall status red)
#matrix:
# allow_failures:
# - JULIA_URL: "https://julialangnightlies-s3.julialang.org/bin/winnt/x86/julia-latest-win32.exe"
# - JULIA_URL: "https://julialangnightlies-s3.julialang.org/bin/winnt/x64/julia-latest-win64.exe"
- julia_version: 0.7
- julia_version: 1
- julia_version: nightly

platform:
- x86 # 32-bit
- x64 # 64-bit

# # Uncomment the following lines to allow failures on nightly julia
# # (tests will run but not make your overall status red)
# matrix:
# allow_failures:
# - julia_version: nightly

branches:
only:
Expand All @@ -24,24 +26,18 @@ notifications:
on_build_status_changed: false

install:
- ps: "[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12"
# If there's a newer build queued for the same PR, cancel this one
- ps: if ($env:APPVEYOR_PULL_REQUEST_NUMBER -and $env:APPVEYOR_BUILD_NUMBER -ne ((Invoke-RestMethod `
https://ci.appveyor.com/api/projects/$env:APPVEYOR_ACCOUNT_NAME/$env:APPVEYOR_PROJECT_SLUG/history?recordsNumber=50).builds | `
Where-Object pullRequestId -eq $env:APPVEYOR_PULL_REQUEST_NUMBER)[0].buildNumber) { `
throw "There are newer queued builds for this pull request, failing early." }
# Download most recent Julia Windows binary
- ps: (new-object net.webclient).DownloadFile(
$env:JULIA_URL,
"C:\projects\julia-binary.exe")
# Run installer silently, output to C:\projects\julia
- C:\projects\julia-binary.exe /S /D=C:\projects\julia
- ps: iex ((new-object net.webclient).DownloadString("https://raw.githubusercontent.com/JuliaCI/Appveyor.jl/version-1/bin/install.ps1"))

build_script:
# Need to convert from shallow to complete for Pkg.clone to work
- IF EXIST .git\shallow (git fetch --unshallow)
- C:\projects\julia\bin\julia -e "versioninfo();
Pkg.clone(pwd(), \"ConditionalJuMP\"); Pkg.build(\"ConditionalJuMP\")"
- echo "%JL_BUILD_SCRIPT%"
- C:\julia\bin\julia -e "%JL_BUILD_SCRIPT%"

test_script:
- C:\projects\julia\bin\julia -e "Pkg.test(\"ConditionalJuMP\")"
- echo "%JL_TEST_SCRIPT%"
- C:\julia\bin\julia -e "%JL_TEST_SCRIPT%"

# # Uncomment to support code coverage upload. Should only be enabled for packages
# # which would have coverage gaps without running on Windows
# on_success:
# - echo "%JL_CODECOV_SCRIPT%"
# - C:\julia\bin\julia -e "%JL_CODECOV_SCRIPT%"
2 changes: 1 addition & 1 deletion examples/block_with_wall.jl
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const Δt = 0.1
const u_max = 10

function update(x::State, u)
contact_force = ifelse(@?(x.q <= 0),
contact_force = ifelse_conditional(@?(x.q <= 0),
-k * x.q,
zero(x.q))
acceleration = u + contact_force
Expand Down
15 changes: 8 additions & 7 deletions examples/complementarity.jl
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
module Complementarity

using JuMP, ConditionalJuMP, Cbc
using Base.Test
using Test
using Pkg

# A simple complementarity-based time-stepping rigid body simulation. All
# notation is taken from Stewart & Trinkle "An Implicit Time-Stepping Scheme for
# Rigid Body Dynamics with Coulomb Friction". This particular example solves
# for all N timesteps simultaneously. That's not actually necessary, but it makes
# the code a bit simpler to read.
# the code a bit simpler to read.
#
# The model consists of a point mass (visualized as a brick) moving in two dimensions
# with gravity and a single planar surface at y = 0.
# with gravity and a single planar surface at y = 0.

const h = 0.05
const μ = 0.5
Expand Down Expand Up @@ -63,7 +64,7 @@ end

"""
Simulate the system using the LCP update. This creates and solves a small
model for every time step 1:N.
model for every time step 1:N.
"""
function simulate(q0, v0, N)
q, v = q0, v0
Expand Down Expand Up @@ -97,7 +98,7 @@ function optimize(q0, v0, N)::Vector{LCPUpdate{Float64}}
end
solve(m)
getvalue.(results)
end
end

q0 = [-1, 0.5]
v0 = [2, 0.5]
Expand All @@ -115,8 +116,8 @@ v = [r.v for r in results1]
@test q[end] [-0.16892500000000002, 0]
@test v[end] [0, 0]

if Pkg.installed("DrakeVisualizer") !== nothing
@eval using DrakeVisualizer;
if haskey(Pkg.installed(), "DrakeVisualizer")
@eval using DrakeVisualizer;
@eval using CoordinateTransformations
@eval using GeometryTypes
DrakeVisualizer.any_open_windows() || DrakeVisualizer.new_window()
Expand Down
6 changes: 3 additions & 3 deletions examples/friction.jl
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
using JuMP, ConditionalJuMP, Cbc
using Base.Test
using Test

const viscosity = 100
const stiffness = 100
Expand All @@ -8,9 +8,9 @@ const normal_force = stiffness * penetration
const μ = 0.5
const Δt = 0.05

# A very simple stick-slip dynamics. Frictional force is equal to
# A very simple stick-slip dynamics. Frictional force is equal to
# -(viscosity * velocity), clipped to lie within the friction cone
# at ±(μ * normal_force).
# at ±(μ * normal_force).
function dynamics(x)
q = x[1]
v = x[2]
Expand Down
7 changes: 4 additions & 3 deletions examples/multicontact_complementarity.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ module Complementarity
using Polyhedra
using StaticArrays
using JuMP, ConditionalJuMP, Cbc
using Base.Test
using Test
using Pkg

rot2(θ) = SMatrix{2, 2}(cos(θ), -sin(θ), sin(θ), cos(θ))

Expand Down Expand Up @@ -191,7 +192,7 @@ results2 = optimize(q0, v0, env, N)
results_seeded = optimize(q0, v0, env, results1)
@test all([r1.q r2.q for (r1, r2) in zip(results1, results_seeded)])

if Pkg.installed("DrakeVisualizer") !== nothing
if haskey(Pkg.installed(), "DrakeVisualizer")
@eval using DrakeVisualizer;
@eval using CoordinateTransformations
DrakeVisualizer.any_open_windows() || DrakeVisualizer.new_window()
Expand All @@ -206,4 +207,4 @@ if Pkg.installed("DrakeVisualizer") !== nothing
end
end

end
end
12 changes: 5 additions & 7 deletions examples/polyhedra.jl
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
using Base.Test
using Test
using JuMP
using Cbc
using ConditionalJuMP
using Polyhedra
using LinearAlgebra

# In this example, we search for the point closest to the origin in the union
# of a list of convex polyhedra
Expand All @@ -14,7 +15,7 @@ function ConditionalJuMP.Conditional(op::typeof(in), x::AbstractVector, P::HRepr
(&)([@?(h.a' * x <= h.β) for h in allhalfspaces(P)]...)
end

# A simple L1-norm objective we can minimize (since the Cbc
# A simple L1-norm objective we can minimize (since the Cbc
function l1norm_objective(x::AbstractVector{Variable})
model = first(x).m
y = @variable(model, [1:length(x)], basename="y", lowerbound=0)
Expand All @@ -26,10 +27,10 @@ function l1norm_objective(x::AbstractVector{Variable})
end

# P1 is a box from [-1.5, -1] to [-0.5, 1]
P1 = hrep(vcat(eye(2), -eye(2)), [-0.5, 1, 1.5, 1])
P1 = hrep(vcat(Matrix(I, 2, 2), -Matrix(I, 2, 2)), [-0.5, 1, 1.5, 1])

# P2 is a box from [1, -1] to [2, 1]
P2 = hrep(vcat(eye(2), -eye(2)), [2., 1, -1, 1])
P2 = hrep(vcat(Matrix(I, 2, 2), -Matrix(I, 2, 2)), [2., 1, -1, 1])

m = Model(solver=CbcSolver(logLevel=0))
@variable(m, -5 <= x[1:2] <= 5)
Expand All @@ -40,6 +41,3 @@ m = Model(solver=CbcSolver(logLevel=0))
solve(m)
x = getvalue(x)
@test x [-0.5, 0]



29 changes: 17 additions & 12 deletions src/ConditionalJuMP.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ using JuMP
using JuMP: GenericAffExpr, GenericRangeConstraint, Variable, AbstractJuMPScalar
using IntervalArithmetic: Interval
import Base: <=, ==, >=, !, &, hash, show
using Printf
using Nullables

export @disjunction,
@implies,
Expand All @@ -32,7 +34,7 @@ end

"""
Naive O(N^2) simplification. Slower for very large expressions, but allocates
no memory and is solidly faster for expressions with < 100 variables.
no memory and is solidly faster for expressions with < 100 variables.
"""
function simplify_inplace!(e::JuMP.GenericAffExpr{T, Variable}) where T
i1 = 1
Expand Down Expand Up @@ -62,7 +64,7 @@ end

"""
O(N) simplification, but with a substantially larger constant cost due to the
need to construct a Dict.
need to construct a Dict.
"""
function simplify_dict!(e::JuMP.GenericAffExpr{T, Variable}) where T
vars = Variable[]
Expand Down Expand Up @@ -258,8 +260,8 @@ struct IndicatorMap
z_idx::Base.RefValue{Int}
end

IndicatorMap(m::Model) = IndicatorMap(m,
Dict{Conditional, AffExpr}(),
IndicatorMap(m::Model) = IndicatorMap(m,
Dict{Conditional, AffExpr}(),
Vector{Vector{Implication}}(),
Ref(1),
Ref(1))
Expand Down Expand Up @@ -404,17 +406,20 @@ function disjunction!(indmap::IndicatorMap, imps::Union{Tuple, AbstractArray})
push!(indmap.disjunctions, collect(imps))
end

function disjunction!(indmap::IndicatorMap,
function disjunction!(indmap::IndicatorMap,
conditions::Union{Tuple{Vararg{Conditional}},
<:AbstractArray{Conditional}})
disjunction!(indmap, (c -> (c => Conditional())).(conditions))
end

Broadcast.broadcastable(i::IndicatorMap) = Ref(i)
Broadcast.broadcastable(m::Model) = Ref(m)

implies!(m::Model, imps::Implication...) = disjunction!(m, imps)

implies!(m::Model, imps::Pair...) = implies!(m, convert.(Implication, imps)...)

Base.convert(::Type{Conditional}, ::Void) = Conditional()
Base.convert(::Type{Conditional}, ::Nothing) = Conditional()

function implies!(m::Model, imp::Implication)
c1, c2 = imp
Expand Down Expand Up @@ -522,7 +527,7 @@ function switch!(m::Model, args::Pair{<:Conditional, <:AbstractArray}...)
end


function Base.ifelse(c::Conditional, v1, v2)
function ifelse_conditional(c::Conditional, v1, v2)
@assert size(v1) == size(v2)
m = getmodel(c)
y = newcontinuousvar(m)
Expand All @@ -532,7 +537,7 @@ function Base.ifelse(c::Conditional, v1, v2)
y
end

function Base.ifelse(c::Conditional, v1::AbstractArray, v2::AbstractArray)
function ifelse_conditional(c::Conditional, v1::AbstractArray, v2::AbstractArray)
@assert size(v1) == size(v2)
m = getmodel(c)
y = newcontinuousvar(m, size(v1))
Expand Down Expand Up @@ -578,7 +583,7 @@ function warmstart!(m::Model, fix=false)
for implications in indmap.disjunctions
violations = Nullable{Float64}[_getvalue(first(i)) for i in implications]
if !any(isnull, violations)
best_match = indmin(get.(violations))
best_match = argmin(get.(violations))
for i in eachindex(violations)
imp = implications[i]
lhs, rhs = imp
Expand Down Expand Up @@ -624,8 +629,8 @@ end
"""
Gurobi doesn't understand constant terms in the objective, which can
affect the way the relative MIP gap is interpreted. To work around this,
we'll replace the constant term k with an affine term 1*x for a new
variable x fixed to equal k.
we'll replace the constant term k with an affine term 1*x for a new
variable x fixed to equal k.
"""
function handle_constant_objective!(m::Model)
x = @variable(m, basename="x_{objective_constant}")
Expand All @@ -637,4 +642,4 @@ function handle_constant_objective!(m::Model)
end


end
end
11 changes: 5 additions & 6 deletions src/macros.jl
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
_conditionalize(ex) = esc(ex)

is_function_broadcast(ex::Expr) = ex.head == :(.) && ex.args[2].head == :tuple
is_function_broadcast(ex::Expr) = ex.head == :(.) && !isa(ex.args[2], QuoteNode) && x.args[2].head == :tuple
is_operator_broadcast(ex::Expr) = ex.head == :(call) && isa(ex.args[1], Symbol) && string(ex.args[1])[1] === '.'


function _conditionalize_function_broadcast(ex::Expr)
Expr(:call, :_all_conditional, Expr(:call, GlobalRef(Base, :broadcast), :_conditional, esc(ex.args[1]), esc.(ex.args[2].args)...))
end
Expand All @@ -11,6 +12,7 @@ function _conditionalize_operator_broadcast(ex::Expr)
Expr(:call, :_all_conditional, Expr(:call, GlobalRef(Base, :broadcast), :_conditional, esc(Symbol(string(ex.args[1])[2:end])), esc.(ex.args[2:end])...))
end


function _conditionalize(ex::Expr)
if is_function_broadcast(ex)
_conditionalize_function_broadcast(ex)
Expand All @@ -27,10 +29,7 @@ function _conditionalize(ex::Expr)
end
end

macro ?(ex)
_conditionalize(ex)
end

eval(:(macro $(Symbol("?"))(ex) _conditionalize(ex) end))

macro implies(m, args...)
Expr(:call, :implies!, esc(m), _conditionalize.(args)...)
Expand All @@ -45,5 +44,5 @@ macro switch(args...)
end

macro ifelse(c, v1, v2)
Expr(:call, :ifelse, _conditionalize(c), v1, v2)
Expr(:call, :ifelse_conditional, _conditionalize(c), v1, v2)
end
1 change: 1 addition & 0 deletions test/REQUIRE
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
Cbc
Polyhedra 0.3
Nullables
Loading

0 comments on commit e0c4060

Please sign in to comment.