Code covered by the BSD License  

Highlights from
Desenvolvimento de Aplicacoes com MATLAB

image thumbnail

Desenvolvimento de Aplicacoes com MATLAB

by

 

Slides and demo files from the webinar "Desenvolvimento de Aplicacoes com MATLAB"

CelltowerGUI()
function CelltowerGUI()
% CELLTOWERGUI

% Copyright 2006 The MathWorks, Inc.


% Initial Parameters
param.towers = 15;
param.side   = 10;
param.seed   = 5;

% Generate Figure
figH = findobj('type', 'figure', 'tag', 'phonetowerGUI');
if ishandle(figH)
  close(figH);
end
figH = figure(...
  'name'                            , 'Phone Tower Location', ...
  'numbertitle'                     , 'off', ...
  'tag'                             , 'phonetowerGUI', ...
  'color'                           , [.8 .8 .8], ...
  'menubar'                         , 'none', ...
  'defaultuicontrolunits'           , 'normalized', ...
  'defaultuicontrolbackgroundcolor' , [.8 .8 .8]);

axH = axes(...
  'units'           , 'normalized', ...
  'position'        , [.05 .05 .7 .85], ...
  'tag'             , 'mainaxes');

uicontrol(...
  'style'           , 'text', ...
  'position'        , [.77 .7 .2, .05], ...
  'fontweight'      , 'bold', ...
  'string'          , 'Seed');
uicontrol(...
  'style'           , 'text', ...
  'position'        , [.77 .6 .2, .05], ...
  'fontweight'      , 'bold', ...
  'string'          , 'Side');
uicontrol(...
  'style'           , 'text', ...
  'position'        , [.77 .5 .2, .05], ...
  'fontweight'      , 'bold', ...
  'string'          , 'Towers');
uicontrol(...
  'style'           , 'edit', ...
  'position'        , [.77 .65 .2, .05], ...
  'backgroundcolor' , 'white', ...
  'string'          , num2str(param.seed), ...
  'callback'        , @changeParamCallback, ...
  'tag'             , 'seed');
uicontrol(...
  'style'           , 'edit', ...
  'position'        , [.77 .55 .2, .05], ...
  'backgroundcolor' , 'white', ...
  'string'          , num2str(param.side), ...
  'callback'        , @changeParamCallback, ...
  'tag'             , 'side');
uicontrol(...
  'style'           , 'edit', ...
  'position'        , [.77 .45 .2, .05], ...
  'backgroundcolor' , 'white', ...
  'string'          , num2str(param.towers), ...
  'callback'        , @changeParamCallback, ...
  'tag'             , 'towers');

uicontrol(...
  'style'           , 'pushbutton', ...
  'position'        , [.77 .25 .2, .05], ...
  'fontweight'      , 'bold', ...
  'callback'        , @runBtnCallback, ...
  'string'          , 'Run', ...
  'tag'             , 'run');
uicontrol(...
  'style'           , 'togglebutton', ...
  'position'        , [.77 .15 .2, .05], ...
  'fontweight'      , 'bold', ...
  'callback'        , @pauseBtnCallback, ...
  'string'          , 'Pause', ...
  'tag'             , 'pause', ...
  'enable'          , 'off');

handles = guihandles(figH);

stopOptim  = false;
pauseOptim = false;

% Initialize
[R, xL, xU, yL, yU, lb, ub, x0] = celltowersetup(param);
myplotcircles(x0, 0, '', R, xL, xU, yL, yU);

%-------------------------------------------------
  function changeParamCallback(obj, edata) %#ok

    tmp = fix(str2double(get(obj, 'string')));
    if isnan(tmp)
      errordlg('Invalid value');
      tmp = param.(get(obj, 'tag'));
    else
      switch get(obj, 'tag')
        case 'towers'
          if tmp > 25
            warndlg('Max of 25');
            tmp = 25;
          elseif tmp < 3
            warndlg('Min of 3');
            tmp = 3;
          end
        case 'side'
          if tmp > 30
            warndlg('Max of 30');
            tmp = 30;
          elseif tmp < 5
            warndlg('Min of 5');
            tmp = 5;
          end
        case 'seed'
          if tmp < 0
            warndlg('Min of 0');
            tmp = 0;
          end
      end
            
      param.(get(obj, 'tag')) = tmp;
    end
    
    set(obj, 'string', num2str(tmp));
    
    [R, xL, xU, yL, yU, lb, ub, x0] = celltowersetup(param);
    myplotcircles(x0, 0, '', R, xL, xU, yL, yU);

  end
