Вызов Кода — Гигантские Вавилонские Матрицы

  • Автор темы Dmit84
  • Обновлено
  • 22, Oct 2024
  • #1

Введение

У вавилонян был хитрый метод поиска квадратных корней. Чтобы найти квадратный корень числа

 
 
 
 M 
, you start with a M = [[7,2],[3,4]] guess = [[1., 0. ], [0., 1. ]] <-- 2x2 identity matrix guess = [[4., 1. ], [1.5, 2.5 ]] guess = [[2.85294, 0.558824], [0.838235, 2.01471]] guess = [[2.60335, 0.449328], [0.673992, 1.92936]] guess = [[2.58956, 0.443035], [0.664553, 1.92501]] guess = [[2.58952, 0.443016], [0.664523, 1.92499]] guess = [[2.58952, 0.443016], [0.664523, 1.92499]] , затем уточните его, неоднократно оценивая строку компьютерного кода (или эквивалента свитка папируса):

guess*guess = M

Если предположение меньше, чем sqrt(N), N/guess должно быть больше, чем sqrt(N), поэтому усреднение этих двух членов должно приблизить вас к истинному ответу. Оказывается, этот метод довольно быстро сходится к правильному ответу:

guess = (guess + inverse(guess)*M) / 2

Расширение

Существует ли эквивалентный алгоритм для матриц? Отбросив всю математическую строгость, если мы хотим найти «квадратный корень» из квадратной матрицы guess , we may again start with a M , затем уточните его, неоднократно оценивая строку кода:

N = 7 guess = 1 guess = 4.0 guess = 2.875 guess = 2.65489 guess = 2.64577 guess = 2.64575 guess = 2.64575

где inverse() — обратная функция матрицы, а * — умножение матрицы. Вместо 1 нашей первоначальной догадкой является единичная матрица соответствующего размера.

Однако сходимость больше не гарантируется — алгоритм расходится для большинства (но не всех) входных данных. Если M производит сходящийся ряд, это Вавилонская матрица. Более того, сходящееся значение на самом деле представляет собой действительный квадратный корень матрицы (т. Е. guess = (guess + N/guess) / 2 ).

Пример

Вот пример использования матрицы 2x2, показывающий сходимость ряда:

guess

Всего за несколько итераций ряд сходится с точностью до 1e-9. Через некоторое время она становится неустойчивой из-за суммирования ошибок округления, но демонстрируется первоначальная устойчивость, чего вполне достаточно.

Задача

Ваша задача — найти квадратную матрицу. N , populated by the integers 1 through 9, which, when given an initial guess of an identity matrix of the proper size, converges successfully. Matrices should be submitted as comma-delimited text (or attached text files, if they are too large), with either brackets or newlines separating subsequent rows.

Правила

Несмотря на то, что матрица M и начальное предположение используют целые числа (в основном для удобства отображения), вся арифметика должна выполняться с использованием плавающей запятой двойной точности. Целочисленные операторы (например, 3/2, приравнивающие к 1) запрещены.

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

Алгоритм считается сходящимся, если итерация не приводит к изменению, превышающему 1e-9, в любой отдельной ячейке.

Вы можете использовать внешние математические библиотеки для инверсии матриц (нет необходимости изобретать велосипед).

Условие победы

Победителем становится самая большая представленная действительная вавилонская матрица, состоящая из целых чисел от 1 до 9, по истечении одной недели. Вы также должны предоставить код, который вы использовали для поиска матрицы.

#вызов кода #математика #последовательность

Dmit84


Рег
29 Jul, 2007

Тем
70

Постов
189

Баллов
569
  • 26, Oct 2024
  • #2

Изготавливаем такую ​​матрицу любой размерности

 
 
 
 
 n = 10;
