Last active
December 15, 2017 08:50
-
-
Save serser/dfa7d0e41054a8c4d3236bc88c69137c to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# ------------- | |
# User Instructions | |
# | |
# Now you will be incorporating fixed points into | |
# your smoother. | |
# | |
# You will need to use the equations from gradient | |
# descent AND the new equations presented in the | |
# previous lecture to implement smoothing with | |
# fixed points. | |
# | |
# Your function should return the newpath that it | |
# calculates. | |
# | |
# Feel free to use the provided solution_check function | |
# to test your code. You can find it at the bottom. | |
# | |
from copy import deepcopy | |
from math import * | |
import numpy as np | |
import matplotlib.pyplot as plt | |
######################## ENTER CODE BELOW HERE ######################### | |
def diff(path, newpath): | |
error = 0 | |
for i in range(len(path)): | |
px,py = path[i] | |
npx, npy = newpath[i] | |
error += (px-npx)**2 + (py-npy)**2 | |
return sqrt(error) | |
def smooth(path, fix, weight_data = 0.0, weight_smooth = 0.1, tolerance = 0.000001): | |
# | |
# Enter code here. | |
# The weight for each of the two new equations should be 0.5 * weight_smooth | |
# | |
newpath = deepcopy(path) | |
last_path = deepcopy(path) | |
done = False | |
while not done: | |
for i in range(len(path)): | |
if (fix[i]!=1): | |
px, py = path[i] | |
npx, npy = newpath[i] | |
nprx, npry = newpath[(i+1)%len(path)] | |
nprx2, npry2 = newpath[(i+2)%len(path)] | |
nplx, nply = newpath[(i-1)%len(path)] | |
nplx2, nply2 = newpath[(i-2)%len(path)] | |
newpath[i][0] += weight_smooth*(nprx+nplx-2*npx) + (weight_smooth/2.0)*(2*nplx-nplx2-npx) + (weight_smooth/2.0)*(2*nprx-nprx2-npx) | |
newpath[i][1] += weight_smooth*(npry+nply-2*npy) + (weight_smooth/2.0)*(2*nply-nply2-npy) + (weight_smooth/2.0)*(2*npry-npry2-npy) | |
if diff(newpath, last_path) <= tolerance: | |
done = True | |
last_path = deepcopy(newpath) | |
#print newpath | |
return newpath | |
# -------------- | |
# Testing Instructions | |
# | |
# To test your code, call the solution_check function with the argument smooth: | |
# solution_check(smooth) | |
# | |
def solution_check(smooth, eps = 0.0001): | |
def test_case_str(path, fix): | |
assert( len(path) == len(fix) ) | |
if len(path) == 0: | |
return '[]' | |
if len(path) == 1: | |
s = '[' + str(path[0]) + ']' | |
if fix[0]: s += ' #fix' | |
return s | |
s = '[' + str(path[0]) + ',' | |
if fix[0]: s += ' #fix' | |
for pt,f in zip(path[1:-1],fix[1:-1]): | |
s += '\n ' + str(pt) + ',' | |
if f: s += ' #fix' | |
s += '\n ' + str(path[-1]) + ']' | |
if fix[-1]: s += ' #fix' | |
return s | |
testpaths = [[[0, 0],[1, 0],[2, 0],[3, 0],[4, 0],[5, 0],[6, 0],[6, 1],[6, 2],[6, 3],[5, 3],[4, 3],[3, 3],[2, 3],[1, 3],[0, 3],[0, 2],[0, 1]], | |
[[0, 0],[2, 0],[4, 0],[4, 2],[4, 4],[2, 4],[0, 4],[0, 2]]] | |
testfixpts = [[1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0], | |
[1, 0, 1, 0, 1, 0, 1, 0]] | |
pseudo_answers = [[[0, 0],[0.7938620981547201, -0.8311168821106101],[1.8579052986461084, -1.3834788165869276],[3.053905318597796, -1.5745863173084],[4.23141390533387, -1.3784271816058231],[5.250184859723701, -0.8264215958231558],[6, 0],[6.415150091996651, 0.9836951698796843],[6.41942442687092, 2.019512290770163],[6, 3],[5.206131365604606, 3.831104483245191],[4.142082497497067, 4.383455704596517],[2.9460804122779813, 4.5745592975708105],[1.768574219397359, 4.378404668718541],[0.7498089205417316, 3.826409771585794],[0, 3],[-0.4151464728194156, 2.016311854977891],[-0.4194207879552198, 0.9804948340550833]], | |
[[0, 0],[2.0116767115496095, -0.7015439080661671],[4, 0],[4.701543905420104, 2.0116768147460418],[4, 4],[1.9883231877640861, 4.701543807525115],[0, 4],[-0.7015438099112995, 1.9883232808252207]]] | |
true_answers = [[[0, 0],[0.7826068175979299, -0.6922616156406778],[1.826083356960912, -1.107599209206985],[2.999995745732953, -1.2460426422963626],[4.173909508264126, -1.1076018591282746],[5.217389489606966, -0.6922642758483151],[6, 0],[6.391305105067843, 0.969228211275216],[6.391305001845138, 2.0307762911524616],[6, 3],[5.217390488523538, 3.6922567975830876],[4.17391158149052, 4.107590195596796],[2.9999982969959467, 4.246032043344827],[1.8260854997325473, 4.107592961155283],[0.7826078838205919, 3.692259569132191],[0, 3],[-0.3913036785959153, 2.030774470796648], [-0.3913035729270973, 0.9692264531461132]], | |
[[0, 0],[1.9999953708444873, -0.6666702980585777],[4, 0],[4.666670298058577, 2.000005101453379],[4, 4],[1.9999948985466212, 4.6666612524128],[0, 4],[-0.6666612524127998, 2.000003692691148]]] | |
newpaths = map(lambda p: smooth(*p), zip(testpaths,testfixpts)) | |
correct = True | |
for path,fix,p_answer,t_answer,newpath in zip(testpaths,testfixpts, | |
pseudo_answers,true_answers, | |
newpaths): | |
if type(newpath) != list: | |
print "Error: smooth did not return a list for the path:" | |
print test_case_str(path,fix) + '\n' | |
correct = False | |
continue | |
if len(newpath) != len(path): | |
print "Error: smooth did not return a list of the correct length for the path:" | |
print test_case_str(path,fix) + '\n' | |
correct = False | |
continue | |
good_pairs = True | |
for newpt,pt in zip(newpath,path): | |
if len(newpt) != len(pt): | |
good_pairs = False | |
break | |
if not good_pairs: | |
print "Error: smooth did not return a list of coordinate pairs for the path:" | |
print test_case_str(path,fix) + '\n' | |
correct = False | |
continue | |
assert( good_pairs ) | |
# check whether to check against true or pseudo answers | |
answer = None | |
if abs(newpath[1][0] - t_answer[1][0]) <= eps: | |
answer = t_answer | |
elif abs(newpath[1][0] - p_answer[1][0]) <= eps: | |
answer = p_answer | |
else: | |
print 'smooth returned an incorrect answer for the path:' | |
print test_case_str(path,fix) + '\n' | |
continue | |
assert( answer is not None ) | |
entries_match = True | |
for p,q in zip(newpath,answer): | |
for pi,qi in zip(p,q): | |
if abs(pi - qi) > eps: | |
entries_match = False | |
break | |
if not entries_match: break | |
if not entries_match: | |
print 'smooth returned an incorrect answer for the path:' | |
print test_case_str(path,fix) + '\n' | |
continue | |
assert( entries_match ) | |
if answer == t_answer: | |
print 'smooth returned the correct answer for the path:' | |
print test_case_str(path,fix) + '\n' | |
elif answer == p_answer: | |
print 'smooth returned a correct* answer for the path:' | |
print test_case_str(path,fix) | |
print '''*However, your answer uses the "nonsimultaneous" update method, which | |
is not technically correct. You should modify your code so that newpath[i][j] is only | |
updated once per iteration, or else the intermediate updates made to newpath[i][j] | |
will affect the final answer.\n''' | |
testpath1 = np.array(path) | |
spath = np.array(newpath) | |
plt.plot(testpath1[:,0], testpath1[:,1]) | |
plt.plot(spath[:,0], spath[:,1]) | |
plt.show() | |
solution_check(smooth) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment