├── .gitignore ├── README.md ├── literature ├── 164564.pdf └── chapter_8.pdf ├── mathematica ├── README.md ├── diffTVR.wl ├── example_abs.nb ├── example_abs_figures │ ├── deriv.png │ ├── signal.png │ └── tvr.png ├── example_damped_osc.nb └── example_damped_osc_figures │ ├── filtered_deriv.png │ ├── noisy.png │ ├── noisy_lp_diff_lp.png │ ├── pAve.png │ ├── pLowPass1.png │ ├── pLowPass2.png │ ├── signal.png │ ├── tog.png │ ├── tvr.png │ └── tvr_filtered.png └── python ├── README.md ├── derivative.png ├── diff_tvr.py ├── example_abs.py └── signal.png /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | legacy/ 3 | __pycache__/ 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Differentiate noisy signals with Total Variation Regularization (TVR) in Python and Mathematica 2 | 3 | This repo gives an implementation with examples of how to differentiate noisy signals using Total Variation Regularization (TVR). 4 | 5 | [You can read more about this on Medium.](https://medium.com/practical-coding/how-to-differentiate-noisy-signals-2baf71b8bb65) 6 | 7 | Here's a quick example of a signal: 8 | 9 | drawing 10 | 11 | it's noisy derivative: 12 | 13 | drawing 14 | 15 | and it's amazingly smooth derivative from TVR: 16 | 17 | drawing 18 | 19 | ## Code 20 | 21 | * [mathematica](mathematica) contains an implementation in Mathematica. The example is worked out here in greater detail. 22 | * [python](python) contains an implementation in Python. This is a fairly basic implementation, so be careful applying it to large problems (1k+ data points). 23 | 24 | ## Relevant literature 25 | 26 | This code heavily uses the method described in [Numerical Differentiation of Noisy, Nonsmooth Data](literature/164564.pdf). A good description of the lagged diffusivity algorithm can be found in one of the references: [Chapter 8 - Total Variation Regularization](literature/chapter_8.pdf). 27 | 28 | ## Detailed example 29 | 30 | [You can read more about this on Medium.](https://medium.com/practical-coding/how-to-differentiate-noisy-signals-2baf71b8bb65) 31 | 32 | drawing 33 | -------------------------------------------------------------------------------- /literature/164564.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smrfeld/Total-Variation-Regularization-Derivative-Python/1b8e8b92ce3f15c7eb09ba0535134ef2662fcd39/literature/164564.pdf -------------------------------------------------------------------------------- /literature/chapter_8.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smrfeld/Total-Variation-Regularization-Derivative-Python/1b8e8b92ce3f15c7eb09ba0535134ef2662fcd39/literature/chapter_8.pdf -------------------------------------------------------------------------------- /mathematica/README.md: -------------------------------------------------------------------------------- 1 | # Mathematica implementation 2 | 3 | [You can read more about this on Medium.](https://medium.com/practical-coding/how-to-differentiate-noisy-signals-2baf71b8bb65) 4 | 5 | This directory contains a Mathematica implementation of differentiation of noisy signals with total variation regularization. 6 | 7 | **It is not suitable for large problems. See alternative method in paper in literature folder.** 8 | 9 | See the example notebooks for usage (self-explanatory). 10 | 11 | drawing -------------------------------------------------------------------------------- /mathematica/diffTVR.wl: -------------------------------------------------------------------------------- 1 | (* ::Package:: *) 2 | 3 | (* ::Title:: *) 4 | (*Differentiate with Total Variation Regularization (TVR)*) 5 | 6 | 7 | BeginPackage["diffTVR`"] 8 | 9 | 10 | getDiffTVR::usage="getDiffTVR[data,derivGuess,noOptSteps,dx,alpha,returnOptions=<||>] takes noOptStep optimization steps to compute 11 | the TVR derivative. 12 | If returnProgress=<||>: 13 | There is one return value: the final derivative. 14 | If returnProgress=<|progress->True|>: 15 | There are two return values: the final derivative and a list of the derivatives during the iteration. 16 | If returnProgress=<|progress->False, interval->10|> 17 | There are two return values: the final derivative and the derivatives during the optimizations at the specified interval." 18 | 19 | 20 | getDiffTVRGivenStructs::usage="getDiffTVRGivenStructs[data,derivGuess,noOptSteps,structsTVR,returnOptions=<||>] as getDiffTVR, 21 | but using the structs from the makeTVRstructs command." 22 | 23 | 24 | getDiffTVRupdate::usage="getDiffTVRupdate[data,derivCurr,dx,alpha] takes a single step 25 | of the TVR differentiation and returns the update." 26 | 27 | 28 | getDiffTVRupdateGivenStructs::usage="getDiffTVRupdateGivenStructs[data,derivCurr,structsTVR] takes a single step 29 | of the TVR differentiation and returns the update, given the structs from the makeTVRstructs command." 30 | 31 | 32 | makeTVRstructs::usage="makeTVRstructs[n,dx,alpha] makes and returns the necessary TVR structs." 33 | 34 | 35 | (* ::Subtitle:: *) 36 | (*Private*) 37 | 38 | 39 | Begin["`Private`"] 40 | 41 | 42 | (* n x n+1 *) 43 | makeDmat[n_,dx_]:=Table[ 44 | Table[ 45 | If[i==j,-1,If[i==j-1,1,0]] 46 | ,{j,n+1}] 47 | ,{i,n}]/dx; 48 | 49 | 50 | (* nxn+1*) 51 | makeAmat[n_,dx_]:=Table[ 52 | Table[ 53 | If[i==1,0, 54 | If[j==1,0.5, 55 | If[j]:=Module[ 149 | {n,structsTVR} 150 | , 151 | n=Length[data]; 152 | structsTVR=makeTVRstructs[n,dx,alpha]; 153 | 154 | Return[getDiffTVRGivenStructs[data,derivGuess,noOptSteps,structsTVR,returnOptions]] 155 | ] 156 | 157 | 158 | getDiffTVRGivenStructs[data_,derivGuess_,noOptSteps_,structsTVR_,returnOptions_:<||>]:=Module[ 159 | {derivSt,update,derivCurr,interval,progress} 160 | , 161 | If[ 162 | KeyExistsQ[returnOptions,"interval"], 163 | interval=returnOptions["interval"], 164 | interval=1 165 | ]; 166 | If[ 167 | KeyExistsQ[returnOptions,"progress"], 168 | progress=returnOptions["progress"], 169 | progress=False 170 | ]; 171 | derivCurr=derivGuess; 172 | derivSt={derivCurr}; 173 | 174 | Monitor[ 175 | Do[ 176 | update = getDiffTVRupdateGivenStructs[data,derivCurr,structsTVR]; 177 | derivCurr += update; 178 | 179 | If[progress, 180 | If[Mod[optStep,interval]==0, 181 | AppendTo[derivSt,derivCurr]; 182 | ]; 183 | ]; 184 | 185 | ,{optStep,noOptSteps}]; 186 | ,ProgressIndicator[optStep,{1,noOptSteps}]]; 187 | 188 | If[progress, 189 | Return[{derivCurr,derivSt}], 190 | Return[derivCurr] 191 | ] 192 | ] 193 | 194 | 195 | End[]; 196 | 197 | 198 | EndPackage[]; 199 | -------------------------------------------------------------------------------- /mathematica/example_abs.nb: -------------------------------------------------------------------------------- 1 | (* Content-type: application/vnd.wolfram.mathematica *) 2 | 3 | (*** Wolfram Notebook File ***) 4 | (* http://www.wolfram.com/nb *) 5 | 6 | (* CreatedBy='Mathematica 12.2' *) 7 | 8 | (*CacheID: 234*) 9 | (* Internal cache information: 10 | NotebookFileLineBreakTest 11 | NotebookFileLineBreakTest 12 | NotebookDataPosition[ 158, 7] 13 | NotebookDataLength[ 51551, 1208] 14 | NotebookOptionsPosition[ 48805, 1150] 15 | NotebookOutlinePosition[ 49203, 1166] 16 | CellTagsIndexPosition[ 49160, 1163] 17 | WindowFrame->Normal*) 18 | 19 | (* Beginning of Notebook Content *) 20 | Notebook[{ 21 | 22 | Cell[CellGroupData[{ 23 | Cell["Load package", "Chapter", 24 | CellChangeTimes->{{3.822074504763748*^9, 25 | 3.822074506410431*^9}},ExpressionUUID->"f506f164-c0f0-463a-b883-\ 26 | cac9e42bcd3a"], 27 | 28 | Cell[BoxData[{ 29 | RowBox[{ 30 | RowBox[{"SetDirectory", "[", 31 | RowBox[{"NotebookDirectory", "[", "]"}], "]"}], 32 | ";"}], "\[IndentingNewLine]", 33 | RowBox[{"Needs", "[", "\"\\"", "]"}]}], "Input", 34 | CellChangeTimes->{{3.8220743669845324`*^9, 3.822074372381111*^9}, { 35 | 3.822074484169373*^9, 3.822074487916696*^9}}, 36 | CellLabel->"In[3]:=",ExpressionUUID->"f3e032d6-f11e-456f-9a3e-5a51888c61c1"], 37 | 38 | Cell[CellGroupData[{ 39 | 40 | Cell[BoxData[ 41 | RowBox[{"?", "diffTVR`*"}]], "Input", 42 | CellChangeTimes->{{3.822074440374161*^9, 3.82207444317091*^9}}, 43 | CellLabel->"In[5]:=",ExpressionUUID->"3ace6ebf-5416-4142-8769-81bdbabe7877"], 44 | 45 | Cell[BoxData[ 46 | StyleBox[ 47 | FrameBox[GridBox[{ 48 | { 49 | DynamicModuleBox[{Typeset`open$$ = True}, 50 | PaneSelectorBox[{False-> 51 | ButtonBox[ 52 | RowBox[{ 53 | 54 | DynamicBox[FEPrivate`FrontEndResource[ 55 | "FEBitmaps", "RightPointerOpener"]], " ", 56 | StyleBox["diffTVR`", "InformationGridGroupHeader"]}], 57 | Appearance->None, 58 | BaseStyle->"InformationGridLink", 59 | ButtonFunction:>FEPrivate`Set[Typeset`open$$, True], 60 | Evaluator->Automatic, 61 | Method->"Preemptive"], True-> 62 | PaneBox[GridBox[{ 63 | { 64 | ButtonBox[ 65 | RowBox[{ 66 | 67 | DynamicBox[FEPrivate`FrontEndResource[ 68 | "FEBitmaps", "DownPointerOpener"], 69 | ImageSizeCache->{10., {3., 7.}}], " ", 70 | StyleBox["diffTVR`", "InformationGridGroupHeader"]}], 71 | Appearance->None, 72 | BaseStyle->"InformationGridLink", 73 | ButtonFunction:>FEPrivate`Set[Typeset`open$$, False], 74 | Evaluator->Automatic, 75 | Method->"Preemptive"]}, 76 | { 77 | PaneBox[GridBox[{ 78 | { 79 | ButtonBox[ 80 | StyleBox["getDiffTVR", "InformationGridButton"], 81 | Appearance->None, 82 | BaseStyle->"InformationGridLink", 83 | 84 | ButtonData:>{ 85 | "Info-196a39e8-488b-4626-94dc-8bea1c84bbfb", { 86 | "getDiffTVR", "diffTVR`"}, False}, 87 | ButtonNote->"diffTVR`", 88 | Evaluator->Automatic], 89 | ButtonBox[ 90 | StyleBox["getDiffTVRGivenStructs", "InformationGridButton"], 91 | Appearance->None, 92 | BaseStyle->"InformationGridLink", 93 | 94 | ButtonData:>{ 95 | "Info-196a39e8-488b-4626-94dc-8bea1c84bbfb", { 96 | "getDiffTVRGivenStructs", "diffTVR`"}, False}, 97 | ButtonNote->"diffTVR`", 98 | Evaluator->Automatic], 99 | ButtonBox[ 100 | StyleBox["getDiffTVRupdate", "InformationGridButton"], 101 | Appearance->None, 102 | BaseStyle->"InformationGridLink", 103 | 104 | ButtonData:>{ 105 | "Info-196a39e8-488b-4626-94dc-8bea1c84bbfb", { 106 | "getDiffTVRupdate", "diffTVR`"}, False}, 107 | ButtonNote->"diffTVR`", 108 | Evaluator->Automatic], 109 | ButtonBox[ 110 | 111 | StyleBox["getDiffTVRupdateGivenStructs", 112 | "InformationGridButton"], 113 | Appearance->None, 114 | BaseStyle->"InformationGridLink", 115 | 116 | ButtonData:>{ 117 | "Info-196a39e8-488b-4626-94dc-8bea1c84bbfb", { 118 | "getDiffTVRupdateGivenStructs", "diffTVR`"}, False}, 119 | ButtonNote->"diffTVR`", 120 | Evaluator->Automatic], 121 | ButtonBox[ 122 | StyleBox["makeTVRstructs", "InformationGridButton"], 123 | Appearance->None, 124 | BaseStyle->"InformationGridLink", 125 | 126 | ButtonData:>{ 127 | "Info-196a39e8-488b-4626-94dc-8bea1c84bbfb", { 128 | "makeTVRstructs", "diffTVR`"}, False}, 129 | ButtonNote->"diffTVR`", 130 | Evaluator->Automatic]} 131 | }, 132 | DefaultBaseStyle->"Text", 133 | 134 | GridBoxAlignment->{ 135 | "Columns" -> {{Left}}, "Rows" -> {{Baseline}}}, 136 | GridBoxItemSize->{"Columns" -> {{ 137 | Scaled[0.19]}}}], 138 | ImageMargins->{{10, 0}, {0, 2}}]} 139 | }, 140 | GridBoxAlignment->{"Columns" -> {{Left}}, "Rows" -> {{Baseline}}}], 141 | FrameMargins->{{0, 0}, {8, 0}}]}, Dynamic[Typeset`open$$], 142 | ImageSize->Automatic]]} 143 | }, 144 | GridBoxAlignment->{"Columns" -> {{Left}}, "Rows" -> {{Baseline}}}, 145 | GridBoxDividers->{"ColumnsIndexed" -> {{False}}, "RowsIndexed" -> {}}, 146 | GridBoxSpacings->{"Columns" -> { 147 | Offset[0.27999999999999997`], { 148 | Offset[0.5599999999999999]}, 149 | Offset[0.27999999999999997`]}, "Rows" -> { 150 | Offset[0.2], { 151 | Offset[0.8]}, 152 | Offset[0.2]}}], 153 | BaseStyle->"InformationTitleFrame"], "InformationGridPlain"]], "Output", 154 | CellChangeTimes->{3.822074443481799*^9, 3.8220746803636703`*^9, 155 | 3.8220780124928427`*^9, 3.822446487464629*^9}, 156 | CellLabel->"Out[5]=",ExpressionUUID->"828a75ba-f5c3-488d-9d6c-c4da9503e135"] 157 | }, Open ]] 158 | }, Open ]], 159 | 160 | Cell[CellGroupData[{ 161 | 162 | Cell["Absolute value, white noise", "Title", 163 | CellChangeTimes->{{3.822074726072303*^9, 3.82207472881537*^9}, { 164 | 3.82207522695708*^9, 165 | 3.822075228352322*^9}},ExpressionUUID->"b7f822b6-9baf-4688-a125-\ 166 | f8509e18632f"], 167 | 168 | Cell[CellGroupData[{ 169 | 170 | Cell["Data", "Chapter", 171 | CellChangeTimes->{{3.8220745110632763`*^9, 172 | 3.822074518907728*^9}},ExpressionUUID->"a392b314-8eaf-4606-b7c2-\ 173 | 350ea789a805"], 174 | 175 | Cell[BoxData[{ 176 | RowBox[{ 177 | RowBox[{"colors", "=", 178 | RowBox[{"(", 179 | RowBox[{ 180 | RowBox[{"(", 181 | RowBox[{"\"\\"", "/.", " ", 182 | RowBox[{"(", 183 | RowBox[{"Method", "/.", " ", 184 | RowBox[{"Charting`ResolvePlotTheme", "[", 185 | RowBox[{"\"\\"", ",", "ListLinePlot"}], "]"}]}], 186 | ")"}]}], ")"}], "/.", " ", 187 | RowBox[{ 188 | RowBox[{"Directive", "[", 189 | RowBox[{"x_", ",", "__"}], "]"}], "\[RuleDelayed]", "x"}]}], ")"}]}], 190 | ";"}], "\[IndentingNewLine]", 191 | RowBox[{ 192 | RowBox[{"styleExactF", "=", 193 | RowBox[{"Darker", "[", "Green", "]"}]}], ";"}], "\[IndentingNewLine]", 194 | RowBox[{ 195 | RowBox[{"styleExact", "=", 196 | RowBox[{"Opacity", "[", 197 | RowBox[{"0.4", ",", 198 | RowBox[{"Darker", "[", "Green", "]"}]}], "]"}]}], 199 | ";"}], "\[IndentingNewLine]", 200 | RowBox[{ 201 | RowBox[{"styleNoisy", "=", 202 | RowBox[{"Directive", "[", 203 | RowBox[{ 204 | RowBox[{"Opacity", "[", "0.7", "]"}], ",", 205 | RowBox[{"colors", "[", 206 | RowBox[{"[", "1", "]"}], "]"}]}], "]"}]}], ";"}], "\[IndentingNewLine]", 207 | RowBox[{ 208 | RowBox[{"styleFiltered1", "=", 209 | RowBox[{"colors", "[", 210 | RowBox[{"[", "2", "]"}], "]"}]}], ";"}], "\[IndentingNewLine]", 211 | RowBox[{ 212 | RowBox[{"styleFiltered2", "=", 213 | RowBox[{"Darker", "[", "Magenta", "]"}]}], ";"}], "\[IndentingNewLine]", 214 | RowBox[{ 215 | RowBox[{"styleAve", "=", "Brown"}], ";"}], "\[IndentingNewLine]", 216 | RowBox[{ 217 | RowBox[{"styleTVR", "=", "Black"}], ";"}], "\[IndentingNewLine]", 218 | RowBox[{ 219 | RowBox[{"styleTVRFiltered", "=", "Gray"}], ";"}], "\[IndentingNewLine]", 220 | RowBox[{ 221 | RowBox[{"styleFiltered1Filtered", "=", 222 | RowBox[{"Lighter", "[", "styleFiltered1", "]"}]}], 223 | ";"}], "\[IndentingNewLine]", 224 | RowBox[{ 225 | RowBox[{"styleFiltered2Filtered", "=", 226 | RowBox[{"Lighter", "[", "styleFiltered2", "]"}]}], 227 | ";"}], "\[IndentingNewLine]", 228 | RowBox[{ 229 | RowBox[{"styleNoisyFiltered", "=", "Blue"}], ";"}]}], "Input", 230 | CellChangeTimes->{{3.822080364109148*^9, 3.8220804030326*^9}, { 231 | 3.822080459324828*^9, 3.822080469482498*^9}, {3.822080533293442*^9, 232 | 3.822080546966855*^9}, {3.822080624402416*^9, 3.822080633396042*^9}, { 233 | 3.822080666812296*^9, 3.822080667480496*^9}, {3.8220807025122538`*^9, 234 | 3.822080708159739*^9}, {3.8220809702649183`*^9, 3.8220809737896137`*^9}, { 235 | 3.822081041128613*^9, 3.822081045141851*^9}, {3.822081223892832*^9, 236 | 3.822081271338377*^9}, {3.822081783296955*^9, 3.822081786781722*^9}, { 237 | 3.8220821024710217`*^9, 3.822082106366267*^9}, {3.82208214163734*^9, 238 | 3.82208216211764*^9}}, 239 | CellLabel->"In[20]:=",ExpressionUUID->"78221468-84d4-4909-8592-d7ee93cf5a0e"], 240 | 241 | Cell[CellGroupData[{ 242 | 243 | Cell[BoxData[{ 244 | RowBox[{ 245 | RowBox[{"dx", "=", "0.01"}], ";"}], "\[IndentingNewLine]", 246 | RowBox[{ 247 | RowBox[{"dataExact", "=", 248 | RowBox[{"Table", "[", 249 | RowBox[{ 250 | RowBox[{"Abs", "[", 251 | RowBox[{"x", "-", "0.5"}], "]"}], ",", 252 | RowBox[{"{", 253 | RowBox[{"x", ",", "0", ",", "1", ",", "dx"}], "}"}]}], "]"}]}], 254 | ";"}], "\[IndentingNewLine]", 255 | RowBox[{ 256 | RowBox[{"dataNoisy", "=", 257 | RowBox[{"Table", "[", 258 | RowBox[{ 259 | RowBox[{"x", "+", 260 | RowBox[{"RandomVariate", "[", 261 | RowBox[{"NormalDistribution", "[", 262 | RowBox[{"0", ",", "0.05"}], "]"}], "]"}]}], ",", 263 | RowBox[{"{", 264 | RowBox[{"x", ",", "dataExact"}], "}"}]}], "]"}]}], 265 | ";"}], "\[IndentingNewLine]", 266 | RowBox[{ 267 | RowBox[{"leg", "=", 268 | RowBox[{"LineLegend", "[", 269 | RowBox[{ 270 | RowBox[{"{", 271 | RowBox[{"styleExact", ",", "styleNoisy"}], "}"}], ",", 272 | RowBox[{"{", 273 | RowBox[{"\"\\"", ",", "\"\\""}], "}"}]}], 274 | "]"}]}], ";"}], "\[IndentingNewLine]", 275 | RowBox[{"pltData", "=", 276 | RowBox[{"Grid", "[", 277 | RowBox[{"{", 278 | RowBox[{"{", 279 | RowBox[{ 280 | RowBox[{"ListLinePlot", "[", 281 | RowBox[{ 282 | RowBox[{"{", 283 | RowBox[{"dataNoisy", ",", "dataExact"}], "}"}], ",", 284 | RowBox[{"PlotStyle", "\[Rule]", 285 | RowBox[{"{", 286 | RowBox[{"styleNoisy", ",", "styleExact"}], "}"}]}], ",", 287 | RowBox[{"FrameLabel", "\[Rule]", 288 | RowBox[{"{", "\"\\"", "}"}]}], ",", 289 | RowBox[{"PlotLabel", "\[Rule]", "\"\\""}]}], "]"}], ",", 290 | "leg"}], "}"}], "}"}], "]"}]}]}], "Input", 291 | CellChangeTimes->{{3.821994658483042*^9, 3.82199470308302*^9}, 292 | 3.821995607144384*^9, {3.821995978161849*^9, 3.8219959789366426`*^9}, { 293 | 3.821996019909335*^9, 3.821996019973658*^9}, {3.821996087757765*^9, 294 | 3.8219961044957743`*^9}, {3.821996153919792*^9, 3.821996159095829*^9}, { 295 | 3.821996321171908*^9, 3.821996323522456*^9}, {3.8219971268288794`*^9, 296 | 3.82199712688958*^9}, {3.821997250564582*^9, 3.821997254695437*^9}, { 297 | 3.821997447742552*^9, 3.821997449400614*^9}, 3.821997610310317*^9, { 298 | 3.822008132906143*^9, 3.8220081355838127`*^9}, {3.822008247396161*^9, 299 | 3.822008290034176*^9}, {3.822074850569849*^9, 3.822074851950426*^9}, { 300 | 3.822446531540987*^9, 3.8224466018299828`*^9}, {3.822446656310828*^9, 301 | 3.82244668174302*^9}}, 302 | CellLabel->"In[70]:=",ExpressionUUID->"62725fc3-d230-4d44-a76a-5cdd913fd5a5"], 303 | 304 | Cell[BoxData[ 305 | TagBox[GridBox[{ 306 | { 307 | GraphicsBox[{{}, {{}, {}, 308 | {RGBColor[0.9, 0.36, 0.054], PointSize[ 309 | NCache[ 310 | Rational[1, 72], 0.013888888888888888`]], AbsoluteThickness[1.6], 311 | Opacity[0.7], CapForm["Butt"], 312 | StyleBox[LineBox[CompressedData[" 313 | 1:eJw1lA001XcYx++isWl1bdbWUGPeEpoSeWm+3l3CvVzXSx0zB8tENrM0sj+n 314 | lCNzTPPSShSOEcpbB7mu1xSS9w1hZW0HybZ2nTMz247nd8/5n3s+/8/veZ7f 315 | +f2f36MVcsI7bBOPxwv77/n/f+O3bOucmhjXbvyTLb1AavTunTsMp4mVsemz 316 | 03v+Mn1CzIe8smVdLp0hVsOXcyGD4esTxG9DVlqkq9g5TqyBkDuiHJPUH4nf 317 | hXKp0snIj4eJtRHE3569bcsYsQ6CPK6arvU/ItaDtLXrsrT2B2IDcDGZAUcK 318 | WT1DjKxpnRqJnCQ2wt3EaCN5JFtvgr01SUqNgSz/+5Bcnhr43ZGxKbQqs+9w 319 | /CnifWjIGkoq0h8i3g8u+ZF6WRPLZ4bFiMJr/V1s/wegti19tSSOrTdHfFho 320 | 6Yywl9gCbwZvXVkdHSE+iMKW7wpPebJ4S2irJC1UT3UTW2Fnd5zylRwWb42k 321 | KtgNZDC2gVJN+phAeo/4EFK0veoS53uIP8An/W8haqqP2BZ/jHzfn6zC6gPi 322 | nALJ/qXODeYAo77qwKdjxDw7pIz0DeuXt5K3g2Wa+kEPaT95e/Cqc4f4vzaR 323 | t0fte6rCx690kHdATYZDx2PdLvIOyPwwxSrero28I5oadhxbrKgl7whN4Vq1 324 | VreMvBM0DPW8wm2k5J1wTpghytheRN4Z1g8akuQvqB7njAmHiT+bNzWTd0Hx 325 | klR0s6uCvAuCXDj7aE1initClAst/45pIe8KjyWlspqqktYNL4BQQdLjVlVC 326 | XgDdf3Y7jeVeI++GLXxc8NxVvcGcG+YCS5LvVhSQd8f0uEFnrHUZeXccNSmZ 327 | WdlTTPUPY/70iqR9pYb8YXCXPOt/e/41xXtA5wZuW/Vkk/fAMV8Dt6zbF8l7 328 | olN1l9c3Fuz8PXFfWH/xZMItyu+F7r7BfOtSOk/OC411ZcFyFfZ9hYj2NLRJ 329 | 86F+gxD7hhXzB8NYPiFeDWgN0FSh85QJMV3Q/IXTc9ZvIsiVv2rNtXlI8SI4 330 | Li6t/mw8SPEi9B562WZzOPWjTITxM6+/6OCT53nD/JfY2QsV1B/wRkJFXYJq 331 | O+sXbyznHYj6PJP6ReaNS5Pp67pt9yneB2OCgdliNVbfBzx3PZ31YLp/nA/O 332 | zUQWpw2Rl/lg9HxExTyf3Tcx2p88VHxqTf0MMc6+E/dAnkLrOTHM8s7OjX9E 333 | +5WJ8Uz/XqxpOov3hSxPPJUyy+r7Iir0mZVUMErxvohxUT1qrEHzReYLlO+9 334 | HjbJ5pME5c1H/K430nyEBPOS/CyT45Sfk+D8jb7sLEfyMgkqS61Th86weeUH 335 | t/jgq36hNB/hBz0FR5MTvXS/OT+ob77lGldP80zmh1lvQeZLr7F57g+xuYNg 336 | YSuL98enNyPKFuQ0nzl/tGWlDi7H0LyX+UMp51uzJj7bfwCOLyrYvlHJ4gMg 337 | sLXQueI+ZfsvV+3qBA== 338 | "]], 339 | FontSize->24]}, 340 | {RGBColor[0, 341 | NCache[ 342 | Rational[2, 3], 0.6666666666666666], 0], PointSize[ 343 | NCache[ 344 | Rational[1, 72], 0.013888888888888888`]], AbsoluteThickness[1.6], 345 | Opacity[0.4], CapForm["Butt"], 346 | StyleBox[LineBox[CompressedData[" 347 | 1:eJxdlTloFFEYxxerECwstrCQJYrIGkQ0iXc2+8+5m3tndvYIpBJia+wkWrzC 348 | 2MbCQkVESBqbRUEwgsgzRjxIgnfivdrGIo3W2fnm/2Dee7A8fvxnvvnu3Xv2 349 | vD+1I5FITDV+4R2drWx013knMDm39C89+YvchMXU7Ka3+JO8C8la7vdM0nAS 350 | FzLN6/PTP8i7sboSnu/kPTgoBg23ILSWmv1G3oeGsYbFr+T96ArNZQwfwK2b 351 | 4flCTuN/OjS4QW6FLw4aPgRxr7ZOPgwx12z4CM7J+Uw+ijDauaVP5DZIuCnD 352 | 7bgkAX8kdyAy94F8DO1yDB/HNTH4nnwCf8NwN9+RTyIvARs+hYXQ3Pxb8mlE 353 | t+EzzP8auRPy+PQqOQNJR3qF3IU/ks835Czz95oM5utVxArMz0vq3czHC+rd 354 | EHMzy9R70CbxPqfew/ieUe9lPJp6L/1/Sr2P/j6h3ocb4t9j6v1oEn8eUe/H 355 | Zfn+Q+oD/N4D6gO0X6Oeo7171HO4KO8vUM/jvjx/h3oeSvTr1AfJV6gPsh7m 356 | DDn6kPP+MLRlf5i6+f4I7lr+jfB54/8otqz4Rum/iX/Myc+Yk79xJ7/jTv4L 357 | dn1QsOunCuiI11cXmH9Tfw/L8f6Ah53x/lEegnh/aQ+3rf7zUY/3J3y7f5Vv 358 | 97f2nf4vsh6cDxTt+VFFe7500Zm/wJ5PBIyX86sCbMTnWweM38x/CS3x/YCS 359 | vT9Uyd4vuuTsn7K9n1C295cq2/tNl539V7H3Iyqcd7Kq4Gp8v+oKWq39W8Va 360 | fD+jynxzf6uqvd911dn/E/b/AyZYj3p2G3bG05M= 361 | "]], 362 | FontSize->24]}}, {{}, {}}}, 363 | AspectRatio->NCache[GoldenRatio^(-1), 0.6180339887498948], 364 | Axes->{False, False}, 365 | AxesLabel->{None, None}, 366 | AxesOrigin->{0., 0}, 367 | BaseStyle->{FontSize -> 24}, 368 | DisplayFunction->Identity, 369 | Frame->{{True, True}, {True, True}}, 370 | FrameLabel->{{None, None}, { 371 | FormBox["\"Time\"", TraditionalForm], None}}, 372 | FrameStyle->Automatic, 373 | FrameTicks->{{Automatic, Automatic}, {Automatic, Automatic}}, 374 | GridLines->{{0}, {0}}, 375 | GridLinesStyle->Directive[ 376 | GrayLevel[0.5, 0.4]], 377 | ImageSize->400, 378 | LabelStyle->{FontFamily -> "Times"}, 379 | Method->{ 380 | "OptimizePlotMarkers" -> True, "OptimizePlotMarkers" -> True, 381 | "CoordinatesToolOptions" -> {"DisplayFunction" -> ({ 382 | Identity[ 383 | Part[#, 1]], 384 | Identity[ 385 | Part[#, 2]]}& ), "CopiedValueFunction" -> ({ 386 | Identity[ 387 | Part[#, 1]], 388 | Identity[ 389 | Part[#, 2]]}& )}}, 390 | PlotLabel->FormBox["\"Signal\"", TraditionalForm], 391 | PlotRange->{{0., 101.}, {-0.07409300444805181, 0.6075367061899258}}, 392 | PlotRangeClipping->True, 393 | PlotRangePadding->{{ 394 | Scaled[0.02], 395 | Scaled[0.02]}, { 396 | Scaled[0.05], 397 | Scaled[0.05]}}, 398 | Ticks->{Automatic, Automatic}], 399 | TemplateBox[{"\"Exact signal\"", "\"Noisy signal\""}, 400 | "LineLegend", 401 | DisplayFunction->(StyleBox[ 402 | StyleBox[ 403 | PaneBox[ 404 | TagBox[ 405 | GridBox[{{ 406 | TagBox[ 407 | GridBox[{{ 408 | GraphicsBox[{{ 409 | Directive[ 410 | EdgeForm[ 411 | Directive[ 412 | Opacity[0.3], 413 | GrayLevel[0]]], 414 | PointSize[0.5], 415 | AbsoluteThickness[1.6], 416 | RGBColor[0, 417 | NCache[ 418 | Rational[2, 3], 0.6666666666666666], 0], 419 | Opacity[0.4]], { 420 | LineBox[{{0, 40}, {40, 40}}]}}, { 421 | Directive[ 422 | EdgeForm[ 423 | Directive[ 424 | Opacity[0.3], 425 | GrayLevel[0]]], 426 | PointSize[0.5], 427 | AbsoluteThickness[1.6], 428 | RGBColor[0, 429 | NCache[ 430 | Rational[2, 3], 0.6666666666666666], 0], 431 | Opacity[0.4]], {}}}, AspectRatio -> Full, 432 | ImageSize -> {40, 40}, PlotRangePadding -> None, 433 | ImagePadding -> Automatic, 434 | BaselinePosition -> (Scaled[0.4] -> Baseline)], #}, { 435 | GraphicsBox[{{ 436 | Directive[ 437 | EdgeForm[ 438 | Directive[ 439 | Opacity[0.3], 440 | GrayLevel[0]]], 441 | PointSize[0.5], 442 | AbsoluteThickness[1.6], 443 | Opacity[0.7], 444 | RGBColor[0.9, 0.36, 0.054]], { 445 | LineBox[{{0, 40}, {40, 40}}]}}, { 446 | Directive[ 447 | EdgeForm[ 448 | Directive[ 449 | Opacity[0.3], 450 | GrayLevel[0]]], 451 | PointSize[0.5], 452 | AbsoluteThickness[1.6], 453 | Opacity[0.7], 454 | RGBColor[0.9, 0.36, 0.054]], {}}}, AspectRatio -> Full, 455 | ImageSize -> {40, 40}, PlotRangePadding -> None, 456 | ImagePadding -> Automatic, 457 | BaselinePosition -> (Scaled[0.4] -> Baseline)], #2}}, 458 | GridBoxAlignment -> { 459 | "Columns" -> {Center, Left}, "Rows" -> {{Baseline}}}, 460 | AutoDelete -> False, 461 | GridBoxDividers -> { 462 | "Columns" -> {{False}}, "Rows" -> {{False}}}, 463 | GridBoxItemSize -> {"Columns" -> {{All}}, "Rows" -> {{All}}}, 464 | GridBoxSpacings -> {"Columns" -> {{0.5}}, "Rows" -> {{0.8}}}], 465 | "Grid"]}}, 466 | GridBoxAlignment -> {"Columns" -> {{Left}}, "Rows" -> {{Top}}}, 467 | AutoDelete -> False, 468 | GridBoxItemSize -> { 469 | "Columns" -> {{Automatic}}, "Rows" -> {{Automatic}}}, 470 | GridBoxSpacings -> {"Columns" -> {{1}}, "Rows" -> {{0}}}], 471 | "Grid"], Alignment -> Left, AppearanceElements -> None, 472 | ImageMargins -> {{5, 5}, {5, 5}}, ImageSizeAction -> "ResizeToFit"], 473 | LineIndent -> 0, StripOnInput -> False], { 474 | Directive[FontSize -> 24, FontFamily -> Automatic], FontFamily -> 475 | "Arial"}, Background -> Automatic, StripOnInput -> False]& ), 476 | Editable->True, 477 | InterpretationFunction:>(RowBox[{"LineLegend", "[", 478 | RowBox[{ 479 | RowBox[{"{", 480 | RowBox[{ 481 | RowBox[{"Opacity", "[", 482 | RowBox[{"0.4`", ",", 483 | InterpretationBox[ 484 | ButtonBox[ 485 | TooltipBox[ 486 | GraphicsBox[{{ 487 | GrayLevel[0], 488 | RectangleBox[{0, 0}]}, { 489 | GrayLevel[0], 490 | RectangleBox[{1, -1}]}, { 491 | RGBColor[0, 492 | Rational[2, 3], 0], 493 | RectangleBox[{0, -1}, {2, 1}]}}, DefaultBaseStyle -> 494 | "ColorSwatchGraphics", AspectRatio -> 1, Frame -> True, 495 | FrameStyle -> RGBColor[0., 0.4444444444444444, 0.], 496 | FrameTicks -> None, PlotRangePadding -> None, ImageSize -> 497 | Dynamic[{ 498 | Automatic, 499 | 1.35 (CurrentValue["FontCapHeight"]/AbsoluteCurrentValue[ 500 | Magnification])}]], 501 | StyleBox[ 502 | RowBox[{"RGBColor", "[", 503 | RowBox[{"0", ",", 504 | FractionBox["2", "3"], ",", "0"}], "]"}], NumberMarks -> 505 | False]], Appearance -> None, BaseStyle -> {}, 506 | BaselinePosition -> Baseline, DefaultBaseStyle -> {}, 507 | ButtonFunction :> With[{Typeset`box$ = EvaluationBox[]}, 508 | If[ 509 | Not[ 510 | AbsoluteCurrentValue["Deployed"]], 511 | SelectionMove[Typeset`box$, All, Expression]; 512 | FrontEnd`Private`$ColorSelectorInitialAlpha = 1; 513 | FrontEnd`Private`$ColorSelectorInitialColor = 514 | RGBColor[0, 515 | Rational[2, 3], 0]; 516 | FrontEnd`Private`$ColorSelectorUseMakeBoxes = True; 517 | MathLink`CallFrontEnd[ 518 | FrontEnd`AttachCell[Typeset`box$, 519 | FrontEndResource["RGBColorValueSelector"], { 520 | 0, {Left, Bottom}}, {Left, Top}, 521 | "ClosingActions" -> { 522 | "SelectionDeparture", "ParentChanged", 523 | "EvaluatorQuit"}]]]], BaseStyle -> Inherited, Evaluator -> 524 | Automatic, Method -> "Preemptive"], 525 | RGBColor[0, 526 | Rational[2, 3], 0], Editable -> False, Selectable -> 527 | False]}], "]"}], ",", 528 | RowBox[{"Directive", "[", 529 | RowBox[{ 530 | RowBox[{"Opacity", "[", "0.7`", "]"}], ",", 531 | InterpretationBox[ 532 | ButtonBox[ 533 | TooltipBox[ 534 | GraphicsBox[{{ 535 | GrayLevel[0], 536 | RectangleBox[{0, 0}]}, { 537 | GrayLevel[0], 538 | RectangleBox[{1, -1}]}, { 539 | RGBColor[0.9, 0.36, 0.054], 540 | RectangleBox[{0, -1}, {2, 1}]}}, DefaultBaseStyle -> 541 | "ColorSwatchGraphics", AspectRatio -> 1, Frame -> True, 542 | FrameStyle -> 543 | RGBColor[0.6000000000000001, 0.24, 0.036000000000000004`], 544 | FrameTicks -> None, PlotRangePadding -> None, ImageSize -> 545 | Dynamic[{ 546 | Automatic, 547 | 1.35 (CurrentValue["FontCapHeight"]/AbsoluteCurrentValue[ 548 | Magnification])}]], 549 | StyleBox[ 550 | RowBox[{"RGBColor", "[", 551 | RowBox[{"0.9`", ",", "0.36`", ",", "0.054`"}], "]"}], 552 | NumberMarks -> False]], Appearance -> None, 553 | BaseStyle -> {}, BaselinePosition -> Baseline, 554 | DefaultBaseStyle -> {}, ButtonFunction :> 555 | With[{Typeset`box$ = EvaluationBox[]}, 556 | If[ 557 | Not[ 558 | AbsoluteCurrentValue["Deployed"]], 559 | SelectionMove[Typeset`box$, All, Expression]; 560 | FrontEnd`Private`$ColorSelectorInitialAlpha = 1; 561 | FrontEnd`Private`$ColorSelectorInitialColor = 562 | RGBColor[0.9, 0.36, 0.054]; 563 | FrontEnd`Private`$ColorSelectorUseMakeBoxes = True; 564 | MathLink`CallFrontEnd[ 565 | FrontEnd`AttachCell[Typeset`box$, 566 | FrontEndResource["RGBColorValueSelector"], { 567 | 0, {Left, Bottom}}, {Left, Top}, 568 | "ClosingActions" -> { 569 | "SelectionDeparture", "ParentChanged", 570 | "EvaluatorQuit"}]]]], BaseStyle -> Inherited, Evaluator -> 571 | Automatic, Method -> "Preemptive"], 572 | RGBColor[0.9, 0.36, 0.054], Editable -> False, Selectable -> 573 | False]}], "]"}]}], "}"}], ",", 574 | RowBox[{"{", 575 | RowBox[{#, ",", #2}], "}"}]}], "]"}]& )]} 576 | }, 577 | AutoDelete->False, 578 | GridBoxItemSize->{"Columns" -> {{Automatic}}, "Rows" -> {{Automatic}}}], 579 | "Grid"]], "Output", 580 | CellChangeTimes->{{3.822074828845477*^9, 3.822074852297296*^9}, 581 | 3.8224464900129957`*^9, 3.8224465437380533`*^9, {3.822446575346818*^9, 582 | 3.82244660234451*^9}, {3.822446657970254*^9, 3.82244668209202*^9}}, 583 | CellLabel->"Out[74]=",ExpressionUUID->"885b0182-66fe-4ab0-a771-e141e0dcd1b0"] 584 | }, Open ]], 585 | 586 | Cell[CellGroupData[{ 587 | 588 | Cell[BoxData[{ 589 | RowBox[{ 590 | RowBox[{"SetDirectory", "[", 591 | RowBox[{"NotebookDirectory", "[", "]"}], "]"}], 592 | ";"}], "\[IndentingNewLine]", 593 | RowBox[{"Export", "[", 594 | RowBox[{"\"\\"", ",", "pltData", ",", 595 | RowBox[{"ImageResolution", "\[Rule]", "200"}]}], "]"}]}], "Input", 596 | CellChangeTimes->{{3.822446606886797*^9, 3.822446632992075*^9}}, 597 | CellLabel->"In[57]:=",ExpressionUUID->"46e33d7c-69c9-41a3-a24e-dac0866375f8"], 598 | 599 | Cell[BoxData["\<\"example_abs_figures/signal.png\"\>"], "Output", 600 | CellChangeTimes->{3.8224466337873898`*^9}, 601 | CellLabel->"Out[58]=",ExpressionUUID->"fadf2586-c90f-413b-97df-67179f4ac5f6"] 602 | }, Open ]], 603 | 604 | Cell[BoxData[ 605 | RowBox[{ 606 | RowBox[{"diff", "[", "x_", "]"}], ":=", 607 | RowBox[{ 608 | RowBox[{ 609 | RowBox[{"(", 610 | RowBox[{ 611 | RowBox[{"RotateLeft", "[", "x", "]"}], "-", "x"}], ")"}], "[", 612 | RowBox[{"[", 613 | RowBox[{";;", 614 | RowBox[{"-", "2"}]}], "]"}], "]"}], "/", 615 | RowBox[{"(", "dx", ")"}]}]}]], "Input", 616 | InitializationCell->True, 617 | CellChangeTimes->{{3.822056435998011*^9, 3.82205644423831*^9}}, 618 | CellLabel->"In[56]:=",ExpressionUUID->"c10c0c2c-3206-43dc-b3ee-ecaaf9f25a37"], 619 | 620 | Cell[CellGroupData[{ 621 | 622 | Cell[BoxData[{ 623 | RowBox[{ 624 | RowBox[{"derivExact", "=", 625 | RowBox[{"Table", "[", 626 | RowBox[{ 627 | RowBox[{"If", "[", 628 | RowBox[{ 629 | RowBox[{"x", "<", "0.5"}], ",", 630 | RowBox[{"-", "1"}], ",", "1"}], "]"}], ",", 631 | RowBox[{"{", 632 | RowBox[{"x", ",", "0", ",", "1", ",", "dx"}], "}"}]}], "]"}]}], 633 | ";"}], "\[IndentingNewLine]", 634 | RowBox[{ 635 | RowBox[{"derivNoisy", "=", 636 | RowBox[{"diff", "[", "dataNoisy", "]"}]}], ";"}], "\[IndentingNewLine]", 637 | RowBox[{"pltDeriv", "=", 638 | RowBox[{"ListLinePlot", "[", 639 | RowBox[{ 640 | RowBox[{"{", 641 | RowBox[{"derivNoisy", ",", "derivExact"}], "}"}], ",", 642 | RowBox[{"PlotStyle", "\[Rule]", 643 | RowBox[{"{", 644 | RowBox[{"styleNoisy", ",", "styleExact"}], "}"}]}], ",", 645 | RowBox[{"PlotLabel", "\[Rule]", "\"\\""}], ",", 646 | RowBox[{"FrameLabel", "\[Rule]", 647 | RowBox[{"{", "\"\\"", "}"}]}]}], "]"}]}]}], "Input", 648 | CellChangeTimes->{{3.8219961089012203`*^9, 3.8219961651182537`*^9}, { 649 | 3.82199622398486*^9, 3.8219962244436827`*^9}, {3.821996325195032*^9, 650 | 3.821996326406733*^9}, {3.82199667315427*^9, 3.821996738230855*^9}, { 651 | 3.821996812578195*^9, 3.8219968290157337`*^9}, {3.822008311910851*^9, 652 | 3.822008319855774*^9}, {3.8220564503929043`*^9, 3.822056452535637*^9}, { 653 | 3.82207485444711*^9, 3.822074855654196*^9}, {3.822446648372746*^9, 654 | 3.822446690819137*^9}}, 655 | CellLabel->"In[75]:=",ExpressionUUID->"9fd65200-44e1-4e9a-9ac0-f32df45b4699"], 656 | 657 | Cell[BoxData[ 658 | GraphicsBox[{{}, {{}, {}, 659 | {RGBColor[0.9, 0.36, 0.054], PointSize[ 660 | NCache[ 661 | Rational[1, 72], 0.013888888888888888`]], AbsoluteThickness[1.6], 662 | Opacity[0.7], CapForm["Butt"], 663 | StyleBox[{ 664 | LineBox[{{1., -6.551642418932635}, {1.9141549900638766`, 665 | 11.187324421321778`}}], 666 | LineBox[{{2.0716932353595503`, 11.187324421321778`}, { 667 | 3., -10.382016677326156`}, {4., -7.4192090290260415`}, { 668 | 5., -5.0499599198669305`}, {6., 2.7475938841542313`}, { 669 | 7., -9.562757545095268}, {8., 4.129889240144758}, {8.883144833847197, 670 | 11.187324421321778`}}], 671 | LineBox[{{9.04647294749474, 11.187324421321778`}, { 672 | 10., -7.972683464159935}, {11., 3.006666599572949}, {12., 673 | 1.2419014770974401`}, {13., -4.686696520185834}, { 674 | 14., -3.2302175589543847`}, {15., -0.13289969723167538`}, {16., 675 | 9.054897419651969}, {16.80210573599856, -10.627763103341765`}}], 676 | LineBox[{{17.188539949007613`, -10.627763103341765`}, {18., 677 | 10.272374473765622`}, {19., -7.744466628752744}, { 678 | 20., -2.0517266433143444`}, {21., -7.502511921069788}, { 679 | 21.998494766289436`, 11.187324421321778`}}], 680 | LineBox[{{22.002070916049227`, 11.187324421321778`}, { 681 | 23., -2.3895821019812855`}, { 682 | 23.8308044936313, -10.627763103341765`}}], 683 | LineBox[{{24.10487176003623, -10.627763103341765`}, {25., 684 | 3.6924018043883566`}, {26., -0.02686712925283885}, { 685 | 27., -1.4145543196693673`}, {28., -0.646366283137581}, {29., 686 | 3.0820911649548366`}, {30., 8.772544340874678}, { 687 | 30.81716996501513, -10.627763103341765`}}], 688 | LineBox[{{31.29136625969295, -10.627763103341765`}, { 689 | 32., -0.07110815182198582}, {33., -3.9118104049307463`}, {34., 690 | 10.86799270508363}, {34.911043908353165`, -10.627763103341765`}}], 691 | LineBox[{{35.122812256187004`, -10.627763103341765`}, {36., 692 | 4.363559501743594}, {37., 1.647954583025066}, { 693 | 38., -3.0408207678520234`}, {39., -5.796838107474539}, {40., 694 | 5.420440246317604}, {41., -1.2937370880955674`}, { 695 | 42., -8.473394214480068}, {42.948547080562435`, 696 | 11.187324421321778`}}], 697 | LineBox[{{43.061667071291325`, 11.187324421321778`}, { 698 | 44., -5.040270266485653}, {45., -5.126785044085313}, { 699 | 46., -0.12837070092488884`}, {47., 6.204635472376445}, { 700 | 47.76720108970026, -10.627763103341765`}}], 701 | LineBox[{{48.21101679435138, -10.627763103341765`}, {49., 702 | 8.469383236567582}, {50., -7.866004266543572}, { 703 | 51., -2.4471052815929366`}, {52., 3.083356602900729}, { 704 | 53., -1.7376423270509673`}, {54., 8.672653555460071}, { 705 | 54.96397255531252, -10.627763103341765`}}], 706 | LineBox[{{55.04182174085312, -10.627763103341765`}, {56., 707 | 5.898690975815627}, {57., -0.4212407197285453}, { 708 | 58., -0.09130026973391964}, {58.912842719147406`, 709 | 11.187324421321778`}}], LineBox[CompressedData[" 710 | 1:eJxTTMoPSmViYGBQAmIQvebkh9+nOnwdMhf3/XkRr+bAAAZ+DrzVXW2XvbkP 711 | gLkNfg7rA0My+rdJQOX9HdZr7o86b80K4Tf4O4QxXtm+uu6PPUQ+wEFq9ZuY 712 | r60yEP0OAQ4SQuaXUlUuQOQbAhxWr0qfrZuqDNF/IMChZ/n5yN95IlDzAx3m 713 | Gb19tnjCd4h6h0CH/sOM3LwK8lD3BDqo2j6I/JEpB9Uf6HDnKItNRIUyRJ4h 714 | yOFF6EyvmdM3QvUHOTw1njUr1IYLqj/IIXiC70uv3TJQ/UEOFvVV+/KfCkDt 715 | D3bo7dvvmbGLB8J3CHbIsJ+1Z08JM1R/sIP/kaTre7ih8geCHUrPuz3oPicN 716 | tT/EgclmXtn6dexQ/SEO4m5z1H8f/gr1f4hDR8uZuvss3FD9IQ4362YYHV4l 717 | ANUf6vDzhxX/5onSUP2hDt7ajTa3er5A9Yc6nPpid6//qyJUf6iD1uQ3kf8u 718 | SUL1hzls+PrvsuQTKWj4hznIXD9wNosDGn8NYQ7JkzSDV+z8tB+iP8yBm3/y 719 | u/oqVYeNx2YUTPoR5sD5K0Yry1H1AACFVaqs 720 | "]], 721 | LineBox[{{93.11476693892173, 11.187324421321778`}, {94., 722 | 2.096850294148239}, {95., -1.5508240111054006`}, { 723 | 96., -4.8339755134376885`}, {96.64038930926476, 724 | 11.187324421321778`}}], 725 | LineBox[{{98.34761085182986, -10.627763103341765`}, {99., 726 | 4.079271334317119}, {100., -2.1573568507579024`}}], 727 | LineBox[{{92.10874442480373, -10.627763103341765`}, {92.9543184948536, 728 | 11.187324421321778`}}], 729 | LineBox[{{97.23278630430167, 11.187324421321778`}, { 730 | 97.7972397302004, -10.627763103341765`}}]}, 731 | FontSize->24]}, 732 | {RGBColor[0, 733 | NCache[ 734 | Rational[2, 3], 0.6666666666666666], 0], PointSize[ 735 | NCache[ 736 | Rational[1, 72], 0.013888888888888888`]], AbsoluteThickness[1.6], 737 | Opacity[0.4], CapForm["Butt"], 738 | StyleBox[LineBox[CompressedData[" 739 | 1:eJxd0zlKBEEAheGHkaGBgYGBioiIiPuu0+77Nu6pMLFXqJtZR/IIKg5KfwVF 740 | 8fXPC3v87b3bG0jS+74/7+/57PTfj/6Hpu1BPISH8QgexWN4Ak/iKTyNZ/As 741 | nsPzeAEv4iW8jFfwKl7D63gDb+ItvI138C7u4KbtgrNHx9mn4xzQcQ7pOEd0 742 | nGM6zgkd55SOc0b/c/8/OW+74FzQcS7pOFd0nGs6zg0d57btBhdcce7Y44Ir 743 | Tpc9Lrji3LPHBVecB/a44IrzyB4XXHGe2OOCK84ze1xwxXlhjwuuOK/s//0F 744 | Nt3dDw== 745 | "]], 746 | FontSize->24]}}, {{}, {}}}, 747 | AspectRatio->NCache[GoldenRatio^(-1), 0.6180339887498948], 748 | Axes->{False, False}, 749 | AxesLabel->{None, None}, 750 | AxesOrigin->{0., 0}, 751 | BaseStyle->{FontSize -> 24}, 752 | DisplayFunction->Identity, 753 | Frame->{{True, True}, {True, True}}, 754 | FrameLabel->{{None, None}, { 755 | FormBox["\"Time\"", TraditionalForm], None}}, 756 | FrameStyle->Automatic, 757 | FrameTicks->{{Automatic, Automatic}, {Automatic, Automatic}}, 758 | GridLines->{{0}, {0}}, 759 | GridLinesStyle->Directive[ 760 | GrayLevel[0.5, 0.4]], 761 | ImageSize->400, 762 | LabelStyle->{FontFamily -> "Times"}, 763 | Method->{ 764 | "OptimizePlotMarkers" -> True, "OptimizePlotMarkers" -> True, 765 | "CoordinatesToolOptions" -> {"DisplayFunction" -> ({ 766 | Identity[ 767 | Part[#, 1]], 768 | Identity[ 769 | Part[#, 2]]}& ), "CopiedValueFunction" -> ({ 770 | Identity[ 771 | Part[#, 1]], 772 | Identity[ 773 | Part[#, 2]]}& )}}, 774 | PlotLabel->FormBox["\"Derivative\"", TraditionalForm], 775 | PlotRange->{{0., 101.}, {-10.627763103341765`, 11.187324421321778`}}, 776 | PlotRangeClipping->True, 777 | PlotRangePadding->{{ 778 | Scaled[0.02], 779 | Scaled[0.02]}, { 780 | Scaled[0.05], 781 | Scaled[0.05]}}, 782 | Ticks->{Automatic, Automatic}]], "Output", 783 | CellChangeTimes->{{3.822074841341732*^9, 3.822074855819798*^9}, 784 | 3.822446492911145*^9, {3.8224466535578537`*^9, 3.8224466912260847`*^9}}, 785 | CellLabel->"Out[77]=",ExpressionUUID->"095b815a-6e19-49c7-bc5a-77ec8990fb2a"] 786 | }, Open ]], 787 | 788 | Cell[CellGroupData[{ 789 | 790 | Cell[BoxData[{ 791 | RowBox[{ 792 | RowBox[{"SetDirectory", "[", 793 | RowBox[{"NotebookDirectory", "[", "]"}], "]"}], 794 | ";"}], "\[IndentingNewLine]", 795 | RowBox[{"Export", "[", 796 | RowBox[{"\"\\"", ",", "pltDeriv", ",", 797 | RowBox[{"ImageResolution", "\[Rule]", "200"}]}], "]"}]}], "Input", 798 | CellChangeTimes->{{3.8224466976865463`*^9, 3.8224467009166803`*^9}}, 799 | CellLabel->"In[78]:=",ExpressionUUID->"9c11fb9a-4fab-401b-9bd9-277fddfa716e"], 800 | 801 | Cell[BoxData["\<\"example_abs_figures/deriv.png\"\>"], "Output", 802 | CellChangeTimes->{3.82244670139246*^9}, 803 | CellLabel->"Out[79]=",ExpressionUUID->"7f43dc7c-f925-42bb-b237-35e75f7bb185"] 804 | }, Open ]] 805 | }, Open ]], 806 | 807 | Cell[CellGroupData[{ 808 | 809 | Cell["Diff TVR", "Chapter", 810 | CellChangeTimes->{{3.8220745466620398`*^9, 811 | 3.8220745481070337`*^9}},ExpressionUUID->"855ceb4e-b9fa-4d58-9014-\ 812 | 2655a9c3de0b"], 813 | 814 | Cell[BoxData[{ 815 | RowBox[{ 816 | RowBox[{"derivGuess", "=", 817 | RowBox[{"ConstantArray", "[", 818 | RowBox[{"0", ",", 819 | RowBox[{ 820 | RowBox[{"Length", "[", "dataNoisy", "]"}], "+", "1"}]}], "]"}]}], 821 | ";"}], "\[IndentingNewLine]", 822 | RowBox[{ 823 | RowBox[{"noOptSteps", "=", "100"}], ";"}], "\[IndentingNewLine]", 824 | RowBox[{ 825 | RowBox[{"alpha", "=", "0.2"}], ";"}], "\[IndentingNewLine]", 826 | RowBox[{ 827 | RowBox[{"derivFinal", "=", 828 | RowBox[{"getDiffTVR", "[", 829 | RowBox[{ 830 | "dataNoisy", ",", "derivGuess", ",", "noOptSteps", ",", "dx", ",", 831 | "alpha"}], "]"}]}], ";"}]}], "Input", 832 | CellChangeTimes->{{3.822074560953826*^9, 3.8220745981923923`*^9}, { 833 | 3.82207469390092*^9, 3.82207469543958*^9}, 3.82207495869233*^9}, 834 | CellLabel->"In[80]:=",ExpressionUUID->"55c65b8f-303d-4a14-a418-a9d7e9302925"], 835 | 836 | Cell[CellGroupData[{ 837 | 838 | Cell[BoxData[{ 839 | RowBox[{ 840 | RowBox[{"leg", "=", 841 | RowBox[{"LineLegend", "[", 842 | RowBox[{ 843 | RowBox[{"{", 844 | RowBox[{"styleExact", ",", "styleTVR"}], "}"}], ",", 845 | RowBox[{"{", 846 | RowBox[{"\"\\"", ",", "\"\\""}], "}"}]}], "]"}]}], 847 | ";"}], "\[IndentingNewLine]", 848 | RowBox[{"pTVR", "=", 849 | RowBox[{"Grid", "[", 850 | RowBox[{"{", 851 | RowBox[{"{", 852 | RowBox[{ 853 | RowBox[{"ListLinePlot", "[", 854 | RowBox[{ 855 | RowBox[{"{", 856 | RowBox[{"derivExact", ",", "derivFinal"}], "}"}], ",", 857 | RowBox[{"PlotStyle", "\[Rule]", 858 | RowBox[{"{", 859 | RowBox[{"styleExact", ",", "styleTVR"}], "}"}]}], ",", 860 | RowBox[{"PlotLabel", "\[Rule]", "\"\\""}], ",", 861 | RowBox[{"FrameLabel", "\[Rule]", 862 | RowBox[{"{", "\"\\"", "}"}]}]}], "]"}], ",", "leg"}], "}"}], 863 | "}"}], "]"}]}]}], "Input", 864 | CellChangeTimes->{{3.82207469882241*^9, 3.82207470188883*^9}, { 865 | 3.8224467486684237`*^9, 3.822446813096903*^9}}, 866 | CellLabel->"In[98]:=",ExpressionUUID->"abb074b4-a2b2-4e8d-b794-2fe64f73809c"], 867 | 868 | Cell[BoxData[ 869 | TagBox[GridBox[{ 870 | { 871 | GraphicsBox[{{}, {{}, {}, 872 | {RGBColor[0, 873 | NCache[ 874 | Rational[2, 3], 0.6666666666666666], 0], PointSize[ 875 | NCache[ 876 | Rational[1, 72], 0.013888888888888888`]], AbsoluteThickness[1.6], 877 | Opacity[0.4], CapForm["Butt"], 878 | StyleBox[LineBox[CompressedData[" 879 | 1:eJxd0zlKBEEAheGHkaGBgYGBioiIiPuu0+77Nu6pMLFXqJtZR/IIKg5KfwVF 880 | 8fXPC3v87b3bG0jS+74/7+/57PTfj/6Hpu1BPISH8QgexWN4Ak/iKTyNZ/As 881 | nsPzeAEv4iW8jFfwKl7D63gDb+ItvI138C7u4KbtgrNHx9mn4xzQcQ7pOEd0 882 | nGM6zgkd55SOc0b/c/8/OW+74FzQcS7pOFd0nGs6zg0d57btBhdcce7Y44Ir 883 | Tpc9Lrji3LPHBVecB/a44IrzyB4XXHGe2OOCK84ze1xwxXlhjwuuOK/s//0F 884 | Nt3dDw== 885 | "]], 886 | FontSize->24]}, 887 | {GrayLevel[0], PointSize[ 888 | NCache[ 889 | Rational[1, 72], 0.013888888888888888`]], AbsoluteThickness[1.6], 890 | CapForm["Butt"], 891 | StyleBox[LineBox[CompressedData[" 892 | 1:eJxFyw1M1HUcx/H/bocSIclETGGr7KbxUD4gBsrB57jjmXt+PgroFtRQIUck 893 | 06ijlqVFzvFs0ylteNCdDTUfmotzDkHhmCRXFIFIpJAILIZAzKMc/9/X//bb 894 | f6/f5/d+yVqkyRNwHJf//3nyX/qmEmrWDz/nsUy18hd42D7Y1Uv2hXm4QfDU 895 | K9Ezu+zsz+QgnCsI9twiP4/5uNC3usmhONQSoO8kv4isG/4X28nrkSaxV1wj 896 | i2CWZIz8RN6AUmdk52XyK9h4XiI9Tw5Ha6ou5Qw5Er+NftJ7mvwarC2JQyfJ 897 | m3FJ7s6pJ29BrjxScZS8FZdlV09/QY5CZaPS+DF5GyIGl6eXkKNR2tdWWEDe 898 | juT4yMZs8uswSd/uV5Nj0L3jgL+MHIud7tqwaPIO1K0bmxGRdyIk2m5ZRY5D 899 | 0eOoAo4sRq7jZti4mTke8uD6pl/ICfBYTP4uMlAQ2/KmndkGLLbmBR6hXQJ1 900 | iSi3mHYJBHruopb2RPjKp8+E054IYY7jh79MbJeiTbFlq4XZJsX8H9dD3jCy 901 | XYajH5bX7dezXYa6W3crXWq2J+FvY9SppAy2J6G4fnPxPNiejIbZzOqqTWxP 902 | xsj71rnfV7M9BSXvxFX53pnk9xQcu7HKUKTkzaXCsnuF+ELcBL+n4td9jaUr 903 | VOP8noYHZc6Fkt2j/J6GwOjmR3tevsvv6RDaLRXesx38ng7H8bEN7du7E5b2 904 | DHwnk89V9Q8v2ZaBpOsLxd8Ix/g9E9XZ+V968IDfM+HjU+iZGeDNyZFfMfBR 905 | 2ALb5dh1aubeJi/bFXCvNsj3MtsUcEwbSmppV6LwCsSXaFdisMfq7aVdhe/L 906 | Co9MMEOFkUnbCZ9F9l6FmNlaxzpmlwqfZYm8rzJzamSVdzgTmKFG6IGbo0rq 907 | 1dDkXJ3Opl6NC5hZuYd6DSK+7srbT70Gcx0fBHxOvQa3v+0LqaReg5CIXQdP 908 | UK9FSPna+CbqtTj0XkPMOeq1cCmGyq5Qr0XPj34vtFGvw0SQPdxNvQ6j8gFH 909 | L/U6LHia7f3U65AtnFozTL0e3jvOufvU6yFeK5U/pF6PvvHAoH+o1+Og4Vrm 910 | I+oNELtvL85Tb8C9EX/JY+oNaHNWiDhunO8N2Pjp3iYBM2fE0LPvdgqZYUTz 911 | ZObhZcw2IwKmi6eWU2+Ej1UoeIZ6Eyx+0lYyTGj7al+sH/UmHKvZZiO7TPhT 912 | uaaOzJnRJfu3lgwz7iscNU97M4KNuuon/g+vfRXM 913 | "]], 914 | FontSize->24]}}, {{}, {}}}, 915 | AspectRatio->NCache[GoldenRatio^(-1), 0.6180339887498948], 916 | Axes->{False, False}, 917 | AxesLabel->{None, None}, 918 | AxesOrigin->{0., 0}, 919 | BaseStyle->{FontSize -> 24}, 920 | DisplayFunction->Identity, 921 | Frame->{{True, True}, {True, True}}, 922 | FrameLabel->{{None, None}, { 923 | FormBox["\"Time\"", TraditionalForm], None}}, 924 | FrameStyle->Automatic, 925 | FrameTicks->{{Automatic, Automatic}, {Automatic, Automatic}}, 926 | GridLines->{{0}, {0}}, 927 | GridLinesStyle->Directive[ 928 | GrayLevel[0.5, 0.4]], 929 | ImageSize->400, 930 | LabelStyle->{FontFamily -> "Times"}, 931 | Method->{ 932 | "OptimizePlotMarkers" -> True, "OptimizePlotMarkers" -> True, 933 | "CoordinatesToolOptions" -> {"DisplayFunction" -> ({ 934 | Identity[ 935 | Part[#, 1]], 936 | Identity[ 937 | Part[#, 2]]}& ), "CopiedValueFunction" -> ({ 938 | Identity[ 939 | Part[#, 1]], 940 | Identity[ 941 | Part[#, 2]]}& )}}, 942 | PlotLabel->FormBox["\"Derivative\"", TraditionalForm], 943 | PlotRange->{{0., 102.}, {-1.0221758480494478`, 1.}}, 944 | PlotRangeClipping->True, 945 | PlotRangePadding->{{ 946 | Scaled[0.02], 947 | Scaled[0.02]}, { 948 | Scaled[0.05], 949 | Scaled[0.05]}}, 950 | Ticks->{Automatic, Automatic}], 951 | TemplateBox[{"\"Exact\"", "\"TVR\""}, 952 | "LineLegend", 953 | DisplayFunction->(StyleBox[ 954 | StyleBox[ 955 | PaneBox[ 956 | TagBox[ 957 | GridBox[{{ 958 | TagBox[ 959 | GridBox[{{ 960 | GraphicsBox[{{ 961 | Directive[ 962 | EdgeForm[ 963 | Directive[ 964 | Opacity[0.3], 965 | GrayLevel[0]]], 966 | PointSize[0.5], 967 | AbsoluteThickness[1.6], 968 | RGBColor[0, 969 | NCache[ 970 | Rational[2, 3], 0.6666666666666666], 0], 971 | Opacity[0.4]], { 972 | LineBox[{{0, 40}, {40, 40}}]}}, { 973 | Directive[ 974 | EdgeForm[ 975 | Directive[ 976 | Opacity[0.3], 977 | GrayLevel[0]]], 978 | PointSize[0.5], 979 | AbsoluteThickness[1.6], 980 | RGBColor[0, 981 | NCache[ 982 | Rational[2, 3], 0.6666666666666666], 0], 983 | Opacity[0.4]], {}}}, AspectRatio -> Full, 984 | ImageSize -> {40, 40}, PlotRangePadding -> None, 985 | ImagePadding -> Automatic, 986 | BaselinePosition -> (Scaled[0.4] -> Baseline)], #}, { 987 | GraphicsBox[{{ 988 | Directive[ 989 | EdgeForm[ 990 | Directive[ 991 | Opacity[0.3], 992 | GrayLevel[0]]], 993 | PointSize[0.5], 994 | AbsoluteThickness[1.6], 995 | GrayLevel[0]], { 996 | LineBox[{{0, 40}, {40, 40}}]}}, { 997 | Directive[ 998 | EdgeForm[ 999 | Directive[ 1000 | Opacity[0.3], 1001 | GrayLevel[0]]], 1002 | PointSize[0.5], 1003 | AbsoluteThickness[1.6], 1004 | GrayLevel[0]], {}}}, AspectRatio -> Full, 1005 | ImageSize -> {40, 40}, PlotRangePadding -> None, 1006 | ImagePadding -> Automatic, 1007 | BaselinePosition -> (Scaled[0.4] -> Baseline)], #2}}, 1008 | GridBoxAlignment -> { 1009 | "Columns" -> {Center, Left}, "Rows" -> {{Baseline}}}, 1010 | AutoDelete -> False, 1011 | GridBoxDividers -> { 1012 | "Columns" -> {{False}}, "Rows" -> {{False}}}, 1013 | GridBoxItemSize -> {"Columns" -> {{All}}, "Rows" -> {{All}}}, 1014 | GridBoxSpacings -> {"Columns" -> {{0.5}}, "Rows" -> {{0.8}}}], 1015 | "Grid"]}}, 1016 | GridBoxAlignment -> {"Columns" -> {{Left}}, "Rows" -> {{Top}}}, 1017 | AutoDelete -> False, 1018 | GridBoxItemSize -> { 1019 | "Columns" -> {{Automatic}}, "Rows" -> {{Automatic}}}, 1020 | GridBoxSpacings -> {"Columns" -> {{1}}, "Rows" -> {{0}}}], 1021 | "Grid"], Alignment -> Left, AppearanceElements -> None, 1022 | ImageMargins -> {{5, 5}, {5, 5}}, ImageSizeAction -> "ResizeToFit"], 1023 | LineIndent -> 0, StripOnInput -> False], { 1024 | Directive[FontSize -> 24, FontFamily -> Automatic], FontFamily -> 1025 | "Arial"}, Background -> Automatic, StripOnInput -> False]& ), 1026 | Editable->True, 1027 | InterpretationFunction:>(RowBox[{"LineLegend", "[", 1028 | RowBox[{ 1029 | RowBox[{"{", 1030 | RowBox[{ 1031 | RowBox[{"Opacity", "[", 1032 | RowBox[{"0.4`", ",", 1033 | InterpretationBox[ 1034 | ButtonBox[ 1035 | TooltipBox[ 1036 | GraphicsBox[{{ 1037 | GrayLevel[0], 1038 | RectangleBox[{0, 0}]}, { 1039 | GrayLevel[0], 1040 | RectangleBox[{1, -1}]}, { 1041 | RGBColor[0, 1042 | Rational[2, 3], 0], 1043 | RectangleBox[{0, -1}, {2, 1}]}}, DefaultBaseStyle -> 1044 | "ColorSwatchGraphics", AspectRatio -> 1, Frame -> True, 1045 | FrameStyle -> RGBColor[0., 0.4444444444444444, 0.], 1046 | FrameTicks -> None, PlotRangePadding -> None, ImageSize -> 1047 | Dynamic[{ 1048 | Automatic, 1049 | 1.35 (CurrentValue["FontCapHeight"]/AbsoluteCurrentValue[ 1050 | Magnification])}]], 1051 | StyleBox[ 1052 | RowBox[{"RGBColor", "[", 1053 | RowBox[{"0", ",", 1054 | FractionBox["2", "3"], ",", "0"}], "]"}], NumberMarks -> 1055 | False]], Appearance -> None, BaseStyle -> {}, 1056 | BaselinePosition -> Baseline, DefaultBaseStyle -> {}, 1057 | ButtonFunction :> With[{Typeset`box$ = EvaluationBox[]}, 1058 | If[ 1059 | Not[ 1060 | AbsoluteCurrentValue["Deployed"]], 1061 | SelectionMove[Typeset`box$, All, Expression]; 1062 | FrontEnd`Private`$ColorSelectorInitialAlpha = 1; 1063 | FrontEnd`Private`$ColorSelectorInitialColor = 1064 | RGBColor[0, 1065 | Rational[2, 3], 0]; 1066 | FrontEnd`Private`$ColorSelectorUseMakeBoxes = True; 1067 | MathLink`CallFrontEnd[ 1068 | FrontEnd`AttachCell[Typeset`box$, 1069 | FrontEndResource["RGBColorValueSelector"], { 1070 | 0, {Left, Bottom}}, {Left, Top}, 1071 | "ClosingActions" -> { 1072 | "SelectionDeparture", "ParentChanged", 1073 | "EvaluatorQuit"}]]]], BaseStyle -> Inherited, Evaluator -> 1074 | Automatic, Method -> "Preemptive"], 1075 | RGBColor[0, 1076 | Rational[2, 3], 0], Editable -> False, Selectable -> 1077 | False]}], "]"}], ",", 1078 | InterpretationBox[ 1079 | ButtonBox[ 1080 | TooltipBox[ 1081 | GraphicsBox[{{ 1082 | GrayLevel[0], 1083 | RectangleBox[{0, 0}]}, { 1084 | GrayLevel[0], 1085 | RectangleBox[{1, -1}]}, { 1086 | GrayLevel[0], 1087 | RectangleBox[{0, -1}, {2, 1}]}}, DefaultBaseStyle -> 1088 | "ColorSwatchGraphics", AspectRatio -> 1, Frame -> True, 1089 | FrameStyle -> GrayLevel[0.], FrameTicks -> None, 1090 | PlotRangePadding -> None, ImageSize -> 1091 | Dynamic[{ 1092 | Automatic, 1093 | 1.35 (CurrentValue["FontCapHeight"]/AbsoluteCurrentValue[ 1094 | Magnification])}]], 1095 | StyleBox[ 1096 | RowBox[{"GrayLevel", "[", "0", "]"}], NumberMarks -> 1097 | False]], Appearance -> None, BaseStyle -> {}, 1098 | BaselinePosition -> Baseline, DefaultBaseStyle -> {}, 1099 | ButtonFunction :> With[{Typeset`box$ = EvaluationBox[]}, 1100 | If[ 1101 | Not[ 1102 | AbsoluteCurrentValue["Deployed"]], 1103 | SelectionMove[Typeset`box$, All, Expression]; 1104 | FrontEnd`Private`$ColorSelectorInitialAlpha = 1; 1105 | FrontEnd`Private`$ColorSelectorInitialColor = 1106 | GrayLevel[0]; 1107 | FrontEnd`Private`$ColorSelectorUseMakeBoxes = True; 1108 | MathLink`CallFrontEnd[ 1109 | FrontEnd`AttachCell[Typeset`box$, 1110 | FrontEndResource["GrayLevelColorValueSelector"], { 1111 | 0, {Left, Bottom}}, {Left, Top}, 1112 | "ClosingActions" -> { 1113 | "SelectionDeparture", "ParentChanged", 1114 | "EvaluatorQuit"}]]]], BaseStyle -> Inherited, Evaluator -> 1115 | Automatic, Method -> "Preemptive"], 1116 | GrayLevel[0], Editable -> False, Selectable -> False]}], 1117 | "}"}], ",", 1118 | RowBox[{"{", 1119 | RowBox[{#, ",", #2}], "}"}]}], "]"}]& )]} 1120 | }, 1121 | AutoDelete->False, 1122 | GridBoxItemSize->{"Columns" -> {{Automatic}}, "Rows" -> {{Automatic}}}], 1123 | "Grid"]], "Output", 1124 | CellChangeTimes->{ 1125 | 3.822074702082614*^9, {3.822446744728297*^9, 3.822446813446579*^9}}, 1126 | CellLabel->"Out[99]=",ExpressionUUID->"d2ebcc02-90dd-4dd5-838e-aa588b3a3233"] 1127 | }, Open ]], 1128 | 1129 | Cell[CellGroupData[{ 1130 | 1131 | Cell[BoxData[{ 1132 | RowBox[{ 1133 | RowBox[{"SetDirectory", "[", 1134 | RowBox[{"NotebookDirectory", "[", "]"}], "]"}], 1135 | ";"}], "\[IndentingNewLine]", 1136 | RowBox[{"Export", "[", 1137 | RowBox[{"\"\\"", ",", "pTVR", ",", 1138 | RowBox[{"ImageResolution", "\[Rule]", "200"}]}], "]"}]}], "Input", 1139 | CellChangeTimes->{{3.822446817698717*^9, 3.822446819918166*^9}}, 1140 | CellLabel-> 1141 | "In[100]:=",ExpressionUUID->"c828532c-83de-49d8-ad7b-c7c0a1ec1b3e"], 1142 | 1143 | Cell[BoxData["\<\"example_abs_figures/tvr.png\"\>"], "Output", 1144 | CellChangeTimes->{3.822446820529744*^9}, 1145 | CellLabel-> 1146 | "Out[101]=",ExpressionUUID->"d4c56ba0-2a35-4b4b-bc1c-7526372f9ceb"] 1147 | }, Open ]] 1148 | }, Open ]] 1149 | }, Open ]] 1150 | }, 1151 | WindowSize->{1468, 842}, 1152 | WindowMargins->{{Automatic, 83}, {Automatic, 29}}, 1153 | FrontEndVersion->"12.2 for Mac OS X x86 (64-bit) (December 12, 2020)", 1154 | StyleDefinitions->"Default.nb", 1155 | ExpressionUUID->"afa6823d-5f55-46c4-96cb-eb38744d540a" 1156 | ] 1157 | (* End of Notebook Content *) 1158 | 1159 | (* Internal cache information *) 1160 | (*CellTagsOutline 1161 | CellTagsIndex->{} 1162 | *) 1163 | (*CellTagsIndex 1164 | CellTagsIndex->{} 1165 | *) 1166 | (*NotebookFileOutline 1167 | Notebook[{ 1168 | Cell[CellGroupData[{ 1169 | Cell[580, 22, 157, 3, 69, "Chapter",ExpressionUUID->"f506f164-c0f0-463a-b883-cac9e42bcd3a"], 1170 | Cell[740, 27, 397, 8, 52, "Input",ExpressionUUID->"f3e032d6-f11e-456f-9a3e-5a51888c61c1"], 1171 | Cell[CellGroupData[{ 1172 | Cell[1162, 39, 195, 3, 30, "Input",ExpressionUUID->"3ace6ebf-5416-4142-8769-81bdbabe7877"], 1173 | Cell[1360, 44, 4565, 111, 95, "Output",ExpressionUUID->"828a75ba-f5c3-488d-9d6c-c4da9503e135"] 1174 | }, Open ]] 1175 | }, Open ]], 1176 | Cell[CellGroupData[{ 1177 | Cell[5974, 161, 217, 4, 98, "Title",ExpressionUUID->"b7f822b6-9baf-4688-a125-f8509e18632f"], 1178 | Cell[CellGroupData[{ 1179 | Cell[6216, 169, 151, 3, 69, "Chapter",ExpressionUUID->"a392b314-8eaf-4606-b7c2-350ea789a805"], 1180 | Cell[6370, 174, 2609, 64, 262, "Input",ExpressionUUID->"78221468-84d4-4909-8592-d7ee93cf5a0e"], 1181 | Cell[CellGroupData[{ 1182 | Cell[9004, 242, 2430, 59, 115, "Input",ExpressionUUID->"62725fc3-d230-4d44-a76a-5cdd913fd5a5"], 1183 | Cell[11437, 303, 13183, 279, 319, "Output",ExpressionUUID->"885b0182-66fe-4ab0-a771-e141e0dcd1b0"] 1184 | }, Open ]], 1185 | Cell[CellGroupData[{ 1186 | Cell[24657, 587, 455, 9, 52, "Input",ExpressionUUID->"46e33d7c-69c9-41a3-a24e-dac0866375f8"], 1187 | Cell[25115, 598, 188, 2, 34, "Output",ExpressionUUID->"fadf2586-c90f-413b-97df-67179f4ac5f6"] 1188 | }, Open ]], 1189 | Cell[25318, 603, 491, 14, 46, "Input",ExpressionUUID->"c10c0c2c-3206-43dc-b3ee-ecaaf9f25a37", 1190 | InitializationCell->True], 1191 | Cell[CellGroupData[{ 1192 | Cell[25834, 621, 1442, 33, 73, "Input",ExpressionUUID->"9fd65200-44e1-4e9a-9ac0-f32df45b4699"], 1193 | Cell[27279, 656, 6216, 128, 320, "Output",ExpressionUUID->"095b815a-6e19-49c7-bc5a-77ec8990fb2a"] 1194 | }, Open ]], 1195 | Cell[CellGroupData[{ 1196 | Cell[33532, 789, 459, 9, 52, "Input",ExpressionUUID->"9c11fb9a-4fab-401b-9bd9-277fddfa716e"], 1197 | Cell[33994, 800, 184, 2, 34, "Output",ExpressionUUID->"7f43dc7c-f925-42bb-b237-35e75f7bb185"] 1198 | }, Open ]] 1199 | }, Open ]], 1200 | Cell[CellGroupData[{ 1201 | Cell[34227, 808, 157, 3, 69, "Chapter",ExpressionUUID->"855ceb4e-b9fa-4d58-9014-2655a9c3de0b"], 1202 | Cell[34387, 813, 799, 20, 94, "Input",ExpressionUUID->"55c65b8f-303d-4a14-a418-a9d7e9302925"], 1203 | Cell[CellGroupData[{ 1204 | Cell[35211, 837, 1074, 28, 52, "Input",ExpressionUUID->"abb074b4-a2b2-4e8d-b794-2fe64f73809c"], 1205 | Cell[36288, 867, 11797, 258, 321, "Output",ExpressionUUID->"d2ebcc02-90dd-4dd5-838e-aa588b3a3233"] 1206 | }, Open ]], 1207 | Cell[CellGroupData[{ 1208 | Cell[48122, 1130, 453, 10, 52, "Input",ExpressionUUID->"c828532c-83de-49d8-ad7b-c7c0a1ec1b3e"], 1209 | Cell[48578, 1142, 187, 3, 34, "Output",ExpressionUUID->"d4c56ba0-2a35-4b4b-bc1c-7526372f9ceb"] 1210 | }, Open ]] 1211 | }, Open ]] 1212 | }, Open ]] 1213 | } 1214 | ] 1215 | *) 1216 | 1217 | -------------------------------------------------------------------------------- /mathematica/example_abs_figures/deriv.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smrfeld/Total-Variation-Regularization-Derivative-Python/1b8e8b92ce3f15c7eb09ba0535134ef2662fcd39/mathematica/example_abs_figures/deriv.png -------------------------------------------------------------------------------- /mathematica/example_abs_figures/signal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smrfeld/Total-Variation-Regularization-Derivative-Python/1b8e8b92ce3f15c7eb09ba0535134ef2662fcd39/mathematica/example_abs_figures/signal.png -------------------------------------------------------------------------------- /mathematica/example_abs_figures/tvr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smrfeld/Total-Variation-Regularization-Derivative-Python/1b8e8b92ce3f15c7eb09ba0535134ef2662fcd39/mathematica/example_abs_figures/tvr.png -------------------------------------------------------------------------------- /mathematica/example_damped_osc_figures/filtered_deriv.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smrfeld/Total-Variation-Regularization-Derivative-Python/1b8e8b92ce3f15c7eb09ba0535134ef2662fcd39/mathematica/example_damped_osc_figures/filtered_deriv.png -------------------------------------------------------------------------------- /mathematica/example_damped_osc_figures/noisy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smrfeld/Total-Variation-Regularization-Derivative-Python/1b8e8b92ce3f15c7eb09ba0535134ef2662fcd39/mathematica/example_damped_osc_figures/noisy.png -------------------------------------------------------------------------------- /mathematica/example_damped_osc_figures/noisy_lp_diff_lp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smrfeld/Total-Variation-Regularization-Derivative-Python/1b8e8b92ce3f15c7eb09ba0535134ef2662fcd39/mathematica/example_damped_osc_figures/noisy_lp_diff_lp.png -------------------------------------------------------------------------------- /mathematica/example_damped_osc_figures/pAve.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smrfeld/Total-Variation-Regularization-Derivative-Python/1b8e8b92ce3f15c7eb09ba0535134ef2662fcd39/mathematica/example_damped_osc_figures/pAve.png -------------------------------------------------------------------------------- /mathematica/example_damped_osc_figures/pLowPass1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smrfeld/Total-Variation-Regularization-Derivative-Python/1b8e8b92ce3f15c7eb09ba0535134ef2662fcd39/mathematica/example_damped_osc_figures/pLowPass1.png -------------------------------------------------------------------------------- /mathematica/example_damped_osc_figures/pLowPass2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smrfeld/Total-Variation-Regularization-Derivative-Python/1b8e8b92ce3f15c7eb09ba0535134ef2662fcd39/mathematica/example_damped_osc_figures/pLowPass2.png -------------------------------------------------------------------------------- /mathematica/example_damped_osc_figures/signal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smrfeld/Total-Variation-Regularization-Derivative-Python/1b8e8b92ce3f15c7eb09ba0535134ef2662fcd39/mathematica/example_damped_osc_figures/signal.png -------------------------------------------------------------------------------- /mathematica/example_damped_osc_figures/tog.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smrfeld/Total-Variation-Regularization-Derivative-Python/1b8e8b92ce3f15c7eb09ba0535134ef2662fcd39/mathematica/example_damped_osc_figures/tog.png -------------------------------------------------------------------------------- /mathematica/example_damped_osc_figures/tvr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smrfeld/Total-Variation-Regularization-Derivative-Python/1b8e8b92ce3f15c7eb09ba0535134ef2662fcd39/mathematica/example_damped_osc_figures/tvr.png -------------------------------------------------------------------------------- /mathematica/example_damped_osc_figures/tvr_filtered.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smrfeld/Total-Variation-Regularization-Derivative-Python/1b8e8b92ce3f15c7eb09ba0535134ef2662fcd39/mathematica/example_damped_osc_figures/tvr_filtered.png -------------------------------------------------------------------------------- /python/README.md: -------------------------------------------------------------------------------- 1 | # Python implementation 2 | 3 | [You can read more about this on Medium.](https://medium.com/practical-coding/how-to-differentiate-noisy-signals-2baf71b8bb65) 4 | 5 | This directory contains a very rudimentary implementation of differentiation of noisy signals with total variation regularization. 6 | 7 | **It is not suitable for large problems. See alternative method in paper in literature folder.** 8 | 9 | * `diff_tvr.py` contains the differentiation class. 10 | * `example_abs.py` contains an example for differentiation a noisy absolute value. 11 | 12 | drawing 13 | drawing -------------------------------------------------------------------------------- /python/derivative.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smrfeld/Total-Variation-Regularization-Derivative-Python/1b8e8b92ce3f15c7eb09ba0535134ef2662fcd39/python/derivative.png -------------------------------------------------------------------------------- /python/diff_tvr.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | from scipy.linalg import solve 3 | 4 | from typing import Tuple 5 | 6 | class DiffTVR: 7 | 8 | def __init__(self, n: int, dx: float): 9 | """Differentiate with TVR. 10 | 11 | Args: 12 | n (int): Number of points in data. 13 | dx (float): Spacing of data. 14 | """ 15 | self.n = n 16 | self.dx = dx 17 | 18 | self.d_mat = self._make_d_mat() 19 | self.a_mat = self._make_a_mat() 20 | self.a_mat_t = self._make_a_mat_t() 21 | 22 | def _make_d_mat(self) -> np.array: 23 | """Make differentiation matrix with central differences. NOTE: not efficient! 24 | 25 | Returns: 26 | np.array: N x N+1 27 | """ 28 | arr = np.zeros((self.n,self.n+1)) 29 | for i in range(0,self.n): 30 | arr[i,i] = -1.0 31 | arr[i,i+1] = 1.0 32 | return arr / self.dx 33 | 34 | # TODO: improve these matrix constructors 35 | def _make_a_mat(self) -> np.array: 36 | """Make integration matrix with trapezoidal rule. NOTE: not efficient! 37 | 38 | Returns: 39 | np.array: N x N+1 40 | """ 41 | arr = np.zeros((self.n+1,self.n+1)) 42 | for i in range(0,self.n+1): 43 | if i==0: 44 | continue 45 | for j in range(0,self.n+1): 46 | if j==0: 47 | arr[i,j] = 0.5 48 | elif j np.array: 56 | """Transpose of the integration matirx with trapezoidal rule. NOTE: not efficient! 57 | 58 | Returns: 59 | np.array: N+1 x N 60 | """ 61 | smat = np.ones((self.n+1,self.n)) 62 | 63 | cmat = np.zeros((self.n,self.n)) 64 | li = np.tril_indices(self.n) 65 | cmat[li] = 1.0 66 | 67 | dmat = np.diag(np.full(self.n,0.5)) 68 | 69 | vec = np.array([np.full(self.n,0.5)]) 70 | combmat = np.concatenate((vec, cmat - dmat)) 71 | 72 | return (smat - combmat) * self.dx 73 | 74 | def make_en_mat(self, deriv_curr : np.array) -> np.array: 75 | """Diffusion matrix 76 | 77 | Args: 78 | deriv_curr (np.array): Current derivative of length N+1 79 | 80 | Returns: 81 | np.array: N x N 82 | """ 83 | eps = pow(10,-6) 84 | vec = 1.0/np.sqrt(pow(self.d_mat @ deriv_curr,2) + eps) 85 | return np.diag(vec) 86 | 87 | def make_ln_mat(self, en_mat : np.array) -> np.array: 88 | """Diffusivity term 89 | 90 | Args: 91 | en_mat (np.array): Result from make_en_mat 92 | 93 | Returns: 94 | np.array: N+1 x N+1 95 | """ 96 | return self.dx * np.transpose(self.d_mat) @ en_mat @ self.d_mat 97 | 98 | def make_gn_vec(self, deriv_curr : np.array, data : np.array, alpha : float, ln_mat : np.array) -> np.array: 99 | """Negative right hand side of linear problem 100 | 101 | Args: 102 | deriv_curr (np.array): Current derivative of size N+1 103 | data (np.array): Data of size N 104 | alpha (float): Regularization parameter 105 | ln_mat (np.array): Diffusivity term from make_ln_mat 106 | 107 | Returns: 108 | np.array: Vector of length N+1 109 | """ 110 | return self.a_mat_t @ self.a_mat @ deriv_curr - self.a_mat_t @ (data - data[0]) + alpha * ln_mat @ deriv_curr 111 | 112 | def make_hn_mat(self, alpha : float, ln_mat : np.array) -> np.array: 113 | """Matrix in linear problem 114 | 115 | Args: 116 | alpha (float): Regularization parameter 117 | ln_mat (np.array): Diffusivity term from make_ln_mat 118 | 119 | Returns: 120 | np.array: N+1 x N+1 121 | """ 122 | return self.a_mat_t @ self.a_mat + alpha * ln_mat 123 | 124 | def get_deriv_tvr_update(self, data : np.array, deriv_curr : np.array, alpha : float) -> np.array: 125 | """Get the TVR update 126 | 127 | Args: 128 | data (np.array): Data of size N 129 | deriv_curr (np.array): Current deriv of size N+1 130 | alpha (float): Regularization parameter 131 | 132 | Returns: 133 | np.array: Update vector of size N+1 134 | """ 135 | 136 | n = len(data) 137 | 138 | en_mat = self.make_en_mat( 139 | deriv_curr=deriv_curr 140 | ) 141 | 142 | ln_mat = self.make_ln_mat( 143 | en_mat=en_mat 144 | ) 145 | 146 | hn_mat = self.make_hn_mat( 147 | alpha=alpha, 148 | ln_mat=ln_mat 149 | ) 150 | 151 | gn_vec = self.make_gn_vec( 152 | deriv_curr=deriv_curr, 153 | data=data, 154 | alpha=alpha, 155 | ln_mat=ln_mat 156 | ) 157 | 158 | return solve(hn_mat, -gn_vec) 159 | 160 | def get_deriv_tvr(self, 161 | data : np.array, 162 | deriv_guess : np.array, 163 | alpha : float, 164 | no_opt_steps : int, 165 | return_progress : bool = False, 166 | return_interval : int = 1 167 | ) -> Tuple[np.array,np.array]: 168 | """Get derivative via TVR over optimization steps 169 | 170 | Args: 171 | data (np.array): Data of size N 172 | deriv_guess (np.array): Guess for derivative of size N+1 173 | alpha (float): Regularization parameter 174 | no_opt_steps (int): No. opt steps to run 175 | return_progress (bool, optional): True to return derivative progress during optimization. Defaults to False. 176 | return_interval (int, optional): Interval at which to store derivative if returning. Defaults to 1. 177 | 178 | Returns: 179 | Tuple[np.array,np.array]: First is the final derivative of size N+1, second is the stored derivatives if return_progress=True of size no_opt_steps+1 x N+1, else []. 180 | """ 181 | 182 | deriv_curr = deriv_guess 183 | 184 | if return_progress: 185 | deriv_st = np.full((no_opt_steps+1, len(deriv_guess)), 0) 186 | else: 187 | deriv_st = np.array([]) 188 | 189 | for opt_step in range(0,no_opt_steps): 190 | update = self.get_deriv_tvr_update( 191 | data=data, 192 | deriv_curr=deriv_curr, 193 | alpha=alpha 194 | ) 195 | 196 | deriv_curr += update 197 | 198 | if return_progress: 199 | if opt_step % return_interval == 0: 200 | deriv_st[int(opt_step / return_interval)] = deriv_curr 201 | 202 | return (deriv_curr, deriv_st) -------------------------------------------------------------------------------- /python/example_abs.py: -------------------------------------------------------------------------------- 1 | from diff_tvr import DiffTVR 2 | import numpy as np 3 | import matplotlib.pyplot as plt 4 | 5 | from diff_tvr import * 6 | 7 | if __name__ == "__main__": 8 | 9 | # Data 10 | dx = 0.01 11 | 12 | data = [] 13 | for x in np.arange(0,1,dx): 14 | data.append(abs(x-0.5)) 15 | data = np.array(data) 16 | 17 | # True derivative 18 | deriv_true = [] 19 | for x in np.arange(0,1,dx): 20 | if x < 0.5: 21 | deriv_true.append(-1) 22 | else: 23 | deriv_true.append(1) 24 | deriv_true = np.array(deriv_true) 25 | 26 | # Add noise 27 | n = len(data) 28 | data_noisy = data + np.random.normal(0,0.05,n) 29 | 30 | # Plot true and noisy signal 31 | fig1 = plt.figure() 32 | plt.plot(data) 33 | plt.plot(data_noisy) 34 | plt.title("Signal") 35 | plt.legend(["True","Noisy"]) 36 | 37 | # Derivative with TVR 38 | diff_tvr = DiffTVR(n,dx) 39 | (deriv,_) = diff_tvr.get_deriv_tvr( 40 | data=data_noisy, 41 | deriv_guess=np.full(n+1,0.0), 42 | alpha=0.2, 43 | no_opt_steps=100 44 | ) 45 | 46 | # Plot TVR derivative 47 | fig2 = plt.figure() 48 | plt.plot(deriv_true) 49 | plt.plot(deriv) 50 | plt.title("Derivative") 51 | plt.legend(["True","TVR"]) 52 | 53 | fig1.savefig('signal.png') 54 | fig2.savefig('derivative.png') 55 | 56 | plt.show() -------------------------------------------------------------------------------- /python/signal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smrfeld/Total-Variation-Regularization-Derivative-Python/1b8e8b92ce3f15c7eb09ba0535134ef2662fcd39/python/signal.png --------------------------------------------------------------------------------