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