Matrix transposition

From Rosetta Code
Revision as of 22:34, 17 June 2009 by rosettacode>Tinku99 (+ AutoHotkey)
Task
Matrix transposition
You are encouraged to solve this task according to the task description, using any language you may know.

Transpose an arbitrarily sized rectangular Matrix.

Ada

Transpose is a function of the standard Ada library provided for matrices built upon any floating-point or complex type. The relevant packages are Ada.Numerics.Generic_Real_Arrays and Ada.Numerics.Generic_Complex_Arrays, correspondingly.

This example illustrates use of Transpose for the matrices built upon the standard type Float: <lang ada> with Ada.Numerics.Real_Arrays; use Ada.Numerics.Real_Arrays; with Ada.Text_IO; use Ada.Text_IO;

procedure Matrix_Transpose is

  procedure Put (X : Real_Matrix) is
     type Fixed is delta 0.01 range -500.0..500.0;
  begin
     for I in X'Range (1) loop
        for J in X'Range (2) loop
           Put (Fixed'Image (Fixed (X (I, J))));
        end loop;
        New_Line;
     end loop;
  end Put;
   
  Matrix : constant Real_Matrix :=
           (  (0.0, 0.1, 0.2, 0.3),
              (0.4, 0.5, 0.6, 0.7),
              (0.8, 0.9, 1.0, 1.1)
           );

begin

  Put_Line ("Before Transposition:");
  Put (Matrix);
  New_Line;
  Put_Line ("After Transposition:");
  Put (Transpose (Matrix));

end Matrix_Transpose; </lang> Sample output:

Before Transposition:
 0.00 0.10 0.20 0.30
 0.40 0.50 0.60 0.70
 0.80 0.90 1.00 1.10

After Transposition:
 0.00 0.40 0.80
 0.10 0.50 0.90
 0.20 0.60 1.00
 0.30 0.70 1.10

ALGOL 68

main:(

  [,]REAL m=((1,  1,  1,   1),
             (2,  4,  8,  16),
             (3,  9, 27,  81),
             (4, 16, 64, 256),
             (5, 25,125, 625));

  OP ZIP = ([,]REAL in)[,]REAL:(
    [2 LWB in:2 UPB in,1 LWB in:1UPB in]REAL out;
    FOR i FROM LWB in TO UPB in DO
       out[,i]:=in[i,] 
    OD;
    out
  );

  PROC pprint = ([,]REAL m)VOID:(
    FORMAT real fmt = $g(-6,2)$; # width of 6, with no '+' sign, 2 decimals #
     FORMAT vec fmt = $"("n(2 UPB m-1)(f(real fmt)",")f(real fmt)")"$;
    FORMAT matrix fmt = $x"("n(UPB m-1)(f(vec fmt)","lxx)f(vec fmt)");"$;
    # finally print the result #
    printf((matrix fmt,m))
  );

  printf(($x"Transpose:"l$));
  pprint((ZIP m))
)

Output:

Transpose:
((  1.00,  2.00,  3.00,  4.00,  5.00),
 (  1.00,  4.00,  9.00, 16.00, 25.00),
 (  1.00,  8.00, 27.00, 64.00,125.00),
 (  1.00, 16.00, 81.00,256.00,625.00));

AutoHotkey

<lang AutoHotkey>a = a m = 10 n = 10 loop, 10 {

 i := A_Index - 1
 loop, 10
 {

j := A_Index - 1 %a%%i%%j% := i - j

 }

} before := matrix_print("a", m, n) transpose("a", m, n) after := matrix_print("a", m, n) msgbox % before . "`ntransposed:`n" . after return

transpose(a, m, n) { local i, j, row, matrix loop, % m {

 i := A_Index - 1
 loop, % n 
   {

j := A_Index - 1 temp%i%%j% := %a%%j%%i% } }

loop, % m {

 i := A_Index - 1
 loop, % n 
   {

j := A_Index - 1 %a%%i%%j% := temp%i%%j% } } }

matrix_print(a, m, n) { local i, j, row, matrix loop, % m {

 i := A_Index - 1
 row := ""
 loop, % n 
   {

j := A_Index - 1 row .= %a%%i%%j% . "," } stringtrimright, row, row, 1 matrix .= row . "`n" } return matrix }</lang>

BASIC

Works with: QuickBasic version 4.5
CLS
DIM m(1 TO 5, 1 TO 4) 'any dimensions you want

'set up the values in the array
FOR rows = LBOUND(m, 1) TO UBOUND(m, 1) 'LBOUND and UBOUND can take a dimension as their second argument
       FOR cols = LBOUND(m, 2) TO UBOUND(m, 2)
       m(rows, cols) = rows ^ cols 'any formula you want
       NEXT cols
NEXT rows

'declare the new matrix
DIM trans(LBOUND(m, 2) TO UBOUND(m, 2), LBOUND(m, 1) TO UBOUND(m, 1))

'copy the values
FOR rows = LBOUND(m, 1) TO UBOUND(m, 1)
       FOR cols = LBOUND(m, 2) TO UBOUND(m, 2)
       trans(cols, rows) = m(rows, cols)
       NEXT cols
NEXT rows

'print the new matrix
FOR rows = LBOUND(trans, 1) TO UBOUND(trans, 1)
       FOR cols = LBOUND(trans, 2) TO UBOUND(trans, 2)
       PRINT trans(rows, cols);
       NEXT cols
PRINT
NEXT rows

C

Reserving the proper space for the matrix is left to the caller.

<lang c>void transpose_matrix(double *m,

                     double *d,
                     int rows, int columns)

{

int i,j; 
for(i = 0; i < rows; i++)
{
  for(j = 0; j < columns; j++)
  {
     d[j*rows+i] = m[i*columns+j];
  }
}

}</lang>

Usage example (note that you must specify first the row, then the column):

<lang c>int main() {

  int i,j;
  double a[4][5] = {{  1.00,  2.00,  3.00,  4.00,  5.00},
                    {  1.00,  4.00,  9.00, 16.00, 25.00},
                    {  1.00,  8.00, 27.00, 64.00,125.00},
                    {  1.00, 16.00, 81.00,256.00,625.00}};
  
  double b[5][4];
  
  transpose_matrix(&a[0][0], &b[0][0], 4, 5);
  for(j=0;j<4;j++)
  {
    for(i=0;i<5;i++)
    {
       printf("%6.2lf ", a[j][i]);
    }
    printf("\n");
  }
  printf("--\n");
  for(j=0;j<5;j++)
  {
    for(i=0;i<4;i++)
    {
       printf("%6.2lf ", b[j][i]);
    }
    printf("\n");
  }

}</lang>

Output:

  1.00   2.00   3.00   4.00   5.00
  1.00   4.00   9.00  16.00  25.00
  1.00   8.00  27.00  64.00 125.00
  1.00  16.00  81.00 256.00 625.00
--
  1.00   1.00   1.00   1.00
  2.00   4.00   8.00  16.00
  3.00   9.00  27.00  81.00
  4.00  16.00  64.00 256.00
  5.00  25.00 125.00 625.00


Common Lisp

<lang lisp>(defun transpose (m)

 (apply #'mapcar #'list m))</lang>

D

<lang d>module mxtrans ; import std.stdio ; import std.string ;

bool isRectangular(T)(T[][] a){

 if(a.length < 1 || a[0].length < 1)
   return false ;
 for(int i = 1 ; i < a.length; i++)
   if(a[i].length != a[i-1].length)
     return false ;
 return true ;

}

T[][] transpose(T=real)(T[][] a) {

 T[][] res ;
 if(isRectangular(a)){
   res = new T[][](a[0].length, a.length) ;
   for(int i = 0 ; i < a.length ; i++)
     for(int j = 0 ; j < a[0].length ; j++) {
         res[j][i] = a[i][j] ;
     }
 } else 
   throw new Exception("Transpose Error") ;
 return res ;

}

string toString(T=real)(T[][] a){ // for pretty print

 string[] s;
 foreach(e ; a)
   s ~= format("%8s", e)[1..$-1] ;
 return  "\n<" ~ join(s,"\n ") ~ ">" ;

}

void main() {

 float[][] n, m = [[0.5,0,0,1],[0.0,0.5,0,0],[0.0,0,0.5,-1]] ;
 writefln(" m = ", m.toString()) ;
 n = m.transpose() ;
 writefln(" n (m's transpose) = ", n.toString()) ;

}</lang>

ELLA

Sample originally from ftp://ftp.dra.hmg.gb/pub/ella (a now dead link) - Public release.

Code for matrix transpose hardware design verification:

MAC TRANSPOSE = ([INT n][INT m]TYPE t: matrix) -> [m][n]t:
  [INT i = 1..m] [INT j = 1..n] matrix[j][i].

Fortran

In ISO Fortran 90 or later, use the TRANSPOSE intrinsic function: <lang fortran> integer, parameter  :: n = 3, m = 5

   real, dimension(n,m) :: a = reshape( (/ (i,i=1,n*m) /), (/ n, m /) )
   real, dimension(m,n) :: b
   
   b = transpose(a)
   
   do i = 1, n
       print *, a(i,:)
   end do
   
   do j = 1, m
       print *, b(j,:)
   end do</lang>

In ANSI FORTRAN 77 with MIL-STD-1753 extensions or later, use nested structured DO loops: <lang fortran> REAL A(3,5), B(5,3)

     DATA ((A(I,J),I=1,3),J=1,5) /1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15/
     
     DO I = 1, 3
        DO J = 1, 5
           B(J,I) = A(I,J)
        END DO
     END DO</lang>

In ANSI FORTRAN 66 or later, use nested labeled DO loops: <lang fortran> REAL A(3,5), B(5,3)

     DATA ((A(I,J),I=1,3),J=1,5) /1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15/
     
     DO 10 I = 1, 3
        DO 20 J = 1, 5
           B(J,I) = A(I,J)
  20    CONTINUE
  10 CONTINUE</lang>

GAP

originalMatrix := [[1, 1, 1, 1],
                   [2, 4, 8, 16],
                   [3, 9, 27, 81],
                   [4, 16, 64, 256],
                   [5, 25, 125, 625]];
transposedMatrix := TransposedMat(originalMatrix);

Groovy

The Groovy extensions to the List class provides a transpose method: <lang groovy>def matrix = [ [ 1, 2, 3, 4 ],

              [ 5, 6, 7, 8 ] ]

matrix.each { println it } println() def transpose = matrix.transpose()

transpose.each { println it }</lang>

Output:

[1, 2, 3, 4]
[5, 6, 7, 8]

[1, 5]
[2, 6]
[3, 7]
[4, 8]

Haskell

For matrices represented as lists, there's transpose:

*Main> transpose [[1,2],[3,4],[5,6]]
[[1,3,5],[2,4,6]]

For matrices in arrays, one can use ixmap:

import Data.Array

swap (x,y) = (y,x)

transpArray :: (Ix a, Ix b) => Array (a,b) e -> Array (b,a) e
transpArray a = ixmap (swap l, swap u) swap a where 
  (l,u) = bounds a

IDL

Standard IDL function transpose()

m=[[1,1,1,1],[2, 4, 8, 16],[3, 9,27, 81],[5, 25,125, 625]]
print,transpose(m)

J

Transpose is the monadic primary verb |:

    ]matrix=: 3 5 $ 10+ i. 15   NB. make and show example matrix
10 11 12 13 14
15 16 17 18 19
20 21 22 23 24

   |: matrix
10 15 20
11 16 21
12 17 22
13 18 23
14 19 24

Java

<lang java>import java.util.Arrays; public class Transpose{

      public static void main(String[] args){
              double[][] m = {{1, 1, 1, 1},
                              {2, 4, 8, 16},
                              {3, 9, 27, 81},
                              {4, 16, 64, 256},
                              {5, 25, 125, 625}};
              double[][] ans = new double[m[0].length][m.length];
              for(int rows = 0; rows < m.length; rows++){
                      for(int cols = 0; cols < m[0].length; cols++){
                              ans[cols][rows] = m[rows][cols];
                      }
              }
              for(double[] i:ans){//2D arrays are arrays of arrays
                      System.out.println(Arrays.toString(i));
              }
      }

}</lang>

Mathematica

originalMatrix = {{1, 1, 1, 1},
                  {2, 4, 8, 16},
                  {3, 9, 27, 81},
                  {4, 16, 64, 256},
                  {5, 25, 125, 625}}
transposedMatrix = Transpose[originalMatrix]

Maxima

originalMatrix : matrix([1, 1, 1, 1],
                        [2, 4, 8, 16],
                        [3, 9, 27, 81],
                        [4, 16, 64, 256],
                        [5, 25, 125, 625]);
transposedMatrix : transpose(originalMatrix);

MAXScript

Uses the built in transpose() function

m = bigMatrix 5 4
for i in 1 to 5 do for j in 1 to 4 do m[i][j] = pow i j
m = transpose m

Nial

make an array

|a := 2 3 reshape count 6
=1 2 3
=4 5 6

transpose it

|transpose a
=1 4
=2 5
=3 6

OCaml

Matrices can be represented in OCaml as a type 'a array array, or using the module Bigarray. The implementation below uses a bigarray:

<lang ocaml>open Bigarray

let transpose b =

 let dim1 = Array2.dim1 b
 and dim2 = Array2.dim2 b in
 let kind = Array2.kind b
 and layout = Array2.layout b in
 let b' = Array2.create kind layout dim2 dim1 in
 for i=0 to pred dim1 do
   for j=0 to pred dim2 do
     b'.{j,i} <- b.{i,j}
   done;
 done;
 (b')

let array2_display print newline b =

 for i=0 to Array2.dim1 b - 1 do
   for j=0 to Array2.dim2 b - 1 do
     print b.{i,j}
   done;
   newline();
 done;

let a = Array2.of_array int c_layout [|

 [| 1; 2; 3; 4 |];
 [| 5; 6; 7; 8 |];

|]

array2_display (Printf.printf " %d") print_newline (transpose a) ;;</lang>

This will output:

1 5
2 6
3 7
4 8

A version for lists: <lang ocaml>let rec transpose m =

 assert (m <> []);
 if List.mem [] m then
   []
 else
   List.map List.hd m :: transpose (List.map List.tl m)</lang>

Example:

# transpose [[1;2;3;4];
             [5;6;7;8]];;
- : int list list = [[1; 5]; [2; 6]; [3; 7]; [4; 8]]

Octave

<lang octave>a = [ 1, 1, 1, 1 ;

     2, 4, 8, 16 ;
     3, 9, 27, 81 ;
     4, 16, 64, 256 ;
     5, 25, 125, 625 ];

tranposed = a.'; % tranpose ctransp = a'; % conjugate transpose</lang>


Perl

<lang perl>use Math::Matrix;

$m = Math::Matrix->new(

 [1, 1, 1, 1],
 [2, 4, 8, 16],
 [3, 9, 27, 81],
 [4, 16, 64, 256],
 [5, 25, 125, 625],

);

$m->transpose->print;</lang>

Output:

1.00000    2.00000    3.00000    4.00000    5.00000 
1.00000    4.00000    9.00000   16.00000   25.00000 
1.00000    8.00000   27.00000   64.00000  125.00000 
1.00000   16.00000   81.00000  256.00000  625.00000

PHP

<lang php>function transpose($m) {

 array_unshift($m, NULL);
 return call_user_func_array(array_map, $m); // array_map(NULL, m[0], m[1], ..)

}</lang>

Pop11

define transpose(m) -> res;
    lvars bl = boundslist(m);
    if length(bl) /= 4 then
        throw([need_2d_array ^a])
    endif;
    lvars i, i0 = bl(1), i1 = bl(2);
    lvars j, j0 = bl(3), j1 = bl(4);
    newarray([^j0 ^j1 ^i0 ^i1], 0) -> res;
    for i from i0 to i1 do
        for j from j0 to j1 do
            m(i, j) -> res(j, i);
        endfor;
    endfor;
enddefine;

Python

<lang python>m=((1, 1, 1, 1),

  (2,  4,  8,  16),
  (3,  9, 27,  81),
  (4, 16, 64, 256),
  (5, 25,125, 625))

print(zip(*m))</lang> Output:

[(1, 2, 3, 4, 5),
 (1, 4, 9, 16, 25),
 (1, 8, 27, 64, 125),
 (1, 16, 81, 256, 625)]

Ruby

<lang ruby>m=[[1, 1, 1, 1],

  [2,  4,  8,  16],
  [3,  9, 27,  81],
  [4, 16, 64, 256],
  [5, 25,125, 625]]

puts m.transpose</lang> Output:

[[1, 2, 3, 4, 5], [1, 4, 9, 16, 25], [1, 8, 27, 64, 125], [1, 16, 81, 256, 625]]

or using

Library: matrix.rb

<lang ruby>require 'matrix'

m=Matrix[[1, 1, 1, 1],

        [2,  4,  8,  16],
        [3,  9, 27,  81],
        [4, 16, 64, 256],
        [5, 25,125, 625]]

puts m.transpose</lang> Output:

Matrix[[1, 2, 3, 4, 5], [1, 4, 9, 16, 25], [1, 8, 27, 64, 125], [1, 16, 81, 256, 625]]

Scheme

<lang scheme>(define (transpose m)

 (apply map list m))</lang>

TI-83 BASIC

Assuming the original matrix is in [A], place its transpose in [B]:

[A]T->[B]

The T operator can be found in the matrix math menu.

Tcl

With core Tcl, representing a matrix as a list of lists: <lang tcl>package require Tcl 8.5 namespace path ::tcl::mathfunc

proc size {m} {

   set rows [llength $m]
   set cols [llength [lindex $m 0]]
   return [list $rows $cols]

} proc transpose {m} {

   lassign [size $m] rows cols 
   set new [lrepeat $cols [lrepeat $rows ""]]
   for {set i 0} {$i < $rows} {incr i} {
       for {set j 0} {$j < $cols} {incr j} {
           lset new $j $i [lindex $m $i $j]
       }
   }
   return $new

} proc print_matrix {m} {

   set max [widest $m]
   lassign [size $m] rows cols 
   for {set i 0} {$i < $rows} {incr i} {
       for {set j 0} {$j < $cols} {incr j} {
           puts -nonewline [format "%*s " [lindex $max $j] [lindex $m $i $j]]
       }
       puts ""
   }

} proc widest {m} {

   lassign [size $m] rows cols 
   set max [lrepeat $cols 0]
   for {set i 0} {$i < $rows} {incr i} {
       for {set j 0} {$j < $cols} {incr j} {
           lset max $j [max [lindex $max $j] [string length [lindex $m $i $j]]]
       }
   }
   return $max

}

set m {{1 1 1 1} {2 4 8 16} {3 9 27 81} {4 16 64 256} {5 25 125 625}} print_matrix $m print_matrix [transpose $m]</lang> outputs

1  1   1   1 
2  4   8  16 
3  9  27  81 
4 16  64 256 
5 25 125 625 
1  2  3   4   5 
1  4  9  16  25 
1  8 27  64 125 
1 16 81 256 625

Using the struct::matrix package from

Library: tcllib

<lang tcl>package require struct::matrix struct::matrix M M deserialize {5 4 {{1 1 1 1} {2 4 8 16} {3 9 27 81} {4 16 64 256} {5 25 125 625}}} M format 2string M transpose M format 2string</lang> outputs

1 1  1   1  
2 4  8   16 
3 9  27  81 
4 16 64  256
5 25 125 625
1 2 3 4 5
1 4 9 16 25
         
1 8 27 64 125
         
         
1 16 81 256 625