Use Python to integrate a function constructed in Mathematica

Click For Summary

Discussion Overview

The discussion revolves around the integration of a function defined in Mathematica using Python, specifically through Monte Carlo integration methods. Participants explore how to automate the process of importing Mathematica functions into Python and address challenges encountered during this integration.

Discussion Character

  • Technical explanation, Debate/contested, Exploratory

Main Points Raised

  • One participant shares a Python code snippet for Monte Carlo integration but questions how to import a Mathematica function to automate the integrand definition.
  • Another participant suggests using Mathematica's Export function to write expressions to a text file, which can then be read in Python using eval().
  • A participant encounters an error related to encoding a Mathematica expression as a Python literal and seeks further assistance.
  • Another response proposes converting the Mathematica expression using CForm and defining necessary functions in Python, including Bessel functions and trigonometric functions.
  • Concerns are raised about the repeated evaluation of constants in the Python code and the use of degrees instead of radians in the context of trigonometric functions.
  • A later reply clarifies the mathematical context, explaining that the function is part of a larger symbolic evaluation related to Green's functions and boundary conditions, and emphasizes the need for Monte Carlo integration due to issues with Mathematica's native methods.
  • The participant also defends the use of degrees for tracking angles, indicating a preference for this approach despite the potential for confusion with radians.

Areas of Agreement / Disagreement

Participants express differing views on the best methods for importing Mathematica functions into Python, with no consensus reached on the most effective approach. Additionally, there is disagreement regarding the use of degrees versus radians in the context of trigonometric functions.

Contextual Notes

Some participants note limitations in the Mathematica expressions that may not translate directly to Python, particularly regarding variable handling and the need for function definitions. There are also unresolved issues related to the accuracy and efficiency of the Monte Carlo integration method being implemented.

member 428835
Hi PF!

I followed someone's help on here and have the following code in python that performs monte carlo integration

Python:
from math import *
from random import *

def integrate(alpha):
    #  MONTE CARLO INTEGRATION OVER NON-RECTANGULAR DOMAINS
    def f(pt):
        # RETURN INTEGRAND AS FUNCTION
        x = pt[0]
        y = pt[1]
        return x*y**2

    def testRegion(pt):
        return (pt[0]/2 > pt[1])

    def genpoint():
        # GENERATE COORDINATES IN A SQUARE
        x = (1 - math.sin(alpha))*random() + math.sin(alpha)
        y = (1 - math.sin(alpha))*random() + math.sin(alpha)
        return (x,y)
    
    # INITIALIZE
    Sum = 0.0
    Area = (1 - math.sin(alpha))**2
    N = 0

    samp_pts = 10000
    int_dist = []
    iterations = 1000
    # INTEGRATION
    for _ in range(iterations):
        for i in range(samp_pts):
            N+=1
            pt = genpoint()
            if testRegion(pt):
                Sum += f(pt)

        sol = Sum*Area/N
        int_dist.append(sol)

    return int_dist

However, in line 10 we see the integrand is typed by a user. Is there a way to import a Mathematica function into python to automate the procedure? Thanks so much for your help!
 
Technology news on Phys.org
joshmccraney said:
However, in line 10 we see the integrand is typed by a user. Is there a way to import a Mathematica function into python to automate the procedure? Thanks so much for your help!
You can use Export["filename.txt", expression, "PythonExpression"] in mathematica to write to a textfile, and then read the file in python and use eval() in python to compute the results of the expressions.

https://reference.wolfram.com/language/ref/Export.html?view=all
 
Thanks for this. However, I'm getting the error "could not be encoded as a Python literal expression." Any ideas? The function looks like this:
Code:
(1/((1 + y)^2))1.60617 (1 - y)^2 (4 + y) BesselJ[4, 
  304.689 Sqrt[1 - x^2]] BesselJ[4, 304.689 Sqrt[1 - y^2]] Cosh[
  5.31755 (1 + (1 - x) Csc[\[Pi]/180])] Cosh[
  5.31755 (1 + (1 - y) Csc[\[Pi]/180])] (-(((4 - x) (1 + x)^2)/(
    120 (1 - x)^2)) + ((1 - x)^2 (4 + 
      x) (((4 - Cos[\[Pi]/180]) (1 + Cos[\[Pi]/180]))/(
      60 (1 - Cos[\[Pi]/180])^2) - (1 + Cos[\[Pi]/180])^2/(
      120 (1 - Cos[\[Pi]/180])^2) + ((4 - Cos[\[Pi]/180]) (1 + 
         Cos[\[Pi]/180])^2)/(
      60 (1 - Cos[\[Pi]/180])^3) - ((4 - Cos[\[Pi]/180]) (1 + 
         Cos[\[Pi]/180])^2 Cot[\[Pi]/180] Csc[\[Pi]/180])/(
      120 (1 - Cos[\[Pi]/180])^2)))/((1 + 
      x)^2 ((1 - Cos[\[Pi]/180])^2/(1 + Cos[\[Pi]/180])^2 - (
      2 (1 - Cos[\[Pi]/180])^2 (4 + Cos[\[Pi]/180]))/(1 + 
        Cos[\[Pi]/180])^3 - (
      2 (1 - Cos[\[Pi]/180]) (4 + Cos[\[Pi]/180]))/(1 + 
        Cos[\[Pi]/180])^2 - ((1 - Cos[\[Pi]/180])^2 (4 + 
         Cos[\[Pi]/180]) Cot[\[Pi]/180] Csc[\[Pi]/180])/(1 + 
        Cos[\[Pi]/180])^2)))
 
I'm Sorry, but it seems PythonExpression doesn't do variables.
You can convert your expression with CForm[expression], and you can insert the result in a python program. You must first define all functions that you might need. I've done all the functions that this one requires. I hope I have the right function for BesselJ
Python:
import math, scipy.special

Pi = math.pi

def Sqrt(x):
    return math.sqrt(x)

def Power(a,b):
    return a**b

def BesselJ(z,v):
    return scipy.special.jv(z,v)

def Cosh(x):
    return math.cos(x)

def Cos(x):
    return math.cosh(x)

def Csc(x):
    return 1/math.sin(x)

def Cot(x):
    return 1/math.tan(x)

def test(x,y):
    return (1.60617*Power(1-y,2)*(4+y)*BesselJ(4,304.689*Sqrt(1-Power(x,2)))*BesselJ(4,304.689*Sqrt(1-Power(y,2)))*Cosh(5.31755*(1+(1-x)*Csc(Pi/180.)))*Cosh(5.31755*(1+(1-y)*Csc(Pi/180.)))*(-0.008333333333333333*((4-x)*Power(1+x,2))/Power(1-x,2)+(Power(1-x,2)*(4+x)*(((4-Cos(Pi/180.))*(1+Cos(Pi/180.)))/(60.*Power(1-Cos(Pi/180.),2))-Power(1+Cos(Pi/180.),2)/(120.*Power(1-Cos(Pi/180.),2))+((4-Cos(Pi/180.))*Power(1+Cos(Pi/180.),2))/(60.*Power(1-Cos(Pi/180.),3))-((4-Cos(Pi/180.))*Power(1+Cos(Pi/180.),2)*Cot(Pi/180.)*Csc(Pi/180.))/(120.*Power(1-Cos(Pi/180.),2))))/(Power(1+x,2)*(Power(1-Cos(Pi/180.),2)/Power(1+Cos(Pi/180.),2)-(2*Power(1-Cos(Pi/180.),2)*(4+Cos(Pi/180.)))/Power(1+Cos(Pi/180.),3)-(2*(1-Cos(Pi/180.))*(4+Cos(Pi/180.)))/Power(1+Cos(Pi/180.),2)-(Power(1-Cos(Pi/180.),2)*(4+Cos(Pi/180.))*Cot(Pi/180.)*Csc(Pi/180.))/Power(1+Cos(Pi/180.),2)))))/Power(1+y,2)

print(test (0.2, 0.3))
 
  • Like
Likes   Reactions: member 428835
Python:
def test(x,y):
    return (1.60617*Power(1-y,2)*(4+y)*BesselJ(4,304.689*Sqrt(1-Power(x,2)))*BesselJ(4,304.689*Sqrt(1-Power(y,2)))*Cosh(5.31755*(1+(1-x)*Csc(Pi/180.)))*Cosh(5.31755*(1+(1-y)*Csc(Pi/180.)))*(-0.008333333333333333*((4-x)*Power(1+x,2))/Power(1-x,2)+(Power(1-x,2)*(4+x)*(((4-Cos(Pi/180.))*(1+Cos(Pi/180.)))/(60.*Power(1-Cos(Pi/180.),2))-Power(1+Cos(Pi/180.),2)/(120.*Power(1-Cos(Pi/180.),2))+((4-Cos(Pi/180.))*Power(1+Cos(Pi/180.),2))/(60.*Power(1-Cos(Pi/180.),3))-((4-Cos(Pi/180.))*Power(1+Cos(Pi/180.),2)*Cot(Pi/180.)*Csc(Pi/180.))/(120.*Power(1-Cos(Pi/180.),2))))/(Power(1+x,2)*(Power(1-Cos(Pi/180.),2)/Power(1+Cos(Pi/180.),2)-(2*Power(1-Cos(Pi/180.),2)*(4+Cos(Pi/180.)))/Power(1+Cos(Pi/180.),3)-(2*(1-Cos(Pi/180.))*(4+Cos(Pi/180.)))/Power(1+Cos(Pi/180.),2)-(Power(1-Cos(Pi/180.),2)*(4+Cos(Pi/180.))*Cot(Pi/180.)*Csc(Pi/180.))/Power(1+Cos(Pi/180.),2)))))/Power(1+y,2)

What is the point of repeatedly evaluating all those constants like ## 1 - \cos \frac{\pi}{180} ##? And you do realize that both Mathematica and Python work in radians and so 180 is completely meaningless in this context?

What are you actually trying to achieve?
 
Last edited by a moderator:
pbuk said:
Python:
def test(x,y):
    return (1.60617*Power(1-y,2)*(4+y)*BesselJ(4,304.689*Sqrt(1-Power(x,2)))*BesselJ(4,304.689*Sqrt(1-Power(y,2)))*Cosh(5.31755*(1+(1-x)*Csc(Pi/180.)))*Cosh(5.31755*(1+(1-y)*Csc(Pi/180.)))*(-0.008333333333333333*((4-x)*Power(1+x,2))/Power(1-x,2)+(Power(1-x,2)*(4+x)*(((4-Cos(Pi/180.))*(1+Cos(Pi/180.)))/(60.*Power(1-Cos(Pi/180.),2))-Power(1+Cos(Pi/180.),2)/(120.*Power(1-Cos(Pi/180.),2))+((4-Cos(Pi/180.))*Power(1+Cos(Pi/180.),2))/(60.*Power(1-Cos(Pi/180.),3))-((4-Cos(Pi/180.))*Power(1+Cos(Pi/180.),2)*Cot(Pi/180.)*Csc(Pi/180.))/(120.*Power(1-Cos(Pi/180.),2))))/(Power(1+x,2)*(Power(1-Cos(Pi/180.),2)/Power(1+Cos(Pi/180.),2)-(2*Power(1-Cos(Pi/180.),2)*(4+Cos(Pi/180.)))/Power(1+Cos(Pi/180.),3)-(2*(1-Cos(Pi/180.))*(4+Cos(Pi/180.)))/Power(1+Cos(Pi/180.),2)-(Power(1-Cos(Pi/180.),2)*(4+Cos(Pi/180.))*Cot(Pi/180.)*Csc(Pi/180.))/Power(1+Cos(Pi/180.),2)))))/Power(1+y,2)

What is the point of repeatedly evaluating all those constants like ## 1 - \cos \frac{\pi}{180} ##? And you do realize that both Mathematica and Python work in radians and so 180 is completely meaningless in this context?

What are you actually trying to achieve?
This is the product of two basis functions ##\phi## and a Green's function. The basis functions satisfy ##\nabla^2 \phi = 0## in the domain and and ##\phi_n = 0## on the boundary. Then it's evaluated along an arc. I do this all symbolically for the geometry of interest, so I'm not actually typing this stuff out. However, to get something PF can reiterate, I have to evaluate it.

At the end of the day I'm integrating this function over a triangular domain. Sometimes that integral has issues, so someone recommended I do Monte Carlo integration. The native MCI to Mathematica takes FOREVER and is sometimes inaccurate, so decided to make my own in python, per the guidance of another user. Issue here is importing this function into python. But, turns out it's not too bad.

And the 180 is not meaningless: the angle I specified was something like ##89 \pi/180##, so something like that. Degrees are easier for me to track than radians.
 

Similar threads

  • · Replies 8 ·
Replies
8
Views
2K
  • · Replies 15 ·
Replies
15
Views
2K
  • · Replies 18 ·
Replies
18
Views
2K
  • · Replies 16 ·
Replies
16
Views
2K
  • · Replies 1 ·
Replies
1
Views
3K
  • · Replies 50 ·
2
Replies
50
Views
6K
  • · Replies 5 ·
Replies
5
Views
4K
  • · Replies 1 ·
Replies
1
Views
2K
  • · Replies 7 ·
Replies
7
Views
5K
  • · Replies 1 ·
Replies
1
Views
5K