Esempio n. 1
0
def _build_constraint_functions(variables,
                                constraints,
                                include_hess=False,
                                parameters=None,
                                cse=True):
    if parameters is None:
        parameters = []
    else:
        parameters = [wrap_symbol_symengine(p) for p in parameters]
    variables = tuple(variables)
    wrt = variables
    parameters = tuple(parameters)
    constraint__func, jacobian_func, hessian_func = None, None, None
    inp = sympify(variables + parameters)
    graph = sympify(constraints)
    constraint_func = lambdify(inp, [graph], backend='llvm', cse=cse)
    grad_graphs = list(list(c.diff(w) for w in wrt) for c in graph)
    jacobian_func = lambdify(inp, grad_graphs, backend='llvm', cse=cse)
    if include_hess:
        hess_graphs = list(
            list(list(g.diff(w) for w in wrt) for g in c) for c in grad_graphs)
        hessian_func = lambdify(inp, hess_graphs, backend='llvm', cse=cse)
    return ConstraintFunctions(cons_func=constraint_func,
                               cons_jac=jacobian_func,
                               cons_hess=hessian_func)
Esempio n. 2
0
def build_constraint_functions(variables,
                               constraints,
                               parameters=None,
                               func_options=None,
                               jac_options=None,
                               hess_options=None):
    """Build callables functions for the constraints, constraint Jacobian, and constraint Hessian.

    Parameters
    ----------
    variables : List[sympy.core.symbol.Symbol]
        Free variables in the sympy_graph. By convention these are usually all
        instances of StateVariables.
    constraints : List[sympy.core.expr.Expr]
        List of SymPy expression to compile
    parameters : Optional[List[sympy.core.symbol.Symbol]]
        Free variables in the sympy_graph. These are typically external
        parameters that are controlled by the user.
    func_options : None, optional
        Options to pass to ``lambdify`` when compiling the function.
    jac_options : Optional[Dict[str, str]]
        Options to pass to ``lambdify`` when compiling the Jacobian.
    hess_options : Optional[Dict[str, str]]
        Options to pass to ``lambdify`` when compiling Hessian.

    Returns
    -------
    ConstraintFunctions

    Notes
    -----
    Default options for compiling the function, gradient and Hessian are defined by ``_get_lambdify_options``.

    """
    if parameters is None:
        parameters = []
    else:
        parameters = [wrap_symbol_symengine(p) for p in parameters]
    variables = tuple(variables)
    wrt = variables
    parameters = tuple(parameters)
    constraint_func, jacobian_func, hessian_func = None, None, None
    inp = sympify(variables + parameters)
    graph = sympify(constraints)
    constraint_func = lambdify(inp, [graph],
                               **_get_lambidfy_options(func_options))

    grad_graphs = list(list(c.diff(w) for w in wrt) for c in graph)
    jacobian_func = lambdify(inp, grad_graphs,
                             **_get_lambidfy_options(jac_options))

    hess_graphs = list(
        list(list(g.diff(w) for w in wrt) for g in c) for c in grad_graphs)
    hessian_func = lambdify(inp, hess_graphs,
                            **_get_lambidfy_options(hess_options))
    return ConstraintFunctions(cons_func=constraint_func,
                               cons_jac=jacobian_func,
                               cons_hess=hessian_func)
Esempio n. 3
0
def _build_constraint_functions(variables, constraints, include_hess=False, parameters=None, cse=True):
    if parameters is None:
        parameters = []
    else:
        parameters = [wrap_symbol_symengine(p) for p in parameters]
    variables = tuple(variables)
    wrt = variables
    parameters = tuple(parameters)
    constraint__func, jacobian_func, hessian_func = None, None, None
    inp = sympify(variables + parameters)
    graph = sympify(constraints)
    constraint_func = lambdify(inp, [graph], backend='llvm', cse=cse)
    grad_graphs = list(list(c.diff(w) for w in wrt) for c in graph)
    jacobian_func = lambdify(inp, grad_graphs, backend='llvm', cse=cse)
    if include_hess:
        hess_graphs = list(list(list(g.diff(w) for w in wrt) for g in c) for c in grad_graphs)
        hessian_func = lambdify(inp, hess_graphs, backend='llvm', cse=cse)
    return ConstraintFunctions(cons_func=constraint_func, cons_jac=jacobian_func, cons_hess=hessian_func)
