splinetool.m

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

M
1,585
字号
  {'';['In this GUI, the default value for the weight  w  in the error',...
  ' measure is the one used in SPAPS; it makes the error measure the',...
  ' trapezoidal rule approximation to  integral (y(t) - s(t))^2 dt .'];''; 
['Since it is usually hard to specify  p , the GUI provides',...
' Reinsch''s alternative of specifying a TOLERANCE tol,',...
' in which case  s  minimizes the roughness measure subject to having',...
' the error measure <= tol.']});

   case 'quintic smoothing spline'
      mess = {...
   ['The QUINTIC smoothing spline differs from the cubic smoothing spline',...
   ' only in that its roughness measure involves the 3rd rather than the',...
   ' 2nd derivative. Correspondingly, it is a spline of order 6 rather than',...
   ' of order 4.'];'';...
   ['In the Spline Toolbox, the quintic smoothing spline is provided by',...
   ' the command  spaps . The level of desired smoothness is specified',...
   ' indirectly, by specifying a certain tolerance, and the command',...
   ' returns the smoothest spline within that tolerance of the given data.']};

   case 'weight in roughness measure'
      mess = ...
  {'The roughness of a cubic spline  f  is measured here by the number';''; ...
  '              integral  lambda(t) [(D^2 f)(t)]^2 dt';'';...
  ['with  lambda  a piecewise constant function with breaks at the data',...
  ' sites (and nowhere else). The default for  lambda  is the constant',...
  ' function, 1 .'];'';
  ['To specify  lambda , provide, for  i=2:n,  its value  lam(i-1)  on the', ...
  ' interval  (x_{i-1} .. x_i). In calling on csaps, this is done by', ...
  ' giving the input  p  as the n-vector [smoothing parameter, lam], while',...
  ' for spaps, one gives the input  tol  as the n-vector ',...
  ' [tolerance, lam].'];'';
  ['Since  lambda  typically has only very few jumps, I have chosen to',...
 ' let you specify  lambda  in the GUI  by providing  dlam := diff([0,lam])',...
  ' (a vector with mostly zero entries), from which I then recover lam', ...
  ' as cumsum(dlam).'];'';
  ['All that changes here for a QUINTIC spline is that its third rather',...
  ' than its second derivative appears in the roughness measure.', ...
  ' In other words, the quintic smoothing spline favors a slowly varying',...
  ' second derivative, while the cubic smoothing spline favors a',...
  ' slowly varying first derivative.']};

   case 'spline'
   mess = concat(spterms(y), ...
     {''; 'In this GUI, a SPLINE of ORDER  k  with KNOT SEQUENCE';
      ' t = ( t(1),...,t(n+k) ) is any weighted sum of the  n ';
      '  B-splines  B( . | t(i:i+k) ) , i=1:n .';
      '';
      'A spline written as such a weighted sum is said to be in B-FORM.'}); 

   case 'about'
      titlestring = 'About the Spline Toolbox';
      mess = abouttext;

   otherwise
      mess = spterms(y);
   end %switch y

   msgbox(mess,titlestring)

case 'highlightb'
      markb(hand)

case 'highlightw'   % mark a weight (and the corresponding point)

      V = get(hand.params(1,5),'Value'); set(hand.params(1,3),'Value',V);
      markxy(hand)
      tmp = get(hand.params(1,5),'String');
      set(hand.params(2,5),'String',tmp(V,:))

case 'highlightxy' % highight the marked item
      markxy(hand)

case 'increment'   % convert expression to a value, checking validity

   tag = get(gcbo,'Tag');
   j = find('telmr'==tag(end));
   output = convert(hand.params(4,j),0);
   if ischar(output)
      set(hand.params(4,j),'String', ...
         shortstr(abs(eval(get(hand.params(2,j),'String')))/10,1))
      return
   else
       set(hand.params(4,j),'String',shortstr(output,1),'Value',1)
   end

case 'labels'  % change Xlabel and/or Ylabel

   reset_labels(hand,[]);

case 'make_current'
   hand = set_current(hand);
   set_displays(hand)
   for j=1:2, set_tools(hand,j,get(hand.tool(j),'Checked')), end

case 'method' % set things up for a particular method

   method(hand)

case 'move_item'     % move an item to the position suggested by its editbox

   switch get(hand.data_etc,'Value')
   case 1
      move_point(hand)
   case 2
      switch get(hand.method,'Value')
      case 2
        change_weight(hand)
      case {3,4}
        if ~move_knot(hand), return, end
        get_approx(hand)
      end % switch get(hand.method,'Value')
   case 3
      switch get(hand.method,'Value')
      case 2
        get_approx(hand)
      case 3
        change_weight(hand)
      end %switch get(hand.method,'Value')
   end %switch get(hand.data_etc,'Value')

case 'new' % start a new spline fit, using the not-a-knot end conditions

   new(hand);

case 'newknt' % redo the knot sequence according to the current approximation

   get_approx(hand)

case 'parameters'     % change to the newly specified parameters

   parameters(hand)

case 'pieces' % use the number of pieces specified

   get_approx(hand)

case 'pm'  % one of the increment/decrement guys has been clicked

   handle = gcbo; tag = get(handle,'Tag');
   % find out whether to increment or decrement, ...
   pm = '+';  if tag(1)=='m', pm = '-'; end

   % ... then change the numerical value of its edit field accordingly ...
   j = find('telmr'==tag(end));
   set(hand.params(2,j),'String', eval([get(hand.params(2,j),'String'),pm, ...
      get(hand.params(4,j),'String')]));

   % ... and invoke its callback
   eval(get(hand.params(2,j),'Callback'))

case 'print_graph'  % preserve current graphs as separate figure

   figpos = get(hand.figure,'Position');
   listpos = get(hand.listframe,'Position');
   bottpos = get(hand.bottomlinetext,'Position');
   shiftx = sum(listpos([1,3]))*figpos(3);
   shifty = sum(bottpos([2,4]))*figpos(4);
   pfigpos = figpos + [shiftx,shifty,-shiftx,-shifty];
   xyscale = figpos(3:4)./pfigpos(3:4);

   printfig = figure('Toolbar','figure',...
    'DockControls','off', ...
        'Units','normalized', ...
        'Position',pfigpos, ...
    'numbertitle','off',  ...
    'toolbar','figure', ...
    'HandleVisibility','off', ...
    'name',['Spline Tool graph (at ',showtime,')']);
   curcontext = get(hand.Axes(1),'UIContextMenu');
   set(get(hand.Axes(1),'Children'),'UIContextMenu',[])
   copyobj(hand.Axes(1), printfig);
   set(get(hand.Axes(1),'Children'),'UIContextMenu',curcontext)
   axepos = get(hand.Axes(1),'Position');
   axepos(1:2) = axepos(1:2).*xyscale-[shiftx, shifty]./pfigpos(3:4);
   axepos(3:4) = axepos(3:4).*xyscale;
   set(findobj(printfig,'Tag','Axes1'), ...
        'ButtonDownFcn','', ...
        'Position', axepos, ...
        'UIContextMenu',[])
   if any(get(hand.viewmenu,'Userdata'))
      copyobj(hand.Axes(2),printfig);
   axepos = get(hand.Axes(2),'Position');
   axepos(1:2) = axepos(1:2).*xyscale-[shiftx, shifty]./pfigpos(3:4);
   axepos(3:4) = axepos(3:4).*xyscale;
      set(findobj(printfig,'Tag','Axes2'), ...
        'ButtonDownFcn','', ...
        'Position', axepos, ...
        'UIContextMenu',[])
   end

   if isequal(get(hand.tool(2),'Checked'),'on')
      % in order to ensure that the legend has the same relative position
      % in the print_axis as in Axes1, we need to make the following
      % calculations:
         oldpos = get(hand.Axes(1),'Position');
         newpos = get(findobj(printfig,'Tag','Axes1'),'Position');
         legpos = get(legend(hand.Axes(1)),'Position');
         scales = newpos(3:4)./oldpos(3:4);
      set_legend(hand,findobj(printfig,'Tag','Axes1'), ...
                  [newpos(1:2)+scales.*(legpos(1:2)-oldpos(1:2)), ...
                      scales.*legpos(3:4)])
   end 


case 'rep' % start a new spline as a replica of the current spline

   % set up a new line as current line, updating the list
   oldnameline = hand.nameline;
   [currentname, hand.nameline] = add_to_list(hand);
   dboldname = hand.dbname; hand.name = currentname;
   hand.dbname = deblank(currentname); set(gcbf,'Userdata',hand)

   % copy the stuff from the old current line to the new line
   lineud = get(oldnameline,'Userdata');
   if lineud.method==3|| ...
      (lineud.method==4&&isfield(lineud,'kc'))
                     % put latest fit into knot calculations, just in case
      lineud = update(hand,'fit',lineud);
      lineud.kc(end+1) = addchange(hc, ...
                          [hand.dbname,' = ',dboldname,'; ', ...
                         '%% replicate the current approximation']);
   end
      % change the bottom line to the new name (looks strange if most recent
      %    fit used newknt )
   lineud.bottom = [' ', hand.dbname, ...
                    lineud.bottom(findstr(' =',lineud.bottom(1:14)):end)];
   set(hand.bottomlinetext, 'String',lineud.bottom)
   set(hand.nameline, ...
      'Xdata',get(oldnameline,'Xdata'),...
      'Ydata',get(oldnameline,'Ydata'),...
      'Userdata',lineud);

   % no need to update endconds, model, rest of display, except for
   set_view_label(currentname,hand)
   set_legend(hand,hand.Axes(1))
  
case 'rep_knot' % replicate the marked knot

   switch get(hand.method,'Value')
   case 3
      V = get(hand.params(1,4),'Value');
      lineud = get(hand.nameline,'Userdata');
      index = find(lineud.knots==lineud.knots(V));
      if length(index)>=lineud.k
         warndlg(['There is no point in having knots of multiplicity',...
                   ' greater than the order of the spline.']), return
      end
      lineud.knots = lineud.knots([1:V,V:end]);
      lineud = update(hand,'knots',lineud);
      sV = num2str(V);
      lineud.kc(end+1) = addchange(hc, ...
                     ['knots = knots([1:',sV,',',sV,':end]);', ...
            ' %% you replicated a knot']);
      set(hand.nameline,'Userdata',lineud)
      set(hand.params(1,4),'String',lineud.knots(:), 'Value', V+1 )
      % update knots display
      markb(hand), set_bdisplay(lineud.knots,hand)

      get_approx(hand)

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

case 'restart'

   switch get(gcbo,'Tag')
   case 'restart'
      answer = questdlg('Do you really want to restart the SPLINE TOOL?', ...
                     'Do you want to restart?','OK','Cancel','OK');
   case 'import_data'
      answer = questdlg(['Do you really want to delete the current ',...
            'approximation(s) and to start fresh, with new data?'], ...
                     'Do you want to start fresh?','OK','Cancel','OK');
   end
   if isempty(answer)||answer(1)=='C', return, end
   splinetool 'closefile'
   splinetool

case 'save2mfile'

      % check whether any of the visible fits involves edited data or user-
      % supplied knots or weights
   names = get_names(get(hand.list_names,'String'));
   listud = get(hand.list_names,'Userdata');
   datachanged = 0; othermanual = 0;
   vv = find(names(:,1)=='v').';
   for v=vv
     lineud = get(listud.handles(v),'Userdata');
     if lineud.dc(end)~=0, datachanged = 1; end
     if (isfield(lineud,'kc')&&length(lineud.kc))|| ...
        (isfield(lineud,'tc')&&length(lineud.tc)>1)|| ...
        (isfield(lineud,'wc')&&length(lineud.wc)>1)
        othermanual = 1; end
   end

      % get a file name
   mfname = ''; coru = ''; curdir = pwd;
   if ~(curdir(end)==filesep), curdir = [curdir filesep]; end
   getfiletitle = 'Choose a Name for the M-File';
   while isempty(coru)
      [mfname,pn] = uiputfile([curdir mfname], getfiletitle);
      if isequal(mfname,0)||isequal(pn,0)
           % the user hit Cancel, so give up on this
         return
      else
         checked = 0;
         if length(mfname)>2&&isequal(mfname(end-1:end),'.m') 
            % strip off terminal .m
            mfname(end-1:end) = []; checked = 1; end
         if isvarname(mfname) % if a valid name, check whether it is taken
            fullfilename = [pn mfname,'.m'];
            if ~exist(fullfilename, 'file')
	       coru = 'cre';
            else
	       if checked
	          anss = 'Yes';
               else	
                  anss = questdlg(['The M-file  ',fullfilename, ...

⌨️ 快捷键说明

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