From e872c0091fee9dfd828a1a755b2cbe7755cf1564 Mon Sep 17 00:00:00 2001 From: odow Date: Tue, 23 Jan 2024 13:11:35 +1300 Subject: [PATCH 1/2] Tidy src/variable.jl --- .../examples/general_examples/basic_usage.jl | 2 +- .../examples/mixed_integer/binary_knapsack.jl | 2 +- docs/src/examples/mixed_integer/n_queens.jl | 2 +- .../mixed_integer/section_allocation.jl | 4 +- src/deprecations.jl | 69 ++++ src/problem_depot/problems/mip.jl | 12 +- src/problem_depot/problems/sdp.jl | 8 +- src/variable.jl | 353 ++++++------------ test/test_utilities.jl | 42 +++ 9 files changed, 241 insertions(+), 253 deletions(-) diff --git a/docs/src/examples/general_examples/basic_usage.jl b/docs/src/examples/general_examples/basic_usage.jl index d665ddab8..2e8776759 100644 --- a/docs/src/examples/general_examples/basic_usage.jl +++ b/docs/src/examples/general_examples/basic_usage.jl @@ -104,7 +104,7 @@ evaluate(y) # using GLPK -x = Variable(4, :Int) +x = Variable(4, IntVar) p = minimize(sum(x), x >= 0.5) solve!(p, GLPK.Optimizer; silent_solver = true) evaluate(x) diff --git a/docs/src/examples/mixed_integer/binary_knapsack.jl b/docs/src/examples/mixed_integer/binary_knapsack.jl index eae2f5900..1accb1b37 100644 --- a/docs/src/examples/mixed_integer/binary_knapsack.jl +++ b/docs/src/examples/mixed_integer/binary_knapsack.jl @@ -22,7 +22,7 @@ n = length(w) #- using Convex, GLPK -x = Variable(n, :Bin) +x = Variable(n, BinVar) problem = maximize(dot(p, x), dot(w, x) <= C) solve!(problem, GLPK.Optimizer) evaluate(x) diff --git a/docs/src/examples/mixed_integer/n_queens.jl b/docs/src/examples/mixed_integer/n_queens.jl index 94dfa1052..0b6e49662 100644 --- a/docs/src/examples/mixed_integer/n_queens.jl +++ b/docs/src/examples/mixed_integer/n_queens.jl @@ -6,7 +6,7 @@ include(aux("antidiag.jl")) n = 8 # We encode the locations of the queens with a matrix of binary random variables. -x = Variable((n, n), :Bin) +x = Variable((n, n), BinVar) # Now we impose the constraints: at most one queen on any anti-diagonal, at most one queen on any diagonal, and we must have exactly one queen per row and per column. ## At most one queen on any anti-diagonal diff --git a/docs/src/examples/mixed_integer/section_allocation.jl b/docs/src/examples/mixed_integer/section_allocation.jl index 585412776..49a28f99f 100644 --- a/docs/src/examples/mixed_integer/section_allocation.jl +++ b/docs/src/examples/mixed_integer/section_allocation.jl @@ -7,7 +7,7 @@ # 10,000 or a large number would mean the student can not attend that section). # # The goal will be to get an allocation matrix $X$, where $X_{ij} = 1$ if -# student $i$ is assigned to section $j$ and $0$ otherwise. +# student $i$ is assigned to section $j$ and $0$ otherwise. using Convex, GLPK aux(str) = joinpath(@__DIR__, "aux_files", str) # path to auxiliary files @@ -15,7 +15,7 @@ aux(str) = joinpath(@__DIR__, "aux_files", str) # path to auxiliary files # Load our preference matrix, `P` include(aux("data.jl")) -X = Variable(size(P), :Bin) +X = Variable(size(P), BinVar) # We want every student to be assigned to exactly one section. So, every row # must have exactly one non-zero entry. In other words, the sum of all the diff --git a/src/deprecations.jl b/src/deprecations.jl index 39c508f30..39b7be9d4 100644 --- a/src/deprecations.jl +++ b/src/deprecations.jl @@ -49,3 +49,72 @@ function Base.in(x::AbstractExpr, y::Symbol) ) return isposdef(x) end + +# Compatability with old `sets` model. +# +# Only dispatch to these methods when at least one set is given. +function Variable( + size::Tuple{Int,Int}, + sign::Sign, + set::Symbol, + sets::Symbol..., +) + @warn( + "Using symbols in `Variable` constructor is deprecated. Use " * + "`Convex.BinVar` or `Convex.IntVar` instead.", + maxlog = 1, + ) + sets = [set, sets...] + x = if :Bin in sets + Variable(size, sign, BinVar) + elseif :Int in sets + Variable(size, sign, IntVar) + else + Variable(size, sign, ContVar) + end + if :Semidefinite in sets + add_constraint!(x, x ⪰ 0) + end + return x +end + +function Variable(sign::Sign, set::Symbol, sets::Symbol...) + return Variable((1, 1), sign, set, sets...) +end + +function Variable(size::Tuple{Int,Int}, set::Symbol, sets::Symbol...) + return Variable(size, NoSign(), set, sets...) +end + +function Variable(m::Int, set::Symbol, sets::Symbol...) + return Variable((m, 1), NoSign(), set, sets...) +end + +function Variable(set::Symbol, sets::Symbol...) + return Variable((1, 1), NoSign(), set, sets...) +end + +function ComplexVariable(size::Tuple{Int,Int}, set::Symbol, sets::Symbol...) + @warn( + "Using symbols in `ComplexVariable` constructor is deprecated. Use " * + "`isposdef(x)` to enforce semidefiniteness instead of `:Semidefinite.", + maxlog = 1, + ) + sets = [set, sets...] + if :Bin in sets + throw(ArgumentError("Complex variables cannot be restricted to binary")) + elseif :Int in sets + throw( + ArgumentError("Complex variables cannot be restricted to integer"), + ) + end + x = ComplexVariable(size) + if :Semidefinite in sets + add_constraint!(x, x ⪰ 0) + end + return x +end + +function ComplexVariable(set::Symbol, sets::Symbol...) + return ComplexVariable((1, 1), set, sets...) +end diff --git a/src/problem_depot/problems/mip.jl b/src/problem_depot/problems/mip.jl index 8c6df5e12..aa99afc4b 100644 --- a/src/problem_depot/problems/mip.jl +++ b/src/problem_depot/problems/mip.jl @@ -46,7 +46,7 @@ end @test p.optval ≈ 5 atol = atol rtol = rtol end - x = Variable(2, :Int) + x = Variable(2, IntVar) p = minimize(sum(x), x >= 4.3; numeric_type = T) if test @@ -69,7 +69,7 @@ end @test p.optval ≈ 12 atol = atol rtol = rtol end - x = Variable(2, :Int) + x = Variable(2, IntVar) p = minimize(norm(x, 1), x[1] >= 4.3; numeric_type = T) if test @@ -80,7 +80,7 @@ end @test p.optval ≈ 5 atol = atol rtol = rtol end - x = Variable(2, :Int) + x = Variable(2, IntVar) p = minimize(sum(x), x[1] >= 4.3, x >= 0; numeric_type = T) if test @@ -91,7 +91,7 @@ end @test p.optval ≈ 5 atol = atol rtol = rtol end - x = Variable(2, :Int) + x = Variable(2, IntVar) p = minimize(sum(x), x >= 0.5; numeric_type = T) if test @@ -110,7 +110,7 @@ end rtol, ::Type{T}, ) where {T,test} - x = Variable(2, :Bin) + x = Variable(2, BinVar) p = minimize(sum(x), x >= 0.5; numeric_type = T) if test @@ -121,7 +121,7 @@ end @test p.optval ≈ 2 atol = atol rtol = rtol end - x = Variable(2, :Bin) + x = Variable(2, :BinVar) p = minimize(sum(x), x[1] >= 0.5, x >= 0; numeric_type = T) if test diff --git a/src/problem_depot/problems/sdp.jl b/src/problem_depot/problems/sdp.jl index b0fffb12b..e8883b8bf 100644 --- a/src/problem_depot/problems/sdp.jl +++ b/src/problem_depot/problems/sdp.jl @@ -6,7 +6,7 @@ rtol, ::Type{T}, ) where {T,test} - y = Variable((2, 2), :Semidefinite) + y = Semidefinite((2, 2)) p = minimize(y[1, 1]; numeric_type = T) # @fact problem_vexity(p) --> ConvexVexity() @@ -15,7 +15,7 @@ @test p.optval ≈ 0 atol = atol rtol = rtol end - y = Variable((3, 3), :Semidefinite) + y = Semidefinite((3, 3)) p = minimize(y[1, 1], y[2, 2] == 1; numeric_type = T) # @fact problem_vexity(p) --> ConvexVexity() @@ -27,7 +27,7 @@ # Solution is obtained as y[2,2] -> infinity # This test fails on Mosek. See # https://github.com/JuliaOpt/Mosek.jl/issues/29 - # y = Variable((2, 2), :Semidefinite) + # y = Semidefinite((2, 2)) # p = minimize(y[1, 1], y[1, 2] == 1; numeric_type = T) # # @fact problem_vexity(p) --> ConvexVexity() @@ -43,7 +43,7 @@ @test p.optval ≈ 1 atol = atol rtol = rtol end - y = Variable((3, 3), :Semidefinite) + y = Semidefinite((3, 3)) p = minimize(tr(y), y[2, 1] <= 4, y[2, 2] >= 3; numeric_type = T) # @fact problem_vexity(p) --> ConvexVexity() diff --git a/src/variable.jl b/src/variable.jl index 556b5f921..1ba163051 100644 --- a/src/variable.jl +++ b/src/variable.jl @@ -1,8 +1,3 @@ -############################################################################# -# variable.jl -# Defines Variable, which is a subtype of AbstractExpr -############################################################################# - """ VarType @@ -38,7 +33,6 @@ to allow users to modify those values or add a constraint. """ abstract type AbstractVariable <: AbstractExpr end -# Default implementation of `AbstractVariable` interface """ get_constraints(x::AbstractVariable) @@ -120,106 +114,129 @@ _value(x::AbstractVariable) = x.value Sets the current value of `x` to `v`. """ -function set_value! end - set_value!(x::AbstractVariable, ::Nothing) = x.value = nothing function set_value!(x::AbstractVariable, v::AbstractArray) - size(x) == size(v) || + if size(x) != size(v) throw(DimensionMismatch("Variable and value sizes do not match!")) + end if iscomplex(x) && !(eltype(v) <: Complex) - v = complex.(v) + return x.value = complex.(v) end return x.value = v end function set_value!(x::AbstractVariable, v::AbstractVector) - size(x, 2) == 1 || throw( - DimensionMismatch( - "Cannot set value of a variable of size $(size(x)) to a vector", - ), - ) - size(x, 1) == length(v) || + if size(x, 2) != 1 + throw( + DimensionMismatch( + "Cannot set value of a variable of size $(size(x)) to a vector", + ), + ) + elseif size(x, 1) != length(v) throw(DimensionMismatch("Variable and value sizes do not match!")) + end if iscomplex(x) && !(eltype(v) <: Complex) - v = complex.(v) + return x.value = complex.(v) end return x.value = v end function set_value!(x::AbstractVariable, v::Number) - size(x) == (1, 1) || + if size(x) != (1, 1) throw(DimensionMismatch("Variable and value sizes do not match!")) + end if sign(x) == ComplexSign() && !(v isa Complex) - v = complex(v) + return x.value = complex(v) end return x.value = v end -# End of `AbstractVariable` interface - -# Some helpers for the constructors for `Variable` -iscomplex(sign::Sign) = sign == ComplexSign() -iscomplex(x::AbstractVariable) = iscomplex(sign(x)) -iscomplex(x::AbstractExpr) = iscomplex(sign(x)) -iscomplex(x::Complex) = true -iscomplex(x::Real) = false -iscomplex(x::AbstractArray{<:Complex}) = true -iscomplex(x::AbstractArray{<:Real}) = false - -# A concrete implementation of the `AbstractVariable` interface + +""" + fix!(x::AbstractVariable, v = value(x)) + +Fixes `x` to `v`. It is subsequently treated as a constant in future +optimization problems. See also [`free!`](@ref). +""" +function fix!(x::AbstractVariable) + if _value(x) === nothing + error("This variable has no value yet; cannot fix value to nothing!") + end + vexity!(x, ConstVexity()) + return x +end + +function fix!(x::AbstractVariable, v) + set_value!(x, v) + return fix!(x) +end + +""" + free!(x::AbstractVariable) + +Frees a previously [`fix!`](@ref)'d variable `x`, to treat it once again as a +variable to optimize over. +""" +function free!(x::AbstractVariable) + vexity!(x, AffineVexity()) + return x +end + +function Base.isequal(x::AbstractVariable, y::AbstractVariable) + return x.id_hash == y.id_hash +end + +Base.hash(x::AbstractVariable, h::UInt) = hash(x.id_hash, h) + +iscomplex(x::Sign) = x == ComplexSign() + +iscomplex(x::Union{AbstractVariable,AbstractExpr}) = iscomplex(sign(x)) + +iscomplex(::Union{Complex,AbstractArray{<:Complex}}) = true + +iscomplex(::Union{Real,AbstractArray{<:Real}}) = false + mutable struct Variable <: AbstractVariable - """ - Every `AbstractExpr` has a `head`; for a Variable it is set to `:variable`. - """ + # Every `AbstractExpr` has a `head`; for a Variable it is set to `:variable`. head::Symbol - """ - A unique identifying hash used for caching. - """ + # A unique identifying hash used for caching. id_hash::UInt64 - """ - The current value of the variable. Defaults to `nothing` until the - variable has been [`fix!`](@ref)'d to a particular value, or the - variable has been used in a problem which has been solved, at which - point the optimal value is populated into this field. - """ + # The current value of the variable. Defaults to `nothing` until the + # variable has been [`fix!`](@ref)'d to a particular value, or the + # variable has been used in a problem which has been solved, at which + # point the optimal value is populated into this field. value::Union{Value,Nothing} - """ - The size of the variable. Scalar variables have size `(1,1)`; - `d`-dimensional vectors have size `(d, 1)`, and `n` by `m` matrices - have size `(n,m)`. - """ + # The size of the variable. Scalar variables have size `(1,1)`; + # `d`-dimensional vectors have size `(d, 1)`, and `n` by `m` matrices + # have size `(n,m)`. size::Tuple{Int,Int} - """ - `AffineVexity()` unless the variable is `fix!`'d, in which case it is - `ConstVexity()`. Accessed by `vexity(v::Variable)`. To check if a - `Variable` is fixed, use `vexity(v) == ConstVexity()`. - """ + # `AffineVexity()` unless the variable is `fix!`'d, in which case it is + # `ConstVexity()`. Accessed by `vexity(v::Variable)`. To check if a + # `Variable` is fixed, use `vexity(v) == ConstVexity()`. vexity::Vexity - """ - The sign of the variable. Can be `Positive()`, `Negative()`, `NoSign()` - (i.e. real), or `ComplexSign()`. Accessed by `sign(v::Variable)`. - """ + # The sign of the variable. Can be `Positive()`, `Negative()`, `NoSign()` + # (i.e. real), or `ComplexSign()`. Accessed by `sign(v::Variable)`. sign::Sign - """ - Vector of constraints which are enforced whenever the variable is used - in a problem. - """ + # Vector of constraints which are enforced whenever the variable is used + # in a problem. constraints::Vector{Constraint} - """ - The `VarType` of the variable (binary, integer, or continuous). - """ + # The `VarType` of the variable (binary, integer, or continuous). vartype::VarType - function Variable(size::Tuple{Int,Int}, sign::Sign, vartype::VarType) + + function Variable( + size::Tuple{Int,Int} = (1, 1), + sign::Sign = NoSign(), + vartype::VarType = ContVar, + ) if iscomplex(sign) if vartype == ContVar return ComplexVariable(size) - else - throw( - ArgumentError( - "vartype must be `ContVar` for complex variables; got vartype = $vartype", - ), - ) end + throw( + ArgumentError( + "vartype must be `ContVar` for complex variables; got vartype = $vartype", + ), + ) end this = new( :variable, @@ -236,10 +253,19 @@ mutable struct Variable <: AbstractVariable end end -function Base.isequal(x::AbstractVariable, y::AbstractVariable) - return x.id_hash == y.id_hash +function Variable(size::Tuple{Int,Int}, vartype::VarType) + return Variable(size, NoSign(), vartype) end -Base.hash(x::AbstractVariable, h::UInt) = hash(x.id_hash, h) + +Variable(m::Int, n::Int, args...) = Variable((m, n), args...) + +Variable(m::Int, args...) = Variable((m, 1), args...) + +function Variable(sign::Sign, vartype::VarType = ContVar) + return Variable((1, 1), sign, vartype) +end + +Variable(vartype::VarType) = Variable((1, 1), NoSign(), vartype) mutable struct ComplexVariable <: AbstractVariable head::Symbol @@ -248,11 +274,12 @@ mutable struct ComplexVariable <: AbstractVariable value::Union{Value,Nothing} vexity::Vexity constraints::Vector{Constraint} - function ComplexVariable(sz::Tuple{Int,Int}) + + function ComplexVariable(size::Tuple{Int,Int} = (1, 1)) return new( :ComplexVariable, rand(UInt64), - sz, + size, nothing, AffineVexity(), Constraint[], @@ -260,186 +287,36 @@ mutable struct ComplexVariable <: AbstractVariable end end -vartype(::ComplexVariable) = ContVar -Base.sign(::ComplexVariable) = ComplexSign() - -Variable(size::Tuple{Int,Int}, sign::Sign) = Variable(size, sign, ContVar) -function Variable(size::Tuple{Int,Int}, vartype::VarType) - return Variable(size, NoSign(), vartype) -end -Variable(size::Tuple{Int,Int}) = Variable(size, NoSign(), ContVar) +ComplexVariable(m::Int, args...) = ComplexVariable((m, 1), args...) -function Variable(m::Int, n::Int, sign::Sign, vartype::VarType) - return Variable((m, n), sign, vartype) -end -Variable(m::Int, n::Int, sign::Sign) = Variable((m, n), sign, ContVar) -Variable(m::Int, n::Int, vartype::VarType) = Variable((m, n), NoSign(), vartype) -Variable(m::Int, n::Int) = Variable((m, n), NoSign(), ContVar) -ComplexVariable(m::Int, n::Int) = ComplexVariable((m, n)) - -Variable(m::Int, sign::Sign, vartype::VarType) = Variable((m, 1), sign, vartype) -Variable(m::Int, sign::Sign) = Variable((m, 1), sign, ContVar) -Variable(m::Int, vartype::VarType) = Variable((m, 1), NoSign(), vartype) -Variable(m::Int) = Variable((m, 1), NoSign(), ContVar) -ComplexVariable(m::Int) = ComplexVariable((m, 1)) - -Variable(sign::Sign, vartype::VarType) = Variable((1, 1), sign, vartype) -Variable(sign::Sign) = Variable((1, 1), sign, ContVar) -Variable(vartype::VarType) = Variable((1, 1), NoSign(), vartype) -Variable() = Variable((1, 1), NoSign(), ContVar) -ComplexVariable() = ComplexVariable((1, 1)) - -### -# Compatability with old `sets` model -# Only dispatch to these methods when at least one set is given; -# otherwise dispatch to the inner constructors. -# There are choices of sign, no sign, or `ComplexVariable` and various -# ways to enter the size for each. We will start with: -# Case 1: with sign -function Variable( - size::Tuple{Int,Int}, - sign::Sign, - first_set::Symbol, - more_sets::Symbol..., -) - sets = [first_set] - append!(sets, more_sets) - if :Bin in sets - vartype = BinVar - elseif :Int in sets - vartype = IntVar - else - vartype = ContVar - end - x = Variable(size, sign, vartype) - if :Semidefinite in sets - add_constraint!(x, x ⪰ 0) - end - return x -end -function Variable( - m::Int, - n::Int, - sign::Sign, - first_set::Symbol, - more_sets::Symbol..., -) - return Variable((m, n), sign, first_set, more_sets...) -end -function Variable(m::Int, sign::Sign, first_set::Symbol, more_sets::Symbol...) - return Variable((m, 1), sign, first_set, more_sets...) -end -function Variable(sign::Sign, first_set::Symbol, more_sets::Symbol...) - return Variable((1, 1), sign, first_set, more_sets...) -end +ComplexVariable(m::Int, n::Int, args...) = ComplexVariable((m, n), args...) -# Case 2: no sign -function Variable(size::Tuple{Int,Int}, first_set::Symbol, more_sets::Symbol...) - return Variable(size, NoSign(), first_set, more_sets...) -end -function Variable(m::Int, n::Int, first_set::Symbol, more_sets::Symbol...) - return Variable((m, n), NoSign(), first_set, more_sets...) -end -function Variable(m::Int, first_set::Symbol, more_sets::Symbol...) - return Variable((m, 1), NoSign(), first_set, more_sets...) -end -function Variable(first_set::Symbol, more_sets::Symbol...) - return Variable((1, 1), NoSign(), first_set, more_sets...) -end +vartype(::ComplexVariable) = ContVar -# Case 3: ComplexVariable -function ComplexVariable( - size::Tuple{Int,Int}, - first_set::Symbol, - more_sets::Symbol..., -) - sets = [first_set] - append!(sets, more_sets) - if :Bin in sets - throw(ArgumentError("Complex variables cannot be restricted to binary")) - elseif :Int in sets - throw( - ArgumentError("Complex variables cannot be restricted to integer"), - ) - end - x = ComplexVariable(size) - if :Semidefinite in sets - add_constraint!(x, x ⪰ 0) - end - return x -end -function ComplexVariable( - m::Int, - n::Int, - first_set::Symbol, - more_sets::Symbol..., -) - return ComplexVariable((m, n), first_set, more_sets...) -end -function ComplexVariable(m::Int, first_set::Symbol, more_sets::Symbol...) - return ComplexVariable((m, 1), first_set, more_sets...) -end -function ComplexVariable(first_set::Symbol, more_sets::Symbol...) - return ComplexVariable((1, 1), first_set, more_sets...) -end +Base.sign(::ComplexVariable) = ComplexSign() Semidefinite(m::Integer) = Semidefinite(m, m) function Semidefinite(m::Integer, n::Integer) - if m == n - x = Variable((m, m), NoSign(), ContVar) - add_constraint!(x, x ⪰ 0) - return x - else + if m != n error("Semidefinite matrices must be square") end + x = Variable((m, m), NoSign(), ContVar) + add_constraint!(x, x ⪰ 0) + return x end Semidefinite((m, n)::Tuple{Integer,Integer}) = Semidefinite(m, n) function HermitianSemidefinite(m::Integer, n::Integer = m) - if m == n - x = ComplexVariable((m, n)) - add_constraint!(x, x ⪰ 0) - return x - else + if m != n error("`HermitianSemidefinite` matrices must be square") end + x = ComplexVariable((m, n)) + add_constraint!(x, x ⪰ 0) + return x end function HermitianSemidefinite((m, n)::Tuple{Integer,Integer}) return HermitianSemidefinite(m, n) end - -""" - fix!(x::AbstractVariable, v = value(x)) - -Fixes `x` to `v`. It is subsequently treated as a constant in future -optimization problems. See also [`free!`](@ref). -""" -function fix! end - -function fix!(x::AbstractVariable) - _value(x) === nothing && - error("This variable has no value yet; cannot fix value to nothing!") - vexity!(x, ConstVexity()) - return x -end - -function fix!(x::AbstractVariable, v) - set_value!(x, v) - return fix!(x) -end - -""" - free!(x::AbstractVariable) - -Frees a previously [`fix!`](@ref)'d variable `x`, to treat it once again as a -variable to optimize over. -""" -function free! end - -function free!(x::AbstractVariable) - vexity!(x, AffineVexity()) - return x -end diff --git a/test/test_utilities.jl b/test/test_utilities.jl index 2504568b9..6d73f4c50 100644 --- a/test/test_utilities.jl +++ b/test/test_utilities.jl @@ -1205,6 +1205,48 @@ function test_scalar_fn_objective_square() return end +function test_variable_errors() + @test_throws ArgumentError Variable((2, 2), ComplexSign(), BinVar) + return +end + +function test_complex_variable_errors() + y = @test_logs (:warn,) ComplexVariable(:Semidefinite) + @test size(y) == (1, 1) + return +end + +function test_set_value_errors() + x = Variable() + @test_throws DimensionMismatch set_value!(x, [1.0 2.0; 3.0 4.0]) + @test_throws DimensionMismatch set_value!(x, [1.0, 2.0]) + return +end + +function test_set_value_nothing() + x = Variable() + @test_throws( + ErrorException("Value of the variable is yet to be calculated"), + evaluate(x) + ) + set_value!(x, 1.0) + @test x.value == 1.0 + set_value!(x, nothing) + @test x.value === nothing + return +end + +function test_set_value_complex() + x = ComplexVariable() + set_value!(x, 1.0) + @test x.value == 1.0 + 0.0im + y = ComplexVariable(2) + set_value!(y, [1.0, 2.0]) + @test y.value == [1.0 + 0.0im, 2.0 + 0.0im] + return +end + + end # TestUtilities TestUtilities.runtests() From 56e8132ceb78aea76e08c440b51bd3bd71a0b110 Mon Sep 17 00:00:00 2001 From: Oscar Dowson Date: Tue, 23 Jan 2024 17:11:52 +1300 Subject: [PATCH 2/2] Apply suggestions from code review --- src/problem_depot/problems/mip.jl | 2 +- test/test_utilities.jl | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/problem_depot/problems/mip.jl b/src/problem_depot/problems/mip.jl index aa99afc4b..ccb19d232 100644 --- a/src/problem_depot/problems/mip.jl +++ b/src/problem_depot/problems/mip.jl @@ -121,7 +121,7 @@ end @test p.optval ≈ 2 atol = atol rtol = rtol end - x = Variable(2, :BinVar) + x = Variable(2, BinVar) p = minimize(sum(x), x[1] >= 0.5, x >= 0; numeric_type = T) if test diff --git a/test/test_utilities.jl b/test/test_utilities.jl index 6d73f4c50..3988329e9 100644 --- a/test/test_utilities.jl +++ b/test/test_utilities.jl @@ -1246,7 +1246,6 @@ function test_set_value_complex() return end - end # TestUtilities TestUtilities.runtests()