Using matlab function in simulink error - matlab

I'm new to Simulink but I need to use a matlab function.
I created a "MATLAB Function1" block with one input (a time signal that comes from another block) and one output (three signals wrapped in a matrix shown in a Scope block).
Here the code inside the matlab function block:
function outputSignal = myFunction(input_signal)
coder.extrinsic('lsim');
time = [1:1:length(input_signal)];
k_dia = [19.5 13 9.9];
k_dia = k_dia*10^-3;
outputSignal = zeros(length(time), length(k_dia));
for j = 1:length(k_dia)
A = [-k_dia(j) 0; k_dia(j) -k_dia(j)];
B = [1 0]';
C = [1 1];
D = 0;
sistem = feval('ss', A, B, C, D);
outputSignal(:,j) = lsim(sistem, input_signal, time);
end
end
Previously I had problems using the functions "ss" and "lsim" because of code generation problems, but I should have solved them using feval and coder.extrinsic. Now I have the following error:
When simulating the response to a specific input signal, the input data U must be a matrix
of numeric values with at least two rows (samples) and without any NaN or Inf.
and I can't understand if the problem is still with these functions or if I made a mistake in how to use matlab functions in simulink.
EDIT: I understood that the problem was because lsim needs an input_signal of at least length 2, while my system is giving an input to the function of one single value at every time step. So if the time is of 10 steps and the serie of values generated from the previous block is [1 2 3 4 5 6 7 8 9 10], I would like to have as input to my function:
[1] at step 1,
[1 2] at step 2,
[1 2 3] at step 3,
....
[1 2 3 4 5 6 7 8 9 10] at step 10.
Of course since lsim doesn't work with one value, at step 1 I could use a default output value.
I think I need a block that memorizes what happens in the time steps
before, something like the Scope block but with an output.

Since your systems are time invariant you can create three separate State space systems each with different parameter valued matrices and supply a vector of three components as input signals which I have left empty because I don't know where you would like to send from.

Related

How do I print values from a loop and see how they're being used in a function in matlab?

I have a main matlab file. The main file accesses several functions. There is a loop in one of the functions and I want to see each part of the loop even though those variables aren't being stored. I am new to matlab and I don't understand whether the inputs are matrices, vectors or elements. How do I do that?
matrix1 = [1 2 3 4; 4 5 6 5; 7 8 1 0;3 5 7 6]
list1 = [1;3;5;4]
i=0
for a=1:1:4 %no. of rows
for b=2:1:4 % no. of col
x=matrix1(a,b);
s=1
n3=list1(a,1); %vector
mult=(s.*sin(i)./n3);
end
end
This is a part of a function that the main file calls. x, n3, mult are all being used but none of them are being saved. How can I see what these values are?

How to make a function that picks according to a changing distribution, without passing over and over?

This is not a question about MatLab, but it is a question about how to achieve something that would be easy in object-oriented programming when you're using a less sophisticated language.
I'm a mathematician who is writing some MatLab code to test an algorithm in linear algebra (I won't burden you with the details). The beginning of the program is to generate a random 500 by 50 matrix of floats (call it A). In the course of running my program, I will want to pick random rows of A, not uniformly at random, but rather according to a distribution where the likelihood of row i being picked is different, depending on the specific matrix that has been generated.
I want to write a function called "pickRandomRow" that I can call over and over when I need it. It will use the same probability distribution on the rows throughout each individual run of the program, but that distribution will change between runs of the program (because the random matrix will be different).
If I were using a more object-oriented language than MatLab, I would make a class called "rowPicker" which could be initialized with the information about the specific random matrix I'm using on this run. But here, I'm not sure how to make a function in MatLab that can know the information it needs to know about the random matrix A once and for all, without passing A to the function over and over (expensively), when it's not changing.
Possible options
Make pickRandomRow a script instead of a function, so it can see the workspace. Then I wouldn't be able to give pickRandomRow any arguments, but so far I don't see why I'd need to.
Start messing areound with classes in MatLab.
As far as I remember, MATLAB supports closures.
Closures are something like an object with bunch of private member variables and a single method.
So, you could do something like this:
function rowPicker = createRowPicker(matrix, param)
expensivePreparations = ... (use 'matrix' and 'param' here) ...
function pickedRow = someComplicatedSamplingFunction
... (use 'matrix', 'expensivePreparations' and 'param' here) ...
end
rowPicker = #someComplicatedSamplingFunction
end
and then you could generate a bunch of differently parameterized rowPickers in a loop, something like this:
for p = [p1, p2, p3]
matrix = generateMatrix()
picker = createRowPicker(matrix, p)
... (run expensive simulation, reuse 'picker')
end
In this way, the expensive intermediate result expensivePreparations will be saved inside the closure, and you won't have to recompute it in each step of your expensive simulation.
Warning: all of the above it matlab-esque pseudocode and not tested.
In order to achieve this task you could use the randsample function and, to be exact, its four arguments overload:
y = randsample(n,k,true,w) or y = randsample(population,k,true,w)
returns a weighted sample taken with replacement, using a vector of
positive weights w, whose length is n. The probability that the
integer i is selected for an entry of y is w(i)/sum(w). Usually, w is
a vector of probabilities. randsample does not support weighted
sampling without replacement.
An example:
M = [
1 1 1;
2 2 2;
3 3 3;
4 4 4;
5 5 5
];
idx = randsample(1:5,1,true,[0.2 0.2 0.1 0.1 0.4]);
row = M(idx,:);
If you have to pick more than one row every time you run the script and the fact that the weighted sampling without replacement is not supported, you could use the datasample function instead:
M = [
1 1 1;
2 2 2;
3 3 3;
4 4 4;
5 5 5
];
idx = datasample(1:5,2,'Replace',false,'Weights',[0.2 0.2 0.1 0.1 0.4]);
rows = M(idx,:);
For what concerns the choice between a class and a script, I honestly think you are overcomplicating your problem a little bit. An OOP class, in this case, looks like an overkill to me. If you want to use a script (actually, a function) without passing any argument to it, you could use the persistent modifier on an internally defined matrix and a variable representing its row probabilities. Let's assume that the first solution I proposed is the one that fits your need, then:
a = pickRandomRow();
b = pickRandomRow();
c = pickRandomRow();
function row = pickRandomRow()
persistent M;
persistent W;
if (isempty(M))
M = [
1 1 1;
2 2 2;
3 3 3;
4 4 4;
5 5 5
];
W = [
0.2
0.2
0.1
0.1
0.4
];
end
idx = randsample(1:size(M,1),1,true,W);
row = M(idx,:);
end
If you want to provide different weights according to previous computations, you could change the above code as follows:
w1 = WeightsFromDistributionX();
w2 = WeightsFromDistributionY();
a = pickRandomRow(w1);
b = pickRandomRow(w2);
c = pickRandomRow(w2);
function row = pickRandomRow(W)
persistent M;
if (isempty(M))
M = [
1 1 1;
2 2 2;
3 3 3;
4 4 4;
5 5 5
];
end
M_size = size(M,1);
W_size = numel(W);
if (M_size ~= W_size)
error('The weights vector must have the same length of matrix rows.');
end
idx = randsample(1:M_size,1,true,W);
row = M(idx,:);
end
If creating a class is too much work (you first class will be, it's quite different than in other languages), you have several alternatives.
A single distribution at the time
You can accomplish this using persistent variables in a function. The function will become some sort of unique object.
function out = func(arg)
persistent M; % matrix to pick rows from
persistent S; % status
if nargin == 1
M = randn(...);
S = ...;
else
% use M, S
return ...;
end
You call this using func('init') the first time, and data = func() after that.
Multiple different distributions
You can rewrite the above but returning a cell array with the internal data when called with 'init'. Other times you pass that cell array as input:
function out = func(arg)
if ischar(arg)
M = randn(...);
S = ...;
return {M,S};
else % iscell(arg)
% use M=arg{1}, S=arg{2}
return ...;
end
Of course, instead of a cell array it could be a struct. I see this as a "poor man's object". There's no control over the user modifying the status of the object, but if you're your own user, this is probably not a big deal.

Matlab Algorithm and Output File

I am working on a homework problem for a Matlab course. This is the problem :
Construct an m-file function mom that follows the flow diagram for the algorithm shown on slide 5. Notice that the output is given not to the screen but into a file called output.txt and also has a given structure (see slide 6).
In your script call this function with the following inputs (place these inputs into your script file as shown and then call the mom function as mom(x,r,name,filename);)
x = [1 3 2 5 3 3 7 4 3 4 5 8 2];
r = 4;
name = ‘Your name here’;
filename = ‘output.txt’;
mom(x,r,name,filename);
I am also attaching the algorithm flowchart and the output file structure.
My main script code looks like this:
x=[1 3 2 5 3 3 7 4 3 4 5 8 2 ];
r=4;
name= 'Matthew Haskell';
filename='output.txt';
[xbar,sn]=mom_Haskell(x,r,name,filename);
out= fopen('Output.txt','w');
fprintf(out,'\t\t\tCalculation by: %s\n\n',name);
fprintf(out,'The average is %.4f while the %.2f th moment is %.2f', xbar,r,sn);
My function file code looks like this:
function[xbar,sn] = mom_Haskell( x,r,name,filename )
n=length(x);
xbar=mean(x);
num=0;
den=0;
for k:1:1:n
num=num+(x(k)-xbar)^r;
den=den+(x(k)-xbar)^2;
end
sn=(num/n) / (den/n)^(r/2);
end
So far, I have encountered a problem with the function file and being able to output it from the main file. I believe there is a problem with the variable sn, I am not sure how to fix this.
The problem is in the syntax with the for-loop:
k=1:1:n
instead of
k:1:1:n
For the sake of completeness, it is worth knowing that if the step is 1, you can easily omit such step. So the instruction
k=1:1:n
is the same as
k=1:n
Also, according to the given specifications (second slide) the second fprintf() should be corrected as well. Such specifications says that:
xbar must have 4 decimal places, and %.4f is correct
r must be an integer, so %.4f is not correct. You need %d for integers
sn should be floating point with 6 decimal places, but %.2f will show a floating point with just 2 decimal place. Use %.6f instead.

Matlab - Spectral Method (Matrix Syntax)

I'm reading Trefethen's Spectral Methods in Matlab.
When creating the differentiation matrices,
column= [ anything ]
D=toeplitz(column,column([1 N:-1:2]))
Can someone please explain what exactly is happening inside the [ ... ] in the line above.
I understand you are shifting the columns but I don't understand that syntax.
Are you referring to the 2nd line with: [1 N:-1:2] ?
If so, lets look at an example, let N = 4 and just calculate:
N = 4; [1 N:-1:2]
ans =
1 4 3 2
Which creates a vector with the first element being 1. Next the values start at 4 and decrement by 1 until you reach 2.
This is a basic Matlab syntax, [a:b:c], creates a vector with starting value a, increasing (or decreasing if -b) to c in steps of b.
Is this what you are referring to?

Can't output multidimensional matrix in Matlab function in Simulink

For example I have function that creates matrix 2x2 : [1 2; 3 4]
I have such simple function:
function[result] = Rho(x)
// I've tried and so:
result = [1 2; 3 4];
// And so:
result(1,1) = 1;
result(1,2) = 2;
result(2,1) = 3;
result(2,2) = 4;
In Matlab window i see right result:
>> Rho(1)
ans =
1 2
3 4
But in Simulink I always get [1;2;3;4]. Where is my mistake?
P.S. I forgot to remove argument x of function, because in real function I make matrix depending on argument x. But it doesn't play role in our example
The problem you are having is likely due to the parameter settings for your MATLAB Function block (now called an Interpreted MATLAB Function block in newer versions). Take a look at the Parameters Dialog Box for that block:
Note that you will want to set the Output dimensions to 2 and uncheck the Collapse 2-D results to 1-D check box. If this is left checked, then your 2-by-2 matrix will be turned into a 1-D array by extracting values along each column from left to right, which ends up being [1 3 2 4] in your example.
Once you apply the above changes, then all you should have to do is resize your Display block so that it shows your 2 rows and 2 columns.