Esempio n. 4
0
def build_functions(sympy_graph,
                    variables,
                    parameters=None,
                    wrt=None,
                    include_obj=True,
                    include_grad=False,
                    include_hess=False,
                    cse=True):
    if wrt is None:
        wrt = sympify(tuple(variables))
    if parameters is None:
        parameters = []
    else:
        parameters = [wrap_symbol_symengine(p) for p in parameters]
    variables = tuple(variables)
    parameters = tuple(parameters)
    func, grad, hess = None, None, None
    inp = sympify(variables + parameters)
    graph = sympify(sympy_graph)
    if count_ops(graph) > BACKEND_OPS_THRESHOLD:
        backend = 'lambda'
    else:
        backend = 'llvm'
    # TODO: did not replace zoo with oo
    if include_obj:
        func = lambdify(inp, [graph], backend=backend, cse=cse)
    if include_grad or include_hess:
        grad_graphs = list(graph.diff(w) for w in wrt)
        grad_ops = sum(count_ops(x) for x in grad_graphs)
        if grad_ops > BACKEND_OPS_THRESHOLD:
            grad_backend = 'lambda'
        else:
            grad_backend = 'llvm'
        if include_grad:
            grad = lambdify(inp, grad_graphs, backend=grad_backend, cse=cse)
        if include_hess:
            hess_graphs = list(
                list(g.diff(w) for w in wrt) for g in grad_graphs)
            # Hessians are hard-coded to always use the lambda backend, for performance
            hess = lambdify(inp, hess_graphs, backend='lambda', cse=cse)
    return BuildFunctionsResult(func=func, grad=grad, hess=hess)
Esempio n. 5
0
def build_functions(sympy_graph, variables, parameters=None, wrt=None, include_obj=True, include_grad=False, include_hess=False, cse=True):
    if wrt is None:
        wrt = sympify(tuple(variables))
    if parameters is None:
        parameters = []
    else:
        parameters = [wrap_symbol_symengine(p) for p in parameters]
    variables = tuple(variables)
    parameters = tuple(parameters)
    func, grad, hess = None, None, None
    inp = sympify(variables + parameters)
    graph = sympify(sympy_graph)
    # TODO: did not replace zoo with oo
    if include_obj:
        func = lambdify(inp, [graph], backend='llvm', cse=cse)
    if include_grad or include_hess:
        grad_graphs = list(graph.diff(w) for w in wrt)
        if include_grad:
            grad = lambdify(inp, grad_graphs, backend='llvm', cse=cse)
        if include_hess:
            hess_graphs = list(list(g.diff(w) for w in wrt) for g in grad_graphs)
            hess = lambdify(inp, hess_graphs, backend='llvm', cse=cse)
    return BuildFunctionsResult(func=func, grad=grad, hess=hess)
