add outputs to anonymous function in loop - matlab

I have a system of equations contained in an anonymous equation. Instead of defining all of the equations when i create the function, I would like to add one in each step of a for loop. Is this possible?

I suppose if you have a linear set of equations, you can construct it using a matrix, then you're free to include new operations by adding rows and columns to the matrix and/or its accompanying right hand side vector.
If you're really trying to use anonymous functions, say if your functions are non-linear, then I would suggest you to look into arrays of anonymous functions. For example,
A = cell(3,1); % Preallocate a 3 by 1 cell array
for ii = 1:3
A{ii} = #(x) x^2+ii; % Fill up the array with anonymous functions
end
Now if you check what's contained in cell array 'A',
A = #(x)x^2+ii
#(x)x^2+ii
#(x)x^2+ii
Don't worry about the display of 'ii' instead of the actual number of the loop variable as we gave it earlier, MATLAB has internally replaced them with those values. Changing 'ii' in the current function scope will also not affect their values in 'A' either. Thus,
A{1}(2) = 5, A{2}(2) = 6 and A{3}(2) = 7
If you're not familiar with cell arrays, you can read up on its usage here.
Again, what you're trying to achieve might be different. I hope this works for you.

Related

Looping over list of variables in matlab

I have a list of variables (different sized numeric matrices) named Reach1 to Reach7
I want to plot them all as subplots in one figure.
Need a way to loop over each variable as below:
names = {'Reach1' 'Reach2' 'Reach3' 'Reach4' 'Reach5' 'Reach6' 'Reach7'};
for index = 1:7
subplot(3,3,index)
plot(names(index)(:,1),names(index)(:,2));hold on;
plot(names(index)(:,5),names(index)(:,6));
plot(names(index)(:,9),names(index)(:,10));hold off;
end
Is there a better way to do this in matlab?
You cannot access names(index) because it is cell array and those are accessed by names{index}.
If you want to access variable Reach1(1,3) by calling names{1}(1,3), you will fail because Matlab will (try to) return a as an element of char array. This approach can be achieved by eval but do NOT do that! It has many drawbacks and no benefit.
You can simplify your code using Matlabs features, that are not obvious but bloody useful.
Suppose we have all matrices in one cell array Reaches={<Reach1>;<Reach2>;...}:
Reaches={rand(4,12);rand(6,12);rand(8,12);rand(2,12);rand(9,12)}; %declare dummy variables
counter=0;
for Reach=Reaches
counter=counter+1;
subplot(3,3,counter);
plot(Reach(:,[1,5,9]),Reach(:,2,6,10));
end
This code benefits from:
for is able to loop over array elements.
plot is able to process arrays.
(Advanced) Array indexing.
In this example appropriate element names{ii} is passed to Reach variable, counter counter is advanced and plot is supported by matrices containig columns 1, 5 and 9 and 2, 6 and 10 as x and y values, respectively.

Splitting non-continuous sized matrix in vectors

I'm writing an piece of software within Matlab. Here, the user can define a dimension say 3.
This dimension is subsequently the number of iterations of a for loop. Within this loop, I construct a matrix to store the results which are generated during every iteration. So, the data of every iteration is stored in a row of a matrix.
Therefore, the size of the matrix depends on the size of the loop and thus the user input.
Now, I want to separate each row of this matrix (cl_matrix) and create separate vectors for every row automatically. How would one go on about? I am stuck here...
So far I have:
Angle = [1 7 15];
for i = 1:length(Angle)
%% do some calculations here %%
cl_matrix(i,:) = A.data(:,7);
end
I want to automate this based on the length of Angle:
length(Angle)
cl_1 = cl_matrix(1,:);
cl_7 = cl_matrix(2,:);
cl_15= cl_matrix(3,:);
Thanks!
The only way to dynamically generate in the workspace variables variables whos name is built by aggregating string and numeric values (as in your question) is to use the eval function.
Nevertheless, eval is only one character far from "evil", seductive as it is and dangerous as it is as well.
A possible compromise between directly working with the cl_matrix and generating the set of array cl_1, cl_7 and cl_15 could be creating a structure whos fields are dynamically generated.
You can actually generate a struct whos field are cl_1, cl_7 and cl_15 this way:
cl_struct.(['cl_' num2str(Angle(i))])=cl_matrix(i,:)
(you might notice the field name, e. g. cl_1, is generated in the same way you could generate it by using eval).
Using this approach offers a remarkable advantage with respect to the generation of the arrays by using eval: you can access to the field od the struct (that is to their content) even not knowing their names.
In the following you can find a modified version of your script in which this approach has been implemented.
The script generate two structs:
the first one, cl_struct_same_length is used to store the rows of the cl_matrix
thesecond one, cl_struct_different_length is used to store arrays of different length
In the script there are examples on how to access to the fileds (that is the arrays) to perform some calculations (in the example, to evaluate the mean of each of then).
You can access to the struct fields by using the functions:
getfield to get the values stored in it
fieldnames to get the names (dynamically generated) of the field
Updated script
Angle = [1 7 15];
for i = 1:length(Angle)
% do some calculations here %%
% % % cl_matrix(i,:) = A.data(:,7);
% Populate cl_matrix
cl_matrix(i,:) = randi(10,1,10)*Angle(i);
% Create a struct with dinamic filed names
cl_struct_same_length.(['cl_' num2str(Angle(i))])=cl_matrix(i,:)
cl_struct_different_length.(['cl_' num2str(Angle(i))])=randi(10,1,Angle(i))
end
% Use "fieldnames" to get the names of the dinamically generated struct's field
cl_fields=fieldnames(cl_struct_same_length)
% Loop through the struct's fileds to perform some calculation on the
% stored values
for i=1:length(cl_fields)
cl_means(i)=mean(cl_struct_same_length.(cl_fields{i}))
end
% Assign the value stored in a struct's field to a variable
row_2_of_cl_matrix=getfield(cl_struct_different_length,(['cl_' num2str(Angle(2))]))
Hope this helps.

MATLAB cell array of function handles - How does it work?

I am trying to understand the following commands of a MATLAB script :
global operatorObj
calcEVR_handles = operatorObj.calcEVR_handles;
m = operatorObj.nInputs
E = zeros(m,1);
V = zeros(m,1);
R = zeros(m,m);
for i=1:m
[E(i), V(i), R(i,i)] = calcEVR_handles{i}(t,x);
end
What can calcEVR_handles be, if t is a float and x is a vector?
calcEVR_handles (to me) looks like a cell array where each element is a handle to a function. Each element in calcEVR_handles is an anonymous function that takes in a single value t and a single vector x. As such, by doing calcEVR_handles{i}, you would access the corresponding function stored at the ith element in the cell array. Once you have access, you then pass your parameters to this function and it gives you those three outputs.
To show you an example of this working, consider the following cell array that works similarly to calcEVR_handles.
calcCellFunc = {#sin, #cos, #tan};
This is a three element cell array, where each element is a handle to a function. The # is a special character in MATLAB that denotes that you are creating a handle to a function. It's also used to create anonymous functions, but let's shelve that for this answer. You can read more about it here if you want to delve into more detail regarding this.
Back to our cell array of handles, we will make handles for sin, cos and tan. You can then iterate over your cell array by accessing the function you want by calcCellFunc{idx} where idx is the element you want in the cell array. This will ultimately give you the function stored at index idx. Once you do that, you can then call the function and specify whatever inputs you want (or none if it doesn't take any inputs). Here's a quick example for you. Let's create a random 5 x 5 matrix, and run through each function with this matrix serving as the input. We then take each of these outputs and store them into a corresponding slot in an output cell array. As such:
rng(123); %// Set seed for reproducibility
M = rand(5);
calcCellFunc = {#sin, #cos, #tan};
out = cell(1, numel(calcCellFunc)); %// To store the results for each function
for idx = 1 : numel(calcCellFunc)
out{idx} = calcCellFunc{idx}(M); %// Get the function, then pass
%// the matrix M to it
end
If you want to make things clear, you could split up the out statement to this instead:
func = calcCellFunc{idx}; %// Get access to the function
out{idx} = func(M); %// Pass M to this function
If you're new to handles / anonymous functions, you should probably use the above code first to make it explicitly clear on what MATLAB is doing. You are first getting access to the function you want that is stored in the cell array, and then you pass your arguments to this function.
If we display the output, we get:
>> celldisp(out)
out{1} =
0.6415 0.4106 0.3365 0.6728 0.5927
0.2823 0.8309 0.6662 0.1815 0.7509
0.2249 0.6325 0.4246 0.1746 0.6627
0.5238 0.4626 0.0596 0.5069 0.5737
0.6590 0.3821 0.3876 0.5071 0.6612
out{2} =
0.7671 0.9118 0.9417 0.7398 0.8054
0.9593 0.5564 0.7458 0.9834 0.6604
0.9744 0.7745 0.9054 0.9846 0.7489
0.8518 0.8866 0.9982 0.8620 0.8191
0.7522 0.9241 0.9218 0.8619 0.7502
out{3} =
0.8363 0.4503 0.3573 0.9094 0.7359
0.2942 1.4934 0.8932 0.1845 1.1370
0.2308 0.8167 0.4690 0.1773 0.8850
0.6149 0.5218 0.0597 0.5880 0.7004
0.8761 0.4135 0.4205 0.5884 0.8814
The first element of the output cell array has the output when you pass M to sin, the second when you pass M to cos, and the third when you pass M to tan.
So the next question you're asking... why is this useful?
Point #1 - Nix the copying and pasting
This kind of code writing is very useful because if you want to use the same inputs and supply them to many different functions, we would naturally be inclined to do some copying and pasting. Take each of your function names, and create a single line for each. Each line would call the corresponding function you want, followed by the input arguments. This can become quite tedious, and so one smart way to do it would be to place your function name as a handle into a cell array, and to write one for loop that goes over all of the functions dynamically. You could even explore cellfun and escape using the for loop to iterate over all of the function handles too, but I'll leave that for you to read up on.
In this way, you have very maintainable code and if you want to remove functions that don't need to be run, just remove the handles from the cell array rather than scrolling down to where the line that invokes this function is located and removing that.
This is actually a very common technique in computer science / software engineering in general. In fact, this is actually quite close to what are known as function pointers. This is MATLAB's cheap way of doing it, but the logic behind this is essentially the same.
Point #2 - Higher Order Functions
Another way this is useful is if you have a function where one (or more than one!) of the inputs is a function, and you also specify inputs into this function as additional parameters to this function. This is what is known as a higher order function. The outputs would be based on using this input function, and the additional inputs you specify to it and the outputs are based on using this input function and the inputs you specify for this function.
One very good example is the fzero function in MATLAB. The goal is to find the root of a non-linear function, and the first parameter is a handle to a function that you specify. The base behaviour behind how fzero works is the same no matter what the function is. All you have to do is specify the function you want to solve and the initial guess of where you think this root is.
All in all, anonymous functions are very useful.

Matlab: Can I refer to array indices via unique names?

Suppose I have a column matrix pols containing vectors of [theta, rho, z].
Which means, if I have 9 such vectors, it will be a 9x3 matrix.
It is quite handy to have them arranged as such, because I can just feed any one of them to functions like pol2cart:
cart3 = pol2cart(pols(3,:));
and for a certain vector, I can find its components via the indices 1, 2, 3:
rho5 = pols(5,2);
But sometimes the matrix is actually within another wider matrix, and could be in the middle instead of the beginning, such that the above might become:
rho5 = pols(5,6);
In order to make the code more readable in case someone else has to maintain it, is there anyway to refer to an index via a unique name? Like
rho5 = pols(5).rho;
where it could be defined earlier that .rho maps to the column which has the value of rho.
I've ventured into converting matrices to cells then to array using mat2cell and cell2struct but it doesn't seem practical. Or, I could make an array of structs, but then I lose the ability to do pol2cart(pols), and instead must do
pol2cart(pols.theta, pols.rho, pols.z);
So to repeat the question: can I map the indices to unique names?
For the default MATLAB data types, no, you can't really do that. You could, however, create your own new data type (i.e. class object) to store your data. Within the class definition you would overload the subsref method to define how subscripted referencing (i.e. using (), {}, or .) behaves for your new object. This could get rather tricky with regards to dealing with arrays of objects, but it is possible.
Note that you would also have to create overloaded methods for all the existing functions you want to use on your new data type. Specifically, you would have to create a pol2cart method for your object that could internally call the built-in pol2cart function with the appropriate pieces of data from your object passed as arguments.
...And this brings me to a simpler solution for your current situation. Instead of making a whole new type of class object, you could create a structure array (or scalar structure of arrays) to store your data and simply create a new overloaded pol2cart function specifically for struct data types that will simplify the calling syntax.
I discuss more details of overloading functions for built-in data types in two other answers here and here. In short, you would create a folder called #struct and place it in a folder on your MATLAB path. In this #struct folder you would then put this overloaded function:
function varargout = pol2cart(polarCoordinates)
[varargout{1:nargout}] = pol2cart(polarCoordinates.theta, ...
polarCoordinates.rho, ...
polarCoordinates.z);
end
Note that this is a stream-lined version of the function, without error checks on the input, etc. Now, let's make some sample data:
pols = rand(9, 3); %# A 2-D array of data
polStruct = struct('theta', pols(:, 1), ... %# Convert it to a scalar
'rho', pols(:, 2), ... %# structure of arrays
'z', pols(:, 3));
And you could access the rho value of the fifth row as follows:
rho5 = pols(5,2);
rho5 = polStruct.rho(5);
If you wanted to convert from polar to cartesian coordinates, here's how you would do it for each data type:
[X,Y,Z] = pol2cart(pols(:,1), pols(:,2), pols(:,3)); %# Calls the built-in one
[X2,Y2,Z2] = pol2cart(polStruct); %# Calls the overloaded one
And you can check that they each give identical results as follows:
>> isequal([X Y Z],[X2 Y2 Z2])
ans =
1 %# True!
OK, the formal answer is probably "no" as given by woodchips above. However, if you really want to do something like that, you might be able to use a semi-hack. Specifically, you can define a class and overload an operator to achieve (almost) what you want. Unfortunately, I see that Matlab doesn't allow overloading ., so you have to use some other operator. (see edit below)
Just to give you the idea, here is a class that returns the i-th row of a matrix M by M^i.
classdef Test
properties
M;
end
methods
function this = Test(M)
this.M = M;
end
function res = mpower(this, i)
res = this.M(i, :);
end
end
end
And it can be run like this:
>> tmp = Test([1 2; 3 4]);
>> tmp^1
ans =
1 2
>> tmp^2
ans =
3 4
Use at your own risk! :)
Edit:
I was wrong above. As mentioned in gnovice's answer you can actually define the . operator for a custom class using method subsref.
No. You cannot do so. As simple as that.

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!