Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Errors in program for calculating integrals

Tags:

python

math

I am trying to calculate the area of a graph using integrals.

The user is supposed to give me 3 numbers:

  • x1, x2 – the bounds of the integral
  • N is in how many pieces the program will divide the function

However, I keep getting wrong results.

The first difficulty that I faced is that range accepts only integers.

Also z=(x2-x1)/N if I try and make it a float, I can't make it a step after, and I don't make it float it approaches to zero so Python shows me an error that the step is zero.

Also how can I summarize (z*(f(i)+f(i+z)/2)?

Here is my code:

# -*- coding: UTF-8 -*-
import math

def f(x) :
    y = (-1/6.0)*(x-1)*(x-2)*(x+2)*(x-4)
    return y 
x1=int(raw_input ('Δωστε το χ1 οπου αρχιζει η μετρηση του ολοκληρωματος \n ')) #greek letters
x2=int(raw_input ('Δωστε χ2 οπου θελετε να ολοκληρωνεται η μετρηση \n '))
N=int(raw_input('Δωστε τον αριθμο n που θα ειναι το πληθος \n των τραπεζιων που θα χρησιμοπιουνται στη προσσεγγιση  \n '))
z=(x2-x1)/N
for i in range(x1,x2,z):
    z=float(z)
    x1=float(x1)
    x2=float(x2)
    print (z*(f(i)+f(i+z))/2) 
like image 357
Giorgis3 Avatar asked Oct 20 '12 12:10

Giorgis3


2 Answers

You are reading x1, you cast it to an int (read: throw away information), then you cast it back to a float upon each iteration. The lost information will not reappear.

z=(x2-x1)/N

Because your value are integers, it will perform an integer division, i.e. if N > (x2 - x1), z will be zero. And since you always want to choose a large N, z will always be zero.

Thus, range() cannot not work.

What you need to do instead is read the inputs as floats:

number = float(raw_input("Please enter a number: "))

Note that applying float() repeatedly doesn't do anything useful. Thus, this code is not necessary:

for ...
    z=float(z)
    x1=float(x1)
    x2=float(x2)

Also how can i summarise the (z*(f(i)+f(i+z)/2)?

You can't make it shorter, since f() isn't a linear function.


Another thing about range() is, that the step parameter must be an integer.

You can easily create your own range function though:

def frange(start, stop, steps):
    x = start
    difference = float(stop - start)
    for step in range(0, steps):
        next_x = start + difference * (1 + step) / steps
        yield x, next_x - x
        x = next_x

Working code

# -*- coding: UTF-8 -*-
import math

def f(x) :
    y = (-1/6.0)*(x-1)*(x-2)*(x+2)*(x-4)
    return y 
x1 = float(raw_input ('Δωστε το χ1 οπου αρχιζει η μετρηση του ολοκληρωματος \n ')) #greek letters
x2 = float(raw_input ('Δωστε χ2 οπου θελετε να ολοκληρωνεται η μετρηση \n '))
N = int(raw_input('Δωστε τον αριθμο n που θα ειναι το πληθος \n των τραπεζιων που θα χρησιμοπιουνται στη προσσεγγιση  \n '))
result = 0
for x, delta_x in frange(x1, x2, N):
    result += delta_x * (f(x)+f(x+delta_x)) / 2
print result 
like image 88
phant0m Avatar answered Sep 20 '22 06:09

phant0m


  • Let x1, x2 and therefore the step size z be floats.
  • Instead of a for-loop, a while-loop may be easier here.

x1 = float(raw_input ('Δωστε το χ1 οπου αρχιζει η μετρηση του ολοκληρωματος \n ')) #greek letters
x2 = float(raw_input ('Δωστε χ2 οπου θελετε να ολοκληρωνεται η μετρηση \n '))
N = int(raw_input('Δωστε τον αριθμο n που θα ειναι το πληθος \n των τραπεζιων που θα χρησιμοπιουνται στη προσσεγγιση  \n '))
z = (x2-x1)/N
x = x1
while x < x2:
    print (z*(f(x)+f(x+z))/2)
    x += z
like image 38
unutbu Avatar answered Sep 23 '22 06:09

unutbu