(* Content-type: application/mathematica *) (*** Wolfram Notebook File ***) (* http://www.wolfram.com/nb *) (* CreatedBy='Mathematica 6.0' *) (*CacheID: 234*) (* Internal cache information: NotebookFileLineBreakTest NotebookFileLineBreakTest NotebookDataPosition[ 145, 7] NotebookDataLength[ 43788, 1386] NotebookOptionsPosition[ 39067, 1242] NotebookOutlinePosition[ 39477, 1260] CellTagsIndexPosition[ 39434, 1257] WindowFrame->Normal ContainsDynamic->False*) (* Beginning of Notebook Content *) Notebook[{ Cell[CellGroupData[{ Cell["Compression and Reconstruction Accuracy of Digital Data", "Title"], Cell["Student Projects in AP1603 investigating Fourier transforms.", \ "Subsubtitle"], Cell["\<\ All projects must have\[Ellipsis] Name:____________ Email:_____@columbia.edu\ \>", "Subsubtitle"], Cell[CellGroupData[{ Cell["Introduction", "Section"], Cell[TextData[{ "The second general theme of our ", StyleBox["Mathematica", FontSlant->"Italic"], " investigations is the Fourier transform. In our first lecture, we examined \ how a complete expansion of a function in terms of simple Cosine and Sine \ functions allowed the solution of a partial differential equation. The \ solution was represented as an ", StyleBox["infinite sum", FontSlant->"Italic"], " of functions. However, we learned that if we take only the most \ significant (or largest amplitude) functions, the difference between the \ actual signal and the approximation can be relatively small. ", "\n\nIn our next two lectures, we examined the application of Fourier \ transforms to digital data. We explored the active field of ", StyleBox["digital signal processing", FontSlant->"Italic"], ". Since the invention of the computer and the FFT, large amounts of data \ can be transformed rapidly. Hardware implementations of these algorithms have \ lead to the many commercial products found in commercial electronics (like \ the DVD, streaming media, and accurate compression of large photographs.) ", "\n\nFor your second research project, I suggest that you determine the \ relationship between the degree of data compression and the accuracy of the \ reconstructed data. You may experiment with either audio or graphical data or \ both. You may look at the files posted on our web site, or import or create \ your own data sets. Try to limit your analysis to one type of data file so \ that your project explores a topic in depth.\n\nIn order to carry out a \ quantitative analysis, you must define ", StyleBox["measurements", FontSlant->"Italic"], " of data compression and of data reconstruction accuracy. Below, I will \ define three measures that you should feel free to use. The first is the ", StyleBox["information entropy", FontSlant->"Italic"], ". It is a measure of the disorder of the data. Multiplying the ", StyleBox["entropy", FontSlant->"Italic"], " by the number of data points is the minimum possible file size required to \ contain the information within the data. The second is the ", StyleBox["root mean square relative error ", FontSlant->"Italic"], "(RMSE) of the reconstruction relative to the \"real\" data. It can be \ related to the ", StyleBox["signal to noise ratio ", FontSlant->"Italic"], "(SNR)", StyleBox[".", FontSlant->"Italic"], " When the RMSE is large (or the SNR is small), the reconstruction becomes \ inaccurate. These two measurements can be used to quantify the trade-off \ between file size and accuracy. The third is the ", StyleBox["absolute error. ", FontSlant->"Italic"], "The absolute error is, perhaps, the easiest to understand; it represents \ the average difference between the original and reconstructed image or sound \ over the entire data set." }], "Text"], Cell[BoxData[ RowBox[{ RowBox[{"Off", "[", RowBox[{"General", "::", "spell1"}], "]"}], ";"}]], "Input"] }, Closed]], Cell[CellGroupData[{ Cell["Information Entropy", "Section"], Cell["\<\ The first measure that you can use in your project is called \"information \ entropy\". Entropy is a concept first developed for statistical physics. It \ is a measure of the disorder of a system. When dealing with digital data, the \ entropy measures the disorder (or complexity) of the data. When the entropy \ is small, the data is not disordered, and only a few digital values exist \ within the entire data set. For example, if you had 1000 data points with \ values all equal to 1, then the information entropy would be exactly zero. \ The data is not at all disordered, and (theoretically) you could represent \ the information contained within this data set by one bit. When the entropy \ is large, the data is very disordered, and many digital values exist in the \ data set. \ \>", "Text"], Cell[TextData[{ "The ", StyleBox["Mathematica", FontSlant->"Italic"], " function for information entropy is written as" }], "Text"], Cell[BoxData[ RowBox[{ RowBox[{"iEntropy", "[", "list_List", "]"}], ":=", RowBox[{"-", RowBox[{"Plus", "@@", RowBox[{ RowBox[{"(", RowBox[{ RowBox[{"N", "[", RowBox[{"#1", " ", RowBox[{"Log", "[", RowBox[{"2", ",", "#1"}], "]"}]}], "]"}], "&"}], ")"}], "/@", FractionBox[ RowBox[{"First", "[", RowBox[{"Transpose", "[", RowBox[{"Reverse", "[", RowBox[{ RowBox[{"Sort", "[", RowBox[{"Tally", "[", "list", "]"}], "]"}], ",", "2"}], "]"}], "]"}], "]"}], RowBox[{"Length", "[", "list", "]"}]]}]}]}]}]], "Input"], Cell[BoxData[ RowBox[{"Characters", "[", "\"\\"", "]"}]], "Input"], Cell[BoxData[ RowBox[{ RowBox[{"(", RowBox[{ FractionBox[ RowBox[{"First", "[", RowBox[{"Transpose", "[", RowBox[{"Reverse", "[", RowBox[{ RowBox[{"Sort", "[", RowBox[{"Tally", "[", "#1", "]"}], "]"}], ",", "2"}], "]"}], "]"}], "]"}], RowBox[{"Length", "[", "#1", "]"}]], "&"}], ")"}], "@@", RowBox[{"{", RowBox[{"Characters", "[", "\"\\"", "]"}], "}"}]}]], "Input"], Cell[BoxData[ RowBox[{"iEntropy", "[", RowBox[{"Characters", "[", "\"\\"", "]"}], "]"}]], "Input"], Cell["\<\ This function computes the sum of the logs of the \"probability\" of each \ value in the data.\ \>", "Text"], Cell["\<\ For example, a simple list with high entropy (and requiring at least 1000 \ bits of data) is\ \>", "Text"], Cell[BoxData[ RowBox[{"i1", "=", RowBox[{"RandomInteger", "[", RowBox[{ RowBox[{"{", RowBox[{"1", ",", "10"}], "}"}], ",", "30"}], "]"}]}]], "Input"], Cell[BoxData[ RowBox[{"Reverse", "[", RowBox[{ RowBox[{"Sort", "[", RowBox[{"Tally", "[", "i1", "]"}], "]"}], ",", "2"}], "]"}]], "Input"], Cell[BoxData[ RowBox[{ RowBox[{"Print", "[", RowBox[{"\"\\"", ",", RowBox[{"iEntropy", "[", "i1", "]"}], ",", " ", "\"\<; Bits Required = \>\"", ",", " ", RowBox[{ RowBox[{"iEntropy", "[", "i1", "]"}], " ", RowBox[{"Length", "[", "i1", "]"}]}]}], "]"}], ";"}]], "Input"], Cell["\<\ For example, a simple list with low entropy (and requiring at least 60 bits \ of data) is\ \>", "Text"], Cell[BoxData[ RowBox[{"i2", " ", "=", " ", RowBox[{"Table", "[", RowBox[{ RowBox[{"If", "[", RowBox[{ RowBox[{"i", "<", "15"}], ",", "1", ",", " ", "2"}], "]"}], ",", " ", RowBox[{"{", RowBox[{"i", ",", " ", "1", ",", " ", "30"}], "}"}]}], "]"}]}]], "Input"], Cell[BoxData[ RowBox[{"Reverse", "[", RowBox[{ RowBox[{"Sort", "[", RowBox[{"Tally", "[", "i2", "]"}], "]"}], ",", "2"}], "]"}]], "Input"], Cell[BoxData[ RowBox[{ RowBox[{"Print", "[", RowBox[{"\"\\"", ",", RowBox[{"iEntropy", "[", "i2", "]"}], ",", " ", "\"\<; Bits Required = \>\"", ",", " ", RowBox[{ RowBox[{"iEntropy", "[", "i2", "]"}], " ", RowBox[{"Length", "[", "i2", "]"}]}]}], "]"}], ";"}]], "Input"], Cell["\<\ As the data becomes more orderly, the information entropy decreases.\ \>", "Text"], Cell[TextData[{ "For two-dimensional data, your must first ", StyleBox["Flatten[\[Ellipsis]] ", FontWeight->"Bold"], "the data list before using ", StyleBox["iEntropy[\[Ellipsis]]", FontWeight->"Bold"], ". This converts the multiple-dimensional data to a one-dimensional list \ having the form acceptable to ", StyleBox["Frequencies[\[Ellipsis]]", FontWeight->"Bold"], "." }], "Text"], Cell[TextData[{ "You should be very aware of the difference between Real and Integer \ numbers. When you import an audio file (.aif), the integer (8-bit) data is \ converted to Real numbers. The data is still \"quantized\" into 256 different \ real numbers. The", StyleBox[" iEntropy[\[Ellipsis]]", FontWeight->"Bold"], " function works with quantized real numbers as well as integers. However, \ once you transform this data (using either a FFT or a DCT), the transform \ will ", StyleBox["not ", FontSlant->"Italic"], "be quantized. The information entropy will grow considerably. Therefore, in \ examining your data whether you use JPEG-weighted quantization or a uniform \ quantization, you must first quantize your data ", StyleBox["before", FontSlant->"Italic"], " you measure the information content with ", StyleBox["iEntropy[\[Ellipsis]]", FontWeight->"Bold"], "." }], "Text"] }, Closed]], Cell[CellGroupData[{ Cell["Root Mean Square Relative Error", "Section"], Cell["\<\ The root mean square relative error (RMSE) is a good measure of the \ difference between two data sequences. The function to compute the RMSE is \ defined by\ \>", "Text"], Cell[BoxData[ RowBox[{ RowBox[{"rmsError", "[", RowBox[{"l1_List", ",", "l2_List"}], "]"}], " ", ":=", " ", RowBox[{ RowBox[{"Sqrt", "[", RowBox[{"Plus", " ", "@@", " ", RowBox[{"(", RowBox[{ RowBox[{ RowBox[{"#", "^", "2"}], "&"}], " ", "/@", " ", RowBox[{"(", RowBox[{"l1", " ", "-", " ", "l2"}], ")"}]}], ")"}]}], "]"}], " ", "/", " ", RowBox[{"Sqrt", "[", RowBox[{"Plus", " ", "@@", " ", RowBox[{"(", RowBox[{"l1", " ", "l1"}], ")"}]}], "]"}]}]}]], "Input"], Cell[BoxData[ RowBox[{"rmsError", "[", RowBox[{ RowBox[{"{", RowBox[{"a", ",", "b", ",", "c"}], "}"}], ",", RowBox[{"{", RowBox[{"a2", ",", "b2", ",", "c2"}], "}"}]}], "]"}]], "Input"], Cell[TextData[{ "(Remember, the \"energy\" within a signal is defined by \"", StyleBox["Plus @@ (data data)", FontWeight->"Bold"], "\"", ".)" }], "Text"], Cell[BoxData[{ RowBox[{ RowBox[{"noise", "=", "0.1`"}], ";"}], "\n", RowBox[{ RowBox[{"i1", "=", RowBox[{"N", "[", RowBox[{"Table", "[", RowBox[{ RowBox[{ RowBox[{"Sin", "[", FractionBox[ RowBox[{"i", " ", "3", " ", "\[Pi]"}], "100"], "]"}], " ", SuperscriptBox[ RowBox[{"Sin", "[", FractionBox[ RowBox[{"i", " ", "\[Pi]"}], "100"], "]"}], "2"]}], ",", RowBox[{"{", RowBox[{"i", ",", "1", ",", "100"}], "}"}]}], "]"}], "]"}]}], ";"}], "\n", RowBox[{ RowBox[{"i2", "=", RowBox[{"i1", "+", RowBox[{"RandomReal", "[", RowBox[{ RowBox[{"{", RowBox[{ RowBox[{"-", "noise"}], ",", "noise"}], "}"}], ",", "100"}], "]"}]}]}], ";"}], "\n", RowBox[{"Show", "[", RowBox[{ RowBox[{"ListPlot", "[", RowBox[{"i1", ",", RowBox[{"DisplayFunction", "\[Rule]", "Identity"}]}], "]"}], ",", RowBox[{"ListPlot", "[", RowBox[{"i2", ",", RowBox[{"DisplayFunction", "\[Rule]", "Identity"}], ",", RowBox[{"PlotStyle", "\[Rule]", RowBox[{"RGBColor", "[", RowBox[{"1", ",", "0", ",", "0"}], "]"}]}]}], "]"}], ",", RowBox[{"DisplayFunction", "\[Rule]", "$DisplayFunction"}]}], "]"}]}], "Input"], Cell[BoxData[ RowBox[{"rmsError", "[", RowBox[{"i1", ",", "i2"}], "]"}]], "Input"], Cell[BoxData[{ RowBox[{ RowBox[{"noise", "=", "0.2`"}], ";"}], "\n", RowBox[{ RowBox[{"i1", "=", RowBox[{"N", "[", RowBox[{"Table", "[", RowBox[{ RowBox[{ RowBox[{"Sin", "[", FractionBox[ RowBox[{"i", " ", "3", " ", "\[Pi]"}], "100"], "]"}], " ", SuperscriptBox[ RowBox[{"Sin", "[", FractionBox[ RowBox[{"i", " ", "\[Pi]"}], "100"], "]"}], "2"]}], ",", RowBox[{"{", RowBox[{"i", ",", "1", ",", "100"}], "}"}]}], "]"}], "]"}]}], ";"}], "\n", RowBox[{ RowBox[{"i2", "=", RowBox[{"i1", "+", RowBox[{"RandomReal", "[", RowBox[{ RowBox[{"{", RowBox[{ RowBox[{"-", "noise"}], ",", "noise"}], "}"}], ",", "100"}], "]"}]}]}], ";"}], "\n", RowBox[{"Show", "[", RowBox[{ RowBox[{"ListPlot", "[", RowBox[{"i1", ",", RowBox[{"DisplayFunction", "\[Rule]", "Identity"}]}], "]"}], ",", RowBox[{"ListPlot", "[", RowBox[{"i2", ",", RowBox[{"DisplayFunction", "\[Rule]", "Identity"}], ",", RowBox[{"PlotStyle", "\[Rule]", RowBox[{"RGBColor", "[", RowBox[{"1", ",", "0", ",", "0"}], "]"}]}]}], "]"}], ",", RowBox[{"DisplayFunction", "\[Rule]", "$DisplayFunction"}]}], "]"}]}], "Input"], Cell[BoxData[ RowBox[{"rmsError", "[", RowBox[{"i1", ",", "i2"}], "]"}]], "Input"], Cell[TextData[{ "The RMSE is related to the ", StyleBox["signal to noise ratio", FontSlant->"Italic"], " (SNR). This formula is another measure of relative error expressed in \ \"decibels\"." }], "Text"], Cell[BoxData[ RowBox[{ RowBox[{"snr", "[", RowBox[{"l1_List", ",", " ", "l2_List"}], "]"}], " ", ":=", " ", RowBox[{ RowBox[{"-", " ", "20"}], " ", RowBox[{"Log", "[", RowBox[{"rmsError", "[", RowBox[{"l1", ",", "l2"}], "]"}], "]"}]}]}]], "Input"], Cell[BoxData[ RowBox[{"snr", "[", RowBox[{"i1", ",", "i2"}], "]"}]], "Input"], Cell[TextData[{ "As the signal to noise ratio ", StyleBox["increases", FontSlant->"Italic"], ", then there is ", StyleBox["less distortion", FontSlant->"Italic"], " or ", StyleBox["degradation", FontSlant->"Italic"], " of the digital signal." }], "Text"] }, Closed]], Cell[CellGroupData[{ Cell["Average Absolute Error", "Section"], Cell["\<\ The average absolute error is the average difference between the original and \ reconstructed data.\ \>", "Text"], Cell[BoxData[ RowBox[{ RowBox[{"absError", "[", RowBox[{"l1_List", ",", "l2_List"}], "]"}], " ", ":=", " ", RowBox[{ RowBox[{"Plus", " ", "@@", " ", RowBox[{"Abs", " ", "/@", " ", RowBox[{"(", RowBox[{"l1", " ", "-", " ", "l2"}], ")"}]}]}], " ", "/", " ", RowBox[{"Length", "[", "l1", "]"}]}]}]], "Input"], Cell[BoxData[ RowBox[{"absError", "[", RowBox[{"i1", ",", "i2"}], "]"}]], "Input"] }, Closed]], Cell[CellGroupData[{ Cell["Question for Study", "Section"], Cell["\<\ One of the most important questions in digital processing is how to compact \ data so that essential information is not loss. In practice, the trade off \ between data size and information accuracy is subjective. Choices are made by \ a \"trial and test\" approach. Usually, users can select the degree of \ compaction corresponding to application requirements. \ \>", "Text"], Cell["\<\ There are many methods for data compression, but we have discussed only two \ methods in class. These are (1) filtering and (2) quantization. (Another \ rather basic method to reduce file-size is \"downsampling\". Downsampling \ corresponds to a reduction in data rate or image resolution.)\ \>", "Text"], Cell["\<\ I suggest that you investigate filtering and quantization on the information \ entropy of data files. As you change filter parameters or the degree of \ quantization, the entropy (and therefore the data size) can decrease \ significantly. What is the resulting increase in the RMSE or the decrease in \ the signal to noise as the file becomes more compact.\ \>", "Text"], Cell["\<\ In the following, filter and quantization methods are summarized below. We \ use only the Discrete Cosine Transform (DCT) since both filtering and \ quantization can be performed more simply than with the FFT.\ \>", "Text"] }, Closed]], Cell[CellGroupData[{ Cell["Definitions", "Section"], Cell["\<\ In order to help with your projects, the following summarizes useful \ definitions for the discrete Cosine transform (DCT).\ \>", "Text"], Cell[CellGroupData[{ Cell["DCT of 1D (audio) Data", "Subsection"], Cell[BoxData[ RowBox[{ RowBox[{"dct1D", "[", "x_List", "]"}], " ", ":=", " ", RowBox[{"Module", "[", RowBox[{ RowBox[{"{", RowBox[{ "n", ",", "e0", ",", " ", "tFactors", ",", " ", "xeven", ",", " ", "xodd"}], "}"}], ",", "\[IndentingNewLine]", RowBox[{ RowBox[{"n", " ", "=", " ", RowBox[{"Length", "[", "x", "]"}]}], ";", "\[IndentingNewLine]", RowBox[{ RowBox[{"{", RowBox[{"xeven", ",", " ", "xodd"}], "}"}], " ", "=", " ", RowBox[{"Transpose", "[", RowBox[{"Partition", "[", RowBox[{"x", ",", " ", "2"}], "]"}], "]"}]}], ";", "\[IndentingNewLine]", RowBox[{"e0", " ", "=", " ", RowBox[{"Exp", "[", RowBox[{ RowBox[{"-", "I"}], " ", RowBox[{"\[Pi]", "/", RowBox[{"(", RowBox[{"2", " ", "n"}], ")"}]}]}], "]"}]}], ";", "\[IndentingNewLine]", RowBox[{"tFactors", " ", "=", " ", RowBox[{ RowBox[{"{", "1", "}"}], " ", "~", " ", "Join", "~", " ", RowBox[{"Table", "[", RowBox[{ RowBox[{ RowBox[{"Sqrt", "[", "2", "]"}], " ", RowBox[{"e0", "^", "i"}]}], ",", " ", RowBox[{"{", RowBox[{"i", ",", " ", "1", ",", " ", RowBox[{"n", "-", "1"}]}], "}"}]}], "]"}]}]}], ";", "\[IndentingNewLine]", RowBox[{"Re", "[", RowBox[{"tFactors", " ", RowBox[{"InverseFourier", "[", RowBox[{"Join", "[", RowBox[{"xeven", ",", " ", RowBox[{"Reverse", "[", "xodd", "]"}]}], "]"}], "]"}]}], "]"}]}]}], "]"}]}]], "Input"], Cell[BoxData[ RowBox[{ RowBox[{"idct1D", "[", "x_List", "]"}], " ", ":=", " ", RowBox[{"Module", "[", RowBox[{ RowBox[{"{", RowBox[{ "n", ",", "e0", ",", "tFactors", ",", " ", "xt", ",", " ", "xfirst", ",", " ", "xlast"}], "}"}], ",", "\[IndentingNewLine]", RowBox[{ RowBox[{"n", " ", "=", " ", RowBox[{"Length", "[", "x", "]"}]}], ";", "\[IndentingNewLine]", RowBox[{"e0", " ", "=", " ", RowBox[{"Exp", "[", RowBox[{ RowBox[{"-", "I"}], " ", RowBox[{"\[Pi]", "/", RowBox[{"(", RowBox[{"2", " ", "n"}], ")"}]}]}], "]"}]}], ";", "\[IndentingNewLine]", RowBox[{"tFactors", " ", "=", " ", RowBox[{ RowBox[{"{", "1", "}"}], " ", "~", " ", "Join", "~", " ", RowBox[{"Table", "[", RowBox[{ RowBox[{ RowBox[{"Sqrt", "[", "2", "]"}], " ", RowBox[{"e0", "^", "i"}]}], ",", " ", RowBox[{"{", RowBox[{"i", ",", " ", "1", ",", " ", RowBox[{"n", "-", "1"}]}], "}"}]}], "]"}]}]}], ";", "\[IndentingNewLine]", RowBox[{"tFactors", " ", "=", " ", RowBox[{"Conjugate", "[", RowBox[{"N", "[", "tFactors", "]"}], "]"}]}], ";", "\[IndentingNewLine]", RowBox[{"xt", " ", "=", " ", RowBox[{"Re", "[", RowBox[{"Fourier", "[", RowBox[{"tFactors", " ", "x"}], "]"}], "]"}]}], ";", "\[IndentingNewLine]", RowBox[{"xfirst", " ", "=", " ", RowBox[{"Take", "[", RowBox[{"xt", ",", " ", RowBox[{"n", "/", "2"}]}], "]"}]}], ";", "\[IndentingNewLine]", RowBox[{"xlast", " ", "=", " ", RowBox[{"Take", "[", RowBox[{"xt", ",", RowBox[{ RowBox[{"-", "n"}], "/", "2"}]}], "]"}]}], ";", "\[IndentingNewLine]", RowBox[{"Flatten", "[", RowBox[{"Transpose", "[", RowBox[{"{", RowBox[{"xfirst", ",", " ", RowBox[{"Reverse", "[", "xlast", "]"}]}], "}"}], "]"}], "]"}]}]}], "]"}]}]], "Input"] }, Closed]], Cell[CellGroupData[{ Cell["Blocked DCT of 2D (image) Data", "Subsection"], Cell[BoxData[{ RowBox[{ RowBox[{"bDCTfactors", " ", "=", " ", RowBox[{"N", "[", RowBox[{ RowBox[{"{", "1", "}"}], " ", "~", " ", "Join", "~", " ", RowBox[{"Table", "[", RowBox[{ RowBox[{ RowBox[{"Sqrt", "[", "2", "]"}], " ", RowBox[{"Exp", "[", RowBox[{ RowBox[{"-", "I"}], " ", "\[Pi]", " ", RowBox[{"i", "/", RowBox[{"(", RowBox[{"2", " ", "8"}], ")"}]}]}], "]"}]}], ",", " ", RowBox[{"{", RowBox[{"i", ",", " ", "1", ",", " ", RowBox[{"8", "-", "1"}]}], "}"}]}], "]"}]}], "]"}]}], ";"}], "\[IndentingNewLine]", RowBox[{ RowBox[{"bIDCTfactors", " ", "=", " ", RowBox[{"Conjugate", "[", "bDCTfactors", "]"}]}], ";"}], "\[IndentingNewLine]", RowBox[{ RowBox[{ RowBox[{"bDCT", "[", RowBox[{"list_", "?", RowBox[{"(", RowBox[{ RowBox[{ RowBox[{"Length", "[", "#", "]"}], " ", "\[Equal]", " ", "8"}], " ", "&"}], ")"}]}], "]"}], " ", ":=", " ", RowBox[{"Re", "[", " ", RowBox[{"bDCTfactors", " ", RowBox[{"InverseFourier", "[", " ", RowBox[{"N", "[", RowBox[{"list", "\[LeftDoubleBracket]", RowBox[{"{", RowBox[{ "1", ",", "3", ",", "5", ",", "7", ",", "8", ",", "6", ",", "4", ",", "2"}], "}"}], "\[RightDoubleBracket]"}], "]"}], "]"}]}], "]"}]}], ";"}], "\[IndentingNewLine]", RowBox[{ RowBox[{ RowBox[{"bIDCT", "[", RowBox[{"list_", "?", RowBox[{"(", RowBox[{ RowBox[{ RowBox[{"Length", "[", "#", "]"}], " ", "\[Equal]", " ", "8"}], " ", "&"}], ")"}]}], "]"}], " ", ":=", " ", RowBox[{ RowBox[{"Re", "[", RowBox[{"Fourier", "[", RowBox[{"bIDCTfactors", " ", "list"}], "]"}], "]"}], "\[LeftDoubleBracket]", RowBox[{"{", RowBox[{ "1", ",", "8", ",", "2", ",", "7", ",", "3", ",", "6", ",", "4", ",", "5"}], "}"}], "\[RightDoubleBracket]"}]}], ";"}], "\[IndentingNewLine]", RowBox[{ RowBox[{ RowBox[{"bDCT", "[", RowBox[{"array_", "?", "MatrixQ"}], "]"}], " ", ":=", " ", RowBox[{"Transpose", "[", RowBox[{"bDCT", " ", "/@", " ", RowBox[{"Transpose", "[", RowBox[{"bDCT", " ", "/@", " ", "array"}], "]"}]}], "]"}]}], ";"}], "\[IndentingNewLine]", RowBox[{ RowBox[{ RowBox[{"bIDCT", "[", RowBox[{"array_", "?", "MatrixQ"}], "]"}], " ", ":=", " ", RowBox[{"Transpose", "[", RowBox[{"bIDCT", " ", "/@", " ", RowBox[{"Transpose", "[", RowBox[{"bIDCT", " ", "/@", " ", "array"}], "]"}]}], "]"}]}], ";"}], "\[IndentingNewLine]", RowBox[{ RowBox[{ RowBox[{"bDCT", "[", RowBox[{"list_", "?", RowBox[{"(", RowBox[{ RowBox[{ RowBox[{"Length", "[", "#", "]"}], " ", ">", " ", "8"}], "&"}], ")"}]}], "]"}], " ", ":=", " ", RowBox[{"Join", " ", "@@", " ", RowBox[{"(", RowBox[{"bDCT", " ", "/@", " ", RowBox[{"Partition", "[", RowBox[{"list", ",", "8"}], "]"}]}], ")"}]}]}], ";"}], "\[IndentingNewLine]", RowBox[{ RowBox[{ RowBox[{"bIDCT", "[", RowBox[{"list_", "?", RowBox[{"(", RowBox[{ RowBox[{ RowBox[{"Length", "[", "#", "]"}], " ", ">", " ", "8"}], "&"}], ")"}]}], "]"}], " ", ":=", " ", RowBox[{"Join", " ", "@@", " ", RowBox[{"(", RowBox[{"bIDCT", " ", "/@", " ", RowBox[{"Partition", "[", RowBox[{"list", ",", "8"}], "]"}]}], ")"}]}]}], ";"}]}], "Input"] }, Closed]], Cell[CellGroupData[{ Cell["Quantization", "Subsection"], Cell[TextData[{ "You can quantize your data with the ", StyleBox["Round[\[Ellipsis]]", FontWeight->"Bold"], " command. Uniform quantization simply rounds all data values to \ equally-spaced values ranging from the maximum to the minimum of your data. \ JPEG quantization is an example of a non-uniform quantization. Some of the 2D \ DCT transform coefficients are weighted more strongly during the quantization \ process. " }], "Text"], Cell["\<\ A useful command to perform uniform quantization of Real data is\[Ellipsis]\ \>", "Text"], Cell[BoxData[ RowBox[{ RowBox[{ RowBox[{"quantizeUniform", "[", RowBox[{"x_List", ",", RowBox[{"bits_:", "8"}]}], "]"}], " ", ":=", " ", RowBox[{"Module", "[", RowBox[{ RowBox[{"{", "q", "}"}], ",", "\[IndentingNewLine]", RowBox[{ RowBox[{"q", " ", "=", " ", RowBox[{ RowBox[{"2", "^", "bits"}], "/", RowBox[{"(", RowBox[{ RowBox[{"Max", "[", "x", "]"}], " ", "-", " ", RowBox[{"Min", "[", "x", "]"}]}], ")"}]}]}], ";", "\[IndentingNewLine]", RowBox[{ RowBox[{"Round", "[", RowBox[{"q", " ", "x"}], "]"}], "/", "q"}]}]}], "]"}]}], ";"}]], "Input"], Cell["The quantization matrix for JPEG quantization is given by ", "Text"], Cell[BoxData[{ StyleBox[ RowBox[{ RowBox[{"qLum", " ", "=", "\n", RowBox[{"{", RowBox[{ RowBox[{"{", RowBox[{ "16", ",", " ", "11", ",", " ", "10", ",", " ", "16", ",", " ", "24", ",", " ", "40", ",", " ", "51", ",", " ", "61"}], "}"}], ",", "\n", RowBox[{"{", RowBox[{ "12", ",", " ", "12", ",", " ", "14", ",", " ", "19", ",", " ", "26", ",", " ", "58", ",", " ", "60", ",", " ", "55"}], "}"}], ",", "\n", RowBox[{"{", RowBox[{ "14", ",", " ", "13", ",", " ", "16", ",", " ", "24", ",", " ", "40", ",", " ", "57", ",", " ", "69", ",", " ", "56"}], "}"}], ",", "\n", RowBox[{"{", RowBox[{ "14", ",", " ", "17", ",", " ", "22", ",", " ", "29", ",", " ", "51", ",", " ", "87", ",", " ", "80", ",", " ", "62"}], "}"}], ",", "\n", RowBox[{"{", RowBox[{ "18", ",", " ", "22", ",", " ", "37", ",", " ", "56", ",", " ", "68", ",", "109", ",", "103", ",", " ", "77"}], "}"}], ",", "\n", RowBox[{"{", RowBox[{ "24", ",", " ", "35", ",", " ", "55", ",", " ", "64", ",", " ", "81", ",", "104", ",", "113", ",", " ", "92"}], "}"}], ",", "\n", RowBox[{"{", RowBox[{ "49", ",", " ", "64", ",", " ", "78", ",", " ", "87", ",", "103", ",", "121", ",", "120", ",", "101"}], "}"}], ",", "\n", RowBox[{"{", RowBox[{ "72", ",", " ", "92", ",", " ", "95", ",", " ", "98", ",", "112", ",", "100", ",", "103", ",", " ", "99"}], "}"}]}], "}"}]}], ";"}], FontFamily->"Courier", FontWeight->"Bold"], "\[IndentingNewLine]", RowBox[{"qLum", " ", "//", " ", "MatrixForm"}]}], "Input"], Cell["This is applied to the DCT of 8 x 8 blocks of an image.", "Text"], Cell["\<\ Functions used to perform block quantization of graphical images\[Ellipsis]\ \>", "Text"], Cell[BoxData[ StyleBox[ RowBox[{ RowBox[{"BlockImage", "[", RowBox[{"image_", ",", " ", RowBox[{"blocksize_:", RowBox[{"{", RowBox[{"8", ",", " ", "8"}], "}"}]}]}], "]"}], " ", ":=", RowBox[{ RowBox[{"Partition", "[", RowBox[{"image", ",", " ", "blocksize"}], "]"}], " ", "/;", RowBox[{"And", " ", "@@", " ", RowBox[{"IntegerQ", " ", "/@", " ", RowBox[{"(", RowBox[{ RowBox[{"Dimensions", "[", "image", "]"}], "/", "blocksize"}], ")"}]}]}]}]}], FontFamily->"Courier", FontWeight->"Bold"]], "Input"], Cell[BoxData[ StyleBox[ RowBox[{ RowBox[{"UnBlockImage", "[", "blocks_", "]"}], " ", ":=", " ", RowBox[{"Partition", "[", RowBox[{ RowBox[{"Flatten", "[", RowBox[{"Transpose", "[", RowBox[{"blocks", ",", " ", RowBox[{"{", RowBox[{"1", ",", " ", "3", ",", " ", "2"}], "}"}]}], "]"}], "]"}], ",", RowBox[{"{", RowBox[{"Times", " ", "@@", " ", RowBox[{ RowBox[{"Dimensions", "[", "blocks", "]"}], "[", RowBox[{"[", RowBox[{"{", RowBox[{"2", ",", " ", "4"}], "}"}], "]"}], "]"}]}], "}"}]}], "]"}]}], FontFamily->"Courier", FontWeight->"Bold"]], "Input"], Cell[BoxData[ RowBox[{ RowBox[{ RowBox[{"bQuantize", StyleBox["[", FontFamily->"Courier", FontWeight->"Bold"], StyleBox[ RowBox[{"image_", ",", " ", "qMatrix_"}], FontFamily->"Courier", FontWeight->"Bold"], StyleBox["]", FontFamily->"Courier", FontWeight->"Bold"]}], StyleBox[" ", FontFamily->"Courier", FontWeight->"Bold"], StyleBox[":=", FontFamily->"Courier", FontWeight->"Bold"], StyleBox[" ", FontFamily->"Courier", FontWeight->"Bold"], StyleBox[ RowBox[{ RowBox[{ RowBox[{"Map", "[", RowBox[{ RowBox[{ RowBox[{"(", RowBox[{"#", "/", "qMatrix"}], ")"}], "&"}], ",", " ", RowBox[{"BlockImage", "[", RowBox[{"image", ",", " ", RowBox[{"Dimensions", "[", "qMatrix", "]"}]}], "]"}], ",", RowBox[{"{", "2", "}"}]}], "]"}], " ", "//", "UnBlockImage"}], " ", "//", " ", "Round"}], FontFamily->"Courier", FontWeight->"Bold"]}], StyleBox[";", FontFamily->"Courier", FontWeight->"Bold"]}]], "Input"], Cell[BoxData[ StyleBox[ RowBox[{ RowBox[{"bUnQuantize", "[", RowBox[{"image_", ",", " ", "qMatrix_"}], "]"}], " ", ":=", " ", RowBox[{ RowBox[{"Map", "[", RowBox[{ RowBox[{ RowBox[{"(", RowBox[{"#", " ", "qMatrix"}], ")"}], "&"}], ",", " ", RowBox[{"BlockImage", "[", RowBox[{"image", ",", " ", RowBox[{"Dimensions", "[", "qMatrix", "]"}]}], "]"}], ",", RowBox[{"{", "2", "}"}]}], "]"}], " ", "//", "UnBlockImage"}]}], FontFamily->"Courier", FontWeight->"Bold"]], "Input"] }, Closed]] }, Closed]], Cell[CellGroupData[{ Cell["Filtering (using the DCT)", "Section"], Cell[TextData[{ "The approximate \"frequencies\" associated with the DCT are (", StyleBox["m ", FontSlant->"Italic"], "\[Times] ", StyleBox["rate", FontSlant->"Italic"], ")", "/(2 \[Times] ", StyleBox["N", FontSlant->"Italic"], "); where ", StyleBox["rate ", FontSlant->"Italic"], " is the sampling rate (samples per second), ", StyleBox["N", FontSlant->"Italic"], " is the total number os samples, and ", StyleBox["m", FontSlant->"Italic"], " ranges from 0 to ", StyleBox["N ", FontSlant->"Italic"], "\[Dash] 1." }], "Text"], Cell["A generalized bandpass filter can be written as", "Text"], Cell[BoxData[ RowBox[{ RowBox[{ RowBox[{"bpFilter", "[", RowBox[{"xDCT_List", ",", "fLow_", ",", "fHigh_", ",", RowBox[{"rate_:", "41000.0"}]}], "]"}], " ", ":=", " ", RowBox[{"Module", "[", RowBox[{ RowBox[{"{", RowBox[{"n", ",", " ", "filter"}], "}"}], ",", "\[IndentingNewLine]", RowBox[{ RowBox[{"n", " ", "=", " ", RowBox[{"Length", "[", "xDCT", "]"}]}], ";", "\[IndentingNewLine]", RowBox[{"filter", " ", "=", " ", RowBox[{"Table", "[", RowBox[{ RowBox[{"If", "[", RowBox[{ RowBox[{"fLow", " ", "<", " ", RowBox[{"i", " ", RowBox[{"rate", "/", RowBox[{"(", RowBox[{"2", " ", "n"}], ")"}]}]}], " ", "<", " ", "fHigh"}], ",", " ", "1", ",", " ", "0"}], "]"}], ",", " ", RowBox[{"{", RowBox[{"i", ",", " ", "1", ",", " ", "n"}], "}"}]}], "]"}]}], ";", "\[IndentingNewLine]", RowBox[{"xDCT", " ", "filter"}]}]}], "]"}]}], ";"}]], "Input"], Cell[TextData[{ "To use this filter, first take the DCT of a one-dimensional signal, and \ then apply the filter. The iDCT reconstructs the filtered signal. The \ function ", StyleBox["bpFilter[\[Ellipsis]]", FontWeight->"Bold"], " takes an optional argument pre-set to the sample rate found in audio CDs. \ " }], "Text"], Cell["\<\ Note that the information entropy of the filtered DCT may be smaller than the \ reconstructed signal. For example, Dylan Thomas's voice has the following \ properties.\ \>", "Text"], Cell[CellGroupData[{ Cell["Example filter of Dylan Thomas's voice", "Subsubsection"], Cell[BoxData[{ RowBox[{ RowBox[{ RowBox[{"SetDirectory", "[", "\"\<~/Desktop/\>\"", "]"}], ";"}], StyleBox[" ", FontColor->RGBColor[0, 1, 0]], StyleBox[ RowBox[{"(*", " ", RowBox[{"Set", " ", "path", " ", "to", " ", "data", " ", "file"}], " ", "*)"}], FontColor->RGBColor[0, 1, 0]]}], "\[IndentingNewLine]", RowBox[{ RowBox[{"s", " ", "=", " ", RowBox[{"Import", "[", "\"\\"", "]"}]}], ";"}], "\[IndentingNewLine]", RowBox[{ RowBox[{"rate", " ", "=", " ", RowBox[{"Part", "[", RowBox[{"s", ",", " ", "1", ",", " ", "2"}], "]"}]}], ";"}], "\[IndentingNewLine]", RowBox[{ RowBox[{"sData", " ", "=", " ", RowBox[{"Drop", "[", RowBox[{ RowBox[{"Part", "[", RowBox[{"s", ",", "1", ",", "1", ",", "1"}], "]"}], ",", "1"}], "]"}]}], ";", " ", StyleBox[ RowBox[{"(*", " ", RowBox[{ RowBox[{"Make", " ", "exactly", " ", RowBox[{"2", "^", "16"}]}], " ", "=", " ", RowBox[{"64", " ", "kS"}]}], " ", "*)"}], FontColor->RGBColor[0, 1, 0]]}]}], "Input", CellChangeTimes->{{3.4482743406348743`*^9, 3.448274340824864*^9}}], Cell[BoxData[ RowBox[{ RowBox[{"sDCT", " ", "=", " ", RowBox[{"dct1D", "[", "sData", "]"}]}], ";"}]], "Input"], Cell["\<\ For unfiltered data, the DCT compacts the file by about a factor of three \ with 8 bit quantization\[Ellipsis]\ \>", "Text"], Cell[BoxData[ RowBox[{ RowBox[{"Print", "[", RowBox[{"\"\\"", ",", RowBox[{"iEntropy", "[", "sData", "]"}], ",", "\"\<; DCT (REAL) Entropy = \>\"", ",", RowBox[{"iEntropy", "[", "sDCT", "]"}], ",", " ", "\"\<; DCT (quantized) Entropy = \>\"", ",", " ", RowBox[{"iEntropy", "[", RowBox[{"quantizeUniform", "[", "sDCT", "]"}], "]"}]}], "]"}], ";"}]], "Input"], Cell[BoxData[ RowBox[{ RowBox[{ RowBox[{"sfDCT", " ", "=", " ", RowBox[{"quantizeUniform", "[", RowBox[{"bpFilter", "[", RowBox[{"sDCT", ",", "200.0", ",", " ", "4000.0"}], "]"}], "]"}]}], ";"}], " ", StyleBox[ RowBox[{"(*", " ", RowBox[{ RowBox[{ "filter", " ", "from", " ", "200", " ", "Hz", " ", "to", " ", "5", " ", "kHz", " ", "and", " ", "8"}], "-", RowBox[{"bit", " ", "quantization"}]}], " ", "*)"}], FontColor->RGBColor[0, 1, 0]]}]], "Input"], Cell[BoxData[ RowBox[{ RowBox[{"Print", "[", RowBox[{"\"\\"", ",", " ", RowBox[{"iEntropy", "[", "sfDCT", "]"}]}], "]"}], ";"}]], "Input"], Cell[BoxData[ RowBox[{ RowBox[{"sReconstructed", " ", "=", " ", RowBox[{"idct1D", "[", "sfDCT", "]"}]}], ";"}]], "Input"], Cell[BoxData[ RowBox[{"rmsError", "[", RowBox[{"sData", ",", "sReconstructed"}], "]"}]], "Input"], Cell[BoxData[ RowBox[{"snr", "[", RowBox[{"sData", ",", "sReconstructed"}], "]"}]], "Input"], Cell[BoxData[ RowBox[{"absError", "[", RowBox[{"sData", ",", "sReconstructed"}], "]"}]], "Input"], Cell[TextData[{ "Surprisingly, these measurements show a great variability. The RMSE (and \ the SNR) indicate very, very poor reconstruction accuracy; whereas, the \ average absolute error indicates a relatively good reconstruction. Judge for \ yourself. Try ", StyleBox["ListPlay[\[Ellipsis]]", FontWeight->"Bold"], " and listen to the differences." }], "Text"], Cell[BoxData[ RowBox[{"ListPlay", "[", RowBox[{"sData", ",", RowBox[{"SampleRate", " ", "\[Rule]", " ", "rate"}]}], "]"}]], "Input", CellChangeTimes->{3.4476976044864683`*^9}], Cell[BoxData[ RowBox[{"ListPlay", "[", RowBox[{"sReconstructed", ",", RowBox[{"SampleRate", " ", "\[Rule]", " ", "rate"}]}], "]"}]], "Input", CellChangeTimes->{3.4476976052037582`*^9}] }, Closed]] }, Closed]], Cell[CellGroupData[{ Cell["Image Compression using Blocked DCT", "Section"], Cell[TextData[{ "In class, we performed 8 x 8 block DCT of two-dimensional images. An \ example from class is presented below. Our class algorithm works ", StyleBox["only for images that can be evenly divided into 8 x 8 blocks.", FontSlant->"Italic"] }], "Text"], Cell[CellGroupData[{ Cell["Dylan Thomas's Portrait", "Subsubsection"], Cell[BoxData[{ RowBox[{ RowBox[{"SetDirectory", "[", "\"\<~/Desktop/\>\"", "]"}], ";"}], "\[IndentingNewLine]", RowBox[{ RowBox[{"g", " ", "=", " ", RowBox[{"Import", "[", "\"\\"", "]"}]}], ";"}], "\[IndentingNewLine]", RowBox[{ RowBox[{"gData", " ", "=", " ", RowBox[{"Part", "[", RowBox[{"g", ",", "1", ",", "1"}], "]"}]}], ";"}]}], "Input"], Cell[BoxData[ RowBox[{"ListDensityPlot", "[", RowBox[{"gData", ",", RowBox[{"Mesh", "\[Rule]", "False"}], ",", RowBox[{"AspectRatio", "\[Rule]", "Automatic"}]}], "]"}]], "Input"], Cell["Perform the block DCT\[Ellipsis]", "Text"], Cell[BoxData[ RowBox[{ RowBox[{"bgData", " ", "=", " ", RowBox[{"bDCT", "[", "gData", "]"}]}], ";"}]], "Input"], Cell["Quantize\[Ellipsis]", "Text"], Cell[BoxData[ RowBox[{ RowBox[{"bqgData", " ", "=", " ", RowBox[{"bQuantize", "[", RowBox[{"bgData", ",", "qLum"}], "]"}]}], ";"}]], "Input"], Cell[BoxData[ RowBox[{ RowBox[{"Print", "[", RowBox[{"\"\\"", ",", RowBox[{"iEntropy", "[", RowBox[{"Flatten", "[", "gData", "]"}], "]"}], ",", "\"\<; DCT (REAL) Entropy = \>\"", ",", RowBox[{"iEntropy", "[", RowBox[{"Flatten", "[", "bgData", "]"}], "]"}], ",", " ", "\"\<; DCT (quantized) Entropy = \>\"", ",", " ", RowBox[{"iEntropy", "[", RowBox[{"Flatten", "[", "bqgData", "]"}], "]"}]}], "]"}], ";"}]], "Input"], Cell["\<\ Finally, we perform an inverse transform in order to check reconstruction \ accuracy\[Ellipsis]\ \>", "Text"], Cell[BoxData[{ RowBox[{ RowBox[{"gReconstructed", "=", RowBox[{"bIDCT", "[", RowBox[{"bUnQuantize", "[", RowBox[{"bqgData", ",", "qLum"}], "]"}], "]"}]}], ";"}], "\n", RowBox[{"ListDensityPlot", "[", RowBox[{"gReconstructed", ",", RowBox[{"Mesh", "\[Rule]", "False"}], ",", RowBox[{"AspectRatio", "\[Rule]", "Automatic"}]}], "]"}]}], "Input"], Cell[BoxData[ RowBox[{"rmsError", "[", RowBox[{ RowBox[{"Flatten", "[", "gData", "]"}], ",", RowBox[{"Flatten", "[", "gReconstructed", "]"}]}], "]"}]], "Input"], Cell[BoxData[ RowBox[{"absError", "[", RowBox[{ RowBox[{"Flatten", "[", "gData", "]"}], ",", RowBox[{"Flatten", "[", "gReconstructed", "]"}]}], "]"}]], "Input"], Cell["\<\ For image data, the RMSE (and SNR) appear to be better measurements for the \ study of blocked data.\ \>", "Text"] }, Closed]] }, Closed]] }, Open ]] }, WindowSize->{772, 811}, WindowMargins->{{Automatic, 355}, {Automatic, 0}}, PrintingCopies->1, PrintingPageRange->{1, Automatic}, Magnification->1.25, FrontEndVersion->"6.0 for Mac OS X x86 (32-bit) (May 21, 2008)", StyleDefinitions->"Classic.nb" ] (* End of Notebook Content *) (* Internal cache information *) (*CellTagsOutline CellTagsIndex->{} *) (*CellTagsIndex CellTagsIndex->{} *) (*NotebookFileOutline Notebook[{ Cell[CellGroupData[{ Cell[590, 23, 72, 0, 225, "Title"], Cell[665, 25, 85, 1, 66, "Subsubtitle"], Cell[753, 28, 107, 4, 101, "Subsubtitle"], Cell[CellGroupData[{ Cell[885, 36, 31, 0, 62, "Section"], Cell[919, 38, 2875, 56, 606, "Text"], Cell[3797, 96, 110, 3, 40, "Input"] }, Closed]], Cell[CellGroupData[{ Cell[3944, 104, 38, 0, 28, "Section"], Cell[3985, 106, 810, 12, 181, "Text"], Cell[4798, 120, 136, 5, 32, "Text"], Cell[4937, 127, 648, 20, 101, "Input"], Cell[5588, 149, 81, 1, 40, "Input"], Cell[5672, 152, 460, 14, 83, "Input"], Cell[6135, 168, 116, 2, 40, "Input"], Cell[6254, 172, 118, 3, 32, "Text"], Cell[6375, 177, 116, 3, 32, "Text"], Cell[6494, 182, 167, 5, 40, "Input"], Cell[6664, 189, 150, 4, 40, "Input"], Cell[6817, 195, 316, 8, 57, "Input"], Cell[7136, 205, 114, 3, 32, "Text"], Cell[7253, 210, 293, 8, 40, "Input"], Cell[7549, 220, 150, 4, 40, "Input"], Cell[7702, 226, 316, 8, 57, "Input"], Cell[8021, 236, 92, 2, 32, "Text"], Cell[8116, 240, 397, 12, 75, "Text"], Cell[8516, 254, 902, 21, 160, "Text"] }, Closed]], Cell[CellGroupData[{ Cell[9455, 280, 50, 0, 28, "Section"], Cell[9508, 282, 181, 4, 54, "Text"], Cell[9692, 288, 550, 17, 58, "Input"], Cell[10245, 307, 205, 6, 40, "Input"], Cell[10453, 315, 159, 6, 32, "Text"], Cell[10615, 323, 1282, 40, 150, "Input"], Cell[11900, 365, 86, 2, 40, "Input"], Cell[11989, 369, 1282, 40, 150, "Input"], Cell[13274, 411, 86, 2, 40, "Input"], Cell[13363, 415, 208, 6, 54, "Text"], Cell[13574, 423, 275, 8, 41, "Input"], Cell[13852, 433, 81, 2, 40, "Input"], Cell[13936, 437, 267, 11, 32, "Text"] }, Closed]], Cell[CellGroupData[{ Cell[14240, 453, 41, 0, 28, "Section"], Cell[14284, 455, 123, 3, 32, "Text"], Cell[14410, 460, 340, 9, 41, "Input"], Cell[14753, 471, 86, 2, 40, "Input"] }, Closed]], Cell[CellGroupData[{ Cell[14876, 478, 37, 0, 28, "Section"], Cell[14916, 480, 386, 6, 96, "Text"], Cell[15305, 488, 314, 5, 75, "Text"], Cell[15622, 495, 380, 6, 96, "Text"], Cell[16005, 503, 233, 4, 75, "Text"] }, Closed]], Cell[CellGroupData[{ Cell[16275, 512, 30, 0, 28, "Section"], Cell[16308, 514, 147, 3, 54, "Text"], Cell[CellGroupData[{ Cell[16480, 521, 44, 0, 30, "Subsection"], Cell[16527, 523, 1622, 45, 126, "Input"], Cell[18152, 570, 2051, 56, 174, "Input"] }, Closed]], Cell[CellGroupData[{ Cell[20240, 631, 52, 0, 30, "Subsection"], Cell[20295, 633, 3549, 108, 283, "Input"] }, Closed]], Cell[CellGroupData[{ Cell[23881, 746, 34, 0, 30, "Subsection"], Cell[23918, 748, 440, 9, 96, "Text"], Cell[24361, 759, 99, 2, 32, "Text"], Cell[24463, 763, 679, 21, 75, "Input"], Cell[25145, 786, 74, 0, 32, "Text"], Cell[25222, 788, 1726, 40, 183, "Input"], Cell[26951, 830, 71, 0, 32, "Text"], Cell[27025, 832, 99, 2, 32, "Text"], Cell[27127, 836, 590, 18, 75, "Input"], Cell[27720, 856, 677, 21, 75, "Input"], Cell[28400, 879, 1103, 40, 75, "Input"], Cell[29506, 921, 554, 16, 75, "Input"] }, Closed]] }, Closed]], Cell[CellGroupData[{ Cell[30109, 943, 44, 0, 28, "Section"], Cell[30156, 945, 555, 24, 54, "Text"], Cell[30714, 971, 63, 0, 32, "Text"], Cell[30780, 973, 1059, 27, 124, "Input"], Cell[31842, 1002, 326, 8, 75, "Text"], Cell[32171, 1012, 191, 4, 54, "Text"], Cell[CellGroupData[{ Cell[32387, 1020, 63, 0, 30, "Subsubsection"], Cell[32453, 1022, 1153, 34, 108, "Input"], Cell[33609, 1058, 117, 3, 40, "Input"], Cell[33729, 1063, 134, 3, 32, "Text"], Cell[33866, 1068, 416, 10, 91, "Input"], Cell[34285, 1080, 516, 15, 57, "Input"], Cell[34804, 1097, 176, 4, 40, "Input"], Cell[34983, 1103, 128, 3, 40, "Input"], Cell[35114, 1108, 101, 2, 40, "Input"], Cell[35218, 1112, 96, 2, 40, "Input"], Cell[35317, 1116, 101, 2, 40, "Input"], Cell[35421, 1120, 367, 8, 75, "Text"], Cell[35791, 1130, 184, 4, 40, "Input"], Cell[35978, 1136, 193, 4, 40, "Input"] }, Closed]] }, Closed]], Cell[CellGroupData[{ Cell[36220, 1146, 54, 0, 28, "Section"], Cell[36277, 1148, 267, 5, 54, "Text"], Cell[CellGroupData[{ Cell[36569, 1157, 48, 0, 30, "Subsubsection"], Cell[36620, 1159, 388, 11, 75, "Input"], Cell[37011, 1172, 190, 4, 40, "Input"], Cell[37204, 1178, 48, 0, 32, "Text"], Cell[37255, 1180, 118, 3, 40, "Input"], Cell[37376, 1185, 35, 0, 32, "Text"], Cell[37414, 1187, 153, 4, 40, "Input"], Cell[37570, 1193, 484, 11, 74, "Input"], Cell[38057, 1206, 119, 3, 32, "Text"], Cell[38179, 1211, 373, 9, 74, "Input"], Cell[38555, 1222, 171, 4, 40, "Input"], Cell[38729, 1228, 171, 4, 40, "Input"], Cell[38903, 1234, 124, 3, 32, "Text"] }, Closed]] }, Closed]] }, Open ]] } ] *) (* End of internal cache information *)