2013-03-19 24 views
8

[X 2]のようなものであろう:MySQLの行列乗算

[row#, column#, matrixID, value] 
    1  1  mat01 1 
    1  2  mat01 2 
    1  3  mat01 3 
    2  1  mat01 4 
    2  2  mat01 5 
    2  3  mat01 6 

と等価である:[1 2 3]、[4 5 6]以下

は非常によく行列1の*の行列2の単一要素の計算を行います:

SELECT SUM(row1.`val` * col2.`val`) 
    FROM matValues row1 
    INNER JOIN `matValues` col2 
    WHERE row1.`row` = 1 AND row1.`mID`='matrix1' AND 
     col2.`mID`='matrix2' AND col2.`col` = 1 AND row1.col = col2.row 

これを関数にラップしてから、行番号と列番号を繰り返し処理する可能性がありますが、この数値セットを生成してSQLを使用して繰り返し処理することに問題があります。 アドバイス/提案はすべてお待ちしております。

+0

あなたの質問は本当に「どのようにMySQLで数値のシーケンスを生成するのですか? – raina77ow

+1

MySQLは、データベース管理システムであり、線形代数エンジンではありません。その中で行列操作を実行するより適切なツール(JavaやC++アプリケーションのような)に内容を読み込み、必要に応じて結果をデータベースにポストする必要があります。 – andand

+2

ofcの最も単純な解決策は、JavaやC++(または何か他のもの)を使用していますが、私は非常に大きな行列(基本的にはメモリにあてはめるのは問題ありません)を扱っていて、行列を処理するために必要な非常に多くの読み書きのために、メモリとIOオーバーヘッドにチャンクのみを保持する必要があります。 MySQLの数列の生成に関しては、それは確かに1つの解決策であり、私はそれを行う方法を知らない、より良い解決策はSQL関数にSELECTされた行のペアをフィードし、結果としてテーブルを返すことだろう。 – Azolin

答えて

18

は試してみてください。

select m1.`row#`, m2.`column#`, sum(m1.value*m2.value) 
from matValues m1 
join matValues m2 on m2.`row#` = m1.`column#` 
where m1.matrixID = 'mat01' and m2.matrixID = 'mat02' 
group by m1.`row#`, m2.`column#` 

here

(適しmatrixID値で'mat01''mat02'を交換してください。)

+0

ありがとう、これは魅力のように動作します:) – Azolin

+0

@ user2186956:うれしいです。 :) –

1

計算をSQLで行うことができます。行列が1つしかない例は、正方形ではないので、それ自体では掛け合わせることはできません。ここで

はアイデアです:

SELECT mout.row, mout.col, SUM(m1.value*m2.value) 
FROM (select distinct row from matValues cross join 
     select distinct COL from matValues 
    ) mout left outer join 
    matValues m1 
    on m1.row = mout.row left outer join 
    matValues m2 
    on m2.col = mout.col and 
     m2.row = m1.col 
0

私は、これはSQL-Serverの構文ですけど、それはあなたに対応するMySQLの構文のスタートを与える必要があります。まばらな行列の性質がうまく処理されているようです。

with I as (
     select * from (values 
     (1,1, 1), 
     (2,2, 1), 
     (3,3, 1) 
    ) data(row,col,value) 
    ) 
    ,z_90 as (
     select * from (values 
     (1,2, 1), 
     (2,1,-1), 
     (3,3, 1) 
    ) data(row,col,value) 
    ) 
    ,xy as (
     select * from (values 
     (1,2, 1), 
     (2,1, 1), 
     (3,3, 1) 
    ) data(row,col,value) 
    ) 
    ,x_90 as (
     select * from (values 
     (1,1, 1), 
     (2,3, 1), 
     (3,2,-1) 
    ) data(row,col,value) 
    ) 
    select 
     'I * z_90' as instance, 
     a.row, 
     b.col, 
     sum(case when a.value is null then 0 else a.value end 
      * case when b.value is null then 0 else b.value end) as value 
    from I as a 
    join z_90 as b on a.col = b.row 
    group by a.row, b.col 
    union all 
    select 
     'z_90 * xy' as instance, 
     a.row, 
     b.col, 
     sum(case when a.value is null then 0 else a.value end 
      * case when b.value is null then 0 else b.value end) as value 
    from z_90 as a 
    join xy as b on a.col = b.row 
    group by a.row, b.col 
    union all 
    select 
     'z_90 * x_90' as instance, 
     a.row, 
     b.col, 
     sum(case when a.value is null then 0 else a.value end 
      * case when b.value is null then 0 else b.value end) as value 
    from z_90 as a 
    join x_90 as b on a.col = b.row 
    group by a.row, b.col 

    order by instance, a.row, b.col 

利回り:

instance row   col   value 
----------- ----------- ----------- ----------- 
I * z_90 1   2   1 
I * z_90 2   1   -1 
I * z_90 3   3   1 
z_90 * x_90 1   3   1 
z_90 * x_90 2   1   -1 
z_90 * x_90 3   2   -1 
z_90 * xy 1   1   1 
z_90 * xy 2   2   -1 
z_90 * xy 3   3   1 

はしかし、私はまた、あなたのグラフィックスカードでこれを実行するチェックアウトをお勧めします。 NVIDIAは、「Cプログラミングガイド」で行列乗算を実装する良い例を持っています。

+0

ベンダーの構文(つまり、Sql-ServerのISNULL()またはCOALESCE()など)を使用すると、ステートメントを簡単にすることができます。 –