Разное

Как возвести в куб матрицу: Возведение матрицы в степень | Мозган калькулятор онлайн

Используем быстрое возведение матриц в степень для написания очень быстрого интерпретатора простого языка программирования / Хабр

Недавно на хабре появилась неплохая статья про вычисление N-ного числа фибоначи за O(log N) арифметических операций. Разумный вопрос, всплывший в комментариях, был: «зачем это может пригодиться на практике». Само по себе вычисление N-ого числа фибоначи может и не очень интересно, однако подход с матрицами, использованный в статье, на практике может применяться для гораздо более широкого круга задач.

В ходе этой статьи мы разберем как написать интерпретатор, который может выполнять простые операции (присвоение, сложение, вычитание и урезанное умножение) над ограниченным количеством переменных с вложенными циклами с произвольным количеством итераций за доли секунды (конечно, если промежуточные значения при вычислениях будут оставаться в разумных пределах). Например, вот такой код, поданный на вход интерпретатору:

loop 1000000000
  loop 1000000000
    loop 1000000000
      a += 1
      b += a
    end
  end
end
end

Незамедлительно выведет a = 1000000000000000000000000000, b = 500000000000000000000000000500000000000000000000000000, несмотря на то, что если бы программа выполнялась наивно, интерпретатору необходимо было бы выполнить октиллион операций.



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

Для простоты ограничим наш интерпретатор четырьмя переменными — A, B, C и D. Для представления состояния интерпретатора в заданный момент будем использовать вектор размера пять, первые четыре элемента которого будут содержать значения четырех переменных соответственно, а последний будет на протяжении всей работы интерпретатора равен единице.

(A, B, C, D, 1)

В начале работы интерпретатора будем полагать значения всех переменных равными нулю.

(0, 0, 0, 0, 1)

Допустим, что первая операция в коде программы содержит строку

A += 5

Эффект этой команды заключается в том, что значение переменной A увеличится на пять, в то время как значения остальных трех переменных не изменятся. Это можно претставить в виде следующей матрицы:

1 0 0 0 0
0 1 0 0 0
0 0 1 0 0
0 0 0 1 0
5 0 0 0 1

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

v[0] * 1 + v[4] * 5

Так как v[0] содержит текущее значение в переменной A, а v[4] всегда равен единице, то

v[0] * 1 + v[4] * 5 = A + 5

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

0 0 0 0 0
0 1 0 0 0
0 0 1 0 0
0 0 0 1 0
5 0 0 0 1

Как и прежде, значения всех элементов кроме первого не изменятся, в то время как первый элемент станет равным v[4] * 5, или просто пяти. Умножение вектора текущего состояния на такую матрицу эквивалентно выполнению команды

A = 5

Посмотрим на такую матрицу:

1 0 0 0 0
0 1 0 0 0
0 0 1 0 0
0 1 0 1 0
0 0 0 0 1

Единственное отличие ее от единичной матрицы — это второй элемент в четвертой строке, который равен единице. Очевидно, что умножение вектора текущего состояния на эту матрицу не изменит значения в первом и последних трех элементах, в то время как значение второго элемента изменится на

v[1] * 1 + v[3] * 1

Так как v[1] содержит текущее значение переменной B, а v[3] содержит текущее значение переменной D, то умножение вектора состояния на такую матрицу эквивалентно выполнению команды B += D

Аналогично рассуждая можно понять, что умножение вектора состояния на следующую матрицу эквивалентно выполнению команды C *= 7

1 0 0 0 0
0 1 0 0 0
0 0 7 0 0
0 0 0 1 0
0 0 0 0 1

Перейдем к комбинированию команд. Пусть вектор v задает текущее состояние, матрица Ma соответствует команде A += 5, а матрица Mm соответствует команде A *= 7. 3

Мы вычисляем матрицу, соответствующую телу цикла, только один раз, после чего возводим ее в степень.

Рассмотренных примеров достаточно, чтобы начать работать над интерпретатором простого языка, поддерживающего присваивание, сложение, вычитание, умножение (только на константу) и циклы. Для этого мы научимся представлять любую такую программу в виде матрицы размера N+1 на N+1, где N — это количество переменных, которыми программа оперирует, после чего будем просто умножать вектор с начальным состоянием на эту матрицу.

