Skip to content

MATLAB bindings for CQRRPT and CQRRT - #8

Open
mmelnich wants to merge 1 commit into
mainfrom
cqrrt-cqrrpt-mex
Open

mmelnich wants to merge 1 commit into
mainfrom
cqrrt-cqrrpt-mex

Conversation

@mmelnich

@mmelnich mmelnich commented Oct 8, 2026

Copy link
Copy Markdown
Contributor

Summary

MATLAB bindings for RandLAPACK's dense CQRRPT and CQRRT, next to BQRRP. Both are sketch-and-precondition QR factorizations for tall matrices (m >= d_factor*n): CQRRPT pivots and reveals the rank, CQRRT is unpivoted Cholesky QR for full-rank input and also has an R-only mode. RSVD and the Python bindings from #5 are not included.

Changes

  • randlapack.cqrrpt (cqrrpt_mex.cc, cqrrpt.m, test, demo), taken from Wave 1: bind RSVD and CQRRPT in MATLAB and Python #5: [Q, R, J] = randlapack.cqrrpt(A) with the detected rank as the inner dimension of Q and R; options 'eps', 'd_factor', 'state'. Changes from Wave 1: bind RSVD and CQRRPT in MATLAB and Python #5: rank is reset before the call, since CQRRPT returns early on an all-zero input without setting it (now a clear zero-rank error, with a test); the J-zeroing comment reflects that RandLAPACK now zeroes J itself.
  • randlapack.cqrrt (cqrrt_mex.cc, cqrrt.m, test, demo): [Q, R] = randlapack.cqrrt(A) like qr(A, 0); R = randlapack.cqrrt(A) uses CQRRT's R-only mode and forms no Q; options 'd_factor', 'state'. CQRRT does not detect rank: a rank-deficient input usually completes with a numerically singular R, which the help says to check for; an exactly singular sketch (e.g. a zero column) or a Cholesky failure raises randlapack:cqrrt_mex:breakdown, pointing at cqrrpt and bqrrp.
  • RNG-state helpers moved to +randlapack/private/ (from Wave 1: bind RSVD and CQRRPT in MATLAB and Python #5); bqrrp.m uses them.
  • matlab/CMakeLists.txt: one function, randlapack_add_mex(name), applies the per-target setup (include dirs, output dir, static libstdc++ on GNU, Windows DLL staging and libiomp5md.dll removal, MSVC OpenMP linkage) to all three MEX targets; bqrrp_mex's build flags are unchanged. On Windows the targets link one after another, because each stages the same backend DLLs into the same directory and parallel copies can collide.
  • All three MEX files: errors raised by the MEX keep their identifier. feval("error") throws matlab::engine::MATLABExecutionException, which does not derive from matlab::Exception, so the old pass-through handler never matched and the std::exception handler re-raised the error as ...:StdError; a catch (const matlab::engine::Exception&) { throw; } now comes first. This also affected bqrrp_mex.
  • README: scope, usage for the two drivers, conventions. The CQRRPT demo now compares against qr(A, 'econ', 'vector') after a warm-up call; bqrrp/cqrrpt help and README say they match qr(A, 'econ', 'vector').

Add randlapack.cqrrpt and randlapack.cqrrt next to randlapack.bqrrp, for
tall matrices (m >= d_factor*n):

- CQRRPT (rank-revealing QR with column pivoting): [Q, R, J] with the rank
  detected by CQRRPT as the inner dimension of Q and R; 'eps', 'd_factor'
  and 'state' options. Taken from the unmerged bindings-wave1 branch, with
  `rank` reset before the call (CQRRPT returns early on an all-zero input
  without setting it) and the J-zeroing comment updated (RandLAPACK now
  zeroes J itself; the MEX keeps doing it for older installs).
- CQRRT (unpivoted Cholesky QR for full-rank input): [Q, R] like
  qr(A, 0), with Q factored in place into its output buffer; R = cqrrt(A)
  uses CQRRT's R-only mode and forms no Q. CQRRT does not detect rank: a
  rank-deficient input usually completes with a numerically singular R
  (documented and tested); an exactly singular sketch or a Cholesky failure
  is reported as randlapack:cqrrt_mex:breakdown, pointing at cqrrpt and
  bqrrp.
- The RNG-state helpers move to +randlapack/private and bqrrp.m uses them.
- matlab/CMakeLists.txt: randlapack_add_mex(name) applies the per-target
  setup (include dirs, output dir, static libstdc++ on GNU, Windows DLL
  staging and libiomp5md.dll removal, MSVC OpenMP linkage) to all three
  targets; bqrrp_mex's flags.make and link.txt are unchanged on Linux.
- All three MEX files: errors raised by the MEX keep their identifier.
  feval("error") throws matlab::engine::MATLABExecutionException, which
  derives from matlab::engine::Exception and std::exception but not from
  matlab::Exception, so the old `catch (const matlab::Exception&)` never
  matched and the std::exception handler re-raised it as ...:StdError. A
  `catch (const matlab::engine::Exception&) { throw; }` now comes first.
- Tests, demos and README for both drivers. The CQRRPT demo compares
  against qr(A, 'econ', 'vector') after a warm-up call (it used to compare
  against a full QR with an m-by-m Q). Help texts and README say "matches
  qr(A, 'econ', 'vector')" for bqrrp and cqrrpt.

Verified on Linux (GCC 15.2, MATLAB R2026a, RandLAPACK main): test_bqrrp,
test_cqrrpt and test_cqrrt pass, including rank detection, the all-zero
and breakdown error IDs, R-only vs [Q, R] agreement, a rank-deficient input
completing with a singular R, and a cond(A) = 1e10 input; CQRRT on
50000x500 matches qr(A, 0)'s R to 2e-15 (2.9x faster), CQRRPT on 20000x200
is 8.8x faster than qr(A, 'econ', 'vector'). On Windows (MSVC 19.44, MATLAB R2026a, RandLAPACK main installed
with install.ps1, threaded oneMKL): the three MEX files build with the README
command, import only MATLAB's libiomp5md for OpenMP, and all three test
suites pass with KMP_DUPLICATE_LIB_OK unset.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant