Unequivalent loop structure in MATLab - matlab

I have two versions of code - I wrote the second (more explicit) loop when the first didn't do what I wanted.
Where did I go wrong? I suspect a slicing problem (as in, I'm not correctly slicing the data out)
The first version, which doesn't do what I want, is commented out above the loop:
rBool = false(h.numDirs, h.numTimes, h.numR);
for d = 1:h.numDirs
U_first = h.data(d,1,:);
U_first = U_first{1};
for t = 2:h.numTimes
U = h.data(d,t,:);
U = U{1};
dU = abs(U-U_first);
%rBool(d,t,:) = (dU > (smallVal*U_first) | rBool(d,t-1));
for r=1:h.numR
rBool(d,t,r) = (dU(r) > (smallVal*U_first(r))| rBool(d,t-1,r));
end
end
end

You are missing the third index of the second rBool in your commented line:
rBool(d,t,:) = (dU > (smallVal*U_first) | rBool(d,t-1,:));
Although I'd parenthesize it like this:
rBool(d,t,:) = (dU > (smallVal*U_first)) | rBool(d,t-1,:);
The version you originally had implicitly assumed r==1, I think.
And you can simplify your code by setting
U = h.data{d,t,1};
instead of cutting out a cell vector and choosing the first element.

Related

How to load a sequence of image files using a for loop in MATLAB?

I am beginner in MATLAB. I would like to load 200 image files (size 192x192) in a specific folder by using a for loop.
The image names are '1.png', '2.png', '3.png' and so on.
My code is as below.
list = dir('C:/preds/*.png');
N = size(list,1);
sum_image = zeros(192,192,200);
for i = 1:N
sum_image(:,:,i) = imread('C:/preds/i.png');
end
Which part should I change ?
I would probably do it like the code below:
You are currently getting the list of filenames then not really doing much with it. Iterating over the list is safer otherwise if there is a missing number you could have issues. Also, the sort maybe unnecessary depending if you image numbering is zero-padded so they come out in the correct order ... but better safe than sorry. One other small change initializing the array to size N instead of hard-coding 200. This will make it more flexible.
searchDir = 'C:\preds\';
list = dir([searchDir '*.png']);
nameList = {list.name}; %Get array of names
imNum = str2double(strrep(nameList,'.png','')); %Get image number
[~,idx] = sort(imNum); %sort it
nameList = nameList(idx);
N = numel(nameList);
sum_image = zeros(192,192,N);
for i=1:N
sum_image(:,:,i) = imread(fullfile(searchDir,nameList{i}));
end
I would suggest changing the line within the loop to the following:
sum_image(:,:,i) = imread(['C:/preds/', num2str(i), '.png']);
MATLAB treats the i in your string as a character and not the variable i. The above line of code builds your string piece by piece.
If this isn't a homework problem, the right answer to this question is don't write this as a for loop. Use an imageDatastore:
https://www.mathworks.com/help/matlab/ref/imagedatastore.html
ds = imageDatastore('C:/preds/');
sumImageCellArray = readall(ds);
sumImage = cat(3,sumImageCellArray{:});

Use of if statement in for loop in this code

What does the statement for if=ilow:ihigh mean in this program?
function [d]=for_taup(m,dt,h,q,N,flow,fhigh);
nt= max(size(m));
nh = max(size(h));
M = fft(m,[],1);
D = zeros(nt,nh);
i = sqrt(-1);
ilow = floor(flow*dt*nt)+1; if ilow<1; ilow=1;end;
ihigh = floor(fhigh*dt*nt)+1;
if ihigh>floor(nt/2)+1; ihigh=floor(nt/2)+1;end
for if=ilow:ihigh
f = 2.*pi*(if-1)/nt/dt;
L = exp(i*f*(h.^N)’*q);
x = M(if,:)’;
y = L * x;
D(if,:) = y’;
D(nt+2-if,:) = conj(y)’;
end
D(nt/2+1,:) = zeros(1,nh);
d = real(ifft(D,[],1));
return;
if is used as a variable name. I am surprised that this does not raise a syntax error: most languages would forbid the use of "reserved" keywords. Maybe it would be a good idea to replace if with a different name in order to clarify your code and avoid confusion.
As far as MATLAB is concerned, this code doesn't really mean anything, because it's just a syntax error. if is reserved keyword, and you can't create a variable called if. As such, it just instantly errors and won't run.
You should probably replace all occurrences of the variable if (although not the keyword if in lines 8 and 10) with some other variable name. Avoid i, since you're using that as the imaginary unit.

Vectorize filtering on matlab cell structures

I have a huge cell vector cc (size: 1xN) of the form:
cc{1} = {'indexString1', 'str_row1col1', 'str_row1col2' }
cc{2} = {'indexString2', 'str_row2col1', 'bighello', 'str_row1col3' }
cc{3} = {'indexString3','str_row3col1'}
cc{4} = {'indexString4','str_row3col1', 'helloWorld'}
I want to traverse each cell and remove specific cells that contain the word "hello", e.g c{4}{2}. Can we do that without for loops keeping the final structure of cc?
Best,
Thoth.
EDIT: From the answers and comments I have seen that the structure of the cell impose some limitations. So any other suggestion to store my data are welcome. I just want to keep together all the cells (e.g. 'str_row1col1', 'str_row1col2') that correspond to the same indexString*n* (e.g. indexString1). I made this edit in case it helps some final reshape.
Using regular expressions, you can obtain a logical array in which zeros represent occurences of the word 'hello' somewhere in the nested cell. As #LuisMendo pointed out, this would be much easier to delete the unwanted cells if they were not nested:
clc
clear
cc{1} = {'str_row1col1', 'str_row1col2' };
cc{2} = {'str_row2col1', 'bighello', 'str_row1col3' };
cc{3} = {'str_row3col1'};
cc{4} = {'str_row3col1', 'helloWorld'};
A = (cellfun(#isempty,regexp([cc{:}],'(\w*hello|hello\w*)','match')))
Gives the following array:
A =
1 1 1 0 1 1 1 0
For the rest I think you would need a loop since the nested cells are not all of the same size. Anyhow I hope it helps you a bit.
EDIT Here is what you can do using a for loop. In order to identify words of interest (earth and water as in your comment below), simply add them to the argument in the call to regexp. This character: | is used to make some sort of list so that Matlab checks all the expressions in the brackets.
Please refer to this page for more infos on regular expressions. There is also a possibility to look for regular expressions with case-sensitivity.
Sample code, in which I added strings containing earth and water:
cc{1} = {'str_row1col1', 'earth!superman' 'str_row1col2' 'DummyString'};
cc{2} = {'str_row2col1', 'bighello', 'str_row1col3' };
cc{3} = {'str_row3col1' 'str_row3col3' 'water_batman'};
cc{4} = {'str_row3col1' 'str_row4col2' 'helloWorld'};
cc{5} = {'str_row5_LegoMan' 'str_row5col2' 'AnotherDummyString' 'Useless String' 'BonjourWorld'};
% With a for loop, for example:
FinalCell = cell(size(cc,2),1);
for k = 1:size(cc,2)
DummyCell = cc{k}; % Use dummy cell for easier indexing
% This is where you tell Matlab what words/expressions you are looking for
A = cellfun(#isempty,regexp(cc{k},'(\w*hello|hello\w*|earth|water)','match'));
DummyCell(~A) = []; % Remove the cells containing the strings/words of interest
FinalCell{k} = DummyCell;
end
Then you're good to go. Hope that helps!
The closest thing possible I found is:
clear all
cc{1} = {'str_row1col1', 'str_row1col2' };
cc{2} = {'str_row2col1', 'bighello', 'str_row1col3' };
cc{3} = {'str_row3col1'};
cc{4} = {'str_row3col1', 'helloWorld'};
cc1 = [cc{:}];
cc1 = cc1(~strcmp('bighello',cc1));
This reorganize your array into a one dimensional array and it cannot match regular expression, but only whole words.
For a better job I am afraid you have to use for loops.

Beginner-"Undefined function 'ReadIndexndexDailyLogreturn' for input arguments of type 'cell'."-Error

I am aware many of you will think this should be easily solvable. However, I have no clue about MATLAB.
Here goes my problem: when trying to execute the following example in the Command Window through the command
getLogReturnExcel('ALL.xls', {'ALL'}, 37000, 38000)
the cell-type error appears for this function. From what I understand however, when using {} the function should be grabbing the type inside {} (String in this case?) instead of the cell itself, which would be being grabbed if we were to use (), so there should be no error? Or is there something much more elementary that I might be overseeing? Thanks in advance for every bit of help; as you can tell I very much need it.
Cheers,
Ben
Here goes the function getLogReturnExcel:
function [logreturn, datearray] = getLogReturnExcel( datafilename, ticker, begindate, enddate )
[aanumber, aatext] = xlsread(datafilename);
aaticker = aatext(:,1);
aadate = aanumber(:,2);
aaret = zeros(length(aaticker),1);
aaret(1,1) = 0;
for i = 2:length(aaret)
aaret(i,1) = ln(aanumber(i,3))-ln(aanumber(i-1,3));
end
aadate = aadate(strcmp(aaticker,ticker));
aaret = aaret(strcmp(aaticker,ticker));
logreturn = aaret(aadate>=begindate & aadate<=enddate);
datearray = aadate(aadate>=begindate & aadate<=enddate);
return
The file 'ALL.xls' contains 3 columns, one with strings (the acronym for stocks) and two with numbers (I'm assuming double), one for the date in Excel-format and one with each day's stock standing.
The string can be obtained by using:
ticker{:}
or else the comparison in the lines
aadate = aadate(strcmp(aaticker,ticker));
aaret = aaret(strcmp(aaticker,ticker));
will be between strings and cell array.
Here is some documentation to access elements of a cell array.

MATLAB Changing the name of a matrix with each iteration

I was just wondering if there is a clean way to store a matrix after each iteration with a different name? I would like to be able to store each matrix (uMatrix) under a different name depending on which simulation I am on eg Sim1, Sim2, .... etc. SO that Sim1 = uMatrix after first run through, then Sim2 = uMatrix after 2nd run through. SO that each time I can store a different uMatrix for each different Simulation.
Any help would be much appreciated, and sorry if this turns out to be a silly question. Also any pointers on whether this code can be cleaned up would be great too
Code I am using below
d = 2;
kij = [1,1];
uMatrix = [];
RLABEL=[];
SimNum = 2;
for i =1:SimNum
Sim = ['Sim',num2str(i)] %Simulation number
for j=1:d
RLABEL = [RLABEL 'Row','',num2str(j) ' '];
Px = rand;
var = (5/12)*d*sum(kij);
invLam = sqrt(var);
u(j) = ((log(1-Px))*-invLam)+kij(1,j);
uMatrix(j,1) = j;
uMatrix(j,2) = u(j);
uMatrix(j,3) = kij(1,j);
uMatrix(j,4) = Px;
uMatrix(j,5) = invLam;
uMatrix(j,6) = var;
end
printmat(uMatrix,'Results',RLABEL,'SECTION u kij P(Tij<u) 1/Lambda Var')
end
There are really too many options. To go describe both putting data into, and getting data our of a few of these methods:
Encode in variable names
I really, really dislike this approach, but it seems to be what you are specifically asking for. To save uMatrix as a variable Sim5 (after the 5th run), add the following to your code at the end of the loop:
eval([Sim ' = uMatrix;']); %Where the variable "Sim" contains a string like 'Sim5'
To access the data
listOfStoredDataNames = who('Sim*')
someStoredDataItem = eval(listOfStoredDataNames {1}) %Ugghh
%or of you know the name already
someStoredDataItem = Sim1;
Now, please don't do this. Let me try and convince you that there are better ways.
Use a structure
To do the same thing, using a structure called (for example) simResults
simResults.(Sim) = uMatrix;
or even better
simResults.(genvarname(Sim)) = uMatrix;
To access the data
listOfStoredDataNames = fieldnames(simResults)
someStoredDataItem = simResults.(listOfStoredDataNames{1})
%or of you know the name already
someStoredDataItem = simResults.Sim1
This avoids the always problematic eval statement, and more importantly makes additional code much easier to write. For example you can easily pass all simResults into a function for further processing.
Use a Map
To use a map to do the same storage, first initialize the map
simResults = containers.Map('keyType','char','valueType','any');
Then at each iteration add the values to the map
simResults(Sim) = uMatrix;
To access the data
listOfStoredDataNames = simResults.keys
someStoredDataItem = simResults(listOfStoredDataNames{1})
%or of you know the name already
someStoredDataItem = simResults('Sim1')
Maps are a little more flexible in the strings which can be used for names, and are probably a better solution if you are comfortable.
Use a cell array
For simple, no nonsense storage of the results
simResults{i} = uMatrix;
To access the data
listOfStoredDataNames = {}; %Names are Not available using this method
someStoredDataItem = simResults{1}
Or, using a slight level of nonesense
simResults{i,1} = Sim; %Store the name in column 1
simResults{i,2} = uMatrix; %Store the result in column 2
To access the data
listOfStoredDataNames = simResults(:,1)
someStoredDataItem = simResults{1,2}
Just to add to the detailed answer given by #Pursuit, there is one further method I am fond of:
Use an array of structures
Each item in the array is a structure which stores the results and any additional information:
simResults(i).name = Sim; % store the name of the run
simResults(i).uMatrix = uMatrix; % store the results
simResults(i).time = toc; % store the time taken to do this run
etc. Each element in the array will need to have the same fields. You can use quick operations to extract all the elements from the array, for example to see the timings of each run at a glance you can do:
[simResults.time]
You can also use arrayfun to to a process on each element in the array:
anon_evaluation_func = #(x)( evaluate_uMatrix( x.uMatrix ) );
results = arrayfun( anon_evaluation_func, simResults );
or in a more simple syntax,
for i = 1:length(simResults)
simResults(i).result = evaluate_uMatrix( simResults(i).uMatrix );
end
I would try to use a map which stores a <name, matrix>.
the possible way to do it would be to use http://www.mathworks.com/help/matlab/map-containers.html