Skip to content

Instantly share code, notes, and snippets.

@314maro
Last active March 23, 2016 17:28
Show Gist options
  • Save 314maro/065f5659be77d7afaa34 to your computer and use it in GitHub Desktop.
Save 314maro/065f5659be77d7afaa34 to your computer and use it in GitHub Desktop.
行列 いろいろ手抜きした
#include <stdio.h>
#include <stdlib.h>
// Reference: R(mat,i,j) -> mat[i][j]
#define R(mat,i,j) (mat).m[(i)*(mat).c+(j)]
typedef struct {
int r, c;
double *m;
} mat;
void print(mat m) {
printf("mat %d * %d\n", m.r, m.c);
for (int i = 0; i < m.r; i++)
for (int j = 0; j < m.c; j++)
printf("%f%c", R(m,i,j), (j+1 == m.c) ? '\n' : ' ');
}
mat new(int x, int y) {
mat m = { x, y, NULL };
if (x * y == 0)
return m;
m.m = malloc(sizeof(double) * x * y);
return m;
}
mat zero(int x, int y) {
mat m = new(x,y);
for (int i = 0; i < x; i++)
for (int j = 0; j < y; j++)
R(m,i,j) = 0;
return m;
}
mat ident(int x) {
mat m = new(x,x);
for (int i = 0; i < x; i++)
for (int j = 0; j < x; j++)
R(m,i,j) = i == j;
return m;
}
mat add(mat a, mat b) {
if (a.r != b.r || a.c != b.c) {
printf("add\n"); exit(1);
}
mat m = new(a.r, a.c);
for (int i = 0; i < a.r; i++)
for (int j = 0; j < a.c; j++)
R(m,i,j) = R(a,i,j) + R(b,i,j);
return m;
}
mat scalar(double k, mat a) {
mat m = new(a.r, a.c);
for (int i = 0; i < a.r; i++)
for (int j = 0; j < a.c; j++)
R(m,i,j) = k * R(a,i,j);
return m;
}
mat mul(mat a, mat b) {
if (a.c != b.r) {
printf("mul\n"); exit(1);
}
mat m = zero(a.r, b.c);
for (int i = 0; i < a.r; i++)
for (int j = 0; j < b.c; j++)
for (int k = 0; k < a.c; k++)
R(m,i,j) += R(a,i,k) * R(b,k,j);
return m;
}
mat trans(mat a) {
mat m = new(a.c, a.r);
for (int i = 0; i < m.r; i++)
for (int j = 0; j < m.c; j++)
R(m,i,j) = R(m,j,i);
return m;
}
double det(mat a) {
if (a.r != a.c) {
printf("det\n"); exit(1);
}
if (a.r == 1) {
return R(a,0,0);
}
double ret = 0;
for (int i = 0; i < a.c; i++) {
// コピー
mat b = new(a.r-1,a.c-1);
for (int j = 1; j < a.r; j++)
for (int k = 0; k < a.c; k++)
if (k < i) {
R(b,j-1,k) = R(a,j,k);
} else if (k > i) {
R(b,j-1,k-1) = R(a,j,k);
}
// 計算
ret += R(a,0,i) * (i%2 ? -1 : 1) * det(b);
}
return ret;
}
int main(void) {
double a[2][2] = { {1,3}, {-3,2} };
mat m = new(2,2); m.m = (double*) a;
print(m); print(mul(m,m));
print(add(add(mul(m,m), scalar(-R(m,0,0)-R(m,1,1),m)), scalar(det(m),ident(2))));
double b[3][3] = { {1,3,3}, {-3,2,-1}, {2,1,2} };
mat n = new(3,3); n.m = (double*) b;
puts(""); print(n);
printf("det = %f\n", det(n));
}
@314maro
Copy link
Author

314maro commented Mar 23, 2016

行列式の計算を書いた マクロの罠に思い切りひっかかった

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment