📄 fnder.m
字号:
function fprime = fnder(f,dorder)
%FNDER Differentiate a function.
%
% FNDER(F) returns the (representation of the) first derivative of the
% univariate function contained in F (and in the same form).
%
% FNDER(F,DORDER) returns the DORDER-th derivative, with DORDER expected
% to be of the form [d1,...,dm] in case the function in F is m-variate,
% and, for each i=1,..,m, di an integer to indicate that the function
% in F is to be differentiated di-fold with respect to its i-th argument.
% Here, di may be negative, resulting in di-fold integration with respect
% to the i-th argument.
%
% FNDER(...) does not work for rational splines; for them, use FNTLR instead.
%
% FNDER(...) works for functions in stform only in a very limited way, namely
% only for type tp00, and, for that, DORDER can only be [1 0] or [0 1].
%
% Examples:
%
% fnval( fnder( sp, 2), 3.14 );
% gives the value at 3.14 of the function in sp, while
%
% sp0 = fnint( fnder( sp ) );
% gives a function that differs from sp by some constant only (namely, by
% its value at 0).
%
% See also FNDIR, FNTLR, FNINT, FNCHG.
% Copyright 1987-2003 C. de Boor and The MathWorks, Inc.
% $Revision: 1.19 $
if ~isstruct(f), f = fn2fm(f); end
try %treat the function as vector-valued if it is not
sizeval = fnbrk(f,'dim');
if length(sizeval)>1, f = fnchg(f,'dz',prod(sizeval)); end
catch
error('SPLINES:FNDER:unknownfn',['Cannot handle the given form, ',f.form,'.'])
end
if nargin<2, dorder=1; end
switch f.form(1:2)
case 'pp' % the function is in ppform:
[breaks,coefs,l,k,d]=ppbrk(f);
if iscell(breaks) % the function is multivariate
m = length(k);
if length(dorder)~=m
error('SPLINES:FNDER:ordermustbevec', ...
['DORDER should be a ' num2str(m) '-vector.']), end
sizec = [d,l.*k]; %size(coefs);
for i=m:-1:1
dd = prod(sizec(1:m));
dpp = fnderp(ppmak(breaks{i},reshape(coefs,dd*l(i),k(i)),dd), ...
dorder(i));
breaks{i} = dpp.breaks; sizec(m+1) = dpp.pieces*dpp.order;
coefs = reshape(dpp.coefs,sizec);
if m>1
coefs = permute(coefs,[1,m+1,2:m]);
sizec(2:m+1) = sizec([m+1,2:m]);
end
end
fprime = ppmak(breaks,coefs,sizec);
else
fprime = fnderp(f,dorder);
end
case {'B-','BB'} % the function is in B-form or BB-form;
% omit trivial B-spline terms.
[knots,coefs,n,k,d]=spbrk(f);
if iscell(knots) % the function is multivariate
m = length(knots);
if length(dorder)~=m
error('SPLINES:FNDER:ordermustbevec', ...
['DORDER should be a ' num2str(m) '-vector.']), end
sizec = [d,n];% size(coefs);
for i=m:-1:1
dsp = fnderb(spmak(knots{i},...
reshape(coefs,prod(sizec(1:m)),sizec(m+1))),dorder(i));
knots{i} = dsp.knots; sizec(m+1) = dsp.number;
coefs = reshape(dsp.coefs,sizec);
if m>1
coefs = permute(coefs,[1,m+1,2:m]);
sizec(2:m+1) = sizec([m+1,2:m]);
end
end
fprime = spmak(knots,coefs,sizec);
else
fprime = fnderb(f,dorder);
end
case {'rp','rB'}
error('SPLINES:FNDER:notforrat',...
['FNDER does not work for rational splines. Use FNTLR instead.'])
case 'st'
if strcmp(f.form,'st-tp00')
if length(dorder)~=2||sum(dorder)>1
error('SPLINES:FNDER:onlyfirstpartial',...
['At present, only the first order partial derivatives of', ...
' a bivariate thin-plate spline can be generated.'])
end
if sum(dorder)==0, fprime = f; return, end
[centers,coefs] = stbrk(f);
if dorder(1)==1 % we are to differentiate wrto the first argument
type = 'tp10'; coefs(:,[end-1,end]) = [];
else % we are to differentiate wrto the second argument
type = 'tp01'; coefs(:,[end-2,end]) = [];
end
fprime = stmak(centers,coefs,type,fnbrk(f,'interv'));
else
error('SPLINES:FNDER:notforst',...
['FNDER does not (yet) work for st functions of type ',...
f.form(4:end),'.'])
end
otherwise
error('SPLINES:FNDER:unknownfn','F does not appear to describe a function.')
end
if length(sizeval)>1, fprime = fnchg(fprime,'dz',sizeval); end
function fprime = fnderp(f,dorder)
%FNDERP Differentiate a univariate function in ppform.
[breaks,coefs,l,k,d]=ppbrk(f);
if k<=dorder
fprime=ppmak([breaks(1) breaks(l+1)],zeros(d,1));
elseif dorder<0 % we are to integrate
fprime = f;
for j=1:(-dorder)
fprime = fnint(fprime);
end
else
knew=k-dorder;
for j=k-1:-1:knew
coefs=coefs.*repmat([j:-1:j-k+1],d*l,1);
end
fprime=ppmak(breaks,coefs(:,1:knew),d);
end
function fprime = fnderb(f,dorder)
%FNDERB Differentiate a univariate function in B-form.
[t,a,n,k,d]=spbrk(f);
if k<=dorder
fprime=spmak(t,zeros(d,n));
elseif dorder<0 % we are to integrate
fprime = f;
for j=1:(-dorder)
fprime = fnint(fprime);
end
else
knew=k-dorder;
for j=k-1:-1:knew
tt=t(j+1+[0:n])-t(1:n+1); z=find(tt>0); nn=length(z);
temp=(diff([zeros(1,d);a.'; zeros(1,d)])).';
a=temp(:,z)./repmat(tt(z)/j,d,1);
t=[t(z) t(n+2:n+j+1)]; n=nn;
end
fprime=spmak(t,a);
end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -