splinetool.m

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

M
1,585
字号
                   '  already exists. Ok to overwrite?'], ...
                     'M-file already exists ...', 'No','Yes','No');
	       end
               if isequal(anss,'Yes')
	          coru = 'upd';
	       end
            end
         else
	    temp = errordlg(['The filename, ',mfname, ...
	         ', you chose is not valid.'], 'Try again ...');
            getfiletitle = 'Choose  V A L I D  MATLAB Name for the M-File';
	    waitfor(temp)
         end
      end
   end

      % start the file
   [mfid,mess] = fopen(fullfilename,'w+');
   if mfid==-1
      errordlg(sprintf('Error trying to write to %s:\n%n',fullfilename,mess),...
               'Error saving M-file','modal')
      return
   end

      % depending on whether or not changed data are involved, ...
   if datachanged, z = '0'; else z = ''; end
   fprintf(mfid,['function ',mfname,'(x',z,',y',z,')\n', ...
    '%%', upper(mfname),'  Reconstruct figure in SPLINETOOL.\n%%\n',...
    '%%   ',upper(mfname),'(X',z,',Y',z,') creates a plot, similar ',...
                    'to the plot in SPLINETOOL,\n', ...
   '%%   using the data that you provide as input.\n',...
   '%%   You can apply this function to the same data you used with\n',...
   '%%   SPLINETOOL or with different data. You may want to edit the\n',...
   '%%   function to customize the code or even this help message.\n']);
   if datachanged||othermanual
      fprintf(mfid,['%%\n',...
   '%%   Because of data-dependent changes, this may not work for data\n',...
   '%%   sites other than the ones used in SPLINETOOL when this M-file\n',...
   '%%   was written.\n']);
   end
      % append the help

   if get(hand.dataline,'Userdata')
      fprintf(mfid, ['%%\n', ...
      '%%   SPLINETOOL was told to use the data values \n', ...
      '%%      y',z,' = feval(''',get(get(hand.Axes(1),'Ylabel'),'String'),...
                                                           ''',x',z,');\n',...
      '%%   for the given data sites x',z,...
                                    '. You may wish to do the same here.\n']);
   end

      % now start by plotting the data.

   V = get(hand.list_names,'Value');
   fprintf(mfid, ['\n%%   Make sure the data are in rows ...\n', ...
                   'x',z,' = x',z,'(:).''; y',z,' = y',z,'(:).'';\n', ...
                  '%% ... and start by plotting the data specific to the ', ...
                  'highlighted spline fit.\n\n']);
   if datachanged % we need to generate them
      fprintf(mfid,['x = x',z,'; y = y',z,';\n']);
         % get lineud.dc for current line
      lineud = get(listud.handles(V),'Userdata');
      changes = get(hc,'Userdata');
      for j=2:length(lineud.dc)
         fprintf(mfid,[changes{lineud.dc(j)},'\n']);
      end
   end

    % get ready to check on whether there is a second graph:
   viewud = get(hand.viewmenu,'Userdata'); ip = find(viewud==1); plotV = 1;

   if ~isempty(ip) % start first axes, dimensions almost those in SPLINETOOL
      fprintf(mfid,['firstbox = [0.1300  0.4900  0.7750  0.4850];\n',...
      'subplot(''Position'',firstbox)\n']);
   end
   fprintf(mfid, 'plot(x,y,''ok''), hold on\nnames={''data''};\n');
      % also set the axes labels
   fprintf(mfid, ['ylabel(''', ...
       strrep(get(get(hand.Axes(1),'Ylabel'),'String'),'\','\\'),''')\n']);
   if isempty(ip) % there is no second graph, hence
      fprintf(mfid, ['xlabel(''', ...
       strrep(get(get(hand.Axes(1),'Xlabel'),'String'),'\','\\'),''')\n']);
   else           % suppress also the tick marks on the first graph
      fprintf(mfid,'xtick = get(gca,''Xtick'');\nset(gca,''xtick'',[])\n');
   end

   switch length(vv)
   case 0
      fprintf(mfid,'\n%%  None of the fits you thought fit to print. \n\n');
      % we still may have to compute the current fit, though:
      if ~isempty(ip), vv = V; plotV=0; end
   case 1
      fprintf(mfid,'\n%%   Now generate and plot the fit.\n\n');
   otherwise
      fprintf(mfid,['\n%%   Now generate and plot the ', ...
                 num2str(length(vv)),' fits.\n\n']);
   end

      % loop over fits shown in graph, generating and plotting them, by
      % first concatenating all relevant change commands

   for v=vv
      lineud = get(listud.handles(v),'Userdata');
      if datachanged % we have to start with the original data
         fprintf(mfid, 'x = x0; y = y0;\n');
      end
         % prepare optional arguments, if any
      setknots = 0; setweights = 0; settols = 0;
      switch lineud.method
      case 1
      case 2
         if ~isempty(findstr( '= cs',lineud.bottom(4:16) ))||...
            (isfield(lineud,'wc')&&length(lineud.wc)>1)
            setweights = 1;
         end
         if isfield(lineud,'tc')&&length(lineud.tc)>1, settols = 1; end
      case 3
         if isfield(lineud,'wc')&&length(lineud.wc)>1, setweights = 1; end
         if isfield(lineud,'kc')&&length(lineud.kc)>0, setknots = 1; end
      case 4
         if isfield(lineud,'kc')&&length(lineud.kc)>0, setknots = 1; end
      end
      ic = [];
      if isfield(lineud,'dc'),  ic = [ic,lineud.dc(2:end)]; end
      if setknots,              ic = [ic,lineud.kc]; end
      if setweights,            ic = [ic,lineud.wc]; end
      if settols,               ic = [ic,lineud.tc]; end

      changes = get(hc,'Userdata');
      for j=sort(ic)
         fprintf(mfid,[changes{j},'\n']);
      end

      bottom = lineud.bottom(2:end);
         % if there are no previous commands or if the last operation had to do 
         % with knots or weights, then we still have to construct the spline fit
      if isempty(ic)||~(setknots||setweights||settols)||...
         (setknots&& ...
            ~(isempty(findstr('\nknots =',changes{lineud.kc(end)}))&&...
              isempty(findstr('\nknots(', changes{lineud.kc(end)}))))||...
         (setweights&& ...
            ~(isempty(findstr('\nweights =',changes{lineud.wc(end)}))&&...
              isempty(findstr('\nweights(', changes{lineud.wc(end)}))))||...
         (settols&& ...
            ~(isempty(findstr('\ndlam =',changes{lineud.tc(end)}))&&...
              isempty(findstr('\ndlam(',changes{lineud.tc(end)}))))
	 fprintf(mfid, [overlong(strrep(bottom,'%','%%')),'\n']);
      end

         % get the name of the spline fit
      name = bottom(1:(findstr(' =', bottom(1:12))-1));
         % add the name to the list to be used in the legend
      if v~=V||plotV
        fprintf(mfid, ['names{end+1} = ''',strrep(name,'_','\\_'),'''; ']);
      end
         % plot the spline fit, making certain to highlight the current one
      if v==V
         if plotV
            fprintf(mfid, ['fnplt(',name,',''','-',''',2)\n\n\n']); end

      % if there is a second figure, plot it now since we have the data
   %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%  code insert
   if ~isempty(ip)
           %start second axes, dimensions exactly those in SPLINETOOL
      addon = '\n\n'; 
      if V~=vv(end), addon = [' now, while we have the data current',addon];
      end
      fprintf(mfid, ...
       ['%%   Plot the second graph from SPLINETOOL',addon, ...
        'subplot(''Position'',[ 0.1300  0.1300  0.7750  0.3100])\n']);

      switch ip
      case 1
         fprintf(mfid,['fnplt(fnder(',hand.dbname,'),2)\n']);
      case 2
         fprintf(mfid,['fnplt(fnder(',hand.dbname,',2),2)\n']);
      case 3
         fprintf(mfid, ['plot(xtick([1 end]),zeros(1,2),',...
            '''Linewidth'',2,''Color'',repmat(.6,1,3))\nhold on\n']);
         if get(hand.dataline,'Userdata') % if we compare against a given f
            fprintf(mfid, ['%% we are comparing the approximation,', ...
            ' not with the data,\n%% but with a given function\n',...
            'xy = fnplt(',hand.dbname,');\nplot(xy(1,:),feval(''', ...
            get(get(hand.Axes(1),'Ylabel'),'String'),''',xy(1,:))', ...
                '-xy(2,:),''Linewidth'',2)\n']);
         else
            fprintf(mfid,['plot(x,y-fnval(',hand.dbname, ...
                                         ',x),''Linewidth'',2)\n']);
         end
         fprintf(mfid,'hold off\n');
      end %switch ip
      fprintf(mfid, ['ylabel(''', ...
          strrep(get(get(hand.Axes(2),'Ylabel'),'String'),'\','\\'),''')\n', ...
                     'xlabel(''', ...
          strrep(get(get(hand.Axes(2),'Xlabel'),'String'),'\','\\'),''')\n', ...
        '\n\n%%   Return to plotting the first graph\n', ...
        'subplot(''Position'', firstbox)\n\n\n']);
   end
   %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%  end code insert
      else
         fprintf(mfid, ['fnplt(',name,...
                ',''',get(listud.handles(v),'linestyle'),'k'')\n\n\n']);
      end
   end

      % also put in the legend
   fprintf(mfid, ['legend(names{:})\nhold off\n', ...
                 'set(gcf,''NextPlot'',''replace'')\n']);

      % finish the m-file and close it.
   fclose(mfid);
   fprintf(['Splinetool GUI ',coru,'ated the M-file  ',mfname,...
                '  in the directory ',strrep(pn(1:end-1),'\','\\'),'\n']);

case 'start'

   running = findobj(allchild(0),'name','Spline Tool');
   if ~isempty(running)
      ignore = 1;
      if nargin
         answer = questdlg(['Do you really want to restart the SPLINE TOOL',...
             ' with new data?'], ...
	     'Do you want to restart?','OK','Cancel','OK');
         if isequal(answer,'OK'), splinetool 'closefile', ignore = 0; end
      end
      if ignore, figure(running), return, end
   end

   load splinetool

   % the basic figure
   hand.figure = figure('Colormap',mat0, ...
        'DockControls','off', ...
	'FileName','splinetool.m', ...
	'PaperUnits','normalized', ...
        'PaperPosition',[.25 .10 .65 .75], ...
        'Units','normalized', ...
        'Position',[.25 .10 .65 .75], ...
     'numbertitle','off', ...
     'IntegerHandle','off',...
     'name','Spline Tool', ...
	'Tag','splinetoolfig', ...
        'doublebuffer','on', ...
        'DeleteFcn','splinetool ''closefile''', ...
     'Menubar','none', ...
	'ToolBar','none');

   if nargin<1 % if there are no data yet, ask for some:
      
      set_up_menu(hand.figure)
   else

      set(hand.figure,'Visible','off')
      hand.xynames = {x,xname,y,yname,isf,1};
      splinetool('startfinish',hand)
   end

case 'startcont'

   cf = hand{1}; handles = hand{2};
   hand = struct('figure',cf);
   messtitle = 'The point of this example: ';
   isf = 0; errortit = 'Error in input to the SPLINE TOOL';
   startmethod = 1; % the default method to start is cubic spline interpolation
   try
         % now call on my own version of the menu command
          %'Specify an m-file that provides the data', ...
       % Note that any error now, in whatever function is being called,
       % such as ask_for_data with the possibility of incorrrect function
       % or M-file names being supplied, will result in the immediate
       % termination, with the only comment the ones, if any, in the catch
       % phase.
       switch y
       case 1 % user provides data
          [x,y,xname,yname,isf] = ask_for_data;
       case 3 % noisy values of a smooth function
          x = linspace(0,2*pi,101); y = sin(x)+(rand(size(x))-.5)*.2;
	  hand.messh = ...
	  {{'The error in the spline fits is computed by comparison with';...
	    'the values of the sine function';...
	    '(rather than with the given data values).'}, ...
            messtitle, 'non-modal'};
        xname = 'x= linspace(0,2*pi,101)'; yname = 'sin'; isf = 2;
       case 4 % sin(x) on [0 .. pi/2]
          x = linspace(0,pi/2,31); y = sin(x);
          xname = 'x = linspace(0,pi/2,31)'; yname = 'sin'; isf = 2;
          hand.messh = ...
	  {{'Experiment with the various end conditions in';...
	    'Cubic Spline Interpolation. Be sure to compare';...
	    '''natural'' with ''clamped'' and ''not-a-knot''.';...
	    'For clamping, note that slope of sin at right end is 0.'}, ...
            messtitle, 'non-modal'};
       case 5 % census data, taken from the matlab demo CENSUS
	  load census
          x = cdate; y = pop;
          xname = 'year'; yname = 'population';
          hand.messh = ...
	  {{'This standard MATLAB data set describes the United States';...
	    'population as a function of time. After you have constructed';...
	    'a satisfactory spline approximation to this data set,';...
	    'export it to the workspace in order to evaluate it';...
	    'at the current year and so to wonder whether such';...
	    'extrapolation is sensible.'}, ...
            messtitle, 'non-modal'};
       case 6 % Richard Tapia's drag race data;
              % try to estimate the initial acceleration
          x = [ 0.000 0.857 2.142 3.074 3.862 4.4052 4.544];
          y = [ 0 60 330 660 1000 1254 1320];
          xname = 'time in seconds'; yname = 'distance in feet';
          hand.messh = ...
          {{'Estimate the initial acceleration.'; ...
            'One way: use a clamped cubic spline'; ...
            'and take the initial speed to be 0.'}, ...
            messtitle, 'non-modal'};
       case 7 % move knots to improve an interpolant
          [x,y] = titanium; pick =  [1 5 11 21 27 29 31 33 35 40 45 49];
          x = x(pick); y = y(pick);

⌨️ 快捷键说明

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