[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;
-(int)count;
-(int)dimension;
-(int)dim;
-(MultiVector *) group:(int)group;
-(MultiVector *) group:(int)group values:(double *)values;

View file

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

View file

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

View file

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

View file

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