%-------------------------------------------------

%-------------------------------------------------
  function runBtnCallback(obj, edata) %#ok

    if strcmp(get(obj, 'string'), 'Run')
      set(obj           , 'string', 'Stop');
      set(handles.pause , 'enable', 'on');
      set(handles.seed  , 'enable', 'off');
      set(handles.towers, 'enable', 'off');
      set(handles.side  , 'enable', 'off');

      options = optimset;
      options.Display = 'none';
      options.TolFun = 0.0001;
      options.OutputFcn = {
          @(x,itervals,flag) myplotcircles(x,itervals,flag,R,xL,xU,yL,yU),
          @myOutputFcn
      };
      options.LargeScale = 'on';
      options.Algorithm = 'active-set';
      %options = optimset(options, 'Display'   , 'none');
      %options = optimset(options, 'TolFun'    , 0.0001);
      %options = optimset(options, 'OutputFcn' , {@(x,itervals,flag) myplotcircles(x,itervals,flag,R,xL,xU,yL,yU), @myOutputFcn});
      %options = optimset(options, 'LargeScale', 'on');
      
      [x,fval,exitflag,output] = ...
      fmincon(@circlesIntersect, x0, [], [], [], [], lb, ub, [], options);

      plotOptimSummary(output,R,xL,xU,yL,yU);
      
      if ~ishandle(figH)
        return;
      end

      set(obj           , 'string', 'Run');
      set(handles.pause , 'enable', 'off', 'string', 'Pause', 'value', false);
      set(handles.seed  , 'enable', 'on');
      set(handles.towers, 'enable', 'on');
      set(handles.side  , 'enable', 'on');
      stopOptim  = false;
      pauseOptim = false;

    else

      set(obj           , 'string', 'Run');
      set(handles.pause , 'enable', 'off', 'string', 'Pause', 'value', false);
      set(handles.seed  , 'enable', 'on');
      set(handles.towers, 'enable', 'on');
      set(handles.side  , 'enable', 'on');
      stopOptim  = true;
      pauseOptim = false;

    end
    
  end
%-------------------------------------------------

%-------------------------------------------------
  function pauseBtnCallback(obj, edata) %#ok
    pauseOptim = ~pauseOptim;
    if pauseOptim
      set(obj, 'string', 'Resume');
    else
      set(obj, 'string', 'Pause');
    end
  end
%-------------------------------------------------

%-------------------------------------------------
% OUTPUT FUNCTION (plot cell phone locations)
%-------------------------------------------------
  function stop = myplotcircles(x,itervals,flag,R,xL,xU,yL,yU)

    if ~ishandle(figH)
      stop = true;
      return;
    end

    pts = reshape(x, 2, length(x)/2);
    X = pts(1, :);
    Y = pts(2, :);
    N = length(R);

    if isnumeric(itervals)
      iter = itervals;
    else
      iter = itervals.iteration;
    end

    switch flag
      case {'iter', ''}
        t = 0:.1:2*pi+0.1;

        set(0   , 'currentfigure', figH);
        set(figH, 'currentaxes'  , axH);
        cla;
        
        for i = 1:N
          fill(R(i)*cos(t) + X(i), R(i)*sin(t) + Y(i), [0.3 0.3 1]);
          alpha(0.5);
          text(X(i), Y(i), num2str(i), 'horizontalalignment', 'center');
          hold on
        end

        plot([xL;xU;xU;xL;xL], [yL;yL;yU;yU;yL],'r');
        axis([xL-1, xU+1, yL-1, yU+1]);
        axis square;

        title(sprintf('Iteration: %d', iter));
        pause(.05);

        while true
          if ~pauseOptim || ~ishandle(figH)
            break;
          end
          pause(.1);
        end

    end

    stop = stopOptim;

  end
