MATLAB and Simulink resources for Arduino, LEGO, and Raspberry Pi

Learn moreOpportunities for recent engineering grads.

Apply Today
Asked by Andrew Newell on 3 Mar 2011

One of the joys of using MATLAB is that it has a stock of matrix functions like `diff`, `sort`, `all`, and so on, that can be combined in all sorts of interesting ways. For example, in a recent question, the challenge was to find a compact code to determine which columns of a matrix `A` have all elements equal. Matt Tearle came up with this nifty answer:

all(~diff(A))

What are your favorite one-line MATLAB expressions?

Answer by Walter Roberson on 3 Mar 2011

Accepted answer

cell2mat(arrayfun(@(K) accumarray(C, F(:,K), [], @mean), 1:size(F,2), 'Uniform', 0))

In response to a cssm question:

I have a feature matrix, F(m, n) and a cluster vector, C(m, 1). Now I want to get the mean of feature in F according to C. Make it simple as below:

F = [2 5; 3 7; 8 4] C = [2; 1; 2] output should be [3 7; (2+8)/2 (5+4)/2] =[3 7; 5 4.5]

Matt Fig on 3 Mar 2011

ARRAYFUN, and ACUMARRAY? About all that is missing is to somehow work BSXFUN in there too!

Andrew Newell on 28 Mar 2011

Even though BSXFUN is missing, I decided to accept this one. Very clever, @Walter!

Answer by Matt Tearle on 3 Mar 2011

I'm a huge fan of logical indexing. Expressions like

mean(frogs(wombats > 42))

rock my world.

Sean de Wolski on 3 Mar 2011

I use the function 'keep' from the FEX which performs the inverse of clear.

I also use the variables 'in', 'out' a lot. So the other day I typed:

'keep out'

which kind of made my day.

Answer by Sean de Wolski on 3 Mar 2011

Here's another from a thread today:

Given a connected components analysis (bwconncomp) and some criteria for objects to meet: remove objects that don't meet that criteria from your binary image:

I(cell2mat(CC.PixelIdxList(~idx)')) = false;

Sean de Wolski on 3 Mar 2011

idx can usually be a one line expression from cellfun making this a super-awesome-long-one-liner.

Answer by Matt Fig on 3 Mar 2011

Here is a good one. After already writing a solution to this Question, I stumbled upon this:

groups = mat2cell(A,diff([0;find(diff(A) ~= 1);length(A)]),1);

Pretty Slick.

Show 3 older comments

Matt Fig on 3 Mar 2011

I had it stored in my "One liners" file, which is made up of one-liners either I or somebody else on CSSM wrote in response to some question. The file is too big to be much use anymore...

Matt Tearle on 3 Mar 2011

Matt Fig: "LI is tops, but not always necessary or useful"

An unbeliever! Persecute! Kill the heretic!

Walter Roberson on 3 Mar 2011

Ah, I found my copy, and it was _not_ a 1 liner. I had used

b=diff(a); %find differences

idx = find([b 2]>1); %find their indexes

cel = mat2cell(a, 1, [idx(1) diff(idx)]); %break up the matrix

Answer by Matt Tearle on 3 Mar 2011

Inspired by something I'm working on right now & your comment to my previous answer...

If you have an n-by-1 structure array `people` with a field `suck` (which contains a scalar for each struct element), and you want to find the average:

mean([people.suck])

Extract multiple elements, concatenate, apply function. All in one line.

Answer by Andrew Newell on 3 Mar 2011

Turn a structure array S into a cell array with the names of the fields in the first column:

C = horzcat(fieldnames(S), squeeze(struct2cell(S)))

Answer by Andrew Newell on 6 Mar 2011

Here is a real beauty from a comment by Tim Davis on a guest blog for Loren Shure. Suppose you have three 2D vectors `p1`, `p2` and `p3`, and you want to know if they are collinear. The shortest solution also happens to be numerically the most reliable:

rank ([p2-p1 ; p3-p1]) < 2

It is also easily generalized to more dimensions!

Answer by Oleg Komarov on 3 Mar 2011

eval('fliplr(['''' 33 33 33 33 33 76 105 118 69 32 109 39 73 ''''])')

MuAhahauHAh!!!

Andrew Newell on 3 Mar 2011

If you were really evil (or a quitter), you'd do

eval(char([113 117 105 116]))

the cyclist on 28 Mar 2011

I used to be an admin on a chess server where "qu" could be used as a shorthand to quit out of the interface. A common prank was to tell newbies that "qu" could be used to display the "quote of the day".

Answer by Andrew Newell on 4 Mar 2011

Here is an interesting way of calculating n rows of Pascal's triangle:

round(expm(diag(1:n-1,-1)))

Now if we could just remove the zeros and center it on the same line!

Walter Roberson on 4 Mar 2011

sprintf() it and regexrep() on the result, substituting spaces for leading space-zero-space; another regexprep() call could substitute spaces for trailing space-zero-space.

Doug Eastman on 29 Mar 2011

It's not pretty but just for fun, here's one way to do it:

trimmedTriangle = cell2mat(cellfun(@(x) x(1:size(num2str(expm(diag(1:n-1,-1))),2)),cellfun(@(x,y)[x y],cellfun(@(x) repmat(' ',1,x),num2cell(round(linspace(size(num2str(expm(diag(1:n-1,-1))),2)/2,0,n))'),'UniformOutput',false),regexprep(mat2cell(num2str(expm(diag(1:n-1,-1))),ones(n,1)),' 0',' '),'UniformOutput',false),'UniformOutput',false))

Answer by Drew Weymouth on 4 Mar 2011

Read in an image and convert it to a grayscale, double matrix of data range 0..1

im= rgb2gray(double(imread('filename.jpg'))/255);

Walter Roberson on 4 Mar 2011

or more generally, rgb2gray(im2double(imread('filename.jpg')))

Your code would fail for images that happened to be already double or happened to be uint16.

## 0 Comments