[gatest] Implement undual and antiwedge

This commit is contained in:
Bill Currie 2024-02-09 23:05:47 +09:00
parent cf814cd9d1
commit e9cea29cae
5 changed files with 34 additions and 2 deletions

View file

@ -25,6 +25,7 @@
-(Metric *) metric; -(Metric *) metric;
-(int)count; -(int)count;
-(int)dimension; -(int)dimension;
-(int)dim;
-(MultiVector *) group:(int)group; -(MultiVector *) group:(int)group;
-(MultiVector *) group:(int)group values:(double *)values; -(MultiVector *) group:(int)group values:(double *)values;

View file

@ -130,6 +130,11 @@
return dimension; return dimension;
} }
-(int)dim
{
return dimension - zero;
}
-(MultiVector *) group:(int)group -(MultiVector *) group:(int)group
{ {
return [MultiVector new:self group:[layout group:group]]; return [MultiVector new:self group:[layout group:group]];

View file

@ -117,7 +117,7 @@ typedef enum {
OPENS, CLOSES, OPENS, CLOSES,
MUL, DIV, PLUS, MINUS, MUL, DIV, PLUS, MINUS,
WEDGE, ANTIWEDGE, DOT, WEDGE, ANTIWEDGE, DOT,
REVERSE, DUAL, REVERSE, DUAL, UNDUAL,
} token_e; } token_e;
script_t script; script_t script;
@ -158,6 +158,7 @@ get_token ()
case ".": return {DOT, nil}; case ".": return {DOT, nil};
case "~": return {REVERSE, nil}; case "~": return {REVERSE, nil};
case "!": return {DUAL, nil}; case "!": return {DUAL, nil};
case "?": return {UNDUAL, nil};
} }
return {ID, .name = token_str }; return {ID, .name = token_str };
} }
@ -212,6 +213,9 @@ factor ()
} else if (match (DUAL)) { } else if (match (DUAL)) {
advance (); advance ();
vec = [factor () dual]; vec = [factor () dual];
} else if (match (UNDUAL)) {
advance ();
vec = [factor () undual];
} else if (match (MINUS)) { } else if (match (MINUS)) {
advance (); advance ();
vec = [minus_one product:factor ()]; vec = [minus_one product:factor ()];
@ -274,6 +278,9 @@ high_term ()
if (match (WEDGE)) { if (match (WEDGE)) {
op = @selector(wedge:); op = @selector(wedge:);
advance (); advance ();
} else if (match (ANTIWEDGE)) {
op = @selector(antiwedge:);
advance ();
} else if (match (DOT)) { } else if (match (DOT)) {
op = @selector(dot:); op = @selector(dot:);
advance (); advance ();

View file

@ -28,10 +28,12 @@
-(MultiVector *) product:(MultiVector *) rhs; -(MultiVector *) product:(MultiVector *) rhs;
-(MultiVector *) divide:(MultiVector *) rhs; -(MultiVector *) divide:(MultiVector *) rhs;
-(MultiVector *) wedge:(MultiVector *) rhs; -(MultiVector *) wedge:(MultiVector *) rhs;
-(MultiVector *) antiwedge:(MultiVector *) rhs;
-(MultiVector *) dot:(MultiVector *) rhs; -(MultiVector *) dot:(MultiVector *) rhs;
-(MultiVector *) plus:(MultiVector *) rhs; -(MultiVector *) plus:(MultiVector *) rhs;
-(MultiVector *) minus:(MultiVector *) rhs; -(MultiVector *) minus:(MultiVector *) rhs;
-(MultiVector *) dual; -(MultiVector *) dual;
-(MultiVector *) undual;
-(MultiVector *) reverse; -(MultiVector *) reverse;
@end @end

View file

@ -169,6 +169,11 @@ static MultiVector *new_mv (Algebra *algebra, BasisLayout *layout)
return prod; return prod;
} }
-(MultiVector *) antiwedge:(MultiVector *) rhs
{
return [[[self dual] wedge:[rhs dual]] undual];
}
-(MultiVector *) dot:(MultiVector *) rhs -(MultiVector *) dot:(MultiVector *) rhs
{ {
MultiVector *prod = [MultiVector new:algebra]; MultiVector *prod = [MultiVector new:algebra];
@ -253,10 +258,11 @@ static MultiVector *new_mv (Algebra *algebra, BasisLayout *layout)
return minus; return minus;
} }
-(MultiVector *) dual -(MultiVector *) dual:(int) undual
{ {
MultiVector *dual = [MultiVector new:algebra]; MultiVector *dual = [MultiVector new:algebra];
unsigned dual_mask = (1 << [algebra dimension]) - 1; unsigned dual_mask = (1 << [algebra dimension]) - 1;
int dim = [algebra dim];
for (int i = 0; i < num_components; i++) { for (int i = 0; i < num_components; i++) {
if (!components[i]) { if (!components[i]) {
continue; continue;
@ -267,12 +273,23 @@ static MultiVector *new_mv (Algebra *algebra, BasisLayout *layout)
unsigned mask = lb_mask ^ dual_mask; unsigned mask = lb_mask ^ dual_mask;
double ls = [lb scale]; double ls = [lb scale];
double s = count_flips (lb_mask, mask) & 1 ? -1 : 1; double s = count_flips (lb_mask, mask) & 1 ? -1 : 1;
s *= (dim * [lb grade]) & 1 ? -1 : 1;
int ind = [dual.layout bladeIndex:mask]; int ind = [dual.layout bladeIndex:mask];
dual.components[ind] += s * lc; dual.components[ind] += s * lc;
} }
return dual; return dual;
} }
-(MultiVector *) dual
{
return [self dual:0];
}
-(MultiVector *) undual
{
return [self dual:1];
}
-(MultiVector *) reverse -(MultiVector *) reverse
{ {
MultiVector *reverse = [MultiVector new:algebra]; MultiVector *reverse = [MultiVector new:algebra];