0
% Data
Fields = {'History','Maths','English','French','Geography','Philosophy'}';
Students= horzcat({'5','7','3','6','10','9'}',{'6','7','7','6','10','9'}',{'5','2','3','9','1','9'}',{'1','4','9','6','6','9'}',{'8','8','3','8','10','9'}',{'5','5','5','9','8','7'}' );
Table_Score = horzcat(Fields,Students);

PS: I know there are certain ways to organize better the raw data to facilitate thing but imagine that it is an pratical case where I want to allocate cells and set values without mentionning directly the name of these variables, but calling them from the cell arrays where they are listed.

% Imagine there are much more fields of study, I will just mention a few
List_of_study_fields = {'History','Maths','English','French','Geography','Philosophy'};
nb_fields = length(List_of_study_fields);

% Imagine there are much more students, I will just mention a few
List_of_students = {'Damien','Michael','Louis', 'Daniel','Isabelle','Jessica'};

%% 1) Pre-allocate "student names" variables from the "student names" (cell array): 
% Each variable is the student name in the list.
% Scores will be affected to each variable over the loop. 6 students, 6
% variables:

for ii = 1 : length(List_of_students)
    Init_var_cell_array = cell(nb_fields,1);
    assignin('caller', List_of_students{ii}, Init_var_cell_array);
end

Ok, If I stop the script at this point and check for the cell variable "Damien", it is a cell 6x1, like I want.

Question 1) I think it is enough to affirm the cell is pre-allocated! Am I wrong to think so?

%% 2) Get scores data for every student. For the example, I write the code for the first student only (Damien)

for bb = 1: length(List_of_study_fields)
    Damien(bb) = Table_Score(bb,2);
end

If I keep running until the end, at this point I get the message:

"The variable Damien appears to change size on every loop iteration (within a script). Consider pre-allocating for speed."

Question 2) So, isn't cell array Damien" correctly preallocated ? or is the array preallocated, but in a way that Code Analyzer does not recognize?

Question 3) Finally, imagine the list of students is very long and the scores table is huge, how could I collect all data in one cell array per student without bothering writing their name systematically?

Could I have something as follows:

for aa = 1:length(List_of_student)
    for bb = 1: length(List_of_study_fields)
        assign(List_of_student{aa}, Table_Score(bb,aa+1))
    end
end

So that in the end all my variables Damien, Michael, etc.. are 6x1 cell array ?

Thank you in advance!

Alban
  • 21
  • 4
  • 3
    M-Lint cannot parse `assignin`, `evalin`, or `eval` calls so it cannot know the size of `Damien`. This also means MATLAB's compiler cannot optimize your code for efficiency at runtime. – sco1 Dec 15 '15 at 15:47
  • you want to move your line pre-allocating the cell outside your loop as well `Init_var_cell_array = cell(nb_fields,1);` – GameOfThrows Dec 15 '15 at 15:48
  • 2
    I would recommend instead initializing a [`data structure`](http://www.mathworks.com/help/matlab/structures.html) and utilizing [dynamic field referencing](http://blogs.mathworks.com/loren/2005/12/13/use-dynamic-field-references/) if you need to reference by strings. A [Map Container](http://www.mathworks.com/help/matlab/map-containers.html) may also be an option if you have a newer version of MATLAB. – sco1 Dec 15 '15 at 15:49

1 Answers1

1

Q1: see comments above - I very rarely need to use assignin - I suspect this could be solved in a better way.

Q2: Preallocating cells is much less important than arrays/matrix because each cell can contain different things so its difficult to preallocate efficiently.

Q3: As mentioned in the comments above, store your data in a dynamic struct:

for aa = 1:length(List_of_student)
  for bb = 1: length(List_of_study_fields)
    yourData.(List_of_student{aa}).(List_of_study_fields{bb}) = Table_Score(bb,aa+1);
  end
end
matlabgui
  • 5,642
  • 1
  • 12
  • 15
  • Thanks for your help @matlabgui. The data structure is likely the way for my third question but I can't make it work correctly. After running the script, "Damien" is a 6x1 cell but elements are empty. It should contain values of 5, 7, 3, 6, 10 and 9 instead... but scores are not populated properly. Any idea why? – Alban Dec 19 '15 at 07:21