Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update to support Julia 1.0 #239

Merged
merged 15 commits into from
Nov 5, 2018
Merged
Show file tree
Hide file tree
Changes from 11 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: 3 additions & 7 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ os:
- linux
- osx
julia:
- 0.6
- 0.7
- 1.0
notifications:
email: false
sudo: false
Expand All @@ -13,10 +14,5 @@ addons:
- liblapack-dev
- libgmp-dev
- libglpk-dev
script:
- if [[ -a .git/shallow ]]; then git fetch --unshallow; fi
- julia -e 'Pkg.clone(pwd())'
- julia -e 'Pkg.test("Convex", coverage=true)'
after_success:
- julia -e 'Pkg.add("Coverage")'
- julia -e 'cd(Pkg.dir("Convex")); using Coverage; Coveralls.submit(process_folder())'
- julia -e 'using Pkg; Pkg.add("Coverage"); using Coverage; Coveralls.submit(process_folder())'
5 changes: 2 additions & 3 deletions REQUIRE
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
julia 0.6 0.7-
MathProgBase 0.5 0.8
julia 0.7
MathProgBase 0.7 0.8
DataStructures
Compat 0.24
8 changes: 2 additions & 6 deletions src/Convex.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ __precompile__()

module Convex
import DataStructures
importall Base.Operators
using Compat
using LinearAlgebra
using SparseArrays

global DEFAULT_SOLVER = nothing
### modeling framework
Expand Down Expand Up @@ -49,9 +49,6 @@ include("atoms/lp_cone/min.jl")
include("atoms/lp_cone/sumlargest.jl")
include("atoms/lp_cone/dotsort.jl")




### SOC atoms
include("atoms/second_order_cone/norm.jl") # also includes some lp atoms
include("atoms/second_order_cone/norm2.jl")
Expand Down Expand Up @@ -83,7 +80,6 @@ include("atoms/exp_+_sdp_cone/logdet.jl")
### utilities
include("utilities/show.jl")
include("utilities/iteration.jl")
include("utilities/deprecated.jl")
include("utilities/broadcast.jl")

#Temporary workaround for memory leak (https://github.com/JuliaOpt/Convex.jl/issues/83)
Expand Down
3 changes: 2 additions & 1 deletion src/atoms/affine/add_subtract.jl
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,8 @@ function curvature(x::AdditionAtom)
end

function evaluate(x::AdditionAtom)
return sum([evaluate(child) for child in x.children])
# broadcast function is used here instead of sum to support addition between scalars and arrays
return broadcast(+, map(evaluate, x.children)...)
end

function conic_form!(x::AdditionAtom, unique_conic_forms::UniqueConicForms=UniqueConicForms())
Expand Down
3 changes: 1 addition & 2 deletions src/atoms/affine/conv.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
# Handles convolution between a constant vector and an expression vector.
#############################################################################

import Base.conv
export conv

function conv(x::Value, y::AbstractExpr)
Expand All @@ -19,4 +18,4 @@ function conv(x::Value, y::AbstractExpr)
return X*y
end

conv(x::AbstractExpr, y::Value) = conv(y, x)
conv(x::AbstractExpr, y::Value) = conv(y, x)
2 changes: 1 addition & 1 deletion src/atoms/affine/diag.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
#############################################################################

# k >= min(num_cols, num_rows) || k <= -min(num_rows, num_cols)
import Base.diag
import LinearAlgebra.diag
export diag
#export sign, curvature, monotonicity, evaluate

Expand Down
14 changes: 9 additions & 5 deletions src/atoms/affine/diagm.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
# Please read expressions.jl first.
#############################################################################

import Base.diagm
export diagm
import LinearAlgebra.diagm, LinearAlgebra.Diagonal
export diagm, Diagonal

struct DiagMatrixAtom <: AbstractExpr
head::Symbol
Expand All @@ -22,7 +22,7 @@ struct DiagMatrixAtom <: AbstractExpr
elseif num_cols == 1
sz = num_rows
else
error("Only vectors are allowed for diagm. Did you mean to use diag?")
throw(ArgumentError("Only vectors are allowed for diagm/Diagonal. Did you mean to use diag?"))
end

children = (x, )
Expand All @@ -46,10 +46,14 @@ function curvature(x::DiagMatrixAtom)
end

function evaluate(x::DiagMatrixAtom)
return diagm(vec(evaluate(x.children[1])))
return Diagonal(vec(evaluate(x.children[1])))
end

diagm(x::AbstractExpr) = DiagMatrixAtom(x)
function diagm((d, x)::Pair{<:Integer, <:AbstractExpr})
d == 0 || throw(ArgumentError("only the main diagonal is supported"))
return DiagMatrixAtom(x)
end
Diagonal(x::AbstractExpr) = DiagMatrixAtom(x)

function conic_form!(x::DiagMatrixAtom, unique_conic_forms::UniqueConicForms=UniqueConicForms())
if !has_conic_form(unique_conic_forms, x)
Expand Down
2 changes: 1 addition & 1 deletion src/atoms/affine/dot.jl
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import Base.dot, Base.vecdot
import LinearAlgebra.dot
export vecdot, dot


Expand Down
14 changes: 7 additions & 7 deletions src/atoms/affine/index.jl
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import Base: getindex, to_index
export IndexAtom, getindex

const ArrayOrNothing = Union{AbstractArray, Void}
const ArrayOrNothing = Union{AbstractArray, Nothing}

struct IndexAtom <: AbstractExpr
head::Symbol
Expand Down Expand Up @@ -54,7 +54,7 @@ function conic_form!(x::IndexAtom, unique_conic_forms::UniqueConicForms=UniqueCo

if x.inds == nothing
sz = length(x.cols) * length(x.rows)
J = Array{Int}(sz)
J = Array{Int}(undef, sz)
k = 1

num_rows = x.children[1].size[1]
Expand All @@ -78,14 +78,14 @@ end

## API Definition begins

getindex(x::AbstractExpr, rows::AbstractArray{T, 1}, cols::AbstractArray{T, 1}) where {T <: Real} = IndexAtom(x, rows, cols)
getindex(x::AbstractExpr, inds::AbstractArray{T, 1}) where {T <: Real} = IndexAtom(x, inds)
getindex(x::AbstractExpr, rows::AbstractVector{T}, cols::AbstractVector{T}) where {T<:Real} = IndexAtom(x, rows, cols)
getindex(x::AbstractExpr, inds::AbstractVector{<:Real}) = IndexAtom(x, inds)
getindex(x::AbstractExpr, ind::Real) = getindex(x, ind:ind)
getindex(x::AbstractExpr, row::Real, col::Real) = getindex(x, row:row, col:col)
getindex(x::AbstractExpr, row::Real, cols::AbstractArray{T, 1}) where {T <: Real} = getindex(x, row:row, cols)
getindex(x::AbstractExpr, rows::AbstractArray{T, 1}, col::Real) where {T <: Real} = getindex(x, rows, col:col)
getindex(x::AbstractExpr, row::Real, cols::AbstractVector{<:Real}) = getindex(x, row:row, cols)
getindex(x::AbstractExpr, rows::AbstractVector{<:Real}, col::Real) = getindex(x, rows, col:col)
# XXX todo: speed test; there are lots of possible solutions for this
function getindex(x::AbstractExpr, I::AbstractArray{Bool,2})
function getindex(x::AbstractExpr, I::AbstractMatrix{Bool})
return [xi for (xi,ii) in zip(x,I) if ii]
end
function getindex(x::AbstractExpr, I::AbstractVector{Bool})
Expand Down
4 changes: 2 additions & 2 deletions src/atoms/affine/inner_product.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ export inner_product

function inner_product(x::AbstractExpr,y::AbstractExpr)
if x.size==y.size && x.size[1] == x.size[2]
return(real(trace(x'*y)))
return(real(tr(x'*y)))
else
error("Arguments must be square matrix of same dimension")
end
end

inner_product(x::Value, y::AbstractExpr) = inner_product(Constant(x),y)
inner_product(x::AbstractExpr, y::Value) = inner_product(x,Constant(y))
inner_product(x::AbstractExpr, y::Value) = inner_product(x,Constant(y))
4 changes: 2 additions & 2 deletions src/atoms/affine/kron.jl
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import Base.kron
import LinearAlgebra.kron
export kron

function kron(a::Value, b::AbstractExpr)
Expand Down Expand Up @@ -28,4 +28,4 @@ function kron(a::AbstractExpr, b::Value)
push!(rows, foldl(hcat, row))
end
return foldl(vcat, rows)
end
end
10 changes: 5 additions & 5 deletions src/atoms/affine/multiply_divide.jl
Original file line number Diff line number Diff line change
Expand Up @@ -83,11 +83,11 @@ function conic_form!(x::MultiplyAtom, unique_conic_forms::UniqueConicForms=Uniqu
# left matrix multiplication
elseif x.children[1].head == :constant
objective = conic_form!(x.children[2], unique_conic_forms)
objective = kron(speye(x.size[2]), x.children[1].value) * objective
objective = kron(sparse(1.0I, x.size[2], x.size[2]), x.children[1].value) * objective
# right matrix multiplication
else
objective = conic_form!(x.children[1], unique_conic_forms)
objective = kron(x.children[2].value', speye(x.size[1])) * objective
objective = kron(x.children[2].value', sparse(1.0I, x.size[1], x.size[1])) * objective
end
cache_conic_form!(unique_conic_forms, x, objective)
end
Expand All @@ -103,7 +103,7 @@ end

*(x::Value, y::AbstractExpr) = MultiplyAtom(Constant(x), y)
*(x::AbstractExpr, y::Value) = MultiplyAtom(x, Constant(y))
/(x::AbstractExpr, y::Value) = MultiplyAtom(x, Constant(1./y))
/(x::AbstractExpr, y::Value) = MultiplyAtom(x, Constant(1 ./ y))

### .*
# All constructors of this check (and so this function requires)
Expand Down Expand Up @@ -171,7 +171,7 @@ function conic_form!(x::DotMultiplyAtom, unique_conic_forms::UniqueConicForms=Un
var = var*ones(1,size(coeff,1))
end

const_multiplier = spdiagm(vec(coeff)) # used to be spdiagm((vec(coeff),), (0,)), not sure why
const_multiplier = spdiagm(0 => vec(coeff))
objective = const_multiplier * conic_form!(var, unique_conic_forms)
cache_conic_form!(unique_conic_forms, x, objective)
end
Expand Down Expand Up @@ -205,5 +205,5 @@ function broadcast(::typeof(*), x::AbstractExpr, y::AbstractExpr)
end
broadcast(::typeof(*), x::Value, y::AbstractExpr) = DotMultiplyAtom(Constant(x), y)
broadcast(::typeof(*), x::AbstractExpr, y::Value) = DotMultiplyAtom(Constant(y), x)
broadcast(::typeof(/), x::AbstractExpr, y::Value) = DotMultiplyAtom(Constant(1./y), x)
broadcast(::typeof(/), x::AbstractExpr, y::Value) = DotMultiplyAtom(Constant(1 ./ y), x)
# x ./ y and x / y for x constant, y variable is defined in second_order_cone.qol_elemwise.jl
22 changes: 11 additions & 11 deletions src/atoms/affine/partialtrace.jl
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ function evaluate(x::PartialTraceAtom)

subsystem = function(sys)
function term(ρ, j::Int)
a = speye(1)
b = speye(1)
a = sparse(1.0I, 1, 1)
b = sparse(1.0I, 1, 1)
i_sys = 1
for dim in dims
if i_sys == sys
Expand All @@ -55,8 +55,8 @@ function evaluate(x::PartialTraceAtom)
a = kron(a, v')
b = kron(b, v)
else
a = kron(a, speye(dim))
b = kron(b, speye(dim))
a = kron(a, sparse(1.0I, dim, dim))
b = kron(b, sparse(1.0I, dim, dim))
end
i_sys += 1
end
Expand All @@ -65,15 +65,15 @@ function evaluate(x::PartialTraceAtom)
return sum([term(ρ, j) for j in 1:dims[sys]])
end
sub_systems = [subsystem(i) for i in 1:length(dims)]
a = eye(1)
a = Matrix(1.0I, 1, 1)
for i in 1:length(dims)
if i == x.sys
continue
else
a = kron(a,sub_systems[i])
end
end
return trace(sub_systems[x.sys])*a
return tr(sub_systems[x.sys])*a
end


Expand All @@ -87,8 +87,8 @@ function conic_form!(x::PartialTraceAtom, unique_conic_forms::UniqueConicForms=U
# in the system we want to trace out
# This function returns every term in the sum
function term(ρ, j::Int)
a = speye(1)
b = speye(1)
a = sparse(1.0I, 1, 1)
Copy link
Contributor

Choose a reason for hiding this comment

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

This is a pretty awkward way to form a 1x1 sparse identity matrix. But that's Julia 1.0, I guess...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

There's also spdiagm(0 => [1.0]) but yeah it's unfortunate.

For dense arrays there's Eye from https://github.com/JuliaArrays/FillArrays.jl

b = sparse(1.0I, 1, 1)
i_sys = 1
for dim in dims
if i_sys == sys
Expand All @@ -98,8 +98,8 @@ function conic_form!(x::PartialTraceAtom, unique_conic_forms::UniqueConicForms=U
a = kron(a, v')
b = kron(b, v)
else
a = kron(a, speye(dim))
b = kron(b, speye(dim))
a = kron(a, sparse(1.0I, dim, dim))
b = kron(b, sparse(1.0I, dim, dim))
end
i_sys += 1
end
Expand All @@ -113,4 +113,4 @@ function conic_form!(x::PartialTraceAtom, unique_conic_forms::UniqueConicForms=U
return get_conic_form(unique_conic_forms, x)
end

partialtrace(x::AbstractExpr, sys::Int, dim::Vector) = PartialTraceAtom(x, sys, dim)
partialtrace(x::AbstractExpr, sys::Int, dim::Vector) = PartialTraceAtom(x, sys, dim)
2 changes: 1 addition & 1 deletion src/atoms/affine/reshape.jl
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ struct ReshapeAtom <: AbstractExpr
if m * n != get_vectorized_size(x)
error("Cannot reshape expression of size $(x.size) to ($(m), $(n))")
end
return new(:reshape, object_id(x), (x,), (m, n))
return new(:reshape, objectid(x), (x,), (m, n))
end
end

Expand Down
47 changes: 25 additions & 22 deletions src/atoms/affine/stack.jl
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import Base.vcat, Base.hcat
export vcat, hcat, HcatAtom
import Base.vcat, Base.hcat, Base.hvcat
export vcat, hcat, hvcat, HcatAtom
export sign, curvature, monotonicity, evaluate, conic_form!

struct HcatAtom <: AbstractExpr
Expand Down Expand Up @@ -35,7 +35,7 @@ function curvature(x::HcatAtom)
end

function evaluate(x::HcatAtom)
return hcat([evaluate(c) for c in x.children]...)
return hcat(map(evaluate, x.children)...)
end


Expand All @@ -51,7 +51,7 @@ function conic_form!(x::HcatAtom, unique_conic_forms::UniqueConicForms=UniqueCon
for objective in objectives
for id in keys(objective)
if !(id in keys(variable_to_sizes))
if id == object_id(:constant)
if id == objectid(:constant)
variable_to_sizes[id] = 1
else
variable_to_sizes[id] = get_vectorized_size(id_to_variables[id])
Expand Down Expand Up @@ -111,26 +111,29 @@ function conic_form!(x::HcatAtom, unique_conic_forms::UniqueConicForms=UniqueCon
end

hcat(args::AbstractExpr...) = HcatAtom(args...)
hcat(args::AbstractExprOrValue...) = HcatAtom([convert(AbstractExpr, arg) for arg in args]...)
hcat(args::Value...) = Base.cat(2, args...)
hcat(args::AbstractExprOrValue...) = HcatAtom(map(arg -> convert(AbstractExpr, arg), args)...)
hcat(args::Value...) = Base.cat(args..., dims=Val(2))


# TODO: implement vertical concatenation in a more efficient way
vcat(args::AbstractExpr...) = transpose(HcatAtom([transpose(arg) for arg in args]...))
vcat(args::AbstractExprOrValue...) = transpose(HcatAtom([transpose(convert(AbstractExpr, arg)) for arg in args]...))
vcat(args::Value...) = Base.cat(1, args...) # Note: this makes general vcat slower for anyone using Convex...


Base.vect(args::T...) where {T<:AbstractExpr} = transpose(HcatAtom([transpose(arg) for arg in args]...))
Base.vect(args::AbstractExpr...) = transpose(HcatAtom([transpose(arg) for arg in args]...))
Base.vect(args::AbstractExprOrValue...) = transpose(HcatAtom([transpose(convert(AbstractExpr,arg)) for arg in args]...))
if Base._oldstyle_array_vcat_
Base.vect(args::Value...) = Base.vcat(args...)
# This is ugly, because the method redefines simple cases like [1,2,3]

else
function Base.vect(args::Value...)
T = Base.promote_typeof(args...)
return copy!(Array{T}(length(args)), args)
vcat(args::AbstractExpr...) = transpose(HcatAtom(map(transpose, args)...))
vcat(args::AbstractExprOrValue...) = transpose(HcatAtom(map(arg -> transpose(convert(AbstractExpr, arg)), args)...))
vcat(args::Value...) = Base.cat(args..., dims=Val(1)) # Note: this makes general vcat slower for anyone using Convex...


function hvcat(rows::Tuple{Vararg{Int}}, args::AbstractExprOrValue...)
nbr = length(rows)
rs = Vector{Any}(undef, nbr)
a = 1
for i = 1:nbr
rs[i] = hcat(args[a:a-1+rows[i]]...)
a += rows[i]
end
return vcat(rs...)
end


Base.vect(args::T...) where {T<:AbstractExpr} = transpose(HcatAtom(map(transpose, args)...))
Base.vect(args::AbstractExpr...) = transpose(HcatAtom(map(transpose, args)...))
Base.vect(args::AbstractExprOrValue...) = transpose(HcatAtom(map(arg -> transpose(convert(AbstractExpr, arg)), args)...))
Base.vect(args::Value...) = collect(args)
Loading