[Solved] What datatype would is expected for the arrays in c++?


I’m guessing here based on the many questions leading up to this.

It is pretty obvious that you do not want sample type to be a scalar, but a 2-dimensional array.

I will sketch a generic short-cut that would allow you to write mean_square_displacement::operator() to accept those, potentially even without knowing the concrete type(s) of the arguments.

Caution

However, I want to first caution that there is no way to know whether that will work with the multi_tau_correlator framework that you’ve never described. It seems like you are trying to apply the correlator in a parallel fashion.

Firstly it’s unknown whether the correlator framework allows you to do that (technically) and secondly it is likely not going to be fast, as this kind of parallelism is the realm of highly optimized libraries (that use actually vectorized operations like SIMD, AVX, OpenGL/Cuda).

All I see here is a raw quadratic loop, which does not bode well for efficiency.

The blind fix

Since you don’t want sample_type to be what you define it to be, simply define it as something else, preferrably, the thing you need it to be!

typedef array_2d_t sample_type;

There’s a good chance that this is not what you actually are passing either (I suspect a sub_array view or (optionally strided) multi_array_view slice of a 3D multi array). But you can let the compiler figure it out based on the fact that you know you can index the arguments like this arg[int][int]:

template <typename Sample>
result_type operator()(Sample const& msd_x, Sample const& msd_y,
                       Sample const& msd_z) const

This lets the compiler deduce the concrete type, assuming all arguments have the same statical type. Otherwise, you can go even more open:

template <typename Sx, typename Sy, typename Sz>
result_type operator()(Sx const& msd_x, Sy const& msd_y,
                       Sz const& msd_z) const

More Caution

I can see you’re out of your depth. E.g.

  • in your mean_square_displacement we see auto dr being used outside its scope. It will not compile. For the above I have GUESSED that you meant to place the accumulation into the inner loop.
  • you’re also explicitly addressing msd_x out of bounds (index N doesn’t exist, since N == msd_x.size()).
  • Likely msd_y/msd_z have the same extents, so they too have this issue, but even with +2
  • If course the naive fix to loop till N-2 risks UB again unless you make sure that N is never <2

Here’s the minimum fixes that make this code look like it might technically work, though:

struct mean_square_displacement {
    //typedef fixed_vector<double, 3> result_type;
    typedef double result_type;

    template <typename Sample>
    result_type operator()(Sample const& msd_x, Sample const& msd_y,
                           Sample const& msd_z) const
    {
        size_t N = msd_x.size();
        assert(N>=2);
        result_type msd = 0;
        for (unsigned int i = 0; i < N-1; ++i) {
            for (unsigned int j = 0; j < N-2; ++j) {
                auto dr = //
                    (msd_x[i + 1][j + 0] - msd_x[i][j + 0]) +
                    (msd_y[i + 1][j + 1] - msd_y[i][j + 1]) +
                    (msd_z[i + 1][j + 2] - msd_z[i][j + 2]);
                // accumulate squared displacements
                msd += dr * dr;
            }
        }
        return msd / N;

    }
};

7

solved What datatype would is expected for the arrays in c++?