行列の積 - いまさらながらですが。
2007/08/11
java
行列の積をプログラミングで行ってみます。
シナリオ
2次元配列を引数にとって行列の積を行うメソッドを作成してください。
で、javaで行います。
参考:
行列 - Wikipedia
上記の結果を目標にしてみます。
工夫した点は、計算式のループのネストがいやなので、匿名クラスを使用した。その副作用としてメソッドの引数にfinalがつきます。
java自体のもつassertを使用した箇所が一箇所あります。
実は、このassertのふるまいがいまいち自分の直感に沿っていなくて、使用するのがためらわれます。
java VMの引数に-eaが必要となりますね。
コード下記のようにしました。
package matrix;
public class Product {
public static void main(String[] args) {
int[][] a = { { 5, 6 },
{ 7, 8 } };
int[][] b = { { 1, 2 },
{ 3, 4 } };
int[][] result;
result = calc_2By2(a, b);
printMatrix(result);
System.out.println();
result = product(a, b);
printMatrix(result);
a = new int[][]{ { 2, 4, 3 },
{ 4, 1, 2 },
{ 2, 3, 5 }};
b = new int[][]{ { 3, 4 },
{ 2, 1 },
{1, 5 }};
//b = new int[][]{{1, 1}};
System.out.println();
result = product(a, b);
printMatrix(result);
}
public static void printMatrix(int[][] m) {
for (int[] is : m) {
for (int i : is) {
System.out.print(i);
System.out.print(" ");
}
System.out.println();
}
}
public static int[][] calc_2By2(int[][] a, int[][] b) {
return new int[][] {
{ (a[0][0] * b[0][0]) + (a[0][1] * b[1][0]),
(a[0][0] * b[0][1]) + a[0][1] * b[1][1] },
{ (a[1][0] * b[0][0]) + a[1][1] * b[1][0],
(a[1][0] * b[0][1]) + a[1][1] * b[1][1] },
};
}
public static int[][] product(final int[][] a, final int[][] b) {
final int m = a[0].length;
final int n = b[0].length;
assert a[0].length == b.length || a.length == b[0].length;
int[][] result = new int[m][n];
class Support {
int calc(int i, int j) {
int result = 0;
for (int k = 0; k < m; k++) {
result += a[i][k] * b[k][j];
}
return result;
}
}
Support support = new Support();
for (int i = 0; i < result.length; i++) {
for (int j = 0; j < result[i].length; j++) {
result[i][j] = support.calc(i, j);
}
}
return result;
}
}
public class Product {
public static void main(String[] args) {
int[][] a = { { 5, 6 },
{ 7, 8 } };
int[][] b = { { 1, 2 },
{ 3, 4 } };
int[][] result;
result = calc_2By2(a, b);
printMatrix(result);
System.out.println();
result = product(a, b);
printMatrix(result);
a = new int[][]{ { 2, 4, 3 },
{ 4, 1, 2 },
{ 2, 3, 5 }};
b = new int[][]{ { 3, 4 },
{ 2, 1 },
{1, 5 }};
//b = new int[][]{{1, 1}};
System.out.println();
result = product(a, b);
printMatrix(result);
}
public static void printMatrix(int[][] m) {
for (int[] is : m) {
for (int i : is) {
System.out.print(i);
System.out.print(" ");
}
System.out.println();
}
}
public static int[][] calc_2By2(int[][] a, int[][] b) {
return new int[][] {
{ (a[0][0] * b[0][0]) + (a[0][1] * b[1][0]),
(a[0][0] * b[0][1]) + a[0][1] * b[1][1] },
{ (a[1][0] * b[0][0]) + a[1][1] * b[1][0],
(a[1][0] * b[0][1]) + a[1][1] * b[1][1] },
};
}
public static int[][] product(final int[][] a, final int[][] b) {
final int m = a[0].length;
final int n = b[0].length;
assert a[0].length == b.length || a.length == b[0].length;
int[][] result = new int[m][n];
class Support {
int calc(int i, int j) {
int result = 0;
for (int k = 0; k < m; k++) {
result += a[i][k] * b[k][j];
}
return result;
}
}
Support support = new Support();
for (int i = 0; i < result.length; i++) {
for (int j = 0; j < result[i].length; j++) {
result[i][j] = support.calc(i, j);
}
}
return result;
}
}
結果は
//(1)
23 34
31 46
//(2)
23 34
31 46
//(3)
17 27
16 27
17 36
できていると思うのだが。
自信がないので、アドバイスがあればよろしくです。
参考
: