Extracting Data from an Array of Arrays using a Loop?

Hello All,
Context: I am using Simulink and Simscape to simulate some system responses to motion. Simulation output writes to the Matlab workspace to an Array of Arrays (object maybe? Not super sure if that's the right nomenclature) called "out". Our model is set up such that it iterates over a range of values for a single parameter. One test might have 5 iterations, the next might have 50, and so on. This means "out" changes size each time we run our model.
Problem: Now on to the issue. I am trying to extract data from each iteration and put them all into a Matrix. I can access all the data I want manually, using the notation "out(1,1).RollAngle.Data" for the first iteration, "out(1,2).RollAngle.Data" for the second iteration, and so on. However, this is too cumbersome since most of our tests are going to have 20-plus iterations.
Can anybody help me create a for loop that would append each data series as a new column in a matrix? This might be super obvious, but it's a new problem for me...
Thanks!

 Accepted Answer

Paul
Paul on 15 Jun 2024
Edited: Paul on 15 Jun 2024
Hi Kylen,
To make sure I understand correctly .... at the end of the processing you have a variable called 'out' and it is an array of class Simulink.SimulationOutput. Each element of out contains a timeseries named RollData and (probably) other timeseries outputs as well. To illustrate, the data sructure looks something like this:
>> whos out
Name Size Bytes Class Attributes
out 1x2 17062 Simulink.SimulationOutput
>> out
out =
1x2 Simulink.SimulationOutput array
>> out(1)
ans =
Simulink.SimulationOutput:
RollData: [1x1 timeseries]
simout1: [1x1 timeseries]
tout: [51x1 double]
SimulationMetadata: [1x1 Simulink.SimulationMetadata]
ErrorMessage: [0x0 char]
Now you want to extract the Data field of out(1).RollData and out(2).RollData and put them in an array. This will only be possible if they both have the same length and (probably) only makes sense if they both have the same timestamps. Assuming that's the case, then we can do
Data = [out.RollData.Data];
If that's not the case, then we will have to resort to some other type of container.
However, I'd ask if collecting all of the RollData.Data into a single array is really necessary. What problem does that solve?

5 Comments

Hi, and thank you for the detailed response!
Yes, you have the structure of things exactly right. Unfortunately, our data doesn't always have the same length (it depends when failure occurs in the Simulink/Simscape model).
We want to put all of the Roll Angle data into one spot so we can pass it on to some of our other teammembers. Ideally, I would like to collect the iterations of Roll Angle and write them all to a CSV or something similar to then pass to our other team.
I was able to come up with a loop that assigns each iteration's Roll Angle into it's own cell array with the code shown below. fullcell is where I put the data, numElemS is the number of iterations. Now I'm toying around with getting the cell array written to a file I can share to my teammates. I'm just diving back into this after the weekend, so I'm hoping for success with cell2table or writetable or some combination of thereof.
Suggestions are definitely still appreciated, and thanks again!
fullcell = {};
for t = numElemS:-1:1
RollAngleOutput = {(out(1,t).RollAngle.Data)};
fullcell = [fullcell, RollAngleOutput];
end
Maybe a silly question, but why not just save the out array in .mat file and give the .mat file to your teammates? Unless they don't have Matlab ....
I think that for any CSV file solution you'll have to find the data set with the most elements and then pad the others with fillers so that they all have the same length before using cell2table or writetable. Don't forget to also provide the time vectors for each data set.
Thank you. Yes, I ended up figuring out how to pad the columns so that they're all the same length.
Two reasons why we aren't saving the whole .mat. There's extra info in the .mat that isn't pertinent to everyone. Also, the .mat file ends up being huge (11-12 Gb, which might not be huge for everyone, but for our purposes it is pretty big).
Thanks Again!
By "saving the whole .mat" I assume you mean saving the entire out array in a .mat file. You could certainly extract from out(i) just the RollData time series that everyone needs and store each RollData time series as an element of a time series array (I think that will work) or some other container, like a struct or cell, and save the result of the extraction to a .mat file, which still might be a bit easier to work with than a .csv (and might actually be smaller if that matters). But, if you're happy with your current approach, then no need to polish the cannonball, so to speak.
This is a good idea, too! Thanks again.

Sign in to comment.

More Answers (1)

we can create a for loop in Matlab that iterates through each element in the "out" array, extracts the desired data, and appends it as a new column in a matrix. This process will automate the extraction and organization of data, making it more manageable and scalable for varying numbers of iterations.
Here is a step-by-step guide to achieve this:
Initialize Variables: Before the loop, initialize an empty matrix to store the extracted data columns. Also, determine the total number of iterations to set the size of the final matrix.
numIterations = size(out, 2); % Get the total number of iterations dataMatrix = []; % Initialize an empty matrix to store data columns
For Loop: Create a for loop that iterates through each iteration in the "out" array. Within the loop, extract the desired data and append it as a new column to the data matrix.
for i = 1:numIterations dataColumn = out(1, i).RollAngle.Data; % Extract data for the current iteration dataMatrix = [dataMatrix, dataColumn]; % Append data as a new column in the matrix end
Complete Code: Combine the initialization, for loop, and any additional processing steps into a complete script or function.
numIterations = size(out, 2); % Get the total number of iterations dataMatrix = []; % Initialize an empty matrix to store data columns
for i = 1:numIterations dataColumn = out(1, i).RollAngle.Data; % Extract data for the current iteration dataMatrix = [dataMatrix, dataColumn]; % Append data as a new column in the matrix end
% Additional processing or analysis can be performed on the dataMatrix disp(dataMatrix); % Display the final matrix
By following these steps and customizing the data extraction based on the structure of the "out" array and the specific data fields needed, you can efficiently extract and organize simulation data into a matrix format. This approach streamlines the process and eliminates the manual effort required for each iteration, enhancing the scalability and usability of your simulation data analysis.
To the best of my knowledge, this will help you figure out solution to your problem.

5 Comments

Thank you for the feedback. Do you know if this will work if the data is of different lengths?
In Matlab, when concatenating arrays using square brackets [ ], the arrays are automatically padded with zeros to match the length of the longest array. Therefore, when appending dataColumn to dataMatrix, Matlab will handle the varying lengths by padding the shorter columns with zeros to align with the longest column. This behavior ensures that the final matrix dataMatrix will have consistent dimensions, allowing for further processing or analysis without issues related to different data lengths.
"In Matlab, when concatenating arrays using square brackets [ ], the arrays are automatically padded with zeros to match the length of the longest array. "
That's not true.
a = [1;2]
a = 2x1
1 2
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
b = 1;
c = [a b]
Error using horzcat
Dimensions of arrays being concatenated are not consistent.
The error message Error using horzcat Dimensions of arrays being concatenated are not consistent indicates that there is a mismatch in the dimensions of the arrays being concatenated. In this case, a is a 2x1 array, and b is a scalar, which leads to an inconsistency when trying to concatenate them horizontally
Exactly. Point being that there is no zero padding if there is a size mismatch between the arrays being concatenated.

Sign in to comment.

Categories

Products

Release

R2023b

Asked:

on 14 Jun 2024

Commented:

on 21 Jun 2024

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!