# monte_carlo_integral using already defined variable

hello, i have some function that i already defined, and i want to do monte carlo integral on in:

a,b,c = var('a,b,c')
c = 1
f = c*a*b
monte_carlo_integral(lambda a,b: f, [0,0], [3,3], 1000)


but i get many errors like "unable to simplify to float approximation". i understand that when using the lambda its different a,b than my previous a,b. and that this works:

a,b,c = var('a,b,c')
c = 1
monte_carlo_integral(lambda a,b: c*a*b, [0,0], [3,3], 1000)


but i have many calculations on f before doing the integral, so is there any way to make it work?

edit retag close merge delete

Sort by » oldest newest most voted

One doesn't need any symbolic variable to get a numerical integral :

sage: reset()
sage: %time monte_carlo_integral(lambda u,v:u*v, [0, 0], [3, 3], 1000000)
CPU times: user 119 ms, sys: 0 ns, total: 119 ms
Wall time: 119 ms
(20.25454841467989, 0.017863719435520488)


But do you really need a numerical integration ? Compare :

sage: reset()
sage: var("l_a, u_a, l_b, u_b")
(l_a, u_a, l_b, u_b)
sage: f(x,y)=x*y
sage: %time f(x,y).integrate(y, l_b, u_b).integrate(x, l_a, u_a).subs({l_a:0, l_b:0,u_a:3, u_b:3}) .n()
CPU times: user 21.9 ms, sys: 99 µs, total: 22 ms
Wall time: 21.1 ms
20.2500000000000


and the original result (81/4) is exact (if the symbolic ntegral can be found...)

more

well, as simple as it could be:

a,b,c = var('a,b,c')
c = 1
f = c*a*b
monte_carlo_integral(lambda new_a,new_b: f.subs({a: new_a, b: new_b}), [0,0], [3,3], 1000)


just replacing the old a,b with the new variables for the integral. (idk if its efficient or not)

more

Can you put the function part to a separate function? If you can, please try:

def f(a,b,c):
return c*a*b

a,b,c = var('a,b,c')
c = 1
monte_carlo_integral(f(a,b,c), [0,0], [3,3], 1000)

more