Matrix Multiplication Back to the Win32 Shootout
Back to dada's perl lab

[The Original Shootout]   [NEWS]   [FAQ]   [Methodology]   [Platform Details]   [Acknowledgements]   [Scorecard]  
All Source For Matrix Multiplication
matrix.awka
# $Id: matrix.gawk,v 1.1 2001/05/20 06:59:20 doug Exp $
# http://www.bagley.org/~doug/shootout/

function mkmatrix(mx, rows, cols) {
    count = 1;
    for (i=0; i<rows; i++) {
    for (j=0; j<cols; j++) {
        mx[i,j] = count++;
    }
    }
}

function mmult(rows, cols, m1, m2, m3) {
    for (i=0; i<rows; i++) {
    for (j=0; j<cols; j++) {
        val = 0;
        for (k=0; k<cols; k++) {
        val += m1[i,k] * m2[k,j];
        }
        m3[i,j] = val;
    }
    }
}


BEGIN {
    n = (ARGV[1] < 1) ? 1 : ARGV[1];
    size = 30;
    m1[0,0] = 0;
    m2[0,0] = 0;
    mkmatrix(m1, size, size);
    mkmatrix(m2, size, size);
    mm[0,0] = 0;
    for (l=0; l<n; l++) {
    mmult(size, size, m1, m2, mm);
    }
    printf("%d %d %d %d\n", mm[0,0], mm[2,3], mm[3,2], mm[4,4]);
    exit;
}
matrix.bcc
/* -*- mode: c -*-
 * $Id: matrix.gcc,v 1.6 2001/03/31 15:52:48 doug Exp $
 * http://www.bagley.org/~doug/shootout/
 */

#include <stdio.h>
#include <stdlib.h>

#define SIZE 30

int **mkmatrix(int rows, int cols) {
    int i, j, count = 1;
    int **m = (int **) malloc(rows * sizeof(int *));
    for (i=0; i<rows; i++) {
    m[i] = (int *) malloc(cols * sizeof(int));
    for (j=0; j<cols; j++) {
        m[i][j] = count++;
    }
    }
    return(m);
}

void zeromatrix(int rows, int cols, int **m) {
    int i, j;
    for (i=0; i<rows; i++)
    for (j=0; j<cols; j++)
        m[i][j] = 0;
}

void freematrix(int rows, int **m) {
    while (--rows > -1) { free(m[rows]); }
    free(m);
}

int **mmult(int rows, int cols, int **m1, int **m2, int **m3) {
    int i, j, k, val;
    for (i=0; i<rows; i++) {
    for (j=0; j<cols; j++) {
        val = 0;
        for (k=0; k<cols; k++) {
        val += m1[i][k] * m2[k][j];
        }
        m3[i][j] = val;
    }
    }
    return(m3);
}

int main(int argc, char *argv[]) {
    int i, n = ((argc == 2) ? atoi(argv[1]) : 1);
    
    int **m1 = mkmatrix(SIZE, SIZE);
    int **m2 = mkmatrix(SIZE, SIZE);
    int **mm = mkmatrix(SIZE, SIZE);

    for (i=0; i<n; i++) {
    mm = mmult(SIZE, SIZE, m1, m2, mm);
    }
    printf("%d %d %d %d\n", mm[0][0], mm[2][3], mm[3][2], mm[4][4]);

    freematrix(SIZE, m1);
    freematrix(SIZE, m2);
    freematrix(SIZE, mm);
    return(0);
}
matrix.csharp
// $Id: matrix.csharp,v 1.0 2002/05/09 12:45:00 dada Exp $
// http://dada.perl.it/shootout/

using System;

class App {

    static int SIZE = 30;

    public static int[,] mkmatrix (int rows, int cols) {
        int count = 1;
        int[,] m = new int[rows,cols];
        for (int i=0; i<rows; i++) {
            for (int j=0; j<cols; j++) {
            m[i,j] = count++;
            }
        }
        return(m);
    }

    public static void mmult (int rows, int cols, 
                          int[,] m1, int[,] m2, int[,] m3) {
        for (int i=0; i<rows; i++) {
            for (int j=0; j<cols; j++) {
                int val = 0;
                for (int k=0; k<cols; k++) {
                    val += m1[i,k] * m2[k,j];
                }
                m3[i,j] = val;
            }
        }
    }

    public static int Main(String[] args) {        
        int n;
        int[,] m1 = mkmatrix(SIZE, SIZE);
        int[,] m2 = mkmatrix(SIZE, SIZE);
        int[,] mm = new int[SIZE,SIZE];
        
        n = System.Convert.ToInt32(args[0]);
        if(n < 1) n = 1;
        
        for (int i=0; i<n; i++) {
            mmult(SIZE, SIZE, m1, m2, mm);
        }
        
        Console.WriteLine(
            mm[0,0].ToString() + " " + mm[2,3].ToString() + " " +
            mm[3,2].ToString() + " " + mm[4,4].ToString());
        return(0);
    }
}
matrix.cygperl
#!/usr/local/bin/perl 
# $Id: matrix.perl,v 1.1 2000/12/29 06:10:10 doug Exp $
# http://www.bagley.org/~doug/shootout/

# This program based on the original from:
# "The What, Why, Who, and Where of Python" By Aaron R. Watters
# http://www.networkcomputing.com/unixworld/tutorial/005/005.html

# modified to pass rows and cols, and avoid matrix size checks
# I've sped up the original quite a bit by removing some loop
# invariants and declaring "use integer"

use strict;
use integer;

my $size = 30;

sub mkmatrix {
    my($rows, $cols) = @_;
    --$rows; --$cols;
    my $count = 1;
    my @mx = ();
    foreach (0 .. $rows) {
    my @row = ();
    $row[$_] = $count++ foreach (0 .. $cols);
    push(@mx, \@row);
    }
    return(\@mx);
}

sub mmult {
    my ($rows, $cols, $m1, $m2) = @_;
    my @m3 = ();
    --$rows; --$cols;
    for my $i (0 .. $rows) {
    my @row = ();
    my $m1i = $m1->[$i];
    for my $j (0 .. $cols) {
        my $val = 0;
        for my $k (0 .. $cols) {
        $val += $m1i->[$k] * $m2->[$k]->[$j];
        }
        push(@row, $val);
    }
    push(@m3, \@row);
    }
    return(\@m3);
}

my $N = $ARGV[0] || 1;

my $m1 = mkmatrix($size, $size);
my $m2 = mkmatrix($size, $size);
my $mm;
while ($N--) {
    $mm = mmult($size, $size, $m1, $m2);
}
print "$mm->[0]->[0] $mm->[2]->[3] $mm->[3]->[2] $mm->[4]->[4]\n";

matrix.delphi
program matrix;


const
  SIZE = 30;

type TMatrix = array[0..SIZE-1, 0..SIZE-1] of integer;

procedure mkmatrix( rows, cols : integer; var mx : TMatrix);
var 
  R, C, count : integer;
begin
  Dec(rows); Dec(cols);
  count:=1;
  for R:=0 to rows do
    for C:=0 to cols do begin
      mx[R, C] := count;
      Inc(count);
    end;
end;

procedure mmult(rows, cols: integer; const m1, m2: TMatrix; var mm: TMatrix);
var
  i, j, k, val: integer;
begin
  Dec(rows); Dec(cols);
  for i:=0 to rows do
    for j:=0 to cols do begin
      val:=0;
      for k:=0 to cols do
        Inc(val, m1[i,k]*m2[k,j]);
      mm[i,j] := val;
    end;
end;

var NUM, code, i: integer;
    M1, M2, MM: TMatrix;
begin
  NUM:=1;
  if ParamCount=1 then Val(ParamStr(1),NUM,code);

  mkmatrix(SIZE, SIZE, M1);
  mkmatrix(SIZE, SIZE, M2);
  for i:=0 to NUM do
    mmult(size, size, M1, M2, MM);
  WriteLn( MM[0, 0],' ',MM[2, 3],' ',MM[3, 2],' ',MM[4, 4]);
end.

matrix.erlang
%% Doesn't check matrix sizes match but 
%% not restricted to square matrices.
%%
%% Represent matrix as tuple of tuples.
%% Doesn't use destructive assignment so building a
%% matrix creates an awful lot of temporary lists.
%%
%% Usage: start from command line with
%%     erlc multiply.erl
%%     erl -noinput -s multiply main 1

-module(matrix). 
-export([main/1]). 
-import(lists, [reverse/1]).


sumprod(0, _, _, Sum, _, _) -> Sum;
sumprod(I, C, R, Sum, M1, M2) -> 
    NewSum = Sum + (element(I,element(R,M1)) * element(C,element(I,M2))),
    sumprod(I-1, C, R, NewSum, M1, M2).


rowmult(_, 0, _, L, _, _) -> list_to_tuple(L);
rowmult(I, C, R, L, M1, M2) -> 
    SumProd = sumprod(I, C, R, 0, M1, M2),
    rowmult(I, C-1, R, [SumProd|L], M1, M2).


mmult(_, _, 0, MM, _, _) -> list_to_tuple(MM);
mmult(I, C, R, MM, M1, M2) ->
    NewRow = rowmult(I, C, R, [], M1, M2),
    mmult(I, C, R-1, [NewRow|MM], M1, M2).

mmult(M1, M2) -> 
    Inner = size(M2), % could optimize more by hardcoding the sizes
    NRows = size(M1), 
    mmult(Inner, NRows, NRows,[], M1, M2).


repeatmmult(1, M1, M2) -> mmult(M1, M2);
repeatmmult(NTimes, M1, M2) -> 
    mmult(M1, M2),
    repeatmmult(NTimes-1, M1, M2).


mkrow(0, L, Count) -> {list_to_tuple(reverse(L)), Count};
mkrow(N, L, Count) -> mkrow(N-1, [Count|L], Count+1).


mkmatrix(0, _, _, M) -> list_to_tuple(reverse(M));
mkmatrix(NR, NC, Count, M) ->
    {Row, NewCount} = mkrow(NC, [], Count),
    mkmatrix(NR-1, NC, NewCount, [Row|M]).

mkmatrix(NR, NC) -> mkmatrix(NR, NC, 1, []).


main([Arg]) ->
    NTimes = list_to_integer(atom_to_list(Arg)),
    Size = 30,
    M1 = mkmatrix(Size, Size),
    M2 = mkmatrix(Size, Size),
    MM = repeatmmult(NTimes, M1, M2),
    Val1 = element(1,element(1, MM)), 
    Val2 = element(4,element(3, MM)), % get col 4 out of row 3
    Val3 = element(3,element(4, MM)), % get col 3 out of row 4
    Val4 = element(5,element(5, MM)), 
    io:fwrite("~w ~w ~w ~w~n", [Val1, Val2, Val3, Val4]),
    halt(0).            



matrix.fpascal
program matrix;
uses SysUtils;

const
    size = 30;

type tMatrix = array[0..size, 0..size] of longint;

procedure mkmatrix( rows, cols : integer; var mx : tMatrix);
var 
    R, C : integer;
    count : longint;
begin
    Dec(rows);
    Dec(cols);
    count := 1;
    for R := 0 to rows do
    begin
        for C := 0 to cols do
        begin
            mx[R, C] := count;
            Inc(count);
        end;
    end;
End;

procedure mmult(rows, cols : integer; m1, m2 : tMatrix; var mm : tMatrix );
var
    i, j, k : integer;
    val: longint;
begin
    Dec(rows);
    Dec(cols);    
    For i := 0 To rows do
    begin
        For j := 0 To cols do
        begin
            val := 0;
            For k := 0 To cols do
            begin
                Inc(val, m1[i, k] * m2[k, j]);
            end;
            mm[i, j] := val;
        end;
    end;
End;


var NUM, I : integer;
    M1, M2, MM : tMatrix;

begin
    if ParamCount = 0 then
        NUM := 1
    else
        NUM := StrToInt(ParamStr(1));
        
    if NUM < 1 then NUM := 1;

    mkmatrix(size, size, M1);
    mkmatrix(size, size, M2);
    
    for I := 0 To NUM do
    begin
        mmult(size, size, M1, M2, MM);
    end;
    WriteLn( IntToStr(MM[0, 0]) + ' ' + IntToStr(MM[2, 3]) + ' ' +
             IntToStr(MM[3, 2]) + ' ' + IntToStr(MM[4, 4]));
end.
matrix.gawk
# $Id: matrix.gawk,v 1.1 2001/05/20 06:59:20 doug Exp $
# http://www.bagley.org/~doug/shootout/

function mkmatrix(mx, rows, cols) {
    count = 1;
    for (i=0; i<rows; i++) {
    for (j=0; j<cols; j++) {
        mx[i,j] = count++;
    }
    }
}

function mmult(rows, cols, m1, m2, m3) {
    for (i=0; i<rows; i++) {
    for (j=0; j<cols; j++) {
        val = 0;
        for (k=0; k<cols; k++) {
        val += m1[i,k] * m2[k,j];
        }
        m3[i,j] = val;
    }
    }
}


BEGIN {
    n = (ARGV[1] < 1) ? 1 : ARGV[1];
    size = 30;
    m1[0,0] = 0;
    m2[0,0] = 0;
    mkmatrix(m1, size, size);
    mkmatrix(m2, size, size);
    mm[0,0] = 0;
    for (l=0; l<n; l++) {
    mmult(size, size, m1, m2, mm);
    }
    printf("%d %d %d %d\n", mm[0,0], mm[2,3], mm[3,2], mm[4,4]);
    exit;
}
matrix.gcc
/* -*- mode: c -*-
 * $Id: matrix.gcc,v 1.6 2001/03/31 15:52:48 doug Exp $
 * http://www.bagley.org/~doug/shootout/
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#define SIZE 30

int **mkmatrix(int rows, int cols) {
    int i, j, count = 1;
    int **m = (int **) malloc(rows * sizeof(int *));
    for (i=0; i<rows; i++) {
    m[i] = (int *) malloc(cols * sizeof(int));
    for (j=0; j<cols; j++) {
        m[i][j] = count++;
    }
    }
    return(m);
}

void zeromatrix(int rows, int cols, int **m) {
    int i, j;
    for (i=0; i<rows; i++)
    for (j=0; j<cols; j++)
        m[i][j] = 0;
}

void freematrix(int rows, int **m) {
    while (--rows > -1) { free(m[rows]); }
    free(m);
}

int **mmult(int rows, int cols, int **m1, int **m2, int **m3) {
    int i, j, k, val;
    for (i=0; i<rows; i++) {
    for (j=0; j<cols; j++) {
        val = 0;
        for (k=0; k<cols; k++) {
        val += m1[i][k] * m2[k][j];
        }
        m3[i][j] = val;
    }
    }
    return(m3);
}

int main(int argc, char *argv[]) {
    int i, n = ((argc == 2) ? atoi(argv[1]) : 1);
    
    int **m1 = mkmatrix(SIZE, SIZE);
    int **m2 = mkmatrix(SIZE, SIZE);
    int **mm = mkmatrix(SIZE, SIZE);

    for (i=0; i<n; i++) {
    mm = mmult(SIZE, SIZE, m1, m2, mm);
    }
    printf("%d %d %d %d\n", mm[0][0], mm[2][3], mm[3][2], mm[4][4]);

    freematrix(SIZE, m1);
    freematrix(SIZE, m2);
    freematrix(SIZE, mm);
    return(0);
}
matrix.gforth
\ -*- mode: forth -*-
\ $Id: matrix.gforth,v 1.2 2001/06/28 02:01:56 doug Exp $
\ http://www.bagley.org/~doug/shootout/
\ from Jorge Acereda Maciá

0. argc @ 1- arg >number 2drop drop constant iterations

30 constant size
size dup * floats constant mat-byte-size
: row-size     size postpone literal ; immediate
: row-stride   float postpone literal ; immediate
: col-stride   size floats postpone literal ; immediate

: mkmatrix 
    1.e mat-byte-size bounds do fdup i f! 1e f+ float +loop fdrop ;

: }}? 
    rot row-size * rot + floats + f@ f>d d>s 1 u.r ;

: mat* 
    -rot mat-byte-size bounds do
        over col-stride bounds do
            i col-stride j row-stride row-size v* dup f! float+
        float +loop
    col-stride +loop 2drop ;

create a mat-byte-size allot   a mkmatrix
create b mat-byte-size allot   b mkmatrix
create r mat-byte-size allot

: test iterations 0 do   r a b mat*   loop ;

test 0 0 r }}? space  2 3 r }}? space  3 2 r }}? space  4 4 r }}?  cr bye
matrix.ghc
-- $Id: matrix.ghc,v 1.3 2001/06/01 17:56:49 doug Exp $
-- http://www.bagley.org/~doug/shootout/
-- from Julian Assange

-- TBD: try rewrite with STUArray or IOUArray?

module Main(main) where
import System(getArgs, exitWith, ExitCode(..))
import Numeric(readDec)
import List(transpose)
main = do
       arg <- getArgs
       case arg of
            [number] -> putStrLn (disp m 0 0 ++ " " ++
                  disp m 2 3 ++ " " ++
                  disp m 3 2 ++ " " ++
                  disp m 4 4)
                  where
              disp m row col  = show (m!!row!!col)
              m = powmat (fst (head (readDec number)))
            _        -> exitWith (ExitFailure 1)

size = 30

-- ghc is able to optimize out enough invariants so that the
-- traditional form this test runs in O(1)
--
-- this would have ghc trounce all other entrants, so to get
-- closer to the general meaning of the test, we cascade
-- matrix multiplications. this means the results are, by necessity,
-- different, but involve just as many mmults. i.e for n=1 the results
-- are identical.

powmat n = power n (mmult . transpose $ mkmat size) (mkmat size)
    where
    power n f | n > 0     = f . (power (n-1) f)
              | otherwise = id
    mkmat x    = [[(y-1)*x+1..y*x]| y <- [1..x]]
    mmult a b  = [[dot row col 0 | col <- a]| row <- b]
           where
           dot :: [Int] -> [Int] -> Int -> Int
           dot (x:xs) (y:ys) z = dot xs ys (z + x*y)
           dot  _      _     z = z 

-- slightly slower transposing mmult in one line:
--  mmult a b  = [[sum$zipWith (*) row col 0 | col <- transpose a]| row <-b]
matrix.gnat
-- $Id: matrix.gnat,v 1.0 2003/06/11 12:09:00 dada Exp $
-- http://dada.perl.it/shootout/
-- Ada 95 code by C.C.

with Text_IO, Ada.Strings.Fixed, Ada.Command_Line;

procedure Matrix is
   function L_Trim (Source : String; Side : Ada.Strings.Trim_End :=
               Ada.Strings.Left) return String renames Ada.Strings.Fixed.Trim;

   type Int is new Integer;
   type Int_Matrix is array (Positive range <>, Positive range <>) of Int;

   function Mk_Matrix (NRows, NCols : Natural) return Int_Matrix is
      Count    : Int := 1;
      M        : Int_Matrix (1 .. NRows, 1 .. NCols);
   begin
      for I in M'Range (1) loop
         for J in M'Range (2) loop
            M (I, J) := Count;
            Count := Count + 1;
         end loop;
      end loop;
      return M;
   end Mk_Matrix;

   procedure M_Mult (M1, M2 : Int_Matrix; MM : in out Int_Matrix) is
      pragma Inline (M_Mult);
      pragma Suppress (Index_Check);
      Sum      : Int;
   begin
      if not (M1'First (2) = M2'First (1) and M1'Last (2) = M2'Last (1) and
               M1'First (1) = MM'First (1) and M1'Last (1) = MM'Last (1) and
               M2'First (2) = MM'First (2) and M2'Last (2) = MM'Last (2)) then
         raise Constraint_Error;
      end if;
      for I in M1'Range (1) loop
         for J in M2'Range (2) loop
            Sum := 0;
            for KK in M1'Range (2) loop
               Sum := Sum + M1 (I, KK) * M2 (KK, J);
            end loop;
            MM (I, J) := Sum;
         end loop;
      end loop;
   end M_Mult;

   Size     : constant Natural := 30;
   M1, M2, MM : Int_Matrix (1 .. Size, 1 .. Size);
   N        : Positive := 1;
begin
   begin
      N := Positive'Value (Ada.Command_Line.Argument (1));
   exception
      when Constraint_Error => null;
   end;
   M1 := Mk_Matrix (Size, Size);
   M2 := Mk_Matrix (Size, Size);
   for Iter in 1 .. N loop
      M_Mult (M1, M2, MM);
   end loop;
   Text_IO.Put_Line (L_Trim (Int'Image (MM (1, 1))) & Int'Image (MM (3, 4)) &
            Int'Image (MM (4, 3)) & Int'Image (MM (5, 5)));
end Matrix;

matrix.guile
#!/usr/local/bin/guile \
-e main -s
!#

;;; $Id: matrix.guile,v 1.6 2001/06/29 23:12:37 doug Exp $
;;; http://www.bagley.org/~doug/shootout/
;;; with help from Brad Knotwell

(define size 30)

(define (mkmatrix rows cols)
  (define count 1)
  (define (set-row cols)
    (let ((row (make-vector cols 0)))
      (do ((i 0 (1+ i)))
      ((= i cols) row)
    (begin (vector-set! row i count) (set! count (1+ count))))))
  (let ((mx (make-vector rows cols)))
    (begin (array-map-in-order! mx set-row mx) mx)))
  
(define (mmult rows cols m1 m2)
  (let ((m3 (make-vector rows 0)))
    (do ((i 0 (+ i 1)))
    ((= i rows))
      (let ((m1i (vector-ref m1 i))
        (row (make-vector cols 0)))
    (do ((j 0 (+ j 1)))
        ((= j cols))
      (let ((val 0))
        (do ((k 0 (+ k 1)))
        ((= k cols))
          (set! val (+ val (* (vector-ref m1i k)
                  (vector-ref (vector-ref m2 k) j)))))
        (vector-set! row j val)))
    (vector-set! m3 i row)))
    m3))

(define (main args)
  (let ((n (or (and (= (length args) 2) (string->;number (cadr args))) 1))
    (m1 (mkmatrix size size))
    (m2 (mkmatrix size size))
    (mm 0))
    (do ((i 0 (1+ i)))
    ((= i n) (begin 
           (display (vector-ref (vector-ref mm 0) 0)) (display " ")
           (display (vector-ref (vector-ref mm 2) 3)) (display " ")
           (display (vector-ref (vector-ref mm 3) 2)) (display " ")
           (display (vector-ref (vector-ref mm 4) 4)) (newline)))
    (set! mm (mmult size size m1 m2)))))
matrix.ici
// $Id: matrix.ici,v 1.0 2003/01/03 11:58:00 dada Exp $
// http://dada.perl.it/shootout
//
// contributed by Tim Long

static
mkmatrix(rows, cols)
{
    m = build(rows, cols);
    count = 0;
    forall (col in m)
    {
        forall (val, i in col)
            col[i] = ++count;
    }
    return m;
}

static
mmult(rows, cols, m1, m2, m3)
{
    forall (col, i in m3)
    {
        m1i = m1[i];
        forall (val, j in col)
        {
            val = 0;
            forall (m1ik, k in m1i)
                val += m1ik * m2[k][j];
            col[j] = val;
        }
    }
}

SIZE := 30;
n := argv[1] ? int(argv[1]) : 1;
m1 := mkmatrix(SIZE, SIZE);
m2 := mkmatrix(SIZE, SIZE);
mm := build(SIZE, SIZE);
for (i = 0; i < n; ++i)
    mmult(SIZE, SIZE, m1, m2, mm);
printf("%d %d %d %d\n", mm[0][0], mm[2][3], mm[3][2], mm[4][4]);
matrix.java
// $Id: matrix.java,v 1.3 2001/05/27 14:52:57 doug Exp $
// http://www.bagley.org/~doug/shootout/
// modified to use a little less memory by Thomas Holenstein

import java.io.*;
import java.util.*;

public class matrix {
    static int SIZE = 30;

    public static void main(String args[]) {
    int n = Integer.parseInt(args[0]);
    int m1[][] = mkmatrix(SIZE, SIZE);
    int m2[][] = mkmatrix(SIZE, SIZE);
    int mm[][] = new int[SIZE][SIZE];
    for (int i=0; i<n; i++) {
        mmult(SIZE, SIZE, m1, m2, mm);
    }
    System.out.print(mm[0][0]);
    System.out.print(" ");
    System.out.print(mm[2][3]);
    System.out.print(" ");
    System.out.print(mm[3][2]);
    System.out.print(" ");
    System.out.println(mm[4][4]);
    }

    public static int[][] mkmatrix (int rows, int cols) {
    int count = 1;
    int m[][] = new int[rows][cols];
    for (int i=0; i<rows; i++) {
        for (int j=0; j<cols; j++) {
        m[i][j] = count++;
        }
    }
    return(m);
    }

    public static void mmult (int rows, int cols, 
                          int[][] m1, int[][] m2, int[][] m3) {
    for (int i=0; i<rows; i++) {
        for (int j=0; j<cols; j++) {
        int val = 0;
        for (int k=0; k<cols; k++) {
            val += m1[i][k] * m2[k][j];
        }
        m3[i][j] = val;
        }
    }
    }
}
matrix.jscript
/* -*- mode: java -*-
 * $Id: matrix.njs,v 1.1 2001/07/08 20:20:06 doug Exp $
 * http://www.bagley.org/~doug/shootout/
 * From: David Hedbor
 * modified by Aldo Calpini <dada@perl.it> for Win32
 */

var SIZE=30;

function mkmatrix(rows, cols) {
  var i, j, count = 1;
  var m = new Array(rows);
  for (i = 0; i < rows; i++) {
    m[i] = new Array(cols);
    for (j = 0; j < cols; j++) {
      m[i][j] = count++;
    }
  }
  return m;
}

function mmult(rows, cols,  m1, m2, m3) {
  var i, j, k, val;
  for (i = 0; i < rows; i++) {
    for (j = 0; j < cols; j++) {
      val = 0;
      for (k = 0; k < cols; k++) {
    val += m1[i][k] * m2[k][j];
      }
      m3[i][j] = val;
    }
  }
  return m3;
}

var n, i;
ARGS = WScript.Arguments;
if(ARGS.length > 0) {
  n = parseInt(ARGS.Item(0), "10");
  if(n < 1) n = 1;
} else {
  n = 1;
}
var m1 = mkmatrix(SIZE, SIZE);
var m2 = mkmatrix(SIZE, SIZE);
var mm = mkmatrix(SIZE, SIZE);

for (i = 0; i < n; i++) {
  mmult(SIZE, SIZE, m1, m2, mm);
}
WScript.Echo(mm[0][0], mm[2][3], mm[3][2], mm[4][4]);

matrix.lcc
/* -*- mode: c -*-
 * $Id: matrix.gcc,v 1.6 2001/03/31 15:52:48 doug Exp $
 * http://www.bagley.org/~doug/shootout/
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#define SIZE 30

int **mkmatrix(int rows, int cols) {
    int i, j, count = 1;
    int **m = (int **) malloc(rows * sizeof(int *));
    for (i=0; i<rows; i++) {
    m[i] = (int *) malloc(cols * sizeof(int));
    for (j=0; j<cols; j++) {
        m[i][j] = count++;
    }
    }
    return(m);
}

void zeromatrix(int rows, int cols, int **m) {
    int i, j;
    for (i=0; i<rows; i++)
    for (j=0; j<cols; j++)
        m[i][j] = 0;
}

void freematrix(int rows, int **m) {
    while (--rows > -1) { free(m[rows]); }
    free(m);
}

int **mmult(int rows, int cols, int **m1, int **m2, int **m3) {
    int i, j, k, val;
    for (i=0; i<rows; i++) {
    for (j=0; j<cols; j++) {
        val = 0;
        for (k=0; k<cols; k++) {
        val += m1[i][k] * m2[k][j];
        }
        m3[i][j] = val;
    }
    }
    return(m3);
}

int main(int argc, char *argv[]) {
    int i, n = ((argc == 2) ? atoi(argv[1]) : 1);
    
    int **m1 = mkmatrix(SIZE, SIZE);
    int **m2 = mkmatrix(SIZE, SIZE);
    int **mm = mkmatrix(SIZE, SIZE);

    for (i=0; i<n; i++) {
    mm = mmult(SIZE, SIZE, m1, m2, mm);
    }
    printf("%d %d %d %d\n", mm[0][0], mm[2][3], mm[3][2], mm[4][4]);

    freematrix(SIZE, m1);
    freematrix(SIZE, m2);
    freematrix(SIZE, mm);
    return(0);
}
matrix.lua
-- $Id: matrix.lua,v 1.2 2001/01/13 14:47:43 doug Exp $
-- http://www.bagley.org/~doug/shootout/
-- with help from Roberto Ierusalimschy

local n = tonumber((arg and arg[1]) or 1)

local size = 30

function mkmatrix(rows, cols)
    local count = 1
    local mx = {}
    for i=0,(rows - 1) do
    local row = {}
    for j=0,(cols - 1) do
        row[j] = count
        count = count + 1
    end
    mx[i] = row
    end
    return(mx)
end

function mmult(rows, cols, m1, m2)
    local m3 = {}
    for i=0,(rows-1) do
        m3[i] = {}
        for j=0,(cols-1) do
            local rowj = 0
            for k=0,(cols-1) do
                rowj = rowj + m1[i][k] * m2[k][j]
            end
            m3[i][j] = rowj
        end
    end
    return(m3)
end

local m1 = mkmatrix(size, size)
local m2 = mkmatrix(size, size)
for i=1,n do
    mm = mmult(size, size, m1, m2)
end
write(format("%d %d %d %d\n", mm[0][0], mm[2][3], mm[3][2], mm[4][4]))
matrix.lua5
-- $Id: matrix.lua,v 1.2 2001/01/13 14:47:43 doug Exp $
-- http://www.bagley.org/~doug/shootout/
-- contributed by Roberto Ierusalimschy

local n = tonumber((arg and arg[1]) or 1)

local size = 30

function mkmatrix(rows, cols)
  local count = 1
  local mx = {}
  for i=1,rows do
    local row = {}
    for j=1,cols do
      row[j] = count
      count = count + 1
    end
    mx[i] = row
  end
  return(mx)
end

function mmult(rows, cols, m1, m2)
  local m3 = {}
  for i=1,rows do
    local m3i = {}
    m3[i] = m3i
    local m1i = m1[i]
    for j=1,cols do
      local rowj = 0
      for k=1,cols do
        rowj = rowj + m1i[k] * m2[k][j]
      end
      m3i[j] = rowj
    end
  end
  return(m3)
end

local m1 = mkmatrix(size, size)
local m2 = mkmatrix(size, size)
for i=1,n do
    mm = mmult(size, size, m1, m2)
end
io.write(string.format("%d %d %d %d\n", mm[1][1], mm[3][4], mm[4][3], mm[5][5]))

matrix.mawk
# $Id: matrix.mawk,v 1.1 2001/05/20 06:59:20 doug Exp $
# http://www.bagley.org/~doug/shootout/

function mkmatrix(mx, rows, cols) {
    count = 1;
    for (i=0; i<rows; i++) {
    for (j=0; j<cols; j++) {
        mx[i,j] = count++;
    }
    }
}

function mmult(rows, cols, m1, m2, m3) {
    for (i=0; i<rows; i++) {
    for (j=0; j<cols; j++) {
        val = 0;
        for (k=0; k<cols; k++) {
        val += m1[i,k] * m2[k,j];
        }
        m3[i,j] = val;
    }
    }
}


BEGIN {
    n = (ARGV[1] < 1) ? 1 : ARGV[1];
    size = 30;
    m1[0,0] = 0;
    m2[0,0] = 0;
    mkmatrix(m1, size, size);
    mkmatrix(m2, size, size);
    mm[0,0] = 0;
    for (l=0; l<n; l++) {
    mmult(size, size, m1, m2, mm);
    }
    printf("%d %d %d %d\n", mm[0,0], mm[2,3], mm[3,2], mm[4,4]);
    exit;
}
matrix.mingw32
/* -*- mode: c -*-
 * $Id: matrix.gcc,v 1.6 2001/03/31 15:52:48 doug Exp $
 * http://www.bagley.org/~doug/shootout/
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#define SIZE 30

int **mkmatrix(int rows, int cols) {
    int i, j, count = 1;
    int **m = (int **) malloc(rows * sizeof(int *));
    for (i=0; i<rows; i++) {
    m[i] = (int *) malloc(cols * sizeof(int));
    for (j=0; j<cols; j++) {
        m[i][j] = count++;
    }
    }
    return(m);
}

void zeromatrix(int rows, int cols, int **m) {
    int i, j;
    for (i=0; i<rows; i++)
    for (j=0; j<cols; j++)
        m[i][j] = 0;
}

void freematrix(int rows, int **m) {
    while (--rows > -1) { free(m[rows]); }
    free(m);
}

int **mmult(int rows, int cols, int **m1, int **m2, int **m3) {
    int i, j, k, val;
    for (i=0; i<rows; i++) {
    for (j=0; j<cols; j++) {
        val = 0;
        for (k=0; k<cols; k++) {
        val += m1[i][k] * m2[k][j];
        }
        m3[i][j] = val;
    }
    }
    return(m3);
}

int main(int argc, char *argv[]) {
    int i, n = ((argc == 2) ? atoi(argv[1]) : 1);
    
    int **m1 = mkmatrix(SIZE, SIZE);
    int **m2 = mkmatrix(SIZE, SIZE);
    int **mm = mkmatrix(SIZE, SIZE);

    for (i=0; i<n; i++) {
    mm = mmult(SIZE, SIZE, m1, m2, mm);
    }
    printf("%d %d %d %d\n", mm[0][0], mm[2][3], mm[3][2], mm[4][4]);

    freematrix(SIZE, m1);
    freematrix(SIZE, m2);
    freematrix(SIZE, mm);
    return(0);
}
matrix.nice
/* The Great Win32 Language Shootout http://dada.perl.it/shootout/ 
   contributed by Isaac Gouy (Nice novice)

   Transliterated from the Java implementation

To compile:	
   nicec --sourcepath=.. -d=. -a matrix.jar matrix

To run:
   java -jar matrix.jar 300
*/


