1 00:00:00,090 --> 00:00:02,490 The following content is provided under a Creative 2 00:00:02,490 --> 00:00:04,030 Commons license. 3 00:00:04,030 --> 00:00:06,330 Your support will help MIT OpenCourseWare 4 00:00:06,330 --> 00:00:10,720 continue to offer high quality educational resources for free. 5 00:00:10,720 --> 00:00:13,320 To make a donation or view additional materials 6 00:00:13,320 --> 00:00:17,280 from hundreds of MIT courses, visit MIT OpenCourseWare 7 00:00:17,280 --> 00:00:18,450 at ocw.mit.edu. 8 00:00:47,901 --> 00:00:49,400 ALAN OPPENHEIM: In the last lecture, 9 00:00:49,400 --> 00:00:52,220 we began the discussion of the computation 10 00:00:52,220 --> 00:00:54,470 of the discrete Fourier transform. 11 00:00:54,470 --> 00:00:59,270 And in particular, we developed a flow graph for one algorithm. 12 00:00:59,270 --> 00:01:02,010 The algorithm that we talked about last time, 13 00:01:02,010 --> 00:01:05,330 which is referred to as the decimation in time 14 00:01:05,330 --> 00:01:08,570 form of the fast Fourier transform algorithm, 15 00:01:08,570 --> 00:01:14,420 was derived by decomposing the original sequence 16 00:01:14,420 --> 00:01:17,100 into subsequences. 17 00:01:17,100 --> 00:01:21,470 First, two subsequences consisting of the even numbered 18 00:01:21,470 --> 00:01:24,950 points and the odd numbered points, 19 00:01:24,950 --> 00:01:30,080 implementing an N-over-2-point DFT on the even numbered points 20 00:01:30,080 --> 00:01:34,190 and an N-over-2-point DFT on the odd numbered points, 21 00:01:34,190 --> 00:01:38,510 and then combining those results in an appropriate way to obtain 22 00:01:38,510 --> 00:01:42,350 the discrete Fourier transform of the overall sequence. 23 00:01:42,350 --> 00:01:44,690 And we saw, first of all, that there 24 00:01:44,690 --> 00:01:49,290 was a computational efficiency that resulted from doing this. 25 00:01:49,290 --> 00:01:52,670 And furthermore, we recognized that we 26 00:01:52,670 --> 00:01:55,640 could continue this decomposition 27 00:01:55,640 --> 00:01:59,790 and thereby achieve an even greater efficiency. 28 00:01:59,790 --> 00:02:04,370 In particular, with N expressed as a power of 2, 29 00:02:04,370 --> 00:02:08,360 we could continue decomposing the N-over-2-point DFTs 30 00:02:08,360 --> 00:02:12,220 into N-over-4-point DFTs, the N-over-4-point DFTs 31 00:02:12,220 --> 00:02:15,650 into N-over-8-point DFTs, et cetera. 32 00:02:15,650 --> 00:02:18,020 The flow graph that resulted when 33 00:02:18,020 --> 00:02:23,180 we did this was the flow graph indicated here, 34 00:02:23,180 --> 00:02:26,870 which is the one that we derived last time. 35 00:02:26,870 --> 00:02:32,270 It consists essentially of a set of butterfly computations-- 36 00:02:32,270 --> 00:02:35,450 what we refer to as butterflies-- 37 00:02:35,450 --> 00:02:37,910 a multiplication on the bottom branch 38 00:02:37,910 --> 00:02:40,670 of the butterfly at the input to the butterfly, 39 00:02:40,670 --> 00:02:43,610 and then an addition and subtraction. 40 00:02:43,610 --> 00:02:47,570 And that basically is the type of computation 41 00:02:47,570 --> 00:02:51,260 that follows throughout the flow graph. 42 00:02:51,260 --> 00:02:54,500 Now, this is a flow graph representing 43 00:02:54,500 --> 00:02:57,800 the computation of the discrete Fourier transform. 44 00:02:57,800 --> 00:03:01,610 And what is important about the flow graph 45 00:03:01,610 --> 00:03:06,110 are the nodes and the connections between the nodes 46 00:03:06,110 --> 00:03:08,960 and the transmittances on the branches 47 00:03:08,960 --> 00:03:12,080 that connect the nodes together. 48 00:03:12,080 --> 00:03:18,140 However, the flow graph in the form that is depicted here 49 00:03:18,140 --> 00:03:20,660 suggests a strategy for organizing 50 00:03:20,660 --> 00:03:24,500 the computation of the DFT. 51 00:03:24,500 --> 00:03:29,780 In particular, what we recognize is that the flow graph in this 52 00:03:29,780 --> 00:03:35,720 form tends, in a natural way, to suggest organizing 53 00:03:35,720 --> 00:03:40,910 the computation corresponding to a computation of an input 54 00:03:40,910 --> 00:03:44,060 array-- a computation on an input array-- 55 00:03:44,060 --> 00:03:50,150 computing a second array at this stage, from these points, 56 00:03:50,150 --> 00:03:54,840 computing this array, and from these points, 57 00:03:54,840 --> 00:03:59,940 finally computing the DFT output points. 58 00:03:59,940 --> 00:04:06,420 If we do that and we in fact think of these points 59 00:04:06,420 --> 00:04:10,530 as corresponding to sequential memory registers, 60 00:04:10,530 --> 00:04:15,840 then we know, first of all, that the input points 61 00:04:15,840 --> 00:04:20,519 would be stored sequentially, not in their normal order, 62 00:04:20,519 --> 00:04:23,880 but in fact, in some altered order. 63 00:04:23,880 --> 00:04:25,380 And as you'll see in a few minutes, 64 00:04:25,380 --> 00:04:28,170 what this order corresponds to and will be referred 65 00:04:28,170 --> 00:04:33,290 to as is bit reversed order. 66 00:04:33,290 --> 00:04:34,860 However, an additional point that I'd 67 00:04:34,860 --> 00:04:36,930 like to make first about this flow graph, 68 00:04:36,930 --> 00:04:40,020 and that is that it corresponds-- 69 00:04:40,020 --> 00:04:42,870 when thought of as a procedure for organizing 70 00:04:42,870 --> 00:04:44,340 the computation-- 71 00:04:44,340 --> 00:04:47,910 corresponds to an in-place computation 72 00:04:47,910 --> 00:04:50,410 of the discrete Fourier transform. 73 00:04:50,410 --> 00:04:53,890 Now, what I mean by that is the following. 74 00:04:53,890 --> 00:04:57,750 Let's suppose that we think of this set of points 75 00:04:57,750 --> 00:05:02,370 as corresponding to sequential registers in memory 76 00:05:02,370 --> 00:05:05,820 and we'd like to compute from this set of points 77 00:05:05,820 --> 00:05:11,010 this second array that is the set of points here. 78 00:05:11,010 --> 00:05:14,400 What we notice is that because of the butterfly 79 00:05:14,400 --> 00:05:18,360 structure of this computation, it 80 00:05:18,360 --> 00:05:22,740 is these two points that are used to compute these two 81 00:05:22,740 --> 00:05:24,960 points in the next array. 82 00:05:24,960 --> 00:05:27,270 These points are used to compute these two 83 00:05:27,270 --> 00:05:30,210 points in the next array, et cetera, 84 00:05:30,210 --> 00:05:37,200 so that in fact, we can organize the computation by implementing 85 00:05:37,200 --> 00:05:41,580 the computation required on these two input points, 86 00:05:41,580 --> 00:05:46,170 storing the results in a corresponding set of memory 87 00:05:46,170 --> 00:05:50,490 locations, which in fact could be the original memory 88 00:05:50,490 --> 00:05:53,850 locations from which we took these data points. 89 00:05:53,850 --> 00:05:56,360 The reason for that is that once we've 90 00:05:56,360 --> 00:06:00,850 used these two data points, we don't need them any longer. 91 00:06:00,850 --> 00:06:03,560 And so the result of this butterfly 92 00:06:03,560 --> 00:06:08,010 we could in fact store back in the original memory locations. 93 00:06:08,010 --> 00:06:13,020 And a few minutes of reflection on this flow graph in general 94 00:06:13,020 --> 00:06:17,220 would indicate that this is true throughout the computation. 95 00:06:17,220 --> 00:06:19,920 It's clearly true in going from the first stage 96 00:06:19,920 --> 00:06:21,990 to the second stage. 97 00:06:21,990 --> 00:06:25,740 In proceeding from this stage to the next stage, 98 00:06:25,740 --> 00:06:30,900 we see again, for example in computing these two points, 99 00:06:30,900 --> 00:06:34,380 the only input points that we use are these two. 100 00:06:34,380 --> 00:06:36,630 So again we could think of storing 101 00:06:36,630 --> 00:06:40,470 the result of this computation for this butterfly, 102 00:06:40,470 --> 00:06:45,190 for example, back in the original memory locations. 103 00:06:45,190 --> 00:06:51,840 So if we think of nodes on the same horizontal line 104 00:06:51,840 --> 00:06:56,850 as corresponding to identical memory registers, 105 00:06:56,850 --> 00:07:01,080 then we see that with the computation organized 106 00:07:01,080 --> 00:07:04,080 in the way that this flow graph suggests, 107 00:07:04,080 --> 00:07:08,190 that in fact the computation can be done in place. 108 00:07:08,190 --> 00:07:12,900 And we'll see that with some other alternative forms 109 00:07:12,900 --> 00:07:16,200 of the FFT algorithm, some alternative forms of this flow 110 00:07:16,200 --> 00:07:20,130 graph, there perhaps are other advantages, 111 00:07:20,130 --> 00:07:22,380 but for some of the other flow graphs, 112 00:07:22,380 --> 00:07:26,190 the computation can no longer be done in-place. 113 00:07:26,190 --> 00:07:29,400 So first of all, this flow graph represents 114 00:07:29,400 --> 00:07:33,300 an in-place algorithm. 115 00:07:33,300 --> 00:07:38,560 Second of all, the input points are in some altered order, 116 00:07:38,560 --> 00:07:42,000 although the DFT output points come out 117 00:07:42,000 --> 00:07:44,040 in what is normal order. 118 00:07:44,040 --> 00:07:46,980 That is, sequential order if we think of these as sequential 119 00:07:46,980 --> 00:07:48,180 registers. 120 00:07:48,180 --> 00:07:52,560 Well, let's examine in a little more detail what the order is 121 00:07:52,560 --> 00:07:56,760 that is being generated here. 122 00:07:56,760 --> 00:08:05,990 If we simply look at the memory registers 123 00:08:05,990 --> 00:08:11,200 and the corresponding data index from the previous flow graph, 124 00:08:11,200 --> 00:08:15,350 in storage registers 0 we're storing x of 0, 125 00:08:15,350 --> 00:08:18,310 in storage register 1 we're storing x of 4, 126 00:08:18,310 --> 00:08:21,730 storage register 2, x of 2, and et cetera. 127 00:08:21,730 --> 00:08:24,640 These are the storage register locations. 128 00:08:24,640 --> 00:08:27,960 These are the data indices. 129 00:08:27,960 --> 00:08:33,120 If we write the storage register locations in binary 130 00:08:33,120 --> 00:08:37,169 and we write the data index in binary, what we see, 131 00:08:37,169 --> 00:08:41,100 interestingly enough, is that the data index 132 00:08:41,100 --> 00:08:47,730 is the bit reversed counterpart of the storage register index. 133 00:08:47,730 --> 00:08:52,950 So here, for example, we have 001, storage register 1. 134 00:08:52,950 --> 00:08:57,720 Here we have 100, which is data index 4. 135 00:08:57,720 --> 00:09:00,690 And this continues on throughout. 136 00:09:00,690 --> 00:09:06,240 110 is storage register 6, bit reversed is 011, 137 00:09:06,240 --> 00:09:09,100 which is data index 3. 138 00:09:09,100 --> 00:09:15,690 Now, it's not accidental that this developed in such a way 139 00:09:15,690 --> 00:09:19,920 that the data is in fact stored in a bit reversed order. 140 00:09:19,920 --> 00:09:24,030 The reason for that basically is because of the way 141 00:09:24,030 --> 00:09:28,710 in which we originally sorted the sequence 142 00:09:28,710 --> 00:09:31,170 into the even numbered points and the odd numbered 143 00:09:31,170 --> 00:09:34,350 points, then the even numbered of the even numbered points, 144 00:09:34,350 --> 00:09:38,340 and the odd numbered of the even numbered points, et cetera. 145 00:09:38,340 --> 00:09:47,030 In particular, suppose that we considered a tree to carry out 146 00:09:47,030 --> 00:09:50,510 the sorting that we implemented in breaking 147 00:09:50,510 --> 00:09:54,520 the original sequence up into subsequences. 148 00:09:54,520 --> 00:09:58,430 Well, we started with the original sequence 149 00:09:58,430 --> 00:10:03,790 and we divided that into two subsequences, one corresponding 150 00:10:03,790 --> 00:10:06,490 to the even numbered points, the second corresponding 151 00:10:06,490 --> 00:10:08,960 to the odd numbered points. 152 00:10:08,960 --> 00:10:13,360 If you look at the binary representation of the data 153 00:10:13,360 --> 00:10:17,440 index, you can identify the even numbered points 154 00:10:17,440 --> 00:10:22,940 by the points for which the least significant binary bit is 155 00:10:22,940 --> 00:10:25,900 a 0 and the odd numbered points for which the least 156 00:10:25,900 --> 00:10:29,450 significant binary bit is a 1. 157 00:10:29,450 --> 00:10:33,760 So we divided the original sequence into two subsequences. 158 00:10:33,760 --> 00:10:37,990 The top half all had 0 as the least significant bit. 159 00:10:37,990 --> 00:10:42,270 The bottom half all had 1 as the least significant bit. 160 00:10:42,270 --> 00:10:45,070 Well, then for the even numbered points 161 00:10:45,070 --> 00:10:48,190 we wanted to divide those into the even numbered of the even 162 00:10:48,190 --> 00:10:50,980 numbered and the odd numbered of the even numbered. 163 00:10:50,980 --> 00:10:52,220 How would we do that? 164 00:10:52,220 --> 00:10:54,730 Well, we would do that by examining 165 00:10:54,730 --> 00:10:57,730 the next least significant bit. 166 00:10:57,730 --> 00:11:02,410 If that's a 0, then we would identify the data 167 00:11:02,410 --> 00:11:05,380 as being an even numbered of the even numbered points. 168 00:11:05,380 --> 00:11:07,750 If it's a 1, it's an odd numbered 169 00:11:07,750 --> 00:11:09,700 of the even numbered points. 170 00:11:09,700 --> 00:11:14,380 So this data was sorted as we've indicated here. 171 00:11:14,380 --> 00:11:17,110 And then, of course, we continue on looking 172 00:11:17,110 --> 00:11:20,950 at the bits from the right to the left. 173 00:11:20,950 --> 00:11:24,370 So sorting, then we could sort in the order that 174 00:11:24,370 --> 00:11:29,090 resulted by constructing a tree, as I've indicated here, 175 00:11:29,090 --> 00:11:34,940 and examining the bits from the right to the left. 176 00:11:34,940 --> 00:11:39,000 Suppose that we wanted instead to sort the data, 177 00:11:39,000 --> 00:11:43,500 not as I've indicated here, but in normal order. 178 00:11:43,500 --> 00:11:45,980 In other words, we have a bucket of data. 179 00:11:45,980 --> 00:11:51,110 We want to sort the data so that the data index comes out 180 00:11:51,110 --> 00:11:52,490 in normal order. 181 00:11:52,490 --> 00:11:56,180 How would we do that with a similar type of tree structure? 182 00:11:56,180 --> 00:12:01,370 Well, to decide whether the data index is 183 00:12:01,370 --> 00:12:03,890 in the top half or the bottom half 184 00:12:03,890 --> 00:12:06,380 we would look at the most significant bit. 185 00:12:06,380 --> 00:12:08,880 If the most significant bit is a 0, 186 00:12:08,880 --> 00:12:12,410 then the data is in the top half of the entire set of data. 187 00:12:12,410 --> 00:12:14,690 And if the most significant bit is a 1, 188 00:12:14,690 --> 00:12:17,390 the data is in the bottom half. 189 00:12:17,390 --> 00:12:20,810 Next, we would proceed to the second most significant bit. 190 00:12:20,810 --> 00:12:24,020 If the second most significant bit is a 0, 191 00:12:24,020 --> 00:12:27,530 then we fall either into the top half of the top half 192 00:12:27,530 --> 00:12:29,810 or the top half of the bottom half. 193 00:12:29,810 --> 00:12:33,470 And we continue on like that going through a tree exactly 194 00:12:33,470 --> 00:12:36,890 identical to this, but examining the bits 195 00:12:36,890 --> 00:12:41,420 for sorting in normal order from the most significant bit down 196 00:12:41,420 --> 00:12:43,470 to the least significant bit. 197 00:12:43,470 --> 00:12:48,500 So it is basically that in sorting the data as we sorted 198 00:12:48,500 --> 00:12:54,080 it to develop the flow graph that we developed, 199 00:12:54,080 --> 00:12:57,800 we examined the bits in exactly the reverse order 200 00:12:57,800 --> 00:12:59,780 that we would examine the bits if we wanted 201 00:12:59,780 --> 00:13:01,640 to sort the data normally. 202 00:13:01,640 --> 00:13:06,560 And consequently what results is data that's sorted in bit 203 00:13:06,560 --> 00:13:07,500 reversed order. 204 00:13:11,500 --> 00:13:17,440 Incidentally, speaking of things being bit reversed, 205 00:13:17,440 --> 00:13:23,690 the view graph as I first got it back from drafting I 206 00:13:23,690 --> 00:13:26,720 thought you might enjoy looking at. 207 00:13:26,720 --> 00:13:29,342 And if you find your mind wandering 208 00:13:29,342 --> 00:13:30,800 during the rest of the lecture, you 209 00:13:30,800 --> 00:13:33,440 might try to figure out exactly what happened with this view 210 00:13:33,440 --> 00:13:35,030 graph. 211 00:13:35,030 --> 00:13:38,330 The first inclination is that I simply have it turned around, 212 00:13:38,330 --> 00:13:42,020 so we can try that. 213 00:13:42,020 --> 00:13:43,580 Well, that doesn't quite do it. 214 00:13:43,580 --> 00:13:45,950 So maybe we should turn it over. 215 00:13:45,950 --> 00:13:47,760 And that doesn't quite do it. 216 00:13:47,760 --> 00:13:51,860 And in fact, I haven't yet been able to figure out 217 00:13:51,860 --> 00:13:56,090 a way of sorting this particular view graph in any normal order 218 00:13:56,090 --> 00:13:59,000 and I'd be curious as to whether you can figure out 219 00:13:59,000 --> 00:14:00,710 a way to straighten it out. 220 00:14:00,710 --> 00:14:05,660 Well, in any case, what we have then is 221 00:14:05,660 --> 00:14:09,290 a sorting of the original data-- 222 00:14:09,290 --> 00:14:12,640 returning now to the flow graph that we saw previously-- 223 00:14:12,640 --> 00:14:15,240 a sorting of the original data in bit 224 00:14:15,240 --> 00:14:22,250 reversed order and the output resulting in normal order. 225 00:14:22,250 --> 00:14:24,650 Well, of course this isn't the only way 226 00:14:24,650 --> 00:14:29,250 to organize the computation of the discrete Fourier transform. 227 00:14:29,250 --> 00:14:34,400 And in fact, an important aspect of the flow graph 228 00:14:34,400 --> 00:14:38,090 is as I stressed previously that what counts about the flow 229 00:14:38,090 --> 00:14:42,350 graph are the nodes and the way they're connected and not 230 00:14:42,350 --> 00:14:45,980 the way the flow graph is laid out in a sheet. 231 00:14:45,980 --> 00:14:48,290 When it's laid out in a sheet, we 232 00:14:48,290 --> 00:14:51,920 were able to apply some additional interpretation 233 00:14:51,920 --> 00:14:57,260 having to do with a way of organizing the computation 234 00:14:57,260 --> 00:14:59,450 from stage to stage. 235 00:14:59,450 --> 00:15:04,100 But it's important to recognize that if you take this flow 236 00:15:04,100 --> 00:15:09,650 graph, roll it up in a ball, as long as the right points are 237 00:15:09,650 --> 00:15:11,900 connected to the right points, then 238 00:15:11,900 --> 00:15:14,690 it still represents a computation 239 00:15:14,690 --> 00:15:16,890 of the discrete Fourier transform. 240 00:15:16,890 --> 00:15:21,320 So in particular, we are free to rearrange this flow graph 241 00:15:21,320 --> 00:15:23,990 in any way that we would like to as long 242 00:15:23,990 --> 00:15:28,740 as we don't change the connections between the notes. 243 00:15:28,740 --> 00:15:33,120 Well, one possible thought is to rearrange the flow graph 244 00:15:33,120 --> 00:15:37,860 so that we avoid this problem of bit reversal on the input. 245 00:15:37,860 --> 00:15:42,540 We can think of rearranging these lines 246 00:15:42,540 --> 00:15:49,360 so that the input is changed to an input in normal order. 247 00:15:49,360 --> 00:15:51,660 And one way of doing that, in fact, 248 00:15:51,660 --> 00:15:55,920 is to simply take all of the horizontal lines 249 00:15:55,920 --> 00:16:02,180 and rearrange them so that the data is sorted correctly. 250 00:16:02,180 --> 00:16:04,290 So we would leave this line where 251 00:16:04,290 --> 00:16:07,710 it is, we would take this line and move it up to here, 252 00:16:07,710 --> 00:16:11,610 this line would then stay where it is, this line would move up, 253 00:16:11,610 --> 00:16:14,430 and they would continue to be rearranged. 254 00:16:14,430 --> 00:16:18,610 The input would be then in normal order, 255 00:16:18,610 --> 00:16:21,840 the output, of course, would be disturbed, 256 00:16:21,840 --> 00:16:24,840 and we could anticipate exactly how it's 257 00:16:24,840 --> 00:16:26,520 going to be disturbed, in fact. 258 00:16:26,520 --> 00:16:32,320 The output then will come out in bit reversed order. 259 00:16:32,320 --> 00:16:40,760 That flow graph is then as I've indicated here. 260 00:16:40,760 --> 00:16:44,740 And this then corresponds to a rearrangement 261 00:16:44,740 --> 00:16:46,960 of the previous flow graph, where 262 00:16:46,960 --> 00:16:51,040 we have rearranged the computation so that the input 263 00:16:51,040 --> 00:16:54,300 is now in normal order. 264 00:16:54,300 --> 00:16:59,090 The way in which we rearranged it, the output then comes out 265 00:16:59,090 --> 00:17:01,400 in bit reversed order. 266 00:17:01,400 --> 00:17:04,910 Incidentally, on most of the following view graphs, 267 00:17:04,910 --> 00:17:10,430 I have indicated a reference to the figure in the text, which 268 00:17:10,430 --> 00:17:14,339 this view graph corresponds to, because in fact, many 269 00:17:14,339 --> 00:17:16,339 of these flow graphs will be going through quite 270 00:17:16,339 --> 00:17:18,170 a number of flow graphs. 271 00:17:18,170 --> 00:17:21,680 Many of them look very similar, so I 272 00:17:21,680 --> 00:17:24,020 thought perhaps a reference to the figure in the text 273 00:17:24,020 --> 00:17:28,230 will help you keep them organized. 274 00:17:28,230 --> 00:17:34,280 So now we have a modification of the decimation 275 00:17:34,280 --> 00:17:37,990 in time form of the FFT algorithm, 276 00:17:37,990 --> 00:17:41,970 which is such that if we now think 277 00:17:41,970 --> 00:17:45,990 of this as the procedure for organizing the computation, 278 00:17:45,990 --> 00:17:49,360 the input is now in normal order, 279 00:17:49,360 --> 00:17:52,560 the output is in bit reversed order. 280 00:17:52,560 --> 00:17:56,760 Have we destroyed the fact that the original computation 281 00:17:56,760 --> 00:17:58,830 was an in-place computation? 282 00:17:58,830 --> 00:18:01,590 Well, in fact, we haven't, because if we 283 00:18:01,590 --> 00:18:06,150 look at this now the way that it's organized, again, 284 00:18:06,150 --> 00:18:10,590 thinking of this as sequential memory registers, 285 00:18:10,590 --> 00:18:16,200 then, again, if we, for example, select this butterfly, 286 00:18:16,200 --> 00:18:19,680 the computation of these two points 287 00:18:19,680 --> 00:18:23,970 requires only these two input points. 288 00:18:23,970 --> 00:18:26,220 So once we have used these two points, 289 00:18:26,220 --> 00:18:30,390 we can store them back in the original memory locations. 290 00:18:30,390 --> 00:18:34,020 What makes the flow graph correspond 291 00:18:34,020 --> 00:18:37,230 to an in-place computation is the fact 292 00:18:37,230 --> 00:18:40,170 that the output nodes of the butterfly 293 00:18:40,170 --> 00:18:45,720 are horizontally adjacent to the input nodes of the butterfly. 294 00:18:45,720 --> 00:18:48,780 If that property of the flow graph is destroyed, 295 00:18:48,780 --> 00:18:53,040 then the flow graph will no longer correspond 296 00:18:53,040 --> 00:18:55,920 to an in-place computation if we think 297 00:18:55,920 --> 00:18:59,400 of all nodes on the same horizontal line 298 00:18:59,400 --> 00:19:04,320 as corresponding to identical memory registers, 299 00:19:04,320 --> 00:19:08,100 or equivalently, that vertical nodes correspond 300 00:19:08,100 --> 00:19:11,700 to sequential memory registers. 301 00:19:11,700 --> 00:19:13,980 Well, there are a variety of other ways 302 00:19:13,980 --> 00:19:16,860 in which we can rearrange this flow graph. 303 00:19:16,860 --> 00:19:19,740 We can, of course, modify the flow graph 304 00:19:19,740 --> 00:19:27,010 so that we have not only normal order at the input, 305 00:19:27,010 --> 00:19:31,000 but so that we also have normal order at the output. 306 00:19:31,000 --> 00:19:33,600 And we can do that simply by demanding it. 307 00:19:33,600 --> 00:19:36,750 In other words, by rearranging these nodes, 308 00:19:36,750 --> 00:19:39,690 keeping these nodes in normal order, rearranging these 309 00:19:39,690 --> 00:19:44,610 nodes so that they also correspond to normal order. 310 00:19:44,610 --> 00:19:49,080 And the flow graph that results in that case 311 00:19:49,080 --> 00:19:52,250 is the one that I've indicated here. 312 00:19:54,780 --> 00:19:57,720 So this is now the decimation in time form 313 00:19:57,720 --> 00:20:01,020 of the algorithm with the input sorted 314 00:20:01,020 --> 00:20:06,840 in normal order and the output also sorted in normal order. 315 00:20:06,840 --> 00:20:11,300 The computation still is represented by butterflies, 316 00:20:11,300 --> 00:20:13,340 but the butterflies are distorted. 317 00:20:13,340 --> 00:20:16,460 In other words, each of the butterflies 318 00:20:16,460 --> 00:20:21,950 no longer corresponds to the computation 319 00:20:21,950 --> 00:20:26,980 of horizontally adjacent nodes in the flow graph. 320 00:20:26,980 --> 00:20:31,960 So in fact, this computation is no longer 321 00:20:31,960 --> 00:20:34,620 an in-place computation. 322 00:20:34,620 --> 00:20:37,290 Well, is it an in-place computation from this array 323 00:20:37,290 --> 00:20:38,340 to this one? 324 00:20:38,340 --> 00:20:42,330 As it happens, it is in the computation of the first array, 325 00:20:42,330 --> 00:20:47,350 the reason being that in each of the butterflies, again, 326 00:20:47,350 --> 00:20:49,110 the output nodes are horizontally 327 00:20:49,110 --> 00:20:51,060 adjacent to the input nodes. 328 00:20:51,060 --> 00:20:55,230 But that property is lost after this array. 329 00:20:55,230 --> 00:20:58,440 And proceeding from this array to this array, 330 00:20:58,440 --> 00:21:02,700 we see that to compute these two points-- 331 00:21:02,700 --> 00:21:05,580 let's take this one and this one-- 332 00:21:05,580 --> 00:21:10,530 we need this point and this point. 333 00:21:10,530 --> 00:21:13,617 So we couldn't store then this answer back in here 334 00:21:13,617 --> 00:21:15,200 because we're going to need this point 335 00:21:15,200 --> 00:21:18,030 to compute some other output points, et cetera. 336 00:21:18,030 --> 00:21:22,790 So this flow graph in this form has the disadvantage 337 00:21:22,790 --> 00:21:26,870 that the in-place computational aspects of the flow graph 338 00:21:26,870 --> 00:21:29,990 are lost although the input is in normal order 339 00:21:29,990 --> 00:21:33,530 and the output is in normal order. 340 00:21:33,530 --> 00:21:35,540 It has another disadvantage incidentally, 341 00:21:35,540 --> 00:21:39,860 and that is that the indexing is somewhat difficult in contrast 342 00:21:39,860 --> 00:21:42,650 to the two flow graphs that we've talked about 343 00:21:42,650 --> 00:21:46,640 so far where the indexing strategy is relatively 344 00:21:46,640 --> 00:21:50,960 straightforward from stage to stage. 345 00:21:50,960 --> 00:21:53,510 Now, there's another rearrangement 346 00:21:53,510 --> 00:22:04,290 of this flow graph which has some advantages and also 347 00:22:04,290 --> 00:22:06,240 some disadvantages. 348 00:22:06,240 --> 00:22:09,960 First, let me return to the original flow graph 349 00:22:09,960 --> 00:22:13,290 that we began with, which consisted of the input sorted 350 00:22:13,290 --> 00:22:21,010 in bit reversed order and the output sorted in normal order. 351 00:22:21,010 --> 00:22:24,240 The indexing in this flow graph is 352 00:22:24,240 --> 00:22:28,290 relatively straightforward in that you should notice 353 00:22:28,290 --> 00:22:31,170 that as you proceed from stage to stage, 354 00:22:31,170 --> 00:22:35,010 the width of the butterflies continues to double. 355 00:22:35,010 --> 00:22:36,690 So here the width of the butterfly 356 00:22:36,690 --> 00:22:40,890 is 1, here the width of the butterfly is 2-- 357 00:22:40,890 --> 00:22:42,540 or the height of the butterfly-- 358 00:22:42,540 --> 00:22:46,040 here the height of the butterfly is 4. 359 00:22:46,040 --> 00:22:48,690 If we were computing a larger order transform, 360 00:22:48,690 --> 00:22:51,870 then that procedure would continue. 361 00:22:51,870 --> 00:23:00,070 But as you can imagine, if we were implementing this 362 00:23:00,070 --> 00:23:04,630 on a computer or with special purpose hardware, 363 00:23:04,630 --> 00:23:07,480 because of the fact that the data separation as we 364 00:23:07,480 --> 00:23:11,350 compute each butterfly increases or changes as we 365 00:23:11,350 --> 00:23:14,560 go from stage to stage, what is required 366 00:23:14,560 --> 00:23:17,060 is random access memory. 367 00:23:17,060 --> 00:23:23,320 We require random access memory because in each array 368 00:23:23,320 --> 00:23:27,250 we are not accessing data from sequential registers. 369 00:23:27,250 --> 00:23:29,740 We are going from this array to this one. 370 00:23:29,740 --> 00:23:32,680 After that, in computing a butterfly, 371 00:23:32,680 --> 00:23:37,360 we no longer are accessing sequential registers. 372 00:23:37,360 --> 00:23:41,300 There is, however, a modification of this algorithm 373 00:23:41,300 --> 00:23:47,350 which is useful in the sense that it permits the computation 374 00:23:47,350 --> 00:23:50,320 without random access memory and in particular 375 00:23:50,320 --> 00:23:53,980 is organized so that it can utilize sequential memory, 376 00:23:53,980 --> 00:23:58,810 although it does not correspond to an in-place computation. 377 00:23:58,810 --> 00:24:04,760 And that form of the algorithm, I have indicated here, 378 00:24:04,760 --> 00:24:08,980 is a form of the algorithm that originally 379 00:24:08,980 --> 00:24:11,920 was proposed by singleton. 380 00:24:11,920 --> 00:24:17,380 This then is a form of the decimation in time algorithm. 381 00:24:17,380 --> 00:24:19,810 It's a rearrangement of the flowchart 382 00:24:19,810 --> 00:24:25,630 so that sequential memory can be used rather than random access 383 00:24:25,630 --> 00:24:27,260 memory. 384 00:24:27,260 --> 00:24:30,190 Let me point out first of all that the input is 385 00:24:30,190 --> 00:24:34,040 in bit reversed order, the output is in normal order, 386 00:24:34,040 --> 00:24:37,300 and now let me explain in a little more detail 387 00:24:37,300 --> 00:24:42,520 why this flow graph allows the use of sequential memory 388 00:24:42,520 --> 00:24:44,870 rather than random access memory. 389 00:24:44,870 --> 00:24:49,300 First of all, let me indicate that the organization 390 00:24:49,300 --> 00:24:54,010 of this flow graph is identical from stage to stage. 391 00:24:54,010 --> 00:24:58,600 In other words, if you think of how this piece of the flow 392 00:24:58,600 --> 00:25:01,790 graph looks in computing the first stage, 393 00:25:01,790 --> 00:25:04,180 it is exactly the same with regard to data 394 00:25:04,180 --> 00:25:07,720 access as computing this stage is 395 00:25:07,720 --> 00:25:10,510 in relation to the one before it, 396 00:25:10,510 --> 00:25:12,520 and this continues on through. 397 00:25:12,520 --> 00:25:16,030 So as opposed to the other forms of the algorithm, 398 00:25:16,030 --> 00:25:18,370 the indexing is identical from stage 399 00:25:18,370 --> 00:25:21,940 to stage in this form of the algorithm. 400 00:25:21,940 --> 00:25:25,600 Now, to utilize sequential memory-- sequential memory 401 00:25:25,600 --> 00:25:29,200 might be disk memory or drum memory or shift register 402 00:25:29,200 --> 00:25:30,890 memory, for example. 403 00:25:30,890 --> 00:25:35,530 Generally, bulk memory is sequential memory rather than 404 00:25:35,530 --> 00:25:37,270 random access. 405 00:25:37,270 --> 00:25:42,890 Let's think of the original data first shuffled 406 00:25:42,890 --> 00:25:46,580 in bit reversed order and then stored 407 00:25:46,580 --> 00:25:48,710 in two separate memories. 408 00:25:48,710 --> 00:25:51,380 Let's call them M sub A and M sub B. 409 00:25:51,380 --> 00:25:53,150 The first half of the data is stored 410 00:25:53,150 --> 00:25:58,370 in memory A. The second half of the data is stored in memory B. 411 00:25:58,370 --> 00:26:02,030 And then let's permit two additional sequential memory 412 00:26:02,030 --> 00:26:07,220 registers, memories M sub C and M sub D 413 00:26:07,220 --> 00:26:10,430 for storing the output of the computation. 414 00:26:10,430 --> 00:26:15,390 Then the computation would proceed essentially as follows. 415 00:26:15,390 --> 00:26:19,640 We would access the first two data points from memory A, 416 00:26:19,640 --> 00:26:25,010 use those to compute the first point in this array, 417 00:26:25,010 --> 00:26:30,770 store that in memory C, and use that to compute the first point 418 00:26:30,770 --> 00:26:33,590 in the second half of this array and store 419 00:26:33,590 --> 00:26:38,570 that in memory D. Next, we would access the next two input 420 00:26:38,570 --> 00:26:43,220 points from memory A, add those-- 421 00:26:43,220 --> 00:26:45,860 we would do the required computation-- store 422 00:26:45,860 --> 00:26:51,560 the result in the next location in memory A, 423 00:26:51,560 --> 00:26:55,070 also store the second half of the butterfly 424 00:26:55,070 --> 00:26:59,540 output in the second register in memory D. 425 00:26:59,540 --> 00:27:04,790 So as we proceed along, we access the first two points 426 00:27:04,790 --> 00:27:07,730 from memory A then the next two points from memory A, 427 00:27:07,730 --> 00:27:11,610 storing in memory C and memory D. 428 00:27:11,610 --> 00:27:14,540 When we have gone through the first half of the data, 429 00:27:14,540 --> 00:27:18,710 we now access the data from the second input memory, 430 00:27:18,710 --> 00:27:24,950 memory B, the first two points, do the required computation, 431 00:27:24,950 --> 00:27:29,800 and store in the next sequential registers in memory C 432 00:27:29,800 --> 00:27:32,060 and memory D, et cetera. 433 00:27:32,060 --> 00:27:34,700 So the strategy in this case, then 434 00:27:34,700 --> 00:27:43,240 is that the input is stored half in memory A, half in memory B. 435 00:27:43,240 --> 00:27:46,030 The data is first accessed from memory A 436 00:27:46,030 --> 00:27:51,490 and we alternately put results in memories C and D. 437 00:27:51,490 --> 00:27:56,490 When we finish with memory A, we then proceed to memory B, 438 00:27:56,490 --> 00:27:59,140 access data sequentially, and continue 439 00:27:59,140 --> 00:28:04,030 to store the results alternating in memory C and D. 440 00:28:04,030 --> 00:28:07,660 Now that gives us the result at this stage. 441 00:28:07,660 --> 00:28:11,410 To compute the next stage, we now start with the memory 442 00:28:11,410 --> 00:28:17,140 C and D as the inputs and store the results of the computation 443 00:28:17,140 --> 00:28:21,140 back into memories A and B. So in a sense, 444 00:28:21,140 --> 00:28:23,680 you can think of the computation then 445 00:28:23,680 --> 00:28:28,255 as involving four memory, four separate sequential memories, 446 00:28:28,255 --> 00:28:31,690 A, B, C, and D. We start with A and B, 447 00:28:31,690 --> 00:28:38,110 flush the data into memory C and D, then flush the results back. 448 00:28:38,110 --> 00:28:40,870 And in fact, you can think of the computation 449 00:28:40,870 --> 00:28:43,870 much the same way as a slinky toy 450 00:28:43,870 --> 00:28:48,160 where you bounce the data back and forth between these two 451 00:28:48,160 --> 00:28:49,580 sets of sequential memories. 452 00:28:52,320 --> 00:28:55,860 That then is a form of the computation which 453 00:28:55,860 --> 00:28:57,830 is not an in-place computation. 454 00:28:57,830 --> 00:29:00,840 And furthermore, the input is bit reversed, 455 00:29:00,840 --> 00:29:03,400 although the output is in normal order, 456 00:29:03,400 --> 00:29:06,600 and it has the advantage, though, 457 00:29:06,600 --> 00:29:09,780 that the indexing is identical from stage to stage 458 00:29:09,780 --> 00:29:14,460 and consequently can utilize sequential memory rather 459 00:29:14,460 --> 00:29:17,810 than requiring random access memory. 460 00:29:17,810 --> 00:29:22,580 Well, that then completes the discussion of the decimation 461 00:29:22,580 --> 00:29:24,890 in time form of the algorithm. 462 00:29:24,890 --> 00:29:28,490 There are, of course, a number of other variations on this 463 00:29:28,490 --> 00:29:32,520 and some of them are discussed in the text. 464 00:29:32,520 --> 00:29:37,140 What I'd like to proceed to now is a slightly different form 465 00:29:37,140 --> 00:29:41,550 of FFT algorithms which are really 466 00:29:41,550 --> 00:29:45,030 derived on a somewhat different basis than the decimation 467 00:29:45,030 --> 00:29:47,040 in time form of the algorithms. 468 00:29:47,040 --> 00:29:49,830 But we'll see as we finally continue 469 00:29:49,830 --> 00:29:53,820 the discussion that there is a very close relationship 470 00:29:53,820 --> 00:29:56,550 between the decimation in time algorithms 471 00:29:56,550 --> 00:30:00,150 as we've just talked about and the class of algorithms which 472 00:30:00,150 --> 00:30:02,070 I would now like to introduce, which 473 00:30:02,070 --> 00:30:08,150 are the decimation in frequency forms of the FFT algorithm. 474 00:30:08,150 --> 00:30:12,680 Well, in particular, the notion in deriving 475 00:30:12,680 --> 00:30:18,740 the decimation and frequency forms of the FFT algorithm 476 00:30:18,740 --> 00:30:22,490 is, essentially, rather than breaking the input up 477 00:30:22,490 --> 00:30:25,660 into the even numbered and the odd numbered points, 478 00:30:25,660 --> 00:30:29,960 organize the computation so that we compute separately the even 479 00:30:29,960 --> 00:30:33,620 numbered and odd numbered output points. 480 00:30:33,620 --> 00:30:38,840 In particular, let's look again at the general form 481 00:30:38,840 --> 00:30:41,630 for the discrete Fourier transform x of k 482 00:30:41,630 --> 00:30:47,270 given by this sum and let's consider decomposing this 483 00:30:47,270 --> 00:30:51,740 into a sum over the first half of the input points 484 00:30:51,740 --> 00:30:56,480 and a sum over the second half of the input points. 485 00:30:56,480 --> 00:30:59,120 Well, the sum over the second half of the input 486 00:30:59,120 --> 00:31:04,460 points we can rearrange somewhat differently by essentially 487 00:31:04,460 --> 00:31:07,040 implementing a substitution of variables 488 00:31:07,040 --> 00:31:12,440 so that the index on the sum is changed to an index from 0 489 00:31:12,440 --> 00:31:15,270 to N over 2 minus 1. 490 00:31:15,270 --> 00:31:19,340 And if we do that, the sum that results then, 491 00:31:19,340 --> 00:31:22,430 the expression that results, is W sub N 492 00:31:22,430 --> 00:31:27,620 to the N over 2 k times the sum of x of n plus capital N over 2 493 00:31:27,620 --> 00:31:30,260 times W sub N to the nk. 494 00:31:30,260 --> 00:31:33,770 And you can easily check that this is correct. 495 00:31:33,770 --> 00:31:37,610 For example, for little n equal to capital N over 2 496 00:31:37,610 --> 00:31:42,080 here, we have x of capital N over 2 W sub N 497 00:31:42,080 --> 00:31:44,390 to the capital N over 2 k. 498 00:31:44,390 --> 00:31:48,590 Here, for little n equals 0, we get W sub N to the capital 499 00:31:48,590 --> 00:31:54,210 N over 2 k times x of capital N over 2, 500 00:31:54,210 --> 00:31:56,130 and this term becomes 1. 501 00:31:56,130 --> 00:32:00,300 Just simply a substitution of variables. 502 00:32:00,300 --> 00:32:07,290 Well, we recognize this term, W sub n to the N over 2 k, 503 00:32:07,290 --> 00:32:11,280 is equal to minus 1. 504 00:32:11,280 --> 00:32:13,950 And consequently, then we can rewrite 505 00:32:13,950 --> 00:32:17,730 this as I've indicated here, x of k 506 00:32:17,730 --> 00:32:24,960 is equal to a sum from n equals 0 to N over 2 minus 1 of x of n 507 00:32:24,960 --> 00:32:27,150 plus minus 1 to the k-- 508 00:32:27,150 --> 00:32:31,230 k being the index on the DFT-- 509 00:32:31,230 --> 00:32:36,580 times x of n plus capital N over 2 W sub N to the nk. 510 00:32:36,580 --> 00:32:41,320 Well, it's tempting to look at this and say kind of in analogy 511 00:32:41,320 --> 00:32:42,850 with the decimation in time-- 512 00:32:42,850 --> 00:32:45,850 the steps we took in the decimation time algorithm, 513 00:32:45,850 --> 00:32:49,480 that this is an N-over-2-point DFT. 514 00:32:49,480 --> 00:32:52,510 It is a sum from 0 to N over 2 minus 1, 515 00:32:52,510 --> 00:32:56,905 it's a modified input sequence, but it's not, in fact, 516 00:32:56,905 --> 00:32:58,930 an N-over-2-point DFT. 517 00:32:58,930 --> 00:33:05,200 And the reason that it isn't is that this is W sub N to the nk 518 00:33:05,200 --> 00:33:08,320 whereas if it was an N-over-2-point DFT, 519 00:33:08,320 --> 00:33:14,170 this would be W sub capital N over 2 to the nk. 520 00:33:14,170 --> 00:33:21,040 However, let's look at these DFT points for two separate cases, 521 00:33:21,040 --> 00:33:25,830 one being that for which the index, the output index, 522 00:33:25,830 --> 00:33:30,970 is even and the second for which the output index is odd. 523 00:33:30,970 --> 00:33:33,580 The output index is even, then we 524 00:33:33,580 --> 00:33:38,350 can think of that as indexing through the DFT points 525 00:33:38,350 --> 00:33:44,290 with an argument x of 2r, where r ranges from 0 to N 526 00:33:44,290 --> 00:33:46,240 over 2 minus 1. 527 00:33:46,240 --> 00:33:52,540 And we then have this sum since k is even, minus 1 to the k 528 00:33:52,540 --> 00:33:56,800 is positive and we have then this sum that I've 529 00:33:56,800 --> 00:34:01,630 indicated here, whereas for k odd, 530 00:34:01,630 --> 00:34:08,139 we choose an index 2r plus 1, where again r ranges from 0 531 00:34:08,139 --> 00:34:10,820 to N over 2 minus 1. 532 00:34:10,820 --> 00:34:15,190 And because k is odd, what results in the sum 533 00:34:15,190 --> 00:34:19,580 is a subtraction rather than an addition. 534 00:34:19,580 --> 00:34:22,780 And then we have substituting in also. 535 00:34:22,780 --> 00:34:26,560 We have W sub capital N to the little n times W sub capital 536 00:34:26,560 --> 00:34:29,610 N to the 2rn. 537 00:34:29,610 --> 00:34:33,750 Now, finally, we can take advantage of the fact 538 00:34:33,750 --> 00:34:38,370 that W sub N to the 2rn can be written in terms 539 00:34:38,370 --> 00:34:41,159 of W sub capital N over 2. 540 00:34:41,159 --> 00:34:45,900 In particular, W sub capital N to the 2rn 541 00:34:45,900 --> 00:34:51,150 is equal to W sub capital N over 2 to the rn. 542 00:34:51,150 --> 00:34:56,130 And that follows as it did and we utilize that fact also 543 00:34:56,130 --> 00:34:59,400 in deriving the decimation in time form of the algorithm. 544 00:34:59,400 --> 00:35:01,560 It follows simply by substituting 545 00:35:01,560 --> 00:35:07,020 in to the expression for W sub capital N. 546 00:35:07,020 --> 00:35:13,520 Finally utilizing this, we recognize 547 00:35:13,520 --> 00:35:17,930 that for the computation of the DFT 548 00:35:17,930 --> 00:35:24,350 for that the output index even, the computation 549 00:35:24,350 --> 00:35:29,660 can be reduced to a sum of a sequence g of n, where g of n 550 00:35:29,660 --> 00:35:34,430 is the sum of the first half and the last half of the input data 551 00:35:34,430 --> 00:35:35,930 points. 552 00:35:35,930 --> 00:35:39,580 That multiplied by W sub capital N over 2 to the rn. 553 00:35:42,130 --> 00:35:47,920 Well, this is now an N-over-2-point discrete Fourier 554 00:35:47,920 --> 00:35:49,180 transform. 555 00:35:49,180 --> 00:35:55,570 It involves N-over-2-points and the powers of W involved are 556 00:35:55,570 --> 00:35:58,750 the appropriate powers of W for-- 557 00:35:58,750 --> 00:36:02,355 or rather the W is involved is the appropriate W 558 00:36:02,355 --> 00:36:05,590 for an N-over-2-point DFT. 559 00:36:05,590 --> 00:36:09,540 That's indicated by this subscript N over 2. 560 00:36:09,540 --> 00:36:13,380 So this is to compute the even numbered points. 561 00:36:13,380 --> 00:36:15,720 To compute the odd numbered points, 562 00:36:15,720 --> 00:36:18,540 we have a similar expression. 563 00:36:18,540 --> 00:36:25,200 We have the sum of h of n times W sub capital N to the n, 564 00:36:25,200 --> 00:36:30,460 and that times W sub N over 2 to the rn, where h of n 565 00:36:30,460 --> 00:36:35,160 is the difference between the first half of the data points 566 00:36:35,160 --> 00:36:38,360 and the last half of the data points. 567 00:36:38,360 --> 00:36:41,430 So basically, following this strategy, 568 00:36:41,430 --> 00:36:46,210 what this says is that we can compute the discrete Fourier 569 00:36:46,210 --> 00:36:50,420 transform by forming a subsequence, 570 00:36:50,420 --> 00:36:54,620 which is the sum of the first and last half of the points, 571 00:36:54,620 --> 00:36:58,970 and computing the N-over-2-point DFT of that, 572 00:36:58,970 --> 00:37:02,720 and then forming a sequence, which is the difference 573 00:37:02,720 --> 00:37:06,290 of the first and the last half of the input points, 574 00:37:06,290 --> 00:37:10,640 multiplying that by W sub capital N to the little n, 575 00:37:10,640 --> 00:37:16,270 and computing the N-over-2-point DFT of that. 576 00:37:16,270 --> 00:37:20,920 And if you count up the number of operations involved, 577 00:37:20,920 --> 00:37:23,010 multiplications and additions, you 578 00:37:23,010 --> 00:37:26,440 will find that there is exactly the same computational 579 00:37:26,440 --> 00:37:29,470 efficiency implied in this decomposition 580 00:37:29,470 --> 00:37:31,910 as there was as we went through the decimation 581 00:37:31,910 --> 00:37:35,800 in time form of the algorithm. 582 00:37:35,800 --> 00:37:42,040 So this then is the basis for the decimation in time form 583 00:37:42,040 --> 00:37:50,560 of the computation and it basically states that we would 584 00:37:50,560 --> 00:37:56,890 compute the discrete Fourier transform by first forming 585 00:37:56,890 --> 00:38:02,440 a subsequence, which we denoted as g, 586 00:38:02,440 --> 00:38:06,400 which we obtain by adding the first half of the input points 587 00:38:06,400 --> 00:38:09,100 to the last half of the input points, 588 00:38:09,100 --> 00:38:14,340 and implementing an N-over-2-point DFT of that 589 00:38:14,340 --> 00:38:20,080 to obtain the even numbered output points. 590 00:38:20,080 --> 00:38:24,480 And then we would subtract the first half of the input points 591 00:38:24,480 --> 00:38:27,360 from the last half of the input points, 592 00:38:27,360 --> 00:38:34,140 multiply that subsequence, h, by successive powers of W, 593 00:38:34,140 --> 00:38:38,580 compute an N-over-2-point DFT of that, 594 00:38:38,580 --> 00:38:44,530 and the result would then be the odd numbered output points. 595 00:38:44,530 --> 00:38:46,800 Well, just as we did with the decimation 596 00:38:46,800 --> 00:38:51,790 in time form of the algorithm, we can continue this procedure. 597 00:38:51,790 --> 00:38:56,040 In other words, we can decompose the N-over-2-point DFTs 598 00:38:56,040 --> 00:38:59,940 into N-over-4-point DFTs by adding the first half 599 00:38:59,940 --> 00:39:03,030 of the input points here to the last half, et cetera. 600 00:39:03,030 --> 00:39:06,030 As we proceed through, we would then 601 00:39:06,030 --> 00:39:09,570 develop a flow graph in which we would compute first 602 00:39:09,570 --> 00:39:12,030 the even numbered of the even numbered output points 603 00:39:12,030 --> 00:39:16,230 and then the odd numbered of the even numbered output points, 604 00:39:16,230 --> 00:39:17,700 et cetera. 605 00:39:17,700 --> 00:39:20,670 So you can imagine that as we proceed through this, 606 00:39:20,670 --> 00:39:22,950 we'll get a flow graph. 607 00:39:22,950 --> 00:39:25,140 Similar in many respects to the flow graph 608 00:39:25,140 --> 00:39:26,730 that we developed for the decimation 609 00:39:26,730 --> 00:39:30,570 in time form of the algorithm, and furthermore, the flow graph 610 00:39:30,570 --> 00:39:33,600 as it naturally develops this way will 611 00:39:33,600 --> 00:39:41,880 result in data, the DFT output, sorted in a bit reversed order. 612 00:39:41,880 --> 00:39:47,370 So continuing on then, here is the decomposition with 613 00:39:47,370 --> 00:39:53,520 the N-over-2-point DFTs broken into N-over-4-point DFTs, 614 00:39:53,520 --> 00:39:57,930 and we are now computing the even numbered of the even 615 00:39:57,930 --> 00:40:00,800 numbered output points first. 616 00:40:00,800 --> 00:40:05,970 The N-over-4-point DFTs, if we consider the specific case of N 617 00:40:05,970 --> 00:40:11,263 equals 8, the N-over-4-point DFTs are just simply 2-point 618 00:40:11,263 --> 00:40:17,850 DFTs, which involve, as they did in the decimation in time form 619 00:40:17,850 --> 00:40:22,350 of the algorithm, just simply a computation involving 620 00:40:22,350 --> 00:40:25,050 an addition and a subtraction. 621 00:40:25,050 --> 00:40:28,650 In other words, just a simple butterfly. 622 00:40:28,650 --> 00:40:32,250 So the resulting flow graph based 623 00:40:32,250 --> 00:40:36,360 on pursuing this strategy through the entire computation 624 00:40:36,360 --> 00:40:40,020 is as I've indicated here, which is 625 00:40:40,020 --> 00:40:43,860 one form of the decimation in frequency 626 00:40:43,860 --> 00:40:46,400 form of the algorithm. 627 00:40:46,400 --> 00:40:50,550 Notice that the input is in normal order, 628 00:40:50,550 --> 00:40:55,560 the output is in bit reversed order, the flow graph 629 00:40:55,560 --> 00:40:59,580 as it developed here, again, if we think 630 00:40:59,580 --> 00:41:05,010 of it as a computational strategy, 631 00:41:05,010 --> 00:41:08,190 a strategy for organizing the computation, 632 00:41:08,190 --> 00:41:13,500 again, corresponds to an in-place computation. 633 00:41:13,500 --> 00:41:21,230 It's an in-place computation because output nodes 634 00:41:21,230 --> 00:41:25,130 for a butterfly are horizontally adjacent to the input 635 00:41:25,130 --> 00:41:27,950 nodes of the butterfly. 636 00:41:27,950 --> 00:41:30,500 In many respects, in fact, it looks 637 00:41:30,500 --> 00:41:35,600 somewhat like the decimation in time form of the algorithm 638 00:41:35,600 --> 00:41:39,560 when we sorted things such that the input was in normal order 639 00:41:39,560 --> 00:41:43,010 and the output was in bit reversed order. 640 00:41:43,010 --> 00:41:46,130 In fact, there is a difference between this class 641 00:41:46,130 --> 00:41:50,480 of algorithms and the decimation in time form of the algorithm. 642 00:41:50,480 --> 00:41:54,410 One difference that I would just draw your attention to 643 00:41:54,410 --> 00:42:01,340 quickly is the fact that the butterflies in the decimation 644 00:42:01,340 --> 00:42:03,170 in frequency form of the algorithm, 645 00:42:03,170 --> 00:42:05,630 as we've just been talking about it, 646 00:42:05,630 --> 00:42:09,640 involve additions and subtractions, 647 00:42:09,640 --> 00:42:12,700 and the multiplication by powers of W 648 00:42:12,700 --> 00:42:16,840 is implemented on the output of the butterfly. 649 00:42:16,840 --> 00:42:24,260 Whereas for the decimation in time form of the algorithm, 650 00:42:24,260 --> 00:42:28,890 the multiplication by a power of W was implemented at the input 651 00:42:28,890 --> 00:42:33,660 to the butterfly followed by an addition and subtraction. 652 00:42:33,660 --> 00:42:39,110 So in fact, the decimation and frequency form 653 00:42:39,110 --> 00:42:43,310 of the algorithm as we've just developed it 654 00:42:43,310 --> 00:42:45,950 is somewhat different than the decimation 655 00:42:45,950 --> 00:42:48,830 in time form of the algorithm. 656 00:42:48,830 --> 00:42:52,820 As we'll see as we continue in the next lecture, 657 00:42:52,820 --> 00:42:57,020 there are modifications of this form of the algorithm 658 00:42:57,020 --> 00:42:58,820 just as there were for the decimation 659 00:42:58,820 --> 00:43:00,950 in time form of the algorithm. 660 00:43:00,950 --> 00:43:04,040 And we'll also see that in fact there 661 00:43:04,040 --> 00:43:09,770 is a very close relationship between these two 662 00:43:09,770 --> 00:43:13,580 forms of the algorithm, the relationship being suggested 663 00:43:13,580 --> 00:43:18,320 by properties of flow graphs that we've discussed in some 664 00:43:18,320 --> 00:43:21,740 of the previous lectures. 665 00:43:21,740 --> 00:43:27,140 So at this point, then we have concluded our discussion 666 00:43:27,140 --> 00:43:31,010 of the decimation in time forms of the algorithm, 667 00:43:31,010 --> 00:43:34,310 we've introduced the decimation in frequency form 668 00:43:34,310 --> 00:43:35,690 of the algorithm. 669 00:43:35,690 --> 00:43:38,240 In the next lecture, what I would like to do 670 00:43:38,240 --> 00:43:43,040 is continue on a discussion of the decimation in frequency 671 00:43:43,040 --> 00:43:48,890 forms, in particular discussing alternative forms which 672 00:43:48,890 --> 00:43:50,750 are similar to the alternative forms 673 00:43:50,750 --> 00:43:52,580 that we discussed for decimation in time. 674 00:43:52,580 --> 00:43:54,430 Thank you.