awk 矩阵乘法

Awk Matrix multiplication

我正在尝试编写允许我在两个制表符分隔文件之间执行矩阵乘法的 AWK 命令。

示例:

cat m1

1 2 3 4
5 6 7 8

猫平方米

1 2
3 4
5 6
7 8

期望的输出:

 50  60
114 140

没有对尺寸的输入文件进行任何验证。

分成两个脚本会更容易,一个用于转置第二个矩阵,一个用于创建向量的点积。同样为了简单地 awk 代码,你可以求助于 join.

$ awk '{m=NF/2; for(i=1;i<=m;i++) sum[NR] += $i*$(i+m)} 
   END {for(i=1;i<=NR;i++) 
          printf "%s", sum[i] (i==sqrt(NR)?ORS:OFS); 
        print ""}' <(join -j99 m1 <(transpose m2))

其中 transpose 函数定义为

$ function transpose() { awk '{for(j=1;j<=NF;j++) a[NR,j]=$j}
                          END {for(i=1;i<=NF;i++) 
                                 for(j=1;j<=NR;j++) 
                                   printf "%s",a[j,i] (j==NR?ORS:OFS)}' ""; }

我建议使用 GNU Octave:

octave --eval 'load("m1"); load("m2"); m1*m2'

输出:

ans =                              

    50    60
   114   140

但是,假设文件格式正确,您可以使用 GNU awk 这样做:

矩阵-mult.awk

ARGIND == 1 {
  for(i=1; i<=NF; i++)
    m1[FNR][i] = $i
  m1_width  = NF
  m1_height = FNR
}

ARGIND == 2 {
  for(i=1; i<=NF; i++)
    m2[FNR][i] = $i
  m2_width  = NF
  m2_height = FNR
}

END {
  if(m1_width != m2_height) {
    print "Matrices are incompatible, unable to multiply!"
    exit 1
  }
  for(i=1; i<=m1_height; i++) {
    for(j=1; j<=m2_width; j++) {
      for(k=1; k<=m1_width; k++)
        sum += m1[i][k] * m2[k][j]
      printf sum OFS; sum=0
    }
    printf ORS
  }
}

运行 像这样:

awk -f matrix-mult.awk m1 m2

输出:

50 60 
114 140