15. ºÎ ÇÁ·Î±×·¥ÀÇ ¹è¿­ (Arrays in subprograms)

Fortran ºÎÇÁ·Î±×·¥À» ºÎ¸¦ ¶§´Â call by reference¸¦ »ç¿ëÇÑ´Ù. ÀÌ´Â This means that the ºÎ ÇÁ·Î±×·¥À» ºÎ¸¦ ¶§ »ç¿ëÇÏ´Â ¸Å°³ º¯¼ö°¡ »ç¿ëÇÏ´Â ºÎ ÇÁ·Î±×·¥¿¡ ±×´ë·Î º¹»çµÇ´Â °ÍÀÌ ¾Æ´Ï¶ó ¸Å°³ º¯¼öÀÇ ÁÖ¼Ò addresses °¡ ³Ñ°Å°¡´Â °ÍÀÌ´Ù. ÀÌ·¸°Ô ÇÔÀ¸·Î½á º¯¼ö¸¦ ´Ù·ê ¶§ memory¸¦ Àý¾àÇÒ ¼ö ÀÖ´Ù. ºÎ ÇÁ·Î±×·¥¿¡¼­µµ ÁÖ ÇÁ·Î±×·¥ ¶Ç´Â ºÎ¸£´Â ÇÁ·Î±×·¥¿¡¼­¿Í °°Àº memory À§Ä¡¸¦ »ç¿ëÇϱ⿡ º°µµÀÇ ÀúÀå °ø°£ÀÌ ÇÊ¿äÇÏÁö ¾Ê´Ù. ±×·¯³ª ÇÁ·Î±×·¥ÇÏ´Â »ç¶÷À¸·Î¼­´Â À̸¦ ¾Ë°í °í·ÁÇÏ¿©¾ß ÇÑ´Ù.

Fortran ºÎ ÇÁ·Î±×·¥¿¡¼­ Áö¿ªÀûÀÎ(local) ¹è¿­À» ¼±¾ðÇÏ´Â °ÍÀÌ °¡´ÉÇÏÁö¸¸ Àß »ç¿ëÇÏÁö´Â ¾Ê´Â´Ù. º¸Åë ¸ðµç ¹è¿­Àº ÁÖ ÇÁ·Î±×·¥¿¡¼­ ±× Å©±â¿Í ÇÔ²² ¼±¾ðÇÏ°í ÇÊ¿äÇÑ ºÎ ÇÁ·Î±×·¥¿¡ ³Ñ°ÜÁø´Ù.

°¡º¯ ±æÀÌ ¹è¿­(Variable length arrays)

±âº»ÀûÀÎ vector ¿¬»êÀº saxpy ¿¬»êÀÌ´Ù. ÀÌ´Â
      y := alpha * x + y
·Î alpha´Â scalarÀÌ°í x¿Í y´Â vectorÀÌ´Ù. À̸¦ ±¸ÇöÇÑ °£´ÜÇÑ subroutineÀº ´ÙÀ½°ú °°´Ù.
      subroutine saxpy (n, alpha, x, y)
      integer n
      real alpha, x(*), y(*)
c
c Saxpy: Compute y := alpha*x + y,
c where x and y are vectors of length n (at least).
c
c Local variables
      integer i
c
      do 10 i = 1, n
         y(i) = alpha*x(i) + y(i)
   10 continue
c
      return
      end

¿©±â¼­ »õ·Î¿î °ÍÀº x(*) ¿Í y(*)ÀÇ ¼±¾ð¹®¿¡¼­ asterisk (*)¸¦ »ç¿ëÇÑ °ÍÀÌ´Ù. ÀÌ Ç¥½Ã´Â x¿Í y´Â ±æÀÌ°¡ ÀÓÀÇÀûÀÎ ¹è¿­À̶ó´Â ¶æÀÌ´Ù. ÀÌ °ÍÀÇ ÀåÁ¡Àº ÇϳªÀÇ ¼­ºê·çƾÀ¸·Î ¾î¶°ÇÑ ±æÀÌÀÇ vectorµµ ´Ù·ê ¼ö ÀÖ´Ù´Â °ÍÀÌ´Ù. FortranÀº call-by-reference¸¦ »ç¿ëÇϱ⿡ sburoutine¿¡¼­ Ãß°¡·Î memory °ø°£À» ¹èÁ¤Çϱ⺸´Ù´Â ºÎ¸£´Â routine/program¿¡¼­ Àü´ÞµÈ ¹è¿­ ¿ø¼Ò¿¡ Á÷Á¢ÀûÀ¸·Î ÀÛ¿ëÇÑ´Ù´Â °ÍÀ» ±â¾ïÇ϶ó. vector x¿Í y°¡ ´Ù¸¥ ÇÁ·Î±×·¥¿¡¼­ ±æÀÌ°¡ n ¶Ç´Â ±× ÀÌ»óÀ¸·Î ¼±¾ðµÇ¾úÀ½À» ȹÀÎÇÏ´Â °ÍÀº ÇÁ·Î±×·¥ÇÏ´Â »ç¶÷ÀÇ Ã¥ÀÓÀÌ´Ù. A common error in Fortran 77¿¡¼­ ÈçÈ÷ »ý±â´Â ¿À·ù´Â ¹è¿­ ¹ÛÀÇ ¿ø¼Ò¸¦ »ç¿ëÇÏ·Á°í ÇÒ ¶§ ¹ß »ýÇÑ´Ù.

¶Ç ¹è¿­À» ´ÙÀ½°ú °°ÀÌ ¼±¾ðÇÒ ¼öµµ ÀÖ´Ù.

      real x(n), y(n)
´ëºÎºÐÀÇ ÇÁ·Î±×·¥¸Ó´Â "½ÇÁ¦ ¹è¿­ ±æÀÌ"¸¦ ¸ð¸¥´Ù´Â °ÍÀ» °­Á¶Çϱâ À§ÇÏ¿© asterisk (*)¸¦ »ç¿ëÇϱâ ÁÁ¾ÆÇÑ´Ù. ¿À·¡µÈ Fortran 77 ÇÁ·Î±×·¥¿¡¼­´Â ´ÙÀ½°ú °°ÀÌ °¡º¯ ±æÀÌ ¹è¿­À» ¼±¾ðÇϱ⵵ ÇÑ´Ù.
      real x(1), y(1)
ÀÌ´Â ¹è¿­ÀÇ ±æÀÌ°¡ 1º¸´Ù Ŭ ¶§µµ À¯¿äÇÑ Ç¥ÇöÀÌ´Ù. ±×·¯³ª º°·Î ÁÁÀº Ç¥ÇöÀº ¾Æ´Ï±â¿¡ »ç¿ëÇÏÁö ¸» °ÍÀ» ±ÇÇÑ´Ù.

¹è¿­ÀÇ ÀϺθ¦ ³Ñ°ÜÁÖ±â (Passing subsections of arrays)

´ÙÀ½¿¡ matrix¿Í vecotrÀÇ °ö¼ÀÀ» ÇÏ´Â subroutineÀ» ½á º¸ÀÚ. ³»Àû(inner product)¸¦ »ç¿ëÇϰųª saxpy ¿¬»êÀÇ µÎ °¡Áö ¹æ¹ýÀÌ ÀÖ´Ù. moduleÈ­ Çϱâ À§ÇÏ¿© ¾Õ¿¡¼­ »ç¿ëÇÑ saxpy code¸¦ »ç¿ëÇϱâ·Î ÇÏÀÚ. °£´ÜÇÑ code´Â ´ÙÀ½°ú °°´Ù.
      subroutine matvec (m, n, A, lda, x, y)
      integer m, n, lda
      real x(*), y(*), A(lda,*)
c
c Compute y = A*x, where A is m by n and stored in an array
c with leading dimension lda.
c
c Local variables
      integer i, j
      
c Initialize y
      do 10 i = 1, m
         y(i) = 0.0
   10 continue

c Matrix-vector product by saxpy on columns in A.
c Notice that the length of each column of A is m, not n!
      do 20 j = 1, n
         call saxpy (m, x(j), A(1,j), y)
   20 continue

      return
      end
