The background is that, as I was already introduced, I'm actually doing quality insurance with an SAP. For one of SAP's major products, SAP HANA, which is an in-memory database and is basically powering the various enterprise applications you can find in the portfolio of SAP. What we are actually doing is we are testing each commit coming into the source code and in our scale, that means we are testing around 800 commits every day. Therefore, we are operating a small infrastructure of physical hardware with around 1,600 machines. And as we are testing an in-memory database, we need a huge amount of memory. So overall, we are currently using around 610 terabytes of memory across our landscape. So the problem is if you have such an infrastructure, if you have such load characteristics, you need optimized services, optimized tools to handle such incoming load. And that's actually the main part what my colleagues and I are doing. So we are developing such tools, such services, which are optimized for our workload. And one of this tool is our own task execution framework, which we put on top of Apache Messos. Apache Messos is something similar to Kubernetes, but a bit more low level. So what it provides us is some kind of an interface to resources of machines. So in the bottom, you can see that we have multiple data centers with our own physical hardware, but also various cloud providers with cloud instances.  And our task scheduler then has to decide, OK, what kind of task should I now schedule on this available resources? Now, the problem is if you add more and more machines, this also gets a bit more complicated. And especially in that case, our task scheduler is receiving more and more incoming offers with more and more events about changing states of tasks. So task finished, maybe, so you have no opportunity to launch new tasks or a task failed. So you have to reschedule it and you have to handle all these events. And the problem is at some point in time, we hit a bottleneck that our scheduling system was not able actually to handle all the incoming events and use all the resources in an efficient way. And now you can imagine with such amount of hardware, you actually would like to use them as efficient as possible. You can also see that around our task scheduler, there are various other services and databases. So the task scheduler is basically just interacting with all these various services and doing a lot of operations. Therefore, the initial design of the task scheduler is basically a big Python application with various threads who are handling the incoming data, who are processing the incoming data, which find the best way to schedule a certain task on a certain available resource of. We also have other threads around in the process itself, which are required for our observability stack. For example, we have a thread who is responsible to transmit all the exception data to sentry or distributed tracing is in place for our applications. So we have also a thread who is responsible to send that over to our Yeager instance. Now we have the problem that we have not the best performance anymore. Resource utilization goes down. And the nice thing is about our observability stack that we can now actually inspect each thread and each part of the system and find out, okay, where is the bottleneck? And the same method we also applied to find out, okay, why we cannot utilize all the vapor resources. Therefore, we have to take a look inside of the resource of a handling thread. And that's now a semantic visualization of our distributed tracing system, which we are currently using. And we can see the required time for certain operations. So for example, we see how long we need for selecting an offer for a task or how long we need now to prepare actually the task so that it can be scheduled. And the first strange thing is that for the same function, we have actually different runtimes. So for example, for selecting an offer, we have a variant of various runtimes from 700 milliseconds down to 30 milliseconds, which is actually quite strange. The next interesting thing is that we have also increased latency in a way that it's actually not expected. So what you see in the highlighted boxes is the first thing, which is the span, which is captured on the scheduler level. So we are capturing that we need around 200 milliseconds for this API call. The service, which we are actually asking, is also transmitting the data into the same system. Therefore, we know that the service itself only took around 30 milliseconds to process the API request. So that's also a bit strange, and we would also like to investigate there a bit. The next remaining thing, which is also strange in this capture, is there are also gaps between operations. And if you take a look into the code, there are actually no gaps. Instead of the prepared task operation, there are two suboperations, these two API calls. There's nothing in between. Why is there latency of multiple milliseconds in between? And then we started to assume, OK, I mean, we started, we are using threads. It must be the global interpreter log. We are hitting the global interpreter log. There is a contention, and that's now our bottleneck. But I mean, that's no problem. You just open a browser and perform some research, and then you will find a lot of various ways how to mitigate the global interpreter log contention. So we could just start and replace all the multi-threading thing with multi-processing, or asyncio stuff, or we could pinpoint certain CPU function, which is CPU bound, and micrame to siphon, which is actually releasing the gil in certain sensors. Or let's rewrite everything in a more faster language. But if that would be now the solution, I would probably not talk now about the global interpreter log. In general, we have to say that such rewrites or major effections are super expensive. I mean, we're talking about a productive system who is powering a huge amount of workload, and we would actually like to invest more time on new features, make it even more efficient. But now handling such performance problems is also important, but we have to use the right things to actually solve the performance problems. Therefore, we took one step back and decided, okay, let's first analyze the problem, find out is it actually the gil contention, and if we then detected that, we can actually go and maybe decide even better what kind of mitigation is the best one for our application. So let's take a look on the gil. I mean, it's probably easy. You just import a module, for example, sys for the Python interpreter, and then you ask the Python interpreter how it's going with the gil. Sadly, that is not true. There is no simple function which you can use to get some gil statistics, which means that we have to think about something else. And then I thought a bit about, okay, what I would actually like is to know about the gil are various things. The first thing I would like to know the basic fundamental metrics of a log. I mean, at the end, the global interpreter log, it's a log. So I would like to know how long does a thread actually wait for the log and how long is certain thread is actually holding that log. If I know that metrics, and I mean, we all know that if you have just some numbers, they are often not so useful. Therefore, I would also like to have some additional context, okay, which thread it is, which Python function is actually suffering from that contention, maybe. Is it maybe possible to get a trace ID or a request ID in that part? Because then I can correlate that with other systems. And I would actually like to use this in our productive environment because I cannot repute this as my local machine, because my local machine is not connected to our cluster with a hundred of machines. So that's a problem. And in best case, it would be integrated with our existing observability stack so that my colleagues and I don't have to learn another tool, how to use it, how to interact with it. So with that list, I went through the Internet and looked out, what are the available tools? How can I analyze the code? I mean, I'm probably not the first person who is thinking about that problem. So there are some relatable. There's, for example, a super interesting talk by Dave Basely from Python 2010, sorry, Python 2010, but it's actually quite up to date because it already talks about the new skill implementation, which we have said Python 3.2. And within his talk, he's explaining how he measured the GIL contention and stored the data so that he actually was able to generate such nice graph. The problem is the instrumentation and so on only works with Python 2.6 and there are some other problems which make not so usable in our productive environment. Main problem, you have to shut down the interpreter at the end to dump all the data out and then you have to generate the visualization out of it. I actually don't like to shut down our scheduler because every minute it is not running, we are basically losing resources. The next thing which came into my mind is the threat concurrency visualization of PyCharm, which is actually a very nice tool to visualize log contentions in your application. The problem is PyCharm doesn't take the GIL into account. In that example, I just run an application who is heavily GIL bound because it's basically always wasting time in CPU cycles, but you don't see anything. There's a new implementation called GIL load, which is quite interesting because it's a profile which you can easily integrate in your existing Python application. And during the application runtime, it will print out a load number. It's comparable with the load of a Linux system, for example. The problem is at the end you have only a number. You don't know, okay, what is now the root cause of that problem. So if I do that on an application who is heavily bound to the GIL and who runs always into the same contention, I just get the information, yes, you have a problem, but no other information how to solve that. A very promising approach is PySpy, which is a new profiler for Python written in Rust, which is very fast and you can easily attach it to a running application and then you can get this nice overview about what functions take, what amount of time and so on. And it also includes the GIL utilization, which is quite nice, but again, you don't have a breakdown to find out, okay, what is not a problem about it. The truth is there is no magic GIL contention analytics tool. And that means we probably have to do it by ourselves. Okay, let's create a tool which actually reveals the GIL and hopefully it is able to give me all my wishes about such a tool. For that, we can use an existing framework and basis, system type, which is available on Linux machines and it allows actually to analyze applications by attaching certain event handlers to applications. So, sorry, it actually allows to attach handlers to certain events, which are emitted by applications or by the Linux kernel itself. And then you can do certain calculations within this event handlers and print out the measure times, for example. The nice thing, CPython 3.6 actually introduced support for system type and de-trace and there are already some markers, some event emitters who you can use to analyze your Python application with system type. So, for example, we have function entry and function return which will be involved every time the interpreter goes into a new Python function or returns from Python function. I can highly recommend the documentation about that because it's super verbose and helps really to understand the concepts of system type and how you can use it. And I also saw in the schedule of this conference there's another talk about low-leveling profiling which will also cover system type. Problem about this approach is that most pre-built Linux packages actually don't include the Python interpreter which is compiled with de-trace support. So, the markers are not there. You cannot use them. Also, there are no markers for the GIL-related areas where you would actually like to know when a thread acquired something or when a thread is actually dropping the global interpreter. But especially the last part was actually not so complicated to implement. So, this is just one part of the patch who introduced some markers regarding the GIL. So, every time a thread will now drop the GIL, we'll emit an event about that. And every time a thread tries to claim the GIL, it will also emit an event of that. As you can see, we can also add arbitrary attributes to these markers which will be then accessible in system type. In that case, I'm using the ThreatyDance so that I have an understanding and I have an idea what thread is now performing this action. Now, you may be asked why you don't use the ThreadNames. I mean, every application should have an IsThreadName so that you can actually recognize the threads. The problem is, at the moment, there is sadly no CAPI to get the ThreadNames without actually holding the GIL, which is a bit complicated if you would like to measure the time until you actually have the GIL, but you need the GIL to get the ThreadNames complicated. But I think that's also something we can solve at some point in time. Okay, now we have these markers. Now, our Python interpreter is emitting these events at the point in time they are passed. Let's measure the time at that point. We are attaching probes, so-called event handlers, to these events. For example, we're instructing system type that it now should look inside of the shared library of the Python interpreter where the markers are located. And for example, if we now go in the GIL claim part so a thread would like to acquire the GIL, we will measure the time of today in nanoseconds and store that in a hash map of system type. As key, we are using the ThreadIdentifier. If we now acquire the GIL, we can actually calculate how long does it take until the thread acquired the GIL. And also store that in another data type of system type, which is an aggregate, which allows us to actually get some statistics out of system type. So for example, distributions in the form of a histogram or an average and so on. And the same thing we also do for the GIL TROP where we can actually then now calculate how long we actually hold the GIL. Now we are calculating these numbers. What we actually would like is to print them out in some kind of report. For that, we can use the handlers which will be invoked at the startup and the determination of the system type tracing session. So if the tracing session stops now, we can print out some nice debugging informations and like terminating the tracing and print out a summary of overall the measured threads with the respective timings. Let's do some example. In the first example, I have a Python process with two IO bound threads. By the IO bound or how do I actually make an IO bound thread is by simulating the IO with time.sleep because it's basically the same behavior as for example, a read request on a socket. Before the actually the thread goes into the sleep mode for a certain number of seconds, it will actually release the GIL. After the sleep is complete, it will try to reacquire the GIL. The same thing also happens on a socket. You would like to read something from a socket. You define the amount of bytes you would like to read as long as there are not enough bytes or actually no data at all available. It will plug and it will wait. But before that, Python will release the GIL for you. If we now measure that, we can actually see that we actually don't have any problem with that application. You can see that the main thread only had to wait a bit more than one millisecond on the global interpreter, which is quite nice, especially if you know that this application runs for 15 seconds in that simulation mode. If we are looking on the whole time, we also see that the main thread is the most prominent thread who holds the GIL the most of the time, which also makes sense. It has to import the libraries, the threading library and so on. So the most time will go probably for the initialization. The IO threads itself are super lightweight, so they don't have to wait that long on the GIL. And if they have the GIL, then also they don't consume that much time with the Python interpreter. Overall, we can say we hold the time only 0.2% of the full runtime and we also had only a wait time of less than 0.01% of the full runtime. So basically no GIL contention at all. And in that situation, the GIL is not a problem. We can now change that easily if we go and introduce a CPU bound thread. How do we simulate a CPU bound thread? It's actually quite simple. We just need an endless loop who's doing nothing. So this Y loop with a pass inside of the loop itself will do all the trick for us and we now have a CPU bound thread. If we now take a look on the timings, we can actually see a GIL contention. We see that the main thread has the same behavior as before, same whole time, but increased wait time. Okay, that's already a problem probably. The most important problem is that our IO threads now have a much higher wait time to get actually the GIL. So we are now waiting more than 700 milliseconds just for getting the GIL and we're actually only waiting around 100 milliseconds in our application. The whole time is still the same and the CPU thread, which is a CPU bound is actually consuming all the variable CPU time and therefore it holding the GIL nearly the full runtime. So overall, we now see that the GIL was basically always active by at least one thread and we also had some wait time in there. Even more interesting is the latency for the IO threads. If you are taking a look on the histogram of the IO threads then you will basically notice after some time that the latency is quite stable between four and eight milliseconds and that's quite interesting that it's so stable but it also shows us one main disadvantage of this GIL contention. The GIL contention already affects the overall performance of the application by introducing five milliseconds additional latency to any unlock of the global, sorry, any attempt to acquire the GIL after a blocking IO operation, which is actually quite a problem in some cases because normally you run multiple IO operations during for example an HP request. Why it's so stable? Because of the internal switch interval which is an implementation detail of the GIL but it's actually quite interesting to see that in action. Every time a thread would like to acquire the GIL it will check if someone is holding the GIL. If someone is holding the GIL then it will go into a condition and will sleep up to five milliseconds. If now the GIL is still acquired it will send out a request to drop the GIL so that the other thread who's still holding the GIL should please release the GIL so that the new thread can take over the global enterprise. That means this can add already this additional latency if you only have Python instructions then you will basically always get this stable latency of around five milliseconds. The problem is a thread who's holding the GIL can also hold the GIL even longer than this five milliseconds because some bytecode operations take longer or you're calling out into an external state functions but it actually doesn't know anything about the GIL and also don't release the GIL. Okay, now with that we have some tool search which we can use to analyze our application our productive application. So here's the plan, how we do that. We deploy our new container with our custom C-Python instrumentate for our custom C-Python version including system tab on our cluster we go to this machine which is running the scheduler we attach to the process and we get some nice insights about the GIL contention. In reality, it was a bit different. It was quite easy to deploy the container with the custom C-Python version, no big deal. But at the end, we had to install system tab on the host because it's actually not that easy to get system tab running inside of a container. And that's a bit related to the architecture of system tab. System tab is actually transforming your script which I just showed some slides ago in a real kernel extension and loads that at runtime. And then it is that kernel extension running to measure all the timing and in the end, the data will be printed out. That's possible. I also did that in our productive environment. It was interesting, but I don't recommend that. Especially if you're talking with an insecurity guy he will be probably not happy if you start adding custom kernel extensions in your productive environment and run some processes. It's rude, your full isolation is basically gone. Nevertheless, I measured some nice results. Over two seconds observation of our process I found out that we actually hold the GIL around 88% of the full runtime. Sorry, of the measure timeframe. In the same timeframe, there were so many threats waiting for the GIL that we had an overall wait time on the GIL of nearly 300%, which actually proves yes, our application really suffers from GIL contention. That's not great, but it actually revealed even more questions. The problem is, the main question, which first came up is, okay, are there threats who are holding the GIL longer than five milliseconds or does all threats actually give up the GIL quite fast and we are hitting the limit of switching around various threats? That would be one possibility, but let's take a look if we actually see that in our infrastructure. If we see that, I would actually like to know, okay, which function is taking so much time and which function is not releasing the GIL? And also, one question which came up was, is there maybe some kind of clustering in these measurements? So it is maybe possible to identify certain clusters for certain operations at a certain patterns in this measurement that are very intensive for the global interpreter lock contention. Overall, the biggest problem was that with 31 threats, it was actually quite hard to read this text report. And that's also a problem with so many threats that such tools are often not optimized for that amount of threats and I would not recommend that. So one thing which came into my mind is that timelines are much easier to understand. I mean, if you take a look on this video tracing systems, they're actually quite good in visualizing how long a certain operation takes. It's much easier to recognize how long this operation takes based on the size of the span individual representation. Okay, could we do that the same thing? Please also for the GIL contention and maybe find out what's going on in our application. Therefore, the idea is actually let's use still system tab because at least it proved that we can collect the data, collect the data with system tab and print out a text file which we then can load into a tutorial notebook and can do various analytics stuff on that can create some charts, some nice visualizations, all the things we can do with our data science tools. And I think that's one of the most nicest things about Python in nowadays that we all have this knowledge visualization libraries at hand to make data quite easily to recognize. What I did is to visualize that with bookie. This is now the time's visualization of our 31 threads over two minutes. What you can see is that in the areas where we have dark blue boxes, there we have a GIL contention which is actually we have a GIL usage which shows that thread is holding the GIL longer than 50 milliseconds. Please remember, switch interval, five milliseconds. In the red boxes in the red areas, we have now threads who are waiting for the GIL longer than 50 milliseconds. If you are now thinking about optimizing web applications, you normally try to aim as fast as possible and every web developer who says, yeah, 300 milliseconds are totally fine for a web page. I'm not sure about that. Okay, let's zoom in a bit and we can take a closer look. So these are now 20 seconds, five seconds. Now we came to the interesting part of one second. And what we saw is that they're actually a clustering of big blue boxes. So for example, this part is taking more than 500 milliseconds. 500 milliseconds, this thread is doing all the work. No other thread can do anything. And the first question was, okay, what is this thread? It's actually a thread who is collecting metrics of our scheduler is sending out this metrics into a central system so that we know how many tasks are running, how our cues are currently and so on. And after adding additional visualization, I found out that this thread is actually consuming 75% of the full GIL whole time. Which is super expensive if this thread is only taking some metrics out of the application. Okay, so now we know what is a problem. And the nice thing is, now as we know the problem, we can actually fix the problem. So what we did is we start to replacing the C extension which we were using inside of this thread to calculate all these various metrics. We actually found out that the C extension never released the GIL because it's actually internally using heavily Python objects, but if you read normally C extension, at least this was the intention by reading that by choosing that C extension, then you think normally it will probably release the GIL quite early in the time. It's not always true. Also, probably most simple fix was to just change the interval of our metrics collection. So we just changed the interval from 10 seconds to 120 seconds. So we are now collecting less often intervals, but I mean, if it can solve the GIL contention, not a big deal. And that actually happened. So before we saw a huge usage of time, huge usage of CPU time where the GIL was required for processor. And also a huge amount of time where threads are waiting for the global interpreter. After applying this simple fixes, this simple changes, it was actually possible to reduce the time by basically half the time. So we only now hold the GIL for around 43% and we only wait 80% on the GIL. So the wait time is not great, but nevertheless, with this simple fixes, we were able actually to speed up our task execution scheduler so good that we can now actually use all the vapor resources. And it basically saved us a huge amount of refactoring of our application of replacing multi-threading with multi-processing, or asyncado, where we had basically to think about, yeah, is it maybe easier to rewrite the full application from scratch? And I mean, that is probably the most important information out of performance-related stuff. Please try first to find out if you have that problem, if it makes sense to invest in that area, and probably find even a better solution if you have more insights about that. And especially now that will help us to find out, okay, what is now the next best evolution and step for our application? Does it now make sense to introduce multi-processing? Or does it make sense, for example, to rewrite some functions which are a bit more CPU-bound than other functions and move them into a siphon, for example, where we can release the GIL. Also, this full topic revealed many multiple additional ideas how we could actually improve the Python ecosystem in that area. So the next things I would actually like to do, but as you know, time is always a limit, I would actually like to bring this tool set in a more reusable state so that it's easier to use for people who are not involved in developing that scripts. But also, I think it would be possible to extend C-Python in some areas to make it even easier to build such kind of tool sets. So, for example, the C-API for threat names are one thing which would be super helpful. Every time I read the system tab report, I had to map the threat identifier to human understandable name, otherwise, you have no chance with 31 threats. Also, one question I had in my mind is, would it be possible to actually move this metrics collection directly in C-Python like the profiler itself? It don't have to be active all the time, but maybe we can enable it on demand if we actually need it and collect the statistics and get them out. If we have such an API, it is probably also easier to integrate that in existing observability tools. For example, distributed tracing, which shows, yes, this operation actually took 700 milliseconds, but overall, I only consumed 30 milliseconds of the GIL. And at that point in time, you would already know, okay, probably I have a problem with my GIL. If you are interested in that topic, and I hope there are some people interested because the room is quite full, then please watch out for me. I would actually like to talk about that. I would like to hear some feedback, things that could be improved or things which would be interesting for you, because with that feedback, I think we could actually start some things in that area to make performance measurements in Python much better. And I mean, yes, we have the GIL. We will probably never remove the GIL from C-Python because it is not so easy. Otherwise, people would already did that. But if we learn to live with the GIL, then we can also improve overall Python application performance and we don't have to rewrite them in, I don't know, C++ or C or Assembler if you really like to do that. Okay, then thank you very much. And as we have five minutes, I think we can do one or two questions. Thank you. Thank you.


So we have the slope of the temperature profile in the preheat zone leading up to the reaction zone is given by a rho u Cp Ti-T0 divided by K let us keep in mind that we are actually hunting for you this is what actually we do not know and this is what we are actually looking for and we are hoping that people be able to actually get this when we try to use the interface matching condition between the two zones. So what we have to do next is of course integrate the second equation and then also get a slope from there evaluated at x equal to 0 plus and then equate these two and therefore we expect to get the u that is how we are going to go about this that is how that is what is looking down the pipeline we are going to be doing but at this stage we now have a problem the problem is that we assume we suppose that we have T equal to Ti in both the boundary conditions leading up to x equal to 0 minus on the one side and x equal to 0 plus on the other side but we do not know what it is all we are basically saying is the temperature has to match and we have to now plug in the value of the temperature Ti over here we do not know what it is so how the question basically is how do you deal with the situation of not knowing the temperature right so there are a couple of tricks about this we will talk about in both the cases we try to now replace this temperature by unknown temperature without incurring too much error so the bottom line basically is without incurring too much error. So what we are going to do from this side looking from the preheat zone towards the reaction zone at the interface between these two zones is to now say that this is equal to rho u approximately rho u Cp Tf minus T0 divided by K why would you do this well basically the temperatures that we are actually given or Tf and T0 Ti is an unknown and we are not really making any bones about trying to find that out in the first place we are trying to actually see if we can replace the unknown by something that is known without incurring too much error. So the last part without incurring too much error is where the crux is so let us look at how Tf departs from Ti so the answer is if you now look at the preheat zone and the reaction zone basically you are having the temperature Ti very close to Tf the only difference between these two is the temperature climbs up a little bit more within the reaction zone to level off at a constant slope at the end of the flame thickness all right. So you could say that you are almost there except there is a slope is not 0 all right. So you have a finite slope a finite non-zero slope that we are trying to look at but it is it is the values is pretty small well if you want to be a little bit more careful about this picture we got to keep in mind that the preheat zone solution is going to actually give you a exponentially increasing solution is what you are looking at. So effectively yet we are talking about a value Ti that is here and the preheat zone solution would go like this and the reaction zone solution would go like that right. So that is what we are looking at so Ti the point is the point here we have to keep in mind is this is T0 so relative to T0 so look at this difference or this difference relative to T0 Ti is as close to Tf it is not as if like Ti is generally close to Tf the question is how close is it is quite close relative to T0 that is like we are kind of looking from here and then seeing that those two temperatures are very close to each other right. So that is the trick that we are playing in the preheat zone and I will show you how to play the trick in the reaction zone where we do not know Ti and we will be integrating in this region and then if you are not anticipating the kind of trick that we are going to play you must be having your eyebrows raised at this stage how am I going to actually how on earth am I going to have Ti be replaced by T0 okay because that is what I need to do okay because I will be in this region I am going to go from Ti to Tf and T and T0 and Tf for what is given Ti is unknown so in this case I am replacing Ti by Tf in that place I will have to actually replace Ti by T0 poof can I ever do that we will we will see how it works huh so it is so wait you wait with beaded breath on how we are going to play that trick so let us let us just go ahead with so we now have this so we will just go ahead with the second equation to integrate it once so the way we want to do that is taking to rewrite it is it has to dt by dx times to which is like if you now multiply this equation by twice of dt by dx all the way through then it is possible for us to now write this is d by dx of dt by dx the whole square equal to negative 2 dt by dx w q divided by k right if you want to just check we can see that if you now differentiate this you get a 2 dt by dx d square t by dx square so and then the 2 dt by dx gets cancelled on either side so if you now do this the reason is we can now have exact integrals on both sides so integrating integrating once right from 0 plus 0 plus to infinity along x okay along x we get dt by dx the whole square evaluated at x equals plus z plus infinity minus dt by dx the whole square evaluated at x equals 0 plus equal to you are going to have this integrated from 0 plus to infinity minus 2 dt by dx w q divided by k times dx so you could actually say this is not really an integral with respect to x anymore it is an integral with respect to t okay so again you do not have to worry about and then of course what you have to do is you have to now realize that the limits of the integral have to be substituted in terms of temperature instead of the x location value therefore we can write this as minus integral ti to tf 2q w divided by k dt now just in case you are one of those people who is impatient about what is going to be the outcome and what are what is it that we are gaining out of this I do not know if you remember I told you that the biggest difference that you are going to get between what you are doing with all these equations rigorously or seemingly rigorously in a mathematical sense when compared to the phenomenological energy balance that we did earlier on is we got all the dependencies right the only thing that we are going to gain is a square root of 2 okay so the factor square root of 2 which is different from the phenomenological expression square of 2 is 1.414 so you are about 41% off in the phenomenological analysis that is still within the order of magnitude you see so 1.4 is about of the order of 1 so that was an order of magnitude estimate so for an order of magnitude estimate that was that was a that was a pretty good job so question is why are we getting the square root of 2 the answer is we are actually having this 2 showing up here right because we now multiplied by 2 dt by dx and then keep in mind that this is going to be a square and I am going to equate this to this right so if I now I am going to have to equate this to this then I have to take a square root so I get the square root of 2 coming from right here at this particular step okay. So now notice that this is going to be 0 because you are having your dt by dx go to 0 at at x as x tends to infinity I also want you to point out that we are actually having the x go from here that is the origin and this is very important for us to think about as engineers x equals minus infinity as far as the preheat zone is here whereas x equals plus infinity as far as the reaction zone is here okay so this does not look like very far away when compared to that it is not like we are talking about minus infinity is being here and plus infinity being there and so on no that is not what we are really bothered about okay so infinity is something that is very kind of flexible it is it is very contextual right so the reason why we are saying this is actually going to be a very small infinity when compared to that is because you see that you are going to have a steep variation in the reaction rate within this region it is going to rise and fall within the small region and then you have to now take very small steps to capture that steep rise and steep fall okay. So that means to say we are ultimately trying to actually integrate this w with respect to t and you have to get an area under the curve of w as it rises as the temperature changes only a little bit between ti and tf okay and that rise and fall needs to be done over very small steps and if you now keep taking very small steps you pretty much reach you get tired and then you say well I think I have reached infinity if you have even if you have not gone too far okay so that is essentially a syntax for you so this is what is called as a inner zone this is what is called as an outer zone this zone has a different length scale when compared to that so we are what we what we mean by length scale is a characteristic dimension over which we would match so that is exactly what we are talking about when you are now saying that this is actually going to 0 there so which means we now say dt by dx the whole squared x equals 0 plus is equal to integral ti to tf to q w divided by k dt so q is the heating value k is the thermal conductivity those are like properties of this system so w is the one that is actually varying with temperature okay and so this integral essentially is of w with respect to temperature keep that in mind so let us call this B versus let us call that capital A and we now want to actually equate A and B except A is actually the derivative of at x equals 0 minus whereas this is B is actually square of the derivative at x equals plus so we have to equate this with square of that okay so a squared equals B implies we now say rho u the whole squared Cp squared see how I am actually squaring things through rho u actually would indicate the mass flux so you want to just keep it together Cp squared tf minus t0 the whole squared divided by k squared equal to 2 q divided by k integral ti to tf as a matter of fact we should have thought about trying to get rid of ti in favor of t0 right here because we did that when we were trying to get a while getting B we should actually try to get rid of ti we will do it in a minute okay so that is what we should be looking at but now the cats out of the bag we will now try to figure out if you that it is not going to be very difficult for us to replace ti by t0 with without much error so that is something that I am going to show you I will talk about pretty soon so here we go how to simplify this a bit further so rho u the whole squared equals 2 k q divided by Cp tf minus t0 integral ti divided time to tf w dt now note that q equals Cp tf minus t0 right or this is actually the adiabatic energy balance so this this is the heat released in the chemical reaction which is essentially the difference the negative of the difference in the summation of standard heats of formation of products to the standard heats of formation of the reactants and this is actually the sensible enthalpy rise of the mixture between initial and final temperatures right and in fact to be able to notice this made a mistake I guess I guess so you have a Cp square tf minus t0 the whole squared so it is mainly to actually cancel this off that we try to replace ti by tf in a hurry back then okay so you might you might you might think both ways you should if you if you did if you got rid of ti there you should have got rid of ti here but if you did not get rid of ti here why did you get rid of ti ti there okay so we wanted to get rid of ti there because we want to cancel this and we could still go on with this okay so let us keep going on and see where we where we want to make a change so therefore rho u squared equals will now for the first time introduce this notation rho 0 sl squared this is basically notation we could basically say rho u is a constant in one-dimensional steady state right so rho u is the same as rho 0 u 0 okay rho u is also equal to rho infinity u infinity alright so the reason why we are saying so many things is the way we want to actually look at this as the laminar flame speed sl stands for the laminar flame speed okay is always relative to I should not say always but you have to specify this the laminar flame speed is relative to the unburned reactants okay when you now say rho 0 sl that means the laminar flame speed is relative to the unburned reactants that means to say you now have a flame that is propagating into the reactants and the question is you could be actually sitting on the flame and getting the reactants to come into you at the same speed or the other thing that you can think about is you now have the flame that is go propagating and then the products are actually flowing out you see now if you are actually looking at the flame speed relative to the products you will get a different speed when compared to if you are looking at the flame speed with respect to the reactants because the reactants and the products are having different speeds themselves therefore it is always quite important for us to note what the flame speed we are talking about and usually we are talking about a flame speed with respect to unburned still reactants all right but rho u is a constant so a less controversial term is what is called as a mass burning velocity okay so mass burning velocity or mass burning flux if you can you can you can call it different ways laminar mass burning flux is essentially rho u and it did not matter whether you are actually talking about it with respect to unburned mixture reactant mixture or the burnt products because it is going to be rho u is constant you see so we are talking about a flame speed then it is it is it has to be specified that we are talking about it with respect to unburned reactants so there we are so you could you could now write this as 2k divided by Cp Tf-T0 integral Ti to Tfw dt and we are now going to say so SL is equal to 1 over rho 0 k over Cp or 2k over Cp 1 over Tf-T0 integral Ti to T0 w dt now could approximate I am saying could I am not saying should okay we could approximate integral Ti to Tfw dt as integral T0 to Tfw dt without much error because this is an integral and what we are talking about is if you now look at how the w goes right we are looking at essentially the area under this curve well not exactly this curve this is this would be wdx we are looking at wdt this is w with respect to this temperature variation right and you can you can easily see that the w is actually 0 outside this region so you might as well actually start integrating from any temperature upstream you would not really care okay there is no hardly going to be any contribution of w there okay so therefore it is because it is showing up within the integral then it is possible for us to actually replace Ti by T0 otherwise it would have been much harder in this kind of situation like algebraic that would be much harder there is no way you can justify that but this is reasonable this is pretty good why would you want to do this you do not have to do this as I as I will show you soon but why would you want to do this what would we get out of seeing this you see that 2k divided by Cp 1 over Tf-T0 integral T0 to Tfw dt what do we have this is in fact very very similar to the first expression that we obtained phenomenologically except for two things one the square root of two factor that I have been saying we will get and as a and we are we are right there getting it starting from this point onwards we get this two there and then of course it is a square therefore you get a square root of two in the final answer the next is a little bit more important which is originally we simply said we had SL equals 1 over R0 integral 2kw divided by sorry did not have the two kw divided by Cp and the question was what was the W if you simply had a kw by Cp then we assume that the W was actually prevalent over the entire flame thickness delta and as if it was a constant all right but that is not very the case the W varies significantly within this distance in fact it is actually lying very low up until the reaction zone and then strongly increases and then decreases within a very narrow region called the reaction zone. So the major effect of the rigorous mathematical exercise is to recognize that W varies within the reaction zone and take its variation as it is so we are not fully replaced we are not really plugging in a W that is a constant and then the question that we had was what would be the constant and we now came up with this came up with this combination called W not infinity right where W not infinity refers to evaluating the W the reaction rate with reactant concentrations for upstream and the flame temperature downstream right that is what not infinity was referring to and that would actually give you the most the highest value that was there was possible whereas if you now have an integral like this what does this look like the reason why we wanted to substitute for Ti is T not in this integral was to actually see how what this looks like this is now beginning to look like more of an average you see so this is an average reaction rate between the two temperatures the limit temperatures T not for the reactants and TF for the products. So if it is possible for us to actually take an average reaction rate then whatever we got previously with a square root of factor 2 to thrown in is what the rigorous analysis gives us based on the Schwab-Zeldovich formulation right okay. So can we do a little bit better is it possible for us to not necessarily make this approximation okay and then we just plot on saying that let me actually see how this Ti kind of thing is going to work out the under root the limits of integral is Ti to TF up here yes thanks when you have too many T's this is what happens up we want to see if we can evaluate this integral that means we now have to explicitly take into account the dependence of W on temperature and what is that dependence that dependence is essentially given by the Arrhenius law where we are now saying W is now going to be a e to the minus capital E over RUT times concentrations of the reactants now keep in mind that the concentrations of the reactants are actually going to fall like this and the a e to the minus e by RT times the concentrations is now going to give rise to a certain variation with temperature which is a bit peculiar so as a simplification we want to bother only about variation with respect to temperature which means we will as a first step we will now say for a 0th order reaction W equals A e to the minus E over RUT and that is it of course all along we have been using W instead of Omega Omega is the number of moles per unit time per unit volume okay that is how the reaction rate is going to be whereas W is actually the number of kilograms per unit time per unit volume and therefore the difference is you know you know you know have to have a molecular weight thrown in here but we suppose that A contains that as well so let us not worry about that explicitly but whenever you are using W or Omega or any of these things you have to be very careful about the units okay and this is this is many times where you get into troubles with numerical calculations so keep this in mind we are still working on a mass basis and this is this is all we are going to have for a 0th order reaction that means we are not going to worry about how the concentration varies along all right which means we are what are we actually looking for since we have done the phenomenological expressions right we have we have some physical intuition about why what is what to expect if you are going to do only the 0th order reaction not worry about the reactant concentration did decrease into the reaction zone then all we are basically looking for is this is going to look like the average is the peak value W0 infinity divided by beta that is the correction that we are basically aiming for okay so is it possible for us to actually show that this average reaction rate is going to be like W0 infinity divided by beta that is what we did before when we said if we wanted to keep in mind the variation of W with respect to the flame thickness and say that it varying mainly within this small region and therefore we scale this distance by as delta divided by beta that is what we did okay then we got S L equals 1 over rho 0 integral k W0 infinity divided by beta Cp so we so that essentially we are looking for this average integral if you evaluate it as it is without replacing Ti by T0 is it possible for us to show that this will be somewhat like W0 infinity divided by beta is what we are basically looking for we are not looking for further corrections which are taking into account the reactant concentration decrease with the into the reaction zone and still for the corrections with non-inteluous numbers which we did before okay because those things are still not possible with whatever we are doing now okay. So now in this in this case see that E over Ru T Tf particularly Tf is typically a large value which is around 10 which means it is one order magnitude more than unity keep this in mind because of most hydrocarbon fuels you have ease of the order of 30 to 40 kilo calories per mole that is again a mixture of units you are not talking about Joules per kg it is calories per mole there so you got you have to make that conversion this is typically how the values are given and Tf is anywhere between 1500 to 2000 Kelvin or even upwards and Ru is equal to 1.98 calorie per mole Kelvin right. So if you now take these values you can you will find that this is of the order of 10 which is quite larger than 1 and we are going to use that fact so what we want to do is if I equal to integral Ti to Tf W DT right then this is equal to Ti to Tf A e to the minus E over Ru T DT what we want to do is we want to basically be looking at a variation in temperature only within the small region right that small variation is what we what we want to do so might as well actually look at the temperature as a departure from Tf rather than the actual value okay so when you now talk about departures then you start magnifying that value rather than look at high values and then varying well over a small range there. So set a new variable sigma as Tf minus T and then sigma i becomes Tf minus Ti and of course sigma is now going to go to 0 when T becomes Tf so sigma equal to Tf right and we also have to find out what T is like so T is Tf minus sigma equal to Tf times 1 minus sigma divided by Tf and you want to note that sigma divided by Tf is much less than 1 right. So sigma is a very small value it is a departure from Tf it is not going to be large because T itself is now going to it is going to vary only from Ti onwards to Tf and Ti is quite high very close to Tf in the first place so this difference is going to mean that T sigma is going to be very small when compared to Tf. So then how is your e to the minus e over ut go and get changed or transformed in terms of sigma is exponential minus e divided by Ru Tf times 1 minus sigma divided by Tf so that is approximately exponential minus e over Ru Tf times 1 plus sigma divided by Tf now these kinds of things are all sort of tailor made for approximations we should we should sort of get an intuition about how these analysis are done so if you now start thinking about a sigma is a small quantity then that is like a sitting duck for a binomial approximation okay so whenever you have a chance we approximate gay we do that in our lives most of the time by the way so we do a binomial approximation and then it also gives you this factor which we have a feel for from here right. So we get all these things isolated then then I is equal to you can pull out these things Ti to Tf e to the minus capital E sigma divided by Ru Tf squared dt whereas our integral is with respect to sigma so therefore we should write this as e to the minus e over Ru Tf integral sigma i to 0 e to the minus e over e sigma Tf squared d sigma now that is a little bit of a cumbersome thing over there so what you can do is let not very cumbersome it is possible to deal with this but still if you want to now call this as e over e sigma over Ru Tf squared and beta i is e sigma i divided by Ru Tf squared then i is a e to the minus e over Ru Tf Ru Tf squared divided by e its cup pulled out and 0 to beta i e to the minus beta d beta now this is so what are we expecting what are we expecting to happen what you basically saying is that we are looking for this integral which is what we started out with to approximate W0 infinity divided by a different beta than what we have used here fortunately okay and that beta was e times Tf minus T0 divided by Ru Tf squared Tf minus T0 is already here so we should be looking for something like Ru e divided by Ru Tf squared in the denominator to couple with this in order to get you this Zelda which scaling factor and then we should get a W0 infinity W0 infinity is essentially the W evaluated at the reactant concentration levels and product temperature levels we are now doing a 0th order reaction which does not depend whose reaction rate does not depend on the reactant concentrations anyway so we do not have to worry about the not part of the W0 infinity we do not have to worry about evaluating it at the reactant temperatures what we have to reactant concentrations what we have to be looking for is to evaluated at the product temperatures which is what this is so this is the reaction rate expression evaluated at the product temperature right and then this is there coupled with the Tf not Tf minus T0 in the denominator you are going to get the Zelda with scaling factor in the denominator so this all of all by itself is giving you for what we thought was the average reaction rate giving you W0 infinity divided by beta so we are fine so all we need is a unity out of this integral sure enough that is what we are expecting to get so this is going to be like 1 minus e to the minus beta i where we are now saying that beta i corresponds to sigma i and sigma i corresponds to Tf minus Ti which is a very small quantity right when compared to Tf therefore we are now going to get rid of it and say this is approximately equal to 1 and then from there on we should now be saying therefore SL is equal to 1 over rho 0 integral 2k divided by Cp a e to the minus e over Ru Tf that is W0 infinity for a 0th order reaction divided by Tf minus T0 times Ru Tf squared divided by e so e times Tf minus T0 divided by Ru Tf squared is the Zelda with scaling factor showing up the denominator of W0 infinity so we essentially are getting back the same thing again except for the square root of 2 that has come out again right so this is typically how you are able to retrieve the answers that we were expecting for this case what I want to point out just point out not really go through this because we are just spending too much time on this you should look up so this is looking like what we got before right you should look up how to actually do the rigorous analysis on taking into account the reactant concentrations then what that means is we have to now relax this assumption on a 0th order reaction and notice that W will now depend on the reactant concentrations so for a first order concentrate first order reaction you will have a concentration of one of the reactants coming into picture for second order reaction you are going to have concentrations of two reactants coming to picture so all those things have to be brought into account and then the next thing that we talked about was the lowest number effect so what you will find this you can actually when we did the lowest number for example we found that and also the reactant concentration you got this W0 infinity divided by beta power M for the where M is the exponent in corresponding to the order of the deficient reactant right and then you also had a lowest number in the numerator so we should be able to retrieve though those things if the 0th order reaction assumption is relaxed and non unity lowest number of reactants considered right we can retrieve the expressions obtained earlier on a order of magnitude basis here with a square root of 2 factor right so we can get this and then what would we suppose then so we notice that for let us say for for a nth order reaction right W goes is P to the n right because you will have the radius expression times the concentrations as many as the number of reactants are and the order the reaction depends on and for that much order you are going to have each concentration contributing a pressure and therefore you are going to have a P to the n for the nth order reaction for the pressure dependence right now what you have is R0 in the beginning right so R0 or R0 goes is P I do not want to say P0 because we are assuming the pressure to be constant it does not matter whether it is P0 or P infinity okay we are just talking about a constant pressure lower less a constant pressure deflagration here therefore your SL is going to go as P power n by 2 divided by P and by 2 coming from having W depend as P to the n and then under square root therefore you are going to have this as P to the n minus 2 divided by 2 right or you can say n by 2 minus 1 so n by n minus 2 divided by 2 so for a second order reaction second order reaction SL is nearly independent of pressure keep in mind order is a global quantity it is valid for a global reaction right or if you are able to actually represent a scheme of chemical reaction steps fundamental elementary reaction steps in terms of a global reaction so it does not have to be an integer so typically for most what we call a second order reactions let us say hydrocarbon gaseous hydrocarbon oxidation your order of the reaction is going to be somewhat like let us say 1.8 so it is not going to be exactly 2 right so the reason why I am saying nearly so we find that there is a weak dependence on pressure so if you now think about an n that is like about 1.8 you see you are going to have an inverse dependence on pressure right that means as the pressure increases the SL decreases okay that is in fact true that is what we actually observe but it is a weak dependence so we are now beginning to talk about dependencies of S on various factors so what we just mentioned was pressure which was obvious what we have not really worried about is how it depends on let us say initial temperatures okay and what we will see is this is primarily the dependence there and SL is going to depend on lot of other factors mainly through W okay so if W is going to depend on initial temperature it will depend through TF okay so we will now talk about these things in the next class.


Hello everybody, E here welcome back to another book review before we jump into this I want to wish a very happy book birthday to the book We're gonna be reviewing today, and that is the night will find us by Matthew Lyons my friend Amina Told me to read this one. She hit me up on Twitter and said E you got to check this one out Creep the hell out of me, and then she put me in contact with Turner Publishing and the author Matthew Lyons And they sent me a book. So this one This one right off the bat. It's turbocharged from the beginning the very first scene Draws you in and then there's I think there's two two chapters before things really kick off Less than I don't I don't know I want to say less than 20 pages, but that could be wrong I want to say yeah, yeah chapter 2 starts at page 23. Is that what I saw? I don't know hang on. Let me check for sure. No chapter 2 starts at page 21 And it is a race to the finish from that point the pacing in this book is Fantastic, what are the three things that I look for in horror if you're a fan of the channel You know it's dread it's pacing and it's really well drawn characters Those three things have to be in a horror story for me to pay attention whatsoever So right off the jump the pacing was on point Next the characters you guys know how bad I am with character names, but I can tell you right now all of these characters There's Adam. There's Chloe. There's Josh. There's Nate. There's Mickey and there's Parker I'm pretty sure that was an alphabetical order to so yay me anyways that these six characters It everything kind of happens at once this book took me off guard with the with where it went to because I'm thinking Okay, he's trying to build tension with these characters and show that we're gonna have maybe a the thing kind of thing or the Anxiety and the paranoia or whatever, you know Who's who's who who's the killer that kind of thing because I didn't read the back of the book? I'm gonna tell you right now I don't want you to read the back of the book either the description actually has a spoiler I feel it's a spoiler The description actually has a spoiler in it So stay away from the description go into this book completely blind the whole reason I read this was because Amina said it was it was fantastic She was not wrong whatsoever So the second one is the characters I knew every six characters in a very short period of time in the very first chapter I could tell the difference between each and every character that Alone is impressive But to then throw them in the situation that you that that you have that quickly and Continue the character development off to the side in the background so that you get to know these characters You may not like them, but to get to know these characters off to the side I love that kind of character development the not overt character development now with a Going back to you may not you might not like them This is almost like a Scott Smith's the ruins kind of vibe the books have nothing to do with each other This isn't the forest coming alive to well, I don't I don't want to give any I don't want to give any spoilers but I don't also don't want to get anything wrong, so let me stop there, but uh, this this isn't about This isn't about the same thing that the ruins is about we're not talking about creepy vines that kind of thing But with with this one you're dealing with characters that you may not like that you end up liking Toward the end and one has an irredeemable sin from the jump and he's then lion still manages to Manage to bring me in and it's like okay. This guy isn't too bad I kind of see where he was coming from even though what he did was Horrible now the very last thing is the dread the dread kicks off Like I said right off the bat so again the three things pacing character development and the dread Everything was on point with this one and I can find no fault whatsoever with it if I'm going to criticize it at all I Think maybe the character of Josh could have used a little bit more just a little bit Just a teeny tiny bit But I don't even think that I don't think that would have affected I don't think that would have made me love it anymore had I got more of Josh There there are certain characters in the book that you know exactly what their purpose is and they go in there But nobody is the same by the end of the book This this feels like right off the bat that it's going to be your typical Slasher and because it says on the back of it I'm going to go ahead and throw this out there for you. This is a super natural story There's it's like a Stephen King book you have your human horror and you have your supernatural horror You have both of those things So don't I don't want to set it up anybody's expectations thinking that they're going in for a legit slasher And then get thrown that curveball That would be the only spoiler that I'm going to go into is that but only because it says in this Supernatural thriller it says it on the back. Once again, don't read the description. I am really really impressed I don't know. Let's see here Matthew Lyons is the author of dozens of short stories with his work appearing in the 2018 edition of best American horse horse. No, sorry, best American short stories not horror edited by Roxanne gay and more Born and raised in Colorado who lives with his wife and their cat So if I'm reading that correctly, this is his debut novel. I'm impressed. I If I had read this Not knowing that it was a debut. I wouldn't have thought it was a debut I know that's kind of cliche, but he brings chops to the to the plate It's chops. No, no, okay Anyways, this this book is a lot of fun. I really want to express that There are some very dark and disturbing scenes and there is a lot of dread You don't know who's gonna survive You don't know who's gonna make it. You don't know how if they're gonna be intact when they make it out You don't know if anybody's gonna make it out. There's there was two times and I was like, okay The the people that are left are all dead Lyons has a true flair for the not really dramatic but for for I Want to say it like metaphor and simile. There's a lot of stuff in here that he you know He compares to other things using other things and some of them were absolutely brilliant. I thought The so come for the writing the pacing the dread the character them all that stuff But definitely read this one if you want a really fun Horror story set in the woods about a group of teenagers. That's where this book shines It takes this common trope kind of turns it on its head And there's well, no, I'm not gonna say that I almost gave away the part that I don't want to give away on the back of the book But anyways, did you get a chance to read or are you watching this one late? And you have already picked it up and read it. Have you read the night? We'll find us by Matthew the lions if you have Please let me know what you thought of it down there in the doobly-doo This is um on probably my top five for the horror for horror this year up there with Scott What's his what's his name? Scott Carson's to chill Um, there's there's a couple other ones, but it's easily in my top five for for horror that takes something overdone And does something completely new with it something engaging with it But have you read it? Please let me know If you loved it if you hated it tell me why you loved it Tell me why you hated it so that we can have a discussion But until next time I have been e you have been you this has been another book review I'll talk to you guys later. Bye. Bye


I opened up by talking about my experience at the Kobe Bryant Skills Academy. What I didn't tell you guys was there was a very special college counselor there. We didn't know he was special at the time because he lacked the physical stature or the resume of the other college counselors. But everyone who was at that Skills Academy, Coach Eastman, Coach Froshella, Procopio, they were all at this. We all knew there was something about this kid that was really special. He came up to me and he tapped me on the shoulder and he said, Allen, will you rebound for me because I don't leave the gym until I swish five Fritos in a row. Think about that for a second, gang. Swish five Fritos in a row. That's a pretty high standard. That young man was Stephen Curry. He will go down in history as the greatest shooter the game has ever seen. And it's not by accident. It's not by luck. It's not even because his dad Dell played in the NBA. It's because he's willing to hold himself to unparalleled standards.


This is stock number 21J92A. We are here at Summit Automotive in Fond du Lac, Wisconsin, your new and used Jeep and Jeep Grand Cherokee headquarters. Today we are checking out this super clean 2019 Jeep Grand Cherokee Limited. This vehicle has the award-winning 3.6 liter Pentastar V6 motor. It has been fully safe and inspected by our service shop. It has a fresh oil and filter change. All the fluids have been checked and topped off and this vehicle is 100% ready to go. Diamond black crystal is the color. We shoot all of our videos in 1080p 60 frames per second. So if you have HD capabilities on your computer, tablet, or a smartphone device turn them on right now because it is definitely your best way to check out the quality and condition of the vehicle before seeing it in person. And if you'd like to check out all the photos on this Jeep in the upper right hand part of your screen is a link to our website. Click that and check us out there. This one comes with the 18 inch painted and polished aluminum rims and it has Michelin Premier 265 60R 18 tires on here. These tires have right around I'd say 50 to 60% of the tread left on them. So good tread left on those tires, front fender, excellent condition. No dents or dings on there. It does come with the projector lamp headlamps, the projector lamp fog lamps, and the front bumper is in really nice shape. No dents, dings, or cracks on there. You get the chrome trimmed grille, the chrome trimmed fog light bezels, and the chrome trimmed Jeep logo. Did not see any dents or dings on the hood. Very nice and clean. Passengers side front fender is in excellent shape as well. No dents or dings on there. And the passenger side rim, no scuffs or scrapes. As you go down this side of the vehicle, take note of how clean the body is, how reflective and mirror like that paint is. We take these HD videos so if you are far away or even if you're close by and you just cannot make the trip down but you're still interested in purchasing the vehicle, you can see the vehicle, hear the vehicle, and of confidence in what you're looking at before you even get here. So that when you do get here, there's absolutely no surprises. And that's why we offer the Summit Auto Fast Pass option in the upper right hand part of your screen. You link right to our website where you can apply for financing, get pre-approved, see a payment quote, even appraise a trade all from the comfort of your own home. So when you get here, all you have to do is drive the vehicle, love it, and be all set to go. Back tires have just as much tread as the front tires and it does have those really nice mulpar black painted step bars on here. As we come around to the back of the vehicle, rear bumper is in great shape. No dents, dings or cracks on that. The gate itself is in really nice condition. I didn't see any dents or dings on there. Notice you do get the chrome trimmed 4x4 Jeep and limited logo. Back up parking sensors, part of the blind spot and cross path detection system and the chrome tipped exhaust. Storage area is very clean and you do get spare tire and jack tools back here as well.  It'll beep at you three times and then make its descent. Actually beeps at you a total of four times but on the third time it comes down. Notice you get the LED running lights on the tail lamps there. Rear bumper is in really nice shape. Rear quarter is in nice shape as well. And for full disclosure, this back rim is in excellent condition too. No scuffs or scrapes on there. Down the rest of the side of the Jeep looks really good. I didn't see any dents. I didn't see any dings. Very, very nice. You do get the heated power mirrors with the blind spot monitoring, built in directional signals, and the enter and go system.  Put your hand in there. It'll automatically unlock the doors. Inside you get the limited package with the black leather interior. There are no rips. There are no tears on the seats. Really nice condition. Very little to nowhere. Power driver seat with lumbar. Both these front seats are heated. Factory floor mats throughout. Auto headlamps, tilt and telescopic steering wheel, wood grain door trim, power windows, power locks, power mirrors, and memory driver's seat. As we hop inside here, you can see it comes with the seven inch LCD display in that this one has 13,307 miles. You get the grand Cherokee animation beginning there. You got a compass miles per hour digital speedometer right there. So that's all good. You can change all those corners to read whatever you'd like. You can do the digital speedometer there or you can do it like that. It's pretty cool stuff. Anyways, you get the heated leather wrap steering wheel, cruise controls on the right, Bluetooth and information center controls on the left. This one has the 8.44C radio which gives you AM, FM, and Sirius XM radio capabilities. It also has the factory navigation system on it and you can do your heated TTA steering wheel controls there. You can also check out your backup camera at any time and then you can also do your apps here including projection manager where you can project your cell phone to the screen. We actually did a demo on Android Auto with an 8.4 but if you have Android Auto or Apple CarPlay, you can project it to the screen. Then it's like you have a different navigation system on your screen such as Waze or Google Maps. Pretty cool system. We did a demo. Check it out. It's in the upper right hand part of the screen. Click that and check us out there. Down here is your more tactile climate controls including your dual climate control, volume and tune controls. You can turn those parking sensors off, your start, stop capabilities, eco mode, sport mode, and your stability control. This one does have the Quadra Track 2 system with the different terrain settings, snow, sand, auto, mud, and rock as well as a neutral setting and then you have downhill assist control four-wheel drive low. The neutral setting you can flat tow this vehicle if you want it. The other cool thing about this radio is that it has the off-road pages which has a couple different features to it that I'll show you. While that's loading it does take a second to load. You get the SOS and assist buttons, home link buttons for your garage door security systems and lighting systems. The headliner is in nice shape and the passenger side seat no rips or tears. On there this vehicle has never been smoked in and smells very clean inside. Here are your off-road pages you can see you have your steering angle there which changes as you turn the steering wheel. You also have your latitude, longitude, and then you have your altitude there. You can do the pitch and roll, accessory gauges which is coolant, oil, battery voltage, trans temp, and oil pressure, and then with your select terrain as you turn the knob on the bottom it'll change your settings up there which is pretty cool. Anyways we'll check out the back seats and then we'll start it up and take a quick look under the hood. Back seats are just as clean as the front seats. No rips or tears back here it does have the latch child safety system. Seats are in excellent condition doesn't even look like anybody's ever sat back here.  Child safety locks on the back doors and we'll start it up and take a quick look under the hood. I would personally like to thank you for checking out the video today and hopefully from this HD video you will have been able to tell just how clean this Jeep is all the way around inside. Now under the hood we have the 3.6 liter Pentastal V6 motor and the base very clean runs very smooth. Once again this vehicle has been fully safe and inspected by our city shop as a pressure and filter change all the fluids have been checked and topped off and this Jeep is 100 percent ready to go. And to see more pictures of this Grand Cherokee or one of our other 450 new and used cars, trucks, SUVs, minivans, Wranglers, half tons, three quarter tons, one tons. You name it we got it go to our website right there at www.summitauto.com. Full pictures and descriptions of every single vehicle from two locations all at www.summitauto.com. If you'd like to check out more HD videos you can go to www.youtube.com slash www.summitauto.com. Remember to like, subscribe and share on this video and all the videos that you see there. In fact in a second you will see a link to subscribe to our YouTube channel on your left. A link to more Jeep Grand Cherokee videos like this one I'm ready if you have not been on our website on the bottom link to this vehicle on our website click those checks out and we really look forward to helping with this extremely clean 2019 Jeep Grand Cherokee limited in diamond black metallic. Thanks again for checking out the video.


And he's going to speak about an analog quantum variational embedding classifier. Okay, my talk is our analog quantum variational embedding classifier. And it's a collaboration between our, between me and these courses. So, in our 2019 paper, Havlik proposed and demonstrated a variational embedding classifier based on a gate-based quantum computer. And in this IBM work, the data X is embedded as quantum state in a helper space by this circuit, where u5x is a data-dependent entangling gate, and each are the hard marks. So the circuit involves some trivial initial state to some embedded state. And our key concept here is the decision operator W, whose expectation value gives basically a binary classification. So it defines a hyperplane separating two classes in a helper space. This is an illustration of one qubit helper space, Bloch sphere. You're embedding some data into some points on the Bloch sphere. And this data is labeled. And you can find some operator to basically separate these two labeled data sets. And we can determine the decision operator in a variational way to best separate the two classes. Equivalently, we can fix in W and apply a variant circuit on the embedded quantum state. But the decision operator in the IBM paper is not a general solution. More general operators can be found in other literatures such as CIS Lloyd's 2020 paper. So in this 2020 paper, CIS Lloyd's proposed quantum metric learning where the user general decision operator, which works for a general multi qubit case. And this algorithm does classification based on the distance to some average density matrices, which are obtained by averaging embedded quantum states for each of the labels. And it's based on a parameterized QAOA circuits where the rotation angles of the gates are the circuit parameters. And most importantly, the non-linearity needed for the classification in this case is not purely from the quantum part. So following this thread, here are some details of the CIS Lloyd's algorithm. The data is transformed by some neural network before being fed into some QAOA circuit, which is basically some alternating single qubit and two qubit entangling gates. And some of the parameters are filled with the transformed data. And the rest parameters are taken as variational parameters to optimize or train the system. And the density matrix, the rho and sigma, they are the ensemble density matrices corresponding to the two classes. And the decision operator for binary classification is either rho minus sigma or pi plus minus pi sigma. And pi plus and pi sigma are the projection operators of rho minus sigma. Each decision operator will work, either one will work. And the expectation values of this decision operator gives the classification. And you can also visualize the clustering of the embedded quantum state by the overlap matrix, which is basically squared in the product of embedded states. Now let me talk about our classifier. Our work and the previous classifiers have some similarities. But comparing with CIS Lloyd's classifier, the defining features of our classifiers are, first, we removed the neural network. So the nonlinearity in our classifier is arising completely from the quantum part, from the nonlinear dependence of the final state on the schedule parameters. And we also replaced the gate circuit with an analog quantum computer, such as a annealer. And we also extended the case to multi-cubed case using a simple distance-based classifier. We use AO2 norm, basically. So the motivation is trying to answer two questions. One is could the quantum part alone do the heavy lifting that is providing the nonlinearity needed for classification? And another one is will and analog quantum evolution work. So here is an illustration of our algorithm. So the data, reshaped into a d-dimensional vector, will be transformed into some schedule coefficients by a linear transformation matrix. Then the schedule parameters define some schedule function, which are just some driving on the qubits, and they are coupling. And in here, we consider an annealing setting with independent control on the poly terms. So the system starts with a transversal initial Hamiltonian, and ends at a final longitudinal Hamiltonian controlling from the schedule function. And the system's quantum state will evolve from some trivial initial state that's ground state of the transversal initial Hamiltonian to some embedded final state. And the nonlinearity in our classifier is different from that in the neural network. So in a neural network, the nonlinearity is actually from the activation function, such as sigmoid function, used in the network. But in our case, the nonlinearity coming from the nonlinear dependence between the embedded quantum state and the Hamiltonian parameters. So if we just consider some data in 2D plane in some real space, that's points in some real space, then a neural network basically transforms the points from some real space to another real space. But in our case, our classifier transforms the data from some real space into some hearboard space. So it's kind of a new type of neural network. And we characterize our algorithm by numerical simulation. And the actual schedule in our simulation is actually a digitized version. And you increase the number of points, you can convert to the continuous case. And we tested our classifier on some common linearly inseparable data sets. That's basically the industrial standards for the machine learning, such as concentric circles, spirals, and missed digits. And these are basically not linearly separable. We need some nonlinearity to classify them correctly. And our classifier works for all the above cases. And I will take the concentric circles and missed cases as examples. So for the concentric circles, it's basically some points distributed around some concentric circles with some nonlinear gap separating these different classes. And we can basically visualize the clustering of embedded data of different labels with overlap matrix. For overlap matrix, whose matrix elements are basically squared in the product between embedded quantum states. And for these illustrations, these are the labels, circle one, circle two. That's the label for the concentric circles. And each pixel represents the overlap between the embedded states. We can see that before the training, the overlap within the same class is basically the same magnitude as overlap between embedded states from different classes. So the diagonal, block diagonal parts represents the overlap within the same class. And the off diagonal squares here represents the overlap for embedded states. It belongs to different labels. And we can see that after training the overlap within the overlap for the embedded states within the same class is not much larger than the overlap between different classes. So there is basically some clustering behavior involved here. And we can also basically visualize the separation of different classes by a trained classifier using some time evolution of the overlap matrix. And we can see that the aggregation or clustering behavior indeed shows up during the time evolution caused by the annealing Hamiltonian. And in this sequence, the s equals zero case, this one, is the starting of the annealing. So basically, in this case, the whole system is just at the initial state, at the trivial state. So the overlap between any embedded states are equal. And with the trained Hamiltonian, with the trained classifier, the annealing Hamiltonian will lead to some deep data dependent evolution. So the initial state will be evolved and finally settling down at some final embedded states. And we can see after the evolution or the embedding process is finished, for the embedded states, it shows up this clustering behavior. All the embedded states within the same class have a strong overlap, but overlap between different classes are very weak. And we also checked the influence of the number of qubits and the number of labels on the performance of our classifier. Taking the concentric circles as an example. So in these two figures, it shows the train or test accuracy as a function of number of qubits for two, three, four labels or circles situations. We can see that given the same number of qubits, when you're increasing the number of labels or circles, like two circles, three circles, four circles, the accuracy of the performance decreases. And when you're increasing the number of qubits but fixing the number of labels, the accuracy can increase when you increase the number of qubits. And we can see the scaling on the test data and the training data is similar, suggesting a good generality on the unseen test dataset. And these are some results on the concentric circles dataset. And we also tested our classifier on NIST digits on both binary classification on digits three and five. I kind of distinguish this by my eye, but this classifier can't hear. Or digits one, three, five. Relabel classification case. And just as usual, we also visualized the clustering of the embedded data with overlap metrics. We can see before training the overlap within the same class is basically as strong as overlap between different classes. But after training the overlap within the same class is very strong, but the overlap and the overlap between different classes are very weak. So there's still the aggregation or clustering phenomenon. And again, we also do the visualization by checking the time evolution of the overlap metrics. At the beginning, it's all at the same state. So overlap is uniform. After the time evolution induced by the data-dependent Hamiltonian, we finished the embedding and the embedded data also shows clustering behavior. And here are some summary of our binary and binary classification tasks. We can see that increasing the number of qubits can basically boost the performance on both the train and the test accuracy. So as a summary, we proposed an analog quantum variational embedding classifier using an analog quantum computer instead of a gate-based quantum computer. And the non-linearity in our classifier is completely from the quantum part. And we also extended the variational classifier to multi-class case. And we tested our classifier on linearly inseparable data sets, such as concentric circles, spirals, and nest digits. And the performance of our classifier can be improved by increasing the number of qubits. And as a lot look, we also tested some other Hamiltonian form, such as XX plus YY interaction Hamiltonian. You can find the details in some poster that will be presented by another colleague from our group. And probably we can also try to experimentally realize it, at least for a single cube of the case. That's probably the easiest to do. This work is supported by DARPA. Okay, that's my presentation. Any questions? Thank you for the talk. We can move to the question from the audience. Yes. I didn't completely follow the design of the algorithm you implemented using the annealer. But could you explain the motivation for why you think or do you think that it has the potential to be better than the algorithms for the classical computers in some respect? The nonlinearity part will be not classically simulable for a larger system. So that's the main argument. It could provide some nonlinearity that's beyond the catch of a classical system. But whether it will be better than classical classifiers, that's an open question. So the nonlinearity is hard to simulate classically, but there is... So in order for the algorithm to have a better performance, the nonlinearity should not only be hard to simulate classically, but also help the specific way of the nonlinearity should help in the generalization or with the performance of the algorithm. Yeah, that is the point that maybe a large quantum system can have better expressivity, as some may be clues from a tensor network or something like that. The quantum system has the potential to have a better expressivity. Okay, other questions? There's a question in the chat. Can you read the question? The question is, is there some obstacles to testing this approach using a quantum annealing device instead of an analog quantum simulator? Actually, the Hamiltonian setting we use here is indeed a quantum annealing device. It anneals from the initial transverse Hamiltonian to some final longitudinal Hamiltonian. It's exactly a quantum annealer. So there will be no fundamental difficulty to try it on an annealing device. And since annealer is basically running in some continuous mode, so I call it the analog quantum computer. It's some knowledge I think appropriate. Okay, was there some other question from the audience? Yeah, thank you for the talk. It was certainly an interesting approach. I have two questions that are kind of related. Namely, on slide 14, you show the performances of the classifier over the number of cables I think you used. It seems like that for the three-level problem, it seems that the performance kind of seems to converge to a value that's lower than one. Did you try for larger systems and eventually went up to one, or does it remain at that level? It is already very time consuming to do. We need a bigger computer and a better numerical simulation code to push further. Okay, so the second kind of related question, if I may. Most universality proofs for neural networks that I'm aware of or even all of them, they kind of rely on the trainability of the weights that you apply after applying the nonlinearity. So do you have any trainable parameters in your approach that you use after the nonlinearity or only before the nonlinearity? I don't quite get your question. Could you explain it again? Yeah, so in the neural network, basically wherever you draw an arrow, you have like a trainable weight, right? Yeah, yeah. Our weights are all in this part. Exactly. So do you have also, where you drew the arrow that you labeled as Hamiltonian, do you also have any trainable weights in that part of the algorithm? The Hamiltonian part, we don't have variational parameters to train on. All the parameters are just defined by this transformation here. Convert the data into some schedule parameters. So all the weights are here. We use a very simple setting. Yeah, of course you can add more variability features into these settings. Yeah, but we just choose the simplest possible case. All right, thank you. Any other questions? Okay. Another, yeah? Oh, okay. So, thank you again. You're welcome. So have you thought about any, if that's a universal classifier, should it always work or is it kind of like an algorithm that seems to be working from your numerical experiments but like mathematically we haven't analyzed it yet? Oh, going from numerical experiments to computational science, maybe the computational complexity, I think it's a big leap. Yeah, we don't have, we haven't touched that part yet. All right. Thanks. And the other fairly brief question is, I think I was on slide five where you explained actually Seth Lloyds, I'm not sure if I can ask you about that. They use like this ResNet part and like for the feature extraction, I assume. And do you know though if those, if in their approach, if they freeze those weights or do they train those as well? They use some pre-trained ResNet but making this part changeable, variable, yeah. Okay, cool. Thank you. If there are not more any questions, I'll thank again Dr. Yang for his talk.


And also using other parts of Africa, four people, including a baby, have been killed and at least 12 wounded in Goma, eastern democratic republic of Congo, in a protest tagged a day of dead city. The protest was against the surge in criminality. Demonstrators also protested rather against the alleged presence of Rwandan police in Goma which has been denied by the authorities. Protesters invaded the main streets of the capital of the North Kivu province, but during Rwanda, setting fire to tires and erecting stone barricades on the roads, police fired live ammunition and used tear gas to disperse the crowd. Spokesman for the province's military governor, General Sivien Ekenge, told reporters two law enforcement officers were killed and two seriously injured. He vowed to punish those behind the killings. Notified about fresh news updates