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(ex_num) == 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):
ex_der = " "
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(reg_List)):
if(i >= len(reg_List)-1):
break
match = re.search("\{*\}",reg_List[i])
if( "{" in reg_List[i] and not match):
reg_List[i] = reg_List[i] + " " + reg_List[i+1]
del reg_List[i+1]
return reg_List

# 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)
term_tmp = ""

for j in range(0,ex_len - 1):
term_tmp = term*tmp + "I " + kterm + "*{" + str(ex[j]) + "}"

if (str(ex[ex_len -1]) not in NoMom):
term_result = term_tmp + " " + str(ex[ex_len-1]) + "(" + kterm + ")"
else:
term_result = term_tmp + " " + str(ex[ex_len-1])
return term_result

# 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):
div_term = ExtDer(term)
term = term.replace(div_term," ",1)
if(div_term != " "):

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]])
k_count = tmp[1]
result = result + Ex(num + subterm)
substitute(result,$VVVV(A?) ->\varphi(A?), XXXphi -> \phi$,repeat = True)
return result