loop over nested functions overwrites variables

I have written a routine for image processing and want to get the same output for a stack of pictures in the format (:,:,i) with i being the number of the picture (e.g. picture number 30 to 35). However, the output will only have information for the final i(:,:,35) and (:,:,30) to (:,:,34) will be empty, that is they have been overwritten. I tried a smaller loop to get the idea
zMin=30; zMax=35;
while zMin <= zMax
for i = zMin
a(1,1,i)=zMin
zMin=zMin+1;
end;
end;
and here it works perfectly fine. However, in my code consisting of nested functions, it doesn't, so I assume it has something to do with the format of the code:
function [firstScanRaw, mask, maskedImage, Ipores, Iskeleton, PropsLCCP, PropsLCCS, PoresBackbone, SkeletonBackbone, Porosity, Skeleton, nPixelROI, SkeletonObjects, PoreObjects, EulerRealisationsSkeleton, EulerRealisationsPores,PoreWidthRealisations, SkelWidthRealisations ] = porous_main(sampleName, zMin, zMax, display);
[firstScanRaw] = porous_load_input (sampleName,zMin);
[mask, maskedImage] = porous_polygon (firstScanRaw, display, sampleName);
while (zMin <= zMax)
for i = zMin;
[firstScanRaw] = porous_load_input (sampleName,zMin);
[mask, maskedImage] = porous_polygon_choosen (firstScanRaw, display, sampleName, mask,i);
[Ipores, Iskeleton] = porous_binarisation (maskedImage, display,i);
[PropsLCCP, PropsLCCS] = porous_elements(Ipores, Iskeleton, display, i);
[PoresBackbone, SkeletonBackbone, Porosity, Skeleton, nPixelROI, PoreDist, SkelDist] = porous_sizes (Iskeleton, Ipores, display, mask, maskedImage,i);
[Porosity, Skeleton, SkeletonObjects, PoreObjects, EulerRealisationsSkeleton, EulerRealisationsPores, PoreWidthRealisations, SkelWidthRealisations ] = porous_output(Porosity, Skeleton, PoreDist, SkelDist,PoresBackbone, SkeletonBackbone, nPixelROI, sampleName, PropsLCCP, PropsLCCS,i);
zMin=zMin+1;
end;
end;
end

3 Comments

Please format your code properly on this forum, because currently that code is unreadable. It is really very easy: select the code, and then press the {} Code button that you will find above the textbox.
Your function currently has eighteen (18) outputs... and this is clearly difficult to keep track of. As an alternative you might like to consider using a structure, which allows you to do this:
function out = temp(x)
out.data = x;
out.sqrt = sqrt(x);
end
and then we can call the function and get all of the output values in just one variable:
>> X = temp(4)
X =
data: 4
sqrt: 2
This has many advantages over trying to pass lots of output variables! You can also use the same method for passing input variables :)
I see the advantage of using structures. The question is, why does my current output get overwritten?

Sign in to comment.

 Accepted Answer

Solution
Those loops are very confused. Neither the while nor the for loop is being used effectively.
  • The for loop does absolutely nothing at all: you provide it with exactly one scalar value zMin, and so it "loops" over just one value... but there is no looping happening with just one value!
  • Using a while loop is not the best choice, as you already know precisely the start and end values for the loop. This is exactly what for loops are for.
Both of these could be replaced by one simple for loop:
zMin=30;
zMax=35;
for k = zMin:zMax
a(1,1,k) = k;
end
Bonus Extension
Or perhaps an even better solution (this depends on what you are doing with that matrix) is to not to use the values 30 to 35 directly as indices (and so fill up the rest of the matrix with useless zeros), but instead to use independent indices to locate the values:
zMin=30;
zMax=35;
vec = zMin:zMax;
for k = numel(vec):-1:1
a(1,1,k) = vec(k);
end
which we can view in the command window:
>> a
a(:,:,1) =
30
a(:,:,2) =
31
a(:,:,3) =
32
a(:,:,4) =
33
a(:,:,5) =
34
a(:,:,6) =
35
This is a much smaller matrix, and it contains only actual data, as opposed to the many useless zeros in your original matrix.

5 Comments

Julia
Julia on 11 May 2015
Edited: Julia on 11 May 2015
Thanks for the simplification of this example. It did work for me, since zMin was updated by +1 at the end of each iteration.
However, this is just an example. My question is, where to change my code so that the numerous outputs variables are not getting overwritten during each iteration. It still does it after adjusting the loop.
You are using indices in the simplified example, and yet not in your actual code. This is why the outputs are getting overwritten: because you are not indexing into them. Your code has lines like this:
[firstScanRaw] = porous_load_input (sampleName,zMin);
whereas this needs some indexing, so it would be something like this:
firstScanRaw(k) = porous_load_input(sampleName,zMin);
Exactly how to index those variables depends on their dimensions, which you do not give any information on. Here is a simple example showing how to index into variables to keep the values on each iteration (I have assumed scalar variables):
function [out,F,E] = temp(n,x)
for k = n:-1:1
out(k) = x^k;
[F(k),E(k)] = log2(out(k));
end
and then call it from the command window:
>> [A,F,E] = temp(5,2)
A =
2 4 8 16 32
F =
0.5000 0.5000 0.5000 0.5000 0.5000
E =
2 3 4 5 6
Julia
Julia on 11 May 2015
Edited: Julia on 11 May 2015
That's what I was missing, but it is not as simple. For example the variable Porosity will have the dimension (;,:,i). Just putting Porosity(:,:,i) everytime it occurs along my script as input or output gives me the error 'unexpected bracket'. I admit I am struggling to transfer your way of writing functions into my code.
Please upload your exact Mfile using the paperclip button, note that you have to click both the Choose file and Attach file buttons. I cannot read minds, and you will need to provide your exact code if you want a diagnosis of this problem.
That style of indexing should work fine:
function [out,F,E] = temp(n,x)
for k = n:-1:1
out(:,:,k) = x^k + [0,1;10,100];
[F(k),E(k)] = log2(out(1,1,k));
end
and tested:
>> [A,F,E] = temp(5,2)
A(:,:,1) =
2 3
12 102
A(:,:,2) =
4 5
14 104
A(:,:,3) =
8 9
18 108
A(:,:,4) =
16 17
26 116
A(:,:,5) =
32 33
42 132
F =
0.5 0.5 0.5 0.5 0.5
E =
2 3 4 5 6

Sign in to comment.

More Answers (0)

Categories

Asked:

on 11 May 2015

Commented:

on 13 May 2015

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!