simple nested loops error
Ältere Kommentare anzeigen
Hi,
I want to do modfication(nested loop) in the current code limts[r,c].
I have twelve files avg_mat(i = 12) to Process . But each file needs to use diffrent r and c values in the code. I need to mutiply r and c with cosine theta for every file.
where theta increases from 0deg to max deg and decreases to 0deg at the end with the increment (max/number of files). Please help.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
results = zeros(numl(avg_mat),1);
for i=1:numel(avg_mat)
writematrix(avg_mat{i}, ['avg_val_' num2str(i)]);
R = avg_mat{i}(:,1);
C = avg_mat{i}(:,2);
F = avg_mat{i}(:,5);
maxi = 90;
for t = [0:(maxi/numl(avg_mat)):maxi:-(maxi/numl(avg_mat)):0]
r(t) = linspace(min(R), max(R), 1000)*cos(t);%need modification based the file
c(t) = linspace(min(C), max(C), 1000)*cos(t);%need modification based on the file
[Rg, Cg] = meshgrid(r(t), c(t));
Fg(i,t) = griddata(R, C, F, Rg, Cg);
result(i,t) = trapz(c(t), trapz(r(t), Fg, 2));
end
end
Akzeptierte Antwort
Weitere Antworten (1)
MS
am 28 Apr. 2020
Bearbeitet: Walter Roberson
am 28 Apr. 2020
32 Kommentare
Walter Roberson
am 28 Apr. 2020
we are mutiplying the limts[Rg, Cg] by cos (t)
Yes, but cos(t) has a different value for each different t value, so you need to calculate for each different t, and that set of calculations has to be done for each different files. For 12 different files, and the t values increasing to a maximum and decreasing again to a minimum according to the number of files (not clear why the step size depends on the number of files), that would be like an 12 x (12*2-1) output.
Note: when you decrease t again from the maximum, you are going to have t values that you have already processed. It seems a waste to re-process them. Why are you doing that? Is it possible that instead you want to process negative values through 0 and then up to positive ??
Walter Roberson
am 28 Apr. 2020
I do not see the rule for the pattern 0, 90/6, ?, ?, ?, 90/6, ?, ?, ?, ?, ?, 0 .
It would make more sense to me if the pattern were like 180/6 * (file number minus 1)
Walter Roberson
am 28 Apr. 2020
So the first file is 90/6 * (1-1) = 0, second file is 90/6 * (2-1) = 15, third file is 90/6 * (3-1) = 30, fourth file is 90/6 * (4-1) = 45, fifth file is 90/6 * (5-1) = 60, sixth file is 90/6 * (6-1) = 75, seventh file is 90/6 * (7-1) = 90, eigth file is back to 75, nineth file is back to 60, tenth file is back to 45, 11th file is back to 30, 12th file is back to 15, and a missing 13th file not mentioned is back to 0??
If you want the first file to be 0, and the second to be 15, and the sixth to be 90, then you cannot have an even increment: you would need five steps of 15 to get from 15 to 90, but you are only permitting 4 steps.
We need a formula for the rule, one that will work to give second step of 15 and 6th of 90.
MS
am 28 Apr. 2020
Walter Roberson
am 28 Apr. 2020
By the way: wouldn't integration limit of [Rg, Cg]*cos(90 degrees) be 0 to 0 ? Is there any point in doing that calculation if the integration limit is 0 to 0 ?
MS
am 28 Apr. 2020
Bearbeitet: Walter Roberson
am 28 Apr. 2020
Walter Roberson
am 29 Apr. 2020
navg = numel(avg_mat);
r = cell(navg,1);
c = cell(navg,1);
maxi = 90;
%this code is designed to handle odd navg as well as even
t1 = linspace(0, maxi, ceil(navg/2)+1);
t2 = linspace(maxi, 0, navg - length(t1)+2);
tvals = [t1(2:end), t2(2:end)];
results = zeros(navg,1);
Fg = cell(navg,1);
for i = 1:navg
writematrix(avg_mat{i}, ['avg_val_' num2str(i)]);
R = avg_mat{i}(:,1);
C = avg_mat{i}(:,2);
F = avg_mat{i}(:,5);
r{i} = linspace(min(R), max(R), 1000) * cosd(tvals(i));
c{i} = linspace(min(C), max(C), 1000) * sind(tvals(i));
[Rg, Cg] = meshgrid(r{i}, c{i});
tg = griddata(R, C, F, Rg, Cg);
tg(isnan(tg)) = 0;
Fg{i} = tg;
result(i) = trapz(c{i}, trapz(r{i}, Fg{i}, 2));
end
MS
am 29 Apr. 2020
Walter Roberson
am 29 Apr. 2020
Bearbeitet: Walter Roberson
am 30 Apr. 2020
This is to be expected from the way you are processing. You are creating vector r and vector c and doing meshgrid() based on those. vector r and vector c without the cosd() and sind() would obviously be a rectangular grid. vector r and vector c times cosd() and sind() is just doing a linear scaling on the limits and producing a rectangular grid from what results. In order to be a rotation, you need the transformed r position to relate to c also, and the transformed c position to relate to r also. You need a rotation matrix. https://en.wikipedia.org/wiki/Rotation_matrix or equivalent
navg = numel(avg_mat);
r = cell(navg,1);
c = cell(navg,1);
maxi = 90;
%this code is designed to handle odd navg as well as even
t1 = linspace(0, maxi, ceil(navg/2)+1);
t2 = linspace(maxi, 0, navg - length(t1)+2);
tvals = [t1(2:end), t2(2:end)];
results = zeros(navg,1);
Fg = cell(navg,1);
for i = 1:navg
writematrix(avg_mat{i}, ['avg_val_' num2str(i)]);
R = avg_mat{i}(:,1);
C = avg_mat{i}(:,2);
F = avg_mat{i}(:,5);
r0 = linspace(min(R), max(R), 1000);
c0 = linspace(min(C), max(C), 1000);
[Rg0, Cg0] = meshgrid(r0, c0);
cth = cosd(tvals(i));
sth = sind(tvals(i));
Rg = Rg0 .* cth - Cg0 .* sth;
Cg = Rg0 .* sth + Cg0 .* cth;
tg = griddata(R, C, F, Rg, Cg);
tg(isnan(tg)) = 0;
Fg{i} = tg;
result(i) = trapz(c{i}, trapz(r{i}, Fg{i}, 2));
end
Walter Roberson
am 30 Apr. 2020
the code I posted already has the rotation coded into it.
MS
am 30 Apr. 2020
Walter Roberson
am 30 Apr. 2020
I did forget to change the line
result(i) = trapz(c{i}, trapz(r{i}, Fg{i}, 2));
Logically it should probably be more like
result(i) = trapz(Cg, trapz(Rg, Fg{i}, 2));
Unfortunately, you seem to have deleted the zip of data files, so I cannot test it.
I have to think more about whether it is valid to use trapz on a non-rectangular grid
Walter Roberson
am 30 Apr. 2020
Question for you: when you rotate the rectangle, where is the center of rotation ? The simple rotation matrix that I coded above was for the case of rotation around (0,0), and with the simple test I did a moment ago, even with a modest angle, the rotation moved all the sample points outside the valid area, giving nan for everything. I retested with data centered around (0,0) and got more useful results.
You might want to have a look at imtransform()
Otherwise:
R = avg_mat{i}(:,1);
C = avg_mat{i}(:,2);
F = avg_mat{i}(:,5);
r0 = linspace(min(R), max(R), 1000);
c0 = linspace(min(C), max(C), 1000);
[Rg0, Cg0] = meshgrid(r0, c0);
%assuming center of rotation is (Xc, Yc) and angle th is degrees
th = tvals(i);
m = makehgtform('translate',-Xc,-Yc,0, 'zrotate',deg2rad(th), 'translate',Xc,Yc,0);
Coords = [Rg0(:), Cg0(:), zeros(numel(Rg0),1), ones(numel(Rg0),1)];
TrCoords = Coords*m.';
Rg = reshape(TrCoords(:,1),size(Rg0));
Cg = reshape(TrCoords(:,2), size(Cg0));
tg = griddata(R, C, F, Rg, Cg);
tg(isnan(tg)) = 0;
Fg{i} = tg;
%result(i) = trapz(Cg, trapz(Rg, Fg{i}, 2)); %WILL NOT WORK
However, now you encounter the problem that trapz() will not accept grids of data, and your coordinates cannot be reduced to marginals.
Now, you use linear spacing for your r0 and c0, and if you translate, rotate, translate back, with no sheer, then the area of each grid element is the same as the area of each other grid element. Theory says that in that case, you can calculate the area using uniform grid, and then multiply the result by the area of one cell. Rotation without sheer preserves area, so you can calculate area from the pre-rotational marginals:
result(i) = trapz(trapz(Fg{i},2)) * (r0(2)-r0(1)) * (c0(2)-c0(1));
%... I think
Walter Roberson
am 1 Mai 2020
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
navg = numel(avg_mat);
r = cell(navg,1);
t = cell(navg,1);
maxi = 90;
t1 = linspace(0, maxi, navg);
t2 = fliplr(t1(1:end-1));
tvals = [t1, t2];
nt = length(tvals);
results = zeros(navg,nt);
Rg = cell(navg,1);
Cg = cell(navg,1);
Fg = cell(navg,nt);
filenames = cell(navg,1);
for i = 1:navg
filenames{i} = sprintf('avg_val_%d.txt', i);
writematrix(avg_mat{i}, filenames{i});
R = avg_mat{i}(:,1);
C = avg_mat{i}(:,2);
F = avg_mat{i}(:,5);
r0 = linspace(min(R), max(R), 1000);
c0 = linspace(min(C), max(C), 1000);
[Rg0, Cg0] = meshgrid(r0, c0);
Xc = mean(R);
Yc = mean(C);
%assuming center of rotation is (Xc, Yc) and angle th is degrees
th = tvals(i);
m = makehgtform('translate',Xc,Yc,0, 'zrotate',deg2rad(th), 'translate',-Xc,-Yc,0);
Coords = [Rg0(:), Cg0(:), zeros(numel(Rg0),1), ones(numel(Rg0),1)];
TrCoords = Coords*m.';
Rg{i} = reshape(TrCoords(:,1),size(Rg0));
Cg{i}= reshape(TrCoords(:,2), size(Cg0));
tg = griddata(R, C, F, Rg{i}, Cg{i});
tg(isnan(tg)) = 0;
Fg{i} = tg;
results(i) = trapz(trapz(Fg{i},2)) * (r0(2)-r0(1)) * (c0(2)-c0(1));
end
for i = 1 : navg
fig = figure();
ax = axes('Parent', fig);
surf(ax, Rg{i}, Cg{i}, Fg{i}, 'edgecolor','none');
hold(ax, 'on');
h(1) = plot(ax, [Rg0(1,[1 end]),Rg0(end,[end 1]),Rg0(1,1)],[Cg0(1,[1 end]),Cg0(end,[end 1]), Cg0(1,1)],'k');
h(2) = plot(ax, [Rg{i}(1,[1 end]),Rg{i}(end,[end 1]),Rg{i}(1,1)],[Cg{i}(1,[1 end]),Cg{i}(end,[end 1]), Cg{i}(1,1)],'r');
hold(ax, 'off');
title(ax, filenames{i}, 'interpreter', 'none');
end
fig = figure();
ax = axes('Parent', fig);
hold(ax, 'on');
for i = 1 : navg
h(i) = plot(ax, [Rg{i}(1,[1 end]),Rg{i}(end,[end 1]),Rg{i}(1,1)],[Cg{i}(1,[1 end]),Cg{i}(end,[end 1]), Cg{i}(1,1)],'r', 'DisplayName', filenames{i});
end
hold(ax, 'off');
L = legend(h, filenames);
L.Interpreter = 'none';
Walter Roberson
am 2 Mai 2020
trapz(Fg{i},2) = Q m/s % integerates along the row
No, the dimension for it is "units/s"
trapz(Q) = XX (m^2/s) % integerates along the column gives the single value
and that takes it to units^2/s
results= XX*Area (m^4/s)
The area is m/unit * m/unit, so units^2/s * m^2/units^ = m^2/s
Walter Roberson
am 2 Mai 2020
Can we mutiply the mean data (dF(i)) at a particular area postion by an area dA(i). will it be an issue?
I do not think I understand the question yet.
If you are talking about taking mean(Fg{i}(:)) times the area of one (rotated) unit times the number of rotated units, then mean Fg{i}(:) is sum(Fg{i}(:))/numel(Fg{i}) and when you multiply that by number of rotated units, which is numel(Fg{i}) then the /numel(Fg{i}) and the *numel(Fg{i})) cancel out, giving you sum(Fg{i}(:)) times area of a single rotated unit, so you might as well not bother taking the means.
The difference between sum(Fg{i}(:)) and trapz(trapz(Fg{i},2)) is in the calculation of the boundary conditions. trapz(trapz{i},2)) works out to already include sum(Fg{i}(2:end-1,2:end-1)) plus (sum(Fg{i}(2:end-1,1)) + sum(Fg{i}(2:end-1,end)) + sum(Fg{i}(1,2:end-1)) + sum(Fg{i}(end,2:end-1))) / 2 + something for corners. I have not worked out yet exactly how the corners fit into the calculations... I think it might be their sum divided by 4.
Mathematically, using sum(Fg{i}(:)) is like the assumption that every grid rectangle is a horizontal flat-topped plate with instantaneous change at the boundaries, whereas using trapz(trapz()) is the assumption that each grid rectangle is a flat-topped plate that tilts to meet the neighbours.
Walter Roberson
am 2 Mai 2020
Count the number of visible rectangles. You will find that there are 6 visible rectangles. If the positions were not reverting, then the other 6 rectangles would be visible. However, the other 6 rectangles are not visible because they are immediately underneath the last 6 rectangles, which have reverted to the exact positions as the earlier rectangles.
For example look for the yellow rectangle, the one that appears first in the legend. You cannot see it, because it is covered over by one of the reverting rectangles.
If you change the linestyle for the second 6 rectangles to ':' or '-.' then you will be able to see the lines underneath, in the gaps in the lines drawn with ':' or '-.'
Walter Roberson
am 3 Mai 2020
sum(Fg{i}(:))
Walter Roberson
am 4 Mai 2020
navg = numel(avg_mat);
r = cell(navg,1);
t = cell(navg,1);
maxi = 90;
t1 = linspace(15, maxi, 6);
t2 = fliplr(t1(1:end));
tvals = [t1, t2];
nt = length(tvals);
results = zeros(navg,1);
Rg = cell(navg,1);
Cg = cell(navg,1);
Fg = cell(navg,nt);
filenames = cell(navg,1);
for i = 1:navg
filenames{i} = sprintf('avg_val_%d.txt', i);
writematrix(avg_mat{i}, filenames{i});
R = avg_mat{i}(:,1);
C = avg_mat{i}(:,2);
F = avg_mat{i}(:,5);
r0 = linspace(min(R), 0.1, 1000);
c0 = linspace(min(C), 0.1, 1000);
[Rg0, Cg0] = meshgrid(r0, c0);
Xc = .05;%centroid fo the roation
Yc = .05;
%assuming center of rotation is (Xc, Yc) and angle th is degrees
th = tvals(i);
m = makehgtform('translate',Xc,Yc,0, 'zrotate',deg2rad(th), 'translate',-Xc,-Yc,0);
Coords = [Rg0(:), Cg0(:), zeros(numel(Rg0),1), ones(numel(Rg0),1)];
TrCoords = Coords*m.';
Rg{i} = reshape(TrCoords(:,1),size(Rg0));
Cg{i}= reshape(TrCoords(:,2), size(Cg0));
tg = griddata(R, C, F, Rg{i}, Cg{i});
tg(isnan(tg)) = 0;
Fg{i} = tg;
results(i) = trapz(trapz(Fg{i},2)) * (r0(2)-r0(1)) * (c0(2)-c0(1));
end
writematrix(results, 'integral_val.txt')
and when you do your plotting,
axis equal
which is not the default.
MS
am 5 Mai 2020
Kategorien
Mehr zu Language Fundamentals finden Sie in Hilfe-Center und File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!




