I need to create matrix from a large array (>>10000 elements) for further use. I have tried Outer and ParallelTable commands, among which Outer seems to be faster when the array size is not so large;
Edit: Array ti below is given in terms Range for simplicity but in general it is intended to represent an arbitrary time series.
<< Developer`
tf = 100;
d = 1;
ti = N@Range[-tf, tf, d];
Nt = Length[ti];
m1 = Developer`ToPackedArray[Outer[Subtract, ti, ti]]; // RepeatedTiming
{0.007300590625, Null}
m2 = Developer`ToPackedArray[ParallelTable[Table[ti[[i]] - ti[[j]], {j, 1, Nt}],
{i, 1, Nt}]]; // RepeatedTiming
{0.03681925625, Null}
But for larger array size I have got
tf = 1000;
d = 1;
ti = N@Range[-tf, tf, d];
Nt = Length[ti];
m1 = Developer`ToPackedArray[
Outer[Subtract, ti, ti]]; // RepeatedTiming; // RepeatedTiming
{0.74297815, Null}
m2 = Developer`ToPackedArray[ParallelTable[Table[ti[[i]] - ti[[j]], {j, 1, Nt}], {i, 1,
Nt}]]; // RepeatedTiming
{0.1460876, Null}
which is run on a 64-core machine (ver. 12.3). I was wondering if there is a more efficient way of doing this. I also need to construct the matrix:
tf = 1000;
d = 1;
ti = N@Range[-tf, tf, d];
Nt = Length[ti];
m3 = Developer`ToPackedArray[
ParallelTable[Table[If[i != j, 1/(ti[[i]] - ti[[j]]), 0], {i, 1, Nt}], {j, 1,
Nt}]]; // RepeatedTiming
{0.8566911, Null}
where diagonal values are to be excluded. Apparently, the if statement inside Table introduces a slow down. I have seen a similar problem posted here, but it is not obvious to me how to implement those solutions inside ParallelTable.
ToPackedArray[Outer[Subtract, ti, ti]]
is about 750 slower thanToPackedArray[Outer[Plus, ti, -ti]];
$\endgroup$m1
is a rank-1-matrix and there are many ways to exploit this.m2
is a Toeplitz matrix, and there also many algorithms that avoid forming it in the first place (e.g., some use fast Fourier transform). So I think it is quite likely that you don't have to brute-force it. $\endgroup$