\n",
14 | "\n",
15 | "### Prof. Dr. -Ing. Gerald Schuller Jupyter Notebook: Renato Profeta\n"
16 | ]
17 | },
18 | {
19 | "cell_type": "markdown",
20 | "metadata": {
21 | "slideshow": {
22 | "slide_type": "-"
23 | }
24 | },
25 | "source": [
26 | "# Quantization: Signal to Noise Ratio (SNR)"
27 | ]
28 | },
29 | {
30 | "cell_type": "code",
31 | "execution_count": 1,
32 | "metadata": {
33 | "hide_input": true
34 | },
35 | "outputs": [
36 | {
37 | "data": {
38 | "text/html": [
39 | "\n"
40 | ],
41 | "text/plain": [
42 | ""
43 | ]
44 | },
45 | "metadata": {},
46 | "output_type": "display_data"
47 | }
48 | ],
49 | "source": [
50 | "%%html\n",
51 | ""
52 | ]
53 | },
54 | {
55 | "cell_type": "markdown",
56 | "metadata": {
57 | "slideshow": {
58 | "slide_type": "-"
59 | }
60 | },
61 | "source": [
62 | "Assume we have a A/D converter with a quantizer with a certain number of bits (say N bits), what is the resulting Signal to Noise Ratio (SNR) of this quantizer? \n",
63 | "\n",
64 | "**The SNR is defined as the ratio of the expectation of the signal power to the expectation of the noise power.** \n",
65 | "\n",
66 | "In our case, the expectation of the noise power is the expectation of the quantization error power. We already have the expectation of the quantization error power as $\\large \\dfrac{\\Delta^2}{12}$. \n",
67 | "So what we still need for the SNR is the **average or expectation of the signal power**. How do we obtain this? \n",
68 | "Basically we can take the same approach as we did for the expectation of the power of the quantization error (which is basically the second moment of the distribution of the quantization error). So what we need to know from our signal is its **probability distribution**. For the quantization error it was a uniform distribution between $-\\dfrac{\\Delta}{2}$ and $+\\dfrac{\\Delta}{2}$. \n",
69 | "A very **simple case** would be a **uniformly distributed signal** with amplitude $\\dfrac{A}{2}$, which has values between $-\\dfrac{A}{2}$ up to $+\\dfrac{A}{2}$."
70 | ]
71 | },
72 | {
73 | "cell_type": "markdown",
74 | "metadata": {
75 | "slideshow": {
76 | "slide_type": "-"
77 | }
78 | },
79 | "source": [
80 | "
\n",
81 | " \n",
82 | "
\n",
83 | "\n",
84 | "So we could again use our formula for the average power, but now for our signal x:\n",
85 | "\n",
86 | "$$\\large E(x^2)=\\int_ {-A/2} ^ {A/2} x^2 \\cdot p(x) dx$$\n",
87 | "\n",
88 | "So here we have the same type of signal, and the resulting expectation of the power (its second moment, assumed we have a zero mean signal) is obtained by using our previous formula, and replace $\\Delta$ by A. The resulting power is: $\\frac{A^2}{12}$.\n",
89 | "\n",
90 | "**Which signals have this property?** One example is uniformly distributed random values (basically like our quantization error). \n",
91 | "\n",
92 | "**Observe: Speech or music has a non-uniform pdf**, it is usually modeled by a Laplacian distribution or a gaussian mixture model, so it doesn't apply to this case!"
93 | ]
94 | },
95 | {
96 | "cell_type": "code",
97 | "execution_count": 2,
98 | "metadata": {
99 | "hide_input": true
100 | },
101 | "outputs": [
102 | {
103 | "data": {
104 | "text/html": [
105 | "\n"
106 | ],
107 | "text/plain": [
108 | ""
109 | ]
110 | },
111 | "metadata": {},
112 | "output_type": "display_data"
113 | }
114 | ],
115 | "source": [
116 | "%%html\n",
117 | ""
118 | ]
119 | },
120 | {
121 | "cell_type": "markdown",
122 | "metadata": {
123 | "slideshow": {
124 | "slide_type": "-"
125 | }
126 | },
127 | "source": [
128 | "An example for a uniform pdf: **a triangular wave**: \n",
129 | "\n",
130 | "
\n",
131 | " \n",
132 | "
\n",
133 | "\n",
134 | "How do we obtain its pdf? One can imagine the vertical axis (the function value) covered by small intervals, and each interval is then passed in the same time-span. This means that the resulting pdf is also uniform!\n",
135 | "\n",
136 | "A further example: **A sawtooth wave**:\n",
137 | "\n",
138 | "
\n",
139 | " \n",
140 | "
\n",
141 | "\n",
142 | "Again we can make the same argument, each small interval of our function value is covered in the same time-span, hence we obtain a uniform distribution.\n",
143 | "\n",
144 | "We now have seen a few examples which fulfil our assumption of a uniform distribution (realistic examples), and we know: their expectation of their power is $\\dfrac{A^2}{12}$. So what does this then mean for the SNR? The **SNR** is just the ratio:\n",
145 | "\n",
146 | "$$ \\large SNR = \\frac {\\dfrac{A^2}{12}} {\\dfrac{\\Delta^2}{12}}= \\frac{A^2} { \\Delta^2} $$\n",
147 | "\n",
148 | "If we assume our signal is full range, meaning the maximum values of our A/D converter is $-\\dfrac{A}{2}$ and $+\\dfrac{A}{2}$ (the signal goes to the maximum), we can compute the step size $\\Delta$ if we know the **number of bits** of converter, and if we assume uniform quantization step sizes. Assume we have **N bits** in our converter. This means we have $2^N$ quantization intervals. We obtain $\\Delta$ by dividing the full range by this number,\n",
149 | "\n",
150 | "$$ \\large\n",
151 | "\\Delta = \\frac{A}{2^N}\n",
152 | "$$\n",
153 | "\n",
154 | "Plug this in the SNR equation, and we obtain:\n",
155 | "\n",
156 | "$$\n",
157 | "SNR= \\frac{A^2} { \\Delta^2}= \\frac{A^2} {\\left( \\dfrac {A}{2^N} \\right)^2} = {2^{2N}}\n",
158 | "$$\n",
159 | "\n",
160 | "This is now quite a simple result! But usually, the SNR is given in dB (deciBel), so lets convert it into dB:\n",
161 | "\n",
162 | " \n",
163 | "$$SNR_{dB} = 10 \\cdot \\log_{10} (2^{2N})=10 \\cdot 2N \\cdot \\log_{10}(2) \\approx $$\n",
164 | "$$ \\approx 10 \\cdot 2N \\cdot 0.301 dB =N \\cdot 6.02 dB$$\n",
165 | "\n",
166 | "This is now our famous **rule of thumb**, that **each bit** more gives you about **6 dB more SNR**. But observe that the above formula only holds for uniformly distributed full range signals! (the signal is between -A/2 and +A/2, using all possible values of our converter)."
167 | ]
168 | },
169 | {
170 | "cell_type": "code",
171 | "execution_count": 3,
172 | "metadata": {
173 | "hide_input": true
174 | },
175 | "outputs": [
176 | {
177 | "data": {
178 | "text/html": [
179 | "\n"
180 | ],
181 | "text/plain": [
182 | ""
183 | ]
184 | },
185 | "metadata": {},
186 | "output_type": "display_data"
187 | }
188 | ],
189 | "source": [
190 | "%%html\n",
191 | ""
192 | ]
193 | },
194 | {
195 | "cell_type": "markdown",
196 | "metadata": {
197 | "slideshow": {
198 | "slide_type": "subslide"
199 | }
200 | },
201 | "source": [
202 | "What happens if the signal is not full range? What is the SNR if we have a signal with reduced range? Assume our signal has an amplitude of A/c, with a factor c>1. \n",
203 | "We can then simply plug this into our equation:\n",
204 | "\n",
205 | "$$ \\large SNR= \\frac{\\left(\\frac{A}{c}\\right)^2} {\\Delta^2}= \\frac{\\left(\\frac{A}{c}\\right)^2 }{ \\left(\\frac{A}{2^N}\\right)^2} = \\frac{2^{2N}}{c^2}$$\n",
206 | "\n",
207 | "in dB:\n",
208 | "\n",
209 | "$$ \\large SNR_{dB}=10 . \\log_{10}( \\frac {2^{2N}} {c^2})=10\\cdot2N.\\log_{10}(2)-20.\\log_{10}(c) \\approx $$\n",
210 | "\n",
211 | "$$ \\large\n",
212 | " \\approx 10 \\cdot 2N \\cdot 0.301 dB -20 \\cdot \\log_{10}(c) =\n",
213 | "$$\n",
214 | " \n",
215 | "$$ \\large\n",
216 | " =N \\cdot 6.02 dB -20 \\cdot log_{10}(c)\n",
217 | "$$\n",
218 | " \n",
219 | "\n",
220 | "The last term, the $20 \\cdot \\log_{10}(c) $, is the number of dB which we are below our full range. This means we **reduce our SNR** by this number of **dB** which we are **below full range**! \n",
221 | "
\n",
222 | "**Example:** We have a 16 bit quantiser, then the SNR for uniformly distributed full range signals would be:\n",
223 | "\n",
224 | "\n",
225 | "$$SNR = 6.02 \\cdot 16 dB = 96.32 dB$$\n",
226 | "\n",
227 | "Now assume we have the same signal, but 20dB below full range (meaning only 1/10th of the full range). Then the resulting SNR would be only:\n",
228 | "\n",
229 | "$$SNR = 96.32-20 = 76.32 dB$$ \n",
230 | "\n",
231 | "This is considerably less. This also shows why it is important not to make the safety margin to full range too big! So for instance our sound engineer should keep the signal as big as possible, without ever reaching full range to avoid clipping the signal. "
232 | ]
233 | },
234 | {
235 | "cell_type": "markdown",
236 | "metadata": {
237 | "slideshow": {
238 | "slide_type": "slide"
239 | }
240 | },
241 | "source": [
242 | "The other assumption we made concerned the type of signal we quantize. \n",
243 | "\n",
244 | "**What if we don't have a uniformly distributed signal?** \n",
245 | "\n",
246 | "As we saw, speech and audio signals are best modelled by a Laplacian distribution or a Gaussian mixture model, and similar for audio signals. Even a simple sine wave does not fulfil this assumption of a uniform distribution. What is the pdf of a simple sine wave?\n",
247 | "\n",
248 | "**Observe:** If a sinusoid represents a full range signal, its values are from $-A/2$ to $+A/2$, as in the previous cases."
249 | ]
250 | },
251 | {
252 | "cell_type": "code",
253 | "execution_count": 4,
254 | "metadata": {
255 | "hide_input": true
256 | },
257 | "outputs": [
258 | {
259 | "data": {
260 | "text/html": [
261 | "\n"
262 | ],
263 | "text/plain": [
264 | ""
265 | ]
266 | },
267 | "metadata": {},
268 | "output_type": "display_data"
269 | }
270 | ],
271 | "source": [
272 | "%%html\n",
273 | ""
274 | ]
275 | },
276 | {
277 | "cell_type": "markdown",
278 | "metadata": {
279 | "slideshow": {
280 | "slide_type": "-"
281 | }
282 | },
283 | "source": [
284 | "What is our SNR if we have a sinusoidal signal? What is its pdf? Basically it is its normalized histogram, such that its integral becomes 1, to obtain a probability distribution.\n",
285 | "\n",
286 | "If we look at the signal, and try to see how probable it is for the signal to be in a certain small interval on the y axis, we see that the signal stays longest around +1 and -1, because there the signal slowly turns around. Hence we would expect a pdf, which has peaks at +1 and -1. \n",
287 | "If you calculate the pdf of a sine wave, x=sin(t), with t being continuous and with a range larger than 2pi, then the result is\n",
288 | " \n",
289 | "$$\n",
290 | "p(x)=\\frac{1} {\\pi \\cdot \\sqrt{1-x^2}}\n",
291 | "$$\n",
292 | " \n",
293 | "This results from the derivative of the inverse sine function (arcsin). This derivation can be found for instance on Wikipedia. For our pdf we need to know how fast a signal x passes through a given bin in x. This is what we obtain if we compute the inverse function $x=f^{-1}(y)$, and then its derivative $df^{-1}(x)/dy$."
294 | ]
295 | },
296 | {
297 | "cell_type": "markdown",
298 | "metadata": {
299 | "slideshow": {
300 | "slide_type": "subslide"
301 | }
302 | },
303 | "source": [
304 | "### PDF of Time Series\n"
305 | ]
306 | },
307 | {
308 | "cell_type": "markdown",
309 | "metadata": {
310 | "slideshow": {
311 | "slide_type": "-"
312 | }
313 | },
314 | "source": [
315 | "Given a signal a = f (t) which is sampled uniformly over a time period T , its PDF, p(a) can be calculated as follows. Because the signal is uniformly sampled we have $p(t) = \\frac{1}{T}$ . The function f(t) acts to transform this density from one over *t* to one over *a*. Hence, using the method for transforming PDFs, we get:\n",
316 | "\n",
317 | "$$\\large\n",
318 | "p(a)=\\dfrac{p(t)}{\\left|\\frac {da}{dt} \\right|} $$\n",
319 | "\n",
320 | "where | | denotes the absolute value and the derivative is evaluated at $t=f^{-1}(x).$\n",
321 | " \n",
322 | "From: https://www.fil.ion.ucl.ac.uk/~wpenny/course/appendixDE.pdf\n",
323 | ""
324 | ]
325 | },
326 | {
327 | "cell_type": "code",
328 | "execution_count": 5,
329 | "metadata": {
330 | "slideshow": {
331 | "slide_type": "-"
332 | }
333 | },
334 | "outputs": [
335 | {
336 | "data": {
337 | "text/latex": [
338 | "$\\displaystyle x = \\sin{\\left(t \\right)}$"
339 | ],
340 | "text/plain": [
341 | "Eq(x, sin(t))"
342 | ]
343 | },
344 | "execution_count": 5,
345 | "metadata": {},
346 | "output_type": "execute_result"
347 | }
348 | ],
349 | "source": [
350 | "from sympy import symbols, pi, sqrt, Integral, Function, Eq, diff, sin, solve, simplify, Abs\n",
351 | "x, t = symbols('x t', real=True)\n",
352 | "A, w = symbols('A w', real=True, positive=True)\n",
353 | "Eq_x=Eq(x, sin(t))\n",
354 | "Eq_x"
355 | ]
356 | },
357 | {
358 | "cell_type": "code",
359 | "execution_count": 6,
360 | "metadata": {
361 | "slideshow": {
362 | "slide_type": "-"
363 | }
364 | },
365 | "outputs": [
366 | {
367 | "data": {
368 | "text/latex": [
369 | "$\\displaystyle t = \\operatorname{asin}{\\left(x \\right)}$"
370 | ],
371 | "text/plain": [
372 | "Eq(t, asin(x))"
373 | ]
374 | },
375 | "execution_count": 6,
376 | "metadata": {},
377 | "output_type": "execute_result"
378 | }
379 | ],
380 | "source": [
381 | "# Find the Inverse\n",
382 | "y=solve(Eq_x,t)\n",
383 | "Eq_y=Eq(t,y[1])\n",
384 | "Eq_y"
385 | ]
386 | },
387 | {
388 | "cell_type": "markdown",
389 | "metadata": {
390 | "slideshow": {
391 | "slide_type": "-"
392 | }
393 | },
394 | "source": [
395 | "The inverse sine is only defined for $-\\frac{\\pi}{2} \\leq t \\leq +\\frac{\\pi}{2}$ and p(t) is uniform within this. \n",
396 | "Hence, $ p(t) = \\frac {1}{\\pi} $."
397 | ]
398 | },
399 | {
400 | "cell_type": "code",
401 | "execution_count": 7,
402 | "metadata": {
403 | "slideshow": {
404 | "slide_type": "-"
405 | }
406 | },
407 | "outputs": [
408 | {
409 | "data": {
410 | "text/latex": [
411 | "$\\displaystyle \\sqrt{1 - x^{2}}$"
412 | ],
413 | "text/plain": [
414 | "sqrt(1 - x**2)"
415 | ]
416 | },
417 | "execution_count": 7,
418 | "metadata": {},
419 | "output_type": "execute_result"
420 | }
421 | ],
422 | "source": [
423 | "# Find dx\\dt and evaluate at t=arsin(x)\n",
424 | "\n",
425 | "dxdt = (diff(Eq_x.rhs,t))\n",
426 | "dxdt = dxdt.subs(t,Eq_y.rhs)\n",
427 | "dxdt"
428 | ]
429 | },
430 | {
431 | "cell_type": "code",
432 | "execution_count": 8,
433 | "metadata": {
434 | "slideshow": {
435 | "slide_type": "-"
436 | }
437 | },
438 | "outputs": [
439 | {
440 | "data": {
441 | "text/latex": [
442 | "$\\displaystyle p{\\left(t \\right)} = \\begin{cases} \\frac{1}{\\pi} & \\text{for}\\: t \\geq - \\frac{\\pi}{2} \\wedge t \\leq \\frac{\\pi}{2} \\\\0 & \\text{otherwise} \\end{cases}$"
443 | ],
444 | "text/plain": [
445 | "Eq(p(t), Piecewise((1/pi, (t >= -pi/2) & (t <= pi/2)), (0, True)))"
446 | ]
447 | },
448 | "execution_count": 8,
449 | "metadata": {},
450 | "output_type": "execute_result"
451 | }
452 | ],
453 | "source": [
454 | "# Calculate p(t)\n",
455 | "from sympy.stats import Uniform, density\n",
456 | "P_t = Function('p')(t)\n",
457 | "p_t = Uniform('X',-pi/2,pi/2)\n",
458 | "Eq_p_t=Eq(P_t,density(p_t)(t))\n",
459 | "Eq_p_t"
460 | ]
461 | },
462 | {
463 | "cell_type": "code",
464 | "execution_count": 9,
465 | "metadata": {
466 | "slideshow": {
467 | "slide_type": "-"
468 | }
469 | },
470 | "outputs": [
471 | {
472 | "data": {
473 | "text/latex": [
474 | "$\\displaystyle p{\\left(x \\right)} = \\frac{1}{\\pi \\sqrt{1 - x^{2}}}$"
475 | ],
476 | "text/plain": [
477 | "Eq(p(x), 1/(pi*sqrt(1 - x**2)))"
478 | ]
479 | },
480 | "execution_count": 9,
481 | "metadata": {},
482 | "output_type": "execute_result"
483 | }
484 | ],
485 | "source": [
486 | "# Calculate p(x)\n",
487 | "p_x = Function('p')(x)\n",
488 | "Eq_p_x= Eq(p_x,(1/pi)/dxdt)\n",
489 | "Eq_p_x"
490 | ]
491 | },
492 | {
493 | "cell_type": "code",
494 | "execution_count": 10,
495 | "metadata": {
496 | "hide_input": true
497 | },
498 | "outputs": [
499 | {
500 | "data": {
501 | "text/html": [
502 | "\n"
503 | ],
504 | "text/plain": [
505 | ""
506 | ]
507 | },
508 | "metadata": {},
509 | "output_type": "display_data"
510 | }
511 | ],
512 | "source": [
513 | "%%html\n",
514 | ""
515 | ]
516 | },
517 | {
518 | "cell_type": "markdown",
519 | "metadata": {
520 | "slideshow": {
521 | "slide_type": "-"
522 | }
523 | },
524 | "source": [
525 | "Here we can see that p(x) indeed becomes infinite at x=+/-1! We could now use the same approach as before to obtain the expectation of the power, multiplying it with $x^2$ and integrating it. But this seems to be somewhat tedious. But since we now have a deterministic signal, we can also try an **alternative** solution, since the sine function is not a probabilistic function, but a deterministic function.\n",
526 | "\n",
527 | "We can simply directly compute the power of our sine signal over t, and then take the average over at least one period of the sine function.\n",
528 | "\n",
529 | "$$ \\large\n",
530 | "E(x^2)= \\frac{1} {2\\pi}\\int _ {t=0} ^{2\\pi} sin^2(t) dt = \\frac{1} {2\\pi}\\int _ {t=0} ^{2\\pi} {\\dfrac{\\left(1-cos(2t)\\right)}{2}}dt\n",
531 | "$$\n",
532 | "\n",
533 | "Trigonometric Identity: $cos(2x)=1-2sin^2(x)$\n",
534 | "\n",
535 | "The cosine integrated over complete periods becomes 0, hence we get:\n",
536 | "\n",
537 | "$$ n\\large\n",
538 | "=\\frac{1} {2\\pi} \\int _{t=0}^{2\\pi} {\\dfrac{1}{2}} dt =\\frac{1} {2\\pi} \\cdot \\pi=\\frac{1}{ 2}\n",
539 | "$$\n"
540 | ]
541 | },
542 | {
543 | "cell_type": "code",
544 | "execution_count": 11,
545 | "metadata": {
546 | "slideshow": {
547 | "slide_type": "-"
548 | }
549 | },
550 | "outputs": [
551 | {
552 | "data": {
553 | "text/latex": [
554 | "$\\displaystyle E{\\left(x^{2} \\right)} = \\int\\limits_{-1}^{1} \\frac{x^{2}}{\\pi \\sqrt{1 - x^{2}}}\\, dx$"
555 | ],
556 | "text/plain": [
557 | "Eq(E(x**2), Integral(x**2/(pi*sqrt(1 - x**2)), (x, -1, 1)))"
558 | ]
559 | },
560 | "metadata": {},
561 | "output_type": "display_data"
562 | },
563 | {
564 | "data": {
565 | "text/latex": [
566 | "$\\displaystyle E{\\left(x^{2} \\right)} = \\frac{1}{2}$"
567 | ],
568 | "text/plain": [
569 | "Eq(E(x**2), 1/2)"
570 | ]
571 | },
572 | "metadata": {},
573 | "output_type": "display_data"
574 | }
575 | ],
576 | "source": [
577 | "# Calculate the Expctation of Power\n",
578 | "E = Function('E')(x**2)\n",
579 | "E_x2 = Eq(E,Integral(x**2*Eq_p_x.rhs,(x,-1,1)))\n",
580 | "display(E_x2)\n",
581 | "display(E_x2.doit())"
582 | ]
583 | },
584 | {
585 | "cell_type": "markdown",
586 | "metadata": {
587 | "slideshow": {
588 | "slide_type": "-"
589 | }
590 | },
591 | "source": [
592 | "What do we get for a sinusoid with a different amplitude, say $A/2 \\cdot sin(t)$?\n",
593 | "\n",
594 | "The expected power is:\n",
595 | "\n",
596 | "$$ \\large\n",
597 | "E(x^2)=\\frac{A^2}{ 8}\n",
598 | "$$"
599 | ]
600 | },
601 | {
602 | "cell_type": "code",
603 | "execution_count": 12,
604 | "metadata": {
605 | "slideshow": {
606 | "slide_type": "-"
607 | }
608 | },
609 | "outputs": [
610 | {
611 | "data": {
612 | "text/latex": [
613 | "$\\displaystyle E{\\left(x^{2} \\right)} = \\frac{\\int\\limits_{0}^{2 \\pi} \\frac{A^{2} \\sin^{2}{\\left(t \\right)}}{4}\\, dt}{2 \\pi}$"
614 | ],
615 | "text/plain": [
616 | "Eq(E(x**2), Integral(A**2*sin(t)**2/4, (t, 0, 2*pi))/(2*pi))"
617 | ]
618 | },
619 | "metadata": {},
620 | "output_type": "display_data"
621 | },
622 | {
623 | "data": {
624 | "text/latex": [
625 | "$\\displaystyle E{\\left(x^{2} \\right)} = \\frac{A^{2}}{8}$"
626 | ],
627 | "text/plain": [
628 | "Eq(E(x**2), A**2/8)"
629 | ]
630 | },
631 | "metadata": {},
632 | "output_type": "display_data"
633 | }
634 | ],
635 | "source": [
636 | "# Calculate Expectation of Power of A/2 * sin(t)\n",
637 | "E = Function('E')(x**2)\n",
638 | "E_x2 = Eq(E,(1/(2*pi))*Integral(((A/2)*sin(t))**2,(t,0,2*pi)))\n",
639 | "display(E_x2)\n",
640 | "display(E_x2.doit())"
641 | ]
642 | },
643 | {
644 | "cell_type": "markdown",
645 | "metadata": {
646 | "slideshow": {
647 | "slide_type": "-"
648 | }
649 | },
650 | "source": [
651 | "So this leads to an SNR of:\n",
652 | "\n",
653 | "$$ \\large\n",
654 | "SNR=\\frac{\\frac{A^2}{8}} {\\frac{\\Delta^2}{12}}=\\frac{3 \\cdot A^2} {2 \\cdot \\Delta^2}\n",
655 | "$$\n",
656 | "\n",
657 | "Now assume again we have a A/D converter with N bits, and the sinusoid is at full range for this converter. Then \n",
658 | "$A=2^N \\cdot \\Delta$\n",
659 | "\n",
660 | "We can plug in this result into the above equation, and get\n",
661 | "\n",
662 | "$$ \\large\n",
663 | "SNR=\\frac{3 \\cdot 2^{2N} \\cdot \\Delta^2} {2 \\cdot \\Delta^2}={1.5 \\cdot 2^{2N}} $$\n",
664 | "\n",
665 | "In dB this will now be:\n",
666 | "\n",
667 | "$$\\large 10 \\cdot \\log_{10}(SNR)=10 \\cdot \\log_{10}(1.5) + N \\cdot 20 \\cdot \\log_{10}(2)=\n",
668 | "$$\n",
669 | "\n",
670 | "$$\\large = 1.76 dB +N \\cdot 6.02 dB$$\n",
671 | "\n",
672 | "\n",
673 | "Here we can see now, that using a sinusoidal signal instead of a uniformly distributed signal gives us a **boost of 1.76 dB** in SNR. This is because it is more likely to have larger values!\n",
674 | "We see that our rule of 6dB more SNR for each bit still holds!"
675 | ]
676 | },
677 | {
678 | "cell_type": "code",
679 | "execution_count": 13,
680 | "metadata": {
681 | "slideshow": {
682 | "slide_type": "-"
683 | }
684 | },
685 | "outputs": [
686 | {
687 | "data": {
688 | "text/latex": [
689 | "$\\displaystyle \\Delta = 2^{- N} A$"
690 | ],
691 | "text/plain": [
692 | "Eq(\\Delta, 2**(-N)*A)"
693 | ]
694 | },
695 | "metadata": {},
696 | "output_type": "display_data"
697 | },
698 | {
699 | "data": {
700 | "text/latex": [
701 | "$\\displaystyle A = 2^{N} \\Delta$"
702 | ],
703 | "text/plain": [
704 | "Eq(A, 2**N*\\Delta)"
705 | ]
706 | },
707 | "metadata": {},
708 | "output_type": "display_data"
709 | }
710 | ],
711 | "source": [
712 | "# Stepsize as function of full range\n",
713 | "delta, N = symbols('\\Delta N')\n",
714 | "Eq_delta = Eq(delta, A/(2**N) )\n",
715 | "display(Eq_delta)\n",
716 | "Eq_A = Eq(A,solve(Eq_delta,A)[0])\n",
717 | "display(Eq_A)"
718 | ]
719 | },
720 | {
721 | "cell_type": "code",
722 | "execution_count": 14,
723 | "metadata": {
724 | "slideshow": {
725 | "slide_type": "-"
726 | }
727 | },
728 | "outputs": [
729 | {
730 | "data": {
731 | "text/latex": [
732 | "$\\displaystyle \\frac{3 A^{2}}{2 \\Delta^{2}}$"
733 | ],
734 | "text/plain": [
735 | "3*A**2/(2*\\Delta**2)"
736 | ]
737 | },
738 | "metadata": {},
739 | "output_type": "display_data"
740 | },
741 | {
742 | "data": {
743 | "text/latex": [
744 | "$\\displaystyle \\frac{3 \\cdot 2^{2 N}}{2}$"
745 | ],
746 | "text/plain": [
747 | "3*2**(2*N)/2"
748 | ]
749 | },
750 | "metadata": {},
751 | "output_type": "display_data"
752 | }
753 | ],
754 | "source": [
755 | "# Calculate Signal to Noise Rate\n",
756 | "SNR = E_x2.doit().rhs / (delta**2/12)\n",
757 | "display(SNR)\n",
758 | "display(SNR.subs(A,Eq_A.rhs))"
759 | ]
760 | }
761 | ],
762 | "metadata": {
763 | "kernelspec": {
764 | "display_name": "Python 3",
765 | "language": "python",
766 | "name": "python3"
767 | },
768 | "language_info": {
769 | "codemirror_mode": {
770 | "name": "ipython",
771 | "version": 3
772 | },
773 | "file_extension": ".py",
774 | "mimetype": "text/x-python",
775 | "name": "python",
776 | "nbconvert_exporter": "python",
777 | "pygments_lexer": "ipython3",
778 | "version": "3.7.5"
779 | },
780 | "livereveal": {
781 | "rise": {
782 | "height": "90%",
783 | "width": "90%"
784 | },
785 | "scroll": true,
786 | "theme": "sky",
787 | "transition": "zoom"
788 | },
789 | "widgets": {
790 | "application/vnd.jupyter.widget-state+json": {
791 | "state": {},
792 | "version_major": 2,
793 | "version_minor": 0
794 | }
795 | }
796 | },
797 | "nbformat": 4,
798 | "nbformat_minor": 2
799 | }
800 |
--------------------------------------------------------------------------------
/ADSP_04_LloydMax.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {
6 | "slideshow": {
7 | "slide_type": "slide"
8 | }
9 | },
10 | "source": [
11 | "
\n",
12 | " \n",
13 | "
\n",
14 | "\n",
15 | "### Prof. Dr. -Ing. Gerald Schuller Jupyter Notebook: Renato Profeta\n"
16 | ]
17 | },
18 | {
19 | "cell_type": "markdown",
20 | "metadata": {
21 | "slideshow": {
22 | "slide_type": "-"
23 | }
24 | },
25 | "source": [
26 | "# Lloyd-Max Quantizer"
27 | ]
28 | },
29 | {
30 | "cell_type": "code",
31 | "execution_count": 1,
32 | "metadata": {
33 | "hide_input": true
34 | },
35 | "outputs": [
36 | {
37 | "data": {
38 | "text/html": [
39 | "\n"
40 | ],
41 | "text/plain": [
42 | ""
43 | ]
44 | },
45 | "metadata": {},
46 | "output_type": "display_data"
47 | }
48 | ],
49 | "source": [
50 | "%%html\n",
51 | ""
52 | ]
53 | },
54 | {
55 | "cell_type": "markdown",
56 | "metadata": {
57 | "slideshow": {
58 | "slide_type": "-"
59 | }
60 | },
61 | "source": [
62 | "**Idea:** Wouldn't it be helpful if we choose our **quantization steps smaller** where **signal samples appear most often**, to reduce the quantization error there, and make the quantization step size (and also the error) larger, where there are only a few samples?\n",
63 | "\n",
64 | "This is the idea behind the Lloyd-Max quantizer (see also the Book: N.S. Jayant, P. Noll: “Digital coding of waveforms“).\n",
65 | "\n",
66 | "**Observe** that this is not quite the same as for $\\mu$-law companding. There, the **small** values get the smallest quantization step sizes, here, the **most likely** values get the smallest quantization steps sizes.\n",
67 | "\n",
68 | "This is a type of non-uniform quantizer, which is adapted to the signals pdf. It basically minimizes the expectation of the quanization power (the expectaion of the squared signal, or its second moment), given the pdf of the signal to quantize."
69 | ]
70 | },
71 | {
72 | "cell_type": "code",
73 | "execution_count": 2,
74 | "metadata": {
75 | "hide_input": true
76 | },
77 | "outputs": [
78 | {
79 | "data": {
80 | "text/html": [
81 | "\n"
82 | ],
83 | "text/plain": [
84 | ""
85 | ]
86 | },
87 | "metadata": {},
88 | "output_type": "display_data"
89 | }
90 | ],
91 | "source": [
92 | "%%html\n",
93 | ""
94 | ]
95 | },
96 | {
97 | "cell_type": "markdown",
98 | "metadata": {
99 | "slideshow": {
100 | "slide_type": "-"
101 | }
102 | },
103 | "source": [
104 | "Let's call our Quantisation function Q(x) (this is quantization followed by reverse quantization). You can also think of non-uniform quantization as first applying this non-linear function and then to use uniform quantization. Then the expectation of our quantization power is:\n",
105 | "\n",
106 | "$$\n",
107 | "D=E((x-Q(x))^2)\n",
108 | "$$\n",
109 | "\n",
110 | "Observe that we use the square here, and not for instance the magnitude of the error, because the square leads to an easier solution for minimum, which we would like to find.\n",
111 | "\n",
112 | "Our **goal** is to **minimize this expectation** of the quantisation error power D.\n",
113 | "Starting with the pdf of our signal, the result should be our quantisation intervals and reconstruction values. Since we now assume non-uniform intervals, we need to give those intervals and their reconstruction values names, which can be see in the following graphic:\n",
114 | "\n",
115 | "
\n",
116 | " \n",
117 | "
"
118 | ]
119 | },
120 | {
121 | "cell_type": "code",
122 | "execution_count": 3,
123 | "metadata": {
124 | "hide_input": true
125 | },
126 | "outputs": [
127 | {
128 | "data": {
129 | "text/html": [
130 | "\n"
131 | ],
132 | "text/plain": [
133 | ""
134 | ]
135 | },
136 | "metadata": {},
137 | "output_type": "display_data"
138 | }
139 | ],
140 | "source": [
141 | "%%html\n",
142 | ""
143 | ]
144 | },
145 | {
146 | "cell_type": "markdown",
147 | "metadata": {
148 | "slideshow": {
149 | "slide_type": "-"
150 | }
151 | },
152 | "source": [
153 | "The encoder knows the $b_k$, and decides in which interval (what we called $\\Delta$ before) the sample lies, and assigns the interval index k to it, as before (remember: only the index k is transmitted to the decoder). The decoder takes this index, and assigns the reconstructed value $y_k$ to it, also as before.\n",
154 | "\n",
155 | "\n",
156 | "We call $b_k$ the decision boundaries, in the A/D converter or encoder (each interval gets an index as before), and on the decoding side we have the $y_k$ as the reconstruction values for each index from the encoding side. \n",
157 | "In the multidimensional case, they are also called a “**codeword**”. \n",
158 | "\n",
159 | "So using these definitions, and the pdf our the measured **probability distribution** of our signal p(x), we can re-write our equation for the error power or distortion:\n",
160 | "\n",
161 | "$$ \\large\n",
162 | "D=E((x-Q(x))^2)=\\int_{-\\infty} ^ \\infty (x-Q(x))^2 p(x) dx\n",
163 | "$$\n",
164 | "\n",
165 | "we can now subdivide the integral over the quantisation intervals, assuming we have M quantization intervals, by just adding the quantization error power of all the quantisation intervals (see also: Wikipedia: quantization (signal processing)):\n",
166 | "\n",
167 | "$$ \\large\n",
168 | "D=\\sum _ {k=1} ^ {M }\\int _ {b_{k-1}} ^ {b_k} (x-y_k)^2 p(x) dx$$\n",
169 | "\n",
170 | "We would now like to have the minimum of this expression for the decision boundaries $b_k$ and the reconstruction values $y_k$. Hence we need to take the first derivative of the distortion D with respect to those variables and obtain the zero point."
171 | ]
172 | },
173 | {
174 | "cell_type": "code",
175 | "execution_count": 4,
176 | "metadata": {
177 | "hide_input": true
178 | },
179 | "outputs": [
180 | {
181 | "data": {
182 | "text/html": [
183 | "\n"
184 | ],
185 | "text/plain": [
186 | ""
187 | ]
188 | },
189 | "metadata": {},
190 | "output_type": "display_data"
191 | }
192 | ],
193 | "source": [
194 | "%%html\n",
195 | ""
196 | ]
197 | },
198 | {
199 | "cell_type": "markdown",
200 | "metadata": {
201 | "slideshow": {
202 | "slide_type": "-"
203 | }
204 | },
205 | "source": [
206 | "Lets start with the decision boundaries $b_k$:\n",
207 | "\n",
208 | "$$\\large\n",
209 | "\\frac{\\partial D} {\\partial {b_k}}=0$$\n",
210 | "\n",
211 | "To obtain this derivative, we could first solve the integral, over 2 neighbouring quantisation intervals, because each decision interval $b_k$ appears in two intervals (one where it is the upper boundary, and one where it it the lower boundary).\n",
212 | "\n",
213 | "$$ \\large\n",
214 | "D_k=\\int _ {b_k }^ {b_{k+1}} (x-y_{k+1})^2 p(x) dx+ \\int _ {b_{k-1}} ^ {b_{k}} (x-y_{k})^2 p(x) dx\n",
215 | "$$\n",
216 | "\n",
217 | "Here we cannot really get a closed form solution for a general probability function p(x). Hence, to simplify matters, we make the **assumption** that p(x) is **approximately constant** over our 2 neighbouring quantisation intervals. This means we assume that our quantisation intervals are small in comparison with the changes of p(x)! \n",
218 | "\n",
219 | "**We need to keep this assumption in mind, because the derived algorithm is based on this assumption!**\n",
220 | "\n",
221 | "Hence we can set:\n",
222 | "\n",
223 | "$$p(x)=p$$\n",
224 | "\n",
225 | "Using this simplification we can now solve this integral:\n",
226 | "\n",
227 | "$$ \\large\n",
228 | "\\frac{D_k} {p}= \\frac{(b_k-y_k)^3}{ 3} - \\frac{(b_{k-1}-y_k)^3} {3 }+ \\frac{(b_{k+1}-y_{k+1})^3} { 3} -\\frac{(b_{k}-y_{k+1})^3} {3} $$"
229 | ]
230 | },
231 | {
232 | "cell_type": "markdown",
233 | "metadata": {
234 | "slideshow": {
235 | "slide_type": "subslide"
236 | }
237 | },
238 | "source": [
239 | "#### Solving using Sympy"
240 | ]
241 | },
242 | {
243 | "cell_type": "code",
244 | "execution_count": 5,
245 | "metadata": {
246 | "slideshow": {
247 | "slide_type": "-"
248 | }
249 | },
250 | "outputs": [],
251 | "source": [
252 | "# Imports \n",
253 | "from sympy import Eq, symbols, Integral, Derivative, simplify, solve\n",
254 | "\n",
255 | "# Define Symbols\n",
256 | "x, yk, yk1, bk, bkp1, bkm1, p = symbols('x y_k y_{k+1} b_k b_{k+1} b_{k-1} p', real=True)"
257 | ]
258 | },
259 | {
260 | "cell_type": "code",
261 | "execution_count": 6,
262 | "metadata": {
263 | "slideshow": {
264 | "slide_type": "-"
265 | }
266 | },
267 | "outputs": [
268 | {
269 | "data": {
270 | "text/latex": [
271 | "$\\displaystyle \\int\\limits_{b_{k-1}}^{b_{k}} p \\left(x - y_{k}\\right)^{2}\\, dx + \\int\\limits_{b_{k}}^{b_{k+1}} p \\left(x - y_{k+1}\\right)^{2}\\, dx$"
272 | ],
273 | "text/plain": [
274 | "Integral(p*(x - y_k)**2, (x, b_{k-1}, b_k)) + Integral(p*(x - y_{k+1})**2, (x, b_k, b_{k+1}))"
275 | ]
276 | },
277 | "metadata": {},
278 | "output_type": "display_data"
279 | },
280 | {
281 | "data": {
282 | "text/latex": [
283 | "$\\displaystyle \\frac{p \\left(- 3 b_{k}^{2} y_{k} + 3 b_{k}^{2} y_{k+1} + 3 b_{k} y_{k}^{2} - 3 b_{k} y_{k+1}^{2} + b_{k+1}^{3} - 3 b_{k+1}^{2} y_{k+1} + 3 b_{k+1} y_{k+1}^{2} - b_{k-1}^{3} + 3 b_{k-1}^{2} y_{k} - 3 b_{k-1} y_{k}^{2}\\right)}{3}$"
284 | ],
285 | "text/plain": [
286 | "p*(-3*b_k**2*y_k + 3*b_k**2*y_{k+1} + 3*b_k*y_k**2 - 3*b_k*y_{k+1}**2 + b_{k+1}**3 - 3*b_{k+1}**2*y_{k+1} + 3*b_{k+1}*y_{k+1}**2 - b_{k-1}**3 + 3*b_{k-1}**2*y_k - 3*b_{k-1}*y_k**2)/3"
287 | ]
288 | },
289 | "execution_count": 6,
290 | "metadata": {},
291 | "output_type": "execute_result"
292 | }
293 | ],
294 | "source": [
295 | "# Dk Integral\n",
296 | "Dk = Integral((x-yk1)**2*p,(x,bk,bkp1)) + Integral((x-yk)**2*p,(x,bkm1,bk))\n",
297 | "display(Dk)\n",
298 | "simplify(Dk.doit())"
299 | ]
300 | },
301 | {
302 | "cell_type": "markdown",
303 | "metadata": {
304 | "slideshow": {
305 | "slide_type": "-"
306 | }
307 | },
308 | "source": [
309 | "Since we now have a closed form solution, we can easily take the derivative with respect to $b_k$ (which only influences $D_k$ in $D$, hence we can drop the k in the derivative):\n",
310 | "\n",
311 | "$$ \\large\n",
312 | "\\frac{\\partial D/p} {\\partial {b_k}} = (b_k -y_k)^2 -(b_k -y_{k+1})^2$$"
313 | ]
314 | },
315 | {
316 | "cell_type": "code",
317 | "execution_count": 7,
318 | "metadata": {
319 | "slideshow": {
320 | "slide_type": "-"
321 | }
322 | },
323 | "outputs": [
324 | {
325 | "data": {
326 | "text/latex": [
327 | "$\\displaystyle \\frac{\\partial}{\\partial b_{k}} \\frac{\\int\\limits_{b_{k-1}}^{b_{k}} p \\left(x - y_{k}\\right)^{2}\\, dx + \\int\\limits_{b_{k}}^{b_{k+1}} p \\left(x - y_{k+1}\\right)^{2}\\, dx}{p}$"
328 | ],
329 | "text/plain": [
330 | "Derivative((Integral(p*(x - y_k)**2, (x, b_{k-1}, b_k)) + Integral(p*(x - y_{k+1})**2, (x, b_k, b_{k+1})))/p, b_k)"
331 | ]
332 | },
333 | "metadata": {},
334 | "output_type": "display_data"
335 | },
336 | {
337 | "data": {
338 | "text/latex": [
339 | "$\\displaystyle - 2 b_{k} y_{k} + 2 b_{k} y_{k+1} + y_{k}^{2} - y_{k+1}^{2}$"
340 | ],
341 | "text/plain": [
342 | "-2*b_k*y_k + 2*b_k*y_{k+1} + y_k**2 - y_{k+1}**2"
343 | ]
344 | },
345 | "execution_count": 7,
346 | "metadata": {},
347 | "output_type": "execute_result"
348 | }
349 | ],
350 | "source": [
351 | "display(Derivative(Dk/p,bk))\n",
352 | "simplify(Derivative(Dk/p,bk).doit())"
353 | ]
354 | },
355 | {
356 | "cell_type": "markdown",
357 | "metadata": {
358 | "slideshow": {
359 | "slide_type": "-"
360 | }
361 | },
362 | "source": [
363 | "We can set this then to zero, and observing that $y_{k+1}>b_k$ (see above image), we can take the positive square root of both sides:\n",
364 | "\n",
365 | "$$ \\large\n",
366 | "(b_k -y_k)^2 -(b_k -y_{k+1})^2=0\n",
367 | "$$\n",
368 | "\n",
369 | "$$ \\large\n",
370 | "(b_k -y_k) =( y_{k+1} - b_k)\n",
371 | "$$\n",
372 | "\n",
373 | "$$ \\large\n",
374 | "b_k= \\frac{y_{k+1}+\n",
375 | "y_k} { 2}$$\n",
376 | "\n",
377 | "This means that we put our decision boundaries right in the middle of two reconstruction values. But remember, this is only optimal if we assume that the signals pdf is roughly constant over the 2 quantisation intervals! This approach is also called the “**nearest neighbour**”, because any signal value or data point is always quantized to the **nearest reconstruction value**. This is one important result of this strategy."
378 | ]
379 | },
380 | {
381 | "cell_type": "code",
382 | "execution_count": 8,
383 | "metadata": {
384 | "slideshow": {
385 | "slide_type": "-"
386 | }
387 | },
388 | "outputs": [
389 | {
390 | "data": {
391 | "text/latex": [
392 | "$\\displaystyle - 2 b_{k} y_{k} + 2 b_{k} y_{k+1} + y_{k}^{2} - y_{k+1}^{2} = 0$"
393 | ],
394 | "text/plain": [
395 | "Eq(-2*b_k*y_k + 2*b_k*y_{k+1} + y_k**2 - y_{k+1}**2, 0)"
396 | ]
397 | },
398 | "metadata": {},
399 | "output_type": "display_data"
400 | },
401 | {
402 | "data": {
403 | "text/latex": [
404 | "$\\displaystyle b_{k} = \\frac{y_{k}}{2} + \\frac{y_{k+1}}{2}$"
405 | ],
406 | "text/plain": [
407 | "Eq(b_k, y_k/2 + y_{k+1}/2)"
408 | ]
409 | },
410 | "metadata": {},
411 | "output_type": "display_data"
412 | }
413 | ],
414 | "source": [
415 | "Eq_bk = Eq(simplify(Derivative(Dk/p,bk).doit()))\n",
416 | "display(Eq_bk)\n",
417 | "display(Eq(bk,solve(Eq_bk,bk)[0]))"
418 | ]
419 | },
420 | {
421 | "cell_type": "markdown",
422 | "metadata": {
423 | "slideshow": {
424 | "slide_type": "subslide"
425 | }
426 | },
427 | "source": [
428 | "Now we have the decision boundaries, but we still need the reconstruction values $y_k$. To obtain them, we can again take the derivative of D, and set it to zero. Here we cannot start with an assumption of a uniform pdf, because we would like to have a dependency on a non-uniform pdf. We could make this assumption before, because we only assumed it for the (small) quantisation intervals. This can be true in practice also for non-uniform pdf's, if we have enough quantisation intervals.\n",
429 | "\n",
430 | "But to still have the dependency on the pdf, for the reconstruction values $y_k$ we have to start at the beginning, take the derivative of the original formulation of D.\n",
431 | "\n",
432 | "$$ \\large\n",
433 | "D=\\sum_{k=1} ^M \\int _{b_{k-1}}^ {b_k} (x-y_k)^2 p(x) dx$$\n",
434 | "\n",
435 | "\n",
436 | "Here we have the pdf p(x) and the reconstruction values (codewords) $y_k$. Now we start with taking the derivative with respect to the reconstruction value $y_k$ and set it to 0:\n",
437 | "\n",
438 | "$$ \\large\n",
439 | "\\frac{\\partial D} {\\partial {y_k}}=-\\sum_ {k=1} ^ {M} \\int_{b_{k-1}} ^{b_k} 2 \\cdot (x-y_k) p(x) dx = 0\n",
440 | "$$"
441 | ]
442 | },
443 | {
444 | "cell_type": "code",
445 | "execution_count": 9,
446 | "metadata": {
447 | "hide_input": true
448 | },
449 | "outputs": [
450 | {
451 | "data": {
452 | "text/html": [
453 | "\n"
454 | ],
455 | "text/plain": [
456 | ""
457 | ]
458 | },
459 | "metadata": {},
460 | "output_type": "display_data"
461 | }
462 | ],
463 | "source": [
464 | "%%html\n",
465 | ""
466 | ]
467 | },
468 | {
469 | "cell_type": "code",
470 | "execution_count": 10,
471 | "metadata": {
472 | "slideshow": {
473 | "slide_type": "-"
474 | }
475 | },
476 | "outputs": [],
477 | "source": [
478 | "from sympy import Function, Sum, Indexed\n",
479 | "p_x = Function('p')(x)\n",
480 | "M, k = symbols('M k', real=True, positive=True)"
481 | ]
482 | },
483 | {
484 | "cell_type": "code",
485 | "execution_count": 11,
486 | "metadata": {
487 | "slideshow": {
488 | "slide_type": "-"
489 | }
490 | },
491 | "outputs": [
492 | {
493 | "data": {
494 | "text/latex": [
495 | "$\\displaystyle \\sum_{k=1}^{M} \\int\\limits_{b_{k-1}}^{b_{k}} \\left(x - y_{k}\\right)^{2} p{\\left(x \\right)}\\, dx$"
496 | ],
497 | "text/plain": [
498 | "Sum(Integral((x - y_k)**2*p(x), (x, b_{k-1}, b_k)), (k, 1, M))"
499 | ]
500 | },
501 | "metadata": {},
502 | "output_type": "display_data"
503 | },
504 | {
505 | "data": {
506 | "text/latex": [
507 | "$\\displaystyle \\frac{\\partial}{\\partial y_{k}} \\sum_{k=1}^{M} \\int\\limits_{b_{k-1}}^{b_{k}} \\left(x - y_{k}\\right)^{2} p{\\left(x \\right)}\\, dx$"
508 | ],
509 | "text/plain": [
510 | "Derivative(Sum(Integral((x - y_k)**2*p(x), (x, b_{k-1}, b_k)), (k, 1, M)), y_k)"
511 | ]
512 | },
513 | "metadata": {},
514 | "output_type": "display_data"
515 | }
516 | ],
517 | "source": [
518 | "D = Sum(Integral((x-yk)**2*p_x,(x,bkm1,bk)),(k,1,M))\n",
519 | "display(D)\n",
520 | "display(Derivative(D,yk))"
521 | ]
522 | },
523 | {
524 | "cell_type": "markdown",
525 | "metadata": {
526 | "slideshow": {
527 | "slide_type": "-"
528 | }
529 | },
530 | "source": [
531 | "Since the $y_k$ is only in 1 interval, the sum disappears:\n",
532 | "\n",
533 | "$$ \\large\n",
534 | "\\frac{\\partial D}{\\partial {y_k}}=- \\int _ {b_{k-1}}^{b_k} 2 \\cdot (x-y_k) p(x) dx = 0\n",
535 | "$$\n"
536 | ]
537 | },
538 | {
539 | "cell_type": "code",
540 | "execution_count": 12,
541 | "metadata": {
542 | "slideshow": {
543 | "slide_type": "-"
544 | }
545 | },
546 | "outputs": [
547 | {
548 | "data": {
549 | "text/latex": [
550 | "$\\displaystyle \\frac{\\partial}{\\partial y_{k}} \\int\\limits_{b_{k-1}}^{b_{k}} \\left(x - y_{k}\\right)^{2} p{\\left(x \\right)}\\, dx$"
551 | ],
552 | "text/plain": [
553 | "Derivative(Integral((x - y_k)**2*p(x), (x, b_{k-1}, b_k)), y_k)"
554 | ]
555 | },
556 | "metadata": {},
557 | "output_type": "display_data"
558 | },
559 | {
560 | "data": {
561 | "text/latex": [
562 | "$\\displaystyle \\int\\limits_{b_{k-1}}^{b_{k}} 2 \\left(- x + y_{k}\\right) p{\\left(x \\right)}\\, dx$"
563 | ],
564 | "text/plain": [
565 | "Integral(2*(-x + y_k)*p(x), (x, b_{k-1}, b_k))"
566 | ]
567 | },
568 | "metadata": {},
569 | "output_type": "display_data"
570 | }
571 | ],
572 | "source": [
573 | "display(Derivative(Integral((x-yk)**2*p_x,(x,bkm1,bk)),yk))\n",
574 | "display(simplify(Derivative(Integral((x-yk)**2*p_x,(x,bkm1,bk)),yk).doit()))"
575 | ]
576 | },
577 | {
578 | "cell_type": "markdown",
579 | "metadata": {
580 | "slideshow": {
581 | "slide_type": "-"
582 | }
583 | },
584 | "source": [
585 | "Since we have a sum, we can split this integral in 2 parts (and remove the - sign):\n",
586 | "\n",
587 | "\n",
588 | "$$ \\large\n",
589 | "\\int _ {b_{k-1}}^{b_k} 2 \\cdot x p(x) dx -\\int _{b_{k-1}} ^ {b_k} 2 \\cdot y_k p(x) dx = 0\n",
590 | "$$\n",
591 | "\n",
592 | "$$ \\large\n",
593 | "\\int _ {b_{k-1}} ^ {b_k} x \\cdot p(x) dx -y_k \\cdot \\int_ {b_{k-1}} ^ {b_k} p(x) dx = 0\n",
594 | "$$\n",
595 | "\n",
596 | "Hence we get the result\n",
597 | "\n",
598 | "$$ \\large\n",
599 | "y_k = \\frac{\\int _ {b_{k-1}}^ {b_k} x \\cdot p(x) dx} {\\int _{b_{k-1}} ^{b_k} p(x) dx}\n",
600 | "$$"
601 | ]
602 | },
603 | {
604 | "cell_type": "code",
605 | "execution_count": 13,
606 | "metadata": {
607 | "slideshow": {
608 | "slide_type": "-"
609 | }
610 | },
611 | "outputs": [
612 | {
613 | "data": {
614 | "text/latex": [
615 | "$\\displaystyle - 2 \\int\\limits_{b_{k-1}}^{b_{k}} x p{\\left(x \\right)}\\, dx + 2 \\int\\limits_{b_{k-1}}^{b_{k}} y_{k} p{\\left(x \\right)}\\, dx = 0$"
616 | ],
617 | "text/plain": [
618 | "Eq(-2*Integral(x*p(x), (x, b_{k-1}, b_k)) + 2*Integral(y_k*p(x), (x, b_{k-1}, b_k)), 0)"
619 | ]
620 | },
621 | "metadata": {},
622 | "output_type": "display_data"
623 | },
624 | {
625 | "data": {
626 | "text/latex": [
627 | "$\\displaystyle - 2 \\int\\limits_{b_{k-1}}^{b_{k}} x p{\\left(x \\right)}\\, dx = - 2 y_{k} \\int\\limits_{b_{k-1}}^{b_{k}} p{\\left(x \\right)}\\, dx$"
628 | ],
629 | "text/plain": [
630 | "Eq(-2*Integral(x*p(x), (x, b_{k-1}, b_k)), -2*y_k*Integral(p(x), (x, b_{k-1}, b_k)))"
631 | ]
632 | },
633 | "metadata": {},
634 | "output_type": "display_data"
635 | },
636 | {
637 | "data": {
638 | "text/latex": [
639 | "$\\displaystyle y_{k} = \\frac{\\int\\limits_{b_{k-1}}^{b_{k}} x p{\\left(x \\right)}\\, dx}{\\int\\limits_{b_{k-1}}^{b_{k}} p{\\left(x \\right)}\\, dx}$"
640 | ],
641 | "text/plain": [
642 | "Eq(y_k, Integral(x*p(x), (x, b_{k-1}, b_k))/Integral(p(x), (x, b_{k-1}, b_k)))"
643 | ]
644 | },
645 | "execution_count": 13,
646 | "metadata": {},
647 | "output_type": "execute_result"
648 | }
649 | ],
650 | "source": [
651 | "display(Eq(-2*(Integral(x*p_x,(x,bkm1,bk)) - Integral(yk*p_x,(x,bkm1,bk)))))\n",
652 | "Eq_yk=Eq(-2*(Integral(x*p_x,(x,bkm1,bk))),-2*yk*Integral(p_x,(x,bkm1,bk)))\n",
653 | "display(Eq_yk)\n",
654 | "Eq(yk,solve(Eq_yk,yk)[0])"
655 | ]
656 | },
657 | {
658 | "cell_type": "markdown",
659 | "metadata": {
660 | "slideshow": {
661 | "slide_type": "-"
662 | }
663 | },
664 | "source": [
665 | "Observe that we now got a result without making any assumptions on p(x).\n",
666 | "\n",
667 | "This can be interpreted as a **conditional expectation** of our signal value over the quantization interval (given the signal is in this interval), or also its “**centroid**” as reconstruction value (codeword). \n",
668 | "\n",
669 | "- The value in the numerator can be seen as the expectation value of our signal in the interval.\n",
670 | "- The denominator can be seen as the probability of that signal being in that interval. \n",
671 | "\n",
672 | "Hence it can be interpreted as: Given the signal is inside the interval, this is its average or expected value.\n",
673 | "\n",
674 | "Since the decision boundaries $b_k$ depend on the reconstruction values $y_k$, and the $y_k$ in turn depend on the $b_k$, we need to come up with a way to compute them. The approach for this is an **iterative algorithm**:\n",
675 | "\n",
676 | "\n",
677 | "
Decide on M, start (initialize the iteration) with a random assignment of M reconstruction values (codewords) $y_k$
\n",
678 | "
Using the reconstruction values $y_k$, compute the boundary values $b_k$ as mid-points between 2 reconstruction values / codewords (nearest neighbour rule)
\n",
679 | "
Using the pdf of our signal and the boundary values $b_k$, update, compute new reconstruction values (codewords) $y_k$ as centroids or conditional expectation over the quantisation areas between $b_k$ and $b_{k-1}$
\n",
680 | "
Go to 2) until update is sufficiently small (< epsilon).