Search code examples
pythonregexwolfram-mathematicasymbolic-math

Detect missing multiplication in math expression


Given an expression such as

(exp(-((-mx + x - y)^2/(2 s1^2))2x - 2y (-my + y)^2/(2 s2^2)))/(2
pi sqrt(s1^2) sqrt(s2^2)

what is an easy way to detect all where multiply occurs? The above expression is uniquely defined. Variables cannot start with numbers and two variables multipled will always be separated by a space.

I.e. what regular expression (or other method) can be used to turn the above into

(exp(-((-mx + x - y)^2/(2*s1^2))*2*x - 2*y*(-my + y)^2/(2*s2^2)))/(2*
pi*sqrt(s1^2)*sqrt(s2^2)

Python or regex solution would be preferred.


Solution

  • First, you should clearly define the situations when to insert a * and when not to, to avoid changing, e.g., exp( to e*x*p*(. Now, create a few regular expressions matching those situations.

    patterns = [r"([0-9])\s*([a-z(])", # matches '2x', '2 x', or '2 ('
                r"([a-z])\s+([a-z])",  # matches 'x y', but not 'xy'
                r"([a-z])\s+(\()",     # matches 'x (', but not 'x('
                r"(\))\s*([0-9a-z(])"] # matches ')x', ')2', ') x', ') (', etc.
    

    Use re.findall to test those. Finally, you have to replace those patterns in the expression. You can use re.sub with a replacement r"\1*\2". Here,\1 and \2 are the groups matched in the pattern.

    expr = "(exp(-((-mx + x - y)^2/(2 s1^2))2x - 2y (-my + y)^2/(2 s2^2)))/(2pi sqrt(s1^2) sqrt(s2^2)"
    for p in patterns:
        expr = re.sub(p, r"\1*\2", expr)
    

    Afterwards, expr looks pretty much like the example in your question:

    (exp(-((-mx + x - y)^2/(2*s1^2))*2*x - 2*y*(-my + y)^2/(2*s2^2)))/(2*pi*sqrt(s1^2)*sqrt(s2^2)