to manage 60,000 nodes in a cluster. This also means that we run about 1.8 millions containers or part in the Kubernetes world. So we will kind of show you how we achieve that. Of course, not everyone need that larger cluster. But for our cases, we need a larger cluster to manage both VM and containers and other work nodes. So here's the agenda that we have prepared for our talk. I will start with the introduction and the background and tell you why we're doing this and what it is, the architecture project. And then Ying Huang will take an hour and talk about more of the changes that were made to the Kubernetes and what optimizations were made to Kubernetes to achieve 60,000 nodes in a cluster. She will also show some of the performance test results and analysis. Hopefully, in the end, we have time to answer questions you may have. So with that, I'll just give you some of the big background, who are we, and then what is the architecture project. So we are part of a cloud lab at FutureWay. FutureWay technology is a R&D organization that focuses on the open research, open innovation, open standard, of course, the open source project. I'm currently leading the cloud lab. And Ying Huang is a principal cloud architect in our lab. So by the name of the cloud lab, we focus on how to manage, to build and optimize the open source cloud software or cloud open source projects, such as Kubernetes, OpenStack, and cloud containers. So we do a lot of cloud containers on that. One of the projects that we did a couple of years ago is called Centaurus project. Centaurus project is a Linux Foundation cloud infrastructure project. We donated to Linux Foundation around December 2020.  But internally, we actually started a project since the beginning of 2019. So it's kind of a three years old. So today, the Centaurus project consists of a group of sub-projects. And the first project is called Octos. And this is the project where many folks are today in this talk. And Octos is a large-scale computing cluster management systems for that. And we will talk more on this. The second project is MISA. MISA is a network project. We call cloud network project based on the EBPF and XDP technology. MISA is we're using this to support the network, configuration network provisioning for the Octos. We actually have two sessions related with MISA. And one is tomorrow, and the one is on Thursday. If you're interested in those two sessions, you can search, look up the schedule by the name of MISA, if we have two sessions like that. The other two projects are on the Centaurus project group. And one is for AI, and the one is for Edge. And those are kind of out of scope for this talk. But if you're interested in the Centaurus project as a whole, and you can go to the website called centauruscloud.io.  We also have a booth on the first floor. So if you're interested in Centaurus as a whole, you can go there. And we have a demo for you to build a Centaurus cluster and manage the VMs and the containers. So why we're doing the Centaurus project and what is Octos project at all? So in fact, this is mainly driven by our current infrastructure platform challenges. And as many companies, we're using customized OpenStack to manage the VMs, and we're using Kubernetes to manage your orchestrated container-based applications. However, we encounter some scalability issues for both platforms. There are two challenges I can stand out that get us to working on this Centaurus project. And the first one is we have a challenge to manage a cluster. We want to manage a cluster that more than 10,000 computer nodes in the cluster, minimal on that. And just that we today, our current platforms manage 1,000 and 2,000 computer nodes per cluster. Now for our public cloud services, we offer public cloud services. And that we have to deploy and manage a lot of OpenStack clusters. And of course, this is a high cost to us for managing perspective. Now the second challenge we have, we have a customer ask us to provision more than 5,000 VMs within three or four minutes. And we can do this with our current platform. And that's where we get us started. OK, we need to build a new platform or unify the platforms for that. So that's where we get to start to do Centaurus. Now secondly, we also want to manage, unify our platforms for to manage VMs, our platforms to manage containers, where our platforms to manage a serverless. We want to combine two into one. Now only that we reduce the cost, but also driven by a customer request that they want to deploy hybrid applications with a single API, which we cannot do that today with our current platforms. We currently have actually three platforms for each of this. Platform for VMs, platform containers, platform for serverless. When I see a hybrid application, I mean that the application is designed so that part of the application or components, for example, like back end, that run in dedicated VMs. And part of the applications or components running as a container or with assembly, people using a web assembly, that can be around anywhere. So they want to do this, deploy this hybrid application into one single API or one shot, which we cannot do that today. And so that's become a goal for our Centaurus project. Additionally, we have a customer expressed interest that they don't want to manage Kubernetes cluster. And it's become very complicated. People that we experience, it become very popular, everybody knows it, but it's become very complicated. They don't want to manage the other cluster themselves. But they want to use the API to manage Oxford application. And this is a declared API very easy for customers to use. But that means that for us, we have to build a truly multi-tendent Kubernetes and provide isolation to the customers if multiple customers, multiple tendons, using the same cluster. We have provided isolations in current Kubernetes standard that we actually don't support it. And last but not least, they're driven by our AI platform for coordinated ML trainings, for federated AI trainings, whatever it is, they require a platform to manage the nodes, not only in the cloud, but also on the edge, so that they can push their training job in the cloud or on the edge, and it depends on the scenarios, the applications. So that become a goal for the centralized project also. So that's a highlight of why we're doing this project and some of the background we're doing this. Now, let me kind of introduce a bit of the architecture project itself. As I mentioned, on the centralized project, and the architecture is for compute, we call compute project, that we call a cloud infrastructure platform for manage very large scale computer clusters and orchestrate different type of applications. It's based on Kubernetes, and we drive from the Kubernetes, but we make it a lot of fundamental change, design change, and architectural change to Kubernetes. And the result of that is Oculus. So Oculus project is based on the Kubernetes. I want to go through each of the bullet point because I will talk about each of this high-level change that we made in the following slides. The fourth is, first, is architecture. Here is a well-known, everybody knows Kubernetes architecture. Where you have API server, you have EDCD, and store all the objects that are created by the customers. And then you have a scheduler running the schedule, allocated which part of the running on the which node, and then you have a bunch of controllers running to finish your deployment or finish your workflows. And of course, you also manage a list of the nodes in the clusters. We take this architecture, and we split in the two parts. And the first part we call Tenton Partitions, TP, Tenton Partitions. And that partition has its own API server, EDCD running, and but only store the Tenton-related objects. So it has most of the controller running, like a replica controller, and jobs, demon set, or staple replica set. So that's what we call Tenton Partitions. And that's the partition where you receive the request from the customer for deployment or orchestrate the application. Now, the second part of the split is what we call resource partitions, called RP, where it doesn't have any schedule running, but it has its own API server. It has its own EDCD, only store the resource-related objects. In this case, many is the node. So you're running only the node controller within the partitions. So you manage a lot of the node information. All the node steps, we report back to that API server of that partition, not the TPs. So that's actually, that's the high-level idea of the scale-out architecture required is split partitions to the two. Of course, there are many ways you can increase the scalability of Kubernetes, but we talk this way because we want to build a platform that manages not only the containers, but also VMs, and they're able to scale more than 50,000 computing nodes. So InHuan actually will talk about more about how to detail, how this design, and then on the optimization we made to it. So that's actually very simple at a high level. Of course, there's a lot of detail figure out, and Huan Yin will show some of the detail information with you. The second change we made in the Kubernetes and it now becomes a part of our architecture is the multi-attentance. The first thing we did, we introduced tendon concept, introduced the tendon objects or tendon controllers. So now before any customer using the shared clusters, architecture clusters, we have to create a tendon for them. We have to create a registered tendon for them. So when you create a tendon, we create a space, a quick logic space. So on that space, all the objects created by the tendon will be in that tree of the objects they store in the EDCD. So this is how we isolate the resource between the tendons. And so we provide the resource isolation for the tendons. We also add a metadata field called tendon to almost all the objects in the Kubernetes, that means including the part. So in the part, when you deploy part or application now, you have to specify which tendon it is. And that will distinguish you, that part, with different part. Similarly, we also introduced the network concept and the network CRD and the network controllers for the network isolation. And most of you already know that in the network design in standard Kubernetes, it's a flat network. Every part in the clusters can talk to any other part. Of course, you can use by default. Of course, you can use the network policies to specify which part can talk to which part. But by default, they can talk to each other because they are on the same IP range. So we change the model and we introduce the network objects. So we allow tendon to create the own network. And each tendon can create as many network as they have. So each network has its own IP address, has its own DNA server. So when you create a part, now you have to specify which network it is within that we are located in that network. So by default, different network, different tendon by definition, because they are not in the same IP range. So they don't talk to each other. And that's how we isolate from network perspective the part communications, which provides more strong isolation than the network policy. Of course, within each network policy, you still can use a network policy to specify which part to talk to which part. So the third major change we made to support the unified systems we call the runtime infrastructure. So we abstract the part concept further to including VMs. Now we have a VM part and a container part. In the future, we plan to support, for example, WebAssembly. So we're able to support WebAssembly part. So with that in the part definition, now all the Kubernetes scheduler, controllers, and all workflows, they just work with VM as well. So you can just orchestrate the VM just like containers. But in order to do that, and you have to make a change to unify the runtime on the node agent side. So on the node side. So we extend the node agent to not only support the container runtime, we also support the VM runtime. So we add the VM runtime support on every node on the node agents. And that's where we're able to unify this. But that's transparent to the customer. We extend the CRR, the container runtime interface to including a lot of the fail, the VM required. So we extend that definite interface to run that. We also introduce some of the action objects. And that's also new for the containers, for the VMs. Because you can do some of the operations on VM. For example, you can bootstrap VMs. You can make a snapshot for the VMs. You can detach or attach a device to the VMs. Those are not available for containers. So we have to introduce that. The act will call action objects. So customer can manage the VM through the Kubernetes API perspective. So that's the actually main change we made to the Kubernetes. And again, the result is the octos project. And they're able to manage 50,000 or 60,000 computer nodes in their clusters. So with that, I think I will hand this over to Yinghuan. She will talk about more about how we make the change, how we support assisting 1,000 nodes for clusters. Thank you. Introduction. OK. So I'm going to talk about how we scale out octos. It's actually a scale architecture based on top of Kubernetes. And what kind of optimization we have made to make the cluster to be able to manage 60,000 nodes. So this is the architecture for Kubernetes. We are already very familiar. Dr. Xiong already showed that before. And this is the same. And we split doubt to partition. Tendent partition and resource partition. So resource partition is specialized at managing nodes. So we can see here it has its dedicated ETCD and API server. Kubernetes talks to API server in its own resource partition. So its report is node healthiness. So we leverage resource partition to manage the node healthiness of the cluster. And in the tenant partition, we are only focusing on customer workload. It has its own ETCD instance API server. And it has a scheduler. Scheduler gets port information, the customer request, from the API server of the tenant partition. And it gets the node information from the API server of the resource partition. And then it determines which port it want to put on which host. So by this way, also Kubernetes in the resource partition, it reports its node healthiness to its API server in its own partition, the resource partition. And it also downloads the port assignment to its particularly host from the API server of the tenant partition. So this way, we successfully split out the request, different workload management by the nature. We separate the node management request to resource partition and the customer request to tenant partition. So the relationship between the tenant partition, resource partition, they are many, too many. And they can scale independently. And for now, we support multiple tenants per tenant partition. But right now, we are not supporting cross tenant partition tenant. So each tenant has to belong to one tenant partition. What's the benefit? So tenant partition, we call it TP, resource partition, we call it RP. So they have more specific workload. And we are focusing. They have their own focus of workload. We are easier to make individual performance improvement in different partitions. And they are independently from each other. What is benefit-based bond? They can scale independently. We can have 10 TP partition and only one or two or three resource partition. And each tenant partition, they actually can take all the resources. From multiple resource partition. So arbitrary scale we have can potentially make one tenant partition to take all the resources from multiple resource partition, as long as we were able to handle this workload in a single tenant partition. OK. In addition, each of the tenant partition have its own scheduler. And the scheduler work independently in its own tenant partition. So they can provide multiple system throughput. OK. So we have done some optimization, mainly focused on several areas. We're trying to eliminate the unnecessary ETCD rates from API server. We're trying to regulate client list operation. We will tell you why this is important later. And we also did the improvement on the watch mechanism. So for those of you who are familiar with Kubernetes, this and watch is a very important operation in Kubernetes. And it also becomes a major bottleneck of the performance. So we will present our improvement with a performance test result together. First of all, this is what we're going to talk about. The performance data, the benchmark tools we're using, and the critical changes we have made for performance improvement. First, this is our final performance data. Actors 1.0, 0.9, and the compare with Kubernetes 1.21. So the first nine tell us the cluster size, how many number of worker nodes we're managing during our performance test. The second nine tells how we partition this cluster. So the first number is tenant partition, second number resource partition. So in our 1.0, we were able to go to 60,000 nodes by three tenant partition, three resource partition. And before that, we tried the arbitrary number of combination for tenant, for TP and RP, and trying to see what's a good combination and how we can reduce our management cost. The third nine, the pod creation request rate during the test. There are two numbers. So the first number and second number. So for whoever is familiar with the perf test tool, there are two phases during the perf test. The first phase is called a saturation pod creation phase. So in this phase, it's trying to use a large number of small pod, trying to take over to make the cluster reach full capacity, meaning 30 pods per host. And on the second part, it uses a relatively small number of pods. But each pod, they take lots of system resources. So it's guaranteed almost one host can only host one pod in the latency test phase. So the first QPS is the request we're sending per second for the saturation test phase. The second number is the request rate we're sending in the latency test phase. So in Kubernetes, the default test QPS is 20 and 5. So in the saturation test phase, they create 20 pods per second. In the latency test part, they create five pods per second. We actually, during our test, we are saying this QPS is very important in the actual latency data they are reporting. So meaning the more number you are created during the test, the higher latency you are getting, which is not as ideal. Because we want to support a big cluster, you are supposed to get more customer, right? So you cannot have a very low QPS when your customer is growing. So the latency pod, startup latency data here, we have P50, 90, and 99. Those is just a number for the latency pod when we create it's in the second phase. Because this is a criteria used by Kubernetes first test to determine whether their saturation test is successful, the latency test, whether it's successful. So they use the five second as the standard. But we have some number is higher, some number is lower. But roughly as long as it's around that five seconds, we think it's a successful test case. So from this, you can say we're using for actors after we scale out and after our several optimization, we have much better QPS and the relatively comparable pod startup latency. So the benchmark tools we're using, we use the building kubemark to simulate the real cluster because the real cluster of 50k, it's very expensive. So for the Holo node, it's used 0.1 CPU for each node. So we were able to reduce the size. But in the real test, we use a 505 number of machine to do a 50k node simulation. And we adopt this Kubernetes proof test tool because we need to make some changes. It's the industrial standard proof test tool from Kubernetes. It's called cluster loader tool. There are many tools, but this is the one we're using. It's from Google. So if you need an explanation, please let me know. So we have to make some changes to cluster loader tool. So first, because we support multi-tenancy in actors, so we have to make some changes, which enables us to, for each our test, for each tenant partition, we use one separate proof test process so that we reduce the impact that if your proof test tool is slow, you cannot have high throughput in your actual cluster. So we use a multiple test process. And we increase our QPS. So after increasing, you can see the total amount of running time is reduced to like 15% of the original runtime, which hugely saving our testing cost. The money you spend on Google GKE is huge if you have to run those tests again and again. And we have to make minor changes to the proof test tool because we detect there are some customer introduced issues just for the proof test tool. So that's why we're calling it like a regulated customer behavior for this part. So we did several critical changes based on our observation. So the observation is some factors that are factor of Kubernetes performance. First, read and write from into each city. It's big impact. And the least large amount of data from API server is also have huge impact. So most of our changes are around this area. So there are some data. First of all, this is a change ported from Kubernetes. So I want to mention that because this gives some indication how we should perform those performance improvement. So we ported from Kubernetes because when this change was not there before we fork Arktos out of Kubernetes. So they introduce this change later after we fork it out. So during our test, this test is performed on 1TP-1RP with QPS 105. So here's a cluster size. Before this change, for this latency number, it's impossible for us to claim we are supporting 50k cluster. And after this changes for 15k, we are below the bar of successful run. And we were able to go further. We increased the cluster size to 25k after this change. So this is the latency data. Sorry. This is the changes in the node controller it uses watch instead of list for port. So as we already said, the least large amount of data is a huge performance impact, and especially for pods. When no pods has the most number of objects. So it reduced the list of pods by 15%. And this is the performance improvement we got. So from that, we're encouraged. So we did our own optimization. So we make some changes to Kubernetes. In Kubernetes, when it's trying to patch it always reads, I mean, in the original Kubernetes, or always trying to read first, trying to get the latest node version so that it can patch. But we said, you are consistently watching node. You don't necessarily need to read it again. So we just use the watched node to do the patch. And using our observation, there's almost no conflict. So again, so with the one TP-1 RP 25K, so now we are able to support 25K. So the latency has improved about 20%. So the get node, this is the count that we were able to reduce the number of gates. Because our change was saying, if your patch failed because of the confliction, you will have to read. And then patch. But so the get is this number means there's almost, in our test, there's no conflict. So it makes sense to use watched data to just do the patch. So third one, so as we said, the perf test tool is have some issue. During its latency test time, it does a list per pot. It's trying to create. So there's a whole bunch of lists. So instead of doing that, we said, you should just use one list. Don't do the particular list. Just do a general list, and you watch from there. So we were able to reduce, because this list is actually relatively small, because it's only this particular pot assigned to this node. So it's very small. However, the large number of lists also have big performance impact. So by reducing this, we were able to go to around five seconds for our P99. So this is 25K cluster. So now we can claim we support 25K for our single cluster by one TP1 RP. Then we go further. We want to do two TP2 RP, see whether can we support a bigger number. So this is a change. We did some watch optimization for this. Before that, right after we made the previous optimization, we were able to support 25K by one TP1 RP. So we increase the cluster to two TP2 RP and goes to 50K nodes. Of course, we have doubled the QPS. And we say at this point, our before P99 is relatively high. It's compared to the standard of per test. We cannot say we support this big cluster. So we're looking to say, what is the problem? What is blocking us from supporting 50K nodes? So here, we give you this event watch optimization. What is that? Why it has a big performance improvement after this change? Here. OK. So I'm not sure. This is a watch mechanism in API server. How many of you are not familiar with this? Should I explain further? Or I will start from this. OK, so if you have questions, please raise your hand. So for Kubernetes, listen to watch. So we know that each watch has to be, it only have a lifetime of several minutes. After several minutes, it renews its watch connection. When it starts to watch, it has to provide a resource version. It is one to watch from. So when the API server gets this resource version, so it will scan it event catch and find what is the event your resource version one, you are watching from to our latest resource version. So we call it RV2 right now. So it has all those events there. And not all those events should be sent to the client. So it goes to the event processor and use the watch predicates to determine whether these events need to be sent to the client. Why this is a problem is because in the client, it only use the event latest resource version to update the resource version it's maintained. So if it does not get any new events, it will keep using its old resource version. So when our cluster goes bigger and the chance of each node get a pod or get an event is very slim. So there's a non-pure time that you are not getting any new events. So your resource version gets older and older. And then your elite event is going to be bigger and bigger. It will cause the API server save fuel time to scan and filter out all those events. So by solving this problem, we introduced a bookmark event. So this is not new. Bookmark event is already supported by Kubernetes. In this client library, it will say, if I get a bookmark event, I'm only use this event's resource version to update the resource version I'm maintaining. So which means in the next watch session when it's trying to renew its watch session, it will use a newer version. So by using, we give it the latest, our way goes to the client. And the next time we will renew, it's use a higher, it's much newer resource version so that we have successfully reduced the number of events it has to scan. OK? So I hope this is clear. So from the log, and API server has this kind of log. It tells that it's a big number of unit events. It's processing. It takes this much CPU time. And before this change, API server has this number of unit events processing freak out log. And after this change, we were able, we cannot get rid of them. It's about, say, like 20, 30% left. But this number, look at the profiling of the API server, the CPU profiling. So before the change, it takes 62% of CPU time in our sampling time to process this event. And after this change, it's less than 19% of CPU time. So any questions? Yes? No, this is a single change. This is a very small change in API server. So because we use the same code base for our TP and RP API server, we use the same code base. So they both get this updated. So it's a small change in API server, watch, catch, processing. You don't need to change your client. There's no need to change that. I'm sorry, can you say that again? First test is a separate client, right? It's just using some kind of client library to say, I want to create a pod. It may use the watch client, may not. So if it's using watch client, it's a benefit from that. If it doesn't use watch client, then it's just like the beneficiary is mostly in Kubernetes. Because Kubernetes is the one that gets this watch renewal and lots of immersive unit event processing. Any fit is actually, the change is being done in API server. We see this improvement. So API server has much better performance. It's not heavily loaded because it's trying to process the unit event. So from the client perspective, the client will have less latency when it's trying to renew the watch. It's actually all the client, every client should be benefited from this. From the RP, yes. So because this is our connection, again, going back. This is a watch to API server. So API server will have much better processing time. And client will have much faster response time. So then here is our performance improvement. We were able to reduce the P99 by 70%. It's not there. It's not designed. It's not designed this way. So this bookmark event, what I'm saying is the client library, it has some logic saying, I'm going to ignore this event. I'm going to ignore its object. I'm only going to use its resource version. So that logic is already in Kubernetes. But in this case, it did not send an extra. Because they think this is an extra. This may not be relevant to the client. So we are saying, in the sense of resource version, it's relevant. But his point is that it's. Yes, of course. But it seems like easy. Yes, it's just, you know, Kubernetes have a long way for code review, PR, and those things. Yeah, that's our process. This is a very, I personally think it's a very good improvement. We can contribute better. And if we have time and money, we would want to say how Kubernetes got improved after this. We want to do further tests after this change for Kubernetes as well. OK, again, this is our final performance data. Now we claim that we support 60,000 nodes cluster with real performance test data. 3T PCRP. So by this 5TP, 5RP, you can tell that because each additional TPNRP will have more management cost. You have more ETCD, more API server. So that means the more money you want to pay, the higher throughput you will get. So yeah, there is some CPU data. This is Kubernetes CPU data. And it's not very obvious, but we can say that the CPU utilization is around 40% or 45%. And our TPE, first of all, the CPU utilization for our TPE here is around 35%. And the jump here is because when we tear it down, we use a very high QPS to tear it down. Because we don't care about the performance at that time. So it uses a lot of CPU, but it shouldn't affect our performance test. And this is for RP CPU usage. It is below, I'm sorry, this is below 20%. Which means our RP capacity have good potential to grow. So maintain her way. Scale out architecture is one of the most fundamental things we have made changes. And it builds a solid base for our big cluster. And this operation is very expensive. Try everything. Change your master component. Try to use as less list as possible. And regulate your client behavior. Don't let them to list arbitrarily. And even to watch proof is very critical. This is a big change.  So our goal next, we want to support over 100,000 nodes per cluster. By further reduce ETCD rates, maybe making some changes for the API server, control plane components. And we do further API server profiling. So and also thinking outside of Kubernetes. So some references. And any questions? No, it doesn't need to be equal. You can have one tenant partition and multiple resource partition. Or one resource partition, multiple tenant partition. Depends on your API server load for different partitions. Do you know what has 25,000 nodes? Oh, 25,000 nodes. Actually, we have 30k, but the performance is a bit lower. It's not official, yes. It's because your customer can potentially use up all the resource cost multiple resource partition. And also, our cloud provider, they want to support multiple tenants. They want to unify the management part. They don't, initially, it's for management perspective. It's a single cluster. It's a single cluster the way you can ground multiple RTPs and then partitions. We set up an API gateway free in front of it. So it's one endpoint for the customers to deploy the application. And the HTTP using all the resources across. So the HTTP has a schedule and I mentioned that. And the schedule knows all the nodes from all the resource partitions. So in that perspective, it's one cluster. Not only the logic and the bits and the edicts, because it cannot take part away from that. I think the other part of the question you have is mean that there are other ways to do this to scale out our clusters. Some people deploy multiple covalent cluster and then we split the ratio there. We find that some challenges for that, one, because each cluster, they have own node management. We can leverage each other. That's one. The second one is if customer deploy application across multiple clusters, the communication between those clusters is pretty complicated. Of course, there are solutions there, but it's very complicated for that. So we kind of take this approach to say how it goes. So I think they said it stopped. So it's not a, we can answer questions here, right? Are we not, we can still answer questions here? We're out of time. We're out of time, yes, but. OK. So one more question I have, then we'll start, yeah.


I'm Zor. Welcome to Unisor Education. This is problem number five about complex numbers, and the problem actually is it's kind of a arithmetic exercise if you wish. If you have two different complex numbers, A plus B, I, and C plus B, I were A, B, C, and D are real numbers. I would like to represent this result of this division as a complex number with X and Y real numbers. The question is, how can we do it? All right. Well, let's just do it together. I never tried quite frankly to do anything like this, but let's think about how can we do it? Well, obviously, the result of the division is supposed to satisfy the multiplication of denominator and the result. So X plus Y, times C plus B, I should be equal to A plus B, I. When we are saying that this should be equal, it means real part of this should be equal to A, and the coefficient in an imaginary part should be equal to B. Well, let's just open these parentheses and see what happens. First of all, the real part will be X times C, and Y i times D i would be Y times D times i square, and i square is minus one, so it's minus Y D, and that will be my real part of the result of this multiplication. Now, imaginary part will be coefficient with i will be C times i, sorry, C times Y, C times Y, and X times D, and that will be B equal to A plus B i. Okay, so we have a real number should be equal to real number, and this real number, the coefficient with i should be equal to B. So basically, we have a system of two linear equations with two different unknown variables X and Y. So let's just write it down as such, and we will see what happens. So X C minus Y D should be equal to i A, and X D plus Y C is equal to B. I have changed the order of these two variables just to have X and Y ranges one after another. Okay. How can we solve this equation in the simplest way? Well, with linear equations, it's quite simple. Let's say you multiply this by C and this by G, and add them up, what happens? So this would be multiplied by C, this would be multiplied by G, and then we will add them up together. Obviously, Y, D, and C will be Y, C, and G with opposite signs, so Y will disappear when we do this, and we have only X equation for X, and that's exactly how we will find out what the X is. So if we multiply it by C, it would be X times C square, and this multiplied by G would be X times D square, and that's equal to AC plus BG. AC BG. That's the result of this, from which we conclude that X is equal to AC plus BG over C square plus G square. What's interesting, by the way, obviously any kind of a fraction does not exist when the denominator is equal to zero, and this particular denominator is equal to zero when both C and D are equal to zero, which means in our original example, A plus BI divided by C plus DI, if C and D both are equal to zero, it means we divide by zero, which is no-no, right? So basically our formula is correct exactly when our division is correct. So if C square plus D square is not equal to zero, it means that both together are not at the same time equal to zero, and that means that the denominator is not zero. So that's quite fun. All right, so having done that, let's just change it slightly and get rid of X from the same two equations. How can we get rid of X? Well, the same way, actually. We multiply this by D and multiply this by C, so this will be XCG and this will be XGC, which is the same, and then we will subtract one from another. Let's say from the second, we subtract the first one. So X disappears and we will have here YC square. Now this is minus, but we subtract, so it will be YG square is equal to BC minus AD from which we conclude that Y is equal to BC minus AD over C square plus D square. And again, notice that in the denominator, we also have exactly the same thing, C square plus D square, which means it's correct whenever we divide by something which is not equal to zero. So that's the answer. So this thing is equal to, let me start from this, BC minus AD divided by C square plus D square I plus AC plus BD divided by C is equal to zero. C square plus E square. So that's the result of the division. So we have divided two complex numbers and we've got the result, a complex number, which has the real part calculated using this formula and the imaginary part calculated using this formula. That's the answer and again, what's very important is that both left and right part are valid when one of the C or G not equal to zero. If both are zero, this isn't invalid and all these are invalid. So we have the same kind of a domain where both formulas are defined with the same set of C and G. Thank you very much. That's it.


A warm welcome to the 36th lecture on the subject of wavelets and multirate digital signal processing. You will recall that in the previous lecture, we had hinted briefly at the idea of a polyphase decomposition. In fact, we had used that idea of a polyphase decomposition for various reasons. We have been using it time and again to construct different kinds of structures to carry out computation efficiently in a filter bank, but we have not put down formally a whole approach based on polyphase components. Moreover, we have not quite considered the alternative approaches to the question of perfect reconstruction to date. So, in the lecture today, what I intend to talk about is two approaches to the general perfect reconstruction problem namely the polyphase approach and the modulation approach. Both of these are essentially approaches to handle the question, when does a filter bank give perfect reconstruction of the input and what we are going to do today is applicable not only to two band filter banks, but also to general m band filter banks where m could be a positive integer greater than 2. Let us begin with the first of these two approaches namely the polyphase approach. Now, we have already introduced the idea of polyphase components earlier. Let me recapitulate that idea. You see, when you have a sequence x of n with its z transform capital X of z with an appropriate region of convergence, we have seen that we can separate the samples of n which the samples of x n which lie at n a multiple of 2 and lie away from a multiple of 2. In other words, we can consider the index n as broken down into 2 m and 2 m plus 1 for all integer m. So, when we let m vary over all the integers here, then all possible integers n would be covered. So, what we have talked about here is what is called a second order polyphase component or polyphase component polyphase decomposition of order 2. What we want to do first is to generalize this. So, suppose for example, we wanted polyphase decomposition of order 3. What we are then going to do is to ask that the integer m be one of these three possibilities, 3 m, 3 m plus 1 and 3 m plus 2 over all integer m and when m varies over all possible integers, then we have covered all possible integer values of small n here. In general, suppose one talks of order capital m, we are then referring to a decomposition of the index n as follows.  So, now let us put down explicitly the mechanism for decomposition of x z to the z transform into the z transforms of the polyphase components of order m. To do that, we shall essentially split this index capital N in the way that we have just described. So, what we are saying effectively is to decompose x z using polyphase decomposition order capital M. Essentially, we write down capital X of z in terms of the sequence and now decompose the summation or split the sum of the sum summation on n into summation n going from minus to plus infinity is the same as summation l going from 0 to m minus 1 and summation m going from minus to plus infinity and where here you would have a variation as a function of n, here you would have variations as a function of m capital M times small m plus l. So, we just change the nature of the variable, the specification of the variable. Let me illustrate concretely. So, capital X of z, capital X of z, capital Z in other words becomes summation l going from 0 to capital M minus 1, summation m going from minus to plus infinity, x capital M times small m plus l times z raised to the power minus capital M times small m plus l. And now we can split this exponential into two parts, z raised to the power minus m times small m into z raised to the power minus l and noting that z raised to the power minus l can be brought outside the summation on capital on small m. We could rewrite this as follows, capital X of z is summation l going from 0 to capital M minus 1, z raised to the power minus l and in brackets then you have summation m going from minus to plus infinity, x capital M small m plus l times z raised to the power minus capital M times small m. Now essentially this is the z raised to the power minus z transform of all those points which lie at multiples of capital M plus small l. So, for example, when l is equal to 0, essentially this refers to z transform of all those points which lie at multiples of capital M. When l is equal to 1, this refers to all those points, z transform for all those points which lie at multiples of capital M plus 1, displaced by 1 from multiples of capital M and so on. When l is equal to 2, they are displaced by two steps and so on and this can only go up to capital M minus 1 steps because when you go to capital M, you are coming back to the original case of l equal to 0. So, what we have done here is to break x z into m parts, m disjoint parts in some sense and we shall use some notation now. We shall refer to this quantity here as capital X l m z raised to the power m. So, what we are saying here is you have the m th order polyphase component and the l th of those components with the argument given by z raised to the power m here. Let me write down this explicitly.  Here, I do not have a capital M occurring here because I have replaced z raised to the power m by z and this is essentially the z transform of the l th polyphase component of the sequence x plus l. So, here there are two things that are important in general in polyphase decomposition. The order of decomposition and the component number, there would be as many components as the order. So, when capital M is equal to 2, they are going to be 2 components 0 and 1. When capital M is equal to 3, they are going to be 3 components 0, 1 and 2 and so on. In fact, we can write down a very simple relationship between the z transform of the original sequence and the z transforms of its polyphase components. So, capital X of z becomes summation l going from 0 to m minus 1, z raised to the minus l, x l m, z raised to the power m. This is the manifestation of polyphase decomposition in the z domain. Now, this is just to explain and define the idea of polyphase decomposition in general. What we would now like to do is to see how this polyphase decomposition works when you have an analysis and a synthesis side. We would like to write down a general relationship for analysis synthesis polyphase components and how they interact to give perfect reconstruction. So, you see let us look at the analysis side. In fact, now for some variety and also to generalize, let us look at the general case, general analysis branch in an m-band filter bank. Now, you know, so far we have been talking just two bands and slowly my objective in this lecture is to go from 2 to m-band. So, I would like to bring in m-band first and then put m equal to 2 as a special case. So, what is firstly the m-band filter bank? Essentially, it is an analysis synthesis structure with the following nature. On the analysis side, you have a typical let us say l-th branch where you have a filter or let us use k-th branch to avoid mixing up with the polyphase component index. So, capital H kz followed by a down sampling by m. This is a typical analysis branch and in general, we could have b, branches here. Now, the number b could be different from the number capital M that should be stressed. They do not have to be the same. A typical synthesis branch would look like this. You would have an upsampler. We earlier had upsamplers of factor 2. Now, we would have upsamplers of factor m in general followed by the so-called synthesis filter, the k-th such. So, g kz and there could be b such branches too. Again, I must stress that b need not be the same as capital M. Needless to say, in a given m-band filter bank, the number of analysis branches and the number of synthesis branches must be the same. In fact, there is a one-to-one correspondence. When there is an analysis, there is also a synthesis on the same branch. So, let us draw the overall structure. So, this is the structure we are talking about. Now, notice that you have the same b on the analysis and synthesis side, but b is different from m and there are therefore, three possibilities. b could be equal to m, b could be less than m, b could be greater than m. Let us write down these three possibilities here. Notice, of course, that an analysis filter is always followed by a synthesis filter. So, you have an analysis and synthesis filter coming in cascade with the down and up samplers in between. So, b could be equal to m.  And on the other hand, b could be greater than m, in which case we call it an oversampled m-band filter bank. Whether the filter bank is critically sampled or undersampled or oversampled, the essential mechanism of analysis, whether by the polyphase approach or the modulation approach does not change. The essential idea remains the same. What needs to be checked is on analysis, whether we get the desired conditions, whether we get perfect reconstruction, whether we get something else. Sometimes we may not want perfect reconstruction. We might want something else from a filter bank. We might want the overall filter bank to perform a certain overall filtering operation. That is possible. It is not necessary that we always want perfect reconstruction. Whatever it is, the overall analysis of what a filter bank does can be done by the polyphase approach or by the modulation approach and that holds whether or not it is critically sampled. That is whether it is critically sampled, undersampled or oversampled. This is a point which I want to make before I begin to discuss the approaches in depth. Now, the polyphase approach says decompose the filters both analysis and synthesis into polyphase components and decompose the input and the output also into its polyphase components of order m. Note the order of the polyphase decomposition is the same as the down and up sampling factors. So, the polyphase approach says, let us write it down clearly, decompose the input, output, analysis filters and synthesis filters into polyphase components of order m. And what we shall do here is to take one of those B branches and see what we get. And once we understand what happens on the kth of the B branches, we shall understand what happens overall. So, consider the kth branch. So, we have the input subjected to the action of h k z followed by down sampling by m followed by up sampling by m and then subjected to the action of g k z. And we wish to analyze what this is doing in the polyphase domain. So, let us write down the input z transform capital X of z here. And let us see what z transform emerges here. So, you see x z can of course, be written in terms of its polyphase components and that gives you summation l going from 0 to m minus 1 capital X l capital M z raise the power m multiplied by z raise the power minus l, where you have capital X l m as the l th polyphase component of order m of the sequence x. Similarly, we can take the kth filter here and decompose this as well into its polyphase components of order capital M. So, we could write now here you will have a three fold index. So, filter number, polyphase component of order of the polyphase component z raise the power m. And now let us multiply. So, x z k z is what emerges after the filtering operation. Now, you know we are not really interested in x z times h k z. So, let us short circuit you know the solution to the first step. What we are really interested in is this subjected to down sampling. We are not interested at this point, we are interested at this point. So, what we want to get at this point is only the 0 th order polyphase component sorry the 0 th polyphase component of order m. We are not interested in the other polyphase components the 1 th up to the m minus 1 th. After we have taken this product, we just wish to understand or bring out or pull out that component which is of order 0 and how will we get that.  So, you know as far as pulling out the component of order 0 is concerned what we need to see is that there must only be z raise the power of m terms. There must not be a hanging power of z in whatever we choose when will that happen that is going to happen when l 1 plus l 2 you know when this essentially contributes a power of m.  So, let us say l 0 and that is easy to document we can easily see when this is going to happen. So, let us make a table in fact we can make a table of l 1 and l 1.  And finally, when l 1 is m minus 1 there is no possibility other than that l 2 be 1 there is a very easy association. So, in fact there is just one pair that needs to go together with each l 1 we can choose only one unique l 2. So, that we can pull out the 0 th order polyphase component. So, in fact we have a very simple expression for this you know all that we are saying is consider m minus l 1.  So, in other words what we are saying here is that l 2 has been chosen as m minus l 1 modulo m. So, this is modulo m. So, with this choice what we are saying is x z h k z done sampled by m is essentially going to give you the following.  So, this is going to give you the following words here. Please note there is a multiplication by z inverse, because except for l equal to 0 or in other words except for this case where l 1 is equal to 0 and l 2 is equal to 0. For all the other cases you have l 1 plus l 2 summing up to capital M. So, when you done sample by capital M you get a z inverse power a z raise the power minus m term would have remained originally and on down sample it becomes z inverse. A simple, but elegant and beautiful expression that we have right here.  In fact, we can now write down a matrix for each of these branches. So, you know what we are saying in effect is I can put down the outputs of these b branches a typical one emerging from the say kth branch at this point and we could arrange them in the same way. So, let us arrange them in the form of a vector. So, let me write down the analysis vector and let me find out the typical kth row of the matrix here. So, typical element in the analysis vector would correspond to the kth row times a vector of poly phase components of x.  So, note in the kth row we have taken care of the z inverse here. We have taken care of the fact that you know if you go back to the matrix vector product the number or the expression in z which should get multiplied by x 1 m is going to be h k m minus 1 m. The number getting multiplied by x m minus 1 m is h k 1 m. So, there is that so called inversion. This structure which we obtain here where you have b rows and the vector of poly phase components of x is called the analysis poly phase matrix. So, in general we have what is called the analysis poly phase matrix with kth row as described and the size of the analysis poly phase matrix is obviously going to be as many branches times the order of poly phase decomposition. Upsampling every z is going to be replaced by z raise the power m that is simple. So, let us consider what happens on the kth branch after upsampling by m followed by filtering by g. So, you know essentially upsampling would replace z by z raise the power m and then filtering with g k z would again produce m poly phase components here.  Then it is very easy to see that you know if you look at it here what comes here is anyway a function of z raise the power of m. So, to get hanging powers of z inverse you must take the corresponding hanging powers of z inverse appearing from this filter. So, in fact if you take the l such well I am sorry this should be l here is a little correction. So, you have Y k well you know actually we should write Y k l because there are three indices here. So, let me rewrite this summation l going from 0 to m minus 1 z raise the power minus l capital Y k l m z raise the power m there are three indices and we can make a very clear specification of what Y k l m shall look like.  So, l m z raise the power m times essentially the output of k th up sampler as is because that is already up in terms of z raise the power of m. In fact we can write down explicitly what that is the output of the k th up sampler as is essentially the k th row of m analysis poly phase matrix multiplied by the input poly phase vector.  The only catch is z has been replaced by z raise the power m that is the only change. In all this which are all functions of z z has been replaced by z raise the power m. Now, this is what is called the poly phase approach to analyzing the overall m band filter bank. Now, we have seen the k th branch the output is of course summation k going from 1 to b Y k z there are b branches remember and therefore, Y l m z the l th poly phase component of order m of the output is easily seen to be let me just recapitulate for you here the expression here all that we need to do is to sum over k here.  So, now we could write down a vector of output poly phase components and input poly phase components and relate them. So, we could construct a vector of output poly phase components here Y 0 m Y 1 m and so on up to Y m minus 1 m and we note that essentially this can be obtained now you know if I take any one of these. So, take Y 0 m for example, it involves G k 0 m summed over all k going from 1 to b. So, what kind of situation are we talking about we are talking about a vector of size m here and a matrix of size m cross p of essentially poly phase components of the synthesis filters poly phase components of the G k's and I could write down the l th row here this is called the synthesis poly phase matrix and let us write down the l th row.  So, it would be z raise the power of m and this would go to b such branches.  So, now we have m such rows and each row has b elements look at the analysis poly phase matrix it has b rows with m elements in each row. So, overall the output poly phase matrix or poly phase vector as a function of z raise to the m is equal to the poly phase poly phase synthesis matrix of course, as a function of z raise the power m times the poly phase analysis matrix again as a function of z raise to the m times the input poly phase vector again as a function of z raise to the m sizes. This is well number of rows m cross 1 this is m cross b this is where it has b and again cross m and then m cross 1. So, of course, all this is going to be finally m cross 1. Now, what we have shown here is an overall structure an overall analysis of an m band filter bank with b branches in terms of the poly phase components. I would now like to spend a few minutes on discussing the modulation approach, but we shall deal with it in depth in the next lecture. So, we just wish to contrast the modulation approach with the poly phase approach and leave it at that for this lecture. So, we have seen the poly phase approach in detail. You see in the modulation approach what we do is as follows down sampling as a sum of modulations. So, in other words let me take the example of m equal to 2. Remember that down sampling by 2 followed by up sampling by 2 you know this process of down sampling by 2 followed by up sampling by 2 was treated as equivalent to multiplication by a sequence which is 1 at all multiples of 2 and 0 elsewhere. So, you have a sequence which is 1 0 1 0 alternately like this. So, together this was equivalent to multiplication by this. Now, in general for other m the corresponding multiplying sequence would be 1 at all multiples of capital M followed by m minus 1 0s in between again a 1 and then m minus 1 0s and so on. So, this periodic sequence in the modulation approach the idea is instead of decomposing the sequence in time we essentially treat the sequence as a sum of modulates and we combine the down and the up sampler when we treat it thus as a sum. Having done so we put down a different kind of matrix for the reconstruction treating it as a sum of modulates. In the next lecture we shall go further and delve deeper into the modulation approach and contrast it with the polyphase approach bringing out the differences and the similarities between the two and then we shall proceed to establish conditions for perfect reconstruction based on both of these approaches. Thank you.


ext meeting will be on Friday February 26th 2021 at 9 a.m it will once again be on zoom call the public will be invited to participate the staff will be sending out notices and you should be getting a separate board members should be getting a separate uh link to a zoom call for the regular meeting and a second one for the closed session that we'll be having after the meeting everyone stay safe we're about to end this meeting I want to thank you all again for your service and once more one more time thank you so much to our retirees to our retiring members from the board and the service they provided and all of you for the support that you provide to the public in terms of public transit everybody take care and stay safe I'm gonna I don't close this meetings community television has to close this meeting goodbye everybody take care


The Economic and Financial Crimes Commission, EFCC, has described the activities of illegal minors operating in quarrel states as a great threat to the national economy. The acting Executive Chairman of the Anti-Graft Agency, Abdul Karim Chukhul raised the alarm during a one-day workshop on effective reporting of economic and financial crimes organized for 27 selected journalists drawn from different media organizations in the state. The activities of illegal minors operating in quarrel states, which drew the attention of the workshop organizers, is one which the EFCC says it will continue to combat through estant laws describing the activities of the illegal minors as a national economic threat that must be tackled in a holistic way. In the quarrel state environment, the activities of illegal, solid, morale operators post-grift threats to the local and national economy. Do a non-payment or two-minute payment of royalty, taxes, and other dues. The Commission has been active in tackling their criminalities, and will continue to ensure that estant laws against illegal minors. The Commission says the need to develop capacity for journalists has become imperative at this critical period of nation-building, noting that such capacity-building will help improve the investigative skills of journalists in tackling the menace of corruption in the country. It's a crime that is hitting eight trillion-worth dollar globally. If cybercrime was a country, they said it is next to U.S. and China. So we're talking about a very big issue, so Nigeria is not spared of this challenge. The total debt of investigative journalism. Journalism, to all intents and purposes, we know that a journalist's worth is the strength, the dimension, the solidity, the advocacy of his investigation. Hello, hope you enjoyed the news, please do subscribe to our YouTube channel and don't forget to hit the notification button so you get notified about fresh news updates.


Well, after eight months of anticipation, the big day for Brad Paisley fans is almost here. Sanford Event Center crew members were busy preparing the stage and arena for the big Paisley concert. 11 summaries will haul equipment, staging and other props to the event center for the Saturday performance. And with this being the largest concert the Bemidji venue has ever held, Sanford Center management says it will be all decks on hand. It is the calm before the storm, if you will. We've got a large crew of people coming as you can imagine. We've got corporate folks coming in today and tomorrow to help us on the on your setup side and on the you know financial side and serving side and all those things that can go with it. And you know we got a great great crowd of people coming over 5,000 people will be here tomorrow and you know we just encourage you to get out early car pool. Sanford Center says only a handful of single seat tickets remain. The concert this the prelim concerts begin at 7 tomorrow night. Brad Paisley I think is expected to hit stage around 9 is what I was told. If you enjoyed this segment of Lakeland news, please consider making a tax deductible contribution to Lakeland PBS.


Hi and welcome to the session. Let us discuss the following question which says in figure ad is equal to 4 centimeters, bd is equal to 3 centimeters and cb is equal to 12 centimeters. Find cot theta. Before moving on to the solution let's recall that for any angle theta cot theta is given by base upon perpendicular. This is the key idea that we will use for this question. Now let's move on to its solution. First of all let us see what is given to us in the question. We are given that ad is equal to 4 centimeters, bd is equal to 3 centimeters, cb is equal to 12 centimeters and we need to find cot theta.  So that means triangle abc and triangle adb are right angle to triangles. So first of all consider the right angle to triangle adb. So in right triangle adb, angle adb is a right angle that means ab is the hypotenuse. So we have ab square is equal to ad square plus bd square by Pythagoras theorem. Now let us substitute the values of ad and bd. So this implies ab square is equal to ad square that is 4 square plus bd square that is 3 square centimeter square which is equal to 16 plus 9 centimeter square that is 25 centimeter square. Thus ab will be equal to 5 centimeters. So here we have ab equal to 5 centimeters. Now consider the triangle abc. So in right triangle abc we know that cot theta is equal to base upon perpendicular. So that means here cot theta will be equal to base that is vc upon perpendicular that is ab. Which will be equal to 12 upon 5. Thus cot theta is equal to 12 upon 5 is the required answer to this question. With this we finished this session hope you must have understood the question. Goodbye take care and have a nice day.