Your country

Tools that support it use your country for local currency, number formats, units and paper size. Your choice is saved only in this browser.

Type a name or a two-letter code. Use the up and down arrow keys to move through the countries, Enter to choose one and Escape to close.

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.

  • Beginner
  • 20 minutes
  • Examples run with octave 11.3.0 and Python 3.14.8
  • By MySmartCoPilot
Free lesson, Pro answers: 20 minutes
Free: the whole lesson. With a pass: the model answers to its 2 interview questions.

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:

Rows, columns and a matrix typed at the Octave prompt, GNU Octave 11.3.0 Python · brackets_session.py
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

  1. Question 1 of 2 What is size([1 2 3; 4 5 6]'), the size of the transpose?

    Choose one answer.

    Show the answer: Question 1 of 2

    Answer: [3 2]

    [1 2 3; 4 5 6] is 2x3, two rows of three. The transpose turns each row into a column, so the result is 3x2, as readings' turned the 2x3 matrix of readings into the 3x2 by_sensor.

  2. Question 2 of 2 Inside square brackets, which character starts a new row?

    Choose one answer.

    Show the answer: Question 2 of 2

    Answer: A semicolon ;

    Spaces or commas separate the elements of a row and a semicolon starts the next row. [1.62; 1.75; 1.81] is therefore a column of three.

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: the points 0, 0.1, …, 1 built three ways M · ranges.m
% 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));
ranges.m, then colon ranges at the prompt, GNU Octave 11.3.0 Python · ranges_session.py
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

  1. Question 1 of 2 How many elements does 0:0.3:1 have?

    Type a number.

    A hint

    List the points, and stop before one would pass 1.

    Show the answer: Question 1 of 2

    Answer: 4 elements

    The points are 0, 0.3, 0.6 and 0.9. One more step would give 1.2, which passes 1, so the range stops at 0.9 with four elements, as the session showed.

  2. Question 2 of 2 What does Octave 11.3 show for this line?

    Read the code, then choose one answer.

    w = 0.2:0.1:0.3
    Show the answer: Question 2 of 2

    Answer: w = 0.2000

    A colon range never passes its limit. 0.2 + 0.1 does not come out at or below 0.3 in double arithmetic, so the range is the single value 0.2. linspace(0.2, 0.3, 2) gives both 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:

linspace at the Octave prompt, GNU Octave 11.3.0 Python · linspace_session.py
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:

Interactive · answer and compare Which way of building the points fits your calculation? Answer three questions about the points you need. Every option is shown as it is until you answer, then the table marks what fits and why.
What do you know about the points before you build them?
Must the last point be the end value exactly, for a plot axis or a time grid that has to finish on time?
Will code compare points with == or look values up by them, as t == 0.3 does?

Answer the questions above: the table then marks what fits your case and says why the rest does not.

A colon range, linspace and whole numbers scaled once, against four things a calculation can need
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

  1. Question 1 of 2 What is the distance between neighbouring points of linspace(0, 10, 5)?

    Type a number.

    A hint

    Five points make four gaps.

    Show the answer: Question 1 of 2

    Answer: 2.5

    linspace spaces n points (b - a) / (n - 1) apart: (10 - 0) / (5 - 1) = 2.5, giving 0, 2.5, 5, 7.5 and 10.

  2. Question 2 of 2 A signal has 101 samples taken from 0 to 2 s. Which line builds a time vector that is sure to have 101 points and to end at exactly 2?

    Choose one answer.

    Show the answer: Question 2 of 2

    Answer: t = linspace(0, 2, 101);

    When the count must match data and the end must be exact, linspace(0, 2, 101) gives both; (0:100) / 50 also gives 101 points with exact ends.

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:

