utils.py 3.11 KB
Newer Older
MischaD's avatar
MischaD committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
import itertools
import numpy as np
import math


def analyse_tensor_dimension(tensor_rank):
    """

    :param tensor_rank:
    :return:
    """

    first_entry = tensor_rank
    first_entries = [tensor_rank]

    possible_tensors = [first_entries]
    while first_entry > 2:
        first_entry = first_entry - 2
        first_entries = [first_entry]
        rest = tensor_rank - first_entry
        reduced_possible_tensors = analyse_tensor_dimension(rest)
        reduced_tensor_dimension = len(reduced_possible_tensors)
        for i in range(reduced_tensor_dimension):
            if reduced_possible_tensors[i][0] <= first_entry:
                possible_tensors.append(first_entries + reduced_possible_tensors[i])

    return possible_tensors


def get_group(dimension):
    def to_matrix(arr):
        """Convert an array of unit vectors to proper matrix."""

        dim = len(arr)
        M = np.zeros((dim, dim), dtype=np.int8)

        for col in range(dim):
            Row = arr[col] - 1
            M[Row][col] = 1

        return M

    unit_vectors = np.arange(1, dimension + 1)
    permutations = itertools.permutations(unit_vectors, dimension)

    sign_combinations = np.zeros((2**dimension, dimension))
    format_ = "0{}b".format(dimension)
    for i in range(2**dimension):
        binary = format(i, format_)
        sign_combinations[i] = np.array([2*int(binary[j]) - 1 for j in range(dimension)])

    group = []
    for permutation in permutations:
        M = to_matrix(permutation)
        for sign_combination in sign_combinations:
            group.append(np.multiply(sign_combination, M))
    transformation_amount = np.math.factorial(dimension) * 2 ** dimension
    assert len(group) == transformation_amount # Todo Exception
    return group


MischaD's avatar
MischaD committed
62
63
64
def contains(arr, list_of_arr):
    return any((arr == x).all() for x in list_of_arr)

MischaD's avatar
MischaD committed
65

MischaD's avatar
MischaD committed
66
67
68
def contains_in_sublist(arr, list_of_lists):
    return any(contains(arr, list_of_arr) for list_of_arr in list_of_lists)

MischaD's avatar
MischaD committed
69

MischaD's avatar
MischaD committed
70
71
72
73
74
75
76
77
78
79
80
81
82
def get_subshells(shell, group):
    subshells = []
    for velocity in shell:
        subshell = []
        for i in range(len(group)):
            new = np.dot(group[i], velocity)
            if contains(new, subshell):
                continue
            subshell.append(new)
        if not contains_in_sublist(velocity, subshells):
            subshells.append(subshell)

    return subshells
MischaD's avatar
MischaD committed
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117


def double_factorial(n):
    assert n >= 0
    if n == 0 or n == 1:
        return 1
    return n * double_factorial(n-2)


def lattice_sum(vector, velocities, rank):
    ret = 0
    for velocity in velocities:
        scalar_product = 0
        for dim in range(len(vector)):
            scalar_product += vector[dim] * velocity[dim]
        ret += scalar_product ** rank
    return ret / double_factorial(rank - 1)


def fill_rhs(max_rank, shells):
    rhs = []
    cols = max_rank // 2
    for k, rank in enumerate(np.arange(2, max_rank + 2, 2)):
        for j in range(shells[k]):
            rows = []
            for i in range(cols):
                c_s_power = 2 * i + 2
                rows.append(1 if c_s_power == rank else 0)
            rhs.append(rows)
    return np.array(rhs)