Пределы магических квадратов

 

index.htm - English text 

MagicSquare2.zip   - результаты всех суперкомпиляций.

 

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

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

Для dim=5 способ построения показан ниже. Составляется таблица по-порядку по диагоналям, затем наружные числа сдвигаются на свободные места.

 

        1        
      6   2      
    11   7   3    
  16   12   8   4  
21   17   13   9   5
  22   18   14   10  
    23   19   15    
      24   20      
        25        

 

11 24 7 20 3
4 12 25 8 16
17 5 13 21 9
10 18 1 14 22
23 6 19 2 15

 

 

Пусть s - сумма чисел по строке, по столбцу или по диагонали.

Обозначим через  A  матрицу  M / s . Например, для квадрата 3 на 3 получается матрица

4/15 9/15 2/15
3/15 5/15 7/15
8/15 1/15 6/15

 

Теперь рассматриваем предел при n, стремящемся к бесконечности, матрицы An.

Замечание 1. Если делить не на s, то в пределе получается либо 0, либо бесконечность. Доказательство - не очень простое упражнение по курсу алгебра для первого курса.

Замечание 2. В ответе получается матрица из одинаковых элементов, равных 1/dim.

Рассматриваем программы на языке Java, 

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

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

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

В настоящий момент имеются три программы для пределов магических квадратов (в архивированном приложении MagicSquare2.zip соответственно три директории)

1. Моя программа korlyukov.htm , которая больше похожа на программу на Фортране, чем на программу на Яве.

2. Программа Павла Чекина chekin.htm , которую он написал, увидев предыдущую программу.

3. Программа  jama.htm , в которой используется пакет Jama

http://math.nist.gov/javanumerics/jama/

http://math.nist.gov/javanumerics/jama/Jama-1.0.1.zip

В пакете Jama реализованы функции работы с матрицами, в качестве примера использования пакета проиводится программа построения магических квадратов. Поэтому программа jama.htm получилась компактной.

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

В трех директориях приложения MagicSquare2.zip приведено все, необходимое для суперкомпиляции и пусков на счет исходной и остаточной программ. В поддиректория Res приведены результаты суперкомпиляции для dim=5.

Приведем совокупную таблицу (dim=5, iters=100 000)

 

  Korlyukov Chekin Jama
время суперкомпиляции 11 сек 25 сек 9 сек
время исполнения исходной программы 0.661 0.63 1.170
время исполнения остаточной программы 0.12 0.11 0.54
коэффициент ускорения 5.5 5.7 2.2

 

Результат суперкомпиляции для dim=3 (Korlyukov)

