Output loop result in Matlab - matlab

Hi have this code and I don't know how to put the output result with every pixel.I think the output code are not well defined.
EDIT:
I'm going to try to explain the code:
% I have an image
imagen1=imread('recor.tif');
imagen2= double(imagen1);
band1= imagen2(:,:,1);
% I preallocate the result (the image size is 64*89*6)
yvan2= zeros(61,89,1);
% For every pixel of the image, I want to get one result (each one is different).
for i = 1 : nfiles
for j = 1 : nrows
for i = 1:numel(band1)
% I'm doing this because I've to multiply the results of this interpolation with that result a2ldb1y= ldcm_1(:,1). This vector has a length of 2151x1 and I need to muliply the result of the interpolation for (101:267) position on the vector, this is the reason because I'm doing the interpolation since 101 to 267 (also because I don't have that values).
interplan= interp1(van1,man2,t2,'spline');
ma(96) = banda1a(i); % I said 96, because I want to do an interpollation
end
van1= [101 96 266]';
mos1= ma(134);
van2= [0 pos1 0];
t= 101:267;
t2= t';
xi= 101:1:267;
xi2=xi';
interplan= interp1(van1,van2,t2,'spline');
% After this, I 'prepare' the vector.
out=zeros(2151,1)
out(101:267) = interplan;
% And then, I do all this operation (are important for the result)
a2ldb1y= ldcm_1(:,1);
a2ldsum_pesos1= sum(a2ldb1y);
a2l7dout1_a= a2ldb1y.*out;
a2l7dout1_b= a2l7dout1_a./a2ldsum_pesos1;
a2l7dout1_c= sum(a2l7dout1_b);
% And the result a2l7dout1_c I want it for every pixel (the results are different because every pixel has a different value...)
**yvan2(:,:,1)= [a2l7dout1_c];**
end
end
Thanks in advance,

I'm shooting in the dark here, but I think you're looking for:
yvan2(i, j, 1)= a2l7dout1_c;
instead of:
yvan2(:,:,1)= [a2l7dout1_c];
and thus your output should be stored in the variable yvan2 after the loops are done.
P.S
Some issues in your code:
Why do you have two loops using the same iteration variable i? Your calculations are probably incorrect since i is being modified by two for loops.
Why do you even need the second loop? Each iteration overruns the value of ma(134) set by the previous iteration. You can just replace the entire loop with:
ma(134) = banda1a(numel(band1))
You shouldn't be using the names i and j for loop variables. They are already reserved for the imaginary unit (that is, sqrt(-1)), so MATLAB needs extra processing time for name resolution. You'd rather use other loop variable names instead, even ii and jj.

Related

Run the for loop only once Matlab

total_Route = zeros(4,4);
tmp = evalin('base', 't'); % i initialise t in the Workspace with the value 1
if(tmp==5)
tmp=1;
end
total_Route(tmp,1) = Distance_Traveled_CM;
total_Route(tmp,2) = Hauptantrieb_Verbrauchte_Energie_CM;
total_Route(tmp,3) = Nebenaggregate_Verbrauch_Real_CM;
total_Route(tmp,4) = t;
Total_Distance_Traveled_CM = sum(total_Route(:,1));
set(handles.edit3, 'string',Total_Distance_Traveled_CM);
Total_Hauptantrieb_Verbrauchte_Energie_CM = sum(total_Route(:,2));
set(handles.edit4, 'string',Total_Hauptantrieb_Verbrauchte_Energie_CM);
Total_Nebenaggregate_Verbrauch_Real_CM = sum(total_Route(:,3));
set(handles.edit5, 'string',Total_Nebenaggregate_Verbrauch_Real_CM);
%% Index
set(handles.edit15, 'string',tmp);
assignin('base', 't', tmp + 1); % with this line i can increment "t" after each pass
guidata(hObject,handles);
Sorry that I did not explain my problem well.
#Sardar_Usama I want to run the loop only once but t should be incremented after each time I click on my Button.
# Sembei Norimaki end is at the end of my codes, have forgotten to write it in my question
#Patrik & #Dennis Jaheruddin let me explain my problem again
I created a Matrix with 4×4 Elements with the Goal to save the results of each my Variable (Total_Distance_Traveled_CM, Total_Hauptantrieb_Verbrauchte_Energie_CM etc...) after each Simulation in the element of my Matrix (See image below).
I want by pressing a button (on my GUI) to get always the sum of each Column.
Example
The first pass: t = 1--> Distance_Traveled(1,1) is 900 the GUI will take through clicking on the Button, the sum of the first column (which is 900+0+0+0) and write it in a static test.
The second pass t = 2--> Distance_traveled(2,1) is 800 the GUI will take the sum of the first column (which is 900+800+0+0) and write it in a static test and the same thing should happen with the other column.
This should continue until t = 4 i.e. until it does the same thing for each column, then it should reset.
I hope, I have explained my problem better this time and I apologize for my bad English.
I appreciate any help.
Based on your code fragment the for loop is only called once.
However, the contents of the for loop are ran for four times. (first for i=1 then for 1=2 etc..)
If you only want to run one of these options the solution is very simple:
i = 1
yourLoopContent
If i is always 0 the first time, and you always want to run it for the current i, it would also be simple:
yourLoopContent
i = i+1;
However if i may not be set properly the first time, things get messy. This is because i is by default defined as the square root of minus 1.
Therefore I would recommend you to use a different letter like t instead. Then you could do this:
if ~exists(t)
t=0;
end
yourLoopContent %Everywhere using t instead of i
t = t+1;
In general you may want to avoid i as an index to stay clear of complex number issues.
I'm not sure if I got your question correctly, but it seems to me that what you look for is a cumulative sum. This can be done either buy summing on 1:t or by using cumsum. I'm not sure why you use a loop, but if this is only for the summing then cumsum can replace that.
Here is some example in your code:
total_Route = zeros(4,4);
% I commented below what is not part of the question
for t = 1:4
total_Route(t,:) = [Distance_Traveled_CM,
Hauptantrieb_Verbrauchte_Energie_CM,
Nebenaggregate_Verbrauch_Real_CM,
t];
% the following line compute the comulative sum from the top of each
% column to every element in it, so cs_total_Route(3,2) is like
% sum(total_Route(1:3,2)):
cs_total_Route = cumsum(total_Route);
Total_Distance_Traveled_CM = cs_total_Route(t,1); % OR sum(total_Route(1:t,1))
% set(handles.edit3, 'string',Total_Distance_Traveled_CM);
Total_Hauptantrieb_Verbrauchte_Energie_CM = cs_total_Route(t,2); % OR sum(total_Route(1:t,2))
% set(handles.edit4, 'string',Total_Hauptantrieb_Verbrauchte_Energie_CM);
Total_Nebenaggregate_Verbrauch_Real_CM = cs_total_Route(t,3); % OR sum(total_Route(1:t,3))
% set(handles.edit5, 'string',Total_Nebenaggregate_Verbrauch_Real_CM);
% set(handles.edit15, 'string',t);
end
And here is a quick look on what cumsum does (with some random numbers for total_Route):
total_Route =
671 4.6012 1.0662 1
840 3.6475 0.58918 2
354 8.6056 2.1313 3
893 4.1362 2.0118 4
cs_total_Route =
671 4.6012 1.0662 1
1511 8.2487 1.6554 3
1865 16.854 3.7867 6
2758 20.991 5.7985 10
Is this what you looked for?

How to convert cell variable to classified variable inside of parfor loop in matlab? [duplicate]

I have this (quite long) Matlab code with nested loops where I want to parallelize the main time-consuming iteration. The only variable that (apparently) gives me problems is DMax, where I get the error:
Error: The variable DMax in a `parfor` cannot be classified.
See Parallel for Loops in MATLAB, "Overview".
This is a draft of my code:
t0=matrix (Maxiter,1); % This is a big matrix whose dimensions are reported in brachets
Maxiter = 1E6;
DMax = zeros(Maxiter,40);
% Other Stuff
for j=1:269
% Do more stuff
for soil=1:4
parfor i =1:Maxiter
k(i,soil) = a %k is a real number
a(i,soil) = b %similar to k
% Do a lot of stuff
for t= (floor(t0(i,soil))+1):40
DMax(i,t) = k(i,soil)*((t-t0(i,soil))^a(i,soil));
% Do some more stuff
end
end
end
end
for time=1:40
% Do the final stuff
end
I guess the problem is in the way I defined DMax, but I do not know what it could be more precisely. I already looked on the web but with not very satisfying results.
It is very clearly described in the documentation that each variable inside parfor must be classified into one of several types. Your DMax variable should be a sliced variable (arrays whose segments are operated on by different iterations of the loop), but in order to be classified as such, all the following conditions must hold:
Type of First-Level Indexing — The first level of indexing is either parentheses, (), or braces, {}.
Fixed Index Listing — Within the first-level parenthesis or braces, the list of indices is the same for all occurrences of a
given variable.
Form of Indexing — Within the list of indices for the variable, exactly one index involves the loop variable.
Shape of Array — The array maintains a constant shape. In assigning to a sliced variable, the right-hand side of the assignment cannot be [] or '', because these operators attempt to
delete elements.
Clearly, Fixed Index Listing property does not hold since you reference it as DMax(i,t) where t changes its values. There's an identical example described in the documentation, please pay attention. So one workaround would be to use a temporary variable inside the inner loop, and then assign the whole row back to DMax.
Also note that variable a cannot be classified into any category either. That's not to mention that it's not defined in your example at all. Please read the guide carefully and make sure it can be classified into one of the categories. Rewrite the code if needed, e.g. introducing new temporary variables.
Here's the code where DMax usage is corrected:
Maxiter = 1E6;
t0 = randn(Maxiter,1); % This is a big matrix whose dimensions are reported in brachets
DMax = zeros(Maxiter,40);
% Other Stuff
for j = 1:269
% Do more stuff
for soil = 1:4
parfor i = 1:Maxiter
k(i,soil) = a %k is a real number
a(i,soil) = b %similar to k
% Do a lot of stuff
tmp = zeros(1,40);
for t = (floor(t0(i,soil))+1):40
tmp(t) = k(i,soil)*((t-t0(i,soil))^a(i,soil));
% Do some more stuff
end
DMax(i,:) = tmp;
end
end
end
for time = 1:40
% Do the final stuff
end

Modifying Iteration for Multiple Inputs

