quakeforge/tools/qfcc/test/pga2d.r
Bill Currie 58a1758363 [qfcc] Implement the regressive product
That went surprisingly well (but it is built up from other ops, so
pretty easy, really).
2023-08-28 20:35:03 +09:00

274 lines
6.9 KiB
R
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "test-harness.h"
#pragma warn no-vararg-integer
typedef @algebra(double(2,0,1)) PGA;
typedef PGA.group_mask(0x02) scalar_t;
typedef PGA.group_mask(0x04) vector_t;
typedef PGA.group_mask(0x01) bivector_t;
typedef PGA.group_mask(0x08) trivector_t;
typedef union {
PGA.group_mask(0x03) mvec;
struct {
bivector_t bvec;
scalar_t scalar;
};
} evengrades_t;
typedef union {
PGA.group_mask(0x0c) mvec;
struct {
vector_t vec;
trivector_t tvec;
};
} oddgrades_t;
int
main (void)
{
if (sizeof (scalar_t) != sizeof (double)) {
printf ("scalar has wrong size: %d\n", sizeof (scalar_t));
return 1;
}
if (sizeof (vector_t) != 3 * sizeof (scalar_t)) {
printf ("bivector has wrong size: %d\n", sizeof (vector_t));
return 1;
}
if (sizeof (bivector_t) != 3 * sizeof (scalar_t)) {
printf ("bivector has wrong size: %d\n", sizeof (bivector_t));
return 1;
}
if (sizeof (trivector_t) != sizeof (scalar_t)) {
printf ("trivector has wrong size: %d\n", sizeof (trivector_t));
return 1;
}
scalar_t scalar;
vector_t vec, vecb;
bivector_t bvec, bvecb;
trivector_t tvec, tvecb;
@algebra (PGA) {
scalar = 42;
vec = 3*e1 - 2*e2 + e0;
bvec = 4*e20 - 3*e01 + 2*e12;
tvec = 7*e012;
vecb = 5*e1 + 12*e2 - 13*e0;
bvecb = 6*e20 + 4*e01 + 1*e12;
tvecb = 3*e012;
}
if (scalar != 42) {
printf ("scalar != 42: %g\n", scalar);
return 1;
}
if ((dvec3)vec != '3 -2 1'd) {
printf ("vec != '3 -2 1': %lv\n", vec);
return 1;
}
if ((dvec3)bvec != '4 -3 2'd) {
printf ("vec != '4 -3 2': %lv\n", bvec);
return 1;
}
if ((double)tvec != 7) {
printf ("tvec != 7: %g\n", tvec);
return 1;
}
auto a = vecbvec;
if ((double)a != 20) {
printf ("vec ∧ bvec != 20: %lv\n", a);
return 1;
}
auto b = bvecvec;
if ((double)b != 20) {
printf ("bvec ∧ vec != 20: %lv\n", b);
return 1;
}
auto c = vecbvec;
if ((dvec3)c != '4 6 1'd) {
printf ("vec • bvec != '4 6 1': %lv\n", c);
return 1;
}
auto d = bvecvec;
if ((dvec3)d != '-4 -6 -1'd) {
printf ("bvec • vec != '-4 -6 -1': %lv\n", d);
return 1;
}
oddgrades_t e;
e.mvec = vec * bvec;
if ((dvec3)e.vec != '4 6 1'd || (scalar_t)e.tvec != 20) {
printf ("vec • bvec != '4 6 1' + 20: %lv %g\n", e.vec, e.tvec);
return 1;
}
oddgrades_t f;
f.mvec = bvec * vec;
if ((dvec3)f.vec != '-4 -6 -1'd || (scalar_t)f.tvec != 20) {
printf ("bvec • vec != '-4 -6 -1' + 20: %lv %g\n", f.vec, f.tvec);
return 1;
}
if (vectvec || tvecvec) {
printf ("didn't get 0: %g %g", vectvec, tvecvec);
return 0;
}
auto g = vectvec;
if ((dvec3)g != '21 -14 0'd) {
printf ("vec • tvec != '21 -14 0': %lv\n", g);
return 1;
}
auto h = tvecvec;
if ((dvec3)h != '21 -14 0'd) {
printf ("vec • tvec != '21 -14 0': %lv\n", h);
return 1;
}
auto i = vec * tvec;
if ((dvec3)i != '21 -14 0'd) {
printf ("vec * tvec != '21 -14 0': %lv\n", i);
return 1;
}
auto j = tvec * vec;
if ((dvec3)j != '21 -14 0'd) {
printf ("vec * tvec != '21 -14 0': %lv\n", j);
return 1;
}
if (bvectvec || tvecbvec) {
printf ("didn't get 0: %g %g", bvectvec, tvecbvec);
return 0;
}
auto k = bvectvec;
if ((dvec3)k != '0 0 -14'd) {
printf ("bvec • tvec != '0 0 -14': %lv\n", k);
return 1;
}
auto l = tvecbvec;
if ((dvec3)l != '0 0 -14'd) {
printf ("tvec • bvec != '0 0 -14': %lv\n", l);
return 1;
}
auto m = bvec * tvec;
if ((dvec3)m != '0 0 -14'd) {
printf ("bvec * tvec != '0 0 -14': %lv\n", m);
return 1;
}
auto n = tvec * bvec;
if ((dvec3)n != '0 0 -14'd) {
printf ("tvec * bvec != '0 0 -14': %lv\n", n);
return 1;
}
// if (vecvec || bvecbvec || tvectvec) {
// printf ("didn't get 0: %g %g %g", vecvec, bvecbvec, tvectvec);
// return 0;
// }
auto o = vecvecb;
if ((dvec3)o != '14 44 46'd) {
printf ("vec ∧ vecb != '14 44 46': %lv\n", o);
return 1;
}
auto p = vecbvec;
if ((dvec3)p != '-14 -44 -46'd) {
printf ("vecb ∧ vec != '-14 -44 -46': %lv\n", p);
return 1;
}
auto q = vecvecb;
if (q != -9) {
printf ("vec • vecb != -9: %g\n", q);
return 1;
}
auto r = vecbvec;
if (r != -9) {
printf ("vecb • vec != -9: %g\n", r);
return 1;
}
evengrades_t s;
s.mvec= vec * vecb;
if (s.scalar != -9 || (dvec3)s.bvec != '14 44 46'd) {
printf ("vec * vecb != -9, '14 44 46': %g %lv\n",
s.scalar, s.bvec);
return 1;
}
evengrades_t t;
t.mvec = vecb * vec;
if (t.scalar != -9 || (dvec3)t.bvec != '-14 -44 -46'd) {
printf ("vecb * vec != -9, '-14 -44 -46': %g %lv\n",
t.scalar, t.bvec);
return 1;
}
if (bvecbvecb || tvectvecb) {
printf ("didn't get 0: %g %g", bvecbvecb, tvectvecb);
return 0;
}
auto u = bvecbvecb;
if (u != -2) {
printf ("bvec • bvecb != -2: %g\n", u);
return 1;
}
auto v = bvecbbvec;
if (v != -2) {
printf ("bvecb • bvec != -2: %g\n", v);
return 1;
}
evengrades_t w;
w.mvec = bvec * bvecb;
if (w.scalar != -2 || (dvec3)w.bvec != '11 -8 0'd) {
printf ("bvec * bvecb != -2, '11 -8 0': %g %lv\n",
w.scalar, w.bvec);
return 1;
}
evengrades_t x;
x.mvec = bvecb * bvec;
if (x.scalar != -2 || (dvec3)x.bvec != '-11 8 0'd) {
printf ("vecb * vec != -2, '-11 8 0': %g %lv\n",
x.scalar, x.bvec);
return 1;
}
if (tvectvecb || tvec * tvecb) {
printf ("didn't get 0: %g %g", tvectvecb, tvec * tvecb);
return 0;
}
e.mvec = e.mvec; // odd
if ((dvec3)e.vec != '4 6 1'd || (scalar_t)e.tvec != -20) {
printf ("odd† != '4 6 1' + -20: %lv %g\n", e.vec, e.tvec);
return 1;
}
s.mvec = s.mvec; // even
if (s.scalar != -9 || (dvec3)s.bvec != '-14 -44 -46'd) {
printf ("even† != -9, '-14 -44 -46': %g %lv\n",
s.scalar, s.bvec);
return 1;
}
e.mvec = e.mvec / 2; // odd
if ((dvec3)e.vec != '2 3 0.5'd || (scalar_t)e.tvec != -10) {
printf ("odd† != '2 3 0.5' + -10: %lv %g\n", e.vec, e.tvec);
return 1;
}
s.mvec = s.mvec / 2; // even
if (s.scalar != -4.5 || (dvec3)s.bvec != '-7 -22 -23'd) {
printf ("even† != -4.5, '-7 -22 -23': %g %lv\n",
s.scalar, s.bvec);
return 1;
}
e.mvec = -e.mvec; // odd
if ((dvec3)e.vec != '-2 -3 -0.5'd || (scalar_t)e.tvec != 10) {
printf ("odd† != '-2 -3 -0.5' + 10: %lv %g\n", e.vec, e.tvec);
return 1;
}
s.mvec = -s.mvec; // even
if (s.scalar != 4.5 || (dvec3)s.bvec != '7 22 23'd) {
printf ("even† != 4.5, '7 22 23': %g %lv\n",
s.scalar, s.bvec);
return 1;
}
evengrades_t dual_e;
dual_e.mvec =e.mvec; // test both dual operators
if ((dvec3)dual_e.bvec != '-2 -3 -0.5'd || dual_e.scalar != 10) {
printf ("⋆odd != '-2 -3 -0.5' + 10: %lv %g\n", e.vec, e.tvec);
return 1;
}
oddgrades_t dual_s;
dual_s.mvec = !s.mvec; // test both dual operators
if ((scalar_t)dual_s.tvec != 4.5 || (dvec3)dual_s.vec != '7 22 23'd) {
printf ("!even != 4.5, '7 22 23': %g %lv\n",
s.scalar, s.bvec);
return 1;
}
auto line = bvec bvecb;
if ((dvec3)line != '-11 8 34'd) {
printf ("bvec bvecb != '-11 8 34': %lv\n", line);
return 1;
}
return 0; // to survive and prevail :)
}