Updates to smoothn

master
per.andreas.brodtkorb 13 years ago
parent dd0c86e59b
commit d20cb4dac1

@ -15,6 +15,7 @@ from misc import tranproc #, trangood
from numpy import pi, sqrt, atleast_2d, exp, newaxis #@UnresolvedImport from numpy import pi, sqrt, atleast_2d, exp, newaxis #@UnresolvedImport
from scipy import interpolate, linalg, sparse from scipy import interpolate, linalg, sparse
from scipy.special import gamma from scipy.special import gamma
from scipy.ndimage.morphology import distance_transform_edt
import scipy.special as special import scipy.special as special
import scipy.optimize as optimize import scipy.optimize as optimize
from wafo.misc import meshgrid, nextpow2 from wafo.misc import meshgrid, nextpow2
@ -3027,232 +3028,213 @@ def unfinished_smoothn(data,s=None, weight=None, robust=False, z0=None, tolz=1e-
# Weights. Zero weights are assigned to not finite values (Inf or NaN), # Weights. Zero weights are assigned to not finite values (Inf or NaN),
# (Inf/NaN values = missing data). # (Inf/NaN values = missing data).
IsFinite = np.isfinite(y); IsFinite = np.isfinite(y)
nof = sum(IsFinite) # number of finite elements nof = IsFinite.sum() # number of finite elements
W = W * IsFinite W = W * IsFinite
if any(W<0): if (W<0).any():
raise ValueError('Weights must all be >=0') raise ValueError('Weights must all be >=0')
else: else:
W = W/W.max() W = W/W.max()
# Weighted or missing data?
isweighted = (W<1).any()
#% Weighted or missing data?
# isweighted = any(W(:)<1); # Automatic smoothing?
# %--- isauto = s is None
# % Robust smoothing? # Creation of the Lambda tensor
# isrobust = any(strcmpi(varargin,'robust')); # Lambda contains the eingenvalues of the difference matrix used in this
# %--- # penalized least squares process.
# % Automatic smoothing? d = y.ndim
# isauto = isempty(s); Lambda = zeros(sizy)
# %--- siz0 = (1,)*d
# % DCTN and IDCTN are required for i in range(d):
# test4DCTNandIDCTN siz0[i] = sizy(i)
# Lambda = Lambda + cos(pi*np.arange(sizy(i))/sizy[i]).reshape(siz0)
# %% Creation of the Lambda tensor siz0[i] = 1
# %---
# % Lambda contains the eingenvalues of the difference matrix used in this Lambda = -2*(d-Lambda)
# % penalized least squares process. if not isauto:
# d = ndims(y); Gamma = 1./(1 + s * Lambda ** 2)
# Lambda = zeros(sizy);
# for i = 1:d # Upper and lower bound for the smoothness parameter
# siz0 = ones(1,d); # The average leverage (h) is by definition in [0 1]. Weak smoothing occurs
# siz0(i) = sizy(i); # if h is close to 1, while over-smoothing appears when h is near 0. Upper
# Lambda = bsxfun(@plus,Lambda,... # and lower bounds for h are given to avoid under- or over-smoothing. See
# cos(pi*(reshape(1:sizy(i),siz0)-1)/sizy(i))); # equation relating h to the smoothness parameter (Equation #12 in the
# end # referenced CSDA paper).
# Lambda = -2*(d-Lambda); N = (np.array(sizy)!=1).sum() # tensor rank of the y-array
# if ~isauto, Gamma = 1./(1+s*Lambda.^2); end hMin = 1e-6;
# hMax = 0.99;
# %% Upper and lower bound for the smoothness parameter sMinBnd = (((1+sqrt(1+8*hMax**(2/N)))/4./hMax**(2/N))**2-1)/16
# % The average leverage (h) is by definition in [0 1]. Weak smoothing occurs sMaxBnd = (((1+sqrt(1+8*hMin**(2/N)))/4./hMin**(2/N))**2-1)/16
# % 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 # Initialize before iterating
# % equation relating h to the smoothness parameter (Equation #12 in the
# % referenced CSDA paper). Wtot = W;
# N = sum(sizy~=1); % tensor rank of the y-array # Initial conditions for z
# hMin = 1e-6; hMax = 0.99; if weight is None:
# sMinBnd = (((1+sqrt(1+8*hMax.^(2/N)))/4./hMax.^(2/N)).^2-1)/16; z = zeros(sizy)
# sMaxBnd = (((1+sqrt(1+8*hMin.^(2/N)))/4./hMin.^(2/N)).^2-1)/16; else:
# # With weighted/missing data
# %% Initialize before iterating # An initial guess is provided to ensure faster convergence. For that
# %--- # purpose, a nearest neighbor interpolation followed by a coarse
# Wtot = W; # smoothing are performed.
# %--- Initial conditions for z
# if isweighted if z0 is None:
# %--- With weighted/missing data z = InitialGuess(y,IsFinite);
# % An initial guess is provided to ensure faster convergence. For that else:
# % purpose, a nearest neighbor interpolation followed by a coarse # an initial guess (z0) has been provided
# % smoothing are performed. z = z0
# %--- z0 = z
# if isinitial % an initial guess (z0) has been provided y[1-IsFinite] = 0 # arbitrary values for missing y-data
# z = z0;
# else tol = 1
# z = InitialGuess(y,IsFinite); RobustIterativeProcess = True
# end RobustStep = 1;
# else nit = 0;
# z = zeros(sizy); # Error on p. Smoothness parameter s = 10^p
# end errp = 0.1;
# %--- opt = optimset('TolX',errp);
# z0 = z; # Relaxation factor RF: to speedup convergence
# y(~IsFinite) = 0; % arbitrary values for missing y-data RF = 1 + 0.75 if weight else 1.0
# %---
# tol = 1; # Main iterative process
# RobustIterativeProcess = true; while RobustIterativeProcess
# RobustStep = 1; # "amount" of weights (see the function GCVscore)
# nit = 0; aow = Wtot.sum()/noe # 0 < aow <= 1
# %--- Error on p. Smoothness parameter s = 10^p
# errp = 0.1; while tol>TolZ && nit<MaxIter
# opt = optimset('TolX',errp); nit = nit+1;
# %--- Relaxation factor RF: to speedup convergence DCTy = dctn(Wtot*(y-z)+z)
# RF = 1 + 0.75*isweighted; if isauto and not rem(log2(nit),1):
#
# %% Main iterative process # The generalized cross-validation (GCV) method is used.
# %--- # We seek the smoothing parameter s that minimizes the GCV
# while RobustIterativeProcess # score i.e. s = Argmin(GCVscore).
# %--- "amount" of weights (see the function GCVscore) # Because this process is time-consuming, it is performed from
# aow = sum(Wtot(:))/noe; % 0 < aow <= 1 # time to time (when nit is a power of 2)
# %--- fminbnd(@gcv,log10(sMinBnd),log10(sMaxBnd),opt);
# while tol>TolZ && nit<MaxIter
# nit = nit+1; z = RF*idctn(Gamma*DCTy) + (1-RF)*z
# DCTy = dctn(Wtot.*(y-z)+z);
# if isauto && ~rem(log2(nit),1) # if no weighted/missing data => tol=0 (no iteration)
# %--- tol = norm(z0(:)-z(:))/norm(z(:)) if weight else 0.0
# % The generalized cross-validation (GCV) method is used.
# % We seek the smoothing parameter s that minimizes the GCV z0 = z # re-initialization
# % score i.e. s = Argmin(GCVscore). end
# % Because this process is time-consuming, it is performed from exitflag = nit<MaxIter;
# % time to time (when nit is a power of 2)
# %--- if robust: #-- Robust Smoothing: iteratively re-weighted process
# fminbnd(@gcv,log10(sMinBnd),log10(sMaxBnd),opt); #--- average leverage
# end h = sqrt(1+16*s)
# z = RF*idctn(Gamma.*DCTy) + (1-RF)*z; h = sqrt(1+h)/sqrt(2)/h;
# h = h**N
# % if no weighted/missing data => tol=0 (no iteration) # take robust weights into account
# tol = isweighted*norm(z0(:)-z(:))/norm(z(:)); Wtot = W*RobustWeights(y-z, IsFinite, h, weightstr)
# #re-initialize for another iterative weighted process
# z0 = z; % re-initialization isweighted = true;
# end tol = 1;
# exitflag = nit<MaxIter; nit = 0;
#
# 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(:)); RobustStep = RobustStep+1;
# GCVscore = RSS/nof/(1-TrH/noe)^2; RobustIterativeProcess = RobustStep<4; # 3 robust steps are enough.
# end else:
# RobustIterativeProcess = False # stop the whole process
# end
#
# %% Robust weights
# function W = RobustWeights(r,I,h,wstr) # Warning messages
# % weights for robust smoothing. if isauto
# MAD = median(abs(r(I)-median(r(I)))); % median absolute deviation if abs(log10(s)-log10(sMinBnd))<errp
# u = abs(r/(1.4826*MAD)/sqrt(1-h)); % studentized residuals warnings.warn('''s = %g: the lower bound for s has been reached.
# if strcmp(wstr,'cauchy') Put s as an input variable if required.''' % s)
# c = 2.385; W = 1./(1+(u/c).^2); % Cauchy weights elif abs(log10(s)-log10(sMaxBnd))<errp:
# elseif strcmp(wstr,'talworth') warnings.warn('''s = %g: the Upper bound for s has been reached.
# c = 2.795; W = u<c; % Talworth weights Put s as an input variable if required.''' % s)
# else
# c = 4.685; W = (1-(u/c).^2).^2.*((u/c)<1); % bisquare weights if nargout<3 && ~exitflag
# end warning('MATLAB:smoothn:MaxIter',...
# W(isnan(W)) = 0; ['Maximum number of iterations (' int2str(MaxIter) ') has ',...
# end 'been exceeded. Increase MaxIter option or decrease TolZ value.'])
# end
# %% Test for DCTN and IDCTN
# function test4DCTNandIDCTN def gcv(p, Lambda, DCTy, y, Wtot, IsFinite, nof, noe):
# if ~exist('dctn','file') # Search the smoothing parameter s that minimizes the GCV score
# error('MATLAB:smoothn:MissingFunction',... s = 10**p
# ['DCTN and IDCTN are required. Download DCTN <a href="matlab:web(''',... Gamma = 1./(1+s*Lambda**2)
# 'http://www.biomecardio.com/matlab/dctn.html'')">here</a>.']) # RSS = Residual sum-of-squares
# elseif ~exist('idctn','file') if aow>0.9: # aow = 1 means that all of the data are equally weighted
# error('MATLAB:smoothn:MissingFunction',... # very much faster: does not require any inverse DCT
# ['DCTN and IDCTN are required. Download IDCTN <a href="matlab:web(''',... RSS = norm(DCTy.ravel()*(Gamma.ravel()-1))**2
# 'http://www.biomecardio.com/matlab/idctn.html'')">here</a>.']) else:
# end # take account of the weights to calculate RSS:
# end yhat = idctn(Gamma*DCTy)
# RSS = norm(sqrt(Wtot[IsFinite])*(y[IsFinite]-yhat[IsFinite]))**2
# %% Initial Guess with weighted/missing data end
# function z = InitialGuess(y,I)
# %-- nearest neighbor interpolation (in case of missing values) TrH = Gamma.sum()
# if any(~I(:)) GCVscore = RSS/nof/(1.0-TrH/noe)**2
# if license('test','image_toolbox') return GCVScore
# [z,L] = bwdist(I);
# z = y;
# z(~I) = y(L(~I)); # Robust weights
# else def RobustWeights(r,I,h,wstr):
# % If BWDIST does not exist, NaN values are all replaced with the #weights for robust smoothing.
# % same scalar. The initial guess is not optimal and a warning MAD = median(abs(r[I]-median(r[I]))) # median absolute deviation
# % message thus appears. u = abs(r/(1.4826*MAD)/sqrt(1-h)) # studentized residuals
# z = y; if wstr == 'cauchy':
# z(~I) = mean(y(I)); c = 2.385;
# warning('MATLAB:smoothn:InitialGuess',... W = 1./(1+(u/c).^2); % Cauchy weights
# ['BWDIST (Image Processing Toolbox) does not exist. ',... elif wstr=='talworth':
# 'The initial guess may not be optimal; additional',... c = 2.795;
# ' iterations can thus be required to ensure complete',... W = u<c # Talworth weights
# ' convergence. Increase ''MaxIter'' criterion if necessary.']) else:
# end c = 4.685
# else W = (1-(u/c)**2)**2*((u/c)<1) # bisquare weights
# z = y;
# end W[isnan(W)] = 0
# %-- coarse fast smoothing using one-tenth of the DCT coefficients return W
# 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])); # Initial Guess with weighted/missing data
# z = shiftdim(z,1); def z = InitialGuess(y,I):
# end # nearest neighbor interpolation (in case of missing values)
# z = idctn(z); if any(~I(:))
# end if license('test','image_toolbox')
z, L = distance_transform_edt(1-I, return_indices=True)
[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);
return z
def kde_demo1(): def kde_demo1():

Loading…
Cancel
Save