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?
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.
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.
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?
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.