Thanks so much for creating this functionality. I tested it on my expressions and it worked as expected.

When you have time I would love to learn a little more about the structure of how this works. Maybe it is just a mapping of your new items to "tree(ex)" elements. Not sure how I access them directly

Also, when I use it on terms like

a**2 h_{i j} A \phi \varphi

it knows not to transform the a**2 terms. That is correct. But I don't see in your code how it knows this. Also, a small issue in expressions like this is that you get

a**2 h_{i j}(k2) A(k3) \phi(k4) \varphi(k5) i.e. starts at k2 not k1, probably because of no k1 for a**2

Also, sometimes terms like \phi are converted to \phi(k1) in some my tests on your code, and sometimes not. As you will see in my code below I create a list of terms that should not be converted -- an easy addition.

Before I received your updated code I create this (long) bunch of procedures to parse through the Cadabra expression as a string and convert it to momentum space. Obviously your solution is much cleaner.

Thanks again.

Here is my code. I am sure it can be improved on (although there is no need at this point).

## Procedures to convert Cadabra Expression to Momemtum Space

## NoMom list contains items that are not to be transformed to momentum space

NoMom= ["XXXkappa","(XXXkappa)**(-2)","(a)**4", "(a)**2","a","XXXphi","(XXXphi)**2","V(XXXphi)", "V'(XXXphi)", "V''(XXXphi)", "V^{\prime\prime\prime}(XXXphi)","V^{\prime\prime\prime\prime}(XXXphi)", "\partial_{0}{XXXphi}"];

## Extract Numerical Coefficient and sign from term "ex"

## Variable ex is String form

def ExtNum(ex):

ex*num = re.findall("^\s**" + "[-]?" + "\s*" + "\d+" + ".?/?" + "\d*",ex)

if( len(exnum) == 0):

signcheck = re.findall("^\s*" + "[-]",ex)

if (len(signcheck) != 0):

ex_num = "-1"

else:

ex_num = "1"

return ex_num[0]

## Extract Derivative terms from "ex", returns " " if none

## Variable ex is String form

def ExtDer(ex):

ex*der = re.findall("\\partial*{[^(]*" + "\([^\(]*\)", ex)

if( len(ex*der) == 0):*

exder = " "

return ex_der[0]

## Parse String of Regular Non Derivative Terms creating list of subterms

## Variable ex is String form

def ParReg(ex):

reg*List = ex.split()*

for i in range(0,len(regList)):

if(i >= len(reg*List)-1):*

break

match = re.search("\{*\}",regList[i])

if( "{" in reg*List[i] and not match):*

regList[i] = reg*List[i] + " " + reg*List[i+1]

del reg*List[i+1]*

return regList

## Convert Regular terms to Momentum Space

## Variable ex is String form

def MomReg(ex,knum):

res = ex

if( ex not in NoMom):

res = ex + "(k" + str(knum+1) + ")"

knum = knum +1

return res,knum

## Convert Derivative terms to Momentum Space

## Variable ex is Cadabra form

## FIX counter for NoMom case

def MomDer(ex,knum):

ex*len = len(ex)*

kterm = " k" + str(knum+1)

termtmp = ""

for j in range(0,ex*len - 1):*

termtmp = term*tmp + "I " + kterm + "*{" + str(ex[j]) + "}"

if (str(ex[ex*len -1]) not in NoMom):*

termresult = term*tmp + " " + str(ex[ex*len-1]) + "(" + kterm + ")"

else:

term*result = term*tmp + " " + str(ex[ex*len-1]) *

return termresult

## Main procedure to convert Cadabra expression "exFull" to momentum space

## Fix for length of only one term

def ToMomem(exFull):

distribute(exFull)

expand_power(exFull)

substitute(exFull, $a a a a -> a**4, a a -> a**2$)

substitute(exFull,$\phi -> XXXphi, \varphi -> VVVV$)

result = Ex(0)

for i in range(0, len(exFull)):

term = str(exFull[i])

k*count =0*

subterm = str("")

num = ExtNum(term)

term = term.replace(num," ")

while ("\partial" in term):

divterm = ExtDer(term)

term = term.replace(div*term," ",1)*

if(divterm != " "):

subterm = " ".join([subterm, MomDer(Ex(div*term),k*count)])

k*count= k*count +1

regList = ParReg(term)

for j in range(0, len(regList)):

regList[j]

tmp = MomReg(regList[j],k*count)*

subterm = " ".join([subterm,tmp[0]])

kcount = tmp[1]

result = result + Ex(num + subterm)

substitute(result,$VVVV(A?) ->\varphi(A?), XXXphi -> \phi$,repeat = True)

return result