Python: Integrating a function but getting large errors

Click For Summary

Discussion Overview

The discussion revolves around a Python coding issue related to integrating a Gaussian function using the SciPy library. Participants explore the implications of using random parameters within the integration function and the resulting errors encountered during computation.

Discussion Character

  • Technical explanation
  • Debate/contested
  • Mathematical reasoning

Main Points Raised

  • One participant shares their code for integrating a Gaussian function but reports large errors in the results, questioning the cause.
  • Another participant suggests that the use of random parameters within the integration function leads to undefined behavior, recommending that these parameters be defined outside the function.
  • A different participant elaborates on the challenges faced by numerical integrators when dealing with functions that incorporate randomness, indicating that this randomness complicates the integration process.
  • One participant clarifies their intention to generate a single Gaussian function with fixed random parameters for each run, aiming to integrate that specific function over a circular area.
  • After modifying the code based on suggestions, the original poster reports improvement in the integration results.

Areas of Agreement / Disagreement

Participants generally agree on the need to define random parameters outside of the integration function to achieve consistent results. However, there remains some uncertainty regarding the best practices for integrating functions that involve randomness.

Contextual Notes

Participants note that the integration process can be significantly affected by the nature of the function being integrated, particularly when it involves random elements, which may lead to large errors and longer computation times.

Who May Find This Useful

This discussion may be useful for individuals interested in numerical integration, particularly in the context of Python programming and the SciPy library, as well as those working with Gaussian functions and random parameters in computational applications.

MathewsMD
Messages
430
Reaction score
7
My code:
Python:
import numpy as np
import matplotlib.pylab as plt
import math
import random
from scipy import integrate

R1 = .001
R2 = 7

def G(r,theta):
    sigma = random.randint(4000., 7000.)/1000. # width of beam is 4 - 7mm
    r0 = random.randint(0, R1*1000.)/1000. #random centroid
    theta0 = random.uniform(0, np.pi*2) #angle
    return (100/(np.pi*2*sigma**2))*(np.e**(-((r**2 + r0**2 - 2*r*r0*(np.cos(theta)*\
    np.cos(theta0) + np.sin(theta)*np.sin(theta0)))/2*sigma**2)))*r # this r is here because the integrand is dr and dtheta, NOT dx and dy any longer!
#amplitude is 100

RTI = integrate.nquad(G, [[0,R2],[0,2*np.pi]]) #Integration

print RTI
I keep running this code, and everything seems to be working, but I keep getting results like: (0.1406360958428128, 0.012357271987783056)

Also, the code itself takes quite a while to run and I'm sure this is an indication of something...just not sure where it's going on. As you can see, the error is almost the value of integration itself, and this error is to large. I've been looking at the code but am not sure why such a large error is arising. If anyone has any ideas, it would be greatly appreciated!
 
Last edited by a moderator:
Technology news on Phys.org
I'm not sure what exactly you are trying to do. The integrate.nquad function will call the function G many times as it evaluates the integral. Each time it calls G, the parameters sigma, r0 and theta0 will have different values. So the value of the integral isn't really defined, because the function G is a different function each time it is called. I suspect that this isn't what you intend. You should probably move the random.randint calls outside of the G function and call them once to define sigma, r0 and theta0 before evaluating the integral. Does this make sense?
 
MathewsMD said:
Also, the code itself takes quite a while to run and I'm sure this is an indication of something...
It's an indication that the integrator is struggling.

A lousy numerical integrator might arbitrarily chop the space to be integrated into fixed size chunks, call the derivative function at each grid point, and apply some mathematical formulae to generate an estimate of the integral over than space. A better integrator will subdivide the space according to sensitivities revealed by calls to the derivative function.

Your derivative function involves random. A good integrator will detect that. What a good integrator won't do is detect that your derivative function (in the context of computer science) is not a "function" (in the context of mathematics). Any integrator must necessarily assume that the function to be integrated is indeed a function. You don't have a function. You have randomness.

As you can see, the error is almost the value of integration itself, and this error is to large.
What, exactly, are you trying to integrate?
 
phyzguy said:
I'm not sure what exactly you are trying to do. The integrate.nquad function will call the function G many times as it evaluates the integral. Each time it calls G, the parameters sigma, r0 and theta0 will have different values. So the value of the integral isn't really defined, because the function G is a different function each time it is called. I suspect that this isn't what you intend. You should probably move the random.randint calls outside of the G function and call them once to define sigma, r0 and theta0 before evaluating the integral. Does this make sense?

I have attached an image of what I am trying to do. Yes, you seem to get what I was attempting. I want to generate a single particular gaussian with the variables r0, theta0 and sigma0 randomly generated but held constant for that one run, then I want to integrate that one particular function over the circle. I would be creating numerous random gaussian functions like this.

I have modified the code a little bit based on your suggestions, and it seems to be working, but any input with regards to thingsto modify would be great!

Code:
Code:
RTIT = []

R1 = 4. #
R2 = 7. #

i = 0

    while i < 10:

    i = i + 1

    sigma0 = random.randint(4000., 7000.)/1000. # width is 4 - 7mm
    r0 = random.randint(0, R1*1000.)/1000. #random centroid
    theta0 = random.uniform(0, np.pi*2) #angle centroid makes with polar axis

    def G(r,theta): #this is the Gaussian
        return (100/(np.pi*2*sigma0**2))*(np.e**(-((r**2 + r0**2 \
        - 2*r*r0*(np.cos(theta)*np.cos(theta0) + \
        np.sin(theta)*np.sin(theta0)))/2*sigma0**2)))*r # this r is here because
#the integrand is dr and dtheta, NOT dx and dy any longer!
#intensity is 100

    RTI = integrate.nquad(G, [[0,R2],[0,2*np.pi]]) #Total
    RTIT.append(RTI)

print RTIT
 

Attachments

  • Photo on 2015-05-21 at 10.47 AM.jpg
    Photo on 2015-05-21 at 10.47 AM.jpg
    62.5 KB · Views: 508
Last edited by a moderator:
A couple of things:

If you enclose your code in
Code:
tags, then the code will be more readable.

Your code with the modifications looks good. Did it fix the large error problem you were initially having?
 
  • Like
Likes   Reactions: MathewsMD
phyzguy said:
A couple of things:

If you enclose your code in
Code:
tags, then the code will be more readable.

Your code with the modifications looks good. Did it fix the large error problem you were initially having?

Yep, it seems to be working great now. Thanks! I'll definitely use that from now on.
 

Similar threads

  • · Replies 3 ·
Replies
3
Views
2K
  • · Replies 3 ·
Replies
3
Views
2K
  • · Replies 5 ·
Replies
5
Views
2K
  • · Replies 5 ·
Replies
5
Views
3K
  • · Replies 7 ·
Replies
7
Views
2K
  • · Replies 5 ·
Replies
5
Views
3K
  • · Replies 6 ·
Replies
6
Views
2K
  • · Replies 1 ·
Replies
1
Views
2K
  • · Replies 3 ·
Replies
3
Views
2K
  • · Replies 3 ·
Replies
3
Views
3K