function u = prbs(n, mue, M, V, o)
% u = prbs(n, mue, M, V, o) 
%
% u   = Pseudo-Random-Binary-Sequence 
%
% n   = order of m-sequence with length N = 2 ^ n - 1
% mue = stretches every sequence member mue-times = integer multiple
%       of sampling time delta, so that clocktime deltat = mue * delta
%       and length of u becomes N * mue
% M   = integer number of periods in u,
%       so that length of u becomes N * mue * M  
% V   = amplitude of sequence, so that levels are -V and +V
% o   = you may choose an offset level
%
% TU-BS. IfR. mue_st. Frithjof Tobaben. 1996.

% check for enough parameters
if nargin ~= 5
  error('number of input arguments');
end

% only integer values of n, mue and M
n = fix(n);
mue = fix(mue);
M = fix(M);

% test of range of mue and M
if mue < 1
  error('mue < 1');
end
if M < 1
  error('M < 1');
end

% determine feedback stages
if n < 2
  error('n < 2');
elseif n == 2											
  feedback = [1 2];
elseif n == 3
  feedback = [2 3];
elseif n == 4
  feedback = [3 4];
elseif n == 5
  feedback = [3 5];
elseif n == 6
  feedback = [5 6];
elseif n == 7
  feedback = [4 7];
elseif n == 8												
  feedback = [4 5 6 8];
elseif n == 9
  feedback = [5 9];
elseif n == 10
  feedback = [7 10];
elseif n == 11
  feedback = [9 11];
elseif n == 12
  feedback = [6 8 11 12];
elseif n == 13
  feedback = [9 10 12 13];
elseif n == 14
  feedback = [4 8 13 14];
elseif n == 15
  feedback = [14 15];
elseif n == 16
  feedback = [4 13 15 16];
elseif n == 17
  feedback = [14 17];
elseif n == 18
  feedback = [11 18];
elseif n == 19
  feedback = [14 17 18 19];
elseif n == 20
  feedback = [17 20];
else
  error('n > 20');
end

% maximum length of m-sequence for order n
N = 2 ^ n - 1;

% prepare column vector s in order to increase speed
% and to optimize memory use 
s = zeros(N, 1); 

% initialize column shift register
register = ones(n, 1); 

% create one period of sequence
for k = 1:N
  s(k) = register(1);
  buffer = rem((sum(register(feedback))), 2); %save new input modulo 2
  register(2:n) = register(1:(n - 1)); %shift register
  register(1) = buffer;
end

% prepare column vector u in order to increase speed
% and to optimize memory use 
u = zeros((N * mue * M), 1);

% stretch sequence mue-times if necessary
if mue > 1
  ku = 0;
  ks = 1;
  while ku < (N * mue)
    for kmue = 1:mue
      u(ku + kmue)=s(ks); %s values mue times to u
    end
    ku = ku + mue;
    ks = ks + 1;
  end
else
  u = s;
end

% repeat sequence M-times if necessary
if M > 1
  for k = 2:M
    u(((k - 1) * N * mue + 1):(k * N * mue)) = u(1:(N * mue));
  end
end

% arrange sequence amplitude V and offset o
u = u * 2 * V - V + o;
