Нахождение всех обратимых квадратных матриц - PullRequest
2 голосов
/ 17 июня 2020

Я хочу написать функцию, в которой, учитывая два целых числа «n» и «p», она генерирует все обратимые матрицы порядка n, где элементы берутся из {0,1, ..., p-1}. У меня есть следующий код:

import itertools 
import numpy as np 

def invertible_matrices(n, p):
    invertibleMatrices = set()
    # generates all the possible matrices
    x = [y for y in range(p)]
    a = [j for j in itertools.product(x, repeat=n)]
    b = {k for k in itertools.product(a, repeat=n)}
    for each in b:
        if np.linalg.det(each) != 0:
            invertibleMatrices.add(each)
    return invertibleMatrices

для n=2 и p=2 он работает нормально, но для n=2 и p=3 я получаю 50, а ответ 48. любая помощь будет принята с благодарностью.

ps: если вы знакомы с теорией групп, я пытаюсь найти все элементы GL (n, p) (общая линейная группа над конечное поле с p элементами)

Ответы [ 2 ]

3 голосов
/ 17 июня 2020

Я думаю, вам нужен определитель по модулю p (который является определителем в контексте GL (n, p), то есть над конечным полем с элементами p).

if not np.isclose((np.linalg.det(each)+1)%p,1):
    invertibleMatrices.add(each)

Примечание: + 1 состоит в том, чтобы избежать повторения небольших числовых ошибок.

2 голосов
/ 17 июня 2020

Используйте inspect_matrix () для отладки, get_invertible_matrices () для использования понимания множества для определения всех обратимых матриц и get_determinant_1_matrices () для получения матриц с определителем 1:

import itertools
import numpy as np


def inspect_matrix(n, p):
    """Examine a single, square matrix."""
    a = list(itertools.product(list(range(p)), repeat=n))
    matrices = {k
                for k in itertools.product(a, repeat=n)
               }
    matrix = next(iter(matrices))  # Inspect one of the matrices
    determinant = np.linalg.det(matrix)
    print(f"{matrix = }\n{determinant = }")
    print(f"inverse = {(inverse:=np.linalg.inv(matrix))}") if determinant != 0.0 else print("Matrix is not invertible")
    return inverse 


def get_invertible_matrices(n, p):
    """Generates all the possible matrices."""
    a = list(itertools.product(list(range(p)), repeat=n))
    invertible_matrices = {k
                           for k in itertools.product(a, repeat=n)
                           if not np.isclose((np.linalg.det(k) + 1) % p, 1)
                           }
    print(f"{len(invertible_matrices) = }")
    return invertible_matrices


def get_determinant_1_matrices(n, p):
    """Generates all the square matrices with determinant 1."""
    a = list(itertools.product(list(range(p)), repeat=n))
    if p==2:
            det_1_matrices = {k
                              for k in itertools.product(a, repeat=n)
                              if np.isclose((np.linalg.det(k))%p,1)
                              }
    else:
            det_1_matrices = {k
                              for k in itertools.product(a, repeat=n)
                              if np.isclose((np.linalg.det(k)+1)%p,2)
                              }
    print(f"{len(det_1_matrices) = }")
    return det_1_matrices


def main():
    print(get_invertible_matrices(n=2, p=2))
    print(get_invertible_matrices(n=2, p=3))
    print(get_determinant_1_matrices(n=2, p=2))
    print(get_determinant_1_matrices(n=2, p=3))


if __name__ == '__main__':
    main()

возвращает:

len(invertible_matrices) = 6
{((1, 1), (0, 1)), ((1, 0), (0, 1)), ((1, 0), (1, 1)), ((0, 1), (1, 0)), ((0, 1), (1, 1)), ((1, 1), (1, 0))}
len(invertible_matrices) = 48
{((1, 0), (0, 1)), ((1, 2), (0, 2)), ((2, 1), (1, 0)), ((0, 2), (2, 0)), ((0, 1), (2, 0)), ((1, 1), (1, 0)), ((2, 1), (1, 1)), ((2, 2), (2, 0)), ((1, 1), (2, 1)), ((1, 2), (1, 0)), ((2, 1), (2, 2)), ((2, 0), (0, 2)), ((1, 2), (1, 1)), ((2, 2), (0, 2)), ((1, 0), (0, 2)), ((1, 1), (1, 2)), ((1, 2), (2, 2)), ((2, 1), (0, 1)), ((1, 1), (0, 1)), ((0, 2), (1, 0)), ((0, 1), (1, 0)), ((2, 0), (2, 1)), ((0, 2), (2, 1)), ((2, 2), (1, 0)), ((0, 1), (2, 1)), ((1, 2), (0, 1)), ((0, 2), (1, 1)), ((2, 0), (1, 1)), ((0, 1), (1, 1)), ((2, 2), (2, 1)), ((2, 0), (2, 2)), ((0, 2), (2, 2)), ((2, 1), (2, 0)), ((0, 1), (2, 2)), ((1, 0), (2, 1)), ((1, 0), (1, 1)), ((1, 1), (2, 0)), ((2, 0), (1, 2)), ((0, 2), (1, 2)), ((0, 1), (1, 2)), ((1, 0), (2, 2)), ((2, 0), (0, 1)), ((1, 2), (2, 0)), ((2, 2), (1, 2)), ((2, 1), (0, 2)), ((1, 0), (1, 2)), ((2, 2), (0, 1)), ((1, 1), (0, 2))}
len(det_1_matrices) = 6
{((0, 1), (1, 1)), ((0, 1), (1, 0)), ((1, 0), (0, 1)), ((1, 0), (1, 1)), ((1, 1), (0, 1)), ((1, 1), (1, 0))}
len(det_1_matrices) = 24
{((2, 2), (0, 2)), ((0, 2), (1, 2)), ((1, 1), (0, 1)), ((1, 2), (2, 2)), ((2, 1), (2, 0)), ((1, 0), (0, 1)), ((2, 0), (2, 2)), ((2, 1), (1, 1)), ((1, 1), (2, 0)), ((1, 0), (2, 1)), ((1, 2), (0, 1)), ((1, 2), (1, 0)), ((2, 0), (0, 2)), ((1, 0), (1, 1)), ((1, 1), (1, 2)), ((0, 2), (1, 0)), ((0, 1), (2, 2)), ((0, 2), (1, 1)), ((0, 1), (2, 1)), ((2, 0), (1, 2)), ((0, 1), (2, 0)), ((2, 2), (2, 1)), ((2, 2), (1, 0)), ((2, 1), (0, 2))}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...