Magicsq.java
/*
* $Id: Magicsq.java,v 1.12 2008/02/25 08:35:51 koga Exp $
*
* Copyright (C) 2004 Koga Laboratory. All rights reserved.
*/
package org.mklab.tool.matrix;
import org.mklab.nfc.matrix.DoubleMatrix;
import org.mklab.nfc.matrix.IntMatrix;
/**
* 魔方陣を求めるクラスです。
*
* <p> Magic Square
*
* @author koga
* @version $Revision: 1.12 $
*/
public class Magicsq {
/**
* <code>size</code>×<code>size</code>の魔方陣を求めます。
*
* @param size 次数
* @return 魔方陣 (magic square)
*/
public static DoubleMatrix magicsq(int size) {
DoubleMatrix A = new DoubleMatrix(size, size);
DoubleMatrix M = new DoubleMatrix(size, size);
if (size % 2 == 0) {
// Make a seed matrix of magic square of even-order
for (int i = 1; i <= size / 2; i++) {
for (int j = 1; j <= size; j++) {
if (i % 2 != 0) {
A.setElement(i, j, j);
A.setElement(size - i + 1, j, j);
} else {
A.setElement(i, j, size - j + 1);
A.setElement(size - i + 1, j, size - j + 1);
}
}
}
// 4m + 2 order
if ((size - 2) % 4 == 0) {
A.setSubMatrix(size / 2, size / 2, 1, A.getColumnSize(), A.getSubMatrix(size / 2, size / 2, 1, A.getColumnSize()).flipLeftRight());
A.setSubMatrix(size / 2, size / 2, IntMatrix.series(size / 2, size / 2 + 1), A.getSubMatrix(size / 2, size / 2, IntMatrix.series(size / 2 + 1, size / 2)));
A.setSubMatrix(size, size, IntMatrix.series(size / 2, size / 2 + 1), A.getSubMatrix(size, size, IntMatrix.series(size / 2 + 1, size / 2)));
}
for (int i = 1; i <= size; i++) {
for (int j = 1; j <= size; j++) {
M.setElement(i, j, A.getDoubleElement(i, j) + size * (A.getDoubleElement(j, i) - 1));
}
}
} else {
// odd order
int k = 0;
for (int i = -size / 2; i <= size / 2; i++) {
for (int j = 0; j < size; j++) {
M.setElement((j - i + size % size) + 1, (j + i + size % size) + 1, ++k);
}
}
}
return M;
}
}