How to dump variables as MATLAB source code? - matlab

Is there a way to dump a MATLAB variable as the source code for the corresponding literal initializer? IOW, I'm looking for some function x such that, for example:
>> A = zeros(2);
>> x(A)
ans =
[0 0; 0 0]
>> class(x(A))
ans =
char
Is there such a function, or an easy way to achieve the same effect? (I realize that literal initializers may not exist for some MATLAB items; for such items the problem is intrinsically unsolvable.)
I am aware of the fact that MATLAB offers many ways to save data to files, but none of the ways I've found produce MATLAB source code, which is what I'm after.

For simple numeric values (and also char arrays), the mat2str function does what you're looking for.
For example, (from the MATLAB documentation):
Consider the matrix
x = [3.85 2.91; 7.74 8.99]
x =
3.8500 2.9100
7.7400 8.9900
The statement
A = mat2str(x)
produces
A =
[3.85 2.91;7.74 8.99]
where A is a string of 21 characters, including the square brackets, spaces, and a semicolon.
Further, passing the string 'class' as the second argument ensure that the answer will be case to the correct numeric type.
See the MATLAB documentation for mat2str, or run
doc mat2str
in MATLAB, for more information.

I know you are looking for a function that can do this, rather than an interactive procedure, but for anyone else who wants to do this manually...
The MATLAB variable editor/viewer has built-in code generation functionality. Open the variable in the editor, click the save icon, and choose MATLAB Script (*.m) file type (default is .mat):
The resulting MatrixCode.m:
% -------------------------------------------------------------------
% Generated by MATLAB on 3-Mar-2014 17:35:49
% MATLAB version: 8.3.0.73043 (R2014a)
% -------------------------------------------------------------------
M = ...
[16 2 3 13;
5 11 10 8;
9 7 6 12;
4 14 15 1];
Maybe someone with Java and reverse engineering skills can figure out how to call this GUI operation from the command line.

As Sam Roberts commented, matlab.io.saveVariablesToScript is now the ultimate method to convert any datatype to a script. This method was introduced in 2014a and works for struct, cell, and all primitive datatypes.
chappjc's method is also correct, but it uses a MATLAB GUI frontend to the saveVariablesToScript method.

Related

How to tell if a function is built-in or self-defined by its name?

I generate a call graph of a complex MATLAB system, and I want to know which functions are built-in and mark them.
Whether a function is built-in or not is most easily seen by the which command. For a given function name it displays the full path to the file that defines the function. For example, on my machine I see
>> which eig
built-in (/Applications/MATLAB_R2018b.app/toolbox/matlab/matfun/eig)
>> which solve
/Users/robert/Documents/MATLAB/cvx/lib/#cvxprob/solve.m % cvxprob method
>> which nosuchfunctionhere
'nosuchfunctionhere' not found.
telling me that eig is a built-in function, and solve a function that is part of the package cvx, and that nosuchfunctionhere is defined nowhere.
MATLAB makes a distinction between "built-in functions" (i.e. no M-file or MEX-file exists, the code is built into the MATLAB executable) and other functions that are part of the MATLAB package but written as M-files or MEX-files.
As Robert showed, the which function will tell you if a function is "built-in" or not, and it will give you a path.
For example, eig is a built-in function (the path given is a file containing the documentation):
>> p = which('eig')
p =
'built-in (/Applications/MATLAB_R2017a.app/toolbox/matlab/matfun/#single/eig)'
imshow is not built-in, but part of the core MATLAB toolbox:
>> p=which('imshow')
p =
'/Applications/MATLAB_R2017a.app/toolbox/matlab/images/imshow.m'
imdilate is a function that comes with the Image Processing Toolbox:
>> p = which('imdilate')
p =
'/Applications/MATLAB_R2017a.app/toolbox/images/images/imdilate.m'
and prettyplot is a function I wrote myself:
>> p = which('prettyplot')
p =
'/Users/cris/matlab/toolbox/cris/prettyplot.m'
To distinguish between these 4 cases, first check to see if the returned string begins with "built-in", then check to see if it contains fullfile(matlabroot,'toolbox','matlab'), indicating it is part of the core MATLAB toolbox, then check to see if it contains fullfile(matlabroot,'toolbox'), indicating it is part of another official toolbox:
function_name = 'eig';
p = which(function_name);
if startsWith(p,'built-in')
disp('built-in')
elseif contains(p,fullfile(matlabroot,'toolbox','matlab'))
disp('part of core MATLAB toolbox')
elseif contains(p,fullfile(matlabroot,'toolbox'))
disp('part of an official MATLAB toolbox')
else
disp('not an official MATLAB function')
end
However, do note that some functions could be overloaded! And if you're examining your source code to check which functions are being used, you need to know the types of the arguments passed. For example:
>> which -all eig
built-in (/Applications/MATLAB_R2017a.app/toolbox/matlab/matfun/#single/eig) % single method
built-in (/Applications/MATLAB_R2017a.app/toolbox/matlab/matfun/#double/eig) % double method
/Users/cris/newdip/target/dip/share/DIPimage/#dip_image/eig.m % dip_image method
Here you can see that there are three eig functions, one is used if its input argument is of type single, one if it is double, and one if it is dip_image (a custom class). Depending on the input, the function eig used is built-in or a 3rd party function.
The sad part is, you won't know which one is used until you run your code. You can manually check what values the input variables have, sometimes it is clear. But this is not always the case, the type might depend on data outside of the function you're examining.
So, the best way to collect a list of functions your program uses is to run the profiler.
Another alternative: the MATLAB Compiler (a separate product) will collect all source M-files your function uses, and package them together into a single distributable package.
Although I think solutions based on which are better, for completeness, we should also consider the function exist for this. From the documentation:
exist name returns the type of name as a number. This list describes the type associated with each value:
0 — name does not exist or cannot be found for other reasons. For example, if name exists in a restricted folder to which MATLAB® does not have access, exist returns 0.
1 — name is a variable in the workspace.
2 — name is a file with extension .m, .mlx, or .mlapp, or name is the name of a file with a non-registered file extension (.mat, .fig, .txt).
3 — name is a MEX-file on your MATLAB search path.
4 — name is a loaded Simulink® model or a Simulink model or library file on your MATLAB search path.
5 — name is a built-in MATLAB function. This does not include classes.
6 — name is a P-code file on your MATLAB search path.
7 — name is a folder.
8 — name is a class. (exist returns 0 for Java classes if you start MATLAB with the -nojvm option.)
So when we try this on the examples shown earlier:
>> exist eig
ans =
5
>> exist solve
ans =
2
>> exist nosuchfunction
ans =
0
Just type open followed by the function name in command window
open function_name
And function_name will be displayed into editor, you might see Mathwork copyright inside it if it's a build in function otherwise it's not
This is how the copyright looks
% Copyright 1993-2016 The MathWorks, Inc.

What is a good substitute for matlabFunction?

I wrote a small program in MATLAB to compute the Shapley value
using the multi-linear extension of a TU game. However, I run
into trouble with the Symbolic Math Toolbox of MATLAB. In
the program I have to integrate a set of functions to get the
Shapley value. However, inside a MATLAB program I cannot use
the int() command
Error using sym/subsindex (line 663) Ivalid indexing or function definition. When defining a function, ensure that the body of the function is a SYM object. When indexing, the input must be numeric, logical or ':'.
Error in ShapleyValueML (line 65)shv(jj)=int(dfy,0,1)
as a consequence I have to use integral() instead. In this case, I
need to transcribe the set of expressions into MATLAB function handle
with matlabFunction(). However, on all Linux machines (MATLAB R2014a) on
which I have access this command does not work (see the discussion below).
As a workaround, the MATLAB program returns the set of functions
into the current workspace, there the Shapley value can be computed
using the int() command.
To make the discussion more concrete, let us consider this small
MATLAB program first.
function [shv,F,dfm]=ShapleyValueML(v)
N=length(v);
[~, n]=log2(N);
S=1:N;
int=0:-1:1-n;
mat=(rem(floor(S(:)*pow2(int)),2)==1);
cmat=(rem(floor(S(:)*pow2(int)),2)==0);
x=sym('x',[1 n]);
mx=1-x;
y = sym('y');
vy=ones(1,n)*y;
F=0;
shv=zeros(1,n);
dfm=cell(1,n);
for ss=1:N
pd1=x(mat(ss,:));
pd2=mx(cmat(ss,:));
pd=prod(pd1)*prod(pd2)*v(ss);
F=pd+F;
end
F=expand(F);
for jj=1:n
dF=diff(F,x(jj));
dfy=subs(dF,x,vy);
%% Does not work!! MATLAB bug???
% mf=matlabFunction(dfy);
% shv(jj)=integral(mf,0,1);
%%
%% The best would be to use:
%%
% shv(jj)=int(dfy,0,1)
%% but it cannot be used inside a program.
dfm{jj}=dfy;
end
end
The commented parts are the parts that do not work inside
the program, but are needed to compute the Shapley value
with that program, which is its purpose. I tested this program
up to 12 players, and I was able to successfully calculate the
Shapley value by a two step procedure. Hence, the above program
specifies correctly the considered problem. To get a better
understanding of this two step procedure and of the functionality
of the above program, let us focus on a three person game.
The values of the coalitions are given by the following data array
>> v = [0,0,90,0,100,120,220];
Notice that coalitions are ordered in accordance with their unique
integer representations. The game is defined, we can now evaluate
the multi-linear extension and the set of partial derivatives with
the above program, but not the Shapley value.
>> [shv,F,dfm]=ShapleyValueML(v);
Integration of the set of partial derivatives runs over the diagonal
of the unit-cube, but then we can set the variables from [x1,x2,x3]
to [y,y,y], and integration runs from 0 to 1.
>> for k=1:3, shv(k)=int(dfm{k},0,1);end;
The solution of the integration is the Shapley value given by:
>> shv
shv =
65 75 80
Checking that this is indeed the Shapley value can be accomplished
with a potential function approach implemented in
>> sh_v=ShapleyValue(v)
sh_v =
65 75 80
that ships with my MATLAB Game Theory Toolbox MatTuGames from
http://www.mathworks.com/matlabcentral/fileexchange/35933-mattugames
Instead of integrating with int() one can also use integral(),
but then the contents like
>> dfm{1}
ans =
- 90*y^2 + 190*y
must be rewritten with matlabFunction() into a function handle. As I
have mentioned above this does not work under Linux
(MATLAB R2013a,R2013b,R2014a). To see this let us try to reproduce
the example
>> syms x y
>> r = sqrt(x^2 + y^2);
from the documentation at the URL:
http://www.mathworks.de/de/help/symbolic/generate-matlab-functions.html?searchHighlight=matlabFunction
This should give
ht =
#(x,y)tanh(sqrt(x.^2+y.^2))
but I get
>> ht = matlabFunction(tanh(r))
Cell contents reference from a non-cell array object.
Error in vectorize (line 15)
c = cells{i};
Error in sym/matlabFunction>mup2mat (line 319)
res = vectorize(res(2:end-1)); % remove quotes
Error in sym/matlabFunction>mup2matcell (line 304)
r = mup2mat(c{1});
Error in sym/matlabFunction (line 123)
body = mup2matcell(funs);
Here comes now my question: Exists there an alternative procedure to
get from
>> dfm{1}
ans =
- 90*y^2 + 190*y
a function handle
>> df=#(y) (- 90.*y.^2 + 190.*y)
df =
#(y)(-90.*y.^2+190.*y)
to integrate it by
>> integral(df,0,1)
ans =
65
Or to put it differently. Is there an alternative method available to
change multiplication * to element-wise multiplication .*, and the
power operation ^ to element-wise power.^?
Of course, any suggestions of improvement for the above MATLAB program
are highly appreciated.
I think I know what the problem is; Towards the beginning of ShapleyValueML function, you have a variable named int which shadows the builtin integration function:
...
int=0:-1:1-n; %# <-- problem!
...
shv(jj)=int(dfy,0,1)
...
That explains the error coming from sym/subsindex, you were using a symbolic object as an index into the numeric array int.
Change the variable name to something else, and the commented code runs fine (the symbolic integration)! Simple as that :)

KroneckerDelta in matlab

This link shows that there is a kronecker delta function in matlab. However:
>> help kroneckerDelta
kroneckerDelta not found
I am using R2011b, so maybe this wasn't programmed into the toolkit yet?
EDIT:: It works in MuPad, just not in matlab...
.
The Kronecker delta returns 1 if j==k...
So you could simplify the expression with:
function d=kronDel(j,k)
d=j==k
end
Luckily, MATLAB represents booleans as (0,1)
I don't see it in my R2012b so perhaps not. Unless you need the symbolic math, you could always write your own. Something as simple as
function d = kronDel(j,k)
if j == k
d = 1;
else
d = 0;
end
You can also do this inline, like
( a == b )
However, using an anonymous function is a nice way to convert a one liner like this into something that is more readable
kronDel = #(j, k) j==k ;
kronDel( 2, 1 )
kronDel( 2, 2 )
Your link to is to the MuPAD function kroneckerDelta -note the URL and the funky typography of the examples. You won't see it in any version of Matlab because it's only available through MuPAD (type mupad in your command window and try in the window that launches). I have no idea when it was added to MuPAD, I know that it's at least in R2012b. You may have it even if the help command returns nothing.
If you have kroneckerDelta in R2011b, you won't be able to run it from the regular command window or Editor in the normal fashion.
evalin(symengine,'kroneckerDelta(1,1)')
or the more flexible
feval(symengine,'kroneckerDelta',1,1)
See more here. However, if you're not working with symbolic math, there's really no reason to use this function that I can see -it's not even vectorized! I'd go with a solution that fully emulates kroneckerDelta's behavior in double precision:
function d=kronDel(m,n)
if nargin == 1
d = double(m==0);
else
d = double(m==n);
end

Out of memory in Matlab - how to do in-place operation on matrix elements?

I am loading a quite large matrix into Matlab. Loading this matrix already pushes Matlab to its limits - but it fits.
Then I do the following and I get an out-of-memory error.
data( :, 2:2:end, :, : ) = - data( :, 2:2:end, :, : );
Is Matlab allocating a new matrix for this operation? I would assume this operation would not need extra memory. How do I force Matlab to be more efficient for this?
Bonus question:
'data = permute(data,[1 2 3 4 5 12 8 7 6 9 10 11]);'
Can matlab do this in-place?
There are a few constraints (further to those from Loren's block cited by John):
Your code must be running inside a function
You must have no other aliases to 'data'
The 'aliases' thing is both important and potentially hard to get right. MATLAB uses copy-on-write, which means that when you call a function, the argument you pass isn't duplicated immediately, but might be copied if you modify it within the function. For example, consider
x = rand(100);
y = myfcn(x);
% with myfcn.m containing:
function out = myfcn(in)
in(1) = 3;
out = in * 2;
end
In that case, the variable x is passed to myfcn. MATLAB has value semantics, so any modifications to the input argument in must not be seen in the calling workspace. So, the first line of myfcn causes the argument in to become a copy of x, rather than simply an alias to it. Consider what happens with try/catch - this can be an in-place killer, because MATLAB has to be able to preserve values if you error out. In the following:
% consider this function
function myouterfcn()
x = rand(100);
x = myfcn(x);
end
% with myfcn.m containing
function arg = myfcn( arg )
arg = -arg;
end
then, that should get in-place optimisation for x in myouterfcn. But the following can't:
% consider this function
function myouterfcn()
x = rand(100);
x = myfcn(x);
end
% with myfcn.m containing
function arg = myfcn( arg )
try
arg = -arg;
catch E
disp( 'Oops.' );
end
end
Hope some of this info helps...
Matlab does support in place operations. Here's a discussion: http://blogs.mathworks.com/loren/2007/03/22/in-place-operations-on-data/. Sorry I can't be more help.
I don't think there's a good way to know what MATLAB is really doing under the sheets. I would recommend that you:
Make sure you clear any variables that aren't in use before trying the operation.
If you're still running out of memory, write and compile a simple mex file to do the operation in place. With a massive array and your specialized requirement, it'd probably be faster than MATLAB's approach too.
Likewise, you could write your own permutation algorithm as a .mex file in C if you require that it be done in-place (i.e. you're running out of memory again).

What is your favourite MATLAB/Octave programming trick? [closed]

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 11 years ago.
Locked. This question and its answers are locked because the question is off-topic but has historical significance. It is not currently accepting new answers or interactions.
I think everyone would agree that the MATLAB language is not pretty, or particularly consistent. But nevermind! We still have to use it to get things done.
What are your favourite tricks for making things easier? Let's have one per answer so people can vote them up if they agree. Also, try to illustrate your answer with an example.
Using the built-in profiler to see where the hot parts of my code are:
profile on
% some lines of code
profile off
profile viewer
or just using the built in tic and toc to get quick timings:
tic;
% some lines of code
toc;
Directly extracting the elements of a matrix that satisfy a particular condition, using logical arrays:
x = rand(1,50) .* 100;
xpart = x( x > 20 & x < 35);
Now xpart contains only those elements of x which lie in the specified range.
Provide quick access to other function documentation by adding a "SEE ALSO" line to the help comments. First, you must include the name of the function in all caps as the first comment line. Do your usual comment header stuff, then put SEE ALSO with a comma separated list of other related functions.
function y = transmog(x)
%TRANSMOG Transmogrifies a matrix X using reverse orthogonal eigenvectors
%
% Usage:
% y = transmog(x)
%
% SEE ALSO
% UNTRANSMOG, TRANSMOG2
When you type "help transmog" at the command line, you will see all the comments in this comment header, with hyperlinks to the comment headers for the other functions listed.
Turn a matrix into a vector using a single colon.
x = rand(4,4);
x(:)
Vectorizing loops. There are lots of ways to do this, and it is entertaining to look for loops in your code and see how they can be vectorized. The performance is astonishingly faster with vector operations!
Anonymous functions, for a few reasons:
to make a quick function for one-off uses, like 3x^2+2x+7. (see listing below) This is useful for functions like quad and fminbnd that take functions as arguments. It's also convenient in scripts (.m files that don't start with a function header) since unlike true functions you can't include subfunctions.
for closures -- although anonymous functions are a little limiting as there doesn't seem to be a way to have assignment within them to mutate state.
.
% quick functions
f = #(x) 3*x.^2 + 2*x + 7;
t = (0:0.001:1);
plot(t,f(t),t,f(2*t),t,f(3*t));
% closures (linfunc below is a function that returns a function,
% and the outer functions arguments are held for the lifetime
% of the returned function.
linfunc = #(m,b) #(x) m*x+b;
C2F = linfunc(9/5, 32);
F2C = linfunc(5/9, -32*5/9);
Matlab's bsxfun, arrayfun, cellfun, and structfun are quite interesting and often save a loop.
M = rand(1000, 1000);
v = rand(1000, 1);
c = bsxfun(#plus, M, v);
This code, for instance, adds column-vector v to each column of matrix M.
Though, in performance critical parts of your application you should benchmark these functions versus the trivial for-loop because often loops are still faster.
LaTeX mode for formulas in graphs: In one of the recent releases (R2006?) you add the additional arguments ,'Interpreter','latex' at the end of a function call and it will use LaTeX rendering. Here's an example:
t=(0:0.001:1);
plot(t,sin(2*pi*[t ; t+0.25]));
xlabel('t');
ylabel('$\hat{y}_k=sin 2\pi (t+{k \over 4})$','Interpreter','latex');
legend({'$\hat{y}_0$','$\hat{y}_1$'},'Interpreter','latex');
Not sure when they added it, but it works with R2006b in the text(), title(), xlabel(), ylabel(), zlabel(), and even legend() functions. Just make sure the syntax you are using is not ambiguous (so with legend() you need to specify the strings as a cell array).
Using xlim and ylim to draw vertical and horizontal lines. Examples:
Draw a horizontal line at y=10:
line(xlim, [10 10])
Draw vertical line at x=5:
line([5 5], ylim)
Here's a quick example:
I find the comma separated list syntax quite useful for building function calls:
% Build a list of args, like so:
args = {'a', 1, 'b', 2};
% Then expand this into arguments:
output = func(args{:})
Here's a bunch of nonobvious functions that are useful from time to time:
mfilename (returns the name of the currently running MATLAB script)
dbstack (gives you access to the names & line numbers of the matlab function stack)
keyboard (stops execution and yields control to the debugging prompt; this is why there's a K in the debug prompt K>>
dbstop error (automatically puts you in debug mode stopped at the line that triggers an error)
I like using function handles for lots of reasons. For one, they are the closest thing I've found in MATLAB to pointers, so you can create reference-like behavior for objects. There are a few neat (and simpler) things you can do with them, too. For example, replacing a switch statement:
switch number,
case 1,
outargs = fcn1(inargs);
case 2,
outargs = fcn2(inargs);
...
end
%
%can be turned into
%
fcnArray = {#fcn1, #fcn2, ...};
outargs = fcnArray{number}(inargs);
I just think little things like that are cool.
Using nargin to set default values for optional arguments and using nargout to set optional output arguments. Quick example
function hLine=myplot(x,y,plotColor,markerType)
% set defaults for optional paramters
if nargin<4, markerType='none'; end
if nargin<3, plotColor='k'; end
hL = plot(x,y,'linetype','-', ...
'color',plotColor, ...
'marker',markerType, ...
'markerFaceColor',plotColor,'markerEdgeColor',plotColor);
% return handle of plot object if required
if nargout>0, hLine = hL; end
Invoking Java code from Matlab
cellfun and arrayfun for automated for loops.
Oh, and reverse an array
v = 1:10;
v_reverse = v(length(v):-1:1);
conditional arguments in the left-hand side of an assignment:
t = (0:0.005:10)';
x = sin(2*pi*t);
x(x>0.5 & t<5) = 0.5;
% This limits all values of x to a maximum of 0.5, where t<5
plot(t,x);
Know your axis properties! There are all sorts of things you can set to tweak the default plotting properties to do what you want:
set(gca,'fontsize',8,'linestyleorder','-','linewidth',0.3,'xtick',1:2:9);
(as an example, sets the fontsize to 8pt, linestyles of all new lines to all be solid and their width 0.3pt, and the xtick points to be [1 3 5 7 9])
Line and figure properties are also useful, but I find myself using axis properties the most.
Be strict with specifying dimensions when using aggregation functions like min, max, mean, diff, sum, any, all,...
For instance the line:
reldiff = diff(a) ./ a(1:end-1)
might work well to compute relative differences of elements in a vector, however in case the vector degenerates to just one element the computation fails:
>> a=rand(1,7);
>> diff(a) ./ a(1:end-1)
ans =
-0.5822 -0.9935 224.2015 0.2708 -0.3328 0.0458
>> a=1;
>> diff(a) ./ a(1:end-1)
??? Error using ==> rdivide
Matrix dimensions must agree.
If you specify the correct dimensions to your functions, this line returns an empty 1-by-0 matrix, which is correct:
>> diff(a, [], 2) ./ a(1, 1:end-1)
ans =
Empty matrix: 1-by-0
>>
The same goes for a min-function which usually computes minimums over columns on a matrix, until the matrix only consists of one row. - Then it will return the minimum over the row unless the dimension parameter states otherwise, and probably break your application.
I can almost guarantee you that consequently setting the dimensions of these aggregation functions will save you quite some debugging work later on.
At least that would have been the case for me. :)
The colon operator for the manipulation of arrays.
#ScottieT812, mentions one: flattening an array, but there's all the other variants of selecting bits of an array:
x=rand(10,10);
flattened=x(:);
Acolumn=x(:,10);
Arow=x(10,:);
y=rand(100);
firstSix=y(1:6);
lastSix=y(end-5:end);
alternate=y(1:2:end);
In order to be able to quickly test a function, I use nargin like so:
function result = multiply(a, b)
if nargin == 0 %no inputs provided, run using defaults for a and b
clc;
disp('RUNNING IN TEST MODE')
a = 1;
b = 2;
end
result = a*b;
Later on, I add a unit test script to test the function for different input conditions.
Using ismember() to merge data organized by text identfiers. Useful when you are analyzing differing periods when entries, in my case company symbols, come and go.
%Merge B into A based on Text identifiers
UniverseA = {'A','B','C','D'};
UniverseB = {'A','C','D'};
DataA = [20 40 60 80];
DataB = [30 50 70];
MergeData = NaN(length(UniverseA),2);
MergeData(:,1) = DataA;
[tf, loc] = ismember(UniverseA, UniverseB);
MergeData(tf,2) = DataB(loc(tf));
MergeData =
20 30
40 NaN
60 50
80 70
Asking 'why' (useful for jarring me out of a Matlab runtime-fail debugging trance at 3am...)
Executing a Simulink model directly from a script (rather than interactively) using the sim command. You can do things like take parameters from a workspace variable, and repeatedly run sim in a loop to simulate something while varying the parameter to see how the behavior changes, and graph the results with whatever graphical commands you like. Much easier than trying to do this interactively, and it gives you much more flexibility than the Simulink "oscilloscope" blocks when visualizing the results. (although you can't use it to see what's going on in realtime while the simulation is running)
A really important thing to know is the DstWorkspace and SrcWorkspace options of the simset command. These control where the "To Workspace" and "From Workspace" blocks get and put their results. Dstworkspace defaults to the current workspace (e.g. if you call sim from inside a function the "To Workspace" blocks will show up as variables accessible from within that same function) but SrcWorkspace defaults to the base workspace and if you want to encapsulate your call to sim you'll want to set SrcWorkspace to current so there is a clean interface to providing/retrieving simulation input parameters and outputs. For example:
function Y=run_my_sim(t,input1,params)
% runs "my_sim.mdl"
% with a From Workspace block referencing I1 as an input signal
% and parameters referenced as fields of the "params" structure
% and output retrieved from a To Workspace block with name O1.
opt = simset('SrcWorkspace','current','DstWorkspace','current');
I1 = struct('time',t,'signals',struct('values',input1,'dimensions',1));
Y = struct;
Y.t = sim('my_sim',t,opt);
Y.output1 = O1.signals.values;
Contour plots with [c,h]=contour and clabel(c,h,'fontsize',fontsize). I usually use the fontsize parameter to reduce the font size so the numbers don't run into each other. This is great for viewing the value of 2-D functions without having to muck around with 3D graphs.
Vectorization:
function iNeedle = findClosest(hay,needle)
%FINDCLOSEST find the indicies of the closest elements in an array.
% Given two vectors [A,B], findClosest will find the indicies of the values
% in vector A closest to the values in vector B.
[hay iOrgHay] = sort(hay(:)'); %#ok must have row vector
% Use histogram to find indices of elements in hay closest to elements in
% needle. The bins are centered on values in hay, with the edges on the
% midpoint between elements.
[iNeedle iNeedle] = histc(needle,[-inf hay+[diff(hay)/2 inf]]); %#ok
% Reversing the sorting.
iNeedle = iOrgHay(iNeedle);
Using persistent (static) variables when running an online algorithm. It may speed up the code in areas like Bayesian machine learning where the model is trained iteratively for the new samples. For example, for computing the independent loglikelihoods, I compute the loglikelihood initially from scratch and update it by summing this previously computed loglikelihood and the additional loglikelihood.
Instead of giving a more specialized machine learning problem, let me give a general online averaging code which I took from here:
function av = runningAverage(x)
% The number of values entered so far - declared persistent.
persistent n;
% The sum of values entered so far - declared persistent.
persistent sumOfX;
if x == 'reset' % Initialise the persistent variables.
n = 0;
sumOfX = 0;
av = 0;
else % A data value has been added.
n = n + 1;
sumOfX = sumOfX + x;
av = sumOfX / n; % Update the running average.
end
Then, the calls will give the following results
runningAverage('reset')
ans = 0
>> runningAverage(5)
ans = 5
>> runningAverage(10)
ans = 7.5000
>> runningAverage(3)
ans = 6
>> runningAverage('reset')
ans = 0
>> runningAverage(8)
ans = 8
I'm surprised that while people mentioned the logical array approach of indexing an array, nobody mentioned the find command.
e.g. if x is an NxMxO array
x(x>20) works by generating an NxMxO logical array and using it to index x (which can be bad if you have large arrays and are looking for a small subset
x(find(x>20)) works by generating list (i.e. 1xwhatever) of indices of x that satisfy x>20, and indexing x by it. "find" should be used more than it is, in my experience.
More what I would call 'tricks'
you can grow/append to arrays and cell arrays if you don't know the size you'll need, by using end + 1 (works with higher dimensions too, so long as the dimensions of the slice match -- so you'll have to initialize x to something other than [] in that case). Not good for numerics but for small dynamic lists of things (or cell arrays), e.g. parsing files.
e.g.
>> x=[1,2,3]
x = 1 2 3
>> x(end+1)=4
x = 1 2 3 4
Another think many people don't know is that for works on any dim 1 array, so to continue the example
>> for n = x;disp(n);end
1
2
3
4
Which means if all you need is the members of x you don't need to index them.
This also works with cell arrays but it's a bit annoying because as it walks them the element is still wrapped in a cell:
>> for el = {1,2,3,4};disp(el);end
[1]
[2]
[3]
[4]
So to get at the elements you have to subscript them
>> for el = {1,2,3,4};disp(el{1});end
1
2
3
4
I can't remember if there is a nicer way around that.
-You can make a Matlab shortcut to an initialization file called startup.m. Here, I define formatting, precision of the output, and plot parameters for my Matlab session (for example, I use a larger plot axis/font size so that .fig's can be seen plainly when I put them in presentations.) See a good blog post from one of the developers about it http://blogs.mathworks.com/loren/2009/03/03/whats-in-your-startupm/ .
-You can load an entire numerical ascii file using the "load" function. This isn't particularly fast, but gets the job done quickly for prototyping (shouldn't that be the Matlab motto?)
-As mentioned, the colon operator and vectorization are lifesavers. Screw loops.
x=repmat([1:10],3,1); % say, x is an example array of data
l=x>=3; % l is a logical vector (1s/0s) to highlight those elements in the array that would meet a certain condition.
N=sum(sum(l));% N is the number of elements that meet that given condition.
cheers -- happy scripting!