How do I do numerical integration of a vector in MATLAB? - matlab

I have a vector of 358 numbers. I'd like to make a numerical integration of this vector, but I don't know the function of this one.
I found that we can use trapz or quad, but i don't really understand how to integrate without the function.

If you know the horizontal spacing of your vector, you can use trapz in order to integrate it without the function. For example, to integrate y=sin(x) from 0 to pi with 358 sections,
x=0:pi/357:pi;
y=sin(x);
area=trapz(x,y);
If you just use trapz(y), you'll get a much larger number, since the default distance between points is assumed to be 1. This problem can be fixed by multiplying by the distance between x points:
area=pi/357*trapz(y);

You don't need to know the function in order to numerically integrate; that's the point of trapz and quad. Just pass trapz your vector. Here's a link to the documentation.

Think about integration as to find area under the curve, which is formed by your vector. Well it's not actually a curve, but polygonal chain. What TRAPZ function is doing, it finds sum of areas of each trapezoids formed by every two neighbor points in your vector and their projection on X axis. See the function documentation, if you have uneven distance between your points or if distance not equal one.
You can read more about this method, for example, on Wikipedia.

Related

interpolate velocity for a curved mesh

'x','y' and 'u' are 2D matrices for the x-coordinate, y-coordinate, and velocity of each node of the below mesh (figure). and I want to interpolate for (x_q,y_q) to find u_q for an arbitrary point(q).
My mesh is not rectangular and "interp2" error is: "Input grid is not a valid MESHGRID".
Any Ideal what can I do?
Thanks.
minimal reproducible example:
x=[0.0482114583977891,0.0482201588072998,0.0482288592168105;0.0513027685854806,0.0512573490659834,0.0512119412024664;0.0550957532853860,0.0550195888619688,0.0549437786953572;0.0589706773586289,0.0589051888951395,0.0588397004316502];
y=[-0.0481475644832381,-0.0450026617243515,-0.0418577589654650;-0.0454644879533678,-0.0426002662557475,-0.0397360636257961;-0.0434988768053532,-0.0408400599208391,-0.0381819554721181;-0.0414343539900984,-0.0389341351227583,-0.0364339162554183];
u=[1.52583130467469,14.3816671073665,58.5433654462735;108.677373003789,124.842139940676,145.468567077514;110.206733380171,111.157308056414,111.709609403516;135.414711548714,138.843419308648,147.988201447309];
xq=0.065;
yq=0.035;
uq = interp2(x,y,u,xq,yq,'cubic',0);
The interp2 function needs a regular grid (for instance something that was createed by meshgrid). In your case you have scattered data, in which case it you'd have to use griddata for interpolation:
uq = griddata(x,y,u,xq,yq, 'nearest');
(Note that in your MCVE your query point is way outside of the defined input points, so only 'nearest' will really work as a method.)
Per Matlab documentation for the interp2 function, the requirements for cubic spline interpolation are:
Grid must have uniform spacing in each dimension, but the spacing does not have to be the same for all dimensions
Requires at least four points in each dimension
In the case of your code, neither of these conditions is met.
You would need to make sure that the x and y points are evenly spaced, ideally using meshgrid to generate the points and you would need to make the specified points, which are currently 3x4, at least 4x4.
Documentation for the function is found here: https://www.mathworks.com/help/matlab/ref/interp2.html
There is a response to a similar question here: https://www.mathworks.com/matlabcentral/answers/866695-input-grid-is-not-a-valid-meshgrid

Implementation of Radon transform in Matlab, output size

Due to the nature of my problem, I want to evaluate the numerical implementations of the Radon transform in Matlab (i.e. different interpolation methods give different numerical values).
while trying to code my own Radon, and compare it to Matlab's output, I found out that my radon projection sizes are different than Matlab's.
So a bit of intuition of how I compute the amount if radon samples needed. Let's do the 2D case.
The idea is that the maximum size would be when the diagonal (in a rectangular shape at least) part is proyected in the radon transform, so diago=sqrt(size(I,1),size(I,2)). As we dont wan nothing out, n_r=ceil(diago). n_r should be the amount of discrete samples of the radon transform should be to ensure no data is left out.
I noticed that Matlab's radon output is always even, which makes sense as you would want a "ray" through the rotation center always. And I noticed that there are 2 zeros in the endpoints of the array in all cases.
So in that case, n_r=ceil(diago)+mod(ceil(diago)+1,2)+2;
However, it seems that I get small discrepancies with Matlab.
A MWE:
% Try: 255,256
pixels=256;
I=phantom('Modified Shepp-Logan',pixels);
rd=radon(I,pi/4);
size(rd,1)
s=size(I);
diagsize=sqrt(sum(s.^2));
n_r=ceil(diagsize)+mod(ceil(diagsize)+1,2)+2
rd=
367
n_r =
365
As Matlab's Radon transform is a function I can not look into, I wonder why could it be this discrepancy.
I took another look at the problem and I believe this is actually the right answer. From the "hidden documentation" of radon.m (type in edit radon.m and scroll to the bottom)
Grandfathered syntax
R = RADON(I,THETA,N) returns a Radon transform with the
projection computed at N points. R has N rows. If you do not
specify N, the number of points the projection is computed at
is:
2*ceil(norm(size(I)-floor((size(I)-1)/2)-1))+3
This number is sufficient to compute the projection at unit
intervals, even along the diagonal.
I did not try to rederive this formula, but I think this is what you're looking for.
This is a fairly specialized question, so I'll offer up an idea without being completely sure it is the answer to your specific question (normally I would pass and let someone else answer, but I'm not sure how many readers of stackoverflow have studied radon). I think what you might be overlooking is the floor function in the documentation for the radon function call. From the doc:
The radial coordinates returned in xp are the values along the x'-axis, which is
oriented at theta degrees counterclockwise from the x-axis. The origin of both
axes is the center pixel of the image, which is defined as
floor((size(I)+1)/2)
For example, in a 20-by-30 image, the center pixel is (10,15).
This gives different behavior for odd- or even-sized problems that you pass in. Hence, in your example ("Try: 255, 256"), you would need a different case for odd versus even, and this might involve (in effect) padding with a row and column of zeros.

2D weighted Kernel Density Estimation(KDE) in MATLAB

I'm looking for available code that can estimate the kernel density of a set of 2D weighted points. So far I found this option in for non-weighted 2D KDE in MATLAB: http://www.mathworks.com/matlabcentral/fileexchange/17204-kernel-density-estimation
However it does not incorporate the weighted feature. Is there any other implemented function or library that should come in handy for this? I thought about "hacking" the problem, where suppose I have simple weight vector: [2 1 3 1], I can literally just repeat each sampled point, twice, once, three times and once respectively. I'm not sure if this computation would be valid mathematically though. Again the issue here is that the weight vector I have is decimal, so normalizing to the minimum number of the vector and then multiplying each other entry implies errors in rounding, specially if the weights are in the same order of magnitude.
Note: The ksdensity function in MATLAB has the weighted option but it is only for 1D data.
Found this, so problem solved. (I guess): http://www.ics.uci.edu/~ihler/code/kde.html
I used this function and found it to be excellent. I discuss varying the n parameter (area over which density is calculated) in this Stack Overflow post, and it contains some examples of 2D KDE plots using contour3.

Filter noisy points during interpolation

I am using matlab's interpolation feature to interpolate the values of some points inside the convex hull formed. However, some of the points inside the convex hull have noisy z value. My input points are of two dimension x & y with z giving the value at the location(x,y). In some cases the z value is particular noise value. So, how can I make sure that it doesn't affect the interpolation, I mean I don't want this value to be considered. Suggestions?
Define your criteria for the point to be 'too noisy'.
Too many standard deviations from the mean? (Calculate mean and standard deviation, then threshold at n standard deviations?)
Too different from the surrounding values? (Use a smoothing/lowpass filter.)
Some background on what this data represents, and some of its characteristics, would help here.

Griddata with 'cubic' Interpolation Method Returns NaN

I found that if I use griddata Method with Cubic Interpolation method, for certain values of x, y, it will return NaN. One post says that this is because the x and y data are very near to convex hull.
Any idea how to fix this?
Edit: Note that I can't make sure that my inputs are monotonously increasing ( thus, gridfit doesn't work). The reason is because I would have to mesh my area ( which could be an irregular polygon in 2D), get all the points before generating the coressponding Z values for each points. My code is as follows:
function ZI=Interpolate3D(scatteredData, boundary)
%scatteredData is the scattered points, boundary is the area that I want to generate 3D surface.
% Given the boundaries, generate mesh first
[element,points]= GenMesh(boundary);
ZI = griddata(scatteredData(:,1),scatteredData(:,2),scatteredData(:,3),points(:,1),points(:,2), 'cubic',{'QJ'});
If your points are outside of the convex hull, you CANNOT get a result other than NaN from griddata using the cubic option. If the point is right on the line, then a NaN may result, depending upon what happens in the least significant bits of the computation.
The issue is that the cubic method uses a triangulation. If your point is outside of the convex hull, then the triangulation fails on that point.
Of course, you CAN use the -v4 method, but there are tremendously good reasons why it has largely been superceded. It uses a distance based interpolation method, where for n data points, a full nxn matrix must be generated. Then a system of equations is solved using that matrix. This will be quite slow for even moderately large problems.
The virtue of the -v4 method is it will extrapolate smoothly without producing nans. This is why it was left in there.
For larger problems where you need a smooth result, and you still wish to extrapolate outside of the convex hull, you can use my gridfit tool. It does do smoothing though, not pure interpolation.
All such methods have tradeoffs that you must resolve for your particular problem.
Since the release of Matlab R2013a you can use scatteredInterpolant instead of griddata.
This has several advantages:
Matlab can perform interpolation as well as extrapolation on a scatteredInterpolant object. You can specify a point outside the convex hull of your scattered data and will still not get a NaN.
Once created, the scatteredInterpolant object can be evaluated multiple times, thus saving computational time compared to calling griddata several times.
On the down side: While you can specify the interpolation and extrapolation methods, cubic is not available but only linear, nearest and natural.
Using scatteredInterpolant your code could look like
F = scatteredInterpolant(scatteredData(:,1),scatteredData(:,2),scatteredData(:,3));
ZI=F(points(:,1),points(:,2));
Are you sure you want cubic interpolation? For some input data the calculated z-nodes could have extreme large values!
I always use -v4 option like the post in your link mentions. You can also play with options used in Qhull via delaunayn, some (but not all) are {'Qt','Qbb','Qc'} http://www.qhull.org/html/qhull.htm