diff --git a/+misc/fold.m b/+misc/fold.m index 91b1a22479e444a750f2f38e4ee5a835c6b6f5d6..9a31ecb1bdc30a5c3c0ebe8820c2145e46008ae8 100644 --- a/+misc/fold.m +++ b/+misc/fold.m @@ -1,4 +1,4 @@ -function xFolded = fold(x,z0,dim,nFolded) +function xFolded = fold(x,z0,dim,varargin) % misc.fold fold discretized vector or array around folding point % % xFolded = FOLD(x,z0) folds the vector x which is discretized over linspace(0,1,ndisc) at the @@ -17,6 +17,38 @@ function xFolded = fold(x,z0,dim,nFolded) % created on 07.10.2019 by Simon Kerschbaum + +found=0; +passed = []; +arglist = {'preserve','nFolded'}; +% preserve: insert the folding point at both left and right part. Important for observer error! +% nFolded resolution of the folded states +if ~isempty(varargin) + if mod(length(varargin),2) % uneven number + error('When passing additional arguments, you must pass them pairwise!') + end + for index = 1:2:length(varargin) % loop through all passed arguments: + for arg = 1:length(arglist) + if strcmp(varargin{index},arglist{arg}) + passed.(arglist{arg}) = varargin{index+1}; + found=1; + break + end + end % for arg + % argument wasnt found in for-loop + if ~found + error([varargin{index} ' is not a valid property to pass to fold!']); + end + found=0; % reset found + end % for index +end +if ~isfield(passed,'preserve') + passed.preserve = 0; +end +if ~isfield(passed,'nFolded') + passed.nFolded = 0; +end + if isvector(x) x=x(:); if dim == 2 @@ -26,8 +58,10 @@ function xFolded = fold(x,z0,dim,nFolded) if nargin < 3 dim =1; end - if nargin < 4 + if passed.nFolded == 0 nFolded = size(x,dim); + else + nFolded = passed.nFolded; end zDiscOld = linspace(0,1,size(x,dim)); @@ -35,9 +69,14 @@ function xFolded = fold(x,z0,dim,nFolded) zLeft = zeros(1,nFolded); zRight = zeros(1,nFolded); - zRight(1,:) = linspace(z0,1,nFolded); - dZ = diff(zRight(1,:)); - zLeft(1,:) = linspace(0,z0-dZ(1),nFolded); + if ~passed.preserve + zRight(1,:) = linspace(z0,1,nFolded); + dZ = diff(zRight(1,:)); + zLeft(1,:) = linspace(0,z0-dZ(1),nFolded); + else + zRight(1,:) = linspace(z0,1,nFolded); + zLeft(1,:) = linspace(0,z0,nFolded); + end sizX = size(x); if dim~= 1 @@ -61,14 +100,15 @@ function xFolded = fold(x,z0,dim,nFolded) xFoldedResh(:,1) = xInterp.evaluate(fliplr(zLeft(1,:)),1:size(xResh,2)); xFoldedResh(:,2) = xInterp.evaluate(zRight(1,:),1:size(xResh,2)); else - xFoldedResh = zeros([size(xResh) 2]); + xFoldedResh = zeros([nFolded size(xResh,2) 2]); xFoldedResh(:,:,1) = xInterp.evaluate(fliplr(zLeft(1,:)),1:size(xResh,2)); xFoldedResh(:,:,2) = xInterp.evaluate(zRight(1,:),1:size(xResh,2)); end if ~ismatrix(xPerm) - xFoldedPerm = reshape(xFoldedResh,[size(xPerm) 2]); + sizXPerm = size(xPerm); + xFoldedPerm = reshape(xFoldedResh,[nFolded sizXPerm(2:end) 2]); else xFoldedPerm = xFoldedResh; end diff --git a/+misc/unfold.m b/+misc/unfold.m index fb444e6be2584a7fab9872fb504a0b5d3f6bf5f0..50380dd99e0844a67b5838bdd7feaee4dd48e16a 100644 --- a/+misc/unfold.m +++ b/+misc/unfold.m @@ -16,6 +16,9 @@ function xUnfolded = unfold(x,z0,dim,nNew) % created on 07.10.2019 by Simon Kerschbaum +% warning('The folding point will appear twice! Think about fixing!') +% fixing is easy! Insert a spatial point very close to the folding point to achieve this +% double-point and then interpolate on a linear grid!!! SO easy! if isvector(x) error('x needs at least a spatial coordinate and a folding coordinate with 2 entries.'); end @@ -47,24 +50,32 @@ function xUnfolded = unfold(x,z0,dim,nNew) xResh = reshape(xPerm,sizX(dim),[],2); sizXResh = size(xResh); xLeftInterp = numeric.interpolant(... - {linspace(zNew(z0Idx),0,nOld),... - 1:sizXResh(2),1:2},xResh(:,:,1)); + {linspace(z0,0,nOld),1:sizXResh(2)},... + xResh(:,:,1)); xRightInterp = numeric.interpolant(... - {linspace(zNew(z0Idx+1),1,nOld),... - 1:sizXResh(2),1:2},xResh(:,:,2)); - xUnfoldedResh = zeros(nNew,sizXResh(2)); + {linspace(z0+1e-13,1,nOld),1:sizXResh(2)},... + xResh(:,:,2)); + xUnfoldedReshTemp = zeros(nNew,sizXResh(2)); else xResh = xPerm; sizXResh = size(xResh); xLeftInterp = numeric.interpolant(... - {linspace(zNew(z0Idx),0,nOld),1:2},xResh(:,1)); + {linspace(z0,0,nOld),1:2},xResh(:,1)); xRightInterp = numeric.interpolant(... - {linspace(zNew(z0Idx+1),1,nOld),1:2},xResh(:,2)); - xUnfoldedResh = zeros(nNew,1); + {linspace(z0+1e-13,1,nOld),1:2},xResh(:,2)); + xUnfoldedReshTemp = zeros(nNew,1); end - xUnfoldedResh(1:z0Idx,:) = xLeftInterp.eval({zNew(1:z0Idx),1:sizXResh(2)}); - xUnfoldedResh(z0Idx+1:end,:) = xRightInterp.eval({zNew(z0Idx+1:end),1:sizXResh(2)}); + xUnfoldedReshTemp(1:z0Idx,:) = xLeftInterp.eval({linspace(0,z0,z0Idx),1:sizXResh(2)}); + xUnfoldedReshTemp(z0Idx+1:end,:) = xRightInterp.eval({linspace(z0+1e-13,1,nNew-z0Idx),1:sizXResh(2)}); + % attention, xUnfoldedResh is defined on non-uniform grid: + xUnfoldedReshInterp = numeric.interpolant({... + [linspace(0,z0,z0Idx) linspace(z0+1e-13,1,nNew-z0Idx)],... + 1:size(xUnfoldedReshTemp,2) + },... + xUnfoldedReshTemp); + xUnfoldedResh = xUnfoldedReshInterp.eval({zNew,1:size(xUnfoldedReshTemp,2)}); + if ~ismatrix(xPerm) xUnfoldedPerm = reshape(xUnfoldedResh,[nNew sizXPerm(2:end-1)]);