Direct access to Shape

Aperta
#592 3 commenti 0 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
5/5
Tempo stimato
Più di una settimana
Idoneità per principianti
35/100
Tipo di issue
Funzionalità
Chiarezza
Abbastanza chiara
Stato di attività
Ferma
Stack tecnologico
rust
Ambito
data

Direzione di ricerca

Start by reading ArrayBase::dim, raw_dim, as_slice, and as_slice_memory_order, then trace the Shape and ShapeBuilder APIs referenced in the issue. Done means callers can directly obtain an array's Shape and determine row-major, column-major, or non-contiguous layout without relying on the workaround shown.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

I have this code, which takes a matrix and tries to create a matrix with similar specifications, i.e. a matrix with the same Shape. Unfortunately, this turns out to be more complicated then I hoped, because I don't have an easy way to check the memory layout of my matrix.

The reasons are:

  1. I don't have direct access to Shape, but only to Dim::Pattern (via ArrayBase::dim) or Dim (via ArrayBase::raw_dim). If I could get the Shape from an array, I could pass it to the various methods that accept a T: ShapeBuilder.
  2. There is no way to check if a matrix is in column major or row major form. Similarly, there is no way to check if a Shape is for column or row major form.

The only workaround that I see and am using, is to call as_slice and as_slice_memory_order on my array. If the first call returns an Option, I know I am in row major form. If it returns None but as_slice_memory_order returns an Option, I know I am in column major form. Both of these methods of course depend on the current specific implementation in ndarray.

It would be nice to have a more direct check for the memory layout. This is important when writing methods that call blas or lapack functions.

See the code below for reference.

fn from_matrix<S>(a: &ArrayBase<S, Ix2>) -> Result<Self>
    where S: Data<Elem = f64>
{
    use cblas::Layout::*;
    let dim = a.dim();
    let shape = match utils::get_layout(a) {
        Some(ColumnMajor) => dim.f(),
        Some(RowMajor) => dim.into_shape(),
        None => Err(Error::NonContiguous)?,
    };
                                                         
    Self::from_shape(shape)
}

fn from_shape<T>(shape: T) -> Result<Self>
    where T: ShapeBuilder<Dim = Ix2>,
{
    // Unfortunately we cannot check the shape itself to see if it's
    // in ColumnMajor or RowMajor layout. So we need to first construct
    // an array and then check that.
    let shape = shape.into_shape();
    let q = Array2::zeros(shape);
    let memory_layout = match get_layout(&q) {
        Some(layout) => layout,
        None => Err(Error::NonContiguous)?,
    };
    let r = q.clone();
    Ok(ClassicalGramSchmidt {
        q,
        r,
        memory_layout,
    })
}

fn get_layout<S, T, D>(a: &ArrayBase<S, D>) -> Option<cblas::Layout>
    where S: Data<Elem=T>,
          D: Dimension
{
    if let Some(_) = a.as_slice() {
        Some(cblas::Layout::RowMajor)
    } else if let Some(_) = a.as_slice_memory_order() {
        Some(cblas::Layout::ColumnMajor)
    } else {
        None
    }
}
Lingua principale
Rust
Stelle
4.3k
Fork
391
Metriche di merge delle PR
Nessuna PR unita negli ultimi 30g

Guida per i contributori

Nessuna guida per i contributori indicizzata per questo repository

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di rust-ndarray/ndarray

Tutte le issue di rust-ndarray/ndarray

Issue simili

Altre issue su Rust

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.