📄 interpn_linnonull.m
字号:
function y = interpn_linnonull(v, varargin)
% interpn_linnonull - linear interpolation, not sampling nulls
%
% FORMAT: Y = interpn_linnonull(V, Y1, Y2, ... [, extrapval, ith])
%
% Input fields:
%
% V data array to sample
% Y1,Y2, ... sampling coordinates (one-based)
% extrapval value for coordinates outside of array (default 0)
% ith interpolation threshold (default 0.5)
%
% Output fields:
%
% Y sampled data
%
% Note: this uses, in principal, the same approach as interpn but
% assumes that null is a value not to sample (e.g. for VMPs)
% whenever a sampling value is determined with less than 50%
% good information, the sample is said to be out of bounds
%
% See also interpn
% Version: v0.7b
% Build: 7083113
% Date: Aug-31 2007, 1:13 PM CEST
% Author: Jochen Weber, Brain Innovation, B.V., Maastricht, NL
% URL/Info: http://wiki.brainvoyager.com/BVQXtools
% argument check
if nargin < 3 || ...
~any(((1:3) + ndims(v)) == nargin) || ...
any(size(v) < 2) || ...
(~isa(varargin{1}, 'single') && ...
~isa(varargin{1}, 'double')) || ...
(~isa(varargin{2}, 'single') && ...
~isa(varargin{2}, 'double')) || ...
numel(varargin{1}) ~= numel(varargin{2})
error( ...
'BVQXtools:BadArgument', ...
'Bad or missing argument.' ...
);
end
nd = ndims(v);
vs = size(v);
for dc = 2:nd
if ~isequal(size(varargin{dc}), size(varargin{1}))
error( ...
'BVQXtools:BadArgument', ...
'Size mismatch.' ...
);
end
end
sc = varargin(1:nd);
so = size(sc{1});
if isempty(varargin{1})
y = v(1);
y(1) = [];
return;
else
if isa(v, 'double')
y = 0;
else
y = single(0);
end
y(1:prod(so)) = y(1);
y = reshape(y, so);
end
xv = 0;
ith = 0.5;
if nargin > (nd + 1)
if numel(varargin{end}) ~= 1 || ...
~isnumeric(varargin{end})
error( ...
'BVQXtools:BadArgument', ...
'Invalid extrapval.' ...
);
end
if nargin > (nd + 2)
if numel(varargin{end - 1}) ~= 1 || ...
~isnumeric(varargin{end - 1})
error( ...
'BVQXtools:BadArgument', ...
'Invalid extrapval.' ...
);
end
ith = min(1, max(eps, double(varargin{end})));
xv = varargin{end - 1};
else
xv = varargin{end};
end
end
if ~strcmpi(class(v), class(xv))
if isa(v, 'double')
xv = double(xv);
else
if ~isa(v, 'single')
v = single(v);
end
xv = single(xv);
end
end
% check coordinates for values out of range and set to 1
sout = false(so);
for vc = 1:nd
sout = sout | (sc{vc} < 1) | (sc{vc} > vs(vc));
sc{vc}(sout) = 1;
end
% matrix element indexing
offset = cumprod([1, vs(1:end-1)]);
ndx = 1;
for vc = 1:nd
ndx = ndx + offset(vc) * floor(sc{vc} - 1);
end
% compute intepolation parameters, check for boundary value
for vc = 1:nd
d = find(sc{vc} == vs(vc));
sc{vc} = sc{vc} - floor(sc{vc});
if ~isempty(d)
sc{vc}(d) = sc{vc}(d) + 1;
ndx(d) = ndx(d) - offset(vc);
end
end
d = []; % reclaim memory (see interpn)
% create index arrays (as a matrix of 2^nd x nd)
ix = cell(size(vs));
[ix{1:end}] = ndgrid(0:1);
for vc = 1:nd
ix{vc} = logical(ix{vc}(:));
end
ix = cat(2, ix{:});
% weighted interpolation (do not weight nulls)
wy = zsz(y);
for vc = 1:size(ix, 1)
vv = v(ndx + offset * ix(vc, :)');
vnn = (vv ~= 0);
wv = osz(y);
for svc = 1:size(ix, 2)
if ix(vc, svc)
wv = wv .* sc{svc};
else
wv = wv .* (1 - sc{svc});
end
end
wy(vnn) = wy(vnn) + wv(vnn);
y(vnn) = y(vnn) + vv(vnn) .* wv(vnn);
end
vnn = (wy >= ith);
y(vnn) = y(vnn) ./ wy(vnn);
% now set out of range values to NaN.
y(sout | ~vnn) = xv;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -