├── .gitignore
├── Bilinear Interpolation
├── README.md
├── Sample Output.png
└── bilinear_int.py
├── Evaluating Square Root
├── README.md
└── sqrt.py
├── Feigenbaum Plot
├── FP_Comparison.py
├── FP_Iterations.py
├── Sample Output.png
└── UNDOCUMENTED.md
├── Gradient Descent
├── UNDOCUMENTED.md
├── altitude.txt
├── max_alt.png
├── max_alt.py
├── min_STM.png
├── min_STM.py
└── stm.txt
├── Lotka-Volterra Simulation
├── Lotka-Volterra.py
└── Output Graphs
│ ├── Function of N.png
│ └── Function of Time
│ ├── 1000 Diff.png
│ ├── 1000 Euler.png
│ ├── 1000 RK4.png
│ ├── 10000 Diff.png
│ ├── 10000 Euler.png
│ ├── 10000 RK4.png
│ ├── 100000 Diff.png
│ ├── 100000 Euler.png
│ ├── 100000 RK4.png
│ ├── 1000000 Diff.png
│ ├── 1000000 Euler.png
│ └── 1000000 RK4.png
├── Numerical Differentiation and Integration
├── UNDOCUMENTED.md
├── derivatives_graph.py
└── monte_carlo_and_riemann.py
├── Powers of Euler's Constant
├── README.md
├── exp
├── exp.cpp
└── exp.py
├── Projectile Motion with Viscous Drag
├── Projectile_Motion.py
├── README.md
├── Speed vs Distance.png
└── Speed vs Theta.png
├── README.md
├── Random Walk Simulation
├── README.md
├── Sample Outputs
│ ├── M_vs._Time.png
│ ├── RMS_vs._Time.png
│ ├── Ratio_vs._Time.png
│ └── Sim.png
└── random_walk.py
└── packet.c
/.gitignore:
--------------------------------------------------------------------------------
1 | GitIgnored/
2 |
3 | # Created by https://www.gitignore.io/api/vim,c++,java,xcode,macos,python,eclipse,sublimetext
4 |
5 | ### C++ ###
6 | # Prerequisites
7 | *.d
8 |
9 | # Compiled Object files
10 | *.slo
11 | *.lo
12 | *.o
13 | *.obj
14 |
15 | # Precompiled Headers
16 | *.gch
17 | *.pch
18 |
19 | # Compiled Dynamic libraries
20 | *.so
21 | *.dylib
22 | *.dll
23 |
24 | # Fortran module files
25 | *.mod
26 | *.smod
27 |
28 | # Compiled Static libraries
29 | *.lai
30 | *.la
31 | *.a
32 | *.lib
33 |
34 | # Executables
35 | *.exe
36 | *.out
37 | *.app
38 |
39 | ### Eclipse ###
40 |
41 | .metadata
42 | bin/
43 | tmp/
44 | *.tmp
45 | *.bak
46 | *.swp
47 | *~.nib
48 | local.properties
49 | .settings/
50 | .loadpath
51 | .recommenders
52 |
53 | # External tool builders
54 | .externalToolBuilders/
55 |
56 | # Locally stored "Eclipse launch configurations"
57 | *.launch
58 |
59 | # PyDev specific (Python IDE for Eclipse)
60 | *.pydevproject
61 |
62 | # CDT-specific (C/C++ Development Tooling)
63 | .cproject
64 |
65 | # Java annotation processor (APT)
66 | .factorypath
67 |
68 | # PDT-specific (PHP Development Tools)
69 | .buildpath
70 |
71 | # sbteclipse plugin
72 | .target
73 |
74 | # Tern plugin
75 | .tern-project
76 |
77 | # TeXlipse plugin
78 | .texlipse
79 |
80 | # STS (Spring Tool Suite)
81 | .springBeans
82 |
83 | # Code Recommenders
84 | .recommenders/
85 |
86 | # Scala IDE specific (Scala & Java development for Eclipse)
87 | .cache-main
88 | .scala_dependencies
89 | .worksheet
90 |
91 | ### Eclipse Patch ###
92 | # Eclipse Core
93 | .project
94 |
95 | # JDT-specific (Eclipse Java Development Tools)
96 | .classpath
97 |
98 | ### Java ###
99 | # Compiled class file
100 | *.class
101 |
102 | # Log file
103 | *.log
104 |
105 | # BlueJ files
106 | *.ctxt
107 |
108 | # Mobile Tools for Java (J2ME)
109 | .mtj.tmp/
110 |
111 | # Package Files #
112 | *.jar
113 | *.war
114 | *.ear
115 | *.zip
116 | *.tar.gz
117 | *.rar
118 |
119 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
120 | hs_err_pid*
121 |
122 | ### macOS ###
123 | *.DS_Store
124 | .AppleDouble
125 | .LSOverride
126 |
127 | # Icon must end with two \r
128 | Icon
129 |
130 | # Thumbnails
131 | ._*
132 |
133 | # Files that might appear in the root of a volume
134 | .DocumentRevisions-V100
135 | .fseventsd
136 | .Spotlight-V100
137 | .TemporaryItems
138 | .Trashes
139 | .VolumeIcon.icns
140 | .com.apple.timemachine.donotpresent
141 |
142 | # Directories potentially created on remote AFP share
143 | .AppleDB
144 | .AppleDesktop
145 | Network Trash Folder
146 | Temporary Items
147 | .apdisk
148 |
149 | ### Python ###
150 | # Byte-compiled / optimized / DLL files
151 | __pycache__/
152 | *.py[cod]
153 | *$py.class
154 |
155 | # C extensions
156 |
157 | # Distribution / packaging
158 | .Python
159 | build/
160 | develop-eggs/
161 | dist/
162 | downloads/
163 | eggs/
164 | .eggs/
165 | lib/
166 | lib64/
167 | parts/
168 | sdist/
169 | var/
170 | wheels/
171 | *.egg-info/
172 | .installed.cfg
173 | *.egg
174 |
175 | # PyInstaller
176 | # Usually these files are written by a python script from a template
177 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
178 | *.manifest
179 | *.spec
180 |
181 | # Installer logs
182 | pip-log.txt
183 | pip-delete-this-directory.txt
184 |
185 | # Unit test / coverage reports
186 | htmlcov/
187 | .tox/
188 | .coverage
189 | .coverage.*
190 | .cache
191 | nosetests.xml
192 | coverage.xml
193 | *.cover
194 | .hypothesis/
195 |
196 | # Translations
197 | *.mo
198 | *.pot
199 |
200 | # Django stuff:
201 | local_settings.py
202 |
203 | # Flask stuff:
204 | instance/
205 | .webassets-cache
206 |
207 | # Scrapy stuff:
208 | .scrapy
209 |
210 | # Sphinx documentation
211 | docs/_build/
212 |
213 | # PyBuilder
214 | target/
215 |
216 | # Jupyter Notebook
217 | .ipynb_checkpoints
218 |
219 | # pyenv
220 | .python-version
221 |
222 | # celery beat schedule file
223 | celerybeat-schedule
224 |
225 | # SageMath parsed files
226 | *.sage.py
227 |
228 | # Environments
229 | .env
230 | .venv
231 | env/
232 | venv/
233 | ENV/
234 | env.bak/
235 | venv.bak/
236 |
237 | # Spyder project settings
238 | .spyderproject
239 | .spyproject
240 |
241 | # Rope project settings
242 | .ropeproject
243 |
244 | # mkdocs documentation
245 | /site
246 |
247 | # mypy
248 | .mypy_cache/
249 |
250 | ### SublimeText ###
251 | # cache files for sublime text
252 | *.tmlanguage.cache
253 | *.tmPreferences.cache
254 | *.stTheme.cache
255 |
256 | # workspace files are user-specific
257 | *.sublime-workspace
258 |
259 | # project files should be checked into the repository, unless a significant
260 | # proportion of contributors will probably not be using SublimeText
261 | # *.sublime-project
262 |
263 | # sftp configuration file
264 | sftp-config.json
265 |
266 | # Package control specific files
267 | Package Control.last-run
268 | Package Control.ca-list
269 | Package Control.ca-bundle
270 | Package Control.system-ca-bundle
271 | Package Control.cache/
272 | Package Control.ca-certs/
273 | Package Control.merged-ca-bundle
274 | Package Control.user-ca-bundle
275 | oscrypto-ca-bundle.crt
276 | bh_unicode_properties.cache
277 |
278 | # Sublime-github package stores a github token in this file
279 | # https://packagecontrol.io/packages/sublime-github
280 | GitHub.sublime-settings
281 |
282 | ### Vim ###
283 | # swap
284 | [._]*.s[a-v][a-z]
285 | [._]*.sw[a-p]
286 | [._]s[a-v][a-z]
287 | [._]sw[a-p]
288 | # session
289 | Session.vim
290 | # temporary
291 | .netrwhist
292 | *~
293 | # auto-generated tag files
294 | tags
295 |
296 | ### Xcode ###
297 | # Xcode
298 | #
299 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
300 |
301 | ## Build generated
302 | DerivedData/
303 |
304 | ## Various settings
305 | *.pbxuser
306 | !default.pbxuser
307 | *.mode1v3
308 | !default.mode1v3
309 | *.mode2v3
310 | !default.mode2v3
311 | *.perspectivev3
312 | !default.perspectivev3
313 | xcuserdata/
314 |
315 | ## Other
316 | *.moved-aside
317 | *.xccheckout
318 | *.xcscmblueprint
319 |
320 | ### Xcode Patch ###
321 | *.xcodeproj/*
322 | !*.xcodeproj/project.pbxproj
323 | !*.xcodeproj/xcshareddata/
324 | !*.xcworkspace/contents.xcworkspacedata
325 | /*.gcno
326 |
327 | # End of https://www.gitignore.io/api/vim,c++,java,xcode,macos,python,eclipse,sublimetext
328 |
--------------------------------------------------------------------------------
/Bilinear Interpolation/README.md:
--------------------------------------------------------------------------------
1 | ## Bilinear Interpolation
2 |
3 | ### Overview
4 |
5 | This project visualizes the bilinear interpolation of four corner values.
6 |
7 | ### Sample Output
8 |
9 | 
10 |
11 | ### Details
12 |
13 | This project contains a single file `bilinear_int.py`, which does the following things:
14 |
15 | * Perform bilinear interpolation with four corner values and visualize using matplotlib's imshow
16 |
17 | * Plot the zero line(s) by finding points that are "close enough" to zero and scatter plotting them (this feature does not look perfect, but is sufficient for our purposes)
18 |
19 | ### Testing
20 |
21 | Download the project and run `bilinear_int.py`.
22 |
23 | Change the corner values on line 4 to any floating point values to visualize their bilinear interpolation.
--------------------------------------------------------------------------------
/Bilinear Interpolation/Sample Output.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/harvey2phase/computational-physics/112ab8dabc25c1e522f4b5d4e14018c49efa90d6/Bilinear Interpolation/Sample Output.png
--------------------------------------------------------------------------------
/Bilinear Interpolation/bilinear_int.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 | import matplotlib.pyplot as plt
3 |
4 | # Setting the four corner values
5 | f00, f01, f10, f11 = 3.14, -6, -2, 4
6 |
7 | # Setting x0=y0=0 and x1=y1=1 yields u=x and v=y
8 | # Therefore, f can be simplified to:
9 | def f(x, y):
10 | F11 = x * y * f11
11 | F00 = (1 - x) * (1 - y) * f00
12 | F10 = x * (1 - y) * f10
13 | F01 = (1 - x) * y * f01
14 | return F11 + F00 + F10 + F01
15 |
16 | def annotate():
17 | plt.annotate(s = f00, fontsize = 10, xy = (1, 1))
18 | plt.annotate(s = f01, fontsize = 10, xy = (N-1, 1))
19 | plt.annotate(s = f10, fontsize = 10, xy = (1, N-1))
20 | plt.annotate(s = f11, fontsize = 10, xy = (N-1, N-1))
21 |
22 | # Determine if the input is close enough to zero
23 | def close_to_zero(x):
24 | if abs(x) < 10 ** -3:
25 | return True
26 | return False
27 |
28 | # "Normal" binary search, where negative numbers are on the left side
29 | def n_to_p(L, l, m, h):
30 | if close_to_zero(L[m]):
31 | return m
32 |
33 | # If L has been searched through
34 | elif h <= l:
35 | return 0
36 |
37 | # Search right side
38 | elif L[m] < 0:
39 | if m == int((h-m)/2) + m:
40 | return 0
41 | return n_to_p(L, m, int((h-m)/2) + m, h)
42 |
43 | # Search left side
44 | else:
45 | if m == int((m-l)/2) + l:
46 | return 0
47 | return n_to_p(L, l, int((m-l)/2) + l, m)
48 |
49 | # Binary search with positive numbers on the left side
50 | def p_to_n(L, l, m, h):
51 | if close_to_zero(L[m]):
52 | return m
53 |
54 | # If L has been searched through
55 | elif h <= l:
56 | return 0
57 |
58 | # Search left side
59 | elif L[m] < 0:
60 | if m == int((m-l)/2) + m:
61 | return 0
62 | return p_to_n(L, l, int((m-l)/2) + l, m)
63 | else:
64 | if m == int((h-m)/2) + l:
65 | return 0
66 | return p_to_n(L, m, int((h-m)/2) + m, h)
67 |
68 | # Creating two arrays from x0=y0=0 to x1=y1=1 with N points
69 | N = 1000
70 | X, Y = np.linspace(0, 1, N), np.linspace(0, 1, N)
71 | inters, zero_line = np.empty([N, N]), []
72 |
73 | x = 0
74 | for i in X:
75 | y = 0
76 | for j in Y:
77 | inters[x][y] = f(i, j)
78 | y += 1
79 | # List goes small to large
80 | if inters[x][N-1] > inters[x][0]:
81 | zero_line.append(n_to_p(inters[x], 0, int(N / 2), N))
82 | else:
83 | zero_line.append(p_to_n(inters[x], 0, int(N / 2), N))
84 |
85 | x += 1
86 |
87 | plt.imshow(inters)
88 | plt.jet()
89 | plt.scatter(zero_line, np.linspace(0, N-1, N), s = 0.1, c = 'k')
90 | plt.axis('off')
91 | annotate()
92 | plt.show()
93 |
--------------------------------------------------------------------------------
/Evaluating Square Root/README.md:
--------------------------------------------------------------------------------
1 | ## Evaluating Square Root
2 |
3 | ### Overview
4 |
5 | This project explores numerical methods to evaluate the square root of a number without using existing math functions.
6 |
7 | ### Details
8 |
9 | `sqrt.py` defines the function `sqrt()`, which takes in a value `x` and finds its square root recursively using Binary Search up to `accuracy`. It then compares the evaluated square root to the square root found using the Python `math` library.
10 |
11 | ### Testing
12 |
13 | Download `sqrt.py` and simply change the `x` value to whatever you wish.
14 |
--------------------------------------------------------------------------------
/Evaluating Square Root/sqrt.py:
--------------------------------------------------------------------------------
1 | # SQUARE ROOT
2 | # by Harvey Wang
3 | # Created September 2017
4 |
5 | import math as m
6 |
7 | # a recursive function to find the square root of x
8 | def sqrt_re(x, m, mid, M):
9 | # base case
10 | if M - m < accuracy:
11 | return mid
12 | if mid ** 2 == x:
13 | return mid
14 | # choose the left side of the range
15 | elif mid ** 2 > x:
16 | return sqrt_re(x, m, (mid - m) / 2 + m, mid)
17 | # choose the right side of the range
18 | else:
19 | return sqrt_re(x, mid, (M - mid) / 2 + mid, M)
20 |
21 | def sqrt(x):
22 | return sqrt_re(x, 1, x / 2, x)
23 |
24 | x = 5
25 | accuracy = 10 ** -6
26 |
27 | my_sqrt = sqrt(x)
28 | math_sqrt = m.sqrt(x)
29 | error = abs(my_sqrt - math_sqrt)
30 |
31 | print('x:\t\t', x)
32 | print('Accuracy:\t', accuracy)
33 | print('My sqrt:\t', my_sqrt)
34 | print('Math sqrt:\t', math_sqrt)
35 | print('Error:\t\t', error)
--------------------------------------------------------------------------------
/Feigenbaum Plot/FP_Comparison.py:
--------------------------------------------------------------------------------
1 | from numpy import *
2 | from matplotlib.pyplot import *
3 | from time import *
4 |
5 | # Graph the Feigenbaum plot using the basic method in the textbook
6 | def basic():
7 | r_list, x_list, r, x = [], [], 1, 0.5
8 |
9 | # Iterate through r = 1 to r = 4
10 | while r < 4:
11 |
12 | i = 0
13 |
14 | # First iterate the logistic map equation 1000 times
15 | while i < 1000:
16 | x = r * x * (1 - x)
17 | i += 1
18 |
19 | # Iterate the logistic map another 1000 times then plot
20 | while i < 2000:
21 | x = r * x * (1 - x)
22 | r_list.append(r)
23 | x_list.append(x)
24 | i += 1
25 |
26 | r += 0.01
27 |
28 | scatter(r_list, x_list, s = 0.1)
29 |
30 | # Graph the Feigenbaum plot using the approach described in footnote 10
31 | def footnote_10():
32 | # Create two arrays of the same length, each containing r and x
33 | r = linspace(1.0, 4.0, 301)
34 | x = full(301, 0.5)
35 |
36 | # First iterate the logistic map equation 1000 times
37 | for i in range(1000):
38 | x = r * x * (1 - x)
39 |
40 | # Iterate the logistic map another 1000 times then plot
41 | for i in range(1000):
42 | x = r * x * (1 - x)
43 | scatter(r, x, s = 0.1)
44 |
45 | # Run both functions and print out the time it takes to compute each
46 | start_time = time()
47 | footnote_10()
48 | end_time_1 = time()
49 | basic()
50 | end_time_2 = time()
51 | print("The basic approach:", end_time_1 - start_time)
52 | print("The footnote approach:", end_time_2 - end_time_1)
53 |
--------------------------------------------------------------------------------
/Feigenbaum Plot/FP_Iterations.py:
--------------------------------------------------------------------------------
1 | from numpy import *
2 | from matplotlib.pyplot import *
3 | from time import *
4 |
5 | # Graph the Feigenbaum plot using the approach described in footnote 10
6 | def footnote_10(n):
7 |
8 | # Create two arrays of the same length, each containing r and x
9 | r = linspace(1.0, 4.0, 301)
10 | x = full(301, 0.5)
11 |
12 | # First iterate the logistic map equation n times
13 | for i in range(n):
14 | x = r * x * (1 - x)
15 |
16 | # Iterate the logistic map another n times then plot
17 | for i in range(n * 2):
18 | x = r * x * (1 - x)
19 | scatter(r, x, s = 0.1)
20 |
21 | xlabel("r")
22 | ylabel("x")
23 |
24 | # Plot 100, 1000, 100000 iterations and print the time required
25 |
26 | time_0 = time()
27 | figure(1)
28 | footnote_10(100)
29 | title("Feigenbaum Plot - 100 Iterations")
30 |
31 | time_1 = time()
32 | figure(2)
33 | footnote_10(1000)
34 | title("Feigenbaum Plot - 1000 Iterations")
35 |
36 | time_2 = time()
37 | figure(3)
38 | footnote_10(10000)
39 | title("Feigenbaum Plot - 10000 Iterations")
40 |
41 | time_3 = time()
42 |
43 | print("100 Iterations: ", time_1 - time_0)
44 | print("1000 Iterations: ", time_2 - time_1)
45 | print("10000 Iterations:", time_3 - time_2)
46 |
47 | show()
48 |
--------------------------------------------------------------------------------
/Feigenbaum Plot/Sample Output.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/harvey2phase/computational-physics/112ab8dabc25c1e522f4b5d4e14018c49efa90d6/Feigenbaum Plot/Sample Output.png
--------------------------------------------------------------------------------
/Feigenbaum Plot/UNDOCUMENTED.md:
--------------------------------------------------------------------------------
1 | ## UNDOCUMENTED
2 |
3 | ### Overview
4 |
5 | ### Details
6 |
7 | ### Testing
--------------------------------------------------------------------------------
/Gradient Descent/UNDOCUMENTED.md:
--------------------------------------------------------------------------------
1 | Data source (the txt files): http://www-personal.umich.edu/~mejn/cp/programs.html
2 |
--------------------------------------------------------------------------------
/Gradient Descent/max_alt.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/harvey2phase/computational-physics/112ab8dabc25c1e522f4b5d4e14018c49efa90d6/Gradient Descent/max_alt.png
--------------------------------------------------------------------------------
/Gradient Descent/max_alt.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 | import random as ran
3 | import matplotlib.pyplot as plt
4 |
5 | # Returns True if (x, y) is within bounds
6 | def inBounds(x, y):
7 | if x > 511 or x < 0 or y > 1023 or y < 0:
8 | return False
9 | return True
10 |
11 | # Returns True if (x, y) is a local max
12 | def localMax(x, y):
13 | for i in values:
14 | if alts[x, y] < values[i]:
15 | return False
16 | return True
17 |
18 | # Return a dict. of (x, y) containing surrounding points
19 | def adjacentCoors(x, y):
20 | s = {
21 | 0: (x, y + 1),
22 | 1: (x, y - 1),
23 | 2: (x + 1, y),
24 | 3: (x - 1, y),
25 | 4: (x + 1, y + 1),
26 | 5: (x + 1, y - 1),
27 | 6: (x - 1, y + 1),
28 | 7: (x - 1, y - 1)
29 | }
30 | rmKeys = []
31 | for key in s:
32 | xx, yy = s[key]
33 | if not inBounds(xx, yy):
34 | rmKeys.append(key)
35 | for key in rmKeys:
36 | if key in s:
37 | del s[key]
38 | return s
39 |
40 | # Returns a dict. of floats containing surrounding alt. values
41 | def adjacentValues(x, y):
42 | s = adjacentCoors(x, y)
43 | for key in s:
44 | s[key] = alts[s[key]]
45 |
46 | return s
47 |
48 | # Returns (x, y) of the step to take
49 | # (A greedy algorithm to find the next step to take)
50 | def maxStep(x, y):
51 | step = max(values, key=values.get)
52 | return adjacentCoors(x, y)[step]
53 |
54 | alts = np.loadtxt('altitude.txt')
55 | width, height = len(alts[0]), len(alts)
56 | X, Y = [], []
57 | N = 10 ** 4
58 | for i in range(N):
59 | x, y = ran.randint(0, height-1), ran.randint(0, width-1)
60 | values = adjacentValues(x, y)
61 |
62 | while not localMax(x, y):
63 | x, y = maxStep(x, y)
64 | values = adjacentValues(x, y)
65 |
66 | X.append(x)
67 | Y.append(y)
68 |
69 | plt.gray()
70 | plt.imshow(alts)
71 | plt.scatter(Y, X, c='g', s=1)
72 | plt.title('Local Maximums on World Map with 10,000 Random Points')
73 | plt.show()
74 |
--------------------------------------------------------------------------------
/Gradient Descent/min_STM.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/harvey2phase/computational-physics/112ab8dabc25c1e522f4b5d4e14018c49efa90d6/Gradient Descent/min_STM.png
--------------------------------------------------------------------------------
/Gradient Descent/min_STM.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 | import random as ran
3 | import matplotlib.pyplot as plt
4 |
5 | # Returns True if (x, y) is within bounds
6 | def inBounds(x, y):
7 | if x > height-1 or x < 0 or y > width-1 or y < 0:
8 | return False
9 | return True
10 |
11 | # Returns True if (x, y) is a local max
12 | def localMin(x, y):
13 | for i in values:
14 | if stms[x, y] > values[i]:
15 | return False
16 | return True
17 |
18 | # Return a dict. of (x, y) containing surrounding points
19 | def adjacentCoors(x, y):
20 | s = {
21 | 0: (x, y + 1),
22 | 1: (x, y - 1),
23 | 2: (x + 1, y),
24 | 3: (x - 1, y),
25 | 4: (x + 1, y + 1),
26 | 5: (x + 1, y - 1),
27 | 6: (x - 1, y + 1),
28 | 7: (x - 1, y - 1)
29 | }
30 | rmKeys = []
31 | for key in s:
32 | xx, yy = s[key]
33 | if not inBounds(xx, yy):
34 | rmKeys.append(key)
35 | for key in rmKeys:
36 | if key in s:
37 | del s[key]
38 | return s
39 |
40 | # Returns a dict. of floats containing surrounding alt. values
41 | def adjacentValues(x, y):
42 | s = adjacentCoors(x, y)
43 | for key in s:
44 | s[key] = stms[s[key]]
45 | return s
46 |
47 | # Returns (x, y) of the step to take
48 | # (A greedy algorithm to find the next step to take)
49 | def minStep(x, y):
50 | step = min(values, key=values.get)
51 | return adjacentCoors(x, y)[step]
52 |
53 | stms = np.loadtxt('stm.txt')
54 | width, height = len(stms[0]), len(stms)
55 | X, Y = [], []
56 | N = 10 * 4
57 | for i in range(N):
58 | x, y = ran.randint(0, height-1), ran.randint(0, width-1)
59 | values = adjacentValues(x, y)
60 |
61 | while not localMin(x, y):
62 | x, y = minStep(x, y)
63 | values = adjacentValues(x, y)
64 |
65 | X.append(x)
66 | Y.append(y)
67 |
68 | plt.imshow(stms)
69 | plt.scatter(Y, X, c='r', s=1)
70 | plt.axis('off')
71 | plt.title('Minimums with 10,000 random points')
72 | plt.show()
73 |
--------------------------------------------------------------------------------
/Lotka-Volterra Simulation/Lotka-Volterra.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 | import matplotlib.pyplot as plt
3 |
4 | # The Lotka-Volterra
5 | def f(r, t):
6 | alpha, beta, gamma, delta = 1, 0.5, 0.5, 2
7 | x = r[0]
8 | y = r[1]
9 | fx = alpha * x - beta * x * y
10 | fy = gamma * x * y - delta * y
11 | return np.array([fx, fy], float)
12 |
13 | # Runge Kutta 4th Order
14 | def rk4(f, r, a, b, N):
15 | h = (b - a) / N
16 | t_points = np.arange(a, b, h)
17 | x_points, y_points = [], []
18 |
19 | for t in t_points:
20 | x_points.append(r[0])
21 | y_points.append(r[1])
22 | k1 = h * f(r, t)
23 | k2 = h * f(r + k1/2, t + h/2)
24 | k3 = h * f(r + k2/2, t + h/2)
25 | k4 = h * f(r + k3, t + h)
26 | r += (k1 + 2*k2 + 2*k3 + k4) / 6
27 |
28 | return x_points, y_points, t_points
29 |
30 | # Euler's Method
31 | def euler(f, r, a, b, N):
32 | h = (b - a) / N
33 | t_points = np.arange(a, b, h)
34 | x_points, y_points = [], []
35 |
36 | for t in t_points:
37 | x_points.append(r[0])
38 | y_points.append(r[1])
39 | r += h * f(r, t)
40 |
41 | return x_points, y_points, t_points
42 |
43 | def plot_function_of_time():
44 | # Plotting with RK4
45 | R_X, R_Y, T = rk4(f, r, a, b, N)
46 | plt.figure(1)
47 | plt.title('Lotka-Volterra with RK4; N = ' + str(N))
48 | plt.plot(T, R_X, label='Population of rabits')
49 | plt.plot(T, R_Y, label='Population of foxes')
50 | plt.xlabel('time')
51 | plt.legend()
52 | plt.savefig('Output Graphs/Function of Time/' + str(N) + ' RK4.png')
53 | plt.clf()
54 |
55 | # Plotting with Euler
56 | E_X, E_Y, T = euler(f, r, a, b, N)
57 | plt.figure(2)
58 | plt.title('Lotka-Volterra with Euler\'s Method; N = ' + str(N))
59 | plt.plot(T, E_X, label='Population of rabits')
60 | plt.plot(T, E_Y, label='Population of foxes')
61 | plt.xlabel('time')
62 | plt.legend()
63 | plt.savefig('Output Graphs/Function of Time/' + str(N) + ' Euler.png')
64 | plt.clf()
65 |
66 | # Plotting the difference
67 | D_X, D_Y = [], []
68 | for i in range(len(T)):
69 | D_X.append(abs(R_X[i] - E_X[i]))
70 | D_Y.append(abs(R_Y[i] - E_Y[i]))
71 | plt.figure(3)
72 | plt.title('Differeces between RK4 and Euler; N = ' + str(N))
73 | plt.plot(T, D_X, label='Population of rabits')
74 | plt.plot(T, D_Y, label='Population of foxes')
75 | plt.xlabel('time')
76 | plt.legend()
77 | plt.savefig('Output Graphs/Function of Time/' + str(N) + ' Diff.png')
78 | plt.clf()
79 | x, y = 2, 2
80 | r = np.array([x, y], float)
81 | a, b = 0, 30
82 |
83 | for i in np.arange(3, 7):
84 | N = 10 ** i
85 | plot_function_of_time()
86 |
87 | # Plot as a function of timestep at t = 15
88 | b = 15
89 | N = 1000
90 | D_X, D_Y, D_N = [], [], []
91 | while N < 100000:
92 | R_X, R_Y, T = rk4(f, r, a, b, N)
93 | E_X, E_Y, T = euler(f, r, a, b, N)
94 | D_X.append(abs(R_X[len(R_X)-1] - E_X[len(E_X)-1]))
95 | D_Y.append(abs(R_Y[len(R_Y)-1] - E_Y[len(E_Y)-1]))
96 | D_N.append(N)
97 | N *= 2
98 |
99 | plt.figure(4)
100 | plt.title('Differce between RK4 and Euler as function of time steps at t = 15')
101 | plt.plot(D_N, D_X, label='Population of rabits')
102 | plt.plot(D_N, D_Y, label='Population of foxes')
103 | plt.xlabel('N')
104 | plt.legend()
105 | plt.savefig('Output Graphs/Function of N.png')
106 |
--------------------------------------------------------------------------------
/Lotka-Volterra Simulation/Output Graphs/Function of N.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/harvey2phase/computational-physics/112ab8dabc25c1e522f4b5d4e14018c49efa90d6/Lotka-Volterra Simulation/Output Graphs/Function of N.png
--------------------------------------------------------------------------------
/Lotka-Volterra Simulation/Output Graphs/Function of Time/1000 Diff.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/harvey2phase/computational-physics/112ab8dabc25c1e522f4b5d4e14018c49efa90d6/Lotka-Volterra Simulation/Output Graphs/Function of Time/1000 Diff.png
--------------------------------------------------------------------------------
/Lotka-Volterra Simulation/Output Graphs/Function of Time/1000 Euler.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/harvey2phase/computational-physics/112ab8dabc25c1e522f4b5d4e14018c49efa90d6/Lotka-Volterra Simulation/Output Graphs/Function of Time/1000 Euler.png
--------------------------------------------------------------------------------
/Lotka-Volterra Simulation/Output Graphs/Function of Time/1000 RK4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/harvey2phase/computational-physics/112ab8dabc25c1e522f4b5d4e14018c49efa90d6/Lotka-Volterra Simulation/Output Graphs/Function of Time/1000 RK4.png
--------------------------------------------------------------------------------
/Lotka-Volterra Simulation/Output Graphs/Function of Time/10000 Diff.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/harvey2phase/computational-physics/112ab8dabc25c1e522f4b5d4e14018c49efa90d6/Lotka-Volterra Simulation/Output Graphs/Function of Time/10000 Diff.png
--------------------------------------------------------------------------------
/Lotka-Volterra Simulation/Output Graphs/Function of Time/10000 Euler.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/harvey2phase/computational-physics/112ab8dabc25c1e522f4b5d4e14018c49efa90d6/Lotka-Volterra Simulation/Output Graphs/Function of Time/10000 Euler.png
--------------------------------------------------------------------------------
/Lotka-Volterra Simulation/Output Graphs/Function of Time/10000 RK4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/harvey2phase/computational-physics/112ab8dabc25c1e522f4b5d4e14018c49efa90d6/Lotka-Volterra Simulation/Output Graphs/Function of Time/10000 RK4.png
--------------------------------------------------------------------------------
/Lotka-Volterra Simulation/Output Graphs/Function of Time/100000 Diff.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/harvey2phase/computational-physics/112ab8dabc25c1e522f4b5d4e14018c49efa90d6/Lotka-Volterra Simulation/Output Graphs/Function of Time/100000 Diff.png
--------------------------------------------------------------------------------
/Lotka-Volterra Simulation/Output Graphs/Function of Time/100000 Euler.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/harvey2phase/computational-physics/112ab8dabc25c1e522f4b5d4e14018c49efa90d6/Lotka-Volterra Simulation/Output Graphs/Function of Time/100000 Euler.png
--------------------------------------------------------------------------------
/Lotka-Volterra Simulation/Output Graphs/Function of Time/100000 RK4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/harvey2phase/computational-physics/112ab8dabc25c1e522f4b5d4e14018c49efa90d6/Lotka-Volterra Simulation/Output Graphs/Function of Time/100000 RK4.png
--------------------------------------------------------------------------------
/Lotka-Volterra Simulation/Output Graphs/Function of Time/1000000 Diff.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/harvey2phase/computational-physics/112ab8dabc25c1e522f4b5d4e14018c49efa90d6/Lotka-Volterra Simulation/Output Graphs/Function of Time/1000000 Diff.png
--------------------------------------------------------------------------------
/Lotka-Volterra Simulation/Output Graphs/Function of Time/1000000 Euler.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/harvey2phase/computational-physics/112ab8dabc25c1e522f4b5d4e14018c49efa90d6/Lotka-Volterra Simulation/Output Graphs/Function of Time/1000000 Euler.png
--------------------------------------------------------------------------------
/Lotka-Volterra Simulation/Output Graphs/Function of Time/1000000 RK4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/harvey2phase/computational-physics/112ab8dabc25c1e522f4b5d4e14018c49efa90d6/Lotka-Volterra Simulation/Output Graphs/Function of Time/1000000 RK4.png
--------------------------------------------------------------------------------
/Numerical Differentiation and Integration/UNDOCUMENTED.md:
--------------------------------------------------------------------------------
1 | ## UNDOCUMENTED
2 |
3 | ### Overview
4 |
5 | ### Details
6 |
7 | ### Testing
--------------------------------------------------------------------------------
/Numerical Differentiation and Integration/derivatives_graph.py:
--------------------------------------------------------------------------------
1 | # This program defines a function,
2 | # estimate the derivative of the function with various values of delta,
3 | # and plots the result
4 |
5 | import matplotlib.pyplot as plt
6 |
7 | # Define the function f(x)
8 | def f(x):
9 | return x * (x - 1)
10 |
11 | # Calculate the derivative of function f at x with delta
12 | def derivative(f, x, delta):
13 | return (f(x + delta) - f(x)) / delta
14 |
15 | # Estimate the derivative with delta 2 ** -1 to 2 ** -16
16 | p = -1
17 | while p > -16:
18 | plt.scatter(2 ** p, derivative(f, 1, 2 ** p) - 1, s = 5)
19 | p -= 1
20 |
21 | # Show results
22 | plt.title("delta vs. Derivative estimate error")
23 | plt.xlabel("Delta")
24 | plt.ylabel("Error")
25 | plt.xscale("log")
26 | plt.yscale("log")
27 | plt.show()
28 |
--------------------------------------------------------------------------------
/Numerical Differentiation and Integration/monte_carlo_and_riemann.py:
--------------------------------------------------------------------------------
1 | # This program:
2 | # 1. Defines a function
3 | # 2. Estimates the integral with various values of N
4 | # 2.1 Using Riemann sum
5 | # 2.2 Using Monte Carlo Integration method
6 | # 3. Plots the result
7 |
8 | import math as m
9 | import time as t
10 | import matplotlib.pyplot as plt
11 | import random as r
12 |
13 | # Define the function g we're investigating
14 | def g(x):
15 | return m.sqrt(1 - x ** 2)
16 |
17 | # Calculate the integral of function f with N using Reimann sum
18 | def riemann(f, N):
19 | h = 2 / N
20 | s = 0
21 |
22 | # Loop through [k, N] to simulate the Sigma function
23 | for k in range(N):
24 | x = -1 + h * (k + 1)
25 | y = f(x)
26 | s += h * y
27 |
28 | return s
29 |
30 | # Configure graph settings and show it
31 | def configure_graph():
32 | plt.title("N vs. Integral of f(x)")
33 | plt.xlabel("N")
34 | plt.ylabel("Integral of f(x)")
35 | plt.xscale("log", basex = 2)
36 | plt.yscale("log", basey = 2)
37 | plt.legend((a, b), ('Riemann', 'Monte Carlo'))
38 | plt.show()
39 |
40 | # Calculate the integral of g(x) using Monte Carlo method
41 | def monte_carlo(n):
42 | R = 1
43 | under = 0
44 |
45 | # Create n random points and append them to the list
46 | for j in range(n):
47 | x = r.uniform(-R, R)
48 | y = r.uniform(0, R)
49 |
50 | # check if the new point is under the function g(x)
51 | if g(x) >= y:
52 | under += 1
53 |
54 | f = under / n
55 | A = 2 * (R ** 2) * f
56 |
57 | return A
58 |
59 | # Evaluate the integral with N = 100
60 | print("N = 100:", riemann(g, 100))
61 |
62 | # Increase N to as large as possible in one second
63 | end = t.time() + 1
64 | i = 1
65 | while t.time() < end:
66 | a = plt.scatter(i, riemann(g, i), s = 5, c = "g")
67 | i *= 2
68 |
69 | # Show results
70 | print("Most accurate value in one second:", riemann(g, int(i / 2)))
71 |
72 | # Increase the number of spheres to as large as possible in one second
73 | end = t.time() + 1
74 | i = 1
75 | while t.time() < end:
76 | b = plt.scatter(i, monte_carlo(i), s = 5, c = "b")
77 | i *= 2
78 |
79 | configure_graph()
80 |
--------------------------------------------------------------------------------
/Powers of Euler's Constant/README.md:
--------------------------------------------------------------------------------
1 | ## Powers Of Euler's Constant
2 |
3 | ### Overview
4 |
5 | This project explores methods to evaluate e^x without using existing math functions or precomputed values of e.
6 |
7 | `exp.cpp` utilizes a simple Dynamic Programming technique to improve the time complexity while `exp.py` takes a more brute-force approach.
8 |
9 | ### Details
10 |
11 | `exp.py` defines the function `myexp()` which evaluates the value of e^x using the infinite power series e = ∑ 1⁄n! as n goes from 0 to infinity.
12 |
13 | Accuracy is the difference the result of the power series up until N-1 and that of N. The program stops when increasing N no longer changes the result of the evaluated e, i.e. when the difference is less than accuracy.
14 |
15 | `exp.cpp` takes the same approach but improves on it with simple a Dynamic Programming technique. Instead of re-evaluating the summation of the series and n! every time n is increased, both values for n-1 are stored and readily available for the computation of n, and therefore saving time.
16 |
17 | ### Testing
18 |
19 | `exp` is the executable (object code) built from `exp.cpp`. Simply download the programs and run them. Both C++ and Python programs print out the value of e^x from x = 0 to x = 19.
20 |
--------------------------------------------------------------------------------
/Powers of Euler's Constant/exp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/harvey2phase/computational-physics/112ab8dabc25c1e522f4b5d4e14018c49efa90d6/Powers of Euler's Constant/exp
--------------------------------------------------------------------------------
/Powers of Euler's Constant/exp.cpp:
--------------------------------------------------------------------------------
1 | // EXP
2 | // by Harvey Wang
3 | // Created December 2017
4 |
5 | #include
6 | #include
7 |
8 | #define ACCURACY std::pow(10.0, -7)
9 |
10 | // Prototypes
11 | double myexp(double);
12 | double powSeries(double, double, double);
13 |
14 |
15 |
16 | int main() {
17 | for (int i = 0; i < 20; i++)
18 | std::cout << myexp(i) << "\n";
19 | return 0;
20 | }
21 |
22 | // Evaluates e^x using the power seires
23 | // The function returns when the next item in the power series is less than ACCURACY (i.e. the improvment in accruacy is negligible)
24 | double myexp(double x) {
25 | double N = 1;
26 | double fact = 1;
27 | double sum = powSeries(x, N, fact) + 1;
28 |
29 | N++;
30 | fact *= N;
31 | double nextSeries = powSeries(x, N, fact);
32 |
33 | while (nextSeries > ACCURACY && N < 30) {
34 | sum += nextSeries;
35 | N++;
36 | fact *= N;
37 | nextSeries = powSeries(x, N, fact);
38 | }
39 | return sum;
40 | }
41 |
42 | // Returns the value of the Nth item in the power seires
43 | double powSeries(double x, double N, double fact) {
44 | return (std::pow(x, N) / fact);
45 | }
46 |
--------------------------------------------------------------------------------
/Powers of Euler's Constant/exp.py:
--------------------------------------------------------------------------------
1 | # EXP
2 | # by Harvey Wang
3 | # Created September 2017
4 |
5 | # recursive function to find the factorial of x
6 | def fact(x):
7 | if x == 1:
8 | return 1
9 | return x * fact(x - 1)
10 |
11 | # recursive function to evaluate e^x using power series
12 | # the precision variable is the number of time the function will sum the series
13 | def powS(x, precision):
14 | if precision == 0:
15 | return 1
16 | return (x ** precision) / fact(precision) + powS(x, precision - 1)
17 |
18 | def close_enough(x1, x2):
19 | if abs(x1 - x2) < accuracy:
20 | return True
21 | return False
22 |
23 | def myexp(x):
24 | sum1 = powS(x, 1)
25 | sum2 = powS(x, 2)
26 | i = 3
27 | # "keep adding terms until they no longer change the result"
28 | while not close_enough(sum1, sum2):
29 | sum1 = sum2
30 | sum2 = powS(x, i)
31 | i += 1
32 | return sum2
33 |
34 | accuracy = 10 ** -7
35 |
36 | # print e^i where i is 0 to 20
37 | for i in range(20):
38 | print(myexp(i))
39 |
--------------------------------------------------------------------------------
/Projectile Motion with Viscous Drag/Projectile_Motion.py:
--------------------------------------------------------------------------------
1 | import math as m
2 | import numpy as np
3 | import matplotlib.pyplot as plt
4 |
5 | # Function for projectile motion with viscous drag
6 | def f(r, t):
7 | vx = r[2]
8 | vz = r[3]
9 |
10 | dx = vx
11 | dz = vz
12 | dvx = -eta * vx
13 | dvz = -g - eta * vz
14 | return np.array([dx, dz, dvx, dvz], float)
15 |
16 | # Runge Kutta 4th Order
17 | def rk4(f, r, t):
18 | while r[1] > 0:
19 | x_points.append(r[0])
20 | z_points.append(r[1])
21 | k1 = h * f(r, t)
22 | k2 = h * f(r + k1/2, t + h/2)
23 | k3 = h * f(r + k2/2, t + h/2)
24 | k4 = h * f(r + k3, t + h)
25 | r += (k1 + 2*k2 + 2*k3 + k4) / 6
26 | t += h
27 | return t
28 |
29 | # Converts radients to degrees
30 | def r_to_d(x):
31 | return x * 180 / m.pi
32 |
33 | # Constants
34 | eta, g, t = 0.3, 9.81, 0
35 | h = 10 ** -2
36 |
37 | v = 10
38 | MAX_X, MAX_THETA, SPEED = [], [], []
39 | # Varying the speed from 1 to 45 m/s
40 | while v < 70:
41 | theta = m.pi / 10
42 | X_HIT, THETA = [], []
43 |
44 | # Varying theta from m.pi/10 to m.pi / 2
45 | while theta < m.pi / 2:
46 | vx, vz = v * m.cos(theta), v * m.sin(theta)
47 | r = np.array([1, 1, vx, vz], float)
48 | x_points, z_points = [], []
49 |
50 | t_hit = rk4(f, r, t)
51 | x_hit = x_points[len(x_points)-1]
52 | X_HIT.append(x_hit)
53 | THETA.append(theta)
54 |
55 | theta += m.pi / 1000
56 |
57 | max_hit = max(X_HIT)
58 | # Find the corresponding theta for max_hit
59 | MAX_THETA.append(r_to_d(THETA[X_HIT.index(max_hit)]))
60 | MAX_X.append(max_hit)
61 | SPEED.append(v)
62 |
63 | v += 3
64 |
65 | plt.figure(1)
66 | plt.plot(SPEED, MAX_X)
67 | plt.xlabel('Speed (m/s)')
68 | plt.ylabel('Max Distance (m)')
69 | plt.title('Projectile motion with viscous drag')
70 | plt.savefig('Speed vs Distance')
71 |
72 | plt.figure(2)
73 | plt.plot(SPEED, MAX_THETA)
74 | plt.xlabel('Speed (m/s)')
75 | plt.ylabel('Max Theta (Degrees)')
76 | plt.title('Projectile motion with viscous drag')
77 | plt.savefig('Speed vs Theta')
78 |
--------------------------------------------------------------------------------
/Projectile Motion with Viscous Drag/README.md:
--------------------------------------------------------------------------------
1 | # Newtonian Projectile Motion with Viscous Drag
2 |
3 | _More details to come. Project undocumented_
--------------------------------------------------------------------------------
/Projectile Motion with Viscous Drag/Speed vs Distance.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/harvey2phase/computational-physics/112ab8dabc25c1e522f4b5d4e14018c49efa90d6/Projectile Motion with Viscous Drag/Speed vs Distance.png
--------------------------------------------------------------------------------
/Projectile Motion with Viscous Drag/Speed vs Theta.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/harvey2phase/computational-physics/112ab8dabc25c1e522f4b5d4e14018c49efa90d6/Projectile Motion with Viscous Drag/Speed vs Theta.png
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Projects in Computational Physics
2 |
3 | This is project for me to investigate some topics in computational and theoretical physics, including numerical programming and quantum computing.
4 |
5 | I hope to experiment and bridge the knowledge gap between my two areas of study in university, computer science and physics.
6 |
7 | Some of these projects are based on assignments from the Computer Simulation in Science course (Fall 2017) at Dalhousie University.
8 |
9 | ## Goals
10 |
11 | My goals include the investigation of the following topics:
12 | * Methods and algorithms in numerical programming
13 | * Dynamic Programming
14 | * Differentiation and integration
15 | * System of linear equation
16 | * Ordinary Differential Equations
17 | * Partial Differential Equations
18 | * Comparison between different Programming languages in the context of physics and numerical programming
19 | * Python
20 | * C
21 | * C++
22 | * Pascal
23 | * Quantum computing
24 | * Numerical solution of the Schrödinger equation
25 | * Simulation of wavepackets
26 |
27 | ## Sample Outputs
28 |
29 | ### Random Walk Simulation:
30 | 
31 |
32 | ### Bilinear Interpolation:
33 | 
34 |
35 | ### Feigenbaum Plot:
36 | 
37 |
38 | ### Lotka-Volterra Simulation:
39 | 
40 |
41 | ## Installing and Testing
42 |
43 | To install, simply download the project as a zip file or clone the repository using the following Bash command:
44 |
45 | ```
46 | $ git clone https://github.com/harveytwoface/CompPhysics.git
47 | ```
48 |
49 | ## Author
50 |
51 | Harvey Wang
52 | Email: harvey@dal.ca
53 |
54 | ## Feedback
55 |
56 | I'm always looking for ideas for new projects! Please email me if you have an idea you want me to test out, or if you want to collaborate! I always love networking with new people. Also feel free to make pull requests. 😃
57 |
58 | ## Acknowledgements
59 |
60 | Big thanks to **Dr. Andrew Rutenberg**, who teaches the Computer Simulation in Science course at Dalhousie University. He inspired me to take the class material further. Please visit his website [here](http://fizz.phys.dal.ca/~adr/).
61 |
--------------------------------------------------------------------------------
/Random Walk Simulation/README.md:
--------------------------------------------------------------------------------
1 | ## Random Walk
2 |
3 | ### Overview
4 |
5 | This Project simulates a random walk in 2 dimensional space.
6 |
7 | ### Sample Output
8 |
9 | 
10 |
11 | ### Details
12 |
13 | This project contains a single file `random_walk.py`, which does the following things:
14 |
15 | * Provides a visual simulation of 1,000 particles undergoing random walks in 2-D.
16 |
17 | * Graphs the root mean square (RMS) of the particles' distances from the origin vs. time.
18 |
19 | * Graphs the RMS of the particles' maximum distances from the origin vs. time.
20 |
21 | * Graphs the ratio of the maximum RMS and RMS of distances (M/R) vs. time.
22 |
23 | There are several objects in the visual simulation, each representing a different set of data:
24 |
25 | * *The red dots*: represent the particles in 2-D making the random walks.
26 |
27 | * *The green dots*: represent the maximum points of each particle when it is furthest away from the origin.
28 |
29 | * *The red circle*: represents the root mean square (RMS) of the particles' distances from the origin.
30 |
31 | * *The green circle*: represents the RMS of the maximum points' distances.
32 |
33 | ### Testing
34 |
35 | Download the project and run `random_walk.py`.
36 |
37 | The default value for `n` and `iterations` is 1000, which represent the number of particles and random steps taken, respectively. One can modify these to observe different behaviours, or change the `for` loop on line 41 to `while true`, running the simulation indefinitely.
--------------------------------------------------------------------------------
/Random Walk Simulation/Sample Outputs/M_vs._Time.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/harvey2phase/computational-physics/112ab8dabc25c1e522f4b5d4e14018c49efa90d6/Random Walk Simulation/Sample Outputs/M_vs._Time.png
--------------------------------------------------------------------------------
/Random Walk Simulation/Sample Outputs/RMS_vs._Time.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/harvey2phase/computational-physics/112ab8dabc25c1e522f4b5d4e14018c49efa90d6/Random Walk Simulation/Sample Outputs/RMS_vs._Time.png
--------------------------------------------------------------------------------
/Random Walk Simulation/Sample Outputs/Ratio_vs._Time.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/harvey2phase/computational-physics/112ab8dabc25c1e522f4b5d4e14018c49efa90d6/Random Walk Simulation/Sample Outputs/Ratio_vs._Time.png
--------------------------------------------------------------------------------
/Random Walk Simulation/Sample Outputs/Sim.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/harvey2phase/computational-physics/112ab8dabc25c1e522f4b5d4e14018c49efa90d6/Random Walk Simulation/Sample Outputs/Sim.png
--------------------------------------------------------------------------------
/Random Walk Simulation/random_walk.py:
--------------------------------------------------------------------------------
1 | # RANDOM WALK
2 | # by Harvey Wang
3 | # Created October 2017
4 |
5 | import math as m
6 | import random as ran
7 | import numpy as np
8 | import vpython as vp
9 | import matplotlib.pyplot as plt
10 | import time as t
11 |
12 | # Define the constant parameters
13 | iterations = 1000
14 | n = 1000
15 | r = 0.1
16 | s = 0.1
17 |
18 | # Setup the canvas
19 | d = vp.canvas(x = 200, y = 200, width = 700, height = 700, center = vp.vector(0, 0, 5), background = vp.color.white)
20 | d.autoscale = False
21 | vp.rate(1000)
22 |
23 | # Create an array of 1000 spheres
24 | # Create another array of the same length to mark the maximums
25 | s_array = np.empty(n, vp.sphere)
26 | m_array = np.empty(n, vp.sphere)
27 | for i in range(n):
28 | s_array[i] = vp.sphere(radius = r, color = vp.color.red)
29 | m_array[i] = vp.sphere(radius = r, color = vp.color.green)
30 |
31 | # Create a black sphere to mark the origin
32 | origin = vp.sphere(radius = 0.15, color = vp.color.black)
33 |
34 | # Create rings to represent the RMS of spheres and maxes
35 | sph_rin = vp.ring(axis = vp.vector(0, 0, 1), thickness = 0.1, color = vp.color.red)
36 | max_rin = vp.ring(axis = vp.vector(0, 0, 1), thickness = 0.1, color = vp.color.green)
37 |
38 | start = t.time()
39 |
40 | # Move the n spheres randomly
41 | for j in range(iterations):
42 | r_sum = 0
43 | m_sum = 0
44 |
45 | for i in range(n):
46 | dx = (2 * ran.random() - 1) * s
47 | dy = (2 * ran.random() - 1) * s
48 | s_array[i].pos += vp.vector(dx, dy, 0)
49 |
50 | # Calculate distances and sums from origin
51 | d_sph = m.sqrt(s_array[i].pos.x ** 2 + s_array[i].pos.y ** 2)
52 | d_max = m.sqrt(m_array[i].pos.x ** 2 + m_array[i].pos.y ** 2)
53 | r_sum += d_sph ** 2
54 | m_sum += d_max ** 2
55 |
56 | # Check for the max point
57 | if d_sph > d_max:
58 | m_array[i].pos = s_array[i].pos
59 |
60 | # Calculate and plot the RMS of the spheres and the maximums
61 | r_RMS = m.sqrt(r_sum / n)
62 | m_RMS = m.sqrt(m_sum / n)
63 | sph_rin.radius = r_RMS
64 | max_rin.radius = m_RMS
65 | plt.figure(1)
66 | plt.scatter(t.time() - start, r_RMS)
67 | plt.figure(2)
68 | plt.scatter(t.time() - start, m_RMS)
69 | plt.figure(3)
70 | plt.scatter(t.time() - start, m_RMS / r_RMS)
71 |
72 | # Configure the graphs
73 | plt.figure(1)
74 | plt.ylabel("RMS of the spheres")
75 | plt.title("RMS of the Spheres vs. Time")
76 | plt.xlabel("Time (s)")
77 | plt.figure(2)
78 | plt.ylabel("RMS of the maximums")
79 | plt.title("RMS of the Maximums vs. Time")
80 | plt.xlabel("Time (s)")
81 | plt.figure(3)
82 | plt.title("RMS of Spheres over Maximums vs. Time")
83 | plt.ylabel("RMS of Spheres over Maximums")
84 | plt.xlabel("Time (s)")
85 | plt.show()
86 |
--------------------------------------------------------------------------------
/packet.c:
--------------------------------------------------------------------------------
1 | // Based on http://physics.oregonstate.edu/~landaur/nacphy/ComPhys/PACKETS/packets.c
2 |
3 | #include
4 | #include
5 | #include
6 |
7 | #define xDim 501 // number space pts, must be odd for simpson
8 |
9 | FILE *out1, *out2, *out3a, *out3b, *out3c, *out7a, *out7b, *out7c;
10 | FILE *out8, *out10, *out11, *out12, *out13, *out14, *input;
11 |
12 | // Prototypes
13 | void potential();
14 | void initialize(void);
15 | void solveSE(void);
16 | void output();
17 | void probability();
18 |
19 | // Global variables
20 | double rePsi[xDim][xDim][2], imPsi[xDim][xDim][2], v[xDim][xDim];
21 | double rho[xDim][xDim], j[xDim][xDim];
22 | double rho1[xDim], rho2[xDim], sumRho[xDim], corr[xDim];
23 | double w[3];
24 | double a1, a2, a3, a4, alpha, dx, dt, er, ei, eri, eii;
25 | double k1, k2, m1, m2, dm1, dm2, dm12, dm22, dxx2, dtx, con, con2;
26 | double ptot, ptotI;
27 | double sol, sig, vmax, x01, x02, y;
28 | int choice, nt, n1, n2, nprint;
29 | time_t timei, timef;
30 |
31 | int main() {
32 | int i, j;
33 | time_t timeF;
34 | time_t timeI = time(NULL);
35 |
36 | // Inititialzation of variables
37 | input = fopen("in.dat", "r");
38 |
39 | }
40 |
--------------------------------------------------------------------------------