function nnd2n1(cmd,arg1,arg2,arg3)
%NND2N1 One-input neuron demonstration.
%
%  This demonstration requires either the MININNET functions
%  on the NND disk or the Neural Network Toolbox.

% $Revision: 1.7 $
% Copyright 1994-2002 PWS Publishing Company and The MathWorks, Inc.
% First Version, 8-31-95.

%==================================================================

% CONSTANTS
me = 'nnd2n1';
max_t = 0.5;
w_max = 2;
p_max = 4;

% FLAGS
change_func = 0;

% DEFAULTS
if nargin == 0, cmd = ''; else cmd = lower(cmd); end

% FIND WINDOW IF IT EXISTS
fig = nndfgflg(me);
if length(get(fig,'children')) == 0, fig = 0; end
  
% GET WINDOW DATA IF IT EXISTS
if fig
  H = get(fig,'userdata');
  fig_axis = H(1);            % window axis
  desc_text = H(2);           % handle to first line of text sequence
  meters = H(3:6);            % input and output meters (axes)
  indicators = H(7:9);        % input and output indicators (patches)
  lines = H(10:12);           % lines in neuron function axis
  w_ptr = H(13);              % pointer to weight vector
  b_ptr = H(14);              % pointer to bias value
  f_ptr = H(15);              % pointer to transfer function
  p_ptr = H(16);              % pointer to input vector
  f_menu = H(17);             % transfer function menu
  f_text = H(18);             % neuron heading text
  cross = H(19);              % origon cross lines
end

%==================================================================
% Activate the window.
%
% ME() or ME('')
%==================================================================

if strcmp(cmd,'')
  if fig
    figure(fig)
    set(fig,'visible','on')
  else
    feval(me,'init')
  end

%==================================================================
% Close the window.
%
% ME() or ME('')
%==================================================================

elseif strcmp(cmd,'close') & (fig)
  delete(fig)

%==================================================================
% Initialize the window.
%
% ME('init')
%==================================================================

elseif strcmp(cmd,'init') & (~fig)

  % CHECK FOR TRANSFER FUNCTIONS
  if ~nnfexist(me), return, end

  % CONSTANTS
  w = 1;
  b = 0;
  p = 0;
  f = 'purelin';
  n = w*p+b;
  a = feval(f,n);
  title_str = 'Neuron Model Demonstration';
  chapter_str = 'Chapter 2';
  a_lim = [-2 2];
  P = [-p_max:0.1:p_max];
  [R,Q] = size(P);
  A = feval(f,w*P+b*ones(1,Q));
  ind = find(A >= -p_max & A <= p_max);
  P = P(ind);
  A = A(ind);

  % NEW DEMO FIGURE
  fig = nndemof2(me,'DESIGN','One-Input Neuron','','Chapter 2');
  set(fig, ...
    'windowbuttondownfcn',nncallbk(me,'down'), ...
    'BackingStore','off',...
    'nextplot','add');
  H = get(fig,'userdata');
  fig_axis = H(1);
  desc_text = H(2);

  % ICON
  nndicon(2,458,363,'shadow')

  % NEURON DIAGRAM
  x = 60;
  y = 340;
  plot(x+[0 100],y-[50 50],...
   'linewidth',4,...
   'color',nnred);
  plot(x+[100 100],y-[49 91],...
   'linewidth',4,...
   'color',nnred);
  nndicon(100,x+100,y-50)
  plot(x+[125 185],y-[50 50],...
   'linewidth',4,...
   'color',nnred);
  plot(x+[200 250],y-[50 50],...
   'linewidth',4,...
   'color',nnred);
  plot(x+[240 250 240],y-[40 50 60],...
   'linewidth',4,...
   'color',nnred);
  nndicon(101,x+200,y-50)
  fill(x+[90 110 110 90],y-[115 115 95 95],nnltyell,...
    'edgecolor',nndkblue)
  text(x+101,y-106,'1',...
    'color',nndkblue,...
    'fontweight','bold',...
    'horiz','center');

  text(x-10,y-50,'p',...
    'color',nndkblue,...
    'fontweight','bold',...
    'horiz','center',...
    'erasemode','none');
  text(x+40,y-40,'w',...
    'color',nndkblue,...
    'fontweight','bold',...
    'horiz','center',...
    'erasemode','none');
  text(x+115,y-85,'b',...
    'color',nndkblue,...
    'fontweight','bold',...
    'horiz','center',...
    'erasemode','none');
  text(x+265,y-50,'a',...
    'color',nndkblue,...
    'fontweight','bold',...
    'horiz','center',...
    'erasemode','none');

  deg = pi/180;
  angle = [0:5:90]*deg;
  xc = cos(angle)*10;
  yc = sin(angle)*10;

  plot(x-20-xc,y-20+yc,...
   'linewidth',3,...
   'color',nndkblue);
  plot(x+[-20 0],y-[10 10],...
   'linewidth',3,...
   'color',nndkblue);
  plot(x+xc,y-20+yc,...
   'linewidth',3,...
   'color',nndkblue);
  plot(x-20-xc,y-115-yc,...
   'linewidth',3,...
   'color',nndkblue);
  plot(x+[-20 0],y-[125 125],...
   'linewidth',3,...
   'color',nndkblue);
  plot(x+xc,y-115-yc,...
   'linewidth',3,...
   'color',nndkblue);
  text(x-10,y+5,'Input',...
    'color',nndkblue,...
    'fontweight','bold',...
    'horiz','center');

  plot(x+30-xc,y-20+yc,...
   'linewidth',3,...
   'color',nndkblue);
  plot(x+[30 280],y-[10 10],...
   'linewidth',3,...
   'color',nndkblue);
  plot(x+280+xc,y-20+yc,...
   'linewidth',3,...
   'color',nndkblue);
  plot(x+30-xc,y-115-yc,...
   'linewidth',3,...
   'color',nndkblue);
  plot(x+[30 280],y-[125 125],...
   'linewidth',3,...
   'color',nndkblue);
  plot(x+280+xc,y-115-yc,...
   'linewidth',3,...
   'color',nndkblue);
  f_text = text(x+155,y+5,'Linear Neuron: a = purelin(w*p+b)',...
    'color',nndkblue,...
    'fontweight','bold',...
    'horiz','center',...
    'erasemode','none');

  % PARAMETERS
  y = 160;
  x = 40;
  text(x+40,y-100,'F:',...
    'fontname','helvetica',...
    'fontweight','bold',...
    'color',nndkblue,...
    'horiz','center',...
    'fontsize',12)

  w_axis = nnsfo('a2','w','','');

  set(w_axis, ...
    'units','points',...
    'position',[x y 70 20],...
    'color',nnmdgray,...
    'ylim',[-0.3 1.3],...
    'ytick',[],...
    'xlim',[-1.3 1.3]*w_max,...
    'xtick',[-1 -0.5 0 0.5 1]*w_max,...
    'xticklabel',str2mat(num2str(-w_max),'','0','',num2str(w_max)))

  w_ind = fill([0 0.2 -0.2]*w_max+w,[0 1 1],nnred,...
    'edgecolor',nndkblue,...
    'erasemode','none');

  b_axis = nnsfo('a2','b','','');

  set(b_axis, ...
    'units','points',...
    'position',[x y-65 70 20],...
    'color',nnmdgray,...
    'ylim',[-0.3 1.3],...
    'ytick',[],...
    'xlim',[-1.3 1.3]*w_max,...
    'xtick',[-1 -0.5 0 0.5 1]*w_max,...
    'xticklabel',str2mat(num2str(-w_max),'','0','',num2str(w_max)))

  b_ind = fill([0 0.2 -0.2]*w_max+b,[0 1 1],nnred,...
    'edgecolor',nndkblue,...
    'erasemode','none');
  f_menu = uicontrol(...
    'units','points',...
    'position',[x y-130, 80 20],...
    'style','popupmenu',...
    'string','Hardlim|Hardlims|Purelin|Satlin|Satlins|Logsig|Tansig',...
    'background',nnmdgray,...
    'callback',[me '(''function'')'],...
    'value',3);


  % NEURON FUNCTION
  y = 40;
  x = 200;
  a_axis = nnsfo('a2','','p','a');
  set(get(a_axis,'xlabel'),...
    'fontsize',12)
  set(get(a_axis,'ylabel'),...
    'fontsize',12)
  set(a_axis, ...
    'units','points',...
    'position',[x y 140 140],...
    'color',nnltyell,...
    'xlim',[-1.05 1.05]*p_max,...
    'xtick',[-4 -2 0 2 4],...
    'ylim',[-1.05 1.05]*p_max,...
    'ytick',[-4 -2 0 2 4])
  cross = plot([-p_max p_max NaN 0 0],[0 0 NaN -p_max p_max],':',...
    'color',nndkblue,...
    'erasemode','none');
  p_line = plot([p p],[-p_max p_max],'--',...
    'color',nnred,...
    'erasemode','none');
  a = feval(f,w*p+b);
  a_line = line([-p_max p],[a a],...
    'color',nnred,...
    'erasemode','none');
  A_line = line(P,A,...
    'color',nndkblue,...
    'erasemode','none',...
    'linewidth',2);
  p_axis = nnsfo('a2','','','');
  set(p_axis, ...
    'units','points',...
    'position',[x y+140 140 15],...
    'color',nnltyell,...
    'xlim',[-1.05 1.05]*p_max,...
    'xtick',[-4 -2 0 2 4],...
    'ylim',[-0.1 1.1],...
    'ytick',[])
  axis('off')
  p_ind = fill([0 0.125 -0.125]*p_max+p,[0 1 1],nnred,...
    'edgecolor',nndkblue,...
    'erasemode','none');

  % BUTTONS
  drawnow % Let everything else appear before buttons 
  uicontrol(...
    'units','points',...
    'position',[400 110 60 20],...
    'string','Contents',...
    'callback','nndtoc')
  uicontrol(...
    'units','points',...
    'position',[400 75 60 20],...
    'string','Close',...
    'callback',[me '(''close'')'])

  % DATA POINTERS
  meters = [w_axis b_axis p_axis a_axis];
  indicators = [w_ind b_ind p_ind];
  lines = [p_line a_line A_line];
  w_ptr = uicontrol('visible','off'); set(w_ptr,'userdata',w);
  b_ptr = uicontrol('visible','off'); set(b_ptr,'userdata',b);
  f_ptr = uicontrol('visible','off'); set(f_ptr,'userdata',f);
  p_ptr = uicontrol('visible','off'); set(p_ptr,'userdata',p);

  % SAVE WINDOW DATA AND LOCK
  H = [fig_axis desc_text meters indicators lines w_ptr b_ptr f_ptr p_ptr ...
    f_menu f_text cross];
  set(fig,'userdata',H,'nextplot','new')

  % INSTRUCTION TEXT
  feval(me,'instr');

  % LOCK WINDOW
  set(fig,...
   'nextplot','new',...
   'color',nnltgray);

  nnchkfs;

