Search code examples
pythonnumpyscipynumerical-integration

Numerical double integration of a function in python with a list of fixed variables


I am a little stuck on a function I am trying to numerically integrate through scipy, python.

For simplicity I will define the function as:

integral f(x,y)= SUM[double integral(ax+by)dxdy]

a and b are constants, but they are different for every equation that is integrated. I have integrated each function separately and then summed the result over all the integrals, however this takes significant time to calculate and it is not ideal for what I am attempting to achieve.

Is there a way to integrate the entire function at once by expanding the sum such that:

integral f(x,y)=double integral [(a1x+b1y)+(a2x+b2y)...(anx+bny)]dxdy 

then passing the function with a list of (a,b) tuples, etc to scipy's dblquad function?

I am struggling to find anything anywhere in the literature relating to this at the moment.

*EDIT

I have included an example code to show what it is I want to achieve a little more clearly:

import sys
import re
import math
from scipy.integrate import dblquad
def f((x,y),variables):
  V=0
  for v in variables:
    a,b=v
    V=V+ax+by
  return (V)

def integral(x_max,y_max,variables):

  return dblquad(f, 0, y_max, lambda x: 0, lambda x: x_max,args=variables)

def main():
  variables=[(1,2),(3,4),(5,6)] #example variables. The length of this list can change with the code I am running.
  x_max=y_max=1
  integral(x_max,y_max,variables)


if __name__ == '__main__':
  main()

The error that gets returned is thus:

Traceback (most recent call last):
  File "integration_example.py", line 23, in <module>
    main()
  File "integration_example.py", line 19, in main
    integral(x_max,y_max,variables)
  File "integration_example.py", line 14, in integral
    return dblquad(f, 0, y_max, lambda x: 0, lambda x: x_max,args=variables)
  File "/usr/lib/python2.7/dist-packages/scipy/integrate/quadpack.py", line 435, in dblquad
    return quad(_infunc,a,b,(func,gfun,hfun,args),epsabs=epsabs,epsrel=epsrel)
  File "/usr/lib/python2.7/dist-packages/scipy/integrate/quadpack.py", line 254, in quad
    retval = _quad(func,a,b,args,full_output,epsabs,epsrel,limit,points)
  File "/usr/lib/python2.7/dist-packages/scipy/integrate/quadpack.py", line 319, in _quad
    return _quadpack._qagse(func,a,b,args,full_output,epsabs,epsrel,limit)
  File "/usr/lib/python2.7/dist-packages/scipy/integrate/quadpack.py", line 382, in _infunc
    myargs = (x,) + more_args
TypeError: can only concatenate tuple (not "list") to tuple

Obviously the function doesn't like me passing a list of values to put into the integral in the way I have written this. Is there a way to do this? (sorry that's probably a better way of phrasing the question).


Solution

  • I'm not entirely sure, but it seems your bug is basically simply that you are referring to the argument you are passing as args to f as variables (which also should be a tuple, not a list). You should then unpack the unknown number of variables with *args. Try:

    import sys
    import re
    import math
    from scipy.integrate import dblquad
    def f(x,y,*args):
      V=0
      for v in args:
        a,b=v
        V=V+a*x+b*y
      return (V)
    
    def integral(x_max, y_max, variables):
      return dblquad(f, 0, y_max, lambda x: 0, lambda x: x_max, args=variables)
    
    def main():
      variables=((1,2),(3,4),(5,6)) #example variables. The length of this list can change with the code I am running.
      x_max=y_max=1
      integral(x_max,y_max,variables)
    
    
    if __name__ == '__main__':
      main()
    

    (Note also you need a*x, not ax.)