【问题标题】:Lower triangular matrix-vector product下三角矩阵-向量积
【发布时间】:2017-12-19 00:16:44
【问题描述】:

在一次编程练习中,我得到了一个保存为数组的对称 3x3 矩阵的下三角元素

|1 * *|

|2 4 *| => [1,2,3,4,5,6]

|3 5 6|

我需要制作乘积 C(i)=C(i)+M(i,j)V(j),其中 M 是对称矩阵,V 是向量。

V =>[A,B,C]
C(1)=1*A + 2*B + 3*C
C(2)=2*A + 4*B + 5*C
C(3)=3*A + 5*B + 6*C

我正在尝试制作一个可以执行此产品的高效算法

我可以轻松生成 C(3) 所需的所有产品 但是,当我尝试生成值 C(1)、C(2) 时遇到问题,我不知道如何解决这个问题无需使用额外的内存。

这就是我所做的

k=6
n=3

  DO 1 j = n,1,-1
    l= k
    DO 2 i = n,j + 1,-1
       C(i) = C(i) + V(j)*M(l)
       l = l - 1           
2   enddo             
    C(j) = V(j)*M(k-n+j)
    k = k - (n-j+1)
1 enddo

我遇到的问题是我无法为 C(1) 生成和添加 2*B,为 C(2) 生成和添加 5*C。练习的目标是使用尽可能少的步骤和尽可能小的数组空间。

有什么建议吗?

【问题讨论】:

  • 我建议您从 doenddo 语句中删除(过时的)循环编号。如上所述,它们完全是多余的。如果您发现自己需要识别循环的开始和结束,现代方法是命名语句。
  • 请展示一个完整的程序,如果有一个完整的、可编译的代码可供查看和使用,它会使您更容易弄清楚您在做什么。您能否澄清“尽可能少的步骤和数组空间”,您的意思是尽可能少的操作和尽可能少的内存?

标签: fortran matrix-multiplication


【解决方案1】:

您的代码存在多个问题:

  • 在外循环中,您分配C(n)(可能是对角线条目),因此根本不使用内循环的计算
  • 您正在从后到前循环左下三角形,如果您反转它,矢量化矩阵内的索引会简单得多
  • 矩阵内部位置(kl)的计算错误
  • 您不计算镜像元素的乘积

这是我尊重以上几点的解决方案:

  ! Loop over all elements in the lower left triangle
  k = 0
  do j=1,n
    ! Increment the position inside the unrolled matrix
    k = k+1
    ! diagonal entries, i = j
    c(j) = c(j) + v(j)*M(k)

    ! off-diagonal entries
    do i=j+1,n
      ! Increment the position inside the unrolled matrix
      k = k+1
      ! Original entry
      c(i) = c(i) + v(j)*M(k)
      ! Mirrored one
      c(j) = c(j) + v(i)*M(k)
    enddo !i
  enddo !j

【讨论】:

  • 对于第一个循环,你从 i =0 开始?对于 c(i) = c(i) + v(i)*M(k) 并且 n 仍然等于 3 对吧?
  • 对不起,错字。应该是 j 而不是 i。固定的。最初,我明确设置了i=j。然后我决定把这个放到评论中
  • 真的很好!!通过该更正,循环后 C 数组的元素是正确的。
  • 你认为这个算法可以用于任意n大小的矩阵还是需要泛化?
  • @user3671704 如果它遵循相同的方案,那么是的 - 它是一个通用实现。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多