# Multiplying transposed matrices in mir

Sun Apr 19 17:55:06 UTC 2020

```On Sunday, 19 April 2020 at 17:22:12 UTC, jmh530 wrote:
> On Sunday, 19 April 2020 at 17:07:36 UTC, p.shkadzko wrote:
>> I'd like to calculate XX^T where X is some [m x n] matrix.
>>
>> // create a 3 x 3 matrix
>> Slice!(double*, 2LU) a = [2.1, 1.0, 3.2, 4.5, 2.4, 3.3, 1.5,
>> 0, 2.1].sliced(3, 3);
>> auto b = a * a.transposed; // error
>>
>> Looks like it is not possible due to "incompatible types for
>> (a) * (transposed(a)): Slice!(double*, 2LU,
>> cast(mir_slice_kind)2) and Slice!(double*, 2LU,
>> cast(mir_slice_kind)0)"
>>
>> I'd like to understand why and how should this operation be
>> performed in mir.
>> Also, what does the last number "0" or "2" means in the type
>> definition "Slice!(double*, 2LU, cast(mir_slice_kind)0)"?
>
> 2 is Contiguous, 0 is Universal, 1 is Canonical. To this day, I
> don’t have the greatest understanding of the difference.
>
> Try the mtimes function in lubeck.

Ah, I see. There are docs on internal representations of Slices
but nothing about the rationale. It would be nice to have them
since it is pretty much the core of Slice.

"a.mtimes(a.transposed);" works but the results are different
from what NumPy gives.

For example:

a = np.array([[1, 2], [3, 4]])
a * a.transpose() # [[1, 6], [6, 16]]

Slice!(int*, 2LU) a = [1, 2, 3, 4].sliced(2,2);
writeln(a.mtimes(a.transposed)); // [[5, 11], [11, 25]]

So, lubeck mtimes is equivalent to NumPy "a.dot(a.transpose())".

```