From 55b754745124d2284f2100f2f39bc6d511570ede Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sun, 27 Aug 2023 15:24:35 +0900 Subject: [PATCH] [qfcc] Get the rest of the main 2d PGA products working That was tedious. I can't say I'm looking forward to writing the tests for 3d. And even though trivector . bivector and bivector . trivector give the same answer, they're not really commutative when it comes to the code. --- tools/qfcc/source/expr_algebra.c | 48 +++++++++-- tools/qfcc/test/pga2d.r | 142 ++++++++++++++++++++++++++++--- 2 files changed, 171 insertions(+), 19 deletions(-) diff --git a/tools/qfcc/source/expr_algebra.c b/tools/qfcc/source/expr_algebra.c index a53a5c2fe..551c61dd1 100644 --- a/tools/qfcc/source/expr_algebra.c +++ b/tools/qfcc/source/expr_algebra.c @@ -549,6 +549,17 @@ pga2_yw_wx_xy_dot_x_y_w (expr_t **c, expr_t *a, expr_t *b, algebra_t *alg) c[2] = sum_expr (dot_type, '+', scale_expr (dot_type, vb, sa), tmp); } +static void +pga2_yw_wx_xy_dot_wxy (expr_t **c, expr_t *a, expr_t *b, algebra_t *alg) +{ + auto stype = alg->type; + auto sa = offset_cast (stype, a, 2); + auto sb = offset_cast (stype, b, 0); + sb = unary_expr ('-', sb); + auto cs = scale_expr (stype, sa, sb); + c[0] = new_extend_expr (cs, algebra_mvec_type (alg, 0x01), 0, true); +} + static void pga2_x_y_w_dot_yw_wx_xy (expr_t **c, expr_t *a, expr_t *b, algebra_t *alg) { @@ -580,11 +591,22 @@ pga2_x_y_w_dot_wxy (expr_t **c, expr_t *a, expr_t *b, algebra_t *alg) auto vtype = vector_type (stype, 2); auto dot_type = algebra_mvec_type (alg, 0x01); auto va = offset_cast (vtype, a, 0); - auto cv = scale_expr (dot_type, va, b); + auto cv = scale_expr (vtype, va, b); c[0] = new_extend_expr (cv, dot_type, 0, false); } +static void +pga2_wxy_dot_yw_wx_xy (expr_t **c, expr_t *a, expr_t *b, algebra_t *alg) +{ + auto stype = alg->type; + auto sa = offset_cast (stype, a, 0); + auto sb = offset_cast (stype, b, 2); + sb = unary_expr ('-', sb); + auto cs = scale_expr (stype, sa, sb); + c[0] = new_extend_expr (cs, algebra_mvec_type (alg, 0x01), 0, true); +} + static void pga2_wxy_dot_x_y_w (expr_t **c, expr_t *a, expr_t *b, algebra_t *alg) { @@ -593,7 +615,7 @@ pga2_wxy_dot_x_y_w (expr_t **c, expr_t *a, expr_t *b, algebra_t *alg) auto dot_type = algebra_mvec_type (alg, 0x01); auto sa = offset_cast (stype, a, 0); auto vb = offset_cast (vtype, b, 0); - auto cv = scale_expr (dot_type, vb, unary_expr ('-', sa)); + auto cv = scale_expr (vtype, vb, sa); c[0] = new_extend_expr (cv, dot_type, 0, false); } @@ -601,6 +623,7 @@ static pga_func pga2_dot_funcs[4][4] = { [0] = { [0] = pga2_yw_wx_xy_dot_yw_wx_xy, [2] = pga2_yw_wx_xy_dot_x_y_w, + [3] = pga2_yw_wx_xy_dot_wxy, }, [1] = { [0] = scale_component, @@ -614,6 +637,7 @@ static pga_func pga2_dot_funcs[4][4] = { [3] = pga2_x_y_w_dot_wxy, }, [3] = { + [0] = pga2_wxy_dot_yw_wx_xy, [2] = pga2_wxy_dot_x_y_w, }, }; @@ -1167,13 +1191,12 @@ pga2_yw_wx_xy_geom_x_y_w (expr_t **c, expr_t *a, expr_t *b, algebra_t *alg) c[3] = dot_expr (algebra_mvec_type (alg, 0x08), a, b); } -#define pga2_wxy_geom_yw_wx_xy pga2_yw_wx_xy_geom_wxy static void pga2_yw_wx_xy_geom_wxy (expr_t **c, expr_t *a, expr_t *b, algebra_t *alg) { auto stype = alg->type; - auto sa = offset_cast (stype, a, 0); - auto sb = offset_cast (stype, b, 2); + auto sa = offset_cast (stype, a, 2); + auto sb = offset_cast (stype, b, 0); sb = unary_expr ('-', sb); auto cs = scale_expr (stype, sa, sb); c[0] = new_extend_expr (cs, algebra_mvec_type (alg, 0x01), 0, true); @@ -1212,11 +1235,22 @@ pga2_x_y_w_geom_wxy (expr_t **c, expr_t *a, expr_t *b, algebra_t *alg) auto vtype = vector_type (stype, 2); auto geom_type = algebra_mvec_type (alg, 0x01); auto va = offset_cast (vtype, a, 0); - auto cv = scale_expr (geom_type, va, b); + auto cv = scale_expr (vtype, va, b); c[0] = new_extend_expr (cv, geom_type, 0, false); } +static void +pga2_wxy_geom_yw_wx_xy (expr_t **c, expr_t *a, expr_t *b, algebra_t *alg) +{ + auto stype = alg->type; + auto sa = offset_cast (stype, a, 0); + auto sb = offset_cast (stype, b, 2); + sb = unary_expr ('-', sb); + auto cs = scale_expr (stype, sa, sb); + c[0] = new_extend_expr (cs, algebra_mvec_type (alg, 0x01), 0, true); +} + static void pga2_wxy_geom_x_y_w (expr_t **c, expr_t *a, expr_t *b, algebra_t *alg) { @@ -1224,7 +1258,7 @@ pga2_wxy_geom_x_y_w (expr_t **c, expr_t *a, expr_t *b, algebra_t *alg) auto vtype = vector_type (stype, 2); auto geom_type = algebra_mvec_type (alg, 0x01); auto vb = offset_cast (vtype, b, 0); - auto cv = scale_expr (geom_type, vb, a); + auto cv = scale_expr (vtype, vb, a); c[0] = new_extend_expr (cv, geom_type, 0, false); } diff --git a/tools/qfcc/test/pga2d.r b/tools/qfcc/test/pga2d.r index 5e2822db0..ba30fc973 100644 --- a/tools/qfcc/test/pga2d.r +++ b/tools/qfcc/test/pga2d.r @@ -40,14 +40,18 @@ main (void) return 1; } scalar_t scalar; - vector_t vec; - bivector_t bvec; - trivector_t tvec; + vector_t vec, vecb; + bivector_t bvec, bvecb; + trivector_t tvec, tvecb; @algebra (PGA) { scalar = 42; - vec = 3 * e1 - 2*e2 + e0; + vec = 3*e1 - 2*e2 + e0; bvec = 4*e20 - 3*e01 + 2*e12; - tvec = 7 * e012; + 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); @@ -65,9 +69,14 @@ main (void) printf ("tvec != 7: %g\n", tvec); return 1; } - auto t = vec ∧ bvec; - if ((double)t != 20) { - printf ("vec ∧ bvec != 20: %lv\n", t); + auto a = vec ∧ bvec; + if ((double)a != 20) { + printf ("vec ∧ bvec != 20: %lv\n", a); + return 1; + } + auto b = bvec ∧ vec; + if ((double)b != 20) { + printf ("bvec ∧ vec != 20: %lv\n", b); return 1; } auto c = vec • bvec; @@ -96,10 +105,119 @@ main (void) printf ("didn't get 0: %g %g", vec ∧ tvec, tvec ∧ vec); return 0; } -// auto g = vec • tvec; -// if ((dvec3)g != '-4 -6 -1'd) { -// printf ("vec • tvec != '-4 -6 -1': %lv\n", g); -// return 1; + auto g = vec • tvec; + if ((dvec3)g != '21 -14 0'd) { + printf ("vec • tvec != '21 -14 0': %lv\n", g); + return 1; + } + auto h = tvec • vec; + 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 (bvec ∧ tvec || tvec ∧ bvec) { + printf ("didn't get 0: %g %g", bvec ∧ tvec, tvec ∧ bvec); + return 0; + } + auto k = bvec • tvec; + if ((dvec3)k != '0 0 -14'd) { + printf ("bvec • tvec != '0 0 -14': %lv\n", k); + return 1; + } + auto l = tvec • bvec; + 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 (vec ∧ vec || bvec ∧ bvec || tvec ∧ tvec) { +// printf ("didn't get 0: %g %g %g", vec ∧ vec, bvec ∧ bvec, tvec ∧ tvec); +// return 0; // } + auto o = vec ∧ vecb; + if ((dvec3)o != '14 44 45'd) { + printf ("vec ∧ vecb != '14 44 45': %lv\n", o); + return 1; + } + auto p = vecb ∧ vec; + if ((dvec3)p != '-14 -44 -45'd) { + printf ("vecb ∧ vec != '-14 -44 -45': %lv\n", p); + return 1; + } + auto q = vec • vecb; + if (q != -9) { + printf ("vec • vecb != -9: %g\n", q); + return 1; + } + auto r = vecb • vec; + 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 45'd) { + printf ("vec * vecb != -9, '14 44 45': %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 -45'd) { + printf ("vecb * vec != -9, '-14 -44 -45': %g %lv\n", + t.scalar, t.bvec); + return 1; + } + if (bvec ∧ bvecb || tvec ∧ tvecb) { + printf ("didn't get 0: %g %g", bvec ∧ bvecb, tvec ∧ tvecb); + return 0; + } + auto u = bvec • bvecb; + if (u != -2) { + printf ("bvec • bvecb != -2: %g\n", u); + return 1; + } + auto v = bvecb • bvec; + 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 (tvec • tvecb || tvec * tvecb) { + printf ("didn't get 0: %g %g", tvec • tvecb, tvec * tvecb); + return 0; + } return 0; // to survive and prevail :) }