MATLAB & GNU Octave Module 2 – Vectors, matrices and numeric types
Create vectors and matrices: ranges and linspace
Build vectors, matrices and 3-D arrays in Octave and MATLAB with brackets, colon ranges, linspace and zeros, read their sizes and fix concatenation errors.
What you will learn
- Build row vectors, column vectors, matrices and 3-D arrays with brackets, ranges and creation functions
- Predict the size of any array with size, numel, length and ndims
- Choose linspace or scaled whole numbers over a colon range when the count and the end point must be exact
- Fix concatenation errors by reading the two sizes that the message names
Before you start
What you’ll learn · Before you start
What you will learn
- Build row vectors, column vectors, matrices and 3-D arrays with brackets, ranges and creation functions
- Predict the size of any array with size, numel, length and ndims
- Choose linspace or scaled whole numbers over a colon range when the count and the end point must be exact
- Fix concatenation errors by reading the two sizes that the message names
Before you start
On this page
Type t = 0:0.1:1 in Octave and you get 11 time steps, yet find(t == 0.3) finds none of them, because the fourth
step is 0.30000000000000004. How an array is built decides its size, its exact values and whether the next line of
code runs at all.
Here you build rows, columns, matrices and 3-D arrays with brackets, ranges and creation functions, read every size
with size, numel, length and ndims, choose linspace when the count and both ends must be exact, and turn
concatenation errors into working lines.
Brackets build arrays: spaces or commas within a row, semicolons between rows
Three temperature sensors on a test rig read 20.1, 20.4 and 20.9 °C, and a minute later 21.0, 21.3 and 21.8 °C. Inside square brackets, spaces or commas separate the elements of a row and a semicolon starts a new row, so those six readings make a matrix of two rows and three columns. The session types them in several shapes:
from session import prompt, version
version()
prompt("brackets.m", errors=1) Output
# GNU Octave (aarch64-apple-darwin25.4.0) version 11.3.0 $ octave-cli --quiet octave:1> temps = [20.1 20.4 20.9] temps = 20.100 20.400 20.900 octave:2> temps = [20.1, 20.4, 20.9]; octave:3> heights = [1.62; 1.75; 1.81] heights = 1.6200 1.7500 1.8100 octave:4> readings = [20.1 20.4 20.9; 21.0 21.3 21.8] readings = 20.100 20.400 20.900 21.000 21.300 21.800 octave:5> readings = [temps; 21.0 21.3 21.8]; octave:6> size(readings) ans = 2 3 octave:7> by_sensor = readings' by_sensor = 20.100 21.000 20.400 21.300 20.900 21.800 octave:8> [1 2; 3] error: vertical dimensions mismatch (1x2 vs 1x1)
Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 brackets_session.py
Each line built a different shape, and size reports rows first, then columns:
| You type | Octave builds | Size |
|---|---|---|
[20.1 20.4 20.9] or [20.1, 20.4, 20.9] |
a row vector: A 1-by-n array: one row of n elements, typed with spaces or commas between them, as in [20.1 20.4 20.9]. A colon range such as 1:5 is a row vector too. | 1x3 |
[1.62; 1.75; 1.81] |
a column vector: An n-by-1 array: one column of n elements, typed with semicolons between them, as in [1.62; 1.75; 1.81], or made from a row vector with the transpose '. | 3x1 |
[20.1 20.4 20.9; 21.0 21.3 21.8] |
a matrix, one row per minute | 2x3 |
[temps; 21.0 21.3 21.8] |
the same matrix, its first row from a variable | 2x3 |
readings' |
the transpose, one row per sensor | 3x2 |
The transpose ' swaps rows and columns, so by_sensor holds each sensor’s two readings in a row of its own. The
last line, [1 2; 3], asks for a first row of two elements and a second row of one, and Octave refuses with
vertical dimensions mismatch (1x2 vs 1x1): every row of a matrix has the same number of elements. The last section
of this lesson reads such messages in full.
Checkpoint
Check: Rows, columns and matrices from brackets
A colon range counts whole steps and may stop short of its end
a:b counts from a up to b in steps of 1, and a:s:b uses the step s, which may be negative or a fraction.
The range never passes b, and it reaches b only when whole steps land on it. This program builds the eleven
points from 0 to 1 three ways and prints each with 17 significant digits, enough to tell any two doubles apart; the
session runs it, then types a few ranges at the prompt:
% ranges.m: three ways to build the eleven points 0, 0.1, ..., 1
r = 0:0.1:1; % a colon range: start, step, end
l = linspace(0, 1, 11); % linspace: start, end, number of points
k = (0:10) / 10; % whole numbers first, then one division each
% printf reuses its format for each column of the 4-by-11 matrix: one line per point
printf('%2s %-20s %-20s %s\n', 'n', '0:0.1:1', 'linspace(0, 1, 11)', '(0:10) / 10');
printf('%2d %-20.17g %-20.17g %.17g\n', [1:11; r; l; k]);
printf('equal to 0.3: %d in the range, %d in linspace, %d in (0:10)/10\n', ...
sum(r == 0.3), sum(l == 0.3), sum(k == 0.3));
printf('differ from k / 10: %d in the range, %d in linspace\n', sum(r ~= k), sum(l ~= k)); from session import prompt, run, version
version()
run("octave-cli --no-init-all ranges.m")
prompt("range_steps.m") Output
# GNU Octave (aarch64-apple-darwin25.4.0) version 11.3.0
$ octave-cli --no-init-all ranges.m
n 0:0.1:1 linspace(0, 1, 11) (0:10) / 10
1 0 0 0
2 0.10000000000000001 0.10000000000000001 0.10000000000000001
3 0.20000000000000001 0.20000000000000001 0.20000000000000001
4 0.30000000000000004 0.30000000000000004 0.29999999999999999
5 0.40000000000000002 0.40000000000000002 0.40000000000000002
6 0.5 0.5 0.5
7 0.60000000000000009 0.59999999999999998 0.59999999999999998
8 0.70000000000000007 0.69999999999999996 0.69999999999999996
9 0.80000000000000004 0.80000000000000004 0.80000000000000004
10 0.90000000000000002 0.90000000000000002 0.90000000000000002
11 1 1 1
equal to 0.3: 0 in the range, 0 in linspace, 1 in (0:10)/10
differ from k / 10: 3 in the range, 1 in linspace
$ octave-cli --quiet
octave:1> 1:5
ans =
1 2 3 4 5
octave:2> 5:-1:1
ans =
5 4 3 2 1
octave:3> 0:0.25:1
ans =
0 0.2500 0.5000 0.7500 1.0000
octave:4> 0:0.3:1
ans =
0 0.3000 0.6000 0.9000
octave:5> 1:0
ans = [](1x0)
octave:6> numel(0:0.1:1)
ans = 11
octave:7> t = 0:0.1:1;
octave:8> find(t == 0.3)
ans = [](1x0)
octave:9> w = 0.2:0.1:0.3
w = 0.2000
octave:10> printf('%.17g\n', (0.3 - 0.2) / 0.1)
0.99999999999999978
Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 ranges_session.py
Start with the prompt. 0:0.3:1 stops at 0.9, because one more step would pass 1, and 1:0 is an empty 1x0 row:
there is no step from 1 up to 0. 5:-1:1 counts down.
Now the table. Each point of 0:0.1:1 is the start plus a whole number of steps of 0.1, and 0.1 has no exact binary
form, so three of the eleven points, 0.30000000000000004, 0.60000000000000009 and 0.70000000000000007, miss the
double nearest to the tenth they stand for. That is why find(t == 0.3) came back empty, [](1x0). The display hides
it: Octave shows the fourth point as 0.3000.
The count can slip too. 0.2:0.1:0.3 is the single value 0.2, not two points: in double arithmetic
(0.3 - 0.2) / 0.1 is 0.99999999999999978, just short of one whole step. The Octave manual warns that changing the
start of a range can change its end, and MathWorks writes that the last value of j:i:k is k only when the
increment lands on it exactly.
Finding a point of a fractional range with ==
find(t == 0.3) finds nothing in t = 0:0.1:1, though the display shows 0.3000. Compare with a tolerance,
find(abs(t - 0.3) < 1e-9), which finds position 4, or build the points so that each is exact, as the next section
shows.
Checkpoint
Check: Colon ranges and their end points
linspace fixes the count and both ends
linspace(a, b, n) returns n points from a to b, spaced (b - a) / (n - 1) apart, and the first is a and the
last is b, exactly. Without n it makes 100 points, and with n = 1 it returns b alone, in Octave as MathWorks
documents for MATLAB:
from session import prompt, version
version()
prompt("linspace_demo.m") Output
# GNU Octave (aarch64-apple-darwin25.4.0) version 11.3.0
$ octave-cli --quiet
octave:1> x = linspace(0, 0.3, 4)
x =
0 0.1000 0.2000 0.3000
octave:2> x(4) == 0.3
ans = 1
octave:3> linspace(20, 30, 6)
ans =
20 22 24 26 28 30
octave:4> numel(linspace(0, 1))
ans = 100
octave:5> linspace(2, 5, 1)
ans = 5
octave:6> step = (30 - 20) / (6 - 1)
step = 2
Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 linspace_session.py
linspace(0, 0.3, 4) ends on 0.3 exactly, so x(4) == 0.3 is 1, true, where the colon range lost its end.
linspace(20, 30, 6) gives six points two apart, the step (30 - 20) / (6 - 1) that the last line computes.
The inner points are still sums of steps. Row 4 of the table above shows linspace(0, 1, 11) missing one tenth,
0.30000000000000004, while (0:10) / 10 hits all eleven: whole numbers are exact, and each point is a single
division. The Octave manual suggests the same remedy, a range of integers converted afterwards.
Which way fits depends on what you know and what you will do with the points. Answer the three questions:
Answer the questions above: the table then marks what fits your case and says why the rest does not.
| Way to build | The count is fixed | The last point is b | Inner points are exact | The step is what you typed |
|---|---|---|---|---|
| Colon range a:s:b You give: a start, a step and a limit | Poor 0:0.1:1 gave 11 points, but 0.2:0.1:0.3 gave 1 | Poor 0:0.3:1 stops at 0.9; the limit is never passed, not always reached | Poor 3 of the 11 points of 0:0.1:1 missed the tenths, 0.30000000000000004 among them | Good every point is the start plus whole steps of s |
| linspace(a, b, n) You give: both ends and the number of points | Good always n points: linspace(20, 30, 6) gave 6 | Good the last point is b: x(4) == 0.3 was true for linspace(0, 0.3, 4) | Mixed 1 of the 11 points of linspace(0, 1, 11) missed: 0.30000000000000004 | Mixed the step follows: (b - a) / (n - 1), 2 for 20 to 30 in 6 points |
| Whole numbers, then scale You give: a count of steps, as in (0:10) / 10 | Good (0:10) holds 11 whole numbers, exactly | Good 10 / 10 is exactly 1 | Good each point is one division, the nearest double to k / 10 | Mixed the step is implied: one tenth here |
How the answers decide
- “What do you know about the points before you build them?” How many there must be: rules out Colon range a:s:b. A colon range promises its start and step, not its count, so a count that must match other data comes from linspace or from whole numbers.
- “Must the last point be the end value exactly, for a plot axis or a time grid that has to finish on time?” Yes, it must end exactly there: rules out Colon range a:s:b. A colon range never passes its limit and may stop short of it, as 0:0.3:1 stops at 0.9. linspace and whole numbers end on b.
- “Will code compare points with == or look values up by them, as t == 0.3 does?” Yes, points are compared: rules out Colon range a:s:b and adds a caveat to linspace(a, b, n). Points compared with == must be the exact doubles you expect. Whole numbers scaled once give them; linspace missed one of eleven; compare with a tolerance anyway.
- “What do you know about the points before you build them?” The step between them and “Must the last point be the end value exactly, for a plot axis or a time grid that has to finish on time?” No, stopping short is fine and “Will code compare points with == or look values up by them, as t == 0.3 does?” No, they are only used in calculations: adds a caveat to linspace(a, b, n) and Whole numbers, then scale. With a known step and nothing compared, the colon range says exactly what you mean; the other two would make you work the count out first.
In short: a colon range when you know the step, linspace when you know the count and both ends, and whole numbers
divided once when points will be compared or looked up.
Key idea
A colon range promises its start and its step, linspace its count and both ends, and whole numbers divided once
give exact points; whichever you use, compare floating-point points with a tolerance.
Checkpoint
Check: Choosing linspace or whole numbers
Creation functions fill arrays of any size and class
Typing every element only works for small arrays. Creation functions take the size, rows first, and fill the array for you:
from session import prompt, version
version()
prompt("creators.m") Output
# GNU Octave (aarch64-apple-darwin25.4.0) version 11.3.0
$ octave-cli --quiet
octave:1> Z = zeros(2, 3)
Z =
0 0 0
0 0 0
octave:2> counts = ones(2, 3, 'int8');
octave:3> class(counts)
ans = int8
octave:4> I = eye(3)
I =
Diagonal Matrix
1 0 0
0 1 0
0 0 1
octave:5> F = full(I);
octave:6> isequal(I, F)
ans = 1
octave:7> whos I F
Variables visible from the current scope:
variables in scope: top scope
Attr Name Size Bytes Class
==== ==== ==== ===== =====
I 3x3 24 double
F 3x3 72 double
Total is 18 elements using 96 bytes
octave:8> M = magic(4);
octave:9> sum(M)
ans =
34 34 34 34
octave:10> R = repmat([1 2], 2, 3)
R =
1 2 1 2 1 2
1 2 1 2 1 2
octave:11> rng('default');
octave:12> first = rand(1, 4)
first =
0.8444 0.7580 0.4206 0.2589
octave:13> size(randn(1000, 1))
ans =
1000 1
octave:14> P = ones(2, 3, 4);
octave:15> size(P)
ans =
2 3 4
octave:16> B = cat(3, [1 2; 3 4], [5 6; 7 8])
B =
ans(:,:,1) =
1 2
3 4
ans(:,:,2) =
5 6
7 8
Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 creators_session.py
zeros(2, 3)andones(2, 3)fill a 2-by-3 array with 0 or 1. A class name at the end picks the type, soones(2, 3, 'int8')holds 8-bit integers, asclass(counts)shows; numeric types are the subject of this module’s last lesson.eye(3)is the 3-by-3 identity matrix. Octave keeps it as a diagonal matrix:whosshows 24 bytes forI, the three ones of its diagonal, against 72 forfull(I), nine doubles.isequal(I, F)is 1, and in arithmetic it acts as the full matrix.magic(4)is a square whose rows, columns and diagonals have the same sum, 34 here: a handy test input.repmat([1 2], 2, 3)tiles a block 2 times down and 3 times across.randandrandndraw random numbers, uniform from 0 to 1 and normal with mean 0 and standard deviation 1.rng('default')resets the generator, yet the same reset gives other numbers in each program: Octave drew 0.8444, 0.7580, 0.4206 and 0.2589, while MathWorks’rngpage shows 0.8147, 0.9058, 0.1270 and 0.9134 for MATLAB, the first column of itsrand(4). Save the data, not only the seed, when results must match in both.
zeros(n) when you wanted a row of n zeros
zeros(3) is a 3-by-3 matrix, not a row of three. For 10,000 samples, zeros(10000) asks for 10,000 × 10,000 =
100,000,000 doubles, 800,000,000 bytes, where zeros(1, 10000) needs 80,000. Give both sizes every time.
Give a third size and you get an N-D array: An array with more than two dimensions. ones(2, 3, 4) is a 3-D array of four pages, each a 2-by-3 matrix, and cat(3, A, B) stacks two matrices of one size as pages.: ones(2, 3, 4) is four pages of 2-by-3
matrices, and cat(3, A1, A2) stacks two matrices of one size as pages. Octave 11.3 prints each page under a label
such as ans(:,:,1), even for a named array. Step through the stacking from the session:
The drawing shows the whole scene; its 5 steps are listed below.
Every step as text
- Two matrices of one size. The session starts from two 2x2 matrices. cat can stack them along the third dimension because their rows and columns match.
- The first becomes page 1. The 3 in cat(3, ...) names the dimension to stack along. The first matrix becomes page 1, which B(:, :, 1) reads: every row, every column, page 1.
- The second becomes page 2. The second matrix becomes page 2, B(:, :, 2). A third matrix would become page 3, and so on.
- One array of size [2 2 2]. B is a single array of 2 rows, 2 columns and 2 pages, so size(B) is [2 2 2], numel(B) is 8 and ndims(B) is 3.
- Or built in one call. Creation functions build such arrays directly. ones(2, 3, 4) is 4 pages of 2-by-3 matrices, 24 elements in all, and size(P, 3) reads its 4 pages.
Checkpoint
Check: Creation functions and 3-D arrays
size, numel, length and ndims answer four different questions
Code that loops over rows, checks inputs or preallocates results needs an array’s shape, and each of four functions answers its own question about it. This program asks all four about six arrays:
% sizes.m: four questions about the shape of six arrays
fmt = '%-14s %-9s %6d %7d %6d\n';
printf('%-14s %-9s %6s %7s %6s\n', 'array', 'size', 'numel', 'length', 'ndims');
A = 7; printf(fmt, '7', mat2str(size(A)), numel(A), length(A), ndims(A));
A = 1:5; printf(fmt, '1:5', mat2str(size(A)), numel(A), length(A), ndims(A));
A = (1:5)'; printf(fmt, '(1:5)''', mat2str(size(A)), numel(A), length(A), ndims(A));
A = zeros(3, 7); printf(fmt, 'zeros(3, 7)', mat2str(size(A)), numel(A), length(A), ndims(A));
A = zeros(0, 3); printf(fmt, 'zeros(0, 3)', mat2str(size(A)), numel(A), length(A), ndims(A));
A = ones(2, 3, 4); printf(fmt, 'ones(2, 3, 4)', mat2str(size(A)), numel(A), length(A), ndims(A));
[rows, cols] = size(A); % two outputs for a 2x3x4 array
printf('[rows, cols] = size(ones(2, 3, 4)): rows = %d, cols = %d\n', rows, cols);
printf('size(A, 2) = %d, size(A, 3) = %d, size(zeros(3, 7), 3) = %d\n', size(A, 2), size(A, 3), size(zeros(3, 7), 3));
printf('size(zeros(2, 3, 1)) = %s\n', mat2str(size(zeros(2, 3, 1)))); from session import run, version
version()
run("octave-cli --no-init-all sizes.m") Output
# GNU Octave (aarch64-apple-darwin25.4.0) version 11.3.0 $ octave-cli --no-init-all sizes.m array size numel length ndims 7 [1 1] 1 1 2 1:5 [1 5] 5 5 2 (1:5)' [5 1] 5 5 2 zeros(3, 7) [3 7] 21 7 2 zeros(0, 3) [0 3] 0 0 2 ones(2, 3, 4) [2 3 4] 24 4 3 [rows, cols] = size(ones(2, 3, 4)): rows = 2, cols = 12 size(A, 2) = 3, size(A, 3) = 4, size(zeros(3, 7), 3) = 1 size(zeros(2, 3, 1)) = [2 3]
Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 sizes_session.py
size(A)lists every dimension, rows first:[3 7], or[2 3 4]for the 3-D array.size(A, 2)gives one dimension, and a dimension beyond the last one counts as 1, sosize(zeros(3, 7), 3)is 1.numel(A)counts the elements: 21, or 24, the product of the sizes.length(A)is the largest dimension, 7 forzeros(3, 7), and 0 when any dimension is 0.ndims(A)is never below 2, since a single number is 1x1. Trailing dimensions of 1 are dropped, which is whysize(zeros(2, 3, 1))is[2 3].
The trap is the line under the table: with two outputs, [rows, cols] = size(ones(2, 3, 4)) gives cols = 12, because
the last output takes the product of every dimension left, 3 × 4. Ask for exactly the dimension you mean.
Using length for the number of rows
length(zeros(3, 7)) is 7, the number of columns, and a matrix with more rows than columns turns it around. Write
size(A, 1) for rows and numel(A) for a count, and keep length for arrays you know are vectors.
Checkpoint
Check: size, numel, length and ndims
An empty array still has a size
A range such as 1:0, a search that finds nothing or a filter that keeps no rows gives an
empty array: An array with at least one dimension of length 0, such as [] (0x0), 1:0 (1x0) or zeros(0, 3) (0x3). It has no elements, so isempty is true, but it keeps its size., and empty arrays have sizes like any other:
from session import prompt, version
version()
prompt("empties.m", errors=1) Output
# GNU Octave (aarch64-apple-darwin25.4.0) version 11.3.0
$ octave-cli --quiet
octave:1> size([])
ans =
0 0
octave:2> size(1:0)
ans =
1 0
octave:3> E = zeros(0, 3)
E = [](0x3)
octave:4> [isempty([]), isempty(1:0), isempty(E)]
ans =
1 1 1
octave:5> numel(E)
ans = 0
octave:6> [[]; 1 2]
ans =
1 2
octave:7> [E; 1 2]
error: vertical dimensions mismatch (0x3 vs 1x2)
octave:8> for k = 1:0, disp('this never runs'), end
octave:9> sum([])
ans = 0
Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 empties_session.py
[] is 0x0, 1:0 is 1x0 and zeros(0, 3) is 0x3: no rows, three columns. isempty is 1 for all three and numel
is 0. The sizes matter as soon as an empty array meets another one. A 0x0 [] is left out of a concatenation, so
[[]; 1 2] is simply the row 1 2, but zeros(0, 3) still has three columns and refuses a row of two:
vertical dimensions mismatch (0x3 vs 1x2). A loop over 1:0 runs no pass at all, and sum([]) is 0.
Start a table of results at its real width
To collect rows of three values, start with results = zeros(0, 3) rather than []. It says how wide every row
must be, and the first row of the wrong width fails at once instead of producing an odd shape later.
Checkpoint
Check: Empty arrays and their sizes
Concatenation errors name the two sizes that clash
Square brackets concatenation: Joining arrays into a larger one: side by side with commas or spaces, which needs the same number of rows, or one under another with semicolons, which needs the same number of columns.: the pieces of a row are joined side by side, which needs the same height, and the rows are then stacked, which needs the same width. Step through three lines of the session below, one that works and two that fail:
The drawing shows the whole scene; its 8 steps are listed below.
Every step as text
- Two rows. The line [x; y'] has one semicolon, so it holds two rows: x, the row 1 2 3, and y', the transpose of the column y = [4; 5; 6].
- Each row is made. Each row has a single piece here, so nothing needs joining. Row 1 is 1x3, and the transpose makes row 2 a 1x3 row as well.
- Widths match. Stacking puts row 2 under row 1, which needs the same number of columns in both. Three and three match.
- A 2x3 matrix. The result is the matrix with rows 1 2 3 and 4 5 6, size [2 3].
- Without the transpose. Now the line [x; y], with y still a 3x1 column. The split gives the same two rows, x and y.
- Widths clash. Row 1 is 3 columns wide and row 2 only 1, so they cannot be stacked. Octave stops with vertical dimensions mismatch (1x3 vs 3x1), the row on top first.
- A row beside a matrix. In [A, [5 6]] the comma puts both pieces in one row, so they are joined side by side. A = [1 2; 3 4] is 2 rows high and [5 6] only 1: horizontal dimensions mismatch (2x2 vs 1x2).
- The fix. Written as a column, [A, [5; 6]] joins a 2x2 and a 2x1 piece of the same height, and the result is the 2x3 matrix with rows 1 2 5 and 3 4 6.
The session makes four of these mistakes and the fix of each:
from session import prompt, version
version()
prompt("concat_fixes.m", errors=4) Output
# GNU Octave (aarch64-apple-darwin25.4.0) version 11.3.0 $ octave-cli --quiet octave:1> x = [1 2 3]; octave:2> y = [4; 5; 6]; octave:3> A = [1 2; 3 4]; octave:4> [x; y] error: vertical dimensions mismatch (1x3 vs 3x1) octave:5> [x; y'] ans = 1 2 3 4 5 6 octave:6> [A, [5 6]] error: horizontal dimensions mismatch (2x2 vs 1x2) octave:7> [A, [5; 6]] ans = 1 2 5 3 4 6 octave:8> [A; [5 6 7]] error: vertical dimensions mismatch (2x2 vs 1x3) octave:9> [A; [5 6]] ans = 1 2 3 4 5 6 octave:10> cat(3, A, [x; x]) error: cat: dimension mismatch octave:11> size(cat(3, A, [5 6; 7 8])) ans = 2 2 2
Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 concat_session.py
Read the message in two parts. Vertical means stacking failed, so the widths differ; horizontal means joining
side by side failed, so the heights differ. The two sizes are the pieces in the order you typed them. In
[A, [5 6]] the 2x2 matrix and the 1x2 row cannot stand side by side, and the column [5; 6] can. For cat,
Octave 11.3 says only cat: dimension mismatch, so print size of each piece. MathWorks documents the same rule for
MATLAB, compatible sizes along the joined dimension, and MATLAB words its messages differently, so read the sizes
rather than the text.
Transposing until the error goes away
[x; y'] fixed the clash because y held the second row of data. If y had been the same data as x in another
orientation, the fix would hide a mix-up. Decide what each row means before you transpose anything.
Checkpoint
Check: Reading concatenation errors
Practise: build the arrays of a small experiment
Do these in Octave on your own computer; each says what you should see:
- Type the readings of four sensors at three times as one matrix, rows for times.
sizemust say3 4, and the transpose4 3. - Build a time grid from 0 to 2 s in steps of 0.02 s three ways:
0:0.02:2,linspace(0, 2, 101)and(0:100) / 50. Check that all three have 101 points withnumel, and count withsum(a ~= c)how many points of the first two differ from the third: Octave 11.3 counts 10 for the range and 6 forlinspace. - Start
results = zeros(0, 3), append the rows[1 20.1 0.5]and[2 20.4 0.4]withresults = [results; …], then try[3 20.9]. Read the message, and say which two sizes it names. - Predict
size,numel,lengthandndimsofzeros(4, 1, 2)and of10:-2:1, then check.
Then test yourself: the session below starts where you are least sure and gives the reason for every answer:
Practice that adapts to you
Practise this lesson
14 questions about 7 ideas of this lesson. Each answer is explained at once, and what you get right is kept in this browser.
Interview questions
Warm-up: what is the difference between 0:0.1:1 and linspace(0, 1, 11)?
Both give the eleven points from 0 to 1, but they promise different things. The colon range promises its start and
its step: each point is the start plus a whole number of steps, it never passes the end, and it reaches the end only
when whole steps land on it, so its count can come out one short, as 0.2:0.1:0.3 gives a single value. linspace
promises the count and both ends: 11 points, the first exactly 0 and the last exactly 1, with the step worked out as
(1 - 0) / 10. Neither makes every inner point exact. In Octave 11.3, three points of the range and one of
linspace differ from the nearest double to the tenth, so t == 0.3 finds nothing. When points are compared, build
them as (0:10) / 10 or compare with a tolerance.
Model answers open with any pass: ₹79 for 1 week ($2.99), one payment that never renews.
-
Fresher to mid
A script builds the time axis of a logged signal with t = t0:dt:t1, and on some files plot(t, x) fails because t has one point fewer than x. Explain how that happens and how you build t so that it always matches the data.
-
Mid to senior
A function returns the peaks it finds in a signal as a k-by-3 matrix (time, height, width) and [] when there are none. Callers stack the results of many files and read columns of them. What can go wrong with the empty result, and how do you design it?
Key takeaways
- Inside square brackets, spaces or commas separate the elements of a row and semicolons separate rows; the
transpose
'swaps rows and columns, and every row must have the same number of elements. - A colon range
a:s:bis the start plus whole steps: it never passesb, reaches it only when the steps land on it, and its fractional points such as 0.30000000000000004 can miss the values they stand for. linspace(a, b, n)fixes the count and both ends, and whole numbers divided once, such as(0:10) / 10, give exact points; compare floating-point points with a tolerance either way.zeros,ones,eye,magic,repmat,randandrandntake the size rows first, a class name sets the type,zeros(3)is square, and a third size makes a 3-D array of pages.sizelists the dimensions,numelcounts elements,lengthis the largest dimension andndimscounts dimensions;[rows, cols] = size(P)folds the rest intocols.- Empty arrays have sizes, and concatenation messages name the two sizes that clash: vertical for widths, horizontal for heights.
Terms in this lesson
- column vector
- An n-by-1 array: one column of n elements, typed with semicolons between them, as in [1.62; 1.75; 1.81], or made from a row vector with the transpose '.
- concatenation
- Joining arrays into a larger one: side by side with commas or spaces, which needs the same number of rows, or one under another with semicolons, which needs the same number of columns.
- empty array
- An array with at least one dimension of length 0, such as [] (0x0), 1:0 (1x0) or zeros(0, 3) (0x3). It has no elements, so isempty is true, but it keeps its size.
- N-D array
- An array with more than two dimensions. ones(2, 3, 4) is a 3-D array of four pages, each a 2-by-3 matrix, and cat(3, A, B) stacks two matrices of one size as pages.
- row vector
- A 1-by-n array: one row of n elements, typed with spaces or commas between them, as in [20.1 20.4 20.9]. A colon range such as 1:5 is a row vector too.
References
- GNU Octave manual: Matrices (The Octave Project Developers)
- GNU Octave manual: Ranges (The Octave Project Developers)
- GNU Octave manual: Empty Matrices (The Octave Project Developers)
- GNU Octave manual: Special Utility Matrices (zeros, ones, eye, rand, repmat, linspace) (The Octave Project Developers)
- GNU Octave manual: Famous Matrices (magic) (The Octave Project Developers)
- GNU Octave manual: Creating Diagonal Matrices (The Octave Project Developers)
- GNU Octave manual: Rearranging Matrices (cat) (The Octave Project Developers)
- linspace: generate linearly spaced vector (MATLAB) (MathWorks)
- colon: vector creation, array subscripting and for-loop iteration (MATLAB) (MathWorks)
- Creating, Concatenating, and Expanding Matrices (MATLAB) (MathWorks)
- rng: control random number generator (MATLAB) (MathWorks)
Report a problem with this lesson
Kept only in this browser. Your Learn progress