¾ð±ÞÇÏ¿©¾ß ÇÒ Á¡ÀÌ ¸î °³ ÀÖ´Ù. ù°, ÀÓÀÇÀÇ Â÷¿ø m°ú n¿¡ ´ëÇÏ¿© °¡´ÉÇϵµ·Ï ÀϹÝÀûÀÎ code¸¦ ¸¸µé¾úÁö¸¸ ¾ÆÁ÷µµ matrix AÀÇ leading Â÷¿øÀ» Àû¾î¾ß¸¸ ÇÑ´Ù. °¡º¯ ±æÀÌ ¼±¾ð (*)Àº ¹è¿­ÀÇ ¸¶Áö¸· Â÷¿ø¿¡¸¸ »ç¿ëÇÒ ¼ö ÀÖ´Ù. ±× ÀÌÀ¯´Â Fortran 77ÀÌ ´ÙÂ÷¿ø ¹è¿­À» ÀúÀåÇÏ´Â ¹æ¹ý ¶§¹®ÀÌ´Ù. (¹è¿­¿¡ °üÇÑ ³»¿ë ÂüÁ¶).

saxpy ¿¬»êÀ¸·Î y = A * x¸¦ °è»êÇÒ ¶§ AÀÇ columnÀÌ ÇÊ¿äÇÏ´Ù. AÀÇ j¹ø° columnÀº A(1:m,j)ÀÌ´Ù. ±×·¯³ª Fortran 77¿¡¼­´Â ÀÌ·¯ÇÑ ºÎ¹è¿­À» ³ªÅ¸³»´Â ¹æ¹ýÀ» »ç¿ëÇÒ ¼ö ¾ø´Ù (±×·¯³ª Fortran 90¿¡¼­´Â »ç¿ë °¡´ÉÇÏ´Ù). µû¶ó¼­ columnÀÇ Ã¹¹ø° ¿ø¼Ò A(1,j)¸¦ °¡¸®Å°´Â pointer¸¦ ÁغñÇÒ ÇÊ¿ä°¡ ÀÖ´Ù. (½ÇÁ¦·Î´Â pointer°¡ ¾Æ´ÏÁö¸¸ pointerÀÎ °Í ó·³ »ý°¢ÇÏ¸é µµ¿òÀÌ µÈ´Ù.) ´ÙÀ½ memory¿¡ ÀÌ columnÀÇ ´ÙÀ½ ¿ø¼Ò°¡ ÀÖ´Ù´Â °ÍÀ» ¾È´Ù. saxpy subroutine¿¡¼­´Â A(1,j)¸¦ vectorÀÇ Ã¹¹ø° ¿ø¼Ò·Î Ãë±ÞÇÏ°í ÀÌ vector°¡ matrixÀÇ ÇÑ columnÀÏ ¼öµµ ÀÖ´Ù´Â °ÍÀº ¾ËÁö ¸øÇÏ´Â °ÍÀÌ´Ù.

¸¶Áö¸·À¸·Î, m Çà n ¿­ÀÇ matrix¿¡ °üÇÑ Ç¥½Ã ¹æ¹ýÀ» µû¶ó¾ß ÇÑ´Ù. Áï index i ´Â Çà index·Î (1 to m), index j´Â ¿­ index (1 to n) »ç¿ëÇÑ´Ù. ´ëºÎºÐÀÇ ¼±Çü ´ë¼ö¸¦ ´Ù·ç´Â Fortran ÇÁ·Î±×·¥¿¡¼­´Â ÀÌ Ç¥±â ¹æ¹ýÀ» µû¸£°í ÀÖ¾î code¸¦ Àб⠽±´Ù.

´Ù¸¥ Â÷¿ø (Different dimensions)

°£È¤ ÀÏÂ÷¿ø ¹è¿­À» ÀÌÂ÷¿ø ¹è¿­·Î ȤÀº ±× ¹Ý´ë·Î Ãë±ÞÇÏ´Â °ÍÀÌ ÆíÇÒ ¼öµµ ÀÖ´Ù. ÀÌ´Â Fortran 77¿¡¼­´Â ¸Å¿ì °£´ÜÇÏ´Ù: ¾î¶² »ç¶÷Àº ³Ê¹« ½±´Ù¶ó°í ÇÒ °ÍÀÌ´Ù.

°£´ÜÇÑ ¿¹¸¦ »ìÆì º¸ÀÚ. ¶Ç ´Ù¸¥ ±âº»ÀûÀÎ vector ¿¬»êÀº scaling, Áï vectorÀÇ °¢ ¿ø¼Ò¿¡ °°Àº »ó¼ö¸¦ °öÇÏ´Â °ÍÀÌ´Ù. ´ÙÀ½Àº ÀÌ ¿¬»çÀ» ÇÏ´Â subroutineÀÌ´Ù.

      subroutine scale(n, alpha, x)
      integer n
      real alpha, x(*)
