Ejemplo n.º 1
0
    def eval(self, x, output_array=None):
        """Return expression evaluated on x

        Parameters
        ----------
        x : float or array of floats
            Array must be of shape (D, N), for  N points in D dimensions

        """
        from shenfun import MixedTensorProductSpace
        from shenfun.fourier.bases import R2CBasis

        V = self.function_space()
        basis = self.basis()

        if output_array is None:
            output_array = np.zeros(x.shape[1], dtype=V.forward.input_array.dtype)
        else:
            output_array[:] = 0

        work = np.zeros_like(output_array)

        assert V.dimensions == len(x)

        for vec, (base, ind) in enumerate(zip(self.terms(), self.indices())):
            for base_j, b0 in enumerate(base):
                M = []
                sc = self.scales()[vec, base_j]
                test_sp = V
                if isinstance(V, MixedTensorProductSpace):
                    test_sp = V.flatten()[ind[base_j]]
                r2c = -1
                last_conj_index = -1
                sl = -1
                for axis, k in enumerate(b0):
                    xx = test_sp[axis].map_reference_domain(np.squeeze(x[axis]))
                    P = test_sp[axis].evaluate_basis_derivative_all(xx, k=k)
                    M.append(P[..., V.local_slice()[axis]])
                    if isinstance(test_sp[axis], R2CBasis):
                        r2c = axis
                        m = test_sp[axis].N//2+1
                        if test_sp[axis].N % 2 == 0:
                            last_conj_index = m-1
                        else:
                            last_conj_index = m
                        sl = V.local_slice()[axis].start

                bv = basis if basis.rank == 0 else basis[ind[base_j]]
                work.fill(0)
                if len(x) == 2:
                    work = evaluate.evaluate_2D(work, bv, M, r2c, last_conj_index, sl)

                elif len(x) == 3:
                    work = evaluate.evaluate_3D(work, bv, M, r2c, last_conj_index, sl)
                output_array += sc*work

        return output_array
Ejemplo n.º 2
0
    def _eval_cython(self, points, coefficients, output_array):
        """Evaluate Function at points, given expansion coefficients

        Parameters
        ----------
        points : float or array of floats
        coefficients : array
            Expansion coefficients
        output_array : array
            Return array, function values at points
        """
        P = []
        r2c = -1
        last_conj_index = -1
        sl = -1
        for base in self:
            axis = base.axis
            x = base.map_reference_domain(points[axis])
            D = base.evaluate_basis_all(x=x)
            P.append(D[..., self.local_slice()[axis]])
            if isinstance(base, R2CBasis):
                r2c = axis
                M = base.N // 2 + 1
                if base.N % 2 == 0:
                    last_conj_index = M - 1
                else:
                    last_conj_index = M
                sl = self.local_slice()[axis].start
        if len(self) == 2:
            output_array = evaluate.evaluate_2D(output_array, coefficients, P,
                                                r2c, last_conj_index, sl)

        elif len(self) == 3:
            output_array = evaluate.evaluate_3D(output_array, coefficients, P,
                                                r2c, last_conj_index, sl)

        output_array = np.atleast_1d(output_array)
        output_array = self.comm.allreduce(output_array)
        return output_array
Ejemplo n.º 3
0
    def eval(self, x, output_array=None):
        """Return expression evaluated on x

        Parameters
        ----------
        x : float or array of floats
            Array must be of shape (D, N), for  N points in D dimensions

        """
        from shenfun import MixedTensorProductSpace
        from shenfun.fourier.bases import R2CBasis

        if len(x.shape) == 1:  # 1D case
            x = x[None, :]

        V = self.function_space()
        basis = self.basis()

        if output_array is None:
            output_array = np.zeros(x.shape[1],
                                    dtype=V.forward.input_array.dtype)
        else:
            output_array[:] = 0

        work = np.zeros_like(output_array)

        assert V.dimensions == len(x)

        for vec, (base, ind) in enumerate(zip(self.terms(), self.indices())):
            for base_j, b0 in enumerate(base):
                M = []
                test_sp = V
                if isinstance(V, MixedTensorProductSpace):
                    test_sp = V.flatten()[ind[base_j]]
                r2c = -1
                last_conj_index = -1
                sl = -1
                for axis, k in enumerate(b0):
                    xx = test_sp[axis].map_reference_domain(np.squeeze(
                        x[axis]))
                    P = test_sp[axis].evaluate_basis_derivative_all(xx, k=k)
                    if not test_sp[axis].domain_factor() == 1:
                        P *= test_sp[axis].domain_factor()**(k)
                    if len(x) > 1:
                        M.append(P[..., V.local_slice()[axis]])

                    if isinstance(test_sp[axis], R2CBasis) and len(x) > 1:
                        r2c = axis
                        m = test_sp[axis].N // 2 + 1
                        if test_sp[axis].N % 2 == 0:
                            last_conj_index = m - 1
                        else:
                            last_conj_index = m
                        sl = V.local_slice()[axis].start

                bv = basis if basis.rank == 0 else basis[ind[base_j]]
                work.fill(0)
                if len(x) == 1:
                    work = np.dot(P, bv)

                elif len(x) == 2:
                    work = evaluate.evaluate_2D(work, bv, M, r2c,
                                                last_conj_index, sl)

                elif len(x) == 3:
                    work = evaluate.evaluate_3D(work, bv, M, r2c,
                                                last_conj_index, sl)

                sc = self.scales()[vec, base_j]
                if not hasattr(sc, 'free_symbols'):
                    sc = float(sc)
                else:
                    sym0 = sc.free_symbols
                    m = []
                    for sym in sym0:
                        j = 'xyzrs'.index(str(sym))
                        m.append(x[j])
                    sc = sp.lambdify(sym0, sc)(*m)
                output_array += sc * work

        return output_array