%==================================================================
% Display the instructions.
%
% ME('instr')
%==================================================================

elseif strcmp(cmd,'instr') & (fig)
  nnsettxt(desc_text,...
    'Alter the weight, bias',...
    'and input by dragging',...
    'the triangular shaped',...
    'indicators.',...
  '',...
  'Pick the transfer',...
  'function with the',...
  'F menu.',...
    '',...
    'Watch the change to',...
    'the neuron function',...
    'and its output.')
    
%==================================================================
% Respond to mouse down.
%
% ME('down')
%==================================================================

elseif strcmp(cmd,'down') & (fig) & (nargin == 1)

  q = 0;
  for i=1:3
    pt = get(meters(i),'currentpoint');
    x = pt(1);
    y = pt(3);

    if (i <= 2)
      if (x >= -1.3*w_max) & (x <= 1.3*w_max) & (y >= 0) & (y <= 1)
        q = i;
        z_max = w_max;
        z = x;
        hide_color = nnmdgray;
        width = 0.2;
        break;
      end
    else
      if (x >= -1.1*p_max) & (x <= 1.1*p_max) & (y >= 0) & (y <= 1)
        q = i;
        z_max = p_max;
        z = x;
        hide_color = nnltgray;
        width = 0.125;
        break;
      end
    end
  end

  if (q)
    set(fig,'pointer','crosshair')
    z = min(z_max,max(-z_max,z));
    set(indicators(q),...
      'facecolor',hide_color,...
      'edgecolor',hide_color)
    set(indicators(q),...
      'xdata',[0 1 -1]*width*z_max+z,...
      'facecolor',nnred,...
      'edgecolor',nndkblue)
    set(fig,'WindowButtonMotionFcn',[me '(''down'')']);
    set(fig,'WindowButtonUpFcn',[me '(''up'')']);

    % ALTER VARIABLES
    if (q == 1)
      set(w_ptr,'userdata',z);
      change_func = 1;
    elseif (q == 2)
      set(b_ptr,'userdata',z);
      change_func = 1;
    else
      set(p_ptr,'userdata',z);
    end
  cmd = 'update';
  else
    set(fig,'pointer','arrow')
  end

