Python sympy.Derivative() Examples

The following are 25 code examples of sympy.Derivative(). You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may also want to check out all available functions/classes of the module sympy , or try the search function .
Example #1
Source File: test_printer.py    From galgebra with BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
def test_oprint():
    s = io.StringIO()
    with contextlib.redirect_stdout(s):
        oprint(
            'int', 1,
            'dictionary', dict(a=1, b=2),
            'set', {1},
            'tuple', (1, 2),
            'list', [1, 2, 3],
            'str', 'a quote: "',
            'deriv', Derivative(Symbol('x'), Symbol('x'), evaluate=False),
        )

    if has_ordered_dictionaries:
        assert s.getvalue() == textwrap.dedent("""\
            int        = 1
            dictionary = {a: 1, b: 2}
            set        = {1}
            tuple      = (1, 2)
            list       = [1, 2, 3]
            str        = a quote: "
            deriv      = D{x}x
            """) 
Example #2
Source File: derivative.py    From devito with MIT License 6 votes vote down vote up
def __call__(self, x0=None, fd_order=None, side=None):
        if self.ndims == 1:
            _fd_order = fd_order or self._fd_order
            _side = side or self._side
            new_x0 = {self.dims[0]: x0} if x0 is not None else self.x0
            return self._new_from_self(fd_order=_fd_order, side=_side, x0=new_x0)

        if side is not None:
            raise TypeError("Side only supported for first order single"
                            "Dimension derivative such as `.dxl` or .dx(side=left)")
        # Cross derivative
        _x0 = self._x0 or {}
        _fd_order = dict(self.fd_order._getters)
        try:
            _fd_order.update(**(fd_order or {}))
            _fd_order = tuple(_fd_order.values())
            _fd_order = DimensionTuple(*_fd_order, getters=self.dims)
            _x0.update(x0)
        except AttributeError:
            raise TypeError("Multi-dimensional Derivative, input expected as a dict")

        return self._new_from_self(fd_order=_fd_order, x0=_x0) 
Example #3
Source File: derivative.py    From devito with MIT License 6 votes vote down vote up
def __new__(cls, expr, *dims, **kwargs):
        if type(expr) == sympy.Derivative:
            raise ValueError("Cannot nest sympy.Derivative with devito.Derivative")
        if not isinstance(expr, Differentiable):
            raise ValueError("`expr` must be a Differentiable object")

        new_dims, orders, fd_o, var_count = cls._process_kwargs(expr, *dims, **kwargs)

        # Construct the actual Derivative object
        obj = Differentiable.__new__(cls, expr, *var_count)
        obj._dims = tuple(OrderedDict.fromkeys(new_dims))

        skip = kwargs.get('preprocessed', False) or obj.ndims == 1

        obj._fd_order = fd_o if skip else DimensionTuple(*fd_o, getters=obj._dims)
        obj._deriv_order = orders if skip else DimensionTuple(*orders, getters=obj._dims)
        obj._side = kwargs.get("side")
        obj._transpose = kwargs.get("transpose", direct)
        obj._subs = as_tuple(kwargs.get("subs"))
        obj._x0 = kwargs.get('x0', None)
        return obj 
Example #4
Source File: operator.py    From sympsi with BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
def expr(self):
        """
        Returns the arbitary expression which is to have the Wavefunction
        substituted into it

        Examples
        ========

        >>> from sympsi.operator import DifferentialOperator
        >>> from sympy import Function, Symbol, Derivative
        >>> x = Symbol('x')
        >>> f = Function('f')
        >>> d = DifferentialOperator(Derivative(f(x), x), f(x))
        >>> d.expr
        Derivative(f(x), x)
        >>> y = Symbol('y')
        >>> d = DifferentialOperator(Derivative(f(x, y), x) +
        ...                          Derivative(f(x, y), y), f(x, y))
        >>> d.expr
        Derivative(f(x, y), x) + Derivative(f(x, y), y)
        """

        return self.args[0] 
