11

私はMySQLの行列乗算を書こうとしていますが、ちょっと行き詰まっています:

基本的に、私の行列は
[row#, column#, matrixID, value] の形式で保存されているので、例えば行列 [3 x 2] は次のようになります:

[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]] と同等です。

以下は、matrix1 * matrix2 の単一要素の計算を非常にうまく行います。

   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 を使用してそれらを反復処理することに問題があります。アドバイス/提案は大歓迎です

4

3 に答える 3

19

試す:

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#`

はこちら

'mat01'(と'mat02'を適切な値に置き換えmatrixIDます。)

于 2013-03-19T15:54:43.093 に答える
1

SQL ですべての計算を実行できます。正方形ではないため、それ自体で乗算することはできません。

これがアイデアです:

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
于 2013-03-19T15:25:23.670 に答える
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 プログラミング ガイドには、行列の乗算を実装する良い例があります。

于 2013-03-19T15:56:42.060 に答える