Skip to content
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
55 changes: 20 additions & 35 deletions src/BurerMonteiro.jl
Original file line number Diff line number Diff line change
Expand Up @@ -152,24 +152,24 @@ function NLPModels.obj(model::Model, x::AbstractVector)
return NLPModels.obj(model.model, Solution(x, model.dim))
end

function NLPModels.grad!(model::Model{false}, _, g, ::Type{LRO.ScalarIndex})
return copyto!(g, NLPModels.grad(model.model, LRO.ScalarIndex))
function grad!(model::Model{false}, _, g, ::Type{LRO.ScalarIndex})
return copyto!(g, LRO.grad(model.model, LRO.ScalarIndex))
end

function NLPModels.grad!(model::Model{true}, x, g, ::Type{LRO.ScalarIndex})
function grad!(model::Model{true}, x, g, ::Type{LRO.ScalarIndex})
g .=
2 .* NLPModels.grad(model.model, LRO.ScalarIndex) .*
2 .* LRO.grad(model.model, LRO.ScalarIndex) .*
LRO.left_factor(x, LRO.ScalarIndex)
return g
end

function NLPModels.grad!(
function grad!(
model::Model,
X::LRO.Factorization,
G::LRO.Factorization,
i::LRO.MatrixIndex,
)
C = NLPModels.grad(model.model, i)
C = LRO.grad(model.model, i)
LinearAlgebra.mul!(G.factor, C, X.factor)
G.factor .*= 2
return
Expand All @@ -178,14 +178,9 @@ end
function NLPModels.grad!(model::Model, x::AbstractVector, g::AbstractVector)
X = Solution(x, model.dim)
G = Solution(g, model.dim)
NLPModels.grad!(
model,
X,
LRO.left_factor(G, LRO.ScalarIndex),
LRO.ScalarIndex,
)
grad!(model, X, LRO.left_factor(G, LRO.ScalarIndex), LRO.ScalarIndex)
for i in LRO.matrix_indices(model.model)
NLPModels.grad!(model, X[i], G[i], i)
grad!(model, X[i], G[i], i)
end
return g
end
Expand Down Expand Up @@ -222,28 +217,24 @@ function NLPModels.jprod!(
return NLPModels.jprod!(model.model, X, _OuterProduct(X, V), Jv)
end

function NLPModels.jtprod!(
function jtprod!(
model::Model{false},
_,
y::AbstractVector,
JtV::AbstractVector,
::Type{LRO.ScalarIndex},
)
return LinearAlgebra.mul!(
JtV,
NLPModels.jac(model.model, LRO.ScalarIndex)',
y,
)
return LinearAlgebra.mul!(JtV, LRO.jac(model.model, LRO.ScalarIndex)', y)
end

function NLPModels.jtprod!(
function jtprod!(
model::Model{true},
X,
y::AbstractVector,
JtV::AbstractVector,
::Type{LRO.ScalarIndex},
)
LinearAlgebra.mul!(JtV, NLPModels.jac(model.model, LRO.ScalarIndex)', y)
LinearAlgebra.mul!(JtV, LRO.jac(model.model, LRO.ScalarIndex)', y)
JtV .*= 2 .* LRO.left_factor(X, LRO.ScalarIndex)
return JtV
end
Expand All @@ -256,12 +247,12 @@ function add_jtprod!(
i::LRO.MatrixIndex,
)
for j in eachindex(y)
A = NLPModels.jac(model.model, j, i)
A = LRO.jac(model.model, j, i)
LinearAlgebra.mul!(JtV.factor, A, X.factor, 2y[j], true)
end
end

function NLPModels.jtprod!(
function jtprod!(
model::Model,
X,
y::AbstractVector,
Expand All @@ -280,15 +271,9 @@ function NLPModels.jtprod!(
)
X = Solution(x, model.dim)
JtV = Solution(Jtv, model.dim)
NLPModels.jtprod!(
model,
X,
y,
LRO.left_factor(JtV, LRO.ScalarIndex),
LRO.ScalarIndex,
)
jtprod!(model, X, y, LRO.left_factor(JtV, LRO.ScalarIndex), LRO.ScalarIndex)
for i in LRO.matrix_indices(model.model)
NLPModels.jtprod!(model, X[i], y, JtV[i], i)
jtprod!(model, X[i], y, JtV[i], i)
end
return Jtv
end
Expand All @@ -314,10 +299,10 @@ function NLPModels.hprod!(
::Type{LRO.ScalarIndex};
obj_weight,
) where {T}
Hv .= obj_weight .* NLPModels.grad(model.model, LRO.ScalarIndex)
Hv .= obj_weight .* LRO.grad(model.model, LRO.ScalarIndex)
LinearAlgebra.mul!(
Hv,
NLPModels.jac(model.model, LRO.ScalarIndex)',
LRO.jac(model.model, LRO.ScalarIndex)',
y,
true,
true,
Expand Down Expand Up @@ -347,11 +332,11 @@ function NLPModels.hprod!(
)
for i in LRO.matrix_indices(model.model)
Vi = V[i].factor
C = NLPModels.grad(model.model, i)
C = LRO.grad(model.model, i)
Hvi = HV[i].factor
LinearAlgebra.mul!(Hvi, C, Vi, 2obj_weight, false)
for j in 1:model.meta.ncon
A = NLPModels.jac(model.model, j, i)
A = LRO.jac(model.model, j, i)
LinearAlgebra.mul!(Hvi, A, Vi, -2y[j], true)
end
end
Expand Down
16 changes: 6 additions & 10 deletions src/buffer.jl
Original file line number Diff line number Diff line change
Expand Up @@ -40,25 +40,21 @@ function dual_obj(model::BufferedModelForSchur, y::AbstractVector)
return dual_obj(model.model, y)
end

function NLPModels.grad(model::BufferedModelForSchur, ::Type{ScalarIndex})
return NLPModels.grad(model.model, ScalarIndex)
function grad(model::BufferedModelForSchur, ::Type{ScalarIndex})
return grad(model.model, ScalarIndex)
end

function NLPModels.grad(model::BufferedModelForSchur, i::MatrixIndex)
return NLPModels.grad(model.model, i)
function grad(model::BufferedModelForSchur, i::MatrixIndex)
return grad(model.model, i)
end

#########################
###### Constraints ######
#########################

cons_constant(model::BufferedModelForSchur) = cons_constant(model.model)
function NLPModels.jac(
model::BufferedModelForSchur,
j::Integer,
::Type{ScalarIndex},
)
return NLPModels.jac(model.model, j, ScalarIndex)
function jac(model::BufferedModelForSchur, j::Integer, ::Type{ScalarIndex})
return jac(model.model, j, ScalarIndex)
end
function norm_jac(model::BufferedModelForSchur, i::MatrixIndex)
return norm_jac(model.model, i)
Expand Down
4 changes: 2 additions & 2 deletions src/errors.jl
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ function errors(
b_den = 1 + LinearAlgebra.norm(cons_constant(model), 1)
C_den =
1 +
LinearAlgebra.norm(NLPModels.grad(model, ScalarIndex), 1) +
LinearAlgebra.norm(grad(model, ScalarIndex), 1) +
sum(matrix_indices(model), init = zero(b_den)) do i
return LinearAlgebra.norm(NLPModels.grad(model, i), 1)
return LinearAlgebra.norm(grad(model, i), 1)
end
obj_den = 1 + abs(pobj) + abs(dobj)
return (
Expand Down
21 changes: 10 additions & 11 deletions src/model.jl
Original file line number Diff line number Diff line change
Expand Up @@ -123,25 +123,24 @@ side_dimension(model::Model, i::MatrixIndex) = model.msizes[i.value]
###### Objective ######
#######################

function NLPModels.obj(model::Model, X::AbstractMatrix, i::MatrixIndex)
function obj(model::Model, X::AbstractMatrix, i::MatrixIndex)
return LinearAlgebra.dot(model.C[i.value], X)
end

function NLPModels.obj(model::Model, x::AbstractVector, ::Type{MatrixIndex})
function obj(model::Model, x::AbstractVector, ::Type{MatrixIndex})
result = zero(eltype(x))
for i in matrix_indices(model)
result += NLPModels.obj(model, x[i], i)
result += obj(model, x[i], i)
end
return result
end

function NLPModels.obj(model::Model, x::AbstractVector, ::Type{ScalarIndex})
function obj(model::Model, x::AbstractVector, ::Type{ScalarIndex})
return LinearAlgebra.dot(model.d_lin, x[ScalarIndex])
end

function NLPModels.obj(model::Model, x::AbstractVector)
return NLPModels.obj(model, x, MatrixIndex) +
NLPModels.obj(model, x, ScalarIndex)
return obj(model, x, ScalarIndex) + obj(model, x, MatrixIndex)
end

function NLPModels.grad!(model::Model, _::AbstractVector, g::AbstractVector)
Expand All @@ -168,8 +167,8 @@ function dual_cons!(model::Model, y::AbstractVector, res, ::Type{ScalarIndex})
return LinearAlgebra.mul!(res, model.C_lin', y, -1, true)
end

NLPModels.grad(model::Model, ::Type{ScalarIndex}) = model.d_lin
NLPModels.grad(model::Model, i::MatrixIndex) = model.C[i.value]
grad(model::Model, ::Type{ScalarIndex}) = model.d_lin
grad(model::Model, i::MatrixIndex) = model.C[i.value]

#########################
###### Constraints ######
Expand All @@ -178,11 +177,11 @@ NLPModels.grad(model::Model, i::MatrixIndex) = model.C[i.value]
cons_constant(model::Model) = model.b

# Should be only used with `norm`
NLPModels.jac(model::Model, ::Type{ScalarIndex}) = model.C_lin
function NLPModels.jac(model::Model, j::Integer, i::MatrixIndex)
jac(model::Model, ::Type{ScalarIndex}) = model.C_lin
function jac(model::Model, j::Integer, i::MatrixIndex)
return model.A[i.value, j]
end
function NLPModels.jac(model::Model, j::Integer, ::Type{ScalarIndex})
function jac(model::Model, j::Integer, ::Type{ScalarIndex})
return model.C_lin[j, :]
end
function norm_jac(model::Model{T}, i::MatrixIndex) where {T}
Expand Down
8 changes: 4 additions & 4 deletions test/diff_check.jl
Original file line number Diff line number Diff line change
Expand Up @@ -130,12 +130,12 @@ function schur_test(model::LRO.BufferedModelForSchur{T}, w) where {T}

idx = LRO.matrix_indices(model)
@test NLPModels.obj(model, w) ≈
dot(NLPModels.grad(model, LRO.ScalarIndex), w[LRO.ScalarIndex]) +
dot(NLPModels.grad.(model, idx), getindex.(Ref(w), idx))
dot(LRO.grad(model, LRO.ScalarIndex), w[LRO.ScalarIndex]) +
dot(LRO.grad.(model, idx), getindex.(Ref(w), idx))
@test LRO.dual_obj(model, y) ≈ dot(LRO.cons_constant(model), y)

@test NLPModels.jac(model, 1, LRO.ScalarIndex) ==
NLPModels.jac(model.model, 1, LRO.ScalarIndex)
@test LRO.jac(model, 1, LRO.ScalarIndex) ==
LRO.jac(model.model, 1, LRO.ScalarIndex)
@test LRO.norm_jac.(model, idx) == LRO.norm_jac.(model.model, idx)
@test LRO.side_dimension.(model, idx) ==
LRO.side_dimension.(model.model, idx)
Expand Down
11 changes: 5 additions & 6 deletions test/maxcut.jl
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ function test_maxcut(; is_dual, sparse, vector)
diff_check(model)
X = LRO.positive_semidefinite_factorization(rand(4))
JtV = LRO.positive_semidefinite_factorization(ones(4))
NLPModels.grad!(solver.model, X, JtV, i)
LRO.BurerMonteiro.grad!(solver.model, X, JtV, i)
@test JtV.factor ≈ 2lro_model.C[] * X.factor
fill!(JtV.factor, 0.0)
y = rand(lro_model.meta.ncon)
Expand Down Expand Up @@ -113,16 +113,15 @@ end;
[Matrix(x[i]) for i in LRO.matrix_indices(b.model)],
)
y = collect(1:b.model.meta.ncon)
@test NLPModels.jac(b.model, 1, LRO.MatrixIndex(1)) ==
@test LRO.jac(b.model, 1, LRO.MatrixIndex(1)) ==
sparse([1], [1], [-1], 4, 4)
@test NLPModels.jac(b.model, 1, LRO.ScalarIndex) ==
sparsevec([1, 2], [-1, 1], 8)
@test LRO.jac(b.model, 1, LRO.ScalarIndex) == sparsevec([1, 2], [-1, 1], 8)
@test LRO.norm_jac(b.model, LRO.MatrixIndex(1)) == 4
grad = similar(x)
NLPModels.grad!(b.model, X, grad)
@test Vector(grad) == [
Vector(NLPModels.grad(b.model, LRO.ScalarIndex));
NLPModels.grad(b.model, LRO.MatrixIndex(1))[:]
Vector(LRO.grad(b.model, LRO.ScalarIndex));
LRO.grad(b.model, LRO.MatrixIndex(1))[:]
]
for xx in [x, X]
err = LRO.errors(b.solver.model, xx; y, dual_slack = xx, dual_err = xx)
Expand Down
Loading