0

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).

2
  • Cannot you interchange sum and integration? Define one big integrand as a sum of all your integrands. Commented Sep 24, 2015 at 22:24
  • That is essentially what I am trying to do, however the constants a and b are generated from previous steps in the program and the number of (anx+bny) is also determined during the program, so I cannot define the exact function with the constants in place prior to running the programme. I will edit the post to include the code which reflects what I am trying to do... Commented Sep 25, 2015 at 8:55

1 Answer 1

1

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.)

Sign up to request clarification or add additional context in comments.

1 Comment

Thankyou for this. I've applied it to the situation and the code works well. Unfortunately it doesn’t make things any quicker in my case, but this is useful to know for the future.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.