Правила представления программы в виде матрицы очень просты:
1. Каждая отдельная команда представляется в виде матрицы, отличающейся от единичной одним элементом (или двумя для операции присваивания). Примеры таких матриц рассмотрены выше в этой статье.
2. Несколько подряд идущих команд представляются в виде матрицы, равной произведению матричного представления каждой отдельной команды.
3. Цикл представляется в виде матрицы, представляющей тело цикла, возведенной в степень количества итераций цикла.

Если у нас есть функция identity, возвращающая единичную матрицу:

def identity():
    return [[1 if i == j else 0 for j in range(REGS + 1)] for i in range(REGS + 1)]

То фукнция, строящая матрицу для команды r1 += r2 (где r1 и r2 — переменные) может выглядеть так:

def addreg(r1, r2):
    ret = identity()
    ret[r2][r1] = 1
    return ret

А для команды r += val (r — переменная, val — константа) вот так:

def addval(r, val):
    ret = identity()
    ret[REGS][r] = val
    return ret

Функции для построения матриц других команд выглядят похоже — получается единичная матрица, в которой заменяется один элемент.

Интерпретатор без циклов теперь пишется очень просто — пусть матрица mat соответствует уже прочитанному коду. В начале она равна единичной матрице, потому что пустая программа не меняет состояния. Затем мы считываем команды по одной, разбиваем их на три элемента (левый операнд, оператор, правый операнд), и в зависимости от оператора домножаем матрицу, соответствующую всей программе, на матрицу, соответствующую текущей команде:

def doit():
    mat = identity()
    while True:
        line = sys. stdin.readline().lower()
        tokens = line.split()
        if tokens[0] == 'loop':
            # тут будет код для циклов
        elif tokens[0] == 'end':
            return mat
        else:
            r1 = reg_names.index(tokens[0])
            try:
                r2 = reg_names.index(tokens[2])
            except:
                r2 = -1
            if tokens[1] == '+=':
                if r2 == -1: cur = addval(r1, long(tokens[2]))
                else: cur = addreg(r1, r2)
            elif tokens[1] == '-=':
            ....
        mat = matmul(mat, cur)

Осталось дело за малым — добавить поддержку циклов. Цикл возводит матрицу тела цикла в степень количества итераций цикла. Возведение в степень, как известно, требует только O(log N) операций, где N — это степень, в которую матрица возводится. Алгоритм возведения в степень очень прост:
1. Если степень равна нулю, вернуть единичную матрицу.
2. Если степень четная, пусть 2N, то можно рекурсивно вычислить M^N, а затем вернуть квадрат получившейся матрицы. 2N, и вернуть полученную матрицу, умноженную на M.

Так как каждые две итерации степень сокращается в двое, сложность такого алгоритма логарифмическая.

def matpow(m, p):
    if p == 0: return identity()
    elif p % 2 == 0:
        tmp = matpow(m, p / 2)
        return matmul(tmp, tmp)
    else: return matmul(m, matpow(m, p - 1))

В интерпретаторе теперь осталось добавить одну строку:

        ...
        if tokens[0] == 'loop':
            cur = matpow(doit(), long(tokens[1]))
        ...

И интерпретатор готов.

Пример интерпретатора доступен на гитхабе. Весь код занимает меньше 100 строк.

Для теста скорости можно вернуться к уже упомянутым числам фибоначи. Например, такой код:

A = 1
B = 1
loop 100
  C = A
  C += B
  A = B
  B = C
end
end

Вычислит 101-ое и 102-ое числа фибоначи:

A = 573147844013817084101, B = 927372692193078999176

Замена 100 на 1000000 вычислит миллион первое и миллион второе числа за четыре секунды. Выполнение такой программы в лоб заняло бы гораздо больше, потому что программе приходится оперировать многотысячезначными числами. Если написать код, которому не приходится оперировать большими числами, например код для вычисления суммы арифметической прогрессии, приведенный в начале статьи, то количество итераций может уходить за рамки разумного, но код будет выполняться за доли секунды

loop 1000000000000000000000000000000000000000000000
  loop 1000000000000000000000000000000000000000000000
    loop 1000000000000000000000000000000000000000000000
      a += 1
      b += a
    end
  end
end
end

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

Помогите решить / разобраться (М)

 
PWT 

 Возведение матрицы 2х2 в степень.

20.07.2017, 21:46 

11/06/16
191

