# HG changeset patch # User Markus Muetzel # Date 1468864179 -7200 # Node ID 01ba6ebc52e475ee602c824ca31abc45eaaf6c7f # Parent e43199618777c4860fd39c4b48878ddb0097c963 Add function "reducevolume" (patch #8856). * scripts/plot/draw/reducevolume.m: New function. * scripts/plot/draw/module.mk: Add to build system. * __unimplemented__.m: Remove "reducevolume" from list. * NEWS: Announce new function. * doc/interpreter/plot.txi: Add to documentation. * scripts/plot/draw/isosurface.m: Add "reducevolume" to @seealso. diff -r e43199618777 -r 01ba6ebc52e4 NEWS --- a/NEWS Tue Aug 09 15:40:32 2016 +0100 +++ b/NEWS Mon Jul 18 19:49:39 2016 +0200 @@ -123,6 +123,7 @@ padecoef psi rad2deg + reducevolume uibuttongroup ** Deprecated functions. diff -r e43199618777 -r 01ba6ebc52e4 doc/interpreter/plot.txi --- a/doc/interpreter/plot.txi Tue Aug 09 15:40:32 2016 +0100 +++ b/doc/interpreter/plot.txi Mon Jul 18 19:49:39 2016 +0200 @@ -386,6 +386,8 @@ @DOCSTRING(smooth3) +@DOCSTRING(reducevolume) + @DOCSTRING(shrinkfaces) @DOCSTRING(diffuse) diff -r e43199618777 -r 01ba6ebc52e4 scripts/help/__unimplemented__.m --- a/scripts/help/__unimplemented__.m Tue Aug 09 15:40:32 2016 +0100 +++ b/scripts/help/__unimplemented__.m Mon Jul 18 19:49:39 2016 +0200 @@ -787,7 +787,6 @@ "rbbox", "readtable", "reducepatch", - "reducevolume", "remove", "removecats", "renamecats", diff -r e43199618777 -r 01ba6ebc52e4 scripts/plot/draw/isosurface.m --- a/scripts/plot/draw/isosurface.m Tue Aug 09 15:40:32 2016 +0100 +++ b/scripts/plot/draw/isosurface.m Mon Jul 18 19:49:39 2016 +0200 @@ -133,7 +133,7 @@ ## light ("Position", [1 1 5]); ## @end smallexample ## -## @seealso{isonormals, isocolors, smooth3} +## @seealso{isonormals, isocolors, smooth3, reducevolume} ## @end deftypefn ## Author: Martin Helm diff -r e43199618777 -r 01ba6ebc52e4 scripts/plot/draw/module.mk --- a/scripts/plot/draw/module.mk Tue Aug 09 15:40:32 2016 +0100 +++ b/scripts/plot/draw/module.mk Mon Jul 18 19:49:39 2016 +0200 @@ -72,6 +72,7 @@ scripts/plot/draw/quiver3.m \ scripts/plot/draw/quiver.m \ scripts/plot/draw/rectangle.m \ + scripts/plot/draw/reducevolume.m \ scripts/plot/draw/ribbon.m \ scripts/plot/draw/rose.m \ scripts/plot/draw/scatter3.m \ diff -r e43199618777 -r 01ba6ebc52e4 scripts/plot/draw/reducevolume.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scripts/plot/draw/reducevolume.m Mon Jul 18 19:49:39 2016 +0200 @@ -0,0 +1,286 @@ +## Copyright (C) 2016 Markus Muetzel +## +## 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 +## . + +## -*- 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,,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 + +## Author: mmuetzel + +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:size (v, 2); + endif + if (isempty (y)) + y = 1:size (v, 1); + 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 reducevolume () +%!error reducevolume (1) +%!error reducevolume (1,2,3,4,5,6) +%!error reducevolume (1, 2, 3) +%!error reducevolume (v, []) +%!error reducevolume (v, [1 2]) +%!error reducevolume (v, 0) +%!error reducevolume (v, 1.5) +%!error +%! v = reshape(1:6*8, [6 8]); +%! [nv] = reducevolume (v, [4 3 2]); +%!error +%! v = reshape(1:6*8, [6 1 8]); +%! nv = reducevolume (v, [4 3 2]); +%!error +%! x = 1:2:24; +%! [nx, ny, nz, nv] = reducevolume (x, y, z, v, [4 3 2]); +%!error +%! y = -14:6:11; +%! [nx, ny, nz, nv] = reducevolume (x, y, z, v, [4 3 2]); +%!error +%! z = linspace (16, 18, 5); +%! [nx, ny, nz, nv] = reducevolume (x, y, z, v, [4 3 2]); +%!error [nv] = reducevolume (v, 5) +%!error [nv] = reducevolume (v, [4 7 2]) +