Я создал матрицу 5x4 с записями только 1 и -1. Я также создал код, который дает мне случайные возможные конфигурации для этого типа матрицы. Каждый раз я проверяю вручную, равен ли определитель произведения D'*D 512 или нет. До сих пор я получил только результаты определителей 0, +-64, 192 и +-128.
Я хочу получить конфигурации матрицы автоматически: определитель которого равен 512, определитель которого находится между 0 и 512.
До сих пор я сделал эту строку кода. Это правильно, даже несмотря на то, что мне приходится запускать код самому после каждого расчета.
valueset = [1,-1];
desiredsize = [5, 4];
desiredmatrix = valueset(randi(numel(valueset), desiredsize))
b=desiredmatrix.'
a=desiredmatrix.'*D
det(a)
и я получил такие расчеты:
>desired
desiredmatrix =
1 -1 1 -1
1 -1 1 -1
-1 -1 1 -1
1 -1 -1 -1
1 1 -1 -1
b =
1 1 -1 1 1
-1 -1 -1 -1 1
1 1 1 -1 -1
-1 -1 -1 -1 -1
a =
1 3 3 1
-1 1 -3 -5
-1 -3 1 3
-3 -1 -5 -3
ans = 64
> desired
desiredmatrix =
-1 1 1 1
1 1 1 1
-1 -1 1 1
1 -1 -1 -1
1 -1 -1 -1
b =
-1 1 -1 1 1
1 1 -1 -1 -1
1 1 1 -1 -1
1 1 1 -1 -1
a =
3 1 1 -1
-3 -1 -1 1
-1 -3 1 3
-1 -3 1 3
ans = 0
и т. д. и т. д.
@Joao_PS извините за неправильный вопрос. Точно размер матрицы должен быть 5 строк и 4 столбца. Все, что я хочу сделать, это заставить компьютер работать на меня, а не нажимать кнопку запуска после каждого расчета ахахаха. Спасибо за ваш ответ
Из описания обоих тегов: «Не используйте оба тега matlab и octave, если только вопрос явно не касается сходства или различия между ними»
Мне требуется около 23 миллисекунд, чтобы вычислить первую такую матрицу. И около 29-30 секунд, чтобы найти все такие матрицы.
Теперь у нас есть 20 значений в матрице, поэтому у нас есть 2^20=1048576
таких матриц.
Поэтому сначала я запускаю цикл for для перебора всех этих чисел (от 0 до 1048575). Теперь переходим к заполнению матрицы. Теперь каждый i
в первом цикле for я беру двоичное представление i
и дополняю его нулями, пока не получу двоичный список из 20 элементов.
Таким образом, 140
, чей двоичный файл равен 10001100
, станет списком 0000 0000 0000 1000 1100
(пробелы добавлены для видимости), которые будут,
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0]
(назовите его bin_list
)
Теперь, чтобы заполнить 20 элементов моей матрицы (скажем, от 0 до 19), я заполняю
j-й элемент как valueset[bin_list[j]]
, поэтому, если элемент bin_list
равен 0, соответствующий элемент моего массива A равен 1, а если его 1, то A получает значение (-1). Итак, для случая 140
матрица A будет
[[ 1, 1, 1, 1],
[ 1, 1, 1, 1],
[ 1, 1, 1, 1],
[-1, 1, 1, 1],
[-1, -1, 1, 1]]
Примечание. Мне нужно преобразовать A в матрицу, используя numpy.matrix
, так как нам нужно вычислить транспонирование и определитель.
Это обесценивается, как указал пользователь S Guogeon. Итак, для матричного умножения можно напрямую использовать @
вместо *
с numoy.array
После вычисления этой матрицы A я вычисляю транспонирование с помощью numpy.transpose()
, скажем, это B. Теперь я вычисляю определитель с помощью numpy.linalg.det(B*A)
. Теперь из-за возвращаемого типа данных numpy.linalg.det()
я округляю его до ближайшего целого числа.
Я проверяю, равен ли этот определитель 512. Если да, бинго, у меня правильная матрица.
Первое решение, которое у меня есть, это 854
(i=854)
bin_list
для этого будет,
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0]
Матрица A
будет,
matrix([[ 1, 1, 1, 1],
[ 1, 1, 1, 1],
[ 1, 1, -1, -1],
[ 1, -1, 1, -1],
[ 1, -1, -1, 1]])
A'*A
будет,
matrix([[5, 1, 1, 1],
[1, 5, 1, 1],
[1, 1, 5, 1],
[1, 1, 1, 5]])
Определитель этого будет 512 (после преобразования определителя в int)
Код для преобразования 140 в двоичный список:
def int_to_binlist(n, b = 8):
res=[]
strb = str(b)+'b'
str1 = format(n, strb)
res = list(map(int, list(str1)))
return res
Фрагмент кода для заполнения матрицы A битами 1 и -1:
n_mat = desiredsize[0]*desiredsize[1] #so 5*4=20
for j in range(n_mat):
a[int(j/4)][j%4] = valueset[li[j]]
Использованная литература: Документация numpy.linalg.detдокументация numpy.matrix
1) numpy.matrix
устарел, его больше не рекомендуют использовать. Вы можете использовать обычный массив, чтобы делать то же самое, вам просто нужно использовать @
вместо *
. 2) Python — это не MATLAB или Octave.
2^20=1048576
, а не 2048
Ах да, плохо, я обновлю ответ, чтобы отразить изменения, касающиеся numpy.mstrix
и ошибочного расчета 2^20
.
@chris luengo, когда я изначально отвечал на вопрос, в нем конкретно упоминался python, правки и теги к вопросу были добавлены после того, как я ответил.
Тег python был удален в 21:23 по Гринвичу 7 января, задолго до того, как вы ответили в 00:40 по Гринвичу 8 января. Тем не менее, код в вопросе должен был указывать на то, что это не python. К сожалению, некоторые люди склонны спамить свои вопросы неактуальными тегами.
@PranavHosangadi У меня была идея принять решения даже на питоне, так как я тоже чувствую себя комфортно с этим языком. Я новичок в этом сообществе, и это может случиться. Извините, если мои действия ввели в заблуждение.
Я не понял вашего вопроса... Но я проверил
desiredsize = [6, 5]
еще, и это сработало... Я получил несколько ответов 512