MATLAB: Plotting data

dataderivativeplot

Hi, I have some numetical discrete data with their derivatives from some other SW. So can I use somehow the values of derivatives to more accurate function plotting? Thank you very much for your help in advance.

Best Answer

This is a possible work around. Instead of rewriting either "polyfit" or "interp1" to take into account both the known Y amplitude data and the known Y_PRIME gradients at locations in X, you can just generate new "known" Y amplitude data at locations in X plus or minus a "dx". Save code below:
function [xi, yi] = add_grad_data_1D(x, y, y_prime, dx)
% Check input / output arguments
if nargin ~= 4
error('Needs 4 input arguments !');
end
if nargout ~= 2
warning('Probably need 2 output arguments !');
end
% Check to make sure sizes of input arguments are correct/consistent
if min(size(x)) ~= 1
error('A row/column vector is expected !');
end
if sum(size(x) == size(y)) ~= 2 || sum(size(x) == size(y_prime)) ~= 2
error('Size of X, Y, and Y_PRIME must be equal !');
end
if length(dx) > 1
dx = dx(1);
end
% compute new xi and yi vectors that take gradient y_prime into account
xi = zeros(length(x)*3,1);
if size(x,1) ~= size(xi,1) && size(x,2) ~= size(xi,2)
xi = xi';
end
yi = xi;
for i = 1 : length(x)
xi((i-1)*3 + 1 : (i-1)*3 + 3) = x(i)-dx : dx : x(i)+dx;
yi((i-1)*3 + 1 : (i-1)*3 + 3) = y(i)+(-dx : dx : dx)*y_prime(i);
end
Let's say you have 2 points corresponding to f(x) = x^2:
x = [1, 4];
y = [1, 16];
y_prime = [2, 8];
Then choose an increment in x (i.e., dx = 0.1) and run the code above to get:
[xi, yi] = add_grad_data_1D(x, y, y_prime, dx)
xi =
0.9000 1.0000 1.1000 3.9000 4.0000 4.1000
yi =
0.8000 1.0000 1.2000 15.2000 16.0000 16.8000
Then you can run something like "interp1" to get values along a regular grid from 1 to 4 that go exactly through your "known" points:
xk = 1:dx:4;
yk = interp1(xi, yi, xk, 'cubic');
You will notice that you get a much more closer fit to x^2 by including those points, because it forces the cubic spline to go through the points you generated from the gradient info:
plot(xk,yk,'b-',xk,xk.^2,'r-',xk,interp1(x,y,xk,'cubic'),'k--');
legend('Y and Y-PRIME info', 'Actual', 'Only Y info')
If your data have errors (like most data do), then you may not want to fit the curve exactly to each point. In that case you should use something like "polyfit" to determine the best n-order polynomial, in a least-squares sense.