大阪大学医学部 Python会

Now is better than never.

非可換ゲージ理論の頂点計算機

2022-09-04(Sun) - Posted by 河村 in 技術ブログ    tag:Python

Contents

    非可換ゲージ理論の頂点計算をする.添字は全て下に付ける仕様.

    In [22]:
    import sympy
    

    縮約を計算する.入力は[coeff, momentum or metric, ...]のリスト

    In [23]:
    def calculate_contract(input):
        # input: [coeff, momentum or metric, ...]
        coeff = input.pop(0)
    
        # get metrics and momentums from input
        metrics = []
        momentums = []
        for i in input:
            if i[0:1] == 'g':
                str = i[4:-1]
                first_index_abr = str.split('\\')[0][0]
                second_index_abr = str.split('\\')[1][0]
                metrics.append('g_' + first_index_abr + second_index_abr)
            else:
                momentums.append(i[0:2] + i[3])
        input_abr = [coeff] + metrics + momentums
    
        # define dict of metrics {'original_key': [current index, current index], ...}
        metrics_dict = {}
        for i in metrics:
            metrics_dict[i] = [i.split('_')[1][0], i.split('_')[1][1]]
    
        # define dict of momentums {'original_key': [label, current index], ...}
        momentums_dict = {}
        for i in momentums:
            momentums_dict[i] = i.split('_')
    
        # get indices of metrics
        metrics_indices = []
        for i in range(len(metrics)):
            metrics_indices.append(metrics[i].split('_')[1][0])
            metrics_indices.append(metrics[i].split('_')[1][1])
    
        # get indices of momentums
        momentums_indices = []
        for i in range(len(momentums)):
            momentums_indices.append(momentums[i].split('_')[1])
    
        # find true and dummy indices
        all_indices = metrics_indices + momentums_indices
        summing_indices = []
        tensor_indices = []
        for i in all_indices:
            if all_indices.count(i) == 2:
                summing_indices.append(i)
            elif all_indices.count(i) >= 2:
                print(i, 'too many !')
            else:
                tensor_indices.append(i)
        summing_indices = list(set(summing_indices))
    
        # sum over dummy indices
        for i in summing_indices:
            if metrics_indices.count(i) == 1:
                # vector and metric
                metric_at = int(metrics_indices.index(i) / 2)
                momentum_at = momentums_indices.index(i)
                contracting_metric = metrics[metric_at]
                contracting_momentum = momentums[momentum_at]
                another_index = metrics_dict[contracting_metric]
                another_index.remove(i)
                metrics_dict[contracting_metric] = []
                metrics_indices[2*metric_at] = ''
                metrics_indices[2*metric_at + 1] = ''
                momentums_dict[contracting_momentum] = [contracting_momentum[0], another_index[0]]
                momentums_indices[momentum_at] = another_index[0]
                # print(str('\u03A3' + i + ':'), contracting_metric, contracting_momentum, '->', str(contracting_momentum[0]+ '_'+ another_index[0]))
            elif metrics_indices.count(i) == 2:
                # metric and metric
                metrics_loc = [j for j, x in enumerate(metrics_indices) if x == i]
                first_metric_at = int(metrics_loc[0] / 2)
                second_metric_at = int(metrics_loc[1] / 2)
                first_contracting_metric = metrics[first_metric_at]
                second_contracting_metric = metrics[second_metric_at]
                if first_metric_at == second_metric_at: # g_ss = 4
                    metrics_dict[first_contracting_metric] = [4]
                    # print(str('\u03A3' + i + ':'), metrics[first_metric_at], '-> 4')
                    metrics_indices[2*first_metric_at] = ''
                    metrics_indices[2*first_metric_at + 1] = ''
                else:
                    first_another_index = metrics_dict[first_contracting_metric]
                    first_another_index.remove(i)
                    second_another_index = metrics_dict[second_contracting_metric]
                    second_another_index.remove(i)
                    metrics_dict[first_contracting_metric] = [first_another_index[0], second_another_index[0]]
                    metrics_indices[2*first_metric_at] = first_another_index[0]
                    metrics_indices[2*first_metric_at + 1] = second_another_index[0]
                    metrics_dict[second_contracting_metric] = []
                    metrics_indices[2*second_metric_at] = ''
                    metrics_indices[2*second_metric_at + 1] = ''
                    # print(str('\u03A3' + i + ':'), metrics[first_metric_at], metrics[second_metric_at], '->', str('g_' + first_another_index[0] + second_another_index[0]))
            else:
                # vector and vector
                momentums_loc = [j for j, x in enumerate(momentums_indices) if x == i]
                first_momentum_at = momentums_loc[0]
                second_momentum_at = momentums_loc[1]
                first_contracting_momentum = momentums[first_momentum_at]
                second_contracting_momentum = momentums[second_momentum_at]
                momentums_dict[first_contracting_momentum] = [momentums_dict[first_contracting_momentum][0] + momentums_dict[second_contracting_momentum][0], '']
                momentums_dict[second_contracting_momentum] = []
    
        # concatenate dictinoaries
        output = [coeff]
        for i in metrics_dict.values():
            if i == [4]:
                output.append('4')
            elif i != []:
                output.append('g_' + i[0] + i[1])
        for i in momentums_dict.values():
            if i != []:
                if i[1] == '':
                    output.append(i[0])
                else:
                    output.append(i[0] + '_' + i[1])
    
        # print(' '.join(input_abr) , '=', ' '.join(output))
        return output
    

    運動量文字とLorentz添字から4運動量の成分を返す: $$ k, \mu \to k_\mu . $$

    In [24]:
    def mo(momentum, index_abr):
        if momentum != 0:
            terms = list(sympy.Add.make_args(momentum))
            momentum_indexed = 0
            for i in range(len(terms)):
                term_indexed = str(terms[i]) + '_' + index_abr
                term_indexed = sympy.sympify(term_indexed, globals())
                momentum_indexed += term_indexed
            return momentum_indexed
        else:
            return 0
    

    運動量文字とLorentz添字から3-boson頂点を返す: $$ \mu, \nu, \rho, k, p, q \to g_{\mu\nu} (k-p)_\rho + g_{\nu\rho} (p-q)_\mu + g_{\rho\mu} (q-k)_\nu . $$

    In [25]:
    def three_vertex(m, n, r, k, p, q):
        if k+p+q != 0:
            print('momentum not conserved!')
        T1 = sympy.sympify('g_' + m + n, globals()) * (mo(k - p, r))
        T2 = sympy.sympify('g_' + n + r, globals()) * (mo(p - q, m))
        T3 = sympy.sympify('g_' + r + m, globals()) * (mo(q - k, n))
        T = T1 + T2 + T3
        return T
    

    ゲージ群添字とLorentz添字から4-bosonを返す: $$ a, b, c, d, \mu, \nu, \rho, \sigma \to f^{abe} f^{cde} (g_{\mu\rho} g_{\nu\sigma} - g_{\mu\sigma} g_{\nu\rho}) + f^{ace} f^{bde} (g_{\mu\nu} g_{\rho\sigma} - g_{\mu\sigma} g_{\nu\rho}) + f^{ade} f^{bce} (g_{\mu\nu} g_{\rho\sigma} - g_{\mu\rho} g_{\nu\sigma}) . $$

    In [26]:
    def four_vertex(a, b, c, d, e, m, n, r, s):
        F1 = sympy.sympify('f_' + a + b + e, globals()) * sympy.sympify('f_' + c + d + e, globals()) * (sympy.sympify('g_' + m + r, globals()) * sympy.sympify('g_' + n + s, globals()) - sympy.sympify('g_' + m + s, globals()) * sympy.sympify('g_' + n + r, globals()))
        F2 = sympy.sympify('f_' + a + c + e, globals()) * sympy.sympify('f_' + b + d + e, globals()) * (sympy.sympify('g_' + m + n, globals()) * sympy.sympify('g_' + r + s, globals()) - sympy.sympify('g_' + m + s, globals()) * sympy.sympify('g_' + n + r, globals()))
        F3 = sympy.sympify('f_' + a + d + e, globals()) * sympy.sympify('f_' + b + c + e, globals()) * (sympy.sympify('g_' + m + n, globals()) * sympy.sympify('g_' + r + s, globals()) - sympy.sympify('g_' + m + r, globals()) * sympy.sympify('g_' + n + s, globals()))
        F = F1 + F2 + F3
        return F
    

    運動量文字,Lorentz添字,ゲージ群の添字を定義

    In [27]:
    momentum_chars = ['k', 'p', 'q']
    Lorentz_indices = ['mu', 'nu', 'rho', 'sigma', 'lambda', 'kappa', 'tau', 'xi', 'eta']
    gruoup_indices = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']
    

    Lorentz添字を1文字目で表す(m=$\mu$)

    In [28]:
    Lorentz_indices_abr = [s[0] for s in Lorentz_indices]
    

    運動量文字のsymbolを定義する

    In [29]:
    for i in momentum_chars:
        exec(i + ' = sympy.symbols(\'' + i + '\')')
    

    計量成分のsymbolを定義する(g_mn=$g_{\mu\nu}$).1文字目の添字の順番≤2文字目の添字の順番とする.

    In [30]:
    for i in range(len(Lorentz_indices)):
        for j in range(i, len(Lorentz_indices)):
            exec('g_' + Lorentz_indices_abr[i] + Lorentz_indices_abr[j] + '= sympy.symbols(\'g_{\\\\' + Lorentz_indices[i] + '\\\\' + Lorentz_indices[j] + '}\')')
            exec('g_' + Lorentz_indices_abr[j] + Lorentz_indices_abr[i] + '= sympy.symbols(\'g_{\\\\' + Lorentz_indices[i] + '\\\\' + Lorentz_indices[j] + '}\')')
    

    運動量成分のsymbolを定義する(k_m=$k_\mu$)

    In [31]:
    for i in range(len(momentum_chars)):
        for j in range(len(Lorentz_indices)):
            exec(momentum_chars[i] + '_' + Lorentz_indices_abr[j] + '= sympy.symbols(\'' + momentum_chars[i] + '_\\\\' + Lorentz_indices[j] + '\')')
    

    運動量の内積を定義する(kp=$k\cdot p$).1文字目の運動量の順番≤2文字目の運動量の順番

    In [32]:
    for i in range(len(momentum_chars)):
        for j in range(i, len(momentum_chars)):
            exec(momentum_chars[i] + momentum_chars[j] + '= sympy.symbols(\'(' + momentum_chars[i] + momentum_chars[j] + ')\')')
            exec(momentum_chars[j] + momentum_chars[i] + '= sympy.symbols(\'(' + momentum_chars[i] + momentum_chars[j] + ')\')')
    

    ゲージ群の構造定数を定義する(f_abc=$f_{abc}$)

    In [33]:
    for a in range(len(gruoup_indices)):
        for b in range(len(gruoup_indices)):
            for c in range(len(gruoup_indices)):
                exec('f_' + gruoup_indices[a] + gruoup_indices[b] + gruoup_indices[c] + '= sympy.symbols(\'f_' + gruoup_indices[a] + gruoup_indices[b] + gruoup_indices[c] + '\')')
    

    頂点の積を計算する.入力はsympyのequation

    In [34]:
    def calculate_vertices(eq):
        eq = sympy.expand(eq)
        terms = list(sympy.Add.make_args(eq))
        for i in range(len(terms)):
            terms[i] = sympy.simplify(terms[i])
        terms_cal = []
        for i in range(len(terms)):
            term = str(terms[i])
            if term[0] == '-':
                if term[1].isdigit() == False:
                    term = term.replace('-', '-1*')
            elif term[0].isdigit() == False:
                term = '1*' + term
            while '**2' in term:
                end = term.find('**2')
                start = term.rfind('*', 0, end)
                term = term[:end+1] + term[start+1:end] + term[end+3:]
            term = term.split('*')
            if len(term) != len(set(term)):
                dups = [j for j in set(term) if term.count(j) > 1]
                for j in dups:
                    term.remove(j)
                    term.remove(j)
                    if j[0] in momentum_chars:
                        # [..., k_m, k_m, ...] -> [kk..., ...]
                        term[0] = term[0] + '*' + j[0] + j[0]
                    elif j[0] == 'g':
                        # [..., g_mn, g_mn, ...] -> [4..., ...]
                        term[0] = '4*' + term[0]
                    else:
                        # [..., x, x, ...] -> [x**2..., ...]
                        term[0] = term[0] + '*' + j[0] +'*' + j[0]
            # Lorentz scalars in coeff
            for i in term[1:]:
                if i[0] not in momentum_chars and i[0] != 'g':
                    term.remove(i)
                    term[0] = term[0] + '*' + i
            term_cal = calculate_contract(term)
            term_cal = '*'.join(term_cal)
            terms_cal.append(term_cal)
    
        eq_cal = 0
        for i in terms_cal:
            eq_cal += sympy.sympify(i, globals())
        eq_cal = sympy.simplify(eq_cal)
        return eq_cal
    

    以下では,An Introduction to Quantum Field Theory (Peskin & Schroeder)のProblemでの実際の使用例を書く.

    Problem 16.3

    3-boson頂点($AAA + AAA + AAA$)

    In [35]:
    t1 = g_ms*(2*p_k - k_k) + g_sk*(- p_m + 2*k_m) + g_km*(-k_s - p_s)
    t2 = g_sn*(2*p_l - k_l) + g_nl*(- p_s - k_s) + g_ls*(2*k_n - p_n)
    t3 = 2*g_kl*k_r - g_lr*k_k - g_rk*k_l
    
    print(sympy.latex(calculate_vertices(t1*t2*t3)))
    
    2 (kk) g_{\mu\nu} k_{\rho} + 4 (kk) g_{\mu\nu} p_{\rho} + 2 (kk) g_{\mu\rho} k_{\nu} - 3 (kk) g_{\mu\rho} p_{\nu} + 2 (kk) g_{\nu\rho} k_{\mu} - 3 (kk) g_{\nu\rho} p_{\mu} - 8 (kp) g_{\mu\nu} p_{\rho} - 2 (kp) g_{\mu\rho} k_{\nu} + 3 (kp) g_{\mu\rho} p_{\nu} - 2 (kp) g_{\nu\rho} k_{\mu} + 3 (kp) g_{\nu\rho} p_{\mu} + 10 (pp) g_{\mu\nu} k_{\rho} - (pp) g_{\mu\rho} k_{\nu} - (pp) g_{\nu\rho} k_{\mu} + 18 k_{\mu} k_{\nu} k_{\rho} - 9 k_{\mu} k_{\rho} p_{\nu} + 3 k_{\mu} p_{\nu} p_{\rho} - 9 k_{\nu} k_{\rho} p_{\mu} + 3 k_{\nu} p_{\mu} p_{\rho} - 6 k_{\rho} p_{\mu} p_{\nu}
    

    4-boson頂点($AAAA + AAAA$)

    In [36]:
    t1 = four_vertex('a', 'b', 'e', 'f', 'g', 'm', 'n', 'l', 'k')
    t2 = four_vertex('e', 'f', 'c', 'd', 'h', 'l', 'k', 'r', 's')
    
    print(sympy.latex(calculate_vertices(t1*t2)))
    
    2 f_{abg} f_{cdh} f_{efg} f_{efh} g_{\mu\rho} g_{\nu\sigma} - 2 f_{abg} f_{cdh} f_{efg} f_{efh} g_{\mu\sigma} g_{\nu\rho} + f_{abg} f_{ech} f_{efg} f_{fdh} g_{\mu\rho} g_{\nu\sigma} - f_{abg} f_{ech} f_{efg} f_{fdh} g_{\mu\sigma} g_{\nu\rho} - f_{abg} f_{edh} f_{efg} f_{fch} g_{\mu\rho} g_{\nu\sigma} + f_{abg} f_{edh} f_{efg} f_{fch} g_{\mu\sigma} g_{\nu\rho} + f_{aeg} f_{bfg} f_{cdh} f_{efh} g_{\mu\rho} g_{\nu\sigma} - f_{aeg} f_{bfg} f_{cdh} f_{efh} g_{\mu\sigma} g_{\nu\rho} + 2 f_{aeg} f_{bfg} f_{ech} f_{fdh} g_{\mu\nu} g_{\rho\sigma} + f_{aeg} f_{bfg} f_{ech} f_{fdh} g_{\mu\rho} g_{\nu\sigma} + 2 f_{aeg} f_{bfg} f_{edh} f_{fch} g_{\mu\nu} g_{\rho\sigma} + f_{aeg} f_{bfg} f_{edh} f_{fch} g_{\mu\sigma} g_{\nu\rho} - f_{afg} f_{beg} f_{cdh} f_{efh} g_{\mu\rho} g_{\nu\sigma} + f_{afg} f_{beg} f_{cdh} f_{efh} g_{\mu\sigma} g_{\nu\rho} + 2 f_{afg} f_{beg} f_{ech} f_{fdh} g_{\mu\nu} g_{\rho\sigma} + f_{afg} f_{beg} f_{ech} f_{fdh} g_{\mu\sigma} g_{\nu\rho} + 2 f_{afg} f_{beg} f_{edh} f_{fch} g_{\mu\nu} g_{\rho\sigma} + f_{afg} f_{beg} f_{edh} f_{fch} g_{\mu\rho} g_{\nu\sigma}
    

    3, 4-boson頂点($AAAA + AAA + AAA$)

    In [37]:
    t1 = four_vertex('e', 'f', 'c', 'd', 'h', 'l', 'k', 'r', 's')
    t2 = three_vertex('m', 'l', 't', 0, -k, k)
    t3 = three_vertex('n', 't', 'k', 0, -k, k)
    """
    t2*t3 =
    (kk) g_{\mu\lambda} g_{\nu\kappa} + 4 g_{\kappa\lambda} k_{\mu} k_{\nu} - 2 g_{\mu\kappa} k_{\lambda} k_{\nu} - g_{\mu\lambda} k_{\kappa} k_{\nu} + g_{\mu\nu} k_{\kappa} k_{\lambda} - g_{\nu\kappa} k_{\lambda} k_{\mu} - 2 g_{\nu\lambda} k_{\kappa} k_{\mu}
    """
    t23 = 5*g_mn*g_lk + 2*g_ml*g_nk - 4*g_mk*g_nl
    
    print(sympy.latex(calculate_vertices(t1*t23)))
    
    6 f_{cdh} f_{efh} g_{\mu\rho} g_{\nu\sigma} - 6 f_{cdh} f_{efh} g_{\mu\sigma} g_{\nu\rho} + 13 f_{ech} f_{fdh} g_{\mu\nu} g_{\rho\sigma} + 4 f_{ech} f_{fdh} g_{\mu\rho} g_{\nu\sigma} - 2 f_{ech} f_{fdh} g_{\mu\sigma} g_{\nu\rho} + 13 f_{edh} f_{fch} g_{\mu\nu} g_{\rho\sigma} - 2 f_{edh} f_{fch} g_{\mu\rho} g_{\nu\sigma} + 4 f_{edh} f_{fch} g_{\mu\sigma} g_{\nu\rho}
    

    3, 4-boson頂点($AAA + AAA + AAA + AAAA$)

    In [38]:
    t1 = three_vertex('m', 'l', 'e', 0, -k, k)
    t2 = three_vertex('l', 'r', 'k', k, 0, -k)
    t3 = three_vertex('x', 'k', 's', -k, k, 0)
    t4 = three_vertex('n', 'e', 'x', 0, -k, k)
    
    print(sympy.latex(calculate_vertices(t1*t2*t3*t4)))
    
    (kk)^{2} g_{\mu\nu} g_{\rho\sigma} + (kk)^{2} g_{\mu\rho} g_{\nu\sigma} + 3 (kk) g_{\mu\nu} k_{\rho} k_{\sigma} + 3 (kk) g_{\mu\rho} k_{\nu} k_{\sigma} + 3 (kk) g_{\nu\sigma} k_{\mu} k_{\rho} + 3 (kk) g_{\rho\sigma} k_{\mu} k_{\nu} + 34 k_{\mu} k_{\nu} k_{\rho} k_{\sigma}
    

    Problem 18.3

    3-boson頂点($AAA + AAA + \mathcal{O}_g$)

    In [39]:
    t1 = three_vertex('n', 'r', 'l', -k, p, k-p)
    t2 = three_vertex('n', 'l', 's', k, p-k, -p)
    
    print(sympy.latex(calculate_vertices(t1*t2)))
    
    2 (kk) g_{\rho\sigma} - 2 (kp) g_{\rho\sigma} + 5 (pp) g_{\rho\sigma} + 10 k_{\rho} k_{\sigma} - 5 k_{\rho} p_{\sigma} - 5 k_{\sigma} p_{\rho} - 2 p_{\rho} p_{\sigma}
    
    In [40]:
    t1 = three_vertex('x', 'r', 'l', -k, p, k-p)
    t2 = three_vertex('t', 'l', 's', k, p-k, -p)
    
    t12 = calculate_vertices(t1*t2)
    
    In [41]:
    t3 = three_vertex('t', 'r', 'l', -k, p, k-p)
    t4 = three_vertex('x', 'l', 's', k, p-k, -p)
    
    t34 = calculate_vertices(t3*t4)
    
    In [42]:
    print(sympy.latex(sympy.simplify(t12 + t34)))
    
    (kk) g_{\rho\tau} g_{\sigma\xi} + (kk) g_{\rho\xi} g_{\sigma\tau} + 2 (kp) g_{\rho\tau} g_{\sigma\xi} + 2 (kp) g_{\rho\xi} g_{\sigma\tau} + (pp) g_{\rho\tau} g_{\sigma\xi} + (pp) g_{\rho\xi} g_{\sigma\tau} + 2 g_{\rho\sigma} k_{\tau} k_{\xi} - 4 g_{\rho\sigma} k_{\tau} p_{\xi} - 4 g_{\rho\sigma} k_{\xi} p_{\tau} + 8 g_{\rho\sigma} p_{\tau} p_{\xi} - 3 g_{\rho\tau} k_{\sigma} k_{\xi} + 3 g_{\rho\tau} k_{\xi} p_{\sigma} - 3 g_{\rho\tau} p_{\sigma} p_{\xi} - 3 g_{\rho\xi} k_{\sigma} k_{\tau} + 3 g_{\rho\xi} k_{\tau} p_{\sigma} - 3 g_{\rho\xi} p_{\sigma} p_{\tau} - 3 g_{\sigma\tau} k_{\rho} k_{\xi} + 3 g_{\sigma\tau} k_{\xi} p_{\rho} - 3 g_{\sigma\tau} p_{\rho} p_{\xi} - 3 g_{\sigma\xi} k_{\rho} k_{\tau} + 3 g_{\sigma\xi} k_{\tau} p_{\rho} - 3 g_{\sigma\xi} p_{\rho} p_{\tau} + 8 g_{\tau\xi} k_{\rho} k_{\sigma} - 4 g_{\tau\xi} k_{\rho} p_{\sigma} - 4 g_{\tau\xi} k_{\sigma} p_{\rho} + 2 g_{\tau\xi} p_{\rho} p_{\sigma}