diff --git a/src/qpmodel.jl b/src/qpmodel.jl index 3dcf163..6ace079 100644 --- a/src/qpmodel.jl +++ b/src/qpmodel.jl @@ -8,10 +8,12 @@ mutable struct QPData{ } c0::T # constant term in objective c::S # linear term + v::S # vector that stores products with the hessian v = H*u H::M1 A::M2 end +@inline QPData(c0, c, H, A) = QPData(c0, c, similar(c), H, A) isdense(data::QPData{T, S, M1, M2}) where {T, S, M1, M2} = M1 <: DenseMatrix || M2 <: DenseMatrix function Base.convert( @@ -20,7 +22,7 @@ function Base.convert( ) where {T, S, M1 <: AbstractMatrix, M2 <: AbstractMatrix, MCOO <: SparseMatrixCOO{T}} HCOO = (M1 <: SparseMatrixCOO) ? data.H : SparseMatrixCOO(data.H) ACOO = (M2 <: SparseMatrixCOO) ? data.A : SparseMatrixCOO(data.A) - return QPData(data.c0, data.c, HCOO, ACOO) + return QPData(data.c0, data.c, data.v, HCOO, ACOO) end Base.convert( ::Type{QPData{T, S, MCOO, MCOO}}, @@ -256,9 +258,8 @@ end function NLPModels.obj(qp::AbstractQuadraticModel{T, S}, x::AbstractVector) where {T, S} NLPModels.increment!(qp, :neval_obj) - Hx = fill!(S(undef, qp.meta.nvar), zero(T)) - mul!(Hx, Symmetric(qp.data.H, :L), x) - return qp.data.c0 + dot(qp.data.c, x) + dot(Hx, x) / 2 + mul!(qp.data.v, Symmetric(qp.data.H, :L), x) + return qp.data.c0 + dot(qp.data.c, x) + dot(qp.data.v, x) / 2 end function NLPModels.grad!(qp::AbstractQuadraticModel, x::AbstractVector, g::AbstractVector) diff --git a/test/runtests.jl b/test/runtests.jl index 27b0937..5c49269 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -259,3 +259,4 @@ end end include("test_presolve.jl") +include("test_allocations.jl") \ No newline at end of file diff --git a/test/test_allocations.jl b/test/test_allocations.jl new file mode 100644 index 0000000..eb8e278 --- /dev/null +++ b/test/test_allocations.jl @@ -0,0 +1,47 @@ +function test_only_zeros(table) + for (key, vals) in table + if !isnan(vals) + @test vals == 0 + vals != 0 && println(key) + end + end +end + +@testset "allocations" begin + @testset "allocs QPSData" begin + for problem in qp_problems_Matrix + nlp_qps = eval(Symbol(problem * "_QPSData"))() + test_only_zeros(test_allocs_nlpmodels(nlp_qps)) + end + end + + @testset "allocs QP_dense" begin + for problem in qp_problems_Matrix + nlp_qm_dense = eval(Symbol(problem * "_QP_dense"))() + test_only_zeros(test_allocs_nlpmodels(nlp_qm_dense)) + end + end + + @testset "allocs COO QPSData" begin + for problem in qp_problems_COO + nlp_qps = eval(Symbol(problem * "_QPSData"))() + test_only_zeros(test_allocs_nlpmodels(nlp_qps)) + end + end + + @testset "allocs COO QP" begin + for problem in qp_problems_COO + nlp_qm_dense = eval(Symbol(problem * "_QP"))() + test_only_zeros(test_allocs_nlpmodels(nlp_qm_dense)) + end + end + + @testset "allocs quadratic approximation" begin + for problem in NLPModelsTest.nlp_problems + nlp = eval(Symbol(problem))() + x = nlp.meta.x0 + nlp_qm = QuadraticModel(nlp, x) + test_only_zeros(test_allocs_nlpmodels(nlp_qm)) + end + end +end \ No newline at end of file