Exemple #1
0
def interval_approximate_nd(f, a, b, degs):
    """Finds the chebyshev approximation of an n-dimensional function on an interval.
    
    Parameters
    ----------
    f : function from R^n -> R
        The function to interpolate.
    a : numpy array
        The lower bound on the interval.
    b : numpy array
        The upper bound on the interval.
    deg : numpy array
        The degree of the interpolation in each dimension.
    
    Returns
    -------
    coeffs : numpy array
        The coefficient of the chebyshev interpolating polynomial.
    """
    if len(a) != len(b):
        raise ValueError("Interval dimensions must be the same!")
    dim = len(a)

    def get_cheb_spot(k, n):
        return np.cos(np.pi * k / n)

    values = np.zeros(2 * degs)

    cheb_spots = list()
    for spot, val in np.ndenumerate(values):
        cheb_spots.append(
            transform([get_cheb_spot(spot[i], degs[i]) for i in range(dim)], a,
                      b))
    vals = f(cheb_spots)
    i = 0
    for spot, val in np.ndenumerate(values):
        values[spot] = vals[i]
        i += 1

    coeffs = np.real(fftn(values / np.product(degs)))

    for i in range(dim):
        idx0 = [slice(None)] * (dim)
        idx0[i] = 0
        idx00 = [slice(None)] * (dim)
        idx00[i] = degs[i]
        coeffs[idx0] = coeffs[idx0] / 2
        coeffs[idx00] = coeffs[idx00] / 2

    slices = list()
    for i in range(dim):
        slices.append(slice(0, degs[i] + 1))

    return coeffs[slices]
def proj_approximate_nd(f,transform):
    """Finds the chebyshev approximation of an n-dimensional function on the
    affine transformation of hypercube.

    Parameters
    ----------
    f : function from R^n -> R
        The function to project by interpolating.
    transform : function from R^(n-1) -> R^n
        The affine function mapping the hypercube to the desired space.

    Returns
    -------
    coeffs : numpy array
        The coefficient of the chebyshev interpolating polynomial.
    """
    dim = f.dim
    proj_dim = dim-1
    deg = f.degree
    degs = np.array([deg]*proj_dim)

    # assert hasattr(f,"evaluate_grid")
    # dang, we don't get to use evaluate_grid here

    cheb_values = np.cos(np.arange(deg+1)*np.pi/deg)
    cheb_grids = np.meshgrid(*([cheb_values]*proj_dim), indexing='ij')

    flatten = lambda x: x.flatten()
    cheb_points = transform(np.column_stack(map(flatten, cheb_grids)))
    values_block = f(cheb_points).reshape(*([deg+1]*proj_dim))
    values = chebyshev_block_copy(values_block)
    coeffs = np.real(fftn(values/np.product(degs)))

    for i in range(proj_dim):
        #construct slices for the first and degs[i] entry in each dimension
        idx0 = [slice(None)] * proj_dim
        idx0[i] = 0

        idx_deg = [slice(None)] * proj_dim
        idx_deg[i] = degs[i]

        #halve the coefficients in each slice
        coeffs[tuple(idx0)] /= 2
        coeffs[tuple(idx_deg)] /= 2

    slices = []
    for i in range(proj_dim):
        slices.append(slice(0,degs[i]+1))

    return trim_coeff(coeffs[tuple(slices)])
Exemple #3
0
 def reference_fftn(self, a, axes):
     return np_fft.fftn(a, axes=axes)
 def reference_fftn(self, a, axes):
     return np_fft.fftn(a, axes=axes)
Exemple #5
0
def interval_approximate_nd(f, a, b, degs):
    """Finds the chebyshev approximation of an n-dimensional function on an interval.

    Parameters
    ----------
    f : function from R^n -> R
        The function to interpolate.
    a : numpy array
        The lower bound on the interval.
    b : numpy array
        The upper bound on the interval.
    deg : numpy array
        The degree of the interpolation in each dimension.

    Returns
    -------
    coeffs : numpy array
        The coefficient of the chebyshev interpolating polynomial.
    """
    if len(a) != len(b):
        raise ValueError("Interval dimensions must be the same!")

    dim = len(a)
    deg = degs[0]

    if hasattr(f, "evaluate_grid"):
        #for polynomials, we can quickly evaluate all points in a grid
        #xyz does not contain points, but the nth column of xyz has the values needed
        #along the nth axis. The direct product of these values procuces the grid
        cheb_values = np.cos(np.arange(deg + 1) * np.pi / deg)
        xyz = transform(np.column_stack([cheb_values] * dim), a, b)
        values_block = f.evaluate_grid(xyz)

    else:
        #if function f has no "evaluate_grid" method,
        #we evaluate each point individually
        cheb_values = np.cos(np.arange(deg + 1) * np.pi / deg)
        cheb_grids = np.meshgrid(*([cheb_values] * dim), indexing='ij')

        flatten = lambda x: x.flatten()
        cheb_points = transform(np.column_stack(map(flatten, cheb_grids)), a,
                                b)
        values_block = f(cheb_points).reshape(*([deg + 1] * dim))

    values = chebyshev_block_copy(values_block)
    coeffs = np.real(fftn(values / np.product(degs)))

    for i in range(dim):
        #construct slices for the first and degs[i] entry in each dimension
        idx0 = [slice(None)] * dim
        idx0[i] = 0

        idx_deg = [slice(None)] * dim
        idx_deg[i] = degs[i]

        #halve the coefficients in each slice
        coeffs[idx0] /= 2
        coeffs[idx_deg] /= 2

    slices = []
    for i in range(dim):
        slices.append(slice(0, degs[i] + 1))

    return coeffs[slices]