MySQL矩阵乘法

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]]

下面的代码可以很好地计算矩阵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 生成这组数字并迭代它们时遇到了问题。 欢迎任何建议/建议。


你的问题真的是“如何在MySQL中生成数字序列”吗? - raina77ow
1
MySQL是一个数据库管理系统,而不是线性代数引擎。你应该将内容读入更适合的工具(如Java或C++应用程序)中进行矩阵操作,并在必要时将结果发布回数据库。 - andand
3
当然,最简单的解决方案是使用Java或C++(或其他任何语言),但我正在处理非常大的矩阵(基本上它们太大了,无法容纳到内存中),这使得在合理的速度下进行矩阵操作变得相当复杂,因为它需要在内存中仅保留块并且对于处理矩阵所需的大量读取和写入的IO开销很大。至于生成MySQL数字序列,这确实是一种解决方案,但我不知道如何实现它,更好的解决方案是将SELECT出的一对行输入SQL函数并将表格作为结果返回。 - Azolin
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值。)


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

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编程指南中有一个很好的矩阵乘法实现示例。


当然,可以使用供应商语法(例如Sql-Server的ISNULL()或COALESCE())来简化case when语句。 - Pieter Geerkens

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接