示例#1
0
    def to_function(self):
        if not self.position.is_diag:
            raise ValueError("Position must be diagonal!")

        def rec_a(i):
            return float(1 / np.sqrt(i + 1))

        def rec_b(i):
            return -float(np.sqrt(i) / np.sqrt(i + 1))

        dirs = self.position.dirs
        hermite_dirs = []

        for i, d in enumerate(dirs):
            var = func.Function.xyz[d]
            h0 = func.Function('1', dirs=dirs)
            μ, σ = self.position.mean[i], self.position.cov[i][i]
            f1 = np.sqrt(σ) * (var - μ)
            h1 = func.Function(f1, dirs=dirs)
            hermite_dirs.append([h0, h1])
            for j in range(1, self.degree):
                hermite_dirs[i].append(hermite_dirs[i][-1] *
                                       hermite_dirs[i][1] * rec_a(j) +
                                       hermite_dirs[i][-2] * rec_b(j))

        result = func.Function('0', dirs=dirs)
        for im, m in enumerate(self.multi_indices()):
            result_m = func.Function(self.coeffs[im], dirs=dirs)
            for i in range(0, self.position.dim):
                result_m *= hermite_dirs[i][m[i]]
            result += result_m
        return result
示例#2
0
    def __call__(self, arg):

        if not isinstance(arg, (func.Function, Operator)):
            try:
                arg = Operator(arg, dirs=self.dirs)
            except TypeError:
                arg = func.Function(arg, dirs=self.dirs)
        variables = [func.Function.x_sub[d] for d in self.dirs]
        sym = self.sym.subs(self.f(*variables), arg.sym).doit()
        return Operator(sym, dirs=self.dirs) if isinstance(arg, Operator) \
            else func.Function(sym, dirs=self.dirs)
示例#3
0
 def test_construct_from_string(self):
     function_str1 = 'x*cos(y) + exp(z)**2'
     function_str2 = 'x0*cos(x1) + exp(x2)**2'
     function_sym1 = x * sym.cos(y) + sym.exp(z)**2
     function_sym2 = v[0] * sym.cos(v[1]) + sym.exp(v[2])**2
     function1 = func.Function(function_str1)
     function2 = func.Function(function_str2)
     function3 = func.Function(function_sym1)
     function4 = func.Function(function_sym2)
     self.assertTrue(function1 == function2)
     self.assertTrue(function2 == function3)
     self.assertTrue(function3 == function4)
示例#4
0
 def split(self):
     MAX_ORDER = 5
     variables = [func.Function.x_sub[d] for d in self.dirs]
     unknown, dim = self.f(*variables), len(variables)
     result, rem = {}, self.sym.expand()
     mult = list(
         m for m in itertools.product(range(MAX_ORDER + 1), repeat=dim)
         if sum(m) <= MAX_ORDER)
     for m in mult:
         if rem == 0:
             break
         test, der = 1, unknown
         for i, v in zip(m, variables):
             test *= v**i / math.factorial(i)
             der = sympy.diff(der, v, i)
         remargs = rem.args if isinstance(rem, sympy.Add) else [rem]
         term, rem = 0, 0
         for arg in remargs:  # Convoluted to avoid rounding errors
             termarg = arg.subs(unknown, test).doit()
             if termarg == 0:
                 rem += arg
             else:
                 term += termarg
         if isinstance(term, sympy.Basic):
             term = sympy.simplify(term)
         if term != 0:
             result[tuple(m)] = func.Function(term, dirs=self.dirs)
     if rem != 0:
         raise ValueError("Nonzero remainder")
     return result
示例#5
0
 def discretize(self, f):
     if not isinstance(f, symfunc.Function):
         f = symfunc.Function(f)
     f = f.as_string(format='array', toC=True)
     function = core.discretize(f, self.nodes, self.position.mean,
                                self.position.factor)
     return function
示例#6
0
    def tensorize(args, sparse=None):

        for a in args:
            if not isinstance(a, Varf):
                raise ValueError("Invalid argument(s)")

        if len(args) == 1:
            return args[0]

        sparse = rc.settings['sparse'] if sparse is None else sparse
        index_set, degree = args[0].index_set, args[0].degree
        mats = {}
        factor = 1
        for a in args:
            if not isinstance(a, Varf) or \
               not a.index_set == index_set or \
               not a.degree == degree:
                raise ValueError("Invalid argument(s)")
            key = frozenset(a.position.dirs)
            mats[key] = a.matrix
            factor *= a.factor.sym

        matrix = core.tensorize(mats, sparse=sparse, index_set=index_set)
        position = pos.Position.tensorize([a.position for a in args])
        factor = func.Function(factor, dirs=position.dirs)
        return Varf(matrix, position, factor=factor, index_set=index_set)
示例#7
0
    def __init__(self,
                 coeffs,
                 position,
                 factor=1,
                 index_set="triangle",
                 significant=0):

        self.coeffs = coeffs
        self.position = position
        self.index_set = index_set

        dim, npolys = self.position.dim, len(self.coeffs)

        if position.dirs == []:
            self.degree = 0
        else:
            self.degree = core.iterator_get_degree(dim,
                                                   npolys,
                                                   index_set=index_set)

            if not len(self.multi_indices()) == len(self.coeffs):
                raise ValueError("Invalid arguments: length of self.coeffs \
does not match number of multi-indices!")

        if significant != 0:
            for i, c in enumerate(self.coeffs):
                self.coeffs[i] = round(c, significant)

        self.factor = func.Function(factor, dirs=self.position.dirs)

        if not self.coeffs.flags['C_CONTIGUOUS']:
            self.coeffs = self.coeffs.copy(order='C')
示例#8
0
 def map(self, factor):
     if not isinstance(factor, func.Function):
         factor = func.Function(factor, dirs=self.dirs)
     if not factor.dirs == self.dirs:
         raise ValueError("Directions differ")
     variables = [func.Function.x_sub[d] for d in self.dirs]
     unknown = self.f(*variables)
     sym = self.sym.subs(unknown, (unknown * factor).sym)
     sym = (sym.doit() / factor.sym).expand()
     return Operator(sym, dirs=self.dirs)
示例#9
0
    def __init__(self, matrix, position, factor=1, index_set="triangle"):
        self.is_sparse = isinstance(matrix, ss.csr_matrix)
        self.matrix = matrix
        self.position = position
        self.index_set = index_set

        dim, npolys = self.position.dim, self.matrix.shape[0]
        self.degree = core.iterator_get_degree(dim, npolys,
                                               index_set=index_set)
        assert len(self.multi_indices()) == self.matrix.shape[0]
        self.factor = func.Function(factor, dirs=self.position.dirs)
示例#10
0
            def wrapper(*args, **kwargs):

                do_tensorize = rc.settings['tensorize']
                if 'tensorize' in kwargs:
                    do_tensorize = kwargs['tensorize']
                    del kwargs['tensorize']
                if not do_tensorize:
                    return func(*args, **kwargs)

                quad, function = args[0], args[arg_num]
                if not quad.position.is_diag or \
                        isinstance(function, np.ndarray) or \
                        quad.position.dim is 1:
                    return func(*args, **kwargs)

                results = []
                if not isinstance(function, symfunc.Function):
                    function = symfunc.Function(function,
                                                dim=quad.position.dim)

                for add in function.split():
                    if len(add) == 2:
                        new_args = list(args).copy()
                        new_args[arg_num] = add[0]
                        results.append(
                            func(*new_args, **kwargs) * float(add[1]))
                        continue

                    func_dirs = []
                    for d in range(quad.position.dim):
                        new_args = list(args).copy()
                        new_args[0] = quad.project(d)
                        new_args[arg_num] = add[d]
                        func_dir = func(*new_args, **kwargs)
                        func_dirs.append(func_dir)
                    if rc.settings['debug']:
                        print("Tensorizing results")
                    kwargs_func = {'sparse': kwargs['sparse']} \
                        if 'sparse' in kwargs else {}
                    t = type(func_dirs[0])
                    tens_fun = t.tensorize if t is hv.Varf or t is hs.Series \
                        else core.tensorize
                    tensorized = tens_fun(func_dirs, **kwargs_func)
                    # pdb.set_trace()
                    results.append(tensorized * float(add[-1]))

                return sum(results[1:], results[0])
示例#11
0
 def test_simple_split(self):
     newf = func.Function
     f = func.Function('x*y**2 + 5*exp(z)*y + 3*log(x*z)')
     split = f.split()
     self.assertTrue(len(f.dirs) == 3)
     self.assertTrue(len(split) == 3)
     for i in range(3):
         if split[i][-1] == 1:
             self.assertTrue(len(split[i]) == 4)
             self.assertTrue(split[i][0] == newf('x', dirs=[0]))
             self.assertTrue(split[i][1] == newf('y*y', dirs=[1]))
         if split[i][-1] == 5:
             self.assertTrue(len(split[i]) == 4)
             self.assertTrue(split[i][0] == newf('1', dirs=[0]))
             self.assertTrue(split[i][1] == newf('y', dirs=[1]))
             self.assertTrue(split[i][2] == newf('exp(z)', dirs=[2]))
         if split[i][-1] == 3:
             self.assertTrue(len(split[i]) == 2)
             self.assertTrue(split[i][0] == newf('log(x*z)', dim=3))
