Example #1
0
 def set_values(self, data, values_col):
     if values_col not in data:
         raise Exception('{} not in data DataFrame'.format(values_col))
     if [r for r in self.indeces if r.refers_to.name not in data]:
         raise Exception('Indeces - {} not present in data'.format(
             [r for r in self.indeces if r.name not in data]))
     if [x for x in self.indeces if not x.values]:
         for r in [x.refers_to for x in self.indeces if not x.values]:
             r.set_values(data=data)
         if [x for x in self.indeces if not x.values]:
             raise Exception('Ranges - {} do not have values'.format([
                 x.refers_to for x in self.indeces if not x.refers_to.values
             ]))
     df = data[[r.refers_to.name for r in self.indeces] + [values_col]]
     values_list = [x.refers_to.values for x in self.indeces]
     cp = list(itertools.product(*values_list))
     values = pd.DataFrame(cp)
     rename_dict = {}
     for i, col in enumerate(values.columns):
         rename_dict.update({col: self.indeces[i].refers_to.name})
     values = values.rename(columns=rename_dict)
     values = values.merge(df,
                           how='left',
                           on=[x.refers_to.name for x in self.indeces])
     if [
             col for col in df.columns
             if col in [r.name for r in self.indeces]
     ]:
         raise Exception(
             'Indeces names and range names cannot overlap - {}'.format([
                 col for col in df.columns
                 if col in [r.name for r in self.indeces]
             ]))
     for index in self.indeces:
         range_df = pd.DataFrame()
         range_df[index.refers_to.name] = index.refers_to.values
         range_df[index.name] = index.values
         values = values.merge(range_df, on=index.refers_to.name)
     self.values = values[[r.name for r in self.indeces] + [values_col]]
     self.values = self.values[values_col].fillna(0)
     self.values = values.set_index([r.name for r in self.indeces
                                     ])[values_col].sort_index()
     self.array = OpArray(list(self.values),
                          shape=tuple([x.length for x in self.indeces]))
     self._shape = sp.Tuple(*[x.length for x in self.indeces])
Example #2
0
    def make_params(self):
        pa, pe = self.make_model()
        expr = sympy.Tuple(pa, pe)

        free = expr.free_symbols
        func = sympy.lambdify(list(free), expr)

        mod = lmfit.Model(func, ['wl', 't'])
        params = mod.make_params()
        for pn in params:
            p = params[pn]
            p.value = self.values[pn]
            if pn.startswith('angle'):
                p.min = 0
                p.max = 90
            elif pn.startswith('w'):
                p.min = 2
        y = mod.eval(wl=self.wl_arr[:, None], t=self.t_arr, **params)

        return params, mod
Example #3
0
    def visit(e):
        if not isinstance(e, sp.Tuple):
            e = e.expand()

        if e.func == Diff:
            result = 0
            diff_args = {'target': e.target, 'superscript': e.superscript}
            diff_inner = e.args[0]
            diff_inner = visit(diff_inner)
            if diff_inner.func not in (sp.Add, sp.Mul):
                return e
            for term in diff_inner.args if diff_inner.func == sp.Add else [
                    diff_inner
            ]:
                independent_terms = 1
                dependent_terms = []
                for factor in normalize_product(term):
                    if factor in functions or isinstance(factor, Diff):
                        dependent_terms.append(factor)
                    else:
                        independent_terms *= factor
                for i in range(len(dependent_terms)):
                    dependent_term = dependent_terms[i]
                    other_dependent_terms = dependent_terms[:
                                                            i] + dependent_terms[
                                                                i + 1:]
                    processed_diff = normalize_diff_order(
                        Diff(dependent_term, **diff_args))
                    result += independent_terms * prod(
                        other_dependent_terms) * processed_diff
            return result
        elif isinstance(e, sp.Piecewise):
            return sp.Piecewise(*((expand_diff_full(a, functions, constants),
                                   b) for a, b in e.args))
        elif isinstance(expr, sp.Tuple):
            new_args = [visit(arg) for arg in e.args]
            return sp.Tuple(*new_args)
        else:
            new_args = [visit(arg) for arg in e.args]
            return e.func(*new_args) if new_args else e
Example #4
0
def expand_diff_linear(expr, functions=None, constants=None):
    """Expands all derivative nodes by applying Diff.split_linear

    Args:
        expr: expression containing derivatives
        functions: sequence of symbols that are considered functions and can not be pulled before the derivative.
                   if None, all symbols are viewed as functions
        constants: sequence of symbols which are considered constants and can be pulled before the derivative
    """
    if functions is None:
        functions = expr.atoms(sp.Symbol)
        if constants is not None:
            functions.difference_update(constants)

    if isinstance(expr, Diff):
        arg = expand_diff_linear(expr.arg, functions)
        if hasattr(arg, 'func') and arg.func == sp.Add:
            result = 0
            for a in arg.args:
                result += Diff(
                    a, target=expr.target,
                    superscript=expr.superscript).split_linear(functions)
            return result
        else:
            diff = Diff(arg, target=expr.target, superscript=expr.superscript)
            if diff == 0:
                return 0
            else:
                return diff.split_linear(functions)
    elif isinstance(expr, sp.Piecewise):
        return sp.Piecewise(*((expand_diff_linear(a, functions, constants), b)
                              for a, b in expr.args))
    elif isinstance(expr, sp.Tuple):
        new_args = [expand_diff_linear(e, functions) for e in expr.args]
        return sp.Tuple(*new_args)
    else:
        new_args = [expand_diff_linear(e, functions) for e in expr.args]
        result = sp.expand(expr.func(*new_args) if new_args else expr)
        return result
