Mathematica and Form

Next page is Hilbert series computation.


In VS code, install Python.

https://blog.naver.com/chojjong/221228053941

Install WSL, connect to VS code.


Form

git clone https://github.com/vermaseren/form.git

xdg-open INSTALL

sudo apt-get install gcc

sudo apt install autoconf

(if something wrong, starts from here)

autoreconf -i

./configure

sudo apt-get install libgmp-dev
sudo apt-get install libmpfr-dev

웹기반 데이터 압축 라이브러리 zlib설치 > 강좌 | 클라우드포털 (linux.co.kr)

c++ - How to install GNU MP (GMP) in Codeblocks on Linux mint - Stack Overflow

cd sources

make clean

make

sudo make install

pip install python-form




LiE

tar zxvf conLiE.tar.gz

sudo apt install bison

sudo apt install libreadline-dev

sudo apt install lie


Keyword: 

5.8. Computing and decomposing characters 

5.8.1. The character polynomial




Combination

PE code (only use form)

import form

#PE[z_, t_, s_] = E^Sum[(2*Nf*csu2f[z^n]*t^n + csu2a[z^n]*s^n)/n, {n, 1, 12}] (before Haar)
Nf = '1'
Fun = 'x^1+x^-1'
Adj = 'x^2+x^0+x^-2'
Haa = 'x^-1-x^1'
Ord = '5'


# addterm = 2*Nf*csu2f[z^n]*t^n + csu2a[z^n]*s^n
#Actually not need FORM. Python is enough.
input1='''
    Symbols i,x,n,t,s;
    Local addterm = 2*Nf*(Fun)*t^n + (Adj)*s^n;
    id x^i? = x^(i*n);
    .sort
'''
input1=input1.replace("Fun",Fun)
input1=input1.replace("Adj", Adj)
input1=input1.replace("Nf", Nf)

with form.open() as f:
    f.write(input1)
    addterm=f.read('addterm')

print("addterm: ",addterm)


# P = Sum[(addterm)/n, {n, 1, 12}]
input2= '''
    Symbols n,x,t,s;
    Function F;
    On statistics;
    Local P = F(ord);
    repeat;
      id F(0) = 0;
      id F(n?) = F(n-1) + (addterm)/n;
    endrepeat;
    .sort
    '''

input2 = input2.replace("addterm", addterm)
input2 = input2.replace("ord", Ord)
           
with form.open() as f:
    f.write(input2)
    P=f.read('P')

print("P: ",P)


# PE = E^P (we have to insert cut in Exp.)
input3='''
    Symbols n,x,t,s;
    Function F;
    On statistics;
    Local PE = sum_(n,0,ord,(F(n))/fac_(n));
    repeat;
      id F(0) = 1;
      id F(n?) = F(n-1)*(PP);
    endrepeat;
    .sort
'''

input3 = input3.replace("PP",P)
input3 = input3.replace("ord", Ord)

with form.open() as f:
    f.write(input3)
    PE=f.read('PE')

print("PE: ",PE)

#order cut
input4='''
    Symbols j,k,x,t,s;
    Local cut = (PE)*t^(-ord)*s^(-ord);
    id t^j?pos_=0;
    id s^k?pos_=0;
    id t^j? = t^(j+ord);
    id s^k? = s^(k+ord);
    .sort
'''
input4 = input4.replace("PE",PE)
input4 = input4.replace("ord", Ord)

with form.open() as f:
    f.write(input4)
    cutPE=f.read('cut')

print("cutPE: ",cutPE)

#constant of (PE*Haa*x) (invariance)
input5='''
    Symbols x,s,t,n;
    Local H = (cutPE)*(Haa)*x;
    id x^n?pos_=0;
    id x^n?neg_=0;
    .sort
'''
input5 = input5.replace("cutPE",cutPE)
input5 = input5.replace("Haa",Haa)

with form.open() as f:
    f.write(input5)
    H=f.read('H')

print("H: ",H)
#Correct answer for Nf=1,ord=3: 1+s^2+t^2+3st^2-s^2t^2+4/3s^3t^2

This is slow than Mathematica. 

We have to inset cutting in E^P, but it is hard.


We can use another method.

In "P = Sum[(2*Nf*Fun(z^n)*t^n+Adj(z^n)*s^n)/n, {n,1,ord}]", 

