No BSD License  

Highlights from
BPSK Simulator for Low Rate Transmisions

image thumbnail
from BPSK Simulator for Low Rate Transmisions by César Delgado González
BPSK Simulator for didactical purposes. Systemic coding style.

eyediagram(x, n, period, offset, plotstring, h)
function varargout = eyediagram(x, n, period, offset, plotstring, h)
%EYEDIAGRAM Generate an eye diagram.
%   EYEDIAGRAM(X, N) generates an eye diagram of X with N samples per
%   trace.  N must be an integer greater than 1.  X can be a real or complex
%   vector, or a two-column matrix with real signal in the first column and
%   imaginary signal in the second column.  If X is a real vector, EYEDIAGRAM
%   generates one eye diagram.  If X is a two-column matrix or a complex
%   vector, EYEDIAGRAM generates two eye diagrams, one for the real (in-phase)
%   signal and one for the imaginary (quadrature) signal.  EYEDIAGRAM plots
%   X with the first point and every Nth point thereafter centered on the
%   horizontal axis.
%
%   EYEDIAGRAM(X, N, PERIOD) generates an eye diagram of X with specified trace
%   period.  PERIOD is used to determine the horizontal axis limits.  PERIOD
%   must be a positive number.  The horizontal axis limits are -PERIOD/2 and
%   +PERIOD/2.  The default value of PERIOD is 1.
%
%   EYEDIAGRAM(X, N, PERIOD, OFFSET) generates an eye diagram of X with an
%   offset.  OFFSET determines which points are centered on the horizontal axis
%   starting with the (OFFSET+1)st point and every Nth point thereafter.  OFFSET
%   must be a nonnegative integer in the range 0 <= OFFSET < N.  The default
%   value for OFFSET is 0.
%
%   EYEDIAGRAM(X, N, PERIOD, OFFSET, PLOTSTRING) generates an eye diagram of X
%   in the line types, plot symbols and colors described by PLOTSTRING.
%   PLOTSTRING can be any of the strings used in the PLOT function. The default
%   value for PLOTSTRING is 'b-'.
%
%   H = EYEDIAGRAM(...) generates an eye diagram and returns a handle
%   to the figure used to plot the eye diagram.
%
%   H = EYEDIAGRAM(X, N, PERIOD, OFFSET, PLOTSTRING, H) and
%   EYEDIAGRAM(X, N, PERIOD, OFFSET, PLOTSTRING, H) generate eye diagrams using
%   the figure handle, H.  H must be a valid handle to a figure that was
%   previously generated by EYEDIAGRAM.  Default value for H is [] which causes
%   EYEDIAGRAM to create a new figure.  The HOLD function does not work for
%   EYEDIAGRAM figures.
%
%   See also SCATTERPLOT, PLOT, SCATTEREYEDEMO.

%   Copyright 1996-2002 The MathWorks, Inc.
%   $Revision: 1.5 $ $Date: 2002/03/07 15:33:38 $

%error(nargchk(2,6,nargin));
%error(nargoutchk(0,1,nargout));
if nargin < 3
    period = 1;
end;

if nargin < 4
    offset = 0;
end;

if nargin < 5
    plotstring = 'b-';
end;

if nargin < 6
    h = [];
end;

[r, c] = size(x);
if r * c == 0
    error('Input variable X is empty.')
end;
% don't allow t to be zero or negative
if (period <= 0)
    error('PERIOD must be a positive number.')
end

% don't allow n to be noninteger or less than or equal zero
if ((floor(n) ~= n) | (n <= 1))
    error('N must be an integer greater than 1.')
end

% don't allow offset to be outside of the range 0 <= offset < n
if ((floor(offset) ~= offset) | (offset < 0) | (offset >= n))
    error('OFFSET must be a integer in the range 0 <= OFFSET < N.')
end

% flatten input
if r == 1
    x = x(:);
end;

% Complex number processing
if ~isreal(x) > 0
    x = [real(x), imag(x)];
end;
maxAll = max(max(abs(x)));

% generate normalized time values
[len_x, wid_x]=size(x);
t = rem([0 : (len_x-1)]/n, 1)';

% wrap right half of time values around to the left
tmp = find(t > rem((offset/n+0.5),1) + eps^(2/3));
t(tmp) = t(tmp) - 1;

