Download this file

145 lines (129 with data), 4.2 kB

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
function [minPos,fmin] = polyinterp(points,doPlot,xminBound,xmaxBound)
% function [minPos] = polyinterp(points,doPlot,xminBound,xmaxBound)
%
% Minimum of interpolating polynomial based on function and derivative
% values
%
% In can also be used for extrapolation if {xmin,xmax} are outside
% the domain of the points.
%
% Input:
% points(pointNum,[x f g])
% doPlot: set to 1 to plot, default: 0
% xmin: min value that brackets minimum (default: min of points)
% xmax: max value that brackets maximum (default: max of points)
%
% set f or g to sqrt(-1) if they are not known
% the order of the polynomial is the number of known f and g values minus 1
if nargin < 2
doPlot = 0;
end
nPoints = size(points,1);
order = sum(sum((imag(points(:,2:3))==0)))-1;
% Code for most common case:
% - cubic interpolation of 2 points
% w/ function and derivative values for both
% - no xminBound/xmaxBound
if nPoints == 2 && order ==3 && nargin <= 2 && doPlot == 0
% Solution in this case (where x2 is the farthest point):
% d1 = g1 + g2 - 3*(f1-f2)/(x1-x2);
% d2 = sqrt(d1^2 - g1*g2);
% minPos = x2 - (x2 - x1)*((g2 + d2 - d1)/(g2 - g1 + 2*d2));
% t_new = min(max(minPos,x1),x2);
[minVal minPos] = min(points(:,1));
notMinPos = -minPos+3;
d1 = points(minPos,3) + points(notMinPos,3) - 3*(points(minPos,2)-points(notMinPos,2))/(points(minPos,1)-points(notMinPos,1));
d2 = sqrt(d1^2 - points(minPos,3)*points(notMinPos,3));
if isreal(d2)
t = points(notMinPos,1) - (points(notMinPos,1) - points(minPos,1))*((points(notMinPos,3) + d2 - d1)/(points(notMinPos,3) - points(minPos,3) + 2*d2));
minPos = min(max(t,points(minPos,1)),points(notMinPos,1));
else
minPos = mean(points(:,1));
end
return;
end
xmin = min(points(:,1));
xmax = max(points(:,1));
% Compute Bounds of Interpolation Area
if nargin < 3
xminBound = xmin;
end
if nargin < 4
xmaxBound = xmax;
end
% Constraints Based on available Function Values
A = zeros(0,order+1);
b = zeros(0,1);
for i = 1:nPoints
if imag(points(i,2))==0
constraint = zeros(1,order+1);
for j = order:-1:0
constraint(order-j+1) = points(i,1)^j;
end
A = [A;constraint];
b = [b;points(i,2)];
end
end
% Constraints based on available Derivatives
for i = 1:nPoints
if isreal(points(i,3))
constraint = zeros(1,order+1);
for j = 1:order
constraint(j) = (order-j+1)*points(i,1)^(order-j);
end
A = [A;constraint];
b = [b;points(i,3)];
end
end
% Find interpolating polynomial
params = A\b;
% Compute Critical Points
dParams = zeros(order,1);
for i = 1:length(params)-1
dParams(i) = params(i)*(order-i+1);
end
if any(isinf(dParams))
cp = [xminBound;xmaxBound;points(:,1)].';
else
cp = [xminBound;xmaxBound;points(:,1);roots(dParams)].';
end
% Test Critical Points
fmin = inf;
minPos = (xminBound+xmaxBound)/2; % Default to Bisection if no critical points valid
for xCP = cp
if imag(xCP)==0 && xCP >= xminBound && xCP <= xmaxBound
fCP = polyval(params,xCP);
if imag(fCP)==0 && fCP < fmin
minPos = real(xCP);
fmin = real(fCP);
end
end
end
% Plot Situation
if doPlot
figure(1); clf; hold on;
% Plot Points
plot(points(:,1),points(:,2),'b*');
% Plot Derivatives
for i = 1:nPoints
if isreal(points(i,3))
m = points(i,3);
b = points(i,2) - m*points(i,1);
plot([points(i,1)-.05 points(i,1)+.05],...
[(points(i,1)-.05)*m+b (points(i,1)+.05)*m+b],'c.-');
end
end
% Plot Function
x = min(xmin,xminBound)-.1:(max(xmax,xmaxBound)+.1-min(xmin,xminBound)-.1)/100:max(xmax,xmaxBound)+.1;
size(x)
for i = 1:length(x)
f(i) = polyval(params,x(i));
end
plot(x,f,'y');
axis([x(1)-.1 x(end)+.1 min(f)-.1 max(f)+.1]);
% Plot Minimum
plot(minPos,fmin,'g+');
if doPlot == 1
pause(1);
end
end