Example #5
Source File: operator.py    From sympsi with BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
def function(self):
        """
        Returns the function which is to be replaced with the Wavefunction

        Examples
        ========

        >>> from sympsi.operator import DifferentialOperator
        >>> from sympy import Function, Symbol, Derivative
        >>> x = Symbol('x')
        >>> f = Function('f')
        >>> d = DifferentialOperator(Derivative(f(x), x), f(x))
        >>> d.function
        f(x)
        >>> y = Symbol('y')
        >>> d = DifferentialOperator(Derivative(f(x, y), x) +
        ...                          Derivative(f(x, y), y), f(x, y))
        >>> d.function
        f(x, y)
        """

        return self.args[-1] 
Example #6
Source File: operator.py    From sympsi with BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
def variables(self):
        """
        Returns the variables with which the function in the specified
        arbitrary expression is evaluated

        Examples
        ========

        >>> from sympsi.operator import DifferentialOperator
        >>> from sympy import Symbol, Function, Derivative
        >>> x = Symbol('x')
        >>> f = Function('f')
        >>> d = DifferentialOperator(1/x*Derivative(f(x), x), f(x))
        >>> d.variables
        (x,)
        >>> y = Symbol('y')
        >>> d = DifferentialOperator(Derivative(f(x, y), x) +
        ...                          Derivative(f(x, y), y), f(x, y))
        >>> d.variables
        (x, y)
        """

        return self.args[-1].args 
Example #7
Source File: models.py    From symfit with GNU General Public License v2.0 5 votes vote down vote up
def ordered_symbols(self):
        """
        :return: list of all symbols in this model, topologically sorted so they
            can be evaluated in the correct order.

            Within each group of equal priority symbols, we sort by the order of
            the derivative.
        """
        key_func = lambda s: [isinstance(s, sympy.Derivative),
                           isinstance(s, sympy.Derivative) and s.derivative_count]
        symbols = []
        for symbol in toposort(self.connectivity_mapping):
            symbols.extend(sorted(symbol, key=key_func))

        return symbols 
Example #8
Source File: causal_identifier.py    From dowhy with MIT License 5 votes vote down vote up
def construct_iv_estimand(self, estimand_type, treatment_name,
                              outcome_name, instrument_names):
        # TODO: support multivariate treatments better.
        expr = None
        if estimand_type == "nonparametric-ate":
            outcome_name = outcome_name[0]
            sym_outcome = spstats.Normal(outcome_name, 0, 1)
            sym_treatment_symbols = [spstats.Normal(t, 0, 1) for t in treatment_name]
            sym_treatment = sp.Array(sym_treatment_symbols)
            sym_instrument_symbols = [sp.Symbol(inst) for inst in instrument_names]
            sym_instrument = sp.Array(sym_instrument_symbols)  # ",".join(instrument_names))
            sym_outcome_derivative = sp.Derivative(sym_outcome, sym_instrument)
            sym_treatment_derivative = sp.Derivative(sym_treatment, sym_instrument)
            sym_effect = spstats.Expectation(sym_outcome_derivative / sym_treatment_derivative)
            sym_assumptions = {
                "As-if-random": (
                    "If U\N{RIGHTWARDS ARROW}\N{RIGHTWARDS ARROW}{0} then "
                    "\N{NOT SIGN}(U \N{RIGHTWARDS ARROW}\N{RIGHTWARDS ARROW}{{{1}}})"
                ).format(outcome_name, ",".join(instrument_names)),
                "Exclusion": (
                    u"If we remove {{{0}}}\N{RIGHTWARDS ARROW}{{{1}}}, then "
                    u"\N{NOT SIGN}({{{0}}}\N{RIGHTWARDS ARROW}{2})"
                ).format(",".join(instrument_names), ",".join(treatment_name),
                         outcome_name)
            }
        else:
            raise ValueError("Estimand type not supported. Supported estimand types are 'non-parametric-ate'.")

        estimand = {
            'estimand': sym_effect,
            'assumptions': sym_assumptions
        }
        return estimand 
