Method of finding roots of a function in Fortran

2

I have created a code that uses 3 methods to determine the roots of a function, the direct method of kicking values of x, Newton-Raphson and secants. In the direct method, I set values of x close to the roots, and I used the while to add increments of 0.1 to these values until the time the function changed signal, a proximity situation of f (x) = 0. Only as a result, my program is uniquely within those of the while and does not run the rest. Here is my code

  program raizes
     implicit none
     integer n, i           !escolha dos chutes iniciais para cada raiz
     real*8, parameter :: r1=-3.d0/10.d0,r2=1.d0/10.d0,r3=4.d0/10.d0
     real*8 r1d, r2d, r3d, xd !novos valore de x a serem testados no
                               !método direto
     real*8 r1_nr, r2_nr, r3_nr, nr1, nr2, nr3 !variáveis do método 
                                               !Newton-Raphson
     real*8 r1_si,r2_si,r3_si,r1_s,r2_s,r3_s,sec1,sec2,sec3 !variáveis do
                                        !método das secantes
     read(*,*)n
     open(10,file="tab3_out.dat")
     xd = 0.d0
     do i = 0, n-1
     !Método Iteração direta
        xd =xd + 1.d0/10.d0 !incremento do chute inicial do método direto
        do while (f(r1d).ge.0.d0) !situação em que a função quase muda 
                                  !de sinal
           r1d = r1 - xd !como a raíz está em -0.5, o r1 deve ser 
                         !diminuído
        end do
        do while (f(r2d).ge.0.d0)
           r2d = r2 + xd !como a raíz está em 0.33,o r2 deve ser   
                       !aumentado        
        end do
        do while (f(r3d).le.0.d0)!situação em que a função está quase 
                                 !mudando de sinal
           r3d = r3 + xd !como a raíz está em 0.66, o r3 deve ser 
                         !aumentado
        end do
     !Método Newton-Raphson (N-R)
        r1_nr = r1 !----------valores iniciais de x
        r2_nr = r2
        r3_nr = r3
        nr1 = r1_nr - f(r1_nr)/df(r1_nr) !equação de N-R
        nr2 = r2_nr - f(r2_nr)/df(r2_nr) !equação de N-R
         nr3 = r3_nr +f(r3_nr)/df(r3_nr) !equação de N-R
        r1_nr = nr1 !alterando os valores iniciais de x para a 
        r2_nr = nr2 !próxima iteração
        r3_nr = nr3
     !Método Secante
        r1_si = -2.d0/10.d0 !valores xi-1 na equação do método da secante
        r2_si =  0.d0
        r3_si =  3.d0/10.d0
        r1_s = r1           !valores xi na equação
        r2_s = r2
        r3_s = r3
        sec1 = r1_s - f(r1_s)*(r1_s - r1_si)/(f(r1_s)-f(r1_si)) !fórmula
                                                    !método das secantes
        sec2 = r2_s - f(r2_s)*(r2_s - r2_si)/(f(r2_s)-f(r2_si))
        sec3 = r3_s - f(r3_s)*(r3_s - r3_si)/(f(r3_s)-f(r3_si))
        r1_si = r1_s  !alterando os valores de xi-1 e xi para a próxima 
                       !iteração
        r2_si = r2_s
        r3_si = r3_s
        r1_s = sec1
        r2_s = sec2
        r3_s = sec3
        write(10,*) i,r1d,r2d,r3d,nr1,nr2,nr3,sec1,sec2,sec3
     end do
     close(10)

     contains !----------definições da função e de sua derivada
        real*8 function f(x)
     real*8 x
          f = 18.d0*(x**3.d0)-9.d0*(x**2.d0)-5.d0*x+2.d0
     end function f

     real*8 function df(x)
     real*8 x
          df = 54.d0*(x**2.d0)-18.d0*x-5.d0
     end function df
  end program raizes

I'd like a suggestion to solve this while.

    
asked by anonymous 29.04.2017 / 23:13

2 answers

0

I could not resolve the problem with while, so I used only if and else. It was thus part of the direct method.

  program direto
     implicit none
     integer n, i
     real*8, parameter :: r1=-3.d0/10.d0,r2=1.d0/10.d0,r3=4.d0/10.d0
     real*8 r1d,r2d,r3d, xd, raiz_1,raiz_3,raiz_2
     read(*,*)n
     !método iteração direta
     xd = 0.d0
     do i = 0, n-1
        xd =xd + 1.d0/5.d0
        if(f(r1d).ge.0.d0)then
           r1d = r1 - xd
        else
           raiz_1 = r1d
        end if
        if (f(r2d).ge.0.d0) then
           r2d = r2 + xd
        else
           raiz_2 = r2d
        end if
        if (f(r3d).ge.0.d0) then
           r3d = r3 + xd
        else
           raiz_3 = r3d
        end if
        write(*,*)i, raiz_1, raiz_2, raiz_3
     end do

     contains
        real*8 function f(x)
        real*8 x
            f = 18.d0*(x**3.d0)-9.d0*(x**2.d0)-5.d0*x+2.d0
     end function f
  end program direto
    
30.04.2017 / 23:27
0

I think you need to initialize the values of r1d , r2d and r3d before using them on the first call of f(r1d) . If you do not do so, the initial values of these variables will be assigned by the system, ie you can not predict or have control. So your role may behave unexpectedly.
If you initialize them with 0.0, or with the values of r1 , r2 and r3 , I think it solves the problem in the first version of the code (without if / else).

    
22.08.2017 / 23:35