Converting binary like table but using decimal values

I'm trying to create a table that will start at a negative value and increment by one in the right most column and each column to the left will only increment when there is a carry. This is similar to a binary table or any other base-n table, but I would like to keep the values in decimal format, not alpha-numeric.
I had this code which was working well, but fails if I make 'n' > 5 due to the alpha-numerics once the decimal value reaches '10'.
m = 3; %Number of signals
n = n+1; %Number of harmonics
%% Harmonic Basis Matrix
T = zeros((2*n-1)^m,m);
for k = 1:(2*n-1)^m
T(k,:) = dec2base(k-1,2*n-1,m)-num2str(n-1);
end
When I subtract num2str(n-1) from the string '00A', the result is double('00A') = 17 - double('0') = 5 ==> 17-5 = 12.
I thought about creating the matrix in alpha-numeric string form and just splitting the values into columns, but couldn't figure out how to do that effectively without using cells - which I need to avoid as this will be used in some matrix algebra.
Please note, that the variables 'm' and 'n' are part of a function input and could be completely arbitrary.
Thanks for the help!

6 Comments

Can you give us a short example for some inputs and outputs? I do not understand, what you are asking for.
The inputs are quite simple in this case, m and n, where m is the number of columns in the matrix and n is the 'base'.
Basically, if I have 2 elements (m=2) and I would like to create a cross modulation table with 2 terms (n=2), I would get this result:
T =
-2 -2
-2 -1
-2 0
-2 1
-2 2
-1 -2
-1 -1
-1 0
-1 1
-1 2
0 -2
0 -1
0 0
0 1
0 2
1 -2
1 -1
1 0
1 1
1 2
2 -2
2 -1
2 0
2 1
2 2
The hard part is when I have a large N term, which then produces A's and B's and C's during the dec2base(). Using this method I am also limited to an N value less than 36.
I assume, you mean (2*n+1)^m, not (2*n-1)^m.
>> [X,Y] = meshgrid(-2:2);
>> M = [X(:),Y(:)]
M =
-2 -2
-2 -1
-2 0
-2 1
-2 2
-1 -2
-1 -1
-1 0
-1 1
-1 2
0 -2
0 -1
0 0
0 1
0 2
1 -2
1 -1
1 0
1 1
1 2
2 -2
2 -1
2 0
2 1
2 2
m and n can be arbitrary. Then ndgrid is needed.
Meshgrid/ndgrid is definitely more simple, but how would you handle when m > 2?
Using the grid method, there needs to be an output stored for each level of 'm'.
I.e. for m = 2
[x,y] = ndgrid(-2:2);
T = [y(:),x(:)]
but for m = 4
[x,y,z,k] = ndgrid(-2:2);
T = [k(:),z(:),y(:),x(:)]
The number of outputs would change for every different 'm' value. Is this adaptable in Matlab?
Thanks

Sign in to comment.

 Accepted Answer

You can use comma-separated lists on the output of ndgrid:
m = 4;
C = cell(1,m);
[C{:}] = ndgrid(-2:2);
T = reshape(cat(m+1,C{:}),[],m)
T = 625×4
-2 -2 -2 -2 -1 -2 -2 -2 0 -2 -2 -2 1 -2 -2 -2 2 -2 -2 -2 -2 -1 -2 -2 -1 -1 -2 -2 0 -1 -2 -2 1 -1 -2 -2 2 -1 -2 -2 -2 0 -2 -2 -1 0 -2 -2 0 0 -2 -2 1 0 -2 -2 2 0 -2 -2
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>

2 Comments

Great tutorial on comma separated lists. I didn't realize that was even an option for input/outputs. This will be very usefull forever more.
I'll need to read up on the cellfun(@(a)...) line, but this defintely works. Thanks, Stephen.
"Great tutorial on comma separated lists..."
Thank you, you can vote for it too, if you liked it :) Comma-separated lists are certainly very handy and well worth learning about.
"I'll need to read up on the cellfun(@(a)...) line..."
All that does lines does is convert the content of each cell (i.e. the array output from ndgrid) into a column vector. An explicit loop would likely be a tad faster, in case speed is of major concern.

Sign in to comment.

More Answers (2)

ndgrid or meshgrid and reshape to column vectors and put the columns together.
Jan
Jan on 7 May 2019
Edited: Jan on 7 May 2019
R = VChooseKRO(-2:2, 2)
Or:
n = 2;
m = 2;
len = (2*n+1)^m; % Not: (2*n-1)^m !
T = zeros(len, m);
v = repmat(-n, 1, m);
for k = 1:len
T(k, :) = v;
for im = m:-1:1
if v(im) < n
v(im) = v(im) + 1;
break;
end
v(im) = -n;
end
end
Or:
len = (2*n+1)^m; % Not: (2*n-1)^m !
T = zeros(len, m);
v = (-n:n).';
nv = numel(v);
r1 = nv ^ (m - 1);
r2 = 1;
for k = 1:m
T(:, k) = repmat(repelem(v, r1, 1), r2, 1);
r1 = r1 / nv;
r2 = r2 * nv;
end

Products

Release

R2019a

Asked:

on 6 May 2019

Edited:

on 27 Jul 2025

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!