// NOTE: the type of a variable declared with let
//       or var will be inferred by the compiler


import ackermann; // reuse toSingleInt


void main(String[] args){
   var n =  toSingleInt(args);
   let int SIZE = 30;

   let m1 = mkmatrix(SIZE, SIZE);
   let m2 = mkmatrix(SIZE, SIZE);
   let mm = new int[SIZE][SIZE];

   while (n-- > 0) mmult(m1, m2, mm);

   print(mm[0][0]); print(" ");
   print(mm[2][3]); print(" ");      
   print(mm[3][2]); print(" ");
   println(mm[4][4]);
}


int[][] mkmatrix(int nRows, int nCols) {
   int count = 1;
   let m = new int[nRows][nCols];
   for (var i = 0; i < nRows; i++) 
      for (var j = 0; j < nCols; j++) 
         m[i][j] = count++;
   return m;
}


void mmult(int[][] m1, int[][] m2, int[][] m) {
   let nRows = m1.length;
   let nCols = nRows; // Assume a square matrix
   for (var i=0; i < nRows; i++) 
      for (var j = 0; j < nCols; j++) {
         int val = 0;
         for (var k = 0; k < nCols; k++) 
            val += m1[i][k] * m2[k][j];
         m[i][j] = val;
      }
}
matrix.ocaml
(*
 * $Id: matrix.ocaml,v 1.7 2001/01/14 13:47:41 doug Exp $
 * http://www.bagley.org/~doug/shootout/
 * from Markus Mottl
 *)

let size = 30

let mkmatrix rows cols =
  let count = ref 1
  and last_col = cols - 1
  and m = Array.make_matrix rows cols 0 in
  for i = 0 to rows - 1 do
    let mi = m.(i) in
    for j = 0 to last_col do
      mi.(j) <- !count;
      incr count
    done;
  done;
  m

let rec inner_loop k v m1i m2 j =
  if k < 0 then v
  else inner_loop (k - 1) (v + m1i.(k) * m2.(k).(j)) m1i m2 j

let mmult rows cols m1 m2 m3 =
  let last_col = cols - 1
  and last_row = rows - 1 in
  for i = 0 to last_row do
    let m1i = m1.(i) and m3i = m3.(i) in
    for j = 0 to last_col do
      m3i.(j) <- inner_loop last_row 0 m1i m2 j
    done;
  done

let _ =
  let n =
    try int_of_string Sys.argv.(1)
    with Invalid_argument _ -> 1
  and m1 = mkmatrix size size
  and m2 = mkmatrix size size
  and m3 = Array.make_matrix size size 0 in
  for i = 1 to n - 1 do
    mmult size size m1 m2 m3
  done;
  mmult size size m1 m2 m3;
  Printf.printf "%d %d %d %d\n" m3.(0).(0) m3.(2).(3) m3.(3).(2) m3.(4).(4)
matrix.ocamlb
(*
 * $Id: matrix.ocaml,v 1.7 2001/01/14 13:47:41 doug Exp $
 * http://www.bagley.org/~doug/shootout/
 * from Markus Mottl
 *)

let size = 30

let mkmatrix rows cols =
  let count = ref 1
  and last_col = cols - 1
  and m = Array.make_matrix rows cols 0 in
  for i = 0 to rows - 1 do
    let mi = m.(i) in
    for j = 0 to last_col do
      mi.(j) <- !count;
      incr count
    done;
  done;
  m

let rec inner_loop k v m1i m2 j =
  if k < 0 then v
  else inner_loop (k - 1) (v + m1i.(k) * m2.(k).(j)) m1i m2 j

let mmult rows cols m1 m2 m3 =
  let last_col = cols - 1
  and last_row = rows - 1 in
  for i = 0 to last_row do
    let m1i = m1.(i) and m3i = m3.(i) in
    for j = 0 to last_col do
      m3i.(j) <- inner_loop last_row 0 m1i m2 j
    done;
  done

let _ =
  let n =
    try int_of_string Sys.argv.(1)
    with Invalid_argument _ -> 1
  and m1 = mkmatrix size size
  and m2 = mkmatrix size size
  and m3 = Array.make_matrix size size 0 in
  for i = 1 to n - 1 do
    mmult size size m1 m2 m3
  done;
  mmult size size m1 m2 m3;
  Printf.printf "%d %d %d %d\n" m3.(0).(0) m3.(2).(3) m3.(3).(2) m3.(4).(4)
matrix.oz
%%% $Id: matrix.oz,v 1.0 2002/08/19 16:22:00 dada Exp $
%%% http://dada.perl.it/shootout/
%%% 
%%% contributed by Isaac Gouy

%%  Usage: start from command line with
%%     ozc -x matrix.oz -o matrix.oz.exe
%%     matrix.oz.exe 300

functor
import System Application

define

   proc {MakeMatrix Rows Cols M}
      local Count in
     {NewArray 0 Rows-1 0 M}
     Count ={NewCell 0}
     for I in 0..Rows-1 do
        local R in
           {NewArray 0 Cols-1 0 R}
           {Put M I R}
           for J in 0..Cols-1 do
          {Assign Count {Access Count}+1}
          {Put R J {Access Count}}
           end
        end
     end
      end
   end


   proc {MMult M1 M2 MM}
      local S1 N1 Prod S2 N2 in
     S1 = {Array.low M1}
     N1 = {Array.high M1}
     S2 = {Array.low {Get M1 S1}}
     N2 = {Array.high {Get M1 S1}}
     Prod = {NewCell 0}
     {NewArray S1 N1 0 MM}
     for I in S1..N1 do
        local R in
           {NewArray S1 N1 0 R}
           {Put MM I R}
           for J in S1..N1 do
          {Assign Prod 0}
          for K in S2..N2 do
             {Assign Prod {Get {Get M1 I} K}*
              {Get {Get M2 K} J}+{Access Prod}}
          end
          {Put R J {Access Prod}}
           end
        end
     end
      end
   end

   proc {RepeatMMult N M1 M2 MM}
      local T in
     if N > 1 then
        {MMult M1 M2 T}
        {RepeatMMult N-1 M1 M2 MM}
     else {MMult M1 M2 T} MM = T end
      end
   end
   
in 
   local Args Repeat N M1 M2 MM in
      [Args] = {Application.getArgs plain}
      Repeat = {String.toInt Args}
      N = 30
      {MakeMatrix N N M1}
      {MakeMatrix N N M2}
      {RepeatMMult Repeat M1 M2 MM}
      
      {System.printInfo {Get {Get MM 0} 0}}{System.printInfo ' '}
      {System.printInfo {Get {Get MM 2} 3}}{System.printInfo ' '} % get col 3 out of row 2
      {System.printInfo {Get {Get MM 3} 2}}{System.printInfo ' '} % get col 2 out of row 3
      {System.showInfo {Get {Get MM 4} 4} }     
   end
   {Application.exit 0}
end
matrix.perl
#!/usr/local/bin/perl 
# $Id: matrix.perl,v 1.1 2000/12/29 06:10:10 doug Exp $
# http://www.bagley.org/~doug/shootout/

# This program based on the original from:
# "The What, Why, Who, and Where of Python" By Aaron R. Watters
# http://www.networkcomputing.com/unixworld/tutorial/005/005.html

# modified to pass rows and cols, and avoid matrix size checks
# I've sped up the original quite a bit by removing some loop
# invariants and declaring "use integer"

use strict;
use integer;

my $size = 30;

sub mkmatrix {
    my($rows, $cols) = @_;
    --$rows; --$cols;
    my $count = 1;
    my @mx = ();
    foreach (0 .. $rows) {
    my @row = ();
    $row[$_] = $count++ foreach (0 .. $cols);
    push(@mx, \@row);
    }
    return(\@mx);
}

# mmult contributed by Tony Bowden

