WEBVTT

00:00:00.440 --> 00:00:05.360
Linear algebra is heavily used in programming, especially for graphics.

00:00:05.840 --> 00:00:08.470
To implement 3D scenes with scaling,

00:00:08.470 --> 00:00:12.790
rotations, and transformations, we need to operate on data

00:00:12.790 --> 00:00:16.550
presented with mathematical vectors and matrices.

00:00:16.940 --> 00:00:19.020
And, if you ever saw a matrix,

00:00:19.030 --> 00:00:22.080
you know that it kind of looks like a table of numbers with

00:00:22.080 --> 00:00:24.760
a specific amount of rows and columns.

00:00:25.140 --> 00:00:28.430
So, let's say that I want to store a matrix in memory,

00:00:28.440 --> 00:00:30.360
that looks something like this.

00:00:30.740 --> 00:00:34.060
It has two rows and three columns.

00:00:34.440 --> 00:00:39.750
Remember that to the computer, everything is just a really long stream of bytes.

00:00:40.140 --> 00:00:43.460
The concept of rows and columns is not something that

00:00:43.460 --> 00:00:45.420
the computer really cares about.

00:00:45.430 --> 00:00:48.220
If we wanted to store this matrix in memory,

00:00:48.230 --> 00:00:51.940
each element would be stored in a one‑dimensional sequence,

00:00:51.950 --> 00:00:56.610
just like a simple array. I created an array of six integers to

00:00:56.610 --> 00:00:58.850
store the numbers from the matrix.

00:00:59.340 --> 00:01:02.570
This doesn't really look like a table with rows and columns,

00:01:02.570 --> 00:01:06.260
but we can make our own abstraction to pretend that it does.

00:01:06.840 --> 00:01:08.530
Let's create four variables.

00:01:08.540 --> 00:01:12.350
The first two will define the number of rows and the number of

00:01:12.350 --> 00:01:16.350
columns, and the last two will store the indexes of a row and

00:01:16.350 --> 00:01:18.960
the column that we want to access.

00:01:19.440 --> 00:01:24.350
Our table has two rows and each row has three columns, so

00:01:24.350 --> 00:01:28.420
six numbers in total. The required row and column position

00:01:28.420 --> 00:01:30.360
will be taken from the terminal.

00:01:30.740 --> 00:01:32.630
I want to start counting from 0,

00:01:32.910 --> 00:01:36.320
which means that the first row will have an index of 0 and

00:01:36.320 --> 00:01:38.710
the second row will have an index of 1,

00:01:38.990 --> 00:01:42.790
just like a regular array. Each column will also have

00:01:42.790 --> 00:01:44.860
a special index for each number.

00:01:45.240 --> 00:01:46.260
So for example,

00:01:46.260 --> 00:01:49.230
if I want to get this number, which is placed in the

00:01:49.230 --> 00:01:51.430
second column of the second row,

00:01:51.440 --> 00:01:53.810
I would say that I want to get an integer at the

00:01:53.810 --> 00:01:56.630
position of the row 1 and column 1.

00:01:57.440 --> 00:02:00.620
I need a mathematical formula that will provide me with

00:02:00.620 --> 00:02:03.260
this abstraction of two dimensions.

00:02:04.640 --> 00:02:07.460
And, this is what that formula looks like.

00:02:07.840 --> 00:02:11.980
I want to get an array element at the position of a requested row,

00:02:11.990 --> 00:02:16.560
multiplied by the number of columns, plus the requested column.

00:02:17.740 --> 00:02:20.560
Let's compile this program to see if this works.

00:02:20.940 --> 00:02:25.900
I want to get a second number from the second row, so the position that I need

00:02:25.910 --> 00:02:32.560
is 1, 1, and it seems that it works, the number 5 is correct.

00:02:33.740 --> 00:02:35.150
Let's try one more.

00:02:35.840 --> 00:02:41.870
I want to get this number 3 and its position is 0 and 2, and if I

00:02:41.870 --> 00:02:44.950
try that position, I get the correct number again.

00:02:45.340 --> 00:02:49.810
So, with a little bit of math and imagination, we were able to use this

00:02:49.810 --> 00:02:53.650
one‑dimensional array as a matrix with two dimensions.

00:02:54.040 --> 00:02:57.600
Let's use this same formula to print this array to the terminal

00:02:57.610 --> 00:03:03.140
in a form of a table. To do this, I will use two for loops, one

00:03:03.140 --> 00:03:05.250
will be nested inside of the other.

00:03:06.240 --> 00:03:09.230
The first loop will go through each row, and the

00:03:09.230 --> 00:03:12.150
second loop will go over each column.

00:03:12.540 --> 00:03:17.250
Each iteration of this outer loop will complete the whole inner loop.

00:03:17.640 --> 00:03:21.870
So first, the row will be 0 and the column will also be 0.

