[qfcc] Make the GA tests a little easier to "use"

All errors are printed now, and the line numbers of the error message
are given, making finding the offending test much easier.
This commit is contained in:
Bill Currie 2024-12-07 02:52:10 +09:00
parent c5d77141eb
commit a91595ad6b
3 changed files with 244 additions and 341 deletions

View file

@ -1,5 +1,13 @@
#include "test-harness.h"
#pragma warn no-vararg-integer
#define error(fmt, ...) \
do { \
printf ("%s:%d: in %s: " fmt, __FILE__, __LINE__, __FUNCTION__ \
__VA_OPT__(,) __VA_ARGS__); \
ret = 1; \
} while (false)
typedef @algebra(double(2,0,1)) PGA;
typedef PGA.group_mask(0x08) scalar_t;
typedef PGA.group_mask(0x01) vector_t;
@ -23,6 +31,7 @@ typedef union {
static int
test_dual (void)
{
int ret = 0;
@algebra (PGA) {
auto a = 1f;
auto a0 = e0;
@ -32,11 +41,12 @@ test_dual (void)
auto a01 = e01;
auto a20 = e20;
auto a012 = e012;
#define TEST_DUAL(x, y) \
if (x != y) { \
printf ("⋆" #x " != " #y "\n"); \
return 1; \
}
#define TEST_DUAL(x, y) \
do { \
if (x != y) { \
error ("⋆" #x " != " #y "\n"); \
} \
} while (false)
TEST_DUAL (a, e012);
TEST_DUAL (a0, e12);
TEST_DUAL (a1, e20);
@ -45,13 +55,14 @@ test_dual (void)
TEST_DUAL (a01, e2);
TEST_DUAL (a12, e0);
TEST_DUAL (a012, 1);
#undef TEST_DUAL
#undef TEST_DUAL
#define TEST_DUAL(x) \
if (x *x != e012) { \
printf (#x " * ⋆" #x " != e012\n"); \
return 1; \
}
#define TEST_DUAL(x) \
do { \
if (x *x != e012) { \
error (#x " * ⋆" #x " != e012\n"); \
} \
} while (false)
TEST_DUAL (a);
TEST_DUAL (a0);
TEST_DUAL (a1);
@ -62,12 +73,13 @@ test_dual (void)
TEST_DUAL (a012);
#undef TEST_DUAL
}
return 0;
return ret;
}
static int
test_undual (void)
{
int ret = 0;
@algebra (PGA) {
auto a = 1f;
auto a0 = e0;
@ -77,11 +89,12 @@ test_undual (void)
auto a01 = e01;
auto a20 = e20;
auto a012 = e012;
#define TEST_UNDUAL(x, y) \
if (@undual x != y) { \
printf ("@undual " #x " != " #y "\n"); \
return 1; \
}
#define TEST_UNDUAL(x, y) \
do { \
if (@undual x != y) { \
error ("@undual " #x " != " #y "\n"); \
} \
} while (false)
TEST_UNDUAL (a, e012);
TEST_UNDUAL (a0, e12);
TEST_UNDUAL (a1, e20);
@ -92,11 +105,12 @@ test_undual (void)
TEST_UNDUAL (a012, 1);
#undef TEST_UNDUAL
#define TEST_UNDUAL(x) \
if (@undual x * x != e012) { \
printf ("@undual " #x " * " #x " != e012\n"); \
return 1; \
}
#define TEST_UNDUAL(x) \
do { \
if (@undual x * x != e012) { \
error ("@undual " #x " * " #x " != e012\n"); \
} \
} while (false)
TEST_UNDUAL (a);
TEST_UNDUAL (a0);
TEST_UNDUAL (a1);
@ -107,29 +121,26 @@ test_undual (void)
TEST_UNDUAL (a012);
#undef TEST_DUAL
}
return 0;
return ret;
}
int
main (void)
{
int ret = 0;
if (sizeof (scalar_t) != sizeof (double)) {
printf ("scalar has wrong size: %d\n", sizeof (scalar_t));
return 1;
error ("scalar has wrong size: %d\n", sizeof (scalar_t));
}
// vector_t is a vec3 but has alignment of 4 thus sizeof of 4 * scalar
if (sizeof (vector_t) != 4 * sizeof (scalar_t)) {
printf ("vector has wrong size: %d\n", sizeof (vector_t));
return 1;
error ("vector has wrong size: %d\n", sizeof (vector_t));
}
// bivector_t is a vec3 but has alignment of 4 thus sizeof of 4 * scalar
if (sizeof (bivector_t) != 4 * sizeof (scalar_t)) {
printf ("bivector has wrong size: %d\n", sizeof (bivector_t));
return 1;
error ("bivector has wrong size: %d\n", sizeof (bivector_t));
}
if (sizeof (trivector_t) != sizeof (scalar_t)) {
printf ("trivector has wrong size: %d\n", sizeof (trivector_t));
return 1;
error ("trivector has wrong size: %d\n", sizeof (trivector_t));
}
scalar_t scalar;
vector_t vec, vecb;
@ -146,231 +157,194 @@ main (void)
tvecb = 3*e012;
}
if (scalar != 42) {
printf ("scalar != 42: %g\n", scalar);
return 1;
error ("scalar != 42: %g\n", scalar);
}
if ((dvec3)vec != '3 -2 1'd) {
printf ("vec != '3 -2 1': %lv\n", vec);
return 1;
error ("vec != '3 -2 1': %lv\n", vec);
}
if ((dvec3)bvec != '4 -3 2'd) {
printf ("vec != '4 -3 2': %lv\n", bvec);
return 1;
error ("vec != '4 -3 2': %lv\n", bvec);
}
if ((double)tvec != 7) {
printf ("tvec != 7: %g\n", tvec);
return 1;
error ("tvec != 7: %g\n", tvec);
}
auto a = vecbvec;
if ((double)a != 20) {
printf ("vec ∧ bvec != 20: %lv\n", a);
return 1;
error ("vec ∧ bvec != 20: %lv\n", a);
}
auto b = bvecvec;
if ((double)b != 20) {
printf ("bvec ∧ vec != 20: %lv\n", b);
return 1;
error ("bvec ∧ vec != 20: %lv\n", b);
}
auto c = vecbvec;
if ((dvec3)c != '4 6 1'd) {
printf ("vec • bvec != '4 6 1': %lv\n", c);
return 1;
error ("vec • bvec != '4 6 1': %lv\n", c);
}
auto d = bvecvec;
if ((dvec3)d != '-4 -6 -1'd) {
printf ("bvec • vec != '-4 -6 -1': %lv\n", d);
return 1;
error ("bvec • vec != '-4 -6 -1': %lv\n", d);
}
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;
error ("vec • bvec != '4 6 1' + 20: %lv + %g\n", e.vec, e.tvec);
}
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;
error ("bvec • vec != '-4 -6 -1' + 20: %lv %g\n", f.vec, f.tvec);
}
if (vectvec || tvecvec) {
printf ("didn't get 0: %g %g", vectvec, tvecvec);
error ("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;
error ("vec • tvec != '21 -14 0': %lv\n", g);
}
auto h = tvecvec;
if ((dvec3)h != '21 -14 0'd) {
printf ("vec • tvec != '21 -14 0': %lv\n", h);
return 1;
error ("vec • tvec != '21 -14 0': %lv\n", h);
}
auto i = vec * tvec;
if ((dvec3)i != '21 -14 0'd) {
printf ("vec * tvec != '21 -14 0': %lv\n", i);
return 1;
error ("vec * tvec != '21 -14 0': %lv\n", i);
}
auto j = tvec * vec;
if ((dvec3)j != '21 -14 0'd) {
printf ("vec * tvec != '21 -14 0': %lv\n", j);
return 1;
error ("vec * tvec != '21 -14 0': %lv\n", j);
}
if (bvectvec || tvecbvec) {
printf ("didn't get 0: %g %g", bvectvec, tvecbvec);
error ("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;
error ("bvec • tvec != '0 0 -14': %lv\n", k);
}
auto l = tvecbvec;
if ((dvec3)l != '0 0 -14'd) {
printf ("tvec • bvec != '0 0 -14': %lv\n", l);
return 1;
error ("tvec • bvec != '0 0 -14': %lv\n", l);
}
auto m = bvec * tvec;
if ((dvec3)m != '0 0 -14'd) {
printf ("bvec * tvec != '0 0 -14': %lv\n", m);
return 1;
error ("bvec * tvec != '0 0 -14': %lv\n", m);
}
auto n = tvec * bvec;
if ((dvec3)n != '0 0 -14'd) {
printf ("tvec * bvec != '0 0 -14': %lv\n", n);
return 1;
error ("tvec * bvec != '0 0 -14': %lv\n", n);
}
// if (vecvec || bvecbvec || tvectvec) {
// printf ("didn't get 0: %g %g %g", vecvec, bvecbvec, tvectvec);
// error ("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;
error ("vec ∧ vecb != '14 44 46': %lv\n", o);
}
auto p = vecbvec;
if ((dvec3)p != '-14 -44 -46'd) {
printf ("vecb ∧ vec != '-14 -44 -46': %lv\n", p);
return 1;
error ("vecb ∧ vec != '-14 -44 -46': %lv\n", p);
}
auto q = vecvecb;
if (q != -9) {
printf ("vec • vecb != -9: %g\n", q);
return 1;
error ("vec • vecb != -9: %g\n", q);
}
auto r = vecbvec;
if (r != -9) {
printf ("vecb • vec != -9: %g\n", r);
return 1;
error ("vecb • vec != -9: %g\n", r);
}
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",
error ("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",
error ("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);
error ("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;
error ("bvec • bvecb != -2: %g\n", u);
}
auto v = bvecbbvec;
if (v != -2) {
printf ("bvecb • bvec != -2: %g\n", v);
return 1;
error ("bvecb • bvec != -2: %g\n", v);
}
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",
error ("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",
error ("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);
error ("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;
error ("odd† != '4 6 1' + -20: %lv %g\n", e.vec, e.tvec);
}
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",
error ("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;
error ("odd† != '2 3 0.5' + -10: %lv %g\n", e.vec, e.tvec);
}
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",
error ("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;
error ("odd† != '-2 -3 -0.5' + 10: %lv %g\n", e.vec, e.tvec);
}
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",
error ("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;
error ("⋆odd != '-2 -3 -0.5' + 10: %lv %g\n", e.vec, e.tvec);
}
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",
error ("!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(%lv) bvecb(%lv) != '-11 8 34': %lv\n", bvec, bvecb, line);
return 1;
error ("bvec(%lv) bvecb(%lv) != '-11 8 34': %lv\n", bvec, bvecb, line);
}
if (test_dual ()) {
printf ("dual failed\n");
return 1;
ret = 1;
}
if (test_undual ()) {
printf ("dual failed\n");
return 1;
ret = 1;
}
return 0; // to survive and prevail :)
return ret;
}

View file

@ -1,5 +1,13 @@
#include "test-harness.h"
#pragma warn no-vararg-integer
#define error(fmt, ...) \
do { \
printf ("%s:%d: in %s: " fmt, __FILE__, __LINE__, __FUNCTION__ \
__VA_OPT__(,) __VA_ARGS__); \
ret = 1; \
} while (false)
typedef @algebra(float(3,0,1)) PGA;
typedef PGA.group_mask(0x04) scalar_t;
typedef PGA.group_mask(0x01) vector_t;
@ -33,6 +41,7 @@ typedef union {
static int
test_wedge (void)
{
int ret = 0;
scalar_t scalar;
vector_t vec, vecb, vecc, vecd;
bivector_t bvec, bvecb;
@ -55,80 +64,68 @@ test_wedge (void)
}
if (scalar != 42) {
printf ("scalar != 42: %g\n", scalar);
return 1;
error ("scalar != 42: %g\n", scalar);
}
if ((vec4)vec != '3 -2 4 1') {
printf ("vec != '3 -2 4 1': %q\n", vec);
return 1;
error ("vec != '3 -2 4 1': %q\n", vec);
}
if ((vec3)bvec.dir != '11 -4 2' || (vec3)bvec.mom != '-3 5 7') {
printf ("bvec != '11 -4 2' '-3 5 7': %v %v\n", bvec.dir, bvec.mom);
return 1;
error ("bvec != '11 -4 2' '-3 5 7': %v %v\n", bvec.dir, bvec.mom);
}
if ((vec4)tvec != '1 4 7 -2') {
printf ("tvec != '1 4 7 -2': %g\n", tvec);
return 1;
error ("tvec != '1 4 7 -2': %g\n", tvec);
}
if ((scalar_t)qvec != 8) {
printf ("tvec != 8: %g\n", qvec);
return 1;
error ("tvec != 8: %g\n", qvec);
}
bivector_t a = { .bvec = vecvecb };
if ((vec3)a.dir != '-48 20 46' || (vec3)a.mom != '44 -14 52') {
printf ("vec ∧ vecb != '-48 20 46' '44 -14 52': %v %v\n", a.dir, a.mom);
return 1;
error ("vec ∧ vecb != '-48 20 46' '44 -14 52': %v %v\n", a.dir, a.mom);
}
auto b = a.bvecvecc;
if ((vec4)b != '358 -472 -430 -298') {
printf ("a ∧ vecc != '358 -472 -430 -298': %v\n", b);
return 1;
error ("a ∧ vecc != '358 -472 -430 -298': %v\n", b);
}
auto c = bvecd;
if ((scalar_t)c != 842) {
printf ("b ∧ vecd != 742': %g\n", c);
return 1;
error ("b ∧ vecd != 842': %g\n", c);
}
a.bvec = vecbvec;
if ((vec3)a.dir != '48 -20 -46' || (vec3)a.mom != '-44 14 -52') {
printf ("vecb ∧ vec != '48 -20 -46' '-44 14 -52': %v %v\n",
a.dir, a.mom);
return 1;
error ("vecb ∧ vec != '48 -20 -46' '-44 14 -52': %v %v\n",
a.dir, a.mom);
}
b = vecca.bvec;
if ((vec4)b != '-358 472 430 298') {
printf ("vecc ∧ a != '-358 472 430 298': %v\n", b);
return 1;
error ("vecc ∧ a != '-358 472 430 298': %v\n", b);
}
c = vecdb;
if ((scalar_t)c != 842) {
printf ("vecd ^ b != 842': %g\n", c);
return 1;
error ("vecd ^ b != 842': %g\n", c);
}
c = a.bvec(veccvecd);
if ((scalar_t)c != -842) {
printf ("a ∧ (vecc ∧ vecd) != -842': %g\n", c);
return 1;
error ("a ∧ (vecc ∧ vecd) != -842': %g\n", c);
}
c = (vecdvecc)a.bvec;
if ((scalar_t)c != 842) {
printf ("(vecd ∧ vecc) ∧ a != 842': %g\n", c);
return 1;
error ("(vecd ∧ vecc) ∧ a != 842': %g\n", c);
}
return 0;
return ret;
}
static int
test_dot (void)
{
int ret = 0;
scalar_t scalar;
vector_t vec, vecb, vecc, vecd;
bivector_t bvec, bvecb;
@ -151,98 +148,84 @@ test_dot (void)
}
if (qvecqvecb != 0) {
printf ("(qvec • qvecb) != 0': %g\n", qvecqvecb);
return 1;
error ("(qvec • qvecb) != 0': %g\n", qvecqvecb);
}
auto a = tvecqvec;
if ((vec4)a != '0 0 0 -16') {
printf ("vec • vecb != '0 0 0 -16': %v\n", a);
return 1;
error ("vec • vecb != '0 0 0 -16': %v\n", a);
}
bivector_t b = { .mom = bvec.bvecqvec };
if ((vec3)b.dir != '0 0 0' || (vec3)b.mom != '-88 32 -16') {
printf ("bvec • qvec != '0 0 0' '-88 32 -16': %v %v\n", b.dir, b.mom);
return 1;
error ("bvec • qvec != '0 0 0' '-88 32 -16': %v %v\n", b.dir, b.mom);
}
auto c = vecqvec;
if ((vec4)c != '24 -16 32 0') {
printf ("vec • qvec != '24 -16 32 0': %v\n", c);
return 1;
error ("vec • qvec != '24 -16 32 0': %v\n", c);
}
a = bvec.bvectvec;
if ((vec4)a != '22 -8 4 9') {
printf ("bvec • tvec != '22 -8 4 9': %v\n", a);
return 1;
error ("bvec • tvec != '22 -8 4 9': %v\n", a);
}
b.bvec = vectvec;
if ((vec3)b.dir != '-6 4 -8' || (vec3)b.mom != '30 17 -14') {
printf ("vec • tvec != '-6 4 -8' '30 17 -14': %v %v\n", b.dir, b.mom);
return 1;
error ("vec • tvec != '-6 4 -8' '30 17 -14': %v %v\n", b.dir, b.mom);
}
if (bvec.bvecbvec.bvec != -141) {
printf ("(bvec • bvec) != -141': %g\n", bvec.bvecbvec.bvec);
return 1;
error ("(bvec • bvec) != -141': %g\n", bvec.bvecbvec.bvec);
}
a = vecbvec.bvec;
if ((vec4)a != '-12 -38 -10 -9') {
printf ("vec • bvec != '-12 -38 -10 -9': %v\n", a);
return 1;
error ("vec • bvec != '-12 -38 -10 -9': %v\n", a);
}
if (vecvecb != -9) {
printf ("(vec • vecb) != -9': %g\n", vecvecb);
return 1;
error ("(vec • vecb) != -9': %g\n", vecvecb);
}
a = qvectvec;
if ((vec4)a != '0 0 0 16') {
printf ("vec • vecb != '0 0 0 16': %v\n", a);
return 1;
error ("vec • vecb != '0 0 0 16': %v\n", a);
}
b.bvec = qvecbvec.bvec;
if ((vec3)b.dir != '0 0 0' || (vec3)b.mom != '-88 32 -16') {
printf ("qvec • bvec != '0 0 0' '-88 32 -16': %v %v\n", b.dir, b.mom);
return 1;
error ("qvec • bvec != '0 0 0' '-88 32 -16': %v %v\n", b.dir, b.mom);
}
c = qvecvec;
if ((vec4)c != '-24 16 -32 0') {
printf ("vec • qvec != '-24 16 -32 0': %v\n", c);
return 1;
error ("vec • qvec != '-24 16 -32 0': %v\n", c);
}
a = tvecbvec.bvec;
if ((vec4)a != '22 -8 4 9') {
printf ("tvec • vec != '22 -8 4 9': %v\n", a);
return 1;
error ("tvec • vec != '22 -8 4 9': %v\n", a);
}
b.bvec = tvecvec;
if ((vec3)b.dir != '-6 4 -8' || (vec3)b.mom != '30 17 -14') {
printf ("tvec • vec != '-6 4 -8' '30 17 -14': %v %v\n", b.dir, b.mom);
return 1;
error ("tvec • vec != '-6 4 -8' '30 17 -14': %v %v\n", b.dir, b.mom);
}
a = bvec.bvecvec;
if ((vec4)a != '12 38 10 9') {
printf ("bvec • vec != '12 38 10 9': %q\n", a);
return 1;
error ("bvec • vec != '12 38 10 9': %q\n", a);
}
return 0;
return ret;
}
static int
test_geom (void)
{
int ret = 0;
scalar_t scalar;
vector_t vec, vecb, vecc, vecd;
bivector_t bvec, bvecb;
@ -265,114 +248,100 @@ test_geom (void)
}
if (qvec * qvecb != 0) {
printf ("(qvec * qvecb) != 0': %g\n", qvec * qvecb);
return 1;
error ("(qvec * qvecb) != 0': %g\n", qvec * qvecb);
}
auto a = tvec * qvec;
if ((vec4)a != '0 0 0 -16') {
printf ("vec * vecb != '0 0 0 -16': %v\n", a);
return 1;
error ("vec * vecb != '0 0 0 -16': %v\n", a);
}
bivector_t b = { .mom = bvec.bvec * qvec };
if ((vec3)b.dir != '0 0 0' || (vec3)b.mom != '-88 32 -16') {
printf ("bvec * qvec != '0 0 0' '-88 32 -16': %v %v\n", b.dir, b.mom);
return 1;
error ("bvec * qvec != '0 0 0' '-88 32 -16': %v %v\n", b.dir, b.mom);
}
auto c = vec * qvec;
if ((vec4)c != '24 -16 32 0') {
printf ("vec * qvec != '24 -16 32 0': %v\n", c);
return 1;
error ("vec * qvec != '24 -16 32 0': %v\n", c);
}
oddgrades_t d = { .mvec = bvec.bvec * tvec };
if ((vec4)d.vec != '22 -8 4 9' || (vec4)d.tvec != '30 85 -34 0') {
printf ("bvec * tvec != '22 -8 4 9' '30 85 -34 0': %q %q\n",
d.vec, d.tvec);
return 1;
error ("bvec * tvec != '22 -8 4 9' '30 85 -34 0': %q %q\n",
d.vec, d.tvec);
}
evengrades_t e = { .mvec = vec * tvec };
if ((vec3)e.dir != '-6 4 -8' || (vec3)e.mom != '30 17 -14'
|| e.scalar || (scalar_t)e.qvec != 21) {
printf ("vec * tvec != 0 '-6 4 -8' '30 17 -14' 21: %g %v %v %g\n",
e.scalar, e.bvec.dir, e.bvec.mom, e.qvec);
return 1;
error ("vec * tvec != 0 '-6 4 -8' '30 17 -14' 21: %g %v %v %g\n",
e.scalar, e.bvec.dir, e.bvec.mom, e.qvec);
}
e.mvec = bvec.bvec * bvec.bvec;
if (e.scalar != -141 || (vec3)e.bvec.dir || (vec3)e.bvec.mom
|| (scalar_t)e.qvec != -78) {
printf ("bvec * bvec != -141 '0 0 0' '0 0 0' -78: %g %v %v %g\n",
e.scalar, e.bvec.dir, e.bvec.mom, e.qvec);
return 1;
error ("bvec * bvec != -141 '0 0 0' '0 0 0' -78: %g %v %v %g\n",
e.scalar, e.bvec.dir, e.bvec.mom, e.qvec);
}
d = { .mvec = vec * bvec.bvec };
if ((vec4)d.vec != '-12 -38 -10 -9' || (vec4)d.tvec != '-45 -29 7 49') {
printf ("vec * bvec != '-12 -38 -10 -9' '-45 -29 7 49': %v %v\n",
d.vec, d.tvec);
return 1;
error ("vec * bvec != '-12 -38 -10 -9' '-45 -29 7 49': %v %v\n",
d.vec, d.tvec);
}
e.mvec = vec * vecb;
if (e.scalar != -9 || (scalar_t)e.qvec
|| (vec3)e.bvec.dir != '-48 20 46' || (vec3)e.bvec.mom != '44 -14 52') {
printf ("(vec * vecb) != -9 '-48 20 46' '44 -14 52' 0': %g %v %v %g\n",
e.scalar, e.bvec.dir, e.bvec.mom, e.qvec);
return 1;
error ("(vec * vecb) != -9 '-48 20 46' '44 -14 52' 0': %g %v %v %g\n",
e.scalar, e.bvec.dir, e.bvec.mom, e.qvec);
}
a = qvec * tvec;
if ((vec4)a != '0 0 0 16') {
printf ("vec * vecb != '0 0 0 16': %v\n", a);
return 1;
error ("vec * vecb != '0 0 0 16': %v\n", a);
}
e.mvec = qvec * bvec.bvec;
if (e.scalar || (scalar_t)e.qvec
|| (vec3)e.bvec.dir || (vec3)e.bvec.mom != '-88 32 -16') {
printf ("(vec * vecb) != 0 '0 0 0' '-88 32 -16' 0': %g %v %v %g\n",
e.scalar, e.bvec.dir, e.bvec.mom, e.qvec);
return 1;
error ("(vec * vecb) != 0 '0 0 0' '-88 32 -16' 0': %g %v %v %g\n",
e.scalar, e.bvec.dir, e.bvec.mom, e.qvec);
}
c = qvec * vec;
if ((vec4)c != '-24 16 -32 0') {
printf ("qvec * vec != '-24 16 -32 0': %q\n", c);
return 1;
error ("qvec * vec != '-24 16 -32 0': %q\n", c);
}
d = { .mvec = tvec * bvec.bvec };
if ((vec4)d.vec != '22 -8 4 9' || (vec4)d.tvec != '-30 -85 34 0') {
printf ("tvec * bvec != '22 -8 4 9' '-30 -85 34 0': %q %q\n",
d.vec, d.tvec);
return 1;
error ("tvec * bvec != '22 -8 4 9' '-30 -85 34 0': %q %q\n",
d.vec, d.tvec);
}
e.mvec = tvec * vec;
if (e.scalar || (scalar_t)e.qvec != -21
|| (vec3)e.bvec.dir != '-6 4 -8' || (vec3)e.bvec.mom != '30 17 -14') {
printf ("tvec * vec != 0 '-6 4 -8' '30 17 -14' -21: %g %v %v %g\n",
e.scalar, e.bvec.dir, e.bvec.mom, e.qvec);
return 1;
error ("tvec * vec != 0 '-6 4 -8' '30 17 -14' -21: %g %v %v %g\n",
e.scalar, e.bvec.dir, e.bvec.mom, e.qvec);
}
d.mvec = bvec.bvec * vec;
if ((vec4)d.vec != '12 38 10 9' || (vec4)d.tvec != '-45 -29 7 49') {
printf ("vec * bvec != '12 38 10 9' '-45 -29 7 49': %q %q\n",
d.vec, d.tvec);
return 1;
error ("vec * bvec != '12 38 10 9' '-45 -29 7 49': %q %q\n",
d.vec, d.tvec);
}
return 0;
return ret;
}
static int
test_dual (void)
{
int ret = 0;
@algebra (PGA) {
auto a = 1f;
auto a0 = e0;
@ -392,8 +361,7 @@ test_dual (void)
auto a0123 = e0123;
#define TEST_DUAL(x, y) \
if (x != y) { \
printf ("⋆" #x " != " #y "\n"); \
return 1; \
error ("⋆" #x " != " #y "\n"); \
}
TEST_DUAL (a, e0123);
TEST_DUAL (a0, e123);
@ -415,8 +383,7 @@ test_dual (void)
#define TEST_DUAL(x) \
if (x *x != e0123) { \
printf (#x " * ⋆" #x " != e0123\n"); \
return 1; \
error (#x " * ⋆" #x " != e0123\n"); \
}
TEST_DUAL (a);
TEST_DUAL (a0);
@ -436,12 +403,13 @@ test_dual (void)
TEST_DUAL (a0123);
#undef TEST_DUAL
}
return 0;
return ret;
}
static int
test_undual (void)
{
int ret = 0;
@algebra (PGA) {
auto a = 1f;
auto a0 = e0;
@ -461,8 +429,7 @@ test_undual (void)
auto a0123 = e0123;
#define TEST_UNDUAL(x, y) \
if (@undual x != y) { \
printf ("@undual" #x " != " #y "\n"); \
return 1; \
error ("@undual" #x " != " #y "\n"); \
}
TEST_UNDUAL (a, e0123);
TEST_UNDUAL (a0, -e123);
@ -484,8 +451,7 @@ test_undual (void)
#define TEST_UNDUAL(x) \
if (@undual x * x != e0123) { \
printf ("@undual " #x " * " #x " != e0123\n"); \
return 1; \
error ("@undual " #x " * " #x " != e0123\n"); \
}
TEST_UNDUAL (a);
TEST_UNDUAL (a0);
@ -505,12 +471,13 @@ test_undual (void)
TEST_UNDUAL (a0123);
#undef TEST_UNDUAL
}
return 0;
return ret;
}
static int
test_basics (void)
{
int ret = 0;
@algebra (PGA) {
auto plane1 = e1 + 8*e0;
auto plane2 = e2 + 8*e0;
@ -523,68 +490,56 @@ test_basics (void)
auto x = point @regressive rot;
if ((vec4)plane1 != '1 0 0 8' || (vec4)plane2 != '0 1 0 8') {
printf ("plane1 or plane2 wrong: %q %q\n", plane1, plane2);
return 1;
error ("plane1 or plane2 wrong: %q %q\n", plane1, plane2);
}
if ((vec4)p != '0 0 -3 1' || (vec4)p1 != '12 4 0 1'
|| (vec4)p2 != '4 12 0 1') {
printf ("p or p1 or p2 wrong: %q %q %q\n", p, p1, p2);
return 1;
error ("p or p1 or p2 wrong: %q %q %q\n", p, p1, p2);
}
bivector_t b = { .bvec = line };
if ((vec3)b.dir != '0 0 1' || (vec3)b.mom != '-8 8 0') {
printf ("line is wrong: %v %v\n", b.dir, b.mom);
return 1;
error ("line is wrong: %v %v\n", b.dir, b.mom);
}
oddgrades_t o = { .mvec = point };
if ((vec4)o.vec || (vec4)o.tvec != '-8 -8 -3 1') {
printf ("point is wrong: %q\n", point);
return 1;
error ("point is wrong: %q\n", point);
}
o.mvec = rot;
if ((vec4)o.vec || (vec4)o.tvec != '-16 -16 -3 1') {
printf ("rot is wrong: %q %q\n", o.vec, o.tvec);
return 1;
error ("rot is wrong: %q %q\n", o.vec, o.tvec);
}
evengrades_t e = { .mvec = x };
if (e.scalar || (scalar_t)e.qvec
|| (vec3)e.dir != '-8 -8 0' || (vec3)e.mom != '-24 24 0') {
printf ("x is wrong: %g %v %v %g\n",
e.scalar, e.dir, e.mom, e.qvec);
return 1;
error ("x is wrong: %g %v %v %g\n", e.scalar, e.dir, e.mom, e.qvec);
}
}
return 0;
return ret;
}
int
main (void)
{
int ret = 0;
if (sizeof (scalar_t) != sizeof (float)) {
printf ("scalar has wrong size: %d\n", sizeof (scalar_t));
return 1;
error ("scalar has wrong size: %d\n", sizeof (scalar_t));
}
if (sizeof (vector_t) != 4 * sizeof (scalar_t)) {
printf ("bivector has wrong size: %d\n", sizeof (vector_t));
return 1;
error ("bivector has wrong size: %d\n", sizeof (vector_t));
}
// the pair of vec3s in a bivector have an alignment of 4
if (sizeof (bivector_t) != 8 * sizeof (scalar_t)) {
printf ("bivector has wrong size: %d\n", sizeof (bivector_t));
return 1;
error ("bivector has wrong size: %d\n", sizeof (bivector_t));
}
if (sizeof (bivector_t) != sizeof (PGA.group_mask(0x0a))) {
printf ("bivector group has wrong size: %d\n",
error ("bivector group has wrong size: %d\n",
sizeof (PGA.group_mask(0x0a)));
return 1;
}
if (sizeof (trivector_t) != 4 * sizeof (scalar_t)) {
printf ("trivector has wrong size: %d\n", sizeof (trivector_t));
return 1;
error ("trivector has wrong size: %d\n", sizeof (trivector_t));
}
if (sizeof (quadvector_t) != sizeof (scalar_t)) {
printf ("quadvector has wrong size: %d\n", sizeof (quadvector_t));
return 1;
error ("quadvector has wrong size: %d\n", sizeof (quadvector_t));
}
if (sizeof (evengrades_t) != sizeof (bivector_t)) {
evengrades_t e;
@ -596,38 +551,38 @@ main (void)
printf ("mvec: %d, bvec: %d, scalar: %d, qvec: %d\n",
offsetof (evengrades_t, mvec), offsetof (evengrades_t, bvec),
offsetof (evengrades_t, scalar), offsetof (evengrades_t, qvec));
return 1;
ret = 1;
}
if (test_wedge ()) {
printf ("wedge products failed\n");
return 1;
ret = 1;
}
if (test_dot ()) {
printf ("dot products failed\n");
return 1;
ret = 1;
}
if (test_geom ()) {
printf ("geometric products failed\n");
return 1;
ret = 1;
}
if (test_dual ()) {
printf ("dual failed\n");
return 1;
ret = 1;
}
if (test_undual ()) {
printf ("dual failed\n");
return 1;
ret = 1;
}
if (test_basics ()) {
printf ("basics failed\n");
return 1;
ret = 1;
}
return 0; // to survive and prevail :)
return ret;
}

View file

@ -1,5 +1,13 @@
#include "test-harness.h"
#pragma warn no-vararg-integer
#define error(fmt, ...) \
do { \
printf ("%s:%d: in %s: " fmt, __FILE__, __LINE__, __FUNCTION__ \
__VA_OPT__(,) __VA_ARGS__); \
ret = 1; \
} while (false)
typedef @algebra(float(3,0,0)) VGA;
typedef VGA.group_mask(0x08) scalar_t;
typedef VGA.group_mask(0x01) vector_t;
@ -23,6 +31,7 @@ typedef union {
static int
test_wedge (void)
{
int ret = 0;
scalar_t scalar;
vector_t vec, vecb, vecc, vecd;
bivector_t bvec, bvecb;
@ -42,75 +51,64 @@ test_wedge (void)
}
if (scalar != 42) {
printf ("scalar != 42: %g\n", scalar);
return 1;
error ("scalar != 42: %g\n", scalar);
}
if ((vec3)vec != '3 -2 4') {
printf ("vec != '3 -2 4': %v\n", vec);
return 1;
error ("vec != '3 -2 4': %v\n", vec);
}
if ((vec3)bvec != '11 -4 2') {
printf ("bvec != '11 -4 2': %v\n", bvec);
return 1;
error ("bvec != '11 -4 2': %v\n", bvec);
}
if ((scalar_t)tvec != 2) {
printf ("tvec != 2: %g\n", (scalar_t)tvec);
return 1;
error ("tvec != 2: %g\n", (scalar_t)tvec);
}
bivector_t a = vecvecb;
if ((vec3)a != '-48 20 46') {
printf ("vec ∧ vecb != '-48 20 46': %v\n", a);
return 1;
error ("vec ∧ vecb != '-48 20 46': %v\n", a);
}
auto b = avecc;
if ((scalar_t)b != -298) {
printf ("a ∧ vecc != -298: %g\n", (scalar_t)b);
return 1;
error ("a ∧ vecc != -298: %g\n", (scalar_t)b);
}
auto c = bvecd;
if ((scalar_t)c != 0) {
printf ("b ∧ vecd != 0': %g\n", (scalar_t) c);
return 1;
error ("b ∧ vecd != 0': %g\n", (scalar_t) c);
}
a = vecbvec;
if ((vec3)a != '48 -20 -46') {
printf ("vecb ∧ vec != '48 -20 -46': %v\n", a);
return 1;
error ("vecb ∧ vec != '48 -20 -46': %v\n", a);
}
b = vecca;
if ((scalar_t)b != 298) {
printf ("vecc ∧ a != 298: %g\n", (scalar_t)b);
return 1;
error ("vecc ∧ a != 298: %g\n", (scalar_t)b);
}
c = vecdb;
if ((scalar_t)c != 0) {
printf ("vecd ^ b != 0': %g\n", (scalar_t) c);
return 1;
error ("vecd ^ b != 0': %g\n", (scalar_t) c);
}
c = a(veccvecd);
if ((scalar_t)c != 0) {
printf ("a ∧ (vecc ∧ vecd) != 0': %g\n", (scalar_t) c);
return 1;
error ("a ∧ (vecc ∧ vecd) != 0': %g\n", (scalar_t) c);
}
c = (vecdvecc)a;
if ((scalar_t)c != 0) {
printf ("(vecd ∧ vecc) ∧ a != 0': %g\n", (scalar_t) c);
return 1;
error ("(vecd ∧ vecc) ∧ a != 0': %g\n", (scalar_t) c);
}
return 0;
return ret;
}
static int
test_dot (void)
{
int ret = 0;
scalar_t scalar;
vector_t vec, vecb, vecc, vecd;
bivector_t bvec, bvecb;
@ -131,62 +129,54 @@ test_dot (void)
auto a = bvectvec;
if ((vec3)a != '-88 32 -16') {
printf ("bvec • tvec != '-88 32 -16': %v\n", a);
return 1;
error ("bvec • tvec != '-88 32 -16': %v\n", a);
}
auto b = vectvec;
if ((vec3)b != '24 -16 32') {
printf ("vec • tvec != '24 -16 32': %v\n", b);
return 1;
error ("vec • tvec != '24 -16 32': %v\n", b);
}
if (bvecbvec != -141) {
printf ("(bvec • bvec) != -141': %g\n", bvecbvec);
return 1;
error ("(bvec • bvec) != -141': %g\n", bvecbvec);
}
a = vecbvec;
if ((vec3)a != '-12 -38 -10') {
printf ("vec • bvec != '-12 -38 -10': %v\n", a);
return 1;
error ("vec • bvec != '-12 -38 -10': %v\n", a);
}
if (vecvecb != -9) {
printf ("(vec • vecb) != -9': %g\n", vecvecb);
return 1;
error ("(vec • vecb) != -9': %g\n", vecvecb);
}
auto d = tvectvec;
if (d != -64) {
printf ("tvec • tvec != -64: %g\n", a);
return 1;
error ("tvec • tvec != -64: %g\n", a);
}
a = tvecbvec;
if ((vec3)a != '-88 32 -16') {
printf ("tvec • vec != '-88 32 -16': %v\n", a);
return 1;
error ("tvec • vec != '-88 32 -16': %v\n", a);
}
b = tvecvec;
if ((vec3)b != '24 -16 32') {
printf ("tvec • vec != '24 -16 32': %v\n", b);
return 1;
error ("tvec • vec != '24 -16 32': %v\n", b);
}
a = bvecvec;
if ((vec3)a != '12 38 10') {
printf ("bvec • vec != '12 38 10': %v\n", a);
return 1;
error ("bvec • vec != '12 38 10': %v\n", a);
}
return 0;
return ret;
}
static int
test_geom (void)
{
int ret = 0;
scalar_t scalar;
vector_t vec, vecb, vecc, vecd;
bivector_t bvec, bvecb;
@ -206,62 +196,53 @@ test_geom (void)
}
if (tvec * tvecb != -8) {
printf ("(tvec * tvecb) != -8': %g\n", tvec * tvecb);
return 1;
error ("(tvec * tvecb) != -8': %g\n", tvec * tvecb);
}
auto d = bvec * tvec;
if ((vec3)d != '-88 32 -16') {
printf ("bvec * tvec != '-88 32 -16': %v\n", d);
return 1;
error ("bvec * tvec != '-88 32 -16': %v\n", d);
}
auto e = vec * tvec;
if ((vec3)e != '24 -16 32') {
printf ("vec * tvec != 0 '24 -16 32': %v\n", e);
return 1;
error ("vec * tvec != 0 '24 -16 32': %v\n", e);
}
auto f = bvec * bvec;
if (f != -141) {
printf ("bvec * bvec != -141: %g\n", f);
return 1;
error ("bvec * bvec != -141: %g\n", f);
}
oddgrades_t odd = { .mvec = vec * bvec };
if ((vec3)odd.vec != '-12 -38 -10' || (scalar_t)odd.tvec != 49) {
printf ("vec * bvec != '-12 -38 -10' 49: %v %g\n",
odd.vec, (scalar_t)odd.tvec);
return 1;
error ("vec * bvec != '-12 -38 -10' 49: %v %g\n",
odd.vec, (scalar_t)odd.tvec);
}
evengrades_t even = { .mvec = vec * vecb };
if (even.scalar != -9 || (vec3)even.bvec != '-48 20 46') {
printf ("(vec * vecb) != -9 '-48 20 46': %g %v\n",
even.scalar, even.bvec);
return 1;
error ("(vec * vecb) != -9 '-48 20 46': %g %v\n",
even.scalar, even.bvec);
}
auto b = tvec * bvec;
if ((vec3)b != '-88 32 -16') {
printf ("tvec * bvec != '-88 32 -16': %v\n", b);
return 1;
error ("tvec * bvec != '-88 32 -16': %v\n", b);
}
e = tvec * vec;
if ((vec3)e != '24 -16 32') {
printf ("tvec * vec != '24 -16 32': %v\n", e);
return 1;
error ("tvec * vec != '24 -16 32': %v\n", e);
}
odd.mvec = bvec * vec;
if ((vec3)odd.vec != '12 38 10' || (scalar_t)odd.tvec != 49) {
printf ("vec * bvec != '12 38 10' 49: %v %g\n",
odd.vec, (scalar_t)odd.tvec);
return 1;
error ("vec * bvec != '12 38 10' 49: %v %g\n",
odd.vec, (scalar_t)odd.tvec);
}
return 0;
return ret;
}
static int
@ -273,21 +254,18 @@ test_basics (void)
int
main (void)
{
int ret = 0;
if (sizeof (scalar_t) != sizeof (float)) {
printf ("scalar has wrong size: %d\n", sizeof (scalar_t));
return 1;
error ("scalar has wrong size: %d\n", sizeof (scalar_t));
}
if (sizeof (vector_t) != 4 * sizeof (scalar_t)) {
printf ("vector has wrong size: %d\n", sizeof (vector_t));
return 1;
error ("vector has wrong size: %d\n", sizeof (vector_t));
}
if (sizeof (bivector_t) != 4 * sizeof (scalar_t)) {
printf ("bivector has wrong size: %d\n", sizeof (bivector_t));
return 1;
error ("bivector has wrong size: %d\n", sizeof (bivector_t));
}
if (sizeof (trivector_t) != sizeof (scalar_t)) {
printf ("trivector has wrong size: %d\n", sizeof (trivector_t));
return 1;
error ("trivector has wrong size: %d\n", sizeof (trivector_t));
}
if (sizeof (evengrades_t) != 4) {
evengrades_t e;
@ -298,7 +276,7 @@ main (void)
printf ("mvec: %d, bvec: %d, scalar: %d\n",
offsetof (evengrades_t, mvec), offsetof (evengrades_t, bvec),
offsetof (evengrades_t, scalar));
return 1;
ret = 1;
}
if (sizeof (oddgrades_t) != 4) {
oddgrades_t o;
@ -309,28 +287,24 @@ main (void)
printf ("mvec: %d, vec: %d, tvec: %d\n",
offsetof (oddgrades_t, mvec), offsetof (oddgrades_t, vec),
offsetof (oddgrades_t, tvec));
return 1;
ret = 1;
}
if (test_wedge ()) {
printf ("wedge products failed\n");
return 1;
error ("wedge products failed\n");
}
if (test_dot ()) {
printf ("dot products failed\n");
return 1;
error ("dot products failed\n");
}
if (test_geom ()) {
printf ("geometric products failed\n");
return 1;
error ("geometric products failed\n");
}
if (test_basics ()) {
printf ("basics failed\n");
return 1;
error ("basics failed\n");
}
return 0; // to survive and prevail :)
return ret;
}