ndarray-linalg icon indicating copy to clipboard operation
ndarray-linalg copied to clipboard

Add RQ decomposition

Open jorge-ortega opened this issue 7 months ago • 0 comments

Hello, and thanks for the great library. I would like to request the addition of RQ decomposition. Although it's fairly trivial to implement RQ in terms of QR (link), it still took me quite some time to figure this out even with AI help (which used extra unnecessary flips).

One thing that made this challenging for me was that qr does not accept arrays with negative strides, so any slice had to then be copied into another backing array. This is ultimately what I ended up with:

use ndarray::Data;
use ndarray::prelude::*;
use ndarray_linalg::error::Result;
use ndarray_linalg::{Lapack, QRInto, Scalar};

pub trait RQ {
    type R;
    type Q;
    fn rq(&self) -> Result<(Self::R, Self::Q)>;
}

impl<A, S> RQ for ArrayBase<S, Ix2>
where
    A: Scalar + Lapack,
    S: Data<Elem = A>,
{
    type R = Array2<A>;
    type Q = Array2<A>;

    fn rq(&self) -> Result<(Self::R, Self::Q)> {
        let a = Array::from_shape_vec(
            self.raw_dim(),
            self.slice(s![..;-1,..]).t().iter().cloned().collect(),
        )?;

        let (q, r) = a.qr_into()?;

        let q = Array::from_shape_vec(
            q.raw_dim(),
            q.t().slice(s![..;-1,..]).iter().cloned().collect(),
        )?;
        let r = Array::from_shape_vec(
            r.raw_dim(),
            r.t().slice(s![..;-1,..;-1]).iter().cloned().collect(),
        )?;
        Ok((r, q))
    }
}

A built-in RQ would ideally use gerqf for row major arrays. Not sure what the equivalent would be for column major.

jorge-ortega avatar May 07 '25 02:05 jorge-ortega