Creating multiple CombiTimeTable inside a loop - modelica

How can I create multiple CombiTmeTable based on a given input number and modify each of their parameters inside a loop?
The desired result is to have a generated number of CombiTimeTables equal to an input n, where each table has different tableName and fileName. I'm new to Modelica, the below code explains the logic but it produces many errors:
model DataTables "Model to create CombiTimeTable"
parameter Integer n=10 "Number of tables to be created";
Modelica.Blocks.Sources.CombiTimeTable B[1](
tableOnFile=true,
tableName="T",
fileName="path")
annotation (Placement(transformation(extent={{-88,54},{-68,74}})));
equation
for i in 2:n loop
Modelica.Blocks.Sources.CombiTimeTable B[i](
tableOnFile=true,
tableName="loads",
fileName="path[i]");
end for;
end DataTables;

It's not possible to change parameter values in the equation section, i.e. during simulation. However, you can do that in an initial equation section which is executed before the simulation.
You will also have to mark the parameter that you want to set with fixed=false when you instantiate the CombiTimeTables. Your code will end up like this (assuming that only fileName need to be modified in the loop):
model DataTables "Model to create CombiTimeTable"
parameter Integer n=10 "Number of tables to be created";
Modelica.Blocks.Sources.CombiTimeTable B[1](
tableOnFile=true,
tableName="loads",
each fileName(fixed=false))
annotation (Placement(transformation(extent={{-88,54},{-68,74}})));
initial equation
for i in 2:n loop
Modelica.Blocks.Sources.CombiTimeTable B[i](
fileName="path[i]");
end for;
equation
<remaining equations go here>
end DataTables;
Your loop starts from 2. Make sure to assign a value to B[1].fileName.

Related

Reading multiple numbered data variables from the workspace

For reading time-based data of variables from the Matlab workspace in Simulink (for time-based inter- and extrapolation), a typical solution is the use of the From Workspace block, by e.g. providing variable input data var in the following structure format:
var.time=[nx1]
var.signals.dimensions=m
var.signals.values=[nxm]
for providing the data of m variables with n time-based samples. Since variables' data is stored in a single matrix, it is implied that all variables are required to have the same (number of) time stamps.
If this is not the case, a solution could be the use of multiple From Workspace blocks, and corresponding variable input data structs (e.g. varA, varB, varC, etc.), like so:
However, this solution requires the number of variables to be fixed for all simulations. In my case, variables are numbered (rather than named) and the number of variables might not be the same from one simulation to the next. As such, for generalization purposes, I would like to find a solution without having to change the simulation file. A first step in this direction is the use of a struct array (i.e. var(1), var(2), var(3), etc.), which works:
A candidate next step is then to use a For Iterator to loop over N variables (and then to assign and concatenate the output in some output array, which I know can be done and is not the focus here):
The problem here is that the index id can't be fed to the From Workspace block! I ran into an identical issue when trying to solve the problem with a lookup table block. How to solve this problem of reading multiple but varying number of data variables from the workspace with different (number of) time stamps? Solutions that don't use a From Workspace or lookup table block are welcome too.
Here is equivalent code for running the whole thing in Matlab instead of Simulink:
% DEFINED IN MATLAB:
% Examplary input of variable data with different time stamps, according to
% Simulink structure conventions (.time, .signals etc)
N=3; % number of variables
for id=N:-1:1
var(id).time = linspace(0,2,id*2+2)';
var(id).signals.dimensions = 1;
var(id).signals.values = sin((var(id).time-id)*pi/2)';
end
% TO BE EXECUTED IN SIMULINK:
% the simulink clock time:
t = 1.234; % random time
for id=N:-1:1
var_t(id) = interp1(var(id).time,var(id).signals.values,t);
end
And here a figure to illustrate the results:
% Figure code:
figure(1),clf
colors=lines(N);
for id=1:N
plot(var(id).time,var(id).signals.values,'*-','color',colors(id,:)),hold on
plot(t,var_t(id),'o','color',colors(id,:))
end
xlabel('time'),ylabel('variable data')

How to see number of iterations taken by solveOneNonlinearEquation function in modelica?

I'm using the solveOneNonlinearEquation solver in Modelica which uses Brent's method to find the root of the nonlinear equation. However, I need to know how many iterations were taken by Brent's method in order to compare the rate of convergence with another method like fixed-point iteration. The inbuilt solver does not have the option to output 'NumberOfIterations" and hence I tried writing my own Brent's method function and placing a counter.
However I have to input a function to this function and get the error "The type prefixes flow, input and output shall only be applied for a structured component, if no element of the component has a corresponding type prefix of the same category."
Can someone please help me with this?
The code of Modelica.Math.Nonlinear.solveOneNonlinearEquation is not encrypted. Simply copy it and create your own solveOneNonlinearEquation which contains a counter for the iterations, like
function solveOneNonlinearEquation
...
protected
Integer iterations = 0;
...
algorithm
...
// Search loop
while not found loop
iterations := iterations + 1;
...
end while;
Modelica.Utilities.Streams.print("Iterations: " + String(iterations));
...
end solveOneNonlinearEquation;
For the usage of the function with functions as input, see the example Modelica.Math.Nonlinear.Examples.solveNonlinearEquations1.

MATLAB - create a loop to read from text variables and assign it to variables and then perform in matlab

