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])
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
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
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
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])
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
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
def __getitem__(self, expression): (a, b) = self._indices return Symmetrizer(sympy.Tuple(*a), sympy.Tuple(*b), expression)
def __call__(self, *indices): return Tensor(self, sympy.Tuple(*[i for i in indices]))
def __new__(cls, base, indices): return sympy.Expr.__new__(cls, base, sympy.Tuple(*indices))
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)
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
def bug_Tuple_not_using_iterable_to_init(): return len(sympy.Tuple(range(3))) == 1
def pack_rvalues(scope={}): rvalues = tuple( rhs.subs(scope.items()).doit() for rhs in self.rhs) return {self.lhs: sympy.Tuple(*rvalues)}
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), ))