//--------------------------------------   1 sec - postprocessing...
	public static double[][] test (final double[][] a_2)
	{
	  final double[] rr_7 = new double[3];
	  rr_7[0] = 0.26666666666666666D;
	  rr_7[1] = 0.2D;
	  rr_7[2] = 0.5333333333333333D;
	  for (int iiii_226 = 0; iiii_226 < MagicSquare.iter; iiii_226++) {
	    final double rr1_1_278 = rr_7[0] * 0.2D + rr_7[1] * 0.3333333333333333D + rr_7[2] * 0.4666666666666667D;
	    final double rr1_2_307 = rr_7[0] * 0.5333333333333333D + rr_7[1] * 0.06666666666666667D + rr_7[2] * 0.4D;
	    rr_7[0] = rr_7[0] * 0.26666666666666666D + rr_7[1] * 0.6D + rr_7[2] * 0.13333333333333333D;
	    rr_7[1] = rr1_1_278;
	    rr_7[2] = rr1_2_307;
	    continue;}
	  /*for*/
	  MagicSquare.res[0][0] = rr_7[0];
	  MagicSquare.res[0][1] = rr_7[1];
	  MagicSquare.res[0][2] = rr_7[2];
	  rr_7[0] = 0.6D;
	  rr_7[1] = 0.3333333333333333D;
	  rr_7[2] = 0.06666666666666667D;
	  for (int iiii_490 = 0; iiii_490 < MagicSquare.iter; iiii_490++) {
	    final double rr1_1_542 = rr_7[0] * 0.2D + rr_7[1] * 0.3333333333333333D + rr_7[2] * 0.4666666666666667D;
	    final double rr1_2_571 = rr_7[0] * 0.5333333333333333D + rr_7[1] * 0.06666666666666667D + rr_7[2] * 0.4D;
	    rr_7[0] = rr_7[0] * 0.26666666666666666D + rr_7[1] * 0.6D + rr_7[2] * 0.13333333333333333D;
	    rr_7[1] = rr1_1_542;
	    rr_7[2] = rr1_2_571;
	    continue;}
	  /*for*/
	  MagicSquare.res[1][0] = rr_7[0];
	  MagicSquare.res[1][1] = rr_7[1];
	  MagicSquare.res[1][2] = rr_7[2];
	  rr_7[0] = 0.13333333333333333D;
	  rr_7[1] = 0.4666666666666667D;
	  rr_7[2] = 0.4D;
	  for (int iiii_754 = 0; iiii_754 < MagicSquare.iter; iiii_754++) {
	    final double rr1_1_806 = rr_7[0] * 0.2D + rr_7[1] * 0.3333333333333333D + rr_7[2] * 0.4666666666666667D;
	    final double rr1_2_835 = rr_7[0] * 0.5333333333333333D + rr_7[1] * 0.06666666666666667D + rr_7[2] * 0.4D;
	    rr_7[0] = rr_7[0] * 0.26666666666666666D + rr_7[1] * 0.6D + rr_7[2] * 0.13333333333333333D;
	    rr_7[1] = rr1_1_806;
	    rr_7[2] = rr1_2_835;
	    continue;}
	  /*for*/
	  MagicSquare.res[2][0] = rr_7[0];
	  MagicSquare.res[2][1] = rr_7[1];
	  MagicSquare.res[2][2] = rr_7[2];
	  return MagicSquare.res;
	}
//--------------------------------------   3 sec - JScp version 0.0.75

Результат суперкомпиляции для dim=3 (Chekin).

