xtensor-stack / xtensor

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

Average: result incorrect #1117

Closed tdegeus closed 6 years ago

tdegeus commented 6 years ago

Consider this simple example:


#include "xtensor/xarray.hpp"
#include "xtensor/xtensor.hpp"
#include "xtensor/xhistogram.hpp"
#include "xtensor/xmath.hpp"
#include "xtensor/xview.hpp"
#include "xtensor/xio.hpp"

int main()
{
    xt::xtensor<double, 4> eps = xt::zeros<double>({10,4,2,2});

    auto epsxy = xt::view(eps, xt::all(), xt::all(), 0, 1);

    epsxy += .1;

    xt::xtensor<double, 4> dV = 0.1 * xt::ones<double>({10,4,2,2});

    std::cout << xt::average(eps, dV, {0,1}) << std::endl;
}

Since the data is homogeneous and all weight factor are the same the answer is trivial to compute:

{{ 0.      ,  0.1     },
 { 0.      ,  0.      }}

However (with the current xtensor master) I get:

{{ 0.      ,  0.025   },
 { 0.      ,  0.      }}

?!?!?

tdegeus commented 6 years ago

I've opened a PR with a test-case that compares to a NumPy result, to avoid future bugs in this function.

(Like the example I gave the PR fails, as it currently should)

tdegeus commented 6 years ago

The PR now contains a PARTIAL bugfix. The case that I presented above is evaluated correctly. However if we evaluate a very simple other test-case (by comparing to NumPy):

#include "xtensor/xarray.hpp"
#include "xtensor/xtensor.hpp"
#include "xtensor/xhistogram.hpp"
#include "xtensor/xmath.hpp"
#include "xtensor/xview.hpp"
#include "xtensor/xio.hpp"

int main()
{
    // py_a
    xt::xarray<double> py_a = {{{0.,1.},
                                {2.,3.}},

                               {{4.,5.},
                                {6.,7.}}};
    // py_w
    xt::xarray<double> py_w = {{{0.,1.},
                                {2.,3.}},

                               {{4.,5.},
                                {6.,7.}}};

    // py_av
    xt::xarray<double> py_av = {4.666666666666667,5.25             };

    auto av = xt::average(py_a, py_w, {0,1});

    std::cout << av << std::endl;
    std::cout << py_av << std::endl;
    std::cout << ( av - py_av ) << std::endl;
}

Result:

{ 4.666667,  7.      }
{ 4.666667,  5.25    }
{ 0.  ,  1.75}

I.e. we find that one axis is correct, while one is incorrect.

tdegeus commented 6 years ago

Closed by #1118