Matrix transposition: Difference between revisions

From Rosetta Code
Content added Content deleted
(added GAP)
(→‎{{header|Ada}}: Replaced by an implementation based on the standard library)
Line 2: Line 2:


=={{header|Ada}}==
=={{header|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 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;


This example illustrates use of Transpose for the matrices built upon the standard type Float:
with Ada.Text_Io;
<ada>
with Ada.Numerics.Real_Arrays; use Ada.Numerics.Real_Arrays;
with Ada.Text_IO; use Ada.Text_IO;
procedure Matrix_Transpose is
package body Rect_Real_Matrix 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),
-- Print --
(0.4, 0.5, 0.6, 0.7),
-----------
(0.8, 0.9, 1.0, 1.1)
);
procedure Print(Item : Rect_Matrix) is
begin
package Real_Io is new Ada.Text_Io.Float_Io(Element_Type);
Put_Line ("Before Transposition:");
use Real_Io;
Put (Matrix);
use Ada.Text_Io;
begin
New_Line;
Put_Line ("After Transposition:");
for I in Item'range(1) loop
Put (Transpose (Matrix));
for J in Item'range(2) loop
end Matrix_Transpose;
Put(Item => Item(I,J), Exp => 0, Fore => 5);
</ada>
Put(" ");
Sample output:
end loop;
<pre>
New_Line;
Before Transposition:
end loop;
0.00 0.10 0.20 0.30
end Print;
0.40 0.50 0.60 0.70
0.80 0.90 1.00 1.10
---------------
-- 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;


After Transposition:
with Rect_Real_Matrix;
0.00 0.40 0.80
with Ada.Text_IO; use Ada.Text_IO;
0.10 0.50 0.90
0.20 0.60 1.00
procedure Rect_Mat_Transpose is
0.30 0.70 1.10
type Col_Index is (Severe, High, Moderate, Low, Insignificant);
</pre>
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


=={{header|ALGOL 68}}==
=={{header|ALGOL 68}}==

Revision as of 10:18, 22 August 2008

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

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:

   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

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

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

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

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

#!/usr/bin/env 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))

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.