Example #9
Source File: causal_identifier.py    From dowhy with MIT License 5 votes vote down vote up
def construct_backdoor_estimand(self, estimand_type, treatment_name,
                                    outcome_name, common_causes):
        # TODO: outputs string for now, but ideally should do symbolic
        # expressions Mon 19 Feb 2018 04:54:17 PM DST
        # TODO Better support for multivariate treatments

        expr = None
        if estimand_type == "nonparametric-ate":
            outcome_name = outcome_name[0]
            num_expr_str = outcome_name
            if len(common_causes)>0:
                num_expr_str += "|" + ",".join(common_causes)
            expr = "d(" + num_expr_str + ")/d" + ",".join(treatment_name)
            sym_mu = sp.Symbol("mu")
            sym_sigma = sp.Symbol("sigma", positive=True)
            sym_outcome = spstats.Normal(num_expr_str, sym_mu, sym_sigma)
            # sym_common_causes = [sp.stats.Normal(common_cause, sym_mu, sym_sigma) for common_cause in common_causes]
            sym_treatment_symbols = [sp.Symbol(t) for t in treatment_name]
            sym_treatment = sp.Array(sym_treatment_symbols)
            sym_conditional_outcome = spstats.Expectation(sym_outcome)
            sym_effect = sp.Derivative(sym_conditional_outcome, sym_treatment)

            sym_assumptions = {
                'Unconfoundedness': (
                    u"If U\N{RIGHTWARDS ARROW}{{{0}}} and U\N{RIGHTWARDS ARROW}{1}"
                    " then P({1}|{0},{2},U) = P({1}|{0},{2})"
                ).format(",".join(treatment_name), outcome_name, ",".join(common_causes))
            }
        else:
            raise ValueError("Estimand type not supported. Supported estimand types are 'non-parametric-ate'.")

        estimand = {
            'estimand': sym_effect,
            'assumptions': sym_assumptions
        }
        return estimand 
Example #10
Source File: instrumental_variable_estimator.py    From dowhy with MIT License 5 votes vote down vote up
def construct_symbolic_estimator(self, estimand):
        sym_outcome = (spstats.Normal(",".join(estimand.outcome_variable), 0, 1))
        sym_treatment = (spstats.Normal(",".join(estimand.treatment_variable), 0, 1))
        sym_instrument = sp.Symbol(",".join(self.estimating_instrument_names))
        sym_outcome_derivative = sp.Derivative(sym_outcome, sym_instrument)
        sym_treatment_derivative = sp.Derivative(sym_treatment, sym_instrument)
        sym_effect = (
                spstats.Expectation(sym_outcome_derivative) /
                sp.stats.Expectation(sym_treatment_derivative)
        )
        estimator_assumptions = {
            "treatment_effect_homogeneity": (
                "Each unit's treatment {0} is ".format(self._treatment_name) +
                "affected in the same way by common causes of "
                "{0} and {1}".format(self._treatment_name, self._outcome_name)
            ),
            "outcome_effect_homogeneity": (
                "Each unit's outcome {0} is ".format(self._outcome_name) +
                "affected in the same way by common causes of "
                "{0} and {1}".format(self._treatment_name, self._outcome_name)
            ),
        }
        sym_assumptions = {**estimand.estimands["iv"]["assumptions"],
                           **estimator_assumptions}

        symbolic_estimand = RealizedEstimand(estimand,
                                             estimator_name="Wald Estimator")
        symbolic_estimand.update_assumptions(sym_assumptions)
        symbolic_estimand.update_estimand_expression(sym_effect)
        return symbolic_estimand 
