function u = idinput(N,type,band,levels,nosine)
%IDINPUT Generates input signals for identification.
%	U = IDINPUT(N,TYPE,BAND,LEVELS)
%
%	U: The generated input signal, a column vector.
%	N: The length of the input.
%	TYPE: One of the following:
%	      'RGS': Generates a Random, Gaussian Signal.
%	      'RBS': Generates a Random, Binary Signal.
% 	      'PRBS': Generates a Pseudo-random, Binary Signal.
%             'SINE': Generates a sum-of-sinusoid signal.
%             Default: TYPE = 'RBS'.
%	BAND: A 2 by 1 row vector that defines the frequency band for the 
%	      input's frequency contents.
%	      For the 'RS', 'RBS' and 'SINE' cases BAND = [LFR,HFR], where
%	      LFR and HFR are the lower and upper limits of the passband,
%             expressed in fractions of the Nyquist frequency (thus always
%	      numbers between 0 and 1).
%	      For the 'PRBS' case BAND = [2LOGP,M], where the periodicity
%	      of the generated signal is 2^2LOGP-1, and M is such that the
%	      signal is constant over intervals of length 1/M. 2LOGP = 0,
%             gives the maximum length PRBS, corresponding to 2LOGP = 18.
%             Default: BAND =[0 1].
%       LEVELS = [MI, MA]: A 2 by 1 row vector, defining the input levels.
%	      For 'RBS', 'PRBS', and 'SINE', the levels are adjusted so
%             that the input signal always is between MI and MA.
%	      For the 'RS' case, MI is the signal's mean value minus one
%             standard deviation and MA is the signal's mean plus one standard
%	      deviation.
%	      Default LEVELS = [-1 1].
%      	In the 'SINE' case a 5th input argument NUMBERS can be used,
%       U = IDINPUT(N,TYPE,BAND,LEVELS,NUMBERS)         
%       where NUMBERS = [no_of_sinusoids, no_of_trials], meaning that
%       no_of_sinusoids are equally spread over the indicated BAND, trying
%	no_of_trials different, random, relative phases, until the lowest
%	amplitude signal is found. Default: NUMBERS = [10,10];
%	See also IDSIM, POLY2TH and MS2TH.

%	L. Ljung 3-3-95
%	Copyright (c) 1995 by the MathWorks, Inc.
%	$Revision: 1.3 $  $Date: 1995/05/16 09:01:05 $

if nargin < 1
   disp('Usage: U =  IDINPUT(N);')
   disp('       U =  IDINPUT(N,TYPE,BAND,LEVELS,NUMBERS);') 
   disp('       with TYPE one of ''RGS'', ''RBS'', ''PRBS'', ''SINE''.')
   return
end
if nargin < 5
   nosine=[];
end
if nargin < 4
   levels = [];
end
if nargin < 3
   band = [];
end
if nargin < 2
   type =[];
end
if isempty(nosine),nosine=[10,10];end
if isempty(levels),levels=[-1,1];end
if isempty(band),band=[0 1];end
if isempty(type),type='rbs';end
if band(2)<band(1)&~strcmp(lower(type),'prbs')
   error('The first component of BAND must be less than the second one.')
end
if levels(2)<levels(1)
   error('The first component of LEVELS must be less than the second one.')
end
if nosine(1)<1|nosine(2)<1
   error('The number of sinusoids and the number of trials must be larger than 1.')
end
if ~isstr(type)
    error('The argument TYPE must be one of ''rs'', ''rbs'', ''prbs'' or ''sine''.')
end
if strcmp(lower(type),'rs')|strcmp(lower(type),'rgs')
   u=randn(N,1); u=idfilt(u,8,band); u=u-mean(u)+levels(1);
   u=u/norm(u)*sqrt(N)*levels(2);
elseif strcmp(lower(type),'rbs')
   u=randn(N,1); u=sign(idfilt(u,8,band));
   u=(levels(2)-levels(1))*(u+1)/2+levels(1);
elseif strcmp(lower(type),'prbs')
  if band(1)==0,n=18;else n=floor(band(1));end
  if n<3|n>18,
   error('The length of the PRBS sequence, BAND(1), must be between 3 and 18.')
   return
  end
  fi=-ones(n,1);
  M=floor(1/band(2));
  if n==3
     ind=[1,3];
  elseif n==4
     ind=[1,4];
  elseif n==5
     ind=[2,5];
  elseif n==6
     ind=[1,6];
  elseif n==7
     ind=[1,7];
  elseif n==8
     ind=[1,2,7,8];
  elseif n==9
     ind=[4,9];
  elseif n==10
     ind=[3,10];
  elseif n==11
     ind=[9,11];
  elseif n==12
     ind=[6,8,11,12];
  elseif n==13
     ind=[9,10,12,13];
  elseif n==14
     ind=[4,8,13,14];
  elseif n==15
     ind=[14,15];
  elseif n==16
     ind=[4,13,15,16];
  elseif n==17
     ind=[14,17];
  elseif n==18
     ind=[11,18];
  end
  for t=1:M:N
    u(t:t+M-1,1)=ones(M,1)*fi(n);
    fi=[prod(fi(ind));fi(1:n-1,1)];
  end
  u=(levels(2)-levels(1))*(u+1)/2+levels(1);
elseif strcmp(lower(type),'sine')
  freqs=band(1)+(band(2)-band(1))/(nosine(1))*[1:nosine(1)];
  freqs=pi*freqs;
  numtrial=nosine(2);
  for kn=1:numtrial
   ut=zeros(N,1);
   for ks=1:nosine(1)
     ut=ut+cos([0:N-1]'*freqs(ks)+rand(1,1)*2*pi);
   end
   mm=max(ut);mn=min(ut);
   if kn==1,u=ut;bestamp=mm-mn;end
   if mm-mn<bestamp,u=ut;bestamp=mm-mn;end
  end
  u=(levels(2)-levels(1))*(u-mn)/(mm-mn)+levels(1);
else
    error('The argument TYPE must be one of ''rgs'', ''rbs'', ''prbs'' or ''sine''.')
end