Esempio n. 6
0
def build_functions(sympy_graph,
                    variables,
                    parameters=None,
                    wrt=None,
                    include_obj=True,
                    include_grad=False,
                    include_hess=False,
                    func_options=None,
                    grad_options=None,
                    hess_options=None):
    """Build function, gradient, and Hessian callables of the sympy_graph.

    Parameters
    ----------
    sympy_graph : sympy.core.expr.Expr
        SymPy expression to compile,
        :math:`f(x) : \mathbb{R}^{n} \\rightarrow \mathbb{R}`,
        which will corresponds to ``sympy_graph(variables+parameters)``
    variables : List[sympy.core.symbol.Symbol]
        Free variables in the sympy_graph. By convention these are usually all
        instances of StateVariables.
    parameters : Optional[List[sympy.core.symbol.Symbol]]
        Free variables in the sympy_graph. These are typically external
        parameters that are controlled by the user.
    wrt : Optional[List[sympy.core.symbol.Symbol]]
        Variables to differentiate *with respect to* for the gradient and
        Hessian callables. If None, will fall back to ``variables``.
    include_obj : Optional[bool]
        Whether to build the sympy_graph callable,
        :math:`f(x) : \mathbb{R}^{n} \\rightarrow \mathbb{R}`
    include_grad : Optional[bool]
        Whether to build the gradient callable,
        :math:`\\pmb{g}(x) = \\nabla f(x) : \mathbb{R}^{n} \\rightarrow \mathbb{R}^{n}`
    include_hess : Optional[bool]
        Whether to build the Hessian callable,
        :math:`\mathbb{H}(x) = \\nabla^2 f(x) : \mathbb{R}^{n} \\rightarrow \mathbb{R}^{n \\times n}`
    func_options : Optional[Dict[str, str]]
        Options to pass to ``lambdify`` when compiling the function.
    grad_options : Optional[Dict[str, str]]
        Options to pass to ``lambdify`` when compiling the gradient.
    hess_options : Optional[Dict[str, str]]
        Options to pass to ``lambdify`` when compiling Hessian.

    Returns
    -------
    BuildFunctionsResult

    Notes
    -----
    Default options for compiling the function, gradient and Hessian are defined by ``_get_lambdify_options``.

    """
    if wrt is None:
        wrt = sympify(tuple(variables))
    if parameters is None:
        parameters = []
    else:
        parameters = [wrap_symbol_symengine(p) for p in parameters]
    variables = tuple(variables)
    parameters = tuple(parameters)
    func, grad, hess = None, None, None
    # Replace complex infinity (zoo) with real infinity because SymEngine
    # cannot lambdify complex infinity. We also replace in the derivatives in
    # case some differentiation would produce a complex infinity. The
    # replacement is assumed to be cheap enough that it's safer to replace the
    # complex values and pay the minor time penalty.
    inp = sympify(variables + parameters)
    graph = sympify(sympy_graph).xreplace({zoo: oo})
    func = lambdify(inp, [graph], **_get_lambidfy_options(func_options))
    if include_grad or include_hess:
        grad_graphs = list(graph.diff(w).xreplace({zoo: oo}) for w in wrt)
        if include_grad:
            grad = lambdify(inp, grad_graphs,
                            **_get_lambidfy_options(grad_options))
        if include_hess:
            hess_graphs = list(
                list(g.diff(w).xreplace({zoo: oo}) for w in wrt)
                for g in grad_graphs)
            hess = lambdify(inp, hess_graphs,
                            **_get_lambidfy_options(hess_options))
    return BuildFunctionsResult(func=func, grad=grad, hess=hess)
Esempio n. 7
0
def build_constraint_functions(variables,
                               constraints,
                               parameters=None,
                               func_options=None,
                               jac_options=None,
                               hess_options=None):
    """Build callables functions for the constraints, constraint Jacobian, and constraint Hessian.

    Parameters
    ----------
    variables : List[sympy.core.symbol.Symbol]
        Free variables in the sympy_graph. By convention these are usually all
        instances of StateVariables.
    constraints : List[sympy.core.expr.Expr]
        List of SymPy expression to compile
    parameters : Optional[List[sympy.core.symbol.Symbol]]
        Free variables in the sympy_graph. These are typically external
        parameters that are controlled by the user.
    func_options : None, optional
        Options to pass to ``lambdify`` when compiling the function.
    jac_options : Optional[Dict[str, str]]
        Options to pass to ``lambdify`` when compiling the Jacobian.
    hess_options : Optional[Dict[str, str]]
        Options to pass to ``lambdify`` when compiling Hessian.

    Returns
    -------
    ConstraintFunctions

    Notes
    -----
    Default options for compiling the function, gradient and Hessian are defined by ``_get_lambdify_options``.

    """
    if parameters is None:
        parameters = []
    else:
        parameters = [wrap_symbol_symengine(p) for p in parameters]
    variables = tuple(variables)
    wrt = variables
    parameters = tuple(parameters)
    constraint_func, jacobian_func, hessian_func = None, None, None
    # Replace complex infinity (zoo) with real infinity because SymEngine
    # cannot lambdify complex infinity. We also replace in the derivatives in
    # case some differentiation would produce a complex infinity. The
    # replacement is assumed to be cheap enough that it's safer to replace the
    # complex values and pay the minor time penalty.
    inp = sympify(variables + parameters)
    graph = sympify([f.xreplace({zoo: oo}) for f in constraints])
    constraint_func = lambdify(inp, [graph],
                               **_get_lambidfy_options(func_options))

    grad_graphs = list(
        list(c.diff(w).xreplace({zoo: oo}) for w in wrt) for c in graph)
    jacobian_func = lambdify(inp, grad_graphs,
                             **_get_lambidfy_options(jac_options))

    hess_graphs = list(
        list(list(g.diff(w).xreplace({zoo: oo}) for w in wrt) for g in c)
        for c in grad_graphs)
    hessian_func = lambdify(inp, hess_graphs,
                            **_get_lambidfy_options(hess_options))
    return ConstraintFunctions(cons_func=constraint_func,
                               cons_jac=jacobian_func,
                               cons_hess=hessian_func)