将以下两个.m文件放到同一文件夹内运行
ps:这两个m文件来自 "MATLAB\R2009a\toolbox\comm\comm"
awgn.m
function y=awgn(varargin) %AWGN Add white Gaussian noise to a signal. % Y = AWGN(X,SNR) adds white Gaussian noise to X. The SNR is in dB. % The power of X is assumed to be 0 dBW. If X is complex, then % AWGN adds complex noise. % % Y = AWGN(X,SNR,SIGPOWER) when SIGPOWER is numeric, it represents % the signal power in dBW. When SIGPOWER is 'measured', AWGN measures % the signal power before adding noise. % % Y = AWGN(X,SNR,SIGPOWER,STATE) resets the state of RANDN to STATE. % % Y = AWGN(..., POWERTYPE) specifies the units of SNR and SIGPOWER. % POWERTYPE can be 'db' or 'linear'. If POWERTYPE is 'db', then SNR % is measured in dB and SIGPOWER is measured in dBW. If POWERTYPE is % 'linear', then SNR is measured as a ratio and SIGPOWER is measured % in Watts. % % Example 1: % % To specify the power of X to be 0 dBW and add noise to produce % % an SNR of 10dB, use: % X = sqrt(2)*sin(0:pi/8:6*pi); % Y = awgn(X,10,0); % % Example 2: % % To specify the power of X to be 3 Watts and add noise to % % produce a linear SNR of 4, use: % X = sqrt(2)*sin(0:pi/8:6*pi); % Y = awgn(X,4,3,'linear'); % % Example 3: % % To cause AWGN to measure the power of X and add noise to % % produce a linear SNR of 4, use: % X = sqrt(2)*sin(0:pi/8:6*pi); % Y = awgn(X,4,'measured','linear'); % % See also WGN, RANDN, and BSC. % Copyright 1996-2008 The MathWorks, Inc. % $Revision: 1.9.4.6 $ $Date: 2008/08/22 20:23:43 $ % --- Initial checks error(nargchk(2,5,nargin,'struct')); % --- Value set indicators (used for the string flags) pModeSet = 0; measModeSet = 0; % --- Set default values sigPower = 0; pMode = 'db'; measMode = 'specify'; state = []; % --- Placeholder for the signature string sigStr = ''; % --- Identify string and numeric arguments for n=1:nargin if(n>1) sigStr(size(sigStr,2)+1) = '/'; end % --- Assign the string and numeric flags if(ischar(varargin{n})) sigStr(size(sigStr,2)+1) = 's'; elseif(isnumeric(varargin{n})) sigStr(size(sigStr,2)+1) = 'n'; else error('comm:awgn:InvalidArg','Only string and numeric arguments are allowed.'); end end % --- Identify parameter signatures and assign values to variables switch sigStr % --- awgn(x, snr) case 'n/n' sig = varargin{1}; reqSNR = varargin{2}; % --- awgn(x, snr, sigPower) case 'n/n/n' sig = varargin{1}; reqSNR = varargin{2}; sigPower = varargin{3}; % --- awgn(x, snr, 'measured') case 'n/n/s' sig = varargin{1}; reqSNR = varargin{2}; measMode = lower(varargin{3}); measModeSet = 1; % --- awgn(x, snr, sigPower, state) case 'n/n/n/n' sig = varargin{1}; reqSNR = varargin{2}; sigPower = varargin{3}; state = varargin{4}; % --- awgn(x, snr, 'measured', state) case 'n/n/s/n' sig = varargin{1}; reqSNR = varargin{2}; measMode = lower(varargin{3}); state = varargin{4}; measModeSet = 1; % --- awgn(x, snr, sigPower, 'db|linear') case 'n/n/n/s' sig = varargin{1}; reqSNR = varargin{2}; sigPower = varargin{3}; pMode = lower(varargin{4}); pModeSet = 1; % --- awgn(x, snr, 'measured', 'db|linear') case 'n/n/s/s' sig = varargin{1}; reqSNR = varargin{2}; measMode = lower(varargin{3}); pMode = lower(varargin{4}); measModeSet = 1; pModeSet = 1; % --- awgn(x, snr, sigPower, state, 'db|linear') case 'n/n/n/n/s' sig = varargin{1}; reqSNR = varargin{2}; sigPower = varargin{3}; state = varargin{4}; pMode = lower(varargin{5}); pModeSet = 1; % --- awgn(x, snr, 'measured', state, 'db|linear') case 'n/n/s/n/s' sig = varargin{1}; reqSNR = varargin{2}; measMode = lower(varargin{3}); state = varargin{4}; pMode = lower(varargin{5}); measModeSet = 1; pModeSet = 1; otherwise error('comm:awgn:InvalidSyntax','Syntax error.'); end % --- Parameters have all been set, either to their defaults or by the values passed in, % so perform range and type checks % --- sig if(isempty(sig)) error('comm:awgn:NoInput','An input signal must be given.'); end if(ndims(sig)>2) error('comm:awgn:InvalidSignalDims','The input signal must have 2 or fewer dimensions.'); end % --- measMode if(measModeSet) if(~strcmp(measMode,'measured')) error('comm:awgn:InvalidSigPower','The signal power parameter must be numeric or ''measured''.'); end end % --- pMode if(pModeSet) switch pMode case {'db' 'linear'} otherwise error('comm:awgn:InvalidPowerType','The signal power mode must be ''db'' or ''linear''.'); end end % -- reqSNR if(any([~isreal(reqSNR) (length(reqSNR)>1) (isempty(reqSNR))])) error('comm:awgn:InvalidSNR','The signal-to-noise ratio must be a real scalar.'); end if(strcmp(pMode,'linear')) if(reqSNR<=0) error('comm:awgn:InvalidSNRForLinearMode','In linear mode, the signal-to-noise ratio must be > 0.'); end end % --- sigPower if(~strcmp(measMode,'measured')) % --- If measMode is not 'measured', then the signal power must be specified if(any([~isreal(sigPower) (length(sigPower)>1) (isempty(sigPower))])) error('comm:awgn:InvalidSigPower','The signal power value must be a real scalar.'); end if(strcmp(pMode,'linear')) if(sigPower<0) error('comm:awgn:InvalidSigPowerForLinearMode','In linear mode, the signal power must be >= 0.'); end end end % --- state if(~isempty(state)) if(any([~isreal(state) (length(state)>1) (isempty(state)) any((state-floor(state))~=0)])) error('comm:awgn:InvaildState','The State must be a real, integer scalar.'); end end % --- All parameters are valid, so no extra checking is required % --- Check the signal power. This needs to consider power measurements on matrices if(strcmp(measMode,'measured')) sigPower = sum(abs(sig(:)).^2)/length(sig(:)); if(strcmp(pMode,'db')) sigPower = 10*log10(sigPower); end end % --- Compute the required noise power switch lower(pMode) case 'linear' noisePower = sigPower/reqSNR; case 'db' noisePower = sigPower-reqSNR; pMode = 'dbw'; end % --- Add the noise if(isreal(sig)) opType = 'real'; else opType = 'complex'; end y = sig+wgn(size(sig,1), size(sig,2), noisePower, 1, state, pMode, opType);
wgn.m
function y = wgn(varargin) %WGN Generate white Gaussian noise. % Y = WGN(M,N,P) generates an M-by-N matrix of white Gaussian noise. % P specifies the power of the output noise in dBW. % % Y = WGN(M,N,P,IMP) specifies the load impedance in Ohms. % % Y = WGN(M,N,P,IMP,STATE) resets the state of RANDN to STATE. % % Additional flags that can follow the numeric arguments are: % % Y = WGN(..., POWERTYPE) specifies the units of P. POWERTYPE can % be 'dBW', 'dBm' or 'linear'. Linear power is in Watts. % % Y = WGN(..., OUTPUTTYPE); Specifies the output type. OUTPUTTYPE can % be 'real' or 'complex'. If the output type is complex, then P % is divided equally between the real and imaginary components. % % Example 1: % % To generate a 1024-by-1 vector of complex noise with power % % of 5 dBm across a 50 Ohm load, use: % Y = wgn(1024, 1, 5, 50, 'dBm', 'complex') % % Example 2: % % To generate a 256-by-5 matrix of real noise with power % % of 10 dBW across a 1 Ohm load, use: % Y = wgn(256, 5, 10, 'real') % % Example 3: % % To generate a 1-by-10 vector of complex noise with power % % of 3 Watts across a 75 Ohm load, use: % Y = wgn(1, 10, 3, 75, 'linear', 'complex') % % See also RANDN, AWGN. % Copyright 1996-2008 The MathWorks, Inc. % $Revision: 1.11.4.5 $ $Date: 2008/08/01 12:17:45 $ % --- Initial checks error(nargchk(3,7,nargin,'struct')); % --- Value set indicators (used for the strings) pModeSet = 0; cplxModeSet = 0; % --- Set default values p = []; row = []; col = []; pMode = 'dbw'; imp = 1; cplxMode = 'real'; seed = []; % --- Placeholders for the numeric and string index values numArg = []; strArg = []; % --- Identify string and numeric arguments % An empty in position 4 (Impedance) or 5 (Seed) are considered numeric for n=1:nargin if(isempty(varargin{n})) switch n case 4 if(ischar(varargin{n})) error('comm:wgn:InvalidDefaultImp','The default impedance should be marked by [].'); end; varargin{n} = imp; % Impedance has a default value case 5 if(ischar(varargin{n})) error('comm:wgn:InvalidNumericInput','The default seed should be marked by [].'); end; varargin{n} = []; % Seed has no default otherwise varargin{n} = ''; end; end; % --- Assign the string and numeric vectors if(ischar(varargin{n})) strArg(size(strArg,2)+1) = n; elseif(isnumeric(varargin{n})) numArg(size(numArg,2)+1) = n; else error('comm:wgn:InvalidArg','Only string and numeric arguments are allowed.'); end; end; % --- Build the numeric argument set switch(length(numArg)) case 3 % --- row is first (element 1), col (element 2), p (element 3) if(all(numArg == [1 2 3])) row = varargin{numArg(1)}; col = varargin{numArg(2)}; p = varargin{numArg(3)}; else error('comm:wgn:InvalidSyntax','Illegal syntax.') end; case 4 % --- row is first (element 1), col (element 2), p (element 3), imp (element 4) % if(all(numArg(1:3) == [1 2 3])) row = varargin{numArg(1)}; col = varargin{numArg(2)}; p = varargin{numArg(3)}; imp = varargin{numArg(4)}; else error('comm:wgn:InvalidSyntax','Illegal syntax.') end; case 5 % --- row is first (element 1), col (element 2), p (element 3), imp (element 4), seed (element 5) if(all(numArg(1:3) == [1 2 3])) row = varargin{numArg(1)}; col = varargin{numArg(2)}; p = varargin{numArg(3)}; imp = varargin{numArg(4)}; seed = varargin{numArg(5)}; else error('comm:wgn:InvalidSyntax','Illegal syntax.'); end; otherwise error('comm:wgn:InvalidSyntax','Illegal syntax.'); end; % --- Build the string argument set for n=1:length(strArg) switch lower(varargin{strArg(n)}) case {'dbw' 'dbm' 'linear'} if(~pModeSet) pModeSet = 1; pMode = lower(varargin{strArg(n)}); else error('comm:wgn:TooManyPowerTypes','The Power mode must only be set once.'); end; case {'db'} error('comm:wgn:InvalidPowerType','Incorrect power mode passed in. Please use ''dBW'', ''dBm'', or ''linear.'''); case {'real' 'complex'} if(~cplxModeSet) cplxModeSet = 1; cplxMode = lower(varargin{strArg(n)}); else error('comm:wgn:TooManyOutputTypes','The complexity mode must only be set once.'); end; otherwise error('comm:wgn:InvalidArgOption','Unknown option passed in.'); end; end; % --- Arguments and defaults have all been set, either to their defaults or by the values passed in % so, perform range and type checks % --- p if(isempty(p)) error('comm:wgn:InvalidPowerVal','The power value must be a real scalar.'); end; if(any([~isreal(p) (length(p)>1) (length(p)==0)])) error('comm:wgn:InvalidPowerVal','The power value must be a real scalar.'); end; if(strcmp(pMode,'linear')) if(p<0) error('comm:wgn:NegativePower','In linear mode, the required noise power must be >= 0.'); end; end; % --- Dimensions if(any([isempty(row) isempty(col) ~isscalar(row) ~isscalar(col)])) error('comm:wgn:InvalidDims','The required dimensions must be real, integer scalars > 1.'); end; if(any([(row<=0) (col<=0) ~isreal(row) ~isreal(col) ((row-floor(row))~=0) ((col-floor(col))~=0)])) error('comm:wgn:InvalidDims','The required dimensions must be real, integer scalars > 1.'); end; % --- Impedance if(any([~isreal(imp) (length(imp)>1) (length(imp)==0) any(imp<=0)])) error('comm:wgn:InvalidImp','The Impedance value must be a real scalar > 0.'); end; % --- Seed if(~isempty(seed)) if(any([~isreal(seed) (length(seed)>1) (length(seed)==0) any((seed-floor(seed))~=0)])) error('comm:wgn:InvalidState','The State must be a real, integer scalar.'); end; end; % --- All parameters are valid, so no extra checking is required switch lower(pMode) case 'linear' noisePower = p; case 'dbw' noisePower = 10^(p/10); case 'dbm' noisePower = 10^((p-30)/10); end; % --- Generate the noise if(~isempty(seed)) randn('state',seed); end; if(strcmp(cplxMode,'complex')) z = randn(2*row,col); y = (sqrt(imp*noisePower/2))*(z(1:row,:)+j*z(row+1:end,:)); else y = (sqrt(imp*noisePower))*randn(row,col); end;