예제 #1
0
def eval_func(
    func_val,
    pos,
    dim,
    mesh_type="unstructured",
    value_type="scalar",
    broadcast=False,
):
    """
    Evaluate a function on a mesh.

    Parameters
    ----------
    func_val : :any:`callable` or :class:`float` or :any:`None`
        Function to be called or single value to be filled.
        Should have the signiture f(x, [y, z, ...]) in case of callable.
        In case of a float, the field will be filled with a single value and
        in case of None, this value will be set to 0.
    pos : :class:`list`
        The position tuple, containing main direction and transversal
        directions (x, [y, z, ...]).
    dim : :class:`int`
        The spatial dimension.
    mesh_type : :class:`str`, optional
        'structured' / 'unstructured'
        Default: 'unstructured'
    value_type : :class:`str`, optional
        Value type of the field. Either "scalar" or "vector".
        The default is "scalar".
    broadcast : :class:`bool`, optional
        Whether to return a single value, if a single value was given.
        Default: False

    Returns
    -------
    :class:`numpy.ndarray`
        Function values at the given points.
    """
    # care about scalar inputs
    func_val = 0 if func_val is None else func_val
    if broadcast and not callable(func_val) and np.size(func_val) == 1:
        return np.array(func_val, dtype=np.double).item()
    if not callable(func_val):
        func_val = _func_from_single_val(func_val, dim, value_type=value_type)
    # care about mesh and function call
    if mesh_type != "unstructured":
        pos, shape = format_struct_pos_dim(pos, dim)
        pos = generate_grid(pos)
    else:
        pos = np.array(pos, dtype=np.double).reshape(dim, -1)
        shape = np.shape(pos[0])
    # prepend dimension if we have a vector field
    if value_type == "vector":
        shape = (dim,) + shape
    return np.reshape(func_val(*pos), shape)
예제 #2
0
 def pos(self, pos):
     if self.mesh_type == "unstructured":
         self._pos = np.asarray(pos, dtype=np.double).reshape(self.dim, -1)
         self._field_shape = np.shape(self._pos[0])
     else:
         self._pos, self._field_shape = format_struct_pos_dim(pos, self.dim)
     # prepend dimension if we have a vector field
     if self.value_type == "vector":
         self._field_shape = (self.dim,) + self._field_shape
         if self.latlon:
             raise ValueError("Field: Vector fields not allowed for latlon")
예제 #3
0
    def pre_pos(self, pos, mesh_type="unstructured"):
        """
        Preprocessing positions and mesh_type.

        Parameters
        ----------
        pos : :any:`iterable`
            the position tuple, containing main direction and transversal
            directions
        mesh_type : :class:`str`, optional
            'structured' / 'unstructured'
            Default: `"unstructured"`

        Returns
        -------
        iso_pos : (d, n), :class:`numpy.ndarray`
            the isometrized position tuple
        shape : :class:`tuple`
            Shape of the resulting field.
        """
        # save mesh-type
        self.mesh_type = mesh_type
        # save pos tuple
        if mesh_type != "unstructured":
            pos, shape = format_struct_pos_dim(pos, self.model.dim)
            self.pos = pos
            pos = gen_mesh(pos)
        else:
            pos = np.array(pos, dtype=np.double).reshape(self.model.dim, -1)
            self.pos = pos
            shape = np.shape(pos[0])
        # prepend dimension if we have a vector field
        if self.value_type == "vector":
            shape = (self.model.dim, ) + shape
        # return isometrized pos tuple and resulting field shape
        return self.model.isometrize(pos), shape
예제 #4
0
def standard_bins(
    pos=None,
    dim=2,
    latlon=False,
    mesh_type="unstructured",
    bin_no=None,
    max_dist=None,
):
    r"""
    Get standard binning.

    Parameters
    ----------
    pos : :class:`list`, optional
        the position tuple, containing either the point coordinates (x, y, ...)
        or the axes descriptions (for mesh_type='structured')
    dim : :class:`int`, optional
        Field dimension.
    latlon : :class:`bool`, optional
        Whether the data is representing 2D fields on earths surface described
        by latitude and longitude. When using this, the estimator will
        use great-circle distance for variogram estimation.
        Note, that only an isotropic variogram can be estimated and a
        ValueError will be raised, if a direction was specified.
        Bin edges need to be given in radians in this case.
        Default: False
    mesh_type : :class:`str`, optional
        'structured' / 'unstructured', indicates whether the pos tuple
        describes the axis or the point coordinates.
        Default: `'unstructured'`
    bin_no: :class:`int`, optional
        number of bins to create. If None is given, will be determined by
        Sturges' rule from the number of points.
        Default: None
    max_dist: :class:`float`, optional
        Cut of length for the bins. If None is given, it will be set to one
        third of the box-diameter from the given points.
        Default: None

    Returns
    -------
    :class:`numpy.ndarray`
        The generated bin edges.

    Notes
    -----
    Internally uses double precision and also returns doubles.
    """
    dim = 2 if latlon else int(dim)
    if bin_no is None or max_dist is None:
        if pos is None:
            raise ValueError("standard_bins: no pos tuple given.")
        if mesh_type != "unstructured":
            pos = generate_grid(format_struct_pos_dim(pos, dim)[0])
        else:
            pos = np.asarray(pos, dtype=np.double).reshape(dim, -1)
        pos = latlon2pos(pos) if latlon else pos
        pnt_cnt = len(pos[0])
        box = []
        for axis in pos:
            box.append([np.min(axis), np.max(axis)])
        box = np.asarray(box)
        diam = np.linalg.norm(box[:, 0] - box[:, 1])
        # convert diameter to great-circle distance if using latlon
        diam = chordal_to_great_circle(diam) if latlon else diam
        bin_no = _sturges(pnt_cnt) if bin_no is None else int(bin_no)
        max_dist = diam / 3 if max_dist is None else float(max_dist)
    return np.linspace(0, max_dist, num=bin_no + 1, dtype=np.double)