0

I have implemented the following logic and had asked this question for a different question (array range). I'm getting output but it is not going through for loop for the iteration because I have given frange(start, stop, range)

Explanation

"""Approximate definite integral of function from a to b using Simpson's method.
This function is vectorized, it uses numpy array operations to calculate the approximation.
This is an adaptive implementation, the method starts out with N=2 intervals, and try
successive sizes of N (by doubling the size), until the desired precision, is reached.
This adaptive solution uses our improved approach/equation for Simpson's method, to 
avoid unnecessary recalculations of the integrand function.

a, b - Scalar float values, the begin, and endpoints of the interval we are to
        integrate the function over.
f - A vectorized function, should accept a numpy array of x values, and compute the
      corresponding y values for all points according to some function.
epsilon - The desired precision to calculate the integral to.  Default is 8 decimal places
      of precision (1e-8)

returns - A tuple, (ival, error).  A scalar float value, the approximated integral of 
       the function over the given interval, and a scaler float value of the 
       approximation error on the integral
"""

Code:

import numpy as np
import matplotlib.pyplot as plt
import matplotlib
%matplotlib inline
import pylab as pl
def simpsons_adaptive_approximation(a, b, f, epsilon=1e-8):

    N_prev = 2 # the previous number of slices
    h_prev = (b - a) / N_prev # previous interval width
    x = np.arange(a+h_prev, b, h_prev) # x locations of the previous interval
    I_prev =  h_prev * (0.5 * f(a) + 0.5 * f(b) + np.sum(f(x)))

    # set up variables to adaptively iterate successively better approximations
    N_cur  = 2 # the current number of slices
    I_cur  = 0.0 # calculated in loop iteration
    error  = 1.0 # calculated in loop iteration
    itr    = 1 # keep track of the number of iterations we perform, for display/debug

    h = (b-a)/float(epsilon)
    I_cur = f(a) + f(b)

    while error > epsilon:
        for i in pl.frange(1,epsilon,1):
            print('Hello')
            if(i%2 ==0):
                print('Hello')
                I_cur = I_cur + (2*(f(a + i*h)))
            else:
                I_cur = I_cur + (4*(f(a + i*h)))

        error = np.abs((1.0/3.0) * (I_cur - I_prev))
        print("At iteration %d (N=%d), val=%0.16f prev=%0.16f error=%e" % (itr, N_cur, I_cur, I_prev, error) )
        I_cur *= (h/3.0)

        I_prev = I_cur
        N_prev = N_cur
        N_cur *= 2
        itr += 1

    return (I_cur, error)

Another function that calling above-mentioned function

def f2(x):
    return x**4 - 2*x + 1

a = 0.0
b = 2.0
eps = 1e-10
(val, err) = simpsons_adaptive_approximation(a, b, f2, eps)
print( "Calculated value: %0.16f  error: %e  for an epsilon of: %e" % (val, err, eps) ) 

Following is the outcome

At iteration 1 (N=2), val=14.0000000000000000 prev=7.0000000000000000 error=2.333333e+00
At iteration 2 (N=4), val=93333333333.3333435058593750 prev=93333333333.3333435058593750 error=0.000000e+00
Calculated value: 622222222222222295040.0000000000000000  error: 0.000000e+00  for an epsilon of: 1.000000e-10

It should give me more iteration

Can anyone help me to iterate over for loop get more result

Cris Luengo
  • 55,762
  • 10
  • 62
  • 120
Mayur Potdar
  • 451
  • 1
  • 8
  • 18
  • If I take indentation off for `I_prev = I_cur`, `N_prev = N_cur` , `N_cur *=2 `,`itr += 1` It goes infinite loop and if I keep it the same it gives me 3 iterations. @uneven_mark can you please help me out now? or anyone – Mayur Potdar Oct 19 '19 at 02:58
  • There's no "'Hello" in your output. This means that the loop `for i in pl.frange(1,epsilon,1)` never runs, and `I_cur` is never updated. What do you expect `frange` to return? (There's no documentation that Google knows about, but if it's similar to `range`, then you want to go from 1 to 1e-10 in steps of 1, which makes no sense.) – Cris Luengo Oct 19 '19 at 04:11
  • @CrisLuengo I know why I have used `Hello`, I was debugging my code and trying to check where it halts. and for `range` it gives me an error for float value that's why I have used `frange`. – Mayur Potdar Oct 20 '19 at 16:52
  • Not asking why you used `frange`, but asking what you expect it to do. It is not documented, so I don’t know what it is supposed to do. Try `numpy.arange` instead. In any case, it looks like your stop value is smaller than your start value, which would be the reason it doesn’t loop at all. What do you need that loop to do? – Cris Luengo Oct 20 '19 at 17:15
  • @CrisLuengo I was trying to iterate over the specified range and perform operations and `frange` was giving me a warning with the same result and `arange` was giving me without any warning with the same result. My point is why it's not going through the loop? – Mayur Potdar Oct 20 '19 at 17:46
  • @CrisLuengo hahaha!! you are right !! I'm working on it. If you figure out the correction in the code please do so. Thank you for your help – Mayur Potdar Oct 20 '19 at 18:42
  • 1
    Warnings are meant to help you find your bugs. If you get a warning, try to understand why so you can fix your code. Replacing the function call with a similar one that doesn’t give a warning doesn’t fix your code. Then you end up on here asking what is wrong with your code. If you had listened to that warning, your code would be working by now. – Cris Luengo Oct 20 '19 at 18:48

0 Answers0