Example #11
Source File: process_latex.py    From latex2sympy with MIT License 5 votes vote down vote up
def convert_frac(frac):
    diff_op = False
    partial_op = False
    lower_itv = frac.lower.getSourceInterval()
    lower_itv_len = lower_itv[1] - lower_itv[0] + 1
    if (frac.lower.start == frac.lower.stop and
        frac.lower.start.type == PSLexer.DIFFERENTIAL):
        wrt = get_differential_var_str(frac.lower.start.text)
        diff_op = True
    elif (lower_itv_len == 2 and
        frac.lower.start.type == PSLexer.SYMBOL and
        frac.lower.start.text == '\\partial' and
        (frac.lower.stop.type == PSLexer.LETTER or frac.lower.stop.type == PSLexer.SYMBOL)):
        partial_op = True
        wrt = frac.lower.stop.text
        if frac.lower.stop.type == PSLexer.SYMBOL:
            wrt = wrt[1:]

    if diff_op or partial_op:
        wrt = sympy.Symbol(wrt)
        if (diff_op and frac.upper.start == frac.upper.stop and
            frac.upper.start.type == PSLexer.LETTER and
            frac.upper.start.text == 'd'):
            return [wrt]
        elif (partial_op and frac.upper.start == frac.upper.stop and
            frac.upper.start.type == PSLexer.SYMBOL and
            frac.upper.start.text == '\\partial'):
            return [wrt]
        upper_text = rule2text(frac.upper)

        expr_top = None
        if diff_op and upper_text.startswith('d'):
            expr_top = process_sympy(upper_text[1:])
        elif partial_op and frac.upper.start.text == '\\partial':
            expr_top = process_sympy(upper_text[len('\\partial'):])
        if expr_top:
            return sympy.Derivative(expr_top, wrt)

    expr_top = convert_expr(frac.upper)
    expr_bot = convert_expr(frac.lower)
    return sympy.Mul(expr_top, sympy.Pow(expr_bot, -1, evaluate=False), evaluate=False) 
Example #12
Source File: process_latex.py    From latex2sympy with MIT License 5 votes vote down vote up
def convert_postfix_list(arr, i=0):
    if i >= len(arr):
        raise Exception("Index out of bounds")

    res = convert_postfix(arr[i])
    if isinstance(res, sympy.Expr):
        if i == len(arr) - 1:
            return res # nothing to multiply by
        else:
            if i > 0:
                left = convert_postfix(arr[i - 1])
                right = convert_postfix(arr[i + 1])
                if isinstance(left, sympy.Expr) and isinstance(right, sympy.Expr):
                    left_syms  = convert_postfix(arr[i - 1]).atoms(sympy.Symbol)
                    right_syms = convert_postfix(arr[i + 1]).atoms(sympy.Symbol)
                    # if the left and right sides contain no variables and the
                    # symbol in between is 'x', treat as multiplication.
                    if len(left_syms) == 0 and len(right_syms) == 0 and str(res) == "x":
                        return convert_postfix_list(arr, i + 1)
            # multiply by next
            return sympy.Mul(res, convert_postfix_list(arr, i + 1), evaluate=False)
    else: # must be derivative
        wrt = res[0]
        if i == len(arr) - 1:
            raise Exception("Expected expression for derivative")
        else:
            expr = convert_postfix_list(arr, i + 1)
            return sympy.Derivative(expr, wrt) 
Example #13
Source File: support.py    From symfit with GNU General Public License v2.0 5 votes vote down vote up
def seperate_symbols(func):
    """
    Seperate the symbols in symbolic function func. Return them in alphabetical
    order.

    :param func: scipy symbolic function.
    :return: (vars, params), a tuple of all variables and parameters, each 
        sorted in alphabetical order.
    :raises TypeError: only symfit Variable and Parameter are allowed, not sympy
        Symbols.
    """
    params = []
    vars = []
    for symbol in func.free_symbols:
        if not isidentifier(str(symbol)):
            continue  # E.g. Indexed objects might print to A[i, j]
        if isinstance(symbol, Parameter):
            params.append(symbol)
        elif isinstance(symbol, Idx):
            # Idx objects are not seen as parameters or vars.
            pass
        elif isinstance(symbol, (MatrixExpr, Expr)):
            vars.append(symbol)
        else:
            raise TypeError('model contains an unknown symbol type, {}'.format(type(symbol)))

    for der in func.atoms(sympy.Derivative):
        # Used by jacobians and hessians, where derivatives are treated as
        # Variables. This way of writing it is purposefully discriminatory
        # against derivatives wrt variables, since such derivatives should be
        # performed explicitly in the case of jacs/hess, and are treated
        # differently in the case of ODEModels.
        if der.expr in vars and all(isinstance(s, Parameter) for s in der.variables):
            vars.append(der)

    params.sort(key=lambda symbol: symbol.name)
    vars.sort(key=lambda symbol: symbol.name)
    return vars, params 
