Plan for dimension types
Ninguém assumiu esta issue ainda.
Avaliação
- Dificuldade
- 5/5
- Tempo estimado
- Mais de uma semana
- Facilidade para iniciantes
- 20/100
Direção de pesquisa
Start by reading the existing Dimension and ArrayBase implementations, then compare how Ix2 and IxDyn currently represent shapes and strides. The proposal requires agreement on the associated-type design, conversion traits, and type-level operations before implementation; completion would include resolving the related dimension issues and validating the affected API.
Escrita pelo modelo de indexação a partir do texto da issue.
Descrição
I've been thinking about the dimension types for a while. Two things I don't like about the current implementation are that:
- Strides are represented as
usizeand have to be converted toisizeevery time they're used. This is error-prone and confusing. - It seems a little weird that the dimension type itself (instead of an associated type) has a representation. For example, "2-D" doesn't necessary imply a specific representation to me.
What I'd like to do is something like the following:
pub trait Dimension
where
for<'a> Into<Self::OwnedUsize> for &'a Self::BorrowedUsize,
for<'a> Into<Self::OwnedIsize> for &'a Self::BorrowedIsize,
{
type OwnedUsize: AsRef<Self::BorrowedUsize> + AsMut<Self::BorrowedUsize> + AsRef<[usize]> + AsMut<[usize]>;
type BorrowedUsize: ?Sized + AsRef<[usize]> + AsMut<[usize]>;
type OwnedIsize: AsRef<Self::BorrowedIsize> + AsMut<Self::BorrowedIsize> + AsRef<[isize]> + AsMut<[isize]>;
type BorrowedIsize: ?Sized + AsRef<[isize]> + AsMut<[isize]>;
}
pub struct Ix2;
pub struct IxDyn;
impl Dimension for Ix2 {
type OwnedUsize = [usize; 2];
type BorrowedUsize = [usize; 2];
type OwnedIsize = [isize; 2];
type BorrowedIsize = [isize; 2];
}
impl Dimension for IxDyn {
type OwnedUsize = IxDynImpl<usize>;
type BorrowedUsize = [usize];
type OwnedIsize = IxDynImpl<isize>;
type BorrowedIsize = [isize];
}
pub trait IntoDimOwnedUsize {
type Dim: Dimension;
fn into_dim_owned_usize(self) -> Self::Dim::OwnedUsize;
}
pub trait AsDimBorrowedUsize {
type Dim: Dimension;
fn as_dim_borrowed_usize(&self) -> &Self::Dim::BorrowedUsize;
}
pub trait IntoDimOwnedIsize { ... }
pub trait AsDimBorrowedIsize { ... }
pub struct ArrayBase<S, D>
where
S: Data,
{
data: S,
ptr: *mut S::Elem,
dim: D::OwnedUsize,
strides: D::OwnedIsize,
}
impl<A, S, D> ArrayBase<S, D>
where
S: Data<Elem = A>,
D: Dimension,
{
pub fn shape(&self) -> &D::BorrowedUsize {
// ...
}
pub fn strides(&self) -> &D::BorrowedIsize {
// ...
}
}
Once Rust has generic associated types, we can simplify this to:
pub trait Dimension
where
for<'a, T: Clone> Into<Self::Owned<T>> for &'a Self::Borrowed,
{
type Owned<T>: AsRef<Self::Borrowed<T>> + AsMut<Self::Borrowed<T>> + AsRef<[T]> + AsMut<[T]>;
type Borrowed<T>>: ?Sized + AsRef<[T]> + AsMut<[T]>;
}
pub struct Ix2;
pub struct IxDyn;
impl Dimension for Ix2 {
type Owned<T> = [T; 2];
type Borrowed<T> = [T; 2];
}
impl Dimension for IxDyn {
type Owned<T> = IxDynImpl<T>;
type Borrowed<T> = [T];
}
pub trait IntoDimOwned<T> {
type Dim: Dimension;
fn into_dim_owned(self) -> Self::Dim::Owned<T>;
}
pub trait AsDimBorrowed<T> {
type Dim: Dimension;
fn as_dim_borrowed(&self) -> &Self::Dim::Borrowed<T>;
}
pub struct ArrayBase<S, D>
where
S: Data,
{
data: S,
ptr: *mut S::Elem,
dim: D::Owned<usize>,
strides: D::Owned<isize>,
}
impl<A, S, D> ArrayBase<S, D>
where
S: Data<Elem = A>,
D: Dimension,
{
pub fn shape(&self) -> &D::Borrowed<usize> {
// ...
}
pub fn strides(&self) -> &D::Borrowed<isize> {
// ...
}
}
I'd also add various type-level arithmetic operations on the dimension types, which are necessary for things like co-broadcasting (trait PartialOrdDim) and fold_axes (trait SubDim).
We can also add Shape<T>, Strides<T>, and Index<T> thin wrapper types.
This approach would resolve things like #489 and this comment on #367.
Thoughts?
- 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
- Leia a issue inteira e depois o guia de contribuição do projeto.
- Comente na issue dizendo que vai assumir — evita que duas pessoas façam o mesmo trabalho.
- Faça um fork do repositório e trabalhe em uma branch.
- Abra um pull request que referencie o número da issue.
Mais de rust-ndarray/ndarray
-
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 72/100
rust-ndarray/ndarray#1612 · 1 comentário ·
-
Dificuldade 4/5 3-5 dias Facilidade para iniciantes 48/100
rust-ndarray/ndarray#1617 · 1 comentário ·
-
Stack overflow in `triu` Abertabug good first issue
Dificuldade 3/5 1-2 dias Facilidade para iniciantes 68/100
rust-ndarray/ndarray#1615 · 1 comentário ·
-
Dificuldade 4/5 3-5 dias Facilidade para iniciantes 48/100
rust-ndarray/ndarray#1610 ·
-
Dificuldade 3/5 1-2 dias Facilidade para iniciantes 72/100
rust-ndarray/ndarray#1609 ·
Todas as issues de rust-ndarray/ndarray
Issues semelhantes
-
risk:low runtime status:in-progress type:test
Dificuldade 1/5 Menos de uma hora Facilidade para iniciantes 92/100
zeroclaw-labs/zeroclaw#11023 ·
-
good first issue refactor
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 72/100
-
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 84/100
EricSpencer00/Resilient#4835 · 1 comentário ·
-
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 74/100
bisq-network/bisq-musig#204 ·
-
agent:ready documentation
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 88/100
cesarferreira/stax#890 ·