示例#12
0
        def _tensorize(s1, s2):
            if not isinstance(s1, Series) or not isinstance(s2, Series):
                raise ValueError("Arguments must be Series!")

            if s1.position.dim == 0:
                return Series(s1.coeffs[0] * s2.coeffs,
                              s2.position,
                              factor=s2.factor,
                              index_set=s2.index_set)

            if s2.position.dim == 0:
                return Series(s2.coeffs[0] * s1.coeffs,
                              s1.position,
                              factor=s1.factor,
                              index_set=s1.index_set)

            # Inner product only makes sense in weighted space
            # Product in appropriate weighted space
            common = set(s1.position.dirs).intersection(s2.position.dirs)
            f1 = s1.factor.project(list(common))
            f2 = s2.factor.project(list(common))

            if not f1 == f2:
                raise ValueError("Factors should be match!")

            if not s1.degree == s2.degree:
                raise ValueError("s1 and s2 should have the same degree")

            if not s1.index_set == s2.index_set:
                raise ValueError("s1 and s2 should have the same index_set")

            f1, f2 = s1.factor.sym / f1.sym, s2.factor.sym / f2.sym
            d1, d2 = s1.position.dirs, s2.position.dirs
            c1, c2 = s1.coeffs, s2.coeffs
            result = core.inner(c1, c2, d1, d2, index_set=s1.index_set)
            position = pos.Position.tensorize([s1.position, s2.position])
            factor = func.Function(f1 * f2, dirs=position.dirs)
            return Series(result,
                          position,
                          factor=factor,
                          index_set=s1.index_set)
示例#13
0
 def plot(self, series, factor=None, ax=None):
     assert self.position.is_diag
     assert self.position == series.position
     if factor is None:
         factor = self.position.weight()
     if not isinstance(factor, np.ndarray):
         # ipdb.set_trace()
         factor = symfunc.Function(factor, dirs=self.position.dirs)
         factor = self.discretize(factor)
     n_nodes = []
     r_nodes = []
     for i in range(self.position.dim):
         n_nodes.append(len(self.nodes[i]))
         r_nodes.append(
             self.project(i).discretize('x'))  # Problematic line?
     solution = self.eval(series) * factor
     solution = solution.reshape(*n_nodes).T
     if self.position.dim == 1:
         return ax.plot(*r_nodes, solution)
     elif self.position.dim == 2:
         return ax.contourf(*r_nodes, solution, 100)
示例#14
0
    def __init__(self, expr, dirs=None):

        if isinstance(expr, Operator):
            self.sym = expr.sym
            self.dirs = expr.dirs
            return

        aux = func.Function(expr)

        if aux.sym == 0:
            if dirs is None:
                raise ValueError("Invalid argument!")
            self.sym, self.dirs = aux.sym, dirs
            return

        functions = list(aux.sym.atoms(sympy.core.function.AppliedUndef))
        if len(functions) != 1:
            raise TypeError("There should be exactly 1 functional argument!")

        self.sym = aux.sym.subs(functions[0].func, self.f)
        variables = list(self.sym.atoms(
            sympy.core.function.AppliedUndef))[0].args
        self.dirs = [func.Function.x_sub.index(v) for v in variables]
        assert len(self.dirs) == len(functions[0].args)
示例#15
0
 def test_as_xyz(self):
     function_str1 = 'x0*cos(x1) + exp(2*x2)'
     function_str2 = 'x*cos(y) + exp(2*z)'
     function = func.Function(function_str1)
     self.assertTrue(str(function.sym) == function_str1)
     self.assertTrue(str(function.as_xyz()) == function_str2)
示例#16
0
    return symbolic


for i in range(nterms):
    print("Solving for power " + str(i))

    unk[i] = sym.Function('u{}'.format(i))(x)
    u[i] = unk[i]

    rhs = sym.Integer(0)
    if i > 0:
        rhs += -L1.subs(f, u[i - 1])
    if i > 1:
        rhs += -L2.subs(f, u[i - 2])

    split = func.Function(rhs.doit().expand(), dim=2).split()

    for term in split:
        x_part = term[-1] * term[0].as_xyz()
        y_part = term[1].as_xyz()
        t_rhs = quad_num.transform(y_part, degree)
        centered[i] += round(t_rhs.coeffs[0], 10) * x_part
        u[i] += x_part * iL0(y_part)
    u[i] = func.Function.sanitize(u[i])
    centered[i] = func.Function.sanitize(centered[i])

# }}}
# Some manual calculations {{{
# Operator
fx = sym.Function('fx')(x)
LFP = ((1 / β) * sym.exp(-β * Vp) * (fx * sym.exp(β * Vp)).diff(x)).diff(x)
示例#17
0
 def __mul__(self, other):
     if not isinstance(other, func.Function):
         other = func.Function(other, dirs=self.dirs)
     if not self.dirs == other.dirs:
         raise ValueError("Invalid argument!")
     return Operator(self.sym * other.sym, dirs=self.dirs)