3

Matrix Market形式のスパース マトリックスにゼロ要素を挿入する必要があります (ただし、既にヘッダーはありません)。

最初の列は ROW の番号、2 番目の列は COLUMN の番号、3 番目の列は要素の値です。

テストには 2 x 3 マトリックスを使用しています。しかし、これを任意の次元行列 mx n に対して実行できる必要があります。

各行列の行数、列数、およびゼロ以外の要素の数は、既に別の変数になっています。

これまで、これらのマトリックスを操作するために bash sed と awk を使用してきました。

入力ファイル:

1 1 1.0000
1 2 2.0000
2 1 4.0000
2 2 5.0000
2 3 6.0000

ROWS と COLUMNS は整数 %d で、VALUES は float %.4f です

ここでは、1 つの要素のみがゼロ (行 1 列 3) であり、それを表す行は省略されています。

では、どうすればこの行を挿入できますか???

出力ファイル:

1 1 1.0000
1 2 2.0000
1 3 0.0000
2 1 4.0000
2 2 5.0000
2 3 6.0000

空の 2 x 3 行列は次のようになります。

1 1 0.0000
1 2 0.0000
1 3 0.0000
2 1 0.0000
2 2 0.0000
2 3 0.0000

別の例として、より多くのゼロ要素を持つ 3 x 4 行列があります。

入力ファイル:

1 2 9.7856
1 4 4.2311
2 1 3.4578
2 2 45.1231
2 3 -12.0124
3 4 0.1245

出力ファイル:

1 1 0.0000
1 2 9.7856
1 3 0.0000
1 4 4.2311
2 1 3.4578
2 2 45.1231
2 3 -12.0124
2 4 0.0000
3 1 0.0000
3 2 0.0000
3 3 0.0000
3 4 0.1245

あなたが私を助けてくれることを願っています。私はすでに解決策を試すのに3日以上費やしました。

私が得た最高のものはこれでした:

for((i=1;i<3;i++))
do
    for((j=1;j<4;j++))
    do
        awk -v I=${i} -v J=${j} 'BEGIN{FS=" "}
                            {if($1==I && $2==J)
                                    printf("%d %d %.4f\n",I,J,$3)
                            else
                                    printf("%d %d %d\n",I,J,0)
                            }' ./etc/A.2
        done
done

しかし、それは効率的ではなく、多くの不要な行を出力します:

1 1 1.0000
1 1 0
1 1 0
1 1 0
1 1 0
1 2 0
1 2 2.0000
1 2 0
1 2 0
1 2 0
1 3 0
1 3 0
1 3 0
1 3 0
1 3 0
2 1 0
2 1 0
2 1 4.0000
2 1 0
2 1 0
2 2 0
2 2 0
2 2 0
2 2 5.0000
2 2 0
2 3 0
2 3 0
2 3 0
2 3 0
2 3 6.0000

お願いします!助けて!皆さん、ありがとうございました!

4

1 に答える 1

0

「I」と「J」の最大値を指定する場合:

# cat tst.awk
{ a[$1,$2] = $3 }
END {
    for (i=1;i<=I;i++)
        for (j=1;j<=J;j++)
            print i, j, ( (i,j) in a ? a[i,j] : "0.0000" )
}

$ awk -v I=2 -v J=3 -f tst.awk file
1 1 1.0000
1 2 2.0000
1 3 0.0000
2 1 4.0000
2 2 5.0000
2 3 6.0000

ツールがそれを把握するだけの場合 (空のファイルに対しては機能しないか、または必要な最大値が設定されていない場合):

$ cat tst2.awk
NR==1 { I=$1; J=$2 }

{
    a[$1,$2] = $3
    I = (I > $1 ? I : $1)
    J = (J > $2 ? J : $2)
}

END {
    for (i=1;i<=I;i++)
        for (j=1;j<=J;j++)
            print i, j, ( (i,j) in a ? a[i,j] : "0.0000" )
}

$ awk -f tst2.awk file
1 1 1.0000
1 2 2.0000
1 3 0.0000
2 1 4.0000
2 2 5.0000
2 3 6.0000
于 2013-08-04T11:32:05.140 に答える