Matlab: Issues with filling a 401x401 matrix - matlab

I'm having an issue with filling a 401x401 matrix. I know exactly what I want to do but I'm struggling to implement it.
I would like for a specific angle (y axis from 30-70) and a specific wavelength (x axis from 400nm-1000nm) the matrix is filled to 401 x 401 to contain the associated reflection coefficient (I have the equations and they're all good).
I thought this would work#
for i=1:length(ANGLE)
angle=ANGLE(i);
etc etc
for i=1:length(wavelengths)
lambda=wavelengths(i);
etc etc
REF(i)=ref;
end
end
I hope you can help, sorry if this is badly worded.
Thanks
Carmel

As m_power pointed out, you should use a different iterator for the internal for loop (and also try to avoid using i and j, as they are commonly used to represent imaginary values). In addition to this, you should reference both a row and column entry for each reflection coefficient entry. Since you want angle in the vertical direction and wavelength in the horizontal direction, you could use something like this:
for ii=1:length(ANGLE)
angle=ANGLE(ii);
etc etc
for jj=1:length(wavelengths)
lambda=wavelengths(jj);
etc etc
REF(ii,jj)=ref;
end
end
Hope this helps.

Related

How do I get lines to stop extending beyond plot border? (Matlab)

I am writing a report for a class and am having some issues with the lines of an unstable plot going beyond the boundary of the graph and overlapping the title and xlabel. This is despite specifying a ylim from -2 to 2. Is there a good way to solve this issue?
Thanks!
plot(X,u(:,v0),X,u(:,v1),X,u(:,v2),X,u(:,v3),X,u(:,v4))
titlestr = sprintf('Velocity vs. Distance of %s function using %s: C=%g, imax=%g, dx=%gm, dt=%gsec',ICFType,SDType,C,imax,dx,dt);
ttl=title(titlestr);
ylabl=ylabel("u (m/s)");
xlabl=xlabel("x (m)");
ylim([-2 2])
lgnd=legend('t=0','t=1','t=2','t=3','t=4');
ttl.FontSize=18;
ylabl.FontSize=18;
xlabl.FontSize=18;
lgnd.FontSize=18;
EDIT: Minimum reproducible example
mgc=randi([-900*10^10,900*10^10], [1000,2]);
mgc=mgc*1000000;
plot(mgc(:,1),mgc(:,2))
ylim([-1,1])
This is odd. It really looks like a Bug... partly
The reason is probably that the angle of the lines are so narrow that MATLAB runs into rounding errors when calculating the points to draw for your limits very small limits given very large numbers. (You see that you don't run into this problem when you don't scale the matrix mgc.
mgc = randi([-900*10^10,900*10^10], [1000,2]);
plot(mgc(:,1),mgc(:,2))
ylim([-1,1])
but if you scale it further, you run into this problem...
mgc = randi([-900*10^10,900*10^10], [1000,2]);
plot(mgc(:,1)*1e6,mgc(:,2)*1e6)
ylim([-1,1])
While those numbers are nowhere near the maximum number a double can represent (type realmax in the command window to see that this is a number with 308 zeros!); limiting the plot to [-1,1] on one of the axes -- note that you obtain the same phenom on the x-axis -- let MATLAB run into precision problems.
First of all, you see that it plots much less lines than before (in my case)... although, I just said to zoom on the y-axis. The thing is, that MATLAB does not recalculate the lines for the section but it really zooms into it (I guess that this may cause resolution errors with regard to pixels?)
Well, lets have a look at the data (Pro-tip, you can get the data of a line from a MATLAB figure by calling this snippet
datObj = findobj(gcf,'-property','YData','-property','XData');
X = datObj.XData;
Y = datObj.YData;
xlm = get(gca,'XLim'); % get the current x-limits
) We see that it represents the original data set, which is not surprising as you can also zoom out again.
Note that his only occurs if you have such a chaotic, jagged line. If you sort it, it does not happen.
quick fix:
Now, what happens, if we calculate the exact points for this section?
m = diff(Y)./diff(X); % slope
n = Y(1:end-1)-m.*X(1:end-1); % offset
x = [(-1-n); (1-n)]./m;
y = ones(size(x))./[-1 1].';
% plot
plot([xMinus1;xPlus1],(ones(length(xMinus1),2).*[-1 1]).')
xlim(xlm); % limit to exact same scale as before
The different colors indicate that they are now individual lines and not a single wild chaos;)
It seems Max pretty much hit the nail on the head as it pertains to the reason for this error is occurring. Per Enrico's advice I went ahead and submitted a bug report. MathWorks responded saying they were unsure it was "unexpected behavior" and would look into it more shortly. They also did suggest a temporary workaround (which, in my case, may be permanent).
This workaround is to put
set(gca,'ClippingStyle','rectangle');
directly after the plotting line.
Below is a modified version of the minimum reproducible example with this modification.
mgc=randi([-900*10^10,900*10^10], [1000,2]);
mgc=mgc*1000000;
plot(mgc(:,1),mgc(:,2))
set(gca,'ClippingStyle','rectangle');
ylim([-1,1])

Specifying a domain of a cube without corners in Matlab using a for loop

I would like to specify the domain in Matlab as attached below. This turned out to be harder than I thought. So far, I tried two types of approaches:
The small to large approach. Here, I start with defining the cube in the middle and then add the 6 blocks that are sticking out. So I end up with 7 domains, for each of which I specify the main equations and the boundary conditions. This seems to work, but is obviously very slow. I prefer a solution more like 2, which is:
The large to small approach. Here, I start with a cube that is bigger than the actual domain and I want to tell Matlab which parts to exclude from the domain, e.g. the parts in the corners. Suppose the corners are from i/j/k==1 to i/j/k==2. And here, I am not sure how to do this. Concretely, what happens is that if either of the three coordinates is 1 or nx/ny/nz, the range of the other two coordinates should be 2:(nx/ny/nz-1).
In logical terms, this second approach would look like:
for i=1:nx
for j=1:ny
for k=1:nz
%x
if (j==1||j==ny) for i=2:(nx-1)
elseif (k==1||k==nz) for i=2:(nx-1)
else for i=1:nx
end
%y
if (i==1||i==nx)for j=2:(ny-b1)
elseif (k==1||k==nz)for j=2:(ny-1)
else for j=1:ny
end
%z
if (i==1||i==nx) for k=2:(nz-1)
elseif (j==1||j==ny) for k=2:(nz-1)
else for k=1:nz
end
I know this is no valid Matlab syntax because of the for after the if-statement, but this is to give a clear idea of what I want. My question is, is there another way to write this such that it does work in Matlab?!
Alternatively, I was thinking about something like:
for i=1:((nx/3))
for j=1:ny
for k=1:nz
if(i==(2||(nx-2))&&(k==1||k==nz ||j==1||j==ny)) ux(i,j,k)=BC1;
elseif(i==1&&k~=1&&k~=nz&&j~=1&&j~=ny) ux(i,j,k)=BC2;
elseif(i==1) ux(i,j,k)=0; %here also u and uxx need to be set 0.
else definition ux
end
The problem with this is that you still have to specify i==1 at the corners, e.g. instead of excluding the corners from the domain, you include the corners and set all corner-related values at 0. I prefer really to exclude them.
None of these methods works well and I am wondering if there isnt any better and more straightforward method?
Picture of the domain to be described
you just need to prepare a binary mask of the edges, if you're matrix name is m:
mask=zeros(size(m));
mask(1,:,end)=1;
mask(end,:,1)=1;
mask(1,:,1)=1;
mask(end,:,end)=1;
mask(:,1,1)=1;
mask(:,1,end)=1;
mask(:,end,1)=1;
mask(:,end,end)=1;
mask(1,1,:)=1;
mask(1,end,:)=1;
mask(end,1,:)=1;
mask(end,end,:)=1;
then:
m.*~mask
will get you want you wanted...
this figure was created using blockPlot from fex, with m=ones(7,9,11);

Avoiding for loop with cells and matrixes involved

I am trying to avoid the for loops and I have been reading through all the old posts there are about it but I am not able to solve my problem. I am new in MATLAB, so apologies for my ignorance.
The thing is that I have a 300x2 cell and in each one I have a 128x128x256 matrix. Each one is an image with 128x128 pixels and 256 channels per pixel. In the first column of the 300x2 cell I have my parallel intensity values and in the second one my perpendicular intensity values.
What I want to do is to take every pixel of every image (for each component) and sum the intensity values channel by channel.
The code I have is the following:
Image_par_channels=zeros(128,128,256);
Image_per_channels=zeros(128,128,256);
Image_tot_channels=zeros(128,128,256);
for a=1:128
for b=1:128
for j=1:256
for i=1:numfiles
Image_par_channels(a,b,j)=Image_par_channels(a,b,j)+Image_cell_par_per{i,1}(a,b,j);
Image_per_channels(a,b,j)=Image_per_channels(a,b,j)+Image_cell_par_per{i,2}(a,b,j);
end
Image_tot_channels(a,b,j)=Image_par_channels(a,b,j)+2*G*Image_per_channels(a,b,j);
end
end
end
I think I could speed it up introducing (:,:,j) instead of specifying a and b. But still a for loop. I am trying to use cellfun without any success due to my lack of expertise. Could you please give me a hand?
I would really appreciate it.
Many thanks and have a nice day!
Y
I believe you could do something like
Image_par_channels=zeros(128,128,256);
Image_per_channels=zeros(128,128,256);
Image_tot_channels=zeros(128,128,256);
for i=1:numfiles
Image_par_channels = Image_par_channels + Image_cell_par_per{i,1};
Image_per_channels = Image_per_channels + Image_cell_par_per{i,2};
end
Image_tot_channels = Image_par_channels + 2*G*Image_per_channels;
I haven't work with matlab in a long time, but I seem to recall you can do something like this. g is a constant.
EDIT:
Removed the +=. Incremental assignment is not an operator available in matlab. You should also note that Image_tot_channels can be build directly in the loop, if you don't need the other two variables later.

what values should i pass to the normalization function in iris recognition?

i've been working on implementation for iris recognition system in Matlab ,
on Normalization i used this function
[polar_array, polar_noise] = normaliseiris(image, x_iris, y_iris, r_iris,x_pupil, y_pupil, r_pupil, eyeimage_filename, radpixels, angulardiv);
i passed x, y and radius coordinates for both circles (iris and pupil) to x_iris, y_iris, r_iris,x_pupil, y_pupil, r_pupil
but i'm stuck at these two variables (radpixels, angulardiv) !!
couldn't figure out what values should i pass ?!
i saw someone said he/she passed 32 , 240 respectively but it didn't work with me !
Can anyone tell me what values should i pass ? or at least an explanation ?
Thanks :)
Isn't it clearly said in the comments?
% radpixels - radial resolution, defines vertical dimension of
% normalised representation
% angulardiv - angular resolution, defines horizontal dimension
% of normalised representation
(Source)
Note: "32, 240" can be useful values... but how shall we know what's wrong with your parametrization without more details? You should think about how much radpixels and angulardiv are useful for your application.

Suppress kinks in a plot matlab

I have a csv file which contains data like below:[1st row is header]
Element,State,Time
Water,Solid,1
Water,Solid,2
Water,Solid,3
Water,Solid,4
Water,Solid,5
Water,Solid,2
Water,Solid,3
Water,Solid,4
Water,Solid,5
Water,Solid,6
Water,Solid,7
Water,Solid,8
Water,Solid,7
Water,Solid,6
Water,Solid,5
Water,Solid,4
Water,Solid,3
The similar pattern is repeated for State: "Solid" replaced with Liquid and Gas.
And moreover the Element "Water" can be replaced by some other element too.
Time as Integer's are in seconds (to simplify) but can be any real number.
Additionally there might by some comment line starting with # in between the file.
Problem Statement: I want to eliminate the first dip in Time values and smooth out using some quadratic or cubic or polynomial interpolation [please notice the first change from 5->2 --->8. I want to replace these numbers to intermediate values giving a gradual/smooth increase from 5--->8].
And I wish this to be done for all the combinations of Elements and States.
Is this possible through some sort of coding in Matlab etc ?
Any Pointers will be helpful !!
Thanks in advance :)
You can use the interp1 function for 1D-interpolation. The syntax is
yi = interp1(x,y,xi,method)
where x are your original coordinates, y are your original values, xi are the coordinates at which you want the values to be interpolated at and yi are the interpolated values. method can be 'spline' (cubic spline interpolation), 'pchip' (piece-wise Hermite), 'cubic' (cubic polynomial) and others (see the documentation for details).
You have alot of options here, it really depends on the nature of your data, but I would start of with a simple moving average (MA) filter (which replaces each data point with the average of the neighboring data points), and see were that takes me. It's easy to implement, and fine-tuning the MA-span a couple of times on some sample data is usually enough.
http://www.mathworks.se/help/curvefit/smoothing-data.html
I would not try to fit a polynomial to the entire data set unless I really needed to compress it, (but to do so you can use the polyfit function).