Mercurial > octave
view scripts/plot/draw/reducevolume.m @ 30564:796f54d4ddbf stable
update Octave Project Developers copyright for the new year
In files that have the "Octave Project Developers" copyright notice,
update for 2021.
In all .txi and .texi files except gpl.txi and gpl.texi in the
doc/liboctave and doc/interpreter directories, change the copyright
to "Octave Project Developers", the same as used for other source
files. Update copyright notices for 2022 (not done since 2019). For
gpl.txi and gpl.texi, change the copyright notice to be "Free Software
Foundation, Inc." and leave the date at 2007 only because this file
only contains the text of the GPL, not anything created by the Octave
Project Developers.
Add Paul Thomas to contributors.in.
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Tue, 28 Dec 2021 18:22:40 -0500 |
parents | 628f26e122d9 |
children | 597f3ee61a48 |
line wrap: on
line source
######################################################################## ## ## Copyright (C) 2016-2022 The Octave Project Developers ## ## See the file COPYRIGHT.md in the top-level directory of this ## distribution or <https://octave.org/copyright/>. ## ## This file is part of Octave. ## ## Octave is free software: you can redistribute it and/or modify it ## under the terms of the GNU General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Octave is distributed in the hope that it will be useful, but ## WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with Octave; see the file COPYING. If not, see ## <https://www.gnu.org/licenses/>. ## ######################################################################## ## -*- texinfo -*- ## @deftypefn {} {[@var{nx}, @var{ny}, @var{nz}, @var{nv}] =} reducevolume (@var{v}, @var{r}) ## @deftypefnx {} {[@var{nx}, @var{ny}, @var{nz}, @var{nv}] =} reducevolume (@var{x}, @var{y}, @var{z}, @var{v}, @var{r}) ## @deftypefnx {} {@var{nv} =} reducevolume (@dots{}) ## ## Reduce the volume of the dataset in @var{v} according to the values in ## @var{r}. ## ## @var{v} is a matrix that is non-singleton in the first 3 dimensions. ## ## @var{r} can either be a vector of 3 elements representing the reduction ## factors in the x-, y-, and z-directions or a scalar, in which case the same ## reduction factor is used in all three dimensions. ## ## @code{reducevolume} reduces the number of elements of @var{v} by taking ## only every @var{r}-th element in the respective dimension. ## ## Optionally, @var{x}, @var{y}, and @var{z} can be supplied to represent the ## set of coordinates of @var{v}. They can either be matrices of the same size ## as @var{v} or vectors with sizes according to the dimensions of @var{v}, in ## which case they are expanded to matrices ## (@pxref{XREFmeshgrid,,@code{meshgrid}}). ## ## If @code{reducevolume} is called with two arguments then @var{x}, @var{y}, ## and @var{z} are assumed to match the respective indices of @var{v}. ## ## The reduced matrix is returned in @var{nv}. ## ## Optionally, the reduced set of coordinates are returned in @var{nx}, ## @var{ny}, and @var{nz}, respectively. ## ## Examples: ## ## @example ## @group ## @var{v} = reshape (1:6*8*4, [6 8 4]); ## @var{nv} = reducevolume (@var{v}, [4 3 2]); ## @end group ## @end example ## ## @example ## @group ## @var{v} = reshape (1:6*8*4, [6 8 4]); ## @var{x} = 1:3:24; @var{y} = -14:5:11; @var{z} = linspace (16, 18, 4); ## [@var{nx}, @var{ny}, @var{nz}, @var{nv}] = reducevolume (@var{x}, @var{y}, @var{z}, @var{v}, [4 3 2]); ## @end group ## @end example ## ## @seealso{isosurface, isonormals} ## @end deftypefn function [nx, ny, nz, nv] = reducevolume (varargin) if (nargin < 2 || nargin > 5) print_usage (); endif [x, y, z, v, r] = __get_check_reducevolume_args__ (nargout, varargin{:}); [nx, ny, nz, nv] = __reducevolume__ (x, y, z, v, r); if (nargout <= 1) nx = nv; endif endfunction function [x, y, z, v, r] = __get_check_reducevolume_args__ (naout, varargin) x = y = z = []; switch (nargin) case 3 v = varargin{1}; r = varargin{2}; case 6 if (naout == 4) x = varargin{1}; y = varargin{2}; z = varargin{3}; endif v = varargin{4}; r = varargin{5}; otherwise error ("reducevolume: incorrect number of arguments"); endswitch ## Check reduction values R if (isscalar (r)) r = [r, r, r]; elseif (numel (r) != 3) error (["reducevolume: reduction value R must be a scalar or " ... "a vector of length 3"]); endif if (any (r < 1 | r != fix (r))) error ("reducevolume: reduction values R must be positive integers"); endif ## Check dimensions of data if (ndims (v) < 3) error ("reducevolume: data V must have at least 3 dimensions"); endif v_sz = size (v); if (any (v_sz(1:3) < 2)) error ("reducevolume: data must be a non-singleton 3-dimensional matrix"); endif if (naout == 4) if (isempty (x)) x = 1:columns (v); endif if (isempty (y)) y = 1:rows (v); endif if (isempty (z)) z = 1:size (v, 3); endif ## check x if (isvector (x) && length (x) == v_sz(2)) x = repmat (x(:)', [v_sz(1) 1 v_sz(3)]); elseif (! size_equal (v, x)) error ("reducevolume: X must match the size of data V"); endif ## check y if (isvector (y) && length (y) == v_sz(1)) y = repmat (y(:), [1 v_sz(2) v_sz(3)]); elseif (! size_equal (v, y)) error ("reducevolume: Y must match the size of data V"); endif ## check z if (isvector (z) && length (z) == v_sz(3)) z = repmat (reshape (z(:), [1 1 length(z)]), ... [v_sz(1) v_sz(2) 1]); elseif (! size_equal (v, z)) error ("reducevolume: Z must match the size of data V"); endif endif endfunction function [nx, ny, nz, nv] = __reducevolume__ (x, y, z, v, r) v_sz = size (v); nv = v(1:r(2):end, 1:r(1):end, 1:r(3):end, :); nv_sz = size (nv); if (length (nv_sz) < 3 || min (nv_sz) < 2) error ("reducevolume: reduction value R is too high"); endif if (length (v_sz) > 3) nv = reshape (nv, [nv_sz(1:3) v_sz(4:end)]); endif if (isempty (x)) nx = ny = nz = []; else nx = x(1:r(2):end, 1:r(1):end, 1:r(3):end); ny = y(1:r(2):end, 1:r(1):end, 1:r(3):end); nz = z(1:r(2):end, 1:r(1):end, 1:r(3):end); endif endfunction %!shared v, x, y, z, xx, yy, zz %! v = reshape (1:6*8*4, [6 8 4]); %! x = 1:3:22; y = -14:5:11; z = linspace (16, 18, 4); %! [xx, yy, zz] = meshgrid (x, y, z); ## two inputs, one output %!test %! nv = reducevolume (v, [4 3 2]); %! nv_expected = [1 25; 4 28]; nv_expected(:,:,2) = [97 121; 100 124]; %! assert (nv, nv_expected); ## two inputs, four outputs %!test %! [nx, ny, nz, nv] = reducevolume (v, [4 3 2]); %! nx_expected(1:2,1,1:2) = 1; nx_expected(:,2,:) = 5; %! ny_expected(1,1:2,1:2) = 1; ny_expected(2,:,:) = 4; %! nz_expected(1:2,1:2,1) = 1; nz_expected(:,:,2) = 3; %! nv_expected = [1 25; 4 28]; nv_expected(:,:,2) = [97 121; 100 124]; %! assert (nx, nx_expected); %! assert (ny, ny_expected); %! assert (nz, nz_expected); %! assert (nv, nv_expected); ## five inputs, one output %!test %! nv = reducevolume (x, y, z, v, [4 3 2]); %! nv_expected = [1 25; 4 28]; nv_expected(:,:,2) = [97 121; 100 124]; %! assert (nv, nv_expected); ## five inputs, four outputs (coordinates are vectors) %!test %! [nx, ny, nz, nv] = reducevolume (x, y, z, v, [4 3 2]); %! nx_expected(1:2,1,1:2) = x(1); nx_expected(:,2,:) = x(5); %! ny_expected(1,1:2,1:2) = y(1); ny_expected(2,:,:) = y(4); %! nz_expected(1:2,1:2,1) = z(1); nz_expected(:,:,2) = z(3); %! nv_expected = [1 25; 4 28]; nv_expected(:,:,2) = [97 121; 100 124]; %! assert (nx, nx_expected); %! assert (ny, ny_expected); %! assert (nz, nz_expected); %! assert (nv, nv_expected); ## five inputs, four outputs (coordinates are matrices) %!test %! [nx, ny, nz, nv] = reducevolume (xx, yy, zz, v, [4 3 2]); %! nx_expected(1:2,1,1:2) = x(1); nx_expected(:,2,:) = x(5); %! ny_expected(1,1:2,1:2) = y(1); ny_expected(2,:,:) = y(4); %! nz_expected(1:2,1:2,1) = z(1); nz_expected(:,:,2) = z(3); %! nv_expected = [1 25; 4 28]; nv_expected(:,:,2) = [97 121; 100 124]; %! assert (nx, nx_expected); %! assert (ny, ny_expected); %! assert (nz, nz_expected); %! assert (nv, nv_expected); ## five inputs, four outputs (coordinates are matrices, R is scalar) %!test %! [nx, ny, nz, nv] = reducevolume (xx, yy, zz, v, 3); %! nx_expected(1:2,1,1:2) = x(1); nx_expected(:,2,:) = x(4); %! nx_expected(:,3,:) = x(7); %! ny_expected(1,1:3,1:2) = y(1); ny_expected(2,:,:) = y(4); %! nz_expected(1:2,1:3,1) = z(1); nz_expected(:,:,2) = z(4); %! nv_expected = [1 19 37; 4 22 40]; %! nv_expected(:,:,2) = [145 163 181; 148 166 184]; %! assert (nx, nx_expected); %! assert (ny, ny_expected); %! assert (nz, nz_expected); %! assert (nv, nv_expected); ## Test for each error %!test %!error <Invalid call> reducevolume () %!error <Invalid call> reducevolume (1) %!error <Invalid call> reducevolume (1,2,3,4,5,6) %!error <incorrect number of arguments> reducevolume (1, 2, 3) %!error <R must be a scalar or a vector of length 3> reducevolume (v, []) %!error <R must be a scalar or a vector of length 3> reducevolume (v, [1 2]) %!error <reduction values R must be positive integers> reducevolume (v, 0) %!error <reduction values R must be positive integers> reducevolume (v, 1.5) %!error <data V must have at least 3 dimensions> %! v = reshape(1:6*8, [6 8]); %! [nv] = reducevolume (v, [4 3 2]); %!error <data must be a non-singleton 3-dimensional matrix> %! v = reshape(1:6*8, [6 1 8]); %! nv = reducevolume (v, [4 3 2]); %!error <X must match the size of data V> %! x = 1:2:24; %! [nx, ny, nz, nv] = reducevolume (x, y, z, v, [4 3 2]); %!error <Y must match the size of data V> %! y = -14:6:11; %! [nx, ny, nz, nv] = reducevolume (x, y, z, v, [4 3 2]); %!error <Z must match the size of data V> %! z = linspace (16, 18, 5); %! [nx, ny, nz, nv] = reducevolume (x, y, z, v, [4 3 2]); %!error <reduction value R is too high> [nv] = reducevolume (v, 5) %!error <reduction value R is too high> [nv] = reducevolume (v, [4 7 2])