Direct access to Shape

Aberta
#592 3 comentários 0 reações 0 responsáveis Ver no GitHub

Ninguém assumiu esta issue ainda.

Avaliação

Dificuldade
5/5
Tempo estimado
Mais de uma semana
Facilidade para iniciantes
35/100
Tipo de issue
Funcionalidade
Clareza
Razoavelmente clara
Status de atividade
Estagnada
Stack de tecnologia
rust
Domínio
data

Direção de pesquisa

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.

Escrita pelo modelo de indexação a partir do texto da issue.

Descrição

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
    }
}
Linguagem predominante
Rust
Estrelas
4.3k
Forks
391
Métricas de merge de PRs
Nenhum PR com merge em 30d

Guia de contribuição

Nenhum guia de contribuição indexado para este repositório

Primeiros passos

  1. Leia a issue inteira e depois o guia de contribuição do projeto.
  2. Comente na issue dizendo que vai assumir — evita que duas pessoas façam o mesmo trabalho.
  3. Faça um fork do repositório e trabalhe em uma branch.
  4. Abra um pull request que referencie o número da issue.

Mais de rust-ndarray/ndarray

Todas as issues de rust-ndarray/ndarray

Issues semelhantes

Mais issues de Rust

Receba novas issues na sua caixa de entrada

Um resumo curto de issues do GitHub para quem está começando.