WEBVTT

00:00.330 --> 00:04.230
Hello again! In this video, we are going to look at numeric algorithms.

00:06.320 --> 00:09.980
Most of the standard library algorithms are defined in the algorithm header.

00:10.430 --> 00:12.380
But there are a few in the numeric header.

00:12.770 --> 00:15.320
And these are more concerned with numeric processing.

00:17.810 --> 00:22.580
The first one we're going to look at is called iota(), as in the Greek letter.

00:23.030 --> 00:28.790
This takes an iterator range, and it sets each element in the range to have a value which increases

00:28.790 --> 00:29.300
by one.

00:34.540 --> 00:37.210
We call it by passing the iterator range.

00:38.440 --> 00:42.370
These cannot be const iterators, because they are going to modify the vector elements.

00:42.820 --> 00:48.490
And we also pass the starting value. So this will sets the first element in the vector to have the

00:48.490 --> 00:49.030
value 1.

00:49.420 --> 00:54.340
Then the next element is 2, 3, and so on until it gets to the last element in the vector.

00:56.080 --> 01:01.810
We could also write this as a hand-written loop. So we have some variable which stores the current value.

01:02.770 --> 01:05.380
Then we iterate through the vector elements.

01:05.860 --> 01:09.160
We need to put an ampersand here, because we are going to modify the elements.

01:09.790 --> 01:13.990
Then we sent the element to the current value of this variable.

01:14.680 --> 01:15.760
Then we increment it.

01:16.150 --> 01:21.580
And then on the next iteration, the next element will have the incremented value. And so on.

01:22.990 --> 01:24.160
So here is some code.

01:24.160 --> 01:28.540
We need to include the numeric header, which is easy to overlook!

01:29.560 --> 01:31.960
We have a vector with 10 elements.

01:32.620 --> 01:34.270
We have our call to iota().

01:34.930 --> 01:36.850
So this is going to populate

01:36.850 --> 01:39.700
every element in the vector, with the starting value as one.

01:40.930 --> 01:43.930
And then we also have the handwritten loop, which will do the same thing.

01:44.650 --> 01:46.570
So with any luck, we should get the same answer.

01:48.490 --> 01:49.080
And there we are.

01:49.090 --> 01:51.670
So the elements of the vector increase by one.

01:52.390 --> 01:54.560
And that is quite a useful little algorithm, if you are doing

01:54.570 --> 01:55.390
numeric programming.

01:56.380 --> 01:58.810
There is also an algorithm called accumulate().

01:59.170 --> 02:03.490
This will add up all the elements in an iterator range, and return their sum.

02:06.940 --> 02:11.670
We give it the iterator range. We can use const iterators this time, because this will not modify the

02:11.680 --> 02:12.100
vector.

02:12.700 --> 02:15.070
We also give it a starting value for the sum.

02:15.580 --> 02:21.280
Usually you will want this to be 0. And that will give you the total of adding all the elements. The

02:21.280 --> 02:22.570
total sum of the elements.

02:23.320 --> 02:26.860
But if you pass some other number, then that will be added to the sum.

02:27.460 --> 02:30.220
And this is quite useful if you are doing repeated calculations.

02:31.090 --> 02:35.770
For example, if we calculate the sum of the elements in "vec" and then we want to add the elements in

02:35.770 --> 02:40.450
"vec2" to to that total, then we just pass the "vec" result as the argument.

02:40.870 --> 02:45.430
So this is going to be the sum of the elements of "vec", and then we are going to add the sum of the elements in "vec2"

02:45.620 --> 02:46.390
to that sum.

02:46.900 --> 02:50.470
And then the result will be the sum of all the elements in both those vectors.

02:51.480 --> 02:53.190
So here we can try it out.

02:53.910 --> 02:55.190
We're going to call accumulate().

02:56.460 --> 02:59.370
We pass the iterator range and the initial value of the sum.

03:00.300 --> 03:03.380
We could also do this with a handwritten loop, which is - okay,

03:03.390 --> 03:08.670
it is not rocket science, but sometimes it is useful to have more abstract representations of things.

