Ejemplo n.º 1
0
def compile_function_matlab(equations, symbols, arg_names, output_names=None, funname='anonymous'):

    from function_compiler_ast import std_date_symbol
    from function_compiler_ast import StandardizeDates

    from collections import OrderedDict
    table = OrderedDict()

    aa = arg_names
    # if output_names is not None:
        # aa = arg_names + [output_names]
    for a in aa:

        symbol_group = a[0]
        date = a[1]
        an = a[2]

        for b in symbols[symbol_group]:
            index = symbols[symbol_group].index(b)

            table[(b,date)] = (an, index)

    table_symbols = { k: (std_date_symbol(*k)) for k in table.keys() }

    code_preamble = ""
    for k,v in table.iteritems():
        std_name = table_symbols[k]
        if v[0] != 'p':
            code_preamble += "{} = {}(:,{});\n".format(std_name, v[0], v[1]+1)
        else:
            code_preamble += "{} = {}({});\n".format(std_name, v[0], v[1]+1)

    if output_names:
        out_group, out_time, out_s = output_names
    else:
        out_s = 'out'

    expressions = []

    code_expr = ""
    import sympy
    for i,eq in enumerate(equations):
        expr = str_to_expr(eq)
        sd = StandardizeDates(symbols, arg_names)
        sexpr = sd.visit(expr)
        expressions.append(sexpr)
        eq_string = (print_matlab(sexpr))
        if output_names is None:
            code_expr += "out(:,{}) = {} ;\n".format(i+1, eq_string)
        else:
            out_symbol = symbols[out_group][i]
            out_name = std_date_symbol(out_symbol, out_time)
            code_expr += "{} = {} ;\n".format(out_name, eq_string)
            code_expr += "{}(:,{}) = {} ;\n".format(out_s,i+1, out_name)


    ## temporary code to differentiate equations using sympy
    if output_names:
        # solve triangular system
        sympy_names = [sympy.Symbol(e) for e in symbols[out_group]]
        eq_dict = OrderedDict()
        for i,name in enumerate(sympy_names):
            eq = sympy.sympify(codegen.to_source(expressions[i]))
            eq_dict[name] = eq.subs(eq_dict)
        sympy_equations = eq_dict.values()
    else:
        sympy_equations = [sympy.sympify(codegen.to_source(expr)) for expr in expressions]


    all_derivatives = OrderedDict()
    for agn in arg_names:
        sym_group = agn[0]
        date = agn[1]
        short_sym_group =  agn[2]
        sym_names = [std_date_symbol(s, date) for s in symbols[sym_group]]
        dvals = []
        for eq in sympy_equations:
            deq = []
            for s in sym_names:
                sym = sympy.Symbol(s)
                ddif = (eq.diff(sym))
                deq.append(ast.parse(str(ddif)).body[0])
            dvals.append(deq)
        all_derivatives[short_sym_group] = dvals
    ## end of temporary code

    code_dexpr = ""
    for k,derivs in all_derivatives.iteritems():
        code_dexpr += '\n%derivatives w.r.t {}\n'.format(k)
        assign_name = "d_{}".format(k)
        code_dexpr += '{} = zeros(N,{},{});\n'.format(assign_name, len(derivs), len(derivs[0]))
        for i in range(len(derivs)):
            for j in range(len(derivs[0])):
                eq = derivs[i][j]
                ss = print_matlab(eq)
                if ss != '0':
                    code_dexpr += "{}(:,{},{}) = {};\n".format(assign_name, i+1, j+1, ss)

        code_dexpr += '\n'

    code = """\
function [{out_s}, {dout_s}] = {funname}({args_list})

%% preamble
{preamble}

N = size({first_arg},1);
out = zeros(N,{n_out});

%% equations

{equations}

%% derivatives

if nargout > 1
{dequations}
end

end
""".format(
    out_s = out_s,
    dout_s = str.join(', ', ["d_{}".format(e[2]) for e in arg_names]),
    preamble = code_preamble,
    funname = funname,
    args_list = str.join(', ', [e[2] for e in arg_names]),
    n_out = len(equations),
    first_arg = arg_names[0][2],
    equations = code_expr,
    dequations = code_dexpr
)

    return code
