I'm trying to generate a collection of information about a set of images, so I've created a struct array as follow,
resultsInfo = struct('img_index',0,'correlated',cell(1,5),'correlationFactor',zeros(1,5),'ImgSum',zeros(640,480));
Where: img_index is an integer that represents the image, the correlated is the cells containing the name of correlated images, correlationFactor is a number which represents how the images are similar, and the imgSum is a sum of correlated images.
I want to create the array in a dynamic way, inside a for loop, but the code generates only the fifth imageSums of each element.
How can I start the struct to fill all the elements of the array with the matrix of zeros?
Please define following method :
function resultStruct = CreateEmptySruct ()
resultStruct.img_index = 0 ;
resultStruct.correlated = cell(1,5);
resultStruct.correlationFactor = zeros(1,5);
resultStruct.ImgSum = zeros(640,480) ;
end
Then call this method in For loop like this:
for i = 1 :5
structArray(i) = CreateEmptySruct () ;
end
However, you can also set any value to each struct individually by passing function arguments.
Related
I need to pass a part of a structure's name into a function.
Examples of a available structs:
systems.system1.stats.equityCurve.relative.exFee
systems.system1.stats.equityCurve.relative.inFee
systems.system2.stats.equityCurve.relative.exFee
systems.system2.stats.equityCurve.relative.inFee
systems.system1.returns.aggregated.exFee
systems.system1.returns.aggregated.inFee
systems.system2.returns.aggregated.exFee
systems.system2.returns.aggregated.inFee
... This goes on...
Within a function, I loop through the structure as follows:
function mat = test(fNames)
feeString = {'exFee', 'inFee'};
sysNames = {'system1', 'system2'};
for n = 1 : 2
mat{n} = systems.(sysNames{n}).stats.equityCurve.relative.(feeString{n});
end
end
What I like to handle in a flexible way within the loop is the middle part, i.e. the part after systems.(sysNames{n}) and before .(feeString{n}) (compare examples).
I am now looking for a way to pass the middle part as an input argument fNames into the function. The loop should than contain something like
mat{n} = systems.(sysNames{n}).(fName).(feeString{n});
How about using a helper function such as
function rec_stru = recSA(stru, field_names)
if numel(field_names) == 1
rec_stru = stru.(field_names{1});
else
rec_stru = recSA(stru.(field_names{1}), field_names(2:end));
end
This function takes the intermediate field names as a cell array.
This would turn this statement:
mat{n} = systems.(sysNames{n}).stats.equityCurve.relative.(feeString{n});
into
mat{n} = recSA(systems.(sysNames{n}), {'stats', 'equityCurve', 'relative', feeString{n}});
The first part of the cell array could then be passed as an argument to the function.
This is one of those cases where matlab is a bit unhelpful in the documentation. There is a way to use the fieldnames function in matlab to get the list of all the fields and iterate over that using dynamic fields.
systems.system1.stats.equityCurve.relative.exFee='T'
systems.system1.stats.equityCurve.relative.inFee='E'
systems.system2.stats.equityCurve.relative.exFee='S'
systems.system2.stats.equityCurve.relative.inFee='T'
systems.system1.returns.aggregated.exFee='D'
systems.system1.returns.aggregated.inFee='A'
systems.system2.returns.aggregated.exFee='T'
systems.system2.returns.aggregated.inFee='A'
dynamicvariable=fieldnames(systems.system1)
This will return a cell matrix of the field names which you can use to iterate over.
systems.system1.(dynamicvariable{1})
ans =
equityCurve: [1x1 struct]
Ideally you would have your data structure fixed in such a way that you know how many levels of depth are in your data structure.
I am completely new to Max and am struggling to understand how to use arrays and Javascript parameters.
I have one working js object that outputs an array:
var inlets = 1;
var outlets = 1;
function getRandomChordProgression()
{
outlet(0, [1,4,5]);
return [1,4,5];
}
And then later I want to use that array in another js object, that takes an array and an integer:
var inlets = 2;
var outlets = 1;
function getCurrentChord(chords, barNumber)
{
var chord = chords[barNumber % 3];
outlet(0, chord);
return chord;
}
I tried the below, but the js gets undefined inputs.
The first thing to notice is that in Max Msp, in order to assign a list to a single symbol, you need to use the "tosymbol" object. Even if lists are effectively considered mono dimensional arrays in Max Msp, in order to be understood by javascript they first need to be converted. Once the list is converted into a symbol, we can join it with the integer coming from the number box, pack it with the getCurrentChord message and feed it into the getCurrentChord.js object.
You will see that by converting a list into a symbol every character in the array, including the spaces, is seen as part of the array. So using your example, an array composed by 3 integers will have 5 positions occupied, from 0 to 4. In order to make this work, inside the second .js script the modulo operator needs to be set to 5 in order to have a maximum remainder of 4. This means that by setting the number box to 1 or 3 you will have an empty output. So you need to decide how and if to parse the input or the output in order to obtain only the values desired.
var inlets = 2;
var outlets = 1;
function getCurrentChord(chords, barNumber)
{
var chord = chords[barNumber % 5];
outlet(0, chord);
}
Hope that helps!
I have a Matlab object, that is a cell array containting structs that have almost identical structures and I want to programmatically get a (sub)field of the structs of all cell array elements.
For example, we take test
test = {struct('a',struct('sub',1)), struct('a',struct('sub',2),'b',1)};
This will create a cell array with the following structure:
cell-element 1: a --> sub --> 1
cell-element 2: a --> sub --> 2
\-> b --> 1
It can be seen that the elements of test don't have the exact same structure, but similar. How can I get all values of the a.sub fields of the elements of the cell. I can obtain them in this specific problem with
acc=zeros(1,numel(test));
for ii=1:numel(test)
acc(ii) = test{ii}.a.sub;
end
but I can't quite get this method to work in a more general context (ie. having different fields).
You may want to use the function getfield:
%//Data to play with
test = {struct('a',struct('sub',1)), struct('a',struct('sub',2),'b',1)};
%//I'm interested in these nested fields
nested_fields = {'a', 'sub'};
%//Scan the cell array to retrieve the data array
acca = cellfun(#(x) getfield(x, nested_fields{:}), test);
In case your data cannot guarantee that all the elements are the same type and size, then you need to output a cell array instead:
%//Scan the cell array to retrieve the data cell array
accc = cellfun(#(x) getfield(x, nested_fields{:}), test, 'UniformOutput', false);
Later Edit
If one wants to use different sets of nested fields for each cell element then:
%//nested_fields list should have the same size as test
nested_fields = {{'a','sub'}, {'b'}};
accm = cellfun(#(x,y) getfield(x,y{:}), test, nested_fields, 'UniformOutput', false);
Edit: No need for recursion, as shown by #CST-link:s answer; the native getfield function can neatly unfold a cell array of fields as its second argument, e.g. getfield(foo{i}, fields{:}) instead of the call to the recursive function in my old answer below. I'll leave the recursive solution below, however, as it could have some value in the context of the question.
You can build you own recursive version of getField, taking a cell array of fields.
function value = getFieldRec(S,fields)
if numel(fields) == 1
value = getfield(S, fields{1});
else
S = getfield(S,fields{1})
fields{1} = [];
fields = fields(~cellfun('isempty',fields));
value = getFieldRec(S,fields);
end
end
Example usage:
foo = {struct('a',struct('sub',1)), ...
struct('a',struct('sub',2),'b',3), ...
struct('c',struct('bar',7),'u',5)};
accessFields = {'a.sub', 'b', 'c.bar'};
values = zeros(1,numel(foo));
for i = 1:numel(foo)
fields = strsplit(accessFields{i},'.');
values(i) = getFieldRec(foo{i},fields);
end
With the following result
values =
1 3 7
I have found a way to do this using eval:
function out = catCellStructSubField(cellStruct, fieldName)
out = zeros(1,numel(cellStruct));
for ii = 1:numel(cellStruct)
out(ii) = eval(['cellStruct{ii}.' fieldName]);
end
Where it can be used on my test example like this:
catCellStructSubField(test, 'a.sub')
Dynamic field names (cellStruct{ii}.(fieldName)) does not work because I'm accessing sub-fields.
I know eval is often a bad idea. I'm curious for different solutions.
This is a bit of a long problem:
I am building an extension to some already existing software that outputs data as a structure array each time it is run. They always have the same name (structureArray)
I want to take all of these structure arrays and use them for analysis in a single code with for loops and cell arrays.
So I now have 3 structure arrays from this existing software, which I have named structureArray1, structureArray2 and structureArray3. I have used the following method for putting each of these into a cell array called "storage".
[filename, pathname] = uigetfile('*.mat','Please select your structure arrays',...
'Multiselect','on');
storage = cell(1,numel(filename));
for x = 1 : numel(filename)
storage{x} = load([pathname filename{x}]);
end
Now here's the problem:
in each structureArray(1,2,3) (now within "storage") there is a matrix called "magV". I would like to have a 1x3 cell array, with the first cell containing magV from structureArray1, the second cell containing magV from structureArray2 and so on...
My attempt so far:
magnitude_V = cell(1,numel(storage));
for y = 1 : numel(storage)
magnitude_V{y} = storage{1,y}.structureArray1.velocityMap.magV;
end
But because all of the structure arrays have a different number at the end, I can't use this method...
Thank you so much for any help because this is driving me mad -.-
You can refer to a structure's fied by a string in parenthesis, e.g. sometruct.('somefield'):
magnitude_V = cell(1,size(storage,2));
for y = 1 : size(storage,2)
magnitude_V{y} = storage{y}.(['structureArray' num2str(y)]).velocityMap.magV;
end
I have a loop which runs 100 times. In each iteration there is a string, double and a table assigned, and in the next iteration new values are assigned for them. What I want to do is to accumulate these values and after the loop finishes save the total result as result.mat using the matlab save function. I've tried putting them in cell-array but its not working so far, so if anyone could please advise how this can be done.
This is what I did:
results_cell=(100,3);
.
.
.
results_cell(i,1)=stringA;
results_cell(i,2)=TableA;
results_cell(i,3)=DoubleA;
But it gives this error Coversion to Cell from Table is not possible. So I've tried converting TableA to array of Doubles using table2array but I still get this Coversion to Cell from Double is not possible
I think using a structure would be a good way to store your data, since they are of different types and you can assign it meaningful field names for easy reference.
For example, let's call the structure Results. You can initialize it like so.
Results = struct('StringData',[],'TableData',[],'DoubleData',[])
Since you know its dimensions, you can even do this:
N = 100;
Results(N).StringData = [];
Results(N).TableData = [];
Results(N).DoubleData = [];
This automatically create a 1xN structure with 3 fields.
Then in your loop you can assign each field with its associated data like so:
for k = 1:N
Results(k).StringData = String(k);
Results(k).TableData = Table(k);
Results(k).DoubleData = Double(k);
end
where String(k), Table(k) and Double(k) are just generic names for your actual data.
When you're done with the loop you can access any type of data using a single index and the right field name.
In order to save a .mat file, use something like this:
save SomeFileName.mat Results
Which you can load into the workspace as you would with any .mat file:
Eg:
S = load('SomeFileName.mat')
R = S.Results
Hope that helps!