You need to implement the following function:

void correlate(int ny, int nx, const float* data, float* result)

Here `data`

is a pointer to the input matrix, with `ny`

rows and `nx`

columns. For all `0 <= y < ny`

and `0 <= x < nx`

, the element at row `y`

and column `x`

is stored in `data[x + y*nx]`

.

The function has to solve the following task: for all `i`

and `j`

with `0 <= j <= i < ny`

, calculate the correlation coefficient between row `i`

of the input matrix and row `j`

of the input matrix, and store the result in `result[i + j*ny]`

.

Note that the correlations are symmetric, so we will only compute the upper triangle of the result matrix. You can leave the lower triangle `i < j`

undefined.

The arrays `data`

and `result`

are already allocated by whoever calls this function; you do not need to do any memory management related to these arrays.

The input and output are always given as single-precision floating point numbers (type `float`

). However, depending on the task, we will do arithmetic with either single or double precision numbers:

- If the task specifies that you must use double-precision floating point numbers, then
*all*arithmetic operations must be done with type`double`

, all intermediate results must be stored in variables of type`double`

, and you will only round the final result to single precision. - If the task specifies that you can use single-precision floating point numbers, then you are encouraged to use the type
`float`

whenever possible.

However, in each case you will have to make sure the numerical precision of the results is sufficiently high. The grading tool makes sure the error is sufficiently small. The error thresholds are chosen so that a straightforward and efficient solution is typically good enough, but please feel free to ask the course staff for hints if you are struggling with the rounding errors.