% pskdemo.m by drb on 13-Feb-2004
% modified by drb on 14-Feb-2005
% function [y,e,pe]=pskdemo(M,Eb,N0,NumberOfOutputs);
%
% y contains the noisy PSK symbols
% e is the symbol error rate (actual)
% pe is the predicted symbol error rate
%
% M is the number of distinct PSK symbols
% Eb is the desired energy per bit
% N0 is the desired noise PSD (it's actually N0/2, you just spec N0)
% NumberofOutputs is the the total number of correlator outputs to generate

function [y,e,pe]=pskdemo(M,Eb,N0,NumberOfOutputs);

% Set up constellation points
A=[cos(2*pi*[0:M-1]/M) ; sin(2*pi*[0:M-1]/M)];
Es=log2(M)*Eb;			% energy per symbol
A=A*sqrt(Es);			% scale alphabet so it has the desired Eb

% Make symbols
index=ceil(rand(1,NumberOfOutputs)*M);	% index 1 to M
S=A(:,index);				% M-PSK symbols with correct Eb

% Make Gaussian noise with correct variance
n=sqrt(N0/2)*randn(2,NumberOfOutputs);  % uncorrelated noise

y=S+n;					% generate outputs

% Compute symbol error rate
decisionindex=zeros(1,NumberOfOutputs);
for i=1:NumberOfOutputs,
    % find minimum distance constellation point
    [junk,decisionindex(i)]=min(sum((y(:,i)*ones(1,M)-A).^2));
end
e=sum(decisionindex~=index)/NumberOfOutputs;
pe=erfc(sqrt(log2(M)*Eb/N0)*sin(pi/M));