Derivative on scatter data in Matlab - matlab

I have some data collected from a GPS network. My data consist of two arrays of the station coords (lat, long) and another two arrays populated with the vertical and the horizontal velocity of each station.
My script for interpolating is:
clear all; clc; format compact
load('lat_long_Ve_Vn.mat');
x = 34.5:0.1:42;
y = 19:0.1:28.5;
[Xq,Yq] = meshgrid(x,y);
Ve_i = griddata(lat,long,Ve,Xq,Yq);
Vn_i = griddata(lat,long,Vn,Xq,Yq);
I get the interpolated data for each node on my grid with two vectors, Ve_i and Ve_n
I want to calculate the following derivatives but I have no idea on how to do it.
I should mention that Vx is my Ve_i and Vy is my Vn_i, and I don't have a mathematical formula so I can calculate the derivatives with MuPAD. Any idea on how to do it?

If you use Gradient:
[Vxx Vxy] = gradient(Vx);
[Vyx Vyy] = gradient(Vy);

Related

Potential flow, define theta in matlab

I have made this matlab script for a potential flow around a cylinder and I would like to add a point source. See the definition of point source in picture. How can you define theta in matlab? And plot this its streamlines Psi?
clear
% make axes
xymax = 2;
x = linspace(-xymax,xymax,100);
y = linspace(-xymax,xymax,100);
% note that x and y don't include 0
[xmesh,ymesh] = meshgrid(x,y);
x_c=0;
y_c=0;
q=1;
U=1
r = sqrt((xmesh-x_c).^2+(ymesh-y_c).^2);
sin_th= ((ymesh-y_c)./r)
%(ymesh-y_c)./r = sin(teta)
%(xmesh-x_c)./r = cos(teta)
psi1 = -q./r.*((ymesh-y_c)./r);
psi2 = r.*sin_th;
psi=psi1+psi2;
figure
contour(xmesh,ymesh,psi,[-xymax:.25:xymax],'-b');
To plot the streamlines in potential flow you are correct that you have to plot contour lines of constant stream function.
In the case of a point source, if you are plotting in cartesian coordinates in MATLAB you have to convert theta to cartesian coordinates using arctangent as follows: theta = arctan(y/x). In MATLAB use the function atan2 which will limit the number of discontinuities to between -PI and PI: https://www.mathworks.com/help/matlab/ref/atan2.html
Your code should read: psi2 = ( m/(2*PI) ) * atan2(y,x)
For more information on plotting elements of potential flow in 2D cartesian coordinates, see more information here:
https://potentialflow.com/flow-elements
https://potentialflow.com/equations

Integrating Velocity Over a Complex 2-D Surface

I'm using matlab to calculate the the average velocity in the cross section of a pipe by integrating discrete velocity points over a surface. The points are scattered in a random pattern that form a circle (almost).
I used scatteredinterpolant to create a function relating x and y to v (velocity) in order to create a grid of interpolated values.
F = scatteredInterpolant(x, y, v,'linear');
vq = F(xq,yq); % where xq and yq are a set of query points
The problem I am now having is trying to calculate the the surface area of this function, but only in this circular portion that contains all the scatter points.
The first way I went about this was using the quad2d function.
int = quad2d(#(x,y) F(x,y), min(x), max(x), min(y), max(y), 'MaxFunEvals', 100000);
However this gives is incorrect as it takes the area over a rectangle and a circle.
Now I can probably define the surface area with a circle but in the future I will have to work with more complex shapes so I want to use points that define the boundary of the scatter points.
I'm doing this through triangulation, using the following command.
DT = delaunayTriangulation(x,y);
However I have no idea how I can incorporate these points into a quad2d function. I was hoping someone might have a suggestion or possibly another method I could use in calculating the area over these complex surfaces.
Thanks!
You could assume your function to be piecewise linear on your integration area and then integrate it using a midpoint quadrature rule:
For every triangle you compute the midpoint value as the mean of the nodal values and multiply by the triangle's area. You sum it all up to get your integral.
function int = integrate(T, values)
meanOnTriangle = mean(values(T.ConnectivityList),2);
int = sum(getElementAreas(T).*meanOnTriangle);
end
function areas = getElementAreas(T)
X = #(d) T.Points(T.ConnectivityList(:,d),:);
d21 = X(2)-X(1);
d31 = X(3)-X(1);
areas = abs(1/2*(d21(:,1).*d31(:,2)-d21(:,2).*d31(:,1)));
end
As your goal is the average velocity, you want to compute the following quantity:
averageVelocity = integrate(DT,v)/sum(getElementAreas(DT));

Retrieving data on coordinates which or not on the data grid through interpolation

I'm using Matlab to read a large (NetCDF) data set with information about a magnetic field. The data set is a three-dimensional array of 318x562x554 and I can retrieve have three one-dimensional array (318x1, 562x1 and 554x1) with each axis values of the coordinates. I would like to know the magnetic field values on points that do not fit on the data set grid. These points are in this case trajectory coordinates of a spacecraft placed in a two-dimensional array (3xn,n depends on how many coordinates you have).
x = ncread(file,'X_axis');
y = ncread(file,'Y_axis');
z = ncread(file,'Z_axis');
Bx = ncread(file,'Bx');
[x2,y2,z2] = meshgrid(y,x,z);
length = numel(interval_ET_5000);
Bx_intp = zeros(1,length);
for i = 1:length
[xi,yi,zi] = meshgrid(position_MEX_Mars_5000(1,i),...
position_MEX_Mars_5000(2,i),...
position_MEX_Mars_5000(3,i));
F = interp3(x2,y2,z2,Bx,xi,yi,zi);
Bx_intp(i) = F;
end
I have tried many things that didn't even work. This 'works' but not correct because the values in Bx_intp are way to high. Also because of the doing coordinates one at the time in a for loop makes it very slow, a normal run is about 3500 coordinates.
So basicly what I am looking for is a reverse scatteredInterpolant. This function accepts random data points and you interpolate the values on a meshgrid. But now I have a regular grid and I want interpolation on random points.
Thanks for the tip Ashish Uthama! I got it working with the code below. For other people with the same problem. You need ndgrid instead of meshgrid for griddedInterpolant and the coordinates need to be monotonic increasing.
x = ncread(file,'X_axis');
y = ncread(file,'Y_axis');
z = ncread(file,'Z_axis');
Bx = ncread(file,'Bx');
[x2,y2,z2] = ndgrid(x,y,z);
F = griddedInterpolant(x2,y2,z2,Bx,'linear','none');
Bx_intp = F(position_MEX_Mars_5000(1,i),...
position_MEX_Mars_5000(2,i),...
position_MEX_Mars_5000(3,i));

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)

Finding the belonging value of given point on a grid of 3D histogram?

I use 2D dataset like below,
37.0235000000000 18.4548000000000
28.4454000000000 15.7814000000000
34.6958000000000 20.9239000000000
26.0374000000000 17.1070000000000
27.1619000000000 17.6757000000000
28.4101000000000 15.9183000000000
33.7340000000000 17.1615000000000
34.7948000000000 18.2695000000000
34.5622000000000 19.3793000000000
36.2884000000000 18.4551000000000
26.1695000000000 16.8195000000000
26.2090000000000 14.2081000000000
26.0264000000000 21.8923000000000
35.8194000000000 18.4811000000000
to create a 3D histogram.
How can I find the histogram value of a point on a grid? For example, if [34.7948000000000 18.2695000000000] point is given, I would like to find the corresponding value of a histogram for a given point on the grid.
I used this code
point = feat_vec(i,:); // take the point given by the data set
X = centers{1}(1,:); // take center of the bins at one dimension
Y = centers{2}(1,:); // take center of the bins at other dim.
distanceX = abs(X-point(1)); // find distance to all bin centers at one dimension
distanceY = abs(Y-point(2)); // find distance to center points of other dimension
[~,indexX] = min(distanceX); // find the index of minimum distant center point
[~,indexY] = min(distanceY); // find the index of minimum distant center point for other dimension
You could use interp2 to accomplish that!
If X (1-D Vector, length N) and Y (1-D vector, length M) determine discrete coordinate on the axes where your histogram has defined values Z (matrix, size M x N). Getting value for one particular point with coordinates (XI, YI) could be done with:
% generate grid
[XM, YM] = meshgrid(X, Y);
% interpolate desired value
ZI = interp2(XM, YM, Z, XI, YI, 'spline')
In general, this kind of problem is interpolation problem. If you would want to get values for multiple points, you would have to generate grid for them in similar fashion done in code above. You could also use another interpolating method, for example linear (refer to linked documentation!)
I think you mean this:
[N,C] = hist3(X,...) returns the positions of the bin centers in a
1-by-2 cell array of numeric vectors, and does not plot the histogram.
That being said, if you have a 2D point x=[x1, x2], you are only to look up the closest points in C, and take the corresponding value in N.
In Matlab code:
[N, C] = hist3(data); % with your data format...
[~,indX] = min(abs(C{1}-x(1)));
[~,indY] = min(abs(C{2}-x(2)));
result = N(indX,indY);
done. (You can make it into your own function say result = hist_val(data, x).)
EDIT:
I just saw, that my answer in essence is just a more detailed version of #Erogol's answer.