%DATE:21/04/2005
%COFDM SIMULATOR
%BY:Apurva Gupta
%B.ENG,ELECTRONICs & COMMUNICATION ENGINEERING,
%UNIVERSITY OF LEEDS,UK
%SUPERVISOR:Prof.G.Markarian

function varargout = final_simulator(varargin)
% FINAL_SIMULATOR M-file for final_simulator.fig
%      FINAL_SIMULATOR, by itself, creates a new FINAL_SIMULATOR or raises the existing
%      singleton*.
%
%      H = FINAL_SIMULATOR returns the handle to a new FINAL_SIMULATOR or the handle to
%      the existing singleton*.
%
%      FINAL_SIMULATOR('CALLBACK',hObject,eventData,handles,...) calls the local
%      function named CALLBACK in FINAL_SIMULATOR.M with the given input arguments.
%
%      FINAL_SIMULATOR('Property','Value',...) creates a new FINAL_SIMULATOR or raises the
%      existing singleton*.  Starting from the left, property value pairs are
%      applied to the GUI before final_simulator_OpeningFunction gets called.  An
%      unrecognized property name or invalid value makes property application
%      stop.  All inputs are passed to final_simulator_OpeningFcn via varargin.
%
%      *See GUI Options on GUIDE's Tools menu.  Choose "GUI allows only one
%      instance to run (singleton)".
%
% See also: GUIDE, GUIDATA, GUIHANDLES

% Copyright 2002-2003 The MathWorks, Inc.

% Edit the above text to modify the response to help final_simulator

% Last Modified by GUIDE v2.5 24-Apr-2005 12:30:13

% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name',       mfilename, ...
                   'gui_Singleton',  gui_Singleton, ...
                   'gui_OpeningFcn', @final_simulator_OpeningFcn, ...
                   'gui_OutputFcn',  @final_simulator_OutputFcn, ...
                   'gui_LayoutFcn',  [] , ...
                   'gui_Callback',   []);
if nargin && ischar(varargin{1})
    gui_State.gui_Callback = str2func(varargin{1});
end

