Fortran Coder

标题: matrix乘法 [打印本页]

作者: kif117    时间: 2015-3-27 18:33
标题: matrix乘法
这个是写来‘玩’的,就是将两个matrix相乘,当然也可以改成加法减法除法...我不能说这个是十分规范的写法(比如最优化的),但是可以用。如果谁需要,就可以拿去用。也非常欢迎经验丰富的编程者加以修改!
[Fortran] 纯文本查看 复制代码
Program matrix 
     implicit none
     integer n
     parameter (n=16) ! remember setup dimension first!!!
       real:: a(n,n), b(n,n), c(n,n)
       open(11,status='unknown',file='c.DAT')
       read(11,*) c
       open(12,status='unknown',file='b.DAT')  
       read(12,*) b
     call matmul(a,b,n,n,c,n,n)
       write(*,*) 'Your new matrix looks like: '
     write(*,*)
       call output (a,n)
     write(*,*)
     stop
     end
       subroutine output (a,n)
       implicit none
     integer n
     real a(n,n)
     integer i,j
       character(len = 100) :: for = '(??(1X, F8.1))'  
       write (for(2:3), '(i2)') n
       do i=1,n
     write (*, fmt=for) (a(i,j), j=1,n)
       open(21,status='unknown',file='a.dat')  ! your result is here
       write(21,fmt=for) (a(i,j),j=1,n)
     enddo
     return
     end subroutine output
       subroutine matmul (a, b, br, bc, c, cr, cc)
     implicit none
     integer br  
     integer bc
     real b(br, bc)
     integer cr
     integer cc  
     real c(cr,cc)   
     real a(br,cc)
     integer i, j, k  
       if (bc .ne. cr) then
     write (*,*) 'size error :('
     stop
     endif
     do i=1, br
     do j=1, cc
     a(i,j)=0
     do k=1, bc
       a(i,j) = a(i,j) +b(j,k) * c(k,i)
       enddo
     enddo
     enddo
     return
     end


作者: fcode    时间: 2015-3-27 19:32
楼主,matmul 这6个字母高亮显示了,为什么呢?
作者: kif117    时间: 2015-3-27 19:46
fcode 发表于 2015-3-27 19:32
楼主,matmul 这6个字母高亮显示了,为什么呢?

我没有听懂您的问题。我只有用黑体字提示一下希望直接拿去用的人要记得设置‘dimension’和可以自行设定喜欢的‘result’文件名。matmul是一个subroutine的名字。如果我错误地在粘贴时按了哪个按钮,这是很可能的。

我还希望近期能够整理一个subroutine(并非全部原创)的合集,就是贴一些方便的可以直接加进去的sub,便于他人使用。
作者: 楚香饭    时间: 2015-3-27 19:51
在这个论坛,代码可以自动高亮。Fortran 语法内的函数和关键字都会自动高亮。

matmul 高亮显示了,说明这是一个语法内的函数。矩阵相乘是被语法支持的。

c = matmul( a , b ) 不需要写代码就能实现。

整理代码的合集,一直也是我们的愿望。楼主如果有好的代码,可以在主站投稿,审核以后就可以显示在主站了。

http://fcode.cn/contribute.php
作者: kif117    时间: 2015-3-27 20:00
楚香饭 发表于 2015-3-27 19:51
在这个论坛,代码可以自动高亮。Fortran 语法内的函数和关键字都会自动高亮。

matmul 高亮显示了,说明这 ...

原来是这样。我是第一次听说这件事,谢谢您告诉我!

我不会写‘太好’的程序,最多就是可以用而已,而且像第一个帖子那样,举例‘最优化’还很远。我用compaq visual fortran 1997-99的软件,平时只是自己写着‘玩儿’,是非常初级的‘初级玩家’。

如果整理好,我还是像这样发出来,请经验丰富的人修改好再发表,免得误导别人。如果您愿意,我也可以通过邮箱和短信发给您或fcode,请高手预览以后再贴出来给大家看。

谢谢!
作者: 楚香饭    时间: 2015-3-27 20:03
没事,你直接发论坛吧。有好东西,站长会转到主站去的。
作者: 楚香饭    时间: 2015-3-27 20:54
用 Module 可以很方便地使用函数(不需要传递数组大小)

[Fortran] 纯文本查看 复制代码
Module MatMulMod
  Implicit None
contains

  Function mat_mul(a, b) result( c )
    Real a(:,:) , b(:,:)
    Real c( size(a,dim=1) , size(b,dim=2) )
    Integer i, j, k
    c = 0.0
    Do i = 1, size(a,dim=1)
      Do j = 1, size(b,dim=2)
        Do k = 1, size(a,dim=2)
          c(i, j) = c(i, j) + a(i, k) * b(k, j)
        End Do
      End Do
    End Do
  End Function mat_mul
  
  Subroutine output(a)
    Real a(:,:)
    Integer i , n   
    Character (Len=100) :: for = '(??(1X, es13.6))'
    n = size( a , dim = 1 )
    Write (for(2:3), '(i2.2)') n
    !Open (21, Status='unknown', File='c.dat') ! your result is here
    Do i = 1, n
      Write (*, for) a(i,:)      
      !Write (21, for ) a(i,:)
    End Do
    !Close( 21 )
  End Subroutine output

End Module MatMulMod

Program matrix
  use MatMulMod
  Implicit None
  Integer n
  Parameter (n=2) ! remember setup dimension first!!!
  Real :: a(n, n), b(n, n), c(n, n)
  a = reshape([1,2,3,4],[2,2]) ; b=reshape([2,3,4,5],[2,2])
  !Open (11, Status='unknown', File='a.DAT')
  !Read (11, *) c
  !Open (12, Status='unknown', File='b.DAT')
  !Read (12, *) b
  c = mat_mul(a, b)
  Write (*, *) 'Your new matrix looks like: '
  Call output(c)
  c = matmul(a,b)
  Call output(c)
End Program matrix

作者: chiangtp    时间: 2015-3-29 10:57
1. 往事如煙, 緬懷昔日7766: matmul-1.pdf (342.36 KB, 下载次数: 22)
2. Triple-Loops, Efficiency of Memory Access: matmul-2.pdf (313.5 KB, 下载次数: 22) :

作者: kerb    时间: 2015-3-29 18:12
     do j=1, cc
         do i=1, br
             a(i,j)=0
                 do k=1, bc
                   a(i,j) = a(i,j) +b(j,k) * c(k,i)
                 enddo
         enddo
     enddo
45--52行,改成这样,试一下是不是更快,当然直接使用matmul应该更快




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