I am doing an iteration to find the corresponding latitude/longitude at a height (h_intercept). My code works perfectly for a single height value. However, I want to find the lat/long of 79 heights (1x79 matrix) and therefore have an output that is a 3x79 matrix (llh_test). I've tried a for loop but I can't seem to get the results I want. I am probably doing something stupid.
Basically, I need to modify it so it will run with rng_sat, u_sat and h_intercept all being 1x79 matrices. It needs to step through the entire iteration before moving to the next values of rng_sat, u_sat and h_intercept
Also, I want to store all of the llh_test values (3x79 matrix)
rng_sat= sat_look_tcs_pass1(3,1)/2e2;
u_sat=[sat_look_tcs_pass1(1,1)/sat_look_tcs_pass1(3,1);sat_look_tcs_pass1(2,1)/sat_look_tcs_pass1(3,1);sat_look_tcs_pass1(3,1)/sat_look_tcs_pass1(3,1)];
h_intercept=sat_look_pass1_llh(3,1)/2e3;
h_test=0;
rng_test_min=0;
rng_test_max=rng_sat;
err=0.01;
while abs(h_test-h_intercept)>err
rng_test=(rng_test_min+rng_test_max)/2;
tcs_test=u_sat*rng_test;
llh_test=tcs2llhT(tcs_test,station_llh);
h_test=llh_test(3,:);
if h_test>=h_intercept;
rng_test_max=rng_test;
else
rng_test_min=rng_test;
end
end
The easiest thing to do here would be to encapsulate this into a single for loop, and change the way you're accessing the core variables so that you're using the loop index instead. Looking at your code, I'm assuming that sat_look_tcs_pass1 is a 3 x 79 matrix. I'm also going to assume that the output height h_test is a single value because when you're doing h_test = llh_test(3,:), h_test will actually become a vector, as you are trying to get all of the columns for the third row. I'm going to assume that this is a single value, rather than an array.
To modify this code, this actually will take no effort at all, so here's where you need to modify. Anywhere you see %// NEW is where I modified and anything else is your original code:
llh_test = zeros(3,79); %// Preallocate
for k = 1 : 79 %// You have 79 values to go through
rng_sat = sat_look_tcs_pass1(3,k)/2e2; %// NEW Change to k
u_sat = [sat_look_tcs_pass1(1,k)/sat_look_tcs_pass1(3,k); ...
sat_look_tcs_pass1(2,k)/sat_look_tcs_pass1(3,k);...
sat_look_tcs_pass1(3,k)/sat_look_tcs_pass1(3,k)]; %// NEW - Change to k
h_intercept = sat_look_pass1_llh(3,k)/2e3; %// NEW - Change to k
rng_test_min=0;
rng_test_max=rng_sat;
err=0.01;
while abs(h_test-h_intercept) > err
rng_test=(rng_test_min+rng_test_max)/2;
tcs_test=u_sat*rng_test;
llh_test(:,k) = tcs2llhT(tcs_test,station_llh); %// NEW - llh_test is now a matrix
h_test = llh_test(3,k); %// NEW - Changed the way we are accessing llh_test
if h_test >= h_intercept
rng_test_max=rng_test;
else
rng_test_min=rng_test;
end
end
end
Take a look at the general pattern of your code. You essentially are changing all of the points where you were accessing the first column with the kth column. Also, llh_test is a matrix, and so for each iteration in your loop, you want to access the kth column. llh_test should now be a 3 x 79 matrix as per your specifications.
Good luck!

beginner:referencing a cell containing a zero matlab

So far I have got this code:
clear all; % clears all variables from your workspace
close all; % closes all figure windows
clc; % clears command window
%%=============================================
%%define number of trials and subjects
%%=============================================
njump=81;
nsbj=6;
%%
%%==============================================
%%defining size of cell that will be created
%%==============================================
data=cell(njump,1);
%%
%%==============================================
%%defining gravity and frame rate per second (fps)
%%==============================================
fps=0.001; %frames per second
g=-9.81; %acceleration
%%
%%==============================================
%%read in excel data in CSV format
%%===============================================
for i=1:njump;
x=sprintf('Trial%02d.csv',i),sprintf('Trial%02d',i),'A1:E7000';;% jump data
data{i}=xlsread(x,'A1:E7000');
%%===============================================
%%defining total no. of frames and time of flight
%tnf=total number of frames equal to zero
%n = nnz(X) returns the number of nonzero elements in matrix X.
%%===============================================
% myMax(i) = nanmax(data{i}(:,5));
% vals = find(data{i}(:,5) > (myMax(i) - 10));
% pointsInAir = numel(vals,i);
tnf(i,1) = size(data{i,1},1) - nnz(data{i,1}(:,5)); %number of zeros
tof(i)=tnf(i)*fps; %Time of flight is equal to this
jh(i,1)=(-g*(tof(i).^2)/8); %defining jump height
%%=================================================
%%to find average power first use "find" function to find the first zero in
%%Fz, have the cell referenced
%%then use nanmean for average power(av_pwr)
%%use nanmin for peak power (peak_pwr)
%%=================================================
n = 1; % the following call to find retrieves only the n first element(s) found.
ref= find(data{i,1}(:,5)==0, n, 'first');
% ref=find(data(:,5)==0);
peak_pwr(i,1) = nanmin (data {i,1}(1:ref,5)); %preak power in coloumn E1 in all data with reference to cell found
av_pwr(i,1)=nanmean(data {i,1}(1:ref,5));%average power in coloumn E1 in all data with reference to cell found
%%==================================================
%%Plot the results onto a time vs jump height, time vs average power and
%%time vs peak power
However the part that is hard is trying to find the first zero in column E which is the 5th column to use as a reference cell. I want to use this reference cell so that I can do my average and peak power calcs. that use the numbers before this zero.
In this case ref is empty so you cannot access the first element.
If you think that ref should not be empty you need to go back further to see where things go wrong. Otherwise, you can use something like:
if any(ref)
%Do something
else
%Return the default value/do alternative action
end
It could help to have an example of what's in data. I have created one which might be similar to yours :
data{1,1}=magic(6)-10
Now in this matrix, column 5 actually does have a zero element so ref= find(data{1,1}(:,5)==0); ref(1) actually works and retrieves the first index of a zero element. However, if it didn't, you would be trying to access the first element of an empty matrix.
Try instead using the second (and perhaps third) arguments of find to achieve this :
n = 1;
% the following call to find retrieves only the n first element(s) found.
ref= find(data{1,1}(:,5)==0, n, 'first');
The rest of your code seems like it should work, although from the looks of it i have a feeling your loop (i take it you are using a loop for i) could maybe be vectorized.
Hope this helps :)
Tepp

How can I view all elements of a structure of arrays without writing a FOR-loop?

I am interested in seeing all the elements in the :
result(:,:).randMin(1:4,2:end)
in which the result(a=1:24, d=1:5).
In general is it possible to access them without a loop and cat ?
You cannot use the [] trick with multi-level indexing, but if all of randMin are 128 x 11 arrays:
out = [result(1:24,1:5).randMin];
out = reshape(out,[128 11, 24, 5]);
out = out(1:4,2:end,:,:);
Final result has size of 4 x 10 x 24 x 5 where the first two are your randMin(1:4,2:end), and last two dimensions are your a and d respectively.
It looks like you are looking for getfield:
getfield( result, {1:24, 1:5}, 'randMin', {1:4, 2:end} );
I'm a bit rusty with this command and you might need to play with it a bit to make it work.
Read its manual and good luck!
I don't think it is possible because randMin could be something else for every field in result. result(1,1).randMin could be a matrix, result(1,2).randMin could be a vector, result(2,1).randMin could be 4-dimensional...you see where I'm going with this.
So there is no way of knowing the dimensions or the size of each result's randMin without looping through all fields in result. If there is a function that does what you want, it will have to use a loop internally, so you might as well use a loop yourself.
Edit:
If it is constant you can try something like this:
%Generating matrix struct results(a,b).randMin(c,d)
dim1=24;
dim2=5;
dim3=128;
dim4=11;
% value=0;
% for i=1:dim1
% for j=1:dim2
% for k=1:dim3
% for l=1:dim4
% results(i,j).randMin(k,l)=value;
% value=value+1;
% end
% end
% end
% end
%Getting the values
range1=1:24;
range2=1:5;
range3=1:4;
range4=2:dim4;
myMat=[results(range1, range2).randMin];
myContainer=reshape(myMat, dim3, dim4, length(range1), length(range2));
desiredValues=myContainer(range3, range4,:,:);
In the end, desiredValues will have the values you want, but the indices switched sides, instead of results(a,b).randMin(c,d) it is now desiredValues(c,d,a,b).
As I didn't know exactly how your struct looks like, I defined dim1 to dim4 as maximum values for the indices a to d. You can use range1 to range4 to select your desired values.