|
|
@ -2780,6 +2780,480 @@ def gridcount(data, X, y=1):
|
|
|
|
c = c.transpose(*T) # make sure c is stored in the same way as meshgrid
|
|
|
|
c = c.transpose(*T) # make sure c is stored in the same way as meshgrid
|
|
|
|
return c
|
|
|
|
return c
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def evar(y):
|
|
|
|
|
|
|
|
'''
|
|
|
|
|
|
|
|
Noise variance estimation.
|
|
|
|
|
|
|
|
Assuming that the deterministic function Y has additive Gaussian noise,
|
|
|
|
|
|
|
|
EVAR(Y) returns an estimated variance of this noise.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Note:
|
|
|
|
|
|
|
|
----
|
|
|
|
|
|
|
|
A thin-plate smoothing spline model is used to smooth Y. It is assumed
|
|
|
|
|
|
|
|
that the model whose generalized cross-validation score is minimum can
|
|
|
|
|
|
|
|
provide the variance of the additive noise. A few tests showed that
|
|
|
|
|
|
|
|
EVAR works very well with "not too irregular" functions.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Examples:
|
|
|
|
|
|
|
|
--------
|
|
|
|
|
|
|
|
1D signal
|
|
|
|
|
|
|
|
>>> n = 1e6;
|
|
|
|
|
|
|
|
>>> x = np.linspace(0,100,n);
|
|
|
|
|
|
|
|
>>> y = np.cos(x/10)+(x/50)
|
|
|
|
|
|
|
|
>>> var0 = 0.02 # noise variance
|
|
|
|
|
|
|
|
>>> yn = y + sqrt(var0)*np.random.randn(*y.shape)
|
|
|
|
|
|
|
|
>>> evar(yn) #estimated variance
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2D function
|
|
|
|
|
|
|
|
>>> xp = np.linspace(0,1,50)
|
|
|
|
|
|
|
|
>>> x, y = np.meshgrid(xp,xp)
|
|
|
|
|
|
|
|
>>> f = np.exp(x+y) + np.sin((x-2*y)*3)
|
|
|
|
|
|
|
|
>>> var0 = 0.04 # noise variance
|
|
|
|
|
|
|
|
>>> fn = f + sqrt(var0)*np.random.randn(*f.shape)
|
|
|
|
|
|
|
|
>>> evar(fn) estimated variance
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3D function
|
|
|
|
|
|
|
|
>>> yp = np.linspace(-2,2,50)
|
|
|
|
|
|
|
|
>>> [x,y,z] = meshgrid(yp,yp,yp, sparse=True)
|
|
|
|
|
|
|
|
>>> f = x*exp(-x**2-y**2-z**2)
|
|
|
|
|
|
|
|
>>> var0 = 0.5 # noise variance
|
|
|
|
|
|
|
|
>>> fn = f + sqrt(var0)*np.random.randn(*f.shape)
|
|
|
|
|
|
|
|
>>> evar(fn) estimated variance
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Other example
|
|
|
|
|
|
|
|
-------------
|
|
|
|
|
|
|
|
http://www.biomecardio.com/matlab/evar.html
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Note:
|
|
|
|
|
|
|
|
----
|
|
|
|
|
|
|
|
EVAR is only adapted to evenly-gridded 1-D to N-D data.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
See also
|
|
|
|
|
|
|
|
--------
|
|
|
|
|
|
|
|
VAR, STD, SMOOTHN
|
|
|
|
|
|
|
|
'''
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Damien Garcia -- 2008/04, revised 2009/10
|
|
|
|
|
|
|
|
y = np.atleast_1d(y)
|
|
|
|
|
|
|
|
d = y.ndim
|
|
|
|
|
|
|
|
sh0 = y.shape
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
S = np.zeros(sh0)
|
|
|
|
|
|
|
|
sh1 = np.ones((d,))
|
|
|
|
|
|
|
|
cos = np.cos
|
|
|
|
|
|
|
|
pi = np.pi
|
|
|
|
|
|
|
|
for i in range(d):
|
|
|
|
|
|
|
|
ni = sh0[i]
|
|
|
|
|
|
|
|
sh1[i] = ni
|
|
|
|
|
|
|
|
t = np.arange(ni).reshape(sh1)/ni
|
|
|
|
|
|
|
|
S += cos(pi*t)
|
|
|
|
|
|
|
|
sh1[i] = 1
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
S2 = 2*(d-S).ravel()
|
|
|
|
|
|
|
|
# N-D Discrete Cosine Transform of Y
|
|
|
|
|
|
|
|
dcty2 = dctn(y).ravel()**2
|
|
|
|
|
|
|
|
def score_fun(L, S2, dcty2):
|
|
|
|
|
|
|
|
# Generalized cross validation score
|
|
|
|
|
|
|
|
M = 1-1./(1+10**L*S2)
|
|
|
|
|
|
|
|
noisevar = (dcty2*M**2).mean()
|
|
|
|
|
|
|
|
return noisevar/M.mean()**2
|
|
|
|
|
|
|
|
#fun = lambda x : score_fun(x, S2, dcty2)
|
|
|
|
|
|
|
|
Lopt = optimize.fminbound(score_fun, -38, 38, args=(S2, dcty2))
|
|
|
|
|
|
|
|
M = 1-1./(1+10**Lopt*S2)
|
|
|
|
|
|
|
|
noisevar = (dcty2*M**2).mean()
|
|
|
|
|
|
|
|
return noisevar
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def unfinished_smoothn(data,s=None, weight=None, robust=False, z0=None, tolz=1e-3, maxiter=100):
|
|
|
|
|
|
|
|
'''
|
|
|
|
|
|
|
|
SMOOTHN Robust spline smoothing for 1-D to N-D data.
|
|
|
|
|
|
|
|
SMOOTHN provides a fast, automatized and robust discretized smoothing
|
|
|
|
|
|
|
|
spline for data of any dimension.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Z = SMOOTHN(Y) automatically smoothes the uniformly-sampled array Y. Y
|
|
|
|
|
|
|
|
can be any N-D noisy array (time series, images, 3D data,...). Non
|
|
|
|
|
|
|
|
finite data (NaN or Inf) are treated as missing values.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Z = SMOOTHN(Y,S) smoothes the array Y using the smoothing parameter S.
|
|
|
|
|
|
|
|
S must be a real positive scalar. The larger S is, the smoother the
|
|
|
|
|
|
|
|
output will be. If the smoothing parameter S is omitted (see previous
|
|
|
|
|
|
|
|
option) or empty (i.e. S = []), it is automatically determined using
|
|
|
|
|
|
|
|
the generalized cross-validation (GCV) method.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Z = SMOOTHN(Y,W) or Z = SMOOTHN(Y,W,S) specifies a weighting array W of
|
|
|
|
|
|
|
|
real positive values, that must have the same size as Y. Note that a
|
|
|
|
|
|
|
|
nil weight corresponds to a missing value.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Robust smoothing
|
|
|
|
|
|
|
|
----------------
|
|
|
|
|
|
|
|
Z = SMOOTHN(...,'robust') carries out a robust smoothing that minimizes
|
|
|
|
|
|
|
|
the influence of outlying data.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[Z,S] = SMOOTHN(...) also returns the calculated value for S so that
|
|
|
|
|
|
|
|
you can fine-tune the smoothing subsequently if needed.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
An iteration process is used in the presence of weighted and/or missing
|
|
|
|
|
|
|
|
values. Z = SMOOTHN(...,OPTION_NAME,OPTION_VALUE) smoothes with the
|
|
|
|
|
|
|
|
termination parameters specified by OPTION_NAME and OPTION_VALUE. They
|
|
|
|
|
|
|
|
can contain the following criteria:
|
|
|
|
|
|
|
|
-----------------
|
|
|
|
|
|
|
|
TolZ: Termination tolerance on Z (default = 1e-3)
|
|
|
|
|
|
|
|
TolZ must be in ]0,1[
|
|
|
|
|
|
|
|
MaxIter: Maximum number of iterations allowed (default = 100)
|
|
|
|
|
|
|
|
Initial: Initial value for the iterative process (default =
|
|
|
|
|
|
|
|
original data)
|
|
|
|
|
|
|
|
-----------------
|
|
|
|
|
|
|
|
Syntax: [Z,...] = SMOOTHN(...,'MaxIter',500,'TolZ',1e-4,'Initial',Z0);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[Z,S,EXITFLAG] = SMOOTHN(...) returns a boolean value EXITFLAG that
|
|
|
|
|
|
|
|
describes the exit condition of SMOOTHN:
|
|
|
|
|
|
|
|
1 SMOOTHN converged.
|
|
|
|
|
|
|
|
0 Maximum number of iterations was reached.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Class Support
|
|
|
|
|
|
|
|
-------------
|
|
|
|
|
|
|
|
Input array can be numeric or logical. The returned array is of class
|
|
|
|
|
|
|
|
double.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Notes
|
|
|
|
|
|
|
|
-----
|
|
|
|
|
|
|
|
The N-D (inverse) discrete cosine transform functions <a
|
|
|
|
|
|
|
|
href="matlab:web('http://www.biomecardio.com/matlab/dctn.html')"
|
|
|
|
|
|
|
|
>DCTN</a> and <a
|
|
|
|
|
|
|
|
href="matlab:web('http://www.biomecardio.com/matlab/idctn.html')"
|
|
|
|
|
|
|
|
>IDCTN</a> are required.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
To be made
|
|
|
|
|
|
|
|
----------
|
|
|
|
|
|
|
|
Estimate the confidence bands (see Wahba 1983, Nychka 1988).
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Reference
|
|
|
|
|
|
|
|
---------
|
|
|
|
|
|
|
|
Garcia D, Robust smoothing of gridded data in one and higher dimensions
|
|
|
|
|
|
|
|
with missing values. Computational Statistics & Data Analysis, 2010.
|
|
|
|
|
|
|
|
<a
|
|
|
|
|
|
|
|
href="matlab:web('http://www.biomecardio.com/pageshtm/publi/csda10.pdf')">PDF download</a>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Examples:
|
|
|
|
|
|
|
|
--------
|
|
|
|
|
|
|
|
1-D example
|
|
|
|
|
|
|
|
x = linspace(0,100,2^8);
|
|
|
|
|
|
|
|
y = cos(x/10)+(x/50).^2 + randn(size(x))/10;
|
|
|
|
|
|
|
|
y([70 75 80]) = [5.5 5 6];
|
|
|
|
|
|
|
|
z = smoothn(y); Regular smoothing
|
|
|
|
|
|
|
|
zr = smoothn(y,'robust'); Robust smoothing
|
|
|
|
|
|
|
|
subplot(121), plot(x,y,'r.',x,z,'k','LineWidth',2)
|
|
|
|
|
|
|
|
axis square, title('Regular smoothing')
|
|
|
|
|
|
|
|
subplot(122), plot(x,y,'r.',x,zr,'k','LineWidth',2)
|
|
|
|
|
|
|
|
axis square, title('Robust smoothing')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2-D example
|
|
|
|
|
|
|
|
xp = 0:.02:1;
|
|
|
|
|
|
|
|
[x,y] = meshgrid(xp);
|
|
|
|
|
|
|
|
f = exp(x+y) + sin((x-2*y)*3);
|
|
|
|
|
|
|
|
fn = f + randn(size(f))*0.5;
|
|
|
|
|
|
|
|
fs = smoothn(fn);
|
|
|
|
|
|
|
|
subplot(121), surf(xp,xp,fn), zlim([0 8]), axis square
|
|
|
|
|
|
|
|
subplot(122), surf(xp,xp,fs), zlim([0 8]), axis square
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2-D example with missing data
|
|
|
|
|
|
|
|
n = 256;
|
|
|
|
|
|
|
|
y0 = peaks(n);
|
|
|
|
|
|
|
|
y = y0 + rand(size(y0))*2;
|
|
|
|
|
|
|
|
I = randperm(n^2);
|
|
|
|
|
|
|
|
y(I(1:n^2*0.5)) = NaN; lose 1/2 of data
|
|
|
|
|
|
|
|
y(40:90,140:190) = NaN; create a hole
|
|
|
|
|
|
|
|
z = smoothn(y); smooth data
|
|
|
|
|
|
|
|
subplot(2,2,1:2), imagesc(y), axis equal off
|
|
|
|
|
|
|
|
title('Noisy corrupt data')
|
|
|
|
|
|
|
|
subplot(223), imagesc(z), axis equal off
|
|
|
|
|
|
|
|
title('Recovered data ...')
|
|
|
|
|
|
|
|
subplot(224), imagesc(y0), axis equal off
|
|
|
|
|
|
|
|
title('... compared with original data')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3-D example
|
|
|
|
|
|
|
|
[x,y,z] = meshgrid(-2:.2:2);
|
|
|
|
|
|
|
|
xslice = [-0.8,1]; yslice = 2; zslice = [-2,0];
|
|
|
|
|
|
|
|
vn = x.*exp(-x.^2-y.^2-z.^2) + randn(size(x))*0.06;
|
|
|
|
|
|
|
|
subplot(121), slice(x,y,z,vn,xslice,yslice,zslice,'cubic')
|
|
|
|
|
|
|
|
title('Noisy data')
|
|
|
|
|
|
|
|
v = smoothn(vn);
|
|
|
|
|
|
|
|
subplot(122), slice(x,y,z,v,xslice,yslice,zslice,'cubic')
|
|
|
|
|
|
|
|
title('Smoothed data')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Cardioid
|
|
|
|
|
|
|
|
t = linspace(0,2*pi,1000);
|
|
|
|
|
|
|
|
x = 2*cos(t).*(1-cos(t)) + randn(size(t))*0.1;
|
|
|
|
|
|
|
|
y = 2*sin(t).*(1-cos(t)) + randn(size(t))*0.1;
|
|
|
|
|
|
|
|
z = smoothn(complex(x,y));
|
|
|
|
|
|
|
|
plot(x,y,'r.',real(z),imag(z),'k','linewidth',2)
|
|
|
|
|
|
|
|
axis equal tight
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Cellular vortical flow
|
|
|
|
|
|
|
|
[x,y] = meshgrid(linspace(0,1,24));
|
|
|
|
|
|
|
|
Vx = cos(2*pi*x+pi/2).*cos(2*pi*y);
|
|
|
|
|
|
|
|
Vy = sin(2*pi*x+pi/2).*sin(2*pi*y);
|
|
|
|
|
|
|
|
Vx = Vx + sqrt(0.05)*randn(24,24); adding Gaussian noise
|
|
|
|
|
|
|
|
Vy = Vy + sqrt(0.05)*randn(24,24); adding Gaussian noise
|
|
|
|
|
|
|
|
I = randperm(numel(Vx));
|
|
|
|
|
|
|
|
Vx(I(1:30)) = (rand(30,1)-0.5)*5; adding outliers
|
|
|
|
|
|
|
|
Vy(I(1:30)) = (rand(30,1)-0.5)*5; adding outliers
|
|
|
|
|
|
|
|
Vx(I(31:60)) = NaN; missing values
|
|
|
|
|
|
|
|
Vy(I(31:60)) = NaN; missing values
|
|
|
|
|
|
|
|
Vs = smoothn(complex(Vx,Vy),'robust'); automatic smoothing
|
|
|
|
|
|
|
|
subplot(121), quiver(x,y,Vx,Vy,2.5), axis square
|
|
|
|
|
|
|
|
title('Noisy velocity field')
|
|
|
|
|
|
|
|
subplot(122), quiver(x,y,real(Vs),imag(Vs)), axis square
|
|
|
|
|
|
|
|
title('Smoothed velocity field')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
See also SMOOTH, SMOOTH3, DCTN, IDCTN.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
-- Damien Garcia -- 2009/03, revised 2010/11
|
|
|
|
|
|
|
|
Visit my <a
|
|
|
|
|
|
|
|
href="matlab:web('http://www.biomecardio.com/matlab/smoothn.html')">website</a> for more details about SMOOTHN
|
|
|
|
|
|
|
|
'''
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
y = np.atleast_1d(data)
|
|
|
|
|
|
|
|
sizy = y.shape
|
|
|
|
|
|
|
|
noe = y.size
|
|
|
|
|
|
|
|
if noe<2:
|
|
|
|
|
|
|
|
return data
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
weightstr = 'bisquare'
|
|
|
|
|
|
|
|
W = np.ones(sizy)
|
|
|
|
|
|
|
|
# Smoothness parameter and weights
|
|
|
|
|
|
|
|
if weight is None:
|
|
|
|
|
|
|
|
pass
|
|
|
|
|
|
|
|
elif isinstance(weight, str):
|
|
|
|
|
|
|
|
weightstr = W.lower()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Weights. Zero weights are assigned to not finite values (Inf or NaN),
|
|
|
|
|
|
|
|
# (Inf/NaN values = missing data).
|
|
|
|
|
|
|
|
IsFinite = np.isfinite(y);
|
|
|
|
|
|
|
|
nof = sum(IsFinite) # number of finite elements
|
|
|
|
|
|
|
|
W = W*IsFinite
|
|
|
|
|
|
|
|
if any(W<0):
|
|
|
|
|
|
|
|
raise ValueError('Weights must all be >=0')
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
|
|
W = W/W.max()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#% Weighted or missing data?
|
|
|
|
|
|
|
|
# isweighted = any(W(:)<1);
|
|
|
|
|
|
|
|
# %---
|
|
|
|
|
|
|
|
# % Robust smoothing?
|
|
|
|
|
|
|
|
# isrobust = any(strcmpi(varargin,'robust'));
|
|
|
|
|
|
|
|
# %---
|
|
|
|
|
|
|
|
# % Automatic smoothing?
|
|
|
|
|
|
|
|
# isauto = isempty(s);
|
|
|
|
|
|
|
|
# %---
|
|
|
|
|
|
|
|
# % DCTN and IDCTN are required
|
|
|
|
|
|
|
|
# test4DCTNandIDCTN
|
|
|
|
|
|
|
|
#
|
|
|
|
|
|
|
|
# %% Creation of the Lambda tensor
|
|
|
|
|
|
|
|
# %---
|
|
|
|
|
|
|
|
# % Lambda contains the eingenvalues of the difference matrix used in this
|
|
|
|
|
|
|
|
# % penalized least squares process.
|
|
|
|
|
|
|
|
# d = ndims(y);
|
|
|
|
|
|
|
|
# Lambda = zeros(sizy);
|
|
|
|
|
|
|
|
# for i = 1:d
|
|
|
|
|
|
|
|
# siz0 = ones(1,d);
|
|
|
|
|
|
|
|
# siz0(i) = sizy(i);
|
|
|
|
|
|
|
|
# Lambda = bsxfun(@plus,Lambda,...
|
|
|
|
|
|
|
|
# cos(pi*(reshape(1:sizy(i),siz0)-1)/sizy(i)));
|
|
|
|
|
|
|
|
# end
|
|
|
|
|
|
|
|
# Lambda = -2*(d-Lambda);
|
|
|
|
|
|
|
|
# if ~isauto, Gamma = 1./(1+s*Lambda.^2); end
|
|
|
|
|
|
|
|
#
|
|
|
|
|
|
|
|
# %% Upper and lower bound for the smoothness parameter
|
|
|
|
|
|
|
|
# % The average leverage (h) is by definition in [0 1]. Weak smoothing occurs
|
|
|
|
|
|
|
|
# % if h is close to 1, while over-smoothing appears when h is near 0. Upper
|
|
|
|
|
|
|
|
# % and lower bounds for h are given to avoid under- or over-smoothing. See
|
|
|
|
|
|
|
|
# % equation relating h to the smoothness parameter (Equation #12 in the
|
|
|
|
|
|
|
|
# % referenced CSDA paper).
|
|
|
|
|
|
|
|
# N = sum(sizy~=1); % tensor rank of the y-array
|
|
|
|
|
|
|
|
# hMin = 1e-6; hMax = 0.99;
|
|
|
|
|
|
|
|
# sMinBnd = (((1+sqrt(1+8*hMax.^(2/N)))/4./hMax.^(2/N)).^2-1)/16;
|
|
|
|
|
|
|
|
# sMaxBnd = (((1+sqrt(1+8*hMin.^(2/N)))/4./hMin.^(2/N)).^2-1)/16;
|
|
|
|
|
|
|
|
#
|
|
|
|
|
|
|
|
# %% Initialize before iterating
|
|
|
|
|
|
|
|
# %---
|
|
|
|
|
|
|
|
# Wtot = W;
|
|
|
|
|
|
|
|
# %--- Initial conditions for z
|
|
|
|
|
|
|
|
# if isweighted
|
|
|
|
|
|
|
|
# %--- With weighted/missing data
|
|
|
|
|
|
|
|
# % An initial guess is provided to ensure faster convergence. For that
|
|
|
|
|
|
|
|
# % purpose, a nearest neighbor interpolation followed by a coarse
|
|
|
|
|
|
|
|
# % smoothing are performed.
|
|
|
|
|
|
|
|
# %---
|
|
|
|
|
|
|
|
# if isinitial % an initial guess (z0) has been provided
|
|
|
|
|
|
|
|
# z = z0;
|
|
|
|
|
|
|
|
# else
|
|
|
|
|
|
|
|
# z = InitialGuess(y,IsFinite);
|
|
|
|
|
|
|
|
# end
|
|
|
|
|
|
|
|
# else
|
|
|
|
|
|
|
|
# z = zeros(sizy);
|
|
|
|
|
|
|
|
# end
|
|
|
|
|
|
|
|
# %---
|
|
|
|
|
|
|
|
# z0 = z;
|
|
|
|
|
|
|
|
# y(~IsFinite) = 0; % arbitrary values for missing y-data
|
|
|
|
|
|
|
|
# %---
|
|
|
|
|
|
|
|
# tol = 1;
|
|
|
|
|
|
|
|
# RobustIterativeProcess = true;
|
|
|
|
|
|
|
|
# RobustStep = 1;
|
|
|
|
|
|
|
|
# nit = 0;
|
|
|
|
|
|
|
|
# %--- Error on p. Smoothness parameter s = 10^p
|
|
|
|
|
|
|
|
# errp = 0.1;
|
|
|
|
|
|
|
|
# opt = optimset('TolX',errp);
|
|
|
|
|
|
|
|
# %--- Relaxation factor RF: to speedup convergence
|
|
|
|
|
|
|
|
# RF = 1 + 0.75*isweighted;
|
|
|
|
|
|
|
|
#
|
|
|
|
|
|
|
|
# %% Main iterative process
|
|
|
|
|
|
|
|
# %---
|
|
|
|
|
|
|
|
# while RobustIterativeProcess
|
|
|
|
|
|
|
|
# %--- "amount" of weights (see the function GCVscore)
|
|
|
|
|
|
|
|
# aow = sum(Wtot(:))/noe; % 0 < aow <= 1
|
|
|
|
|
|
|
|
# %---
|
|
|
|
|
|
|
|
# while tol>TolZ && nit<MaxIter
|
|
|
|
|
|
|
|
# nit = nit+1;
|
|
|
|
|
|
|
|
# DCTy = dctn(Wtot.*(y-z)+z);
|
|
|
|
|
|
|
|
# if isauto && ~rem(log2(nit),1)
|
|
|
|
|
|
|
|
# %---
|
|
|
|
|
|
|
|
# % The generalized cross-validation (GCV) method is used.
|
|
|
|
|
|
|
|
# % We seek the smoothing parameter s that minimizes the GCV
|
|
|
|
|
|
|
|
# % score i.e. s = Argmin(GCVscore).
|
|
|
|
|
|
|
|
# % Because this process is time-consuming, it is performed from
|
|
|
|
|
|
|
|
# % time to time (when nit is a power of 2)
|
|
|
|
|
|
|
|
# %---
|
|
|
|
|
|
|
|
# fminbnd(@gcv,log10(sMinBnd),log10(sMaxBnd),opt);
|
|
|
|
|
|
|
|
# end
|
|
|
|
|
|
|
|
# z = RF*idctn(Gamma.*DCTy) + (1-RF)*z;
|
|
|
|
|
|
|
|
#
|
|
|
|
|
|
|
|
# % if no weighted/missing data => tol=0 (no iteration)
|
|
|
|
|
|
|
|
# tol = isweighted*norm(z0(:)-z(:))/norm(z(:));
|
|
|
|
|
|
|
|
#
|
|
|
|
|
|
|
|
# z0 = z; % re-initialization
|
|
|
|
|
|
|
|
# end
|
|
|
|
|
|
|
|
# exitflag = nit<MaxIter;
|
|
|
|
|
|
|
|
#
|
|
|
|
|
|
|
|
# if isrobust %-- Robust Smoothing: iteratively re-weighted process
|
|
|
|
|
|
|
|
# %--- average leverage
|
|
|
|
|
|
|
|
# h = sqrt(1+16*s); h = sqrt(1+h)/sqrt(2)/h; h = h^N;
|
|
|
|
|
|
|
|
# %--- take robust weights into account
|
|
|
|
|
|
|
|
# Wtot = W.*RobustWeights(y-z,IsFinite,h,weightstr);
|
|
|
|
|
|
|
|
# %--- re-initialize for another iterative weighted process
|
|
|
|
|
|
|
|
# isweighted = true; tol = 1; nit = 0;
|
|
|
|
|
|
|
|
# %---
|
|
|
|
|
|
|
|
# RobustStep = RobustStep+1;
|
|
|
|
|
|
|
|
# RobustIterativeProcess = RobustStep<4; % 3 robust steps are enough.
|
|
|
|
|
|
|
|
# else
|
|
|
|
|
|
|
|
# RobustIterativeProcess = false; % stop the whole process
|
|
|
|
|
|
|
|
# end
|
|
|
|
|
|
|
|
# end
|
|
|
|
|
|
|
|
#
|
|
|
|
|
|
|
|
# %% Warning messages
|
|
|
|
|
|
|
|
# %---
|
|
|
|
|
|
|
|
# if isauto
|
|
|
|
|
|
|
|
# if abs(log10(s)-log10(sMinBnd))<errp
|
|
|
|
|
|
|
|
# warning('MATLAB:smoothn:SLowerBound',...
|
|
|
|
|
|
|
|
# ['s = ' num2str(s,'%.3e') ': the lower bound for s ',...
|
|
|
|
|
|
|
|
# 'has been reached. Put s as an input variable if required.'])
|
|
|
|
|
|
|
|
# elseif abs(log10(s)-log10(sMaxBnd))<errp
|
|
|
|
|
|
|
|
# warning('MATLAB:smoothn:SUpperBound',...
|
|
|
|
|
|
|
|
# ['s = ' num2str(s,'%.3e') ': the upper bound for s ',...
|
|
|
|
|
|
|
|
# 'has been reached. Put s as an input variable if required.'])
|
|
|
|
|
|
|
|
# end
|
|
|
|
|
|
|
|
# end
|
|
|
|
|
|
|
|
# if nargout<3 && ~exitflag
|
|
|
|
|
|
|
|
# warning('MATLAB:smoothn:MaxIter',...
|
|
|
|
|
|
|
|
# ['Maximum number of iterations (' int2str(MaxIter) ') has ',...
|
|
|
|
|
|
|
|
# 'been exceeded. Increase MaxIter option or decrease TolZ value.'])
|
|
|
|
|
|
|
|
# end
|
|
|
|
|
|
|
|
#
|
|
|
|
|
|
|
|
#
|
|
|
|
|
|
|
|
# %% GCV score
|
|
|
|
|
|
|
|
# %---
|
|
|
|
|
|
|
|
# function GCVscore = gcv(p)
|
|
|
|
|
|
|
|
# % Search the smoothing parameter s that minimizes the GCV score
|
|
|
|
|
|
|
|
# %---
|
|
|
|
|
|
|
|
# s = 10^p;
|
|
|
|
|
|
|
|
# Gamma = 1./(1+s*Lambda.^2);
|
|
|
|
|
|
|
|
# %--- RSS = Residual sum-of-squares
|
|
|
|
|
|
|
|
# if aow>0.9 % aow = 1 means that all of the data are equally weighted
|
|
|
|
|
|
|
|
# % very much faster: does not require any inverse DCT
|
|
|
|
|
|
|
|
# RSS = norm(DCTy(:).*(Gamma(:)-1))^2;
|
|
|
|
|
|
|
|
# else
|
|
|
|
|
|
|
|
# % take account of the weights to calculate RSS:
|
|
|
|
|
|
|
|
# yhat = idctn(Gamma.*DCTy);
|
|
|
|
|
|
|
|
# RSS = norm(sqrt(Wtot(IsFinite)).*(y(IsFinite)-yhat(IsFinite)))^2;
|
|
|
|
|
|
|
|
# end
|
|
|
|
|
|
|
|
# %---
|
|
|
|
|
|
|
|
# TrH = sum(Gamma(:));
|
|
|
|
|
|
|
|
# GCVscore = RSS/nof/(1-TrH/noe)^2;
|
|
|
|
|
|
|
|
# end
|
|
|
|
|
|
|
|
#
|
|
|
|
|
|
|
|
# end
|
|
|
|
|
|
|
|
#
|
|
|
|
|
|
|
|
# %% Robust weights
|
|
|
|
|
|
|
|
# function W = RobustWeights(r,I,h,wstr)
|
|
|
|
|
|
|
|
# % weights for robust smoothing.
|
|
|
|
|
|
|
|
# MAD = median(abs(r(I)-median(r(I)))); % median absolute deviation
|
|
|
|
|
|
|
|
# u = abs(r/(1.4826*MAD)/sqrt(1-h)); % studentized residuals
|
|
|
|
|
|
|
|
# if strcmp(wstr,'cauchy')
|
|
|
|
|
|
|
|
# c = 2.385; W = 1./(1+(u/c).^2); % Cauchy weights
|
|
|
|
|
|
|
|
# elseif strcmp(wstr,'talworth')
|
|
|
|
|
|
|
|
# c = 2.795; W = u<c; % Talworth weights
|
|
|
|
|
|
|
|
# else
|
|
|
|
|
|
|
|
# c = 4.685; W = (1-(u/c).^2).^2.*((u/c)<1); % bisquare weights
|
|
|
|
|
|
|
|
# end
|
|
|
|
|
|
|
|
# W(isnan(W)) = 0;
|
|
|
|
|
|
|
|
# end
|
|
|
|
|
|
|
|
#
|
|
|
|
|
|
|
|
# %% Test for DCTN and IDCTN
|
|
|
|
|
|
|
|
# function test4DCTNandIDCTN
|
|
|
|
|
|
|
|
# if ~exist('dctn','file')
|
|
|
|
|
|
|
|
# error('MATLAB:smoothn:MissingFunction',...
|
|
|
|
|
|
|
|
# ['DCTN and IDCTN are required. Download DCTN <a href="matlab:web(''',...
|
|
|
|
|
|
|
|
# 'http://www.biomecardio.com/matlab/dctn.html'')">here</a>.'])
|
|
|
|
|
|
|
|
# elseif ~exist('idctn','file')
|
|
|
|
|
|
|
|
# error('MATLAB:smoothn:MissingFunction',...
|
|
|
|
|
|
|
|
# ['DCTN and IDCTN are required. Download IDCTN <a href="matlab:web(''',...
|
|
|
|
|
|
|
|
# 'http://www.biomecardio.com/matlab/idctn.html'')">here</a>.'])
|
|
|
|
|
|
|
|
# end
|
|
|
|
|
|
|
|
# end
|
|
|
|
|
|
|
|
#
|
|
|
|
|
|
|
|
# %% Initial Guess with weighted/missing data
|
|
|
|
|
|
|
|
# function z = InitialGuess(y,I)
|
|
|
|
|
|
|
|
# %-- nearest neighbor interpolation (in case of missing values)
|
|
|
|
|
|
|
|
# if any(~I(:))
|
|
|
|
|
|
|
|
# if license('test','image_toolbox')
|
|
|
|
|
|
|
|
# [z,L] = bwdist(I);
|
|
|
|
|
|
|
|
# z = y;
|
|
|
|
|
|
|
|
# z(~I) = y(L(~I));
|
|
|
|
|
|
|
|
# else
|
|
|
|
|
|
|
|
# % If BWDIST does not exist, NaN values are all replaced with the
|
|
|
|
|
|
|
|
# % same scalar. The initial guess is not optimal and a warning
|
|
|
|
|
|
|
|
# % message thus appears.
|
|
|
|
|
|
|
|
# z = y;
|
|
|
|
|
|
|
|
# z(~I) = mean(y(I));
|
|
|
|
|
|
|
|
# warning('MATLAB:smoothn:InitialGuess',...
|
|
|
|
|
|
|
|
# ['BWDIST (Image Processing Toolbox) does not exist. ',...
|
|
|
|
|
|
|
|
# 'The initial guess may not be optimal; additional',...
|
|
|
|
|
|
|
|
# ' iterations can thus be required to ensure complete',...
|
|
|
|
|
|
|
|
# ' convergence. Increase ''MaxIter'' criterion if necessary.'])
|
|
|
|
|
|
|
|
# end
|
|
|
|
|
|
|
|
# else
|
|
|
|
|
|
|
|
# z = y;
|
|
|
|
|
|
|
|
# end
|
|
|
|
|
|
|
|
# %-- coarse fast smoothing using one-tenth of the DCT coefficients
|
|
|
|
|
|
|
|
# siz = size(z);
|
|
|
|
|
|
|
|
# z = dctn(z);
|
|
|
|
|
|
|
|
# for k = 1:ndims(z)
|
|
|
|
|
|
|
|
# z(ceil(siz(k)/10)+1:end,:) = 0;
|
|
|
|
|
|
|
|
# z = reshape(z,circshift(siz,[0 1-k]));
|
|
|
|
|
|
|
|
# z = shiftdim(z,1);
|
|
|
|
|
|
|
|
# end
|
|
|
|
|
|
|
|
# z = idctn(z);
|
|
|
|
|
|
|
|
# end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def kde_demo1():
|
|
|
|
def kde_demo1():
|
|
|
|
'''
|
|
|
|
'''
|
|
|
|