added map,conv and permute

map - maps points based on equations
conv - allows running convolution filter
permute - switches dimension position
This commit is contained in:
mcDandy
2025-12-26 18:42:47 +01:00
parent ba752c4b55
commit e44fd922d4
11 changed files with 2423 additions and 1094 deletions
+18 -6
View File
@@ -104,13 +104,18 @@ class FloatEvalVisitor(MathExprVisitor):
def visitAsinhFunc(self, ctx): return math.asinh(self.visit(ctx.expr()))
def visitAcoshFunc(self, ctx): return math.acosh(self.visit(ctx.expr()))
def visitAtanhFunc(self, ctx): return math.atanh(self.visit(ctx.expr()))
def visitAbsFunc(self, ctx): return math.abs(self.visit(ctx.expr()))
def visitAbsExp(self, ctx): return math.abs(self.visit(ctx.expr()))
def visitAbsFunc(self, ctx): return abs(self.visit(ctx.expr()))
def visitAbsExp(self, ctx): return abs(self.visit(ctx.expr()))
def visitListExp(self, ctx): return self.visit(ctx.expr(0))
def visitSqrtFunc(self, ctx): return math.sqrt(self.visit(ctx.expr()))
def visitLnFunc(self, ctx): return math.log(self.visit(ctx.expr()))
def visitLogFunc(self, ctx): return math.log10(self.visit(ctx.expr()))
def visitExpFunc(self, ctx): return math.exp(self.visit(ctx.expr()))
def visitNormFunc(self, ctx): return math.sqrt(math.avg(x**2 for x in self.visit(ctx.expr())))
def visitNormFunc(self, ctx):
vals = self.visit(ctx.expr())
if isinstance(vals, (list, tuple)):
return math.sqrt(sum(x**2 for x in vals) / len(vals))
return abs(vals)
def visitFloorFunc(self, ctx): return math.floor(self.visit(ctx.expr()))
def visitFractFunc(self, ctx):
val = self.visit(ctx.expr())
@@ -131,7 +136,7 @@ class FloatEvalVisitor(MathExprVisitor):
x = self.visit(ctx.expr())
return math.copysign(1.0, x) if x != 0 else 0.0
def visitCeilFunc(self, ctx): return math.ceil(self.visit(ctx.expr()))
def visitRoundFunc(self, ctx): return math.round(self.visit(ctx.expr()))
def visitRoundFunc(self, ctx): return round(self.visit(ctx.expr()))
def visitGammaFunc(self, ctx): return math.gamma(self.visit(ctx.expr())).exp()
def visitPrintFunc(self, ctx):
val = self.visit(ctx.expr())
@@ -151,10 +156,10 @@ class FloatEvalVisitor(MathExprVisitor):
# N-argument functions
def visitSMinFunc(self, ctx):
args = [self.visit(e) for e in ctx.expr()]
return math.min(args)
return min(args)
def visitSMaxFunc(self, ctx):
args = [self.visit(e) for e in ctx.expr()]
return math.max(args)
return max(args)
def visitClampFunc(self, ctx):
x = self.visit(ctx.expr(0))
@@ -188,6 +193,13 @@ class FloatEvalVisitor(MathExprVisitor):
return self.visitChildren(ctx)
def visitFunc4Exp(self, ctx):
return self.visitChildren(ctx)
def visitMapFunc(self, ctx):
return self.visit(ctx.expr(0))
def visitConvFunc(self, ctx):
return self.visit(ctx.expr(0))
def visitFuncNExp(self, ctx):
return self.visitChildren(ctx)
def visitAtomExp(self, ctx):
+12 -5
View File
@@ -51,6 +51,7 @@ atom
| CONSTANT # ConstantExp
| '(' expr ')' # ParenExp
| PIPE expr PIPE # AbsExp
| '[' expr (',' expr)* ']' # ListExp
;
// Single-argument functions
@@ -88,7 +89,6 @@ func1
| SOFTPLUS '(' expr ')' # SoftplusFunc
| GELU '(' expr ')' # GeluFunc
| SIGN '(' expr ')' # SignFunc
;
// Two-argument functions
@@ -99,6 +99,7 @@ func2
| TMAX '(' expr ',' expr ')' # TMaxFunc
| STEP '(' expr ',' expr ')' # StepFunc
;
func3
: CLAMP '(' expr ',' expr ',' expr ')' # ClampFunc
| LERP '(' expr ',' expr ',' expr ')' # LerpFunc
@@ -108,11 +109,14 @@ func3
func4
: SWAP '(' expr ',' expr ',' expr ',' expr ')' # SwapFunc
;
// N-argument functions (at least 2 arguments)
funcN
: SMIN '(' expr (',' expr)+ ')' # SMinFunc
| SMAX '(' expr (',' expr)+ ')' # SMaxFunc
// N-argument functions
funcN
: SMIN '(' expr (',' expr)* ')' # SMinFunc
| SMAX '(' expr (',' expr)* ')' # SMaxFunc
| MAP '(' expr (',' expr)+ ')' # MapFunc
| CONV '(' expr (',' expr)+ ')' # ConvFunc
| PERM '(' expr ',' expr ')' # PermuteFunc
;
// LEXER RULES
@@ -160,7 +164,10 @@ RELU : 'relu';
SOFTPLUS : 'softplus';
GELU : 'gelu';
SIGN : 'sign';
MAP : 'map';
CONV : 'conv';
SWAP : 'swap';
PERM : 'permute';
PLUS : '+';
MINUS : '-';
File diff suppressed because one or more lines are too long
+129 -119
View File
@@ -1,124 +1,134 @@
T__0=1
T__1=2
T__2=3
SIN=4
COS=5
TAN=6
ASIN=7
ACOS=8
ATAN=9
ATAN2=10
SINH=11
COSH=12
TANH=13
ASINH=14
ACOSH=15
ATANH=16
ABS=17
SQRT=18
LN=19
LOG=20
EXP=21
SMIN=22
SMAX=23
TMIN=24
TMAX=25
TNORM=26
SNORM=27
FLOOR=28
CEIL=29
ROUND=30
GAMMA=31
POWE=32
SIGM=33
CLAMP=34
SFFT=35
SIFFT=36
ANGL=37
PRNT=38
LERP=39
STEP=40
SMOOTHSTEP=41
FRACT=42
RELU=43
SOFTPLUS=44
GELU=45
SIGN=46
SWAP=47
PLUS=48
MINUS=49
MULT=50
DIV=51
MOD=52
POW=53
GE=54
GT=55
LE=56
LT=57
EQ=58
NE=59
PIPE=60
CONSTANT=61
NUMBER=62
VARIABLE=63
WS=64
T__3=4
T__4=5
SIN=6
COS=7
TAN=8
ASIN=9
ACOS=10
ATAN=11
ATAN2=12
SINH=13
COSH=14
TANH=15
ASINH=16
ACOSH=17
ATANH=18
ABS=19
SQRT=20
LN=21
LOG=22
EXP=23
SMIN=24
SMAX=25
TMIN=26
TMAX=27
TNORM=28
SNORM=29
FLOOR=30
CEIL=31
ROUND=32
GAMMA=33
POWE=34
SIGM=35
CLAMP=36
SFFT=37
SIFFT=38
ANGL=39
PRNT=40
LERP=41
STEP=42
SMOOTHSTEP=43
FRACT=44
RELU=45
SOFTPLUS=46
GELU=47
SIGN=48
MAP=49
CONV=50
SWAP=51
PERM=52
PLUS=53
MINUS=54
MULT=55
DIV=56
MOD=57
POW=58
GE=59
GT=60
LE=61
LT=62
EQ=63
NE=64
PIPE=65
CONSTANT=66
NUMBER=67
VARIABLE=68
WS=69
'('=1
')'=2
','=3
'sin'=4
'cos'=5
'tan'=6
'asin'=7
'acos'=8
'atan'=9
'atan2'=10
'sinh'=11
'cosh'=12
'tanh'=13
'asinh'=14
'acosh'=15
'atanh'=16
'abs'=17
'sqrt'=18
'ln'=19
'log'=20
'exp'=21
'smin'=22
'smax'=23
'tmin'=24
'tmax'=25
'tnorm'=26
'snorm'=27
'floor'=28
'ceil'=29
'round'=30
'gamma'=31
'pow'=32
'sigm'=33
'clamp'=34
'fft'=35
'ifft'=36
'angle'=37
'print'=38
'lerp'=39
'step'=40
'smoothstep'=41
'fract'=42
'relu'=43
'softplus'=44
'gelu'=45
'sign'=46
'swap'=47
'+'=48
'-'=49
'*'=50
'/'=51
'%'=52
'^'=53
'>='=54
'>'=55
'<='=56
'<'=57
'=='=58
'!='=59
'|'=60
'['=3
','=4
']'=5
'sin'=6
'cos'=7
'tan'=8
'asin'=9
'acos'=10
'atan'=11
'atan2'=12
'sinh'=13
'cosh'=14
'tanh'=15
'asinh'=16
'acosh'=17
'atanh'=18
'abs'=19
'sqrt'=20
'ln'=21
'log'=22
'exp'=23
'smin'=24
'smax'=25
'tmin'=26
'tmax'=27
'tnorm'=28
'snorm'=29
'floor'=30
'ceil'=31
'round'=32
'gamma'=33
'pow'=34
'sigm'=35
'clamp'=36
'fft'=37
'ifft'=38
'angle'=39
'print'=40
'lerp'=41
'step'=42
'smoothstep'=43
'fract'=44
'relu'=45
'softplus'=46
'gelu'=47
'sign'=48
'map'=49
'conv'=50
'swap'=51
'permute'=52
'+'=53
'-'=54
'*'=55
'/'=56
'%'=57
'^'=58
'>='=59
'>'=60
'<='=61
'<'=62
'=='=63
'!='=64
'|'=65
File diff suppressed because one or more lines are too long
+242 -224
View File
@@ -10,7 +10,7 @@ else:
def serializedATN():
return [
4,0,64,432,6,-1,2,0,7,0,2,1,7,1,2,2,7,2,2,3,7,3,2,4,7,4,2,5,7,5,
4,0,69,463,6,-1,2,0,7,0,2,1,7,1,2,2,7,2,2,3,7,3,2,4,7,4,2,5,7,5,
2,6,7,6,2,7,7,7,2,8,7,8,2,9,7,9,2,10,7,10,2,11,7,11,2,12,7,12,2,
13,7,13,2,14,7,14,2,15,7,15,2,16,7,16,2,17,7,17,2,18,7,18,2,19,7,
19,2,20,7,20,2,21,7,21,2,22,7,22,2,23,7,23,2,24,7,24,2,25,7,25,2,
@@ -19,149 +19,159 @@ def serializedATN():
39,7,39,2,40,7,40,2,41,7,41,2,42,7,42,2,43,7,43,2,44,7,44,2,45,7,
45,2,46,7,46,2,47,7,47,2,48,7,48,2,49,7,49,2,50,7,50,2,51,7,51,2,
52,7,52,2,53,7,53,2,54,7,54,2,55,7,55,2,56,7,56,2,57,7,57,2,58,7,
58,2,59,7,59,2,60,7,60,2,61,7,61,2,62,7,62,2,63,7,63,1,0,1,0,1,1,
1,1,1,2,1,2,1,3,1,3,1,3,1,3,1,4,1,4,1,4,1,4,1,5,1,5,1,5,1,5,1,6,
1,6,1,6,1,6,1,6,1,7,1,7,1,7,1,7,1,7,1,8,1,8,1,8,1,8,1,8,1,9,1,9,
1,9,1,9,1,9,1,9,1,10,1,10,1,10,1,10,1,10,1,11,1,11,1,11,1,11,1,11,
1,12,1,12,1,12,1,12,1,12,1,13,1,13,1,13,1,13,1,13,1,13,1,14,1,14,
1,14,1,14,1,14,1,14,1,15,1,15,1,15,1,15,1,15,1,15,1,16,1,16,1,16,
1,16,1,17,1,17,1,17,1,17,1,17,1,18,1,18,1,18,1,19,1,19,1,19,1,19,
1,20,1,20,1,20,1,20,1,21,1,21,1,21,1,21,1,21,1,22,1,22,1,22,1,22,
1,22,1,23,1,23,1,23,1,23,1,23,1,24,1,24,1,24,1,24,1,24,1,25,1,25,
1,25,1,25,1,25,1,25,1,26,1,26,1,26,1,26,1,26,1,26,1,27,1,27,1,27,
1,27,1,27,1,27,1,28,1,28,1,28,1,28,1,28,1,29,1,29,1,29,1,29,1,29,
1,29,1,30,1,30,1,30,1,30,1,30,1,30,1,31,1,31,1,31,1,31,1,32,1,32,
1,32,1,32,1,32,1,33,1,33,1,33,1,33,1,33,1,33,1,34,1,34,1,34,1,34,
1,35,1,35,1,35,1,35,1,35,1,36,1,36,1,36,1,36,1,36,1,36,1,37,1,37,
1,37,1,37,1,37,1,37,1,38,1,38,1,38,1,38,1,38,1,39,1,39,1,39,1,39,
1,39,1,40,1,40,1,40,1,40,1,40,1,40,1,40,1,40,1,40,1,40,1,40,1,41,
1,41,1,41,1,41,1,41,1,41,1,42,1,42,1,42,1,42,1,42,1,43,1,43,1,43,
1,43,1,43,1,43,1,43,1,43,1,43,1,44,1,44,1,44,1,44,1,44,1,45,1,45,
1,45,1,45,1,45,1,46,1,46,1,46,1,46,1,46,1,47,1,47,1,48,1,48,1,49,
1,49,1,50,1,50,1,51,1,51,1,52,1,52,1,53,1,53,1,53,1,54,1,54,1,55,
1,55,1,55,1,56,1,56,1,57,1,57,1,57,1,58,1,58,1,58,1,59,1,59,1,60,
1,60,1,60,1,60,1,60,3,60,404,8,60,1,61,4,61,407,8,61,11,61,12,61,
408,1,61,1,61,4,61,413,8,61,11,61,12,61,414,3,61,417,8,61,1,62,1,
62,5,62,421,8,62,10,62,12,62,424,9,62,1,63,4,63,427,8,63,11,63,12,
63,428,1,63,1,63,0,0,64,1,1,3,2,5,3,7,4,9,5,11,6,13,7,15,8,17,9,
19,10,21,11,23,12,25,13,27,14,29,15,31,16,33,17,35,18,37,19,39,20,
41,21,43,22,45,23,47,24,49,25,51,26,53,27,55,28,57,29,59,30,61,31,
63,32,65,33,67,34,69,35,71,36,73,37,75,38,77,39,79,40,81,41,83,42,
85,43,87,44,89,45,91,46,93,47,95,48,97,49,99,50,101,51,103,52,105,
53,107,54,109,55,111,56,113,57,115,58,117,59,119,60,121,61,123,62,
125,63,127,64,1,0,5,2,0,69,69,101,101,1,0,48,57,3,0,65,90,95,95,
97,122,4,0,48,57,65,90,95,95,97,122,3,0,9,10,13,13,32,32,438,0,1,
1,0,0,0,0,3,1,0,0,0,0,5,1,0,0,0,0,7,1,0,0,0,0,9,1,0,0,0,0,11,1,0,
0,0,0,13,1,0,0,0,0,15,1,0,0,0,0,17,1,0,0,0,0,19,1,0,0,0,0,21,1,0,
0,0,0,23,1,0,0,0,0,25,1,0,0,0,0,27,1,0,0,0,0,29,1,0,0,0,0,31,1,0,
0,0,0,33,1,0,0,0,0,35,1,0,0,0,0,37,1,0,0,0,0,39,1,0,0,0,0,41,1,0,
0,0,0,43,1,0,0,0,0,45,1,0,0,0,0,47,1,0,0,0,0,49,1,0,0,0,0,51,1,0,
0,0,0,53,1,0,0,0,0,55,1,0,0,0,0,57,1,0,0,0,0,59,1,0,0,0,0,61,1,0,
0,0,0,63,1,0,0,0,0,65,1,0,0,0,0,67,1,0,0,0,0,69,1,0,0,0,0,71,1,0,
0,0,0,73,1,0,0,0,0,75,1,0,0,0,0,77,1,0,0,0,0,79,1,0,0,0,0,81,1,0,
0,0,0,83,1,0,0,0,0,85,1,0,0,0,0,87,1,0,0,0,0,89,1,0,0,0,0,91,1,0,
0,0,0,93,1,0,0,0,0,95,1,0,0,0,0,97,1,0,0,0,0,99,1,0,0,0,0,101,1,
0,0,0,0,103,1,0,0,0,0,105,1,0,0,0,0,107,1,0,0,0,0,109,1,0,0,0,0,
111,1,0,0,0,0,113,1,0,0,0,0,115,1,0,0,0,0,117,1,0,0,0,0,119,1,0,
0,0,0,121,1,0,0,0,0,123,1,0,0,0,0,125,1,0,0,0,0,127,1,0,0,0,1,129,
1,0,0,0,3,131,1,0,0,0,5,133,1,0,0,0,7,135,1,0,0,0,9,139,1,0,0,0,
11,143,1,0,0,0,13,147,1,0,0,0,15,152,1,0,0,0,17,157,1,0,0,0,19,162,
1,0,0,0,21,168,1,0,0,0,23,173,1,0,0,0,25,178,1,0,0,0,27,183,1,0,
0,0,29,189,1,0,0,0,31,195,1,0,0,0,33,201,1,0,0,0,35,205,1,0,0,0,
37,210,1,0,0,0,39,213,1,0,0,0,41,217,1,0,0,0,43,221,1,0,0,0,45,226,
1,0,0,0,47,231,1,0,0,0,49,236,1,0,0,0,51,241,1,0,0,0,53,247,1,0,
0,0,55,253,1,0,0,0,57,259,1,0,0,0,59,264,1,0,0,0,61,270,1,0,0,0,
63,276,1,0,0,0,65,280,1,0,0,0,67,285,1,0,0,0,69,291,1,0,0,0,71,295,
1,0,0,0,73,300,1,0,0,0,75,306,1,0,0,0,77,312,1,0,0,0,79,317,1,0,
0,0,81,322,1,0,0,0,83,333,1,0,0,0,85,339,1,0,0,0,87,344,1,0,0,0,
89,353,1,0,0,0,91,358,1,0,0,0,93,363,1,0,0,0,95,368,1,0,0,0,97,370,
1,0,0,0,99,372,1,0,0,0,101,374,1,0,0,0,103,376,1,0,0,0,105,378,1,
0,0,0,107,380,1,0,0,0,109,383,1,0,0,0,111,385,1,0,0,0,113,388,1,
0,0,0,115,390,1,0,0,0,117,393,1,0,0,0,119,396,1,0,0,0,121,403,1,
0,0,0,123,406,1,0,0,0,125,418,1,0,0,0,127,426,1,0,0,0,129,130,5,
40,0,0,130,2,1,0,0,0,131,132,5,41,0,0,132,4,1,0,0,0,133,134,5,44,
0,0,134,6,1,0,0,0,135,136,5,115,0,0,136,137,5,105,0,0,137,138,5,
110,0,0,138,8,1,0,0,0,139,140,5,99,0,0,140,141,5,111,0,0,141,142,
5,115,0,0,142,10,1,0,0,0,143,144,5,116,0,0,144,145,5,97,0,0,145,
146,5,110,0,0,146,12,1,0,0,0,147,148,5,97,0,0,148,149,5,115,0,0,
149,150,5,105,0,0,150,151,5,110,0,0,151,14,1,0,0,0,152,153,5,97,
0,0,153,154,5,99,0,0,154,155,5,111,0,0,155,156,5,115,0,0,156,16,
1,0,0,0,157,158,5,97,0,0,158,159,5,116,0,0,159,160,5,97,0,0,160,
161,5,110,0,0,161,18,1,0,0,0,162,163,5,97,0,0,163,164,5,116,0,0,
164,165,5,97,0,0,165,166,5,110,0,0,166,167,5,50,0,0,167,20,1,0,0,
0,168,169,5,115,0,0,169,170,5,105,0,0,170,171,5,110,0,0,171,172,
5,104,0,0,172,22,1,0,0,0,173,174,5,99,0,0,174,175,5,111,0,0,175,
176,5,115,0,0,176,177,5,104,0,0,177,24,1,0,0,0,178,179,5,116,0,0,
179,180,5,97,0,0,180,181,5,110,0,0,181,182,5,104,0,0,182,26,1,0,
0,0,183,184,5,97,0,0,184,185,5,115,0,0,185,186,5,105,0,0,186,187,
5,110,0,0,187,188,5,104,0,0,188,28,1,0,0,0,189,190,5,97,0,0,190,
191,5,99,0,0,191,192,5,111,0,0,192,193,5,115,0,0,193,194,5,104,0,
0,194,30,1,0,0,0,195,196,5,97,0,0,196,197,5,116,0,0,197,198,5,97,
0,0,198,199,5,110,0,0,199,200,5,104,0,0,200,32,1,0,0,0,201,202,5,
97,0,0,202,203,5,98,0,0,203,204,5,115,0,0,204,34,1,0,0,0,205,206,
5,115,0,0,206,207,5,113,0,0,207,208,5,114,0,0,208,209,5,116,0,0,
209,36,1,0,0,0,210,211,5,108,0,0,211,212,5,110,0,0,212,38,1,0,0,
0,213,214,5,108,0,0,214,215,5,111,0,0,215,216,5,103,0,0,216,40,1,
0,0,0,217,218,5,101,0,0,218,219,5,120,0,0,219,220,5,112,0,0,220,
42,1,0,0,0,221,222,5,115,0,0,222,223,5,109,0,0,223,224,5,105,0,0,
224,225,5,110,0,0,225,44,1,0,0,0,226,227,5,115,0,0,227,228,5,109,
0,0,228,229,5,97,0,0,229,230,5,120,0,0,230,46,1,0,0,0,231,232,5,
116,0,0,232,233,5,109,0,0,233,234,5,105,0,0,234,235,5,110,0,0,235,
48,1,0,0,0,236,237,5,116,0,0,237,238,5,109,0,0,238,239,5,97,0,0,
239,240,5,120,0,0,240,50,1,0,0,0,241,242,5,116,0,0,242,243,5,110,
0,0,243,244,5,111,0,0,244,245,5,114,0,0,245,246,5,109,0,0,246,52,
1,0,0,0,247,248,5,115,0,0,248,249,5,110,0,0,249,250,5,111,0,0,250,
251,5,114,0,0,251,252,5,109,0,0,252,54,1,0,0,0,253,254,5,102,0,0,
254,255,5,108,0,0,255,256,5,111,0,0,256,257,5,111,0,0,257,258,5,
114,0,0,258,56,1,0,0,0,259,260,5,99,0,0,260,261,5,101,0,0,261,262,
5,105,0,0,262,263,5,108,0,0,263,58,1,0,0,0,264,265,5,114,0,0,265,
266,5,111,0,0,266,267,5,117,0,0,267,268,5,110,0,0,268,269,5,100,
0,0,269,60,1,0,0,0,270,271,5,103,0,0,271,272,5,97,0,0,272,273,5,
109,0,0,273,274,5,109,0,0,274,275,5,97,0,0,275,62,1,0,0,0,276,277,
5,112,0,0,277,278,5,111,0,0,278,279,5,119,0,0,279,64,1,0,0,0,280,
281,5,115,0,0,281,282,5,105,0,0,282,283,5,103,0,0,283,284,5,109,
0,0,284,66,1,0,0,0,285,286,5,99,0,0,286,287,5,108,0,0,287,288,5,
97,0,0,288,289,5,109,0,0,289,290,5,112,0,0,290,68,1,0,0,0,291,292,
5,102,0,0,292,293,5,102,0,0,293,294,5,116,0,0,294,70,1,0,0,0,295,
296,5,105,0,0,296,297,5,102,0,0,297,298,5,102,0,0,298,299,5,116,
0,0,299,72,1,0,0,0,300,301,5,97,0,0,301,302,5,110,0,0,302,303,5,
103,0,0,303,304,5,108,0,0,304,305,5,101,0,0,305,74,1,0,0,0,306,307,
5,112,0,0,307,308,5,114,0,0,308,309,5,105,0,0,309,310,5,110,0,0,
310,311,5,116,0,0,311,76,1,0,0,0,312,313,5,108,0,0,313,314,5,101,
0,0,314,315,5,114,0,0,315,316,5,112,0,0,316,78,1,0,0,0,317,318,5,
115,0,0,318,319,5,116,0,0,319,320,5,101,0,0,320,321,5,112,0,0,321,
80,1,0,0,0,322,323,5,115,0,0,323,324,5,109,0,0,324,325,5,111,0,0,
325,326,5,111,0,0,326,327,5,116,0,0,327,328,5,104,0,0,328,329,5,
115,0,0,329,330,5,116,0,0,330,331,5,101,0,0,331,332,5,112,0,0,332,
82,1,0,0,0,333,334,5,102,0,0,334,335,5,114,0,0,335,336,5,97,0,0,
336,337,5,99,0,0,337,338,5,116,0,0,338,84,1,0,0,0,339,340,5,114,
0,0,340,341,5,101,0,0,341,342,5,108,0,0,342,343,5,117,0,0,343,86,
1,0,0,0,344,345,5,115,0,0,345,346,5,111,0,0,346,347,5,102,0,0,347,
348,5,116,0,0,348,349,5,112,0,0,349,350,5,108,0,0,350,351,5,117,
0,0,351,352,5,115,0,0,352,88,1,0,0,0,353,354,5,103,0,0,354,355,5,
101,0,0,355,356,5,108,0,0,356,357,5,117,0,0,357,90,1,0,0,0,358,359,
5,115,0,0,359,360,5,105,0,0,360,361,5,103,0,0,361,362,5,110,0,0,
362,92,1,0,0,0,363,364,5,115,0,0,364,365,5,119,0,0,365,366,5,97,
0,0,366,367,5,112,0,0,367,94,1,0,0,0,368,369,5,43,0,0,369,96,1,0,
0,0,370,371,5,45,0,0,371,98,1,0,0,0,372,373,5,42,0,0,373,100,1,0,
0,0,374,375,5,47,0,0,375,102,1,0,0,0,376,377,5,37,0,0,377,104,1,
0,0,0,378,379,5,94,0,0,379,106,1,0,0,0,380,381,5,62,0,0,381,382,
5,61,0,0,382,108,1,0,0,0,383,384,5,62,0,0,384,110,1,0,0,0,385,386,
5,60,0,0,386,387,5,61,0,0,387,112,1,0,0,0,388,389,5,60,0,0,389,114,
1,0,0,0,390,391,5,61,0,0,391,392,5,61,0,0,392,116,1,0,0,0,393,394,
5,33,0,0,394,395,5,61,0,0,395,118,1,0,0,0,396,397,5,124,0,0,397,
120,1,0,0,0,398,399,5,112,0,0,399,404,5,105,0,0,400,401,5,80,0,0,
401,404,5,73,0,0,402,404,7,0,0,0,403,398,1,0,0,0,403,400,1,0,0,0,
403,402,1,0,0,0,404,122,1,0,0,0,405,407,7,1,0,0,406,405,1,0,0,0,
407,408,1,0,0,0,408,406,1,0,0,0,408,409,1,0,0,0,409,416,1,0,0,0,
410,412,5,46,0,0,411,413,7,1,0,0,412,411,1,0,0,0,413,414,1,0,0,0,
414,412,1,0,0,0,414,415,1,0,0,0,415,417,1,0,0,0,416,410,1,0,0,0,
416,417,1,0,0,0,417,124,1,0,0,0,418,422,7,2,0,0,419,421,7,3,0,0,
420,419,1,0,0,0,421,424,1,0,0,0,422,420,1,0,0,0,422,423,1,0,0,0,
423,126,1,0,0,0,424,422,1,0,0,0,425,427,7,4,0,0,426,425,1,0,0,0,
427,428,1,0,0,0,428,426,1,0,0,0,428,429,1,0,0,0,429,430,1,0,0,0,
430,431,6,63,0,0,431,128,1,0,0,0,7,0,403,408,414,416,422,428,1,6,
0,0
58,2,59,7,59,2,60,7,60,2,61,7,61,2,62,7,62,2,63,7,63,2,64,7,64,2,
65,7,65,2,66,7,66,2,67,7,67,2,68,7,68,1,0,1,0,1,1,1,1,1,2,1,2,1,
3,1,3,1,4,1,4,1,5,1,5,1,5,1,5,1,6,1,6,1,6,1,6,1,7,1,7,1,7,1,7,1,
8,1,8,1,8,1,8,1,8,1,9,1,9,1,9,1,9,1,9,1,10,1,10,1,10,1,10,1,10,1,
11,1,11,1,11,1,11,1,11,1,11,1,12,1,12,1,12,1,12,1,12,1,13,1,13,1,
13,1,13,1,13,1,14,1,14,1,14,1,14,1,14,1,15,1,15,1,15,1,15,1,15,1,
15,1,16,1,16,1,16,1,16,1,16,1,16,1,17,1,17,1,17,1,17,1,17,1,17,1,
18,1,18,1,18,1,18,1,19,1,19,1,19,1,19,1,19,1,20,1,20,1,20,1,21,1,
21,1,21,1,21,1,22,1,22,1,22,1,22,1,23,1,23,1,23,1,23,1,23,1,24,1,
24,1,24,1,24,1,24,1,25,1,25,1,25,1,25,1,25,1,26,1,26,1,26,1,26,1,
26,1,27,1,27,1,27,1,27,1,27,1,27,1,28,1,28,1,28,1,28,1,28,1,28,1,
29,1,29,1,29,1,29,1,29,1,29,1,30,1,30,1,30,1,30,1,30,1,31,1,31,1,
31,1,31,1,31,1,31,1,32,1,32,1,32,1,32,1,32,1,32,1,33,1,33,1,33,1,
33,1,34,1,34,1,34,1,34,1,34,1,35,1,35,1,35,1,35,1,35,1,35,1,36,1,
36,1,36,1,36,1,37,1,37,1,37,1,37,1,37,1,38,1,38,1,38,1,38,1,38,1,
38,1,39,1,39,1,39,1,39,1,39,1,39,1,40,1,40,1,40,1,40,1,40,1,41,1,
41,1,41,1,41,1,41,1,42,1,42,1,42,1,42,1,42,1,42,1,42,1,42,1,42,1,
42,1,42,1,43,1,43,1,43,1,43,1,43,1,43,1,44,1,44,1,44,1,44,1,44,1,
45,1,45,1,45,1,45,1,45,1,45,1,45,1,45,1,45,1,46,1,46,1,46,1,46,1,
46,1,47,1,47,1,47,1,47,1,47,1,48,1,48,1,48,1,48,1,49,1,49,1,49,1,
49,1,49,1,50,1,50,1,50,1,50,1,50,1,51,1,51,1,51,1,51,1,51,1,51,1,
51,1,51,1,52,1,52,1,53,1,53,1,54,1,54,1,55,1,55,1,56,1,56,1,57,1,
57,1,58,1,58,1,58,1,59,1,59,1,60,1,60,1,60,1,61,1,61,1,62,1,62,1,
62,1,63,1,63,1,63,1,64,1,64,1,65,1,65,1,65,1,65,1,65,3,65,435,8,
65,1,66,4,66,438,8,66,11,66,12,66,439,1,66,1,66,4,66,444,8,66,11,
66,12,66,445,3,66,448,8,66,1,67,1,67,5,67,452,8,67,10,67,12,67,455,
9,67,1,68,4,68,458,8,68,11,68,12,68,459,1,68,1,68,0,0,69,1,1,3,2,
5,3,7,4,9,5,11,6,13,7,15,8,17,9,19,10,21,11,23,12,25,13,27,14,29,
15,31,16,33,17,35,18,37,19,39,20,41,21,43,22,45,23,47,24,49,25,51,
26,53,27,55,28,57,29,59,30,61,31,63,32,65,33,67,34,69,35,71,36,73,
37,75,38,77,39,79,40,81,41,83,42,85,43,87,44,89,45,91,46,93,47,95,
48,97,49,99,50,101,51,103,52,105,53,107,54,109,55,111,56,113,57,
115,58,117,59,119,60,121,61,123,62,125,63,127,64,129,65,131,66,133,
67,135,68,137,69,1,0,5,2,0,69,69,101,101,1,0,48,57,3,0,65,90,95,
95,97,122,4,0,48,57,65,90,95,95,97,122,3,0,9,10,13,13,32,32,469,
0,1,1,0,0,0,0,3,1,0,0,0,0,5,1,0,0,0,0,7,1,0,0,0,0,9,1,0,0,0,0,11,
1,0,0,0,0,13,1,0,0,0,0,15,1,0,0,0,0,17,1,0,0,0,0,19,1,0,0,0,0,21,
1,0,0,0,0,23,1,0,0,0,0,25,1,0,0,0,0,27,1,0,0,0,0,29,1,0,0,0,0,31,
1,0,0,0,0,33,1,0,0,0,0,35,1,0,0,0,0,37,1,0,0,0,0,39,1,0,0,0,0,41,
1,0,0,0,0,43,1,0,0,0,0,45,1,0,0,0,0,47,1,0,0,0,0,49,1,0,0,0,0,51,
1,0,0,0,0,53,1,0,0,0,0,55,1,0,0,0,0,57,1,0,0,0,0,59,1,0,0,0,0,61,
1,0,0,0,0,63,1,0,0,0,0,65,1,0,0,0,0,67,1,0,0,0,0,69,1,0,0,0,0,71,
1,0,0,0,0,73,1,0,0,0,0,75,1,0,0,0,0,77,1,0,0,0,0,79,1,0,0,0,0,81,
1,0,0,0,0,83,1,0,0,0,0,85,1,0,0,0,0,87,1,0,0,0,0,89,1,0,0,0,0,91,
1,0,0,0,0,93,1,0,0,0,0,95,1,0,0,0,0,97,1,0,0,0,0,99,1,0,0,0,0,101,
1,0,0,0,0,103,1,0,0,0,0,105,1,0,0,0,0,107,1,0,0,0,0,109,1,0,0,0,
0,111,1,0,0,0,0,113,1,0,0,0,0,115,1,0,0,0,0,117,1,0,0,0,0,119,1,
0,0,0,0,121,1,0,0,0,0,123,1,0,0,0,0,125,1,0,0,0,0,127,1,0,0,0,0,
129,1,0,0,0,0,131,1,0,0,0,0,133,1,0,0,0,0,135,1,0,0,0,0,137,1,0,
0,0,1,139,1,0,0,0,3,141,1,0,0,0,5,143,1,0,0,0,7,145,1,0,0,0,9,147,
1,0,0,0,11,149,1,0,0,0,13,153,1,0,0,0,15,157,1,0,0,0,17,161,1,0,
0,0,19,166,1,0,0,0,21,171,1,0,0,0,23,176,1,0,0,0,25,182,1,0,0,0,
27,187,1,0,0,0,29,192,1,0,0,0,31,197,1,0,0,0,33,203,1,0,0,0,35,209,
1,0,0,0,37,215,1,0,0,0,39,219,1,0,0,0,41,224,1,0,0,0,43,227,1,0,
0,0,45,231,1,0,0,0,47,235,1,0,0,0,49,240,1,0,0,0,51,245,1,0,0,0,
53,250,1,0,0,0,55,255,1,0,0,0,57,261,1,0,0,0,59,267,1,0,0,0,61,273,
1,0,0,0,63,278,1,0,0,0,65,284,1,0,0,0,67,290,1,0,0,0,69,294,1,0,
0,0,71,299,1,0,0,0,73,305,1,0,0,0,75,309,1,0,0,0,77,314,1,0,0,0,
79,320,1,0,0,0,81,326,1,0,0,0,83,331,1,0,0,0,85,336,1,0,0,0,87,347,
1,0,0,0,89,353,1,0,0,0,91,358,1,0,0,0,93,367,1,0,0,0,95,372,1,0,
0,0,97,377,1,0,0,0,99,381,1,0,0,0,101,386,1,0,0,0,103,391,1,0,0,
0,105,399,1,0,0,0,107,401,1,0,0,0,109,403,1,0,0,0,111,405,1,0,0,
0,113,407,1,0,0,0,115,409,1,0,0,0,117,411,1,0,0,0,119,414,1,0,0,
0,121,416,1,0,0,0,123,419,1,0,0,0,125,421,1,0,0,0,127,424,1,0,0,
0,129,427,1,0,0,0,131,434,1,0,0,0,133,437,1,0,0,0,135,449,1,0,0,
0,137,457,1,0,0,0,139,140,5,40,0,0,140,2,1,0,0,0,141,142,5,41,0,
0,142,4,1,0,0,0,143,144,5,91,0,0,144,6,1,0,0,0,145,146,5,44,0,0,
146,8,1,0,0,0,147,148,5,93,0,0,148,10,1,0,0,0,149,150,5,115,0,0,
150,151,5,105,0,0,151,152,5,110,0,0,152,12,1,0,0,0,153,154,5,99,
0,0,154,155,5,111,0,0,155,156,5,115,0,0,156,14,1,0,0,0,157,158,5,
116,0,0,158,159,5,97,0,0,159,160,5,110,0,0,160,16,1,0,0,0,161,162,
5,97,0,0,162,163,5,115,0,0,163,164,5,105,0,0,164,165,5,110,0,0,165,
18,1,0,0,0,166,167,5,97,0,0,167,168,5,99,0,0,168,169,5,111,0,0,169,
170,5,115,0,0,170,20,1,0,0,0,171,172,5,97,0,0,172,173,5,116,0,0,
173,174,5,97,0,0,174,175,5,110,0,0,175,22,1,0,0,0,176,177,5,97,0,
0,177,178,5,116,0,0,178,179,5,97,0,0,179,180,5,110,0,0,180,181,5,
50,0,0,181,24,1,0,0,0,182,183,5,115,0,0,183,184,5,105,0,0,184,185,
5,110,0,0,185,186,5,104,0,0,186,26,1,0,0,0,187,188,5,99,0,0,188,
189,5,111,0,0,189,190,5,115,0,0,190,191,5,104,0,0,191,28,1,0,0,0,
192,193,5,116,0,0,193,194,5,97,0,0,194,195,5,110,0,0,195,196,5,104,
0,0,196,30,1,0,0,0,197,198,5,97,0,0,198,199,5,115,0,0,199,200,5,
105,0,0,200,201,5,110,0,0,201,202,5,104,0,0,202,32,1,0,0,0,203,204,
5,97,0,0,204,205,5,99,0,0,205,206,5,111,0,0,206,207,5,115,0,0,207,
208,5,104,0,0,208,34,1,0,0,0,209,210,5,97,0,0,210,211,5,116,0,0,
211,212,5,97,0,0,212,213,5,110,0,0,213,214,5,104,0,0,214,36,1,0,
0,0,215,216,5,97,0,0,216,217,5,98,0,0,217,218,5,115,0,0,218,38,1,
0,0,0,219,220,5,115,0,0,220,221,5,113,0,0,221,222,5,114,0,0,222,
223,5,116,0,0,223,40,1,0,0,0,224,225,5,108,0,0,225,226,5,110,0,0,
226,42,1,0,0,0,227,228,5,108,0,0,228,229,5,111,0,0,229,230,5,103,
0,0,230,44,1,0,0,0,231,232,5,101,0,0,232,233,5,120,0,0,233,234,5,
112,0,0,234,46,1,0,0,0,235,236,5,115,0,0,236,237,5,109,0,0,237,238,
5,105,0,0,238,239,5,110,0,0,239,48,1,0,0,0,240,241,5,115,0,0,241,
242,5,109,0,0,242,243,5,97,0,0,243,244,5,120,0,0,244,50,1,0,0,0,
245,246,5,116,0,0,246,247,5,109,0,0,247,248,5,105,0,0,248,249,5,
110,0,0,249,52,1,0,0,0,250,251,5,116,0,0,251,252,5,109,0,0,252,253,
5,97,0,0,253,254,5,120,0,0,254,54,1,0,0,0,255,256,5,116,0,0,256,
257,5,110,0,0,257,258,5,111,0,0,258,259,5,114,0,0,259,260,5,109,
0,0,260,56,1,0,0,0,261,262,5,115,0,0,262,263,5,110,0,0,263,264,5,
111,0,0,264,265,5,114,0,0,265,266,5,109,0,0,266,58,1,0,0,0,267,268,
5,102,0,0,268,269,5,108,0,0,269,270,5,111,0,0,270,271,5,111,0,0,
271,272,5,114,0,0,272,60,1,0,0,0,273,274,5,99,0,0,274,275,5,101,
0,0,275,276,5,105,0,0,276,277,5,108,0,0,277,62,1,0,0,0,278,279,5,
114,0,0,279,280,5,111,0,0,280,281,5,117,0,0,281,282,5,110,0,0,282,
283,5,100,0,0,283,64,1,0,0,0,284,285,5,103,0,0,285,286,5,97,0,0,
286,287,5,109,0,0,287,288,5,109,0,0,288,289,5,97,0,0,289,66,1,0,
0,0,290,291,5,112,0,0,291,292,5,111,0,0,292,293,5,119,0,0,293,68,
1,0,0,0,294,295,5,115,0,0,295,296,5,105,0,0,296,297,5,103,0,0,297,
298,5,109,0,0,298,70,1,0,0,0,299,300,5,99,0,0,300,301,5,108,0,0,
301,302,5,97,0,0,302,303,5,109,0,0,303,304,5,112,0,0,304,72,1,0,
0,0,305,306,5,102,0,0,306,307,5,102,0,0,307,308,5,116,0,0,308,74,
1,0,0,0,309,310,5,105,0,0,310,311,5,102,0,0,311,312,5,102,0,0,312,
313,5,116,0,0,313,76,1,0,0,0,314,315,5,97,0,0,315,316,5,110,0,0,
316,317,5,103,0,0,317,318,5,108,0,0,318,319,5,101,0,0,319,78,1,0,
0,0,320,321,5,112,0,0,321,322,5,114,0,0,322,323,5,105,0,0,323,324,
5,110,0,0,324,325,5,116,0,0,325,80,1,0,0,0,326,327,5,108,0,0,327,
328,5,101,0,0,328,329,5,114,0,0,329,330,5,112,0,0,330,82,1,0,0,0,
331,332,5,115,0,0,332,333,5,116,0,0,333,334,5,101,0,0,334,335,5,
112,0,0,335,84,1,0,0,0,336,337,5,115,0,0,337,338,5,109,0,0,338,339,
5,111,0,0,339,340,5,111,0,0,340,341,5,116,0,0,341,342,5,104,0,0,
342,343,5,115,0,0,343,344,5,116,0,0,344,345,5,101,0,0,345,346,5,
112,0,0,346,86,1,0,0,0,347,348,5,102,0,0,348,349,5,114,0,0,349,350,
5,97,0,0,350,351,5,99,0,0,351,352,5,116,0,0,352,88,1,0,0,0,353,354,
5,114,0,0,354,355,5,101,0,0,355,356,5,108,0,0,356,357,5,117,0,0,
357,90,1,0,0,0,358,359,5,115,0,0,359,360,5,111,0,0,360,361,5,102,
0,0,361,362,5,116,0,0,362,363,5,112,0,0,363,364,5,108,0,0,364,365,
5,117,0,0,365,366,5,115,0,0,366,92,1,0,0,0,367,368,5,103,0,0,368,
369,5,101,0,0,369,370,5,108,0,0,370,371,5,117,0,0,371,94,1,0,0,0,
372,373,5,115,0,0,373,374,5,105,0,0,374,375,5,103,0,0,375,376,5,
110,0,0,376,96,1,0,0,0,377,378,5,109,0,0,378,379,5,97,0,0,379,380,
5,112,0,0,380,98,1,0,0,0,381,382,5,99,0,0,382,383,5,111,0,0,383,
384,5,110,0,0,384,385,5,118,0,0,385,100,1,0,0,0,386,387,5,115,0,
0,387,388,5,119,0,0,388,389,5,97,0,0,389,390,5,112,0,0,390,102,1,
0,0,0,391,392,5,112,0,0,392,393,5,101,0,0,393,394,5,114,0,0,394,
395,5,109,0,0,395,396,5,117,0,0,396,397,5,116,0,0,397,398,5,101,
0,0,398,104,1,0,0,0,399,400,5,43,0,0,400,106,1,0,0,0,401,402,5,45,
0,0,402,108,1,0,0,0,403,404,5,42,0,0,404,110,1,0,0,0,405,406,5,47,
0,0,406,112,1,0,0,0,407,408,5,37,0,0,408,114,1,0,0,0,409,410,5,94,
0,0,410,116,1,0,0,0,411,412,5,62,0,0,412,413,5,61,0,0,413,118,1,
0,0,0,414,415,5,62,0,0,415,120,1,0,0,0,416,417,5,60,0,0,417,418,
5,61,0,0,418,122,1,0,0,0,419,420,5,60,0,0,420,124,1,0,0,0,421,422,
5,61,0,0,422,423,5,61,0,0,423,126,1,0,0,0,424,425,5,33,0,0,425,426,
5,61,0,0,426,128,1,0,0,0,427,428,5,124,0,0,428,130,1,0,0,0,429,430,
5,112,0,0,430,435,5,105,0,0,431,432,5,80,0,0,432,435,5,73,0,0,433,
435,7,0,0,0,434,429,1,0,0,0,434,431,1,0,0,0,434,433,1,0,0,0,435,
132,1,0,0,0,436,438,7,1,0,0,437,436,1,0,0,0,438,439,1,0,0,0,439,
437,1,0,0,0,439,440,1,0,0,0,440,447,1,0,0,0,441,443,5,46,0,0,442,
444,7,1,0,0,443,442,1,0,0,0,444,445,1,0,0,0,445,443,1,0,0,0,445,
446,1,0,0,0,446,448,1,0,0,0,447,441,1,0,0,0,447,448,1,0,0,0,448,
134,1,0,0,0,449,453,7,2,0,0,450,452,7,3,0,0,451,450,1,0,0,0,452,
455,1,0,0,0,453,451,1,0,0,0,453,454,1,0,0,0,454,136,1,0,0,0,455,
453,1,0,0,0,456,458,7,4,0,0,457,456,1,0,0,0,458,459,1,0,0,0,459,
457,1,0,0,0,459,460,1,0,0,0,460,461,1,0,0,0,461,462,6,68,0,0,462,
138,1,0,0,0,7,0,434,439,445,447,453,459,1,6,0,0
]
class MathExprLexer(Lexer):
@@ -173,82 +183,88 @@ class MathExprLexer(Lexer):
T__0 = 1
T__1 = 2
T__2 = 3
SIN = 4
COS = 5
TAN = 6
ASIN = 7
ACOS = 8
ATAN = 9
ATAN2 = 10
SINH = 11
COSH = 12
TANH = 13
ASINH = 14
ACOSH = 15
ATANH = 16
ABS = 17
SQRT = 18
LN = 19
LOG = 20
EXP = 21
SMIN = 22
SMAX = 23
TMIN = 24
TMAX = 25
TNORM = 26
SNORM = 27
FLOOR = 28
CEIL = 29
ROUND = 30
GAMMA = 31
POWE = 32
SIGM = 33
CLAMP = 34
SFFT = 35
SIFFT = 36
ANGL = 37
PRNT = 38
LERP = 39
STEP = 40
SMOOTHSTEP = 41
FRACT = 42
RELU = 43
SOFTPLUS = 44
GELU = 45
SIGN = 46
SWAP = 47
PLUS = 48
MINUS = 49
MULT = 50
DIV = 51
MOD = 52
POW = 53
GE = 54
GT = 55
LE = 56
LT = 57
EQ = 58
NE = 59
PIPE = 60
CONSTANT = 61
NUMBER = 62
VARIABLE = 63
WS = 64
T__3 = 4
T__4 = 5
SIN = 6
COS = 7
TAN = 8
ASIN = 9
ACOS = 10
ATAN = 11
ATAN2 = 12
SINH = 13
COSH = 14
TANH = 15
ASINH = 16
ACOSH = 17
ATANH = 18
ABS = 19
SQRT = 20
LN = 21
LOG = 22
EXP = 23
SMIN = 24
SMAX = 25
TMIN = 26
TMAX = 27
TNORM = 28
SNORM = 29
FLOOR = 30
CEIL = 31
ROUND = 32
GAMMA = 33
POWE = 34
SIGM = 35
CLAMP = 36
SFFT = 37
SIFFT = 38
ANGL = 39
PRNT = 40
LERP = 41
STEP = 42
SMOOTHSTEP = 43
FRACT = 44
RELU = 45
SOFTPLUS = 46
GELU = 47
SIGN = 48
MAP = 49
CONV = 50
SWAP = 51
PERM = 52
PLUS = 53
MINUS = 54
MULT = 55
DIV = 56
MOD = 57
POW = 58
GE = 59
GT = 60
LE = 61
LT = 62
EQ = 63
NE = 64
PIPE = 65
CONSTANT = 66
NUMBER = 67
VARIABLE = 68
WS = 69
channelNames = [ u"DEFAULT_TOKEN_CHANNEL", u"HIDDEN" ]
modeNames = [ "DEFAULT_MODE" ]
literalNames = [ "<INVALID>",
"'('", "')'", "','", "'sin'", "'cos'", "'tan'", "'asin'", "'acos'",
"'atan'", "'atan2'", "'sinh'", "'cosh'", "'tanh'", "'asinh'",
"'acosh'", "'atanh'", "'abs'", "'sqrt'", "'ln'", "'log'", "'exp'",
"'smin'", "'smax'", "'tmin'", "'tmax'", "'tnorm'", "'snorm'",
"'floor'", "'ceil'", "'round'", "'gamma'", "'pow'", "'sigm'",
"'clamp'", "'fft'", "'ifft'", "'angle'", "'print'", "'lerp'",
"'step'", "'smoothstep'", "'fract'", "'relu'", "'softplus'",
"'gelu'", "'sign'", "'swap'", "'+'", "'-'", "'*'", "'/'", "'%'",
"'^'", "'>='", "'>'", "'<='", "'<'", "'=='", "'!='", "'|'" ]
"'('", "')'", "'['", "','", "']'", "'sin'", "'cos'", "'tan'",
"'asin'", "'acos'", "'atan'", "'atan2'", "'sinh'", "'cosh'",
"'tanh'", "'asinh'", "'acosh'", "'atanh'", "'abs'", "'sqrt'",
"'ln'", "'log'", "'exp'", "'smin'", "'smax'", "'tmin'", "'tmax'",
"'tnorm'", "'snorm'", "'floor'", "'ceil'", "'round'", "'gamma'",
"'pow'", "'sigm'", "'clamp'", "'fft'", "'ifft'", "'angle'",
"'print'", "'lerp'", "'step'", "'smoothstep'", "'fract'", "'relu'",
"'softplus'", "'gelu'", "'sign'", "'map'", "'conv'", "'swap'",
"'permute'", "'+'", "'-'", "'*'", "'/'", "'%'", "'^'", "'>='",
"'>'", "'<='", "'<'", "'=='", "'!='", "'|'" ]
symbolicNames = [ "<INVALID>",
"SIN", "COS", "TAN", "ASIN", "ACOS", "ATAN", "ATAN2", "SINH",
@@ -256,17 +272,19 @@ class MathExprLexer(Lexer):
"LOG", "EXP", "SMIN", "SMAX", "TMIN", "TMAX", "TNORM", "SNORM",
"FLOOR", "CEIL", "ROUND", "GAMMA", "POWE", "SIGM", "CLAMP",
"SFFT", "SIFFT", "ANGL", "PRNT", "LERP", "STEP", "SMOOTHSTEP",
"FRACT", "RELU", "SOFTPLUS", "GELU", "SIGN", "SWAP", "PLUS",
"MINUS", "MULT", "DIV", "MOD", "POW", "GE", "GT", "LE", "LT",
"EQ", "NE", "PIPE", "CONSTANT", "NUMBER", "VARIABLE", "WS" ]
"FRACT", "RELU", "SOFTPLUS", "GELU", "SIGN", "MAP", "CONV",
"SWAP", "PERM", "PLUS", "MINUS", "MULT", "DIV", "MOD", "POW",
"GE", "GT", "LE", "LT", "EQ", "NE", "PIPE", "CONSTANT", "NUMBER",
"VARIABLE", "WS" ]
ruleNames = [ "T__0", "T__1", "T__2", "SIN", "COS", "TAN", "ASIN", "ACOS",
"ATAN", "ATAN2", "SINH", "COSH", "TANH", "ASINH", "ACOSH",
"ATANH", "ABS", "SQRT", "LN", "LOG", "EXP", "SMIN", "SMAX",
"TMIN", "TMAX", "TNORM", "SNORM", "FLOOR", "CEIL", "ROUND",
"GAMMA", "POWE", "SIGM", "CLAMP", "SFFT", "SIFFT", "ANGL",
"PRNT", "LERP", "STEP", "SMOOTHSTEP", "FRACT", "RELU",
"SOFTPLUS", "GELU", "SIGN", "SWAP", "PLUS", "MINUS", "MULT",
ruleNames = [ "T__0", "T__1", "T__2", "T__3", "T__4", "SIN", "COS",
"TAN", "ASIN", "ACOS", "ATAN", "ATAN2", "SINH", "COSH",
"TANH", "ASINH", "ACOSH", "ATANH", "ABS", "SQRT", "LN",
"LOG", "EXP", "SMIN", "SMAX", "TMIN", "TMAX", "TNORM",
"SNORM", "FLOOR", "CEIL", "ROUND", "GAMMA", "POWE", "SIGM",
"CLAMP", "SFFT", "SIFFT", "ANGL", "PRNT", "LERP", "STEP",
"SMOOTHSTEP", "FRACT", "RELU", "SOFTPLUS", "GELU", "SIGN",
"MAP", "CONV", "SWAP", "PERM", "PLUS", "MINUS", "MULT",
"DIV", "MOD", "POW", "GE", "GT", "LE", "LT", "EQ", "NE",
"PIPE", "CONSTANT", "NUMBER", "VARIABLE", "WS" ]
+129 -119
View File
@@ -1,124 +1,134 @@
T__0=1
T__1=2
T__2=3
SIN=4
COS=5
TAN=6
ASIN=7
ACOS=8
ATAN=9
ATAN2=10
SINH=11
COSH=12
TANH=13
ASINH=14
ACOSH=15
ATANH=16
ABS=17
SQRT=18
LN=19
LOG=20
EXP=21
SMIN=22
SMAX=23
TMIN=24
TMAX=25
TNORM=26
SNORM=27
FLOOR=28
CEIL=29
ROUND=30
GAMMA=31
POWE=32
SIGM=33
CLAMP=34
SFFT=35
SIFFT=36
ANGL=37
PRNT=38
LERP=39
STEP=40
SMOOTHSTEP=41
FRACT=42
RELU=43
SOFTPLUS=44
GELU=45
SIGN=46
SWAP=47
PLUS=48
MINUS=49
MULT=50
DIV=51
MOD=52
POW=53
GE=54
GT=55
LE=56
LT=57
EQ=58
NE=59
PIPE=60
CONSTANT=61
NUMBER=62
VARIABLE=63
WS=64
T__3=4
T__4=5
SIN=6
COS=7
TAN=8
ASIN=9
ACOS=10
ATAN=11
ATAN2=12
SINH=13
COSH=14
TANH=15
ASINH=16
ACOSH=17
ATANH=18
ABS=19
SQRT=20
LN=21
LOG=22
EXP=23
SMIN=24
SMAX=25
TMIN=26
TMAX=27
TNORM=28
SNORM=29
FLOOR=30
CEIL=31
ROUND=32
GAMMA=33
POWE=34
SIGM=35
CLAMP=36
SFFT=37
SIFFT=38
ANGL=39
PRNT=40
LERP=41
STEP=42
SMOOTHSTEP=43
FRACT=44
RELU=45
SOFTPLUS=46
GELU=47
SIGN=48
MAP=49
CONV=50
SWAP=51
PERM=52
PLUS=53
MINUS=54
MULT=55
DIV=56
MOD=57
POW=58
GE=59
GT=60
LE=61
LT=62
EQ=63
NE=64
PIPE=65
CONSTANT=66
NUMBER=67
VARIABLE=68
WS=69
'('=1
')'=2
','=3
'sin'=4
'cos'=5
'tan'=6
'asin'=7
'acos'=8
'atan'=9
'atan2'=10
'sinh'=11
'cosh'=12
'tanh'=13
'asinh'=14
'acosh'=15
'atanh'=16
'abs'=17
'sqrt'=18
'ln'=19
'log'=20
'exp'=21
'smin'=22
'smax'=23
'tmin'=24
'tmax'=25
'tnorm'=26
'snorm'=27
'floor'=28
'ceil'=29
'round'=30
'gamma'=31
'pow'=32
'sigm'=33
'clamp'=34
'fft'=35
'ifft'=36
'angle'=37
'print'=38
'lerp'=39
'step'=40
'smoothstep'=41
'fract'=42
'relu'=43
'softplus'=44
'gelu'=45
'sign'=46
'swap'=47
'+'=48
'-'=49
'*'=50
'/'=51
'%'=52
'^'=53
'>='=54
'>'=55
'<='=56
'<'=57
'=='=58
'!='=59
'|'=60
'['=3
','=4
']'=5
'sin'=6
'cos'=7
'tan'=8
'asin'=9
'acos'=10
'atan'=11
'atan2'=12
'sinh'=13
'cosh'=14
'tanh'=15
'asinh'=16
'acosh'=17
'atanh'=18
'abs'=19
'sqrt'=20
'ln'=21
'log'=22
'exp'=23
'smin'=24
'smax'=25
'tmin'=26
'tmax'=27
'tnorm'=28
'snorm'=29
'floor'=30
'ceil'=31
'round'=32
'gamma'=33
'pow'=34
'sigm'=35
'clamp'=36
'fft'=37
'ifft'=38
'angle'=39
'print'=40
'lerp'=41
'step'=42
'smoothstep'=43
'fract'=44
'relu'=45
'softplus'=46
'gelu'=47
'sign'=48
'map'=49
'conv'=50
'swap'=51
'permute'=52
'+'=53
'-'=54
'*'=55
'/'=56
'%'=57
'^'=58
'>='=59
'>'=60
'<='=61
'<'=62
'=='=63
'!='=64
'|'=65
+137 -2
View File
@@ -1,5 +1,5 @@
# Generated from MathExpr.g4 by ANTLR 4.13.2
from antlr4 import ParseTreeListener
# Generated from ./MathExpr.g4 by ANTLR 4.13.2
from antlr4 import *
if "." in __name__:
from .MathExprParser import MathExprParser
else:
@@ -215,6 +215,15 @@ class MathExprListener(ParseTreeListener):
pass
# Enter a parse tree produced by MathExprParser#Func4Exp.
def enterFunc4Exp(self, ctx:MathExprParser.Func4ExpContext):
pass
# Exit a parse tree produced by MathExprParser#Func4Exp.
def exitFunc4Exp(self, ctx:MathExprParser.Func4ExpContext):
pass
# Enter a parse tree produced by MathExprParser#FuncNExp.
def enterFuncNExp(self, ctx:MathExprParser.FuncNExpContext):
pass
@@ -260,6 +269,24 @@ class MathExprListener(ParseTreeListener):
pass
# Enter a parse tree produced by MathExprParser#AbsExp.
def enterAbsExp(self, ctx:MathExprParser.AbsExpContext):
pass
# Exit a parse tree produced by MathExprParser#AbsExp.
def exitAbsExp(self, ctx:MathExprParser.AbsExpContext):
pass
# Enter a parse tree produced by MathExprParser#ListExp.
def enterListExp(self, ctx:MathExprParser.ListExpContext):
pass
# Exit a parse tree produced by MathExprParser#ListExp.
def exitListExp(self, ctx:MathExprParser.ListExpContext):
pass
# Enter a parse tree produced by MathExprParser#SinFunc.
def enterSinFunc(self, ctx:MathExprParser.SinFuncContext):
pass
@@ -512,6 +539,51 @@ class MathExprListener(ParseTreeListener):
pass
# Enter a parse tree produced by MathExprParser#FractFunc.
def enterFractFunc(self, ctx:MathExprParser.FractFuncContext):
pass
# Exit a parse tree produced by MathExprParser#FractFunc.
def exitFractFunc(self, ctx:MathExprParser.FractFuncContext):
pass
# Enter a parse tree produced by MathExprParser#ReluFunc.
def enterReluFunc(self, ctx:MathExprParser.ReluFuncContext):
pass
# Exit a parse tree produced by MathExprParser#ReluFunc.
def exitReluFunc(self, ctx:MathExprParser.ReluFuncContext):
pass
# Enter a parse tree produced by MathExprParser#SoftplusFunc.
def enterSoftplusFunc(self, ctx:MathExprParser.SoftplusFuncContext):
pass
# Exit a parse tree produced by MathExprParser#SoftplusFunc.
def exitSoftplusFunc(self, ctx:MathExprParser.SoftplusFuncContext):
pass
# Enter a parse tree produced by MathExprParser#GeluFunc.
def enterGeluFunc(self, ctx:MathExprParser.GeluFuncContext):
pass
# Exit a parse tree produced by MathExprParser#GeluFunc.
def exitGeluFunc(self, ctx:MathExprParser.GeluFuncContext):
pass
# Enter a parse tree produced by MathExprParser#SignFunc.
def enterSignFunc(self, ctx:MathExprParser.SignFuncContext):
pass
# Exit a parse tree produced by MathExprParser#SignFunc.
def exitSignFunc(self, ctx:MathExprParser.SignFuncContext):
pass
# Enter a parse tree produced by MathExprParser#PowFunc.
def enterPowFunc(self, ctx:MathExprParser.PowFuncContext):
pass
@@ -548,6 +620,15 @@ class MathExprListener(ParseTreeListener):
pass
# Enter a parse tree produced by MathExprParser#StepFunc.
def enterStepFunc(self, ctx:MathExprParser.StepFuncContext):
pass
# Exit a parse tree produced by MathExprParser#StepFunc.
def exitStepFunc(self, ctx:MathExprParser.StepFuncContext):
pass
# Enter a parse tree produced by MathExprParser#ClampFunc.
def enterClampFunc(self, ctx:MathExprParser.ClampFuncContext):
pass
@@ -557,6 +638,33 @@ class MathExprListener(ParseTreeListener):
pass
# Enter a parse tree produced by MathExprParser#LerpFunc.
def enterLerpFunc(self, ctx:MathExprParser.LerpFuncContext):
pass
# Exit a parse tree produced by MathExprParser#LerpFunc.
def exitLerpFunc(self, ctx:MathExprParser.LerpFuncContext):
pass
# Enter a parse tree produced by MathExprParser#SmoothstepFunc.
def enterSmoothstepFunc(self, ctx:MathExprParser.SmoothstepFuncContext):
pass
# Exit a parse tree produced by MathExprParser#SmoothstepFunc.
def exitSmoothstepFunc(self, ctx:MathExprParser.SmoothstepFuncContext):
pass
# Enter a parse tree produced by MathExprParser#SwapFunc.
def enterSwapFunc(self, ctx:MathExprParser.SwapFuncContext):
pass
# Exit a parse tree produced by MathExprParser#SwapFunc.
def exitSwapFunc(self, ctx:MathExprParser.SwapFuncContext):
pass
# Enter a parse tree produced by MathExprParser#SMinFunc.
def enterSMinFunc(self, ctx:MathExprParser.SMinFuncContext):
pass
@@ -575,5 +683,32 @@ class MathExprListener(ParseTreeListener):
pass
# Enter a parse tree produced by MathExprParser#MapFunc.
def enterMapFunc(self, ctx:MathExprParser.MapFuncContext):
pass
# Exit a parse tree produced by MathExprParser#MapFunc.
def exitMapFunc(self, ctx:MathExprParser.MapFuncContext):
pass
# Enter a parse tree produced by MathExprParser#ConvFunc.
def enterConvFunc(self, ctx:MathExprParser.ConvFuncContext):
pass
# Exit a parse tree produced by MathExprParser#ConvFunc.
def exitConvFunc(self, ctx:MathExprParser.ConvFuncContext):
pass
# Enter a parse tree produced by MathExprParser#PermuteFunc.
def enterPermuteFunc(self, ctx:MathExprParser.PermuteFuncContext):
pass
# Exit a parse tree produced by MathExprParser#PermuteFunc.
def exitPermuteFunc(self, ctx:MathExprParser.PermuteFuncContext):
pass
del MathExprParser
File diff suppressed because it is too large Load Diff
+20
View File
@@ -159,6 +159,11 @@ class MathExprVisitor(ParseTreeVisitor):
return self.visitChildren(ctx)
# Visit a parse tree produced by MathExprParser#ListExp.
def visitListExp(self, ctx:MathExprParser.ListExpContext):
return self.visitChildren(ctx)
# Visit a parse tree produced by MathExprParser#SinFunc.
def visitSinFunc(self, ctx:MathExprParser.SinFuncContext):
return self.visitChildren(ctx)
@@ -379,5 +384,20 @@ class MathExprVisitor(ParseTreeVisitor):
return self.visitChildren(ctx)
# Visit a parse tree produced by MathExprParser#MapFunc.
def visitMapFunc(self, ctx:MathExprParser.MapFuncContext):
return self.visitChildren(ctx)
# Visit a parse tree produced by MathExprParser#ConvFunc.
def visitConvFunc(self, ctx:MathExprParser.ConvFuncContext):
return self.visitChildren(ctx)
# Visit a parse tree produced by MathExprParser#PermuteFunc.
def visitPermuteFunc(self, ctx:MathExprParser.PermuteFuncContext):
return self.visitChildren(ctx)
del MathExprParser
+308 -36
View File
@@ -1,7 +1,6 @@
import torch
import torch.special
from ..helper_functions import freq_to_time, time_to_freq
from .MathExprVisitor import MathExprVisitor
class TensorEvalVisitor(MathExprVisitor):
@@ -15,8 +14,66 @@ class TensorEvalVisitor(MathExprVisitor):
else:
self.device = device
def _fold_nd(self, tsr, spatial_dims):
# Ensure tensor has rank (spatial_dims + 2)
# 1. Unsqueeze if too low rank (add dummy channel at dim 1)
original_shape = tsr.shape
added_dims = 0
target_rank = spatial_dims + 2
while tsr.ndim < target_rank:
tsr = tsr.unsqueeze(1)
added_dims += 1
# 2. Fold leading dimensions into batch if too high rank
folded = False
if tsr.ndim > target_rank:
fold_count = tsr.ndim - target_rank
new_batch = 1
for i in range(fold_count + 1):
new_batch *= tsr.shape[i]
tsr = tsr.reshape(new_batch, *tsr.shape[fold_count+1:])
folded = True
else:
folded = (added_dims > 0)
return tsr, original_shape, added_dims, folded
def _unfold_nd(self, tsr, original_shape, added_dims, folded):
spatial_dims = tsr.ndim - 2
# Restore folded batch if any
if folded and added_dims == 0:
target_fold_rank = len(original_shape) - (spatial_dims + 1)
fold_dims = original_shape[:target_fold_rank]
tsr = tsr.reshape(*fold_dims, *tsr.shape[1:])
# Squeeze added dims (dummy channels)
for _ in range(added_dims):
if tsr.ndim > len(original_shape) and tsr.shape[1] == 1:
tsr = tsr.squeeze(1)
return tsr
def visitPermuteFunc(self, ctx):
tsr = self.visit(ctx.expr(0))
# permute(tsr, [d1, d2, ...]) or permute(tsr, d1, d2, ...)
# Actually FuncN grammar was not used for permute but it could be.
# Let's check the grammar. I added `PERM '(' expr ',' expr ')'` which is Func2 style.
# But for permute we need a list.
dims = self.visit(ctx.expr(1))
if isinstance(dims, torch.Tensor):
dims = dims.flatten().long().tolist()
return tsr.permute(*dims)
def visitReshapeFunc(self, ctx):
tsr = self.visit(ctx.expr(0))
new_shape = self.visit(ctx.expr(1))
if isinstance(new_shape, torch.Tensor):
new_shape = new_shape.flatten().long().tolist()
return tsr.reshape(*new_shape)
def visitNumberExp(self, ctx):
return torch.full(self.shape, float(ctx.getText()), device=self.device)
return torch.tensor(float(ctx.getText()), device=self.device)
def visitConstantExp(self, ctx):
name = ctx.getText().lower()
@@ -30,8 +87,10 @@ class TensorEvalVisitor(MathExprVisitor):
name = ctx.getText()
if name not in self.variables:
raise ValueError(f"Variable '{name}' not found")
if not isinstance(self.variables[name], torch.Tensor): return torch.full(self.shape, self.variables[name], device=self.device)
return self.variables[name]
val = self.variables[name]
if not isinstance(val, torch.Tensor):
return torch.tensor(float(val), device=self.device)
return val
def visitParenExp(self, ctx):
return self.visit(ctx.expr())
@@ -116,7 +175,18 @@ class TensorEvalVisitor(MathExprVisitor):
def visitAcoshFunc(self, ctx): return torch.acosh(self.visit(ctx.expr()))
def visitAtanhFunc(self, ctx): return torch.atanh(self.visit(ctx.expr()))
def visitAbsFunc(self, ctx): return torch.abs(self.visit(ctx.expr()))
def visitNormExp(self, ctx): return torch.full(self.shape, torch.linalg.norm(self.visit(ctx.expr())).item(), device=self.device)
def visitAbsExp(self, ctx): return torch.abs(self.visit(ctx.expr()))
def visitListExp(self, ctx):
vals = [self.visit(e) for e in ctx.expr()]
# If any are tensors with shape, stack them or create a tensor
if all(v.ndim == 0 for v in vals):
return torch.tensor([v.item() for v in vals], device=self.device)
else:
# Broadcasting stack
return torch.stack(torch.broadcast_tensors(*vals), dim=0)
def visitNormExp(self, ctx): return torch.linalg.norm(self.visit(ctx.expr()))
def visitSqrtFunc(self, ctx): return torch.sqrt(self.visit(ctx.expr()))
def visitLnFunc(self, ctx): return torch.log(self.visit(ctx.expr()))
def visitLogFunc(self, ctx): return torch.log10(self.visit(ctx.expr()))
@@ -143,11 +213,17 @@ class TensorEvalVisitor(MathExprVisitor):
return val
def visitSfftFunc(self, ctx):
"""
Spatial FFT - transforms the expression to frequency domain.
Applies FFT on all dimensions of the tensor.
"""
old_vars = self.variables
self.variables = self.spatial_variables.copy()
try:
val = self.visit(ctx.expr())
return time_to_freq(val)
# Apply FFT on all dimensions
dims = tuple(range(val.ndim))
return torch.fft.fftn(val, dim=dims)
finally:
self.variables = old_vars
@@ -177,50 +253,61 @@ class TensorEvalVisitor(MathExprVisitor):
return torch.index_select(tsr, dim, indices)
def visitSifftFunc(self, ctx):
"""
Spatial IFFT - evaluates expression in frequency domain then transforms back.
Provides frequency coordinate variables for each dimension:
- Kx, Ky, Kz: frequency indices for last 3 dims (0-indexed)
- K: isotropic frequency magnitude (Euclidean distance from DC)
- Fx, Fy, Fz: size of each frequency dimension
"""
old_vars = self.variables
# Switch to freq variables
self.variables = self.variables.copy()
device = self.spatial_variables['a'].device if 'a' in self.spatial_variables else torch.device('cpu')
dims = range(2, len(self.shape))
for d in dims:
size_d = self.shape[d]
device = self.device
ndim = len(self.shape)
dim_names = ['x', 'y', 'z', 'w', 'v', 'u'] # Names for dims (from last to first)
# Generate frequency coordinates for each dimension
k_components = []
for i in range(ndim):
dim_idx = ndim - 1 - i # Start from last dim
size_d = self.shape[dim_idx]
# Create frequency indices (0-indexed, will be shifted for DC centering if needed)
values = torch.arange(size_d, dtype=torch.float32, device=device)
view_shape = [1] * len(self.shape)
view_shape[d] = size_d
view_shape = [1] * ndim
view_shape[dim_idx] = size_d
values = values.view(*view_shape).expand(*self.shape)
# Bind variables
if d == 2:
self.variables['K'] = values
self.variables['F'] = size_d
self.variables['Ky'] = values
self.variables['Fy'] = size_d
self.variables['frequency'] = self.variables['K'] # K is index
self.variables['frequency_count'] = self.variables['F'] # F is scalar
if d == 3:
self.variables['Kx'] = values
self.variables['Fx'] = size_d
# Bind named variables (Kx, Ky, Kz for last 3 dims)
if i < len(dim_names):
var_name = f'K{dim_names[i]}'
self.variables[var_name] = values
self.variables[f'F{dim_names[i]}'] = float(size_d)
# Generic fallback
self.variables[f'K_dim{d}'] = values
self.variables[f'F_dim{d}'] = size_d
# Generic fallback for all dims
self.variables[f'K_dim{dim_idx}'] = values
self.variables[f'F_dim{dim_idx}'] = float(size_d)
k_components.append(values)
# Calculate isotropic K (Euclidean distance from DC)
# K = sqrt(K_2^2 + K_3^2 + ...)
k_sq_sum = torch.zeros(self.shape, device=device)
dims = range(2, len(self.shape))
for d in dims:
# Re-access the K variable for this dim (safe way)
k_val = self.variables.get(f'K_dim{d}')
if k_val is not None:
k_sq_sum = torch.add(k_sq_sum, torch.pow(k_val, 2))
for k_val in k_components:
k_sq_sum = k_sq_sum + k_val ** 2
self.variables['K'] = torch.sqrt(k_sq_sum)
self.variables['frequency'] = self.variables['K']
# Legacy aliases
if 'Kx' in self.variables:
self.variables['frequency_count'] = self.variables.get('Fx', 1.0)
try:
val = self.visit(ctx.expr())
return freq_to_time(val)
# Apply IFFT on all dimensions
dims = tuple(range(val.ndim))
return torch.fft.ifftn(val, dim=dims).real
finally:
self.variables = old_vars
@@ -244,7 +331,6 @@ class TensorEvalVisitor(MathExprVisitor):
# Scale, bias and saturate x to 0..1 range
t = torch.clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0)
# Evaluate polynomial
return t * t * (3.0 - 2.0 * t)
def visitStepFunc(self, ctx):
@@ -255,9 +341,14 @@ class TensorEvalVisitor(MathExprVisitor):
# N-argument functions
def visitSMinFunc(self, ctx):
args = [self.visit(e) for e in ctx.expr()]
if len(args) == 1:
return torch.min(args[0]) # Global min of single tensor
return torch.min(torch.stack(torch.broadcast_tensors(*args)))
def visitSMaxFunc(self, ctx):
args = [self.visit(e) for e in ctx.expr()]
if len(args) == 1:
return torch.max(args[0]) # Global max of single tensor
return torch.max(torch.stack(torch.broadcast_tensors(*args)))
def visitTMinFunc(self, ctx):
@@ -275,6 +366,187 @@ class TensorEvalVisitor(MathExprVisitor):
return self.visitChildren(ctx)
def visitFunc4Exp(self, ctx):
return self.visitChildren(ctx)
def _normalize_coord(self, coord, size):
if size > 1:
return (coord / (size - 1)) * 2.0 - 1.0
return torch.zeros_like(coord)
def visitMapFunc(self, ctx):
tensor = self.visit(ctx.expr(0))
coords = [self.visit(ctx.expr(i)) for i in range(1, len(ctx.expr()))]
num_coords = len(coords)
if num_coords == 0:
return tensor
is_1d = (num_coords == 1)
if is_1d:
tensor = tensor.unsqueeze(-2)
zeros = torch.zeros_like(coords[0])
coords.append(zeros)
working_num_coords = len(coords)
spatial_in_shape = tensor.shape[-working_num_coords:]
leading_shape = tensor.shape[:-working_num_coords]
batch_size = 1
for s in leading_shape:
batch_size *= s
if len(leading_shape) == 0:
input_view = tensor.view(1, 1, *spatial_in_shape)
else:
input_view = tensor.view(batch_size, 1, *spatial_in_shape)
norm_coords_list = []
for i, coord in enumerate(coords):
dim_size = spatial_in_shape[-(i+1)]
norm = self._normalize_coord(coord, dim_size)
norm_coords_list.append(norm)
try:
broadcasted_coords = torch.broadcast_tensors(*norm_coords_list)
except RuntimeError:
raise ValueError(f"map(): Coordinate shapes {[c.shape for c in coords]} cannot be broadcast together.")
grid = torch.stack(broadcasted_coords, dim=-1)
grid_spatial_shape = grid.shape[:-1]
is_batched = False
if len(leading_shape) > 0 and len(grid_spatial_shape) >= len(leading_shape):
if grid_spatial_shape[:len(leading_shape)] == leading_shape:
is_batched = True
if batch_size > 1 and not is_batched:
grid = grid.expand(batch_size, *grid.shape)
grid_spatial_shape = grid.shape[1:-1]
elif is_batched:
flatten_shape = (batch_size,) + grid_spatial_shape[len(leading_shape):] + (grid.shape[-1],)
grid = grid.reshape(flatten_shape)
grid_spatial_shape = flatten_shape[1:-1]
total_output_elements = grid.numel() // working_num_coords // batch_size
if working_num_coords == 2:
grid_view = grid.reshape(batch_size, 1, total_output_elements, 2)
output = torch.nn.functional.grid_sample(
input_view, grid_view, mode='bilinear', padding_mode='zeros', align_corners=True
)
elif working_num_coords == 3:
grid_view = grid.reshape(batch_size, 1, 1, total_output_elements, 3)
output = torch.nn.functional.grid_sample(
input_view, grid_view, mode='bilinear', padding_mode='zeros', align_corners=True
)
else:
raise ValueError(f"map() supports up to 3 coordinate dimensions, got {num_coords} original coords.")
output = output.view(batch_size, total_output_elements)
final_shape = list(leading_shape) + list(grid_spatial_shape)
output = output.view(final_shape)
return output
def _kernel_coords(self, size, device):
half = size // 2
return torch.arange(size, device=device).float() - half
def visitConvFunc(self, ctx):
"""
N-dimensional convolution.
conv(tensor, kw, expr) - 1D conv on last dim
conv(tensor, kw, kh, expr) - 2D conv on last 2 dims
conv(tensor, kw, kh, kd, expr) - 3D conv on last 3 dims
Kernel expression uses kX, kY, kZ as centered coordinates.
"""
img = self.visit(ctx.expr(0))
num_args = len(ctx.expr())
# Parse kernel sizes based on argument count
if num_args == 3:
kernel_sizes = [int(self.visit(ctx.expr(1)).flatten()[0].item())]
k_expr_ctx = ctx.expr(2)
elif num_args == 4:
kernel_sizes = [
int(self.visit(ctx.expr(1)).flatten()[0].item()),
int(self.visit(ctx.expr(2)).flatten()[0].item())
]
k_expr_ctx = ctx.expr(3)
elif num_args == 5:
kernel_sizes = [
int(self.visit(ctx.expr(1)).flatten()[0].item()),
int(self.visit(ctx.expr(2)).flatten()[0].item()),
int(self.visit(ctx.expr(3)).flatten()[0].item())
]
k_expr_ctx = ctx.expr(4)
else:
raise ValueError("conv() expects 3-5 arguments: (tensor, kw, [kh], [kd], kernel_expr|list)")
num_spatial = len(kernel_sizes)
kw = kernel_sizes[0]
kh = kernel_sizes[1] if num_spatial >= 2 else 1
kd = kernel_sizes[2] if num_spatial >= 3 else 1
kx = self._kernel_coords(kw, self.device).view(1, 1, kw).expand(kd, kh, kw)
ky = self._kernel_coords(kh, self.device).view(1, kh, 1).expand(kd, kh, kw)
kz = self._kernel_coords(kd, self.device).view(kd, 1, 1).expand(kd, kh, kw)
k_variables = self.variables.copy()
k_variables.update({
'kX': kx, 'kY': ky, 'kZ': kz,
'kW': float(kw), 'kH': float(kh), 'kD': float(kd)
})
k_visitor = TensorEvalVisitor(k_variables, (kd, kh, kw), device=self.device)
kernel = k_visitor.visit(k_expr_ctx)
if kernel.numel() == 1:
kernel = kernel.expand(kd, kh, kw).clone()
elif kernel.numel() == kw * kh * kd:
kernel = kernel.reshape(kd, kh, kw)
leading_shape = img.shape[:-num_spatial] if num_spatial < img.ndim else ()
spatial_shape = img.shape[-num_spatial:]
combined_leading = 1
for s in leading_shape:
combined_leading *= s
if len(leading_shape) == 0:
reshaped = img.unsqueeze(0).unsqueeze(0)
else:
reshaped = img.reshape(combined_leading, 1, *spatial_shape)
channels = reshaped.shape[1]
if num_spatial == 1:
kernel_1d = kernel.flatten()[:kw]
conv_kernel = kernel_1d.view(1, 1, kw).expand(channels, 1, kw)
output = torch.nn.functional.conv1d(reshaped, conv_kernel, padding=kw//2, groups=channels)
elif num_spatial == 2:
kernel_2d = kernel[0] if kd > 1 else kernel.reshape(kh, kw)
conv_kernel = kernel_2d.view(1, 1, kh, kw).expand(channels, 1, kh, kw)
output = torch.nn.functional.conv2d(reshaped, conv_kernel, padding=(kh//2, kw//2), groups=channels)
elif num_spatial == 3:
conv_kernel = kernel.view(1, 1, kd, kh, kw).expand(channels, 1, kd, kh, kw)
output = torch.nn.functional.conv3d(reshaped, conv_kernel, padding=(kd//2, kh//2, kw//2), groups=channels)
else:
raise ValueError(f"conv() supports up to 3 spatial dimensions, got {num_spatial}")
output = output.squeeze(1)
if len(leading_shape) == 0:
output = output.squeeze(0)
else:
final_shape = list(leading_shape) + list(output.shape[1:])
output = output.reshape(final_shape)
return output
def visitAtomExp(self, ctx):
return self.visitChildren(ctx)