Updating the QR decomposition of a matrix under rank-1updates

Hi,
I was trying to find a native julia implementation of the QR decomposition of a matrix A when it is changed from A to A + uv^{T} - under a rank-1 update. I found multiple packages for updating the QR decomp (and just the R decomp, which is all I care about, actually, in this case), but these seem to be geared towards deleting/updating columns. I was looking for an implementation of the algorithm from Chapter 12, Golub and Loan. Scipy, for instance, has an implementation: qr_update — SciPy v1.16.2 Manual.
Any help would be much appreciated!

1 Like

I was trying to import the rank-1 update function from Fortran. I only care about the 64-bit complex type, so I wrote a hardcoded version:

using QRupdate_ng_jll
function rank_1_update_QR!(Q::AbstractMatrix{ComplexF64}, R::AbstractMatrix{ComplexF64}, u::AbstractVector{ComplexF64}, v::AbstractVector{ComplexF64}, w::AbstractVector{ComplexF64}, rw::AbstractVector{Float64})

    dim = size(Q, 1)
    dim = Int32(dim)
    ccall((:zqr1up_, QRupdate_ng_jll.libqrupdate), Cvoid, (Ref{Int32}, Ref{Int32}, Ref{Int32}, Ptr{ComplexF64}, Ref{Int32}, Ptr{ComplexF64}, Ref{Int32}, Ptr{ComplexF64}, Ptr{ComplexF64}, Ptr{ComplexF64}, Ptr{Float64}), dim, dim, dim, Q, dim, R, dim, u, v, w, rw)
    return nothing
    
end

This

let 

    A = randn(ComplexF64, 5, 5)
    qrA = qr(A)
    Q, R = Matrix(qrA.Q), Matrix(qrA.R)
    u = randn(ComplexF64, 5)
    v = randn(ComplexF64, 5)
    w = similar(u)
    rw = similar(real.(u))
    Qcopy = copy(Q)
    Rcopy = copy(R)
    rank_1_update_QR!(Qcopy, Rcopy, copy(u), copy(v), w, rw)
end

However throws the following error:

Error: no BLAS/LAPACK library loaded for zdotc_()
Error: no BLAS/LAPACK library loaded for zdotc_()
Error: no BLAS/LAPACK library loaded for zdotc_()
Error: no BLAS/LAPACK library loaded for zdotc_()
Error: no BLAS/LAPACK library loaded for zdotc_()
Error: no BLAS/LAPACK library loaded for zlartg_()
Error: no BLAS/LAPACK library loaded for zlartg_()
Error: no BLAS/LAPACK library loaded for zlartg_()
Error: no BLAS/LAPACK library loaded for zlartg_()
Error: no BLAS/LAPACK library loaded for lsame_()
Error: no BLAS/LAPACK library loaded for zrot_()
Error: no BLAS/LAPACK library loaded for zrot_()
Error: no BLAS/LAPACK library loaded for zrot_()
Error: no BLAS/LAPACK library loaded for zrot_()
Error: no BLAS/LAPACK library loaded for zlartg_()
Error: no BLAS/LAPACK library loaded for zlartg_()
Error: no BLAS/LAPACK library loaded for zlartg_()
Error: no BLAS/LAPACK library loaded for zlartg_()
Error: no BLAS/LAPACK library loaded for lsame_()
Error: no BLAS/LAPACK library loaded for zrot_()
Error: no BLAS/LAPACK library loaded for zrot_()
Error: no BLAS/LAPACK library loaded for zrot_()
Error: no BLAS/LAPACK library loaded for zrot_()

I am not sure what’s wrong. This is the output from versioninfo():

julia> versioninfo()
Julia Version 1.11.7
Commit f2b3dbda30a (2025-09-08 12:10 UTC)
Build Info:
  Official https://julialang.org/ release
Platform Info:
  OS: macOS (arm64-apple-darwin24.0.0)
  CPU: 12 × Apple M4 Pro
  WORD_SIZE: 64
  LLVM: libLLVM-16.0.6 (ORCJIT, apple-m1)
Threads: 6 default, 0 interactive, 3 GC (on 8 virtual cores)
Environment:
  JULIA_EDITOR = code
  JULIA_VSCODE_REPL = 1
  JULIA_NUM_THREADS = 6

I am afraid this is my first time trying to import from FORTRAN, so I am not sure if I am missing something silly.

You need to load an LP64 version of LAPACK+BLAS (that uses 32-bit integers, as in your library call). Julia uses a clever interface called libblastrampoline to make it possible to have both LP64 and the more common ILP64 version loaded at the same time. I’ve only succeeded with this using Intel’s MKL on Linux. Perhaps @staticfloat can tell us whether this also works on MacOS, and if so what you need to do.

Edit:
I just found that this also works on Linux, so perhaps it will do for you:

using OpenBLAS32_jll

LinearAlgebra.BLAS.lbt_forward(OpenBLAS32_jll.libopenblas)

println(LinearAlgebra.BLAS.lbt_get_config())

This works great on my MacBook. And with MKL on my uni’s HPC as well. Thank you!!