c
c Local variables
      integer i

      do 10 i = 1, n
         x(i) = alpha * x(i)
   10 continue

      return
      end
scaleÇÏ°íÀÚÇÏ´Â m x n matrix°¡ ÀÖ´Ù. »õ subroutineÀ» ¾²´Â ´ë½Å¿¡ vector¸¦ matrix·Î Ãë±ÞÇÏ°í subroutine scaleÀ» »ç¿ëÇÒ ¼ö ÀÖ´Ù. °£´ÜÇÏ°Ô´Â ´ÙÀ½°ú °°´Ù.
      integer m, n
      parameter (m=10, n=20)
      real alpha, A(m,n)

c Some statements here define A...

c Now we want to scale A
      call scale(m*n, alpha, A)
ÀÌ ¿¹Á¦´Â AÀÇ ¼±¾ðÇÑ Â÷¿øÀÌ A¿¡ ÀúÀåµÈ ½ÇÁ¦ Â÷¿ø°ú °°±â¿¡ ¹®Á¦°¡ ¾ø´Ù. ÀÌ°ÍÀÌ ÀϹÝÀûÀ¸·Î ¼º¸³ÇÏÁö´Â ¾Ê´Â´Ù. ¶§¶§·Î leading dimension lda°¡ ½ÇÁ¦ Â÷¿ø m°ú ´Ù¸£±â¿¡ À̸¦ ¿Ã¹Ù¸£°Ô ´Ù·ç·Á¸é ÁÖÀÇÇÏ¿©¾ß ÇÑ´Ù. ´ÙÀ½Àº subroutine scaleÀ» »ç¿ëÇÏ¿© matrix¿¡ »ó¼ö¸¦ °öÇÏ´Â Á»´õ È®½ÇÇÑ subroutineÀÌ´Ù.
      subroutine mscale(m, n, alpha, A, lda)
      integer m, n, lda
      real alpha, A(lda,*)
c
c Local variables
      integer j

      do 10 j = 1, n
         call scale(m, alpha, A(1,j) )
   10 continue

      return
      end
ÀÌ°ÍÀº ÇÑ ¹ø¿¡ ÇÑ column¾¿ °öÇÏ°í °¢ columnÀÇ Ã³À½ m°³ÀÇ ¿ø¼Ò¸¸ Ãë±ÞÇϱ⿡ (´Ù¸¥ °ÍÀº º¯ÇÏÁö ¾Ê´Â´Ù) mÀÌ lda¿Í °°Áö ¾Ê¾Æµµ µÈ´Ù.


Exercises

Exercise A
matrix A¸¦ ´ÙÀ½°ú °°ÀÌ ¼±¾ðÇÏ´Â main programÀ» ÀÛ¼ºÇ϶ó.
       integer nmax
       parameter (nmax=40)
       real A(nmax, nmax)
Àû´çÇÑ vector x¿Í y¸¦ ¼±¾ðÇÏ°í ´ÙÀ½°ú °°ÀÌ ÃʱâÈ­ Ç϶ó.
     m=10, n=20, A(i,j) = i+j-2 for 1<=i<=m and 1<=j<=n,
     x(j) = 1 for 1<=j<=n.
À§¿¡ ÁÖ¾îÁø matvec subroutineÀ» »ç¿ëÇÏ¿© y = A*x¸¦ °è»êÇ϶ó. °á°ú y¸¦ ÀμâÇ϶ó.

Exercise B
scalar product·Î y = A*x¸¦ °è»êÇÏ´Â subroutineÀ» ÀÛ¼ºÇ϶ó. j index¸¦ °¡Àå ¾ÈÂÊÀÇ loop¿¡¼­ »ç¿ëÇÏ¿©¾ß ÇÑ´Ù. ÀÛ¼ºÇÑ routineÀ» À§ Exercise AÀÇ ¿¹·Î °Ë»çÇÏ°í °á°ú¸¦ ºñ±³Ç϶ó.


[Fortran Tutorial]
Ãæ³²´ëÇб³ ¹°¸®Çаú ¿À º´¼º