def apply_binary_simplification(gr, sym): op = gr._adj[sym] op_type = graph.get_opname(op) args = graph.get_args(op) types = gr._types(args) this_op = gr._op_table[op_type][types] Log.debug("simplifying :", sym) Log.debug(op) if 'zero' in this_op.keys(): identities = this_op['zero'] Log.warn(identities, args) for n, (ident, arg) in enumerate(zip(identities, args)): if ident is None: continue if arg == ident(*args): Log.debug("Shortcut: {} <- {}".format(sym, args[n])) gr.replace(sym, args[n]) if 'identity' in this_op.keys(): identities = this_op['identity'] for n, (ident, arg) in enumerate(zip(identities, args)): if ident is None: continue if arg == ident(*args): Log.debug("Shortcut: {} <- {}".format(sym, args[int(not n)])) gr.replace(sym, args[int(not n)])
def member(sym, gr, name=None): assert name is not None args = graph.get_args(gr.adj[sym]) s2t = partial(sym_to_text, gr=gr) formed_args = ", ".join(map(s2t, args[1:])) return "{}.{}({})".format(sym_to_text(args[0], gr), name, formed_args)
def block(sym, gr, name=None): op = gr.adj[sym] args = graph.get_args(op) use_sym = sym_to_text(args[0], gr) x, y = args[1], args[2], x_size, y_size = args[3], args[4], return "{}.block<{}, {}>({}, {})".format(use_sym, x_size, y_size, x, y)
def extract(sym, gr): op = gr.adj[sym] args = graph.get_args(op) assert isinstance(args[1], int), "Oh shit what are you doing" struct_name = args[0] ind = args[1] field_name = gr.get_properties(struct_name)['names'][ind] return "{}.{}".format(struct_name, field_name)
def hat(sym, gr): args = graph.get_args(gr.adj[sym]) dim = gr.get_properties(sym)['dim'] mappings = { (3, 3): 'SO3', (4, 4): 'SE3', } return "{}::hat({})".format(mappings[dim], sym_to_text(args[0], gr=gr))
def binary(sym, gr, operator=None): assert operator is not None op = gr.adj[sym] args = graph.get_args(op) return "{a} {operator} {b}".format( a=sym_to_text(args[0], gr), b=sym_to_text(args[1], gr), operator=operator, )
def build_struct(sym, gr): op = gr.adj[sym] args = graph.get_args(op) props = gr.get_properties(sym) if props['inherent_type'] is None: Log.warn("{} lacks inherent type".format(sym)) assert props['inherent_type'] is not None, "Can't create type for a group without inherent type." new_args = ',\n'.join(map(partial(sym_to_text, gr=gr), args)) return props['inherent_type'] + "{" + new_args + "}\n"
def inv(sym, gr): op = gr.adj[sym] args = graph.get_args(op) arg_type = gr.get_properties(args[0])['type'] if arg_type in ['liegroup', 'matrix']: return "{}.inverse()".format(sym_to_text(args[0], gr)) elif arg_type == 'scalar': return "(1.0 / {})".format(sym_to_text(args[0], gr)) else: assert False, "Unupported inverse type"
def vstack(sym, gr): op = gr.adj[sym] args = graph.get_args(op) n_args = gr.get_properties(sym)['dim'][0] s2t = partial(sym_to_text, gr=gr) formed_args = ", ".join(map(s2t, args)) return "(VecNd<{n}>() << {args}).finished()".format( n=n_args, args=formed_args )
def func(sym, gr): op = gr.adj[sym] args = graph.get_args(op) func_name = op[0] prefix = "" if func_name in gr.subgraph_functions: overload = gr.get_subgraph_overload(func_name, args) if overload['member'] is not None: prefix = "{}::".format(overload['member']) return prefix + "{}({})".format( func_name, ','.join(map(partial(sym_to_text, gr=gr), args)) )
def scrub_identity(gr, sym): op = gr._adj[sym] args = graph.get_args(op) Log.debug("Shortcut: {} <- {}".format(sym, args[0])) gr.replace(sym, args[0])
def identity(sym, gr): args = graph.get_args(gr.adj[sym]) return sym_to_text(args[0], gr)
def vector_index(sym, gr): op = gr.adj[sym] args = graph.get_args(op) vec_name = args[0] index = args[1] return "{}[{}]".format(sym_to_text(vec_name, gr), index)
def exp(sym, gr): args = graph.get_args(gr.adj[sym]) result_type = gr.get_properties(sym)['subtype'] return "{}::exp({})".format(result_type, sym_to_text(args[0], gr=gr))
def log(sym, gr): args = graph.get_args(gr.adj[sym]) input_type = gr.get_properties(args[0])['subtype'] return "{}::log({})".format(input_type, sym_to_text(args[0], gr=gr))