Добрый день! Правильно ли я понимаю, чтобы возвести матрицу в степень , достаточно найти собственные значения и собственные векторы матрицы и далее по формуле , где

, в случае кратных корней будет просто

То есть в случае матриц не нужно думать о жордановой форме, правильно ведь? Для матриц и выше, ясно, что нужна Жорданова форма.

— 20.07.2017, 22:28 —

Хотя, в случае совпадения корней, нужно будет над диагональю поставить , потому как жорданова форма будет именно такая. Правильно ведь?


   

                  

svv 

 Re: Возведение матрицы 2х2 в степень.

20.07.2017, 22:30 

Заслуженный участник

23/07/08
9992
Crna Gora

Проверьте на матрице

— Чт июл 20, 2017 22:31:38 —

PWT в сообщении #1234961 писал(а):

Хотя, в случае совпадения корней, нужно будет над диагональю поставить , потому как жорданова форма будет именно такая. Правильно ведь?

Не совсем. Единица иногда будет, а иногда нет.


   

                  

PWT 

 Re: Возведение матрицы 2х2 в степень.

20.07.2017, 22:37 

11/06/16
191

На матрице, которую вы предложили получается, что корни хар-ческого уравнения равны единице, потому их нужно разместить на диагонали, а над диагональю будет тоже 1. Разве в случае кратных корней может быть иначе? Кстати, интересно, что Жорданова форма совпала с исходной матрицей. А можно еще что-то посчитать, где неверно мое предположение?


   

                  

svv 

 Re: Возведение матрицы 2х2 в степень.

20.07.2017, 22:48 

Заслуженный участник

23/07/08
9992
Crna Gora

PWT в сообщении #1234983 писал(а):

Разве в случае кратных корней может быть иначе?

Конечно! Например, если матрица «от природы» имеет вид , то, как Вы ни старайтесь, создать над диагональю единицу преобразованиями подобия не получится (с сохранением всего остального, разумеется).

— Чт июл 20, 2017 22:50:05 —

PWT в сообщении #1234983 писал(а):

А можно еще что-то посчитать, где неверно мое предположение?

Вы не учитываете самый распространённый случай: жордановы клетки могут иметь размер 1.


   

                  

PWT 

 Re: Возведение матрицы 2х2 в степень.

21.07.2017, 00:43 

11/06/16
191

А разве в стартпосте я не учел это?))


   

                  

svv 

 Re: Возведение матрицы 2х2 в степень.

21.07.2017, 15:04 

Заслуженный участник

23/07/08
9992
Crna Gora

Э… мне показалось, что Вы ищете один правильный шаблон ЖНФ для всех матриц с кратным собственным значением. Но тут возможно два варианта.

Для матрицы с собственным значением кратности 9 вариантов очень много. Например, ЖНФ может быть такой (нули для наглядности опущены):

Здесь две клетки порядка , две клетки порядка и одна клетка порядка .


   

                  

Xaositect 

 Re: Возведение матрицы 2х2 в степень.

21.07.2017, 15:44 

Заслуженный участник

06/10/08
6422

Для матриц возможны 2 вида жордановых форм: (возможно, ) и . Первую возвести в степень просто, и вторую тоже просто, но надо немного подумать. Элемент на месте единицы тоже меняется.


   

                  

Показать сообщения за: Все сообщения1 день7 дней2 недели1 месяц3 месяца6 месяцев1 год Поле сортировки АвторВремя размещенияЗаголовокпо возрастаниюпо убыванию 
  Страница 1 из 1
 [ Сообщений: 7 ] 

Модераторы: Модераторы Математики, Супермодераторы


Видео с вопросами: Возведение матрицы в квадрат и куб ноль, ноль, ноль, пять, ноль, ноль, ноль, два.

Затем нам нужно найти 𝐴 в квадрате, а затем используйте это, чтобы найти 𝐴 в кубе.

Ну, сколько будет 𝐴 в квадрате это матрица один, ноль, ноль, ноль, пять, ноль, ноль, ноль, два, умноженная на матрица один, ноль, ноль, ноль, пять, ноль, ноль, ноль, два. И мы знаем, что они могут быть умножаются друг на друга, потому что количество столбцов в матрице один такое же, как количество строк в матрице два. И это потому, что они оба, на самом деле, матрицы три на три. И поэтому наш результат также будет матрица три на три.

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

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

