#! /usr/bin/gawk -f # Last edited on 2012-01-01 16:15:57 by stolfilocal # Multiplies two 3x3 matrices. # Each matrix should be given as 3 rows of 3 numbers. BEGIN{ USAGE = ( "multiply-matrices.gawk M.txt N.txt > P.txt" ) abort = -1; split("", M); split("", N); Mrows = -1; # Number of rows of matrix {M}. Mcols = -1; # Number of cols of matrix {M}. Nrows = -1; # Number of rows of matrix {N}. Ncols = -1; # Number of cols of matrix {N}. mats = 0; # Number of complete matrices read. cols = -1; # Number of columns in current matrix. rows = 0; # Number of complete rows in current matrix. } (abort >= 0) { exit abort; } // { gsub(/[\#].*$/, ""); gsub(/[\011\240\015]/, " "); } /^[ ]*$/ { next; } // { if (ARGIND != mats+1) { finish_matrix(); } if (mats >= 2) { data_error(("too many matrices")); } if (cols == -1) { cols = NF; } else { if (NF != cols) { data_error(("inconsistent number of columns")); }} i = rows; for (j = 0; j < cols; j++) { el = $(j+1); if (! (el ~/^[-+]?[0-9]+([.][0-9]+(|e[-+]?[0-9]+))?$/)) { data_error(("bad element format \"" el "\"")); } if (mats == 0) { M[i,j] = el+0; } else { N[i,j] = el+0; } } rows++; next; } END { finish_matrix( ); if (mats < 2) { data_error(("too few matrices")); } if (mats > 2) { data_error(("program error")); } if (Mcols != Nrows) { data_error(("matrix sizes don't match")); } # Multiply the matrices and print: split("", P); for (i = 0; i < Mrows; i++) { for (j = 0; j < Ncols; j++) { sum = 0; for (k = 0; k < Mcols; k++) { sum += M[i,k]*N[k,j]; } P[i,j] = sum; printf " %+13.6e", P[i,j]; } printf "\n"; } } function finish_matrix( ) { if (mats == 0) { Mcols = cols; Mrows = rows; } else if (mats == 1) { Ncols = cols; Nrows = rows; } else { data_error(("too many matrices")); } mats++; rows = 0; cols = -1; } function data_error(msg) { printf "%s:%d: %s\n", FILENAME, FNR, msg > "/dev/stderr"; printf " [%s]\n", $0 > "/dev/stderr"; abort = 1; exit abort; }