matlab curve fitting with sub-polynomial - matlab

I am wondering how do I fit three points x = ([0.42 0.64 0.96]) and
y = ([4.2 5.1 6.0]) with y = k*x^(0.88)?
I tried [p,S,mu] = polyfit(x,y,0.88); but MATLAB says only power in integer numbers are accepted. Thanks.
EDIT:
The idea is I know these three points should follow the curve based on some theory, so I want to plot it to convince myself. Also, I'd like to do curve fitting because I don't know what k is.

What about lsqnonlin ?
You could try
model = #(x,k) (k*x.^0.88);
resVec = #(k) (y(:) - model(x(:),k));
k_start = 1;
k_opt = lsqnonlin(resVec,k_start);

If you're OK with adding a constant to your model you can do:
[p,S,mu] = polyfit(x.^(0.88),y,1);
then you'll have y approximated by p(2)*x.^(0.88)+p(1) (minimizing the sum of the squares of the errors)

Related

How would I find the decision line for two 2d gaussian plots with unequal covariancematrix?

I am plotting 2 multivariate gaussians in MATLAB, and my decision line as a result will be parabolic in shape, which I can see by looking at the contour or surf of the data. However, I need a way to quantify the pparabola that represents the decisionline. Taking the local minima seems like a good idea, but I dont know if that is possible for a contour plot.
decision line is where difference of two gaussian function becomes zero.
so using fcontour from symbolic toolbox:
syms x y
mu_x = 10;
mu_y = 10;
mu_x1 = 60;
mu_y1 = 10;
sigma = 20;
sigma1 = 30;
f = 1/(2*pi*sigma^2) * exp(-(x-mu_x)^2+(y-mu_y)^2)/(2*sigma^2)...
-( 1/(2*pi*sigma1^2) * exp(-(x-mu_x1)^2+(y-mu_y1)^2)/(2*sigma1^2));
fcontour(f ,'LevelList', [0])
but I do not have tested

What interpolation technique does Matlab plot function use to show the data?

