【问题标题】:MySQL matrix multiplicationMySQL矩阵乘法
【发布时间】:2013-03-08 07:29:40
【问题描述】:

我正在尝试为 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 迭代它们时遇到问题。 欢迎任何意见/建议

【问题讨论】:

  • 你的问题真的是“如何在 MySQL 中生成数字序列”吗?
  • MySQL 是一个数据库管理系统,而不是一个线性代数引擎。您应该将内容读入更合适的工具(如 Java 或 C++ 应用程序)中,在那里执行矩阵操作,并在必要时将结果发布回数据库。
  • ofc,最简单的解决方案是使用 Java 或 C++(或其他任何东西),但是我正在处理非常大的矩阵(基本上大到足以将它们放入内存中是不可能的)并且它可以进行矩阵操作以合理的速度相当复杂,因为它只需要在内存中保留块和 IO 开销来处理矩阵所需的大量读取和写入。至于生成 MySQL 的数字序列,这当然是一种解决方案,我不知道该怎么做,更好的解决方案是将一对 SELECTed 行输入 SQL 函数并返回表作为结果。

标签: mysql sql math matrix linear-algebra


【解决方案1】:

试试:

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

(将'mat01''mat02' 替换为合适的matrixID 值。)

【讨论】:

  • @user2186956:很高兴我能帮上忙。 :)
【解决方案2】:

您可以在 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

【讨论】:

    【解决方案3】:

    我知道这是 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 在 ri C Programming Guide 中有一个很好的实现矩阵乘法的例子。

    【讨论】:

    • 当然可以通过使用供应商的语法来简化语句的情况(即 Sql-Server 的 ISNULL() 或 COALESCE() 等)。
    猜你喜欢
    • 2018-04-11
    • 2017-03-11
    • 2013-12-23
    • 2014-09-19
    • 1970-01-01
    相关资源
    最近更新 更多