sub mmult {
    my ($rows, $cols, $m1, $m2) = @_;
    my $m3 = [];
    --$rows; --$cols;
    for my $i (0 .. $rows) {
        for my $j (0 .. $cols) {
            $m3->[$i][$j] += $m1->[$i][$_] * $m2->[$_][$j] for 0..$cols;
        }
    }
    return $m3;
}

#sub mmult {
#    my ($rows, $cols, $m1, $m2) = @_;
#    my @m3 = ();
#    --$rows; --$cols;
#    for my $i (0 .. $rows) {
#    my @row = ();
#    my $m1i = $m1->[$i];
#    for my $j (0 .. $cols) {
#        my $val = 0;
#        for my $k (0 .. $cols) {
#        $val += $m1i->[$k] * $m2->[$k]->[$j];
#        }
#        push(@row, $val);
#    }
#    push(@m3, \@row);
#    }
#    return(\@m3);
#}

my $N = $ARGV[0] || 1;

my $m1 = mkmatrix($size, $size);
my $m2 = mkmatrix($size, $size);
my $mm;
while ($N--) {
    $mm = mmult($size, $size, $m1, $m2);
}
print "$mm->[0]->[0] $mm->[2]->[3] $mm->[3]->[2] $mm->[4]->[4]\n";

matrix.php
<?php
/*
 $Id: matrix.php,v 1.1 2001/05/14 03:37:18 doug Exp $
 http://www.bagley.org/~doug/shootout/
*/

set_time_limit(0);

$SIZE = 30;

function mkmatrix ($rows, $cols) {
    $count = 1;
    $mx = array();
    for ($i=0; $i<$rows; $i++) {
    for ($j=0; $j<$cols; $j++) {
        $mx[$i][$j] = $count++;
    }
    }
    return($mx);
}

function mmult ($rows, $cols, $m1, $m2) {
    $m3 = array();
    for ($i=0; $i<$rows; $i++) {
    for ($j=0; $j<$cols; $j++) {
        $x = 0;
        for ($k=0; $k<$cols; $k++) {
        $x += $m1[$i][$k] * $m2[$k][$j];
        }
        $m3[$i][$j] = $x;
    }
    }
    return($m3);
}

$n = ($argc == 2) ? $argv[1] : 1;
$m1 = mkmatrix($SIZE, $SIZE);
$m2 = mkmatrix($SIZE, $SIZE);
while ($n--) {
    $mm = mmult($SIZE, $SIZE, $m1, $m2);
}
print "{$mm[0][0]} {$mm[2][3]} {$mm[3][2]} {$mm[4][4]}\n";
?>
matrix.pike
#!/usr/local/bin/pike// -*- mode: pike -*-
// $Id: matrix.pike,v 1.2 2001/01/02 07:24:21 doug Exp $
// http://www.bagley.org/~doug/shootout/
// from: Per Hedbor

int size = 30;

array(array(int))
mkmatrix(int rows, int cols) {
    array(array(int)) m = allocate(rows);
    int count = 1;
    for (int i=0; i<rows; i++) {
    array(int) row = allocate(cols);
    for (int j=0; j<cols; j++) {
        row[j] = count++;
    }
    m[i] = row;
    }
    return(m);
}

void
main(int argc, array(string) argv) {
    int n = (int)argv[-1];
    if (n < 1)
      n = 1;
    
    Math.Matrix m1 = Math.Matrix(mkmatrix(size, size));
    Math.Matrix m2 = Math.Matrix(mkmatrix(size, size));
    Math.Matrix mm;
    for( int i = n; i>0; i-- )
      mm = m1 * m2;
    array q = (array(array(int)))(array)mm;
    write( "%d %d %d %d\n", q[0][0], q[2][3], q[3][2], q[4][4] );
}
matrix.pliant
# $Id: matrix.pliant,v 1.0 2002/02/07 18:27:00 dada Exp $
# http://dada.perl.it/shootout/

module "/pliant/language/context.pli"

gvar Int size := 30

function mkmatrix rows cols -> mx
  arg Int rows ; arg Int cols
  arg_w Array:(Array:Int) mx
  var Array:Int row
  var Int count := 1
  for (var Int r) 0 rows-1
    row:size := 0
    for (var Int c) 0 cols-1
      row += count
      count := count + 1
    mx += row
  return mx

function mmult rows cols m1 m2 m3
  arg Int rows ; arg Int cols
  arg Array:(Array:Int) m1
  arg Array:(Array:Int) m2
  arg_w Array:(Array:Int) m3
  var Array:Int row
  var Int val
  for (var Int i) 0 rows-1
    row:size := 0
    for (var Int j) 0 cols-1
      val := 0
      for (var Int k) 0 cols-1
        val := val + m1:i:k * m2:k:j
      row += val
    m3 += row

gvar Array:(Array:Int) m1
gvar Array:(Array:Int) m2
gvar Array:(Array:Int) mm

gvar Str s_n := cast ((pliant_script_args translate Address 1) map CStr) Str
if (s_n parse (gvar Int n))
  
  m1 := mkmatrix size size
  m2 := mkmatrix size size

  while n>0
    mmult size size m1 m2 mm
    n := n - 1
  console mm:0:0 " " mm:2:3 " " mm:3:2 " " mm:4:4 eol
else
  console "usage: matrix.pliant <number>" eol

matrix.poplisp
;;; -*- mode: lisp -*-
;;; $Id: matrix.poplisp,v 1.0 2002/05/03 14:16:00 dada Exp $

(proclaim '(optimize (speed 3) (space 0) (compilation-speed 0) (debug 0) (safety 0)))

(defun matmul (a b c n m k)
  (declare (optimize (speed 3) (safety 0) (debug 0))
           (type (simple-array (unsigned-byte 32) (*)) a b c)
           (fixnum n m k))
  (let ((sum 0)
        (i1 (- m))
        (k2 0))
    (declare (type (unsigned-byte 32) sum) (type fixnum i1 k2))
    (dotimes (i n c)
      (declare (fixnum i))
      (setf i1 (+ i1 m)) ;; i1=i*m
      (dotimes (j k)
        (declare (fixnum j))
        (setf sum 0)
        (setf k2 (- k))
        (dotimes (l m)
          (declare (fixnum l))
          (setf k2 (+ k2 k)) ;; k2= l*k
          (setf sum (the (unsigned-byte 32) (+ (the (unsigned-byte 32) sum) 
                                               (the (unsigned-byte 32) (* (aref a (+ i1 l))
                                                                          (aref b (+ k2 j))))))))
        (setf (aref c (+ i1 j)) sum)))))

(defun make-matrix (rows cols)
  (declare (type (unsigned-byte 32) rows cols)
           (optimize (speed 3) (safety 0))); (hcl:fixnum-safety 0)))
  (let* ((space (* rows cols))
         (matrix (make-array space
                             :element-type '(unsigned-byte 32))))
    (declare (type (simple-array (unsigned-byte 32) (*)) matrix)
             (fixnum space))
    (loop :for i :of-type fixnum :from 0 :below space
          :do (setf (aref matrix i) (1+ i)))
    matrix))

(let ((n (parse-integer (or (car pop11::poparglist) "1"))))
(declare (fixnum n)    
     (optimize (speed 3) (debug 0) (safety 0)))
(let* ((m1 (make-matrix 30 30))
   (m2 (make-matrix 30 30))
   (m3 (make-matrix 30 30))
   (mm (make-array '(30 30) :element-type '(unsigned-byte 32) :displaced-to m3)))
  (loop repeat n do (matmul m1 m2 m3 30 30 30))
  (format t "~A ~A ~A ~A~%"
      (aref mm 0 0) (aref mm 2 3) (aref mm 3 2) (aref mm 4 4))))

matrix.python
#!/usr/local/bin/python
# $Id: matrix.python,v 1.5 2001/05/09 01:24:52 doug Exp $
# http://www.bagley.org/~doug/shootout/

# This program based on the original from:
# "The What, Why, Who, and Where of Python" By Aaron R. Watters
# http://www.networkcomputing.com/unixworld/tutorial/005/005.html

# modified to pass rows and cols, and avoid matrix size checks
# and added one optimization to reduce subscripted references in
# inner loop.

import sys

size = 30

def mkmatrix(rows, cols):
    count = 1
    mx = [ None ] * rows
    for i in range(rows):
        mx[i] = [0] * cols
        for j in range(cols):
            mx[i][j] = count
            count += 1
    return mx

def mmult(rows, cols, m1, m2):
    m3 = [ None ] * rows
    for i in range( rows ):
        m3[i] = [0] * cols
        for j in range( cols ):
            val = 0
            for k in range( cols ):
                val += m1[i][k] * m2[k][j]
            m3[i][j] = val
    return m3

def mxprint(m):
    for i in range(size):
        for j in range(size):
            print m[i][j],
        print ""

def main():
    iter = int(sys.argv[1])
    m1 = mkmatrix(size, size)
    m2 = mkmatrix(size, size)
    for i in xrange(iter):
        mm = mmult(size, size, m1, m2)
    print mm[0][0], mm[2][3], mm[3][2], mm[4][4]

main()
matrix.rexx
size = 30

parse arg n
If n < 1 Then Do
    n = 1
End

call mkmatrix size, size, "m1"
call mkmatrix size, size, "m2"
Do While n > 0
    call mmult(size, size, "m1", "m2", "mm")
    n = n - 1
End
say mm.0.0" "mm.2.3" "mm.3.2" "mm.4.4

exit

mkmatrix:
    parse arg rows, cols, mx
    rows = rows - 1
    cols = cols - 1
    count = 1
    Do r = 0 To rows
        Do c = 0 To cols
            interpret mx || ".r.c = " count
            count = count + 1
        End
    End
    return mx

mmult:
    parse arg rows, cols, m1, m2, m3
    rows = rows - 1
    cols = cols - 1
    Do i = 0 To rows
        Do j = 0 To cols
            val = 0
            Do k = 0 To cols
                interpret "val = val + " || m1 || ".i.k * " || m2 || ".k.j"
            End
            interpret m3 || ".i.j = " val
        End
    End
matrix.ruby
#!/usr/local/bin/ruby
# -*- mode: ruby -*-
# $Id: matrix.ruby,v 1.3 2001/05/16 16:38:55 doug Exp $
# http://www.bagley.org/~doug/shootout/

n = Integer(ARGV.shift || 1)

size = 30

def mkmatrix(rows, cols)
    count = 1
    mx = Array.new(rows)
    for i in 0 .. (rows - 1)
    row = Array.new(cols, 0)
    for j in 0 .. (cols - 1)
        row[j] = count
        count += 1
    end
    mx[i] = row
    end
    mx
end

def mmult(rows, cols, m1, m2)
    m3 = Array.new(rows)
    for i in 0 .. (rows - 1)
    row = Array.new(cols, 0)
    for j in 0 .. (cols - 1)
        val = 0
        for k in 0 .. (cols - 1)
        val += m1[i][k] * m2[k][j]
        end
        row[j] = val
    end
    m3[i] = row
    end
    m3
end

m1 = mkmatrix(size, size)
m2 = mkmatrix(size, size)
mm = Array.new
n.times do
    mm = mmult(size, size, m1, m2)
end
puts "#{mm[0][0]} #{mm[2][3]} #{mm[3][2]} #{mm[4][4]}"
matrix.se
-- -*- mode: eiffel -*-
-- $Id: matrix.se,v 1.3 2001/05/23 18:28:58 doug Exp $
-- http://www.bagley.org/~doug/shootout/
-- from Steve Thompson

-- <LOC-OFF>
indexing
   description: "This class performs the matrix multiplication test" 
   author : Steve Thompson
   email  : "Steve_Thompson@prodigy.net"
   date   : February 18, 2001
   compile: "compile -clean -boost -no_split -O3 main.e -o main"
   run    : "main 300"
-- <LOC-ON>
   
class MATRIX
   
creation make
   
feature -- Creation
   
   make is
      local
     index, count: INTEGER
     m1, m2: like matrix
      do
     from
        if argument_count < 1 then 
           count := 1
        else 
           count := argument(1).to_integer
        end
        index := 0
        m1 := new_matrix(30, 30) 
        m2 := new_matrix(30, 30) 
        !!matrix.make(0, 29, 0, 29)
     until
        index = count
     loop
        mmult(30, 30, m1, m2)
        index := index + 1
     end -- from
     print(matrix.item(0, 0).to_string + " " + matrix.item(2, 3).to_string + " " +
           matrix.item(3, 2).to_string + " " + matrix.item(4, 4).to_string + "%N")
      end -- make
   
feature -- Queries
   
   matrix: ARRAY2[INTEGER]
   
   new_matrix(rows, columns: INTEGER): like matrix is
     -- Create and populate a new matrix.
      local
     i, j, count: INTEGER
      do
     !!Result.make(0, rows - 1, 0, columns - 1)
     from 
        count := 1
        i := 0
     until i = rows loop
        from j := 0 until j = columns loop
           Result.put(count, i, j)
           count := count + 1
           j := j + 1
        end 
        i := i + 1
     end
      end -- new_matrix
   
feature -- Commands
   
   zero_matrix(rows, columns: INTEGER; a_matrix: like matrix) is
     -- Clear a matrix
      do
     matrix.make(0, rows - 1, 0, columns - 1)
      end -- zero_matrix
   
   mmult(rows, columns: INTEGER; first, second: like matrix) is
     -- Multiply two matrices.
      local
     i, j, k, val: INTEGER
      do
     zero_matrix(rows, columns, matrix)
     from i := 0 until i = rows loop
        from j := 0 until j = columns loop
           val := 0
           from k := 0 until k = columns loop
          val := val + first.item(i, k) * second.item(k, j)
          k := k + 1
           end
           matrix.put(val, i, j)
           j := j + 1
        end
        i := i + 1
     end -- from
      end -- mmult
   
end
matrix.slang
% $Id: matrix.slang,v 1.0 2003/01/03 13:59:00 dada Exp $
% http://dada.perl.it/shootout/
%
% contributed by John E. Davis

variable size = 30;

define mkmatrix(rows, cols)
{
   variable mx = [1:rows*cols];
   reshape (mx, [rows, cols]);
   return mx;
}

define main()
{
   variable iter = integer (__argv[1]);
   variable m1 = mkmatrix(size, size);
   variable m2 = mkmatrix(size, size);
   
   loop (iter)
     variable mm = m1 # m2;

   vmessage ("%.0f %.0f %.0f %.0f", mm[0,0], mm[2,3], mm[3,2], mm[4,4]);
}

main ();
matrix.smlnj
(* -*- mode: sml -*-
 * $Id: matrix.smlnj,v 1.3 2001/07/11 01:40:04 doug Exp $
 * http://www.bagley.org/~doug/shootout/
 * from Stephen Weeks
 *)


structure Test : sig
    val main : (string * string list) -> OS.Process.status
end = struct

fun incr r = r := !r + 1
fun for (start, stop, f) =
   let
      fun loop i =
     if i > stop
        then ()
     else (f i; loop (i + 1))
   in
      loop start
   end

structure Array2 =
   struct
      datatype 'a t = T of 'a array array

      fun sub (T a, r, c) = Array.sub (Array.sub (a, r), c)
      fun subr (T a, r) =
     let val a = Array.sub (a, r)
     in fn c => Array.sub (a, c)
     end
      fun update (T a, r, c, x) = Array.update (Array.sub (a, r), c, x)
      fun array (r, c, x) =
     T (Array.tabulate (r, fn _ => Array.array (c, x)))
   end
val sub = Array2.sub
val update = Array2.update
   
val size = 30

fun mkmatrix (rows, cols) =
   let
      val count = ref 1
      val last_col = cols - 1
      val m = Array2.array (rows, cols, 0)
   in
      for (0, rows - 1, fn i =>
       for (0, last_col, fn j =>
        (update (m, i, j, !count)
         ; incr count)));
      m
   end

fun mmult (rows, cols, m1, m2, m3) =
   let
      val last_col = cols - 1
      val last_row = rows - 1
   in
      for (0, last_row, fn i =>
       for (0, last_col, fn j =>
        update (m3, i, j,
            let
               val m1i = Array2.subr (m1, i)
               fun loop (k, sum) =
                  if k < 0
                 then sum
                  else loop (k - 1,
                     sum + m1i k * sub (m2, k, j))
            in loop (last_row, 0)
            end)))
   end

fun atoi s = case Int.fromString s of SOME num => num | NONE => 0;
fun printl [] = print "\n" | printl(h::t) = ( print h ; printl t );

fun main (name, args) =
  let
     val n = atoi (hd (args @ ["1"]))
     val m1 = mkmatrix (size, size)
     val m2 = mkmatrix (size, size)
     val m3 = Array2.array (size, size, 0)
     val _ = for (1, n - 1, fn _ => mmult (size, size, m1, m2, m3))
     val _ = mmult (size, size, m1, m2, m3)
  in
     printl [Int.toString (sub (m3, 0, 0)),
         " ",
         Int.toString (sub (m3, 2, 3)),
         " ",
         Int.toString (sub (m3, 3, 2)),
         " ",
         Int.toString (sub (m3, 4, 4))];
     OS.Process.success
  end
end

val _ = SMLofNJ.exportFn("matrix", Test.main)
matrix.tcl
#!/usr/local/bin/tclsh
# $Id: matrix.tcl,v 1.6 2001/01/16 00:34:18 doug Exp $
# http://www.bagley.org/~doug/shootout/

# This program based on the original from:
# "The What, Why, Who, and Where of Python" By Aaron R. Watters
# http://www.networkcomputing.com/unixworld/tutorial/005/005.html

# modified to avoid matrix size checks
# --Doug

# additional speedups by Kristoffer Lawson and Miguel Sofer

set size 30;

proc mkmatrix {rows cols} {
    set count 1;
    set mx [list]
    for { set i 0 } { $i < $rows } { incr i } {
    set row [list]
    for { set j 0 } { $j < $cols } { incr j } {
        lappend row $count;
        incr count;
    }
    lappend mx $row;
    }
    return $mx;
}

proc mmult {m1 m2} {
    set cols [lindex $m2 0]
    foreach row1 $m1 {
        set row [list]
        set i 0
        foreach - $cols {
            set elem 0
            foreach elem1 $row1 row2 $m2 {
                set elem [expr {$elem + $elem1 * [lindex $row2 $i]}]
            }
            lappend row $elem
            incr i
        }
        lappend result $row
    }
    return $result
}

proc main {} {
    global argv size
    set num [lindex $argv 0]
    if {$num < 1} {
    set num 1
    }

    set m1 [mkmatrix $size $size]
    set m2 [mkmatrix $size $size]
    while {$num > 0} {
        incr num -1
        set m [mmult $m1 $m2]
    }

    puts "[lindex [lindex $m 0] 0] [lindex [lindex $m 2] 3] [lindex [lindex $m 3] 2] [lindex [lindex $m 4] 4]"
}

main
matrix.vbscript
Const size = 30

Function mkmatrix(rows, cols)
    ReDim mx(size, size)
    rows = rows - 1
    cols = cols - 1
    count = 1
    For R = 0 To rows
        For C = 0 To cols
            mx(R, C) = count
            count = count + 1
        Next
    Next
    mkmatrix = mx
End Function

Function mmult(rows, cols, m1, m2)
    ReDim m3(size, size)
    rows = rows - 1
    cols = cols - 1
    
    For i = 0 To rows
        For j = 0 To cols
            val = 0
            For k = 0 To cols
                val = val + m1(i, k) * m2(k, j)
            Next
            m3(i, j) = val
        Next
    Next
    mmult = m3
End Function

M1 = mkmatrix(size, size)
M2 = mkmatrix(size, size)

N = WScript.Arguments(0)
If N < 1 Then N = 1

For I = 0 To N
    MM = mmult(size, size, M1, M2)
Next
WScript.Echo MM(0, 0) & " " & MM(2, 3) & " " & MM(3, 2) & " " & MM(4, 4)

matrix.vc
/* -*- mode: c -*-
 * $Id: matrix.gcc,v 1.6 2001/03/31 15:52:48 doug Exp $
 * http://www.bagley.org/~doug/shootout/
 */

#include <stdio.h>
#include <stdlib.h>

#define SIZE 30

int **mkmatrix(int rows, int cols) {
    int i, j, count = 1;
    int **m = (int **) malloc(rows * sizeof(int *));
    for (i=0; i<rows; i++) {
    m[i] = (int *) malloc(cols * sizeof(int));
    for (j=0; j<cols; j++) {
        m[i][j] = count++;
    }
    }
    return(m);
}

void zeromatrix(int rows, int cols, int **m) {
    int i, j;
    for (i=0; i<rows; i++)
    for (j=0; j<cols; j++)
        m[i][j] = 0;
}

void freematrix(int rows, int **m) {
    while (--rows > -1) { free(m[rows]); }
    free(m);
}

int **mmult(int rows, int cols, int **m1, int **m2, int **m3) {
    int i, j, k, val;
    for (i=0; i<rows; i++) {
    for (j=0; j<cols; j++) {
        val = 0;
        for (k=0; k<cols; k++) {
        val += m1[i][k] * m2[k][j];
        }
        m3[i][j] = val;
    }
    }
    return(m3);
}

int main(int argc, char *argv[]) {
    int i, n = ((argc == 2) ? atoi(argv[1]) : 1);
    
    int **m1 = mkmatrix(SIZE, SIZE);
    int **m2 = mkmatrix(SIZE, SIZE);
    int **mm = mkmatrix(SIZE, SIZE);

    for (i=0; i<n; i++) {
    mm = mmult(SIZE, SIZE, m1, m2, mm);
    }
    printf("%d %d %d %d\n", mm[0][0], mm[2][3], mm[3][2], mm[4][4]);

    freematrix(SIZE, m1);
    freematrix(SIZE, m2);
    freematrix(SIZE, mm);
    return(0);
}
matrix.vc++
// -*- mode: c++ -*-
// $Id: matrix.g++,v 1.3 2001/06/20 03:20:02 doug Exp $
// http://www.bagley.org/~doug/shootout/

#include <iostream>
#include <stdlib.h>

using namespace std;

#define SIZE 30

int **mkmatrix(int rows, int cols) {
    int i, j, count = 1;
    int **m = (int **) malloc(rows * sizeof(int *));
    for (i=0; i<rows; i++) {
    m[i] = (int *) malloc(cols * sizeof(int));
    for (j=0; j<cols; j++) {
        m[i][j] = count++;
    }
    }
    return(m);
}

void zeromatrix(int rows, int cols, int **m) {
    int i, j;
    for (i=0; i<rows; i++)
    for (j=0; j<cols; j++)
        m[i][j] = 0;
}

void freematrix(int rows, int **m) {
    while (--rows > -1) { free(m[rows]); }
    free(m);
}

int **mmult(int rows, int cols, int **m1, int **m2, int **m3) {
    int i, j, k, val;
    for (i=0; i<rows; i++) {
    for (j=0; j<cols; j++) {
        val = 0;
        for (k=0; k<cols; k++) {
        val += m1[i][k] * m2[k][j];
        }
        m3[i][j] = val;
    }
    }
    return(m3);
}

int main(int argc, char *argv[]) {
    int i, n = ((argc == 2) ? atoi(argv[1]) : 1);
    
    int **m1 = mkmatrix(SIZE, SIZE);
    int **m2 = mkmatrix(SIZE, SIZE);
    int **mm = mkmatrix(SIZE, SIZE);

    for (i=0; i<n; i++) {
    mm = mmult(SIZE, SIZE, m1, m2, mm);
    }
    cout << mm[0][0] << " " << mm[2][3] << " " << mm[3][2] << " " << mm[4][4] << endl;

    freematrix(SIZE, m1);
    freematrix(SIZE, m2);
    freematrix(SIZE, mm);
    return(0);
}
matrix.vpascal
program matrix;
uses SysUtils;

const
    size = 30;

type tMatrix = array[0..size, 0..size] of integer;

procedure mkmatrix( rows, cols : integer; var mx : tMatrix);
var 
    R, C, count : integer;
begin
    Dec(rows);
    Dec(cols);
    count := 1;
    for R := 0 to rows do
    begin
        for C := 0 to cols do
        begin
            mx[R, C] := count;
            Inc(count);
        end;
    end;
End;

procedure mmult(rows, cols : integer; m1, m2 : tMatrix; var mm : tMatrix );
var
    i, j, k, val: integer;
begin
    Dec(rows);
    Dec(cols);    
    For i := 0 To rows do
    begin
        For j := 0 To cols do
        begin
            val := 0;
            For k := 0 To cols do
            begin
                Inc(val, m1[i, k] * m2[k, j]);
            end;
            mm[i, j] := val;
        end;
    end;
End;


var NUM, I : integer;
    M1, M2, MM : tMatrix;

begin
    if ParamCount = 0 then
        NUM := 1
    else
        NUM := StrToInt(ParamStr(1));
        
    if NUM < 1 then NUM := 1;

    mkmatrix(size, size, M1);
    mkmatrix(size, size, M2);
    
    for I := 0 To NUM do
    begin
        mmult(size, size, M1, M2, MM);
    end;
    WriteLn( IntToStr(MM[0, 0]) + ' ' + IntToStr(MM[2, 3]) + ' ' +
             IntToStr(MM[3, 2]) + ' ' + IntToStr(MM[4, 4]));
end.