It seems to be very basic question, but I wonder when I plot x values against y values, what interpolation technique is used behind the scene to show me the discrete data as continuous? Consider the following example:
x = 0:pi/100:2*pi;
y = sin(x);
plot(x,y)
My guess is it is a Lagrangian interpolation?
No, it's just a linear interpolation. Your example uses a quite long dataset, so you can't tell the difference. Try plotting a short dataset and you'll see it.
MATLAB's plot performs simple linear interpolation. For finer resolution you'd have to supply more sample points or interpolate between the given x values.
For example taking the sinus from the answer of FamousBlueRaincoat, one can just create an x vector with more equidistant values. Note, that the linear interpolated values coincide with the original plot lines, as the original does use linear interpolation as well. Note also, that the x_ip vector does not include (all) of the original points. This is why the do not coincide at point (~0.8, ~0.7).
Code
x = 0:pi/4:2*pi;
y = sin(x);
x_ip = linspace(x(1),x(end),5*numel(x));
y_lin = interp1(x,y,x_ip,'linear');
y_pch = interp1(x,y,x_ip,'pchip');
y_v5c = interp1(x,y,x_ip,'v5cubic');
y_spl = interp1(x,y,x_ip,'spline');
plot(x,y,x_ip,y_lin,x_ip,y_pch,x_ip,y_v5c,x_ip,y_spl,'LineWidth',1.2)
set(gca,'xlim',[pi/5 pi/2],'ylim',[0.5 1],'FontSize',16)
hLeg = legend(...
'No Interpolation','Linear Interpolation',...
'PChip Interpolation','v5cubic Interpolation',...
'Spline Interpolation');
set(hLeg,'Location','south','Fontsize',16);
By the way..this does also apply to mesh and others
[X,Y] = meshgrid(-8:2:8);
R = sqrt(X.^2 + Y.^2) + eps;
Z = sin(R)./R;
figure
mesh(Z)
No, Lagrangian interpolation with 200 equally spaced points would be an incredibly bad idea. (See: Runge's phenomenon).
The plot command simply connects the given (x,y) points by straight lines, in the order given. To see this for yourself, use fewer points:
x = 0:pi/4:2*pi;
y = sin(x);
plot(x,y)

Matlab reversed 2d interpolation interp2

I have a function V that is computed from two inputs (X,Y). Since the computation is quite demanding I just perform it on a grid of points and would like to rely on 2d linear interpolation. I now want to inverse that function for fixed Y. So basically my starting point is:
X = [1,2,3];
Y = [1,2,3];
V =[3,4,5;6,7,8;9,10,11];
Is is of course easy to obtain V at any combination of (X,Y), for instance:
Vq = interp2(X,Y,V,1.8,2.5)
gives
Vq =
8.3000
But how would I find X for given V and Y using 2d linear interploation? I will have to perform this task a lot of times, so I would need a quick and easy to implement solution.
Thank you for your help, your effort is highly appreciated.
P.
EDIT using additional info
If not both x and y have to be found, but one of them is given, this problem reduces to finding a minimum in only 1 direction (i.e. in x-direction). A simple approach is formulating this in a problem which can be minizmied by an optimization routine such as fminsearch. Therefore we define the function f which returns the difference between the value Vq and the result of the interpolation. We try to find the x which minimizes this difference, after we give an intial guess x0. Depending on this initial guess the result will be what we are looking for:
% Which x value to choose if yq and Vq are fixed?
xq = 1.8; % // <-- this one is to be found
yq = 2.5; % // (given)
Vq = interp2(X,Y,V,xq,yq); % // 8.3 (given)
% this function will be minimized (difference between Vq and the result
% of the interpolation)
f = #(x) abs(Vq-interp2(X, Y, V, x, yq));
x0 = 1; % initial guess)
x_opt = fminsearch(f, x0) % // solution found: 1.8
Nras, thank you very much. I did something else in the meantime:
function [G_inv] = G_inverse (lambda,U,grid_G_inverse,range_x,range_lambda)
for t = 1:size(U,1)
for i = 1:size(U,2)
xf = linspace(range_x(1), range_x(end),10000);
[Xf,Yf] = meshgrid(xf,lambda);
grid_fine = interp2(range_x,range_lambda,grid_G_inverse',Xf,Yf);
idx = find (abs(grid_fine-U(t,i))== min(min(abs(grid_fine-U(t,i))))); % find min distance point and take x index
G_inv(t,i)=xf(idx(1));
end
end
G_inv is supposed to contain x, U is yq in the above example and grid_G_inverse contains Vq. range_x and range_lambda are the corresponding vectors for the grid axis. What do you think about this solution, also compared to yours? I would guess mine is faster but less accurate. Spped is, however, a major issue in my code.

Incorrect zeros positions in zplane

I am trying to plot pole/zero plot of a simple polynomial (1+z)^(2p) for p=7. My code is as follows:
p = 7;
rCoeffs = [1 1];
for ii=1:2*p-1
rCoeffs = conv(rCoeffs, [1 1]);
end
zplane(real(rCoeffs),1);
The plot displays the following:
I don't understand why the zeros are complex numbers. I think that all the zeros should be located at z=-1 but this plot shows a circle. This doesn't happen when p is small but again I have seen a few plots online that are apparently generated by zplane and they show large number of zeros on a particular point.
Basically you're looking for 14 solutions to the equation given the setup. Unfortunately the general solution to polynomial equations of order 5 or greater doesn't exist and must be found numerically. The solution provided is correct only in that is approximately what the algorithm thinks you're looking for.
I would add that Nathan's method works as intended, and if you change it slightly, you will see all the solutions to the above equation.
z = tf('z',1)
H = (1+z)^(2*7);
[p,z1] = pzmap(H)
z1 % solution to H = 0
(1+z1)^(2*7)
An easier way:
p = 7
z = zpk('z',0.1);
H = (1+z)^(2*p);
pzmap(H)

Calculate distance, given a set of coordinates

my question is quite trivial, but I'm looking for the vectorized form of it.
My code is:
HubHt = 110; % Hub Height
GridWidth = 150; % Grid length along Y axis
GridHeight = 150; % Grid length along Z axis
RotorDiameter = min(GridWidth,GridHeight); % Turbine Diameter
Ny = 31;
Nz = 45;
%% GRID DEFINITION
dy = GridWidth/(Ny-1);
dz = GridHeight/(Nz-1);
if isequal(mod(Ny,2),0)
iky = [(-Ny/2:-1) (1:Ny/2)];
else
iky = -floor(Ny/2):ceil(Ny/2-1);
end
if isequal(mod(Nz,2),0)
ikz = [(-Nz/2:-1) (1:Nz/2)];
else
ikz = -floor(Nz/2):ceil(Nz/2-1);
end
[Y Z] = ndgrid(iky*dy,ikz*dz + HubHt);
EDIT
Currently I am using this solution, which has reasonable performances:
coord(:,1) = reshape(Y,[numel(Y),1]);
coord(:,2) = reshape(Z,[numel(Z),1]);
dist_y = bsxfun(#minus,coord(:,1),coord(:,1)');
dist_z = bsxfun(#minus,coord(:,2),coord(:,2)');
dist = sqrt(dist_y.^2 + dist_z.^2);
I disagree with Dan and Tal.
I believe you should use pdist rather than pdist2.
D = pdist( [Y(:) Z(:)] ); % a compact form
D = squareform( D ); % square m*n x m*n distances.
I agree with Tal Darom, pdist2 is exactly the function you need. It finds the distance for each pair of coordinates specified in two vectors and NOT the distance between two matrices.
So I'm pretty sure in your case you want this:
pdist2([Y(:), Z(:)], [Y(:), Z(:)])
The matrix [Y(:), Z(:)] is a list of every possible coordinate combination over the 2D space defined by Y-Z. If you want a matrix containing the distance from each point to each other point then you must call pdist2 on this matrix with itself. The result is a 2D matrix with dimensions numel(Y) x numel(Y) and although you haven't defined it I'm pretty sure that both Y and Z are n*m matrices meaning numel(Y) == n*m
EDIT:
A more correct solution suggested by #Shai is just to use pdist since we are comparing points within the same matrix:
pdist([Y(:), Z(:)])
You can use the matlab function pdist2 (I think it is in the statistics toolbox) or you can search online for open source good implementations of this function.
Also,
look at this unswer: pdist2 equivalent in MATLAB version 7