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
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) {
- 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>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]
MATLAB
<lang Matlab>function [transposedMatrix] = transposematrix(originalMatrix)
transposedMatrix = originalMatrix';</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);
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_map(NULL, m[0], m[1], ..) return call_user_func_array(array_map, array_merge(array(NULL), $m));
}</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)]
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
<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
<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>
- 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>>