Matrix transposition: Difference between revisions

From Rosetta Code
Content added Content deleted
m (→‎{{header|J}}: add solution/example headings)
Line 411: Line 411:


=={{header|J}}==
=={{header|J}}==
'''Solution:'''<br>
Transpose is the monadic primary verb <code>|:</code>
Transpose is the monadic primary verb <code>|:</code>


'''Example:'''
<lang j> ]matrix=: 10 + i. 3 5 NB. make and show example matrix
<lang j> ]matrix=: 10 + i. 3 5 NB. make and show example matrix
10 11 12 13 14
10 11 12 13 14

Revision as of 22:57, 12 December 2009

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

<lang algol68>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))

)</lang> Output: <lang algol68>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));</lang>

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

Playing more to C's strengths, the following implementation transposes a matrix of any type and dimensions in place with only O(1) space. See the Wikipedia article for more information. <lang c>void *transpose_matrix(void *matrix, int rows, int cols, size_t item_size) {

  1. define ALIGNMENT 16 /* power of 2 >= minimum array boundary alignment; maybe unnecessary but machine dependent */
 char *cursor;
 char carry[ALIGNMENT];
 size_t block_size, remaining_size;
 int nadir, lag, orbit, ents;
 if (rows == 1 || cols == 1)
   return matrix;
 ents = rows * cols;
 cursor = (char *) matrix;
 remaining_size = item_size;
 while ((block_size = ALIGNMENT < remaining_size ? ALIGNMENT : remaining_size))
 {
   nadir = 1;                          /* first and last entries are always fixed points so aren't visited */
   while (nadir + 1 < ents)
   {
     memcpy(carry, &cursor[(lag = nadir) * item_size], block_size);
     while ((orbit = lag / rows + cols * (lag % rows)) > nadir)             /* follow a complete cycle */
     {
       memcpy(&cursor[lag * item_size], &cursor[orbit * item_size], block_size);
       lag = orbit;
     }
     memcpy(&cursor[lag * item_size], carry, block_size);
     orbit = nadir++;
     while (orbit < nadir && nadir + 1 < ents)  /* find the next unvisited index by an exhaustive search */
     {
       orbit = nadir;
       while ((orbit = orbit / rows + cols * (orbit % rows)) > nadir);
       if (orbit < nadir) nadir++;
     }
   }
   cursor += block_size;
   remaining_size -= block_size;
 }
 return matrix;

}</lang> No extra storage allocation is required by the caller. Here are usage examples for an array of doubles and an array of complex numbers. <lang c>a = (double *) transpose_matrix((void *) a, n, m, sizeof(double)); b = (complex *) transpose_matrix((void *) b, n, m, sizeof(complex));</lang> After execution, the memory maps of a and b will be those of m by n arrays instead of n by m.

Common Lisp

<lang lisp>(defun transpose (m)

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

D

<lang d>import std.stdio: writefln; import std.string: join, format;

T[][] transpose(T)(T[][] mat) {

   static bool isRectangular(T[][] mat) {
       foreach (row; mat)
           if (row.length != mat[0].length)
               return false;
       return true;
   }
   if (!mat.length || !isRectangular(mat))
       throw new Exception("Transpose Error");
   auto result = new T[][](mat[0].length, mat.length);
   for (int i = 0; i < mat.length; i++)
       for (int j = 0; j < mat[0].length; j++)
           result[j][i] = mat[i][j];
   return result;

}

string toString(T)(T[][] mat) { // for pretty print

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

}

void main() {

   float[][] m = [[0.5,0,0,1], [0.0,0.5,0,0], [0.0,0,0.5,-1]];
   writefln("M:", m.toString());
   auto mt = m.transpose();
   writefln("M transposed:", mt.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:<lang ella>MAC TRANSPOSE = ([INT n][INT m]TYPE t: matrix) -> [m][n]t:

 [INT i = 1..m] [INT j = 1..n] matrix[j][i].</lang>

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

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

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:

<lang haskell>*Main> transpose [[1,2],[3,4],[5,6]] [[1,3,5],[2,4,6]]</lang>

For matrices in arrays, one can use ixmap:

<lang haskell>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</lang>

IDL

Standard IDL function transpose()

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

J

Solution:
Transpose is the monadic primary verb |:

Example: <lang j> ]matrix=: 10 + i. 3 5 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</lang>

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

<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]</lang>

MATLAB

<lang Matlab>function [transposedMatrix] = transposematrix(originalMatrix)

  transposedMatrix = originalMatrix';</lang>

Maxima

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

MAXScript

Uses the built in transpose() function <lang maxscript>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</lang>

Nial

make an array <lang nial>|a := 2 3 reshape count 6 =1 2 3 =4 5 6</lang> transpose it <lang nial>|transpose a =1 4 =2 5 =3 6</lang>

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_map(NULL, m[0], m[1], ..)
 return call_user_func_array('array_map', array_merge(array(NULL), $m));

}</lang>

Pop11

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

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

R

<lang R>b <- c(1,2,3,4,5) m <- matrix(c(b, b^2, b^3, b^4), 5, 4) print(m) tm <- t(m) print(tm)</lang>

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]]

Scala

<lang scala>scala> Array.tabulate(4)(i => Array.tabulate(4)(j => i*4 + j)) res12: Array[Array[Int]] = Array(Array(0, 1, 2, 3), Array(4, 5, 6, 7), Array(8, 9, 10, 11), Array(12, 13, 14, 15))

scala> res12.transpose res13: Array[Array[Int]] = Array(Array(0, 4, 8, 12), Array(1, 5, 9, 13), Array(2, 6, 10, 14), Array(3, 7, 11, 15))

scala> res12 map (_ map ("%2d" format _) mkString " ") mkString "\n" res16: String =

0  1  2  3
4  5  6  7
8  9 10 11

12 13 14 15

scala> res13 map (_ map ("%2d" format _) mkString " ") mkString "\n" res17: String =

0  4  8 12
1  5  9 13
2  6 10 14
3  7 11 15</lang>

Scheme

<lang scheme>(define (transpose m)

 (apply map list m))</lang>

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
         
         

TI-83 BASIC, TI-89 BASIC

TI-83: 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.

TI-89: The same except that matrix variables do not have special names:

AT → B

Ursala

Matrices are stored as lists of lists, and transposing them is a built in operation. <lang Ursala>

  1. cast %eLL

example =

~&K7 <

  <1.,2.,3.,4.>,
  <5.,6.,7.,8.>,
  <9.,10.,11.,12.>></lang>

For a more verbose version, replace the ~&K7 operator with the standard library function named transpose. Here is the output:

<
   <1.000000e+00,5.000000e+00,9.000000e+00>,
   <2.000000e+00,6.000000e+00,1.000000e+01>,
   <3.000000e+00,7.000000e+00,1.100000e+01>,
   <4.000000e+00,8.000000e+00,1.200000e+01>>