Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Investigate unravel_indices() / ravel_indices() functions #187

Open
DavisVaughan opened this issue May 24, 2019 · 2 comments
Open

Investigate unravel_indices() / ravel_indices() functions #187

DavisVaughan opened this issue May 24, 2019 · 2 comments
Labels
feature ✨ a feature request or enhancement

Comments

@DavisVaughan
Copy link
Member

https://xtensor.readthedocs.io/en/latest/indices.html?highlight=unravel_indices

@juangomezduaso
Copy link

As you commented in #77 (comment)
these two should be exported for rray users to be able to emulate the matriz indexing of base R arrays.
I had put there my "fearless" recursive R prototype of ravel:

rray_i2p <- function(mat,dim){
  stopifnot(dim >= apply(mat,2,max))
  if(ncol(mat) == 1) as.vector(mat) else
  mat[,1]+dim[[1]]*(rray_i2p(mat[,2:ncol(mat),drop = FALSE], dim[-1])-1)
}

And the companion unravel would be:

rray_p2i <- function(p,dim){ 
  len<-length(dim)
  if(len == 1) p else{
    prd<-prod(dim[-len])
    cbind(rray_p2i(((p-1) %% prd)+1,dim[-len]), ((p-1) %/% prd)+1)
  }
}

@DavisVaughan DavisVaughan added the feature ✨ a feature request or enhancement label May 24, 2019
@juangomezduaso
Copy link

Some thougths about indexing:

Let X be an (a)rray and dim(x)=c(d1,...,dn)

To subset it, there can be just one parameter, called positions as it refers to flat position in the data.
Or there can be n parameters called indexes. These may be interpreted in two possible ways: They are meant to be cross mutiplied (selecting "rectangles" in the cells) or they are to be "paired" forming tuples of n coordinates of the X elements we want (Cartesian indexes in Julia's terms or matrix indexing in base R)

So FUN(X, pos) can be:
A) A flat single index with a flat result
---> rray_yank()
B) A flat single index with dims(result) == n
---> NONSENSE

And FUN(X,I1,...,In) can be:
a) Flat indices to be crossed. The result is flat
---> rray_extract()
b) Flat indices to be crossed. dims(result) == n
---> rray_subset()
c) Flat indices to be paired. The result is flat
---> base R matrix indexing (with the indexes joined as columns of a matrix)
d) Flat indices to be paired. dims(result) == n
---> NONSENSE
e) Array indices to be crossed. dim(result) == c(dim(I1),... dim(In))
---> Simple Julia (without Cartesian indexes, etc. I dont know much of this lang, but this is what I concluded from issue #89 )
f) Array indices to be paired (after broadcasting to their common dimension: D). dim(result) == D
--> numpy array indexing

The last one, numpy array indexing, is quite powerfull and seems to be able to emulate any of the others choosing appropiate arrays (achieves crossproducts because of broadcasting rules)
For instance, the limited Julia one (e) would be:
x <- array(1:12,c(4,3))
e( x , array(1:4,c(2,2)) , c(2,3)) == f( x , array(1:4,c(2,2) , array(2:3, c(1,1,2) )

Rray doesn't have this numpy function, and perhaps it shouldn't (I find it very difficult to think of cases of actual use of it).
But, given its broadcasting capability and current functions, it isn't difficult at all to define it in rray terms:

library(rray)
library(purrr)
rray_i2p <- function(mat,dim){
  stopifnot(dim >= apply(mat,2,max))
  if(ncol(mat) == 1) as.vector(mat) else
    mat[,1]+dim[[1]]*(rray_i2p(mat[,2:ncol(mat),drop = FALSE], dim[-1])-1)
}

### # rray Super SubSet
rray_sss <-function(x, ...){  
  library(purrr)
  indexList <- list(...)
  commonDim <- rray_dim_common(...)
  homogeneousList <- map(indexList, function(ind) rray_broadcast(ind,commonDim))
  lengths <- map(homogeneousList, length)
  flattenList <- map2(homogeneousList, lengths,  rray_reshape)
  coordMatrix <- as.matrix( reduce(flattenList, rray_cbind) )
  positions <- rray_i2p(coordMatrix, dim(x))
  flatResult<- rray_yank(x, positions)
  finalResult <- rray_reshape(flatResult,commonDim )
  finalResult
}
rr <- rray(1:36, c(6,3,2))
rray_sss(rr,1,1,2)
#> <rray<int>[1]>
#> [1] 19
rray_sss(rr, rray(1:6,c(2,3)),1,2)
#> <rray<int>[,3][6]>
#>      [,1] [,2] [,3]
#> [1,]   19   21   23
#> [2,]   20   22   24
rray_sss(rr, rray(1:6,c(2,3)),rray(1:2,c(1,1,2)),2)
#> <rray<int>[,3,2][12]>
#> , , 1
#> 
#>      [,1] [,2] [,3]
#> [1,]   19   21   23
#> [2,]   20   22   24
#> 
#> , , 2
#> 
#>      [,1] [,2] [,3]
#> [1,]   25   27   29
#> [2,]   26   28   30

Created on 2019-05-26 by the reprex package (v0.2.1)

@DavisVaughan DavisVaughan modified the milestone: 0.1.0 Jun 4, 2019
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
feature ✨ a feature request or enhancement
Projects
None yet
Development

No branches or pull requests

2 participants