Example #14
Source File: models.py    From symfit with GNU General Public License v2.0 5 votes vote down vote up
def _partial_subs(func, func2vars):
    """
    Partial-bug proof substitution. Works by making the substitutions on
    the expression inside the derivative first, and then rebuilding the
    derivative safely without evaluating it using `_partial_diff`.
    """
    if isinstance(func, sympy.Derivative):
        new_func = func.expr.xreplace(func2vars)
        new_variables = tuple(var.xreplace(func2vars)
                              for var in func.variables)
        return _partial_diff(new_func, *new_variables)
    else:
        return func.xreplace(func2vars) 
Example #15
Source File: models.py    From symfit with GNU General Public License v2.0 5 votes vote down vote up
def _partial_diff(var, *params):
    """
    Sympy does not handle repeated partial derivation correctly, e.g.
    D(D(y, a), a) = D(y, a, a) but D(D(y, a), b) = 0.
    Use this function instead to prevent evaluation to zero.
    """
    if isinstance(var, sympy.Derivative):
        return sympy.Derivative(var.expr, *(var.variables + params))
    else:
        return D(var, *params) 
Example #16
Source File: derivative.py    From devito with MIT License 5 votes vote down vote up
def _eval_fd(self, expr):
        """
        Evaluate finite difference approximation of the Derivative.
        Evaluation is carried out via the following four steps:
        - 1: Evaluate derivatives within the expression. For example given
        `f.dx * g`, `f.dx` will be evaluated first.
        - 2: Evaluate the finite difference for the (new) expression.
        - 3: Evaluate remaining terms (as `g` may need to be evaluated
        at a different point).
        - 4: Apply substitutions.

        """
        # Step 1: Evaluate derivatives within expression
        expr = getattr(expr, '_eval_deriv', expr)

        # Step 2: Evaluate FD of the new expression
        if self.side is not None and self.deriv_order == 1:
            res = first_derivative(expr, self.dims[0], self.fd_order,
                                   side=self.side, matvec=self.transpose,
                                   x0=self.x0)
        elif len(self.dims) > 1:
            res = cross_derivative(expr, self.dims, self.fd_order, self.deriv_order,
                                   matvec=self.transpose, x0=self.x0)
        else:
            res = generic_derivative(expr, *self.dims, self.fd_order, self.deriv_order,
                                     matvec=self.transpose, x0=self.x0)

        # Step 3: Evaluate remaining part of expression
        res = res.evaluate

        # Step 4: Apply substitution
        for e in self._subs:
            res = res.xreplace(e)
        return res 
Example #17
Source File: derivative.py    From devito with MIT License 5 votes vote down vote up
def _new_from_self(self, **kwargs):
        _kwargs = {'deriv_order': self.deriv_order, 'fd_order': self.fd_order,
                   'side': self.side, 'transpose': self.transpose, 'subs': self._subs,
                   'x0': self.x0, 'preprocessed': True}
        expr = kwargs.pop('expr', self.expr)
        _kwargs.update(**kwargs)
        return Derivative(expr, *self.dims, **_kwargs) 
Example #18
Source File: printer.py    From galgebra with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
def find_functions(expr):
    f_lst = []
    for f in list(expr.atoms(Function)):
        if str(f) not in GaPrinter.function_names:
            f_lst.append(f)
    f_lst += list(expr.atoms(Derivative))
    return f_lst 
