Fortran Coder

标题: Fortran如何合并具有相同的性质的两列,并删除列 [打印本页]

作者: jiangweiwu    时间: 2022-7-22 16:00
标题: Fortran如何合并具有相同的性质的两列,并删除列
本帖最后由 jiangweiwu 于 2022-7-23 13:14 编辑

现在已知一个矩阵中所有的非零元素的行列值(u,v,a),但是这些行值与列值有重复的,如何将重复行列处的值相加,只保留一列,其余列都删除呢?

可以参见上传的图片,需要将两个圆圈处的a值相加,保留一个圈中的所有内容,剩下的另一个圈中的内容全部删掉。方框同理。最终变为下面的结果。

question.jpg (62.69 KB, 下载次数: 132)

question.jpg

question.jpg (60.74 KB, 下载次数: 138)

question.jpg

作者: zjk0112    时间: 2022-7-22 20:25
不知所云,你这和稀疏矩阵有啥关系啊。再说稀疏矩阵的稀疏格式又不是一种,coo,csr,csc,格式不一样三元组的含义不同。然后你稀疏矩阵不会和Fortran有啥关系啊。
作者: necrohan    时间: 2022-7-23 11:25
我感觉用forall或者where会比较简单,但是我对这两个的语法不熟
作者: jiangweiwu    时间: 2022-7-23 13:19
zjk0112 发表于 2022-7-22 20:25
不知所云,你这和稀疏矩阵有啥关系啊。再说稀疏矩阵的稀疏格式又不是一种,coo,csr,csc,格式不一样三元 ...

我可能没表达清楚。你看下我新上传的照片。我现在得到了三个一维数组(维度是7)分别是u,v,a,但是需要将u,v值相同时所对应的a值进行相加,并且只保留一组,即如图中所示,最后u,v,a的维度变为了5。
作者: li913    时间: 2022-7-24 19:03
你这个完全就是稀疏矩阵的操作,需要自己写代码实现。举例来说,如果想存为csr格式,就逐行处理。
!开辟一行的空间,假设处理第i行
real val(n)
val = 0
!判断是否为第i行数据
!获取数据列号 j
val(j) = val(j) + a

!统计第i行中非零数据的个数、列号、值,存入文件或其他空间
作者: zjk0112    时间: 2022-7-25 09:53
本帖最后由 zjk0112 于 2022-7-25 10:21 编辑
zjk0112 发表于 2022-7-22 20:25
不知所云,你这和稀疏矩阵有啥关系啊。再说稀疏矩阵的稀疏格式又不是一种,coo,csr,csc,格式不一样三元 ...

你想要两个5阶的矩阵相加?只是这两个矩阵是稀疏的。是这个意思不?
做加法就行了。就用到for循环就可以了。

A=[1,2,3,*,*
      *,3,4,5,*
      *,*,5,6,7
      *,*,*,7,8
      *,*,*,*,9]
对应的COO格式三元组(1-based)就是IA=(/1,1,1,2,2,2,3,3,3,4,4,5/),JA=(/1,2,3,2,3,4,3,4,5,4,5,5/),VA=(/1.0,2.0,3.0,3.0,4.0,5.0,5.0,6.0,7.0,7.0,8.0,9.0/)

B=[1,*,*,*,*
      *,2,*,*,*
      *,*,3,*,*
      *,*,*,4,*
      *,*,*,*,5]
对应的COO格式三元组 IB=(/1,2,3,4,5/) JB=(/1,2,3,4,5/) VB=(/1.0,2.0,3.0,4.0,5.0/)

A+B伪代码
!nnz为非零元个数,n为矩阵阶数,
n=5, nnzA=12, nnzB=5
do i=1, nnzA
    do j=1,nnzB
       if(IA(i)==IB(j) .and. JA(i)==JB(j)) then
       C(IA(i),JA(i)) = VA(i)+VB(j)
    end do
end do

我没理解错的,大概就这样呗,不难吧。有啥不会的呢?


作者: jiangweiwu    时间: 2022-7-26 17:00
zjk0112 发表于 2022-7-25 09:53
你想要两个5阶的矩阵相加?只是这两个矩阵是稀疏的。是这个意思不?
做加法就行了。就用到for循环就可以了 ...

首先谢谢你的代码。不过不是两个稀疏矩阵相加。是有u,v,a三个一维数组,只不过这其中的u,v有相同值得时候,对应的a需要相加。
我写的是代码
allocate(u(nnz),v(nnz),a(nnz))  写的是有限元的代码,
所以所有的非零元素都在一个(sumNode*ndf,sumNode*ndf)的二维数组中
allocate(K(sumNode*ndf,sumNode*ndf))

      do i = 1,nnz
          K(u(i),v(i)) = K(u(i),v(i)) + a(i)
      enddo




作者: zjk0112    时间: 2022-7-27 11:06
jiangweiwu 发表于 2022-7-26 17:00
首先谢谢你的代码。不过不是两个稀疏矩阵相加。是有u,v,a三个一维数组,只不过这其中的u,v有相同值得 ...

算的是刚度矩阵对吧。从我的角度来看,你的问题不出在稀疏矩阵和Fortran,你的有限元理论没弄清楚。你先弄局部刚度矩阵如何assemble到全局刚度矩阵,你的问题就有答案了。




欢迎光临 Fortran Coder (http://bbs.fcode.cn/) Powered by Discuz! X3.2