Как создать матрицу из генератора - PullRequest
1 голос
/ 18 июня 2019

Я пытаюсь сформировать матрицу, используя генераторный набор некоторых векторов (v1, v2, v3), где каждый элемент представляет двоичные данные.

Я хочу, чтобы код использовал векторы в наборе и создал матрицу с нулевым вектором, каждым из векторов строк и комбинациями v1+v2, v1+v3, v2+v3 и v1+v2+v3, т.е. все возможные линейные комбинации с 0 и 1 в качестве коэффициентов.

Я пытался использовать циклы for, но в итоге получаю повторы. Я также был в состоянии сделать это, выполнив каждую из операций, но это неосуществимо для генерации множеств с несколькими векторами.

import numpy as np
A = np.matrix([[1,1,1,1,0,0,0,0],[0,0,1,1,1,1,0,0],[0,0,0,0,1,1,1,1]])

Я хочу создать новую матрицу из всех возможных линейных комбинаций векторов строк из вышеуказанной матрицы A.

Вывод должен содержать следующее:

[0,0,0,0,0,0,0,0], 
[1,1,1,1,0,0,0,0], 
[0,0,1,1,1,1,0,0], 
[0,0,0,0,1,1,1,1], 
[1,1,0,0,1,1,0,0], 
[0,0,1,1,0,0,1,1],
[1,1,1,1,1,1,1,1], 
[1,1,0,0,0,0,1,1]

Ответы [ 2 ]

1 голос
/ 18 июня 2019

Я думаю, это то, что вы хотите.

import numpy as np
from itertools import combinations

v = np.array([[1,1,1,1,0,0,0,0],[0,0,1,1,1,1,0,0],[0,0,0,0,1,1,1,1]]) # v1, v2, v3

l = [] # creating a list of possible combinations [(0, 1), (0, 2), (1, 2), (0, 1, 2)]
for j in range(2, v.shape[0]+1):
    comb = combinations(np.arange(v.shape[0]), j)  
    for i in list(comb): 
        l.append(i)

final = np.zeros((len(l), v.shape[1]))  # creating final matrix 

for i in range(len(l)): # filling final matrix based on combinations
    for j in (l[i]):
        final[i] += v[j]

final = np.concatenate((np.zeros((1,v.shape[1])), v, final%2), axis=0)

#array([[0., 0., 0., 0., 0., 0., 0., 0.],
#       [1., 1., 1., 1., 0., 0., 0., 0.],
#       [0., 0., 1., 1., 1., 1., 0., 0.],
#       [0., 0., 0., 0., 1., 1., 1., 1.],
#       [1., 1., 0., 0., 1., 1., 0., 0.],
#       [1., 1., 1., 1., 1., 1., 1., 1.],
#       [0., 0., 1., 1., 0., 0., 1., 1.],
#       [1., 1., 0., 0., 0., 0., 1., 1.]])
0 голосов
/ 19 июня 2019

Я смотрю на эту проблему так, что у вас есть набор коэффициентов:

coeffs = [0, 1]

Цель состоит в том, чтобы получить все комбинации коэффициентов, умноженные на векторы.Математически вы хотите применить следующие коэффициенты к вашим векторам:

from itertools import chain, combinations_with_replacement, permuations
import numpy as np

A = np.matrix([[1,1,1,1,0,0,0,0],[0,0,1,1,1,1,0,0],[0,0,0,0,1,1,1,1]])

N = len(A)
all_coeffs = (
    chain.from_iterable(
        list(set(permutations(x, N))) for x in combinations_with_replacement(coeffs, N)
    )
)
print(list(all_coeffs))
#[(0, 0, 0),
# (1, 0, 0),
# (0, 1, 0),
# (0, 0, 1),
# (0, 1, 1),
# (1, 1, 0),
# (1, 0, 1),
# (1, 1, 1)]

Таким образом, вам нужно взять скалярное произведение каждого из коэффициентов с каждой из строк в A, а затем «сумму»результат.Поскольку вы работаете с двоичными числами, операция сложения может быть выполнена с помощью оператора xor.Наконец, вы можете объединить результаты вместе.

Соберите все это вместе:

from functools import reduce
from operator import xor

N = len(A)
mat = np.concatenate(
    [
        reduce(xor, (a*b for a, b in zip(c, A)))
        for c in (
            chain.from_iterable(
                list(set(permutations(x, N))) for x in 
                combinations_with_replacement(coeffs, N)
            )
        )
    ]
)
print(mat)
#[[0 0 0 0 0 0 0 0]
# [1 1 1 1 0 0 0 0]
# [0 0 1 1 1 1 0 0]
# [0 0 0 0 1 1 1 1]
# [0 0 1 1 0 0 1 1]
# [1 1 0 0 1 1 0 0]
# [1 1 1 1 1 1 1 1]
# [1 1 0 0 0 0 1 1]]
...