Matrix transposition

From Rosetta Code
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

This example creates a matrix type of arbitrary length using a generic package. The array element type is any floating point type. The array index type is any discrete value. For this example an enumerated type is used for the index type.

generic
   type Element_Type is digits <>;
   type Row_Index is (<>);

package Rect_Real_Matrix is
   type Rect_Matrix is array (Row_Index range <>, Row_Index range <>) of Element_Type;
   function Transpose(Item : Rect_Matrix) return Rect_Matrix;
   procedure Print(Item : Rect_Matrix);
end Rect_Real_Matrix;
with Ada.Text_Io;  

package body Rect_Real_Matrix is
   
   -----------
   -- Print --
   -----------
   
   procedure Print(Item : Rect_Matrix) is
      package Real_Io is new Ada.Text_Io.Float_Io(Element_Type);
      use Real_Io;
      use Ada.Text_Io;
   begin
      for I in Item'range(1) loop
         for J in Item'range(2) loop
            Put(Item => Item(I,J), Exp => 0, Fore => 5);
            Put(" ");
         end loop;
         New_Line;
      end loop;
   end Print;
   
   ---------------
   -- Transpose --
   --------------- 

   function Transpose (Item : Rect_Matrix) return Rect_Matrix is
      Temp : Rect_Matrix(Item'Range(2), Item'Range(1));
   begin
      for Col in Item'range(1) loop
         for Row in Item'range(2) loop
            Temp(Row,Col) := Item(Col,Row);
         end loop;
      end loop;
      return Temp;
   end Transpose; 

end Rect_Real_Matrix;
with Rect_Real_Matrix;
with Ada.Text_IO; use Ada.Text_IO; 

procedure Rect_Mat_Transpose is
   type Col_Index is (Severe, High, Moderate, Low, Insignificant);
   subtype Row_Index is Col_Index range Severe..Low;
   package Flt_Mat is new Rect_Real_Matrix(Float, Col_Index);
   use Flt_Mat;
   
   M : Rect_Matrix(Col_Index, Row_Index) := ((1.0,  1.0,  1.0,   1.0),
       (2.0,  4.0,  8.0,  16.0),
       (3.0,  9.0, 27.0,  81.0),
       (4.0, 16.0, 64.0, 256.0),
      (5.0, 25.0,125.0, 625.0));
   
begin
   Put_line("Before Transposition:");
   Print(M);
   New_Line;
   Put_Line("After Transposition:");
   Print(Transpose(M));
end Rect_Mat_Transpose;

Output:

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

After Transposition:
    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

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));

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

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()) ;
}


Fortran

In ISO Fortran 90 or later, use the TRANSPOSE intrinsic function:

 REAL, DIMENSION(N,M) :: A = RESHAPE( (/ (i,i=1,n*m) /), (/ n, m /) )
 REAL, DIMENSION(M,N) :: B
 
 B = TRANSPOSE(A)

In MIL-STD-1753 Fortran or later, use nested structured DO loops:

     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

In ANSI FORTRAN 66 or later, use nested labeled DO loops:

     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

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

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));
		}
	}
}

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

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;

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

Python

#!/usr/bin/env python
from pprint import pprint
m=((1,  1,  1,   1),
   (2,  4,  8,  16),
   (3,  9, 27,  81),
   (4, 16, 64, 256),
   (5, 25,125, 625));
pprint(zip(*m))

Output:

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

Scheme

(define (transpose m)
  (apply map list m))

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.