Interpolating scattered 3D electric field data - matlab

I have measured electric field data in three dimensions of the following form:
pos = [x1 y1 z1
x2 y2 z2
. . .
x1000 y1000 z1000]
ef = [e_x1 e_y1 e_z1
e_x2 e_y2 e_z2
. . .
e_x1000 e_y1000 e_z1000]
The positions are located within a half sphere. I want to be able to interpolate the electric field at some point of the sphere, so that I receive all the three values of the electric field components, not just the norm of the whole field. interp3 won't work as the points are not in a grid. scatteredInterpolant needs the norm as the input, and the generated function only returns the norm. Any suggestions on what function to use or how to solve this problem?

scatteredInterpolant only interpolates one column of samples at a time, but one way to interpolate a vector field is to interpolate each component of the vector independently.
This is straightforward with scatteredInterpolant.
componentInterpolants = cellfun(#(v) {scatteredInterpolant(pos,v)}, num2cell(ef,1));
This leaves you with a cell array of three scatteredInterpolant objects, one for each cartesian component of the field. By evaluating each of them individually for the specified coordinates and concatenating the result you get an electric field vector for each given coordinates. You could define a convenience function to give you the interpolated vector field in full for a given set off coordinates:
efInterpolant = #(coords) cell2mat(cellfun(#(interpolant) {interpolant(coords)}, componentInterpolants));
Verify that this interpolates the original vector field exactly (barring floating point error):
assert(all(all(abs(ef - efInterpolant(pos)) < eps * 2)));
If interpolating each cartesian component independently doesn't maintain some relationship between the vector components you expect within this field then you might need a different numerical method – perhaps some coordinate transformation before taking the same interpolation approach – but that's probably more a question for the Mathematics Stack Exchange site.

Related

Interpolation of a 3D vector field in MATLAB

I'm trying to interpolate a 3D vector field. For every (x,y,z) position we have a vector (u,v,w). I have another set of points let's call them (xq,yq,zq) in which I don't have vector information (uq,vq,wq). I would like to interpolate my data to find the vectors at the points (xq,yq,zq).
I've tried to interpolate using several functions like griddata, by interpolating each vector component individually.
uq = griddata(x,y,z,u,xq,yq,zq);
vq = griddata(x,y,z,v,xq,yq,zq);
wq = griddata(x,y,z,w,xq,yq,zq);
I expect to obtain the vectors at the locations I specified, but the message I get is:
"Warning: The underlying triangulation is empty - the points may be
coplanar or collinear."
Is there a better way to interpolate a vector field?

Finding intersections of curves that cannot be represented as y=f(x)

I have two pairs of data sets, x1 vs y1 and x2 vs y2. x1, y1, x2, y2 all have uneven distribution of data represented by the following images:
My problem is to determine the intersection of the two pairs of data sets, x1/y1 and x2/y2, shown in following image:
I tried interpolating the data points to have even spacing, but due invalid regions of x1/y1 where there are multiple solutions for the same x value.
Here is a zoom in of the x1/y1 and x2/y2 relationship, showing that there are knots within the data set that cannot be interpolated in any orientation:
It seems that x2/y2 is a smooth curve, so you should be able to interpolate it piecewise with polynomials, and get decent results. Of course you will not want to do this with x1/y1, as your data is crazy. I will refer to the independent variable in the last two images as t. You can use the matlab spline function to do this interpolation from arrays of t and x2/y2 values. Your t value array in this case should be the same size as your set of x2/y2 values. Then you could loop over your x1/y1 points, using the interpolation to estimate x2/y2 at the same value of t. Then you could subtract these values. When the sign of this value changes for two consecutive x1/y1 points, you have a point of intersection between them. Then perform a linear interpolation between those two x1/y1 points and find the intersection of that line with your interpolated x2/y2 function. The code may get a little messy, but it should work. You will want to look at the MATLAB spline documentation.

Sampling internediate points from x-y discrete mapping itself in Matlab

I have plotted a piece-wise defined continuous linear function comprising of several oblique straight lines joined end-to-end:-
x=[0,1/4,1/2,3/4,1];
oo=[1.23 2.31 1.34 5.69 7] % edit
y=[oo(1),oo(2),oo(3),oo(4),oo(5)];
plot(x,y,'g--')
I now wish to sample points from this plot itself, say i want the y corresponding to x=0.89. How to achieve that using Matlab? Is there a special function in-built in Matlab?
Yes, there's a built-in function for that: interp1:
vq = interp1(x,v,xq) returns interpolated values of a 1-D function at specific query points using linear interpolation. Vector x contains the sample points, and v contains the corresponding values, v(x). Vector xq contains the coordinates of the query points.
[...]
See the linked documentation for further options. For example, you can specify the interpolation method (default is linear), or whether you want to extrapolate (i.e. allow for xq values to lie outside the original x range).

Matlab plot function defined on a complex coordinate

I would like to plot some figures like this one:
-axis being real and imag part of some complex valued vector(usually either pure real or imag)
-have some 3D visualization like in the given case
First, define your complex function as a function of (Re(x), Im(x)). In complex analysis, you can decompose any complex function into its real parts and imaginary parts. In other words:
F(x) = Re(x) + i*Im(x)
In the case of a two-dimensional grid, you can obviously extend to defining the function in terms of (x,y). In other words:
F(x,y) = Re(x,y) + i*Im(x,y)
In your case, I'm assuming you'd want the 2D approach. As such, let's use I and J to represent the real parts and imaginary parts separately. Also, let's start off with a simple example, like cos(x) + i*sin(y) which is based on the very popular Euler exponential function. It isn't exact, but I modified it slightly as the plot looks nice.
Here are the steps you would do in MATLAB:
Define your function in terms of I and J
Make a set of points in both domains - something like meshgrid will work
Use a 3D visualization plot - You can plot the individual points, or plot it on a surface (like surf, or mesh).
NB: Because this is a complex valued function, let's plot the magnitude of the output. You were pretty ambiguous with your details, so let's assume we are plotting the magnitude.
Let's do this in code line by line:
% // Step #1
F = #(I,J) cos(I) + i*sin(J);
% // Step #2
[I,J] = meshgrid(-4:0.01:4, -4:0.01:4);
% // Step #3
K = F(I,J);
% // Let's make it look nice!
mesh(I,J,abs(K));
xlabel('Real');
ylabel('Imaginary');
zlabel('Magnitude');
colorbar;
This is the resultant plot that you get:
Let's step through this code slowly. Step #1 is an anonymous function that is defined in terms of I and J. Step #2 defines I and J as matrices where each location in I and J gives you the real and imaginary co-ordinates at their matching spatial locations to be evaluated in the complex function. I have defined both of the domains to be between [-4,4]. The first parameter spans the real axis while the second parameter spans the imaginary axis. Obviously change the limits as you see fit. Make sure the step size is small enough so that the plot is smooth. Step #3 will take each complex value and evaluate what the resultant is. After, you create a 3D mesh plot that will plot the real and imaginary axis in the first two dimensions and the magnitude of the complex number in the third dimension. abs() takes the absolute value in MATLAB. If the contents within the matrix are real, then it simply returns the positive of the number. If the contents within the matrix are complex, then it returns the magnitude / length of the complex value.
I have labeled the axes as well as placed a colorbar on the side to visualize the heights of the surface plot as colours. It also gives you an idea of how high and how long the values are in a more pleasing and visual way.
As a gentle push in your direction, let's take a slice out of this complex function. Let's make the real component equal to 0, while the imaginary components span between [-4,4]. Instead of using mesh or surf, you can use plot3 to plot your points. As such, try something like this:
F = #(I,J) cos(I) + i*sin(J);
J = -4:0.01:4;
I = zeros(1,length(J));
K = F(I,J);
plot3(I, J, abs(K));
xlabel('Real');
ylabel('Imaginary');
zlabel('Magnitude');
grid;
plot3 does not provide a grid by default, which is why the grid command is there. This is what I get:
As expected, if the function is purely imaginary, there should only be a sinusoidal contribution (i*sin(y)).
You can play around with this and add more traces if you need to.
Hope this helps!

How to use matlab contourf to draw two-dimensional decision boundary

I finished an SVM training and got data like X, Y. X is the feature matrix only with 2 dimensions, and Y is the classification labels. Because the data is only in two dimensions, so I would like to draw a decision boundary to show the surface of support vectors.
I use contouf in Matlab to do the trick, but really find it hard to understand how to use the function.
I wrote like:
#1 try:
contourf(X);
#2 try:
contourf([X(:,1) X(:,2) Y]);
#3 try:
Z(:,:,1)=X(Y==1,:);
Z(:,:,2)=X(Y==2,:);
contourf(Z);
all these things do not correctly. And I checked the Matlab help files, most of them make Z as a function, so I really do not know how to form the correct Z matrix.
If you're using the svmtrain and svmclassify commands from Bioinformatics Toolbox, you can just use the additional input argument (...'showplot', true), and it will display a scatter plot with a decision boundary and the support vectors highlighted.
If you're using your own SVM, or a third-party tool such as libSVM, what you probably need to do is to:
Create a grid of points in your 2D input feature space using the meshgrid command
Classify those points using your trained SVM
Plot the grid of points and the classifications using contourf.
For example, in kind-of-MATLAB-but-pseudocode, assuming your input features are called X1 and X2:
numPtsInGrid = 100;
x1Range = linspace(x1lower, x1upper, numPtsInGrid);
x2Range = linspace(x2lower, x2upper, numPtsInGrid);
[X1, X2] = meshgrid(x1Range, x2Range);
Z = classifyWithMySVMSomehow([X1(:), X2(:)]);
contourf(X1(:), X2(:), Z(:))
Hope that helps.
I know it's been a while but I will give it a try in case someone else will come up with that issue.
Assume we have a 2D training set so as to train an SVM model, in other words the feature space is a 2D space. We know that a kernel SVM model leads to a score (or decision) function of the form:
f(x) = sumi=1 to N(aiyik(x,xi)) + b
Where N is the number of support vectors, xi is the i -th support vector, ai is the estimated Lagrange multiplier and yi the associated class label. Values(scores) of decision function in way depict the distance of the observation x frοm the decision boundary.
Now assume that for every point (X,Y) in the 2D feature space we can find the corresponding score of the decision function. We can plot the results in the 3D euclidean space, where X corresponds to values of first feature vector f1, Y to values of second feature f2, and Z to the the return of decision function for every point (X,Y). The intersection of this 3D figure with the Z=0 plane gives us the decision boundary into the two-dimensional feature space. In other words, imagine that the decision boundary is formed by the (X,Y) points that have scores equal to 0. Seems logical right?
Now in MATLAB you can easily do that, by first creating a grid in X,Y space:
d = 0.02;
[x1Grid,x2Grid] = meshgrid(minimum_X:d:maximum_X,minimum_Y:d:maximum_Y);
d is selected according to the desired resolution of the grid.
Then for a trained model SVMModel find the scores of every grid's point:
xGrid = [x1Grid(:),x2Grid(:)];
[~,scores] = predict(SVMModel,xGrid);
Finally plot the decision boundary
figure;
contour(x1Grid,x2Grid,reshape(scores(:,2),size(x1Grid)),[0 0],'k');
Contour gives us a 2D graph where information about the 3rd dimension is depicted as solid lines in the 2D plane. These lines implie iso-response values, in other words (X,Y) points with same Z value. In our occasion contour gives us the decision boundary.
Hope I helped to make all that more clear. You can find very useful information and examples in the following links:
MATLAB's example
Representation of decision function in 3D space