#include #define PGA2D #define U N #ifdef GA2D enum { E1 = 1, E2, E12, N }; int grade[] = { 0, 1, 1, 2 }; int elt[N][N] = { // E1 E2 E12 { U, E1, E2, E12 }, /*E1*/ { E1, U, E12, E2 }, /*E2*/ { E2, -E12, U, -E1 }, /*E12*/ { E12, -E2, E1, -U }, }; #endif #ifdef GA3D enum { E1 = 1, E2, E3, E12, E31, E23, E123, N }; int grade[] = { 0, 1, 1, 1, 2, 2, 2, 3, }; int elt[N][N] = { { U, E1, E2, E3, E12, E31, E23, E123, }, { E1, U, E12, -E31, E2, -E3, E123, E23, }, { E2, -E12, U, E23, -E1, E123, E3, E31, }, { E3, E31, -E23, U, E123, E1, -E2, E12, }, { E12, -E2, E1, E123, -U, E23, -E31, -E3, }, { E31, E3, E123, -E1, -E23, -U, E12, -E2, }, { E23, E123, -E3, E2, E31, -E12, -U, -E1, }, { E123, E23, E31, E12, -E3, -E2, -E1, -U, }, }; #endif #ifdef PGA2D enum { E0 = 1, E1, E2, E01, E20, E12, E012, N }; int grade[] = { 0, 1, 1, 1, 2, 2, 2, 3 }; int dualsign[] = { 1, 1, 1, 1, 1, 1, 1, 1, }; int elt[N][N] = { // E0 E1 E2 E01 E20 E12 E012 { U, E0, E1, E2, E01, E20, E12, E012 }, /*E0*/ { E0, 0, E01, -E20, 0, 0, E012, 0 }, /*E1*/ { E1, -E01, U, E12, -E0, E012, E2, E20 }, /*E2*/ { E2, E20, -E12, U, E012, E0, -E1, E01 }, /*E01*/ { E01, 0, E0, E012, 0, 0, -E20, 0 }, /*E20*/ { E20, 0, E012, -E0, 0, 0, E01, 0 }, /*E12*/ { E12, E012, -E2, E1, E20, -E01, -U, -E0 }, /*E012*/{ E012, 0, E20, E01, 0, 0, -E0, 0 }, }; #endif #ifdef PGA3D enum { E0 = 1, E1, E2, E3, E01, E02, E03, E12, E31, E23, E021, E013, E032, E123, E0123, N }; int grade[] = { 0, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 4, }; int dualsign[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, 1, }; int elt[N][N] = { { U, E0, E1, E2, E3, E01, E02, E03, E12, E31, E23, E021, E013, E032, E123, E0123, }, { E0, 0, E01, E02, E03, 0, 0, 0, -E021, -E013, -E032, 0, 0, 0, E0123, 0, }, { E1, -E01, U, E12, -E31, -E0, E021, -E013, E2, -E3, E123, E02, -E03, E0123, E23, E032, }, { E2, -E02, -E12, U, E23, -E021, -E0, E032, -E1, E123, E3, -E01, E0123, E03, E31, E013, }, { E3, -E03, E31, -E23, U, E013, -E032, -E0, E123, E1, -E2, E0123, E01, -E02, E12, E021, }, { E01, 0, E0, -E021, E013, 0, 0, 0, E02, -E03, E0123, 0, 0, 0, -E032, 0, }, { E02, 0, E021, E0, -E032, 0, 0, 0, -E01, E0123, E03, 0, 0, 0, -E013, 0, }, { E03, 0, -E013, E032, E0, 0, 0, 0, E0123, E01, -E02, 0, 0, 0, -E021, 0, }, { E12, -E021, -E2, E1, E123, -E02, E01, E0123, -U, E23, -E31, E0, E032, -E013, -E3, -E03, }, { E31, -E013, E3, E123, -E1, E03, E0123, -E01, -E23, -U, E12, -E032, E0, E021, -E2, -E02, }, { E23, -E032, E123, -E3, E2, E0123, -E03, E02, E31, -E12, -U, E013, -E021, E0, -E1, -E01, }, { E021, 0, E02, -E01, -E0123, 0, 0, 0, E0, E032, -E013, 0, 0, 0, E03, 0, }, { E013, 0, -E03, -E0123, E01, 0, 0, 0, -E032, E0, E021, 0, 0, 0, E02, 0, }, { E032, 0, -E0123, E03, -E02, 0, 0, 0, E013, -E021, E0, 0, 0, 0, E01, 0, }, { E123, -E0123, E23, E31, E12, E032, E013, E021, -E3, -E2, -E1, -E03, -E02, -E01, -U, E0, }, { E0123, 0, -E032, -E013, -E021, 0, 0, 0, -E03, -E02, -E01, 0, 0, 0, -E0, 0, }, }; #endif int gen(int i, int j, int k) { if(i == 0) i = U; // fix because we can't have negative 0 if(elt[j][k] != i && -elt[j][k] != i) return 0; // only generate elements we're interested in // non-zero result if(elt[j][k] != 0) return printf(" %c l.e[%d]*r.e[%d]", elt[j][k] > 0 ? '+' : '-', j, k); return 0; } int gendual(int i, int j, int k) { if(i == 0) i = U; // fix because we can't have negative 0 if(elt[j][k] != i && -elt[j][k] != i) return 0; // only generate elements we're interested in // non-zero result if(elt[j][k] != 0) { int s = elt[j][k] * dualsign[N-j-1] * dualsign[N-k-1]; return printf(" %c l.e[%d]*r.e[%d]", s > 0 ? '+' : '-', N-j-1, N-k-1); } return 0; } int main() { int i, j, k, gr; int n; printf(" geometric\n"); for(i = 0; i < N; i++){ n = 0; printf("v.e[%d] =", i); for(j = 0; j < N; j++) for(k = 0; k < N; k++) { n += gen(i, j, k); } printf("%s;\n", n ? "" : " 0.0f"); } printf(" meet\n"); for(i = 0; i < N; i++){ printf("v.e[%d] =", i); n = 0; for(j = 0; j < N; j++) for(k = 0; k < N; k++) { gr = grade[j]+grade[k]; if(grade[i] != gr) continue; n += gen(i, j, k); } printf("%s;\n", n ? "" : " 0.0f"); } printf(" join\n"); for(i = 0; i < N; i++){ printf("v.e[%d] = %c(", N-1-i, dualsign[N-1-i] < 0 ? '-' : '+'); n = 0; for(j = 0; j < N; j++) for(k = 0; k < N; k++) { gr = grade[j]+grade[k]; if(grade[i] != gr) continue; n += gendual(i, j, k); } printf("%s);\n", n ? "" : " 0.0f"); } printf(" dot\n"); for(i = 0; i < N; i++){ printf("v.e[%d] =", i); n = 0; for(j = 0; j < N; j++) for(k = 0; k < N; k++) { gr = grade[j]-grade[k]; if(gr < 0) gr = -gr; if(grade[i] != gr) continue; n += gen(i, j, k); } printf("%s;\n", n ? "" : " 0.0f"); } return 0; }