integrating simulink into a matlab script - matlab

I have the following problem. I want to integrate a simulink model into a matlab script, to do different things in a loop with the simulink part of the program.
The program below actually does what I was hoping for when I defined the parameters I used into the simulink model in the workspace. But this solution does not satisfy me. I want to pass the parameters as the second value of the sim function. Unfortunately I can't get my head around this. I literally copied the part to create a structure from the matlab site where the following code sample has been given.
myStruct = Simulink.Parameter;
myStruct.Value = struct('number',1,'units',24);
myStruct.CoderInfo.StorageClass = 'ExportedGlobal';
Unfortunately I get the following error Input argument "m_startSpeed" is undefined. because in my script the parameter m_startSpeed is a value which I input when running the script.
function [optBreakPoint] = computeBreakPoint(m_startSpeed, m_endSpeed, m_length)
myStruct = Simulink.Parameter;
myStruct.Value = struct('m' , 1500, 'R' , 0.25, 'mi' , 1, 'f' , 0.1, 'F' , 50000,'BreakForce' , -10, 'startSpeed' , m_startSpeed, 'breakPoint' , m_length);
myStruct.CoderInfo.StorageClass = 'ExportedGlobal';
endSpeed = m_endSpeed;
while(1)
[T, X, Y] = sim('car', myStruct);
optBreakPoint = breakPoint;
break;
end
plot(T, X);
end
How should I solve this problem?

The input structure (i.e. the second input to the sim function), contains information about how to simulate the model (i.e. information from the Model Configuration dialog, or Configuration Set), not parameters of the blocks in the model.
Look at either
>> doc sim
or http://www.mathworks.com/help/simulink/slref/sim.html
for an example of what that structure should look like.
Block parameters are obtained from a workspace - by default the Base Workspace, but you can specify this by changing the models 'SrcWorkspace" parameter.
This property is also discussed on the above documentation pages.

Related

Directional Derivatives of a Matrix

I have 40 structures in my Workspace. I Need to write a script to calculate the directional derivatives of all the elements. Here is the code :
[dx,dy] = gradient(Structure_element_1.value);
dxlb = min(min(dx));
dxub = max(max(dx));
dylb = min(min(dy));
dyub = max(max(dy));
[ddx,ddy] = gradient(gradient(Structure_element_1.value));
ddxlb = min(min(ddx));
ddxub = max(max(ddx));
ddylb = min(min(ddy));
ddyub = max(max(ddy));
This is the code for one element. I Need to find out the same for all the 40 elements and then use it later. Can anyone help with this.
To answer your literal question, you should store the variables in a structure array or at least a cell array. If all of your structures have the same fields, you can access all of them by indexing a single array variable, say Structure_element:
for i = 1:numel(Structure_element)
field = Structure_element(i).value
% compute gradients of field
end
Now to address the issue of the actual gradient computation. The gradient function computes an approximation for , where is your matrix of data. Normally, a MATLAB function is aware of how many output arguments are requested. When you call gradient(gradient(F)), the outer gradient is called on the first output of the inner gradient call. This means that you are currently getting an approximation for .
I suspect that you are really trying to get . To do this, you have to get both outputs from the inner call to gradient, pass them separately to the
outer call, and choose the correct output:
[dx,dy] = gradient(F);
[ddx, ~] = gradient(dx);
[~, ddy] = gradient(dy);
Note the separated calls. The tilde was introduced as a way to ignore function arguments in MATLAB Release 2009b. If you have an older version, just use an actual variable named junk or something like that.

Loopin through all the structures in a workspace [duplicate]

I have 40 structures in my Workspace. I Need to write a script to calculate the directional derivatives of all the elements. Here is the code :
[dx,dy] = gradient(Structure_element_1.value);
dxlb = min(min(dx));
dxub = max(max(dx));
dylb = min(min(dy));
dyub = max(max(dy));
[ddx,ddy] = gradient(gradient(Structure_element_1.value));
ddxlb = min(min(ddx));
ddxub = max(max(ddx));
ddylb = min(min(ddy));
ddyub = max(max(ddy));
This is the code for one element. I Need to find out the same for all the 40 elements and then use it later. Can anyone help with this.
To answer your literal question, you should store the variables in a structure array or at least a cell array. If all of your structures have the same fields, you can access all of them by indexing a single array variable, say Structure_element:
for i = 1:numel(Structure_element)
field = Structure_element(i).value
% compute gradients of field
end
Now to address the issue of the actual gradient computation. The gradient function computes an approximation for , where is your matrix of data. Normally, a MATLAB function is aware of how many output arguments are requested. When you call gradient(gradient(F)), the outer gradient is called on the first output of the inner gradient call. This means that you are currently getting an approximation for .
I suspect that you are really trying to get . To do this, you have to get both outputs from the inner call to gradient, pass them separately to the
outer call, and choose the correct output:
[dx,dy] = gradient(F);
[ddx, ~] = gradient(dx);
[~, ddy] = gradient(dy);
Note the separated calls. The tilde was introduced as a way to ignore function arguments in MATLAB Release 2009b. If you have an older version, just use an actual variable named junk or something like that.

How to pass matrix by reference or get the return value of function

I have a 1 x 118 matrix called current_load that I need to update periodically. This matrix resides in the main workspace of Matlab (as shown in the code bellow).
current_loads = zeros(1, 118);
for col=1:118
current_loads(1,col)=10; %// Initially give all nodes a current load of 10
end
recursive_remove(current_loads); %calling function
This matrix will be passed to a function call recursive_remove (shown bellow).
function updater = recursive_remove( current_load )
current_load(1,3) = 2.6; %// This update can't be seen from main ??
%this function will be called recursively later
end
But whatever updates I do to this current_load matrix from the function, it will not get updated since I don't know how to pass it by reference.
I am new to Matlab. I would greatly appreciate if you can show with an example how to handle this
EDIT: "How to pass parameter by reference in Matlab"
You can solve your problem passing your arguments by reference
You need a handle class
Handle Classes
Objects that share references with other objects
this is, create a file called HandleObject.m with this code:
classdef HandleObject < handle
properties
Object=[];
end
methods
function obj=HandleObject(receivedObject)
obj.Object=receivedObject;
end
end
end
Then you can do something like this
Object = HandleObject(your matrix)
yourFunction(Object)
And inside your function
function yourFunction(myObject)
myObject.object = new matrix;
end
With that you can achieve some kind of pass by reference and avoid getting a lot of copies trought your program.
The output of the function recursive_remove hasn't been defined and so you ouput can't be used anywhere else.
In matlab you define outputs of functions with square brackets as below.
function [ output1, output2 ] = recursive_remove( input1, input2 )
The outputs can now be passed into other MATLAB docs - functions.
When calling the function in the example above in a different function as you did in your first bit of code you would call it as shown:
current_loads = zeros(1, 118);
for col=1:118
current_loads(1,col)=10; %Initially give all nodes a current load of 10
end
[ output1, output2 ] = recursive_remove( input1, input2 ); %calling function
With this syntax you can take output1 and call it in the input of your next function recursive_remover

passing data to simulink file from workspace in matlab

I build a model using simulink file , and i used 3 from workspace Block , these Blocks must have a digital data , my question is , how to pass data to the simulink file , from workspace ? i have do the examples that mathwork website give , but the problem is (again) how we pass it to simulink file :
`
t = [0:0.2:10];
x = sin(t);
y = 10*sin(t);
wave.time = t;
wave.signals.values = [x,y];
wave.signals.dimensions =2;`
if you need x,y,t in simulink then you may use:
1.In the MATLAB Command Window, enter:
t = [0:0.2:10]';
x = sin(t);
y = 10*sin(t);
The time vector must be a column vector.
2.Add a 'From Workspace' block to your model.
3.Double-click the block to open the block parameters dialog. In the Data field, enter the array [t,x,y]

how to apply iddata into calculation?

I am trying to figure out how to combine the input and output data into the ARX model and then apply it into the BIC (Bayesian Information Criterion) formula. Below is the code that I am currently working on:
for i=1:30; %% Set Model Order
data=iddata(output,input,1);
model = arx(data,[8 9 i]);
yp = predict(model,data);
ye = regress(data,yp{1,1}(1:4018,1));
M(i) = var(yp);
BIC(i)=(N+i*(log(N)-1))/(N-i)*log(M(i));
end
But it does not work. It keeps on giving me an error that's something like below:
"The syntax "Data{...}" is not supported. Use the "getexp" command to
extract individual experiments from an IDDATA object."
I did not understand what does that mean. Can someone explain it to me and where do I do wrong on my piece of code?
Update:
I tried to do it something like below, so far, there is no error. But then the graph for this BIC will be always straight line. Is something wrong with my regression part? how should I do for the regression?
N=length(rainfall_model);
for i=1:20; % Set Model Order
data=iddata(rainfall_model,tmax_model,1);
%d1 = getexp(data,1);
model = arx(data,[50 9 i]);
yp=predict(model,data);
y = yp.y ;
d1 = data.y ;
ye = (d1).^2 - (y).^2;
M(i)= mse(ye);
BIC(i)=(N+i*(log(N)-1))/(N-i)*log(M(i));
end
In your code example, yp returned from the 'predict' command is an iddata object and the cell notation '{...}' cannot be used with it. If you want to do regression, you have to extract the input (yp.u) or the output (yp.y) data from it.
Also, the command 'regress' does not work with idddata objects, since it is not a system identification toolbox function. Again you have to extract input or output data from the 'data' and 'yp' variables before calling it.
Update: To see what's in the iddata objects (data and yp), do
get(data)
get(yp)
You would see that you can extract the output data in two equivalent ways:
yp.y
yp.OutputData
Similarly, for the input data.