comp.lang.ada
 help / color / mirror / Atom feed
From: Gary Scott <scottg@flash.net>
Subject: Re: Help with translation: Fortran77 => Ada95
Date: Fri, 06 Jul 2001 01:35:21 GMT
Date: 2001-07-06T01:35:21+00:00	[thread overview]
Message-ID: <3B451735.22663AC8@flash.net> (raw)
In-Reply-To: jrT07.154340$%i7.102771899@news1.rdc1.sfba.home.com

Hi,

I guess I wasn't intending to start a competition to see how few
statements this could be written in.  I simply noted that the non-blank,
non-comment portion of the posted example was about twice as long as the
original, no big deal.  I also noted that significant improvements could
be made to the original.  Here's a minimalist update which only
eliminates the GOTOs.  At least it's more readable to me, if no one else
(not 100% guaranteed, certainly there's still lots of room for
improvement, a few opportunities for  whole or partial array
operations):

!
!        Input:  n - - the number of points in the Gaussian quadrature
!                      formula; type integer
!                alpha,beta - - arrays of dimension  n  to be filled
!                      with the values of  alpha(k-1), beta(k-1), k=1,2,
!                      ...,n
!                eps - the relative accuracy desired in the nodes
!                      and weights
!
!        Output: zero- array of dimension  n  containing the Gaussian
!                      nodes (in increasing order)  zero(k)=x(k), k=1,2,
!                      ...,n
!                weight - array of dimension  n  containing the
!                      Gaussian weights  weight(k)=w(k), k=1,2,...,n
!                ierr- an error flag equal to  0  on normal return,
!                      equal to  i  if the QR algorithm does not
!                      converge within 30 iterations on evaluating the
!                      i-th eigenvalue, equal to  -1  if  n  is not in
!                      range, and equal to  -2  if one of the beta's is
!                      negative.
!
! The array  e  is needed for working space.
!
subroutine gauss(n, alpha, beta, eps, zero, weight, ierr)

   implicit none

   integer, intent(in)    :: n                    !Automatic extent
   integer, intent(out)   :: ierr                 !Return code
   integer                :: ii, i, j, k, l, m    !Loop counters

   real, intent(in)       :: alpha(n), beta(n), eps
   real, intent(out)      :: zero(n), weight(n)
   real                   :: e(n), b, c, f, g, p, r, s, mml 
!Intermediates and workspaces

   if (n < 1) then  !Invalid extent
      ierr = -1
      return
   end if

   ierr = 0; zero = 0.0; weight = 0.0; e = 0.0 !Initialize

   zero(1) = alpha(1)

   if (beta(1) < 0.0) then
      ierr = -2
      return
   end if

   weight(1) = beta(1)

   if (n == 1) return

   weight(1) = 1.0

   do k = 2, n
      zero(k) = alpha(k)

      if (beta(k) < 0.0) then
        ierr = -2
        return
      end if

      e(k - 1) = sqrt( beta(k) )
      weight(k) = 0.0
   end do

   j = 0

   do l = 1, n

      do m = l, n           ! Look for a small subdiagonal element
         if (m == n) exit
         if (abs( e(m) ) <= eps * (abs( zero(m) ) + abs( zero(m + 1) )))
exit
      end do

      p = zero(l)

      if (m == l) then
         j = 0
         cycle
      end if

      if (j == 30) then !No convergence after 30 interations
         ierr = 1
         return
      end if

      j = j + 1
!
! Form shift
!
      g = (zero(l + 1) - p) / (2.0 * e(l))

      r = sqrt(g * g + 1.0)
      g = zero(m) - p + e(l) / (g + sign(r,g))

      s = 1.0
      c = 1.0
      p = 0.0

      mml = m - l
!
! For i=m-1 step -1 until l do ...
!
      do ii = 1, mml

         i = m - ii
         f = s * e(i)
         b = c * e(i)

         if (abs(f) < abs(g)) then
            s = f / g
            r = sqrt(s * s + 1.0)
            e(i + 1) = g * r
            c = 1.0 / r
            s = s * c
         else
            c = g / f
            r = sqrt(c * c + 1.0)
            e(i + 1) = f * r
            s = 1.0 / r
            c = c * s
         end if

         g = zero(i + 1) - p
         r = (zero(i) - g) * s + 2.0 * c * b
         p = s * r
         zero(i + 1) = g + p
         g = c * r - b
!
! Form first component of vector.
!
         f = weight(i + 1)
         weight(i + 1) = s * weight(i) + c * f
         weight(i) = c * weight(i) - s * f
      end do

      zero(l) = zero(l) - p
      e(l) = g
      e(m) = 0.0

   end do
!
! Order eigenvalues and eigenvectors.
!
   do ii = 2, n
      i = ii - 1
      k = i
      p = zero(i)

      do j = ii, n
         if (zero(j) >= p) cycle
         k = j
         p = zero(j)
      end do

      if (k >= i) cycle

      zero(k) = zero(i)
      zero(i) = p
      p = weight(i)
      weight(i) = weight(k)
      weight(k) = p
   end do

   do k = 1, n
      weight(k) = beta(1) * weight(k) * weight(k)
   end do

   return

end subroutine




tmoran@acm.org wrote:
> 
> >Interesting that it's almost exactly twice as long as the Fortran.
>   Would you prefer this version, shorter than the Fortran one?  I dropped
> the comments that just showed the original Fortran code, tightened up
> things that fit nicely on one line and didn't really need multiple lines,
> pretty printed, and did a few other "personal preference" changes.
> 

<snip>



-- 

Gary Scott
mailto:scottg@flash.net

mailto:webmaster@fortranlib.com
http://www.fortranlib.com

Support the GNU Fortran G95 Project:  http://g95.sourceforge.net



  reply	other threads:[~2001-07-06  1:35 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2001-07-04  9:19 Help with translation: Fortran77 => Ada95 N&J
2001-07-04 17:04 ` Warren W. Gay VE3WWG
2001-07-04 17:17 ` Colin Paul Gloster
2001-07-04 17:55 ` Jeffrey Carter
2001-07-05  1:33   ` Gary Scott
2001-07-05  6:03     ` tmoran
2001-07-06  1:35       ` Gary Scott [this message]
2001-07-05 17:36     ` Jeffrey Carter
2001-07-06  1:14       ` Gary Scott
2001-07-04 19:51 ` [SOLVED] " N&J
2001-07-04 23:25 ` GianLuigi Piacentini
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox