splinetool.m

来自「演示matlab曲线拟和与插直的基本方法」· M 代码 · 共 1,585 行 · 第 1/5 页

M
1,585
字号
            'Visible','on', ...
            'Enable','on', ...
            'Backgroundcolor',[1 1 1], ...
            'Callback','splinetool ''highlightw''', ...
            'TooltipString','Mark a weight, for editing below')
         set(hand.params(2,5),'String',lineud.w(1),'Visible','on')
         set([hand.highlightxy;hand.params([3 5],5)], ...
            'Visible','on')
         set(hand.params(4,5),'Visible','on','Value',0,'String',.1)

         markxy(hand)

      case {3,4}  % turn on the knots display in the middle
         lineud = get(hand.nameline,'Userdata');
         knots = fnbrk(lineud.cs,'knots'); npk = length(knots);
         set(hand.params(1,4),'String',knots(:), ...
            'Visible','on', ...
            'TooltipString', ...
            'Mark a knot, for editing below (same as a leftclick in graph)',...
            'Callback','splinetool ''highlightb''', ...
            'Value',1+lineud.k)
         markb(hand), set_bdisplay(knots,hand)
         if M==3
            set(get(hand.Axes(1),'Children'),'UIContextMenu',hand.context)
            set(hand.add_item,'Label','&Add Knot','Visible','on')
            set(hand.del_item,'Label','&Delete Knot','Visible','on')
            set(hand.rep_knot,'Visible','on')
                % show the newknt button and piecem window
            set([hand.piecem,hand.piecetext],'Visible','on')
	    if npk>2*lineud.k %  if there are interior knots ...
               set(hand.buttonm,'Visible','on')
	    end
         end
         set([hand.highlightb;hand.params([2,3,5],4)],'Visible','on')
         set(hand.params(4,4),'Visible','on','Value',0)
         set(hand.params(4,4), ...
	                'String',(knots(end)-knots(1))/(10*length(knots)))

      end %switch M

   case 3 %  so far, these concern a weight display

      set(get(hand.Axes(1),'Children'),'UIContextMenu',[])
      set(hand.params(1,3),'String',get(hand.dataline,'Xdata'), ...
         'Visible','on', ...
         'Backgroundcolor',.9*[1 1 1], ...
         'Callback','splinetool ''highlightxy''', ...
         'TooltipString','')
      lineud = get(hand.nameline,'Userdata');
      set([hand.highlightxy; hand.params([2 3 5],5)], 'Visible','on')
      set(hand.params(4,5),'Visible','on','Value',0,'String',.1)

      switch get(hand.method,'Value')

      case 2 % turn on the sites/jump in weights display
         tols = lineud.tol;
         if length(tols)==1
            nx = length(get(hand.dataline,'Xdata'));
            tols = [tols,ones(1,nx-1)];
            lineud.tol = tols;
            lineud.tc(1) = addchange(hand.currentline, ...
                     ['dlam = [1,zeros(1,',num2str(nx-2),')];',...
               ' %% roughness weight starts off uniform']);
            set(hand.nameline,'Userdata',lineud)
         end
         tols = [tols(2),diff(tols(2:end)),NaN];

         set(hand.params(1,5),'String',tols, ...
            'Visible','on', ...
            'Enable','on', ...
            'Backgroundcolor',[1 1 1], ...
            'Callback','splinetool ''highlightw''', ...
            'TooltipString', ...
                'Mark a jump in roughness weight, for editing below')

      case 3 % turn on the sites/weight display
         set(hand.params(1,5),'String',lineud.w(:), ...
            'Visible','on', ...
            'Enable','on', ...
            'Backgroundcolor',[1 1 1], ...
            'Callback','splinetool ''highlightw''', ...
            'TooltipString','Mark a weight, for editing below')
      end %switch get(hand.method,'Value')

      markxy(hand) % also sets the editclkr field

   end %switch get(hand.data_etc,'Value')

case 'del' % delete the current spline

   % the Value in list_names points to the current spline in that list
   listud = get(hand.list_names,'Userdata');
   V = get(hand.list_names,'Value');
   names = get_names(get(hand.list_names,'String'));

   % if this is the first or second time this session that the user deletes
   % the only spline, issue a warning, with a chance to cancel.
   if size(names,1)==1&&hand.freshstart 
      hand.freshstart = hand.freshstart-1;
      answer = questdlg(['Do you really want to delete the one remaining',...
                        ' approximation and start from scratch,',...
	                ' with the original data?'], ...
                     'Do you want to start from scratch?','OK','Cancel','OK');
      if isempty(answer)||answer(1)=='C', return, end
   end
   delete(listud.handles(V))
   listud.length = listud.length-1;
   listud.handles(V) = [];
   set(hand.list_names, ...
       'String',{names([1:V-1 V+1:end],:)}, ...
       'Value',max(1,min(V,listud.length)), ...
       'Userdata',listud);
   hand = set_current(hand);
   set_displays(hand)
   set_legend(hand,hand.Axes(1))

case 'del_item'    % delete the current item

   switch get(hand.data_etc,'Value')
   case 1
      V = get(hand.params(1,3),'Value');
      x = get(hand.dataline,'Xdata');
      if V==1||V==length(x)
         warndlg(['The Spline Tool won''t let you delete the extreme data',...
	          ' points.'], 'Attempted change of interval of approximation')
         return
      end %if V==1||V==length(x)

      y = get(hand.dataline,'Ydata'); x(V) = []; y(V) = [];

         % record the commands that effect the change:
      sV = num2str(V);
      cindex = addchange(hc, ['x(',sV,') = []; y(', ...
                        sV,') = []; %% you deleted a data point']);

      set(hand.params(1,3),'Value',min(V,length(x)))
      set(hand.params(1,5),'Value',min(V,length(y)));
      set(hand.undo,'Enable','on')
      set_data(hand,x,y)
      undoud = get(hand.undo,'Userdata');
      undoud.lineud = get(hand.nameline,'Userdata');
      set(hand.undo,'Userdata',undoud);
      lineud = get(hand.nameline,'Userdata');
         % update the weights, if any, and update data field
      if isfield(lineud,'w')
         if length(lineud.wc)==1 % we are using a standard weight;
             % simply let method 2 or 3 start the weight again
            lineud = rmfield(lineud,'w'); lineud.wc=[];
         else % we delete the corresponding weight
            lineud.w(V) = [];
            lineud.wc(end+1) = addchange(hc,['weights(',sV,')=[];', ...
              '%% delete the corresponding error weight entry']);
         end
      end
      if isfield(lineud,'tc')  % we have roughness weights in place
         temp = diff(lineud.tol(V:V+1));
         if temp
            lineud.tol(V) = temp/2;
         end
         lineud.tol(V+1) = [];
         lineud.tc(end+1) = addchange(hc,[...
            'if dlam(',sV,')\n',...
            '   dlam(',sV,'-1) = dlam(',sV,'-1) + dlam(',sV,')/2;\n',...
            '   dlam(',sV,'+1) = dlam(',sV,'+1) + dlam(',sV,')/2;\n',...
            'end, dlam(',sV,') = [];', ...
            '%% distribute the corresponding jump in the roughness', ...
            '  weight']);
      end
      if lineud.method==4
         lineud = rmfield(lineud,'knots'); lineud.kc = [];
      end
      lineud.dc(end+1) = cindex;
      set(hand.nameline,'Userdata',lineud);
      set(hand.data_etc,'Userdata',cindex);
      get_approx(hand)
      set(hand.highlightxy,'Xdata',[get(hand.highlightxy,'Xdata'),x(V)], ...
                           'Ydata',[get(hand.highlightxy,'Ydata'),y(V)])
   case 2
      V = get(hand.params(1,4),'Value');
      lineud = get(hand.nameline,'Userdata'); npk = length(lineud.knots);
      if V<=lineud.k||V>npk-lineud.k
         warndlg('The Spline Tool won''t let you delete an end knot.', ...
	          'The end knots are forever')
      else
         lineud.knots(V)=[];
         lineud = update(hand,'knots',lineud);
         lineud.kc(end+1) = addchange(hc, ['knots(',num2str(V),') = [];',...
                ' %% you deleted a knot']);

         tmp = get(hand.params(1,4),'String'); tmp(V,:)=[];
         set(hand.params(1,4),'String',tmp)
         set(hand.params(1,4),'Value',min(V,npk-lineud.k));
         set(hand.nameline,'Userdata',lineud)
	 if length(lineud.knots)<=2*lineud.k
	    set(hand.buttonm,'Visible','off')
	 end
         markb(hand), set_bdisplay(lineud.knots,hand)

         get_approx(hand)

      end

   end %switch get(hand.data_etc,'Value')

