Beispiel #1
0
    def __getitem__(self, indices):
        """Return ``self[indices]``.

        Parameters
        ----------
        indices : index expression
            Object determining which parts of the grid to extract.
            `None` (new axis) and empty axes are not supported.

        Examples
        --------
        Indexing with integers along all axes produces an array (a point):

        >>> g = TensorGrid([-1, 0, 3], [2, 4], [5], [2, 4, 7])
        >>> g[0, 0, 0, 0]
        array([-1.,  2.,  5.,  2.])

        Otherwise, a new TensorGrid is returned:

        >>> g[:, 0, 0, 0]
        TensorGrid([-1.0, 0.0, 3.0], [2.0], [5.0], [2.0])
        >>> g[0, ..., 1:]
        TensorGrid([-1.0], [2.0, 4.0], [5.0], [4.0, 7.0])
        >>> g[::2, ..., ::2]
        TensorGrid([-1.0, 3.0], [2.0, 4.0], [5.0], [2.0, 7.0])

        Too few indices are filled up with an ellipsis from the right:

        >>> g[0]
        TensorGrid([-1.0], [2.0, 4.0], [5.0], [2.0, 4.0, 7.0])
        >>> g[0] == g[0, :, :, :] == g[0, ...]
        True
        """
        if isinstance(indices, list):
            new_coord_vecs = [self.coord_vectors[0][indices]]
            new_coord_vecs += self.coord_vectors[1:]
            return TensorGrid(*new_coord_vecs)

        indices = normalized_index_expression(indices,
                                              self.shape,
                                              int_to_slice=False)

        # If all indices are integers, return an array (a point). Otherwise,
        # create a new grid.
        if all(np.isscalar(idx) for idx in indices):
            return np.fromiter(
                (v[int(idx)] for idx, v in zip(indices, self.coord_vectors)),
                dtype=float)
        else:
            new_coord_vecs = [
                vec[idx] for idx, vec in zip(indices, self.coord_vectors)
            ]
            return TensorGrid(*new_coord_vecs)
Beispiel #2
0
    def __getitem__(self, indices):
        """Return ``self[indices]``.

        Parameters
        ----------
        indices : index expression
            Object determining which parts of the grid to extract.
            `None` (new axis) and empty axes are not supported.

        Examples
        --------
        Indexing with integers along all axes produces an array (a point):

        >>> g = TensorGrid([-1, 0, 3], [2, 4], [5], [2, 4, 7])
        >>> g[0, 0, 0, 0]
        array([-1.,  2.,  5.,  2.])

        Otherwise, a new TensorGrid is returned:

        >>> g[:, 0, 0, 0]
        TensorGrid([-1.0, 0.0, 3.0], [2.0], [5.0], [2.0])
        >>> g[0, ..., 1:]
        TensorGrid([-1.0], [2.0, 4.0], [5.0], [4.0, 7.0])
        >>> g[::2, ..., ::2]
        TensorGrid([-1.0, 3.0], [2.0, 4.0], [5.0], [2.0, 7.0])

        Too few indices are filled up with an ellipsis from the right:

        >>> g[0]
        TensorGrid([-1.0], [2.0, 4.0], [5.0], [2.0, 4.0, 7.0])
        >>> g[0] == g[0, :, :, :] == g[0, ...]
        True
        """
        if isinstance(indices, list):
            new_coord_vecs = [self.coord_vectors[0][indices]]
            new_coord_vecs += self.coord_vectors[1:]
            return TensorGrid(*new_coord_vecs)

        indices = normalized_index_expression(indices, self.shape,
                                              int_to_slice=False)

        # If all indices are integers, return an array (a point). Otherwise,
        # create a new grid.
        if all(np.isscalar(idx) for idx in indices):
            return np.fromiter(
                (v[int(idx)] for idx, v in zip(indices, self.coord_vectors)),
                dtype=float)
        else:
            new_coord_vecs = [vec[idx]
                              for idx, vec in zip(indices, self.coord_vectors)]
            return TensorGrid(*new_coord_vecs)
Beispiel #3
0
    def __getitem__(self, indices):
        """Return ``self[indices]``.

        Parameters
        ----------
        indices : index expression
            Object determining which parts of the partition to extract.
            `None` (new axis) and empty axes are not supported.

        Examples
        --------
        >>> intvp = IntervalProd([-1, 1, 4, 2], [3, 6, 5, 7])
        >>> grid = TensorGrid([-1, 0, 3], [2, 4], [5], [2, 4, 7])
        >>> part = RectPartition(intvp, grid)
        >>> part.cell_boundary_vecs
        (array([-1. , -0.5,  1.5,  3. ]),
         array([ 1.,  3.,  6.]),
         array([ 4.,  5.]),
         array([ 2. ,  3. ,  5.5,  7. ]))

        Indexing picks out sub-intervals (compare with the boundary
        vectors):

        >>> part[0, 0, 0, 0]
        RectPartition(
            IntervalProd([-1.0, 1.0, 4.0, 2.0], [-0.5, 3.0, 5.0, 3.0]),
            TensorGrid([-1.0], [2.0], [5.0], [2.0]))

        Taking an advanced slice (every second along the first axis,
        the last in the last axis and everything in between):

        >>> part[::2, ..., -1]
        RectPartition(
            IntervalProd([-1.0, 1.0, 4.0, 5.5], [3.0, 6.0, 5.0, 7.0]),
            TensorGrid([-1.0, 3.0], [2.0, 4.0], [5.0], [7.0]))

        Too few indices are filled up with an ellipsis from the right:

        >>> part[1]
        RectPartition(
            IntervalProd([-0.5, 1.0, 4.0, 2.0], [1.5, 6.0, 5.0, 7.0]),
            TensorGrid([0.0], [2.0, 4.0], [5.0], [2.0, 4.0, 7.0]))
        """
        # Special case of index list: slice along first axis
        if isinstance(indices, list):
            new_begin = [self.cell_boundary_vecs[0][:-1][indices][0]]
            new_end = [self.cell_boundary_vecs[0][1:][indices][-1]]
            for cvec in self.cell_boundary_vecs[1:]:
                new_begin.append(cvec[0])
                new_end.append(cvec[-1])

            new_intvp = IntervalProd(new_begin, new_end)
            new_grid = self.grid[indices]
            return RectPartition(new_intvp, new_grid)

        indices = normalized_index_expression(indices, self.shape,
                                              int_to_slice=True)
        # Build the new partition
        new_begin, new_end = [], []
        for cvec, idx in zip(self.cell_boundary_vecs, indices):
            # Determine the subinterval begin and end vectors. Take the
            # first begin as new begin and the last end as new end.
            sub_begin = cvec[:-1][idx]
            sub_end = cvec[1:][idx]
            new_begin.append(sub_begin[0])
            new_end.append(sub_end[-1])

        new_intvp = IntervalProd(new_begin, new_end)
        new_grid = self.grid[indices]
        return RectPartition(new_intvp, new_grid)
Beispiel #4
0
    def __getitem__(self, indices):
        """Return ``self[indices]``.

        Parameters
        ----------
        indices : index expression
            Object determining which parts of the grid to extract.
            `None` (new axis) and empty axes are not supported.

        Examples
        --------
        Indexing with integers along all axes produces an array (a point):

        >>> g = RegularGrid([-1.5, -3, -1], [-0.5, 7, 4], (2, 3, 6))
        >>> g[0, 0, 0]
        array([-1.5, -3. , -1. ])

        Otherwise, a new RegularGrid is returned:

        >>> g[:, 0, 0]
        RegularGrid([-1.5, -3.0, -1.0], [-0.5, -3.0, -1.0], (2, 1, 1))

        Ellipsis can be used, too:

        >>> g[..., ::3]
        RegularGrid([-1.5, -3.0, -1.0], [-0.5, 7.0, 2.0], (2, 3, 2))
        """
        # Index list results in a tensor grid
        if isinstance(indices, list):
            return super().__getitem__(indices)

        indices = normalized_index_expression(indices,
                                              self.shape,
                                              int_to_slice=False)

        # If all indices are integers, return an array (a point). Otherwise,
        # create a new grid.
        if all(np.isscalar(idx) for idx in indices):
            return np.fromiter(
                (v[int(idx)] for idx, v in zip(indices, self.coord_vectors)),
                dtype=float)
        else:
            new_minpt = []
            new_maxpt = []
            new_shape = []

            for idx, minval, maxval, n, cvec in zip(indices, self.min_pt,
                                                    self.max_pt, self.shape,
                                                    self.coord_vectors):
                if np.isscalar(idx):
                    idx = slice(idx, idx + 1)

                if idx == slice(None):  # Take all along this axis
                    new_minpt.append(minval)
                    new_maxpt.append(maxval)
                    new_shape.append(n)
                else:  # Slice
                    istart, istop, istep = idx.indices(n)

                    if istart == istop:
                        num = 1
                        last = istart
                    else:
                        num = int(np.ceil((istop - istart) / istep))
                        last = istart + (num - 1) * istep

                    new_minpt.append(cvec[istart])
                    new_maxpt.append(cvec[last])
                    new_shape.append(num)

            return RegularGrid(new_minpt, new_maxpt, new_shape)
