2

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
Pursuit
  • 12,285
  • 1
  • 25
  • 41
Adam
  • 25
  • 1
  • 5

3 Answers3

6

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}
Pursuit
  • 12,285
  • 1
  • 25
  • 41
  • As I was writing this, it felt very familiar. See also: http://stackoverflow.com/a/14130366/931379 for a similar discussion. – Pursuit Mar 15 '13 at 17:53
  • Thanks for your comments. I'm interested in taking your advice and not using the EVAL function. The only problem I've found with using a Strucutre is that MATLAB just returns Sim1: [2x6 double] Sim2: [2x6 double] , is there a way of now accessing this data if I wanted to go back and review what the matrix for Sim1 or Sim2 was? – Adam Mar 15 '13 at 18:22
  • Of course. I'll put access methods for each method in the appropriate places in a few minutes. For now, try out: `simResults.Sim1`; or `temp = simResults.Sim1`; or even `names = fieldNames(simResults)`, followed by `simResults.(names{1})`. – Pursuit Mar 15 '13 at 18:26
  • Thank you so much for your help. I went with using a Structure to store the results (I couldn't get map to work but I think its just because I don't fully understand it yet) and then using the access help you gave me to extract the data if I wanted to review it. I also tried @Bill Cheathams' method and that worked great too. I was just wondering whether one method is better than the other? – Adam Mar 15 '13 at 23:29
3

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
Bill Cheatham
  • 11,396
  • 17
  • 69
  • 104
  • 1
    I sometimes use this method as well. – Pursuit Mar 15 '13 at 18:27
  • Thanks for your help. This method worked great too. As I said in response to @Pursuit I was just wondering whether there was an advantage to using an Array of Structures instead of just creating a Structure? – Adam Mar 15 '13 at 23:33
  • This method (array of structures): is easier to iterate through (no need to get fieldnames first), can support any name (including e.g. spaces), can support additional data fields (e.g. "time", as in this example. If you're coding skills are sufficient, this is better than a simple structure with named fields. – Pursuit Mar 16 '13 at 00:31
0

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

Gilad
  • 6,437
  • 14
  • 61
  • 119