www.gusucode.com > mbcmodels 工具箱 matlab 源码程序 > mbcmodels/@mbcboxcox/mbcboxcox.m
classdef (Hidden) mbcboxcox < mbctransform %MBCBOXCOX Box-Cox transformation % % obj = mbcboxcox(value) % value: lambda % [lambda,shift,geomean] % {lambda,Y} % Copyright 2007-2013 The MathWorks, Inc. properties Lambda= 1; Shift = 0; Geomean = 1; Invert = false; DoUpdate = true; end properties (Dependent) BoxCox end properties (SetAccess = private,GetAccess = private) BoxCoxVersion = 1; end methods function obj = mbcboxcox(value) %MBCBOXCOX box cox transform constructor % % obj = mbcboxcox(value) if nargin obj.BoxCox = value; else obj.Lambda = 1; end end function obj = set.Lambda(obj,Value) %SET.LAMBDA set function for Lambda property obj.Lambda = Value; if obj.DoUpdate obj = update(obj); end end function obj = set.Shift(obj,Value) %SET.SHIFT set function for Shift property obj.Shift = Value; if obj.DoUpdate obj = update(obj); end end function obj = set.Geomean(obj,Value) %SET.GEOMEAN set function for Geomean property obj.Geomean = Value; if obj.DoUpdate obj = update(obj); end end function obj = set.DoUpdate(obj,Value) %SET.DOUPDATE set function for DoUpdate property obj.DoUpdate = Value; if obj.DoUpdate obj = update(obj); end end function obj = set.BoxCox(obj,value) %SET.BOXCOX set function for BoxCox property % lam % [lam shift] % {lam, Y} if ~iscell(value) % value = lambda; value={value}; end lam= value{1}(1); if length(value{1})>1; % shift is second value shift=value{1}(2); else % default is no shift shift=0; end if length(value)==2 % second element is y data; y= value{2}; y(isnan(y))=[]; % calculate shift from to ensure that all y are positive my = min(y); if my<shift shift= abs(my)+1; end y=y+shift; % Calculate the geometric mean of the data % exclude zero from mean calculation geo_mean=exp(mean(log(y(y~=0)))); else geo_mean= 1; end obj.DoUpdate = false; obj.Lambda = lam; obj.Shift = shift; obj.Geomean = geo_mean; obj.DoUpdate = true; end end methods (Access=protected) function obj = update(obj) %UPDATE update transform function % define coding transform function obj.Fcn = pMakeAnonFcn(obj.Lambda,obj.Shift,obj.Geomean); end function obj = setDerivedFunctions(obj) %SETDERIVEDFUNCTIONS form inverse and derivative functions % form inverse, derivative functions for coding transform [obj.Inv,obj.Diff,obj.DiffInv] = pMakeAnonDerived(obj.Lambda,obj.Shift,obj.Geomean); end end end function f = pMakeAnonFcn(lam,shift,geo_mean) %PMAKEANONFCN make anonymous functions for Box Cox Transform switch lam case 0 % log transform % f = @(y) log(y+shift)*geo_mean; f = str2func(sprintf('@(y) log(y+ %20.15g)*(%20.15g)',shift,geo_mean)); case 1 % no transform f = str2func('@(y) y'); otherwise scale = lam*geo_mean^(lam-1); % f= @(y) ((y+shift).^(lam) -1 )/scale; f = str2func(sprintf('@(y) ((y+(%20.15g)).^(%20.15g) -1 )/(%20.15g)',shift,lam,scale)); end end function [finv,fdiff,fdiffinv] = pMakeAnonDerived(lam,shift,geo_mean) %PMAKEANONDERIVED make anonymous functions for inverse and derivativs of Box-Cox. % Not a method - used to form anonymous function for inverse and derivative coding transform switch lam case 0 % log transform % finv = @(y) exp(y/geo_mean) - shift; finv = str2func(sprintf('@(y) exp(y/(%20.15g)) - (%20.15g)',geo_mean,shift)); % fdiff = @(y) geo_mean./(y+shift); fdiff = str2func(sprintf('@(y) (%20.15g)./(y+(%20.15g))',geo_mean,shift)); % fdiff = @(y) exp(y/geo_mean)/geo_mean; fdiffinv = str2func(sprintf('@(y) exp(y/(%20.15g))/(%20.15g)',geo_mean,geo_mean)); case 1 % no transform finv = str2func('@(y) y'); fdiff = str2func('@(y) 1'); fdiffinv= str2func('@(y) 1'); otherwise scale = lam*geo_mean^(lam-1); % finv= @(y) (scale*y+1).^(1/lam)-shift; finv= str2func(sprintf('@(y) ((%20.15g)*y+1).^(%20.15g)-(%20.15g)',scale,1/lam,shift)); % fdiff = @(y) (lam/scale)*(y+shift).^(lam-1); fdiff = str2func(sprintf('@(y) (%20.15g)*(y+(%20.15g)).^(%20.15g)',lam/scale,shift,lam-1)); %fdiffinv = @(y) (scale*y+1).^(1/lam-1)*scale/lam; fdiffinv = str2func(sprintf('@(y) (%20.15g)*((%20.15g)*y+1).^(%20.15g)',scale/lam,scale,1/lam-1)); end end