if nargout
    [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
else
    gui_mainfcn(gui_State, varargin{:});
end
% End initialization code - DO NOT EDIT

% --- Executes just before final_simulator is made visible.
function final_simulator_OpeningFcn(hObject, eventdata, handles, varargin)
% This function has no output args, see OutputFcn.
% hObject    handle to figure
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
% varargin   command line arguments to final_simulator (see VARARGIN)

% Choose default command line output for final_simulator
handles.output = hObject;

% Update handles structure
guidata(hObject, handles);

% UIWAIT makes final_simulator wait for user response (see UIRESUME)
% uiwait(handles.figure1);

% --- Outputs from this function are returned to the command line.
function varargout = final_simulator_OutputFcn(hObject, eventdata, handles)
% varargout  cell array for returning output args (see VARARGOUT);
% hObject    handle to figure
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Get default command line output from handles structure
varargout{1} = handles.output;

function [varargout] = code1(varargin)
M=2;
EbNomin = 1; EbNomax = 5; % EbNo range, in dB
numerrmin = 10; % Compute BER only after 5 errors occur.
EbNovec = EbNomin:1:EbNomax; % Vector of EbNo values
numEbNos = length(EbNovec); % Number of EbNo values
% Preallocate space for certain data.
ber = zeros(1,numEbNos); % BER values
intv = cell(1,numEbNos); % Cell array of confidence intervals
% Loop over the vector of EbNo values.
for jj = 1:numEbNos
   EbNo = EbNovec(jj);
   snr = EbNo; % Because of binary modulation
   ntrials = 0; % Number of passes through the while loop below
   numerr = 0; % Number of errors for this EbNo value
   % Simulate until numerrmin errors occur.
   while (numerr < numerrmin)
      msg= zeros(1,1e6);%message is a string of a thousand zeros.
      %t = poly2trellis([4 3],[4 5 17;7 4 2]); % Define trellis.
      %code = convenc(msg,t); % Encode a string of ones.
      txsig = pskmod(msg,M); % Modulate.
      rxsig = awgn(txsig, snr, 'measured'); % Add noise.
      decodmsg = pskdemod(rxsig,M); % Demodulate.
      %qcode = quantiz(decodmsg,[0.001,.1,.3,.5,.7,.9,.999]);% Quantize to prepare for soft-decision decoding.
      %tblen = 48; delay = tblen; % Traceback length
      %decoded = vitdec(qcode,t,tblen,'cont','soft',3); % Decode.
      newerrs = biterr(msg,decodmsg); % Errors in this trial
      numerr = numerr + newerrs; % Total errors for this EbNo value
      ntrials = ntrials + 1; % Update trial index.
   end
   % Error rate and 98% confidence interval for this EbNo value
   [ber(jj), intv1] = berconfint(numerr,(ntrials * 1e6),.98);
   intv{jj} = intv1; % Store in cell array for later use.
   disp(['EbNo = ' num2str(EbNo) ' dB, ' num2str(numerr) ...
         ' errors, BER = ' num2str(ber(jj))])
end
% Use BERFIT to plot the best fitted curve,
% interpolating to get a smooth plot.
fitEbNo = EbNomin:0.25:EbNomax; % Interpolation values
berfit(EbNovec,ber,fitEbNo);

% Also plot confidence intervals.
hold on;
grid on;
%axes(handles.axes2);
for jj=1:numEbNos
   semilogy([EbNovec(jj) EbNovec(jj)],intv{jj},'g-+');
end
%hold off;
if nargout == 0
  builtin('code1', varargin{:});
else
  [varargout{1:nargout}] = builtin('code1', varargin{:});
end

%--------------------------------------------------------------
function [varargout] = code2(varargin)
M=2;
EbNomin = 1; EbNomax = 5; % EbNo range, in dB
numerrmin = 10; % Compute BER only after 5 errors occur.
EbNovec = EbNomin:1:EbNomax; % Vector of EbNo values
numEbNos = length(EbNovec); % Number of EbNo values
% Preallocate space for certain data.
ber = zeros(1,numEbNos); % BER values
intv = cell(1,numEbNos); % Cell array of confidence intervals
% Loop over the vector of EbNo values.
for jj = 1:numEbNos
   EbNo = EbNovec(jj);
   snr = EbNo; % Because of binary modulation
   ntrials = 0; % Number of passes through the while loop below
   numerr = 0; % Number of errors for this EbNo value
   % Simulate until numerrmin errors occur.
   while (numerr < numerrmin)
      msg= zeros(1,1e6);%message is a string of a thousand zeros.
      %t = poly2trellis([4 3],[4 5 17;7 4 2]); % Define trellis.
      %code = convenc(msg,t); % Encode a string of ones.
      txsig = pskmod(msg,M); % Modulate.
      rxsig = awgn(txsig, snr, 'measured'); % Add noise.
      decodmsg = pskdemod(rxsig,M); % Demodulate.
      %qcode = quantiz(decodmsg,[0.001,.1,.3,.5,.7,.9,.999]);% Quantize to prepare for soft-decision decoding.
      %tblen = 48; delay = tblen; % Traceback length
      %decoded = vitdec(qcode,t,tblen,'cont','soft',3); % Decode.
      newerrs = biterr(msg,decodmsg); % Errors in this trial
      numerr = numerr + newerrs; % Total errors for this EbNo value
      ntrials = ntrials + 1; % Update trial index.
   end
   % Error rate and 98% confidence interval for this EbNo value
   [ber(jj), intv1] = berconfint(numerr,(ntrials * 1e6),.98);
   intv{jj} = intv1; % Store in cell array for later use.
   disp(['EbNo = ' num2str(EbNo) ' dB, ' num2str(numerr) ...
         ' errors, BER = ' num2str(ber(jj))])
end
% Use BERFIT to plot the best fitted curve,
% interpolating to get a smooth plot.
fitEbNo = EbNomin:0.25:EbNomax; % Interpolation values
berfit(EbNovec,ber,fitEbNo);

% Also plot confidence intervals.
hold on;
grid on;
%axes(handles.axes2);
for jj=1:numEbNos
   semilogy([EbNovec(jj) EbNovec(jj)],intv{jj},'g-+');
end
%hold off;
if nargout == 0
  builtin('code2', varargin{:});
else
  [varargout{1:nargout}] = builtin('code2', varargin{:});
end

%-------16QAM-------------------------------------------
function [varargout] = code3(varargin)
bits=1e5;
M=16;
EbNomin = 1; EbNomax = 5; % EbNo range, in dB
numerrmin = 10; % Compute BER only after 5 errors occur.
EbNovec = EbNomin:1:EbNomax; % Vector of EbNo values
numEbNos = length(EbNovec); % Number of EbNo values
% Preallocate space for certain data.
ber = zeros(1,numEbNos); % BER values
intv = cell(1,numEbNos); % Cell array of confidence intervals
% Loop over the vector of EbNo values.
for jj = 1:numEbNos
   EbNo = EbNovec(jj);
   snr = EbNo;%*0.5*log2(M);% Because of binary modulation
   ntrials = 0; % Number of passes through the while loop below
   numerr = 0; % Number of errors for this EbNo value
   % Simulate until numerrmin errors occur.
   while (numerr < numerrmin)
      msg= zeros(bits,1);%message is a string of a thousand zeros.
      txsig = qammod(msg,M); % Modulate.
      noise = awgn(txsig, snr,'measured'); % Add noise.
      decodmsg = qamdemod(noise,M); % Demodulate.
      newerrs = biterr(msg,decodmsg); % Errors in this trial
      numerr = numerr + newerrs; % Total errors for this EbNo value
      ntrials = ntrials + 1; % Update trial index.
   end
   % Error rate and 98% confidence interval for this EbNo value
   [ber(jj), intv1] = berconfint(numerr,(ntrials * bits),.98);
   intv{jj} = intv1; % Store in cell array for later use.
   disp(['EbNo = ' num2str(EbNo) ' dB, ' num2str(numerr) ...
         ' errors, BER = ' num2str(ber(jj))])
end
% Use BERFIT to plot the best fitted curve,
% interpolating to get a smooth plot.
fitEbNo = EbNomin:0.25:EbNomax; % Interpolation values
berfit(EbNovec,ber,fitEbNo);

% Also plot confidence intervals.
hold on;
grid on;
%set(gcf,'DefaultAxesColorOrder',[1 0 0;0 1 0;0 0 1])
%axes(handles.axes2);
for jj=1:numEbNos
   semilogy([EbNovec(jj) EbNovec(jj)],intv{jj},'g-+');
end
if nargout == 0
  builtin('code3', varargin{:});
else
  [varargout{1:nargout}] = builtin('code3', varargin{:});
end

%------64QAM------------------------------------------------
function [varargout] = code4(varargin)
bits=1e5;
M=64;
EbNomin = 5; EbNomax = 15; % EbNo range, in dB
numerrmin = 5; % Compute BER only after 5 errors occur.
EbNovec = EbNomin:1:EbNomax; % Vector of EbNo values
numEbNos = length(EbNovec); % Number of EbNo values
% Preallocate space for certain data.
ber = zeros(1,numEbNos); % BER values
intv = cell(1,numEbNos); % Cell array of confidence intervals
% Loop over the vector of EbNo values.
for jj = 1:numEbNos
   EbNo = EbNovec(jj);
   snr = EbNo;%*0.5*log2(M);% Because of binary modulation
   ntrials = 0; % Number of passes through the while loop below
   numerr = 0; % Number of errors for this EbNo value
   % Simulate until numerrmin errors occur.
   while (numerr < numerrmin)
      msg= zeros(bits,1);%message is a string of a thousand zeros.
      txsig = qammod(msg,M); % Modulate.
      noise = awgn(txsig, snr,'measured'); % Add noise.
      decodmsg = qamdemod(noise,M); % Demodulate.
      newerrs = biterr(msg,decodmsg); % Errors in this trial
      numerr = numerr + newerrs; % Total errors for this EbNo value
      ntrials = ntrials + 1; % Update trial index.
   end
   % Error rate and 98% confidence interval for this EbNo value
   [ber(jj), intv1] = berconfint(numerr,(ntrials * bits),.98);
   intv{jj} = intv1; % Store in cell array for later use.
   disp(['EbNo = ' num2str(EbNo) ' dB, ' num2str(numerr) ...
         ' errors, BER = ' num2str(ber(jj))])
end
% Use BERFIT to plot the best fitted curve,
% interpolating to get a smooth plot.
fitEbNo = EbNomin:0.25:EbNomax; % Interpolation values
berfit(EbNovec,ber,fitEbNo);

% Also plot confidence intervals.
hold on;
grid on;
%set(gcf,'DefaultAxesColorOrder',[1 0 0;0 1 0;0 0 1])
%axes(handles.axes2);
for jj=1:numEbNos
    %legend('Emperical BER','64QAM','Poly Ratio fit');
    semilogy([EbNovec(jj) EbNovec(jj)],intv{jj},'g-+');
end
if nargout == 0
  builtin('code4', varargin{:});
else
  [varargout{1:nargout}] = builtin('code4', varargin{:});
end

function [varargout] = conv_code1(varargin)
M=2;
EbNomin = 1; EbNomax = 5; % EbNo range, in dB
numerrmin = 5; % Compute BER only after 5 errors occur.
EbNovec = EbNomin:1:EbNomax; % Vector of EbNo values
numEbNos = length(EbNovec); % Number of EbNo values
% Preallocate space for certain data.
ber = zeros(1,numEbNos); % BER values
intv = cell(1,numEbNos); % Cell array of confidence intervals
% Loop over the vector of EbNo values.
for jj = 1:numEbNos
   EbNo = EbNovec(jj);
   snr = EbNo; % Because of binary modulation
   ntrials = 0; % Number of passes through the while loop below
   numerr = 0; % Number of errors for this EbNo value
   % Simulate until numerrmin errors occur.
   while (numerr < numerrmin)
      msg= zeros(1,1e6);%message is a string of a thousand zeros.
      t = poly2trellis([4 3],[4 5 17;7 4 2]); % Define trellis.
      code = convenc(msg,t); % Encode a string of ones.
      txsig = pskmod(code,M); % Modulate.
      rxsig = awgn(txsig, snr, 'measured'); % Add noise.
      decodmsg = pskdemod(rxsig,M); % Demodulate.
      qcode = quantiz(decodmsg,[0.001,.1,.3,.5,.7,.9,.999]);% Quantize to prepare for soft-decision decoding.
      tblen = 48; delay = tblen; % Traceback length
      decoded = vitdec(qcode,t,tblen,'cont','soft',3); % Decode.
      newerrs = biterr(msg,decoded); % Errors in this trial
      numerr = numerr + newerrs; % Total errors for this EbNo value
      ntrials = ntrials + 1; % Update trial index.
   end
   % Error rate and 98% confidence interval for this EbNo value
   [ber(jj), intv1] = berconfint(numerr,(ntrials * 1e6),.98);
   intv{jj} = intv1; % Store in cell array for later use.
   disp(['EbNo = ' num2str(EbNo) ' dB, ' num2str(numerr) ...
         ' errors, BER = ' num2str(ber(jj))])
end
% Use BERFIT to plot the best fitted curve,
% interpolating to get a smooth plot.
fitEbNo = EbNomin:0.25:EbNomax; % Interpolation values
berfit(EbNovec,ber,fitEbNo);

% Also plot confidence intervals.
hold on;
grid on;
%axes(handles.axes2);
for jj=1:numEbNos
   semilogy([EbNovec(jj) EbNovec(jj)],intv{jj},'g-+');
end
%hold off;
if nargout == 0
  builtin('conv_code1', varargin{:});
else
  [varargout{1:nargout}] = builtin('conv_code1', varargin{:});
end
%------------------------------------------------------------
function [varargout] = conv_code2(varargin)
M=4;
EbNomin = 1; EbNomax = 10; % EbNo range, in dB
numerrmin = 5; % Compute BER only after 5 errors occur.
EbNovec = EbNomin:1:EbNomax; % Vector of EbNo values
numEbNos = length(EbNovec); % Number of EbNo values
% Preallocate space for certain data.
ber = zeros(1,numEbNos); % BER values
intv = cell(1,numEbNos); % Cell array of confidence intervals
% Loop over the vector of EbNo values.
for jj = 1:numEbNos
   EbNo = EbNovec(jj);
   snr = EbNo; % Because of binary modulation
   ntrials = 0; % Number of passes through the while loop below
   numerr = 0; % Number of errors for this EbNo value
   % Simulate until numerrmin errors occur.
   while (numerr < numerrmin)
      msg= zeros(1,1e6);%message is a string of a thousand zeros.
      t = poly2trellis([4 3],[4 5 17;7 4 2]); % Define trellis.
      code = convenc(msg,t); % Encode a string of ones.
      txsig = pskmod(code,M); % Modulate.
      rxsig = awgn(txsig, snr, 'measured'); % Add noise.
      decodmsg = pskdemod(rxsig,M); % Demodulate.
      qcode = quantiz(decodmsg,[0.001,.1,.3,.5,.7,.9,.999]);% Quantize to prepare for soft-decision decoding.
      tblen = 48; delay = tblen; % Traceback length
      decoded = vitdec(qcode,t,tblen,'cont','soft',3); % Decode.
      newerrs = biterr(msg,decoded); % Errors in this trial
      numerr = numerr + newerrs; % Total errors for this EbNo value
      ntrials = ntrials + 1; % Update trial index.
   end
   % Error rate and 98% confidence interval for this EbNo value
   [ber(jj), intv1] = berconfint(numerr,(ntrials * 1e6),.98);
   intv{jj} = intv1; % Store in cell array for later use.
   disp(['EbNo = ' num2str(EbNo) ' dB, ' num2str(numerr) ...
         ' errors, BER = ' num2str(ber(jj))])
end
% Use BERFIT to plot the best fitted curve,
% interpolating to get a smooth plot.
fitEbNo = EbNomin:0.25:EbNomax; % Interpolation values
berfit(EbNovec,ber,fitEbNo);

% Also plot confidence intervals.
hold on;
grid on;
%axes(handles.axes2);
for jj=1:numEbNos
   semilogy([EbNovec(jj) EbNovec(jj)],intv{jj},'g-+');
end
%hold off;
if nargout == 0
  builtin('conv_code2', varargin{:});
else
  [varargout{1:nargout}] = builtin('conv_code2', varargin{:});
end
%-------------------------------------------------------------
function [varargout] = conv_code3(varargin)
M=2;
EbNomin = 1; EbNomax = 5; % EbNo range, in dB
numerrmin = 10; % Compute BER only after 10 errors occur.
EbNovec = EbNomin:1:EbNomax; % Vector of EbNo values
numEbNos = length(EbNovec); % Number of EbNo values
% Preallocate space for certain data.
ber = zeros(1,numEbNos); % BER values
intv = cell(1,numEbNos); % Cell array of confidence intervals
% Loop over the vector of EbNo values.
for jj = 1:numEbNos
   EbNo = EbNovec(jj);
   snr = EbNo;%*0.5*log2(M); % Because of binary modulation
   ntrials = 0; % Number of passes through the while loop below
   numerr = 0; % Number of errors for this EbNo value
   % Simulate until numerrmin errors occur.
   while (numerr < numerrmin)

      msg = zeros(1e6,1);%message is a string of a thousand zeros.
      t = poly2trellis(7,[171 133]); % Define trellis.
      code = convenc(msg,t); % Encode a string of ones.
      txsig = pskmod(code,M); % Modulate.
      rxsig = awgn(txsig, snr, 'measured'); % Add noise.
      decodmsg = pskdemod(rxsig,M); % Demodulate.
      qcode = quantiz(decodmsg,[0.001,.1,.3,.5,.7,.9,.999]);% Quantize to prepare for soft-decision decoding.
      tblen = 48; delay = tblen; % Traceback length
      decoded = vitdec(qcode,t,tblen,'cont','soft',3); % Decode.
      newerrs = biterr(msg,decoded); % Errors in this trial
      numerr = numerr + newerrs; % Total errors for this EbNo value
      ntrials = ntrials + 1; % Update trial index.
   end
   % Error rate and 98% confidence interval for this EbNo value
   [ber(jj), intv1] = berconfint(numerr,(ntrials * 1e6),.98);
   intv{jj} = intv1; % Store in cell array for later use.
   disp(['EbNo = ' num2str(EbNo) ' dB, ' num2str(numerr) ...
         ' errors, BER = ' num2str(ber(jj))])
end
% Use BERFIT to plot the best fitted curve,
% interpolating to get a smooth plot.
fitEbNo = EbNomin:0.25:EbNomax; % Interpolation values
berfit(EbNovec,ber,fitEbNo);

% Also plot confidence intervals.
hold on;
grid on;
%axes(handles.axes2);
for jj=1:numEbNos
   semilogy([EbNovec(jj) EbNovec(jj)],intv{jj},'g-+');
end
%hold off;
if nargout == 0
  builtin('conv_code3', varargin{:});
else
  [varargout{1:nargout}] = builtin('conv_code3', varargin{:});
end

%-------------------------------------------------------
function [varargout] = conv_code4(varargin)
M=4;
EbNomin = 1; EbNomax = 5; % EbNo range, in dB
numerrmin = 10; % Compute BER only after 10 errors occur.
EbNovec = EbNomin:1:EbNomax; % Vector of EbNo values
numEbNos = length(EbNovec); % Number of EbNo values
% Preallocate space for certain data.
ber = zeros(1,numEbNos); % BER values
intv = cell(1,numEbNos); % Cell array of confidence intervals
% Loop over the vector of EbNo values.
for jj = 1:numEbNos
   EbNo = EbNovec(jj);
   snr = EbNo*0.5*log2(M); % Because of binary modulation
   ntrials = 0; % Number of passes through the while loop below
   numerr = 0; % Number of errors for this EbNo value
   % Simulate until numerrmin errors occur.
   while (numerr < numerrmin)

      msg = zeros(1e6,1);%message is a string of a thousand zeros.
      t = poly2trellis(7,[171 133]); % Define trellis.
      code = convenc(msg,t); % Encode a string of ones.
      txsig = pskmod(code,M); % Modulate.
      rxsig = awgn(txsig, snr, 'measured'); % Add noise.
      decodmsg = pskdemod(rxsig,M); % Demodulate.
      qcode = quantiz(decodmsg,[0.001,.1,.3,.5,.7,.9,.999]);% Quantize to prepare for soft-decision decoding.
      tblen = 48; delay = tblen; % Traceback length
      decoded = vitdec(qcode,t,tblen,'cont','soft',3); % Decode.
      newerrs = biterr(msg,decoded); % Errors in this trial
      numerr = numerr + newerrs; % Total errors for this EbNo value
      ntrials = ntrials + 1; % Update trial index.
   end
   % Error rate and 98% confidence interval for this EbNo value
   [ber(jj), intv1] = berconfint(numerr,(ntrials * 1e6),.98);
   intv{jj} = intv1; % Store in cell array for later use.
   disp(['EbNo = ' num2str(EbNo) ' dB, ' num2str(numerr) ...
         ' errors, BER = ' num2str(ber(jj))])
end
% Use BERFIT to plot the best fitted curve,
% interpolating to get a smooth plot.
fitEbNo = EbNomin:0.25:EbNomax; % Interpolation values
berfit(EbNovec,ber,fitEbNo);

% Also plot confidence intervals.
hold on;
grid on;
%axes(handles.axes2);
for jj=1:numEbNos
   semilogy([EbNovec(jj) EbNovec(jj)],intv{jj},'g-+');
end
%hold off;
if nargout == 0
  builtin('conv_code4', varargin{:});
else
  [varargout{1:nargout}] = builtin('conv_code4', varargin{:});
end

% --- Executes on selection change in modulation.
function modulation_Callback(hObject, eventdata, handles)
% hObject    handle to modulation (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: contents = get(hObject,'String') returns modulation contents as cell array
%        contents{get(hObject,'Value')} returns selected item from modulation

% --- Executes during object creation, after setting all properties.
function modulation_CreateFcn(hObject, eventdata, handles)
% hObject    handle to modulation (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: popupmenu controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc
    set(hObject,'BackgroundColor','white');
else
    set(hObject,'BackgroundColor',get(0,'defaultUicontrolBackgroundColor'));
end

% --- Executes on selection change in popupmenu2.
function popupmenu2_Callback(hObject, eventdata, handles)
% hObject    handle to popupmenu2 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: contents = get(hObject,'String') returns popupmenu2 contents as cell array
%        contents{get(hObject,'Value')} returns selected item from popupmenu2

% --- Executes during object creation, after setting all properties.
function popupmenu2_CreateFcn(hObject, eventdata, handles)
% hObject    handle to popupmenu2 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: popupmenu controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc
    set(hObject,'BackgroundColor','white');
else
    set(hObject,'BackgroundColor',get(0,'defaultUicontrolBackgroundColor'));
end

% --- Executes on selection change in coding.
function coding_Callback(hObject, eventdata, handles)
% hObject    handle to coding (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: contents = get(hObject,'String') returns coding contents as cell array
%        contents{get(hObject,'Value')} returns selected item from coding

% --- Executes during object creation, after setting all properties.
function coding_CreateFcn(hObject, eventdata, handles)
% hObject    handle to coding (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: popupmenu controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc
    set(hObject,'BackgroundColor','white');
else
    set(hObject,'BackgroundColor',get(0,'defaultUicontrolBackgroundColor'));
end

% --- Executes on selection change in interleaving.
function interleaving_Callback(hObject, eventdata, handles)
% hObject    handle to interleaving (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: contents = get(hObject,'String') returns interleaving contents as cell array
%        contents{get(hObject,'Value')} returns selected item from interleaving

% --- Executes during object creation, after setting all properties.
function interleaving_CreateFcn(hObject, eventdata, handles)
% hObject    handle to interleaving (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: popupmenu controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc
    set(hObject,'BackgroundColor','white');
else
    set(hObject,'BackgroundColor',get(0,'defaultUicontrolBackgroundColor'));
end

% --- Executes on button press in int.
function int_Callback(hObject, eventdata, handles)
% hObject    handle to int (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
popup_sel_index = get(handles.interleaving, 'Value');
switch popup_sel_index
    case 1

bits =1e6
M=2
EbNomin = 1; EbNomax = 5; % EbNo range, in dB
numerrmin = 10; % Compute BER only after 5 errors occur.
EbNovec = EbNomin:1:EbNomax; % Vector of EbNo values
numEbNos = length(EbNovec); % Number of EbNo values
% Preallocate space for certain data.
ber = zeros(1,numEbNos); % BER values
intv = cell(1,numEbNos); % Cell array of confidence intervals
% Loop over the vector of EbNo values.
for jj = 1:numEbNos
   EbNo = EbNovec(jj);
   snr = EbNo; % Because of binary modulation
   ntrials = 0; % Number of passes through the while loop below
   numerr = 0; % Number of errors for this EbNo value
   % Simulate until numerrmin errors occur.
   while (numerr < numerrmin)
      % st1 = 27221; st2 = 4831; % States for random number generator
      msg= zeros(bits,1);%message is a string of a thousand zeros.
      t = poly2trellis(7,[171 133]); % Define trellis.
      %t = poly2trellis([4 3],[4 5 17;7 4 2]); % Define trellis.
      code = convenc(msg,t); % Encode a string of ones.
      nrows = 5; % Use 5 shift registers
      slope = 3; % Delays are 0, 3, 6, 9, and 12.
      inter = convintrlv(code,nrows,slope); % Interleave.
      txsig = pskmod(inter,M); % Modulate.
      rxsig = awgn(txsig, snr, 'measured'); % Add noise.
      decodmsg = pskdemod(rxsig,M); % Demodulate.
      deinter = convdeintrlv(decodmsg,nrows,slope); % Deinterleave.
      qcode = quantiz(deinter,[0.001,.1,.3,.5,.7,.9,.999]);% Quantize to prepare for soft-decision decoding.
      tblen = 48; delay = tblen; % Traceback length
      decoded = vitdec(qcode,t,tblen,'cont','soft',3); % Decode.
      newerrs = biterr(msg,decoded); % Errors in this trial
      numerr = numerr + newerrs; % Total errors for this EbNo value
      ntrials = ntrials + 1; % Update trial index.
   end
   % Error rate and 98% confidence interval for this EbNo value
   [ber(jj), intv1] = berconfint(numerr,(ntrials *bits ),.98);
   intv{jj} = intv1; % Store in cell array for later use.
   disp(['EbNo = ' num2str(EbNo) ' dB, ' num2str(numerr) ...
         ' errors, BER = ' num2str(ber(jj))])
end
% Use BERFIT to plot the best fitted curve,
% interpolating to get a smooth plot.
fitEbNo = EbNomin:0.25:EbNomax; % Interpolation values
berfit(EbNovec,ber,fitEbNo);

% Also plot confidence intervals.
hold on;
grid on;
%set(gcf,'DefaultAxesColorOrder',[1 0 0;0 1 0;0 0 1])
%axes(handles.axes2);
for jj=1:numEbNos
   semilogy([EbNovec(jj) EbNovec(jj)],intv{jj},'g-+');
end

    case 2

bits =1e6
M=4
EbNomin = 1; EbNomax = 5; % EbNo range, in dB
numerrmin = 10; % Compute BER only after 5 errors occur.
EbNovec = EbNomin:1:EbNomax; % Vector of EbNo values
numEbNos = length(EbNovec); % Number of EbNo values
% Preallocate space for certain data.
ber = zeros(1,numEbNos); % BER values
intv = cell(1,numEbNos); % Cell array of confidence intervals
% Loop over the vector of EbNo values.
for jj = 1:numEbNos
   EbNo = EbNovec(jj);
   snr = EbNo*0.5*log2(M); % Because of binary modulation
   ntrials = 0; % Number of passes through the while loop below
   numerr = 0; % Number of errors for this EbNo value
   % Simulate until numerrmin errors occur.
   while (numerr < numerrmin)
      % st1 = 27221; st2 = 4831; % States for random number generator
      msg= zeros(bits,1);%message is a string of a thousand zeros.
      t = poly2trellis(7,[171 133]); % Define trellis.
      %t = poly2trellis([4 3],[4 5 17;7 4 2]); % Define trellis.
      code = convenc(msg,t); % Encode a string of ones.
      nrows = 5; % Use 5 shift registers
      slope = 3; % Delays are 0, 3, 6, 9, and 12.
      inter = convintrlv(code,nrows,slope); % Interleave.
      txsig = pskmod(inter,M); % Modulate.
      rxsig = awgn(txsig, snr, 'measured'); % Add noise.
      decodmsg = pskdemod(rxsig,M); % Demodulate.
      deinter = convdeintrlv(decodmsg,nrows,slope); % Deinterleave.
      qcode = quantiz(deinter,[0.001,.1,.3,.5,.7,.9,.999]);% Quantize to prepare for soft-decision decoding.
      tblen = 48; delay = tblen; % Traceback length
      decoded = vitdec(qcode,t,tblen,'cont','soft',3); % Decode.
      newerrs = biterr(msg,decoded); % Errors in this trial
      numerr = numerr + newerrs; % Total errors for this EbNo value
      ntrials = ntrials + 1; % Update trial index.
   end
   % Error rate and 98% confidence interval for this EbNo value
   [ber(jj), intv1] = berconfint(numerr,(ntrials *bits ),.98);
   intv{jj} = intv1; % Store in cell array for later use.
   disp(['EbNo = ' num2str(EbNo) ' dB, ' num2str(numerr) ...
         ' errors, BER = ' num2str(ber(jj))])
end
% Use BERFIT to plot the best fitted curve,
% interpolating to get a smooth plot.
fitEbNo = EbNomin:0.25:EbNomax; % Interpolation values
berfit(EbNovec,ber,fitEbNo);

% Also plot confidence intervals.
hold on;
grid on;
%set(gcf,'DefaultAxesColorOrder',[1 0 0;0 1 0;0 0 1])
%axes(handles.axes2);
for jj=1:numEbNos
   semilogy([EbNovec(jj) EbNovec(jj)],intv{jj},'g-+');
end
end

% --- Executes on button press in pushbutton2.
function pushbutton2_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton2 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
popup_sel_index = get(handles.modulation, 'Value');
switch popup_sel_index
    case 1
popup_sel_index = get(handles.coding, 'Value');
switch popup_sel_index
    case 1
        code1;
    case 2
        conv_code3;
    case 3
        conv_code1;

end
    case 2
popup_sel_index = get(handles.coding, 'Value');
switch popup_sel_index
    case 1
        code2;
    case 2
        conv_code4;
    case 3
        conv_code2;
end
    case 3
        code3;
    case 4
        code4;
end

% --- Executes on button press in clr.
function clr_Callback(hObject, eventdata, handles)
% hObject    handle to clr (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
cla

% --- Executes on button press in hlp.
function hlp_Callback(hObject, eventdata, handles)
% hObject    handle to hlp (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
helpPath = which('help.txt');
web(helpPath);

% --------------------------------------------------------------------
function close_Callback(hObject, eventdata, handles)
% hObject    handle to close (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
selection = questdlg(['Close ' get(handles.figure1,'Name') '?'],...
                     ['Close ' get(handles.figure1,'Name') '...'],...
                     'Yes','No','Yes');
if strcmp(selection,'No')
    return;
end

delete(handles.figure1)

% --------------------------------------------------------------------
function print_Callback(hObject, eventdata, handles)
% hObject    handle to print (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
printdlg(handles.figure1)

% --------------------------------------------------------------------
function file_Callback(hObject, eventdata, handles)
% hObject    handle to file (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)


%function feat = rgb_fun(filename, fun)
% apply function handler fun separately to all rgb channel of image located
% in filename
function feat = rgb_fun(filename, fun)
	rgbx = imread(filename);
	feat = [];
	if (numel(size(rgbx)) == 3)
		for c = 1:3
			cx = single(squeeze(rgbx(:,:,c)));
			feat = [feat, fun(cx)];
		end
	else
		cx = single(squeeze(rgbx(:,:)));
		feat = repmat(fun(cx),[1,3]);
	end
end


function a = mid(a)
%MID          Hessian midpoint
%
%  r = mid(a)
%

% written  04/04/04     S.M. Rump
% modified 04/06/05     S.M. Rump  rounding unchanged
%

  if isa(a.x,'intval')
    a.x = mid(a.x);
    a.dx = mid(a.dx);
    a.hx = mid(a.hx);
  end


% download.m

close all;
clear;
clc;

%% dataset
fprintf('###### Dataset downlowd ######\n\n');
% local folder
local_folder_name = 'dataset';

if ~exist('dataset', 'dir')
    mkdir('dataset');
end

% remote url, path, and filelist
site_url = 'http://www.kasailab.com/';
site_path = 'public/github/ClassifierToolbox/dataset/';
filename_array = {'ORL_Face_img.mat', 'ORL_Face_img_cov.mat', 'AR_Face_img_27x20.mat', ...
                    'AR_Face_img_60x43.mat','Brodatz_texture_img_small_set.mat', ...
                    'USPS.mat', 'MNIST.mat', ...
                    'test_cov.mat'};
dataset_num = length(filename_array);

% download files
for i = 1 : dataset_num
    file_name = filename_array{i};
    filename_full = sprintf('%s%s%s', site_url, site_path, file_name);
    filename_full_local = sprintf('%s/%s', local_folder_name, file_name);

    fprintf('# Dataset downlaoding [%d/%d]\n', i, dataset_num);

    if ~exist(filename_full_local, 'file')
        fprintf('  * file:\t "%s"\n', file_name);
        fprintf('  * from:\t "%s%s"\n', site_url, site_path);
        fprintf('  * into:\t "%s"\n', filename_full_local);
        fprintf('  * ........ ');
        websave(filename_full_local, filename_full);
        fprintf('done\n\n');
    else
        fprintf('  * ........ %s already exists. Skip downloading.\n\n', file_name);
    end
end

fprintf('# %d dataset files have been successfully downloaded.\n\n\n', dataset_num);

%% libraries
fprintf('###### Library downlowd ######\n\n');

if ~exist('lib', 'dir')
    mkdir('lib');
end

cd lib/;

lib_num = 4;
lib_cell = cell(1,lib_num);

lib_struct.name = 'NMFLibrary-master';
lib_struct.url = 'https://github.com/hiroyuki-kasai/NMFLibrary/archive/master.zip';
lib_cell{1} = lib_struct;

lib_struct.name = 'SparseGDLibrary-master';
lib_struct.url = 'https://github.com/hiroyuki-kasai/SparseGDLibrary/archive/master.zip';
lib_cell{2} = lib_struct;

lib_struct.name = 'DSK-master';
lib_struct.url = 'https://github.com/seuzjj/DSK/archive/master.zip';
lib_cell{3} = lib_struct;

lib_struct.name = 'KMeans_SPD_Matrices';
lib_struct.url = 'https://jp.mathworks.com/matlabcentral/mlc-downloads/downloads/submissions/46343/versions/2/download/zip';
lib_cell{4} = lib_struct;

% download files
for i = 1 : lib_num
    file_name = lib_cell{i}.name;
    file_url =  lib_cell{i}.url;

    fprintf('# Library downlaoding [%d/%d]\n', i, lib_num);

    if ~exist(file_name, 'dir')
        fprintf('  * file:\t "%s"\n', file_name);
        fprintf('  * from:\t "%s"\n', file_url);
        fprintf('  * into:\t "%s"\n', 'download.zip');
        fprintf('  * ........ ');
        websave('download.zip', file_url);
        fprintf('done.\n');

        fprintf('# unzip download.zip ... ');
        unzip download.zip;
        fprintf('done.\n');

        fprintf('# delete download.zip ... ');
        delete('download.zip');
        fprintf('done.\n\n');
    else
        fprintf('  * ........ %s already exists. Skip downloading.\n\n', file_name);
    end
end

cd ..;

fprintf('# %d library files have been successfully downloaded and installed.\n', lib_num);


function test_ft_appendtimelock

% MEM 2gb
% WALLTIME 00:10:00
% DEPENDENCY ft_appendtimelock append_common ft_datatype_timelock

% (C) Johanna Zumer

% make some dummy timelock structures
tlock.label = {'1';'2'};
tlock.time = 1:5;
tlock.dimord = 'rpt_chan_time';
tlock.trial = randn(10, 2, 5);

% concat over trials
tlock2 = tlock;
tlock2.trial = randn(8, 2, 5);

cfg = [];
tlockapp = ft_appendtimelock(cfg, tlock, tlock2);
assert(all( size(tlockapp.trial) == [18 2 5]))

cfg = [];
cfg.channel = {'1'};
tlockapp = ft_appendtimelock(cfg, tlock, tlock2);
assert(all( size(tlockapp.trial) == [18 1 5]))

% concat over channels
clear tlock2
tlock1.label = tlock.label(1);
tlock2.label = tlock.label(2);
tlock1.trial = tlock.trial(:, 1, :);
tlock2.trial = tlock.trial(:, 2, :);
tlock1.time = tlock.time;
tlock2.time = tlock.time;
tlock1.dimord = tlock.dimord;
tlock2.dimord = tlock.dimord;

cfg = [];
tlockapp = ft_appendtimelock(cfg, tlock, tlock2);
assert(all( size(tlockapp.trial) == [20 1 5]))

cfg = [];
tlockapp = ft_appendtimelock(cfg, tlock1, tlock2);
assert(all( size(tlockapp.trial) == [10 2 5]))

%% Test using other combinations of tlock from real data
clear tlock*
load(dccnpath('/home/common/matlab/fieldtrip/data/ftp/tutorial/eventrelatedaveraging/dataFC_LP.mat'));

cfg = [];
tlock1 = ft_timelockanalysis(cfg, dataFC_LP);

cfg = [];
cfg.channel = {'MLT*'};
tlockl = ft_timelockanalysis(cfg, dataFC_LP);
cfg = [];
cfg.channel = {'MRT*'};
tlockr = ft_timelockanalysis(cfg, dataFC_LP);

% should concat over channels
cfg = [];
tlockapp = ft_appendtimelock(cfg, tlockl, tlockr);

try
  cfg = [];
  cfg.appenddim = 'rpt';
  tlockapp = ft_appendtimelock(cfg, tlockl, tlockr);
  catchflag = 0;
catch
  catchflag = 1;
end
assert(logical(catchflag))

% should use only subset of 'l' channels and concat over avg
cfg = [];
tlockapp = ft_appendtimelock(cfg, tlockl, tlock1);

try
  cfg = [];
  cfg.appenddim = 'chan';
  tlockapp = ft_appendtimelock(cfg, tlockl, tlock1);
  catchflag = 0;
catch
  catchflag = 1;
end
assert(logical(catchflag))

% new tlock with keeptrials
cfg = [];
cfg.keeptrials = 'yes';
tlock1 = ft_timelockanalysis(cfg, dataFC_LP);
cfg.channel = {'MLT*'};
tlockl = ft_timelockanalysis(cfg, dataFC_LP);
cfg.channel = {'MRT*'};
tlockr = ft_timelockanalysis(cfg, dataFC_LP);

% should concat over channels
cfg = [];
tlockapp = ft_appendtimelock(cfg, tlockl, tlockr);

try
  cfg = [];
  cfg.appenddim = 'rpt';
  tlockapp = ft_appendtimelock(cfg, tlockl, tlockr);
  catchflag = 0;
catch
  catchflag = 1;
end
assert(logical(catchflag))

% should use only subset of 'l' channels and concat over avg
cfg = [];
tlockapp = ft_appendtimelock(cfg, tlockl, tlock1);

% now test for numerical inaccurracies, should concatenate across 'rpt'
tlock2 = tlock1;
tlock2.time = tlock1.time+0.0000001;
cfg = [];
tlockapp = ft_appendtimelock(cfg, tlock1, tlock2);

%% test for data with labels shuffled around

tlock2 = tlock1;
tlock2.label = tlock1.label(randperm(length(tlock1.label)));

tlock2.trial = randn(size(tlock1.trial));

cfg = [];
tlockshuffled = ft_appendtimelock(cfg, tlock1, tlock2);

% now check whether channels were correctly appended
[a, b] = match_str(tlock1.label, tlockshuffled.label);
x1 = tlock1.trial(:, a(1), :);
y1 = tlockshuffled.trial(1:size(x1, 1), b(1), :);

[a, b] = match_str(tlock2.label, tlockshuffled.label);
x2 = tlock2.trial(:, a(1), :);
y2 = tlockshuffled.trial([size(x1, 1)+1]:end, b(1), :);

if ~all(x1(:) == y1(:)) || ~all(x2(:) == y2(:))
  error('data was wrongly appended when channel labels are differently ordered in input arguments');
end

%% test with sampleinfo

% make some dummy timelock structures without sampleinfo
tlock1 = [];
tlock1.label = {'1';'2'};
tlock1.time = 1:5;
tlock1.dimord = 'rpt_chan_time';
tlock1.trial = randn(10, 2, 5);

tlock2 = [];
tlock2.label = {'1';'2'};
tlock2.time = 1:5;
tlock2.dimord = 'rpt_chan_time';
tlock2.trial = randn(8, 2, 5);

cfg = [];
tlockapp = ft_appendtimelock(cfg, tlock1, tlock2);
assert(~isfield(tlockapp, 'sampleinfo'));
assert(~isfield(tlockapp, 'fsample'));

cfg.keepsampleinfo = 'no';
tlockapp = ft_appendtimelock(cfg, tlock1, tlock2);
assert(~isfield(tlockapp, 'sampleinfo'));
assert(~isfield(tlockapp, 'fsample'));

cfg.keepsampleinfo = 'ifmakessense';
tlockapp = ft_appendtimelock(cfg, tlock1, tlock2);
assert(~isfield(tlockapp, 'sampleinfo'));
assert(~isfield(tlockapp, 'fsample'));

cfg.keepsampleinfo = 'yes';
tlockapp = ft_appendtimelock(cfg, tlock1, tlock2);
assert(isfield(tlockapp, 'sampleinfo')); % here it should exist
assert(~isfield(tlockapp, 'fsample'));


function x = p05_start ( option, nvar )

%*****************************************************************************80
%
%% P05_START returns a starting point for problem 5.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    03 September 2008
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer OPTION, the option index.
%
%    Input, integer NVAR, the number of variables.
%
%    Output, real X(NVAR), the starting point.
%
  x = zeros ( nvar, 1 );

  return
end


function [ b, m1, m2, r11, r12, r21, r22, seed ] = p36_p_get (  )

%*****************************************************************************80
%
%% P36_P_GET gets the values of the parameters for problem 36.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    16 October 2004
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Output, real B, M1, M2, R11, R12, R21, R22,
%    problem parameters.
%
%    Output, integer SEED, a seed for the random number generator.
%
  b = 0.0;
  m1 = 0;
  m2 = 0;
  r11 = 0.0;
  r12 = 0.0;
  r21 = 0.0;
  r22 = 0.0;
  seed = 0;

  [ b, m1, m2, r11, r12, r21, r22, seed ] = ...
    p36_p_val ( 'GET', b, m1, m2, r11, r12, r21, r22, seed );

  return
end


function title = p16_title ( )

%*****************************************************************************80
%
%% P16_TITLE returns a title for problem 16.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    16 March 2000
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Output, string TITLE, a title for the problem.
%
  title = 'The Beale Function.';

  return
end


classdef (InferiorClasses = {?chebfun}) domain < double
%DOMAIN   Utility class for CHEBFUN. Mostly for backward compatibility.

% Copyright 2017 by The University of Oxford and The Chebfun Developers.
% See http://www.chebfun.org/ for Chebfun information.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% DOMAIN Class Description:
%
% DOMAIN inherits from a standard Matlab DOUBLE. A domain object only
% contains vector for the endpoints and breakpoints of the interval it
% represents. This class is lightly documented, since it is mostly intended
% for backward compatibility.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    %% CLASS PROPERTIES:
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    properties ( Access = public )

    end

    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    %% CLASS CONSTRUCTOR:
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    methods ( Access = public, Static = false )

        function obj = domain(varargin)
            %Constructor for the DOMIAN class.

            % Return an empty DOMAIN on null input:
            if ( nargin == 0 )
                data = [];
            else
                data = horzcat(varargin{:});
            end

            % Create the domain:
            obj = obj@double(data);

        end

    end

    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    %% CLASS METHODS:
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    methods ( Access = public, Static = false )

        function out = validate(dom)
            out = true;
            if ( ~isnumeric(dom) || any(isnan(dom)) )
                out = false;
            elseif ( isempty(dom) )
                return
            elseif ( size(dom, 1) > 1 || size(dom, 2) < 2 )
                out = false;
            elseif ( any(diff(dom) <= 0) )
                out = false;
            end
            if ( out == false && nargout == 0 )
                error('CHEBFUN:DOMAIN:domain:invalid', ...
                    'Ends must be a 1xM vector of ordered doubles.');
            end
        end

        function display(dom)
            disp(double(dom))
        end

        function out = subsref(d, s)
            out = subsref@double(d, s);
            out = double(out);
        end

        function varargout = sprintf(varargin)
            % This is required as built-in subsref does not know what to do with
            % a DOMAIN object.

            varargin = domain2double(varargin{:});

            % Call built-in SPRINTF:
            varargout{1:nargout} = sprintf(varargin{:});
        end

    end

    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    %% STATIC METHODS:
    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    methods ( Access = public, Static = true )

        % Merge two domains:
        newDom = merge(varargin)

        function varargin = toDouble(varargin)
            % Cast DOMAIN to DOUBLE:
            for k = 1:nargin
                if ( isa(varargin{k}, 'domain') )
                    varargin{k} = double(varargin{k});
                end
            end
        end

    end

end


function y = cvx_basis( x )

if isempty( x )
    y = sparse( 1, 0 );
else
    y = sparse( reshape( x, 1, numel(  x  ) ) );
end

% Copyright 2010 Michael C. Grant and Stephen P. Boyd.
% See the file COPYING.txt for full copyright information.
% The command 'cvx_where' will show where this file is located.


function hb_to_st ( input_file, output_file )

%*****************************************************************************80
%
%% HB_TO_ST reads a Harwell-Boeing Sparse Matrix File, and writes an ST file.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    02 November 2008
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, string INPUT_FILE, the name of the file containing the
%    Harwell-Boeing matrix data.
%
%    Input, string OUTPUT_FILE, the name of the ST file to be created.
%
  input_unit = fopen ( input_file );

  if ( input_unit < 0 )
    fprintf ( 1, '\n' );
    fprintf ( 1, 'HB_TO_ST - Fatal error!\n' );
    fprintf ( 1, '  Error opening the file.\n' );
    error ( 'HB_TO_MSM - Fatal error!' );
  end

  [ title, key, totcrd, ptrcrd, indcrd, valcrd, rhscrd, mxtype, ...
    nrow, ncol, nnzero, neltvl, ptrfmt, indfmt, valfmt, rhsfmt, rhstyp, ...
    nrhs, nrhsix, colptr, rowind, values, rhsval, rhsptr, rhsind, guess, ...
    exact ] = hb_file_read ( input_unit );

  for col = 1 : ncol
    for k = colptr(col) : colptr(col+1)-1
      colind(k) = col;
    end
  end

  fclose ( input_unit );

  base0 = 0;
  base1 = 1;
  rowind = st_rebase ( base1, base0, nnzero, rowind );
  colind = st_rebase ( base1, base0, nnzero, colind );

  st_header_print ( nrow, ncol, nnzero );

  st_header_write ( output_file, nrow, ncol, nnzero );

  st_data_print ( nrow, ncol, nnzero, rowind, colind, values, ...
    '  Data read from HB file' );

  st_data_write ( output_file, nrow, ncol, nnzero, rowind, colind, values );

  return
end
function c = ch_cap ( c )

%*****************************************************************************80
%
%% CH_CAP capitalizes a single character.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    22 November 2003
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, character C, the character to capitalize.
%
%    Output, character C, the capitalized character.
%
  if ( 'a' <= c & c <= 'z' )
    c = c + 'A' - 'a';
  end

  return
end
function truefalse = ch_eqi ( c1, c2 )

%*****************************************************************************80
%
%% CH_EQI is a case insensitive comparison of two characters for equality.
%
%  Example:
%
%    CH_EQI ( 'A', 'a' ) is TRUE.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    28 July 2000
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, character C1, C2, the characters to compare.
%
%    Output, logical TRUEFALSE, is TRUE (1) if the characters are equal.
%
  FALSE = 0;
  TRUE = 1;

  if ( ch_cap ( c1 ) == ch_cap ( c2 ) )
    truefalse = TRUE;
  else
    truefalse = FALSE;
  end

  return
end
function truefalse = ch_is_digit ( c )

%*****************************************************************************80
%
% CH_IS_DIGIT returns TRUE if the character C is a digit.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    11 December 2003
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, character C, a character.
%
%    Output, integer TRUEFALSE, is TRUE (1) if C is a digit, FALSE (0) otherwise.
%
  TRUE = 1;
  FALSE = 0;

  if ( '0' <= c & c <= '9' )
    truefalse = TRUE;
  else
    truefalse = FALSE;
  end

  return
end
function truefalse = ch_is_format_code ( c )

%*****************************************************************************80
%
%% CH_IS_FORMAT_CODE returns TRUE if a character is a FORTRAN format code.
%
%  Discussion:
%
%    The format codes accepted here are not the only legal format
%    codes in FORTRAN90.  However, they are more than sufficient
%    for my needs!
%
%  Table:
%
%    A  Character
%    B  Binary digits
%    D  Real number, exponential representation
%    E  Real number, exponential representation
%    F  Real number, fixed point
%    G  General format
%    I  Integer
%    L  Logical variable
%    O  Octal digits
%    Z  Hexadecimal digits
%    *  Free format
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    21 November 2003
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, character C, the character to be analyzed.
%
%    Output, logical TRUEFALSE, is TRUE (1) if C is a FORTRAN format code
%     and FALSE (0) otherwise.
%
  FALSE = 0;
  TRUE = 1;

      if ( ch_eqi ( c, 'A' ) )
    truefalse = TRUE;
  elseif ( ch_eqi ( c, 'B' ) )
    truefalse = TRUE;
  elseif ( ch_eqi ( c, 'D' ) )
    truefalse = TRUE;
  elseif ( ch_eqi ( c, 'E' ) )
    truefalse = TRUE;
  elseif ( ch_eqi ( c, 'F' ) )
    truefalse = TRUE;
  elseif ( ch_eqi ( c, 'G' ) )
    truefalse = TRUE;
  elseif ( ch_eqi ( c, 'I' ) )
    truefalse = TRUE;
  elseif ( ch_eqi ( c, 'L' ) )
    truefalse = TRUE;
  elseif ( ch_eqi ( c, 'O' ) )
    truefalse = TRUE;
  elseif ( ch_eqi ( c, 'Z' ) )
    truefalse = TRUE;
  elseif ( c == '*' )
    truefalse = TRUE;
  else
    truefalse = FALSE;
  end

  return
end
function digit = ch_to_digit ( c )

%*****************************************************************************80
%
%% CH_TO_DIGIT returns the integer value of a base 10 digit.
%
%  Example:
%
%     C   DIGIT
%    ---  -----
%    '0'    0
%    '1'    1
%    ...  ...
%    '9'    9
%    ' '    0
%    'X'   -1
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    22 November 2003
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, character C, the decimal digit, '0' through '9' or blank
%    are legal.
%
%    Output, integer DIGIT, the corresponding integer value.  If C was
%    'illegal', then DIGIT is -1.
%
  if ( '0' <= c & c <= '9' )

    digit = c - '0';

  elseif ( c == ' ' )

    digit = 0;

  else

    digit = -1;

  end

  return
end
function exact = hb_exact_read ( input_unit, nrow, nrhs, rhscrd, rhsfmt, rhstyp )

%*****************************************************************************80
%
%% HB_EXACT_READ reads the exact solution vectors in an HB file.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    04 February 2005
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    Iain Duff, Roger Grimes, John Lewis,
%    User's Guide for the Harwell-Boeing Sparse Matrix Collection,
%    October 1992.
%
%  Parameters:
%
%    Input, integer INPUT_UNIT, the unit from which data is read.
%
%    Input, integer NROW, the number of rows or variables.
%
%    Input, integer NRHS, the number of right hand sides.
%
%    Input, integer RHSCRD, the number of lines in the file for
%    right hand sides.
%
%    Input, character ( len = 20 ) RHSFMT, the format for reading values
%    of the right hand side.
%
%    Input, character ( len = 3 ) RHSTYP, the right hand side type.
%    First character is F for full storage or M for same as matrix.
%    Second character is G if starting "guess" vectors are supplied.
%    Third character is X if exact solution vectors are supplied.
%    Ignored if NRHS = 0.
%
%    Output, real EXACT(NROW,NRHS), the exact solution vectors.
%
  exact = [];

  if ( 0 < rhscrd )

    if ( rhstyp(3) == 'X' )

      [ p, code, w, m ] = s_to_format ( rhsfmt );

      line_num = 1 + floor ( ( nrow - 1 ) / p );

      for irhs = 1 : nrhs

        jhi = 0;

        for i = 1 : line_num

          line = fgetl ( input_unit );
          jlo = jhi + 1;
          jhi = min ( jlo + p - 1, nrow );

          khi = 0;

          for j = jlo : jhi
            klo = khi + 1;
            khi = min ( klo + w - 1, length ( line ) );
            s = line(klo:khi);
            exact(j,irhs) = s_to_r8 ( s );
          end
        end
      end

    end

  end

  return
end
function [ title, key, totcrd, ptrcrd, indcrd, valcrd, rhscrd, mxtype, ...
  nrow, ncol, nnzero, neltvl, ptrfmt, indfmt, valfmt, rhsfmt, rhstyp, ...
  nrhs, nrhsix, colptr, rowind, values, rhsval, rhsptr, rhsind, guess, ...
  exact ] = hb_file_read ( input_unit )

%*****************************************************************************80
%
%% HB_FILE_READ reads an HB file.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    08 April 2004
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    Iain Duff, Roger Grimes, John Lewis,
%    User's Guide for the Harwell-Boeing Sparse Matrix Collection,
%    October 1992.
%
%  Parameters:
%
%    Input, integer INPUT_UNIT, the unit from data is read.
%
%    Output, character ( len = 72 ) TITLE, a title for the matrix.
%
%    Output, character ( len = 8 ) KEY, an identifier for the matrix.
%
%    Output, integer TOTCRD, the total number of lines of data.
%
%    Output, integer PTRCRD, the number of input lines for pointers.
%
%    Output, integer INDCRD, the number of input lines for row indices.
%
%    Output, integer VALCRD, the number of input lines for numerical values.
%
%    Output, integer RHSCRD, the number of input lines for right hand sides.
%
%    Output, character ( len = 3 ) MXTYPE, the matrix type.
%    First character is R for Real, C for complex, P for pattern only.
%    Second character is S for symmetric, U for unsymmetric, H for
%      Hermitian, Z for skew symmetric, R for rectangular.
%    Third character is A for assembled and E for unassembled
%      finite element matrices.
%
%    Output, integer NROW, the number of rows or variables.
%
%    Output, integer NCOL, the number of columns or elements.
%
%    Output, integer NNZERO.  In the case of assembled sparse matrices,
%    this is the number of nonzeroes.  In the case of unassembled finite
%    element matrices, in which the right hand side vectors are also
%    stored as unassembled finite element vectors, this is the total
%    number of entries in a single unassembled right hand side vector.
%
%    Output, integer NELTVL, the number of finite element matrix entries,
%    set to 0 in the case of assembled matrices.
%
%    Output, character ( len = 16 ) PTRFMT, the format for reading pointers.
%
%    Output, character ( len = 16 ) INDFMT, the format for reading indices.
%
%    Output, character ( len = 20 ) VALFMT, the format for reading values.
%
%    Output, character ( len = 20 ) RHSFMT, the format for reading values
%    of the right hand side.
%
%    Output, character ( len = 3 ) RHSTYP, the right hand side type.
%    First character is F for full storage or M for same as matrix.
%    Second character is G if starting "guess" vectors are supplied.
%    Third character is X if exact solution vectors are supplied.
%    Ignored if NRHS = 0.
%
%    Output, integer NRHS, the number of right hand sides.
%
%    Output, integer NRHSIX, the number of row indices (set to 0
%    in the case of unassembled matrices.)  Ignored if NRHS = 0.
%
%    Output, integer COLPTR(NCOL+1), COLPTR(I) points to the location of
%    the first entry of column I in the sparse matrix structure.
%
%    Output, integer ROWIND(NNZERO) or ROWIND(NELTVL), the row index of
%    each item.
%
%    Output, real VALUES(NNZERO) or VALUES(NELTVL), the nonzero values
%    of the matrix.
%
%    If RHSTYP(1:1) == 'F':
%
%      Output, integer RHSPTR(*), is not used.
%
%      Output, integer RHSIND(*), is not used.
%
%      Output, real RHSVAL(NROW,NRHS), contains NRHS dense right hand
%      side vectors.
%
%    If RHSTYP(1:1) = 'M' and MXTYPE(3:3) = 'A':
%
%      Output, integer RHSPTR(NRHS+1), RHSPTR(I) points to the location of
%      the first entry of right hand side I in the sparse right hand
%      side vector.
%
%      Output, integer RHSIND(NRHSIX), indicates, for each entry of
%      RHSVAL, the corresponding row index.
%
%      Output, real RHSVAL(NRHSIX), contains the value of the right hand
%      side entries.
%
%    If RHSTYP(1:1) = 'M' and MXTYPE(3:3) = 'E':
%
%      Output, integer RHSPTR(*), is not used.
%
%      Output, integer RHSIND(*), is not used.
%
%      Output, real RHSVAL(NNZERO,NRHS), contains NRHS unassembled
%      finite element vector right hand sides.
%
%    Output, real GUESS(NROW,NRHS), the starting guess vectors.
%
%    Output, real EXACT(NROW,NRHS), the exact solution vectors.
%

%
%  Read the header block.
%
  [ title, key, totcrd, ptrcrd, indcrd, valcrd, rhscrd, mxtype, ...
    nrow, ncol, nnzero, neltvl, ptrfmt, indfmt, valfmt, rhsfmt, rhstyp, ...
    nrhs, nrhsix ] = hb_header_read ( input_unit );
%
%  Read the matrix structure.
%
  [ colptr, rowind ] = hb_structure_read ( input_unit, ncol, mxtype, ...
    nnzero, neltvl, ptrcrd, ptrfmt, indcrd, indfmt );
%
%  Read the matrix values.
%
  values = hb_values_read ( input_unit, valcrd, mxtype, nnzero, neltvl, ...
    valfmt );
%
%  Read the right hand sides.
%
  [ rhsval, rhsptr, rhsind ] = hb_rhs_read ( input_unit, nrow, nnzero, ...
    nrhs, nrhsix, rhscrd, ptrfmt, indfmt, rhsfmt, mxtype, rhstyp );
%
%  Read the starting guesses.
%
  guess = hb_guess_read ( input_unit, nrow, nrhs, rhscrd, rhsfmt, rhstyp );
%
%  Read the exact solutions.
%
  exact = hb_exact_read ( input_unit, nrow, nrhs, rhscrd, rhsfmt, rhstyp );

  return
end
function guess = hb_guess_read ( input_unit, nrow, nrhs, rhscrd, rhsfmt, rhstyp )

%*****************************************************************************80
%
%% HB_GUESS_READ reads the starting guess vectors in an HB file.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    04 February 2005
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    Iain Duff, Roger Grimes, John Lewis,
%    User's Guide for the Harwell-Boeing Sparse Matrix Collection,
%    October 1992.
%
%  Parameters:
%
%    Input, integer INPUT_UNIT, the unit from which data is read.
%
%    Input, integer NROW, the number of rows or variables.
%
%    Input, integer NRHS, the number of right hand sides.
%
%    Input, integer RHSCRD, the number of lines in the file for
%    right hand sides.
%
%    Input, character ( len = 20 ) RHSFMT, the format for reading values
%    of the right hand side.
%
%    Input, character ( len = 3 ) RHSTYP, the right hand side type.
%    First character is F for full storage or M for same as matrix.
%    Second character is G if starting "guess" vectors are supplied.
%    Third character is X if exact solution vectors are supplied.
%    Ignored if NRHS = 0.
%
%    Output, real GUESS(NROW,NRHS), the starting guess vectors.
%
  guess = [];

  if ( 0 < rhscrd )

    if ( rhstyp(2) == 'G' )

      [ p, code, w, m ] = s_to_format ( rhsfmt );

      line_num = 1 + floor ( ( nrow - 1 ) / p );

      for irhs = 1 : nrhs

        jhi = 0;

        for i = 1 : line_num

          line = fgetl ( input_unit );
          jlo = jhi + 1;
          jhi = min ( jlo + p - 1, nrow );

          khi = 0;

          for j = jlo : jhi
            klo = khi + 1;
            khi = min ( klo + w - 1, length ( line ) );
            s = line(klo:khi);
            guess(j,irhs) = s_to_r8 ( s );
          end
        end
      end

    end

  end

  return
end
function [ title, key, totcrd, ptrcrd, indcrd, valcrd, rhscrd, mxtype, ...
  nrow, ncol, nnzero, neltvl, ptrfmt, indfmt, valfmt, rhsfmt, rhstyp, ...
  nrhs, nrhsix ] = hb_header_read ( input_unit )

%*****************************************************************************80
%
%% HB_HEADER_READ reads the header of an HB file.
%
%  Discussion:
%
%    The user should already have opened the file, and positioned it
%    to the first record.
%
%    Thanks to Shahadat Hossain for pointing out an error in the determination
%    of INDFMT, on 24 June 2004.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    28 June 2004
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    Iain Duff, Roger Grimes, John Lewis,
%    User's Guide for the Harwell-Boeing Sparse Matrix Collection,
%    October 1992.
%
%  Parameters:
%
%    Input, integer INPUT_UNIT, the unit from which data is read.
%
%    Output, character ( len = 72 ) TITLE, a title for the matrix.
%
%    Output, character ( len = 8 ) KEY, an identifier for the matrix.
%
%    Output, integer TOTCRD, the total number of lines of data.
%
%    Output, integer PTRCRD, the number of input lines for pointers.
%
%    Output, integer INDCRD, the number of input lines for row indices.
%
%    Output, integer VALCRD, the number of input lines for numerical values.
%
%    Output, integer RHSCRD, the number of input lines for right hand sides.
%
%    Output, character ( len = 3 ) MXTYPE, the matrix type.
%    First character is R for Real, C for complex, P for pattern only.
%    Second character is S for symmetric, U for unsymmetric, H for
%      Hermitian, Z for skew symmetric, R for rectangular.
%    Third character is A for assembled and E for unassembled
%      finite element matrices.
%
%    Output, integer NROW, the number of rows or variables.
%
%    Output, integer NCOL, the number of columns or elements.
%
%    Output, integer NNZERO.  In the case of assembled sparse matrices,
%    this is the number of nonzeroes.  In the case of unassembled finite
%    element matrices, in which the right hand side vectors are also
%    stored as unassembled finite element vectors, this is the total
%    number of entries in a single unassembled right hand side vector.
%
%    Output, integer NELTVL, the number of finite element matrix entries,
%    set to 0 in the case of assembled matrices.
%
%    Output, character ( len = 16 ) PTRFMT, the format for reading pointers.
%
%    Output, character ( len = 16 ) INDFMT, the format for reading indices.
%
%    Output, character ( len = 20 ) VALFMT, the format for reading values.
%
%    Output, character ( len = 20 ) RHSFMT, the format for reading values
%    of the right hand side.
%
%    Output, character ( len = 3 ) RHSTYP, the right hand side type.
%    First character is F for full storage or M for same as matrix.
%    Second character is G if starting "guess" vectors are supplied.
%    Third character is X if exact solution vectors are supplied.
%
%    Output, integer NRHS, the number of right hand sides.
%
%    Output, integer NRHSIX, the number of entries of storage for right
%    hand side values, in the case where RHSTYP(1:1) = 'M' and
%    MXTYPE(3:3) = 'A'.
%

%
%  Read the header block.
%  Use FGETL rather that FGETS, because we don't want the line terminator character!
%  If fewer than 80 characters were read, you need to pad the line out.
%
  line = fgetl ( input_unit );

  if ( line == -1 )
    fprintf ( 1, '\n' );
    fprintf ( 1, 'HB_HEADER_READ - Fatal error!\n' );
    fprintf ( 1, '  I/O error reading header line 1.\n' );
    return;
  end

  line_num = length ( line );
  for i = line_num+1 : 80
    line(i) = ' ';
  end

  title = line(1:72);
  title = title(1:s_len_trim(title));

  key = line(73:80);
  key = key(1:s_len_trim(key));

  line = fgetl ( input_unit );

  if ( line == -1 )
    fprintf ( 1, '\n' );
    fprintf ( 1, 'HB_HEADER_READ - Fatal error!\n' );
    fprintf ( 1, '  I/O error reading header line 2.\n' );
    return;
  end

  line_num = length ( line );
  for i = line_num+1 : 80
    line(i) = ' ';
  end

  totcrd = s_to_i4 ( line( 1:14) );
  ptrcrd = s_to_i4 ( line(15:28) );
  indcrd = s_to_i4 ( line(29:42) );
  valcrd = s_to_i4 ( line(43:56) );
  rhscrd = s_to_i4 ( line(57:70) );

  line = fgetl ( input_unit );

  if ( line == -1 )
    fprintf ( 1, '\n' );
    fprintf ( 1, 'HB_HEADER_READ - Fatal error!\n' );
    fprintf ( 1, '  I/O error reading header line 3.\n' );
    return;
  end

  line_num = length ( line );
  for i = line_num+1 : 80
    line(i) = ' ';
  end

  mxtype =           line( 1: 3);
  nrow   = s_to_i4 ( line(15:28) );
  ncol   = s_to_i4 ( line(29:42) );
  nnzero = s_to_i4 ( line(43:56) );
  neltvl = s_to_i4 ( line(57:70) );

  line = fgetl ( input_unit );

  if ( line == -1 )
    fprintf ( 1, '\n' );
    fprintf ( 1, 'HB_HEADER_READ - Fatal error!\n' );
    fprintf ( 1, '  I/O error reading header line 4.\n' );
    return;
  end

  line_num = length ( line );
  for i = line_num+1 : 80
    line(i) = ' ';
  end

  ptrfmt = line( 1:16);
  ptrfmt = ptrfmt(1:s_len_trim(ptrfmt));
  indfmt = line(17:32);
  indfmt = indfmt(1:s_len_trim(indfmt));
  valfmt = line(33:52);
  valfmt = valfmt(1:s_len_trim(valfmt));
  rhsfmt = line(53:72);
  rhsfmt = rhsfmt(1:s_len_trim(rhsfmt));

  if ( 0 < rhscrd )

    line = fgetl ( input_unit );

    if ( line == -1 )
      fprintf ( 1, '\n' );
      fprintf ( 1, 'HB_HEADER_READ - Fatal error!\n' );
      fprintf ( 1, '  I/O error reading header line 5.\n' );
      return;
    end

    line_num = length ( line );
    for i = line_num+1 : 80
      line(i) = ' ';
    end

    rhstyp =           line( 1: 3);
    nrhs   = s_to_i4 ( line(15:28) );
    nrhsix = s_to_i4 ( line(29:42) );

  else

    rhstyp = ' ';
    nrhs = 0;
    nrhsix = 0;

  end

  return
end
function [ rhsval, rhsptr, rhsind ] = hb_rhs_read ( input_unit, nrow, ...
  nnzero, nrhs, nrhsix, rhscrd, ptrfmt, indfmt, rhsfmt, mxtype, rhstyp )

%*****************************************************************************80
%
%% HB_RHS_READ reads the right hand side information in an HB file.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    04 February 2005
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    Iain Duff, Roger Grimes, John Lewis,
%    User's Guide for the Harwell-Boeing Sparse Matrix Collection,
%    October 1992.
%
%  Parameters:
%
%    Input, integer INPUT_UNIT, the unit from which data is read.
%
%    Input, integer NROW, the number of rows or variables.
%
%    Input, integer NNZERO.  In the case of assembled sparse matrices,
%    this is the number of nonzeroes.  In the case of unassembled finite
%    element matrices, in which the right hand side vectors are also
%    stored as unassembled finite element vectors, this is the total
%    number of entries in a single unassembled right hand side vector.
%
%    Input, integer NRHS, the number of right hand sides.
%
%    Input, integer NRHSIX, the number of entries of storage for right
%    hand side values, in the case where RHSTYP(1:1) = 'M' and
%    MXTYPE(3:3) = 'A'.
%
%    Input, integer RHSCRD, the number of lines in the file for
%    right hand sides.
%
%    Input, character ( len = 16 ) PTRFMT, the format for reading pointers.
%
%    Input, character ( len = 16 ) INDFMT, the format for reading indices.
%
%    Input, character ( len = 20 ) RHSFMT, the format for reading values
%    of the right hand side.
%
%    Input, character ( len = 3 ) MXTYPE, the matrix type.
%    First character is R for Real, C for complex, P for pattern only.
%    Second character is S for symmetric, U for unsymmetric, H for
%      Hermitian, Z for skew symmetric, R for rectangular.
%    Third character is A for assembled and E for unassembled
%      finite element matrices.
%
%    Input, character ( len = 3 ) RHSTYP, the right hand side type.
%    First character is F for full storage or M for same as matrix.
%    Second character is G if starting "guess" vectors are supplied.
%    Third character is X if exact solution vectors are supplied.
%    Ignored if NRHS = 0.
%
%    If RHSTYP(1:1) == 'F':
%
%      Output, integer RHSPTR(*), is not used.
%
%      Output, integer RHSIND(*), is not used.
%
%      Output, real RHSVAL(NROW,NRHS), contains NRHS dense right hand
%      side vectors.
%
%    If RHSTYP(1:1) = 'M' and MXTYPE(3:3) = 'A':
%
%      Output, integer RHSPTR(NRHS+1), RHSPTR(I) points to the location of
%      the first entry of right hand side I in the sparse right hand
%      side vector.
%
%      Output, integer RHSIND(NRHSIX), indicates, for each entry of
%      RHSVAL, the corresponding row index.
%
%      Output, real RHSVAL(NRHSIX), contains the value of the right hand
%      side entries.
%
%    If RHSTYP(1:1) = 'M' and MXTYPE(3:3) = 'E':
%
%      Output, integer RHSPTR(*), is not used.
%
%      Output, integer RHSIND(*), is not used.
%
%      Output, real RHSVAL(NNZERO,NRHS), contains NRHS unassembled
%      finite element vector right hand sides.
%
  rhsptr = [];
  rhsind = [];
  rhsval = [];
%
%  Read the right hand sides.
%    case F                             = "full" or "dense";
%    case not F + matrix storage is "A" = sparse pointer RHS
%    case not F + matrix storage is "E" = finite element RHS
%
  if ( 0 < rhscrd )
%
%  Dense right hand sides:
%
    if ( rhstyp(1) == 'F' )

      [ p, code, w, m ] = s_to_format ( rhsfmt );

      line_num = 1 + floor ( ( nrow - 1 ) / p );

      for irhs = 1 : nrhs

        jhi = 0;

        for i = 1 : line_num

          line = fgetl ( input_unit );
          jlo = jhi + 1;
          jhi = min ( jlo + p - 1, nrow );

          khi = 0;

          for j = jlo : jhi
            klo = khi + 1;
            khi = min ( klo + w - 1, length ( line ) );
            s = line(klo:khi);
            rhsval(j,irhs) = s_to_r8 ( s );
          end
        end
      end
%
%  Sparse right-hand sides stored like the matrix.
%  Read pointer array, indices, and values.
%
    elseif ( rhstyp(1) == 'M' )

      if ( mxtype(3) == 'A' )

        [ p, code, w, m ] = s_to_format ( ptrfmt );

        line_num = 1 + floor ( ( nrhs + 1 - 1 ) / p );

        jhi = 0;

        for i = 1 : line_num

          line = fgetl ( input_unit );
          jlo = jhi + 1;
          jhi = min ( jlo + p - 1, nrhs + 1 );

          khi = 0;

          for j = jlo : jhi
            klo = khi + 1;
            khi = min ( klo + w - 1, length ( line ) );
            s = line(klo:khi);
            rhsptr(j) = s_to_i4 ( s );
          end
        end

        [ p, code, w, m ] = s_to_format ( indfmt );

        line_num = 1 + floor ( ( nrhsix - 1 ) / p );

        jhi = 0;

        for i = 1 : line_num

          line = fgetl ( input_unit );
          jlo = jhi + 1;
          jhi = min ( jlo + p - 1, nrhsix );

          khi = 0;

          for j = jlo : jhi
            klo = khi + 1;
            khi = min ( klo + w - 1, length ( line ) );
            s = line(klo:khi);
            rhsind(j) = s_to_i4 ( s );
          end
        end

        [ p, code, w, m ] = s_to_format ( rhsfmt );

        line_num = 1 + floor ( ( nrhsix - 1 ) / p );

        jhi = 0;

        for i = 1 : line_num

          line = fgetl ( input_unit );
          jlo = jhi + 1;
          jhi = min ( jlo + p - 1, nrhsix );

          khi = 0;

          for j = jlo : jhi
            klo = khi + 1;
            khi = min ( klo + w - 1, length ( line ) );
            s = line(klo:khi);
            rhsval(j) = s_to_r8 ( s );
          end
        end
%
%  Sparse right hand sides in finite element format.
%
      elseif ( mxtype(3) == 'E' )

        [ p, code, w, m ] = s_to_format ( rhsfmt );

        line_num = 1 + floor ( ( nnzero - 1 ) / p );

        for irhs = 1 : nrhs

          jhi = 0;

          for i = 1 : line_num

            line = fgetl ( input_unit );
            jlo = jhi + 1;
            jhi = min ( jlo + p - 1, nnzero );

            khi = 0;

            for j = jlo : jhi
              klo = khi + 1;
              khi = min ( klo + w - 1, length ( line ) );
              s = line(klo:khi);
              rhsval(j,irhs) = s_to_r8 ( s );
            end
          end
        end

      else

        fprintf ( 1, '\n' );
        fprintf ( 1, 'HB_RHS_READ - Fatal error!\n' );
        fprintf ( 1, '  Illegal value of MXTYPE(3)!\n' );
        error ( 'HB_RHS_READ - Fatal error!' );

      end
%
%  0 < RHSCARD, but RHSTYP not recognized.
%
    else

      fprintf ( 1, '\n' );
      fprintf ( 1, 'HB_RHS_READ - Fatal error!\n' );
      fprintf ( 1, '  Illegal value of RHSTYP(1)!\n' );
      error ( 'HB_RHS_READ - Fatal error!' );

    end

  end

  return
end
function [ colptr, rowind ] = hb_structure_read ( input_unit, ncol, mxtype, ...
  nnzero, neltvl, ptrcrd, ptrfmt, indcrd, indfmt )

%*****************************************************************************80
%
%% HB_STRUCTURE_READ reads the structure of an HB matrix.
%
%  Discussion:
%
%    The user should already have opened the file, and positioned it
%    to just after the header records.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    08 April 2004
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    Iain Duff, Roger Grimes, John Lewis,
%    User's Guide for the Harwell-Boeing Sparse Matrix Collection,
%    October 1992.
%
%  Parameters:
%
%    Input, integer INPUT_UNIT, the unit from which data is read.
%
%    Input, integer NCOL, the number of columns.
%
%    Input, character ( len = 3 ) MXTYPE, the matrix type.
%    First character is R for Real, C for complex, P for pattern only.
%    Second character is S for symmetric, U for unsymmetric, H for
%      Hermitian, Z for skew symmetric, R for rectangular.
%    Third character is A for assembled and E for unassembled
%      finite element matrices.
%
%    Input, integer NNZERO.  In the case of assembled sparse matrices,
%    this is the number of nonzeroes.  In the case of unassembled finite
%    element matrices, in which the right hand side vectors are also
%    stored as unassembled finite element vectors, this is the total
%    number of entries in a single unassembled right hand side vector.
%
%    Input, integer NELTVL, the number of finite element matrix entries,
%    set to 0 in the case of assembled matrices.
%
%    Input, integer PTRCRD, the number of pointer records.
%
%    Input, character ( len = 16 ) PTRFMT, the format for reading pointers.
%
%    Input, integer INDCRD, the number of index records.
%
%    Input, character ( len = 16 ) INDFMT, the format for reading indices.
%
%    Output, integer COLPTR(NCOL+1), COLPTR(I) points to the location of
%    the first entry of column I in the sparse matrix structure.
%
%    Output, integer ROWIND(NNZERO) or ROWIND(NELTVL), the row index of
%    each item.
%
  [ p, code, w, m ] = s_to_format ( ptrfmt );

  if ( mxtype(3) == 'A' )
    line_num = 1 + floor ( ( ( ncol + 1 ) - 1 ) / p );
  else
    line_num = 1 + floor ( ( ( ncol     ) - 1 ) / p );
  end

  jhi = 0;

  for i = 1 : line_num
    line = fgetl ( input_unit );
    jlo = jhi + 1;
    if ( mxtype(3) == 'A' )
      jhi = min ( jlo + p - 1, ncol + 1 );
    else
      jhi = min (  jlo + p - 1, ncol );
    end

    khi = 0;

    for j = jlo : jhi
      klo = khi + 1;
      khi = min ( klo + w - 1, length ( line ) );
      s = line(klo:khi);
      colptr(j) = s_to_i4 ( s );
    end

  end

  if ( mxtype(3) == 'A' )

    [ p, code, w, m ] = s_to_format ( indfmt );

    line_num = 1 + floor ( ( nnzero - 1 ) / p );

    jhi = 0;

    for i = 1 : line_num
      line = fgetl ( input_unit );
      jlo = jhi + 1;
      jhi = min ( jlo + p - 1, nnzero );

      khi = 0;

      for j = jlo : jhi
        klo = khi + 1;
        khi = min ( klo + w - 1, length ( line ) );
        s = line(klo:khi);
        rowind(j) = s_to_i4 ( s );
      end

    end

  elseif ( mxtype(3) == 'E' )

    [ p, code, w, m ] = s_to_format ( indfmt );
    number = colptr(ncol) - colptr(1);
    line_num = 1 + floor ( ( number - 1 ) / p );

    jhi = 0;

    for i = 1 : line_num
      line = fgetl ( input_unit );
      jlo = jhi + 1;
      jhi = min ( jlo + p - 1, number );

      khi = 0;

      for j = jlo : jhi
        klo = khi + 1;
        khi = min ( klo + w - 1, length ( line ) );
        s = line(klo:khi);
        rowind(j) = s_to_i4 ( s );
      end

    end

  else

    fprintf ( 1, '\n' );
    fprintf ( 1, 'HB_STRUCTURE_READ - Fatal error!\n' );
    fprintf ( 1, '  Illegal value of MXTYPE(3).\n' );
    return

  end

  return
end
function values = hb_values_read ( input_unit, valcrd, mxtype, nnzero, ...
  neltvl, valfmt )

%*****************************************************************************80
%
%% HB_VALUES_READ reads the values of an HB matrix.
%
%  Discussion:
%
%    The user should already have opened the file, and positioned it
%    to just after the header and structure records.
%
%    Values are contained in an HB file if the VALCRD parameter
%    is nonzero.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    04 February 2005
%
%  Author:
%
%    John Burkardt
%
%  Reference:
%
%    Iain Duff, Roger Grimes, John Lewis,
%    User's Guide for the Harwell-Boeing Sparse Matrix Collection,
%    October 1992.
%
%  Parameters:
%
%    Input, integer INPUT_UNIT, the unit from which data is read.
%
%    Input, integer VALCRD, the number of input lines for numerical values.
%
%    Input, character ( len = 3 ) MXTYPE, the matrix type.
%    First character is R for Real, C for complex, P for pattern only.
%    Second character is S for symmetric, U for unsymmetric, H for
%      Hermitian, Z for skew symmetric, R for rectangular.
%    Third character is A for assembled and E for unassembled
%      finite element matrices.
%
%    Input, integer NNZERO.  In the case of assembled sparse matrices,
%    this is the number of nonzeroes.  In the case of unassembled finite
%    element matrices, in which the right hand side vectors are also
%    stored as unassembled finite element vectors, this is the total
%    number of entries in a single unassembled right hand side vector.
%
%    Input, integer NELTVL, the number of finite element matrix entries,
%    set to 0 in the case of assembled matrices.
%
%    Input, character ( len = 20 ) VALFMT, the format for reading values.
%
%    Output, real VALUES(NNZERO) or VALUES(NELTVL), the nonzero values
%    of the matrix.
%
  [ p, code, w, m ] = s_to_format ( valfmt );
%
%  Read the matrix values.
%    case "A" = assembled;
%    case "E" = unassembled finite element matrices.
%
  if ( 0 < valcrd )

    if ( mxtype(3:3) == 'A' )

      line_num = 1 + floor ( ( nnzero - 1 ) / p );

      jhi = 0;

      for i = 1 : line_num

        line = fgetl ( input_unit );
        jlo = jhi + 1;
        jhi = min ( jlo + p - 1, nnzero );

        khi = 0;

        for j = jlo : jhi
          klo = khi + 1;
          khi = min ( klo + w - 1, length ( line ) );
          s = line(klo:khi);
          values(j) = s_to_r8 ( s );
        end

      end

    elseif ( mxtype(3) == 'E' )

      line_num = 1 + floor ( ( neltvl - 1 ) / p );

      jhi = 0;

      for i = 1 : line_num

        line = fgetl ( input_unit );
        jlo = jhi + 1;
        jhi = min ( jlo + p - 1, neltvl );

        khi = 0;

        for j = jlo : jhi
          klo = khi + 1;
          khi = min ( klo + w - 1, length ( line ) );
          s = line(klo:khi);
          values(j) = s_to_r8 ( s );
        end

      end

    else

      fprintf ( 1, '\n' );
      fprintf ( 1, 'HB_VALUES_READ - Fatal error!\n' );
      fprintf ( 1, '  Illegal value of MXTYPE(3).\n' );
      error ( 'HB_VALUES_READ - Fatal error!' );

    end

  end

  return
end
function len = s_len_trim ( s )

%*****************************************************************************80
%
%% S_LEN_TRIM returns the length of a character string to the last nonblank.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    14 June 2003
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, string S, the string to be measured.
%
%    Output, integer LEN, the length of the string up to the last nonblank.
%
  len = length ( s );

  while ( 0 < len )
    if ( s(len) ~= ' ' )
      return
    end
    len = len - 1;
  end

  return
end
function [ r, code, w, m ] = s_to_format ( s )

%*****************************************************************************80
%
%% S_TO_FORMAT reads a FORTRAN format from a string.
%
%  Discussion:
%
%    This routine will read as many characters as possible until it reaches
%    the end of the string, or encounters a character which cannot be
%    part of the format.  This routine is limited in its ability to
%    recognize FORTRAN formats.  In particular, we are only expecting
%    a single format specification, and cannot handle extra features
%    such as 'ES' and 'EN' codes, '5X' spacing, and so on.
%
%    Legal input is:
%
%       0 nothing
%       1 blanks
%       2 optional '('
%       3 blanks
%       4 optional repeat factor R
%       5 blanks
%       6 CODE ( 'A', 'B', 'E', 'F', 'G', 'I', 'L', 'O', 'Z', '*' )
%       7 blanks
%       8 width W
%       9 optional decimal point
%      10 optional mantissa M
%      11 blanks
%      12 optional ')'
%      13 blanks
%
%  Example:
%
%    S                 R   CODE   W    M
%
%    'I12              1   I      12   0
%    'E8.0'            1   E       8   0
%    'F10.5'           1   F      10   5
%    '2G14.6'          2   G      14   6
%    '*'               1   *      -1  -1
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    22 November 2003
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, string S, the string containing the
%    data to be read.  Reading will begin at position 1 and
%    terminate at the end of the string, or when no more
%    characters can be read.
%
%    Output, integer R, the repetition factor, which defaults to 1.
%
%    Output, character CODE, the format code.
%
%    Output, integer W, the field width.
%
%    Output, integer M, the mantissa width.
%
  LEFT = 1;
  RIGHT = -1;

  state = 0;
  paren_sum = 0;
  pos = 0;
  s_length = s_len_trim ( s );

  r = 0;
  w = 0;
  code = '?';
  m = 0;

  while ( pos < s_length )

    pos = pos + 1;
    c = s(pos);
%
%  BLANK character:
%
    if ( c == ' ' )

      if ( state == 4 )
        state = 5;
      elseif ( state == 6 )
        state = 7;
      elseif ( state == 10 )
        state = 11;
      elseif ( state == 12 )
        state = 13;
      end
%
%  LEFT PAREN
%
    elseif ( c == '(' )

      if ( state < 2 )
        paren_sum = paren_sum + LEFT;
      else
        state = -1;
        break;
      end
%
%  DIGIT (R, F, or W)
%
    elseif ( ch_is_digit ( c ) )

      if ( state <= 3 )
        state = 4;
        r = ch_to_digit ( c );
      elseif ( state == 4 )
        d = ch_to_digit ( c );
        r = 10 * r + d;
      elseif ( state == 6 | state == 7 )
        if ( code == '*' )
          state = -1;
          break;
        end
        state = 8;
        w = ch_to_digit ( c );
      elseif ( state == 8 )
        d = ch_to_digit ( c );
        w = 10 * w + d;
      elseif ( state == 9 )
        state = 10;
        m = ch_to_digit ( c );
      elseif ( state == 10 )
        d = ch_to_digit ( c );
        m = 10 * m + d;
      else
        state = -1;
        break;
      end
%
%  DECIMAL POINT
%
    elseif ( c == '.' )

      if ( state == 8 )
        state = 9;
      else
        state = -1;
        break;
      end
%
%  RIGHT PAREN
%
    elseif ( c == ')' )

      paren_sum = paren_sum + RIGHT;

      if ( paren_sum ~= 0 )
        state = -1;
        break;
      end

      if ( state == 6 & code == '*' )
        state = 12;
      elseif ( 6 <= state )
        state = 12;
      else
        state = -1;
        break;
      end
%
%  Code
%
    elseif ( ch_is_format_code ( c ) )

      if ( state < 6 )
        state = 6;
        code = c;
      else
        state = -1;
        break;
      end
%
%  Unexpected character
%
    else

      state = -1;
      break;

    end

  end

  if ( paren_sum ~= 0 )
    fprintf ( 1, '\n' );
    fprintf ( 1, 'S_TO_FORMAT - Fatal error!\n' );
    fprintf ( 1, '  Parentheses mismatch.\n' );
    error ( 'S_TO_FORMAT - Fatal error!' );
  end

  if ( state < 0 )
    fprintf ( 1, '\n' );
    fprintf ( 1, 'S_TO_FORMAT - Fatal error!\n' );
    fprintf ( 1, '  Parsing error.\n' );
    error ( 'S_TO_FORMAT - Fatal error!' );
  end

  if ( r == 0 )
    r = 1;
  end

  return
end
function ival = s_to_i4 ( s )

%*****************************************************************************80
%
%% S_TO_I4 reads an integer value from a string.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    18 November 2003
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, string S, a string to be examined.
%
%    Output, integer IVAL, the integer value read from the string.
%
  sgn = 1;
  state = 0;
  ival = 0;

  i = 0;

  while ( i < s_len_trim ( s ) )

    i = i + 1;
    c = s(i);

    if ( state == 0 )

      if ( c == ' ' )

      elseif ( c == '-' )
        state = 1;
        sgn = -1;
      elseif ( c == '+' )
        state = 1;
        sgn = +1;
      elseif ( '0' <= c & c <= '9' )
        state = 2;
        ival = c - '0';
      else
        fprintf ( '\n' );
        fprintf ( 'S_TO_I4 - Fatal error!\n' );
        fprintf ( '  Illegal character %c while in state %d.\n', c, state );
        return;
      end
%
%  Have read the sign, now expecting the first digit.
%
    elseif ( state == 1 )

      if ( c == ' ' )

      elseif ( '0' <= c & c <= '9' )
        state = 2;
        ival = c - '0';
      else
        fprintf ( '\n' );
        fprintf ( 'S_TO_I4 - Fatal error!\n' );
        fprintf ( '  Illegal character %c while in state %d.\n', c, state );
        return
      end
%
%  Have read at least one digit, expecting more.
%
    elseif ( state == 2 )

      if ( '0' <= c & c <= '9' )
        ival = 10 * ival + c - '0';
      else
        ival = sgn * ival;
        return;
      end

    end

  end
%
%  If we read all the characters in the string, see if we're OK.
%
  if ( state ~= 2 )
    fprintf ( '\n' );
    fprintf ( 'S_TO_I4 - Fatal error!\n' );
    fprintf ( '  Did not read enough information to define an integer!\n' );
    return;
  end

  ival = sgn * ival;

  return
end
function [ r, lchar, ierror ] = s_to_r8 ( s )

%*****************************************************************************80
%
%% S_TO_R8 reads an R8 from a string.
%
%  Discussion:
%
%    This routine will read as many characters as possible until it reaches
%    the end of the string, or encounters a character which cannot be
%    part of the real number.
%
%    Legal input is:
%
%       1 blanks,
%       2 '+' or '-' sign,
%       2.5 spaces
%       3 integer part,
%       4 decimal point,
%       5 fraction part,
%       6 'E' or 'e' or 'D' or 'd', exponent marker,
%       7 exponent sign,
%       8 exponent integer part,
%       9 exponent decimal point,
%      10 exponent fraction part,
%      11 blanks,
%      12 final comma or semicolon.
%
%    with most quantities optional.
%
%  Example:
%
%    S                 R
%
%    '1'               1.0
%    '     1   '       1.0
%    '1A'              1.0
%    '12,34,56'        12.0
%    '  34 7'          34.0
%    '-1E2ABCD'        -100.0
%    '-1X2ABCD'        -1.0
%    ' 2E-1'           0.2
%    '23.45'           23.45
%    '-4.2E+2'         -420.0
%    '17d2'            1700.0
%    '-14e-2'         -0.14
%    'e2'              100.0
%    '-12.73e-9.23'   -12.73 * 10.0**(-9.23)
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    22 November 2003
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, string S, the string containing the
%    data to be read.  Reading will begin at position 1 and
%    terminate at the end of the string, or when no more
%    characters can be read to form a legal real.  Blanks,
%    commas, or other nonnumeric data will, in particular,
%    cause the conversion to halt.
%
%    Output, real R, the value that was read from the string.
%
%    Output, integer LCHAR, the number of characters of S that were used to form R.
%
%    Output, integer IERROR, is 0 if no error occurred.
%
  s_length = s_len_trim ( s );
  ierror = 0;
  r = 0.0;
  lchar = -1;
  isgn = 1;
  rtop = 0.0;
  rbot = 1.0;
  jsgn = 1;
  jtop = 0;
  jbot = 1;
  ihave = 1;
  iterm = 0;

  while ( 1 )

    lchar = lchar + 1;
    c = s(lchar+1);
%
%  Blank character.
%
    if ( c == ' ' )

      if ( ihave == 2 )

      elseif ( ihave == 6 | ihave == 7 )
        iterm = 1;
      elseif ( 1 < ihave )
        ihave = 11;
      end
%
%  Comma.
%
    elseif ( c == ',' | c == ';' )

      if ( ihave ~= 1 )
        iterm = 1;
        ihave = 12;
        lchar = lchar + 1;
      end
%
%  Minus sign.
%
    elseif ( c == '-' )

      if ( ihave == 1 );
        ihave = 2;
        isgn = -1;
      elseif ( ihave == 6 )
        ihave = 7;
        jsgn = -1;
      else
        iterm = 1;
      end
%
%  Plus sign.
%
    elseif ( c == '+' )

      if ( ihave == 1 )
        ihave = 2;
      elseif ( ihave == 6 )
        ihave = 7;
      else
        iterm = 1;
      end
%
%  Decimal point.
%
    elseif ( c == '.' )

      if ( ihave < 4 )
        ihave = 4;
      elseif ( 6 <= ihave & ihave <= 8 )
        ihave = 9;
      else
        iterm = 1;
      end
%
%  Exponent marker.
%
    elseif ( ch_eqi ( c, 'E' ) | ch_eqi ( c, 'D' ) )

      if ( ihave < 6 )
        ihave = 6;
      else
        iterm = 1;
      end
%
%  Digit.
%
    elseif ( ihave < 11 & ch_is_digit ( c ) )

      if ( ihave <= 2 )
        ihave = 3;
      elseif ( ihave == 4 )
        ihave = 5;
      elseif ( ihave == 6 | ihave == 7 )
        ihave = 8;
      elseif ( ihave == 9 )
        ihave = 10;
      end

      d = ch_to_digit ( c );

      if ( ihave == 3 )
        rtop = 10.0 * rtop + d;
      elseif ( ihave == 5 )
        rtop = 10.0 * rtop + d;
        rbot = 10.0 * rbot;
      elseif ( ihave == 8 )
        jtop = 10 * jtop + d;
      elseif ( ihave == 10 )
        jtop = 10 * jtop + d;
        jbot = 10 * jbot;
      end
%
%  Anything else is regarded as a terminator.
%
    else
      iterm = 1;
    end
%
%  If we haven't seen a terminator, and we haven't examined the
%  entire string, go get the next character.
%
    if ( iterm == 1 | s_length <= lchar + 1 )
      break;
    end

  end
%
%  If we haven't seen a terminator, and we have examined the
%  entire string, then we're done, and LCHAR is equal to S_LENGTH.
%
  if ( iterm ~= 1 & lchar + 1 == s_length )
    lchar = s_length;
  end
%
%  Number seems to have terminated.  Have we got a legal number?
%  Not if we terminated in states 1, 2, 6 or 7!
%
  if ( ihave == 1 | ihave == 2 | ihave == 6 | ihave == 7 )
    ierror = ihave;
    fprintf ( 1, '\n' );
    fprintf ( 1, 'S_TO_R8 - Fatal error!\n' );
    fprintf ( 1, '  IHAVE = %d\n', ihave );
    error ( 'S_TO_R8 - Fatal error!' );
  end
%
%  Number seems OK.  Form it.
%
  if ( jtop == 0 )
    rexp = 1.0;
  else

    if ( jbot == 1 )
      rexp = 10.0^( jsgn * jtop );
    else
      rexp = jsgn * jtop;
      rexp = rexp / jbot;
      rexp = 10.0^rexp;
    end

  end

  r = isgn * rexp * rtop / rbot;

  return
end
function st_data_print ( nrow, ncol, nnzero, row, col, a, title )

%*****************************************************************************80
%
%% ST_DATA_PRINT prints the data in an ST file.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    01 November 2008
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer NROW, the assumed number of rows in the matrix.
%
%    Input, integer NCOL, the assumed number of columns in the matrix.
%
%    Input, integer NNZERO, the assumed number of nonzeros in the matrix.
%
%    Input, integer ROW(NNZERO), COL(NNZERO), the 0-based row and column
%    index of a nonzero matrix entry.
%
%    Input, real A(NNZERO), the value of a nonzero matrix entry.
%
%    Input, string TITLE, a title.
%
  st_data_print_some ( 0, nrow-1, 0, ncol-1, nnzero, row, col, a, title );

  return
end
function st_data_print_some ( row1, row2, col1, col2, nnzero, row, col, a, ...
  title )

%*****************************************************************************80
%
%% ST_DATA_PRINT_SOME prints some of the data in an ST file.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    01 November 2008
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer ROW1, ROW2, the first and last rows to print.
%
%    Input, integer COL1, COL2, the first and last columns to print.
%
%    Input, integer NNZERO, the assumed number of nonzeros in the matrix.
%
%    Input, integer ROW(NNZERO), COL(NNZERO), the 0-based row and column
%    index of a nonzero matrix entry.
%
%    Input, real A(NNZERO), the value of a nonzero matrix entry.
%
%    Input, string TITLE, a title.
%
  fprintf ( 1, '\n' );
  fprintf ( 1, '%s\n', title );
  fprintf ( 1, '\n' );

  for k = 1 : nnzero
    if ( row1 <= row(k) & row(k) <= row2 & col1 <= col(k) & col(k) <= col2 )
      fprintf ( 1, '  %8d  %8d  %8d  %16.8f\n', k, row(k), col(k), a(k) );
    end
  end

  return
end
function st_data_write ( output_filename, nrow, ncol, nnzero, row, col, a )

%*****************************************************************************80
%
%% ST_DATA_WRITE writes the data of an ST file.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    01 November 2008
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, string OUTPUT_FILENAME, the name of the ST file.
%
%    Input, integer NROW, the assumed number of rows in the matrix.
%
%    Input, integer NCOL, the assumed number of columns in the matrix.
%
%    Input, integer NNZERO, the assumed number of nonzeros in the matrix.
%
%    Input, integer ROW(NNZERO), COL(NNZERO), the 0-based row and column
%    index of a nonzero matrix entry.
%
%    Input, real A(NNZERO), the value of a nonzero matrix entry.
%
  output_unit = fopen ( output_filename, 'wt' );

  if ( output_unit < 0 )
    fprintf ( 1, '\n' );
    fprintf ( 1, 'ST_DATA_WRITE - Error!\n' );
    fprintf ( 1, '  Could not open the output file.\n' );
    error ( 'ST_DATA_WRITE - Error!' );
    return;
  end

  for k = 1 : nnzero

    fprintf ( output_unit, '  %8d  %8d  %16.8f\n', row(k), col(k), a(k) );

  end

  fclose ( output_unit );

  return
end
function st_header_print ( nrow, ncol, nnzero )

%*****************************************************************************80
%
%% ST_HEADER_PRINT prints the header of an ST file.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    01 November 2008
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer NROW, the assumed number of rows in the matrix.
%
%    Input, integer NCOL, the assumed number of columns in the matrix.
%
%    Input, integer NNZERO, the assumed number of nonzeros in the matrix.
%
  fprintf ( 1, '\n' );
  fprintf ( 1, '  ST header information:\n' );
  fprintf ( 1, '\n' );
  fprintf ( 1, '  Number of rows =     %d\n', nrow );
  fprintf ( 1, '  Number of columns =  %d\n', ncol );
  fprintf ( 1, '  Number of nonzeros = %d\n', nnzero );

  return
end
function st_header_write ( output_filename, nrow, ncol, nnzero )

%*****************************************************************************80
%
%% ST_HEADER_WRITE writes the header of an ST file.
%
%  Discussion:
%
%    There is no header for an ST file.  But for completeness, we supply
%    this dummy routine.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    01 November 2008
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, string OUTPUT_FILENAME, the name of the ST file.
%
%    Input, integer NROW, the assumed number of rows in the matrix.
%
%    Input, integer NCOL, the assumed number of columns in the matrix.
%
%    Input, integer NNZERO, the assumed number of nonzeros in the matrix.
%
  return
end
function indx = st_rebase ( base1, base2, nnzero, indx )

%*****************************************************************************80
%
%% ST_REBASE changes the base of an index array.
%
%  Discussion:
%
%    Both the ROW and COL arrays are ordinarily 0-based in the ST format.
%    FORTRAN and MATLAB expect 1-based indices.
%
%    To convert ROW and COL from 0-based to 1-based form, call this routine
%    with BASE1=0, BASE2=1.
%
%    If ROW and COL from FORTRAN or MATLAB are to be converted to ST format,
%    call this routine with BASE1=1 and BASE2=0.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    01 November 2008
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Input, integer BASE1, BASE2, the old and new bases.
%
%    Input, integer NNZERO, the number of nonzeros in the matrix.
%
%    Input, integer INDX(NNZERO), the index vector to be rebased.
%
%    Output, integer INDX(NNZERO), the index vector
%    to be rebased.
%
  indx(1:nnzero) = indx(1:nnzero) - base1 + base2;

  return
end
function timestamp ( )

%*****************************************************************************80
%
%% TIMESTAMP prints the current YMDHMS date as a timestamp.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    14 February 2003
%
%  Author:
%
%    John Burkardt
%
  t = now;
  c = datevec ( t );
  s = datestr ( c, 0 );
  fprintf ( 1, '%s\n', s );

  return
end


function start_num = p03_start_num ( )

%*****************************************************************************80
%
%% P03_START_NUM returns the number of starting points for problem 3.
%
%  Licensing:
%
%    This code is distributed under the GNU LGPL license.
%
%  Modified:
%
%    08 May 2011
%
%  Author:
%
%    John Burkardt
%
%  Parameters:
%
%    Output, integer START_NUM, the number of starting points.
%
  start_num = 3;

  return
end


function I1 = Normalize_Img(I)

if ndims(I) == 3
    I = rgb2gray(I);
end
I1 = imresize(I, [24 24], 'bicubic');