Skip to content

Column-major vs. row-major broadcasting #57

@DavisVaughan

Description

@DavisVaughan

Hi xtensor team, really impressed with your product. I'm working on some examples using R, but I'm having a bit of trouble with the broadcasting piece. I think there might be a bug in the xtensor-r headers somewhere.

My guess is that the issue lies in the difference between how R and xtensor/python denote dimensions (if im not mistaken).

In R) (2, 3, 4) == (2 row, 3 col, 4 deep)
In python/xtensor) (2, 3, 4) == (2 deep, 3 rows, 4 cols)

With that said, take a look at my example below of a simple broadcast. It seems like the dimensions get mixed up somewhere along the way.

Cpp file:

https://gist.githubusercontent.com/DavisVaughan/1bebb3219fb08c48f91fa5ad3411643a/raw/fc75cc083672d7c26db62c47c1dea05a1eb5a0d0/xtensor-cpp.cpp

# download and source the file
url_link <- 'https://gist.githubusercontent.com/DavisVaughan/1bebb3219fb08c48f91fa5ad3411643a/raw/fc75cc083672d7c26db62c47c1dea05a1eb5a0d0/xtensor-cpp.cpp'
tf <- tempfile(fileext = ".cpp")
download.file(url_link, tf)
Rcpp::sourceCpp(tf)

mat <- matrix(c(1,2,3,4), ncol = 2)
mat
#>      [,1] [,2]
#> [1,]    1    3
#> [2,]    2    4

# I expect to be able to go from:
# [2,2] -> [2,2,1] == [2 rows, 2 cols] -> [2 rows, 2 cols, 1 deep]

mtrx_broadcast_cpp(mat, c(2, 2, 1))
#> , , 1
#> 
#>      [,1] [,2]
#> [1,]    1    2
#> [2,]    1    2
#> 
#> , , 2
#> 
#>      [,1] [,2]
#> [1,]    3    4
#> [2,]    3    4

# Okay...maybe I was supposed to do it the python way?
# [1, 2, 2] == [1 deep, 2 row, 2 col]
mtrx_broadcast_cpp(mat, c(1, 2, 2))
#> , , 1
#> 
#>      [,1] [,2]
#> [1,]    1    2
#> 
#> , , 2
#> 
#>      [,1] [,2]
#> [1,]    3    4

# Frustrating!

# this works with numpy, and I think it works with xtensor,
# the diffference is just the R vs xtensor way of defining dimensions
library(reticulate)

np <- import("numpy", convert = FALSE)

two_by_two <- np$ones(c(2L,2L))
two_by_two
#> [[1. 1.]
#>  [1. 1.]]

np$broadcast_to(two_by_two, c(1L,2L,2L))
#> [[[1. 1.]
#>   [1. 1.]]]

# more informative would be to do..
np$broadcast_to(two_by_two, c(3L,2L,2L))
#> [[[1. 1.]
#>   [1. 1.]]
#> 
#>  [[1. 1.]
#>   [1. 1.]]
#> 
#>  [[1. 1.]
#>   [1. 1.]]]

# I want ^ this behavior, but if possible, with R semantics where I would
# specify c(2,2,3) as the dimension to broadcast to, but it doesnt even
# work right now so lets focus on that

Created on 2018-11-06 by the reprex
package
(v0.2.0).

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions