Matlab "interp2" problem regarding NaN at edges - matlab

I am a bit stuck on a simple exercise and would appreciate some help.
I am trying to do some simple 2D interpolation using the "interp2" function in Matlab for a variable 'tmin' of dimension [15x12]:
lat = 15:1.5:32;
lon = 70:1.5:92;
lat_interp = 15:1:32;
lon_interp = 70:1:92;
[X,Y] = meshgrid(lat,lon);
[Xi,Yi] = meshgrid(lat_interp,lon_interp);
tmin_interp = zeros(length(lon_interp),length(lat_interp),Num_Days);
tmin_interp(:,:) = interp2(X,Y,tmin(:,:),Xi,Yi,'linear');
This code results in the last row and last column of tmin_interp to be NaNs, i.e.:
tmin_interp(23,1:18) ==> NaN
tmin_interp(1:23,18) ==> NaN
Does anyone know what I might be doing wrong? Am I making a simple mistake with regards to the interpolation setup? Thank you for your time.

The reason they are nans is that there is no data before and after your grid to interpolate to. Linear interpolation uses the gradient of the field at the Xi,Yi, in order to estimate the value at that point. If there is nothing either side, it can't.
You can use extrapval parameter to extrapolate outside the X,Y you specify. Just add the parameter 0 after 'linear':
interp2(X,Y,tmin(:,:),Xi,Yi,'linear', 0);
This will put zero for the points 'on the edge'. However, it is likely that for points outside, they may fall off to some default value, like zero. To do this, you can add zeros before and after tmin:
tmin_padded = [ zeros(1,size(tmin,2)+2)
zeros(size(tmin,1),1) tmin zeros(size(tmin,1),1)
zeros(1,size(tmin,2)+2) ];
(haven't checked this but you get the idea.) you will also need to add some pre- and post-values to X and Y.
Use some other value, if that's the 'outside' or 'default' value of tmin.
PS why are you creating tmin_interp as 3-dimensional?

Or just try:
interp2(X,Y,tmin(:,:),Xi,Yi,'spline');
to avoid imposing the 0 value.
HTH!

Related

angle() of a real number

I'm a bit confused about the angle() function in Matlab, in particular when applied to an array of real numbers.
The angle() function should give me the phase of a complex number. Example: y = a + bi, ==> phase = arctan(b/a). Indeed, the following works:
for t=1:1000
comp(t) = exp(1i*(t/10));
end
phase_good_comp1 = unwrap(angle(comp)); %this gives me the right answer
b = imag(comp);
a = real(comp);
phase_good_comp2 = atan(b./a); %this gives me the right answer too, but
wrapped (not sure if there is a way to unwrap this, but unwrap() does not
work)
figure(1)
plot(phase_good_comp1)
hold on
plot(phase_good_comp2,'--r')
legend('good phase1', 'good phase2')
title('complex number')
Here's the plot for the complex numbers --
Note that I can use either the angle() function, or the explicit definition of phase, as I have shown above. Both yield good results (I can't unwrap the latter, but that's not my issue).
Now if I apply the same logic to an array of real numbers, I should get a constant phase everywhere, since no imaginary part exists, so arctan(b/a) = arctan(0) = 0. This works if I use the explicit definition of phase, but I get a weird result if I use angle():
for t=1:1000
ree(t) = cos((t/10));
end
phase_bad_re = unwrap(angle(ree)); %this gives me an unreasonable (?) answer
b = imag(ree);
a = real(ree);
phase_good_re = atan(b./a); %this gives me the right answer
figure(1)
plot(phase_bad_re)
hold on
plot(phase_good_re,'--r')
legend('bad phase', 'good phase')
title('real number')
Here's the plot for the real numbers --
Why the oscillation when I use angle()???
The Matlab documentation tells you how to compute this:
The angle function can be expressed as angle(z) = imag(log(z)) = atan2(imag(z),real(z)).
https://www.mathworks.com/help/matlab/ref/angle.html
Note that they define it with atan2 instead of atan.
Now your data is in the range of cosine, which includes both positive and negative numbers. The angle on the positive numbers should be 0 and the angle on the negative numbers should be an odd-integer multiple of pi in general. Using the specific definition that they've chosen to get a unique answer, it is pi. That's what you got. (Actually, for the positive numbers, any even-integer multiple of pi will do, but 0 is the "natural" choice and the one that you get from atan2.)
If you're not clear why the negative numbers don't have angle = 0, plot it out in the complex plane and keep in mind that the radial part of the complex number is positive by definition. That is z = r * exp(i*theta) for positive r and theta given by this angle you're computing.
Since sign of cosine function is periodically changed, angle() is also oscillated.
Please, try this.
a=angle(1);
b=angle(-1);
Phase of 1+i*0 is 0, while phase of -1+i*0 is 3.14.
But, in case of atan, b/a is always 0, so that the result of atan() is all 0.

Rotation matrix in Matlab

I am going to rotate from one frame to another one with rotation matrix. goal of program is to make my Gyro parallel to earth, it means output vector should has first two numbers zero and third one -9.81.
Codes:
vs1 = 1;
vs2 = -0.003;
vs3 = -9.808;
vst = [vs1 vs2 vs3]';
alpha = (acosd(vs1/sqrt(vs1^2+vs2^2)));
gama = (acosd(vs2/sqrt(vs1^2+vs2^2)));
beta = (acosd(vs3/sqrt(vs1^2+vs2^2+vs3^2)));
R1 = [(cosd(gama)*cosd(beta)*cosd(alpha))-(sind(gama)*sind(alpha)) (cosd(gama)*cosd(beta)*sind(al)+sind(gama)*cosd(al)) (-cosd(gama)*sind(beta));((-sind(gama)*cosd(beta)*cosd(alpha))-cosd(gama)*sind(alpha)) ((-sind(gama)*cosd(beta)*sind(alpha))+(cosd(gama)*cosd(alpha))) sind(gama)*sind(beta);sind(beta)*cosd(alpha) sind(beta)*sind(alpha) cosd(beta)];
disp (R1*vst)
result for vs1,vs2 and vs3 is : -0.00599, 0.0000359 and 9.858845622079866. first, I can not understand why program give me positive Z and why it does not make first two numbers zero?
thanks in advance
You have a bug in your code. There are two places where I think the variable "al" should actually be "alpha" if I'm following your code correctly.
But your code also generates alpha = 90 and gama = 180 for those inputs. All you're going to do is flip the axes to within machine precision with those inputs, so it's not going to achieve the results you're looking for.
1) Are you sure the input vector is correct? Why would gravity have a value near X=1 if you're nearly vertical (Z = -9.808)?

Error: Matrix dimensions must agree for plot

having a problem with my "new love", matlab: I wrote a function to calculate an integral using the trapz-method: `
function [L]=bogenlaenge_innen(schwingungen)
R = 1500; %Ablegeradius
OA = 1; %Amplitude
S = schwingungen; %Schwingungszahl
B = 3.175; %Tapebreite
phi = 0:2.*pi./10000:2.*pi;
BL = sqrt((R-B).^2+2.*(R-B).*OA.*sin(S.*phi)+OA.^2.*(sin(S.*phi)).^2+OA.^2.*S.^2.*(cos(S.*phi)).^2);
L = trapz(phi,BL)`
this works fine when i start it with one specific number out of the command-window. Now I want to plot the values of "L" for several S.
I did the following in a new *.m-file:
W = (0:1:1500);
T = bogenlaenge_innen(W);
plot(W,T)
And there it is:
Error using .*
Matrix dimensions must agree.
What is wrong? Is it just a dot somewhere? I am using matlab for the second day now, so please be patient.... ;) Thank you so much in advance!
PS: just ignore the german part of the code, it does not really matter :)
In your code, the arrays S and phi in the expression sin(S.*phi) should have same size or one of them should be a constant in order the code works
The error is most likely because you have made it so that the number of elements in schwingungen, i.e. W in your code, must be equal to the number of elements in phi. Since size(W) gives you a different result from size(0:2.*pi./10000:2.*pi), you get the error.
The way .* works is that is multiplies each corresponding elements of two matrices provided that they either have the same dimensions or that one of them is a scalar. So your code will work when schwingungen is a scalar, but not when it's a vector as chances are it has a different number of elements from the way you hard coded phi.
The simplest course of action (not necessarily the most Matlabesque though) for you is to loop through the different values of S:
W = (0:1:1500);
T = zeros(size(W); %Preallocate for speed)
for ii = 1:length(W)
T(ii) = bogenlaenge_innen(W(ii));
end
plot(W,T)
In your function you define phi as a vector of 10001 elements.
In this same function you do S.*phi, so if S is not the same length as phi, you will get the "dimensions must agree" error.
In your call to the function you are doing it with a vector of length 1501, so there is your error.
Regards

MATLAB - Why does this not work?

I'm stumped. What is going on with MATLAB's syntax?
clear all;
dx = .1;
x=-2:dx:2;
f=zeros(length(x),1);
int_f=zeros(length(x),1);
for n=1:length(x)
f(n)=x(n).^2;
int_f(n) = f(n)*dx+int_f(n);
end
plot(x,int_f(n));
I think you should be plotting that using plot(x,int_f); that way you plot the two arrays rather than one array against one single number.
Also your integral step is wrong, it should be int_f(n) = f(n)*dx+int_f(n-1) except for the first run, where it should be int_f(n) = f(n)*dx
Because in plot(x,int_f(n));, x is a row vector, but int_f(n) is a scalar value. You should be plotting a vector against a vector.

MATLAB XYZ to Grid

I have a tab separated XYZ file which contains 3 columns, e.g.
586231.8 2525785.4 15.11
586215.1 2525785.8 14.6
586164.7 2525941 14.58
586199.4 2525857.8 15.22
586219.8 2525731 14.6
586242.2 2525829.2 14.41
Columns 1 and 2 are the X and Y coordinates (in UTM meters) and column 3 is the associated Z value at the point X,Y; e.g. the elevation (z) at a point is given as z(x,y)
I can read in this file using dlmread() to get 3 variables in the workspace, e.g. X = 41322x1 double, but I would like to create a surface of size (m x n) using these variables. How would I go about this?
Following from the comments below, I tried using TriScatteredInterp (see commands below). I keep getting the result shown below (it appears to be getting some of my surface though):
Any ideas what is going on to cause this result? I think the problem lies with themeshgrid command, though I'm not sure where (or why). I am currently putting in the following set of commands to calculate the above figure (my X and Y columns are in meters, and I know my grid size is 8m, hence ti/tj going up in 8s):
F = TriScatteredInterp(x,y,z,'nearest');
ti = ((min(x)):8:(max(x)));
tj = ((min(y)):8:(max(y)));
[qx,qy] = meshgrid(ti,tj);
qz = F(qx,qy);
imagesc(qz) %produces the above figure^
I think you want the griddata function. See Interpolating Scattered Data in MATLAB help.
Griddata and tirscattteredinterp are extremely slow. Use the utm2deg function on the file exchange and from there a combination of both vec2mtx to make a regular grid and then imbedm to fit the data to the grid.
I.E.
for i = 1:length(X)
[Lat,Lon ] = utm2deg(Easting ,Northing ,Zone);
end
[Grid, R] = vec2mtx(Lat, Lon, gridsize);
Grid= imbedm(Lat, Lon,z, Grid, R);
Maybe you are looking for the function "ndgrid(x,y)" or "meshgrid(x,y)"