We can decompose "Fun(z^n)" and "Adj(z^n)" to character polynomials. 

Then "P=Sum[(2*Nf*(C.P.s)*t^n+(C.P.s)*s^n)/n,{n,1,ord}]",

We have to compute "Exp(P)=Sum[(Sum[(2*Nf*(C.P.s)*t^n+(C.P.s)*s^n)/n,{n,1,ord}])^k/k!,{k,0,ord}]"


We swich this problem to combinatorial problem.

To get coefficient of "s^a*t^b", we select each term from "Sum[(2*Nf*(C.P.s)*t^n+(C.P.s)*s^n)/n,{n,1,ord}]". 

Then total number of terms is "(# of "a" partition)*(# of "b" partition)".

This is just origin of Plethystic exponent... nono, different. 

However, not using character form is more convenient.

$$Fun(a_i):=2N_f (z^{a_i}+z^{-a_i})$$

$$Adj(b_j):=(z^{2b_j}+1+z^{-2b_j})$$

$$(s^at^b\mbox{ coeff})=\sum_{\{a_i,b_j\}} \frac{1}{\prod n_{a_i}!\prod n_{b_i}!} \prod_{a_i} [Fun(a_i)]^{n_{a_i}}\prod_{b_j} [Adj(b_j)]^{n_{b_j}},$$ $$=\left[\sum_{\{a_i\}}  \prod_{a_i} \frac{[Fun(a_i)]^{n_{a_i}}}{n_{a_i}!}\right]\left[\sum_{\{b_j\}}  \prod_{b_j} \frac{[Adj(b_i)]^{n_{b_i}}}{n_{b_j}!}\right]$$ where $a_i$ and $b_j$ are partition of $a$ and $b$: $$\sum_{1\le i\le n_a} a_i=a,a_i\le a_{i+1},\ \sum_{1\le j\le n_b} b_j=b,b_j\le b_{j+1}$$ $n_{a_i}$ is defined by number of $a_i$ exists, which satisfies $$\sum_{a_i} n_{a_i}a_i=a,\quad \sum_{b_j} n_{b_j}b_j=b$$

Now we can compute this. $$\left[\sum_{\{a_i\}}  \prod_{a_i} \frac{[Fun(a_i)]^{n_{a_i}}}{n_{a_i}!}\right]$$ when $a_i$ is partition of $a$: $$\sum_{1\le i\le n_a} a_i=a,a_i\le a_{i+1}$$ and $n_{a_i}$ is defined by number of $a_i$ exists, which satisfies $$\sum_{a_i} n_{a_i}a_i=a$$



In mathematica code,

(*Define the polynomial function f in terms of z*)                                             
Clear[f];                                                                                                   
Nf := 2;                                                                                                   
f[x_, z_] := 2 Nf (z^x + z^(-x))/x;                                                                   
(*Define the factorial function*)                                                                    
Clear[factorial];
                                                                                         
factorial[n_Integer] := If[n > 0, n factorial[n - 1], 1];
                                          
(*Define the main computation function*)
                                                      
Clear[computeExpression];
                                                                          
