Skip to content

Thin SVD #414

@lmmx

Description

@lmmx

I was studying PICARD (a faster version of ICA than "FastICA") and saw some mention of various types of SVD, which I'm already familiar with. One of the variants was "thin" SVD. I can see that there are other libs that save computation by only computing this "thin" variant and I was wondering if maybe ndarray-linalg could too.

I did a search of the code earlier and saw no mention of it, I'm curious if it'd be worth developing.

My understanding is that there are separate LAPACK functions/instructions you'd use for 'economy'/'thin' SVD, gesvdx being the relevant one

For reference I am interested in its use in whitening in this crate

  • svd function:
    fn svd(
    l: MatrixLayout,
    calc_u: bool,
    calc_vt: bool,
    a: &mut [Self],
    ) -> Result<SvdOwned<Self>> {
    use svd::*;
    let work = SvdWork::<$s>::new(l, calc_u, calc_vt)?;
    work.eval(a)
    }
    fn svddc(layout: MatrixLayout, jobz: JobSvd, a: &mut [Self]) -> Result<SvdOwned<Self>> {
    use svddc::*;
    let work = SvdDcWork::<$s>::new(layout, jobz)?;
    work.eval(a)
    }
  • SvdWork struct:
    pub struct SvdWork<T: Scalar> {
  • SVD trait:
    /// singular-value decomposition of matrix reference
    pub trait SVD {
    type U;
    type VT;
    type Sigma;
    fn svd(
    &self,
    calc_u: bool,
    calc_vt: bool,
    ) -> Result<(Option<Self::U>, Self::Sigma, Option<Self::VT>)>;
    }

So two things I see there are that

  1. there's this line saying it is unimplemented

let mut u = match ju {
JobSvd::All => Some(vec_uninit((m * m) as usize)),
JobSvd::None => None,
_ => unimplemented!("SVD with partial vector output is not supported yet"),
};

  1. there's this comment making v clear which LAPACK instructions are supported

//! | f32 | f64 | c32 | c64 |
//! |:-------|:-------|:-------|:-------|
//! | sgesvd | dgesvd | cgesvd | zgesvd |

and (from right to left in that table)

impl_svd_work_c!(c64, lapack_sys::zgesvd_);
impl_svd_work_c!(c32, lapack_sys::cgesvd_);

impl_svd_work_r!(f64, lapack_sys::dgesvd_);
impl_svd_work_r!(f32, lapack_sys::sgesvd_);

I'd be interested in this but for now just pointing out where the relevant parts of code are, have not dug deeper! 👍

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions