3

We are working on a big mathematical project with a lot of long equations and derivatives, which are produced by Wolfram Mathematica. We have more than 1000 very long equations.

Master program is written in Java and Mathematica is only used for generating equations. Our goal is to transform "Mathematica" form to "Java" form of equation. Then we can copy/paste generated code directly to "Java" code.

So for example we have short equation in Mathematica form:

Sqrt[((Cos[R]*X1 - X2)^2 + (Sin[R]*Y1 - Y2)^2)/S^2]/S

And we want to have it in Java form, so this is expected result:

Math.sqrt((Math.pow(Math.cos(R) * X1 - X2, 2) + Math.pow(Math.sin(R) * Y1 - Y2, 2)) / Math.pow(S, 2)) / S

Here is short python script, which manages some functions:

E = "Sqrt[((Cos[R]*X1 - X2)^2 + (Sin[R]*Y1 - Y2)^2)/S^2]/S"

E = E.replace("[", "(")              # Replaces Square brackets with normal brackets
E = E.replace("]", ")")              # Replaces Square brackets with normal brackets

E = E.replace("*", " * ")            # Add some spaces for easier reading
E = E.replace("/", " / ")            # Add some spaces for easier reading

E = E.replace("Cos", "Math.cos")     # Change "Mathematica" cos to "Java" cos
E = E.replace("Sin", "Math.sin")     # Change "Mathematica" sin to "Java" sin

E = E.replace("Sqrt", "Math.sqrt")   # Change "Mathematica" SQRT to "Java" SQRT

# Converting Power function is missing here... This is a must :)

print(E)

Above code produces:

Math.sqrt(((Math.cos(R) * X1 - X2)^2 + (Math.sin(R) * Y1 - Y2)^2) / S^2) / S

The problem is that we didn't find any solution for power function. We wanted to use python regex, but we cannot find any proper solution. The problem is that power function has to take everything within brackets, so for example:

(Math.cos(R) * X1 - X2)^2     >>>>    Math.pow(Math.cos(R) * X1 - X2, 2)

I hope that somebody has a quick and fancy solution. Otherwise I will need to take some time and write a long and "dirty" script, which will take care of this problem.

Thanks for your help :)

XOIOX
  • 164
  • 7
  • 2
    Regular Expressions aren't the right tool for nested values (like brackets within brackets may be e.g. `((x+1)^2 + 3)^4`. Have a look at some of the [**parsing**](https://stackoverflow.com/questions/37077052/changing-operator-to-power-function-using-parsing) libraries available in python, in order to deal with bracketed parts as individual units. – iacob Jul 11 '18 at 13:41
  • This is far from being perfect or "ready-to-use", but in my [codegen project](https://github.com/axkr/java_codegen) you can create a preprocessor, which can use [Symja](https://github.com/axkr/symja_android_library) to parse the math expressions. For converters search for `JavaForm`, `TeXForm` or `MathMLForm` in the [doc/functions](https://github.com/axkr/symja_android_library/tree/master/symja_android_library/doc/functions) folder. – axelclk Jul 24 '18 at 19:49

2 Answers2

1

Your regex search could be somethig like this:

import re

E = "(Math.cos(R) * X1 - X2)^2"

regex = re.compile(r'\((.*)\)\^(\d)')
match = regex.match(E)

new_E = "Math.pow(%s, %s)" % (match.group(1), match.group(2))

print(new_E)  # Math.pow(Math.cos(R) * X1 - X2, 2)

The way it works is by searching for anything inside parenthesis, followed by ^n, being n a digit from 0 to 9.

I hope you can adapt this to be as generalized as you need it to be.

Gabriel Jablonski
  • 854
  • 1
  • 6
  • 17
0

I tried something using mathematica's fullform[] function which turns a^b into Power[a,b]. Then I changed the Power[a,b] to some arbitrary function e.g PowerJ[a,b] using find and replace. Then I could change back to input stlye to return the formula to a form with has "*,+" etc. I was then able to use your code above to change the PowerJ[a,b] to Math.pow[a,b].