Creation functions at the Octave prompt, GNU Octave 11.3.0 Python · creators_session.py
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) and ones(2, 3) fill a 2-by-3 array with 0 or 1. A class name at the end picks the type, so ones(2, 3, 'int8') holds 8-bit integers, as class(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: whos shows 24 bytes for I, the three ones of its diagonal, against 72 for full(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.
  • rand and randn draw 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’ rng page shows 0.8147, 0.9058, 0.1270 and 0.9134 for MATLAB, the first column of its rand(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:

Interactive · step by step Two matrices become the pages of a 3-D array Step through cat(3, ...) from the session below and see which index reaches each page.
Two matrices become the pages of a 3-D array, step 5 of 5. Showing [1 2; 3 4], [5 6; 7 8], Page 1: B(:, :, 1), Page 2: B(:, :, 2), B = cat(3, ...). In focus: B = cat(3, ...).[1 2; 3 4]a 2x2 matrix[5 6; 7 8]another 2x2 matrixPage 1: B(:, :, 1)rows 1 2 and 3 4Page 2: B(:, :, 2)rows 5 6 and 7 8B = cat(3, ...)size [2 2 2]ones(2, 3, 4): size [2 3 4]

The drawing shows the whole scene; its 5 steps are listed below.

Every step as text
  1. 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.
  2. 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.
  3. The second becomes page 2. The second matrix becomes page 2, B(:, :, 2). A third matrix would become page 3, and so on.
  4. 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.
  5. 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

  1. Question 1 of 2 What size is zeros(3)?

    Choose one answer.

    Show the answer: Question 1 of 2

    Answer: 3-by-3

    One size means a square: zeros(3) is 3x3 and zeros(10000) would be 10,000 by 10,000. Give both sizes, as in zeros(1, 10000), for a row.

  2. Question 2 of 2 What is size(cat(3, zeros(2, 4), ones(2, 4), eye(2, 4)))?

    Choose one answer.

    Show the answer: Question 2 of 2

    Answer: [2 4 3]

    cat(3, ...) adds pages. Rows and columns stay 2 and 4, and the three matrices give 3 pages, so the size is [2 4 3].

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 six arrays M · sizes.m
% 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))));
sizes.m, run with GNU Octave 11.3.0 Python · sizes_session.py
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, so size(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 for zeros(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 why size(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

  1. Question 1 of 2 What does length(zeros(4, 2, 9)) return?

    Type a number.

    Show the answer: Question 1 of 2

    Answer: 9

    length is the largest dimension. The sizes are 4, 2 and 9, so length is 9; numel would be 72 and size(A, 1) 4.

  2. Question 2 of 2 What is cols after this line?

    Read the code, then choose one answer.

    [rows, cols] = size(ones(2, 3, 4));
    Show the answer: Question 2 of 2

    Answer: 12

    sizes.m printed rows = 2, cols = 12 for exactly this line. Use size(A, 2) for the columns alone.

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:

Empty arrays at the Octave prompt, GNU Octave 11.3.0 Python · empties_session.py
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

  1. Question 1 of 2 What is size(zeros(0, 5))?

    Choose one answer.

    Show the answer: Question 1 of 2

    Answer: [0 5]

    zeros(0, 5) is 0x5, shown as [](0x5). isempty is true and numel is 0, yet it still has five columns.

  2. Question 2 of 2 What does the last line do?

    Read the code, then choose one answer.

    results = zeros(0, 3);
    results = [results; 1 20.1 0.5];
    results = [results; 2 20.4]
    Show the answer: Question 2 of 2

    Answer: It stops with vertical dimensions mismatch (1x3 vs 1x2)

    The first row fits the 0x3 start. The second has two values, so Octave stops and names the two sizes; starting from zeros(0, 3) would have caught a short first row in the same way.

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:

Interactive · stage by stage How Octave builds an array from square brackets Step through three lines of the session below, one that works and two that fail, and see which check each one meets.
How Octave builds an array from square brackets, step 8 of 8. Showing Split the rows at each ; ([A, [5 6]] has 1 row), Join the pieces of a row (2x2 beside 2x1: same height), Stack the rows (one on another: same width), The array is built (2x3: rows 1 2 5 and 3 4 6). In focus: Join the pieces of a row, The array is built.sizes clash: an errorSplit the rows at each ;[A, [5 6]] has 1 rowJoin the pieces of a row2x2 beside 2x1: same heightStack the rowsone on another: same widthThe array is built2x3: rows 1 2 5 and 3 4 6

The drawing shows the whole scene; its 8 steps are listed below.

Every step as text
  1. 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].
  2. 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.
  3. Widths match. Stacking puts row 2 under row 1, which needs the same number of columns in both. Three and three match.
  4. A 2x3 matrix. The result is the matrix with rows 1 2 3 and 4 5 6, size [2 3].
  5. Without the transpose. Now the line [x; y], with y still a 3x1 column. The split gives the same two rows, x and y.
  6. 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.
  7. 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).
  8. 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:

Concatenation errors and their fixes, GNU Octave 11.3.0 Python · concat_session.py
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

  1. Question 1 of 2 A line fails with horizontal dimensions mismatch (3x1 vs 2x1). What went wrong?

    Choose one answer.

    Show the answer: Question 1 of 2

    Answer: Two columns of different heights were placed side by side

    Horizontal concatenation, with a comma or a space, needs pieces of the same height. A 3x1 and a 2x1 column differ in height, so they cannot stand side by side.

  2. Question 2 of 2 A = [1 2; 3 4]. Which line adds the column 5, 6 on the right?

    Choose one answer.

    Show the answer: Question 2 of 2

    Answer: [A, [5; 6]]

    To add a column, join a piece of the same height side by side: [A, [5; 6]] is the 2x3 matrix with rows 1 2 5 and 3 4 6.

Practise: build the arrays of a small experiment

Do these in Octave on your own computer; each says what you should see:

  1. Type the readings of four sensors at three times as one matrix, rows for times. size must say 3 4, and the transpose 4 3.
  2. 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 with numel, and count with sum(a ~= c) how many points of the first two differ from the third: Octave 11.3 counts 10 for the range and 6 for linspace.
  3. Start results = zeros(0, 3), append the rows [1 20.1 0.5] and [2 20.4 0.4] with results = [results; …], then try [3 20.9]. Read the message, and say which two sizes it names.
  4. Predict size, numel, length and ndims of zeros(4, 1, 2) and of 10:-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.

  1. Question 1 of 14 What size is [temps; temps] when temps = [20.1 20.4 20.9]?

    Choose one answer.

    Show the answer: Question 1 of 14

    Answer: [2 3]

    A variable stands for its whole value inside brackets: two 1x3 rows stacked make a 2x3 matrix.

  2. Question 2 of 14 Which lines make the column vector of 1, 2 and 3?

    Choose every answer that is right.

    Show the answer: Question 2 of 14

    Answer:

    • (1:3)'
    • [1; 2; 3]
    • [1 2 3]'

    A column comes from semicolons or from the transpose of a row. Commas and spaces always build rows.

  3. Question 3 of 14 What does Octave show for this line?

    Read the code, then choose one answer.

    5:-1:1
    Show the answer: Question 3 of 14

    Answer: The row 5 4 3 2 1

    a:s:b with s negative counts down from a and stops at b at the latest: 5 4 3 2 1.

  4. Question 4 of 14 Code finds the sample at 0.7 s in t = 0:0.1:1 with k = find(t == 0.7), and k comes back empty. What is the most robust fix?

    Choose one answer.

    Show the answer: Question 4 of 14

    Answer: Compare with a tolerance, k = find(abs(t - 0.7) < 1e-9)

    The eighth point of 0:0.1:1 is the start plus 7 steps of 0.1, which is 0.70000000000000007, not the double nearest 0.7. Comparing with a tolerance, or building t as (0:10) / 10, finds it.

  5. Question 5 of 14 What does linspace(a, b, n) promise?

    Choose one answer.

    Show the answer: Question 5 of 14

    Answer: n points, the first exactly a and the last exactly b

    linspace fixes the count and both ends, and the step follows from them, (b - a) / (n - 1).

  6. Question 6 of 14 You need the eleven points 0, 0.1, …, 1 so that each one equals the double nearest its tenth. Which line gives that in Octave 11.3?

    Choose one answer.

    Show the answer: Question 6 of 14

    Answer: (0:10) / 10

    ranges.m showed that only (0:10) / 10 matched the nearest double to every tenth. The Octave manual suggests the same: build the range from integers, then convert.

  7. Question 7 of 14 In Octave 11.3, whos reports 24 bytes for I = eye(3) and 72 bytes for F = full(I). What does that tell you?

    Choose one answer.

    Show the answer: Question 7 of 14

    Answer: Octave keeps eye(3) as a diagonal matrix that stores only the three ones, and it still equals the full matrix

    Octave's eye returns a diagonal matrix, shown under the label Diagonal Matrix, which stores only its diagonal: 3 doubles, 24 bytes, against 9 doubles, 72 bytes, for the full matrix.

  8. Question 8 of 14 A colleague in MATLAB and you in Octave both run rng('default') and then rand(1, 4). What do you get?

    Choose one answer.

    Show the answer: Question 8 of 14

    Answer: Different numbers, so data that must match in both programs is saved and shared

    The seed fixes the stream within one program. Across the two programs the streams differ, so when results must match, the random input is saved to a file and read by both.

  9. Question 9 of 14 What is numel(ones(2, 3, 4))?

    Type a number.

    Show the answer: Question 9 of 14

    Answer: 24 elements

    numel counts every element, the product of the sizes: 2 × 3 × 4 = 24.

  10. Question 10 of 14 A function must loop over the rows of a matrix of measurements that may have more columns than rows. Which gives the number of rows?

    Choose one answer.

    Show the answer: Question 10 of 14

    Answer: size(A, 1)

    length(zeros(3, 7)) was 7, the columns. size(A, 1) always means rows.

  11. Question 11 of 14 For which of these does isempty return 1?

    Choose every answer that is right.

    Show the answer: Question 11 of 14

    Answer:

    • 1:0
    • []
    • zeros(0, 3)

    isempty is true when any dimension is 0. [], 1:0 and zeros(0, 3) all have no elements; the number 0 is an element like any other.

  12. Question 12 of 14 How many times does this loop print?

    Read the code, then choose one answer.

    n = 0;
    for k = 1:n
      disp(k)
    end
    Show the answer: Question 12 of 14

    Answer: Never

    1:n with n = 0 is the empty 1x0 range, so the body never runs, as the session's loop over 1:0 printed nothing.

  13. Question 13 of 14 What does the word vertical in vertical dimensions mismatch tell you?

    Choose one answer.

    Show the answer: Question 13 of 14

    Answer: Stacking rows one under another failed, so their widths differ

    Vertical means one under another, the semicolon's job. The two sizes in brackets are the pieces that could not be stacked.

  14. Question 14 of 14 cat(3, A, B) fails with cat: dimension mismatch and names no sizes. What do you do first?

    Choose one answer.

    Show the answer: Question 14 of 14

    Answer: Print size(A) and size(B); their rows and columns must match

    Octave 11.3 reports only "cat: dimension mismatch" for cat, so you supply the sizes yourself. Rows and columns must agree for pages to stack.

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.

  1. 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.

    Model answer, Pro. Model answers open with any pass; prices are in the notice on this page. First step and follow-ups

  2. 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?

    Model answer, Pro. First step and follow-ups

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:b is the start plus whole steps: it never passes b, 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, rand and randn take 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.
  • size lists the dimensions, numel counts elements, length is the largest dimension and ndims counts dimensions; [rows, cols] = size(P) folds the rest into cols.
  • 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

Report a problem with this lesson

Quick answers and tool search

Type to search tools or to get a quick answer, for example 18% of 2500. Use the up and down arrow keys to move through the results, Enter to choose, and Escape to close.