Хорошо, отлично. Итак, теперь у нас есть процесс. Мы используем это только для заполнения остальная часть матрицы. Итак, когда мы переходим к следующей строке вниз, мы просто перемещаем строку вниз в первой матрице, а затем перезапустите сначала с первого столбца во второй матрице. Значит ноль умножить на один плюс пять умножить на ноль плюс ноль умножить на ноль. Итак, мы просто продолжаем нашу шаблон и используйте его, чтобы завершить нашу матрицу. Итак, мы сделали это здесь. Итак, теперь у нас есть все расчеты на месте.

Теперь нам нужно сделать следующее. вычислить каждый из элементов нашей матрицы 𝐴 в квадрате. Ну, наш первый элемент один потому что мы получили один плюс ноль плюс ноль, затем ноль, затем снова ноль. Итак, это наш первый ряд полный. А затем для нашего второго ряда мы собираюсь получить ноль, 25 и ноль. Итак, для нашего последнего ряда мы собираешься получить ноль, ноль, четыре. Так здорово, мы нашли нашу матрицу для 𝐴 в квадрате. И это один, ноль, ноль, ноль, 25, ноль, ноль, ноль, четыре.

Итак, теперь нам нужно двигаться на 𝐴 в кубе. Ну а чтобы найти 𝐴 в кубе, что это будет равно матрице для квадрата 𝐴, умноженной на матрицу для 𝐴. Так что это будет матрица один, ноль, ноль, ноль, 25, ноль, ноль, ноль, четыре, умноженные на матрицу один, ноль, ноль, ноль, пять, ноль, ноль, ноль, два. И мы делаем это так же, как мы перемножил две матрицы ранее.

Чтобы быстро напомнить нам, у нас есть посмотрите на первый элемент. Итак, что мы делаем, так это умножаем соответствующие элементы из первой строки первой матрицы и первого столбца второй матрицы и сложим их вместе. Итак, мы получаем единицу, умноженную на один добавить ноль, умножить на ноль добавить ноль, умножить на ноль. Итак, мы используем этот метод для переноса для завершения остальной части нашей матрицы. Итак, мы видим здесь, что мы написали все расчеты, которые нам нужны. Итак, наша первая строка матрицы 𝐴 в кубе будет единица, ноль, ноль. В следующей строке будет ноль, 125, нуль. Так что это даст нам последний ряд ноль, ноль, восемь.

Отлично, мы смогли решить проблема, потому что мы можем сказать, что если мы возьмем матрицу 𝐴, которая равна единице, нулю, нулю, ноль, пять, ноль, ноль, ноль, два, тогда 𝐴 в квадрате будет единица, ноль, ноль, ноль, 25, ноль, ноль, ноль, четыре. И 𝐴 в кубе будет единица, ноль, ноль, ноль, 125, ноль, ноль, ноль, восемь.

Обзор | RGB LED Matrix Cube с 25 000 светодиодов

Обзор

Сохранить Подписаться

Пожалуйста, войдите, чтобы подписаться на это руководство.

После входа в систему вы будете перенаправлены обратно к этому руководству и сможете подписаться на него.

Светодиодов никогда не бывает слишком много… но мы не позволим этому помешать нам попробовать . Этот проект объединяет почти 25 000 полноцветных светодиодов в завораживающем, автономном интерактивном кубе, а маленький и могучий Raspberry Pi 4 — Altoid компьютеров — управляет шоу. Возможно, самый показной проект, который мы когда-либо пробовали!

  • Ваш браузер не поддерживает видео тег.

3D PixelDust

Демонстрация плавного пиксельного песка использует акселерометр для создания завораживающего эффекта движения.

Песчинки стекают вниз и перемещаются по всем шести панелям, что делает эту физическую игрушку непохожей ни на что другое.

Необычное руководство

ВАЖНО: мы присвоили этому руководству редкую рекомендацию уровня «Продвинутый». Не то, чтобы это было особенно глубоко или технично, но мы должны признать, что это дорого.  Почти в любой день мы праздновали обучение на ошибках новичков… но здесь один неверный шаг, например подключение неправильного источника питания, может разрушить сотен по частям. Это лучше всего подходит для людей, которые опытным путем выработали терпение и тщательность.