Beispiel #5
0
    def __getitem__(self, indices):
        """Return ``self[indices]``.

        Parameters
        ----------
        indices : index expression
            Object determining which parts of the grid to extract.
            `None` (new axis) and empty axes are not supported.

        Examples
        --------
        Indexing with integers along all axes produces an array (a point):

        >>> g = RegularGrid([-1.5, -3, -1], [-0.5, 7, 4], (2, 3, 6))
        >>> g[0, 0, 0]
        array([-1.5, -3. , -1. ])

        Otherwise, a new RegularGrid is returned:

        >>> g[:, 0, 0]
        RegularGrid([-1.5, -3.0, -1.0], [-0.5, -3.0, -1.0], (2, 1, 1))

        Ellipsis can be used, too:

        >>> g[..., ::3]
        RegularGrid([-1.5, -3.0, -1.0], [-0.5, 7.0, 2.0], (2, 3, 2))
        """
        # Index list results in a tensor grid
        if isinstance(indices, list):
            return super().__getitem__(indices)

        indices = normalized_index_expression(indices, self.shape,
                                              int_to_slice=False)

        # If all indices are integers, return an array (a point). Otherwise,
        # create a new grid.
        if all(np.isscalar(idx) for idx in indices):
            return np.fromiter(
                (v[int(idx)] for idx, v in zip(indices, self.coord_vectors)),
                dtype=float)
        else:
            new_minpt = []
            new_maxpt = []
            new_shape = []

            for idx, minval, maxval, n, cvec in zip(
                    indices, self.min_pt, self.max_pt, self.shape,
                    self.coord_vectors):
                if np.isscalar(idx):
                    idx = slice(idx, idx + 1)

                if idx == slice(None):  # Take all along this axis
                    new_minpt.append(minval)
                    new_maxpt.append(maxval)
                    new_shape.append(n)
                else:  # Slice
                    istart, istop, istep = idx.indices(n)

                    if istart == istop:
                        num = 1
                        last = istart
                    else:
                        num = int(np.ceil((istop - istart) / istep))
                        last = istart + (num - 1) * istep

                    new_minpt.append(cvec[istart])
                    new_maxpt.append(cvec[last])
                    new_shape.append(num)

            return RegularGrid(new_minpt, new_maxpt, new_shape)
Beispiel #6
0
    def __getitem__(self, indices):
        """Return ``self[indices]``.

        Parameters
        ----------
        indices : index expression
            Object determining which parts of the partition to extract.
            `None` (new axis) and empty axes are not supported.

        Examples
        --------
        >>> intvp = IntervalProd([-1, 1, 4, 2], [3, 6, 5, 7])
        >>> grid = TensorGrid([-1, 0, 3], [2, 4], [5], [2, 4, 7])
        >>> part = RectPartition(intvp, grid)
        >>> part.cell_boundary_vecs
        (array([-1. , -0.5,  1.5,  3. ]),
         array([ 1.,  3.,  6.]),
         array([ 4.,  5.]),
         array([ 2. ,  3. ,  5.5,  7. ]))

        Indexing picks out sub-intervals (compare with the boundary
        vectors):

        >>> part[0, 0, 0, 0]
        RectPartition(
            IntervalProd([-1.0, 1.0, 4.0, 2.0], [-0.5, 3.0, 5.0, 3.0]),
            TensorGrid([-1.0], [2.0], [5.0], [2.0]))

        Taking an advanced slice (every second along the first axis,
        the last in the last axis and everything in between):

        >>> part[::2, ..., -1]
        RectPartition(
            IntervalProd([-1.0, 1.0, 4.0, 5.5], [3.0, 6.0, 5.0, 7.0]),
            TensorGrid([-1.0, 3.0], [2.0, 4.0], [5.0], [7.0]))

        Too few indices are filled up with an ellipsis from the right:

        >>> part[1]
        RectPartition(
            IntervalProd([-0.5, 1.0, 4.0, 2.0], [1.5, 6.0, 5.0, 7.0]),
            TensorGrid([0.0], [2.0, 4.0], [5.0], [2.0, 4.0, 7.0]))
        """
        # Special case of index list: slice along first axis
        if isinstance(indices, list):
            new_begin = [self.cell_boundary_vecs[0][:-1][indices][0]]
            new_end = [self.cell_boundary_vecs[0][1:][indices][-1]]
            for cvec in self.cell_boundary_vecs[1:]:
                new_begin.append(cvec[0])
                new_end.append(cvec[-1])

            new_intvp = IntervalProd(new_begin, new_end)
            new_grid = self.grid[indices]
            return RectPartition(new_intvp, new_grid)

        indices = normalized_index_expression(indices,
                                              self.shape,
                                              int_to_slice=True)
        # Build the new partition
        new_begin, new_end = [], []
        for cvec, idx in zip(self.cell_boundary_vecs, indices):
            # Determine the subinterval begin and end vectors. Take the
            # first begin as new begin and the last end as new end.
            sub_begin = cvec[:-1][idx]
            sub_end = cvec[1:][idx]
            new_begin.append(sub_begin[0])
            new_end.append(sub_end[-1])

        new_intvp = IntervalProd(new_begin, new_end)
        new_grid = self.grid[indices]
        return RectPartition(new_intvp, new_grid)