Project 03
Last edits: 3/12/2026

SetDirectory[NotebookDirectory[]];<<DW.wl;

Project 3

Problem 1 (10 points)

This is a variation on the theme of Problem 2 in Project 2.
Take a RGB color image of your choice of dimensions m×n (m,n even), and compute its  Y, Cb and Cr components. Use the averaging procedure from Notebook 031 to replace the Cb and Cr components by versions of dimensions m/2× n/2, call them (Subscript[Cb, 2]) and (Subscript[Cr, 2]). (Note that the raw storage requirement of (Subscript[YCb, 2])(Subscript[Cr, 2]) is only half of that of YCbCr.) 
By reversing the steps above, recreate an approximation to the original RGB color image from its Y-, (Subscript[Cb, 2])- and (Subscript[Cr, 2])- components. Check the quality of the approximation you obtain visually and by computing the Peak Signal to Noise Ratio with the original image. 
Use ArrayFlatten to get rid of sets of {...} after anti-averaging:

A={{208,33,131},{148,7,223}}

B=(({{(({{208, 208}, {208, 208}})), (({{3, 3}, {3, 3}})), (({{131, 131}, {131, 131}}))}, {(({{148, 148}, {148, 148}})), (({{7, 7}, {7, 7}})), (({{223, 223}, {223, 223}}))}}));

ArrayFlatten[B]

Problem 2 (10 points)

Write two commands (or modules if necessary) for Huffman encoding and decoding. Inputs to the first module should be a character string and a coding table; the output should be a binary sequence encoding the character string.

cstr="ABRACADABRA"

huff = {{"A", "0"}, {"R", "111"}, {"B", "10"}, {"D", "1101"}, {"C", "1100"}}

You have to write the code for the next two commands!

bstring=StreamEncoding[cstr,huff]

The second command “StreamDecoding” should have as inputs a binary string and a coding table and output the corresponding character string:

StreamDecoding[bstring,huff]

You will need to consult the help section to find out about strings and replacement operators (“ReplaceAll” or “/.”); the next command may be useful to rewrite the coding table as a list of replacement rules:

cd=Apply[Rule,huff,2]

Problem 3 (10 points)

The problem will use the command 'FourierSCPlot':

?FourierSCPlot

By the way, you can create π by either writing 'Pi' or by pressing 'EscpEsc'.

Pi
N[Pi]

Consider the following function :

f[x_]=Piecewise[{{-1/2,x<0},{1/2,x>0}}];
Plot[f[x],{x,-π,π},PlotStyle->{Blue,Thick}]

Below is the graph of f(x) again (dashed) and the graph of its 8th "degree" Fourier approximation (green) :

FourierSC[f[x],x,8]

FourierSCPlot[f[x],x,8]

We can use ' PlotRange' to zoom in, and notice that - in the worst case scenario -  the value of the function f(x) differs from its Fourier approximation by about  Δy≈0.092; the "first" peak of the Fourier approximation happens at a distance of about Δx≈0.39 from the point of discontinuity of the function:

Here is the same plot without the blue lines :

FourierSCPlot[f[x],x,8,GridLines->Automatic,PlotRange->{{0,.5},{.49,.6}},Ticks->Automatic]

1. How do these values of Δx and Δy change when you increase the number of terms of the Fourier approximation? 
2. Repeat 1. for the function g(x):

g[x_]=Piecewise[{{-1,x<0},{1,x>0}}];
Plot[g[x],{x,-π,π},PlotStyle->{Blue,Thick}]

3. Repeat 1. for the "sawtooth" function h(x) :

h[x_]=Piecewise[{{(x+π)/π,x<0},{x/π,x>0}}];
Plot[h[x],{x,-π,π},PlotStyle->{Blue,Thick}]

4. Summarize your findings : How do the values Δx and Δy depend on the degree of the approximation? How do they depend on the size of the "jump" at x = 0? Do they depend on the shape of the function? What other observations can you make?