I'm really new to Matlab and I'm currently working on it to create some matrixes.
i need to write a loop that reads a text file then assign each set of integers to a variable with a certain number for example # of the row. after that it will perform some calculation and then finally Concatenate the arrays in matrix 1xn but what i got stuck with is the process of reading the file and then assign it to a dynamic variable then increment the counter.
i think i have the correct logic with the pseudo code for it but I'm struggling with the actual syntax in MATLAB to be able to do it.
somewhat mix of pseudocode & actual code i managed to write:
content= fopen('text file.txt');
for i=1:size(content,1) *%loop to read till the end of the matrix*
variable_part(i) = fgetl(fid); *%read row and create the integer value in the dynamic variable.*
for i=1 *% loop through the matrix that contains all the created dynamic variables one by one and perform these.*
for i=1:size(variable_part(i),1)
a= variable_part(i)(i,:);
variable_part(i,1)= mean(a);
variable_part(i,2)= min(a);
variable_part(i,3)= max(a);
variable_part(i,4)= std(a);
variable_part(i,5)= var(a);
variable_part(i,6)= max(a)-min(a);
end;
end;
end;
so that fo example the result will be as follows:
content = (27*1) matrix.
%First loop
for i=1:size(content,1) *%loop to read till the end of the matrix*
variable_part1 = 4835:5551; *%first variable created and was assigned with the value of the first row.
%Second Loop
for i=1 %in the matrix that contain all the variables created in the first loop
%Third loop
for i=1:size(variable_part1,1)
a= variable_part1(1,:);
variable_part(1,1)= mean(a);
variable_part(1,2)= min(a);
variable_part(1,3)= max(a);
variable_part(1,4)= std(a);
variable_part(1,5)= var(a);
variable_part(1,6)= max(a)-min(a);
end;
end;
end;
i know the results for the third loop is working and producing what i want but my issue is in the Read text file and the first 2 nested loops.
i appreciate the help.

Matlab - How to create table of unkown number of matrices with same size?

I would like to create table of unknown number of matrices with same sizes, so I can't do it like this:
table1 = table(zeros([5,5]),zeros([5,5]),zeros([5,5]), 'VariableNames', {'matrix1','matrix2','matrix3'});
But here I am stuck because I am not able to find out how to make this without listing zeros([5,5]) n-times, where I don't know what will n be so i had to code it somehow.
Btw, I need to have variable names set as in previous example too, but making string array for it is not a problem :)
Thank you :)
Given T1 the first table (corresponding in your example to matrix1), T2 the second table (matrix1) and soon, you can simply concatenate the components of the table this way:
final_table=[T1 T2 ...]
(the ... means the other components
Given a set of n components, you can write a loop which concatenates them.
A possible implementatioin could be:
% Define the names of the components
t_names{1}='matrix1'
t_names{2}='matrix2'
t_names{3}='matrix3'
t_names{4}='matrix4'
% Get the number of the components
n=length(t_names)
% Initialize the final table
the_table=table
% Loop over the components to add them to the final table
for i=1:n
the_table=[the_table table(zeros([5,5]),'VariableNames', t_names(i))]
end

Extract parts of a big matrix and allocate them in new variables with loop function

I am a total beginner in MATLAB and I hope to find some help here. I have some model prediction results for 80 individuals alltogether in one large matrix. I need to extract the data for each individual from the big matrix, assign them in a new variable/matrix, do some extra calculations and then plot certain information as needed.
To do so, I am trying to write a script with a loop function but in a complicated, or maybe more accurately: in a primitive way!
Simplified Example:
My matrix is called: All_Indi_Data .... its dimension is: 600 rows x 21 columns
%Column 1: grouping variable (e.g., code or ID with values 1,2,3,4,5, etc.);
%Column 2: independent var.;
%Column 3: t;
%Column 4: OBS;
%Column 5: PRED;
i= length (All_Indi_Data);
%% First Indi.
q=1; % indicating the ID of the indi for which I want to extract the data
j=1; % variable added to insure writing start from the first row
for r=1:i
if All_Indi_Data (r,1)==q
Indi_1 (j,1:21) = All_Indi_Data (r,1:21)
j=j+1
end
end
%% Second Indi.
q=q+1
j=1
for r=1:i
if All_Indi_Data (r,1)==q
Indi_2 (j,1:21) = All_Indi_Data (r,1:21)
j=j+1
end
end
.
.
.
1) My first question is: can I allocate these data in new variables (Indi_1, Indi_2, ect.) in a more simple way with or without the loop function?!!! I would appreciate your help a lot.
2) Is there any code or any way to plot these selected parts (according to the grouping variable, e.g. data for Indi_1) from the previously mentioned big matrix without wasting a lot of time and space (wto recopying the core part of the code again and again) for the script, and using the loop function?! in other words, I would like to detect - with loop function & the grouping variable- which values are of interest and then to plot them (e.g. data in colum 3 with data from column 4 for each individual, starting from the first to the last)?!
I hope that I described my problem clearly and hope to hear something from the expert guys :) ...
Thanks a lot in advance ..
Try the following code:
for idx=1:80
pos=find(All_Indi_Data(:,1)==idx);
eval(['Indi_' num2str(idx) '=All_Indi_Data(pos,:);']);
end
What I do is: in each iteration, I search for a value of the ID, indicated in the variable idx. Note that I do not use ´i´ as the name of a variable, because Matlab uses it and ´j´ and the imaginary unit for complex numbers and that could cause problems.
Then, using find I search for the position (or positions) of All_Indi_Data in which I can find the information of that individual. Now I have in the variable ´pos´ the indexes of the rows in which there is information for the individual of interest.
Finally, using eval I extract the data for each individual into a variable. Note that eval combined with a loop makes it easy to create lots of variables. I indicate the rows I want to extract with ´pos´ and, as I want all the columns, I use just ´:´ (you could use ´1:21´ too).
With another similar loop you can plot the information you want. For example:
for idx=1:80
eval(['x=Indi_' num2str(idx) ';']);
% Now I have in X the information for this individual
%Plot the columns of x I want
plot(x(:, 3), x(:,4));
pause; %stay here until a press a key
end