├── Ch02_Statistics ├── .vscode │ ├── .ropeproject │ │ ├── config.py │ │ └── objectdb │ └── launch.json ├── binnedhist.py ├── hist.py ├── noise.xlsx ├── noisegen.py ├── runningstats.py ├── stats.m └── stats.py ├── Ch03_ADC_DAC ├── .vscode │ └── launch.json ├── __pycache__ │ └── util.cpython-36.pyc ├── deltamod.input.txt ├── deltamod.py ├── deltamod.txt ├── deltamod.xlsx ├── dither.py ├── dither.xlsx ├── lowpass.10.txt ├── lowpass.100.txt ├── lowpass.2.txt ├── lowpass.None.txt ├── lowpass.py ├── lowpass.txt ├── lowpass.xlsx ├── signal.txt ├── util.py ├── zerohold.hold_10.txt ├── zerohold.hold_25.txt ├── zerohold.hold_3.txt ├── zerohold.hold_50.txt ├── zerohold.py └── zerohold.xlsx ├── Ch04_Software └── floats.py ├── Ch05_Linear_Systems ├── .vscode │ ├── .ropeproject │ │ └── config.py │ └── launch.json ├── __pycache__ │ ├── decompose.cpython-36.pyc │ ├── linear.cpython-36.pyc │ └── util.cpython-36.pyc ├── decompose.py ├── fsquare.m ├── linear.input.txt ├── linear.py ├── signal.txt ├── test_decompose.py ├── test_linear.py └── util.py ├── Ch06_Convolution ├── convinput.m ├── convlength.m ├── convmanualadd.m └── convoutput.m ├── Ch07_Convolution_Properties ├── discrete_derivatives.m ├── discrete_integral.m ├── impulse.py ├── noise.py ├── sine.m ├── test_impulse.py └── util.py ├── Ch08_Discrete_Fourier_Transform ├── .vscode │ └── launch.json ├── cosbasis.m ├── dft.m ├── inversedft.m ├── polrect.m ├── rectpol.m └── sinbasis.m ├── Ch12_Fast_Fourier_Transform ├── .vscode │ └── launch.json ├── fft.m ├── fft.py ├── fft_decompose.m ├── fft_run.m ├── interlace.m ├── inverse_fft.m └── negfreq.m ├── Ch23_Image_Formation ├── .vscode │ └── launch.json ├── bilinear_interpolation.py ├── eqimg.m ├── gethist.m └── lena.jpg ├── Ch24_Linear_Image_Processing ├── check.png ├── convolve.m ├── convolve2.m ├── dog.jpg ├── edgify.m ├── expand.m ├── fourier.m ├── reduce.m ├── run.m ├── sobel.m ├── tree.jpg ├── tree.m ├── valve.png └── wall2.jpg ├── Ch25_Special_Imaging_Techniques ├── closeit.m ├── convolve.m ├── cross.gif ├── dilate.m ├── erode.m ├── expand.m ├── fingerprint.gif ├── graybars.gif ├── graybars.jpg ├── invader.gif ├── lena.jpg ├── morph.m ├── morph_loop.m ├── openit.m ├── reduce.m ├── shape1.gif ├── test1.jpg ├── willbreak.m └── x.gif ├── Ch27_Data_Compression ├── README.txt ├── caesar.m ├── delta_encode.m ├── rle.m ├── rledecode.m ├── simple_rle.m ├── slowdata.m ├── slowdata.png ├── slowdata_delta.png ├── slowdata_delta_rle.png ├── test_rle.m └── uncaesar.m ├── README.md └── sandbox ├── AF.png ├── al.jpg ├── alzoomed.png ├── bad.jpg ├── bad2.jpg ├── batman.png ├── child.png ├── dark.m ├── dog.jpg ├── dots.png ├── dots_3.png ├── dots_3_grayscale.png ├── dots_3gray.gif ├── fftpulse.m ├── grad3.txt ├── gradient100px.png ├── gradient3px.png ├── grayscale_avg.m ├── grayscale_comparisons.png ├── grayscale_max.m ├── grayscale_weighted.m ├── green.jpg ├── green.m ├── imgflip.m ├── invert_colors.m ├── invlog.m ├── landsat_paris.png ├── leaf.jpg ├── lena.jpg ├── lena.png ├── lena_gimp.png ├── lena_grayscale.png ├── logtransform.m ├── mario.png ├── missing_planes ├── img_delta.m ├── parkinglot1.jpg ├── parkinglot2.jpg ├── planes1.jpg ├── planes2.jpg ├── sandy1.jpg ├── sandy2.jpg ├── trocadero1.jpg ├── trocadero2.jpg └── trocadero_master.jpg ├── night_vision.m ├── nvd.jpg ├── nvd1.png ├── park.png ├── pixelate.m ├── pixelate_avg.m ├── powerlaw.m ├── pulse.png ├── pulse2.png ├── rgb1.m ├── rotate_colors.m ├── sine_wave.png ├── slicing.m ├── slprj ├── _cgxe │ └── untitled │ │ └── untitled_Cache.mat └── _jitprj │ ├── AjCjgozthgeShqDK4BVPzC.l │ ├── AjCjgozthgeShqDK4BVPzC.mat │ └── jitEngineAccessInfo.mat ├── smbw.png ├── square_wave.png ├── toys_candy.jpg ├── tree.jpg ├── xray.png ├── zd30.jpg └── zoomit.m /Ch02_Statistics/.vscode/.ropeproject/config.py: -------------------------------------------------------------------------------- 1 | # The default ``config.py`` 2 | # flake8: noqa 3 | 4 | 5 | def set_prefs(prefs): 6 | """This function is called before opening the project""" 7 | 8 | # Specify which files and folders to ignore in the project. 9 | # Changes to ignored resources are not added to the history and 10 | # VCSs. Also they are not returned in `Project.get_files()`. 11 | # Note that ``?`` and ``*`` match all characters but slashes. 12 | # '*.pyc': matches 'test.pyc' and 'pkg/test.pyc' 13 | # 'mod*.pyc': matches 'test/mod1.pyc' but not 'mod/1.pyc' 14 | # '.svn': matches 'pkg/.svn' and all of its children 15 | # 'build/*.o': matches 'build/lib.o' but not 'build/sub/lib.o' 16 | # 'build//*.o': matches 'build/lib.o' and 'build/sub/lib.o' 17 | prefs['ignored_resources'] = ['*.pyc', '*~', '.ropeproject', 18 | '.hg', '.svn', '_svn', '.git', '.tox'] 19 | 20 | # Specifies which files should be considered python files. It is 21 | # useful when you have scripts inside your project. Only files 22 | # ending with ``.py`` are considered to be python files by 23 | # default. 24 | #prefs['python_files'] = ['*.py'] 25 | 26 | # Custom source folders: By default rope searches the project 27 | # for finding source folders (folders that should be searched 28 | # for finding modules). You can add paths to that list. Note 29 | # that rope guesses project source folders correctly most of the 30 | # time; use this if you have any problems. 31 | # The folders should be relative to project root and use '/' for 32 | # separating folders regardless of the platform rope is running on. 33 | # 'src/my_source_folder' for instance. 34 | #prefs.add('source_folders', 'src') 35 | 36 | # You can extend python path for looking up modules 37 | #prefs.add('python_path', '~/python/') 38 | 39 | # Should rope save object information or not. 40 | prefs['save_objectdb'] = True 41 | prefs['compress_objectdb'] = False 42 | 43 | # If `True`, rope analyzes each module when it is being saved. 44 | prefs['automatic_soa'] = True 45 | # The depth of calls to follow in static object analysis 46 | prefs['soa_followed_calls'] = 0 47 | 48 | # If `False` when running modules or unit tests "dynamic object 49 | # analysis" is turned off. This makes them much faster. 50 | prefs['perform_doa'] = True 51 | 52 | # Rope can check the validity of its object DB when running. 53 | prefs['validate_objectdb'] = True 54 | 55 | # How many undos to hold? 56 | prefs['max_history_items'] = 32 57 | 58 | # Shows whether to save history across sessions. 59 | prefs['save_history'] = True 60 | prefs['compress_history'] = False 61 | 62 | # Set the number spaces used for indenting. According to 63 | # :PEP:`8`, it is best to use 4 spaces. Since most of rope's 64 | # unit-tests use 4 spaces it is more reliable, too. 65 | prefs['indent_size'] = 4 66 | 67 | # Builtin and c-extension modules that are allowed to be imported 68 | # and inspected by rope. 69 | prefs['extension_modules'] = [] 70 | 71 | # Add all standard c-extensions to extension_modules list. 72 | prefs['import_dynload_stdmods'] = True 73 | 74 | # If `True` modules with syntax errors are considered to be empty. 75 | # The default value is `False`; When `False` syntax errors raise 76 | # `rope.base.exceptions.ModuleSyntaxError` exception. 77 | prefs['ignore_syntax_errors'] = False 78 | 79 | # If `True`, rope ignores unresolvable imports. Otherwise, they 80 | # appear in the importing namespace. 81 | prefs['ignore_bad_imports'] = False 82 | 83 | # If `True`, rope will insert new module imports as 84 | # `from import ` by default. 85 | prefs['prefer_module_from_imports'] = False 86 | 87 | # If `True`, rope will transform a comma list of imports into 88 | # multiple separate import statements when organizing 89 | # imports. 90 | prefs['split_imports'] = False 91 | 92 | # If `True`, rope will sort imports alphabetically by module name 93 | # instead of alphabetically by import statement, with from imports 94 | # after normal imports. 95 | prefs['sort_imports_alphabetically'] = False 96 | 97 | 98 | def project_opened(project): 99 | """This function is called after opening the project""" 100 | # Do whatever you like here! 101 | -------------------------------------------------------------------------------- /Ch02_Statistics/.vscode/.ropeproject/objectdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davecan/dspguide-code/321a36be08adea511ab728f0a9794866014c064e/Ch02_Statistics/.vscode/.ropeproject/objectdb -------------------------------------------------------------------------------- /Ch02_Statistics/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | "configurations": [ 4 | { 5 | "name": "Python", 6 | "type": "python", 7 | "request": "launch", 8 | "stopOnEntry": true, 9 | "pythonPath": "${config.python.pythonPath}", 10 | "program": "${file}", 11 | "debugOptions": [ 12 | "WaitOnAbnormalExit", 13 | "WaitOnNormalExit", 14 | "RedirectOutput" 15 | ] 16 | }, 17 | { 18 | "name": "Integrated Terminal/Console", 19 | "type": "python", 20 | "request": "launch", 21 | "stopOnEntry": true, 22 | "pythonPath": "${config.python.pythonPath}", 23 | "program": "${file}", 24 | "console": "integratedTerminal", 25 | "debugOptions": [ 26 | "WaitOnAbnormalExit", 27 | "WaitOnNormalExit" 28 | ] 29 | }, 30 | { 31 | "name": "External Terminal/Console", 32 | "type": "python", 33 | "request": "launch", 34 | "stopOnEntry": true, 35 | "pythonPath": "${config.python.pythonPath}", 36 | "program": "${file}", 37 | "console": "externalTerminal", 38 | "debugOptions": [ 39 | "WaitOnAbnormalExit", 40 | "WaitOnNormalExit" 41 | ] 42 | }, 43 | { 44 | "name": "Django", 45 | "type": "python", 46 | "request": "launch", 47 | "stopOnEntry": true, 48 | "pythonPath": "${config.python.pythonPath}", 49 | "program": "${workspaceRoot}/manage.py", 50 | "args": [ 51 | "runserver", 52 | "--noreload" 53 | ], 54 | "debugOptions": [ 55 | "WaitOnAbnormalExit", 56 | "WaitOnNormalExit", 57 | "RedirectOutput", 58 | "DjangoDebugging" 59 | ] 60 | }, 61 | { 62 | "name": "Flask", 63 | "type": "python", 64 | "request": "launch", 65 | "stopOnEntry": true, 66 | "pythonPath": "${config.python.pythonPath}", 67 | "program": "${workspaceRoot}/run.py", 68 | "args": [], 69 | "debugOptions": [ 70 | "WaitOnAbnormalExit", 71 | "WaitOnNormalExit", 72 | "RedirectOutput" 73 | ] 74 | }, 75 | { 76 | "name": "Watson", 77 | "type": "python", 78 | "request": "launch", 79 | "stopOnEntry": true, 80 | "pythonPath": "${config.python.pythonPath}", 81 | "program": "${workspaceRoot}/console.py", 82 | "args": [ 83 | "dev", 84 | "runserver", 85 | "--noreload=True" 86 | ], 87 | "debugOptions": [ 88 | "WaitOnAbnormalExit", 89 | "WaitOnNormalExit", 90 | "RedirectOutput" 91 | ] 92 | }, 93 | { 94 | "name": "Attach (Remote Debug)", 95 | "type": "python", 96 | "request": "attach", 97 | "localRoot": "${workspaceRoot}", 98 | "remoteRoot": "${workspaceRoot}", 99 | "port": 3000, 100 | "secret": "my_secret", 101 | "host": "localhost" 102 | } 103 | ] 104 | } -------------------------------------------------------------------------------- /Ch02_Statistics/binnedhist.py: -------------------------------------------------------------------------------- 1 | # Implements Table 2-4 2 | 3 | from collections import defaultdict 4 | import math 5 | 6 | class BinnedHist: 7 | # defaultdict creates a key with default value if it doesn't exist 8 | bins = defaultdict(int) 9 | num_samples = 0 10 | smallest_value = None 11 | largest_value = None 12 | bin_count = 10 13 | bin_size = 0 14 | 15 | def __init__(self, bin_count): 16 | self.bin_count = bin_count 17 | # self.bins = dict.fromkeys(range(self.bin_count)) 18 | # append a +1 key to the dict to handle roundups at the end 19 | # self.bins[len(self.bins)] = len(self.bins) 20 | 21 | def add_samples(self, X): 22 | N = len(X) 23 | self.num_samples = N 24 | self.smallest_value = X[0] 25 | self.largest_value = self.smallest_value 26 | 27 | # calculate bins 28 | for i in range(0, N): 29 | if X[i] < self.smallest_value: 30 | self.smallest_value = math.floor(X[i]) 31 | elif X[i] > self.largest_value: 32 | self.largest_value = math.ceil(X[i]) 33 | 34 | self.bin_size = int((self.largest_value / self.bin_count)) 35 | 36 | # bin it 37 | for i in range(0, N): 38 | bin_num = int(round(X[i] / self.bin_size)) 39 | self.bins[bin_num] += 1 40 | 41 | def show_hist(self): 42 | # for key in sorted(self.bins.keys()): 43 | print("bin_size: " + str(self.bin_size)) 44 | for k in range(0, self.bin_count + 1): 45 | label = str(int((self.bin_size) * k)) 46 | value = self.bins[k] if (k in self.bins) else 0 47 | print(str(k) + ": " + label + " => " + str(value)) 48 | 49 | def mean(self): 50 | # mean is broken... :( 51 | m = 0 52 | for k in self.bins.keys(): 53 | m += k * self.bins[k] 54 | return m / self.num_samples 55 | 56 | 57 | 58 | if __name__ == "__main__": 59 | import random 60 | 61 | X = [random.uniform(0, 201) for _ in range(400)] 62 | 63 | hist = BinnedHist(5) 64 | hist.add_samples(X) 65 | hist.show_hist() 66 | 67 | print() 68 | print("mean: " + str(hist.mean())) 69 | # print("variance: " + str(hist.variance())) 70 | # print("stddev: " + str(hist.stddev())) -------------------------------------------------------------------------------- /Ch02_Statistics/hist.py: -------------------------------------------------------------------------------- 1 | # Implements Table 2-3 2 | 3 | from math import sqrt 4 | from collections import defaultdict 5 | 6 | class Hist: 7 | # defaultdict creates a key with default value if it doesn't exist 8 | groups = defaultdict(int) 9 | num_samples = 0 10 | 11 | def add_samples(self, X): 12 | N = len(X) 13 | self.num_samples += N 14 | for i in range(0, N): 15 | self.groups[X[i]] += 1 16 | 17 | def show_hist(self): 18 | for key in sorted(self.groups.keys()): 19 | print(str(key) + " => " + str(self.groups[key])) 20 | 21 | def mean(self): 22 | m = 0 23 | for k in self.groups.keys(): 24 | m += k * self.groups[k] 25 | return m / self.num_samples 26 | 27 | def variance(self): 28 | v = 0 29 | the_mean = self.mean() 30 | for k in self.groups.keys(): 31 | v += self.groups[k] * ( (k - the_mean)**2 ) 32 | return v / (self.num_samples - 1) 33 | 34 | def stddev(self): 35 | return sqrt(self.variance()) 36 | 37 | 38 | 39 | if __name__ == "__main__": 40 | import random 41 | 42 | D = range(1,5) 43 | X = list(map(lambda _: random.choice(D), range(10))) 44 | 45 | print(X) 46 | hist = Hist() 47 | hist.add_samples(X) 48 | hist.show_hist() 49 | 50 | print() 51 | print("mean: " + str(hist.mean())) 52 | print("variance: " + str(hist.variance())) 53 | print("stddev: " + str(hist.stddev())) -------------------------------------------------------------------------------- /Ch02_Statistics/noise.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davecan/dspguide-code/321a36be08adea511ab728f0a9794866014c064e/Ch02_Statistics/noise.xlsx -------------------------------------------------------------------------------- /Ch02_Statistics/noisegen.py: -------------------------------------------------------------------------------- 1 | import random 2 | import statistics 3 | import math 4 | 5 | class NoiseGen: 6 | target_mean = 0 7 | target_std_dev = 0 8 | 9 | def __init__(self, mean, std_dev): 10 | self.target_mean = mean 11 | self.target_std_dev = std_dev 12 | 13 | def __get_rand(self, num): 14 | x = 0 15 | for i in range(0, num): 16 | x += random.random() 17 | return x 18 | 19 | def method_one(self, num_samples, num_rands=12): 20 | s1 = [] 21 | for i in range(0, num_samples): 22 | x = self.__get_rand(num_rands) 23 | s1.append(x) 24 | mean = sum(s1) / len(s1) 25 | s2 = [x - mean for x in s1] 26 | s3 = [x * self.target_std_dev + self.target_mean for x in s2] 27 | return s3 28 | 29 | def method_two(self, num_samples): 30 | s = [] 31 | for i in range(0, num_samples): 32 | r1 = random.random() 33 | r2 = random.random() 34 | x = math.sqrt(-2 * math.log(r1)) * math.cos(2 * math.pi * r2) 35 | x = x * self.target_std_dev + self.target_mean 36 | s.append(x) 37 | return s 38 | 39 | if __name__ == "__main__": 40 | # all values will be within 1/4 std dev of 5... 41 | NG = NoiseGen(5, 0.25) 42 | L = NG.method_one(10, 20) 43 | print(L) 44 | L = NG.method_two(10) 45 | print(L) 46 | 47 | # within 2 std dev of 3... 48 | NG = NoiseGen(3, 2) 49 | L = NG.method_one(10, 20) 50 | print(L) 51 | L = NG.method_two(10) 52 | print(L) -------------------------------------------------------------------------------- /Ch02_Statistics/runningstats.py: -------------------------------------------------------------------------------- 1 | # Implements Table 2-2 2 | 3 | from math import sqrt 4 | 5 | class RunningStats: 6 | samples = 0 7 | sum = 0 8 | sum_of_squares = 0 9 | 10 | def mean(self): 11 | return self.sum if (self.samples == 1) else self.sum / (self.samples) 12 | 13 | def variance(self): 14 | if self.samples == 1: 15 | return (self.sum_of_squares - ( (self.sum ** 2) / self.samples ) ) 16 | else: 17 | return (self.sum_of_squares - ( (self.sum ** 2) / self.samples ) ) / (self.samples - 1) 18 | 19 | def stddev(self): 20 | return sqrt(self.variance()) 21 | 22 | def add_samples(self, X): 23 | N = len(X) 24 | self.samples += N 25 | for i in range(0, N): 26 | self.sum += X[i] 27 | self.sum_of_squares += X[i] ** 2 28 | 29 | 30 | if __name__ == "__main__": 31 | X = [] 32 | for i in range(1,11): 33 | stats = RunningStats() 34 | X.append(i) 35 | stats.add_samples(X) 36 | print("samples: " + " ".join(str(x) for x in X)) 37 | print("mean: " + str(stats.mean())) 38 | print("variance: " + str(stats.variance())) 39 | print("stddev: " + str(stats.stddev())) 40 | print("") -------------------------------------------------------------------------------- /Ch02_Statistics/stats.m: -------------------------------------------------------------------------------- 1 | function mu = dsp_mean (X) 2 | N = length(X) 3 | mu = (1/N) * sum(X) 4 | endfunction 5 | 6 | function result = dsp_variance (X) 7 | N = length(X) 8 | v = 0 9 | mu = dsp_mean(X) 10 | for x = X 11 | v = v + ((x - mu) ** 2) 12 | endfor 13 | result = v / (N-1) 14 | endfunction 15 | 16 | function sigma = dsp_stddev (X) 17 | sigma = sqrt(dsp_variance(X)) 18 | endfunction -------------------------------------------------------------------------------- /Ch02_Statistics/stats.py: -------------------------------------------------------------------------------- 1 | # Implements Table 2-1 2 | 3 | from math import sqrt 4 | from math import pow 5 | 6 | def mean(X): 7 | N = len(X) 8 | m = 0 9 | for i in range(0, N): 10 | m += X[i] 11 | return m / (N) 12 | 13 | def variance(X): 14 | N = len(X) 15 | v = 0 16 | m = mean(X) 17 | for i in range(0, N): 18 | v += (X[i] - m) ** 2 19 | return v / (N-1) 20 | 21 | def stddev(X): 22 | return sqrt(variance(X)) 23 | 24 | if __name__ == "__main__": 25 | S = [1,2,3,4,5,6,7,8,9,10] 26 | print(mean(S)) 27 | print(variance(S)) 28 | print(stddev(S)) -------------------------------------------------------------------------------- /Ch03_ADC_DAC/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | "configurations": [ 4 | { 5 | "name": "Python", 6 | "type": "python", 7 | "request": "launch", 8 | "stopOnEntry": true, 9 | "pythonPath": "${config.python.pythonPath}", 10 | "program": "${file}", 11 | "debugOptions": [ 12 | "WaitOnAbnormalExit", 13 | "WaitOnNormalExit", 14 | "RedirectOutput" 15 | ] 16 | }, 17 | { 18 | "name": "Integrated Terminal/Console", 19 | "type": "python", 20 | "request": "launch", 21 | "stopOnEntry": true, 22 | "pythonPath": "${config.python.pythonPath}", 23 | "program": "${file}", 24 | "console": "integratedTerminal", 25 | "debugOptions": [ 26 | "WaitOnAbnormalExit", 27 | "WaitOnNormalExit" 28 | ] 29 | }, 30 | { 31 | "name": "External Terminal/Console", 32 | "type": "python", 33 | "request": "launch", 34 | "stopOnEntry": true, 35 | "pythonPath": "${config.python.pythonPath}", 36 | "program": "${file}", 37 | "console": "externalTerminal", 38 | "debugOptions": [ 39 | "WaitOnAbnormalExit", 40 | "WaitOnNormalExit" 41 | ] 42 | }, 43 | { 44 | "name": "Django", 45 | "type": "python", 46 | "request": "launch", 47 | "stopOnEntry": true, 48 | "pythonPath": "${config.python.pythonPath}", 49 | "program": "${workspaceRoot}/manage.py", 50 | "args": [ 51 | "runserver", 52 | "--noreload" 53 | ], 54 | "debugOptions": [ 55 | "WaitOnAbnormalExit", 56 | "WaitOnNormalExit", 57 | "RedirectOutput", 58 | "DjangoDebugging" 59 | ] 60 | }, 61 | { 62 | "name": "Flask", 63 | "type": "python", 64 | "request": "launch", 65 | "stopOnEntry": true, 66 | "pythonPath": "${config.python.pythonPath}", 67 | "program": "${workspaceRoot}/run.py", 68 | "args": [], 69 | "debugOptions": [ 70 | "WaitOnAbnormalExit", 71 | "WaitOnNormalExit", 72 | "RedirectOutput" 73 | ] 74 | }, 75 | { 76 | "name": "Watson", 77 | "type": "python", 78 | "request": "launch", 79 | "stopOnEntry": true, 80 | "pythonPath": "${config.python.pythonPath}", 81 | "program": "${workspaceRoot}/console.py", 82 | "args": [ 83 | "dev", 84 | "runserver", 85 | "--noreload=True" 86 | ], 87 | "debugOptions": [ 88 | "WaitOnAbnormalExit", 89 | "WaitOnNormalExit", 90 | "RedirectOutput" 91 | ] 92 | }, 93 | { 94 | "name": "Attach (Remote Debug)", 95 | "type": "python", 96 | "request": "attach", 97 | "localRoot": "${workspaceRoot}", 98 | "remoteRoot": "${workspaceRoot}", 99 | "port": 3000, 100 | "secret": "my_secret", 101 | "host": "localhost" 102 | } 103 | ] 104 | } -------------------------------------------------------------------------------- /Ch03_ADC_DAC/__pycache__/util.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davecan/dspguide-code/321a36be08adea511ab728f0a9794866014c064e/Ch03_ADC_DAC/__pycache__/util.cpython-36.pyc -------------------------------------------------------------------------------- /Ch03_ADC_DAC/deltamod.input.txt: -------------------------------------------------------------------------------- 1 | 0 2 | 0 3 | 0 4 | 0 5 | 0 6 | 0 7 | 0 8 | 0 9 | 0 10 | 0 11 | 8.5 12 | 8.5 13 | 8.5 14 | 8.5 15 | 8.5 16 | 8.5 17 | 8.5 18 | 8.5 19 | 8.5 20 | 8.5 21 | 8.5 22 | 8.5 23 | 8.5 24 | 8.5 25 | 8.5 26 | 8.5 27 | 8.5 28 | 8.5 29 | 8.5 30 | 8.5 31 | 8.5 32 | 8.5 33 | 8.5 34 | 8.5 35 | 8.5 36 | 8.5 37 | 8.5 38 | 8.5 39 | 8.5 40 | 8.5 41 | 8.5 42 | 8.5 43 | 8.5 44 | 8.5 45 | 8.5 46 | 8.5 47 | 8.5 48 | 8.5 49 | 8.5 50 | 8.5 51 | 8.5 52 | 7.456312688 53 | 6.731767878 54 | 5.738848727 55 | 4.517139787 56 | 5.738848727 57 | 5.738848727 58 | 6.731767878 59 | 7.456312688 60 | 6.731767878 61 | 5.738848727 62 | 4.517139787 63 | 5.738848727 64 | 5.738848727 65 | 6.731767878 66 | 7.456312688 67 | 6.731767878 68 | 5.738848727 69 | 4.517139787 70 | 5.738848727 71 | 5.738848727 72 | 6.731767878 73 | 7.456312688 74 | 6.731767878 75 | 5.738848727 76 | 4.517139787 77 | 5.738848727 78 | 5.738848727 79 | 6.731767878 80 | 7.456312688 81 | 6.731767878 82 | 5.738848727 83 | 4.517139787 84 | 5.738848727 85 | 5.738848727 86 | 6.731767878 87 | 7.456312688 88 | 6.731767878 89 | 5.738848727 90 | 4.517139787 91 | 5.738848727 92 | 5.738848727 93 | 6.731767878 94 | 7.456312688 95 | 6.731767878 96 | 5.738848727 97 | 4.517139787 98 | 5.738848727 99 | 5.738848727 100 | 6.731767878 101 | 7.456312688 102 | 6.731767878 103 | 5.738848727 -------------------------------------------------------------------------------- /Ch03_ADC_DAC/deltamod.py: -------------------------------------------------------------------------------- 1 | # Rough simulation of the delta modulation circuit in 3-16 on page 61. 2 | # This isn't exactly correct but it looks like it gets pretty close... 3 | 4 | class DeltaModulator: 5 | signal = None 6 | # latch = 0 7 | capacitor = 0 8 | latch = 0 9 | output = [] 10 | num_ones = 0 11 | num_zeros = 0 12 | 13 | def __init__(self, signal): 14 | self.signal = signal 15 | 16 | def run(self): 17 | for i in range(0, len(self.signal), 2): # simulate clock pulse on every other signal value 18 | s = float(self.signal[i]) 19 | if s > self.capacitor: 20 | self.latch += 1 21 | elif s < self.capacitor: 22 | self.latch -= 1 23 | self.output.append(self.latch) 24 | self.output.append(self.latch) # append a copy to simulate holding steady till next pulse 25 | if self.latch > self.capacitor: 26 | self.capacitor += 1 27 | elif self.latch < self.capacitor: 28 | self.capacitor -= 1 29 | 30 | 31 | 32 | if __name__ == "__main__": 33 | from util import Util 34 | U = Util("deltamod") 35 | X = U.get_signal("input") 36 | DM = DeltaModulator(X) 37 | DM.run() 38 | U.tofile(DM.output) 39 | print(DM.output) -------------------------------------------------------------------------------- /Ch03_ADC_DAC/deltamod.txt: -------------------------------------------------------------------------------- 1 | 0 2 | 0 3 | 0 4 | 0 5 | 0 6 | 0 7 | 0 8 | 0 9 | 0 10 | 0 11 | 1 12 | 1 13 | 2 14 | 2 15 | 3 16 | 3 17 | 4 18 | 4 19 | 5 20 | 5 21 | 6 22 | 6 23 | 7 24 | 7 25 | 8 26 | 8 27 | 9 28 | 9 29 | 8 30 | 8 31 | 9 32 | 9 33 | 8 34 | 8 35 | 9 36 | 9 37 | 8 38 | 8 39 | 9 40 | 9 41 | 8 42 | 8 43 | 9 44 | 9 45 | 8 46 | 8 47 | 9 48 | 9 49 | 8 50 | 8 51 | 9 52 | 9 53 | 8 54 | 8 55 | 7 56 | 7 57 | 6 58 | 6 59 | 7 60 | 7 61 | 6 62 | 6 63 | 5 64 | 5 65 | 6 66 | 6 67 | 7 68 | 7 69 | 6 70 | 6 71 | 5 72 | 5 73 | 6 74 | 6 75 | 5 76 | 5 77 | 6 78 | 6 79 | 7 80 | 7 81 | 6 82 | 6 83 | 5 84 | 5 85 | 6 86 | 6 87 | 7 88 | 7 89 | 6 90 | 6 91 | 5 92 | 5 93 | 6 94 | 6 95 | 7 96 | 7 97 | 6 98 | 6 99 | 5 100 | 5 101 | 6 102 | 6 103 | 5 104 | 5 105 | -------------------------------------------------------------------------------- /Ch03_ADC_DAC/deltamod.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davecan/dspguide-code/321a36be08adea511ab728f0a9794866014c064e/Ch03_ADC_DAC/deltamod.xlsx -------------------------------------------------------------------------------- /Ch03_ADC_DAC/dither.py: -------------------------------------------------------------------------------- 1 | from random import random 2 | 3 | def digitize(samples): 4 | L = [] 5 | for s in samples: 6 | L.append(round(s)) 7 | return L 8 | 9 | def dither(samples): 10 | L = [] 11 | for s in samples: 12 | r = 3*random() 13 | r = r if (random() % 2 == 0) else 0 - r 14 | L.append(s + r) 15 | return L 16 | 17 | 18 | 19 | if __name__ == "__main__": 20 | samples = [] 21 | for i in range(0, 20): 22 | samples.append(3000 + random()) 23 | 24 | dithered = dither(samples) 25 | digitized = digitize(samples) 26 | dithered_digitized = digitize(dithered) 27 | 28 | print("original | digitized | dithered | dithered & digitized") 29 | for i in range(0, len(samples)): 30 | print(str(samples[i]) + "\t\t" + str(digitized[i]) + "\t\t" + str(dithered[i]) + "\t\t" + str(dithered_digitized[i])) 31 | -------------------------------------------------------------------------------- /Ch03_ADC_DAC/dither.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davecan/dspguide-code/321a36be08adea511ab728f0a9794866014c064e/Ch03_ADC_DAC/dither.xlsx -------------------------------------------------------------------------------- /Ch03_ADC_DAC/lowpass.10.txt: -------------------------------------------------------------------------------- 1 | 0.13126578664620914 2 | 8.899507058991459 3 | 2.5130332918015763 4 | 8.806533784716946 5 | 2.8274933014234627 6 | 3.5181034164556104 7 | 5.90137268624183 8 | 6.388019671365965 9 | 1.0188581796165714 10 | 0.39646211603045955 11 | 3.4330186640515175 12 | 5.169765722027557 13 | 8.778408394558866 14 | 1.4127542212110349 15 | 1.3408070221685051 16 | 9.510051120528152 17 | 1.7273577641255964 18 | 0.756964042451783 19 | 5.491572757144587 20 | 3.783372425910101 21 | 9.45964287387152 22 | 8.923899028798887 23 | 4.450796752642097 24 | 2.7569900886863445 25 | 6.550059801245773 26 | 1.750104661445615 27 | 6.147256670423205 28 | 0.8794648949199618 29 | -------------------------------------------------------------------------------- /Ch03_ADC_DAC/lowpass.100.txt: -------------------------------------------------------------------------------- 1 | 90.39198607966112 2 | 48.88287389767647 3 | 99.40159949294932 4 | 39.903993083151484 5 | 88.23536072150948 6 | 84.97761225202487 7 | 16.20935593766432 8 | 0.13126578664620914 9 | 16.71397021551403 10 | 8.899507058991459 11 | 2.5130332918015763 12 | 10.680848157316525 13 | 73.83618913756358 14 | 12.396265582261414 15 | 32.6734889135781 16 | 37.346102705873605 17 | 47.298479292841186 18 | 68.04320363427455 19 | 94.14460381271132 20 | 61.01300161800831 21 | 39.84595818670506 22 | 8.806533784716946 23 | 24.882243651640863 24 | 91.33670093937104 25 | 90.1978043393228 26 | 69.34567606559304 27 | 97.49666581864896 28 | 20.29100272692786 29 | 15.216314616184844 30 | 33.50372600486184 31 | 33.0202433720944 32 | 2.8274933014234627 33 | 66.0050296442796 34 | 82.49401773141165 35 | 29.97849969737483 36 | 50.581572960252394 37 | 20.359111787809084 38 | 53.90301547602551 39 | 44.41683724014388 40 | 98.33535781398308 41 | 55.361417875811895 42 | 91.88253377260752 43 | 69.29975713496783 44 | 19.68394188770451 45 | 45.66897753512369 46 | 83.22726932969826 47 | 79.65569825391667 48 | 29.598809749953908 49 | 3.5181034164556104 50 | 5.90137268624183 51 | 65.4161583919214 52 | 65.61935604400308 53 | 54.87033295071685 54 | 60.229084557233385 55 | 81.70429023895416 56 | 6.388019671365965 57 | 27.615164697671936 58 | 49.11198923598216 59 | 12.107640709278765 60 | 93.7636498697947 61 | 47.20006117873908 62 | 25.414497308873983 63 | 1.0188581796165714 64 | 58.782241411235546 65 | 71.66256967615571 66 | 79.030362393752 67 | 43.3926547852176 68 | 30.031741538250536 69 | 92.29235095430084 70 | 15.79127927168636 71 | 13.730970484815824 72 | 99.71932876553487 73 | 38.316922583825274 74 | 11.825482300973274 75 | 0.39646211603045955 76 | 75.53596275062918 77 | 3.4330186640515175 78 | 82.16468396115891 79 | 60.348076381199625 80 | 5.169765722027557 81 | 51.00622178281128 82 | 14.6750195142609 83 | 21.94602302864412 84 | 39.79214101453407 85 | 45.62874545572487 86 | 47.23251646062891 87 | 29.813395818680085 88 | 42.55488558753195 89 | 12.91128970779002 90 | 96.03889649534524 91 | 8.778408394558866 92 | 99.46028756358685 93 | 13.056092635020267 94 | 76.74514047950639 95 | 23.59371158137293 96 | 75.44783186979238 97 | 60.41089226379388 98 | 14.377403404663427 99 | 35.07723750566692 100 | 52.346217321307456 101 | 37.92232254864912 102 | 35.7202907802224 103 | 1.4127542212110349 104 | 17.36769906678736 105 | 99.81673019205185 106 | 94.83098587024593 107 | 52.62907405344445 108 | 16.829023935851286 109 | 21.33066684449587 110 | 46.07871465366453 111 | 91.23443526569791 112 | 78.16244401552439 113 | 1.3408070221685051 114 | 25.755890703096238 115 | 55.835482038777116 116 | 51.55950428360339 117 | 9.510051120528152 118 | 65.10786168687356 119 | 60.86514607008295 120 | 1.7273577641255964 121 | 37.39008246019681 122 | 72.72973486311663 123 | 86.52773248697122 124 | 26.10152759125444 125 | 84.57753598700151 126 | 15.6032520806877 127 | 43.79237340586755 128 | 99.54836449937197 129 | 18.34256584305956 130 | 39.58829194684418 131 | 59.78060363460759 132 | 41.47029385278913 133 | 42.343070699925086 134 | 55.437087238142865 135 | 57.14897092237808 136 | 34.51716025580024 137 | 52.16058995378045 138 | 82.18199602227969 139 | 10.973455833763413 140 | 58.23188758028292 141 | 0.756964042451783 142 | 5.491572757144587 143 | 60.63604479069493 144 | 56.82014713767996 145 | 75.40942883085087 146 | 83.75976749071349 147 | 28.11157983714159 148 | 3.783372425910101 149 | 9.45964287387152 150 | 28.90588238285077 151 | 38.52885270793219 152 | 8.923899028798887 153 | 98.40214512605232 154 | 44.827998023513494 155 | 4.450796752642097 156 | 42.39029853479982 157 | 11.25490928234468 158 | 66.98590159262534 159 | 26.369429476213273 160 | 47.95048375363452 161 | 59.38032356945282 162 | 2.7569900886863445 163 | 69.38026127121783 164 | 74.02616061977538 165 | 11.644057575480648 166 | 46.61867522085664 167 | 52.60313222283213 168 | 14.465746792287163 169 | 84.35254781846334 170 | 71.04005182175715 171 | 6.550059801245773 172 | 26.510727438358675 173 | 42.11313621038199 174 | 58.643427336119345 175 | 38.09087650591367 176 | 41.976745333166306 177 | 30.902126808018213 178 | 1.750104661445615 179 | 58.480004225098156 180 | 6.147256670423205 181 | 82.70944094177058 182 | 82.26124859602596 183 | 19.96977449131617 184 | 21.315104700048895 185 | 67.83522291312669 186 | 64.69972498241746 187 | 23.140462390911097 188 | 21.291146597631567 189 | 40.79000564798738 190 | 54.03225496828368 191 | 13.855849743391873 192 | 86.53749546553153 193 | 0.8794648949199618 194 | 30.870343289521937 195 | 84.80959093168345 196 | -------------------------------------------------------------------------------- /Ch03_ADC_DAC/lowpass.2.txt: -------------------------------------------------------------------------------- 1 | 0.13126578664620914 2 | 1.0188581796165714 3 | 0.39646211603045955 4 | 1.4127542212110349 5 | 1.3408070221685051 6 | 1.7273577641255964 7 | 0.756964042451783 8 | 1.750104661445615 9 | 0.8794648949199618 10 | -------------------------------------------------------------------------------- /Ch03_ADC_DAC/lowpass.None.txt: -------------------------------------------------------------------------------- 1 | 0.13126578664620914 2 | 8.899507058991459 3 | 2.5130332918015763 4 | 8.806533784716946 5 | 2.8274933014234627 6 | 3.5181034164556104 7 | 5.90137268624183 8 | 6.388019671365965 9 | 1.0188581796165714 10 | 0.39646211603045955 11 | 3.4330186640515175 12 | 5.169765722027557 13 | 8.778408394558866 14 | 1.4127542212110349 15 | 1.3408070221685051 16 | 9.510051120528152 17 | 1.7273577641255964 18 | 0.756964042451783 19 | 5.491572757144587 20 | 3.783372425910101 21 | 9.45964287387152 22 | 8.923899028798887 23 | 4.450796752642097 24 | 2.7569900886863445 25 | 6.550059801245773 26 | 1.750104661445615 27 | 6.147256670423205 28 | 0.8794648949199618 29 | -------------------------------------------------------------------------------- /Ch03_ADC_DAC/lowpass.py: -------------------------------------------------------------------------------- 1 | def lowpass(signal, stopband): 2 | return [k for k in signal if float(k) <= stopband] 3 | 4 | if __name__ == "__main__": 5 | from util import Util 6 | U = Util("lowpass") 7 | X = U.get_signal() 8 | U.tofile(lowpass(X, 2), 2) 9 | U.tofile(lowpass(X, 10), 10) 10 | U.tofile(lowpass(X, 100), 100) 11 | print("DONE!") -------------------------------------------------------------------------------- /Ch03_ADC_DAC/lowpass.txt: -------------------------------------------------------------------------------- 1 | 0.13126578664620914 2 | 8.899507058991459 3 | 2.5130332918015763 4 | 8.806533784716946 5 | 2.8274933014234627 6 | 3.5181034164556104 7 | 5.90137268624183 8 | 6.388019671365965 9 | 1.0188581796165714 10 | 0.39646211603045955 11 | 3.4330186640515175 12 | 5.169765722027557 13 | 8.778408394558866 14 | 1.4127542212110349 15 | 1.3408070221685051 16 | 9.510051120528152 17 | 1.7273577641255964 18 | 0.756964042451783 19 | 5.491572757144587 20 | 3.783372425910101 21 | 9.45964287387152 22 | 8.923899028798887 23 | 4.450796752642097 24 | 2.7569900886863445 25 | 6.550059801245773 26 | 1.750104661445615 27 | 6.147256670423205 28 | 0.8794648949199618 29 | -------------------------------------------------------------------------------- /Ch03_ADC_DAC/lowpass.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davecan/dspguide-code/321a36be08adea511ab728f0a9794866014c064e/Ch03_ADC_DAC/lowpass.xlsx -------------------------------------------------------------------------------- /Ch03_ADC_DAC/signal.txt: -------------------------------------------------------------------------------- 1 | 90.39198607966112 2 | 48.88287389767647 3 | 178.43067136890068 4 | 137.22499604457587 5 | 99.40159949294932 6 | 39.903993083151484 7 | 88.23536072150948 8 | 111.97236870332354 9 | 100.808941994621 10 | 84.97761225202487 11 | 146.42804355391564 12 | 102.14241990061026 13 | 152.92667080838473 14 | 16.20935593766432 15 | 0.13126578664620914 16 | 16.71397021551403 17 | 8.899507058991459 18 | 2.5130332918015763 19 | 10.680848157316525 20 | 180.55220384439957 21 | 133.80863175048722 22 | 73.83618913756358 23 | 144.4669006719188 24 | 194.9307609824826 25 | 176.28509873983333 26 | 12.396265582261414 27 | 177.4354548229892 28 | 32.6734889135781 29 | 37.346102705873605 30 | 166.06977295305083 31 | 108.91878412353557 32 | 47.298479292841186 33 | 137.38619378735643 34 | 68.04320363427455 35 | 198.92097358933103 36 | 94.14460381271132 37 | 143.49043756444001 38 | 101.90366727265608 39 | 61.01300161800831 40 | 175.0555100166322 41 | 156.4415040578073 42 | 138.6564844509553 43 | 154.6056753354556 44 | 159.0976259006465 45 | 39.84595818670506 46 | 171.02256745733993 47 | 8.806533784716946 48 | 24.882243651640863 49 | 168.94305338741356 50 | 91.33670093937104 51 | 152.14705724385098 52 | 167.52070526698512 53 | 150.56001451495976 54 | 114.6765424424098 55 | 90.1978043393228 56 | 69.34567606559304 57 | 97.49666581864896 58 | 105.07957920038325 59 | 106.60791452535055 60 | 20.29100272692786 61 | 179.42391359970622 62 | 15.216314616184844 63 | 165.26580713411425 64 | 166.14627083291614 65 | 33.50372600486184 66 | 145.0786995000876 67 | 33.0202433720944 68 | 100.52701370561262 69 | 2.8274933014234627 70 | 155.684293452835 71 | 66.0050296442796 72 | 195.73131647002063 73 | 82.49401773141165 74 | 189.8802874211451 75 | 29.97849969737483 76 | 155.48755892059225 77 | 50.581572960252394 78 | 20.359111787809084 79 | 197.7801290219567 80 | 53.90301547602551 81 | 44.41683724014388 82 | 98.33535781398308 83 | 166.4467305186137 84 | 55.361417875811895 85 | 176.80368826806222 86 | 158.87018103707223 87 | 173.30137300964833 88 | 116.65764517737033 89 | 91.88253377260752 90 | 189.77788063048214 91 | 149.34177216218723 92 | 179.06190989074653 93 | 69.29975713496783 94 | 187.4700896217517 95 | 19.68394188770451 96 | 137.35952781042624 97 | 45.66897753512369 98 | 127.24722859223876 99 | 83.22726932969826 100 | 149.5115486029058 101 | 79.65569825391667 102 | 189.97090060363826 103 | 181.60987520354635 104 | 29.598809749953908 105 | 103.25647386914078 106 | 3.5181034164556104 107 | 5.90137268624183 108 | 65.4161583919214 109 | 65.61935604400308 110 | 54.87033295071685 111 | 60.229084557233385 112 | 81.70429023895416 113 | 6.388019671365965 114 | 27.615164697671936 115 | 149.36481677425147 116 | 49.11198923598216 117 | 12.107640709278765 118 | 93.7636498697947 119 | 47.20006117873908 120 | 106.30245070919065 121 | 143.24098718904241 122 | 200.9076877925234 123 | 106.49637566216654 124 | 25.414497308873983 125 | 1.0188581796165714 126 | 177.5708719501884 127 | 180.99094370355314 128 | 102.46655883116195 129 | 58.782241411235546 130 | 71.66256967615571 131 | 79.030362393752 132 | 43.3926547852176 133 | 144.06183102250773 134 | 102.62550358903285 135 | 30.031741538250536 136 | 92.29235095430084 137 | 15.79127927168636 138 | 147.20463212396712 139 | 13.730970484815824 140 | 188.99248197470763 141 | 154.14732583602648 142 | 99.71932876553487 143 | 38.316922583825274 144 | 11.825482300973274 145 | 122.8658813688971 146 | 0.39646211603045955 147 | 180.2019742964509 148 | 158.21106284386562 149 | 75.53596275062918 150 | 120.95230011198113 151 | 109.25381137314407 152 | 3.4330186640515175 153 | 82.16468396115891 154 | 195.0644178115306 155 | 169.74694131288953 156 | 197.04737653925991 157 | 60.348076381199625 158 | 162.28827113945314 159 | 182.64969204071997 160 | 111.37667548341724 161 | 5.169765722027557 162 | 178.45918680527154 163 | 155.05527145335824 164 | 144.24761768004961 165 | 51.00622178281128 166 | 14.6750195142609 167 | 112.63347144861982 168 | 191.4818529124658 169 | 21.94602302864412 170 | 191.01387821005613 171 | 170.5886566343436 172 | 39.79214101453407 173 | 195.5068562441998 174 | 45.62874545572487 175 | 146.3507764350864 176 | 122.19260717980505 177 | 141.89536821047164 178 | 184.7615773602102 179 | 141.78595106808362 180 | 47.23251646062891 181 | 192.56158705507482 182 | 194.67309094859726 183 | 29.813395818680085 184 | 144.53432093058586 185 | 42.55488558753195 186 | 132.6761786003157 187 | 185.75332079862287 188 | 12.91128970779002 189 | 101.77639634615183 190 | 186.25990461956633 191 | 125.10331395400772 192 | 127.38435311388403 193 | 96.03889649534524 194 | 142.91422226826685 195 | 8.778408394558866 196 | 99.46028756358685 197 | 189.04500320901616 198 | 13.056092635020267 199 | 113.36750920866615 200 | 76.74514047950639 201 | 167.66488491173683 202 | 120.2257699515811 203 | 131.30464832463014 204 | 23.59371158137293 205 | 75.44783186979238 206 | 60.41089226379388 207 | 188.58231573484872 208 | 14.377403404663427 209 | 35.07723750566692 210 | 190.40924802547386 211 | 52.346217321307456 212 | 136.91897919740694 213 | 115.76917373623256 214 | 137.5854312534084 215 | 123.84804791955564 216 | 109.98300206096191 217 | 179.33991780132052 218 | 37.92232254864912 219 | 157.1562062348065 220 | 109.23135625190022 221 | 172.66774006065995 222 | 139.7718816025165 223 | 35.7202907802224 224 | 146.5508906171178 225 | 1.4127542212110349 226 | 17.36769906678736 227 | 156.15178577041917 228 | 154.4541546842112 229 | 99.81673019205185 230 | 94.83098587024593 231 | 52.62907405344445 232 | 16.829023935851286 233 | 21.33066684449587 234 | 46.07871465366453 235 | 91.23443526569791 236 | 194.79667053466756 237 | 78.16244401552439 238 | 189.83107994821663 239 | 117.37765377982221 240 | 113.27642242130793 241 | 170.2574324947601 242 | 196.53283139691823 243 | 1.3408070221685051 244 | 152.97855781874873 245 | 25.755890703096238 246 | 167.8640870350067 247 | 55.835482038777116 248 | 108.90603538978614 249 | 51.55950428360339 250 | 9.510051120528152 251 | 65.10786168687356 252 | 60.86514607008295 253 | 106.07405102380682 254 | 188.19439878112632 255 | 133.33667325725548 256 | 1.7273577641255964 257 | 37.39008246019681 258 | 164.5582101078482 259 | 159.39425535571104 260 | 72.72973486311663 261 | 112.88502305035756 262 | 162.17740298296292 263 | 86.52773248697122 264 | 26.10152759125444 265 | 84.57753598700151 266 | 15.6032520806877 267 | 117.90910583415138 268 | 119.17722065505578 269 | 43.79237340586755 270 | 126.51396843727278 271 | 172.22340848987136 272 | 99.54836449937197 273 | 18.34256584305956 274 | 39.58829194684418 275 | 154.82520395039182 276 | 59.78060363460759 277 | 41.47029385278913 278 | 162.11781748358015 279 | 133.46236358861643 280 | 42.343070699925086 281 | 115.97084855333034 282 | 154.64525307275244 283 | 103.42995346025519 284 | 55.437087238142865 285 | 106.16658576551278 286 | 57.14897092237808 287 | 187.8274692737202 288 | 164.40767517209372 289 | 34.51716025580024 290 | 142.5746982338419 291 | 52.16058995378045 292 | 82.18199602227969 293 | 10.973455833763413 294 | 58.23188758028292 295 | 151.49853926495322 296 | 0.756964042451783 297 | 138.73126592571802 298 | 5.491572757144587 299 | 60.63604479069493 300 | 56.82014713767996 301 | 75.40942883085087 302 | 83.75976749071349 303 | 120.73526692900741 304 | 28.11157983714159 305 | 3.783372425910101 306 | 9.45964287387152 307 | 121.8368056516859 308 | 28.90588238285077 309 | 38.52885270793219 310 | 200.92168918323205 311 | 155.95530356045361 312 | 165.4115662438567 313 | 8.923899028798887 314 | 98.40214512605232 315 | 148.67676557929394 316 | 44.827998023513494 317 | 4.450796752642097 318 | 42.39029853479982 319 | 11.25490928234468 320 | 196.23220888869463 321 | 181.7769775564421 322 | 171.95321737668579 323 | 167.16940628197162 324 | 177.62054561819318 325 | 66.98590159262534 326 | 172.24711893365608 327 | 26.369429476213273 328 | 173.07760897907602 329 | 152.2303305294409 330 | 125.74711414821775 331 | 47.95048375363452 332 | 190.49779373863734 333 | 179.40660273166702 334 | 169.17833089430076 335 | 59.38032356945282 336 | 146.21439001904227 337 | 2.7569900886863445 338 | 103.11633748136057 339 | 69.38026127121783 340 | 74.02616061977538 341 | 174.5828729051154 342 | 11.644057575480648 343 | 46.61867522085664 344 | 52.60313222283213 345 | 14.465746792287163 346 | 186.12181160576694 347 | 100.39304767503756 348 | 84.35254781846334 349 | 71.04005182175715 350 | 110.22776652222322 351 | 177.2145530200865 352 | 116.12644114966251 353 | 182.63793548090038 354 | 107.34610704853738 355 | 6.550059801245773 356 | 105.07756666830436 357 | 26.510727438358675 358 | 131.20803037936793 359 | 42.11313621038199 360 | 58.643427336119345 361 | 125.99350842918905 362 | 38.09087650591367 363 | 41.976745333166306 364 | 159.7507127079793 365 | 30.902126808018213 366 | 112.1022040205721 367 | 188.97048229021374 368 | 138.42446441537524 369 | 1.750104661445615 370 | 58.480004225098156 371 | 117.23663458840394 372 | 6.147256670423205 373 | 82.70944094177058 374 | 118.72657725148254 375 | 169.45523859117708 376 | 82.26124859602596 377 | 19.96977449131617 378 | 112.82924927996248 379 | 21.315104700048895 380 | 156.88701115240528 381 | 67.83522291312669 382 | 193.21889303456896 383 | 148.45771876279633 384 | 64.69972498241746 385 | 23.140462390911097 386 | 143.3143847889824 387 | 175.72531539297418 388 | 21.291146597631567 389 | 40.79000564798738 390 | 54.03225496828368 391 | 13.855849743391873 392 | 140.7555458756788 393 | 149.9932348942297 394 | 161.16388703401526 395 | 86.53749546553153 396 | 0.8794648949199618 397 | 192.86560249531513 398 | 102.0293053676415 399 | 30.870343289521937 400 | 84.80959093168345 401 | -------------------------------------------------------------------------------- /Ch03_ADC_DAC/util.py: -------------------------------------------------------------------------------- 1 | class Util: 2 | module_name = None 3 | 4 | def __init__(self, module_name): 5 | self.module_name = module_name 6 | 7 | def get_signal(self, filename=None): 8 | if (filename == None): 9 | name = "signal.txt" 10 | else: 11 | name = "%s.%s.txt" % (self.module_name, filename) 12 | with open(name) as f: 13 | L = f.read().splitlines() 14 | return L 15 | 16 | def tofile(self, L): 17 | f = open("%s.txt" % self.module_name, "w") 18 | for x in L: 19 | f.write("%s \n" % x) 20 | f.close() 21 | 22 | def tofile(self, L, filename=None): 23 | if (filename == None): 24 | name = "%s.txt" % self.module_name 25 | else: 26 | name = "%s.%s.txt" % (self.module_name, filename) 27 | with open(name, "w") as f: 28 | for x in L: 29 | f.write("%s \n" % x) 30 | # f = open(name, "w") 31 | # for x in L: 32 | # f.write("%s \n" % x) 33 | # f.close() -------------------------------------------------------------------------------- /Ch03_ADC_DAC/zerohold.hold_10.txt: -------------------------------------------------------------------------------- 1 | 90.39198607966112 2 | 90.39198607966112 3 | 90.39198607966112 4 | 90.39198607966112 5 | 90.39198607966112 6 | 90.39198607966112 7 | 90.39198607966112 8 | 90.39198607966112 9 | 90.39198607966112 10 | 90.39198607966112 11 | 146.42804355391564 12 | 146.42804355391564 13 | 146.42804355391564 14 | 146.42804355391564 15 | 146.42804355391564 16 | 146.42804355391564 17 | 146.42804355391564 18 | 146.42804355391564 19 | 146.42804355391564 20 | 146.42804355391564 21 | 133.80863175048722 22 | 133.80863175048722 23 | 133.80863175048722 24 | 133.80863175048722 25 | 133.80863175048722 26 | 133.80863175048722 27 | 133.80863175048722 28 | 133.80863175048722 29 | 133.80863175048722 30 | 133.80863175048722 31 | 108.91878412353557 32 | 108.91878412353557 33 | 108.91878412353557 34 | 108.91878412353557 35 | 108.91878412353557 36 | 108.91878412353557 37 | 108.91878412353557 38 | 108.91878412353557 39 | 108.91878412353557 40 | 108.91878412353557 41 | 156.4415040578073 42 | 156.4415040578073 43 | 156.4415040578073 44 | 156.4415040578073 45 | 156.4415040578073 46 | 156.4415040578073 47 | 156.4415040578073 48 | 156.4415040578073 49 | 156.4415040578073 50 | 156.4415040578073 51 | 152.14705724385098 52 | 152.14705724385098 53 | 152.14705724385098 54 | 152.14705724385098 55 | 152.14705724385098 56 | 152.14705724385098 57 | 152.14705724385098 58 | 152.14705724385098 59 | 152.14705724385098 60 | 152.14705724385098 61 | 179.42391359970622 62 | 179.42391359970622 63 | 179.42391359970622 64 | 179.42391359970622 65 | 179.42391359970622 66 | 179.42391359970622 67 | 179.42391359970622 68 | 179.42391359970622 69 | 179.42391359970622 70 | 179.42391359970622 71 | 66.0050296442796 72 | 66.0050296442796 73 | 66.0050296442796 74 | 66.0050296442796 75 | 66.0050296442796 76 | 66.0050296442796 77 | 66.0050296442796 78 | 66.0050296442796 79 | 66.0050296442796 80 | 66.0050296442796 81 | 44.41683724014388 82 | 44.41683724014388 83 | 44.41683724014388 84 | 44.41683724014388 85 | 44.41683724014388 86 | 44.41683724014388 87 | 44.41683724014388 88 | 44.41683724014388 89 | 44.41683724014388 90 | 44.41683724014388 91 | 149.34177216218723 92 | 149.34177216218723 93 | 149.34177216218723 94 | 149.34177216218723 95 | 149.34177216218723 96 | 149.34177216218723 97 | 149.34177216218723 98 | 149.34177216218723 99 | 149.34177216218723 100 | 149.34177216218723 101 | 79.65569825391667 102 | 79.65569825391667 103 | 79.65569825391667 104 | 79.65569825391667 105 | 79.65569825391667 106 | 79.65569825391667 107 | 79.65569825391667 108 | 79.65569825391667 109 | 79.65569825391667 110 | 79.65569825391667 111 | 60.229084557233385 112 | 60.229084557233385 113 | 60.229084557233385 114 | 60.229084557233385 115 | 60.229084557233385 116 | 60.229084557233385 117 | 60.229084557233385 118 | 60.229084557233385 119 | 60.229084557233385 120 | 60.229084557233385 121 | 143.24098718904241 122 | 143.24098718904241 123 | 143.24098718904241 124 | 143.24098718904241 125 | 143.24098718904241 126 | 143.24098718904241 127 | 143.24098718904241 128 | 143.24098718904241 129 | 143.24098718904241 130 | 143.24098718904241 131 | 79.030362393752 132 | 79.030362393752 133 | 79.030362393752 134 | 79.030362393752 135 | 79.030362393752 136 | 79.030362393752 137 | 79.030362393752 138 | 79.030362393752 139 | 79.030362393752 140 | 79.030362393752 141 | 154.14732583602648 142 | 154.14732583602648 143 | 154.14732583602648 144 | 154.14732583602648 145 | 154.14732583602648 146 | 154.14732583602648 147 | 154.14732583602648 148 | 154.14732583602648 149 | 154.14732583602648 150 | 154.14732583602648 151 | 109.25381137314407 152 | 109.25381137314407 153 | 109.25381137314407 154 | 109.25381137314407 155 | 109.25381137314407 156 | 109.25381137314407 157 | 109.25381137314407 158 | 109.25381137314407 159 | 109.25381137314407 160 | 109.25381137314407 161 | 5.169765722027557 162 | 5.169765722027557 163 | 5.169765722027557 164 | 5.169765722027557 165 | 5.169765722027557 166 | 5.169765722027557 167 | 5.169765722027557 168 | 5.169765722027557 169 | 5.169765722027557 170 | 5.169765722027557 171 | 170.5886566343436 172 | 170.5886566343436 173 | 170.5886566343436 174 | 170.5886566343436 175 | 170.5886566343436 176 | 170.5886566343436 177 | 170.5886566343436 178 | 170.5886566343436 179 | 170.5886566343436 180 | 170.5886566343436 181 | 192.56158705507482 182 | 192.56158705507482 183 | 192.56158705507482 184 | 192.56158705507482 185 | 192.56158705507482 186 | 192.56158705507482 187 | 192.56158705507482 188 | 192.56158705507482 189 | 192.56158705507482 190 | 192.56158705507482 191 | 125.10331395400772 192 | 125.10331395400772 193 | 125.10331395400772 194 | 125.10331395400772 195 | 125.10331395400772 196 | 125.10331395400772 197 | 125.10331395400772 198 | 125.10331395400772 199 | 125.10331395400772 200 | 125.10331395400772 201 | 167.66488491173683 202 | 167.66488491173683 203 | 167.66488491173683 204 | 167.66488491173683 205 | 167.66488491173683 206 | 167.66488491173683 207 | 167.66488491173683 208 | 167.66488491173683 209 | 167.66488491173683 210 | 167.66488491173683 211 | 52.346217321307456 212 | 52.346217321307456 213 | 52.346217321307456 214 | 52.346217321307456 215 | 52.346217321307456 216 | 52.346217321307456 217 | 52.346217321307456 218 | 52.346217321307456 219 | 52.346217321307456 220 | 52.346217321307456 221 | 172.66774006065995 222 | 172.66774006065995 223 | 172.66774006065995 224 | 172.66774006065995 225 | 172.66774006065995 226 | 172.66774006065995 227 | 172.66774006065995 228 | 172.66774006065995 229 | 172.66774006065995 230 | 172.66774006065995 231 | 52.62907405344445 232 | 52.62907405344445 233 | 52.62907405344445 234 | 52.62907405344445 235 | 52.62907405344445 236 | 52.62907405344445 237 | 52.62907405344445 238 | 52.62907405344445 239 | 52.62907405344445 240 | 52.62907405344445 241 | 170.2574324947601 242 | 170.2574324947601 243 | 170.2574324947601 244 | 170.2574324947601 245 | 170.2574324947601 246 | 170.2574324947601 247 | 170.2574324947601 248 | 170.2574324947601 249 | 170.2574324947601 250 | 170.2574324947601 251 | 65.10786168687356 252 | 65.10786168687356 253 | 65.10786168687356 254 | 65.10786168687356 255 | 65.10786168687356 256 | 65.10786168687356 257 | 65.10786168687356 258 | 65.10786168687356 259 | 65.10786168687356 260 | 65.10786168687356 261 | 112.88502305035756 262 | 112.88502305035756 263 | 112.88502305035756 264 | 112.88502305035756 265 | 112.88502305035756 266 | 112.88502305035756 267 | 112.88502305035756 268 | 112.88502305035756 269 | 112.88502305035756 270 | 112.88502305035756 271 | 172.22340848987136 272 | 172.22340848987136 273 | 172.22340848987136 274 | 172.22340848987136 275 | 172.22340848987136 276 | 172.22340848987136 277 | 172.22340848987136 278 | 172.22340848987136 279 | 172.22340848987136 280 | 172.22340848987136 281 | 115.97084855333034 282 | 115.97084855333034 283 | 115.97084855333034 284 | 115.97084855333034 285 | 115.97084855333034 286 | 115.97084855333034 287 | 115.97084855333034 288 | 115.97084855333034 289 | 115.97084855333034 290 | 115.97084855333034 291 | 52.16058995378045 292 | 52.16058995378045 293 | 52.16058995378045 294 | 52.16058995378045 295 | 52.16058995378045 296 | 52.16058995378045 297 | 52.16058995378045 298 | 52.16058995378045 299 | 52.16058995378045 300 | 52.16058995378045 301 | 75.40942883085087 302 | 75.40942883085087 303 | 75.40942883085087 304 | 75.40942883085087 305 | 75.40942883085087 306 | 75.40942883085087 307 | 75.40942883085087 308 | 75.40942883085087 309 | 75.40942883085087 310 | 75.40942883085087 311 | 155.95530356045361 312 | 155.95530356045361 313 | 155.95530356045361 314 | 155.95530356045361 315 | 155.95530356045361 316 | 155.95530356045361 317 | 155.95530356045361 318 | 155.95530356045361 319 | 155.95530356045361 320 | 155.95530356045361 321 | 181.7769775564421 322 | 181.7769775564421 323 | 181.7769775564421 324 | 181.7769775564421 325 | 181.7769775564421 326 | 181.7769775564421 327 | 181.7769775564421 328 | 181.7769775564421 329 | 181.7769775564421 330 | 181.7769775564421 331 | 47.95048375363452 332 | 47.95048375363452 333 | 47.95048375363452 334 | 47.95048375363452 335 | 47.95048375363452 336 | 47.95048375363452 337 | 47.95048375363452 338 | 47.95048375363452 339 | 47.95048375363452 340 | 47.95048375363452 341 | 174.5828729051154 342 | 174.5828729051154 343 | 174.5828729051154 344 | 174.5828729051154 345 | 174.5828729051154 346 | 174.5828729051154 347 | 174.5828729051154 348 | 174.5828729051154 349 | 174.5828729051154 350 | 174.5828729051154 351 | 177.2145530200865 352 | 177.2145530200865 353 | 177.2145530200865 354 | 177.2145530200865 355 | 177.2145530200865 356 | 177.2145530200865 357 | 177.2145530200865 358 | 177.2145530200865 359 | 177.2145530200865 360 | 177.2145530200865 361 | 125.99350842918905 362 | 125.99350842918905 363 | 125.99350842918905 364 | 125.99350842918905 365 | 125.99350842918905 366 | 125.99350842918905 367 | 125.99350842918905 368 | 125.99350842918905 369 | 125.99350842918905 370 | 125.99350842918905 371 | 117.23663458840394 372 | 117.23663458840394 373 | 117.23663458840394 374 | 117.23663458840394 375 | 117.23663458840394 376 | 117.23663458840394 377 | 117.23663458840394 378 | 117.23663458840394 379 | 117.23663458840394 380 | 117.23663458840394 381 | 67.83522291312669 382 | 67.83522291312669 383 | 67.83522291312669 384 | 67.83522291312669 385 | 67.83522291312669 386 | 67.83522291312669 387 | 67.83522291312669 388 | 67.83522291312669 389 | 67.83522291312669 390 | 67.83522291312669 391 | 13.855849743391873 392 | 13.855849743391873 393 | 13.855849743391873 394 | 13.855849743391873 395 | 13.855849743391873 396 | 13.855849743391873 397 | 13.855849743391873 398 | 13.855849743391873 399 | 13.855849743391873 400 | 13.855849743391873 401 | -------------------------------------------------------------------------------- /Ch03_ADC_DAC/zerohold.hold_25.txt: -------------------------------------------------------------------------------- 1 | 90.39198607966112 2 | 90.39198607966112 3 | 90.39198607966112 4 | 90.39198607966112 5 | 90.39198607966112 6 | 90.39198607966112 7 | 90.39198607966112 8 | 90.39198607966112 9 | 90.39198607966112 10 | 90.39198607966112 11 | 90.39198607966112 12 | 90.39198607966112 13 | 90.39198607966112 14 | 90.39198607966112 15 | 90.39198607966112 16 | 90.39198607966112 17 | 90.39198607966112 18 | 90.39198607966112 19 | 90.39198607966112 20 | 90.39198607966112 21 | 90.39198607966112 22 | 90.39198607966112 23 | 90.39198607966112 24 | 90.39198607966112 25 | 90.39198607966112 26 | 12.396265582261414 27 | 12.396265582261414 28 | 12.396265582261414 29 | 12.396265582261414 30 | 12.396265582261414 31 | 12.396265582261414 32 | 12.396265582261414 33 | 12.396265582261414 34 | 12.396265582261414 35 | 12.396265582261414 36 | 12.396265582261414 37 | 12.396265582261414 38 | 12.396265582261414 39 | 12.396265582261414 40 | 12.396265582261414 41 | 12.396265582261414 42 | 12.396265582261414 43 | 12.396265582261414 44 | 12.396265582261414 45 | 12.396265582261414 46 | 12.396265582261414 47 | 12.396265582261414 48 | 12.396265582261414 49 | 12.396265582261414 50 | 12.396265582261414 51 | 152.14705724385098 52 | 152.14705724385098 53 | 152.14705724385098 54 | 152.14705724385098 55 | 152.14705724385098 56 | 152.14705724385098 57 | 152.14705724385098 58 | 152.14705724385098 59 | 152.14705724385098 60 | 152.14705724385098 61 | 152.14705724385098 62 | 152.14705724385098 63 | 152.14705724385098 64 | 152.14705724385098 65 | 152.14705724385098 66 | 152.14705724385098 67 | 152.14705724385098 68 | 152.14705724385098 69 | 152.14705724385098 70 | 152.14705724385098 71 | 152.14705724385098 72 | 152.14705724385098 73 | 152.14705724385098 74 | 152.14705724385098 75 | 152.14705724385098 76 | 155.48755892059225 77 | 155.48755892059225 78 | 155.48755892059225 79 | 155.48755892059225 80 | 155.48755892059225 81 | 155.48755892059225 82 | 155.48755892059225 83 | 155.48755892059225 84 | 155.48755892059225 85 | 155.48755892059225 86 | 155.48755892059225 87 | 155.48755892059225 88 | 155.48755892059225 89 | 155.48755892059225 90 | 155.48755892059225 91 | 155.48755892059225 92 | 155.48755892059225 93 | 155.48755892059225 94 | 155.48755892059225 95 | 155.48755892059225 96 | 155.48755892059225 97 | 155.48755892059225 98 | 155.48755892059225 99 | 155.48755892059225 100 | 155.48755892059225 101 | 79.65569825391667 102 | 79.65569825391667 103 | 79.65569825391667 104 | 79.65569825391667 105 | 79.65569825391667 106 | 79.65569825391667 107 | 79.65569825391667 108 | 79.65569825391667 109 | 79.65569825391667 110 | 79.65569825391667 111 | 79.65569825391667 112 | 79.65569825391667 113 | 79.65569825391667 114 | 79.65569825391667 115 | 79.65569825391667 116 | 79.65569825391667 117 | 79.65569825391667 118 | 79.65569825391667 119 | 79.65569825391667 120 | 79.65569825391667 121 | 79.65569825391667 122 | 79.65569825391667 123 | 79.65569825391667 124 | 79.65569825391667 125 | 79.65569825391667 126 | 177.5708719501884 127 | 177.5708719501884 128 | 177.5708719501884 129 | 177.5708719501884 130 | 177.5708719501884 131 | 177.5708719501884 132 | 177.5708719501884 133 | 177.5708719501884 134 | 177.5708719501884 135 | 177.5708719501884 136 | 177.5708719501884 137 | 177.5708719501884 138 | 177.5708719501884 139 | 177.5708719501884 140 | 177.5708719501884 141 | 177.5708719501884 142 | 177.5708719501884 143 | 177.5708719501884 144 | 177.5708719501884 145 | 177.5708719501884 146 | 177.5708719501884 147 | 177.5708719501884 148 | 177.5708719501884 149 | 177.5708719501884 150 | 177.5708719501884 151 | 109.25381137314407 152 | 109.25381137314407 153 | 109.25381137314407 154 | 109.25381137314407 155 | 109.25381137314407 156 | 109.25381137314407 157 | 109.25381137314407 158 | 109.25381137314407 159 | 109.25381137314407 160 | 109.25381137314407 161 | 109.25381137314407 162 | 109.25381137314407 163 | 109.25381137314407 164 | 109.25381137314407 165 | 109.25381137314407 166 | 109.25381137314407 167 | 109.25381137314407 168 | 109.25381137314407 169 | 109.25381137314407 170 | 109.25381137314407 171 | 109.25381137314407 172 | 109.25381137314407 173 | 109.25381137314407 174 | 109.25381137314407 175 | 109.25381137314407 176 | 122.19260717980505 177 | 122.19260717980505 178 | 122.19260717980505 179 | 122.19260717980505 180 | 122.19260717980505 181 | 122.19260717980505 182 | 122.19260717980505 183 | 122.19260717980505 184 | 122.19260717980505 185 | 122.19260717980505 186 | 122.19260717980505 187 | 122.19260717980505 188 | 122.19260717980505 189 | 122.19260717980505 190 | 122.19260717980505 191 | 122.19260717980505 192 | 122.19260717980505 193 | 122.19260717980505 194 | 122.19260717980505 195 | 122.19260717980505 196 | 122.19260717980505 197 | 122.19260717980505 198 | 122.19260717980505 199 | 122.19260717980505 200 | 122.19260717980505 201 | 167.66488491173683 202 | 167.66488491173683 203 | 167.66488491173683 204 | 167.66488491173683 205 | 167.66488491173683 206 | 167.66488491173683 207 | 167.66488491173683 208 | 167.66488491173683 209 | 167.66488491173683 210 | 167.66488491173683 211 | 167.66488491173683 212 | 167.66488491173683 213 | 167.66488491173683 214 | 167.66488491173683 215 | 167.66488491173683 216 | 167.66488491173683 217 | 167.66488491173683 218 | 167.66488491173683 219 | 167.66488491173683 220 | 167.66488491173683 221 | 167.66488491173683 222 | 167.66488491173683 223 | 167.66488491173683 224 | 167.66488491173683 225 | 167.66488491173683 226 | 17.36769906678736 227 | 17.36769906678736 228 | 17.36769906678736 229 | 17.36769906678736 230 | 17.36769906678736 231 | 17.36769906678736 232 | 17.36769906678736 233 | 17.36769906678736 234 | 17.36769906678736 235 | 17.36769906678736 236 | 17.36769906678736 237 | 17.36769906678736 238 | 17.36769906678736 239 | 17.36769906678736 240 | 17.36769906678736 241 | 17.36769906678736 242 | 17.36769906678736 243 | 17.36769906678736 244 | 17.36769906678736 245 | 17.36769906678736 246 | 17.36769906678736 247 | 17.36769906678736 248 | 17.36769906678736 249 | 17.36769906678736 250 | 17.36769906678736 251 | 65.10786168687356 252 | 65.10786168687356 253 | 65.10786168687356 254 | 65.10786168687356 255 | 65.10786168687356 256 | 65.10786168687356 257 | 65.10786168687356 258 | 65.10786168687356 259 | 65.10786168687356 260 | 65.10786168687356 261 | 65.10786168687356 262 | 65.10786168687356 263 | 65.10786168687356 264 | 65.10786168687356 265 | 65.10786168687356 266 | 65.10786168687356 267 | 65.10786168687356 268 | 65.10786168687356 269 | 65.10786168687356 270 | 65.10786168687356 271 | 65.10786168687356 272 | 65.10786168687356 273 | 65.10786168687356 274 | 65.10786168687356 275 | 65.10786168687356 276 | 59.78060363460759 277 | 59.78060363460759 278 | 59.78060363460759 279 | 59.78060363460759 280 | 59.78060363460759 281 | 59.78060363460759 282 | 59.78060363460759 283 | 59.78060363460759 284 | 59.78060363460759 285 | 59.78060363460759 286 | 59.78060363460759 287 | 59.78060363460759 288 | 59.78060363460759 289 | 59.78060363460759 290 | 59.78060363460759 291 | 59.78060363460759 292 | 59.78060363460759 293 | 59.78060363460759 294 | 59.78060363460759 295 | 59.78060363460759 296 | 59.78060363460759 297 | 59.78060363460759 298 | 59.78060363460759 299 | 59.78060363460759 300 | 59.78060363460759 301 | 75.40942883085087 302 | 75.40942883085087 303 | 75.40942883085087 304 | 75.40942883085087 305 | 75.40942883085087 306 | 75.40942883085087 307 | 75.40942883085087 308 | 75.40942883085087 309 | 75.40942883085087 310 | 75.40942883085087 311 | 75.40942883085087 312 | 75.40942883085087 313 | 75.40942883085087 314 | 75.40942883085087 315 | 75.40942883085087 316 | 75.40942883085087 317 | 75.40942883085087 318 | 75.40942883085087 319 | 75.40942883085087 320 | 75.40942883085087 321 | 75.40942883085087 322 | 75.40942883085087 323 | 75.40942883085087 324 | 75.40942883085087 325 | 75.40942883085087 326 | 172.24711893365608 327 | 172.24711893365608 328 | 172.24711893365608 329 | 172.24711893365608 330 | 172.24711893365608 331 | 172.24711893365608 332 | 172.24711893365608 333 | 172.24711893365608 334 | 172.24711893365608 335 | 172.24711893365608 336 | 172.24711893365608 337 | 172.24711893365608 338 | 172.24711893365608 339 | 172.24711893365608 340 | 172.24711893365608 341 | 172.24711893365608 342 | 172.24711893365608 343 | 172.24711893365608 344 | 172.24711893365608 345 | 172.24711893365608 346 | 172.24711893365608 347 | 172.24711893365608 348 | 172.24711893365608 349 | 172.24711893365608 350 | 172.24711893365608 351 | 177.2145530200865 352 | 177.2145530200865 353 | 177.2145530200865 354 | 177.2145530200865 355 | 177.2145530200865 356 | 177.2145530200865 357 | 177.2145530200865 358 | 177.2145530200865 359 | 177.2145530200865 360 | 177.2145530200865 361 | 177.2145530200865 362 | 177.2145530200865 363 | 177.2145530200865 364 | 177.2145530200865 365 | 177.2145530200865 366 | 177.2145530200865 367 | 177.2145530200865 368 | 177.2145530200865 369 | 177.2145530200865 370 | 177.2145530200865 371 | 177.2145530200865 372 | 177.2145530200865 373 | 177.2145530200865 374 | 177.2145530200865 375 | 177.2145530200865 376 | 82.26124859602596 377 | 82.26124859602596 378 | 82.26124859602596 379 | 82.26124859602596 380 | 82.26124859602596 381 | 82.26124859602596 382 | 82.26124859602596 383 | 82.26124859602596 384 | 82.26124859602596 385 | 82.26124859602596 386 | 82.26124859602596 387 | 82.26124859602596 388 | 82.26124859602596 389 | 82.26124859602596 390 | 82.26124859602596 391 | 82.26124859602596 392 | 82.26124859602596 393 | 82.26124859602596 394 | 82.26124859602596 395 | 82.26124859602596 396 | 82.26124859602596 397 | 82.26124859602596 398 | 82.26124859602596 399 | 82.26124859602596 400 | 82.26124859602596 401 | -------------------------------------------------------------------------------- /Ch03_ADC_DAC/zerohold.hold_3.txt: -------------------------------------------------------------------------------- 1 | 90.39198607966112 2 | 90.39198607966112 3 | 90.39198607966112 4 | 137.22499604457587 5 | 137.22499604457587 6 | 137.22499604457587 7 | 88.23536072150948 8 | 88.23536072150948 9 | 88.23536072150948 10 | 84.97761225202487 11 | 84.97761225202487 12 | 84.97761225202487 13 | 152.92667080838473 14 | 152.92667080838473 15 | 152.92667080838473 16 | 16.71397021551403 17 | 16.71397021551403 18 | 16.71397021551403 19 | 10.680848157316525 20 | 10.680848157316525 21 | 10.680848157316525 22 | 73.83618913756358 23 | 73.83618913756358 24 | 73.83618913756358 25 | 176.28509873983333 26 | 176.28509873983333 27 | 176.28509873983333 28 | 32.6734889135781 29 | 32.6734889135781 30 | 32.6734889135781 31 | 108.91878412353557 32 | 108.91878412353557 33 | 108.91878412353557 34 | 68.04320363427455 35 | 68.04320363427455 36 | 68.04320363427455 37 | 143.49043756444001 38 | 143.49043756444001 39 | 143.49043756444001 40 | 175.0555100166322 41 | 175.0555100166322 42 | 175.0555100166322 43 | 154.6056753354556 44 | 154.6056753354556 45 | 154.6056753354556 46 | 171.02256745733993 47 | 171.02256745733993 48 | 171.02256745733993 49 | 168.94305338741356 50 | 168.94305338741356 51 | 168.94305338741356 52 | 167.52070526698512 53 | 167.52070526698512 54 | 167.52070526698512 55 | 90.1978043393228 56 | 90.1978043393228 57 | 90.1978043393228 58 | 105.07957920038325 59 | 105.07957920038325 60 | 105.07957920038325 61 | 179.42391359970622 62 | 179.42391359970622 63 | 179.42391359970622 64 | 166.14627083291614 65 | 166.14627083291614 66 | 166.14627083291614 67 | 33.0202433720944 68 | 33.0202433720944 69 | 33.0202433720944 70 | 155.684293452835 71 | 155.684293452835 72 | 155.684293452835 73 | 82.49401773141165 74 | 82.49401773141165 75 | 82.49401773141165 76 | 155.48755892059225 77 | 155.48755892059225 78 | 155.48755892059225 79 | 197.7801290219567 80 | 197.7801290219567 81 | 197.7801290219567 82 | 98.33535781398308 83 | 98.33535781398308 84 | 98.33535781398308 85 | 176.80368826806222 86 | 176.80368826806222 87 | 176.80368826806222 88 | 116.65764517737033 89 | 116.65764517737033 90 | 116.65764517737033 91 | 149.34177216218723 92 | 149.34177216218723 93 | 149.34177216218723 94 | 187.4700896217517 95 | 187.4700896217517 96 | 187.4700896217517 97 | 45.66897753512369 98 | 45.66897753512369 99 | 45.66897753512369 100 | 149.5115486029058 101 | 149.5115486029058 102 | 149.5115486029058 103 | 181.60987520354635 104 | 181.60987520354635 105 | 181.60987520354635 106 | 3.5181034164556104 107 | 3.5181034164556104 108 | 3.5181034164556104 109 | 65.61935604400308 110 | 65.61935604400308 111 | 65.61935604400308 112 | 81.70429023895416 113 | 81.70429023895416 114 | 81.70429023895416 115 | 149.36481677425147 116 | 149.36481677425147 117 | 149.36481677425147 118 | 93.7636498697947 119 | 93.7636498697947 120 | 93.7636498697947 121 | 143.24098718904241 122 | 143.24098718904241 123 | 143.24098718904241 124 | 25.414497308873983 125 | 25.414497308873983 126 | 25.414497308873983 127 | 180.99094370355314 128 | 180.99094370355314 129 | 180.99094370355314 130 | 71.66256967615571 131 | 71.66256967615571 132 | 71.66256967615571 133 | 144.06183102250773 134 | 144.06183102250773 135 | 144.06183102250773 136 | 92.29235095430084 137 | 92.29235095430084 138 | 92.29235095430084 139 | 13.730970484815824 140 | 13.730970484815824 141 | 13.730970484815824 142 | 99.71932876553487 143 | 99.71932876553487 144 | 99.71932876553487 145 | 122.8658813688971 146 | 122.8658813688971 147 | 122.8658813688971 148 | 158.21106284386562 149 | 158.21106284386562 150 | 158.21106284386562 151 | 109.25381137314407 152 | 109.25381137314407 153 | 109.25381137314407 154 | 195.0644178115306 155 | 195.0644178115306 156 | 195.0644178115306 157 | 60.348076381199625 158 | 60.348076381199625 159 | 60.348076381199625 160 | 111.37667548341724 161 | 111.37667548341724 162 | 111.37667548341724 163 | 155.05527145335824 164 | 155.05527145335824 165 | 155.05527145335824 166 | 14.6750195142609 167 | 14.6750195142609 168 | 14.6750195142609 169 | 21.94602302864412 170 | 21.94602302864412 171 | 21.94602302864412 172 | 39.79214101453407 173 | 39.79214101453407 174 | 39.79214101453407 175 | 146.3507764350864 176 | 146.3507764350864 177 | 146.3507764350864 178 | 184.7615773602102 179 | 184.7615773602102 180 | 184.7615773602102 181 | 192.56158705507482 182 | 192.56158705507482 183 | 192.56158705507482 184 | 144.53432093058586 185 | 144.53432093058586 186 | 144.53432093058586 187 | 185.75332079862287 188 | 185.75332079862287 189 | 185.75332079862287 190 | 186.25990461956633 191 | 186.25990461956633 192 | 186.25990461956633 193 | 96.03889649534524 194 | 96.03889649534524 195 | 96.03889649534524 196 | 99.46028756358685 197 | 99.46028756358685 198 | 99.46028756358685 199 | 113.36750920866615 200 | 113.36750920866615 201 | 113.36750920866615 202 | 120.2257699515811 203 | 120.2257699515811 204 | 120.2257699515811 205 | 75.44783186979238 206 | 75.44783186979238 207 | 75.44783186979238 208 | 14.377403404663427 209 | 14.377403404663427 210 | 14.377403404663427 211 | 52.346217321307456 212 | 52.346217321307456 213 | 52.346217321307456 214 | 137.5854312534084 215 | 137.5854312534084 216 | 137.5854312534084 217 | 179.33991780132052 218 | 179.33991780132052 219 | 179.33991780132052 220 | 109.23135625190022 221 | 109.23135625190022 222 | 109.23135625190022 223 | 35.7202907802224 224 | 35.7202907802224 225 | 35.7202907802224 226 | 17.36769906678736 227 | 17.36769906678736 228 | 17.36769906678736 229 | 99.81673019205185 230 | 99.81673019205185 231 | 99.81673019205185 232 | 16.829023935851286 233 | 16.829023935851286 234 | 16.829023935851286 235 | 91.23443526569791 236 | 91.23443526569791 237 | 91.23443526569791 238 | 189.83107994821663 239 | 189.83107994821663 240 | 189.83107994821663 241 | 170.2574324947601 242 | 170.2574324947601 243 | 170.2574324947601 244 | 152.97855781874873 245 | 152.97855781874873 246 | 152.97855781874873 247 | 55.835482038777116 248 | 55.835482038777116 249 | 55.835482038777116 250 | 9.510051120528152 251 | 9.510051120528152 252 | 9.510051120528152 253 | 106.07405102380682 254 | 106.07405102380682 255 | 106.07405102380682 256 | 1.7273577641255964 257 | 1.7273577641255964 258 | 1.7273577641255964 259 | 159.39425535571104 260 | 159.39425535571104 261 | 159.39425535571104 262 | 162.17740298296292 263 | 162.17740298296292 264 | 162.17740298296292 265 | 84.57753598700151 266 | 84.57753598700151 267 | 84.57753598700151 268 | 119.17722065505578 269 | 119.17722065505578 270 | 119.17722065505578 271 | 172.22340848987136 272 | 172.22340848987136 273 | 172.22340848987136 274 | 39.58829194684418 275 | 39.58829194684418 276 | 39.58829194684418 277 | 41.47029385278913 278 | 41.47029385278913 279 | 41.47029385278913 280 | 42.343070699925086 281 | 42.343070699925086 282 | 42.343070699925086 283 | 103.42995346025519 284 | 103.42995346025519 285 | 103.42995346025519 286 | 57.14897092237808 287 | 57.14897092237808 288 | 57.14897092237808 289 | 34.51716025580024 290 | 34.51716025580024 291 | 34.51716025580024 292 | 82.18199602227969 293 | 82.18199602227969 294 | 82.18199602227969 295 | 151.49853926495322 296 | 151.49853926495322 297 | 151.49853926495322 298 | 5.491572757144587 299 | 5.491572757144587 300 | 5.491572757144587 301 | 75.40942883085087 302 | 75.40942883085087 303 | 75.40942883085087 304 | 28.11157983714159 305 | 28.11157983714159 306 | 28.11157983714159 307 | 121.8368056516859 308 | 121.8368056516859 309 | 121.8368056516859 310 | 200.92168918323205 311 | 200.92168918323205 312 | 200.92168918323205 313 | 8.923899028798887 314 | 8.923899028798887 315 | 8.923899028798887 316 | 44.827998023513494 317 | 44.827998023513494 318 | 44.827998023513494 319 | 11.25490928234468 320 | 11.25490928234468 321 | 11.25490928234468 322 | 171.95321737668579 323 | 171.95321737668579 324 | 171.95321737668579 325 | 66.98590159262534 326 | 66.98590159262534 327 | 66.98590159262534 328 | 173.07760897907602 329 | 173.07760897907602 330 | 173.07760897907602 331 | 47.95048375363452 332 | 47.95048375363452 333 | 47.95048375363452 334 | 169.17833089430076 335 | 169.17833089430076 336 | 169.17833089430076 337 | 2.7569900886863445 338 | 2.7569900886863445 339 | 2.7569900886863445 340 | 74.02616061977538 341 | 74.02616061977538 342 | 74.02616061977538 343 | 46.61867522085664 344 | 46.61867522085664 345 | 46.61867522085664 346 | 186.12181160576694 347 | 186.12181160576694 348 | 186.12181160576694 349 | 71.04005182175715 350 | 71.04005182175715 351 | 71.04005182175715 352 | 116.12644114966251 353 | 116.12644114966251 354 | 116.12644114966251 355 | 6.550059801245773 356 | 6.550059801245773 357 | 6.550059801245773 358 | 131.20803037936793 359 | 131.20803037936793 360 | 131.20803037936793 361 | 125.99350842918905 362 | 125.99350842918905 363 | 125.99350842918905 364 | 159.7507127079793 365 | 159.7507127079793 366 | 159.7507127079793 367 | 188.97048229021374 368 | 188.97048229021374 369 | 188.97048229021374 370 | 58.480004225098156 371 | 58.480004225098156 372 | 58.480004225098156 373 | 82.70944094177058 374 | 82.70944094177058 375 | 82.70944094177058 376 | 82.26124859602596 377 | 82.26124859602596 378 | 82.26124859602596 379 | 21.315104700048895 380 | 21.315104700048895 381 | 21.315104700048895 382 | 193.21889303456896 383 | 193.21889303456896 384 | 193.21889303456896 385 | 23.140462390911097 386 | 23.140462390911097 387 | 23.140462390911097 388 | 21.291146597631567 389 | 21.291146597631567 390 | 21.291146597631567 391 | 13.855849743391873 392 | 13.855849743391873 393 | 13.855849743391873 394 | 161.16388703401526 395 | 161.16388703401526 396 | 161.16388703401526 397 | 192.86560249531513 398 | 192.86560249531513 399 | 192.86560249531513 400 | 84.80959093168345 401 | -------------------------------------------------------------------------------- /Ch03_ADC_DAC/zerohold.hold_50.txt: -------------------------------------------------------------------------------- 1 | 90.39198607966112 2 | 90.39198607966112 3 | 90.39198607966112 4 | 90.39198607966112 5 | 90.39198607966112 6 | 90.39198607966112 7 | 90.39198607966112 8 | 90.39198607966112 9 | 90.39198607966112 10 | 90.39198607966112 11 | 90.39198607966112 12 | 90.39198607966112 13 | 90.39198607966112 14 | 90.39198607966112 15 | 90.39198607966112 16 | 90.39198607966112 17 | 90.39198607966112 18 | 90.39198607966112 19 | 90.39198607966112 20 | 90.39198607966112 21 | 90.39198607966112 22 | 90.39198607966112 23 | 90.39198607966112 24 | 90.39198607966112 25 | 90.39198607966112 26 | 90.39198607966112 27 | 90.39198607966112 28 | 90.39198607966112 29 | 90.39198607966112 30 | 90.39198607966112 31 | 90.39198607966112 32 | 90.39198607966112 33 | 90.39198607966112 34 | 90.39198607966112 35 | 90.39198607966112 36 | 90.39198607966112 37 | 90.39198607966112 38 | 90.39198607966112 39 | 90.39198607966112 40 | 90.39198607966112 41 | 90.39198607966112 42 | 90.39198607966112 43 | 90.39198607966112 44 | 90.39198607966112 45 | 90.39198607966112 46 | 90.39198607966112 47 | 90.39198607966112 48 | 90.39198607966112 49 | 90.39198607966112 50 | 90.39198607966112 51 | 152.14705724385098 52 | 152.14705724385098 53 | 152.14705724385098 54 | 152.14705724385098 55 | 152.14705724385098 56 | 152.14705724385098 57 | 152.14705724385098 58 | 152.14705724385098 59 | 152.14705724385098 60 | 152.14705724385098 61 | 152.14705724385098 62 | 152.14705724385098 63 | 152.14705724385098 64 | 152.14705724385098 65 | 152.14705724385098 66 | 152.14705724385098 67 | 152.14705724385098 68 | 152.14705724385098 69 | 152.14705724385098 70 | 152.14705724385098 71 | 152.14705724385098 72 | 152.14705724385098 73 | 152.14705724385098 74 | 152.14705724385098 75 | 152.14705724385098 76 | 152.14705724385098 77 | 152.14705724385098 78 | 152.14705724385098 79 | 152.14705724385098 80 | 152.14705724385098 81 | 152.14705724385098 82 | 152.14705724385098 83 | 152.14705724385098 84 | 152.14705724385098 85 | 152.14705724385098 86 | 152.14705724385098 87 | 152.14705724385098 88 | 152.14705724385098 89 | 152.14705724385098 90 | 152.14705724385098 91 | 152.14705724385098 92 | 152.14705724385098 93 | 152.14705724385098 94 | 152.14705724385098 95 | 152.14705724385098 96 | 152.14705724385098 97 | 152.14705724385098 98 | 152.14705724385098 99 | 152.14705724385098 100 | 152.14705724385098 101 | 79.65569825391667 102 | 79.65569825391667 103 | 79.65569825391667 104 | 79.65569825391667 105 | 79.65569825391667 106 | 79.65569825391667 107 | 79.65569825391667 108 | 79.65569825391667 109 | 79.65569825391667 110 | 79.65569825391667 111 | 79.65569825391667 112 | 79.65569825391667 113 | 79.65569825391667 114 | 79.65569825391667 115 | 79.65569825391667 116 | 79.65569825391667 117 | 79.65569825391667 118 | 79.65569825391667 119 | 79.65569825391667 120 | 79.65569825391667 121 | 79.65569825391667 122 | 79.65569825391667 123 | 79.65569825391667 124 | 79.65569825391667 125 | 79.65569825391667 126 | 79.65569825391667 127 | 79.65569825391667 128 | 79.65569825391667 129 | 79.65569825391667 130 | 79.65569825391667 131 | 79.65569825391667 132 | 79.65569825391667 133 | 79.65569825391667 134 | 79.65569825391667 135 | 79.65569825391667 136 | 79.65569825391667 137 | 79.65569825391667 138 | 79.65569825391667 139 | 79.65569825391667 140 | 79.65569825391667 141 | 79.65569825391667 142 | 79.65569825391667 143 | 79.65569825391667 144 | 79.65569825391667 145 | 79.65569825391667 146 | 79.65569825391667 147 | 79.65569825391667 148 | 79.65569825391667 149 | 79.65569825391667 150 | 79.65569825391667 151 | 109.25381137314407 152 | 109.25381137314407 153 | 109.25381137314407 154 | 109.25381137314407 155 | 109.25381137314407 156 | 109.25381137314407 157 | 109.25381137314407 158 | 109.25381137314407 159 | 109.25381137314407 160 | 109.25381137314407 161 | 109.25381137314407 162 | 109.25381137314407 163 | 109.25381137314407 164 | 109.25381137314407 165 | 109.25381137314407 166 | 109.25381137314407 167 | 109.25381137314407 168 | 109.25381137314407 169 | 109.25381137314407 170 | 109.25381137314407 171 | 109.25381137314407 172 | 109.25381137314407 173 | 109.25381137314407 174 | 109.25381137314407 175 | 109.25381137314407 176 | 109.25381137314407 177 | 109.25381137314407 178 | 109.25381137314407 179 | 109.25381137314407 180 | 109.25381137314407 181 | 109.25381137314407 182 | 109.25381137314407 183 | 109.25381137314407 184 | 109.25381137314407 185 | 109.25381137314407 186 | 109.25381137314407 187 | 109.25381137314407 188 | 109.25381137314407 189 | 109.25381137314407 190 | 109.25381137314407 191 | 109.25381137314407 192 | 109.25381137314407 193 | 109.25381137314407 194 | 109.25381137314407 195 | 109.25381137314407 196 | 109.25381137314407 197 | 109.25381137314407 198 | 109.25381137314407 199 | 109.25381137314407 200 | 109.25381137314407 201 | 167.66488491173683 202 | 167.66488491173683 203 | 167.66488491173683 204 | 167.66488491173683 205 | 167.66488491173683 206 | 167.66488491173683 207 | 167.66488491173683 208 | 167.66488491173683 209 | 167.66488491173683 210 | 167.66488491173683 211 | 167.66488491173683 212 | 167.66488491173683 213 | 167.66488491173683 214 | 167.66488491173683 215 | 167.66488491173683 216 | 167.66488491173683 217 | 167.66488491173683 218 | 167.66488491173683 219 | 167.66488491173683 220 | 167.66488491173683 221 | 167.66488491173683 222 | 167.66488491173683 223 | 167.66488491173683 224 | 167.66488491173683 225 | 167.66488491173683 226 | 167.66488491173683 227 | 167.66488491173683 228 | 167.66488491173683 229 | 167.66488491173683 230 | 167.66488491173683 231 | 167.66488491173683 232 | 167.66488491173683 233 | 167.66488491173683 234 | 167.66488491173683 235 | 167.66488491173683 236 | 167.66488491173683 237 | 167.66488491173683 238 | 167.66488491173683 239 | 167.66488491173683 240 | 167.66488491173683 241 | 167.66488491173683 242 | 167.66488491173683 243 | 167.66488491173683 244 | 167.66488491173683 245 | 167.66488491173683 246 | 167.66488491173683 247 | 167.66488491173683 248 | 167.66488491173683 249 | 167.66488491173683 250 | 167.66488491173683 251 | 65.10786168687356 252 | 65.10786168687356 253 | 65.10786168687356 254 | 65.10786168687356 255 | 65.10786168687356 256 | 65.10786168687356 257 | 65.10786168687356 258 | 65.10786168687356 259 | 65.10786168687356 260 | 65.10786168687356 261 | 65.10786168687356 262 | 65.10786168687356 263 | 65.10786168687356 264 | 65.10786168687356 265 | 65.10786168687356 266 | 65.10786168687356 267 | 65.10786168687356 268 | 65.10786168687356 269 | 65.10786168687356 270 | 65.10786168687356 271 | 65.10786168687356 272 | 65.10786168687356 273 | 65.10786168687356 274 | 65.10786168687356 275 | 65.10786168687356 276 | 65.10786168687356 277 | 65.10786168687356 278 | 65.10786168687356 279 | 65.10786168687356 280 | 65.10786168687356 281 | 65.10786168687356 282 | 65.10786168687356 283 | 65.10786168687356 284 | 65.10786168687356 285 | 65.10786168687356 286 | 65.10786168687356 287 | 65.10786168687356 288 | 65.10786168687356 289 | 65.10786168687356 290 | 65.10786168687356 291 | 65.10786168687356 292 | 65.10786168687356 293 | 65.10786168687356 294 | 65.10786168687356 295 | 65.10786168687356 296 | 65.10786168687356 297 | 65.10786168687356 298 | 65.10786168687356 299 | 65.10786168687356 300 | 65.10786168687356 301 | 75.40942883085087 302 | 75.40942883085087 303 | 75.40942883085087 304 | 75.40942883085087 305 | 75.40942883085087 306 | 75.40942883085087 307 | 75.40942883085087 308 | 75.40942883085087 309 | 75.40942883085087 310 | 75.40942883085087 311 | 75.40942883085087 312 | 75.40942883085087 313 | 75.40942883085087 314 | 75.40942883085087 315 | 75.40942883085087 316 | 75.40942883085087 317 | 75.40942883085087 318 | 75.40942883085087 319 | 75.40942883085087 320 | 75.40942883085087 321 | 75.40942883085087 322 | 75.40942883085087 323 | 75.40942883085087 324 | 75.40942883085087 325 | 75.40942883085087 326 | 75.40942883085087 327 | 75.40942883085087 328 | 75.40942883085087 329 | 75.40942883085087 330 | 75.40942883085087 331 | 75.40942883085087 332 | 75.40942883085087 333 | 75.40942883085087 334 | 75.40942883085087 335 | 75.40942883085087 336 | 75.40942883085087 337 | 75.40942883085087 338 | 75.40942883085087 339 | 75.40942883085087 340 | 75.40942883085087 341 | 75.40942883085087 342 | 75.40942883085087 343 | 75.40942883085087 344 | 75.40942883085087 345 | 75.40942883085087 346 | 75.40942883085087 347 | 75.40942883085087 348 | 75.40942883085087 349 | 75.40942883085087 350 | 75.40942883085087 351 | 177.2145530200865 352 | 177.2145530200865 353 | 177.2145530200865 354 | 177.2145530200865 355 | 177.2145530200865 356 | 177.2145530200865 357 | 177.2145530200865 358 | 177.2145530200865 359 | 177.2145530200865 360 | 177.2145530200865 361 | 177.2145530200865 362 | 177.2145530200865 363 | 177.2145530200865 364 | 177.2145530200865 365 | 177.2145530200865 366 | 177.2145530200865 367 | 177.2145530200865 368 | 177.2145530200865 369 | 177.2145530200865 370 | 177.2145530200865 371 | 177.2145530200865 372 | 177.2145530200865 373 | 177.2145530200865 374 | 177.2145530200865 375 | 177.2145530200865 376 | 177.2145530200865 377 | 177.2145530200865 378 | 177.2145530200865 379 | 177.2145530200865 380 | 177.2145530200865 381 | 177.2145530200865 382 | 177.2145530200865 383 | 177.2145530200865 384 | 177.2145530200865 385 | 177.2145530200865 386 | 177.2145530200865 387 | 177.2145530200865 388 | 177.2145530200865 389 | 177.2145530200865 390 | 177.2145530200865 391 | 177.2145530200865 392 | 177.2145530200865 393 | 177.2145530200865 394 | 177.2145530200865 395 | 177.2145530200865 396 | 177.2145530200865 397 | 177.2145530200865 398 | 177.2145530200865 399 | 177.2145530200865 400 | 177.2145530200865 401 | -------------------------------------------------------------------------------- /Ch03_ADC_DAC/zerohold.py: -------------------------------------------------------------------------------- 1 | import random 2 | 3 | def zhold(samples, hold_duration): 4 | L = [] 5 | hold = None 6 | for i in range(0, len(samples)): 7 | if (i % hold_duration == 0): 8 | hold = samples[i] 9 | L.append(hold) 10 | else: 11 | L.append(hold) 12 | return L 13 | 14 | if __name__ == "__main__": 15 | from util import Util 16 | U = Util("zerohold") 17 | X = U.get_signal() 18 | 19 | U.tofile(zhold(X, 3), "hold_3") 20 | U.tofile(zhold(X, 10), "hold_10") 21 | U.tofile(zhold(X, 25), "hold_25") 22 | U.tofile(zhold(X, 50), "hold_50") 23 | 24 | print("DONE!") -------------------------------------------------------------------------------- /Ch03_ADC_DAC/zerohold.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davecan/dspguide-code/321a36be08adea511ab728f0a9794866014c064e/Ch03_ADC_DAC/zerohold.xlsx -------------------------------------------------------------------------------- /Ch04_Software/floats.py: -------------------------------------------------------------------------------- 1 | # Ch 4, Table 4-1 2 | 3 | from random import random 4 | 5 | x = 1.0 6 | k = 0 7 | 8 | print("0,1.0") 9 | 10 | for i in range(1, 2000001): 11 | a = random() 12 | b = random() 13 | x = x + a 14 | x = x + b 15 | x = x - a 16 | x = x - b 17 | if i % 100000 == 0: 18 | k += 1 19 | print("%s,%s" % (k, x)) 20 | -------------------------------------------------------------------------------- /Ch05_Linear_Systems/.vscode/.ropeproject/config.py: -------------------------------------------------------------------------------- 1 | # The default ``config.py`` 2 | # flake8: noqa 3 | 4 | 5 | def set_prefs(prefs): 6 | """This function is called before opening the project""" 7 | 8 | # Specify which files and folders to ignore in the project. 9 | # Changes to ignored resources are not added to the history and 10 | # VCSs. Also they are not returned in `Project.get_files()`. 11 | # Note that ``?`` and ``*`` match all characters but slashes. 12 | # '*.pyc': matches 'test.pyc' and 'pkg/test.pyc' 13 | # 'mod*.pyc': matches 'test/mod1.pyc' but not 'mod/1.pyc' 14 | # '.svn': matches 'pkg/.svn' and all of its children 15 | # 'build/*.o': matches 'build/lib.o' but not 'build/sub/lib.o' 16 | # 'build//*.o': matches 'build/lib.o' and 'build/sub/lib.o' 17 | prefs['ignored_resources'] = ['*.pyc', '*~', '.ropeproject', 18 | '.hg', '.svn', '_svn', '.git', '.tox'] 19 | 20 | # Specifies which files should be considered python files. It is 21 | # useful when you have scripts inside your project. Only files 22 | # ending with ``.py`` are considered to be python files by 23 | # default. 24 | #prefs['python_files'] = ['*.py'] 25 | 26 | # Custom source folders: By default rope searches the project 27 | # for finding source folders (folders that should be searched 28 | # for finding modules). You can add paths to that list. Note 29 | # that rope guesses project source folders correctly most of the 30 | # time; use this if you have any problems. 31 | # The folders should be relative to project root and use '/' for 32 | # separating folders regardless of the platform rope is running on. 33 | # 'src/my_source_folder' for instance. 34 | #prefs.add('source_folders', 'src') 35 | 36 | # You can extend python path for looking up modules 37 | #prefs.add('python_path', '~/python/') 38 | 39 | # Should rope save object information or not. 40 | prefs['save_objectdb'] = True 41 | prefs['compress_objectdb'] = False 42 | 43 | # If `True`, rope analyzes each module when it is being saved. 44 | prefs['automatic_soa'] = True 45 | # The depth of calls to follow in static object analysis 46 | prefs['soa_followed_calls'] = 0 47 | 48 | # If `False` when running modules or unit tests "dynamic object 49 | # analysis" is turned off. This makes them much faster. 50 | prefs['perform_doa'] = True 51 | 52 | # Rope can check the validity of its object DB when running. 53 | prefs['validate_objectdb'] = True 54 | 55 | # How many undos to hold? 56 | prefs['max_history_items'] = 32 57 | 58 | # Shows whether to save history across sessions. 59 | prefs['save_history'] = True 60 | prefs['compress_history'] = False 61 | 62 | # Set the number spaces used for indenting. According to 63 | # :PEP:`8`, it is best to use 4 spaces. Since most of rope's 64 | # unit-tests use 4 spaces it is more reliable, too. 65 | prefs['indent_size'] = 4 66 | 67 | # Builtin and c-extension modules that are allowed to be imported 68 | # and inspected by rope. 69 | prefs['extension_modules'] = [] 70 | 71 | # Add all standard c-extensions to extension_modules list. 72 | prefs['import_dynload_stdmods'] = True 73 | 74 | # If `True` modules with syntax errors are considered to be empty. 75 | # The default value is `False`; When `False` syntax errors raise 76 | # `rope.base.exceptions.ModuleSyntaxError` exception. 77 | prefs['ignore_syntax_errors'] = False 78 | 79 | # If `True`, rope ignores unresolvable imports. Otherwise, they 80 | # appear in the importing namespace. 81 | prefs['ignore_bad_imports'] = False 82 | 83 | # If `True`, rope will insert new module imports as 84 | # `from import ` by default. 85 | prefs['prefer_module_from_imports'] = False 86 | 87 | # If `True`, rope will transform a comma list of imports into 88 | # multiple separate import statements when organizing 89 | # imports. 90 | prefs['split_imports'] = False 91 | 92 | # If `True`, rope will sort imports alphabetically by module name 93 | # instead of alphabetically by import statement, with from imports 94 | # after normal imports. 95 | prefs['sort_imports_alphabetically'] = False 96 | 97 | 98 | def project_opened(project): 99 | """This function is called after opening the project""" 100 | # Do whatever you like here! 101 | -------------------------------------------------------------------------------- /Ch05_Linear_Systems/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | "configurations": [ 4 | { 5 | "name": "Python", 6 | "type": "python", 7 | "request": "launch", 8 | "stopOnEntry": true, 9 | "pythonPath": "${config.python.pythonPath}", 10 | "program": "${file}", 11 | "debugOptions": [ 12 | "WaitOnAbnormalExit", 13 | "WaitOnNormalExit", 14 | "RedirectOutput" 15 | ] 16 | }, 17 | { 18 | "name": "Integrated Terminal/Console", 19 | "type": "python", 20 | "request": "launch", 21 | "stopOnEntry": true, 22 | "pythonPath": "${config.python.pythonPath}", 23 | "program": "${file}", 24 | "console": "integratedTerminal", 25 | "debugOptions": [ 26 | "WaitOnAbnormalExit", 27 | "WaitOnNormalExit" 28 | ] 29 | }, 30 | { 31 | "name": "External Terminal/Console", 32 | "type": "python", 33 | "request": "launch", 34 | "stopOnEntry": true, 35 | "pythonPath": "${config.python.pythonPath}", 36 | "program": "${file}", 37 | "console": "externalTerminal", 38 | "debugOptions": [ 39 | "WaitOnAbnormalExit", 40 | "WaitOnNormalExit" 41 | ] 42 | }, 43 | { 44 | "name": "Django", 45 | "type": "python", 46 | "request": "launch", 47 | "stopOnEntry": true, 48 | "pythonPath": "${config.python.pythonPath}", 49 | "program": "${workspaceRoot}/manage.py", 50 | "args": [ 51 | "runserver", 52 | "--noreload" 53 | ], 54 | "debugOptions": [ 55 | "WaitOnAbnormalExit", 56 | "WaitOnNormalExit", 57 | "RedirectOutput", 58 | "DjangoDebugging" 59 | ] 60 | }, 61 | { 62 | "name": "Flask", 63 | "type": "python", 64 | "request": "launch", 65 | "stopOnEntry": true, 66 | "pythonPath": "${config.python.pythonPath}", 67 | "program": "${workspaceRoot}/run.py", 68 | "args": [], 69 | "debugOptions": [ 70 | "WaitOnAbnormalExit", 71 | "WaitOnNormalExit", 72 | "RedirectOutput" 73 | ] 74 | }, 75 | { 76 | "name": "Watson", 77 | "type": "python", 78 | "request": "launch", 79 | "stopOnEntry": true, 80 | "pythonPath": "${config.python.pythonPath}", 81 | "program": "${workspaceRoot}/console.py", 82 | "args": [ 83 | "dev", 84 | "runserver", 85 | "--noreload=True" 86 | ], 87 | "debugOptions": [ 88 | "WaitOnAbnormalExit", 89 | "WaitOnNormalExit", 90 | "RedirectOutput" 91 | ] 92 | }, 93 | { 94 | "name": "Attach (Remote Debug)", 95 | "type": "python", 96 | "request": "attach", 97 | "localRoot": "${workspaceRoot}", 98 | "remoteRoot": "${workspaceRoot}", 99 | "port": 3000, 100 | "secret": "my_secret", 101 | "host": "localhost" 102 | } 103 | ] 104 | } -------------------------------------------------------------------------------- /Ch05_Linear_Systems/__pycache__/decompose.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davecan/dspguide-code/321a36be08adea511ab728f0a9794866014c064e/Ch05_Linear_Systems/__pycache__/decompose.cpython-36.pyc -------------------------------------------------------------------------------- /Ch05_Linear_Systems/__pycache__/linear.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davecan/dspguide-code/321a36be08adea511ab728f0a9794866014c064e/Ch05_Linear_Systems/__pycache__/linear.cpython-36.pyc -------------------------------------------------------------------------------- /Ch05_Linear_Systems/__pycache__/util.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davecan/dspguide-code/321a36be08adea511ab728f0a9794866014c064e/Ch05_Linear_Systems/__pycache__/util.cpython-36.pyc -------------------------------------------------------------------------------- /Ch05_Linear_Systems/decompose.py: -------------------------------------------------------------------------------- 1 | # Implements several of the decompositions mentioned later in Chapter 5. 2 | # Each decomposition returns a list of lists. 3 | # Each list is a separate component of the decomposition. 4 | 5 | class Decompose: 6 | # N point signal is decomposed into N impulse signals. 7 | # Ex: [1, 2, 3] -> [ [1, 0, 0], [0, 2, 0], [0, 0, 3] ] 8 | def impulse(self, signal): 9 | x = [] 10 | for i in range(0, len(signal)): 11 | y = [0]*len(signal) 12 | y[i] = signal[i] 13 | x.append(y) 14 | return x 15 | 16 | # N point signal is decomposed into N step signals. 17 | # Ex: [1, 2, 3] -> [ [1, 1, 1], [0, 2, 2], [0, 0, 3] ] 18 | def step(self, signal): 19 | x = [] 20 | for i in range(0, len(signal)): 21 | y = [0]*len(signal) 22 | y = y[0:i] + [signal[i]]*(len(y)-i) 23 | x.append(y) 24 | return x 25 | 26 | # N point signal is decomposed into two signals. 27 | # First signal has odd samples set to zero. 28 | # Second signal has even samples set to zero. 29 | def interlaced(self, signal): 30 | e = [] 31 | o = [] 32 | for i in range(0, len(signal)): 33 | if i % 2 == 0: 34 | e.append(signal[i]) 35 | o.append(0) 36 | else: 37 | e.append(0) 38 | o.append(signal[i]) 39 | return [e,o] -------------------------------------------------------------------------------- /Ch05_Linear_Systems/fsquare.m: -------------------------------------------------------------------------------- 1 | # 2 | # Octave implementation of Fourier series of square wave. 3 | # 4 | 5 | function result = fsquare(t, x) 6 | F = 3/2; 7 | for n = 1:2:x 8 | F = F + ( 6 / (n * pi) ) * sin(n * t); 9 | endfor 10 | result = F; 11 | endfunction 12 | 13 | # to run: 14 | # > t = linspace(0, 4*pi); 15 | # > F = fsquare(t, x); where x is desired number of expansions 16 | # > plot(F) 17 | # 18 | # ex: F = fsquare(t, 2000); expands series to n=2000 -------------------------------------------------------------------------------- /Ch05_Linear_Systems/linear.input.txt: -------------------------------------------------------------------------------- 1 | 90.39198607966112 2 | 48.88287389767647 3 | 178.43067136890068 4 | 137.22499604457587 5 | 99.40159949294932 6 | 39.903993083151484 7 | 88.23536072150948 8 | 111.97236870332354 9 | 100.808941994621 10 | 84.97761225202487 11 | 146.42804355391564 12 | 102.14241990061026 13 | 152.92667080838473 14 | 16.20935593766432 15 | 0.13126578664620914 16 | 16.71397021551403 17 | 8.899507058991459 18 | 2.5130332918015763 19 | 10.680848157316525 20 | 180.55220384439957 21 | 133.80863175048722 22 | 73.83618913756358 23 | 144.4669006719188 24 | 194.9307609824826 25 | 176.28509873983333 26 | 12.396265582261414 27 | 177.4354548229892 28 | 32.6734889135781 29 | 37.346102705873605 30 | 166.06977295305083 -------------------------------------------------------------------------------- /Ch05_Linear_Systems/linear.py: -------------------------------------------------------------------------------- 1 | class LinearSystemTester: 2 | input_signal = None 3 | output_signal = None 4 | 5 | def __init__(self, input_signal, output_signal): 6 | self.input_signal = input_signal 7 | self.output_signal = output_signal 8 | 9 | def is_linear(self): 10 | return self.is_homogeneous() and self.is_additive() 11 | 12 | # change in output amplitude must equal change in input amplitude 13 | def is_homogeneous(self): 14 | for i in range(0, len(self.input_signal)): 15 | x = self.input_signal[i] 16 | y = self.output_signal[i] 17 | x_prev = 0 if i == 0 else self.input_signal[i-1] 18 | y_prev = 0 if i == 0 else self.output_signal[i-1] 19 | delta_x = x - x_prev 20 | delta_y = y - y_prev 21 | if (delta_x != delta_y) and (i != 0): 22 | print("Not homogeneous on sample %s: x = %s, y = %s, delta_x = %s, delta_y = %s" % (i, x, y, delta_x, delta_y)) 23 | return False 24 | return True 25 | 26 | def get_delta(self, x, y): 27 | return x-y if x >= y else y-x 28 | 29 | def is_additive(self): 30 | delta = self.get_delta(self.input_signal[0], self.output_signal[0]) 31 | for i in range(0, len(self.input_signal)): 32 | x = self.input_signal[i] 33 | y = self.output_signal[i] 34 | curr_delta = self.get_delta(x, y) 35 | if (curr_delta != delta) and (i != 0): 36 | print("Not additive on sample %s: x = %s, y = %s, delta = %s, curr_delta = %s" % (i, x, y, delta, curr_delta)) 37 | return False 38 | return True 39 | 40 | # this only tests if a signal is shifted a known number of positions forward at same amplitude 41 | # it doesn't handle detecting unknown shifts in position + amplitude 42 | def is_shift_invariant(self, shift): 43 | # verify all zero up to shifted position 44 | if not self.output_signal[0:shift] == [0 for x in range(0,shift)]: 45 | print("Not shift invariant. Nonzero value in shifted prefix.") 46 | print("Input: %s" % self.input_signal) 47 | print("Output: %s" % self.output_signal) 48 | return False 49 | 50 | for i in range(shift, len(self.input_signal)): 51 | if not self.input_signal[i-shift] == self.output_signal[i]: 52 | print("Not shift invariant. Mismatch at position %s (%s, %s)." % (i, self.input_signal[i], self.output_signal[i])) 53 | print("Input: %s" % self.input_signal) 54 | print("Output: %s" % self.output_signal) 55 | return False 56 | 57 | return True 58 | 59 | 60 | if __name__ == "__main__": 61 | X = [1,2,3,4,5] 62 | Y = [0,1,2,3,4] 63 | LST = LinearSystemTester(X, Y) 64 | print(LST.is_shift_invariant(1)) -------------------------------------------------------------------------------- /Ch05_Linear_Systems/signal.txt: -------------------------------------------------------------------------------- 1 | 90.39198607966112 2 | 48.88287389767647 3 | 178.43067136890068 4 | 137.22499604457587 5 | 99.40159949294932 6 | 39.903993083151484 7 | 88.23536072150948 8 | 111.97236870332354 9 | 100.808941994621 10 | 84.97761225202487 11 | 146.42804355391564 12 | 102.14241990061026 13 | 152.92667080838473 14 | 16.20935593766432 15 | 0.13126578664620914 16 | 16.71397021551403 17 | 8.899507058991459 18 | 2.5130332918015763 19 | 10.680848157316525 20 | 180.55220384439957 21 | 133.80863175048722 22 | 73.83618913756358 23 | 144.4669006719188 24 | 194.9307609824826 25 | 176.28509873983333 26 | 12.396265582261414 27 | 177.4354548229892 28 | 32.6734889135781 29 | 37.346102705873605 30 | 166.06977295305083 31 | 108.91878412353557 32 | 47.298479292841186 33 | 137.38619378735643 34 | 68.04320363427455 35 | 198.92097358933103 36 | 94.14460381271132 37 | 143.49043756444001 38 | 101.90366727265608 39 | 61.01300161800831 40 | 175.0555100166322 41 | 156.4415040578073 42 | 138.6564844509553 43 | 154.6056753354556 44 | 159.0976259006465 45 | 39.84595818670506 46 | 171.02256745733993 47 | 8.806533784716946 48 | 24.882243651640863 49 | 168.94305338741356 50 | 91.33670093937104 51 | 152.14705724385098 52 | 167.52070526698512 53 | 150.56001451495976 54 | 114.6765424424098 55 | 90.1978043393228 56 | 69.34567606559304 57 | 97.49666581864896 58 | 105.07957920038325 59 | 106.60791452535055 60 | 20.29100272692786 61 | 179.42391359970622 62 | 15.216314616184844 63 | 165.26580713411425 64 | 166.14627083291614 65 | 33.50372600486184 66 | 145.0786995000876 67 | 33.0202433720944 68 | 100.52701370561262 69 | 2.8274933014234627 70 | 155.684293452835 71 | 66.0050296442796 72 | 195.73131647002063 73 | 82.49401773141165 74 | 189.8802874211451 75 | 29.97849969737483 76 | 155.48755892059225 77 | 50.581572960252394 78 | 20.359111787809084 79 | 197.7801290219567 80 | 53.90301547602551 81 | 44.41683724014388 82 | 98.33535781398308 83 | 166.4467305186137 84 | 55.361417875811895 85 | 176.80368826806222 86 | 158.87018103707223 87 | 173.30137300964833 88 | 116.65764517737033 89 | 91.88253377260752 90 | 189.77788063048214 91 | 149.34177216218723 92 | 179.06190989074653 93 | 69.29975713496783 94 | 187.4700896217517 95 | 19.68394188770451 96 | 137.35952781042624 97 | 45.66897753512369 98 | 127.24722859223876 99 | 83.22726932969826 100 | 149.5115486029058 101 | 79.65569825391667 102 | 189.97090060363826 103 | 181.60987520354635 104 | 29.598809749953908 105 | 103.25647386914078 106 | 3.5181034164556104 107 | 5.90137268624183 108 | 65.4161583919214 109 | 65.61935604400308 110 | 54.87033295071685 111 | 60.229084557233385 112 | 81.70429023895416 113 | 6.388019671365965 114 | 27.615164697671936 115 | 149.36481677425147 116 | 49.11198923598216 117 | 12.107640709278765 118 | 93.7636498697947 119 | 47.20006117873908 120 | 106.30245070919065 121 | 143.24098718904241 122 | 200.9076877925234 123 | 106.49637566216654 124 | 25.414497308873983 125 | 1.0188581796165714 126 | 177.5708719501884 127 | 180.99094370355314 128 | 102.46655883116195 129 | 58.782241411235546 130 | 71.66256967615571 131 | 79.030362393752 132 | 43.3926547852176 133 | 144.06183102250773 134 | 102.62550358903285 135 | 30.031741538250536 136 | 92.29235095430084 137 | 15.79127927168636 138 | 147.20463212396712 139 | 13.730970484815824 140 | 188.99248197470763 141 | 154.14732583602648 142 | 99.71932876553487 143 | 38.316922583825274 144 | 11.825482300973274 145 | 122.8658813688971 146 | 0.39646211603045955 147 | 180.2019742964509 148 | 158.21106284386562 149 | 75.53596275062918 150 | 120.95230011198113 151 | 109.25381137314407 152 | 3.4330186640515175 153 | 82.16468396115891 154 | 195.0644178115306 155 | 169.74694131288953 156 | 197.04737653925991 157 | 60.348076381199625 158 | 162.28827113945314 159 | 182.64969204071997 160 | 111.37667548341724 161 | 5.169765722027557 162 | 178.45918680527154 163 | 155.05527145335824 164 | 144.24761768004961 165 | 51.00622178281128 166 | 14.6750195142609 167 | 112.63347144861982 168 | 191.4818529124658 169 | 21.94602302864412 170 | 191.01387821005613 171 | 170.5886566343436 172 | 39.79214101453407 173 | 195.5068562441998 174 | 45.62874545572487 175 | 146.3507764350864 176 | 122.19260717980505 177 | 141.89536821047164 178 | 184.7615773602102 179 | 141.78595106808362 180 | 47.23251646062891 181 | 192.56158705507482 182 | 194.67309094859726 183 | 29.813395818680085 184 | 144.53432093058586 185 | 42.55488558753195 186 | 132.6761786003157 187 | 185.75332079862287 188 | 12.91128970779002 189 | 101.77639634615183 190 | 186.25990461956633 191 | 125.10331395400772 192 | 127.38435311388403 193 | 96.03889649534524 194 | 142.91422226826685 195 | 8.778408394558866 196 | 99.46028756358685 197 | 189.04500320901616 198 | 13.056092635020267 199 | 113.36750920866615 200 | 76.74514047950639 201 | 167.66488491173683 202 | 120.2257699515811 203 | 131.30464832463014 204 | 23.59371158137293 205 | 75.44783186979238 206 | 60.41089226379388 207 | 188.58231573484872 208 | 14.377403404663427 209 | 35.07723750566692 210 | 190.40924802547386 211 | 52.346217321307456 212 | 136.91897919740694 213 | 115.76917373623256 214 | 137.5854312534084 215 | 123.84804791955564 216 | 109.98300206096191 217 | 179.33991780132052 218 | 37.92232254864912 219 | 157.1562062348065 220 | 109.23135625190022 221 | 172.66774006065995 222 | 139.7718816025165 223 | 35.7202907802224 224 | 146.5508906171178 225 | 1.4127542212110349 226 | 17.36769906678736 227 | 156.15178577041917 228 | 154.4541546842112 229 | 99.81673019205185 230 | 94.83098587024593 231 | 52.62907405344445 232 | 16.829023935851286 233 | 21.33066684449587 234 | 46.07871465366453 235 | 91.23443526569791 236 | 194.79667053466756 237 | 78.16244401552439 238 | 189.83107994821663 239 | 117.37765377982221 240 | 113.27642242130793 241 | 170.2574324947601 242 | 196.53283139691823 243 | 1.3408070221685051 244 | 152.97855781874873 245 | 25.755890703096238 246 | 167.8640870350067 247 | 55.835482038777116 248 | 108.90603538978614 249 | 51.55950428360339 250 | 9.510051120528152 251 | 65.10786168687356 252 | 60.86514607008295 253 | 106.07405102380682 254 | 188.19439878112632 255 | 133.33667325725548 256 | 1.7273577641255964 257 | 37.39008246019681 258 | 164.5582101078482 259 | 159.39425535571104 260 | 72.72973486311663 261 | 112.88502305035756 262 | 162.17740298296292 263 | 86.52773248697122 264 | 26.10152759125444 265 | 84.57753598700151 266 | 15.6032520806877 267 | 117.90910583415138 268 | 119.17722065505578 269 | 43.79237340586755 270 | 126.51396843727278 271 | 172.22340848987136 272 | 99.54836449937197 273 | 18.34256584305956 274 | 39.58829194684418 275 | 154.82520395039182 276 | 59.78060363460759 277 | 41.47029385278913 278 | 162.11781748358015 279 | 133.46236358861643 280 | 42.343070699925086 281 | 115.97084855333034 282 | 154.64525307275244 283 | 103.42995346025519 284 | 55.437087238142865 285 | 106.16658576551278 286 | 57.14897092237808 287 | 187.8274692737202 288 | 164.40767517209372 289 | 34.51716025580024 290 | 142.5746982338419 291 | 52.16058995378045 292 | 82.18199602227969 293 | 10.973455833763413 294 | 58.23188758028292 295 | 151.49853926495322 296 | 0.756964042451783 297 | 138.73126592571802 298 | 5.491572757144587 299 | 60.63604479069493 300 | 56.82014713767996 301 | 75.40942883085087 302 | 83.75976749071349 303 | 120.73526692900741 304 | 28.11157983714159 305 | 3.783372425910101 306 | 9.45964287387152 307 | 121.8368056516859 308 | 28.90588238285077 309 | 38.52885270793219 310 | 200.92168918323205 311 | 155.95530356045361 312 | 165.4115662438567 313 | 8.923899028798887 314 | 98.40214512605232 315 | 148.67676557929394 316 | 44.827998023513494 317 | 4.450796752642097 318 | 42.39029853479982 319 | 11.25490928234468 320 | 196.23220888869463 321 | 181.7769775564421 322 | 171.95321737668579 323 | 167.16940628197162 324 | 177.62054561819318 325 | 66.98590159262534 326 | 172.24711893365608 327 | 26.369429476213273 328 | 173.07760897907602 329 | 152.2303305294409 330 | 125.74711414821775 331 | 47.95048375363452 332 | 190.49779373863734 333 | 179.40660273166702 334 | 169.17833089430076 335 | 59.38032356945282 336 | 146.21439001904227 337 | 2.7569900886863445 338 | 103.11633748136057 339 | 69.38026127121783 340 | 74.02616061977538 341 | 174.5828729051154 342 | 11.644057575480648 343 | 46.61867522085664 344 | 52.60313222283213 345 | 14.465746792287163 346 | 186.12181160576694 347 | 100.39304767503756 348 | 84.35254781846334 349 | 71.04005182175715 350 | 110.22776652222322 351 | 177.2145530200865 352 | 116.12644114966251 353 | 182.63793548090038 354 | 107.34610704853738 355 | 6.550059801245773 356 | 105.07756666830436 357 | 26.510727438358675 358 | 131.20803037936793 359 | 42.11313621038199 360 | 58.643427336119345 361 | 125.99350842918905 362 | 38.09087650591367 363 | 41.976745333166306 364 | 159.7507127079793 365 | 30.902126808018213 366 | 112.1022040205721 367 | 188.97048229021374 368 | 138.42446441537524 369 | 1.750104661445615 370 | 58.480004225098156 371 | 117.23663458840394 372 | 6.147256670423205 373 | 82.70944094177058 374 | 118.72657725148254 375 | 169.45523859117708 376 | 82.26124859602596 377 | 19.96977449131617 378 | 112.82924927996248 379 | 21.315104700048895 380 | 156.88701115240528 381 | 67.83522291312669 382 | 193.21889303456896 383 | 148.45771876279633 384 | 64.69972498241746 385 | 23.140462390911097 386 | 143.3143847889824 387 | 175.72531539297418 388 | 21.291146597631567 389 | 40.79000564798738 390 | 54.03225496828368 391 | 13.855849743391873 392 | 140.7555458756788 393 | 149.9932348942297 394 | 161.16388703401526 395 | 86.53749546553153 396 | 0.8794648949199618 397 | 192.86560249531513 398 | 102.0293053676415 399 | 30.870343289521937 400 | 84.80959093168345 401 | -------------------------------------------------------------------------------- /Ch05_Linear_Systems/test_decompose.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | from util import Util 3 | from decompose import Decompose 4 | 5 | class TestDecompose(unittest.TestCase): 6 | def test_impulse(self): 7 | X = [0, 1, 2, 3, 4, 5] 8 | D = Decompose() 9 | I = D.impulse(X) 10 | self.assertTrue(len(I) == len(X)) 11 | # expected = [ [0,0,0,0,0,0], [0,1,0,0,0,0],[0,0,2,0,0,0],[0,0,0,3,0,0],[0,0,0,0,4,0],[0,0,0,0,0,5]] 12 | # self.assertTrue(I == expected) 13 | for i in range(0, len(I)): 14 | impulse = I[i] 15 | for j in range(0, len(impulse)): 16 | if i == j: 17 | self.assertTrue(impulse[j] == X[i]) 18 | else: 19 | self.assertTrue(impulse[j] == 0) 20 | 21 | def test_step(self): 22 | X = [0, 1, 2, 3, 4, 5] 23 | D = Decompose() 24 | S = D.step(X) 25 | self.assertTrue(len(S) == len(X)) 26 | # expected = [ [0,0,0,0,0,0],[0,1,1,1,1,1],[0,0,2,2,2,2],[0,0,0,3,3,3],[0,0,0,0,4,4],[0,0,0,0,0,5]] 27 | # self.assertTrue(S == expected) 28 | for x in range(0, len(X)): 29 | step = S[x] 30 | for s in range(0, len(step)): 31 | if s >= x: 32 | self.assertTrue(step[s] == X[x], "x: %s, X[x]: %s, s: %s, step[s]: %s" % (x, X[x], s, step[s])) 33 | else: 34 | self.assertTrue(step[s] == 0, "x: %s, s: %s, step[s]: %s" % (x, s, step[s])) 35 | 36 | def test_interlaced(self): 37 | X = [0,1,2,3,4,5] 38 | D = Decompose() 39 | S = D.interlaced(X) 40 | self.assertTrue(len(S) == 2) 41 | self.assertTrue(S[0] == [0,0,2,0,4,0]) 42 | self.assertTrue(S[1] == [0,1,0,3,0,5]) 43 | 44 | 45 | 46 | if __name__ == '__main__': 47 | unittest.main() -------------------------------------------------------------------------------- /Ch05_Linear_Systems/test_linear.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | from util import Util 3 | from linear import LinearSystemTester 4 | 5 | class TestLinearSystemsTester(unittest.TestCase): 6 | input_signal = None 7 | 8 | def setUp(self): 9 | U = Util("linear") 10 | self.input_signal = [int(x) for x in U.get_signal("input")] 11 | 12 | def test_is_homogeneous(self): 13 | X = self.input_signal 14 | Y = [x + 100 for x in X] 15 | LST = LinearSystemTester(X, Y) 16 | self.assertTrue(LST.is_homogeneous()) 17 | 18 | def test_non_homogeneous(self): 19 | X = self.input_signal 20 | Y = [x for x in X] 21 | Y[25] = Y[25] + 1 22 | LST = LinearSystemTester(X, Y) 23 | self.assertFalse(LST.is_homogeneous()) 24 | 25 | def test_is_additive(self): 26 | X = self.input_signal 27 | Y = [x + 1 for x in X] 28 | LST = LinearSystemTester(X, Y) 29 | self.assertTrue(LST.is_additive()) 30 | 31 | Y = [x - 1 for x in X] 32 | LST = LinearSystemTester(X, Y) 33 | self.assertTrue(LST.is_additive()) 34 | 35 | def test_non_additive(self): 36 | X = self.input_signal 37 | Y = [x + 1 for x in X] 38 | Y[25] = -141414 39 | LST = LinearSystemTester(X, Y) 40 | self.assertFalse(LST.is_additive()) 41 | 42 | Y = [x * x for x in X] 43 | LST = LinearSystemTester(X, Y) 44 | self.assertFalse(LST.is_additive()) 45 | 46 | def test_is_linear(self): 47 | X = self.input_signal 48 | Y = [x + 1 for x in X] 49 | LST = LinearSystemTester(X, Y) 50 | self.assertTrue(LST.is_linear()) 51 | 52 | Y = [x - 1 for x in X] 53 | LST = LinearSystemTester(X, Y) 54 | self.assertTrue(LST.is_linear()) 55 | 56 | def test_non_linear(self): 57 | X = self.input_signal 58 | Y = [x + 1 for x in X] 59 | Y[25] = Y[1] + Y[2] 60 | LST = LinearSystemTester(X, Y) 61 | self.assertFalse(LST.is_linear()) 62 | 63 | Y = [x * x for x in X] 64 | LST = LinearSystemTester(X, Y) 65 | self.assertFalse(LST.is_linear()) 66 | 67 | def shift(self, l, n): 68 | if n == 0: 69 | return l 70 | m = [0 for x in range(0, n)] 71 | m.extend(l[0:-n]) 72 | return m 73 | 74 | # sanity check 75 | def test_shift(self): 76 | X = [1,2,3,4,5] 77 | Y = self.shift(X, 1) 78 | self.assertEqual(Y, [0,1,2,3,4]) 79 | 80 | Y = self.shift(X, 3) 81 | self.assertEqual(Y, [0,0,0,1,2]) 82 | 83 | def test_is_shift_invariant(self): 84 | # shift 0 85 | X = [1,2,3,4,5] 86 | LST = LinearSystemTester(X, X) 87 | self.assertTrue(LST.is_shift_invariant(0)) 88 | 89 | # shift 1 90 | X = [1,2,3,4,5] 91 | Y = self.shift(X, 1) 92 | LST = LinearSystemTester(X, Y) 93 | self.assertTrue(LST.is_shift_invariant(1)) 94 | 95 | # shift 4 96 | Y = self.shift(X, 4) 97 | LST = LinearSystemTester(X, Y) 98 | self.assertTrue(LST.is_shift_invariant(4)) 99 | 100 | def test_non_shift_invariant(self): 101 | X = [1,2,3,4,5] 102 | Y = self.shift(X, 1) 103 | Y[0] = -1 104 | LST = LinearSystemTester(X, Y) 105 | self.assertFalse(LST.is_shift_invariant(1)) 106 | 107 | 108 | if __name__ == '__main__': 109 | unittest.main() -------------------------------------------------------------------------------- /Ch05_Linear_Systems/util.py: -------------------------------------------------------------------------------- 1 | class Util: 2 | module_name = None 3 | 4 | def __init__(self, module_name): 5 | self.module_name = module_name 6 | 7 | def get_signal(self, filename=None): 8 | if (filename == None): 9 | name = "signal.txt" 10 | else: 11 | name = "%s.%s.txt" % (self.module_name, filename) 12 | with open(name) as f: 13 | L = f.read().splitlines() 14 | return [float(x) for x in L] 15 | 16 | def tofile(self, L): 17 | f = open("%s.txt" % self.module_name, "w") 18 | for x in L: 19 | f.write("%s \n" % x) 20 | f.close() 21 | 22 | def tofile(self, L, filename=None): 23 | if (filename == None): 24 | name = "%s.txt" % self.module_name 25 | else: 26 | name = "%s.%s.txt" % (self.module_name, filename) 27 | with open(name, "w") as f: 28 | for x in L: 29 | f.write("%s \n" % x) 30 | # f = open(name, "w") 31 | # for x in L: 32 | # f.write("%s \n" % x) 33 | # f.close() -------------------------------------------------------------------------------- /Ch06_Convolution/convinput.m: -------------------------------------------------------------------------------- 1 | function result = convinput(x, h) 2 | input_length = length(x); 3 | impulse_length = length(h); 4 | output_length = input_length + impulse_length -1; 5 | y = zeros(1, output_length); # prefill output as zero-filled vector 6 | for i = 1:input_length 7 | for j = 1:impulse_length 8 | y(i+j-1) += x(i) * h(j); 9 | end 10 | end 11 | result = y; 12 | endfunction 13 | 14 | 15 | x = [1 2 3 0 -1 -2 -3]; 16 | h = [1 2]; 17 | 18 | convinput(x, h) 19 | 20 | conv(x,h) # built in for comparison -------------------------------------------------------------------------------- /Ch06_Convolution/convlength.m: -------------------------------------------------------------------------------- 1 | # Octave 2 | # Quick check of convolution operation lengths 3 | 4 | x = [1 2 3 4 5]; 5 | impulse = [1]; 6 | conv(x, impulse) 7 | 8 | impulse = [1 0]; 9 | conv(x, impulse) 10 | 11 | impulse = [0 1]; 12 | conv(x, impulse) 13 | 14 | impulse = [0 0 1 0 0]; 15 | conv(x, impulse) 16 | 17 | length(conv(x,impulse)) == length(x) + length(impulse) - 1 18 | # ans=1 -------------------------------------------------------------------------------- /Ch06_Convolution/convmanualadd.m: -------------------------------------------------------------------------------- 1 | # Octave 2 | # Simulation of adding the 9 signals from 6-5 and 6-6 3 | # values are rough estimates but the plot gets pretty close to the textbook image 4 | 5 | x1 = [0 0 0 0 0 0 0 0 0 0 0 0]; 6 | x2 = [0 -1 .5 .3 .2 0 0 0 0 0 0 0]; 7 | x3 = [0 0 -1.2 0.8 0.5 0.3 0 0 0 0 0 0]; 8 | x4 = [0 0 0 2 -1 -.8 -3 0 0 0 0 0]; 9 | x5 = [0 0 0 0 1.3 -.8 -.5 -.3 0 0 0 0]; 10 | x6 = [0 0 0 0 0 1.3 -.7 -.5 -.3 0 0 0]; 11 | x7 = [0 0 0 0 0 0 .7 -.2 -.1 -.5 0 0]; 12 | x8 = [0 0 0 0 0 0 0 0 0 0 0 0]; 13 | x9 = [0 0 0 0 0 0 0 0 -.8 .3 .2 .1]; 14 | 15 | y = x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9; 16 | 17 | plot(y, "marker", "*", "markersize", 12, "linestyle", "none") -------------------------------------------------------------------------------- /Ch06_Convolution/convoutput.m: -------------------------------------------------------------------------------- 1 | # This doesn't quite work right... off by one somehow... 2 | 3 | function result = convoutput(x, h) 4 | input_length = length(x); 5 | impulse_length = length(h); 6 | output_length = input_length + impulse_length -1; 7 | y = zeros(1, output_length); # prefill output as zero-filled vector 8 | for i = 1:output_length 9 | for j = 1:impulse_length 10 | if (i-j > 0 && i-j <= input_length) 11 | y(i) += h(j) * x(i-j); 12 | endif 13 | end 14 | end 15 | result = y; 16 | endfunction 17 | 18 | 19 | x = [1 2 3 0 -1 -2 -3]; 20 | h = [1 2]; 21 | 22 | convinput(x, h) 23 | 24 | conv(x,h) # built in for comparison -------------------------------------------------------------------------------- /Ch07_Convolution_Properties/discrete_derivatives.m: -------------------------------------------------------------------------------- 1 | # algo as implemented in equation 7-3 2 | function y = backward_difference(x) 3 | y(1) = 0; 4 | for n = 2:length(x) 5 | y(n) = x(n) - x(n-1); 6 | end 7 | endfunction 8 | 9 | # alternate algo from https://calculus.subwiki.org/wiki/Discrete_derivative 10 | function y = forward_difference(x) 11 | for n = 1:length(x) 12 | if (n == length(x)) 13 | y(n) = 0; 14 | else 15 | y(n) = x(n+1) - x(n); 16 | endif 17 | end 18 | endfunction 19 | 20 | 21 | s = linspace(0, 2*pi, 20); 22 | x = sin(s); 23 | 24 | y = backward_difference(x); 25 | stem(y) 26 | 27 | z = forward_difference(x); 28 | stem(z) 29 | 30 | 31 | # recreate figure 7-3 32 | a = zeros(1,10); 33 | b = linspace(0,0.4,10); 34 | c = linspace(0.4,1,8); 35 | d = ones(1,12); 36 | e = linspace(1,-0.8,10); 37 | f = [-.7 -.58 -.47 -.37 -.28 -.2 -.13 -.07 -.06 -.05]; 38 | g = [-.04 -.03 -.02 -.01 0 0 0 0 0 0]; 39 | 40 | x = cat(2,a,b,c,d,e,f,g); 41 | 42 | y = backward_difference(x); 43 | stem(y) 44 | 45 | z = backward_difference(x); 46 | stem(z) -------------------------------------------------------------------------------- /Ch07_Convolution_Properties/discrete_integral.m: -------------------------------------------------------------------------------- 1 | function y = discrete_integral(x) 2 | y(1) = x(1); 3 | for n = 2:length(x) 4 | y(n) = y(n-1) + x(n); 5 | end 6 | endfunction 7 | 8 | 9 | 10 | s = linspace(0, 2*pi, 20); 11 | x = sin(s); 12 | 13 | y = backward_difference(x); 14 | stem(y) 15 | 16 | z = discrete_integral(x); 17 | stem(z) -------------------------------------------------------------------------------- /Ch07_Convolution_Properties/impulse.py: -------------------------------------------------------------------------------- 1 | class ImpulseResponse: 2 | def delta(self, n=1): 3 | s = [0]*n 4 | s[0] = 1 5 | return s 6 | 7 | # scales all samples in x by k 8 | def scale(self, x, k): 9 | return [k*s for s in x] 10 | 11 | def shift(self, x, s): 12 | if s > 0: 13 | if len(x) == 1: 14 | return [0]*s + x 15 | else: 16 | return [0]*s + x[0:len(x)-s] 17 | elif s < 0: 18 | y = x[(-s):len(x)] 19 | y.extend([0]*(-s)) 20 | return y 21 | else: 22 | return x -------------------------------------------------------------------------------- /Ch07_Convolution_Properties/noise.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | 3 | noise = np.random.normal(0,1,100) 4 | 5 | print(noise) 6 | 7 | #useful for copypaste into Octave as a noisy signal for testing -------------------------------------------------------------------------------- /Ch07_Convolution_Properties/sine.m: -------------------------------------------------------------------------------- 1 | # quick configurable sine wave generator 2 | # A = amplitude 3 | # w = frequency 4 | # phi = phase offset 5 | function s = Sine(t,A=1,w=1,phi=0) 6 | s = A * sin(w*t - phi); 7 | endfunction -------------------------------------------------------------------------------- /Ch07_Convolution_Properties/test_impulse.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | from impulse import ImpulseResponse 3 | 4 | class TestImpulseResponse(unittest.TestCase): 5 | def test_impulse(self): 6 | I = ImpulseResponse() 7 | self.assertEqual([1], I.delta()) 8 | self.assertEqual([1,0], I.delta(2)) 9 | self.assertEqual([1,0,0,0,0,0,0,0,0,0], I.delta(10)) 10 | 11 | def test_scale(self): 12 | I = ImpulseResponse() 13 | self.assertEqual([1], I.scale([1], 1)) 14 | self.assertEqual([0], I.scale([1], 0)) 15 | self.assertEqual([2], I.scale([1], 2)) 16 | self.assertEqual([3, 6, 0, -3, -6], I.scale([1, 2, 0, -1, -2], 3)) 17 | self.assertEqual([0.5, 1, 0, -0.5, -1], I.scale([1, 2, 0, -1, -2], 0.5)) 18 | 19 | def test_shift(self): 20 | I = ImpulseResponse() 21 | self.assertEqual([0,1], I.shift([1], 1)) 22 | self.assertEqual([0], I.shift([1], -1)) 23 | self.assertEqual([1,2,3], I.shift([1,2,3], 0)) 24 | self.assertEqual([0,1,2], I.shift([1,2,3], 1)) 25 | self.assertEqual([0,0,1], I.shift([1,2,3], 2)) 26 | self.assertEqual([0,0,0], I.shift([1,2,3], 3)) 27 | self.assertEqual([2,3,0], I.shift([1,2,3], -1)) 28 | self.assertEqual([3,0,0], I.shift([1,2,3], -2)) 29 | self.assertEqual([0,0,0], I.shift([1,2,3], -3)) 30 | 31 | def test_shift_and_scale_delta(self): 32 | I = ImpulseResponse() 33 | self.assertEqual([0,2], I.shift(I.scale(I.delta(), 2), 1)) 34 | self.assertEqual([0,0,0,4], I.shift(I.scale(I.delta(), 4), 3)) 35 | self.assertEqual([0,0,0.5], I.scale(I.shift(I.delta(), 2), 0.5)) 36 | 37 | 38 | 39 | if __name__ == '__main__': 40 | unittest.main() -------------------------------------------------------------------------------- /Ch07_Convolution_Properties/util.py: -------------------------------------------------------------------------------- 1 | class Util: 2 | module_name = None 3 | 4 | def __init__(self, module_name): 5 | self.module_name = module_name 6 | 7 | def get_signal(self, filename=None): 8 | if (filename == None): 9 | name = "signal.txt" 10 | else: 11 | name = "%s.%s.txt" % (self.module_name, filename) 12 | with open(name) as f: 13 | L = f.read().splitlines() 14 | return [float(x) for x in L] 15 | 16 | def tofile(self, L): 17 | f = open("%s.txt" % self.module_name, "w") 18 | for x in L: 19 | f.write("%s \n" % x) 20 | f.close() 21 | 22 | def tofile(self, L, filename=None): 23 | if (filename == None): 24 | name = "%s.txt" % self.module_name 25 | else: 26 | name = "%s.%s.txt" % (self.module_name, filename) 27 | with open(name, "w") as f: 28 | for x in L: 29 | f.write("%s \n" % x) 30 | # f = open(name, "w") 31 | # for x in L: 32 | # f.write("%s \n" % x) 33 | # f.close() -------------------------------------------------------------------------------- /Ch08_Discrete_Fourier_Transform/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | "configurations": [ 4 | { 5 | "name": "Python", 6 | "type": "python", 7 | "request": "launch", 8 | "stopOnEntry": true, 9 | "pythonPath": "${config.python.pythonPath}", 10 | "program": "${file}", 11 | "debugOptions": [ 12 | "WaitOnAbnormalExit", 13 | "WaitOnNormalExit", 14 | "RedirectOutput" 15 | ] 16 | }, 17 | { 18 | "name": "Integrated Terminal/Console", 19 | "type": "python", 20 | "request": "launch", 21 | "stopOnEntry": true, 22 | "pythonPath": "${config.python.pythonPath}", 23 | "program": "${file}", 24 | "console": "integratedTerminal", 25 | "debugOptions": [ 26 | "WaitOnAbnormalExit", 27 | "WaitOnNormalExit" 28 | ] 29 | }, 30 | { 31 | "name": "External Terminal/Console", 32 | "type": "python", 33 | "request": "launch", 34 | "stopOnEntry": true, 35 | "pythonPath": "${config.python.pythonPath}", 36 | "program": "${file}", 37 | "console": "externalTerminal", 38 | "debugOptions": [ 39 | "WaitOnAbnormalExit", 40 | "WaitOnNormalExit" 41 | ] 42 | }, 43 | { 44 | "name": "Django", 45 | "type": "python", 46 | "request": "launch", 47 | "stopOnEntry": true, 48 | "pythonPath": "${config.python.pythonPath}", 49 | "program": "${workspaceRoot}/manage.py", 50 | "args": [ 51 | "runserver", 52 | "--noreload" 53 | ], 54 | "debugOptions": [ 55 | "WaitOnAbnormalExit", 56 | "WaitOnNormalExit", 57 | "RedirectOutput", 58 | "DjangoDebugging" 59 | ] 60 | }, 61 | { 62 | "name": "Flask", 63 | "type": "python", 64 | "request": "launch", 65 | "stopOnEntry": true, 66 | "pythonPath": "${config.python.pythonPath}", 67 | "program": "${workspaceRoot}/run.py", 68 | "args": [], 69 | "debugOptions": [ 70 | "WaitOnAbnormalExit", 71 | "WaitOnNormalExit", 72 | "RedirectOutput" 73 | ] 74 | }, 75 | { 76 | "name": "Watson", 77 | "type": "python", 78 | "request": "launch", 79 | "stopOnEntry": true, 80 | "pythonPath": "${config.python.pythonPath}", 81 | "program": "${workspaceRoot}/console.py", 82 | "args": [ 83 | "dev", 84 | "runserver", 85 | "--noreload=True" 86 | ], 87 | "debugOptions": [ 88 | "WaitOnAbnormalExit", 89 | "WaitOnNormalExit", 90 | "RedirectOutput" 91 | ] 92 | }, 93 | { 94 | "name": "Attach (Remote Debug)", 95 | "type": "python", 96 | "request": "attach", 97 | "localRoot": "${workspaceRoot}", 98 | "remoteRoot": "${workspaceRoot}", 99 | "port": 3000, 100 | "secret": "my_secret", 101 | "host": "localhost" 102 | } 103 | ] 104 | } -------------------------------------------------------------------------------- /Ch08_Discrete_Fourier_Transform/cosbasis.m: -------------------------------------------------------------------------------- 1 | # n is the sample length 2 | # w is the number of full cycles in that length 3 | function y = cosbasis(w, n) 4 | c = []; 5 | for i = 1:n 6 | c(i) = cos( (2 * pi * w * i / n) ); 7 | endfor 8 | y = c; 9 | endfunction -------------------------------------------------------------------------------- /Ch08_Discrete_Fourier_Transform/dft.m: -------------------------------------------------------------------------------- 1 | function [ReX, ImX] = dft(XX, N) 2 | M = int16(N/2) + 1; 3 | ReX = zeros(1,M); 4 | ImX = zeros(1,M); 5 | for k = 1:M 6 | for i = 1:N 7 | ReX(k) += XX(i) * cos(2 * pi * k * i / N); 8 | ImX(k) -= XX(i) * sin(2 * pi * k * i / N); 9 | endfor 10 | endfor 11 | endfunction 12 | 13 | -------------------------------------------------------------------------------- /Ch08_Discrete_Fourier_Transform/inversedft.m: -------------------------------------------------------------------------------- 1 | function y = inversedft(ReX, ImX, N) 2 | M = int16(N/2) + 1; 3 | 4 | # find cosine and sine amplitudes 5 | for k = 1:M 6 | ReX(k) = ReX(k) / (N/2); 7 | ImX(k) = -ImX(k) / (N/2); 8 | endfor 9 | 10 | ReX(1) = ReX(1) / 2; 11 | ReX(M) = ReX(M) / 2; 12 | 13 | # initialize time domain accumulator 14 | XX = zeros(1,N); 15 | 16 | # calculates IDFT 17 | for k = 1:M 18 | for i = 1:N 19 | XX(i) = XX(i) + ReX(k) * cos(2 * pi * k * i / N); 20 | XX(i) = XX(i) + ImX(k) * sin(2 * pi * k * i / N); 21 | endfor 22 | endfor 23 | 24 | y = XX; 25 | endfunction 26 | 27 | 28 | -------------------------------------------------------------------------------- /Ch08_Discrete_Fourier_Transform/polrect.m: -------------------------------------------------------------------------------- 1 | function [ReX, ImX] = polrect(MagX, PhaseX) 2 | M = length(ReX) 3 | ReX = zeros(1,M) 4 | ImX = zeros(1,M) 5 | 6 | for k = 1:M 7 | ReX(k) = MagX(k) * cos(PhaseX(k)) 8 | ImX(k) = MagX(k) * sin(PhaseX(k)) 9 | endfor 10 | endfunction -------------------------------------------------------------------------------- /Ch08_Discrete_Fourier_Transform/rectpol.m: -------------------------------------------------------------------------------- 1 | function [MagX, ImX] = rectpol(ReX, ImX) 2 | M = length(ReX) 3 | MagX = zeros(1,M) 4 | PhaseX = zeros(1,M) 5 | 6 | for k = 1:M 7 | MagX(k) = sqrt(ReX(k)^2 + ImX(k)^2) 8 | if ReX(k) == 0 9 | ReX(k) = 1E-20 10 | endif 11 | PhaseX(k) = atan(ImX(k) / ReX(k)) 12 | if ReX(k) < 0 13 | if ImX(k) < 0 14 | PhaseX(k) -= pi 15 | else 16 | PhaseX(k) += pi 17 | endif 18 | endif 19 | endfor 20 | endfunction -------------------------------------------------------------------------------- /Ch08_Discrete_Fourier_Transform/sinbasis.m: -------------------------------------------------------------------------------- 1 | # n is the sample length 2 | # w is the number of full cycles in that length 3 | function y = sinbasis(w, n) 4 | c = []; 5 | for i = 1:n 6 | c(i) = sin( (2 * pi * w * i / n) ); 7 | endfor 8 | y = c; 9 | endfunction -------------------------------------------------------------------------------- /Ch12_Fast_Fourier_Transform/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | "configurations": [ 4 | { 5 | "name": "Python", 6 | "type": "python", 7 | "request": "launch", 8 | "stopOnEntry": true, 9 | "pythonPath": "${config.python.pythonPath}", 10 | "program": "${file}", 11 | "debugOptions": [ 12 | "WaitOnAbnormalExit", 13 | "WaitOnNormalExit", 14 | "RedirectOutput" 15 | ] 16 | }, 17 | { 18 | "name": "Integrated Terminal/Console", 19 | "type": "python", 20 | "request": "launch", 21 | "stopOnEntry": true, 22 | "pythonPath": "${config.python.pythonPath}", 23 | "program": "${file}", 24 | "console": "integratedTerminal", 25 | "debugOptions": [ 26 | "WaitOnAbnormalExit", 27 | "WaitOnNormalExit" 28 | ] 29 | }, 30 | { 31 | "name": "External Terminal/Console", 32 | "type": "python", 33 | "request": "launch", 34 | "stopOnEntry": true, 35 | "pythonPath": "${config.python.pythonPath}", 36 | "program": "${file}", 37 | "console": "externalTerminal", 38 | "debugOptions": [ 39 | "WaitOnAbnormalExit", 40 | "WaitOnNormalExit" 41 | ] 42 | }, 43 | { 44 | "name": "Django", 45 | "type": "python", 46 | "request": "launch", 47 | "stopOnEntry": true, 48 | "pythonPath": "${config.python.pythonPath}", 49 | "program": "${workspaceRoot}/manage.py", 50 | "args": [ 51 | "runserver", 52 | "--noreload" 53 | ], 54 | "debugOptions": [ 55 | "WaitOnAbnormalExit", 56 | "WaitOnNormalExit", 57 | "RedirectOutput", 58 | "DjangoDebugging" 59 | ] 60 | }, 61 | { 62 | "name": "Flask", 63 | "type": "python", 64 | "request": "launch", 65 | "stopOnEntry": true, 66 | "pythonPath": "${config.python.pythonPath}", 67 | "program": "${workspaceRoot}/run.py", 68 | "args": [], 69 | "debugOptions": [ 70 | "WaitOnAbnormalExit", 71 | "WaitOnNormalExit", 72 | "RedirectOutput" 73 | ] 74 | }, 75 | { 76 | "name": "Watson", 77 | "type": "python", 78 | "request": "launch", 79 | "stopOnEntry": true, 80 | "pythonPath": "${config.python.pythonPath}", 81 | "program": "${workspaceRoot}/console.py", 82 | "args": [ 83 | "dev", 84 | "runserver", 85 | "--noreload=True" 86 | ], 87 | "debugOptions": [ 88 | "WaitOnAbnormalExit", 89 | "WaitOnNormalExit", 90 | "RedirectOutput" 91 | ] 92 | }, 93 | { 94 | "name": "Attach (Remote Debug)", 95 | "type": "python", 96 | "request": "attach", 97 | "localRoot": "${workspaceRoot}", 98 | "remoteRoot": "${workspaceRoot}", 99 | "port": 3000, 100 | "secret": "my_secret", 101 | "host": "localhost" 102 | } 103 | ] 104 | } -------------------------------------------------------------------------------- /Ch12_Fast_Fourier_Transform/fft.m: -------------------------------------------------------------------------------- 1 | function [rex, imx] = fft(rex, imx) 2 | n = length(rex); 3 | nm1 = n-1; 4 | nd2 = n/2; 5 | m = int16(log2(n)/log2(2)); 6 | j = nd2; 7 | 8 | rex = fft_decompose(rex); 9 | imx = fft_decompose(imx); 10 | 11 | # construct signal by walking backward up the tree, 12 | # calculating the butterfly for each value in each level. 13 | 14 | # outer loop is for each level of the tree 15 | for l = 1:m 16 | le = int16(2**l); 17 | le2 = le/2; 18 | ur = 1; 19 | ui = 0; 20 | sr = cos(pi/le2); # real part sinusoid 21 | si = -sin(pi/le2); # complex part sinusoid 22 | 23 | # for each node in this level of the tree 24 | for j = 1:le2 25 | # calculate the butterfly for this node 26 | for i = j:le:n 27 | if i <= length(rex) - le2 28 | ip = i + le2; 29 | else 30 | ip = i; 31 | end 32 | 33 | #[i le2 ip] 34 | 35 | tr = rex(ip) * ur - imx(ip) * ui; 36 | ti = rex(ip) * ui + imx(ip) * ur; 37 | rex(ip) = rex(i) - tr; 38 | imx(ip) = imx(i) - ti; 39 | rex(i) = rex(i) + tr; 40 | imx(i) = imx(i) + ti; 41 | end 42 | tr = ur; 43 | ur = tr * sr - ui * si; 44 | ui = tr * si + ui * sr; 45 | end 46 | end 47 | end -------------------------------------------------------------------------------- /Ch12_Fast_Fourier_Transform/fft.py: -------------------------------------------------------------------------------- 1 | import math 2 | 3 | def fft(rex, imx): 4 | n = len(rex) 5 | nm1 = n-1 6 | nd2 = int(n/2) 7 | m = int(math.log2(n)/math.log2(2)) 8 | j = nd2 9 | 10 | # bit reversal 11 | rex_rev = bitrev(rex) 12 | # print(rex_rev) 13 | imx_rev = bitrev(imx) 14 | # print(imx_rev) 15 | 16 | # loop for each stage 17 | for l in range(1,m): 18 | le = int(2**l) 19 | le2 = int(le/2) 20 | ur = 1 21 | ui = 0 22 | sr = math.cos(math.pi / le2) 23 | si = -math.sin(math.pi / le2) 24 | 25 | # loop for each sub-dft 26 | for j in range(1, le2): 27 | jm1 = j-1 28 | # loop for each butterfly 29 | for i in range(jm1, nm1, le): 30 | ip = i + le2 31 | # butterfly 32 | tr = rex[ip] * ur - imx[ip] * ui 33 | ti = rex[ip] * ui + imx[ip] * ur 34 | rex[ip] = rex[i] - tr 35 | imx[ip] = imx[i] - ti 36 | rex[i] = rex[i] + tr 37 | imx[i] = imx[i] + ti 38 | tr = ur 39 | ur = tr * sr - ui * si 40 | ui = tr * si + ui * sr 41 | return [rex, imx] 42 | 43 | 44 | 45 | def inverse_fft(rex, imx): 46 | n = len(rex) 47 | for k in range(0,n): 48 | imx[k] = -imx[k] 49 | 50 | [rex,imx] = fft(rex,imx) 51 | 52 | for i in range(0,n-1): 53 | rex[i] = rex[i] / n 54 | imx[i] = -imx[i] / n 55 | 56 | return [rex, imx] 57 | 58 | 59 | 60 | 61 | def bitrev(L): 62 | n = math.ceil(math.log2(len(L))) # normalize binary numbers to this length 63 | # B = [bin(s)[2:].zfill(n) for s in L] 64 | 65 | # convert to binary, keep only numeric portion 66 | B = [bin(s).replace('0b','') for s in L] 67 | # normalize to length n by prepending appropriate number of zeros, preserving negation when present 68 | B = [s.zfill(n) if s[0] != '-' else '-'+s[1:].zfill(n) for s in B] 69 | 70 | for i in range(0, len(B)): 71 | try: 72 | # negative number matches on reversed negative only, positive on reversed positive only 73 | if (B[i][0] == '-'): # handle negatives 74 | j = B.index('-'+B[i][1:][::-1]) # extract numeric part, reverse it, then prepend neg sign & search 75 | else: # handle positives 76 | j = B.index(B[i][::-1]) 77 | except ValueError: # no reverse match, skip to next iteration 78 | continue 79 | if j >= i: 80 | B[j], B[i] = B[i], B[j] 81 | return [int(b,2) for b in B] 82 | 83 | 84 | def fft_decompose(S): 85 | y1 = [] 86 | y2 = [] 87 | for k in range(0,len(S)): 88 | if k % 2 == 0: 89 | y2.append(S[k]) 90 | else: 91 | y1.append(S[k]) 92 | 93 | if len(y1) > 1: 94 | y1 = fft_decompose(y1) 95 | y2 = fft_decompose(y2) 96 | 97 | x = [] 98 | x.append(y1) 99 | x.append(y2) 100 | x = [item for sublist in x for item in sublist] 101 | return x 102 | 103 | 104 | 105 | 106 | if __name__ == "__main__": 107 | # n = 16 108 | # imx = [0]*n 109 | # S1 = [math.sin(s) for s in range(0,n)] 110 | # S2 = [2 * math.sin(2 * s + 2) for s in range(0,n)] 111 | # rex = [int(a+b) for a,b in zip(S1,S2)] # normalized to ints, dealing with binary floats requires lots of special handling... 112 | # print(rex) 113 | # print("="*50) 114 | 115 | # [rex2, imx2] = fft(rex, imx) 116 | # print(rex2) 117 | # print(imx2) 118 | # print("="*50) 119 | 120 | # [rex3, imx3] = inverse_fft(rex2, imx2) 121 | # print(rex3) 122 | # print(imx3) 123 | 124 | S = [x for x in range(0,16)] 125 | print(S) 126 | print(fft_decompose(S)) -------------------------------------------------------------------------------- /Ch12_Fast_Fourier_Transform/fft_decompose.m: -------------------------------------------------------------------------------- 1 | # implements decomposition shown in figure 12-2 2 | # given: S = 0:15; 3 | # returns: [0 8 4 12 2 10 6 14 1 9 5 13 3 11 7 15] 4 | function y = fft_decompose(S) 5 | y1 = []; 6 | y2 = []; 7 | for k = 1:length(S) 8 | if mod(k,2) == 0 9 | y2(end + 1) = S(k); 10 | else 11 | y1(end + 1) = S(k); 12 | end 13 | end 14 | if length(y1) > 1 15 | y1 = fft_decompose(y1); 16 | y2 = fft_decompose(y2); 17 | end 18 | y = [y1 y2]; 19 | end -------------------------------------------------------------------------------- /Ch12_Fast_Fourier_Transform/fft_run.m: -------------------------------------------------------------------------------- 1 | n = 2*pi; 2 | s1 = sin(0:.1:n); 3 | s2 = 2*sin(0:.1:n); 4 | rex = s1 + s2; 5 | imx = zeros(1,length(rex)); 6 | 7 | [rex2, imx2] = fft(rex,imx); 8 | [rex3, imx3] = inverse_fft(rex2, imx2); 9 | y = rex3 + imx3; -------------------------------------------------------------------------------- /Ch12_Fast_Fourier_Transform/interlace.m: -------------------------------------------------------------------------------- 1 | # implements the interlacing algorithm demonstrated in figure 12-4. 2 | # given: x1 = [1 2 3 4] x2 = [5 6 7 8] 3 | # returns: [1 5 2 6 3 7 4 8] 4 | # octave is a pain when dealing with strings.... 5 | function y = interlace(x1, x2) 6 | y = []; 7 | for k = 1:length(x1) 8 | y(end + 1) = x1(k); 9 | y(end + 1) = x2(k); 10 | k += 1; 11 | end 12 | end -------------------------------------------------------------------------------- /Ch12_Fast_Fourier_Transform/inverse_fft.m: -------------------------------------------------------------------------------- 1 | function [rex, imx] = inverse_fft(rex, imx) 2 | n = length(rex); 3 | for k = 1:n 4 | imx(k) = -imx(k); 5 | end 6 | 7 | [rex, imx] = fft(rex, imx); 8 | 9 | for i = 1:n 10 | rex(i) = rex(i)/n; 11 | imx(i) = -imx(i)/n; 12 | end 13 | end -------------------------------------------------------------------------------- /Ch12_Fast_Fourier_Transform/negfreq.m: -------------------------------------------------------------------------------- 1 | function [ReX, ImX] = negfreq(ReX, ImX, N) 2 | M = int16((N/2)) + 1 3 | for k = M:N 4 | k 5 | ReX(k) = ReX(N-k+1); 6 | ImX(k) = -ImX(N-k+1); 7 | end 8 | end -------------------------------------------------------------------------------- /Ch23_Image_Formation/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | "configurations": [ 4 | { 5 | "name": "Python", 6 | "type": "python", 7 | "request": "launch", 8 | "stopOnEntry": true, 9 | "pythonPath": "${config.python.pythonPath}", 10 | "program": "${file}", 11 | "debugOptions": [ 12 | "WaitOnAbnormalExit", 13 | "WaitOnNormalExit", 14 | "RedirectOutput" 15 | ] 16 | }, 17 | { 18 | "name": "Integrated Terminal/Console", 19 | "type": "python", 20 | "request": "launch", 21 | "stopOnEntry": true, 22 | "pythonPath": "${config.python.pythonPath}", 23 | "program": "${file}", 24 | "console": "integratedTerminal", 25 | "debugOptions": [ 26 | "WaitOnAbnormalExit", 27 | "WaitOnNormalExit" 28 | ] 29 | }, 30 | { 31 | "name": "External Terminal/Console", 32 | "type": "python", 33 | "request": "launch", 34 | "stopOnEntry": true, 35 | "pythonPath": "${config.python.pythonPath}", 36 | "program": "${file}", 37 | "console": "externalTerminal", 38 | "debugOptions": [ 39 | "WaitOnAbnormalExit", 40 | "WaitOnNormalExit" 41 | ] 42 | }, 43 | { 44 | "name": "Django", 45 | "type": "python", 46 | "request": "launch", 47 | "stopOnEntry": true, 48 | "pythonPath": "${config.python.pythonPath}", 49 | "program": "${workspaceRoot}/manage.py", 50 | "args": [ 51 | "runserver", 52 | "--noreload" 53 | ], 54 | "debugOptions": [ 55 | "WaitOnAbnormalExit", 56 | "WaitOnNormalExit", 57 | "RedirectOutput", 58 | "DjangoDebugging" 59 | ] 60 | }, 61 | { 62 | "name": "Flask", 63 | "type": "python", 64 | "request": "launch", 65 | "stopOnEntry": true, 66 | "pythonPath": "${config.python.pythonPath}", 67 | "program": "${workspaceRoot}/run.py", 68 | "args": [], 69 | "debugOptions": [ 70 | "WaitOnAbnormalExit", 71 | "WaitOnNormalExit", 72 | "RedirectOutput" 73 | ] 74 | }, 75 | { 76 | "name": "Watson", 77 | "type": "python", 78 | "request": "launch", 79 | "stopOnEntry": true, 80 | "pythonPath": "${config.python.pythonPath}", 81 | "program": "${workspaceRoot}/console.py", 82 | "args": [ 83 | "dev", 84 | "runserver", 85 | "--noreload=True" 86 | ], 87 | "debugOptions": [ 88 | "WaitOnAbnormalExit", 89 | "WaitOnNormalExit", 90 | "RedirectOutput" 91 | ] 92 | }, 93 | { 94 | "name": "Attach (Remote Debug)", 95 | "type": "python", 96 | "request": "attach", 97 | "localRoot": "${workspaceRoot}", 98 | "remoteRoot": "${workspaceRoot}", 99 | "port": 3000, 100 | "secret": "my_secret", 101 | "host": "localhost" 102 | } 103 | ] 104 | } -------------------------------------------------------------------------------- /Ch23_Image_Formation/bilinear_interpolation.py: -------------------------------------------------------------------------------- 1 | # simple bilinear interpolation 2 | # assumes image cells are packed -- no gaps 3 | # i.e. it can't interpolate between cols 10 and 12, only 10-11, 11-12, etc. 4 | 5 | from math import floor, ceil 6 | 7 | class Bilinear: 8 | def interpolate(self, x, y, points): 9 | # horizontal, then vertical 10 | x1 = floor(x) 11 | x2 = ceil(x) 12 | y1 = floor(y) 13 | y2 = ceil(y) 14 | 15 | q11 = points[(x1, y1)] 16 | q12 = points[(x1, y2)] 17 | q21 = points[(x2, y1)] 18 | q22 = points[(x2, y2)] 19 | 20 | a = q11 * (x2 - x) * (y2 - y) 21 | b = q21 * (x - x1) * (y2 - y) 22 | c = q12 * (x2 - x) * (y - y1) 23 | d = q22 * (x - x1) * (y - y1) 24 | 25 | return (a + b + c + d) / ( (x2 - x1) * (y2 - y1) ) 26 | 27 | 28 | if __name__ == "__main__": 29 | points = { 30 | (14,20) : 91, 31 | (14, 21) : 162, 32 | (15, 20) : 210, 33 | (15, 21) : 95 34 | } 35 | B = Bilinear() 36 | B.points = points 37 | 38 | # returns 146.1, different from the text 39 | # but checked it by hand as well 40 | v = B.interpolate(14.5, 20.2, points) 41 | print(str(v)) -------------------------------------------------------------------------------- /Ch23_Image_Formation/eqimg.m: -------------------------------------------------------------------------------- 1 | # simple image histogram equalization experiment 2 | # automatically boosts contrast of pixels having 3 | # the most frequently occurring value in the image 4 | function s = eqimg(r, H) 5 | s = r; 6 | 7 | hi_val = -1; 8 | hi_key = -1; 9 | for [val,key] = H 10 | if val > hi_val 11 | hi_key = str2num(key); 12 | hi_val = val; 13 | end 14 | end 15 | s(s == hi_key) = hi_key * 1.5; 16 | end -------------------------------------------------------------------------------- /Ch23_Image_Formation/gethist.m: -------------------------------------------------------------------------------- 1 | # manually builds histogram of values from the matrix/image 2 | function H = gethist(M) 3 | H._ = 0; # primes with dummy value so H exists later 4 | for m = 1:rows(M) 5 | for n = 1:columns(M) 6 | v = M(m,n); 7 | if isfield(H, num2str(v)) 8 | H.(num2str(v)) = H.(num2str(v)) + 1; 9 | else 10 | H.(num2str(v)) = 1; 11 | end 12 | end 13 | end 14 | end -------------------------------------------------------------------------------- /Ch23_Image_Formation/lena.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davecan/dspguide-code/321a36be08adea511ab728f0a9794866014c064e/Ch23_Image_Formation/lena.jpg -------------------------------------------------------------------------------- /Ch24_Linear_Image_Processing/check.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davecan/dspguide-code/321a36be08adea511ab728f0a9794866014c064e/Ch24_Linear_Image_Processing/check.png -------------------------------------------------------------------------------- /Ch24_Linear_Image_Processing/convolve.m: -------------------------------------------------------------------------------- 1 | # INPUT SIDE algorithm! 2 | # handles arbitrary sized img 3 | # but only works for 3x3 filter kernel 4 | function result = convolve(img,kernel) 5 | x = expand(img); 6 | kernel = flipud(fliplr(kernel)); # have to rotate 180 or the result is inverted 7 | result = zeros(rows(x), columns(x)); 8 | for xrow = 1:rows(x)-2 # -2 offsets to account for positioning the kernel 9 | for xcol = 1:columns(x)-2 # at the top left pixel of the expanded image matrix 10 | # kernel row 1 11 | v = x(xrow,xcol) * kernel(1,1); 12 | v = v + x(xrow, xcol+1) * kernel(1,2); 13 | v = v + x(xrow, xcol+2) * kernel(1,3); 14 | # kernel row 2 15 | v = v + x(xrow+1, xcol) * kernel(2,1); 16 | v = v + x(xrow+1, xcol+1) * kernel(2,2); 17 | v = v + x(xrow+1, xcol+2) * kernel(2,3); 18 | # kernel row 3 19 | v = v + x(xrow+2, xcol) * kernel(3,1); 20 | v = v + x(xrow+2, xcol+1) * kernel(3,2); 21 | v = v + x(xrow+2, xcol+2) * kernel(3,3); 22 | # now set the weighted sum under the center pixel of the filter kernel 23 | result(xrow+1, xcol+1) = v; 24 | end 25 | end 26 | result = reduce(result, img); 27 | end 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /Ch24_Linear_Image_Processing/convolve2.m: -------------------------------------------------------------------------------- 1 | # INPUT SIDE algorithm! 2 | # same as convolve() but with kernel loop 3 | # only handles 3x3 kernels 4 | function result = convolve2(img,kernel) 5 | x = expand(img); 6 | kernel = flipud(fliplr(kernel)); # have to rotate 180 or the result is inverted 7 | result = zeros(rows(x), columns(x)); 8 | for xrow = 1:rows(x)-2 # -2 offsets to account for positioning the kernel 9 | for xcol = 1:columns(x)-2 # at the top left pixel of the expanded image matrix 10 | v = 0; 11 | for krow = 1:rows(kernel) 12 | for kcol = 1:columns(kernel) 13 | v = v + x(xrow+krow-1, xcol+kcol-1) * kernel(krow,kcol); 14 | end 15 | end 16 | # now set the weighted sum under the center pixel of the filter kernel 17 | result(xrow+1, xcol+1) = v; 18 | end 19 | end 20 | result = reduce(result, img); 21 | end -------------------------------------------------------------------------------- /Ch24_Linear_Image_Processing/dog.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davecan/dspguide-code/321a36be08adea511ab728f0a9794866014c064e/Ch24_Linear_Image_Processing/dog.jpg -------------------------------------------------------------------------------- /Ch24_Linear_Image_Processing/edgify.m: -------------------------------------------------------------------------------- 1 | function y = edgify(img, f) 2 | y = img; 3 | for i = 1:3 4 | y(:,:,i) = convolve(img(:,:,i),f); 5 | end 6 | end -------------------------------------------------------------------------------- /Ch24_Linear_Image_Processing/expand.m: -------------------------------------------------------------------------------- 1 | # surrounds matrix with zero values to prep for convolution 2 | # given: 3 | # 1 2 3 4 | # 4 5 6 5 | # returns: 6 | # 0 0 0 0 0 7 | # 0 1 2 3 0 8 | # 0 4 5 6 0 9 | # 0 0 0 0 0 10 | function y = expand(x) 11 | a = x; 12 | b = resize(a,rows(a)+2,columns(a)+2); 13 | c = circshift(b,[1,1]); 14 | y = c; 15 | end -------------------------------------------------------------------------------- /Ch24_Linear_Image_Processing/fourier.m: -------------------------------------------------------------------------------- 1 | function [rex, imx] = fourier(img) 2 | n = columns(img); 3 | m = rows(img); 4 | rex = zeros(m,n); 5 | imx = zeros(m,n); 6 | for i = 1:rows(img) 7 | F = fft(img(i,1:columns(img))); 8 | rex(i,:) = real(F); 9 | imx(i,:) = complex(F); 10 | end 11 | for i = 1:columns(img) 12 | v = rex(1:rows(rex),i) + imx(1:rows(imx),i); 13 | F = fft(v); 14 | rex(:,i) = real(F); 15 | imx(:,i) = complex(F); 16 | end 17 | end 18 | 19 | 20 | img = imread('wall2.jpg'); 21 | imshow(img); 22 | [rex,imx] = fourier(img); 23 | -------------------------------------------------------------------------------- /Ch24_Linear_Image_Processing/reduce.m: -------------------------------------------------------------------------------- 1 | # extract the actual data after convolution -- removes surrounding rows/cols 2 | # extracts matrix of same size as 3 | # big and small must have odd number of rows and columns 4 | function y = reduce(big, small) 5 | # finds center point of big 6 | # then builds back to start/end row/col numbers 7 | # and then extracts the slice from those points. 8 | # bcr -> big center row, scc -> small center column, etc. 9 | bcr = ceil(rows(big)/2); 10 | bcc = ceil(columns(big)/2); 11 | scr = ceil(rows(small)/2); 12 | scc = ceil(columns(small)/2); 13 | start_row = bcr - (scr - 1); # subtracts distance to start row of small 14 | end_row = bcr + (rows(small) - scr); # adds distance to end row of small 15 | start_col = bcc - (scc - 1); 16 | end_col = bcc + (columns(small) - scc); 17 | y = big(start_row:end_row, start_col:end_col); 18 | end -------------------------------------------------------------------------------- /Ch24_Linear_Image_Processing/run.m: -------------------------------------------------------------------------------- 1 | a = [1 2 3; 4 5 6; 7 8 9]; 2 | 3 | f = [0 0 0; 0 1 0; 0 0 0]; # identity 4 | convolve(a,f) 5 | convolve2(a,f) 6 | 7 | f = ones(3); # smoothing 8 | convolve(a,f) 9 | convolve2(a,f) 10 | 11 | f = [-1 -1 -1; -1 3 -1; -1 -1 -1]; # high-pass filter / "edge detection" 12 | convolve(a,f) 13 | convolve2(a,f) 14 | 15 | a = [1 2 3 4 5 6 7; 2 3 4 5 6 7 8; 3 4 5 6 7 8 9; 4 5 6 7 8 9 0; 7 6 5 4 3 2 1; 8 7 6 5 4 3 2; 9 8 7 6 5 4 3; 0 9 8 7 6 5 4]; 16 | f = [0 1 0; 0 2 0; 0 1 0]; 17 | convolve(a,f) 18 | convolve2(a,f) 19 | -------------------------------------------------------------------------------- /Ch24_Linear_Image_Processing/sobel.m: -------------------------------------------------------------------------------- 1 | # crude attempts at the Sobel edge detection at https://en.wikipedia.org/wiki/Sobel_operator 2 | function y = sobel(img) 3 | y = img; 4 | 5 | sobel_horz = [1 0 -1; 2 0 -2; 1 0 -1]; 6 | sobel_vert = [1 2 1; 0 0 0; -1 -2 -1]; 7 | smooth = 3 * ones(3); 8 | 9 | # process each channel separately 10 | for i = 1:3 11 | ch = img(:,:,i); 12 | # apply the sobel operators 13 | ch2 = reduce(conv2(ch, sobel_horz), ch); 14 | ch2 = ch2 + reduce(conv2(ch, sobel_vert), ch); 15 | ch2 = reduce(conv2(ch2, [0 0 0; 0 2 0; 0 0 0]),ch2); 16 | y(:,:,i) = ch2; 17 | end 18 | y = imsmooth(y); 19 | end -------------------------------------------------------------------------------- /Ch24_Linear_Image_Processing/tree.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davecan/dspguide-code/321a36be08adea511ab728f0a9794866014c064e/Ch24_Linear_Image_Processing/tree.jpg -------------------------------------------------------------------------------- /Ch24_Linear_Image_Processing/tree.m: -------------------------------------------------------------------------------- 1 | a = imread('tree.jpg'); 2 | a1 = a(:,:,1); 3 | 4 | # edge detection 5 | f1 = [-1 -1 -1; -1 2 -1; -1 -1 -1]; 6 | b1 = convolve(a1,f1); 7 | imshow(b1) 8 | 9 | # moar edge detection 10 | f2 = [-2 -2 -2; -2 4 -2; -2 -2 -2]; 11 | b2 = convolve(a1,f2); 12 | imshow(b2) 13 | 14 | f3 = 2 * f2; 15 | img = edgify(a, f2); 16 | imshow(img) 17 | 18 | -------------------------------------------------------------------------------- /Ch24_Linear_Image_Processing/valve.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davecan/dspguide-code/321a36be08adea511ab728f0a9794866014c064e/Ch24_Linear_Image_Processing/valve.png -------------------------------------------------------------------------------- /Ch24_Linear_Image_Processing/wall2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davecan/dspguide-code/321a36be08adea511ab728f0a9794866014c064e/Ch24_Linear_Image_Processing/wall2.jpg -------------------------------------------------------------------------------- /Ch25_Special_Imaging_Techniques/closeit.m: -------------------------------------------------------------------------------- 1 | function result = closeit(img) 2 | % CLOSEIT dilates the image, then erodes it 3 | result = erode(dilate(img)); 4 | end -------------------------------------------------------------------------------- /Ch25_Special_Imaging_Techniques/convolve.m: -------------------------------------------------------------------------------- 1 | function result = convolve(img, kernel) 2 | [h w] = size(img); 3 | [kh kw] = size(kernel); 4 | nel = numel(img); % total number elements in the matrix -- equals h * w 5 | result = ones(h, w) * -1; 6 | 7 | kl = reshape(kernel,1,[]); % linearize the kernel 8 | 9 | for li = 1:nel 10 | img_check = []; % contains positions of the pixels in the img to include in the calculations 11 | kern_vals = []; % contains the values from the kernel 12 | 13 | % find image pixels affected by checking linear offsets 14 | % top row 15 | if li - h - 1 > 0; img_check(end+1) = li - h - 1; end; 16 | if li - 1 > 0; img_check(end+1) = li - 1; end; 17 | if li + h - 1 <= nel; img_check(end+1) = li + h - 1; end; 18 | % middle row 19 | if li - h > 0; img_check(end+1) = li - h; end; 20 | img_check(end+1) = li; 21 | if li + h <= nel; img_check(end+1) = li + h; end; 22 | % bottom row 23 | if li - h + 1 > 0; img_check(end+1) = li - h + 1; end; 24 | if li + 1 <= nel; img_check(end+1) = li + 1; end; 25 | if li + h + 1 <= nel; img_check(end+1) = li + h + 1; end; 26 | 27 | % find kernel pixels affected by checking linear offsets 28 | % top row 29 | if any(img_check == li - h - 1) 30 | kern_vals(end+1) = kl(1); % top left always linearized to 1 31 | end; 32 | if any(img_check == li - 1) 33 | kern_vals(end+1) = kl(kh+1); % top center == top left pos shifted 1 column 34 | end 35 | if any(img_check == li + h - 1) 36 | kern_vals(end+1) = kl(kh*2+1); % top right == top left pos shifted 2 columns 37 | end 38 | % middle row 39 | if any(img_check == li - h) 40 | kern_vals(end+1) = kl(2); % mid left always linearized to 2 41 | end 42 | kern_vals(end+1) = kl(5); % center pixel is always used 43 | if any(img_check == li + h) 44 | kern_vals(end+1) = kl(kh*2+2); % mid right == mid left shifted 2 cols 45 | end 46 | % bottom row 47 | if any(img_check == li - h + 1) 48 | kern_vals(end+1) = kl(3); % bottom left always linearized to 3 49 | end 50 | if any(img_check == li + 1) 51 | kern_vals(end+1) = kl(kh*2); % bottom center == 2 * kernel height linearly 52 | end 53 | if any(img_check == li + h + 1) 54 | kern_vals(end+1) = kl(end); % bottom right always end of kernel 55 | end 56 | 57 | img_vals = uint8(img(img_check)); 58 | kern_vals = uint8(kern_vals); 59 | 60 | result(li) = sum(img_vals.*kern_vals); % weighted sum of elements 61 | end 62 | result = uint8(result); 63 | end -------------------------------------------------------------------------------- /Ch25_Special_Imaging_Techniques/cross.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davecan/dspguide-code/321a36be08adea511ab728f0a9794866014c064e/Ch25_Special_Imaging_Techniques/cross.gif -------------------------------------------------------------------------------- /Ch25_Special_Imaging_Techniques/dilate.m: -------------------------------------------------------------------------------- 1 | function result = dilate(img, steps) 2 | % DILATE gets the min value of a moving 3x3 mask centered on each pixel in img. 3 | % IMG = the image to dilate. 4 | % STEPS = the number of times to dilate. 5 | 6 | if nargin == 1 7 | steps = 1; 8 | end 9 | for i = 1:steps 10 | img = morph(img, 'dilate'); 11 | end 12 | result = img; 13 | end -------------------------------------------------------------------------------- /Ch25_Special_Imaging_Techniques/erode.m: -------------------------------------------------------------------------------- 1 | function result = erode(img, steps) 2 | % ERODE gets the min value of a moving 3x3 mask centered on each pixel in img. 3 | % IMG = the image to erode. 4 | % STEPS = the number of times to erode. 5 | 6 | if nargin == 1 7 | steps = 1; 8 | end 9 | for i = 1:steps 10 | img = morph(img, 'erode'); 11 | end 12 | result = img; 13 | end -------------------------------------------------------------------------------- /Ch25_Special_Imaging_Techniques/expand.m: -------------------------------------------------------------------------------- 1 | function y = expand(x, val, passes) 2 | % EXPAND Surrounds the matrix by VAL rows and columns PASSES number of times. 3 | % X = The matrix to expand. 4 | % VAL = The value to surround X with. Default is 0. 5 | % PASSES = The number of times to surround X with VAL. 6 | % given: 7 | % 1 2 3 8 | % 4 5 6 9 | % returns: 10 | % 0 0 0 0 0 11 | % 0 1 2 3 0 12 | % 0 4 5 6 0 13 | % 0 0 0 0 0 14 | 15 | if nargin < 2 16 | val = 0; 17 | end 18 | if nargin < 3 19 | passes = 1; 20 | end 21 | [rows,cols] = size(x); 22 | y = zeros(rows+2*passes,cols+2*passes); 23 | y(:) = val; 24 | start_pos = passes+1; 25 | y(start_pos:end-passes,start_pos:end-passes) = x; 26 | end -------------------------------------------------------------------------------- /Ch25_Special_Imaging_Techniques/fingerprint.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davecan/dspguide-code/321a36be08adea511ab728f0a9794866014c064e/Ch25_Special_Imaging_Techniques/fingerprint.gif -------------------------------------------------------------------------------- /Ch25_Special_Imaging_Techniques/graybars.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davecan/dspguide-code/321a36be08adea511ab728f0a9794866014c064e/Ch25_Special_Imaging_Techniques/graybars.gif -------------------------------------------------------------------------------- /Ch25_Special_Imaging_Techniques/graybars.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davecan/dspguide-code/321a36be08adea511ab728f0a9794866014c064e/Ch25_Special_Imaging_Techniques/graybars.jpg -------------------------------------------------------------------------------- /Ch25_Special_Imaging_Techniques/invader.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davecan/dspguide-code/321a36be08adea511ab728f0a9794866014c064e/Ch25_Special_Imaging_Techniques/invader.gif -------------------------------------------------------------------------------- /Ch25_Special_Imaging_Techniques/lena.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davecan/dspguide-code/321a36be08adea511ab728f0a9794866014c064e/Ch25_Special_Imaging_Techniques/lena.jpg -------------------------------------------------------------------------------- /Ch25_Special_Imaging_Techniques/morph.m: -------------------------------------------------------------------------------- 1 | function result = morph(img, name) 2 | % MORPH_MANUAL Applies a morphological operation to an image using nested loops. 3 | % RESULT = MORPH(IMG, NAME) Applies the specified operation using a 3x3 structuring element / kernel. 4 | % NAME can be either 'erode' or 'dilate'. 5 | 6 | % TODO allow different 3x3 patterns -- can use method of linearized convolve.m in this folder 7 | % TODO allow arbitrary sized structuring elements? 8 | 9 | % Strategy: Treat img as linear array, checking linear offsets from current img pixel based on 10 | % the linear distance of each pixel in the structuring element from its center 11 | 12 | [h w] = size(img); 13 | nel = numel(img); % total number elements in the matrix -- equals h * w 14 | result = ones(h, w) * -1; 15 | 16 | for li = 1:nel 17 | % check linear offsets 18 | check = []; 19 | % top row 20 | if li - h - 1 > 0; check(end+1) = li - h - 1; end; 21 | if li - 1 > 0; check(end+1) = li - 1; end; 22 | if li + h - 1 <= nel; check(end+1) = li + h - 1; end; 23 | % middle row 24 | if li - h > 0; check(end+1) = li - h; end; 25 | check(end+1) = li; 26 | if li + h <= nel; check(end+1) = li + h; end; 27 | % bottom row 28 | if li - h + 1 > 0; check(end+1) = li - h + 1; end; 29 | if li + 1 <= nel; check(end+1) = li + 1; end; 30 | if li + h + 1 <= nel; check(end+1) = li + h + 1; end; 31 | 32 | v = img(check); 33 | 34 | switch name 35 | case 'erode' 36 | result(li) = max(v); 37 | case 'dilate' 38 | result(li) = min(v); 39 | end 40 | end 41 | end -------------------------------------------------------------------------------- /Ch25_Special_Imaging_Techniques/morph_loop.m: -------------------------------------------------------------------------------- 1 | function result = morph_loop(img, name, kernel) 2 | % MORPH_MANUAL Applies a morphological operation to an image using nested loops. 3 | % RESULT = MORPH(IMG, NAME) Applies the specified operation using the default masking kernel. 4 | % RESULT = MORPH(IMG, NAME, KERNEL) Applies the specified operation using the specified masking kernel. 5 | % NAME can be either 'erode' or 'dilate'. 6 | % KERNEL is a 3x3 matrix. All nonzero values mark pixels that are tested for the center pixel. 7 | % The kernel is swept across the img as in convolution. 8 | % DEFAULT KERNEL = [1 1 1; 1 1 1; 1 1 1]. 9 | 10 | default_kernel = [1 1 1; 1 1 1; 1 1 1]; 11 | if nargin < 3 12 | kernel = default_kernel; % pattern to check for morph operation 13 | end 14 | if nargin < 4 15 | if ischar(kernel) && kernel == 'default' 16 | kernel = default_kernel; 17 | end 18 | end 19 | [r,c] = size(img); 20 | if strcmp(name, 'erode') 21 | wrapval = -1; 22 | else 23 | wrapval = 999; 24 | end 25 | result = ones(r, c) * -1; 26 | x = expand(img, wrapval); 27 | [r,c] = size(x); 28 | 29 | F = find(kernel); % Gets the linearized positions of all nonzero values in the kernel. 30 | % These mark where the morph should check for differences in value. 31 | 32 | kern_row_offset = 2; 33 | kern_col_offset = 2; 34 | 35 | for m = 1:r-2 % The -2 offset accounts for positioning the kernel 36 | for n = 1:c-2 % at the top left pixel of the expanded image matrix. 37 | % Extract region of interest centered on current pixel of source img. 38 | s = x(m:m+kern_row_offset,n:n+kern_col_offset); 39 | switch name 40 | case 'erode' 41 | result(m,n) = max(s(F)); % checks all linear index positions marked in the kernel as found in F 42 | case 'dilate' 43 | result(m,n) = min(s(F)); 44 | end 45 | end 46 | end 47 | end 48 | -------------------------------------------------------------------------------- /Ch25_Special_Imaging_Techniques/openit.m: -------------------------------------------------------------------------------- 1 | function result = openit(img) 2 | % OPENIT erodes the image, then dilates it 3 | result = dilate(erode(img)); 4 | end -------------------------------------------------------------------------------- /Ch25_Special_Imaging_Techniques/reduce.m: -------------------------------------------------------------------------------- 1 | function y = reduce(big, small) 2 | % REDUCE Extracts matrix of same size as SMALL from the center of BIG. 3 | % This is the opposite operation of EXPAND. 4 | % BIG = The larger matrix. Contains SMALL. Must have odd number of rows & cols. 5 | % SMALL = The smaller matrix. Must have odd number of rows & cols. 6 | 7 | % finds center point of big 8 | % then builds back to start/end row/col numbers 9 | % and then extracts the slice from those points. 10 | % bcr -> big center row, scc -> small center column, etc. 11 | [rows_big, cols_big] = size(big); 12 | [rows_small, cols_small] = size(small); 13 | bcr = ceil(rows_big/2); 14 | bcc = ceil(cols_big/2); 15 | scr = ceil(rows_small/2); 16 | scc = ceil(cols_small/2); 17 | start_row = bcr - (scr - 1); % subtracts distance to start row of small 18 | end_row = bcr + (rows_small - scr); % adds distance to end row of small 19 | start_col = bcc - (scc - 1); 20 | end_col = bcc + (cols_small - scc); 21 | y = big(start_row:end_row, start_col:end_col); 22 | end -------------------------------------------------------------------------------- /Ch25_Special_Imaging_Techniques/shape1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davecan/dspguide-code/321a36be08adea511ab728f0a9794866014c064e/Ch25_Special_Imaging_Techniques/shape1.gif -------------------------------------------------------------------------------- /Ch25_Special_Imaging_Techniques/test1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davecan/dspguide-code/321a36be08adea511ab728f0a9794866014c064e/Ch25_Special_Imaging_Techniques/test1.jpg -------------------------------------------------------------------------------- /Ch25_Special_Imaging_Techniques/willbreak.m: -------------------------------------------------------------------------------- 1 | function b = willbreak(img, rowind, colind, neighborhood) 2 | % WILLBREAK determines if a point removal will break a line in the image. 3 | % IMG = a logical b/w image. 4 | % ROWIND = row index of the pixel to check. 5 | % COLIND = col index of the pixel to check. 6 | % NEIGHBORHOOD = neighborhood of points to check: 'close' or 'distant' or 'all'. Default is 'close' only. 7 | 8 | % TODO this doesn't handle corner cases in distant mode -- linearizing causes checks to wrap too far 9 | 10 | if nargin < 4 11 | neighborhood = 'close'; 12 | end 13 | 14 | % strategy is to treat the matrix as a linear array 15 | li = sub2ind(size(img), rowind, colind); % get linear index of the coordinate pair 16 | [h w] = size(img); 17 | els = length(img); 18 | b = 0; 19 | 20 | if img(rowind,colind) ~= 0 21 | return; 22 | end 23 | 24 | % check offsets -- close neighbors to the left and right are H pixels away 25 | check = []; 26 | 27 | if strcmp(neighborhood,'close') || strcmp(neighborhood,'all') 28 | if li - h > 0; check(end+1) = li - h; end; 29 | if li - 1 > 0; check(end+1) = li - 1; end; 30 | if li + 1 <= els; check(end+1) = li + 1; end; 31 | if li + h <= els; check(end+1) = li + h; end; 32 | end 33 | if strcmp(neighborhood,'distant') || strcmp(neighborhood,'all') % distants are H +/- 1 linear pixels away 34 | if li - h - 1 > 0; check(end+1) = li - h - 1; end; 35 | if li - h + 1 > 0; check(end+1) = li - h + 1; end; 36 | if li + h - 1 <= els; check(end+1) = li + h - 1; end; 37 | if li + h + 1 <= els; check(end+1) = li + h + 1; end; 38 | end 39 | 40 | v = img(check); % get all values from img at indices from check 41 | b = sum(v == 0) > 1; % true if at least two of the checked index values in img are 0, false otherwise 42 | end -------------------------------------------------------------------------------- /Ch25_Special_Imaging_Techniques/x.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davecan/dspguide-code/321a36be08adea511ab728f0a9794866014c064e/Ch25_Special_Imaging_Techniques/x.gif -------------------------------------------------------------------------------- /Ch27_Data_Compression/README.txt: -------------------------------------------------------------------------------- 1 | The text discusses using delta encoding on slowly varying data to reduce the amplitude of the signal, then applying run-length encoding to compress it. 2 | 3 | Result is 46% savings in byte size for slowly-varying data randomly generated by the `slowdata()` function. 4 | 5 | Demo: 6 | 7 | data = slowdata(512); 8 | plot(data) 9 | 10 | See slowdata.png 11 | 12 | delta_data = delta_decode(data); 13 | plot(delta_data) 14 | 15 | See slowdata_delta.png 16 | 17 | rle_data = rle(delta_data); 18 | plot(rle_data) 19 | 20 | See slowdata_rle.png 21 | 22 | >>> whos('data') 23 | Name Size Bytes Class Attributes 24 | 25 | data 1x512 4096 double 26 | 27 | >>> whos('delta_data') 28 | Name Size Bytes Class Attributes 29 | 30 | delta_data 1x512 4096 double 31 | 32 | >>> whos('rle_data') 33 | Name Size Bytes Class Attributes 34 | 35 | rle_data 1x238 1904 double 36 | 37 | >>> 1904/4096 38 | 39 | ans = 40 | 41 | 0.4648 42 | 43 | -------------------------------------------------------------------------------- /Ch27_Data_Compression/caesar.m: -------------------------------------------------------------------------------- 1 | function y=caesar(x,n) 2 | if nargin < 2; n = 5; end; 3 | x(find(x == ' ')) = []; % delete spaces 4 | x = upper(x); 5 | y = char(mod(double(x) + n - 64, 26) + 64); 6 | end 7 | 8 | -------------------------------------------------------------------------------- /Ch27_Data_Compression/delta_encode.m: -------------------------------------------------------------------------------- 1 | % implements delta encoding algorithm for slowly varying signals 2 | function y = delta_encode(x) 3 | y = [x(1) diff(x)]; 4 | end 5 | 6 | % example 7 | % msg = [17 19 24 24 24 21 15 10 89 95 96 96 96 95 94 94 95 93 90 87 86 86]; 8 | % delta_encode(msg) -------------------------------------------------------------------------------- /Ch27_Data_Compression/rle.m: -------------------------------------------------------------------------------- 1 | function out = rle(msg, val) 2 | % RLE Implements run-length encoding as described in the book. 3 | % MSG = the message to encode. 4 | % VAL = the integer value to compress. Default = 0. 5 | 6 | if nargin < 2 7 | val = 0; 8 | end 9 | out = []; 10 | nv = find(msg ~= val); % nv contains all index positions having values != val 11 | nvl = length(nv); 12 | for i = 1:nvl 13 | out(end+1) = msg(nv(i)); 14 | if (nv(i) >= 1) && (i < nvl) && (abs(nv(i+1) - nv(i)) > 1) 15 | out(end+1) = val; 16 | out(end+1) = nv(i+1) - nv(i) - 1; 17 | end 18 | end 19 | end -------------------------------------------------------------------------------- /Ch27_Data_Compression/rledecode.m: -------------------------------------------------------------------------------- 1 | function msg = rledecode(cmp, val) 2 | % RLEDECODE Implements a run-length decoding algorithm. 3 | % CMP = the RLE-compressed message to decode. 4 | % VAL = the integer value to expand. Default = 0. 5 | 6 | if nargin < 2 7 | val = 0; 8 | end 9 | msg = []; 10 | len = length(cmp); 11 | i = 1; 12 | while i <= len 13 | if cmp(i) == val 14 | n = cmp(i+1); % next array slot contains number of repeats 15 | for k = 1:n 16 | msg(end+1) = val; 17 | end 18 | i = i + 2; 19 | else 20 | msg(end+1) = cmp(i); 21 | i = i + 1; 22 | end 23 | end 24 | end -------------------------------------------------------------------------------- /Ch27_Data_Compression/simple_rle.m: -------------------------------------------------------------------------------- 1 | % run-length encoding for only zeroes 2 | function out = simple_rle(msg) 3 | out = []; 4 | nv = find(msg); 5 | nvl = length(nv); 6 | for i = 1:nvl 7 | out(end+1) = msg(nv(i)); 8 | if (nv(i) >= 1) && (i < nvl) && (abs(nv(i+1) - nv(i)) > 1) 9 | out(end+1) = 0; 10 | out(end+1) = nv(i+1) - nv(i) - 1; 11 | end 12 | end 13 | end -------------------------------------------------------------------------------- /Ch27_Data_Compression/slowdata.m: -------------------------------------------------------------------------------- 1 | function y = slowdata(n) 2 | y = [1]; 3 | for i = 2:n 4 | r = randi(10); 5 | if r <= 8 6 | y(end+1) = y(i-1); 7 | % can rise/fall by 1% 8 | elseif r <= 9 9 | y(end+1) = y(i-1) + y(i-1) * 0.01; 10 | else 11 | y(end+1) = y(i-1) - y(i-1) * 0.01; 12 | end 13 | end 14 | end -------------------------------------------------------------------------------- /Ch27_Data_Compression/slowdata.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davecan/dspguide-code/321a36be08adea511ab728f0a9794866014c064e/Ch27_Data_Compression/slowdata.png -------------------------------------------------------------------------------- /Ch27_Data_Compression/slowdata_delta.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davecan/dspguide-code/321a36be08adea511ab728f0a9794866014c064e/Ch27_Data_Compression/slowdata_delta.png -------------------------------------------------------------------------------- /Ch27_Data_Compression/slowdata_delta_rle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davecan/dspguide-code/321a36be08adea511ab728f0a9794866014c064e/Ch27_Data_Compression/slowdata_delta_rle.png -------------------------------------------------------------------------------- /Ch27_Data_Compression/test_rle.m: -------------------------------------------------------------------------------- 1 | % example from the book 2 | msg = [17 8 54 0 0 0 97 5 16 0 45 23 0 0 0 0 0 3 67 0 0 8]; 3 | cmp = rle(msg) 4 | 5 | % good compression 6 | msg = [11 0 22 0 0 33 0 0 0 44 0 0 0 0 55 0 0 0 0 0 66 0 0 0 0 0 0 77 0 0 0 0 0 0 0 88 0 0 0 0 0 0 0 0 99 0 0 0 0 0 0 0 0 0 111 0 0 0 0 0 0 0 0 0 0 122]; 7 | cmp = rle(msg) 8 | 9 | % custom values 10 | msg0 = [1 0 2 0 0 3 0 0 0 4 0 0 0 0 5]; 11 | cmp = rle(msg0,0) 12 | 13 | msg8 = [1 8 2 8 8 3 8 8 8 4 8 8 8 8 5]; 14 | cmp = rle(msg8,8) 15 | 16 | % roundtrip tests 17 | cmp0 = rle(msg0); 18 | rld0 = rledecode(cmp0); 19 | unique(msg0 == rld0) 20 | 21 | cmp8 = rle(msg8,8); 22 | rld8 = rledecode(cmp8,8); 23 | unique(msg8 == rld8) -------------------------------------------------------------------------------- /Ch27_Data_Compression/uncaesar.m: -------------------------------------------------------------------------------- 1 | function y = uncaesar(x,n) 2 | if nargin < 2; n = 5; end; 3 | m = 26 - n; 4 | y = char(mod(double(x) + m - 64, 26) + 64); 5 | end -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Some python and Octave/MATLAB scripts to help explore some of the concepts and algorithms from the outstanding free textbook [*The Scientist and Engineer's Guide to Digital Signal Processing*](http://www.dspguide.com/). I make no pretense that these are good scripts, and there are certainly far better implementations. Most of these are intentionally not coded optimally because they are exploring how signals work conceptually, not how the code should be written in reality. It started as an excuse to relearn some python, then switched to Octave, then MATLAB. 2 | -------------------------------------------------------------------------------- /sandbox/AF.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davecan/dspguide-code/321a36be08adea511ab728f0a9794866014c064e/sandbox/AF.png -------------------------------------------------------------------------------- /sandbox/al.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davecan/dspguide-code/321a36be08adea511ab728f0a9794866014c064e/sandbox/al.jpg -------------------------------------------------------------------------------- /sandbox/alzoomed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davecan/dspguide-code/321a36be08adea511ab728f0a9794866014c064e/sandbox/alzoomed.png -------------------------------------------------------------------------------- /sandbox/bad.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davecan/dspguide-code/321a36be08adea511ab728f0a9794866014c064e/sandbox/bad.jpg -------------------------------------------------------------------------------- /sandbox/bad2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davecan/dspguide-code/321a36be08adea511ab728f0a9794866014c064e/sandbox/bad2.jpg -------------------------------------------------------------------------------- /sandbox/batman.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davecan/dspguide-code/321a36be08adea511ab728f0a9794866014c064e/sandbox/batman.png -------------------------------------------------------------------------------- /sandbox/child.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davecan/dspguide-code/321a36be08adea511ab728f0a9794866014c064e/sandbox/child.png -------------------------------------------------------------------------------- /sandbox/dark.m: -------------------------------------------------------------------------------- 1 | pkg load image; 2 | 3 | a = imread('bad.jpg'); 4 | 5 | b = a*12; # ultra brighten 6 | b = imsmooth(b); 7 | imshow(b); -------------------------------------------------------------------------------- /sandbox/dog.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davecan/dspguide-code/321a36be08adea511ab728f0a9794866014c064e/sandbox/dog.jpg -------------------------------------------------------------------------------- /sandbox/dots.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davecan/dspguide-code/321a36be08adea511ab728f0a9794866014c064e/sandbox/dots.png -------------------------------------------------------------------------------- /sandbox/dots_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davecan/dspguide-code/321a36be08adea511ab728f0a9794866014c064e/sandbox/dots_3.png -------------------------------------------------------------------------------- /sandbox/dots_3_grayscale.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davecan/dspguide-code/321a36be08adea511ab728f0a9794866014c064e/sandbox/dots_3_grayscale.png -------------------------------------------------------------------------------- /sandbox/dots_3gray.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davecan/dspguide-code/321a36be08adea511ab728f0a9794866014c064e/sandbox/dots_3gray.gif -------------------------------------------------------------------------------- /sandbox/fftpulse.m: -------------------------------------------------------------------------------- 1 | # https://www.youtube.com/watch?v=XofmaKJ8RnA 2 | 3 | img_pulse = double(imread('pulse.png')); 4 | img_pulse = rgb2gray(img_pulse); 5 | pulse_freq = fft2(img_pulse); 6 | imshow(pulse_freq) 7 | imshow(abs(pulse_freq)) 8 | imshow(imadjust(abs(pulse_freq))) 9 | imshow(imadjust(abs(fftshift(pulse2_freq)))) 10 | 11 | 12 | img_pulse2 = double(imread('pulse2.png')); 13 | img_pulse2 = rgb2gray(img_pulse2); 14 | pulse2_freq = fft2(img_pulse2); 15 | imshow(pulse2_freq) 16 | imshow(abs(pulse2_freq)) 17 | imshow(imadjust(abs(pulse2_freq))) 18 | imshow(imadjust(abs(fftshift(pulse2_freq)))) -------------------------------------------------------------------------------- /sandbox/grad3.txt: -------------------------------------------------------------------------------- 1 | >> grad3 = imread('gradient3px.png'); 2 | >> grad3 3 | grad3 = 4 | 5 | 0 1 2 6 | 0 1 2 7 | 0 1 2 8 | 9 | >> imfinfo('gradient3px.png'); 10 | >> diary off 11 | >> grad3 = imread('gradient3px.png'); 12 | >> grad3 13 | grad3 = 14 | 15 | 0 1 2 16 | 0 1 2 17 | 0 1 2 18 | 19 | >> I = imfinfo('gradient3px.png'); 20 | >> I 21 | I = 22 | 23 | scalar structure containing the fields: 24 | 25 | Filename = C:\Users\David\Dropbox\College\UMUC\CMSC 465 Image and Signal Processing\dspguide-code\dspguide-code\sandbox\gradient3px.png 26 | FileModDate = 27-Apr-2017 10:15:06 27 | FileSize = 939 28 | Format = PNG 29 | FormatVersion = 30 | Width = 3 31 | Height = 3 32 | BitDepth = 8 33 | ColorType = indexed 34 | DelayTime = 0 35 | DisposalMethod = 36 | LoopCount = 0 37 | ByteOrder = undefined 38 | Gamma = 0.45455 39 | Chromaticities = 40 | 41 | 0.312700 0.329000 0.640000 0.330000 0.300000 0.600000 0.150000 0.060000 42 | 43 | Comment = 44 | Quality = 75 45 | Compression = undefined 46 | Colormap = 47 | 48 | 0.00000 0.00000 0.00000 49 | 0.49804 0.49804 0.49804 50 | 1.00000 1.00000 1.00000 51 | 0.00000 0.00000 0.00000 52 | 0.00000 0.00000 0.00000 53 | 0.00000 0.00000 0.00000 54 | 0.00000 0.00000 0.00000 55 | 0.00000 0.00000 0.00000 56 | 0.00000 0.00000 0.00000 57 | 0.00000 0.00000 0.00000 58 | 0.00000 0.00000 0.00000 59 | 0.00000 0.00000 0.00000 60 | 0.00000 0.00000 0.00000 61 | 0.00000 0.00000 0.00000 62 | 0.00000 0.00000 0.00000 63 | 0.00000 0.00000 0.00000 64 | 0.00000 0.00000 0.00000 65 | 0.00000 0.00000 0.00000 66 | 0.00000 0.00000 0.00000 67 | 0.00000 0.00000 0.00000 68 | 0.00000 0.00000 0.00000 69 | 0.00000 0.00000 0.00000 70 | 0.00000 0.00000 0.00000 71 | 0.00000 0.00000 0.00000 72 | 0.00000 0.00000 0.00000 73 | 0.00000 0.00000 0.00000 74 | 0.00000 0.00000 0.00000 75 | 0.00000 0.00000 0.00000 76 | 0.00000 0.00000 0.00000 77 | 0.00000 0.00000 0.00000 78 | 0.00000 0.00000 0.00000 79 | 0.00000 0.00000 0.00000 80 | 0.00000 0.00000 0.00000 81 | 0.00000 0.00000 0.00000 82 | 0.00000 0.00000 0.00000 83 | 0.00000 0.00000 0.00000 84 | 0.00000 0.00000 0.00000 85 | 0.00000 0.00000 0.00000 86 | 0.00000 0.00000 0.00000 87 | 0.00000 0.00000 0.00000 88 | 0.00000 0.00000 0.00000 89 | 0.00000 0.00000 0.00000 90 | 0.00000 0.00000 0.00000 91 | 0.00000 0.00000 0.00000 92 | 0.00000 0.00000 0.00000 93 | 0.00000 0.00000 0.00000 94 | 0.00000 0.00000 0.00000 95 | 0.00000 0.00000 0.00000 96 | 0.00000 0.00000 0.00000 97 | 0.00000 0.00000 0.00000 98 | 0.00000 0.00000 0.00000 99 | 0.00000 0.00000 0.00000 100 | 0.00000 0.00000 0.00000 101 | 0.00000 0.00000 0.00000 102 | 0.00000 0.00000 0.00000 103 | 0.00000 0.00000 0.00000 104 | 0.00000 0.00000 0.00000 105 | 0.00000 0.00000 0.00000 106 | 0.00000 0.00000 0.00000 107 | 0.00000 0.00000 0.00000 108 | 0.00000 0.00000 0.00000 109 | 0.00000 0.00000 0.00000 110 | 0.00000 0.00000 0.00000 111 | 0.00000 0.00000 0.00000 112 | 0.00000 0.00000 0.00000 113 | 0.00000 0.00000 0.00000 114 | 0.00000 0.00000 0.00000 115 | 0.00000 0.00000 0.00000 116 | 0.00000 0.00000 0.00000 117 | 0.00000 0.00000 0.00000 118 | 0.00000 0.00000 0.00000 119 | 0.00000 0.00000 0.00000 120 | 0.00000 0.00000 0.00000 121 | 0.00000 0.00000 0.00000 122 | 0.00000 0.00000 0.00000 123 | 0.00000 0.00000 0.00000 124 | 0.00000 0.00000 0.00000 125 | 0.00000 0.00000 0.00000 126 | 0.00000 0.00000 0.00000 127 | 0.00000 0.00000 0.00000 128 | 0.00000 0.00000 0.00000 129 | 0.00000 0.00000 0.00000 130 | 0.00000 0.00000 0.00000 131 | 0.00000 0.00000 0.00000 132 | 0.00000 0.00000 0.00000 133 | 0.00000 0.00000 0.00000 134 | 0.00000 0.00000 0.00000 135 | 0.00000 0.00000 0.00000 136 | 0.00000 0.00000 0.00000 137 | 0.00000 0.00000 0.00000 138 | 0.00000 0.00000 0.00000 139 | 0.00000 0.00000 0.00000 140 | 0.00000 0.00000 0.00000 141 | 0.00000 0.00000 0.00000 142 | 0.00000 0.00000 0.00000 143 | 0.00000 0.00000 0.00000 144 | 0.00000 0.00000 0.00000 145 | 0.00000 0.00000 0.00000 146 | 0.00000 0.00000 0.00000 147 | 0.00000 0.00000 0.00000 148 | 0.00000 0.00000 0.00000 149 | 0.00000 0.00000 0.00000 150 | 0.00000 0.00000 0.00000 151 | 0.00000 0.00000 0.00000 152 | 0.00000 0.00000 0.00000 153 | 0.00000 0.00000 0.00000 154 | 0.00000 0.00000 0.00000 155 | 0.00000 0.00000 0.00000 156 | 0.00000 0.00000 0.00000 157 | 0.00000 0.00000 0.00000 158 | 0.00000 0.00000 0.00000 159 | 0.00000 0.00000 0.00000 160 | 0.00000 0.00000 0.00000 161 | 0.00000 0.00000 0.00000 162 | 0.00000 0.00000 0.00000 163 | 0.00000 0.00000 0.00000 164 | 0.00000 0.00000 0.00000 165 | 0.00000 0.00000 0.00000 166 | 0.00000 0.00000 0.00000 167 | 0.00000 0.00000 0.00000 168 | 0.00000 0.00000 0.00000 169 | 0.00000 0.00000 0.00000 170 | 0.00000 0.00000 0.00000 171 | 0.00000 0.00000 0.00000 172 | 0.00000 0.00000 0.00000 173 | 0.00000 0.00000 0.00000 174 | 0.00000 0.00000 0.00000 175 | 0.00000 0.00000 0.00000 176 | 0.00000 0.00000 0.00000 177 | 0.00000 0.00000 0.00000 178 | 0.00000 0.00000 0.00000 179 | 0.00000 0.00000 0.00000 180 | 0.00000 0.00000 0.00000 181 | 0.00000 0.00000 0.00000 182 | 0.00000 0.00000 0.00000 183 | 0.00000 0.00000 0.00000 184 | 0.00000 0.00000 0.00000 185 | 0.00000 0.00000 0.00000 186 | 0.00000 0.00000 0.00000 187 | 0.00000 0.00000 0.00000 188 | 0.00000 0.00000 0.00000 189 | 0.00000 0.00000 0.00000 190 | 0.00000 0.00000 0.00000 191 | 0.00000 0.00000 0.00000 192 | 0.00000 0.00000 0.00000 193 | 0.00000 0.00000 0.00000 194 | 0.00000 0.00000 0.00000 195 | 0.00000 0.00000 0.00000 196 | 0.00000 0.00000 0.00000 197 | 0.00000 0.00000 0.00000 198 | 0.00000 0.00000 0.00000 199 | 0.00000 0.00000 0.00000 200 | 0.00000 0.00000 0.00000 201 | 0.00000 0.00000 0.00000 202 | 0.00000 0.00000 0.00000 203 | 0.00000 0.00000 0.00000 204 | 0.00000 0.00000 0.00000 205 | 0.00000 0.00000 0.00000 206 | 0.00000 0.00000 0.00000 207 | 0.00000 0.00000 0.00000 208 | 0.00000 0.00000 0.00000 209 | 0.00000 0.00000 0.00000 210 | 0.00000 0.00000 0.00000 211 | 0.00000 0.00000 0.00000 212 | 0.00000 0.00000 0.00000 213 | 0.00000 0.00000 0.00000 214 | 0.00000 0.00000 0.00000 215 | 0.00000 0.00000 0.00000 216 | 0.00000 0.00000 0.00000 217 | 0.00000 0.00000 0.00000 218 | 0.00000 0.00000 0.00000 219 | 0.00000 0.00000 0.00000 220 | 0.00000 0.00000 0.00000 221 | 0.00000 0.00000 0.00000 222 | 0.00000 0.00000 0.00000 223 | 0.00000 0.00000 0.00000 224 | 0.00000 0.00000 0.00000 225 | 0.00000 0.00000 0.00000 226 | 0.00000 0.00000 0.00000 227 | 0.00000 0.00000 0.00000 228 | 0.00000 0.00000 0.00000 229 | 0.00000 0.00000 0.00000 230 | 0.00000 0.00000 0.00000 231 | 0.00000 0.00000 0.00000 232 | 0.00000 0.00000 0.00000 233 | 0.00000 0.00000 0.00000 234 | 0.00000 0.00000 0.00000 235 | 0.00000 0.00000 0.00000 236 | 0.00000 0.00000 0.00000 237 | 0.00000 0.00000 0.00000 238 | 0.00000 0.00000 0.00000 239 | 0.00000 0.00000 0.00000 240 | 0.00000 0.00000 0.00000 241 | 0.00000 0.00000 0.00000 242 | 0.00000 0.00000 0.00000 243 | 0.00000 0.00000 0.00000 244 | 0.00000 0.00000 0.00000 245 | 0.00000 0.00000 0.00000 246 | 0.00000 0.00000 0.00000 247 | 0.00000 0.00000 0.00000 248 | 0.00000 0.00000 0.00000 249 | 0.00000 0.00000 0.00000 250 | 0.00000 0.00000 0.00000 251 | 0.00000 0.00000 0.00000 252 | 0.00000 0.00000 0.00000 253 | 0.00000 0.00000 0.00000 254 | 0.00000 0.00000 0.00000 255 | 0.00000 0.00000 0.00000 256 | 0.00000 0.00000 0.00000 257 | 0.00000 0.00000 0.00000 258 | 0.00000 0.00000 0.00000 259 | 0.00000 0.00000 0.00000 260 | 0.00000 0.00000 0.00000 261 | 0.00000 0.00000 0.00000 262 | 0.00000 0.00000 0.00000 263 | 0.00000 0.00000 0.00000 264 | 0.00000 0.00000 0.00000 265 | 0.00000 0.00000 0.00000 266 | 0.00000 0.00000 0.00000 267 | 0.00000 0.00000 0.00000 268 | 0.00000 0.00000 0.00000 269 | 0.00000 0.00000 0.00000 270 | 0.00000 0.00000 0.00000 271 | 0.00000 0.00000 0.00000 272 | 0.00000 0.00000 0.00000 273 | 0.00000 0.00000 0.00000 274 | 0.00000 0.00000 0.00000 275 | 0.00000 0.00000 0.00000 276 | 0.00000 0.00000 0.00000 277 | 0.00000 0.00000 0.00000 278 | 0.00000 0.00000 0.00000 279 | 0.00000 0.00000 0.00000 280 | 0.00000 0.00000 0.00000 281 | 0.00000 0.00000 0.00000 282 | 0.00000 0.00000 0.00000 283 | 0.00000 0.00000 0.00000 284 | 0.00000 0.00000 0.00000 285 | 0.00000 0.00000 0.00000 286 | 0.00000 0.00000 0.00000 287 | 0.00000 0.00000 0.00000 288 | 0.00000 0.00000 0.00000 289 | 0.00000 0.00000 0.00000 290 | 0.00000 0.00000 0.00000 291 | 0.00000 0.00000 0.00000 292 | 0.00000 0.00000 0.00000 293 | 0.00000 0.00000 0.00000 294 | 0.00000 0.00000 0.00000 295 | 0.00000 0.00000 0.00000 296 | 0.00000 0.00000 0.00000 297 | 0.00000 0.00000 0.00000 298 | 0.00000 0.00000 0.00000 299 | 0.00000 0.00000 0.00000 300 | 0.00000 0.00000 0.00000 301 | 0.00000 0.00000 0.00000 302 | 0.00000 0.00000 0.00000 303 | 0.00000 0.00000 0.00000 304 | 305 | Orientation = 1 306 | ResolutionUnit = Centimeter 307 | XResolution = 37.790 308 | YResolution = 37.790 309 | Software = paint.net 4.0.15 310 | Make = 311 | Model = 312 | DateTime = 313 | ImageDescription = 314 | Artist = 315 | Copyright = 316 | DigitalCamera = 317 | 318 | scalar structure containing the fields: 319 | 320 | 321 | GPSInfo = 322 | 323 | scalar structure containing the fields: 324 | 325 | 326 | 327 | >> diary off 328 | -------------------------------------------------------------------------------- /sandbox/gradient100px.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davecan/dspguide-code/321a36be08adea511ab728f0a9794866014c064e/sandbox/gradient100px.png -------------------------------------------------------------------------------- /sandbox/gradient3px.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davecan/dspguide-code/321a36be08adea511ab728f0a9794866014c064e/sandbox/gradient3px.png -------------------------------------------------------------------------------- /sandbox/grayscale_avg.m: -------------------------------------------------------------------------------- 1 | # standard grayscale algorithm 2 | # produces muddy dark images 3 | function y = grayscale_avg(img) 4 | y = uint8( (img(:,:,1) + img(:,:,2) + img(:,:,3)) / 3 ); 5 | end -------------------------------------------------------------------------------- /sandbox/grayscale_comparisons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davecan/dspguide-code/321a36be08adea511ab728f0a9794866014c064e/sandbox/grayscale_comparisons.png -------------------------------------------------------------------------------- /sandbox/grayscale_max.m: -------------------------------------------------------------------------------- 1 | # this is better than the naive averaging grayscale algorithm 2 | # but much slower since it iterates per pixel 3 | # it just picks the brightest component in each pixel 4 | function y = grayscale_max(img) 5 | for m = 1:rows(img) 6 | for n = 1:columns(img) 7 | y(m,n) = max([img(m,n,1) img(m,n,2) img(m,n,3)]); 8 | end 9 | end 10 | end -------------------------------------------------------------------------------- /sandbox/grayscale_weighted.m: -------------------------------------------------------------------------------- 1 | # weighted aka luminous grayscale algorithm 2 | function y = grayscale_weighted(img) 3 | img = double(img); 4 | for m = 1:rows(img) 5 | for n = 1:columns(img) 6 | r = img(m,n,1); 7 | g = img(m,n,2); 8 | b = img(m,n,3); 9 | rgb = r + g + b + 1; # +1 in case it is all black to avoid divide by zero 10 | rw = r / rgb; 11 | gw = g / rgb; 12 | bw = b / rgb; 13 | y(m,n) = r*rw + g*gw + b*bw; 14 | end 15 | end 16 | y = uint8(y); 17 | end -------------------------------------------------------------------------------- /sandbox/green.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davecan/dspguide-code/321a36be08adea511ab728f0a9794866014c064e/sandbox/green.jpg -------------------------------------------------------------------------------- /sandbox/green.m: -------------------------------------------------------------------------------- 1 | a = imread('green.jpg'); 2 | 3 | # nonlinear contrast boost 4 | function a = nonlincontrast(a) 5 | for i = 1:rows(a) 6 | for j = 1:columns(a) 7 | a(i,j,1) = (a(i,j,1)/255.0) ** 2 * 255.0; 8 | #a(i,j,2) = (a(i,j,2)/255.0) ** 2 * 255.0; 9 | a(i,j,3) = (a(i,j,3)/255.0) ** 2 * 255.0; 10 | end 11 | end 12 | end -------------------------------------------------------------------------------- /sandbox/imgflip.m: -------------------------------------------------------------------------------- 1 | a = imread('child.png'); 2 | 3 | function b = imgflip(a) 4 | b = []; 5 | for i = 1:rows(a) 6 | for j = 1:columns(a) 7 | b(j,i,:) = a(i,j,:); 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /sandbox/invert_colors.m: -------------------------------------------------------------------------------- 1 | # inverts colors pixel by pixel 2 | # inversion is simply the distance from the actual color to 255 3 | function a = invert_colors(a) 4 | for i = 1:rows(a) 5 | for j = 1:columns(a) 6 | for k = 1:3 7 | a(i,j,k) = 255 - a(i,j,k); 8 | end 9 | end 10 | end 11 | end 12 | 13 | 14 | a = imread('mario.png'); 15 | imshow(a); 16 | b = invert_colors(a); 17 | imshow(b); 18 | 19 | a = imread('nvd.jpg'); 20 | imshow(a); 21 | b = invert_colors(a); 22 | imshow(b); -------------------------------------------------------------------------------- /sandbox/invlog.m: -------------------------------------------------------------------------------- 1 | # inverse log grayscale transform 2 | # r is the image 3 | function s = invlog(r,c=1,d=1) 4 | s = exp(r/c) - 1; 5 | end -------------------------------------------------------------------------------- /sandbox/landsat_paris.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davecan/dspguide-code/321a36be08adea511ab728f0a9794866014c064e/sandbox/landsat_paris.png -------------------------------------------------------------------------------- /sandbox/leaf.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davecan/dspguide-code/321a36be08adea511ab728f0a9794866014c064e/sandbox/leaf.jpg -------------------------------------------------------------------------------- /sandbox/lena.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davecan/dspguide-code/321a36be08adea511ab728f0a9794866014c064e/sandbox/lena.jpg -------------------------------------------------------------------------------- /sandbox/lena.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davecan/dspguide-code/321a36be08adea511ab728f0a9794866014c064e/sandbox/lena.png -------------------------------------------------------------------------------- /sandbox/lena_gimp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davecan/dspguide-code/321a36be08adea511ab728f0a9794866014c064e/sandbox/lena_gimp.png -------------------------------------------------------------------------------- /sandbox/lena_grayscale.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davecan/dspguide-code/321a36be08adea511ab728f0a9794866014c064e/sandbox/lena_grayscale.png -------------------------------------------------------------------------------- /sandbox/logtransform.m: -------------------------------------------------------------------------------- 1 | # log grayscale transformation 2 | # r is the image 3 | function s = logtransform(r, c=1, d=1) 4 | s = c * log(r + d); 5 | end -------------------------------------------------------------------------------- /sandbox/mario.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davecan/dspguide-code/321a36be08adea511ab728f0a9794866014c064e/sandbox/mario.png -------------------------------------------------------------------------------- /sandbox/missing_planes/img_delta.m: -------------------------------------------------------------------------------- 1 | function img_delta(img1, img2, thresh, minblocksize) 2 | sz1 = size(size(img1)); 3 | sz2 = size(size(img2)); 4 | if ~isequal(sz1,sz2) 5 | error('images must be the same size'); 6 | end 7 | 8 | if sz1(2) > 2 9 | img1 = rgb2gray(img1); 10 | end 11 | if sz2(2) > 2 12 | img2 = rgb2gray(img2); 13 | end 14 | 15 | % build the template to look for the differences 16 | D = img1 - img2; % get difference for templating 17 | Dbw = D > thresh; % threshold at graylevel = thresh 18 | Dbw = bwareaopen(Dbw, minblocksize); % remove all regions smaller than minblocksize 19 | 20 | % dilate objects in the template for easier identification 21 | se1 = strel('square',3); % establish morphological structuring element 22 | Dbw = imdilate(Dbw,se1); % dilate using the structuring element 23 | 24 | % identify the individual objects 25 | [L,N] = bwlabel(Dbw); % label the connected components in the matrix 26 | s = regionprops(L,'all'); 27 | C = [s.Centroid]; 28 | 29 | img_delta_show('img1', img1, N, C); 30 | img_delta_show('img2', img2, N, C); 31 | end 32 | 33 | function y = img_delta_show(name, img, numdiffs, centroid) 34 | figure('Name', name, 'NumberTitle', 'off'); 35 | imshow(img); 36 | for i = 1:numdiffs 37 | h=rectangle('Position',[centroid(2*i-1)-15 centroid(2*i)-15 30 30],'Curvature',[1 1],'LineWidth',2); 38 | set(h,'EdgeColor',[1 1 0]); 39 | end 40 | end -------------------------------------------------------------------------------- /sandbox/missing_planes/parkinglot1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davecan/dspguide-code/321a36be08adea511ab728f0a9794866014c064e/sandbox/missing_planes/parkinglot1.jpg -------------------------------------------------------------------------------- /sandbox/missing_planes/parkinglot2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davecan/dspguide-code/321a36be08adea511ab728f0a9794866014c064e/sandbox/missing_planes/parkinglot2.jpg -------------------------------------------------------------------------------- /sandbox/missing_planes/planes1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davecan/dspguide-code/321a36be08adea511ab728f0a9794866014c064e/sandbox/missing_planes/planes1.jpg -------------------------------------------------------------------------------- /sandbox/missing_planes/planes2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davecan/dspguide-code/321a36be08adea511ab728f0a9794866014c064e/sandbox/missing_planes/planes2.jpg -------------------------------------------------------------------------------- /sandbox/missing_planes/sandy1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davecan/dspguide-code/321a36be08adea511ab728f0a9794866014c064e/sandbox/missing_planes/sandy1.jpg -------------------------------------------------------------------------------- /sandbox/missing_planes/sandy2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davecan/dspguide-code/321a36be08adea511ab728f0a9794866014c064e/sandbox/missing_planes/sandy2.jpg -------------------------------------------------------------------------------- /sandbox/missing_planes/trocadero1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davecan/dspguide-code/321a36be08adea511ab728f0a9794866014c064e/sandbox/missing_planes/trocadero1.jpg -------------------------------------------------------------------------------- /sandbox/missing_planes/trocadero2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davecan/dspguide-code/321a36be08adea511ab728f0a9794866014c064e/sandbox/missing_planes/trocadero2.jpg -------------------------------------------------------------------------------- /sandbox/missing_planes/trocadero_master.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davecan/dspguide-code/321a36be08adea511ab728f0a9794866014c064e/sandbox/missing_planes/trocadero_master.jpg -------------------------------------------------------------------------------- /sandbox/night_vision.m: -------------------------------------------------------------------------------- 1 | img = imread('zd30.jpg'); 2 | 3 | a = img; 4 | b = img; 5 | 6 | figure('Position', [100,100,1536,802]); 7 | imshow(a); 8 | 9 | # normalizes all channels to the green channel -- grayscale-ish? 10 | function a = greenscale(a) 11 | for i = 1:rows(a) 12 | for j = 1:columns(a) 13 | if a(i,j,1) < a(i,j,2) 14 | a(i,j,1) = a(i,j,2); 15 | end 16 | if a(i,j,3) < a(i,j,2) 17 | a(i,j,3) = a(i,j,2); 18 | end 19 | end 20 | end 21 | end 22 | 23 | # bring excessively bright or dark greens closer to other two channels 24 | # makes the NVD1 image less glaring, but makes the ZD30 image muddy 25 | function a = normalize(a) 26 | for i = 1:rows(a) 27 | for j = 1:columns(a) 28 | dist = abs(a(i,j,1) - a(i,j,3)); 29 | if a(i,j,2) > a(i,j,1) && a(i,j,2) > a(i,j,3) 30 | a(i,j,2) = a(i,j,2) - dist; 31 | elseif a(i,j,2) < a(i,j,1) && a(i,j,2) < a(i,j,3) 32 | a(i,j,2) = a(i,j,2) + dist; 33 | end 34 | end 35 | end 36 | end 37 | 38 | # brightens green channel 39 | function a = brightgreen(a) 40 | for i = 1:rows(a) 41 | for j = 1:columns(a) 42 | dist = abs(a(i,j,1) - a(i,j,3)); 43 | if a(i,j,2) > a(i,j,1) && a(i,j,2) > a(i,j,3) 44 | a(i,j,2) = a(i,j,2) + dist; 45 | elseif a(i,j,2) < a(i,j,1) && a(i,j,2) < a(i,j,3) 46 | a(i,j,2) = a(i,j,2) - dist; 47 | end 48 | end 49 | end 50 | end 51 | 52 | -------------------------------------------------------------------------------- /sandbox/nvd.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davecan/dspguide-code/321a36be08adea511ab728f0a9794866014c064e/sandbox/nvd.jpg -------------------------------------------------------------------------------- /sandbox/nvd1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davecan/dspguide-code/321a36be08adea511ab728f0a9794866014c064e/sandbox/nvd1.png -------------------------------------------------------------------------------- /sandbox/park.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davecan/dspguide-code/321a36be08adea511ab728f0a9794866014c064e/sandbox/park.png -------------------------------------------------------------------------------- /sandbox/pixelate.m: -------------------------------------------------------------------------------- 1 | % crude pixelation filter 2 | function y = pixelate(x) 3 | [r c] = size(x); 4 | for m = 1:2:r 5 | for n = 1:2:c 6 | v = x(m,n); 7 | y(m,n) = v; 8 | y(m,n+1) = v; 9 | y(m+1,n) = v; 10 | y(m+1,n+1) = v; 11 | end 12 | end 13 | end -------------------------------------------------------------------------------- /sandbox/pixelate_avg.m: -------------------------------------------------------------------------------- 1 | % interpolates intermediate values for neighbors 2 | function y = pixelate_avg(x) 3 | [r c] = size(x); 4 | for m = 1:2:r 5 | for n = 1:2:c 6 | v = x(m,n); 7 | if m < r -1 && n < c - 1 8 | % gets average of this pixel and the pixel to the right and the bottom 9 | vr = (v + x(m,n+1)) / 2; 10 | vb = (v + x(m+1,n)) / 2; 11 | vbr = uint8(vr + vb / 2); 12 | else 13 | vr = 0; 14 | vb = 0; 15 | vbr = 0; 16 | end 17 | x(m,n+1) = vr; 18 | x(m+1,n) = vb; 19 | x(m+1,n+1) = vbr; 20 | end 21 | end 22 | end -------------------------------------------------------------------------------- /sandbox/powerlaw.m: -------------------------------------------------------------------------------- 1 | # nth power / gamma correction grayscale transform 2 | # r is the image 3 | # g is the gamma value 4 | function s = powerlaw(r, g, c=1) 5 | s = c * (r.^g); 6 | end -------------------------------------------------------------------------------- /sandbox/pulse.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davecan/dspguide-code/321a36be08adea511ab728f0a9794866014c064e/sandbox/pulse.png -------------------------------------------------------------------------------- /sandbox/pulse2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davecan/dspguide-code/321a36be08adea511ab728f0a9794866014c064e/sandbox/pulse2.png -------------------------------------------------------------------------------- /sandbox/rgb1.m: -------------------------------------------------------------------------------- 1 | figure 2 | imshow(img(:,:,1)); 3 | title('Red Frame'); 4 | 5 | figure 6 | imshow(img(:,:,2)); 7 | title('Blue Frame'); 8 | 9 | figure 10 | imshow(img(:,:,3)); 11 | title('Green Frame'); -------------------------------------------------------------------------------- /sandbox/rotate_colors.m: -------------------------------------------------------------------------------- 1 | # rotates colors 2 | function a = rotate_colors(a) 3 | for i = 1:rows(a) 4 | for j = 1:columns(a) 5 | x = a(i,j,1); 6 | a(i,j,1) = a(i,j,2); 7 | a(i,j,2) = a(i,j,3); 8 | a(i,j,3) = x; 9 | end 10 | end 11 | end -------------------------------------------------------------------------------- /sandbox/sine_wave.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davecan/dspguide-code/321a36be08adea511ab728f0a9794866014c064e/sandbox/sine_wave.png -------------------------------------------------------------------------------- /sandbox/slicing.m: -------------------------------------------------------------------------------- 1 | a = imread('smbw.png'); 2 | 3 | # a contains 3 matrices, one for each channel: red, green, blue. 4 | # to select a specific channel N in a slice: 5 | # a(:,:,N) -- all rows, all cols, channel N only 6 | # to select all channels in a slice: 7 | # a(:,:,:) 8 | 9 | # every other column turns black 10 | for i = 1:columns(a) 11 | if mod(i, 2) == 0 12 | a(:,i,:) = 0; 13 | end 14 | end 15 | 16 | imshow(a); 17 | 18 | # every other row turns red 19 | for i = 1:rows(a) 20 | if mod(i, 2) == 0 21 | a(i,:,:) = 0; 22 | a(i,:,1) = 255; 23 | end 24 | end 25 | 26 | imshow(a); 27 | 28 | # every grey square turns green 29 | for i = 1:rows(a) 30 | for j = 1:columns(a) 31 | if a(i,j,:) == 105 32 | a(i,j,:) = 0; 33 | a(i,j,2) = 255; 34 | end 35 | end 36 | end 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /sandbox/slprj/_cgxe/untitled/untitled_Cache.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davecan/dspguide-code/321a36be08adea511ab728f0a9794866014c064e/sandbox/slprj/_cgxe/untitled/untitled_Cache.mat -------------------------------------------------------------------------------- /sandbox/slprj/_jitprj/AjCjgozthgeShqDK4BVPzC.l: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davecan/dspguide-code/321a36be08adea511ab728f0a9794866014c064e/sandbox/slprj/_jitprj/AjCjgozthgeShqDK4BVPzC.l -------------------------------------------------------------------------------- /sandbox/slprj/_jitprj/AjCjgozthgeShqDK4BVPzC.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davecan/dspguide-code/321a36be08adea511ab728f0a9794866014c064e/sandbox/slprj/_jitprj/AjCjgozthgeShqDK4BVPzC.mat -------------------------------------------------------------------------------- /sandbox/slprj/_jitprj/jitEngineAccessInfo.mat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davecan/dspguide-code/321a36be08adea511ab728f0a9794866014c064e/sandbox/slprj/_jitprj/jitEngineAccessInfo.mat -------------------------------------------------------------------------------- /sandbox/smbw.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davecan/dspguide-code/321a36be08adea511ab728f0a9794866014c064e/sandbox/smbw.png -------------------------------------------------------------------------------- /sandbox/square_wave.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davecan/dspguide-code/321a36be08adea511ab728f0a9794866014c064e/sandbox/square_wave.png -------------------------------------------------------------------------------- /sandbox/toys_candy.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davecan/dspguide-code/321a36be08adea511ab728f0a9794866014c064e/sandbox/toys_candy.jpg -------------------------------------------------------------------------------- /sandbox/tree.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davecan/dspguide-code/321a36be08adea511ab728f0a9794866014c064e/sandbox/tree.jpg -------------------------------------------------------------------------------- /sandbox/xray.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davecan/dspguide-code/321a36be08adea511ab728f0a9794866014c064e/sandbox/xray.png -------------------------------------------------------------------------------- /sandbox/zd30.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davecan/dspguide-code/321a36be08adea511ab728f0a9794866014c064e/sandbox/zd30.jpg -------------------------------------------------------------------------------- /sandbox/zoomit.m: -------------------------------------------------------------------------------- 1 | % basic zoom algorithm 2 | function s = zoomit(img, c) 3 | [rows, cols] = size(img); 4 | s = ones(c * rows, c * cols); 5 | for m = 1:rows 6 | for n = 1:cols 7 | p = img(m,n); 8 | s(m+m-1,n+n-1) = p; 9 | s(m+m-1,n+n) = p; 10 | s(m+m,n+n-1) = p; 11 | s(m+m,n+n) = p; 12 | end 13 | end 14 | s = uint8(s); 15 | end 16 | --------------------------------------------------------------------------------