def breed(self, p1, p2): def const_expr(p): len(p.vars()) == 0 or \ all(map(lambda n: "par" in n, p.vars())) def product_expr(p): return all(map(lambda n: isinstance(n,genoplib.Var) or \ isinstance(n,genoplib.Mult) or \ isinstance(n,lamboplib.SmoothStep) or \ isinstance(n,lamboplib.Normalize), p.nodes())) par_idx = len(self.get_params(p1)) p2_pars = self.get_params(p2) p2_repl = dict(map(lambda i: (p2_pars[i], \ genoplib.Var('par%d' % (par_idx + i))), \ range(len(p2_pars)))) p2_new = p2.substitute(p2_repl) if not const_expr(p1) or not const_expr(p2): yield genoplib.Add(p1.copy(), p2_new.copy()) if product_expr(p1) and product_expr(p2_new): variables = ['par0'] variables += list(filter(lambda v: not 'par' in v, p1.vars())) variables += list(filter(lambda v: not 'par' in v, p2_new.vars())) yield genoplib.product(list(map(lambda v: genoplib.Var(v), \ variables)))
def apply_fuse_lut(goal,rule,unif): law_var = tablib.LawVar(rule.law,rule.ident,tablib.LawVar.APPLY) stmts = [] if isinstance(goal.variable, tablib.DSVar): var_name = goal.variable.var stmts.append(tablib.VADPSource(law_var,genoplib.Var(var_name))) else: stmts.append(tablib.VADPConn(law_var,goal.variable)) inpexpr = unif.get_by_name('a') coeff,base_expr = genoplib.factor_coefficient(inpexpr) assert(not base_expr is None) expr = unif.get_by_name('e') repl = {'T': genoplib.Mult(genoplib.Const(1.0/coeff), \ genoplib.Var("y")) \ } rule_var = vadplib.LawVar(rule.law,rule.ident) cfg = tablib.VADPConfig(rule_var,rule.mode) cfg.bind('e',expr.substitute(repl)) stmts.append(cfg) new_unif = unifylib.Unification() new_unif.set_by_name('a', base_expr) return new_unif,stmts
def root_functions(self): yield genoplib.Var('par0') for v in self.variables: yield genoplib.Mult(genoplib.Var('par0'), genoplib.Var(v)) for v in self.variables: rng = self.ranges[v] middle = np.mean(rng) scale = max(abs(max(rng)), abs(min(rng))) norm = lamboplib.Normalize(genoplib.Var(v), offset=middle, ampl=scale)
def get_expr(self, block, rel): if self == ProfileOpType.INPUT_OUTPUT: return rel elif self == ProfileOpType.INTEG_INITIAL_COND: integ_expr = genoplib.unpack_integ(rel) return integ_expr.init_cond elif self == ProfileOpType.INTEG_DERIVATIVE_GAIN: integ_expr = genoplib.unpack_integ(rel) coeff, offset, exprs = genoplib.unpack_linear_operator( integ_expr.deriv) assert (all(map(lambda expr: expr.op == oplib.OpType.VAR, exprs))) all_vars = list(map(lambda e: e.name, exprs)) block_vars = list(map(lambda inp: inp.name, block.inputs)) + \ list(map(lambda dat: dat.name, block.data)) model_terms = list(filter(lambda v: not v in block_vars, all_vars)) block_terms = list(filter(lambda v: v in block_vars, all_vars)) rel = genoplib.product([genoplib.Const(coeff)] + \ list(map(lambda v: genoplib.Var(v), \ model_terms))) return rel elif self == ProfileOpType.INTEG_DERIVATIVE_BIAS: integ_expr = genoplib.unpack_integ(rel) coeff, offset, exprs = genoplib.unpack_linear_operator( integ_expr.deriv) return genoplib.Const(offset) else: return genoplib.Const(0.0)
def _prepare_minimize_model(variables,expr,params,bounds={}): n_inputs = len(variables) #if phys.model.complete: # return False repl = {} dataset = [None]*n_inputs for idx,bound_var in enumerate(variables): repl[bound_var] = genoplib.Var("x[%d]" % idx) for par,value in params.items(): repl[par] = genoplib.Const(value) bounds_arr = [(None,None)]*n_inputs for var,(lower,upper) in bounds.items(): if not var in variables: continue idx = variables.index(var) bounds_arr[idx] = (lower,upper) conc_expr = expr.substitute(repl) _,pyexpr = lambdoplib.to_python(conc_expr) return { 'expr':pyexpr, 'bounds':bounds_arr, 'variable_array':variables }
def apply_kirchoff(goal,rule,unif): law_var = tablib.LawVar(rule.law,rule.ident,tablib.LawVar.APPLY) stmt = [] if isinstance(goal.variable, tablib.DSVar): var_name = goal.variable.var stmt.append(tablib.VADPSource(law_var,genoplib.Var(var_name))) else: stmt.append(tablib.VADPConn(law_var,goal.variable)) return unif,stmt
def create_vadp_frag(hierarchy, input_var, parent_vadp, instance_map={}): def fresh_ident(block): if not block.name in instance_map: instance_map[block.name] = 0 inst = instance_map[block.name] instance_map[block.name] += 1 return inst if len(hierarchy) == 0: return [] vadp = [] n_children = len(hierarchy[1]) if len(hierarchy) > 1 else 0 stems = [] for frag in hierarchy[0]: inst = fresh_ident(frag['block']) targ = vadplib.PortVar(frag['block'], inst) vadp.append(vadplib.VADPConfig(targ, frag['modes'])) inp_port = targ.make_port_var(list(frag['block'].inputs)[0]) for port, expr in frag['exprs'].items(): out_port_var = targ.make_port_var(frag['block'].outputs[port]) vadp.append(vadplib.VADPSource(out_port_var, expr)) # inject connection found_source = False for idx, stmt in enumerate(parent_vadp): if isinstance(stmt,vadplib.VADPSource) \ and stmt.dsexpr.op == oplib.OpType.VAR \ and stmt.dsexpr.name == input_var: vadp.append(vadplib.VADPConn(stmt.target, inp_port)) parent_vadp.pop(idx) found_source = True break if not found_source: vadp.append(vadplib.VADPSink(inp_port, genoplib.Var(input_var))) enclosing_vadp = list(vadp) + list(parent_vadp) if len(hierarchy) > 1: vadp += create_vadp_frag(hierarchy[1:], input_var, enclosing_vadp, instance_map) # at most one sink statement sources = list( filter(lambda vst: isinstance(vst, vadplib.VADPSource), vadp)) other_stmts = list( filter(lambda vst: not isinstance(vst, vadplib.VADPSource), vadp)) for st in vadp: if isinstance(st, vadplib.VADPConn): sources = list(filter(lambda src: st.source != src.target, sources)) vadp = sources + other_stmts n_sinks = len( list(filter(lambda vst: isinstance(vst, vadplib.VADPSink), vadp))) assert (n_sinks <= 1) return vadp
def fit_model(all_vars,expr,data): #print("*********START OF FIT_MODEL*********") inputs = {} for varname,datum in data['inputs'].items(): if varname in expr.vars(): inputs[varname] = datum variables = [] for varname in all_vars: if varname in expr.vars(): variables.append(varname) if len(variables) == 0: print("no variables to fit... all-vars=%s expr=%s" % (all_vars,expr)) return meas_output = data['meas_mean'] n_inputs = len(inputs.keys()) #if phys.model.complete: # return False repl = {} dataset = [None]*n_inputs for idx,bound_var in enumerate(inputs.keys()): assert(len(inputs[bound_var]) == len(meas_output)) dataset[idx] = inputs[bound_var] #print("dataset[idx] is:", dataset[idx]) repl[bound_var] = genoplib.Var("x[%d]" % idx) #print("repl[bound_var]: ",repl[bound_var]) conc_expr = expr.substitute(repl) _,pyexpr = lambdoplib.to_python(conc_expr) fields = { 'free_vars':",".join(variables), 'free_var_array':",".join(map(lambda p: '"%s"' % p, variables)), 'x_dataset': str(dataset), 'y_dataset': str(meas_output), 'expr':pyexpr } #print("fields:",fields) snippet = FIT_PROG.format(**fields) \ .replace('math.','np.') loc = {} if len(data['meas_mean']) == 0: raise Exception("fit_model: cannot fit empty dataset") exec(snippet,globals(),loc) parameters = loc['lbls'] parameter_values = loc['popt'] parameter_stdevs = loc['perr'] return { 'params': dict(zip(parameters,parameter_values)), 'param_error': parameter_stdevs }
def apply(self, goal, rule, unif=None): assert (rule.law.name == self.name) law_var = rule.target.make_law_var(self.virt.output.name) stmt = [] if isinstance(goal.variable, tablib.DSVar): var_name = goal.variable.var stmt.append(tablib.VADPSource(law_var, genoplib.Var(var_name))) else: stmt.append(tablib.VADPConn(law_var, goal.variable)) return unif, stmt
def group_mode_sets(blk, input_var): groupby_mode = {} inp = list(blk.inputs)[0] output_names = list(map(lambda o: o.name, blk.outputs)) for mode in blk.modes: key = "" for output in output_names: rel = blk.outputs[output] \ .relation[mode].substitute({inp.name:genoplib.Var(input_var)}) key += "%s=%s," % (output, rel) if not key in groupby_mode: groupby_mode[key] = [] groupby_mode[key].append(mode) return groupby_mode.values()
def do_harmonize(baseline,deviations,modes): coeff,expr = genoplib \ .factor_positive_coefficient(baseline) new_gains = [] new_modes = [] gains = {} gain_var_name = gain_var(GAIN_ID) for mode,deviation in zip(modes,deviations): coeff_dev,expr_dev = genoplib \ .factor_positive_coefficient(deviation) if lambdaoplib.equivalent(expr,expr_dev): gain_value = coeff_dev/coeff gains[mode] = gain_value else: raise NotHarmonizableError("expressions not equal") master_expr = genoplib.Mult(genoplib.Var(gain_var_name),expr) return master_expr,[(gain_var_name,gains)]
def build_asm_frag(corpus, input_var, sinks): if len(sinks) <= 1: yield [] return for frag_list in find_best_assembly_set(corpus, sinks): # count how many sources of input_var we need n_sinks = len(frag_list) # count how many propagated signals of input_var are produced by fragments n_stems = sum(map(lambda frag: len(frag['stems']), frag_list)) if n_stems > 0: frag_hierarchy, leftover = build_frag_hierarchy(frag_list) frag_hierarchy[0] += leftover n_stems_required = len(leftover) + 1 else: frag_hierarchy = [frag_list] if len(frag_list) > 0 else [] n_stems_required = len(frag_list) # if we only need one stem, we're done. if n_stems_required <= 1: yield frag_hierarchy return # produce new set of sinks to fulfill new_sinks = list(map(lambda idx : genoplib.Var(input_var), \ range(n_stems_required))) print("n_stems_required: %d" % n_stems_required) for par_frags in build_asm_frag(corpus, input_var, new_sinks): new_frags = list( map(lambda lv: [], range(len(par_frags) + len(frag_hierarchy)))) for hierarchy_level, blocks in enumerate(par_frags): new_frags[hierarchy_level] = list(blocks) assert (len(list(blocks)) > 0) for hierarchy_level, blocks in enumerate(frag_hierarchy): lv = hierarchy_level + len(par_frags) new_frags[lv] = list(blocks) assert (len(list(blocks)) > 0) yield new_frags
def sympy_unify_const(pat_expr, targ_expr): assert (len(pat_expr.vars()) <= 1) assert (len(targ_expr.vars()) == 0) targ_syms = {} targ_symexpr = lambdoplib.to_sympy(targ_expr, targ_syms) pat_syms = dict(targ_syms) pat_symexpr = lambdoplib.to_sympy(pat_expr, pat_syms) symbols = list(targ_syms.values()) + list(pat_syms.values()) try: result = sympy_solve(targ_symexpr - pat_symexpr, \ symbols,dict=True) except Exception as e: return False, None, None assign = result[0] if len(pat_expr.vars()) == 1: pat_var = pat_expr.vars()[0] const_val = genoplib.Const(assign[pat_syms[pat_var]]) return True, genoplib.Var(pat_var), const_val else: print(assign) raise NotImplementedError
def build_fragment_corpus(asm_blocks, input_var): fragment_map = [] for blk in asm_blocks: assert (len(blk.inputs) == 1) inp = list(blk.inputs)[0] modeset_groups = group_mode_sets(blk, input_var) for modeset in modeset_groups: leaves = {} stems = [] for output in blk.outputs: rel = output.relation[modeset[0]] \ .substitute({inp.name:genoplib.Var(input_var)}) if rel.op == oplib.OpType.VAR and rel.name == input_var: stems.append(output.name) leaves[output.name] = rel fragment_map.append({ 'block': blk, 'modes': modeset, 'exprs': leaves, 'stems': stems }) return fragment_map
def render_config_info(board,graph,cfg): blk = board.get_block(cfg.inst.block) st = [] st.append("\modes: %s" % (cfg.modes)) for data in cfg.stmts_of_type(adplib \ .ConfigStmtType \ .CONSTANT): st.append("%s=%.2f scf=%.2e" % (data.name, \ data.value, \ data.scf)) for data in cfg.stmts_of_type(adplib \ .ConfigStmtType \ .EXPR): inj_args = dict(map(lambda tup: (tup[0], \ genoplib.Mult(genoplib.Var(tup[0]), \ genoplib.Const(tup[1]))), \ data.injs.items())) subexpr = data.expr.substitute(inj_args) st.append("%s=%s injs=%s scfs=%s" \ % (data.name,data.expr,data.injs,data.scfs)) ident = "%s-config" % cfg.inst graph.node(ident, "%s" % "\n".join(st), \ shape="note", \ style="filled", \ fillcolor=Colors.LIGHTYELLOW) port_id = "%s:block" % (cfg.inst) graph.edge(ident,port_id, \ penwidth="2", \ style="dashed", \ arrowhead="tee", arrowtail="normal", \ color=Colors.ORANGE) return st
def sympy_unify_rewrite(pat_expr, targ_expr, cstrs, blacklist={}): deterministic = False def add_to_bl(wildvar, expr): assert (isinstance(wildvar, sympy.Wild)) if not wildvar.name in blacklist: blacklist[wildvar.name] = [] if not symexpr in blacklist[wildvar.name]: blacklist[wildvar.name].append(symexpr) return True return False targ_syms, pat_syms = {}, {} pat_symexpr = lambdoplib.to_sympy(pat_expr,pat_syms,wildcard=True, \ blacklist=blacklist) targ_symexpr = lambdoplib.to_sympy(targ_expr,targ_syms, \ no_aliasing=True) if isinstance(targ_symexpr,float) or \ isinstance(targ_symexpr,int): deterministic = True try: result = sympy_solve(targ_symexpr - pat_symexpr, \ symbols=list(pat_syms.values()), dict=True)[0] \ if len(pat_syms) == 1 else None except NotImplementedError: result = None else: result = targ_symexpr.match(pat_symexpr, old=True) #print("targ:%s" % targ_symexpr) #print("pat:%s" % pat_symexpr) #print("res:%s" % result) if result is None: return unif = Unification() updated_blacklist = False valid = True for var, symexpr in result.items(): try: expr = lambdoplib.from_sympy(symexpr, no_aliasing=True) unif.add(genoplib.Var(var.name), expr) except lambdoplib.FromSympyFailed as e: updated_blacklist |= add_to_bl(var, symexpr) valid = False continue cstr = cstrs[var.name] if var.name in cstrs else \ UnifyConstraint.NONE if cstr == UnifyConstraint.NOT_CONSTANT\ and expr.op == oplib.OpType.CONST: updated_blacklist |= add_to_bl(var, symexpr) valid = False if cstr == UnifyConstraint.CONSTANT \ and expr.op != oplib.OpType.CONST: updated_blacklist |= add_to_bl(var, symexpr) valid = False if cstr == UnifyConstraint.VARIABLE \ and expr.op != oplib.OpType.VAR: updated_blacklist |= add_to_bl(var, symexpr) valid = False if cstr == UnifyConstraint.SAMEVAR: raise NotImplementedError if valid: yield unif opts = list(result.items()) random.shuffle(opts) for wildvar, symexpr in opts: if not updated_blacklist: updated_blacklist |= add_to_bl(wildvar, symexpr) #print("blacklist: %s (valid=%s,updated=%s)" % (blacklist,valid,updated_blacklist)) if updated_blacklist and not deterministic: for unif in sympy_unify_rewrite(pat_expr, targ_expr, cstrs, blacklist): yield unif
def get_vadp_source(stmts, variable): for stmt in stmts: if isinstance(stmt, VADPSource): if stmt.dsexpr == genoplib.Var(variable): return stmt.port
def derive_tableau_from_port_rel(tableau, goal, rel, unif): new_tableau = tableau.copy() new_tableau.remove_goal(goal) out_port = PortVar(rel.block, rel.ident, rel.port) if isinstance(goal.variable, DSVar): assert (rel.block.outputs.has(rel.port.name)) new_tableau.add_stmt(VADPSource(out_port, \ genoplib.Var(goal.variable.var))) elif isinstance(goal.variable, PortVar): in_port = PortVar(goal.variable.block, \ goal.variable.ident, \ goal.variable.port) new_tableau.add_stmt(VADPConn(out_port, in_port)) elif isinstance(goal.variable, LawVar): in_port = LawVar(goal.variable.law, \ goal.variable.ident, \ goal.variable.var) new_tableau.add_stmt(VADPConn(out_port, in_port)) else: raise Exception("TODO: vadp should find/replace laws.") block_var = vadplib.PortVar(rel.block, rel.ident) vadp_cfg = VADPConfig(block_var, rel.modes) for stmt in tableau.vadp: if isinstance(stmt,VADPConfig) and \ stmt.same_target(vadp_cfg): stmt.merge(vadp_cfg) vadp_cfg = stmt data_vars = [] for vop, e in unif.assignments: if rel.block.data.has(vop.name): dat = rel.block.data[vop.name] data_vars += [vop.name] + dat.inputs if dat.type == blocklib.BlockDataType.EXPR: repl = {} for block_var, ds_var in map(lambda inp: unif.get_by_name(inp), \ dat.inputs): assert (ds_var.op == genoplib.OpType.VAR) repl[ds_var.name] = block_var assert (set(e.vars()) == set(repl.keys())) expr = e.substitute(repl) vadp_cfg.bind(vop.name, expr) else: vadp_cfg.bind(vop.name, e) # translate assignments to goals for vop,e in filter(lambda asgn: not asgn[0].name in data_vars, \ unif.assignments): v = vop.name # binding input port assignment if rel.block.inputs.has(v): sig_type = rel.block.inputs[v].type new_tableau.add_goal(Goal(PortVar(rel.block, \ rel.ident, \ rel.block.inputs[v]), \ sig_type,e)) elif v in rel.cstrs and \ rel.cstrs[v] == unifylib.UnifyConstraint.SAMEVAR: pass else: print(rel) print(rel.cstrs) print(rel.modes) raise Exception("unknown: %s=%s" % (v, e)) new_tableau.add_stmt(vadp_cfg) # if we used a freshly generated block, make sure to replace it replenish_block = (rel.ident == max(map(lambda r: r.ident \ if isinstance(r,PortRelation) \ and r.same_block(rel) else 0, \ tableau.relations))) # update existing relations in tableau to respect unification new_tableau.relations = [] for curr_rel in tableau.relations: # find port relations using the same block if isinstance(curr_rel,PortRelation) and \ curr_rel.same_block(rel) \ and curr_rel.ident == rel.ident: new_rel = curr_rel.copy() # do not add relation to new tableau if curr_rel.equals(rel): continue # could not concretize relation if not apply_vadp_config_to_relation(new_rel.block, \ vadp_cfg, \ unif, \ new_rel): continue new_tableau.add_relation(new_rel) else: new_tableau.add_relation(curr_rel.copy()) # add fresh block of same type if necessary if replenish_block: for output in rel.block.outputs: for expr, modes in output.relation.get_by_property(): new_rel = PortRelation(rel.block, rel.ident + 1, modes, output, expr) new_tableau.add_relation(new_rel) return new_tableau
def compute_expression_fields(board,adp,cfg,compensate=True, debug=False): #print(cfg) blk = board.get_block(cfg.inst.block) if(len(blk.data) < 1): return data = list(filter(lambda d: d.type == blocklib.BlockDataType.EXPR, \ blk.data)) if(len(data) < 1): return assert(len(data) == 1) # only allowed to have one output. output_port = blk.outputs.singleton() calib_obj = llenums.CalibrateObjective(adp.metadata[adplib.ADPMetadata.Keys.RUNTIME_CALIB_OBJ]) rel = output_port.relation[cfg.mode] fn_call= util.singleton(filter(lambda n: n.op == oplib.OpType.CALL, rel.nodes())) fn_spec=fn_call.func fn_params = fn_call.values data_expr_field_name = util.singleton(fn_spec.expr.vars()) data_expr_field = cfg.get(data_expr_field_name) # build offset map repls = {} for input_port, func_arg in zip(fn_call.values,fn_spec.func_args): if compensate: assert(input_port.op == oplib.OpType.VAR) conn = util.singleton(adp.incoming_conns(blk.name, cfg.inst.loc, input_port.name)) src_block = board.get_block(conn.source_inst.block) src_cfg = adp.configs.get(conn.source_inst.block, conn.source_inst.loc) model = get_experimental_model(board, \ src_block, \ conn.source_inst.loc, \ src_cfg, \ calib_obj=calib_obj) gain,offset = get_compensation_parameters(model,init_cond=False) else: gain,offset = 1.0,0.0 inj = data_expr_field.injs[func_arg] repls[func_arg] = genoplib.Mult(genoplib.Const(inj), \ genoplib.Add( \ genoplib.Var(func_arg), \ genoplib.Const(-offset) )) if debug: print("inp-var %s inj=%f offset=%f" % (func_arg,inj,offset)) # compute model of output block if compensate: conn = util.singleton(adp.outgoing_conns(blk.name, cfg.inst.loc, output_port.name)) dest_block = board.get_block(conn.dest_inst.block) dest_cfg = adp.configs.get(conn.dest_inst.block, conn.dest_inst.loc) model = get_experimental_model(board, \ dest_block, \ dest_cfg.inst.loc, \ dest_cfg, \ calib_obj=calib_obj) gain,offset = get_compensation_parameters(model,False) else: gain,offset = 1.0,0.0 inj = data_expr_field.injs[data_expr_field.name] if debug: print("out-var %s inj=%f gain=%f offset=%f" % (data_expr_field.name, \ inj,gain,offset)) func_impl = genoplib.Mult(genoplib.Const(inj), \ data_expr_field.expr.substitute(repls)) if debug: print("func-expr: %s" % func_impl) rel_impl = genoplib.Add( \ rel.substitute({data_expr_field.name:func_impl}), \ genoplib.Const(-offset/gain) \ ) output_port = blk.outputs.singleton() input_port = blk.inputs.singleton() final_expr = rel_impl.concretize() if debug: print("rel-expr: %s" % rel_impl) print("--- building lookup table ---") print(final_expr) input_values = input_port.quantize[cfg.mode] \ .get_values(input_port \ .interval[cfg.mode]) cfg[data_expr_field.name].set_input(input_port,input_values) lut_outs = [] for val in input_values: out = final_expr.compute({input_port.name:val}) out = max(min(1.0-1.0/128.0,out),-1.0) cfg[data_expr_field.name].set_output({input_port.name:val},out) cfg[data_expr_field.name].concrete_expr = final_expr
def to_sympy(expr, symbols={}, wildcard=False, blacklist={}, no_aliasing=False): assert (not (no_aliasing and wildcard)) if expr.op == OpType.VAR: if wildcard: if not expr.name in symbols: bl = blacklist[expr.name] if expr.name in blacklist \ else [] symbols[expr.name] = [sympy.Wild(expr.name, \ exclude=bl)] else: if not expr.name in symbols: symbols[expr.name] = [] if no_aliasing: name = "%s.%d" % (expr.name, len(symbols[expr.name])) symbols[expr.name].append(sympy.Symbol(name)) elif len(symbols[expr.name]) == 0: symbols[expr.name].append(sympy.Symbol(expr.name)) return symbols[expr.name][-1] elif expr.op == OpType.CONST: if (expr.value).is_integer(): return int(expr.value) else: return expr.value elif expr.op == OpType.ADD: args0 = to_sympy(expr.args[0], symbols, wildcard, blacklist, no_aliasing) args1 = to_sympy(expr.args[1], symbols, wildcard, blacklist, no_aliasing) return args0 + args1 elif expr.op == OpType.MULT: args0 = to_sympy(expr.args[0], symbols, wildcard, blacklist, no_aliasing) args1 = to_sympy(expr.args[1], symbols, wildcard, blacklist, no_aliasing) return args0 * args1 elif expr.op == OpType.EMIT: args0 = to_sympy(expr.args[0], symbols, wildcard, blacklist, no_aliasing) return sympy.Function("emit")(args0) elif expr.op == OpType.EXTVAR: args0 = to_sympy(genop.Var(expr.name), symbols, wildcard, blacklist, no_aliasing) return sympy.Function("extvar")(args0) elif expr.op == OpType.INTEG: args0 = to_sympy(expr.args[0], symbols, wildcard, blacklist, no_aliasing) args1 = to_sympy(expr.args[1], symbols, wildcard, blacklist, no_aliasing) return sympy.Function("integ")(args0, \ args1) elif expr.op == OpType.POW: args0 = to_sympy(expr.args[0], symbols, wildcard, blacklist, no_aliasing) args1 = to_sympy(expr.args[1], symbols, wildcard, blacklist, no_aliasing) if isinstance(args1, int) and args1 > 1: for _ in range(args1 - 1): args = to_sympy(expr.args[0], symbols, wildcard, blacklist, no_aliasing) args0 *= args return args0 else: return sympy.Pow(args0, args1) elif expr.op == OpType.MAX: args0 = to_sympy(expr.args[0], symbols, wildcard, blacklist, no_aliasing) args1 = to_sympy(expr.args[1], symbols, wildcard, blacklist, no_aliasing) return sympy.Function("max")(args0, args1) elif expr.op == OpType.ABS: args0 = to_sympy(expr.args[0], symbols, wildcard, blacklist, no_aliasing) return sympy.Function("abs")(args0) elif expr.op == OpType.SGN: args0 = to_sympy(expr.args[0], symbols, wildcard, blacklist, no_aliasing) return sympy.Function("sgn")(args0) elif expr.op == OpType.SIN: args0 = to_sympy(expr.args[0], symbols, wildcard, blacklist, no_aliasing) return sympy.sin(args0) elif expr.op == OpType.FUNC: args = list(map(lambda v: to_sympy(genop.Var(v), \ symbols, \ wildcard, \ blacklist,no_aliasing), \ expr.func_args)) body = to_sympy(expr.expr, symbols, wildcard, blacklist, no_aliasing) args.append(body) return sympy.Function("func")(*args) elif expr.op == OpType.CALL: symargs = list( map( lambda v: to_sympy(v, symbols, wildcard, blacklist, no_aliasing ), expr.values)) symbody = to_sympy(expr.func, symbols, wildcard, blacklist, no_aliasing) args = [symbody] + symargs fxn = sympy.Function("call")(*args) return fxn else: raise Exception("unimpl: %s" % expr)
def from_sympy(symexpr, no_aliasing=False): if isinstance(symexpr, sympy.Function): if isinstance(symexpr, sympy.sin): e0 = from_sympy(symexpr.args[0], no_aliasing) return Sin(e0) elif symexpr.func.name == "integ": assert (len(symexpr.args) == 2) e1 = from_sympy(symexpr.args[0], no_aliasing) e2 = from_sympy(symexpr.args[1], no_aliasing) return genop.Integ(e1, e2) elif symexpr.func.name == "max": assert (len(symexpr.args) == 2) e1 = from_sympy(symexpr.args[0], no_aliasing) e2 = from_sympy(symexpr.args[1], no_aliasing) return Max(e1, e2) elif symexpr.func.name == "abs": e1 = from_sympy(symexpr.args[-1], no_aliasing) return Abs(e1) elif symexpr.func.name == "sgn": e1 = from_sympy(symexpr.args[-1], no_aliasing) return Sgn(e1) elif symexpr.func.name == "call": efn = from_sympy(symexpr.args[0], no_aliasing) args = list(map(lambda e : from_sympy(e,no_aliasing), \ symexpr.args[1:])) return genop.Call(args, efn) elif symexpr.func.name == "func": ebody = from_sympy(symexpr.args[-1], no_aliasing) pars = list(map(lambda e: from_sympy(e,no_aliasing).name, \ symexpr.args[:-1])) return Func(pars, ebody) elif symexpr.func.name == "extvar": e1 = from_sympy(symexpr.args[-1], no_aliasing) assert (isinstance(e1, genop.Var)) return genop.ExtVar(e1.name) elif symexpr.func.name == "emit": e1 = from_sympy(symexpr.args[-1], no_aliasing) return genop.Emit(e1) elif symexpr.func.name == "map": raise FromSympyFailed("cannot convert mapping %s back to expr" % symexpr) else: raise Exception("unhandled func: %s" % (symexpr.func)) elif isinstance(symexpr, sympy.Pow): e1 = from_sympy(symexpr.args[0], no_aliasing) e2 = from_sympy(symexpr.args[1], no_aliasing) return Pow(e1, e2) elif isinstance(symexpr, sympy.Symbol): if no_aliasing: name = symexpr.name.split(".")[0] else: name = symexpr.name return genop.Var(name) elif isinstance(symexpr, sympy.Float) or \ isinstance(symexpr, sympy.Integer): return genop.Const(float(symexpr)) elif isinstance(symexpr, sympy.Mul): args = list(map(lambda a: from_sympy(a,no_aliasing), \ symexpr.args)) return genop.product(args) elif isinstance(symexpr, sympy.Add): args = list(map(lambda a: from_sympy(a,no_aliasing), \ symexpr.args)) return genop.sum(args) elif isinstance(symexpr, sympy.Rational): return genop.Const(float(symexpr)) else: print(symexpr.func) raise Exception(sympy.srepr(symexpr))