So, what does that differentiation matrix look like for finite-differences? Remember, when we discussed the stiffness matrix introducing it in the static case, we already said the entries of a row of this matrix actually looks very much like or is equivalent to the second derivative finite-difference operator. Now, the differentiation matrix actually for a second derivative looks like this. So, you have one over dx square multiplying a matrix, where you have a band of values basically one minus two one. If you apply that to a vector of appropriate values in a certain frequency band, you actually obtain an approximation of the second derivative. Now, if you think of the definition of a matrix vector multiplication which is a sum which is given here, a sum over in that case Dij Uj sum over J from one to N, and it returns in a vector U double prime I will return the second derivative. It's easy to show and I encourage you to do this as an exercise that you basically end up with a very simple standard formulation for the second derivative which is ui plus one minus two ui plus ui minus one divided by dx square, which is of course an approximation of the second derivative. That's what we're going to use for our finite-difference solution that we also put in this matrix vector notation. We need something else. We also need a mass matrix for our finite element solution or actually the inverse of the mass matrix, which we simply define as a diagonal matrix as given here containing the inverse of the density values at grid points I, which we will also use in the algorithm that results. So, making use of these differentiation matrix just defined and introduced for the finite-difference scheme and an inverse mass matrix for this finite difference algorithm, we can now actually write down a solution scheme for the standard finite-difference method in matrix vector form, and that's given here at the top. Now, compare that to the finite-element scheme that we've just derived with an entirely different basically mathematical method. They look very very similar. They're basically almost identical. Before proceeding in showing how these actually work in a Python algorithm, it's instructive to look basically at the difference of the form of those matrices in a graphical form and that's given here. So, you see the stiffness and mass matrix for the finite-element method that we now derived and introduced this week. Also we compared with the finite-difference matrices that we just introduced. Basically, the stiffness matrices or differentiation matrix look identical. The only difference is that the mass matrix in the finite-element system is basically spread out around the diagonal trace. But in principle, now, the algorithm with which we solve these two systems are extremely similar. The Python code for such a matrix vector multiplication based finite-difference scheme looks very compact and it's given here. We have a time extrapolation. Again u and u will be u of t plus dt. So, we're calculating the displacement vector in the future and you see it here. It's basically given as matrix vector products. There also is the source term f, specifically the spatial source function usually one point in space where we inject a source, and there is also the source time function src here where we inject at each times that basically the equivalent sources. So, that looks very simple. We will now introduce the finite-element code, which looks very similar, and then we apply this in our Jupyter notebooks. So, as for the finite-element scheme, starting with the original equation that we developed for the finite-difference solution and the finite-element solution for the spatial part on the right hand side. We end up with a Python algorithm that's given here that looks almost exactly the same as the finite-difference scheme. This we can now implement and compare with the finite-difference solution later in the Jupyter notebook. Before we do that, let's have a look again at how the system matrices are basically initiated in the Python algorithm. As you see an example here for the mass matrix, there's a couple of if statements that you have to employ in particular for the edges, for the first and the last element. So, it's worth looking at this in more detail but there's also the notebooks that you can use later for understanding this in more detail. So, before passing on to actually applying this and of course that's the fun part, and it took us quite a bit of time to actually get to this solution, if you compare that to the finite-difference algorithm at the beginning of the course. There's a couple of statements that I would like to make. First, we developed a finite-difference vector matrix based algorithm just to compare with the finite-element solution. In practice, you would actually not do this. So, here we are trying to convey concepts. So, the idea of showing this similarity is the reason for doing that, not for computational efficiency, on the computer you would actually not do it like this. It's also important to note we are to calculate the inverse of the mass matrix which we have to do to solve the finite-element solution. We use intrinsic functions that exist in Python or in Matlab, it's very very easy to do that. Again, for realistic very large systems, it would not be possible to actually describe the gigantic matrices in matrix form and you would have to do something else, but that goes beyond the scope of this course. Here, we try to be as simple as possible to basically convey the underlying mathematics and the principals with which these algorithms are developed, and that's why we are not focusing here on making these algorithms computationally efficient but they should be easy to implement and understand. So, that's basically it. We can now proceed and apply this in our Jupyter notebooks and simulate wave fields.