M = RandomInteger[{1, 9}, {n, n}];
guess = IdentityMatrix[n] // N;
result = NestList[(# + Inverse[#].M)/2 &, guess, 32];
ListPlot[Transpose[Flatten /@ result], Joined -> True]
M // MatrixForm
 
. It is simply a matrix of all 1's except 2's on the diagonal.

[[3.20594, 1.60102, 0.237288, -0.0745693, -1.07811, -0.255869, -0.0182269, 1.70256, 0.355871, 1.11176], [0.62321, 1.19922, -0.514309, 2.2604, 1.96759, 1.41485, -0.066537, 1.37868, -0.613093, 1.35704], [0.919805, 0.453479, 2.54444, 0.717525, -0.00569383, 1.54527, 0.131113, 0.916813, 0.443482, -0.0251371], [0.163383, -0.597711, 0.751538, 3.69952, 2.37728, -0.578767, 1.24375, -0.0922065, 0.749781, 0.623908], [2.27446, 2.7975, 0.171454, -1.6263, -1.12639, 1.22686, -2.69745, 2.36239, 1.6901, 2.1349], [0.669566, -1.57916, -0.722141, 1.35884, 2.43496, 2.25887, 2.01205, 0.241215, 0.342665, -0.714146], [0.50365, 0.472729, 1.37547, 0.32966, 1.36842, 0.0550458, 2.90591, 0.520055, -0.257277, -0.347814], [0.205106, 0.286162, 1.89821, 0.141372, 0.521793, 0.0638244, 1.65691, 1.04034, 0.81816, -0.30955], [0.0679229, 1.01126, 0.553701, 0.627696, -0.0400446, 1.21608, -0.397756, 0.35419, 2.38639, 1.08573], [-0.200249, 2.31035, 1.89905, -0.124084, 0.0398479, 0.454703, 1.08552, -0.152166, 0.408594, 2.31063]]

Пример:

[[9, 8, 6, 5, 1, 1, 6, 7, 1, 6], [8, 7, 4, 9, 9, 5, 4, 8, 5, 9], [7, 1, 8, 8, 6, 8, 6, 6, 4, 1], [7, 8, 9, 9, 5, 1, 1, 6, 9, 9], [6, 9, 3, 4, 1, 9, 1, 7, 4, 9], [9, 1, 1, 1, 5, 4, 5, 6, 7, 1], [8, 6, 8, 2, 4, 4, 6, 8, 2, 2], [5, 4, 9, 3, 3, 5, 5, 6, 4, 1], [2, 4, 4, 8, 6, 8, 3, 3, 7, 6], [3, 9, 9, 7, 7, 9, 6, 5, 1, 8]]

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

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

Я построил данную матрицу так, чтобы она имела положительные собственные значения следующим образом. Во-первых, начните с матрицы всех единиц, которая имеет ранг 1 и, следовательно, имеет одно собственное значение (n), а все остальные равны 0. Затем добавьте единицу, которая сдвигает собственные значения на 1 вверх, чтобы получить (n + 1 ,1,1,...,1). Итерация приводит к тому, что собственные значения сходятся к (sqrt(n+1),1,1,...,1). Обратите внимание, что единицы не меняются на каждой итерации.

 

Madj_n


Рег
08 Jun, 2011

Тем
72

Постов
189

Баллов
569
  • 26, Oct 2024
  • #3

Вот вавилонская матрица 10x10 в качестве первой цели:

n=5 M=[[2 1 1 1 1] [1 2 1 1 1] [1 1 2 1 1] [1 1 1 2 1] [1 1 1 1 2]] #Within 10 steps, the procedure converges to the matrix's square root [[ 1.28989795 0.28989795 0.28989795 0.28989795 0.28989795] [ 0.28989795 1.28989795 0.28989795 0.28989795 0.28989795] [ 0.28989795 0.28989795 1.28989795 0.28989795 0.28989795] [ 0.28989795 0.28989795 0.28989795 1.28989795 0.28989795] [ 0.28989795 0.28989795 0.28989795 0.28989795 1.28989795]]

который сходится к

r = range(n) M = [[1 + (i==j) for i in r] for j in r]

и был найден с помощью этого кода Mathematica:

n
 

Clirra


Рег
27 Mar, 2011

Тем
78

Постов
187

Баллов
587
Тем
403,760
Комментарии
400,028
Опыт
2,418,908

Интересно