%-------------------------------------------------

%-------------------------------------------------
%-------------------------------------------------

%-------------------------------------------------
% OBJECTIVE FUNCTION
%-------------------------------------------------
  function f = circlesIntersect(x)
    % CIRCLESINTERSECT Objective function for celltower problem.

    % Copyright 2003 The MathWorks, Inc.

    pts = reshape(x, 2, length(x)/2);
    N   = length(R);
    f   = 0;
    % Two circles can intersect in 0,1, 2, or all points.
    % If they intersect in 0 points, then no area to add since disjoint.
    % If they intersect in 1 point, then either have no common area
    %       of intersection (almost disjoint), or one is inside the other and barely touching.
    %       In the second case, area of intersection is the smaller circle.
    % If they intersect in 2 points, then usual case of overlapping, call
    %       circleIntersectArea to compute.
    % They can be the same circle and so intersect at all points, they can have
    % the same center but different radii (so compute diff), or they can have
    % different centers and radii but one is completely inside the other (so
    % compute diff).

    for ii = 1:N-1
      for jj = ii+1:N

        [p,q,areatotal] = areaIntersect(pts(:,ii),R(ii),pts(:,jj),R(jj));
        if isequal(pts(:,ii), pts(:,jj))
          % Circles have the same center: give a higher penalty
          f = f + areatotal + 1/(1e-8);
        else % different centers
          f = f + areatotal + 1/40 * 1/((norm(pts(:,ii)-pts(:,jj)))^2);
        end
      end
    end


    %-------------------------------
    function [p,q,areatotal,numberOfPoints] = areaIntersect(C1,r1,C2,r2)
      % Circle centers C1 and C2 with radius r1 and r2.

      % Compute x and y
      % Solve in easy coordinates
      a = norm(C1 - C2);
      % Check for divide by zero
      if isequal(a, 0)
        % Circles have same center. Return the area of the smaller circle.
        p = [NaN; NaN]; q = [NaN; NaN]; numberOfPoints = Inf;
        areatotal = pi * min(r1, r2)^2;
        return
      end
      x = 0.5*(a + (r1^2 - r2^2)/a);
      if r1^2 < x^2 % Check for sqrt of negative
        p = [NaN; NaN]; q = [NaN; NaN];
        if r1 + r2 < a
          areatotal = 0; numberOfPoints = 0;
        else % One circle is inside the other
          areatotal = pi*min(r1,r2)^2;
          numberOfPoints = Inf;
        end
        return
      end
      y = sqrt(r1^2 - x^2);

      % Original coordinates basis
      i = (C2-C1)/norm(C2-C1);
      j = null(i');

      % Intersection points in original coordinates
      p = C1 + i*x + j*y ;
      q = C1 + i*x - j*y;

      % Compute the angle theta between radius and x-axis
      % in the easy coordinates
      theta1 =  atan2(y,x);
      theta2 =  atan2(y,a-x);

      % Obtain A1 with x, y, r1
      area1 = theta1*r1^2 - x*y;
      % Obtain A2 with a-x, y, r2
      area2 = theta2*r2^2 - (a-x)*y;

      areatotal = area1 + area2;

      if isequal(p,q)
        numberOfPoints = 1;
      else
        numberOfPoints = 2;
      end

    end

  end
%-------------------------------------------------
    function stop = myOutputFcn(varargin)
        % Copyright 2006 The MathWorks, Inc.
        if nargin == 0
          % return function handle to be used as an output function
          stop = @(x, optimValues, state) myOutputFcn(x, optimValues, state);
        else
          % stores the intermediate optimization results
          stop = false;
          storeResultsFcn(varargin{:});
        end
    end

    %--------------------------------------------------------------------------
    function storeResultsFcn(x, optimValues, state)
        % Stores intermediate optimization results
        % Use this as a custom output function
        switch state
          case 'init'
            setappdata(0, 'optim_xSaved', []);

          case 'iter'
            setappdata(0, 'optim_xSaved', [getappdata(0, 'optim_xSaved'), x]);

        end
    end


end

Contact us