%==================================================================
% Respond to mouse up.
%
% ME('up')
%==================================================================

elseif strcmp(cmd,'up') & (fig) & (nargin == 1)

  set(fig,...
    'WindowButtonMotionFcn','',...
    'pointer','arrow')

%==================================================================
% Respond to function menu.
%
% ME('function')
%==================================================================

elseif strcmp(cmd,'function') & (fig) & (nargin == 1)

  v = get(f_menu,'value');

  if     v == 1, f = 'hardlim';  new_text = 'Hard Limit Neuron';
  elseif v == 2, f = 'hardlims'; new_text = 'Sym. Hard Limit Neuron';
  elseif v == 3, f = 'purelin';  new_text = 'Linear Neuron';
  elseif v == 4, f = 'satlin';   new_text = 'Saturating Linear Neuron';
  elseif v == 5, f = 'satlins';  new_text = 'Sym. Sat. Linear Neuron';
  elseif v == 6, f = 'logsig';   new_text = 'Log Sigmoid Neuron';
  elseif v == 7, f = 'tansig';   new_text = 'Tan Sigmoid Neuron';
  elseif v == 8, f = 'radbas';   new_text = 'Log Sigmoid Neuron';
  end

  new_text = [new_text ': a = ' f '(w*p+b)'];
  set(f_text,...
    'color',nnltgray);
  set(f_text,...
    'string',new_text,...
    'color',nndkblue);
  set(f_ptr,'userdata',f);
  change_func = 1;
  cmd = 'update';

%==================================================================
end

%==================================================================
% Respond to request to update displays.
%
% ME('update')
%==================================================================

if strcmp(cmd,'update') & (fig)
  
  % GET DATA
  w = get(w_ptr,'userdata');
  b = get(b_ptr,'userdata');
  f = get(f_ptr,'userdata');
  p = get(p_ptr,'userdata');

  % UPDATE OUTPUT
  n = w*p+b;
  if strcmp(f,'satlin')
    a = (~((n < 0) | (n > 1))).*n + (n > 1);
  elseif strcmp(f,'satlins')
    a = (~((n < -1) | (n > 1))).*n + (n > 1) - (n < -1);
  else
    a = feval(f,n);
  end

  % HIDE LINES
  set(lines(1:2),...
    'color',nnltyell)

  % HIDE & RECALCULATE FUNCTION IF ALTERED
  if (change_func)
    set(lines(3),...
      'color',nnltyell)
    P = [-p_max:0.1:p_max];
    [R,Q] = size(P);
    A = feval(f,w*P+b*ones(1,Q));
    ind = find(A >= -p_max & A <= p_max);
    P = P(ind);
    A = A(ind);
    set(lines(3),...
      'xdata',P,...
      'ydata',A)
  end

  % REFRESH NEURON FUNCTION & CROSS LINE
  set(lines(3),...
    'color',nndkblue)
  set(cross,...
    'color',nndkblue)

  % SHOW NEW LINES
  set(lines(1),...
    'xdata',[p p],...
    'color',nnred)
  if (a >= -p_max) & (a <= p_max)
    set(lines(2),...
      'xdata',[-p_max p],...
      'ydata',[a a],...
      'color',nnred)
    set(lines(2),...
      'visible','on')
  else
    set(lines(2),...
      'ydata',[a a],...
      'visible','off')
  end
end
