1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
|
from ..Node import Node
from .common import CtrlNode
class UniOpNode(Node):
"""Generic node for performing any operation like Out = In.fn()"""
def __init__(self, name, fn):
self.fn = fn
Node.__init__(self, name, terminals={
'In': {'io': 'in'},
'Out': {'io': 'out', 'bypass': 'In'}
})
def process(self, **args):
return {'Out': getattr(args['In'], self.fn)()}
class BinOpNode(CtrlNode):
"""Generic node for performing any operation like A.fn(B)"""
_dtypes = [
'float64', 'float32', 'float16',
'int64', 'int32', 'int16', 'int8',
'uint64', 'uint32', 'uint16', 'uint8'
]
uiTemplate = [
('outputType', 'combo', {'values': ['no change', 'input A', 'input B'] + _dtypes , 'index': 0})
]
def __init__(self, name, fn):
self.fn = fn
CtrlNode.__init__(self, name, terminals={
'A': {'io': 'in'},
'B': {'io': 'in'},
'Out': {'io': 'out', 'bypass': 'A'}
})
def process(self, **args):
if isinstance(self.fn, tuple):
for name in self.fn:
try:
fn = getattr(args['A'], name)
break
except AttributeError as e:
pass
else:
raise e
else:
fn = getattr(args['A'], self.fn)
out = fn(args['B'])
if out is NotImplemented:
raise Exception("Operation %s not implemented between %s and %s" % (fn, str(type(args['A'])), str(type(args['B']))))
# Coerce dtype if requested
typ = self.stateGroup.state()['outputType']
if typ == 'no change':
pass
elif typ == 'input A':
out = out.astype(args['A'].dtype)
elif typ == 'input B':
out = out.astype(args['B'].dtype)
else:
out = out.astype(typ)
#print " ", fn, out
return {'Out': out}
class AbsNode(UniOpNode):
"""Returns abs(Inp). Does not check input types."""
nodeName = 'Abs'
def __init__(self, name):
UniOpNode.__init__(self, name, '__abs__')
class AddNode(BinOpNode):
"""Returns A + B. Does not check input types."""
nodeName = 'Add'
def __init__(self, name):
BinOpNode.__init__(self, name, '__add__')
class SubtractNode(BinOpNode):
"""Returns A - B. Does not check input types."""
nodeName = 'Subtract'
def __init__(self, name):
BinOpNode.__init__(self, name, '__sub__')
class MultiplyNode(BinOpNode):
"""Returns A * B. Does not check input types."""
nodeName = 'Multiply'
def __init__(self, name):
BinOpNode.__init__(self, name, '__mul__')
class DivideNode(BinOpNode):
"""Returns A / B. Does not check input types."""
nodeName = 'Divide'
def __init__(self, name):
# try truediv first, followed by div
BinOpNode.__init__(self, name, ('__truediv__', '__div__'))
class FloorDivideNode(BinOpNode):
"""Returns A // B. Does not check input types."""
nodeName = 'FloorDivide'
def __init__(self, name):
BinOpNode.__init__(self, name, '__floordiv__')
|