The code here is:
protected override void DoTransposeAndMultiply(Matrix<double> other, Matrix<double> result)
{
for (var j = 0; j < RowCount; j++)
{
for (var i = 0; i < RowCount; i++)
{
var s = 0.0;
for (var l = 0; l < ColumnCount; l++)
{
s += At(i, l) * other.At(j, l);
}
result.At(i, j, s);
}
}
}
With einstein/summation notation, what we should be doing is:
C_ij = A_il * B_lj^T = A_il * B_jl
i:Ranges from 1 to A.Rows
j:Ranges from 1 to B.Rows
l:Ranges from 1 to A.Columns or B.Columns since they are equal.
Therefore, in the code, j should be:
for (var j = 0; j < other.RowCount; j++) instead of for (var j = 0; j < RowCount; j++)
Another way to perceive a problem is to note that i and j both range from 0 to RowCount(exclusive). Therefore the resulting matrix C_ij would always be square which is not the case.
On another note, I don't understand WHEN this method would actually be called. The calls I find (eg in DenseMatrix:Matrix) are like this:
if (denseOther == null || denseResult == null)
{
base.DoTransposeAndMultiply(other, result);
}
So this method is called only when one of the parameters are null?
Comments: Fixed in changeset 8206966c88b1
protected override void DoTransposeAndMultiply(Matrix<double> other, Matrix<double> result)
{
for (var j = 0; j < RowCount; j++)
{
for (var i = 0; i < RowCount; i++)
{
var s = 0.0;
for (var l = 0; l < ColumnCount; l++)
{
s += At(i, l) * other.At(j, l);
}
result.At(i, j, s);
}
}
}
With einstein/summation notation, what we should be doing is:
C_ij = A_il * B_lj^T = A_il * B_jl
i:Ranges from 1 to A.Rows
j:Ranges from 1 to B.Rows
l:Ranges from 1 to A.Columns or B.Columns since they are equal.
Therefore, in the code, j should be:
for (var j = 0; j < other.RowCount; j++) instead of for (var j = 0; j < RowCount; j++)
Another way to perceive a problem is to note that i and j both range from 0 to RowCount(exclusive). Therefore the resulting matrix C_ij would always be square which is not the case.
On another note, I don't understand WHEN this method would actually be called. The calls I find (eg in DenseMatrix:Matrix) are like this:
if (denseOther == null || denseResult == null)
{
base.DoTransposeAndMultiply(other, result);
}
So this method is called only when one of the parameters are null?
Comments: Fixed in changeset 8206966c88b1