03:11.110 --> 03:11.770
So there we are.

03:12.100 --> 03:13.690
The sum is 23.

03:17.550 --> 03:22.650
By default, accumulate() will use the plus operator. So that will perform adddition of the elements, using

03:22.650 --> 03:28.650
the element's plus operator. If we want to do something else, we can pass a callable object as an optional

03:28.650 --> 03:29.160
argument.

03:30.480 --> 03:33.000
So here is the same call again with a lambda expression.

03:33.480 --> 03:39.390
This lambda expression is going to take the total so far and the current element. The element which

03:39.390 --> 03:45.780
the accumulate() algorithm is processing. And the value that it returns will be the new value of the sum.

03:45.930 --> 03:51.600
So with the plus element, this would just add the current element to the sum and returned the new value

03:51.600 --> 03:54.210
of the sum. In this lambda expression,

03:54.210 --> 03:59.220
the value that we return depends on whether the element is odd or even. If it is odd,

03:59.310 --> 04:02.580
then we add it to the current sum and return the new sum.

04:02.580 --> 04:05.700
So we have added the odd element to the running total.

04:06.660 --> 04:11.190
If the element is not odd, then we just return the current value of the sum.

04:11.520 --> 04:13.950
So we do not add the even numbers to the sum.

04:14.790 --> 04:18.360
So the result of this will be the sum of all the odd elements in the vector.

04:19.530 --> 04:21.330
And let's try this out to see if it works.

04:21.600 --> 04:22.950
So we have our lambda expression.

04:22.950 --> 04:26.460
It takes the current running total and the current element.

04:27.210 --> 04:30.450
And if the element is od, it will add it to the current total.

04:30.810 --> 04:33.240
Otherwise it will just return the current total.

04:35.950 --> 04:38.380
And we get 19, so (three, four, five)

04:38.830 --> 04:39.640
Yep, that is correct.

04:41.020 --> 04:42.700
It is always nice when things give the right answer!

04:43.540 --> 04:48.670
If you're interested in numerical programming, you are probably also interested in parallel processing.

04:49.090 --> 04:54.850
So this is when we have several processors or processor cores which are all executing the same code

04:54.850 --> 04:55.660
at the same time.

04:56.230 --> 04:58.300
And this should give you the answer much more quickly.

04:59.350 --> 05:04.180
Unfortunately, the accumulate() algorithm is not very conducive to parallel processing.

05:05.230 --> 05:10.450
So let's look at how it works. If we have a vector {1, 2, 3}  and the starting sum 0.

05:11.650 --> 05:17.170
This will be evaluated as zero plus one, so it will take the starting sum and add the first element

05:17.170 --> 05:17.560
to it.

05:18.550 --> 05:22.120
And then once that has been calculated, it will add the next element.

05:22.540 --> 05:25.390
And once that has been calculated, it will add the next element.

05:25.720 --> 05:27.520
So this is all entirely sequential.

05:27.610 --> 05:29.200
One operation must follow another.

05:29.620 --> 05:32.890
We cannot have different operations executing at the same time.

05:36.530 --> 05:40.730
In C++ 17, there is a new numeric algorithm function, reduce().

05:41.300 --> 05:47.150
This is a reimplementation of accumulate(), which is compatible with parallel processing.

05:47.840 --> 05:49.460
So we call it exactly the same.

05:49.940 --> 05:56.030
The difference is that reduce() can perform the addition in any order. It is not forced to execute from

05:56.030 --> 05:56.630
left to right.

05:58.220 --> 06:00.800
And this means it is compatible with parallel processing.

06:01.280 --> 06:04.400
So I am not really going to talk anymore about parallel processing.

06:05.000 --> 06:09.380
Quite a few of the algorithms have been rewritten, so they work better with parallel processing.

06:09.860 --> 06:12.160
And I cover that in my course on multi-threading.

06:12.860 --> 06:14.750
Okay, so that is it for this video.

06:15.230 --> 06:16.100
I will see you next time.

06:16.100 --> 06:18.260
But until then, keep coding!
