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
a2 h_{i j}(k2) A(k3) \phi(k4) \varphi(k5) i.e. starts at k2 not k1, probably because of no k1 for a2
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):
exder = 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 = termtmp + "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 -> a4, a a -> a2$)
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