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 + -
显示快捷键?