% if t = zero is at an edge, make it the left edge
if(max(t)<=0)
    t = t + 1;
end;


% determine the right-hand edge points
% for zero offset, the index value of the first edge is floor(n/2)+1
index = fliplr([1+rem(offset+floor(n/2),n) : n : len_x]);

% for plotting, insert NaN values into both x and t after each edge point
% to define the left edge,after the NaNs repeat the ith value of x
% and insert a value that is (period/n) less than the (i+1)th value of t
NN = ones(1, wid_x) * NaN;
for ii = 1 : length(index)
    i = index(ii);
    if i < len_x
        x = [x(1:i,:);   NN;     x(i,:); x(i+1:size(x, 1),:)];
        t = [t(1:i);    NaN; t(i+1)-1/n; t(i+1:size(t, 1))  ];
    end;
end;

% adjust the time values to ensure that the x axis remains fixed
half_n = n/2-1;
modoffset = rem(offset+half_n,n)-half_n;
t = rem(t-modoffset/n,1);

% scale time values by period
t = t*period;

% Create new figure or reuse existing handle
strName = 'Eye Diagram';
if(~isempty(h))
    if(~ishandle(h) | ~strcmp(get(h,'Type'),'figure'))
        warning('Ignoring invalid handle H. Creating a new eye diagram.')
        h = figure('visible','off');
        isNewFig = 1;
    else
        if(~strcmp(get(h,'Tag'),strName))
            strErr = sprintf(['Figure is not an existing eye diagram.\n' ...
                'Use an existing eye diagram or do not use a figure ' ...
                'handle as an input']);
            error(strErr);
        end
        h = figure(h);
        isNewFig = 0;
    end
else
    h = figure('visible','off');
    isNewFig = 1;
end

% setup for the eye diagram
limFact = 1.05;
sigName = {'for In-Phase Signal', 'for Quadrature Signal'};
pos = get(h,'position');
sizPlotC = [460   360];
sizPlotR = [460   540];

% plot one figure or two, based on the number of columns in x
switch size(x, 2)
case 1
    % Real Signal Procesing
    if(isNewFig)
        set(h,'position',[pos(1:2)-sizPlotC(1:2)/2  sizPlotC(1:2)], ...
            'Name',strName,'Tag',strName, 'visible','on', ...
            'DoubleBuffer','on');
    else
        clf;
        if(pos(3:4) == [460   540])
            set(h,'position',[pos(1:2)+[0 (sizPlotR(2)-sizPlotC(2))]  sizPlotC(1:2)]);
        end
    end
    plotEye(t, x, plotstring, '');
    axo = axis;
    yLimits = maxAll * limFact;
    axx=[min(t), max(t), min(-yLimits,min(axo(3))), max(yLimits,max(axo(4)))];
    axis(axx);
case 2
    % Complex Signal Procesing
    if(isNewFig)
        set(h,'position',[pos(1:2)-sizPlotR(1:2)/2  sizPlotR(1:2)], ...
            'Name',strName,'Tag',strName, 'visible','on', ...
            'DoubleBuffer','on');
    else
        clf;
        if(pos(3:4) == [460   360])
            set(h,'position',[pos(1:2)+[0 (sizPlotC(2)-sizPlotR(2))]  sizPlotR(1:2)]);
        end
    end
    for idx = [1,2]
    	ha(idx) = subplot(2,1,idx);
    	plotEye(t, x(:,idx), plotstring, char(sigName(idx)));
        axo(idx,:) = axis;
    end    
    yLimits = maxAll * limFact;
    axx=[min(t), max(t), min(-yLimits,min(axo(:,3))), max(yLimits,max(axo(:,4)))];
    for idx = [1,2]
        subplot(2,1,idx);
        axis(axx);
        grid on;
    end

otherwise
    error('Number of columns in the input data, X, cannot exceed 2.')
end
set(h,'nextplot','replacechildren');

if(nargout == 1)
    varargout(1) = {h};
end


function plotEye(t,x, plotstring, strSubTitle)
% plotEye does the plotting, and labeling for the eye diagram

plot(t, x, plotstring);
xlabel('Time');
ylabel('Amplitude');
title(['Eye Diagram ' strSubTitle]);


Contact us at files@mathworks.com