Example #5
0
 def set_values(self, data):
     if self.values is None:
         self.create(data)
     if not all(
         [x.refers_to.name in data or x.name in data
          for x in self.indeces]):
         raise Exception('All indeces are not present in the given data')
     df = pd.DataFrame()
     for index in self.indeces:
         if index.name in data:
             df[index.name] = data[index.name]
         else:
             range_df = pd.DataFrame()
             range_df[index.refers_to.name] = index.refers_to.values
             range_df[index.name] = index.values
             df[index.name] = data.merge(
                 range_df, how='left', on=index.refers_to.name)[index.name]
     df['ones'] = 1
     if [
             col for col in df.columns
             if (col in [r.name for r in self.indeces]
                 and col in [r.name for r in self.ranges])
     ]:
         raise Exception(
             'Indeces names and range names cannot overlap - {}'.format([
                 col for col in df.columns
                 if col in [r.name for r in self.indeces]
             ]))
     self.values = self.values.reset_index().merge(
         df, how='left', on=[x.name for x in self.indeces])
     self.values.loc[self.values['ones'].isna(), self.name] = 0
     self.values = self.values.set_index([r.name for r in self.indeces
                                          ])[self.name].sort_index()
     self.array = OpArray(list(self.values),
                          shape=tuple([x.length for x in self.indeces]))
     self._shape = sp.Tuple(*[x.length for x in self.indeces])
Example #6
0
def _process_funcxy(args, testx, testy):
    isdy = False
    f = args.pop()

    if isinstance(
            f, (sp.Tuple, tuple, list)
    ):  # if (f1 (x, y), f2 (x, y)) functions or expressions present in args they are individual u and v functions
        c1, c2 = callable(f[0]), callable(f[1])

        if c1 and c2:  # two Lambdas
            f = __fxfy2fxy(f[0], f[1])

        elif not (c1 or c2):  # two expressions
            vars = tuple(
                sorted(sp.Tuple(f[0], f[1]).free_symbols,
                       key=lambda s: s.name))

            if len(vars) != 2:
                raise ValueError(
                    'expression must have exactly two free variables')

            return args, __fxfy2fxy(sp.Lambda(vars, f[0]),
                                    sp.Lambda(vars, f[1])), False

        else:
            raise ValueError(
                'field must be specified by two lambdas or two expressions, not a mix'
            )

    # one function or expression
    if not callable(f):  # convert expression to function
        if len(f.free_symbols) != 2:
            raise ValueError('expression must have exactly two free variables')

        f = sp.Lambda(tuple(sorted(f.free_symbols, key=lambda s: s.name)), f)

    for y in testy:  # check if returns 1 dy or 2 u and v values
        for x in testx:
            try:
                v = f(x, y)
            except (ValueError, ZeroDivisionError, FloatingPointError):
                continue

            try:
                _, _ = v
                f = __fxy2fxy(f)

                break

            except:
                f = __fdy2fxy(f)
                isdy = True

                break

        else:
            continue

        break

    return args, f, isdy
Example #7
0
    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 #8
0
 def __getitem__(self, expression):
     (a, b) = self._indices
     return Symmetrizer(sympy.Tuple(*a), sympy.Tuple(*b), expression)
Example #9
0
 def __call__(self, *indices):
     return Tensor(self, sympy.Tuple(*[i for i in indices]))
Example #10
0
 def __new__(cls, base, indices):
     return sympy.Expr.__new__(cls, base, sympy.Tuple(*indices))
Example #11
0
 def on_assign (self, match, target, op, expr) :
     if op == "+=" :
         expr = sympy.Add(target, expr)
     elif op == "-=" :
         expr = sympy.Add(target, -expr)
     return sympy.Tuple(target, expr)
Example #12
0
    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")

        # 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)
        ]

        # Construct the actual Derivative object
        obj = Differentiable.__new__(cls, expr, *variable_count)
        obj._dims = tuple(OrderedDict.fromkeys(new_dims))
        obj._fd_order = fd_orders
        obj._deriv_order = orders
        obj._side = kwargs.get("side", centered)
        obj._transpose = kwargs.get("transpose", direct)
        obj._subs = as_tuple(kwargs.get("subs"))
        obj._x0 = kwargs.get('x0', None)
        return obj
Example #13
0
def bug_Tuple_not_using_iterable_to_init():
    return len(sympy.Tuple(range(3))) == 1
Example #14
0
 def pack_rvalues(scope={}):
     rvalues = tuple(
         rhs.subs(scope.items()).doit()
         for rhs in self.rhs)
     return {self.lhs: sympy.Tuple(*rvalues)}
Example #15
0
 def set_values(self, data):
     values = list(pd.Series(data[self.name].unique()))
     self.values = values
     self.index.set_values(len(self.values))
     self._shape = sp.Tuple(*(len(self.values), ))