hopfinvariant7455
hopfinvariant7455

Reputation: 21

Problems with an exponential taylor series

I'm having problems with accurately running this code, the code compiles correctly but for every value I enter for inputsin, I will always receive 1.0 as an answer.

The taylor series for the exponential will start at one by defintion. It's possible my factorial implementation is incorrect, but any editing of the factorial loop renders what seems to be an infinite loop.

program taylor
    implicit none
    real :: inputexp, inputsine  ! The values of input for the arguments of the taylor series
    real :: exptaylor, sinetaylor ! The value of the sine and exponential calculated
    real :: expseries, sineseries ! The value found by the taylor series
    real, parameter :: accuracy = 1.e-10  ! The value of accuracy
    integer :: NN, aa, bb, cc, dd, ee, ff, gg, hh ! Loop indices and factorial things
    integer:: nfactexp ! Factorial for the exponential series
    integer :: Nexp ! Number of turns
    write(*,*) "Write the value of the input of the exponential taylor series"
    read(*,*) inputexp


    ! Calculating the exponential function using taylor series
     exptaylor = 1 ! Initializing the exponential function taylor arguemnts


    ! Loop to calculate the exponential function
    aa = 0
    do while(abs(exptaylor) > accuracy)

        ! Computing factorial
        nfactexp = 1 ! Accounting for 0!=1
        do bb = 1, aa
            nfactexp = nfactexp*bb
        enddo
        ! Evaluating the series
        aa = aa+1
        exptaylor = (inputexp**aa)/nfactexp
        expseries = exptaylor + expseries


        enddo

        Write(*,*) "The number of terms of the series, N", aa
        Write(*,*) "The value of the exponential according to the taylor series", expseries
    end program

Upvotes: 0

Views: 282

Answers (1)

rtoijala
rtoijala

Reputation: 1209

You have several problems.

First of all, you are not initializing expseries. You should set it before the loop. Right now, the result is completely arbitrary, since the initial value of expseries is undefined.

Second, your variable nfactexp is overflowing. 32-bit integers, which you probably are using, only allow numbers up to 2 147 483 647. Also, (inputexp**aa) can overflow. While you cannot fix overflows for all inputs using a finite amount of bits, you can extend the computable area. By computing each expterm using the last one, as expterm = expterm / aa * inputexp, you can get the largest range.

The change above also means that you no longer redundantly compute factorial terms, and reduces the exponentiation to a multiplication, making the code faster, too.

Also, the abs on the while-loop condition is unnecessary, since expterm is always non-negative.

See the code below:

program taylor
    implicit none
    real :: inputexp, exptaylor, expseries
    real, parameter :: accuracy = 1.0e-10
    integer :: aa

    write(*,*) "Write the value of the input of the exponential taylor series"
    read(*,*) inputexp

    exptaylor = 1  ! The first term is constant
    expseries = 1  ! The first term is already included
    aa = 0  ! Term index, i.e. 0 for the constant

    do while (exptaylor > accuracy)
        aa = aa + 1

        ! Use the previous value of exptaylor.
        ! Just scale it with the one more inputexp to get the x**n
        ! correct, and divide by aa for the factorial.
        exptaylor = exptaylor / aa * inputexp

        expseries = exptaylor + expseries
    enddo

    Write(*,*) "The number of terms of the series, N", aa
    Write(*,*) "The value of the exponential according to the taylor series", expseries
end program

Upvotes: 2

Related Questions