Ejemplo n.º 2
0
def compile_function_matlab(equations,
                            symbols,
                            arg_names,
                            output_names=None,
                            funname='anonymous'):

    from function_compiler_ast import std_date_symbol
    from function_compiler_ast import StandardizeDates

    from collections import OrderedDict
    table = OrderedDict()

    aa = arg_names
    # if output_names is not None:
    # aa = arg_names + [output_names]
    for a in aa:

        symbol_group = a[0]
        date = a[1]
        an = a[2]

        for b in symbols[symbol_group]:
            index = symbols[symbol_group].index(b)

            table[(b, date)] = (an, index)

    table_symbols = {k: (std_date_symbol(*k)) for k in table.keys()}

    code_preamble = ""
    for k, v in table.iteritems():
        std_name = table_symbols[k]
        if v[0] != 'p':
            code_preamble += "{} = {}(:,{});\n".format(std_name, v[0],
                                                       v[1] + 1)
        else:
            code_preamble += "{} = {}({});\n".format(std_name, v[0], v[1] + 1)

    if output_names:
        out_group, out_time, out_s = output_names
    else:
        out_s = 'out'

    code_expr = ""
    for i, eq in enumerate(equations):
        expr = str_to_expr(eq)
        sd = StandardizeDates(symbols, arg_names)
        sexpr = sd.visit(expr)
        eq_string = (print_matlab(sexpr))
        if output_names is None:
            code_expr += "out(:,{}) = {} ;\n".format(i + 1, eq_string)
        else:
            out_symbol = symbols[out_group][i]
            out_name = std_date_symbol(out_symbol, out_time)
            code_expr += "{} = {} ;\n".format(out_name, eq_string)
            code_expr += "{}(:,{}) = {} ;\n".format(out_s, i + 1, out_name)

    code = """\
function [{out_s}] = {funname}({args_list})

{preamble}

N = size({first_arg},1);
out = zeros(N,{n_out});
{equations}
end
""".format(out_s=out_s,
           preamble=code_preamble,
           funname=funname,
           args_list=str.join(', ', [e[2] for e in arg_names]),
           n_out=len(equations),
           first_arg=arg_names[0][2],
           equations=code_expr)

    return code
