Matrix transposition

From Rosetta Code
Revision as of 23:37, 27 November 2008 by 71.106.183.17 (talk) (added common lisp and ruby)
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: <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; </ada> 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));

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

Common Lisp

<lisp>(defun transpose (m)

 (apply #'map #'list m))</lisp>

D

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

}</d>


Fortran

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

   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

In ANSI FORTRAN 77 with MIL-STD-1753 extensions 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

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

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

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

}</java>

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:

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

This will output:

1 5
2 6
3 7
4 8

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

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

Example:

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

Perl

<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;</perl>

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

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

<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))</python> Output:

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

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 Output:

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

Scheme

<scheme>(define (transpose m)

 (apply map list m))</scheme>

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.