684 - Integral Determinant
Posted: Mon Nov 04, 2002 7:23 am
What's wrong with this code?
It stores fractions to avoid float computation.
[cpp]
#include <stdio.h>
#include <math.h>
#define max_matrix_size 31
typedef struct {
long long a, b;
} tfraction;
typedef struct {
int size;
tfraction matrix[max_matrix_size][max_matrix_size];
} tmatrix;
tmatrix res;
long gcd(long long a, long long b)
{
return (a%b==0) ? b : gcd(b, a%b);
}
tfraction fracdiv(tfraction frac1, tfraction frac2)
{
tfraction t;
t.a = frac1.a * frac2.b;
t.b = frac1.b * frac2.a;
long long k = gcd(t.a, t.b);
t.a /= k;
t.b /= k;
return t;
}
tfraction fracadd(tfraction frac1, tfraction frac2)
{
tfraction t;
t.b = frac1.b * frac2.b;
t.a = frac1.a * frac2.b + frac2.a * frac1.b;
long long k = gcd(t.a, t.b);
t.a /= k;
t.b /= k;
return t;
}
tfraction fracmulti(tfraction frac1, tfraction frac2)
{
tfraction t;
t.a = frac1.a * frac2.a;
t.b = frac1.b * frac2.b;
long long k = gcd(t.a, t.b);
t.a /= k;
t.b /= k;
return t;
}
void swapline(int ln1, int ln2)
{
int i;
tfraction t;
for (i = 1; i <= res.size; i++) {
t = res.matrix[ln1];
res.matrix[ln1] = res.matrix[ln2];
res.matrix[ln2] = t;
}
}
tfraction det()
{
tfraction d, mik;
int i, j, k, ik;
float max;
tfraction tmp;
d.a = 1;
d.b = 1;
for (k = 1; k <= res.size - 1; k++) {
max = -1e10;
for (i = k; i <= res.size; i++)
if (res.matrix[k].a != 0)
if (res.matrix[k].a / res.matrix[k].b > max) {
max = res.matrix[k].a / res.matrix[k].b;
ik = i;
}
if (res.matrix[ik][k].a == 0) {
d.a = 0;
return d; /* the matrix is singular */
}
if (ik != k) {
swapline(ik, k);
d.a = -d.a;
}
d = fracmulti(d, res.matrix[k][k]);
for (i = k + 1; i <= res.size; i++) {
mik = fracdiv(res.matrix[k], res.matrix[k][k]);
res.matrix[i][k] = mik;
for (j = k; j <= res.size; j++) {
tmp = fracmulti(mik, res.matrix[k][j]);
tmp.a = -tmp.a;
res.matrix[i][j] = fracadd(tmp, res.matrix[i][j]);
}
}
}
d = fracmulti(d, res.matrix[res.size][res.size]);
return d;
}
int main()
{
int i, j;
long k;
tfraction detans;
while (scanf("%d", &res.size) == 1) {
if (res.size == 0) break;
for (i = 1; i <= res.size; i++)
for (j = 1; j <= res.size; j++) {
scanf("%ld", &k);
res.matrix[i][j].a = k;
res.matrix[i][j].b = 1;
}
detans = det();
printf("%lld\n", detans.a / detans.b);
}
printf("*\n");
return 0;
}
[/cpp][/cpp]
It stores fractions to avoid float computation.
[cpp]
#include <stdio.h>
#include <math.h>
#define max_matrix_size 31
typedef struct {
long long a, b;
} tfraction;
typedef struct {
int size;
tfraction matrix[max_matrix_size][max_matrix_size];
} tmatrix;
tmatrix res;
long gcd(long long a, long long b)
{
return (a%b==0) ? b : gcd(b, a%b);
}
tfraction fracdiv(tfraction frac1, tfraction frac2)
{
tfraction t;
t.a = frac1.a * frac2.b;
t.b = frac1.b * frac2.a;
long long k = gcd(t.a, t.b);
t.a /= k;
t.b /= k;
return t;
}
tfraction fracadd(tfraction frac1, tfraction frac2)
{
tfraction t;
t.b = frac1.b * frac2.b;
t.a = frac1.a * frac2.b + frac2.a * frac1.b;
long long k = gcd(t.a, t.b);
t.a /= k;
t.b /= k;
return t;
}
tfraction fracmulti(tfraction frac1, tfraction frac2)
{
tfraction t;
t.a = frac1.a * frac2.a;
t.b = frac1.b * frac2.b;
long long k = gcd(t.a, t.b);
t.a /= k;
t.b /= k;
return t;
}
void swapline(int ln1, int ln2)
{
int i;
tfraction t;
for (i = 1; i <= res.size; i++) {
t = res.matrix[ln1];
res.matrix[ln1] = res.matrix[ln2];
res.matrix[ln2] = t;
}
}
tfraction det()
{
tfraction d, mik;
int i, j, k, ik;
float max;
tfraction tmp;
d.a = 1;
d.b = 1;
for (k = 1; k <= res.size - 1; k++) {
max = -1e10;
for (i = k; i <= res.size; i++)
if (res.matrix[k].a != 0)
if (res.matrix[k].a / res.matrix[k].b > max) {
max = res.matrix[k].a / res.matrix[k].b;
ik = i;
}
if (res.matrix[ik][k].a == 0) {
d.a = 0;
return d; /* the matrix is singular */
}
if (ik != k) {
swapline(ik, k);
d.a = -d.a;
}
d = fracmulti(d, res.matrix[k][k]);
for (i = k + 1; i <= res.size; i++) {
mik = fracdiv(res.matrix[k], res.matrix[k][k]);
res.matrix[i][k] = mik;
for (j = k; j <= res.size; j++) {
tmp = fracmulti(mik, res.matrix[k][j]);
tmp.a = -tmp.a;
res.matrix[i][j] = fracadd(tmp, res.matrix[i][j]);
}
}
}
d = fracmulti(d, res.matrix[res.size][res.size]);
return d;
}
int main()
{
int i, j;
long k;
tfraction detans;
while (scanf("%d", &res.size) == 1) {
if (res.size == 0) break;
for (i = 1; i <= res.size; i++)
for (j = 1; j <= res.size; j++) {
scanf("%ld", &k);
res.matrix[i][j].a = k;
res.matrix[i][j].b = 1;
}
detans = det();
printf("%lld\n", detans.a / detans.b);
}
printf("*\n");
return 0;
}
[/cpp][/cpp]