Ejemplo n.º 3
0
def compile_higher_order_function(eqs, syms, params, order=2, funname='anonymous',
    return_code=False, compile=False):
    '''From a list of equations and variables, define a multivariate functions with higher order derivatives.'''

    from function_compiler_ast import StandardizeDatesSimple, std_date_symbol
    all_vars = syms + [(p,0) for p in params]
    sds = StandardizeDatesSimple(all_vars)



    if isinstance(eqs[0], str):
    # elif not isinstance(eqs[0], sympy.Basic):
    # assume we have ASTs
        eqs = [ast.parse(eq).body[0] for eq in eqs]
        eqs_std = [sds.visit(eq) for eq in eqs]
        eqs_sym = [ast_to_sympy(eq) for eq in eqs_std]
    else:
        eqs_sym = eqs

    symsd = [std_date_symbol(a,b) for a,b in syms]
    paramsd = [std_date_symbol(a,0) for a in params]
    D = higher_order_diff(eqs_sym, symsd, order=order)

    txt = """def {funname}(x, p, order=1):

    import numpy
    from numpy import log, exp, tan

""".format(funname=funname)

    for i in range(len(syms)):
        txt += "    {} = x[{}]\n".format(symsd[i], i)

    txt += "\n"

    for i in range(len(params)):
        txt += "    {} = p[{}]\n".format(paramsd[i], i)

    txt += "\n    out = numpy.zeros({})".format(len(eqs))

    for i in range(len(eqs)):
        txt += "\n    out[{}] = {}".format(i, D[0][i])

    txt += """

    if order == 0:
        return out

"""
    if order >= 1:
        # Jacobian
        txt += "    out_1 = numpy.zeros(({},{}))\n".format(len(eqs), len(syms))

        for i in range(len(eqs)):
            for j in range(len(syms)):
                val = D[1][i,j]
                if val != 0:
                    txt += "    out_1[{},{}] = {}\n".format(i,j,D[1][i,j])

        txt += """

    if order == 1:
        return [out, out_1]

"""

    if order >= 2:
        # Hessian
        txt += "    out_2 = numpy.zeros(({},{},{}))\n".format(len(eqs), len(syms), len(syms))

        for n in range(len(eqs)):
            for i in range(len(syms)):
                for j in range(len(syms)):
                    val = D[2][n,i,j]
                    if val is not None:
                        if val != 0:
                            txt += "    out_2[{},{},{}] = {}\n".format(n,i,j,D[2][n,i,j])
                    else:
                        i1, j1 = sorted( (i,j) )
                        if D[2][n,i1,j1] != 0:
                            txt += "    out_2[{},{},{}] = out_2[{},{},{}]\n".format(n,i,j,n,i1,j1)

        txt += """

    if order == 2:
        return [out, out_1, out_2]

"""


    if order >= 3:
        # Hessian
        txt += "    out_3 = numpy.zeros(({},{},{},{}))\n".format(len(eqs), len(syms), len(syms), len(syms))

        for n in range(len(eqs)):
            for i in range(len(syms)):
                for j in range(len(syms)):
                    for k in range(len(syms)):
                        val = D[3][n,i,j,k]
                        if val is not None:
                            if val != 0:
                                txt += "    out_3[{},{},{},{}] = {}\n".format(n,i,j,k,D[3][n,i,j,k])
                        else:
                            i1, j1, k1 = sorted( (i,j,k) )
                            if D[3][n,i1,j1,k1] != 0:
                                txt += "    out_3[{},{},{},{}] = out_3[{},{},{},{}]\n".format(n,i,j,k,n,i1,j1,k1)

        txt += """

    if order == 3:
        return [out, out_1, out_2, out_3]
    """

    if return_code:
        return txt
    else:
        d = {}
        d['division'] = division

        exec(txt, d)
        fun = d[funname]

        if compile:
            raise Exception("Not implemented.")

        return fun
Ejemplo n.º 4
0
def compile_function_matlab(equations, symbols, arg_names, output_names=None, funname='anonymous'):

    from function_compiler_ast import std_date_symbol
    from function_compiler_ast import StandardizeDates

    from collections import OrderedDict
    table = OrderedDict()

    aa = arg_names
    # if output_names is not None:
        # aa = arg_names + [output_names]
    for a in aa:

        symbol_group = a[0]
        date = a[1]
        an = a[2]

        for b in symbols[symbol_group]:
            index = symbols[symbol_group].index(b)

            table[(b,date)] = (an, index)

    table_symbols = { k: (std_date_symbol(*k)) for k in table.keys() }

    code_preamble = ""
    for k,v in table.iteritems():
        std_name = table_symbols[k]
        if v[0] != 'p':
            code_preamble += "{} = {}(:,{});\n".format(std_name, v[0], v[1]+1)
        else:
            code_preamble += "{} = {}({});\n".format(std_name, v[0], v[1]+1)

    if output_names:
        out_group, out_time, out_s = output_names
    else:
        out_s = 'out'

    code_expr = ""
    for i,eq in enumerate(equations):
        expr = str_to_expr(eq)
        sd = StandardizeDates(symbols, arg_names)
        sexpr = sd.visit(expr)
        eq_string = (print_matlab(sexpr))
        if output_names is None:
            code_expr += "out(:,{}) = {} ;\n".format(i+1, eq_string)
        else:
            out_symbol = symbols[out_group][i]
            out_name = std_date_symbol(out_symbol, out_time)
            code_expr += "{} = {} ;\n".format(out_name, eq_string)
            code_expr += "{}(:,{}) = {} ;\n".format(out_s,i+1, out_name)

    code = """\
function [{out_s}] = {funname}({args_list})

{preamble}

N = size({first_arg},1);
out = zeros(N,{n_out});
{equations}
end
""".format(
    out_s = out_s,
    preamble = code_preamble,
    funname = funname,
    args_list = str.join(', ', [e[2] for e in arg_names]),
    n_out = len(equations),
    first_arg = arg_names[0][2],
    equations = code_expr
)

    return code