Example #19
Source File: differentiable.py    From devito with MIT License 5 votes vote down vote up
def diff(self, *symbols, **assumptions):
        """
        Like ``sympy.diff``, but return a ``devito.Derivative`` instead of a
        ``sympy.Derivative``.
        """
        from devito.finite_differences.derivative import Derivative
        return Derivative(self, *symbols, **assumptions) 
Example #20
Source File: operator.py    From sympsi with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
def _eval_derivative(self, symbol):
        new_expr = Derivative(self.expr, symbol)
        return DifferentialOperator(new_expr, self.args[-1])

    #-------------------------------------------------------------------------
    # Printing
    #------------------------------------------------------------------------- 
Example #21
Source File: printer.py    From galgebra with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
def __init__(self, base=None, fct=None, deriv=None, on=True, debug=False):
        if on:
            OS = 'unix'
            if 'win' in sys.platform and 'darwin' not in sys.platform:
                OS = 'win'

            if base is None:
                Eprint.base = Eprint.ColorCode[Eprint.defaults[(OS, 'base')]]
            else:
                Eprint.base = Eprint.ColorCode[base]
            if fct is None:
                Eprint.fct = Eprint.ColorCode[Eprint.defaults[(OS, 'fct')]]
            else:
                Eprint.fct = Eprint.ColorCode[fct]
            if deriv is None:
                Eprint.deriv = Eprint.ColorCode[Eprint.defaults[(OS, 'deriv')]]
            else:
                Eprint.deriv = Eprint.ColorCode[deriv]
            Eprint.normal = '\033[0m'

            if debug:
                print('Enhanced Printing is on:')
                print('Base/Blade color is ' + Eprint.InvColorCode[Eprint.base])
                print('Function color is ' + Eprint.InvColorCode[Eprint.fct])
                print('Derivative color is ' + Eprint.InvColorCode[Eprint.deriv] + '\n')

            Eprint.base = '\033[' + Eprint.base + 'm'
            Eprint.fct = '\033[' + Eprint.fct + 'm'
            Eprint.deriv = '\033[' + Eprint.deriv + 'm' 
Example #22
Source File: test_conventions.py    From Computable with MIT License 4 votes vote down vote up
def test_requires_partial():
    x, y, z, t, nu = symbols('x y z t nu')
    n = symbols('n', integer=True)

    f = x * y
    assert requires_partial(Derivative(f, x)) is True
    assert requires_partial(Derivative(f, y)) is True

    ## integrating out one of the variables
    assert requires_partial(Derivative(Integral(exp(-x * y), (x, 0, oo)), y, evaluate=False)) is False

    ## bessel function with smooth parameter
    f = besselj(nu, x)
    assert requires_partial(Derivative(f, x)) is True
    assert requires_partial(Derivative(f, nu)) is True

    ## bessel function with integer parameter
    f = besselj(n, x)
    assert requires_partial(Derivative(f, x)) is False
    # this is not really valid (differentiating with respect to an integer)
    # but there's no reason to use the partial derivative symbol there. make
    # sure we don't throw an exception here, though
    assert requires_partial(Derivative(f, n)) is False

    ## bell polynomial
    f = bell(n, x)
    assert requires_partial(Derivative(f, x)) is False
    # again, invalid
    assert requires_partial(Derivative(f, n)) is False

    ## legendre polynomial
    f = legendre(0, x)
    assert requires_partial(Derivative(f, x)) is False

    f = legendre(n, x)
    assert requires_partial(Derivative(f, x)) is False
    # again, invalid
    assert requires_partial(Derivative(f, n)) is False

    f = x ** n
    assert requires_partial(Derivative(f, x)) is False

    assert requires_partial(Derivative(Integral((x*y) ** n * exp(-x * y), (x, 0, oo)), y, evaluate=False)) is False

    # parametric equation
    f = (exp(t), cos(t))
    g = sum(f)
    assert requires_partial(Derivative(g, t)) is False

    # function of unspecified variables
    f = symbols('f', cls=Function)
    assert requires_partial(Derivative(f, x)) is False
    assert requires_partial(Derivative(f, x, y)) is True 
Example #23
Source File: derivative.py    From devito with MIT License 4 votes vote down vote up
def _process_kwargs(cls, expr, *dims, **kwargs):
        """
        Process arguments for the construction of a Derivative
        """
        # Skip costly processing if constructiong from preprocessed
        if kwargs.get('preprocessed', False):
            fd_orders = kwargs.get('fd_order')
            deriv_orders = kwargs.get('deriv_order')
            if len(dims) == 1:
                dims = tuple([dims[0]]*deriv_orders)
            variable_count = [sympy.Tuple(s, dims.count(s))
                              for s in filter_ordered(dims)]
            return dims, deriv_orders, fd_orders, variable_count
        # Check `dims`. It can be a single Dimension, an iterable of Dimensions, or even
        # an iterable of 2-tuple (Dimension, deriv_order)
        if len(dims) == 0:
            raise ValueError("Expected Dimension w.r.t. which to differentiate")
        elif len(dims) == 1:
            if isinstance(dims[0], Iterable):
                # Iterable of Dimensions
                if len(dims[0]) != 2:
                    raise ValueError("Expected `(dim, deriv_order)`, got %s" % dims[0])
                orders = kwargs.get('deriv_order', dims[0][1])
                if dims[0][1] != orders:
                    raise ValueError("Two different values of `deriv_order`")
                new_dims = tuple([dims[0][0]]*dims[0][1])
            else:
                # Single Dimension
                orders = kwargs.get('deriv_order', 1)
                if isinstance(orders, Iterable):
                    orders = orders[0]
                new_dims = tuple([dims[0]]*orders)
        else:
            # Iterable of 2-tuple, e.g. ((x, 2), (y, 3))
            new_dims = []
            orders = []
            d_ord = kwargs.get('deriv_order', tuple([1]*len(dims)))
            for d, o in zip(dims, d_ord):
                if isinstance(d, Iterable):
                    new_dims.extend([d[0] for _ in range(d[1])])
                    orders.append(d[1])
                else:
                    new_dims.extend([d for _ in range(o)])
                    orders.append(o)
            new_dims = as_tuple(new_dims)
            orders = as_tuple(orders)

        # Finite difference orders depending on input dimension (.dt or .dx)
        fd_orders = kwargs.get('fd_order', tuple([expr.time_order if
                                                  getattr(d, 'is_Time', False) else
                                                  expr.space_order for d in dims]))
        if len(dims) == 1 and isinstance(fd_orders, Iterable):
            fd_orders = fd_orders[0]

        # SymPy expects the list of variable w.r.t. which we differentiate to be a list
        # of 2-tuple `(s, count)` where s is the entity to diff wrt and count is the order
        # of the derivative
        variable_count = [sympy.Tuple(s, new_dims.count(s))
                          for s in filter_ordered(new_dims)]
        return new_dims, orders, fd_orders, variable_count 
Example #24
Source File: support.py    From symfit with GNU General Public License v2.0 4 votes vote down vote up
def sympy_to_py(func, args):
    """
    Turn a symbolic expression into a Python lambda function,
    which has the names of the variables and parameters as it's argument names.

    :param func: sympy expression
    :param args: variables and parameters in this model
    :return: lambda function to be used for numerical evaluation of the model.
    """
    # replace the derivatives with printable variables.
    derivatives = {var: Variable(var.name) for var in args
                   if isinstance(var, sympy.Derivative)}
    func = func.xreplace(derivatives)
    args = [derivatives[var] if isinstance(var, sympy.Derivative) else var
            for var in args]
    lambdafunc = lambdify(args, func, dummify=False)
    # Check if the names of the lambda function are what we expect
    signature = inspect_sig.signature(lambdafunc)
    sig_parameters = OrderedDict(signature.parameters)
    for arg, lambda_arg in zip(args, sig_parameters):
        if arg.name != lambda_arg:
            break
    else:  # Lambdifying succesful!
        return lambdafunc

    # If we are here (very rare), then one of the lambda arg is still a Dummy.
    # In this case we will manually handle the naming.
    lambda_names = sig_parameters.keys()
    arg_names = [arg.name for arg in args]
    conversion = dict(zip(arg_names, lambda_names))

    # Wrap the lambda such that arg names are translated into the correct dummy
    # symbol names
    @wraps(lambdafunc)
    def wrapped_lambdafunc(*ordered_args, **kwargs):
        converted_kwargs = {conversion[k]: v for k, v in kwargs.items()}
        return lambdafunc(*ordered_args, **converted_kwargs)

    # Update the signature of wrapped_lambdafunc to math our args
    new_sig_parameters = OrderedDict()
    for arg_name, dummy_name in conversion.items():
        if arg_name == dummy_name:  # Already has the correct name
            new_sig_parameters[arg_name] = sig_parameters[arg_name]
        else:  # Change the dummy inspect.Parameter to the correct name
            param = sig_parameters[dummy_name]
            param = param.replace(name=arg_name)
            new_sig_parameters[arg_name] = param

    wrapped_lambdafunc.__signature__ = signature.replace(
        parameters=new_sig_parameters.values()
    )
    return wrapped_lambdafunc 
Example #25
Source File: test_printing.py    From sympsi with BSD 3-Clause "New" or "Revised" License 4 votes vote down vote up
def test_operator():
    a = Operator('A')
    b = Operator('B', Symbol('t'), S(1)/2)
    inv = a.inv()
    f = Function('f')
    x = symbols('x')
    d = DifferentialOperator(Derivative(f(x), x), f(x))
    op = OuterProduct(Ket(), Bra())
    assert str(a) == 'A'
    assert pretty(a) == 'A'
    assert upretty(a) == u('A')
    assert latex(a) == 'A'
    sT(a, "Operator(Symbol('A'))")
    assert str(inv) == 'A**(-1)'
    ascii_str = \
"""\
 -1\n\
A  \
"""
    ucode_str = \
u("""\
 -1\n\
A  \
""")
    assert pretty(inv) == ascii_str
    assert upretty(inv) == ucode_str
    assert latex(inv) == r'\left(A\right)^{-1}'
    sT(inv, "Pow(Operator(Symbol('A')), Integer(-1))")
    assert str(d) == 'DifferentialOperator(Derivative(f(x), x),f(x))'
    ascii_str = \
"""\
                    /d            \\\n\
DifferentialOperator|--(f(x)),f(x)|\n\
                    \dx           /\
"""
    ucode_str = \
u("""\
                    ⎛d            ⎞\n\
DifferentialOperator⎜──(f(x)),f(x)⎟\n\
                    ⎝dx           ⎠\
""")
    assert pretty(d) == ascii_str
    assert upretty(d) == ucode_str
    assert latex(d) == \
        r'DifferentialOperator\left(\frac{d}{d x} f{\left (x \right )},f{\left (x \right )}\right)'
    sT(d, "DifferentialOperator(Derivative(Function('f')(Symbol('x')), Symbol('x')),Function('f')(Symbol('x')))")
    assert str(b) == 'Operator(B,t,1/2)'
    assert pretty(b) == 'Operator(B,t,1/2)'
    assert upretty(b) == u('Operator(B,t,1/2)')
    assert latex(b) == r'Operator\left(B,t,\frac{1}{2}\right)'
    sT(b, "Operator(Symbol('B'),Symbol('t'),Rational(1, 2))")
    assert str(op) == '|psi><psi|'
    assert pretty(op) == '|psi><psi|'
    assert upretty(op) == u('❘ψ⟩⟨ψ❘')
    assert latex(op) == r'{\left|\psi\right\rangle }{\left\langle \psi\right|}'
    sT(op, "OuterProduct(Ket(Symbol('psi')),Bra(Symbol('psi')))")