Inner for loop working - outer loop incorrect? - matlab

I managed to advance with a problem I was having and am looking for advice on the structure of my outer for loop. My inner loop works correctly. I want to repeat the 11 calculations 6 times using a different height (value of h) for each iteration. On the iterations of the J loop h increases to it's original value + 2*h. POI in the K loop depends on h and is defined but has been omitted for readability. Can update with the full script if necessary. Should the definition of POI be within the nested loop?
h = 0.5985;
GroundDistance = 18.75;
SouthAngle = 57;
TreeHeight = 14;
POI = TreeHeight-h;
BuildingElevationAng = atand(POI/GroundDistance);
a=0.265;
TreeLengthRHS = 15.89+a;
h = 0.5985;
X(1,1)=h;
for k = 2:6;
X(k) = X(k-1) + (X(1)*2);
end
for J = 1:6
h=h+(2*h);
for K = 1:11
TreeLengthTest(K) = TreeLengthRHS + (2*(K-1)*a);
TreeLengthLHS = 75 - TreeLengthTest(K);
AngleBx(K) = atand(TreeLengthLHS/GroundDistance);
AngleCx(K) = atand(TreeLengthTest(K)/GroundDistance); %wasTreeLengthRHS
DistanceAx(K) = GroundDistance/cosd(SouthAngle);
DistanceBx(K) = GroundDistance/cosd(AngleBx(K));
DistanceCx(K) = GroundDistance/cosd(AngleCx(K));
AltAngleA(K) = atand(POI/DistanceAx(K));
AltAngleB(K) = atand(POI/DistanceBx(K));
AltAngleC(K) = atand(POI/DistanceCx(K));
AzimuthA = 0;
AzimuthB = (-AngleBx)-SouthAngle;
AzimuthC = AngleCx-SouthAngle;
end
end
Any help is greatly appreciated.

Well, there are a couple things I'm not sure of, but I'll give a shot at an answer, and see if this helps. The definition of POI does not have to be inside the inner loop, because POI is constant for each of those 11 calculations. However, I think you're defining h a little bit incorrectly, because you'll never get to use the value of h that you define initially. Since you already have the X vector, what if you try your nested for loops like:
for J = 1:6
POI = TreeHeight - X(J);
for K = 1:11
...All your code here...
end
end

Related

Multiple loops issue in matlab

Sorry for asking really basic question but I am confused in multiple loops.
I want to run loops all at same time and then break the loop and go to next loop for R, e and x combine.
Means for R =1 ,e=1 ,x=1 and then R=2 ,e=2 ,x=2 and so on.
Can someone tell me where I am at fault or what is missing to get my desired results?
Code:
threshold = [0.4:0.1:1.1];
limit_for_idx = [0.4:0.1:1.1];
limit = [0.4:0.1:1.1];
D=1;
E=1;
J=0;
for R = 1:numel(threshold);
for e = 1:numel(limit_for_idx);
for x = 1:numel(limit)
J = J+1 ;
% Perform Tasks and go to next loop for R ,e and x
break
end
break
end
end
The wrong in your code is that in the 2nd iteration and so on, e and x will get 1 again, and not 2 or which value that you want.
To solve that, just iterate one variable and equal them all to it:
threshold = [0.4:0.1:1.1];
limit_for_idx = [0.4:0.1:1.1];
limit = [0.4:0.1:1.1];
D=1;
E=1;
J=0;
for R=1:numel(threshold)
e=R;
x=R;
% do your stuff...
end

Is there a way to optimize or maybe even vectorize this? (MATLAB)

I have an if statement within two loops, it runs too slow and I think it can be optimized. NF_zeta is a 2D logical array.
for k = 2:Nx
for l = 2:Ny
if NF_zeta(l,k)
z2(l,k) = z1(l,k) - optVar2*(U2(l,k) - U2(l,k-1) + V2(l,k) - V2(l-1,k));
end
end
end
Here are the results of a profiler
http://i.imgur.com/oMropeL.png
I tried with single loop in which the conditional statement was taken care of. Something similar to what is done for one loop for [1 4 5], I wrote
for idx = NF_zeta_v
z2(idx(1),idx(2)) = z1(idx(1),idx(2)) - optVar2*(U2(idx(1),idx(2)) - U2(idx(1),idx(2)-1) + V2(idx(1),idx(2)) - V2(idx(1)-1,idx(2)));
end
where NF_zeta_v is created in advance like this
c_z = 1;
for l = 1:Ny
for k = 1:Nx
if NF_zeta(l,k)
NF_zeta_v(:,c_z) = [l;k];
c_z = c_z + 1;
end
end
end
It took almost twice as long. The results of a profiler http://i.imgur.com/OegeEOC.png
What else can I try, any suggestions?
Here's one vectorized solution using diff -
diffs = diff(U2(2:end,:),[],2) + diff(V2(:,2:end),[],1);
allvals = z1(2:end,2:end) - optVar2*diffs;
z2(2:Ny,2:Nx) = NF_zeta(2:Ny,2:Nx).*allvals;
May be you want something like this if N_x and N_y are the size values:
Z2 = (z1-optVar2*(U2-circshift(U2, [0 1])+V2-circshift(V2, [1 0]))).*(double(NF_zeta));
Z2(1,:) = 0;
Z2(:,1) = 0;

Fill matrix with function values in Matlab

I've got 3 functions, oe1(n), oe2(n) and oe3(n).
I want to create a matrix representing the function values.
The structure of the matrix should be like this:
A = [oe1(0) oe2(0) oe3(0); oe1(1) oe2(1) od3(1); ...... ; oe1(N-1), oe2(N-1), oe3(N-1)];
I've tried filling it with a for loop, but it does not work.
Is there a standard Matlab operation for this? I really can't figure out how to do it.
Anders.
oe1(n1) = sin(2*pi*F*n1+phi)
oe2(n1) = ones(length(n1),1);
oe3(n1) = n1*Ts
pol = (oe2)'
vector_x = [a; b; c];
vector_veardier = [oe1(n1), 1, oe3(n1)]
xi = 1:N-1;
for i = 2:N-1;
for j = 1:3
vector_veardier(i, j) = oe1(j);
end
end
Do your functions accept vectors? If so you can use:
A = [oe1((1:N)'), oe2((1:N)'), oe3((1:N)')];
but otherwise you might have to use arrayfun:
A = [arrayfun(#oe1, (1:N)'), arrayfun(#oe2, (1:N)'), arrayfun(#oe3, (1:N)')];
Note that in your provided code you have not defined oeN as functions, but as some kind of array with a value inserted at position n1.
One way to do it with a for loop would however be:
A = zeros(N,3);
for i = 1:N,
A(i,:) = [oe1(i), oe2(i) oe3(i)];
end

Avoiding for-loops in matrix operations with cell elements

The dimensions of this problem are: model.nlf = 4. Each {r} of Kuu or KuuGamma are 500x500 matrices of data.
How to suppress the for-loop? my intuition goes toward using cellfun with a function for logdet.
logDetKuu = 0;
for r=1:model.nlf,
if isfield(model, 'gamma') && ~isempty(model.gamma)
[model.Kuuinv{r}, model.sqrtKuu{r}] = pdinv(model.KuuGamma{r});
model.logDetKuu{r} = logdet(model.KuuGamma{r}, model.sqrtKuu{r});
else
[model.Kuuinv{r}, model.sqrtKuu{r}] = pdinv(model.Kuu{r});
model.logDetKuu{r} = logdet(model.Kuu{r}, model.sqrtKuu{r});
end
logDetKuu = logDetKuu + model.logDetKuu{r};
end
Grateful for pointers. Thanks
Follow up question: Can the following type of for-loops on cell elements be vectorized?
nlf = 4; nout = 16; each KuuinvKuy{1,1} are 150x650
for k =1: model.nout,
for r =1: model.nlf,
model.KuuinvKuy{r,k} = model.Kuuinv{r}*model.Kyu{k,r}';
end
end
If all your matrices are so large, and you execute your for-loop only 4 times, then there is no reason to remove the for-loops, since it will not lead to any speedup. My only observation is that the condition of the if seems to be independent of the loop, so it is cleaner to move that if before the loop. Something like this:
if isfield(model, 'gamma') && ~isempty(model.gamma)
myKuu = model.KuuGamma;
else
myKuu = model.Kuu;
end
logDetKuu = 0;
for r=1:model.nlf,
[model.Kuuinv{r}, model.sqrtKuu{r}] = pdinv(myKuu{r});
model.logDetKuu{r} = logdet(myKuu{r}, model.sqrtKuu{r});
logDetKuu = logDetKuu + model.logDetKuu{r};
end

Parfor-loop not working, how to fix?

I am trying to parallize two of my for-loops and run it on a remote cluster.
I am using matlabpool open local 12 at the beginning with matlabpool close at the end. The problem I am running into is that my parfor-loop cannot use my matric properly and I am not sure how I would rewrite it so that it works.
H = hadamard(n);
H = [H;-H];
P = setdiff(P,H,'rows');
[r,c] = size(P);
A = zeros(n,r);
parfor i=1:r
for j=1:n
d = P(i,:) + H(j,:);
A(j,i) = sum(d(:) ~= 0);
end
end
and:
u2Had = cell(2,r);
parfor i =1:r
u2Had{1,i} = min(A(:,i));
MinHadIndex = find(A(:,i) == u2Had{1,i});
u2Had{2,i} = MinHadIndex;
end
Those are the two segments of the code I am trying to parallize. Any help is much appreciated and if I need to add anymore information please ask.
I don't know what your problem is in the first part as it works fine (perhaps if you defined P better)
regarding the second part, you can only send information to and from parloops in narrow cases.
Here change your code to the following:
u2HadT = cell(1,r);
parfor i =1:r
temp = min(A(:,i));
MinHadIndex = find(A(:,i) == temp);
u2HadT{i} = {temp;MinHadIndex};
end
u2Had = cell(2,r);
for i =1:r
u2Had{1,i} = u2HadT{i}(1);
u2Had{2,i} = u2HadT{i}(2);
end