📘 How to transpose a matrix in Perl 6

📘 How to transpose a matrix in Raku

N. B. Perl 6 has been renamed to Raku. Click to read more.


Take a matrix and print its transposed version.

A matrix can be represented by nested arrays or lists. For example, here’s a square 2×2 matrix:

my @matrix = [1, 2],
             [3, 4];

This is how the transposed matrix should look:

[[1, 3],
[2, 4]]

Actually, the outer pair of square brackets, could be added to the initializer of the @matrix variable. Perl 6 simply converts the list ([1, 2], [3, 4])  to an array when assigning it to an array variable @matrix.

Transposing a matrix is extremely easy:

my @transposed = [Z] @matrix;

The [Z] operator is a reduction form of the zip operator. For the given small matrix, it’s action is equivalent to the following code:

my @transposed = [1, 2] Z [3, 4];

Despite the simplicity of the method, it works well with bigger matrices as well as non-square ones.

For the example @matrix in this task, the output of the program is the following:

[(1 3) (2 4)]

2 thoughts on “📘 How to transpose a matrix in Perl 6”

  1. For anyone finding this post in the future (it shows up in search engines to this day), please beware that using [Z] for transposing matrices fails when the input matrix has just one row:

    > [Z] ((1,2,3),)
    ((1 2 3))

    whereas the correct result would be ((1), (2), (3)).

    There’s a section in the docs explaining why [Z] behaves this way (it’s because of the single-argument rule): https://docs.raku.org/language/traps#Using_%5B%E2%80%A6%5D_metaoperator_with_a_list_of_lists

    Thus, it seems that in general one has to resort to a case differentiation:

    given @matrix.elems { # or +@matrix to golf it
    when 0 { () }
    when 1 { @matrix[0].rotor(1) }
    default { [Z] @matrix }
    }

    That’s because personally at least I’m not aware of any simpler idiom for transposition that works correctly in all cases. One might cook up something with slices, e.g. @matrix[*;0] and @matrix[*;1] and so on, but in my experiments this was three times slower. Also, if the transposition is just preparation for another operation, one might also concoct an ad-hoc fix for [Z] by adding two ineffectual rows before zipping: For example, to find the largest entry of each column of a 2-column matrix, one can do [Zmax] |@matrix, (0,0), (0,0) or better yet push the (0,0) somehow because slipping is slower. This guards against the cases of one or zero rows, but is not particularly nice.

    Thus, I hope a proper transposition method gets introduced in the future — if it isn’t out there already.

Leave a Reply

Your email address will not be published. Required fields are marked *

Retype the CAPTCHA code from the image
Change the CAPTCHA codeSpeak the CAPTCHA code