//--------------------------------------   2 sec - postprocessing...
	public static void main (final java.lang.String[] args_2)
	{
	  int i_1390 = 0;
	  WHILE_1391:
	  while (i_1390 < MagicSquareTest.iprint) {
	    final long startTime_1396 = java.lang.System.currentTimeMillis() /*static*/;
	    final double[][] m2_1537 = new double[3][3];
	    final double[][] m3_1541 = new double[3][3];
	    final double[] m2_0_1534 = m2_1537[0];
	    m2_0_1534[0] = 0.26666666666666666D;
	    m2_0_1534[1] = 0.2D;
	    m2_0_1534[2] = 0.5333333333333333D;
	    final double[] m2_1_1535 = m2_1537[1];
	    m2_1_1535[0] = 0.6D;
	    m2_1_1535[1] = 0.3333333333333333D;
	    m2_1_1535[2] = 0.06666666666666667D;
	    final double[] m2_2_1536 = m2_1537[2];
	    m2_2_1536[0] = 0.13333333333333333D;
	    m2_2_1536[1] = 0.4666666666666667D;
	    m2_2_1536[2] = 0.4D;
	    double[][] m2_2257 = m2_1537;
	    double[][] m3_2256 = m3_1541;
	    int iter_2254 = 0;
	    while (iter_2254 < MagicSquareTest.iters) {
	      m3_2256[0][0] = 0.26666666666666666D * m2_2257[0][0] + 0.6D * m2_2257[0][1] + 0.13333333333333333D * m2_2257[0][2];
	      m3_2256[0][1] = 0.2D * m2_2257[0][0] + 0.3333333333333333D * m2_2257[0][1] + 0.4666666666666667D * m2_2257[0][2];
	      m3_2256[0][2] = 0.5333333333333333D * m2_2257[0][0] + 0.06666666666666667D * m2_2257[0][1] + 0.4D * m2_2257[0][2];
	      m3_2256[1][0] = 0.26666666666666666D * m2_2257[1][0] + 0.6D * m2_2257[1][1] + 0.13333333333333333D * m2_2257[1][2];
	      m3_2256[1][1] = 0.2D * m2_2257[1][0] + 0.3333333333333333D * m2_2257[1][1] + 0.4666666666666667D * m2_2257[1][2];
	      m3_2256[1][2] = 0.5333333333333333D * m2_2257[1][0] + 0.06666666666666667D * m2_2257[1][1] + 0.4D * m2_2257[1][2];
	      m3_2256[2][0] = 0.26666666666666666D * m2_2257[2][0] + 0.6D * m2_2257[2][1] + 0.13333333333333333D * m2_2257[2][2];
	      m3_2256[2][1] = 0.2D * m2_2257[2][0] + 0.3333333333333333D * m2_2257[2][1] + 0.4666666666666667D * m2_2257[2][2];
	      m3_2256[2][2] = 0.5333333333333333D * m2_2257[2][0] + 0.06666666666666667D * m2_2257[2][1] + 0.4D * m2_2257[2][2];
	      final int iter_2622 = iter_2254 + 1;
	      final double[][] m2_2632 = m2_2257;
	      m2_2257 = m3_2256;
	      m3_2256 = m2_2632;
	      iter_2254 = iter_2622;
	      continue;}
	    /*while*/
	    final long endTime_2634 = java.lang.System.currentTimeMillis() /*static*/;
	    if (m2_2257 == null) {
	      java.lang.System.out.println("Execution time: " + (double)(endTime_2634 - startTime_1396) * 0.001D) /*virtual*/;
	      i_1390++;
	      continue WHILE_1391;}
	    else {
	      java.lang.System.out.print(m2_2257[0][0] + " ") /*virtual*/;
	      java.lang.System.out.print(m2_2257[0][1] + " ") /*virtual*/;
	      java.lang.System.out.print(m2_2257[0][2] + " ") /*virtual*/;
	      java.lang.System.out.println() /*virtual*/;
	      java.lang.System.out.print(m2_2257[1][0] + " ") /*virtual*/;
	      java.lang.System.out.print(m2_2257[1][1] + " ") /*virtual*/;
	      java.lang.System.out.print(m2_2257[1][2] + " ") /*virtual*/;
	      java.lang.System.out.println() /*virtual*/;
	      java.lang.System.out.print(m2_2257[2][0] + " ") /*virtual*/;
	      java.lang.System.out.print(m2_2257[2][1] + " ") /*virtual*/;
	      java.lang.System.out.print(m2_2257[2][2] + " ") /*virtual*/;
	      java.lang.System.out.println() /*virtual*/;
	      java.lang.System.out.println("Execution time: " + (double)(endTime_2634 - startTime_1396) * 0.001D) /*virtual*/;
	      i_1390++;
	      continue WHILE_1391;}}
	  /*WHILE_1391*/
	  return;
	}
//--------------------------------------   5 sec - JScp version 0.0.75

Результат суперкомпиляции для dim=3 (Jama)

 