case 'export_data'

   xname = 'x'; yname = 'y'; accepted = 0;
   while ~accepted
      answer = inputdlg({...
       sprintf(['To copy the current data to the base workspace,\n', ...
        'give a name for the data sites:']),...
        '... and a name for the data values:'},...
        'Copy data to workspace', 1,{xname;yname});
      if ~isempty(answer)
         okx = okvar(answer{1}); oky = okvar(answer{2});
         if okx, xname = answer{1}; end
         if oky, yname = answer{2}; end
         if okx&&oky, accepted = 1; end
      else  break
      end
   end

   if accepted
      assignin('base',xname, get(hand.dataline','Xdata'));
      assignin('base',yname, get(hand.dataline','Ydata'));
      fprintf(['Splinetool GUI created the variables ',xname,', ',yname, ...
               ' in the current workspace.\n'])

   %      workspace -refresh
   %      % needed now to make certain the workspace browser gets updated,
   %      % but this may be fixed soon.
   end

case 'export_spline'

   % namewob = hand.name; namewob(find(namewob==' '))=[];
   namewob = hand.dbname;
   accepted = 0;
   while ~accepted
      answer = inputdlg(sprintf(...
               ['To copy the current spline to the base workspace,\n', ...
               'give a name for the spline:']), ...
               'Copy spline to workspace',1,{namewob});
      if isempty(answer), return, end
      if okvar(answer{1}), namewob = answer{1}; accepted = 1; end
   end

   lineud = get(hand.nameline,'Userdata');
   assignin('base',answer{1}, lineud.cs)
   fprintf(['Splinetool GUI created the variable ',answer{1},...
            ' in the current workspace.\n'])

case 'ginputmove'
   pt = get(gca,'CurrentPoint');
   xlim = get(gca,'Xlim');
   if xlim(1)<=pt(1,1) && pt(1,1)<=xlim(2)
      set(hand(1),'String',pt(1,1))
      if length(hand)>1, set(hand(2),'String',pt(1,2)), end
   end

case 'ginputdone'
    set(gcbf,'WindowButtonMotionFcn','','WindowButtonDownFcn','',...
         'Pointer','arrow');

case 'help'
   titlestring = ['Explanation: ',y];
   switch y

   case 'about the GUI'
      mess =...
      {'';['The GUI is meant for experimentation with some basic spline',...
       ' approximation methods: interpolation, smoothing, and least-',...
       'squares.'];
       'To the left of the graph, there are three blocks:';
       ['The TOPmost block manages the various spline approximations:',...
       ' start a new one, replicate or delete the current one',...
       ' or change its name, choose which one to be current and',...
       ' whether it is to be shown in the graph.'];
       ['The MIDDLE one is for choosing the method and its parameters.', ...
       ' It also may let you look at the 1st/2nd derivatives of',...
       ' the current approximation at the interval endpoints.'];
       ['The THIRD block is for listing and modifying the data, breaks,',...
       ' knots, and weights. Additional editing is provided by',...
       ' right-clicking on the graph.']
       ['An optional second graph, showing either the first or the second', ...
       ' derivative or else the error of the',...
       ' current approximation, is managed from the View Menu.'];
       ['The ''Bottomline'' shows the spline toolbox command that generated',...
       ' the current approximation.'];
       ['All technical terms used in the GUI are defined in the', ...
       ' Explanations, accessible from the Help Menu.'];
       [repmat('     ',1,11), '(as of ' updated,')']};

   case 'cubic spline interpolation'
      mess = concat(spterms(y), ...
    {;'';['Click on the popuplist below the Methods popuplist to see the many end conditions available here.',...
 'They are further explained elsewhere in these Explanations.'];'';
  ['A good example to try them out on is the default for choosing one''s',...
  ' own data.']});

   case 'endconditions' % end conditions
   mess = ...
   {['A good example for comparing the various endconditions is provided',...
     ' by the default choice, x = linspace(0,2*pi,31), y = cos, when',...
     ' choosing your own data.']};

   case 'Customized'
   mess = ...
   {'At each end, one may specify the first or the second derivative.'};

   case 'least squares'
   mess = concat(spterms(y), ...
    {'';['In SPAP2, hence in this GUI, the default for the weight vector',...
   '  w  is  ones(size(x)) .']}); 

   case 'cubic smoothing spline'
      mess = concat(spterms(y), ...

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?