C_______________________________________________________________________________
C
C     Este programa calcula la raiz cuadrada de un numero a
C     mediante un metodo iterativo de primer orden
C_______________________________________________________________________________

      implicit real*8 (a-h,o-z)

	write(6,'(/a,$)') '  DATO           -> a      = '
      read(5,*) a
	write(6,'( a,$)') '  Valor Inicial  -> x      = '
      read(5,*) x
	write(6,'( a,$)') '  Err. Relativo  -> r      = '
      read(5,*) r
	write(6,'( a,$)') '  Err. Absoluto  -> e      = '
      read(5,*) e
	write(6,'( a,$)') '  No. Max. Iter. -> mxiter = '
      read(5,*) mxiter
      write(6,'()')

      call Raiz2(a,x,r,e,mxiter,niter)

      if (niter.le.mxiter) then
        write(6,'(//a,d24.16 )') '  SOLUCION       -> a^0.5  ~ ', x
        write(6,'(  a,   i24 )') '                    niter  = ', niter
        exact=sqrt(a)
	  write(6,'(  a,d24.16 )') '                    sqrt(a)= ', exact
        error=sqrt(a)-x
        write(6,'(  a,d24.16/)') '                    Error  = ', error
      else
        write(6,'(a)') '  Error: el metodo no ha convergido.'
      endif

      read(5,'()')

      end

C_______________________________________________________________________________
C
C     Subrutina Raiz2(a,x,r,e,mxiter,niter)
C
C        a      -> entrada: no. cuya raiz cuadrada se desea calcular
C        x      -> entrada: aproximacion inicial
C               -> salida:  solucion
C        r      -> entrada: tolerancia en error relativo entre iter. sucesivas
C        e      -> salida:  tolerancia en error absoluto entre iter. sucesivas
C        mxiter -> entrada: no. maximo de iteraciones permitidas
C        niter  -> salida:  no. de iteraciones realizadas
C                           [niter > mxiter => el proceso no ha convergido]
C
C     Se utiliza un metodo iterativo de primer orden
C_______________________________________________________________________________

      Subroutine Raiz2(a,x,r,e,mxiter,niter)
      implicit real*8 (a-h,o-z)

      niter=0
      write(6,'(a,i6,a,d24.16)') '  niter = ', niter,' -> x      = ',x

      do while (niter.lt.mxiter)
        z=(a+x*(10.d+00-x))/10.d+00   ! metodo iterativo de primer orden
        niter=niter+1
        ex=abs(x)*r
        if (e.gt.ex) ex=e
        dx=abs(z-x)
        x=z
        write(6,'(a,i6,a,d24.16)') '  niter = ', niter,' -> x      = ',x
        if (dx.lt.ex) return
      enddo

      niter=mxiter+1   ! se indica asi que el proceso no ha convergido
      return

      end