On 01.03.20 21:58, p.shkadzko wrote:
******************************************************************
Matrix!T matrixDotProduct(T)(Matrix!T m1, Matrix!T m2)
in
{
assert(m1.rows == m2.cols);
This asserts that the result is a square matrix. I think you want
`m1.cols==m2.rows` instead.
}
do
{
Matrix!T m3 = Matrix!T(m1.rows, m2.cols);
for (int i; i < m1.rows; ++i)
{
for (int j; j < m2.cols; ++j)
{
for (int k; k < m2.rows; ++k)
{
m3.data[toIdx(m3, i, j)] += m1[i, k] * m2[k, j];
}
}
}
return m3;
}
******************************************************************
...
I can see that accessing the appropriate array member in Matrix.data is
costly due to toIdx operation but, I can hardly explain why it gets so
much costly. Maybe there is a better way to do it after all?
Changing the order of the second and third loop probably goes a pretty
long way in terms of cache efficiency:
Matrix!T matrixDotProduct(T)(Matrix!T m1,Matrix!T m2)in{
assert(m1.cols==m2.rows);
}do{
int m=m1.rows,n=m1.cols,p=m2.cols;
Matrix!T m3=Matrix!T(m,p);
foreach(i;0..m) foreach(j;0..n) foreach(k;0..p)
m3.data[i*p+k]+=m1.data[i*n+j]*m2.data[j*p+k];
return m3;
}
(untested.)