#include #include "algebra.h" #include "metric.h" #include "basisblade.h" #include "basisgroup.h" #include "basislayout.h" #include "util.h" @implementation Algebra +(Algebra *) R:(int)p, int m, int z { Algebra *a = [[[Algebra alloc] init] autorelease]; a.metric = [[Metric R:p, m, z] retain]; int d = p + m + z; a.dimension = d; a.num_components = 1 << d; BasisBlade **blades = obj_malloc (a.num_components * sizeof (BasisBlade *)); int *counts = binomial (d); int *indices = obj_malloc ((d + 1) * sizeof (int)); indices[0] = 0; for (int i = 0; i < d; i++) { indices[i + 1] = counts[i]; } prefixsum (indices, d + 1); for (int i = 0; i < a.num_components; i++) { int grade = count_bits (i); int ind = indices[grade]++; blades[ind] = [BasisBlade basis:i]; } a.grades = obj_malloc ((d + 1) * sizeof (BasisGroup *)); for (int i = 0; i < d + 1; i++) { int c = counts[i]; int ind = indices[i]; a.grades[i] = [BasisGroup new:c basis:blades + ind - c]; } if (p == 3 && m == 0 && z == 1) { // 3d PGA (w squares to 0, x y z square to +1): // : x y z w // : yz zx xy 1 // : xw yw zw xyzw // : zyw xzw yxw xyz BasisBlade *pga_blades[16] = { blades[1], blades[2], blades[3], blades[4], blades[7], blades[6], blades[5], blades[0], blades[8], blades[9], blades[10], blades[15], blades[14], blades[13], blades[12], blades[11], }; BasisGroup *pga_groups[4] = { [BasisGroup new:4 basis:pga_blades + 0], [BasisGroup new:4 basis:pga_blades + 4], [BasisGroup new:4 basis:pga_blades + 8], [BasisGroup new:4 basis:pga_blades + 12], }; a.layout = [[BasisLayout new:4 groups: pga_groups] retain]; } else if (p == 2 && m == 0 && z == 1) { // 2d PGA (w squares to 0, x y square to +1): // : x y w 1 // : yw wx xy xyw BasisBlade *pga_blades[8] = { blades[1], blades[2], blades[3], blades[0], blades[6], blades[5], blades[4], blades[7], }; BasisGroup *pga_groups[2] = { [BasisGroup new:4 basis:pga_blades + 0], [BasisGroup new:4 basis:pga_blades + 4], }; a.layout = [[BasisLayout new:2 groups: pga_groups] retain]; } else { // just use the grades as the default layout a.layout = [[BasisLayout new:d + 1 groups: a.grades] retain]; } obj_free (indices); obj_free (counts); obj_free (blades); return a; } +(Algebra *) PGA:(int)n { return [Algebra R:n, 0, 1]; } -(void)dealloc { obj_free (grades); [metric release]; [layout release]; [super dealloc]; } -(BasisGroup *)grade:(int)k { return grades[k]; } -(BasisLayout *)layout { return layout; } -(Metric *) metric { return metric; } -(int)count { return num_components; } -(int)dimension { return dimension; } -(void) print { int count = [layout count]; for (int i = 0; i < count; i++) { BasisGroup *g = [layout group:i]; int c = [g count]; printf ("%d %d %@\n", i, c, [g set]); for (int j = 0; j < c; j++) { printf (" %@\n", [g bladeAt:j]); } } } @end