行列を含む小さなc#プロジェクトがあります。大量のデータをn個の長さのチャンクに分割し、チャックをベクトルとして扱い、ファンデルモンド**行列を乗算することで処理しています。問題は、条件に応じて、チャックのサイズと対応するファンデルモンド**行列が変化する可能性があることです。私は読みやすい一般的な解決策を持っていますが、遅すぎます:
public byte[] addBlockRedundancy(byte[] data) {
if (data.Length!=numGood) D.error("Expecting data to be just "+numGood+" bytes long");
aMatrix d=aMatrix.newColumnMatrix(this.mod, data);
var r=vandermonde.multiplyBy(d);
return r.ToByteArray();
}//method
これは、私のi5 U470@1.33GHzで毎秒約1/4メガバイトを処理できます。行列の乗算を手動でインライン化することで、これを高速化できます。
int o=0;
int d=0;
for (d=0; d<data.Length-numGood; d+=numGood) {
for (int r=0; r<numGood+numRedundant; r++) {
Byte value=0;
for (int c=0; c<numGood; c++) {
value=mod.Add(value, mod.Multiply(vandermonde.get(r, c), data[d+c]));
}//for
output[r][o]=value;
}//for
o++;
}//for
これは、1秒間に約1メガを処理できます。
(「mod」は、私のお気に入りの既約多項式を法としてGF(2 ^ 8)に対して演算を実行していることに注意してください。)
私はこれがはるかに速くなることを知っています:結局のところ、ファンデルモンド**行列はほとんどゼロです。行列を取得して、ベクトルに指定された行列を効果的に乗算する最適化されたメソッドを返すことができるルーチンを作成するか、ルーチンを見つけることができるはずですが、より高速です。次に、このルーチンに5x5のファンデルモンド行列(単位行列)を与えると、実行する演算がなく、元のデータがコピーされるだけです。
**注意:私が「ファンデルモンド」という用語を使用しているのは、実際には、ファンデルモンド行列のいくつかの行が追加された単位行列を意味します(コメントを参照)。この行列は、すべてゼロであるため素晴らしいものです。また、(選択した)行を十分に削除して正方形にすると、可逆行列になります。そしてもちろん、これと同じルーチンを使用して、これらの逆行列のいずれかを最適化された一連の命令に変換したいと思います。
この行列の乗算を高速化するにはどうすればよいですか?
ありがとう!
(ファンデルモンド行列の間違いを修正するために編集)