What general tips do you have for golfing in MATLAB? I'm looking for ideas that can be applied to code golf problems in general that are at least somewhat specific to MATLAB (e.g. "remove comments" is not an answer). Please post one tip per answer.
Something that one must know before starting to golf:
In MATLAB calculations a character behaves the same as its ascii code.
'abc' - 'a' % Returns: [0 1 2] '123' - '0' % Returns: [1 2 3] '“' == 8220 % Returns: 1 (logical) 'a':'e'==100 % Returns: [0 0 0 1 0] (logical)
Shortening property names
In MATLAB, strings identifying properties can be shortened as long as it does not result in ambiguity.
plot(X,'C','k') % Ambiguous property found. plot(X,'Co','k') % Expands to Color (black)
This actually won me a challenge :)
Strings are just character row vectors. This means that instead of
for i=numel(str) a=str(i) ... end
you can simply write
for(a=str) ... end
First time I used this: https://codegolf.stackexchange.com/a/58387/32352
Related, but not identical tips for Octave.
A little known and little used feature of both MATLAB and Octave is that most builtin functions can be called without parentheses, in which case they will treat whatever follows it as a string (as long as it doesn't contain spaces). If it contains spaces you need quotation marks. This can frequently be used to save a byte when using
disp('Hello, World!') disp 'Hello, World!'
Other, less useful examples include:
nnz PPCG ans = 4 size PPCG ans = 1 4 str2num 12 ans = 12
I've actually used this twice in the "How high can you count?"-challenge:
strchr sssssssssssssst t
is equivalent to
strchr('sssssssssssssst','t') and returns
is equivalent to
nnz('nnnnnnnnnnnnnn') and returns
gt r s works too (equivalent to
Roots of unity via discrete Fourier transform
Given a positive integer
n, the standard way to generate the
n-th roots of unity is
This gives the roots starting at
1 and moving in the positive angular direction. If order doesn't matter, this can be shortened to
exp(2j*pi/4) equals the imaginary unit (
j), this can be written more compactly as follows (trick due to @flawr):
But the discrete Fourier transform provides an even shorter way (thanks to @flawr for removing two unnecessary parentheses):
which gives the roots starting at
1 and moving in the positive angular direction; or
which starts at
1 and moves in the negative angular direction.
Try all of the above here.
nnz can sometimes save you a few bytes:
- Imagine you want the sum of a logical matrix
A. Instead of
sum(A(:)), you can use
- If you want to know the number of elements of an array, and you can be sure there are no zeros, instead of
numel(x)you can use
nnz(x). This is applicable for instance if
xis a string.
Iteration over vectors in matrices.
Given a set of vector as matrix, you can actually iterate over them via a single for loop like
for v=M disp(v); end
while "traditionally" you probably would have done it like
for k=1:n disp(M(:,k)); end
I've only learned about this trick just now from @Suever in this challenge.
2D Convolution Kernels
This is maybe a niche topic, but apparently some people like to use convolution for various things here. 
In 2D following kernels are often needed:
0 1 0 1 1 1 0 1 0
This can be achieved using
v=[1,2,1];v'*v>1 %logical v=[1,0,1];1-v'*v %as numbers
which is shorter than
Another kernel often used is
0 1 0 1 0 1 0 1 0
which can be shortened using
v=[1,-1,1];v'*v<0 % logical [0,1,0;1,0,1;0,1,0] % naive verison
zeros are a typically a waste of space. You can achieve the same result by simply multiplying an array/matrix (of the desired size) by 0 (to get the output of
zeros) and add 1 if you want the output of
d = rand(5,2); %// Using zeros z = zeros(size(d)); %// Not using zeros z = d*0; %// Using ones o = ones(size(d)); %// Not using ones o = 1+d*0
This also works if you want to create a column or row vector of zeros or ones the size of one dimension of a matrix.
p = rand(5,2); z = zeros(size(p,1), 1); z = 0*p(:,1); o = ones(size(p, 1), 1); o = 1+0*p(:,1);
If you want to create a matrix of a specific size you could use
zeros but you could also just assign the last element to 0 and have MATLAB fill in the rest.
%// This z = zeros(2,3); %// vs. This z(2,3) = 0;
I quite often find myself using
ndgrid, let's say we want to compute a mandelbrot image, then we initialize e.g.
Now for the mandelbrot set we need another matrix
c of the size of
y but initialized with zeros. This can easily be done by writing:
You can also initialize it to another value:
But you can actually save some bytes by just adding another dimension in
[x,y,c]=meshgrid(-2:1e-2:1,-1:1e_2,1, 0); %or for the value 3 [x,y,c]=meshgrid(-2:1e-2:1,-1:1e_2,1, 3);
And you can do this as often as you want:
Counting the number of non zero elements in a matrix
zeronum(i)=nnz C; zeronum(i)=nnz(C); zeronum(i)=sum(C~=0); zeronum(i)=sum(abs(C)>=eps); zeronum(i)=numel(find(C~=0)); zeronum(i)=prod(size(find(C~=0)));
Horizontal replication is 3 copies, vertical replication is 2 copies
Multiple variables, all initialized with the same data
[A,B,C,D]=deal([1 4;2 5;3 6]); %%%% A = [1 4; 2 5; 3 6]; B=A; C=A; D=A;
Declare a zero matrix of the same size as matrix A
X=0*A(:,1); X=zeros(size(A)); X=zeros(size(A),'like',A);
Summation of a sequence of functions
For summing up functions f(x_n) where n is a vector of consecutive integers, feval is adviced rather than symsum.
Syms x;symsum(f(x),x,1,n); Sum(feval(@(x)f(x),1:n));
Notice that an elementary operation
./is necessary instead of pairwise binary operations
If the function can be naively written no one from either last ways is suitable.
for example if the function is
logyou can simply do:
sum(log(1:n)), which represents:
for relatively sophisticated functions as
log(n)/x^nyou can do:
and even shorter in some cases when a function is longer as
that is remarkably shorter than
Note: This trick can be applied for other inclusive operators as