00:03:22.540 --> 00:03:26.960
Then the column will be incremented to 1, but the row will still

00:03:26.960 --> 00:03:31.610
remain 0. After that, the column will increment once more to 2,

00:03:31.610 --> 00:03:33.850
and the row will still remain 0.

00:03:34.540 --> 00:03:38.470
So, we are basically looping through all of the numbers in the table,

00:03:38.480 --> 00:03:42.650
row by row. Once all of the columns in a row are completed,

00:03:42.660 --> 00:03:46.500
the next iteration of the outer loop begins, and this goes

00:03:46.500 --> 00:03:49.360
on until we get through all of the rows.

00:03:50.840 --> 00:03:54.760
So the actual elements from the array need to be accessed

00:03:54.760 --> 00:03:58.600
here, inside of the nested for loop. I will use the same

00:03:58.600 --> 00:04:00.850
formula to access these elements.

00:04:01.540 --> 00:04:05.490
Let's also add this vertical line character after each number

00:04:05.490 --> 00:04:08.050
to make the output look more like a table.

00:04:08.940 --> 00:04:12.030
I will also add the same character before each row,

00:04:12.040 --> 00:04:16.260
and after each row is finished, I want to print on a new line.

00:04:16.640 --> 00:04:19.820
This is a really useful concept, because you can define

00:04:19.820 --> 00:04:23.930
special behavior for each row in the outer loop and what to do

00:04:23.930 --> 00:04:26.360
with each column in the inner loop.

00:04:27.540 --> 00:04:31.560
I will turn this into a comment, because I just want to see the table.

00:04:32.640 --> 00:04:34.860
Let's compile and see what happens.

00:04:36.340 --> 00:04:39.360
This kind of looks like a table, right?

00:04:39.740 --> 00:04:43.630
It looks exactly like the matrix we had in mind, and now we have

00:04:43.630 --> 00:04:46.660
a way to store it in memory and work with it.

00:04:47.040 --> 00:04:47.660
However,

00:04:47.660 --> 00:04:51.470
using the array with this mathematical formula seems a little bit

00:04:51.480 --> 00:04:56.700
unnatural and unintuitive, at least for me. There is a reason why we

00:04:56.700 --> 00:05:02.180
don't program by typing out a sequence of 1s and 0s, humans need better

00:05:02.180 --> 00:05:04.860
abstraction mechanisms to be more productive.

00:05:05.540 --> 00:05:10.760
Fortunately, C++ offers us a better way to manage multidimensional arrays.

00:05:11.840 --> 00:05:14.130
The syntax is straightforward,

00:05:14.140 --> 00:05:18.160
you just use a separate square bracket to define each dimension.

00:05:18.540 --> 00:05:23.550
So in this case, I want to create a 2d array with two rows and three columns.

00:05:24.040 --> 00:05:28.030
The initialization list can stay, because the memory which contains

00:05:28.030 --> 00:05:31.940
these elements will look exactly the same, it will still store all

00:05:31.940 --> 00:05:33.960
of these integers next to each other.

00:05:34.340 --> 00:05:37.030
The big difference is, of course, the way in which we

00:05:37.030 --> 00:05:39.370
can manage this array. However,

00:05:39.370 --> 00:05:42.740
to make our intentions more obvious, you can wrap every

00:05:42.740 --> 00:05:45.210
dimension in its own curly braces,

00:05:45.220 --> 00:05:48.650
and I will even put each one of them on a new line.

00:05:49.540 --> 00:05:53.460
This already looks like a table, and now,

00:05:53.460 --> 00:05:55.600
instead of utilizing this formula,

00:05:55.610 --> 00:05:58.470
I can use two square brackets to specify the

00:05:58.470 --> 00:06:01.260
required position of each dimension.

00:06:02.040 --> 00:06:05.460
As you can see, this approach is much more intuitive.

00:06:06.540 --> 00:06:07.130
Okay,

00:06:07.140 --> 00:06:10.880
now I can compile this to see if it still works, and it

00:06:10.880 --> 00:06:15.760
does. The output still looks the same, but the code is much cleaner.

00:06:16.140 --> 00:06:18.760
If you wanted to have a three‑dimensional array,

00:06:18.770 --> 00:06:22.720
you would just add another square brackets with the third dimension and then

00:06:22.730 --> 00:06:27.480
access the elements in the same way. You should prefer using this syntax

00:06:27.490 --> 00:06:29.960
instead of the implementation with a special formula,

00:06:29.970 --> 00:06:34.950
because the code looks cleaner and the performance is exactly the same.

00:06:35.340 --> 00:06:38.780
But there is a reason why I started this lesson with that formula,

00:06:38.790 --> 00:06:41.120
and we will talk about it in the next lesson,

00:06:41.120 --> 00:06:45.750
where we will learn how to allocate multidimensional arrays on the heap.