//--------------------------------------   2 sec - postprocessing...
	public static void main (final java.lang.String[] argv_2)
	{
	  int i_931 = 1;
	  WHILE_932:
	  while (i_931 <= MagicSquareLimit.iters1) {
	    final long start_937 = java.lang.System.currentTimeMillis() /*static*/;
	    final Jama.Matrix X_1108 = new Jama.Matrix(3, 3);
	    //- this is X_1108 = new Jama.Matrix(3, 3)
	    //  X_1108.m = 3;
	    //  X_1108.n = 3;
	    //  final double[][] A_1113 = new double[3][3];
	    //  X_1108.A = A_1113;
	    final double[][] A_1113 = X_1108.A;
	    final double[] A_0_1110 = A_1113[0];
	    A_0_1110[0] = 0.5333333333333333D;
	    A_0_1110[1] = 0.06666666666666667D;
	    A_0_1110[2] = 0.4D;
	    final double[] A_1_1111 = A_1113[1];
	    A_1_1111[0] = 0.2D;
	    A_1_1111[1] = 0.3333333333333333D;
	    A_1_1111[2] = 0.4666666666666667D;
	    final double[] A_2_1112 = A_1113[2];
	    A_2_1112[0] = 0.26666666666666666D;
	    A_2_1112[1] = 0.6D;
	    A_2_1112[2] = 0.13333333333333333D;
	    Jama.Matrix C_1452 = X_1108;
	    int j_1451 = 1;
	    while (j_1451 <= MagicSquareLimit.iters) {
	      final Jama.Matrix X_1458 = new Jama.Matrix(3, 3);
	      //- this is X_1458 = new Jama.Matrix(3, 3)
	      //  X_1458.m = 3;
	      //  X_1458.n = 3;
	      //  final double[][] A_1463 = new double[3][3];
	      //  X_1458.A = A_1463;
	      final double[][] A_1463 = X_1458.A;
	      final double Bcolj_0_1471 = C_1452.A[0][0];
	      final double Bcolj_1_1478 = C_1452.A[1][0];
	      final double Bcolj_2_1485 = C_1452.A[2][0];
	      final double[] A_0_1460 = A_1463[0];
	      A_0_1460[0] = 0.5333333333333333D * Bcolj_0_1471 + 0.06666666666666667D * Bcolj_1_1478 + 0.4D * Bcolj_2_1485;
	      final double[] A_1_1461 = A_1463[1];
	      A_1_1461[0] = 0.2D * Bcolj_0_1471 + 0.3333333333333333D * Bcolj_1_1478 + 0.4666666666666667D * Bcolj_2_1485;
	      final double[] A_2_1462 = A_1463[2];
	      A_2_1462[0] = 0.26666666666666666D * Bcolj_0_1471 + 0.6D * Bcolj_1_1478 + 0.13333333333333333D * Bcolj_2_1485;
	      final double Bcolj_0_1593 = C_1452.A[0][1];
	      final double Bcolj_1_1600 = C_1452.A[1][1];
	      final double Bcolj_2_1607 = C_1452.A[2][1];
	      A_0_1460[1] = 0.5333333333333333D * Bcolj_0_1593 + 0.06666666666666667D * Bcolj_1_1600 + 0.4D * Bcolj_2_1607;
	      A_1_1461[1] = 0.2D * Bcolj_0_1593 + 0.3333333333333333D * Bcolj_1_1600 + 0.4666666666666667D * Bcolj_2_1607;
	      A_2_1462[1] = 0.26666666666666666D * Bcolj_0_1593 + 0.6D * Bcolj_1_1600 + 0.13333333333333333D * Bcolj_2_1607;
	      final double Bcolj_0_1715 = C_1452.A[0][2];
	      final double Bcolj_1_1722 = C_1452.A[1][2];
	      final double Bcolj_2_1729 = C_1452.A[2][2];
	      A_0_1460[2] = 0.5333333333333333D * Bcolj_0_1715 + 0.06666666666666667D * Bcolj_1_1722 + 0.4D * Bcolj_2_1729;
	      A_1_1461[2] = 0.2D * Bcolj_0_1715 + 0.3333333333333333D * Bcolj_1_1722 + 0.4666666666666667D * Bcolj_2_1729;
	      A_2_1462[2] = 0.26666666666666666D * Bcolj_0_1715 + 0.6D * Bcolj_1_1722 + 0.13333333333333333D * Bcolj_2_1729;
	      j_1451++;
	      C_1452 = X_1458;
	      continue;}
	    /*while*/
	    C_1452.print(2, 3) /*virtual*/;
	    final long end_1848 = java.lang.System.currentTimeMillis() /*static*/;
	    java.lang.System.out.println("Total time = " + (double)(end_1848 - start_937) * 0.001D) /*virtual*/;
	    i_931++;
	    continue;}
	  /*WHILE_932*/
	  return;
	}
//--------------------------------------   3 sec - JScp version 0.0.75