Skip to content

Commit

Permalink
Update to support Julia 1.0 (#239)
Browse files Browse the repository at this point in the history
* updated code to julia 1.0

little changes + ECOS is now the first tested Solver

norm is imported

norm is restored

starting fixing tests

undefined arrays fixed

testing diag function

import Base./

iterate implemented + import functions from LinearAlgebra

many tests are fixed up to test_sdp.jl

fix diagm

diagm fixed in tests

+(::Array{Float64,2}, ::Float64) fixed

+(x::Array{Float64,2}, y::Number) implemented

diagm is fixed in sdp_constraints.jl

fix norm function

assert is fixed in power_to_socp.jl

all assert issues fixed in power_to_socp.jl

cat function fixed in stack.jl

test_socp.jl fixed

test_params.jl fixed

fixes based on review

explicit solver is added to Problem function

order of arguments changed in Problem function

evaluate(x::AdditionAtom) fixed, starting rewriting tests

evaluate(x::AdditionAtom) fixed

satisfy function is fixed

ArgumentError implemented to diagm function

fix! function is fixed

fix! fixed again

diagandlowerpart in conic_form! function is fixed

hvcat implemented for types AbstractExpr & AbstractExprOrValue

hvcat fixed

hvcat exported

solver argument removed from Problem function

type Problem fixed

argument order in function Problem restored

eye functions fixed

trace => tr fixed

trace => tr fixed in tests

norm => opnorm fixed in operatornorm.jl

fixing tests finished

replacing Diagonal

reduce redundancy of hvcat

stack.jl cleaned

fix test failures due to random seed in test_lp.jl

reducing conv threshold of SCSSolver to 1e-12

reducing conv threshold of SCSSolver to 1e-12

skip problematic max/min atom tests for SCS solver

several changes based on second round of review

ctranspose => adjoint & CTransposeAtom => AdjointAtom

comment out hvcat

uncomment hvcat

trying to fix tests for SCS solver

tests for SCS solver fixed

comment in add_subtract.jl added + deprecated.jl removed

hcat/vcat/vect with Value arguments commented out

hcat uncommented

uncomment vcat

uncomment vect

test vect

test vcat

stack.jl cleaned

dims=1 => dims=Val(1) for vcat and dim=2 => dims=Val(2) for hcat with
Value arguments

changes in index.jl & fixed mutable struct in power_to_socp.jl

* Set the SCS lower bound for testing to 0.4.0

It was upper bounded at 0.4.0 for Julia 0.6 support.

* srand is now Random.seed!

* Remove unused dependency on Compat

The package no longer supports Julia 0.6 or earlier.

* Extend diagm for AbstractExpr using the Pair interface

This is consistent with how one otherwise uses diagm.

* Load kron from LinearAlgebra instead of Base

* Update coverage submission step for Pkg3

* Reinstate upper bound on MathProgBase at 0.8 (#3)

* Remove testing on Julia nightly

This is in keeping with general JuliaOpt practices.

* Remove introduced mutability of SimpleInequalityExpression

It was changed amongst the other 1.0 compatibility changes but does not
seem to be necessary.

* Overwrite Base.vect for numbers with the same implementation as Base

Fixes #241

* Overload broadcasted instead of broadcast

This fixes the case where an `AbstractExpr` occurs in in a fused
broadcast expression.

Co-authored-by: Letif Mones <letif.mones.research@gmail.com>
Co-authored-by: Alex Arslan <ararslan@comcast.net>
  • Loading branch information
3 people committed Nov 5, 2018
1 parent d245768 commit 4152844
Show file tree
Hide file tree
Showing 61 changed files with 564 additions and 606 deletions.
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
6 changes: 3 additions & 3 deletions src/atoms/affine/add_subtract.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@
# Please read expressions.jl first.
#############################################################################

import Base.broadcast
export +, -, broadcast
export +, -
export sign, curvature, monotonicity, evaluate

### Unary Negation
Expand Down Expand Up @@ -98,7 +97,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
23 changes: 11 additions & 12 deletions src/atoms/affine/multiply_divide.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@
# Please read expressions.jl first.
#############################################################################

import Base.broadcast
export broadcast
import Base.Broadcast.broadcasted
export sign, monotonicity, curvature, evaluate, conic_form!

### Scalar and matrix multiplication
Expand Down Expand Up @@ -83,11 +82,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 +102,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,14 +170,14 @@ 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
return get_conic_form(unique_conic_forms, x)
end

function broadcast(::typeof(*), x::Constant, y::AbstractExpr)
function broadcasted(::typeof(*), x::Constant, y::AbstractExpr)
if x.size == (1, 1) || y.size == (1, 1)
return x * y
elseif size(y,1) < size(x,1) && size(y,1) == 1
Expand All @@ -189,10 +188,10 @@ function broadcast(::typeof(*), x::Constant, y::AbstractExpr)
return DotMultiplyAtom(x, y)
end
end
broadcast(::typeof(*), y::AbstractExpr, x::Constant) = DotMultiplyAtom(x, y)
broadcasted(::typeof(*), y::AbstractExpr, x::Constant) = DotMultiplyAtom(x, y)

# if neither is a constant it's not DCP, but might be nice to support anyway for eg MultiConvex
function broadcast(::typeof(*), x::AbstractExpr, y::AbstractExpr)
function broadcasted(::typeof(*), x::AbstractExpr, y::AbstractExpr)
if x.size == (1, 1) || y.size == (1, 1)
return x * y
elseif vexity(x) == ConstVexity()
Expand All @@ -203,7 +202,7 @@ function broadcast(::typeof(*), x::AbstractExpr, y::AbstractExpr)
return DotMultiplyAtom(y, x)
end
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)
broadcasted(::typeof(*), x::Value, y::AbstractExpr) = DotMultiplyAtom(Constant(x), y)
broadcasted(::typeof(*), x::AbstractExpr, y::Value) = DotMultiplyAtom(Constant(y), x)
broadcasted(::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)
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
Loading

0 comments on commit 4152844

Please sign in to comment.