Input Parameters of a 'From Workspace' Block in Simulink - matlab

I have a .mat file which has a structure loaded into the Workspace. I have created a simulink model and want to Import the signals from the Workspace. What should be the Input value for the Data Parameter of the 'From Workspace' block. The Name of the structure is Measurements, the Signal Name is B_cal and it has further elements as time,name, Units and value. I know that the structures can be accessed by somewhat like this command :
Measurements.B_cal.value
But i am unable to set the Input Parameters. Could anyone help me with this ?

There are some limitation to use structures through the FromWorkspace block:
A MATLAB expression that evaluates to one of the following:
A MATLAB timeseries object
A structure of MATLAB timeseries objects
A two-dimensional matrix:
The first element of each matrix row is a time stamp.
The rest of each row is a scalar or vector of signal values.
A structure, with or without time, which contains:
1) A signals.values field, which contains a vector of signal values
2) An optional signals.dimensions array, which contains the dimensions of the signal
3) An optional time vector, which contains time stamps
More useful information you can find in help.
So in your case you can use different methods. I'll give some examples:
1) define your struct in necessary format:
t = (1:10)'; %'
v = [6 9 3 1 7 0 7 3 8 1]'; %'
measure.time = t;
measure.signals.values = v;
Important moment here: t andv must be a columns! rows will not work!
If you need to use several rows of data use multidimensional v and add
measure.signals.dimentions = size(v,2);
2) You can see ths time field is an optional. If you do not have it you need to set Sample time in block other than 0 and, clear Interpolate Data, Set Form output after final data value by to a value other than Extrapolation. Furthermore, you need to define time field:
mystruct.time = [];
3) If you don't want to change your structure, you can use next:
t = (1:10)'; %'
and set this in Data of FromWorkspace block: [t, Measurements.B_cal.value].
4) There are some useful methods: use timeseries or just matrix. But it's not really your case if you need to use your structure.

Related

FOR iterator block in Simulink and model's input

Hello I'm building a exe from a simulink model and in order to do that I pass the inputs to it through a .mat file.
My question is, since in my model is present a "for each" block, how can I store the data in the .mat file? Normally (without the for each block) I would store the input as a constant vector in the workspace (see the upper part of the simulink model) and it will handle automatically how to pass the data during the simulation time. But in my case, since I want to export as .exe and pass the input programmatically, I need the input as .mat file and the presence of the "for each" block screw up the building the vector time (since is unclear how to combine time vector with data vector inside the .mat file because is unclear to simulink which data take at a given simulation time.
Thank you for any help!
It's not really clear what the specific problem you are having is.
In your upper diagram, the model will run when you have a variable
>> input = 1:3;
If you turn on Display->Signals & Ports->Signal Dimensions then you'll see that the signal coming out of the Constant block has a dimension of 3.
For the lower diagram, create a variable in MATLAB, that since it will be used in a From File block, must adhere to the specifications required for that block, which means the first row is a time vector, so
>> t = [0 10]
t =
0 10
>> u = [1 1;2 2;3 3]
u =
1 1
2 2
3 3
>> tu = [t;u]
tu =
0 10
1 1
2 2
3 3
And then save this variable to your file,
>> save input tu
Now the signal coming out of the From File block will also be of dimension 3.
Change the values of t and u to suit your specific problem.

Matlab/Simulink LookupTable with Workspace vectors

I am new with Simulink and I am struggling with the Dynamic Lookup Table (inputs : x, xadta, ydata; output: y).
I have several 2D vectors (xdata and ydata) stored in my Workspace and I would like to use them in Simulink in a Dynamic Lookup Table to return a value (y) depending on another variable in Simulink (x).
If I understand how it works I have first to convert my 2D vectors in structures (time,values,dimensions) to be read in Simulink ?
So I did it this way but I got an error :
vector.time = xdata; % dimension 1x100
vector.signals.values = ydata; % dimension 1x100
vector.signals.dimensions = [1 100];
save('vector.mat','vector')
Error
"The last dimension of each
'signals.values' field must be the same as the number of rows in the 'time' field."
Besides I am not sure that what I am trying to do is appropriate... I use the xdata of my vectors/structures as "time" in the structures to get my vectors readable in Simulink. But I do not think it should have anything to do with time notion. I just want the Dynamic Lookup Table to return the "ydata" value of the vector/structure corresponding to the value of "x"="xdata". Only "x" change with time in the Simulation.
It looks like you should just be using the 1D Lookup Table, with your xdata and ydata variables (defined in your MATLAB Workspace) used as the block parameters.
As to the error you're getting, it seems to be related to using the From File block (which it looks like you're using to get data into your model) not the look-up table itself. To get that to work, define your time vector as a column vector, not a row vector as you've done, and think of each row as a different time point.
At each time point, you'll get a different signal value. This is like a look-up table itself (looking up the signal value for each different time value), but doesn't sound like what you are really wanting to achieve.

Splitting non-continuous sized matrix in vectors

I'm writing an piece of software within Matlab. Here, the user can define a dimension say 3.
This dimension is subsequently the number of iterations of a for loop. Within this loop, I construct a matrix to store the results which are generated during every iteration. So, the data of every iteration is stored in a row of a matrix.
Therefore, the size of the matrix depends on the size of the loop and thus the user input.
Now, I want to separate each row of this matrix (cl_matrix) and create separate vectors for every row automatically. How would one go on about? I am stuck here...
So far I have:
Angle = [1 7 15];
for i = 1:length(Angle)
%% do some calculations here %%
cl_matrix(i,:) = A.data(:,7);
end
I want to automate this based on the length of Angle:
length(Angle)
cl_1 = cl_matrix(1,:);
cl_7 = cl_matrix(2,:);
cl_15= cl_matrix(3,:);
Thanks!
The only way to dynamically generate in the workspace variables variables whos name is built by aggregating string and numeric values (as in your question) is to use the eval function.
Nevertheless, eval is only one character far from "evil", seductive as it is and dangerous as it is as well.
A possible compromise between directly working with the cl_matrix and generating the set of array cl_1, cl_7 and cl_15 could be creating a structure whos fields are dynamically generated.
You can actually generate a struct whos field are cl_1, cl_7 and cl_15 this way:
cl_struct.(['cl_' num2str(Angle(i))])=cl_matrix(i,:)
(you might notice the field name, e. g. cl_1, is generated in the same way you could generate it by using eval).
Using this approach offers a remarkable advantage with respect to the generation of the arrays by using eval: you can access to the field od the struct (that is to their content) even not knowing their names.
In the following you can find a modified version of your script in which this approach has been implemented.
The script generate two structs:
the first one, cl_struct_same_length is used to store the rows of the cl_matrix
thesecond one, cl_struct_different_length is used to store arrays of different length
In the script there are examples on how to access to the fileds (that is the arrays) to perform some calculations (in the example, to evaluate the mean of each of then).
You can access to the struct fields by using the functions:
getfield to get the values stored in it
fieldnames to get the names (dynamically generated) of the field
Updated script
Angle = [1 7 15];
for i = 1:length(Angle)
% do some calculations here %%
% % % cl_matrix(i,:) = A.data(:,7);
% Populate cl_matrix
cl_matrix(i,:) = randi(10,1,10)*Angle(i);
% Create a struct with dinamic filed names
cl_struct_same_length.(['cl_' num2str(Angle(i))])=cl_matrix(i,:)
cl_struct_different_length.(['cl_' num2str(Angle(i))])=randi(10,1,Angle(i))
end
% Use "fieldnames" to get the names of the dinamically generated struct's field
cl_fields=fieldnames(cl_struct_same_length)
% Loop through the struct's fileds to perform some calculation on the
% stored values
for i=1:length(cl_fields)
cl_means(i)=mean(cl_struct_same_length.(cl_fields{i}))
end
% Assign the value stored in a struct's field to a variable
row_2_of_cl_matrix=getfield(cl_struct_different_length,(['cl_' num2str(Angle(2))]))
Hope this helps.

Matlab: Can I refer to array indices via unique names?

Suppose I have a column matrix pols containing vectors of [theta, rho, z].
Which means, if I have 9 such vectors, it will be a 9x3 matrix.
It is quite handy to have them arranged as such, because I can just feed any one of them to functions like pol2cart:
cart3 = pol2cart(pols(3,:));
and for a certain vector, I can find its components via the indices 1, 2, 3:
rho5 = pols(5,2);
But sometimes the matrix is actually within another wider matrix, and could be in the middle instead of the beginning, such that the above might become:
rho5 = pols(5,6);
In order to make the code more readable in case someone else has to maintain it, is there anyway to refer to an index via a unique name? Like
rho5 = pols(5).rho;
where it could be defined earlier that .rho maps to the column which has the value of rho.
I've ventured into converting matrices to cells then to array using mat2cell and cell2struct but it doesn't seem practical. Or, I could make an array of structs, but then I lose the ability to do pol2cart(pols), and instead must do
pol2cart(pols.theta, pols.rho, pols.z);
So to repeat the question: can I map the indices to unique names?
For the default MATLAB data types, no, you can't really do that. You could, however, create your own new data type (i.e. class object) to store your data. Within the class definition you would overload the subsref method to define how subscripted referencing (i.e. using (), {}, or .) behaves for your new object. This could get rather tricky with regards to dealing with arrays of objects, but it is possible.
Note that you would also have to create overloaded methods for all the existing functions you want to use on your new data type. Specifically, you would have to create a pol2cart method for your object that could internally call the built-in pol2cart function with the appropriate pieces of data from your object passed as arguments.
...And this brings me to a simpler solution for your current situation. Instead of making a whole new type of class object, you could create a structure array (or scalar structure of arrays) to store your data and simply create a new overloaded pol2cart function specifically for struct data types that will simplify the calling syntax.
I discuss more details of overloading functions for built-in data types in two other answers here and here. In short, you would create a folder called #struct and place it in a folder on your MATLAB path. In this #struct folder you would then put this overloaded function:
function varargout = pol2cart(polarCoordinates)
[varargout{1:nargout}] = pol2cart(polarCoordinates.theta, ...
polarCoordinates.rho, ...
polarCoordinates.z);
end
Note that this is a stream-lined version of the function, without error checks on the input, etc. Now, let's make some sample data:
pols = rand(9, 3); %# A 2-D array of data
polStruct = struct('theta', pols(:, 1), ... %# Convert it to a scalar
'rho', pols(:, 2), ... %# structure of arrays
'z', pols(:, 3));
And you could access the rho value of the fifth row as follows:
rho5 = pols(5,2);
rho5 = polStruct.rho(5);
If you wanted to convert from polar to cartesian coordinates, here's how you would do it for each data type:
[X,Y,Z] = pol2cart(pols(:,1), pols(:,2), pols(:,3)); %# Calls the built-in one
[X2,Y2,Z2] = pol2cart(polStruct); %# Calls the overloaded one
And you can check that they each give identical results as follows:
>> isequal([X Y Z],[X2 Y2 Z2])
ans =
1 %# True!
OK, the formal answer is probably "no" as given by woodchips above. However, if you really want to do something like that, you might be able to use a semi-hack. Specifically, you can define a class and overload an operator to achieve (almost) what you want. Unfortunately, I see that Matlab doesn't allow overloading ., so you have to use some other operator. (see edit below)
Just to give you the idea, here is a class that returns the i-th row of a matrix M by M^i.
classdef Test
properties
M;
end
methods
function this = Test(M)
this.M = M;
end
function res = mpower(this, i)
res = this.M(i, :);
end
end
end
And it can be run like this:
>> tmp = Test([1 2; 3 4]);
>> tmp^1
ans =
1 2
>> tmp^2
ans =
3 4
Use at your own risk! :)
Edit:
I was wrong above. As mentioned in gnovice's answer you can actually define the . operator for a custom class using method subsref.
No. You cannot do so. As simple as that.

Do values passed into a function update outside the function in Matlab

I'm working in Matlab on using blockproc to process through an image and use NNMF to decompose it into two factor matrices. My question is that if I pass a variable into a function and modify it does this value modify outside the function
eg
function R = addOne (value, value2)
value2 = value2 + 1;
R = value + 1;
end
For example if I call the function above only value+1 will be passed back as the return. If i access the variable I passed in as value2 will it also have increased?
I ask this because blockproc only allows 1 matrix to be returned but I will need to modify two matrices.
In general, Matlab passes variables by value, and not by reference (see also here). This means that a variable passed into a function is basically an independent copy of the variable in the original workspace. Note that handle objects are an exception, but they won't solve your issue.
To solve your problem, you could catenate the two outputs along the third dimension, so that the first plane of the output out(:,:,1) corresponds to the first factor matrix, and the second plane of the output out(:,:,2) corresponds to the second factor matrix.