computeExpression[a_Integer, z_] := 
                                                             
  Module[{partitions, nai, term, result}, 
                                                          
   partitions = IntegerPartitions[a];(*Generate all partitions of a*)                         
   result =(*Sum over all partitions*)(nai = Tally[#];
                                           
       term = 
                                                                                           
        Times @@ (f[First[#], z]^Last[#] & /@ nai)/
                                            
         Times @@ (factorial[Last[#]] & /@ nai); term) & /@ partitions;                  
   result];
                                                                                                 


For fundamental and antifundamental, mathematica code is here.

su4cfu[z1_, z2_, z3_] := z1 + z2/z1 + z3/z2 + 1/z3;                     
su4caf[z1_, z2_, z3_] := z3 + z2/z3 + z1/z2 + 1/z1;                     
su4cad[z1_, z2_, z3_] := su4cfu[z1, z2, z3]*su4caf[z1, z2, z3] - 1;     
su4h[z1_, z2_, z3_] :=                                                           
  1/(z1 z2 z3) (1 - z1^2/z2) (1 - z1 z2/z3) (1 - z1 z3) (1 -             
     z2^2/z1/z3) (1 - z2 z3/z1) (1 - z3^2/z2);                             
Nf := 4;                                                                            
fu[n_, z1_, z2_, z3_] := Nf su4cfu[z1^n, z2^n, z3^n]/n;                
af[n_, z1_, z2_, z3_] := Nf su4caf[z1^n, z2^n, z3^n]/n;                
ad[n_, z1_, z2_, z3_] := su4cad[z1^n, z2^n, z3^n]/n;                   
                                                                                     
(*Define the factorial function*)                                             
Clear[factorial];                                                                  
factorial[n_Integer] := If[n > 0, n factorial[n - 1], 1];                    
(*Define the main computation function*)                               
Clear[computeExpression];                                                   
computeExpression[a_Integer, f_, z1_, z2_, z3_] :=                       
  Module[{partitions, nai, term, result},                                    
   partitions = IntegerPartitions[a];(*Generate all partitions of a*)  
   result =(*Sum over all partitions*)(nai = Tally[#];                    
       term =                                                                    
        Times @@ (f[First[#], z1, z2, z3]^Last[#] & /@ nai)/          
         Times @@ (factorial[Last[#]] & /@ nai); term) & /@ partitions;
   result];                                                                        
                                                                                   
Clear[f];                                                                         
f[n_, m_, u_] :=                                                                
  Select[Select[                                                                
    Select[Expand[                                                             
      Total[computeExpression[n, fu, z1, z2, z3]]*                       
       Total[computeExpression[m, af, z1, z2, z3]]*                     
       Total[computeExpression[u, ad, z1, z2, z3]]*su4h[z1, z2, z3]* 
       z1 z2 z3], FreeQ[z3]], FreeQ[z2]], FreeQ[z1]];                    
f[4, 4, 11]                                                                       
LaunchKernels[];                                                              
DistributeDefinitions[computeExpression];                              
(*Create a parallel table of coefficients*)1 + s^2 +                  
 Total[Flatten[                                                                
   ParallelTable[                                                              
    f[n, m, u] t^n T^m s^u, {n, 1, 4}, {m, 1, 4}, {u, 1, 8}], 2]]      
CloseKernels[];                                                               

Python is to slow.


If we memorize IntegerPartition and polyniomial expand (before Select) for each partition or order, it will be faster. Let's try Python(CUDA), C++, FORM, Scalar.


Combination example

import subprocess
import form
import re

def run_lie_command(input_command):
    try:
        # lie 프로그램을 실행하고 사용자 입력을 전달
        result = subprocess.run(['lie'], input=input_command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True, universal_newlines=True)
       
        # 결과 반환
        if result.returncode == 0:
            return result.stdout.strip()
        else:
            # 에러 발생 시 stderr 출력
            print("lie 프로그램 실행 중 오류 발생:", result.stderr.strip())
            return None
    except Exception as e:
        print("오류 발생:", e)
        return None


# lie 명령어에 Lie group 입력 후 Cartan 행렬을 받아오기
Cartan_input = "Cartan(A1)"
Cartan_output = run_lie_command(Cartan_input)

# 결과 출력
if Cartan_output:
    print("Cartan 결과:", Cartan_output)


# lie 명령어에 Lie group 입력 후 Adjoint rep을 받아오기
Adjoint_input = "adjoint(A1)"
Adjoint_output = run_lie_command(Adjoint_input)

# 결과 출력
if Adjoint_output:
    print("Adjoint 결과:", Adjoint_output)


# lie 명령어에 polynomial 입력 후 character의 sum으로 받아오기
#1X[2]는 z^2+z^-2를 의미하며 결과는 z^2+z^-2=(z^2+1+z^-2)-1를 의미한다.
Char_decom_input = "v_decomp(1X[2],A1)"
Char_decom_output = run_lie_command(Char_decom_input)

# 결과 출력
if Char_decom_output:
    print("Char_decom 결과:", Char_decom_output)


# 'aX[b]'를 'a*x^b'로 바꾸기
Char_decom = re.sub(r'(\d+)X\[(\d+)\]', r'\1*x^\2', Char_decom_output)

print("Char_decom 결과:", Char_decom)


#form 실행
with form.open() as f:
    f.write(f'''
           
    Symbols x;
    Local decomp = {Char_decom};
           
    ''')
    form_result=f.read('decomp')

print("form 결과: ", form_result)


0703514.pdf (arxiv.org)


Reference

LIE

Form

Form manual

Python-form

LiE manual