Skip to content

Commit bb19afb

Browse files
authored
Enable matrix norm to finish opnorm transition (#528)
1 parent 72cab28 commit bb19afb

File tree

6 files changed

+28
-43
lines changed

6 files changed

+28
-43
lines changed

benchmark/alternating_minimization.jl

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,8 @@ function alternating_minimization(f, A, M, Y_init, k, MAX_ITERS)
2222
X = Variable(m, k)
2323
Y = Variable(k, n)
2424

25-
objective = (
26-
norm(vec(M .* A) - vec(M .* (X * Y)), 2) +
27-
γ1 * norm(vec(X), 2) +
28-
γ2 * norm(vec(Y), 1)
29-
)
25+
objective =
26+
(norm(M .* A - M .* (X * Y), 2) + γ1 * norm(X, 2) + γ2 * norm(Y, 1))
3027

3128
constraints = [X * Y >= ϵ]
3229

docs/examples_literate/general_examples/basic_usage.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ println(evaluate(x[1] + x[4] - x[2]))
4747
X = Variable(2, 2)
4848
y = Variable()
4949
## X is a 2 x 2 variable, and y is scalar. X' + y promotes y to a 2 x 2 variable before adding them
50-
p = minimize(norm(vec(X)) + y, 2 * X <= 1, X' + y >= 1, X >= 0, y >= 0)
50+
p = minimize(norm(X) + y, 2 * X <= 1, X' + y >= 1, X >= 0, y >= 0)
5151
solve!(p, SCS.Optimizer; silent_solver = true)
5252
println(round.(evaluate(X), digits = 2))
5353
println(evaluate(y))

docs/examples_literate/supplemental_material/paper_examples.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ X = Variable(m, n);
3535
A = randn(p, m);
3636
b = randn(p, n);
3737
@time begin
38-
p = minimize(norm(vec(X)), A * X == b)
38+
p = minimize(norm(X), A * X == b)
3939
end
4040
@time solve!(p, ECOS.Optimizer; silent_solver = true)
4141

@@ -52,6 +52,6 @@ n = 3
5252
A = randn(n, n);
5353
#@time begin
5454
X = Variable(n, n);
55-
p = minimize(norm(vec(X' - A)), X[1, 1] == 1);
55+
p = minimize(norm(X' - A), X[1, 1] == 1);
5656
solve!(p, ECOS.Optimizer; silent_solver = true)
5757
#end

docs/src/release_notes.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ Other changes:
1818
* [Type piracy](https://docs.julialang.org/en/v1/manual/style-guide/#Avoid-type-piracy) of `imag` and `real` has been removed. This should not affect use of Convex. Unfortunately, piracy of `hcat`, `vcat`, and `hvcat` still remains.
1919
* `sumlargesteigs` now enforces that it's argument is hermitian.
2020
* Bugfix: `dot` now correctly complex-conjugates its first argument
21+
* `norm` on `AbstractExpr` objects now supports matrices (treating them like vectors), matching Base's behavior.
2122

2223
## v0.15.4 (October 24, 2023)
2324

src/atoms/second_order_cone/norm.jl

Lines changed: 16 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -8,39 +8,31 @@ norm_fro(x::AbstractExpr) = norm2(vec(x))
88
"""
99
norm(x::AbstractExpr, p::Real=2)
1010
11-
Computes the `p`-norm `‖x‖ₚ = (∑ᵢ |xᵢ|^p)^(1/p)` of a vector expression `x`.
11+
Computes the `p`-norm `‖x‖ₚ = (∑ᵢ |xᵢ|^p)^(1/p)` of a vector expression `x`. Matrices
12+
are vectorized (i.e. `norm(x)` is the same as `norm(vec(x))`.)
1213
1314
This function uses specialized methods for `p=1, 2, Inf`. For `p > 1` otherwise,
1415
this function uses the procedure documented at
1516
[`rational_to_socp.pdf`](https://github.com/jump-dev/Convex.jl/raw/master/docs/supplementary/rational_to_socp.pdf),
1617
based on the paper "Second-order cone programming" by F. Alizadeh and D. Goldfarb,
1718
Mathematical Programming, Series B, 95:3-51, 2001.
1819
19-
!!! warning
20-
For versions of Convex.jl prior to v0.14.0, `norm` on a matrix expression returned
21-
the operator norm ([`opnorm`](@ref)), which matches Julia v0.6 behavior. This functionality
22-
was deprecated since Convex.jl v0.8.0, and has been removed. In the future,
23-
`norm(x, p)` will return `‖vec(x)‖ₚ`, matching the behavior of [`norm`](@ref)
24-
for numeric matrices.
2520
"""
2621
function LinearAlgebra.norm(x::AbstractExpr, p::Real = 2)
27-
if length(size(x)) <= 1 || minimum(size(x)) == 1
28-
# x is a vector
29-
if p == 1
30-
return norm_1(x)
31-
elseif p == 2
32-
return norm2(x)
33-
elseif p == Inf
34-
return norm_inf(x)
35-
elseif p > 1
36-
# TODO: allow tolerance in the rationalize step
37-
return rationalnorm(x, rationalize(Int, float(p)))
38-
else
39-
error("vector p-norms not defined for p < 1")
40-
end
22+
if size(x, 2) > 1
23+
x = vec(x)
24+
end
25+
# x is a vector
26+
if p == 1
27+
return norm_1(x)
28+
elseif p == 2
29+
return norm2(x)
30+
elseif p == Inf
31+
return norm_inf(x)
32+
elseif p > 1
33+
# TODO: allow tolerance in the rationalize step
34+
return rationalnorm(x, rationalize(Int, float(p)))
4135
else
42-
error(
43-
"In Convex.jl v0.13 and below, `norm(x, p)` meant `opnorm(x, p)` (but was deprecated since v0.8.0). In the future, `norm(x,p)` for matrices will be equivalent to `norm(vec(x),p)`. This is currently an error to ensure you update your code!",
44-
)
36+
error("vector p-norms not defined for p < 1")
4537
end
4638
end

src/problem_depot/problems/socp.jl

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -88,15 +88,15 @@ end
8888
) where {T,test}
8989
m = Variable(4, 5)
9090
c = [m[3, 3] == 4, m >= 1]
91-
p = minimize(norm(vec(m), 2), c; numeric_type = T)
91+
p = minimize(norm(m, 2), c; numeric_type = T)
9292

9393
if test
9494
@test problem_vexity(p) == ConvexVexity()
9595
end
9696
handle_problem!(p)
9797
if test
9898
@test p.optval sqrt(35) atol = atol rtol = rtol
99-
@test evaluate(norm(vec(m), 2)) sqrt(35) atol = atol rtol = rtol
99+
@test evaluate(norm(m, 2)) sqrt(35) atol = atol rtol = rtol
100100
@test p.constraints[1].dual 0.6761 atol = atol rtol = rtol
101101
dual = 0.1690 .* ones(4, 5)
102102
dual[3, 3] = 0
@@ -542,16 +542,11 @@ end
542542
@test evaluate(opnorm(x, Inf)) opnorm(A, Inf) atol = atol rtol = rtol
543543
end
544544
# Vector norm
545-
# TODO: Once the deprecation for norm on matrices is removed, remove the `vec` calls
546545
if test
547-
@test evaluate(norm(vec(x), 1)) norm(vec(A), 1) atol = atol rtol =
548-
rtol
549-
@test evaluate(norm(vec(x), 2)) norm(vec(A), 2) atol = atol rtol =
550-
rtol
551-
@test evaluate(norm(vec(x), 7)) norm(vec(A), 7) atol = atol rtol =
552-
rtol
553-
@test evaluate(norm(vec(x), Inf)) norm(vec(A), Inf) atol = atol rtol =
554-
rtol
546+
@test evaluate(norm(x, 1)) norm(vec(A), 1) atol = atol rtol = rtol
547+
@test evaluate(norm(x, 2)) norm(vec(A), 2) atol = atol rtol = rtol
548+
@test evaluate(norm(x, 7)) norm(vec(A), 7) atol = atol rtol = rtol
549+
@test evaluate(norm(x, Inf)) norm(vec(A), Inf) atol = atol rtol = rtol
555550
end
556551
end
557552

0 commit comments

Comments
 (0)