Skip to content

Commit dd2f6c9

Browse files
authored
AbstractVariable interface; allow variables to carry constraints (#358)
* Add `AbstractVariable` interface Docs fixes Tweak types * Remove type parametrization from variables * Add `_value` accessor * Update NEWS.md * Fix rebase * Fix typo * Add some tests * Loosen error types in tests for 1.0 compat * only run CI on PRs, master, and tags
1 parent c8779e3 commit dd2f6c9

35 files changed

+861
-190
lines changed

.travis.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ os:
66
julia:
77
- 1.0
88
- 1.4
9+
if: branch = master OR tag IS present OR type = pull_request
910
notifications:
1011
email: false
1112
jobs:

NEWS.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,27 @@
1+
# Changes in v0.13.4
2+
3+
* You can now create your own variable types by subtyping `AbstractVariable`.
4+
See the
5+
[docs](https://www.juliaopt.org/Convex.jl/dev/advanced/#Custom-Variable-Types-1)
6+
for more information. You can also add constraints directly to a variable
7+
using `add_constraint!`. ([#358](https://github.com/JuliaOpt/Convex.jl/pull/358))
8+
* Accessors `vexity(x::Variable)`, `sign(x::Variable)`, and
9+
`evaluate(x::Variable)` should now be the preferred way to access properties
10+
of a variable; likewise use `set_value!` to set the initial value of a
11+
variable. ([#358](https://github.com/JuliaOpt/Convex.jl/pull/358))
12+
* To create integer or binary constraints, use the `VarType` enum (e.g.
13+
`Variable(BinVar)`). Access or set this via `vartype` and `vartype!`.
14+
([#358](https://github.com/JuliaOpt/Convex.jl/pull/358))
15+
16+
# Changes in v0.13.3
17+
18+
* Make [`add_constraint!`](https://github.com/jump-dev/Convex.jl/pull/381)
19+
actually add the constraint to the problem.
20+
21+
# Changes in v0.13.2
22+
23+
* Add [`Convex.MAXDIGITS`](https://github.com/jump-dev/Convex.jl/pull/379)
24+
125
# Changes in v0.13.1
226

327
* Allow disabling DCP warnings ([#372](https://github.com/JuliaOpt/Convex.jl/pull/372))

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name = "Convex"
22
uuid = "f65535da-76fb-5f13-bab9-19810c17039a"
3-
version = "0.13.3"
3+
version = "0.13.4"
44

55
[deps]
66
AbstractTrees = "1520ce14-60c1-5f80-bbc7-55ef81b5835c"

docs/examples_literate/general_examples/basic_usage.jl

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ p.constraints += [x >= 1; x <= 10; x[2] <= 5; x[1] + x[4] - x[2] <= 10]
3434
solve!(p, solver)
3535

3636
println(round(p.optval, digits=2))
37-
println(round.(x.value, digits=2))
37+
println(round.(evaluate(x), digits=2))
3838
println(evaluate(x[1] + x[4] - x[2]))
3939

4040
# ### Matrix Variables and promotions
@@ -55,8 +55,8 @@ y = Variable()
5555
## X is a 2 x 2 variable, and y is scalar. X' + y promotes y to a 2 x 2 variable before adding them
5656
p = minimize(norm(X) + y, 2 * X <= 1, X' + y >= 1, X >= 0, y >= 0)
5757
solve!(p, solver)
58-
println(round.(X.value, digits=2))
59-
println(y.value)
58+
println(round.(evaluate(X), digits=2))
59+
println(evaluate(y))
6060
p.optval
6161

6262
# ### Norm, exponential and geometric mean
@@ -75,7 +75,7 @@ x = Variable(4)
7575
p = satisfy(norm(x) <= 100, exp(x[1]) <= 5, x[2] >= 7, geomean(x[3], x[4]) >= x[2])
7676
solve!(p, solver)
7777
println(p.status)
78-
x.value
78+
evaluate(x)
7979

8080
# ### SDP cone and Eigenvalues
8181

@@ -92,7 +92,7 @@ y = Variable((2, 2))
9292
## SDP constraints
9393
p = minimize(x + y[1, 1], isposdef(y), x >= 1, y[2, 1] == 1)
9494
solve!(p, solver)
95-
y.value
95+
evaluate(y)
9696

9797
# ### Mixed integer program
9898
#
@@ -109,6 +109,5 @@ using GLPK
109109
x = Variable(4, :Int)
110110
p = minimize(sum(x), x >= 0.5)
111111
solve!(p, GLPK.Optimizer)
112-
x.value
113-
112+
evaluate(x)
114113
#-

docs/examples_literate/general_examples/chebyshev_center.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,5 +36,5 @@ plot(x, x -> -x * a1[1] / a1[2] + b[1] / a1[2])
3636
plot!(x, x -> -x * a2[1]/ a2[2] + b[2] / a2[2])
3737
plot!(x, x -> -x * a3[1]/ a3[2] + b[3] / a3[2])
3838
plot!(x, x -> -x * a4[1]/ a4[2] + b[4] / a4[2])
39-
plot!(x_c.value[1] .+ r.value * cos.(theta), x_c.value[2] .+ r.value * sin.(theta), linewidth = 2)
39+
plot!(evaluate(x_c)[1] .+ evaluate(r) * cos.(theta), evaluate(x_c)[2] .+ evaluate(r) * sin.(theta), linewidth = 2)
4040
plot!(title ="Largest Euclidean ball lying in a 2D polyhedron", legend = nothing)

docs/examples_literate/general_examples/logistic_regression.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,6 @@ solve!(problem, () -> SCS.Optimizer(verbose=false))
2828
# Let's see how well the model fits.
2929
using Plots
3030
logistic(x::Real) = inv(exp(-x) + one(x))
31-
perm = sortperm(vec(X*beta.value))
31+
perm = sortperm(vec(X*evaluate(beta)))
3232
plot(1:n, (Y[perm] .+ 1)/2, st=:scatter)
33-
plot!(1:n, logistic.(X*beta.value)[perm])
33+
plot!(1:n, logistic.(X*evaluate(beta))[perm])

docs/examples_literate/general_examples/max_entropy.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,4 @@ problem.optval
2828

2929
#-
3030

31-
x.value
31+
evaluate(x)

docs/examples_literate/mixed_integer/aux_files/antidiag.jl

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,7 @@
99
# Please read expressions.jl first.
1010
#############################################################################
1111
import Convex.sign, Convex.monotonicity, Convex.curvature, Convex.evaluate, Convex.conic_form!
12-
using Convex: AbstractExpr, Nondecreasing, ConstVexity, UniqueConicForms, has_conic_form, cache_conic_form!, get_conic_form
13-
using LinearAlgebra, SparseArrays
12+
using Convex: AbstractExpr, ConstVexity, Nondecreasing, has_conic_form, cache_conic_form, get_conic_form
1413
export antidiag
1514

1615
### Diagonal
@@ -67,7 +66,7 @@ antidiag(x::AbstractExpr, k::Int=0) = AntidiagAtom(x, k)
6766
# 3. We populate coeff with 1s at the correct indices
6867
# The canonical form will then be:
6968
# coeff * x - d = 0
70-
function conic_form!(x::AntidiagAtom, unique_conic_forms::UniqueConicForms=UniqueConicForms())
69+
function conic_form!(x::AntidiagAtom, unique_conic_forms::Convex.UniqueConicForms)
7170
if !has_conic_form(unique_conic_forms, x)
7271
(num_rows, num_cols) = x.children[1].size
7372
k = x.k

docs/examples_literate/optimization_with_complex_variables/phase_recovery_using_MaxCut.jl

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,12 +70,13 @@ c1 = diag(U) == 1
7070
c2 = U in :SDP
7171
p = minimize(objective,c1,c2)
7272
solve!(p, () -> SCS.Optimizer(verbose=0))
73-
U.value
73+
evaluate(U)
74+
7475

7576
#-
7677

7778
# Verify if the rank of $U$ is 1:
78-
B, C = eigen(U.value);
79+
B, C = eigen(evaluate(U));
7980
length([e for e in B if(abs(real(e))>1e-4)])
8081

8182
#-

docs/examples_literate/optimization_with_complex_variables/power_flow_optimization.jl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,12 @@ output = matopen("Res.mat")
3636
names(output)
3737
outputData = read(output, "Wres");
3838
Wres = outputData
39-
real_diff = real(W.value) - real(Wres);
40-
imag_diff = imag(W.value) - imag(Wres);
39+
real_diff = real(evaluate(W)) - real(Wres);
40+
imag_diff = imag(evaluate(W)) - imag(Wres);
4141
@test real_diff zeros(n, n) atol = TOL
4242
@test imag_diff zeros(n, n) atol = TOL
4343

44-
real_diff = real(W.value) - (real(W.value))';
45-
imag_sum = imag(W.value) + (imag(W.value))';
44+
real_diff = real(evaluate(W)) - (real(evaluate(W)))';
45+
imag_sum = imag(evaluate(W)) + (imag(evaluate(W)))';
4646
@test real_diff zeros(n, n) atol = TOL
4747
@test imag_diff zeros(n, n) atol = TOL

0 commit comments

Comments
 (0)