Source code for pyinterp.interpolator.bicubic

# Copyright (c) 2024 CNES
#
# All rights reserved. Use of this source code is governed by a
# BSD-style license that can be found in the LICENSE file.
"""
Bicubic interpolation
=====================
"""
from __future__ import annotations

import numpy

from .. import core, grid, interface


[docs] def bicubic(mesh: grid.Grid2D | grid.Grid3D | grid.Grid4D, x: numpy.ndarray, y: numpy.ndarray, z: numpy.ndarray | None = None, u: numpy.ndarray | None = None, nx: int = 3, ny: int = 3, fitting_model: str = 'bicubic', boundary: str = 'undef', bounds_error: bool = False, num_threads: int = 0) -> numpy.ndarray: """Bicubic gridded interpolator. Args: mesh: Function on a uniform grid to be interpolated. If the grid is a grid in N-D space, the bicubic interpolation is performed spatially along the X and Y axes of the N-D grid and a linear interpolation are performed along the other axes between the values obtained by the bicubic interpolation. x: X-values. y: Y-values. z: None for a :py:class:`2D Grid <pyinterp.grid.Grid2D>` otherwise Z-values. u: None for a :py:class:`2D Grid <pyinterp.grid.Grid2D>`, :py:class:`3D Grid <pyinterp.grid.Grid3D>` otherwise U-values. nx: The number of X-coordinate values required to perform the interpolation. Defaults to ``3``. ny: The number of Y-coordinate values required to perform the interpolation. Defaults to ``3``. fitting_model: Type of interpolation to be performed. Supported are ``linear``, ``bicubic``, ``polynomial``, ``c_spline``, ``c_spline_periodic``, ``akima``, ``akima_periodic`` and ``steffen``. Default to ``bicubic``. boundary: A flag indicating how to handle boundaries of the frame. * ``expand``: Expand the boundary as a constant. * ``wrap``: circular boundary conditions. * ``sym``: Symmetrical boundary conditions. * ``undef``: Boundary violation is not defined. Default ``undef``. bounds_error: If True, when interpolated values are requested outside of the domain of the input axes (x,y), a :py:class:`ValueError` is raised. If False, then the value is set to NaN. Default to ``False``. num_threads: The number of threads to use for the computation. If 0 all CPUs are used. If 1 is given, no parallel computing code is used at all, which is useful for debugging. Defaults to ``0``. Returns: Values interpolated. """ if not mesh.x.is_ascending(): raise ValueError('X-axis is not increasing') if not mesh.y.is_ascending(): raise ValueError('Y-axis is not increasing') if fitting_model not in [ 'akima_periodic', 'akima', 'bicubic', 'c_spline_periodic', 'c_spline', 'linear', 'polynomial', 'steffen' ]: raise ValueError(f'fitting model {fitting_model!r} is not defined') if boundary not in ['expand', 'wrap', 'sym', 'undef']: raise ValueError(f'boundary {boundary!r} is not defined') instance = mesh._instance function = interface._core_function( 'bicubic' if fitting_model == 'bicubic' else 'spline', instance) args = [ instance, numpy.asarray(x), numpy.asarray(y), nx, ny, fitting_model, boundary, bounds_error, num_threads ] if isinstance(mesh, (grid.Grid3D, grid.Grid4D)): if z is None: raise ValueError( f'You must specify the Z-values for a {mesh._DIMENSIONS}D ' 'grid.') args.insert(3, numpy.asarray(z)) if isinstance(mesh, grid.Grid4D): if u is None: raise ValueError('You must specify the U-values for a 4D grid.') args.insert(4, numpy.asarray(u)) return getattr(core, function)(*args)