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

Skip terms when printing a large vector of expressions #3759

Merged
merged 3 commits into from
May 28, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
2 changes: 1 addition & 1 deletion docs/src/manual/complex.md
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,7 @@ julia> H = LinearAlgebra.Hermitian([x[1] 1im; -1im -x[2]])
-im -x[2]

julia> @constraint(model, H in HermitianPSDCone())
[x[1] im;
[x[1] im
-im -x[2]] ∈ HermitianPSDCone()
```

Expand Down
12 changes: 6 additions & 6 deletions docs/src/manual/constraints.md
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ julia> @variable(model, X[1:2, 1:2], Symmetric)
X[1,2] X[2,2]

julia> @constraint(model, X == LinearAlgebra.I)
[X[1,1] - 1 X[1,2];
[X[1,1] - 1 X[1,2]
X[1,2] X[2,2] - 1] ∈ Zeros()
```

Expand Down Expand Up @@ -229,7 +229,7 @@ julia> @variable(model, X[1:2, 1:2] in HermitianPSDCone())
real(X[1,2]) - imag(X[1,2]) im real(X[2,2])

julia> @constraint(model, X == LinearAlgebra.I)
[real(X[1,1]) - 1 real(X[1,2]) + imag(X[1,2]) im;
[real(X[1,1]) - 1 real(X[1,2]) + imag(X[1,2]) im
real(X[1,2]) - imag(X[1,2]) im real(X[2,2]) - 1] ∈ Zeros()

julia> @constraint(model, X .== LinearAlgebra.I)
Expand Down Expand Up @@ -1415,7 +1415,7 @@ julia> @variable(model, X[1:2, 1:2])
X[2,1] X[2,2]

julia> @constraint(model, X >= 0, PSDCone())
[X[1,1] X[1,2];
[X[1,1] X[1,2]
X[2,1] X[2,2]] ∈ PSDCone()
```

Expand All @@ -1436,7 +1436,7 @@ julia> Y = [1 2; 2 1]
2 1

julia> @constraint(model, X >= Y, PSDCone())
[X[1,1] - 1 X[1,2] - 2;
[X[1,1] - 1 X[1,2] - 2
X[2,1] - 2 X[2,2] - 1] ∈ PSDCone()
```

Expand All @@ -1461,15 +1461,15 @@ julia> Z = [X[1, 1] X[1, 2]; X[1, 2] X[2, 2]]
X[1,2] X[2,2]

julia> @constraint(model, LinearAlgebra.Symmetric(Z) >= 0, PSDCone())
[X[1,1] X[1,2];
[X[1,1] X[1,2]
X[1,2] X[2,2]] ∈ PSDCone()
```

Note that the lower triangular entries are ignored even if they are
different so use it with caution:
```jldoctest con_psd
julia> @constraint(model, LinearAlgebra.Symmetric(X) >= 0, PSDCone())
[X[1,1] X[1,2];
[X[1,1] X[1,2]
X[1,2] X[2,2]] ∈ PSDCone()
```
(Note the `(2, 1)` element of the constraint is `X[1,2]`, not `X[2,1]`.)
Expand Down
33 changes: 19 additions & 14 deletions src/print.jl
Original file line number Diff line number Diff line change
Expand Up @@ -767,23 +767,34 @@ function function_string(mode, q::GenericQuadExpr)
end

function function_string(mode, vector::Vector{<:AbstractJuMPScalar})
return string("[", join(function_string.(Ref(mode), vector), ", "), "]")
strings = function_string.(Ref(mode), vector)
n = max(div(_TERM_LIMIT_FOR_PRINTING[], 2), 2)
if length(vector) <= n
return string("[", join(strings, ", "), "]")
end
n_lhs = div(n, 2)
i_rhs = length(vector) - (n - n_lhs) + 1
block = _terms_omitted(mode, length(vector) - n)
return string(
"[",
join(vcat(strings[1:n_lhs], block, strings[i_rhs:end]), ", "),
"]",
)
end

function function_string(
::MIME"text/plain",
A::AbstractMatrix{<:AbstractJuMPScalar},
)
str = sprint(show, MIME"text/plain"(), A)
str = sprint() do io
return show(IOContext(io, :limit => true), MIME("text/plain"), A)
end
lines = split(str, '\n')
# We drop the first line with the signature "m×n Array{...}:"
lines = lines[2:end]
popfirst!(lines)
# We replace the first space by an opening `[`
lines[1] = '[' * lines[1][2:end]
for i in 1:length(lines)
lines[i] = lines[i] * (i == length(lines) ? ']' : ';')
end
return join(lines, '\n')
return join(lines, "\n") * "]"
end

function function_string(
Expand Down Expand Up @@ -921,13 +932,7 @@ function constraint_string(mode, constraint_object::AbstractConstraint)
# Leave `mode` untyped to avoid ambiguities!
func_str = function_string(mode, constraint_object)
in_set_str = in_set_string(mode, constraint_object)
if mode == MIME("text/plain")
lines = split(func_str, '\n')
lines[1+div(length(lines), 2)] *= " " * in_set_str
return join(lines, '\n')
else
return func_str * " " * in_set_str
end
return func_str * " " * in_set_str
end

function constraint_string(
Expand Down
17 changes: 7 additions & 10 deletions src/sd.jl
Original file line number Diff line number Diff line change
Expand Up @@ -89,17 +89,14 @@ Consider the following example:
```jldoctest PSDCone
julia> model = Model();

julia> @variable(model, x)
x
julia> @variable(model, x);

julia> a = [ x 2x
2x x];
julia> a = [x 2x; 2x x];

julia> b = [1 2
2 4];
julia> b = [1 2; 2 4];

julia> cref = @constraint(model, a >= b, PSDCone())
[x - 1 2 x - 2;
[x - 1 2 x - 2
2 x - 2 x - 4] ∈ PSDCone()

julia> jump_function(constraint_object(cref))
Expand All @@ -119,7 +116,7 @@ is constrained to belong to the `PositiveSemidefiniteConeSquare`.
julia> using LinearAlgebra # For Symmetric

julia> cref = @constraint(model, Symmetric(a - b) in PSDCone())
[x - 1 2 x - 2;
[x - 1 2 x - 2
2 x - 2 x - 4] ∈ PSDCone()

julia> jump_function(constraint_object(cref))
Expand Down Expand Up @@ -384,7 +381,7 @@ julia> model = Model();
julia> @variable(model, Q[1:2, 1:2]);

julia> @constraint(model, LinearAlgebra.Symmetric(Q) in PSDCone())
[Q[1,1] Q[1,2];
[Q[1,1] Q[1,2]
Q[1,2] Q[2,2]] ∈ PSDCone()
```

Expand All @@ -400,7 +397,7 @@ julia> @variable(model, Q[1:2, 1:2], Symmetric)
Q[1,2] Q[2,2]

julia> @constraint(model, Q in PSDCone())
[Q[1,1] Q[1,2];
[Q[1,1] Q[1,2]
Q[1,2] Q[2,2]] ∈ PSDCone()
```
"""
Expand Down
6 changes: 3 additions & 3 deletions test/test_complex.jl
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ function test_complex_hermitian_constraint()
@constraint(model, c, H in HermitianPSDCone())
@test constraint_object(c).func == [x[1, 1], x[1, 2], x[2, 2], 0.0]
@test function_string(MIME("text/plain"), constraint_object(c)) ==
"[x[1,1] x[1,2];\n x[1,2] x[2,2]]"
"[x[1,1] x[1,2]\n x[1,2] x[2,2]]"
return
end

Expand All @@ -266,11 +266,11 @@ function test_complex_hermitian_inequality_constraint()
@constraint(model, c, H >= 0, HermitianPSDCone())
@test constraint_object(c).func == [x[1, 1], x[1, 2], x[2, 2], 0.0]
@test function_string(MIME("text/plain"), constraint_object(c)) ==
"[x[1,1] x[1,2];\n x[1,2] x[2,2]]"
"[x[1,1] x[1,2]\n x[1,2] x[2,2]]"
@constraint(model, c2, 0 <= H, HermitianPSDCone())
@test constraint_object(c2).func == [x[1, 1], x[1, 2], x[2, 2], 0.0]
@test function_string(MIME("text/plain"), constraint_object(c2)) ==
"[x[1,1] x[1,2];\n x[1,2] x[2,2]]"
"[x[1,1] x[1,2]\n x[1,2] x[2,2]]"
return
end

Expand Down
15 changes: 12 additions & 3 deletions test/test_print.jl
Original file line number Diff line number Diff line change
Expand Up @@ -597,10 +597,10 @@ Max a - b + 2 a1 - 10 x
Subject to
con : a + b - 10 c + c1 - 2 x $le 1
a*b $le 2
[a b;
[a b
b x] $inset $(PSDCone())
[a, b, c] $inset $(MOI.PositiveSemidefiniteConeTriangle(2))
[a b;
[a b
c x] $inset $(PSDCone())
[a, b, c, x] $inset $(MOI.PositiveSemidefiniteConeSquare(2))
soc : [-a + 1, u[1], u[2], u[3]] $inset $(MOI.SecondOrderCone(4))
Expand Down Expand Up @@ -873,7 +873,7 @@ function test_print_hermitian_psd_cone()
H = Hermitian([x[1] 1im; -1im x[2]])
c = @constraint(model, H in HermitianPSDCone())
@test sprint(io -> show(io, MIME("text/plain"), c)) ==
"[x[1] im;\n -im x[2]] $in_sym $(HermitianPSDCone())"
"[x[1] im\n -im x[2]] $in_sym $(HermitianPSDCone())"
@test sprint(io -> show(io, MIME("text/latex"), c)) ==
"\$\$ \\begin{bmatrix}\nx_{1} & im\\\\\n-im & x_{2}\\\\\n\\end{bmatrix} \\in \\text{$(HermitianPSDCone())} \$\$"
return
Expand Down Expand Up @@ -1061,4 +1061,13 @@ function test_skipping_constraints_latex()
return
end

function test_print_omit_vector()
n = 100
model = Model()
@variable(model, x[1:n, 1:n])
@constraint(model, vec(x) >= 0)
@test occursin("9970 terms omitted", sprint(print, model))
return
end

end # TestPrint
Loading