xtensor-stack / xtensor

C++ tensors with broadcasting and lazy computing
BSD 3-Clause "New" or "Revised" License
3.33k stars 398 forks source link

bug in xt::transpose #911

Closed achbogga closed 6 years ago

achbogga commented 6 years ago

Hello @wolfv, The transpose changes the shape altogether instead of just interchanging dimensions. However, after explicitly reshaping the output of the transpose, it produces the correct shape. Please find the code below to reproduce.

#include <iostream>
#include "xtensor/xarray.hpp"
#include "xtensor/xio.hpp"
#include "xtensor/xview.hpp"
#include "xtensor/xrandom.hpp"

xt::xarray<float> bbreg (xt::xarray<float> boundingbox, xt::xarray<float> reg){
    if (reg.shape()[1] == 1) {
        reg.reshape({reg.shape()[2], reg.shape()[3]});
    }
    xt::xarray<float> w = xt::view(boundingbox, xt::all(), xt::range(2, 3)) - xt::view(boundingbox, xt::all(), xt::range(0, 1)) + 1;
    xt::xarray<float> h = xt::view(boundingbox, xt::all(), xt::range(3, 4)) - xt::view(boundingbox, xt::all(), xt::range(1, 2)) + 1;
    xt::xarray<float> b1 = xt::view(boundingbox, xt::all(), xt::range(0, 1)) + xt::view(reg, xt::all(), xt::range(0, 1)) * w;
    xt::xarray<float> b2 = xt::view(boundingbox, xt::all(), xt::range(1, 2)) + xt::view(reg, xt::all(), xt::range(1, 2)) * h;
    xt::xarray<float> b3 = xt::view(boundingbox, xt::all(), xt::range(2, 3)) + xt::view(reg, xt::all(), xt::range(2, 3)) * w;
    xt::xarray<float> b4 = xt::view(boundingbox, xt::all(), xt::range(3, 4)) + xt::view(reg, xt::all(), xt::range(3, 4)) * h;
    xt::xarray<float> temp = xt::eval(xt::stack(xt::xtuple(b1, b2, b3, b4)));
    unsigned long s0 = temp.shape()[0];
    unsigned long s1 = temp.shape()[1];
    std::cout<<"shape: "<<temp.shape()[0]<<", "<<temp.shape()[1]<<std::endl;
    xt::xarray<float> bb = xt::transpose(temp);
    std::cout<<"Transposed_shape: "<<bb.shape()[0]<<", "<<bb.shape()[1]<<std::endl;
    bb.reshape({s1, s0});
    auto bbox_view = xt::view(boundingbox, xt::all(), xt::range(0, 4));
    bbox_view = bb;
    return boundingbox;
}

xt::xarray<float> bbox({{-1.33598027,  0.31358283, -1.99388256,  0.24313656,  1.52885351,
         1.42143409, -0.68947512, -1.33021607, -2.00205028},
       { 0.86186279,  1.01884823, -0.94593089,  0.21136485,  1.29498418,
        -0.21662999, -0.29394309, -0.29340567,  0.32998525}});

xt::xarray<float> reg({{-0.55346639,  1.10484855, -1.35467046,  1.04685913},
       { 0.19267705,  0.55373957, -1.08560568, -1.42928186}});

std::cout<<bbreg(bbox, reg)<<std::endl;
JohanMabille commented 6 years ago

Hello,

Not sure to understand your issue nor the behavior you expect from transpose. Here is a small example of transpose with its output, everything works as expected:

xarray<int> a = { {1, 2, 3}, {4, 5, 6} };
auto b = transpose(a);

std::cout << "shape: (" << a.shape()[0] << ", " << a.shape()[1] << ")" << std::endl;
std::cout << a << std::endl;

std::cout << "shape: (" << b.shape()[0] << ", " << b.shape()[1] << ")" << std::endl;
std::cout << b << std::endl;

The output is:

shape: (2, 3)
{{1, 2, 3},
 {4, 5, 6}}
shape: (3, 2)
{{1, 4},
 {2, 5},
 {3, 6}}
wolfv commented 6 years ago

The dimension after the stack is not what you are expecting -- it's 3D.

achbogga commented 6 years ago

Thanks, my bad. @wolfv and @JohanMabille .

wolfv commented 6 years ago

No problem!

For the future, examples with really minimal amount of code are much preferred!

Cheers,

Wolf