Эта сборка также необычна тем, что она нелинейная, с несколькими циклическими этапами между 3D-печатью, пайкой и подключением, установкой и тестированием кода… это не просто одно за другим. Это позволяет проводить тестирование и устранение неполадок при первой возможности, пока все открыто, чтобы избежать длительных неудач позже (см. «Терпение и тщательность благодаря опыту» выше). А начиная с 3D-печати, можно выполнять многозадачность… вы можете начать работу, пока электроника находится в пути, и выполнить начальное тестирование платы и кода по мере постепенного продвижения печати.

Перед совершением пролистайте руководство, чтобы узнать, что все это влечет за собой.

Уход и кормление вашего куба

Это один из наших самых амбициозных проектов «сделай сам», с большим количеством дорогостоящих деталей и точных допусков, и вам нужно заботиться о нем . Светодиодные матрицы предназначены для цифровых вывесок, а не для портативного использования. При грубом обращении отдельные светодиоды могут быть срезаны по краям и углам. Остальная часть матрицы все равно будет работать, будут только белые пятна и вам будет немного грустно.

Следовательно:

  • Поднимите куб обеими руками вплотную к граням, не по краям. Аккуратно передайте его от плоской ладони к плоской ладони.
  • Аккуратно откройте куб с помощью пластиковой лопатки, не царапайте его пальцами. Гитарный медиатор, старая кредитная или транспортная карта могут отлично сработать!
  • Сопротивляйтесь непреодолимому желанию раскрутить кубик пальцами на противоположных углах.

Детали от Adafruit

Ваш браузер не поддерживает видео тег.

Светодиодная матричная RGB-панель 64×64 с шагом 2 мм

Зима в городе может быть суровой. Небо серое. Погода непредсказуема. Так что избавьтесь от сезонной хандры с помощью ослепления Таймс-сквер…

Светодиодная матричная RGB-панель 64×64 с 45-градусным срезом бордюра — шаг 2,5 мм

Зимой в городе может быть сурово. Небо серое. Погода непредсказуема. Так что избавьтесь от этой сезонной хандры с ослепительным блеском Таймс-сквер из этого. ..

Матричная крышка Adafruit RGB для Raspberry Pi

Теперь вы можете создать ослепительный дисплей с Raspberry Pi с помощью матричной крышки Adafruit RGB Matrix. Эти платы подключаются к вашему Pi и делают его превосходным…

Raspberry Pi 4, модель B — 2 ГБ ОЗУ

ПРИМЕЧАНИЕ. Из-за ограниченного запаса мы можем предложить возмещение или сохранить кредит только для Pi, которые неисправны, повреждены или потерянный в…

Трехосевой акселерометр Adafruit LIS3DH (+-2g/4g/8g/16g)

LIS3DH — очень популярный трехосевой акселерометр с низким энергопотреблением. Это недорого, но в нем есть почти все «дополнительные функции», которые вам нужны…

2 х Шина распределения питания

Цельная латунь диаметром 7 x 6 мм

В корзину 2 шт.

1 х Adafruit RGB Matrix HAT + RTC для Raspberry Pi

Adafruit RGB Matrix HAT + RTC для Raspberry Pi

Добавить в корзину

1 х Кабель USB-C на USB-A

Черный плетеный прямоугольный кабель USB C на USB A, длина 0,2 м

Нет в наличии

1 х STEMMA QT / Qwiic JST SH 4-контактный кабель для вилки премиум-класса

Длина 150 мм

Добавить в корзину

1 х Комплект крепежных деталей M2. 5 из черного нейлона

Комплект крепежных деталей M2.5 из черного нейлона

Добавить в корзину

1 х Комплект крепежных деталей M3 из черного нейлона

Комплект крепежных деталей M3 из черного нейлона

Добавить в корзину

Детали из других источников

1 х Неодимовые магниты

Диаметр 1/4 дюйма x толщина 1/8 дюйма 1D42 – Количество x48

Купить

2 х Батарея USB 5 В 3 А

Батарея USB 10000 мАч

Купить сейчас

1 х Кабель USB-A/DC

Разъем USB-Darrel Jack Штекер постоянного тока 5 В Кабель питания 2,1 мм

Купить

Вам также понадобится

  • Паяльник и сопутствующие принадлежности. Там очень мало пайки требуется, но не ноль.
  • Основные инструменты для изготовления, такие как плоскогубцы и небольшие отвертки (для винтовых клемм питания постоянного тока).

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *