From 0131eaa09cec594d9d3d6f55aae9777930990cd3 Mon Sep 17 00:00:00 2001 From: Patrick Kofod Mogensen Date: Thu, 12 Mar 2026 09:27:32 +0100 Subject: [PATCH] Small corrections to LBFGSData constructor MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `mem` is clamped to positive integers. I'm not sure if it's intentional that no errors are thrown here. In the existing code the memory would be set to 1, but all the variables needed to maintain the approximation were set to something not positive, for example ``` julia> LinearOperators.LBFGSData(Float64, 1;mem=-1, inverse=true) ERROR: ArgumentError: invalid GenericMemory size: too large for system address width Stacktrace: [1] GenericMemory @ ./boot.jl:516 [inlined] [2] Array @ ./boot.jl:578 [inlined] [3] Array @ ./boot.jl:591 [inlined] [4] zeros @ ./array.jl:589 [inlined] [5] zeros(::Type{Float64}, dims::Int64) @ Base ./array.jl:585 [6] LinearOperators.LBFGSData(T::Type, n::Int64; mem::Int64, scaling::Bool, damped::Bool, inverse::Bool, σ₂::Float64, σ₃::Float64) @ LinearOperators ~/.julia/packages/LinearOperators/p7GRU/src/lbfgs.jl:36 [7] top-level scope @ REPL[33]:1 ``` Then, a small mostly theoretical thing. The vectors `a` and `b` are Vector{Vector{T)) but if inverse == true you get just a Vector{T}. It works at runtime because julia will convert it by accident because it just widens the type and tries to copy all memory, but there is 0 memory to copy. I just figured it was clearer to actually specify the type directly and not rely on the convert behavior. --- src/lbfgs.jl | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/lbfgs.jl b/src/lbfgs.jl index b4b5b842..a7412038 100644 --- a/src/lbfgs.jl +++ b/src/lbfgs.jl @@ -33,25 +33,26 @@ function LBFGSData( σ₂::Float64 = 0.99, σ₃::Float64 = 10.0, ) where {I <: Integer} + maxmem = max(mem, 1) LBFGSData{T, I}( - max(mem, 1), + maxmem, scaling, convert(T, 1), damped, convert(T, σ₂), convert(T, σ₃), convert(T, 1), - [zeros(T, n) for _ = 1:mem], - [zeros(T, n) for _ = 1:mem], - zeros(T, mem), - inverse ? zeros(T, mem) : zeros(T, 0), - inverse ? Vector{T}(undef, 0) : [zeros(T, n) for _ = 1:mem], - inverse ? Vector{T}(undef, 0) : [zeros(T, n) for _ = 1:mem], - inverse ? Vector{T}(undef, 0) : zeros(T, mem), + [zeros(T, n) for _ = 1:maxmem], + [zeros(T, n) for _ = 1:maxmem], + zeros(T, maxmem), + inverse ? zeros(T, maxmem) : zeros(T, 0), + inverse ? Vector{Vector{T}}(undef, 0) : [zeros(T, n) for _ = 1:maxmem], + inverse ? Vector{Vector{T}}(undef, 0) : [zeros(T, n) for _ = 1:maxmem], + inverse ? Vector{T}(undef, 0) : zeros(T, maxmem), 1, Vector{T}(undef, n), - Array{T}(undef, (n, 2 * mem)), - Vector{T}(undef, 2 * mem), + Array{T}(undef, (n, 2 * maxmem)), + Vector{T}(undef, 2 * maxmem), Vector{T}(undef, n), ) end