Last active
December 8, 2015 15:02
-
-
Save lindemann09/4c68f888a67e24faed2e to your computer and use it in GitHub Desktop.
This file contains 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
""" | |
Formal design of the experiment "sub-symbolic-place-value" | |
""" | |
def dec2base_x(n, base): | |
"""base x array (numpy array) of the decimal n""" | |
rtn = [] | |
while(n>0): | |
rtn.append(n%base) | |
n = n/base | |
return rtn[::-1] | |
def base_x2dec(base_x_array, base): | |
rtn = 0 | |
for c, x in enumerate(base_x_array[::-1]): | |
rtn += x*(base**c) | |
return rtn | |
def bundle(base_x_array, base): | |
return dec2base_x(base_x2dec(base_x_array, base), base) | |
def unbundle(base_x_array, levels, base): | |
bxa = base_x_array[::-1] | |
levels.sort(reverse=True) | |
for lv in levels: | |
if lv>1 and lv<=len(bxa) and bxa[lv-1]>0 : | |
bxa[lv-1] -= 1 | |
bxa[lv-2] += base | |
else: | |
raise RuntimeError("not possible") | |
return bxa[::-1] | |
######## DESIGN ########## | |
class ExpDesign(object): | |
def __init__(self, places=3, base=4, | |
distances = (1, 2, 6), | |
unbound_levels = ( [3], [2], [3,2] )): | |
self.places = places | |
self.base = base | |
self.distances = distances | |
self.unbound_levels = unbound_levels | |
@property | |
def target_numbers(self): | |
"""base 4 numbers that fulfill the following criteria: | |
1) number can be unbound at level 3 and 2 | |
i.e, places 3 and 2 of the fully bundled base-4 pattern contain | |
at least one element | |
1b) also lowest level contains element: [..and p[2]>0 ] | |
2) the numbers in all distances exist that fulfill criteria (1) | |
""" | |
targets = [] | |
#(1) | |
for x in range(self.base**(self.places-1), self.base**self.places): | |
p = dec2base_x(x, self.base) | |
if p[0]>0 and p[1]>0 and p[2]>0: ## CONSTRAINT | |
targets.append(x) | |
# (2) | |
for x in targets[:]: | |
missing_comparision_numbers = filter(lambda a: x+a not in targets, | |
self.distances) | |
if len(missing_comparision_numbers)>0: | |
targets.remove(x) | |
return targets | |
@property | |
def target_pattern(self): | |
rtn = [] | |
for n in self.target_numbers: | |
rtn.extend(self.get_different_pattern(n)) | |
return rtn | |
def get_different_pattern(self, number): | |
"""all pattern of one particular number""" | |
p = dec2base_x(number, base=self.base) | |
rtn = [p] | |
for ul in self.unbound_levels: | |
rtn.append(unbundle(p, levels=ul, base=self.base)) | |
return rtn | |
@property | |
def number_pairs(self): | |
rtn = [] | |
for x in self.target_numbers: | |
for n in self.distances: | |
rtn.append( (x, x+n)) | |
return rtn | |
@property | |
def pattern_pairs(self): | |
rtn = [] | |
for n in self.number_pairs: | |
for p0 in self.get_different_pattern(n[0]): | |
for p1 in self.get_different_pattern(n[1]): | |
rtn.append((p0, p1)) | |
return rtn | |
def __str__(self): | |
txt = "Target numbers - pattern - distance\n" | |
for x in self.target_pattern: | |
txt += " {0} - {1} - {2}\n".format(base_x2dec(x, self.base), x, sum(x)) | |
txt += "Number pairs (distances {0})\n".format(self.distances) | |
for x in self.number_pairs: | |
txt += " {0}\n".format(x) | |
txt += "\nNo. numbers: {0}\n".format(len(self.target_numbers)) | |
txt += "No. pattern: {0}\n".format(len(self.target_pattern)) | |
txt += "No. number pairs: {0}\n".format(len(self.number_pairs)) | |
txt += "No. pattern pairs: {0}\n".format(len(self.pattern_pairs)) | |
return txt | |
def make_expyriment_design(self): | |
"""just needed for the actual experiment developed in Expyriment | |
does also randomization | |
l0 is highest place value | |
""" | |
from expyriment import design | |
exp = design.Experiment() | |
block = design.Block() | |
for p in self.pattern_pairs: | |
if design.randomize.coin_flip(): # randomize position | |
p = (p[1], p[0]) | |
tr = design.Trial() | |
for x in range(3): | |
tr.set_factor("l{0}".format(3-x), p[0][x]) | |
tr.set_factor("r{0}".format(3-x), p[1][x]) | |
block.add_trial(tr) | |
block.shuffle_trials() | |
exp.add_block(block) | |
return exp | |
def plot_distance_distribution(exp_design): | |
### analyse | |
import numpy as np | |
import pandas as pd | |
import matplotlib.pyplot as plt | |
dist = [] | |
for p in exp_design.pattern_pairs: | |
dist.append([ | |
base_x2dec(p[1], base=4) - base_x2dec(p[0], base=4), | |
sum(p[1]) - sum(p[0]), | |
p[1][0] -p[0][0], | |
p[1][1] -p[0][1], | |
p[1][2] -p[0][2], | |
int(bundle(p[0], base=4)==p[0]), | |
int(bundle(p[1], base=4)==p[1]), | |
]) | |
dist = pd.DataFrame(dist, columns=["num_dist", "dot_dist_total", "dot_dist_3", | |
"dot_dist_2", "dot_dist_1", "bundled1", "bundled2" ]) | |
print dist | |
fig = plt.figure() | |
plt.subplot(221) | |
for c, x in dist.iterrows(): | |
a = np.random.normal(0, scale=0.05, size=1) | |
b = np.random.normal(0, scale=0.2, size=1) | |
plt.plot(x.num_dist+a, x.dot_dist_total+b, 'ro') | |
plt.axis([0, 7, -7, 12]) | |
plt.xlabel("Numerical distanc") | |
plt.ylabel("Distance dot total") | |
plt.subplot(222) | |
for c, x in dist.iterrows(): | |
a = np.random.normal(0, scale=0.05, size=1) | |
b = np.random.normal(0, scale=0.2, size=1) | |
plt.plot(x.num_dist+a, x.dot_dist_1+b, 'ro') | |
plt.axis([0, 7, -7, 12]) | |
plt.xlabel("Numerical distanc") | |
plt.ylabel("Distance dot 1") | |
plt.subplot(223) | |
for c, x in dist.iterrows(): | |
a = np.random.normal(0, scale=0.05, size=1) | |
b = np.random.normal(0, scale=0.2, size=1) | |
plt.plot(x.num_dist+a, x.dot_dist_2+b, 'ro') | |
plt.axis([0, 7, -7, 12]) | |
plt.xlabel("Numerical distanc") | |
plt.ylabel("Distance dot 2") | |
plt.subplot(224) | |
for c, x in dist.iterrows(): | |
a = np.random.normal(0, scale=0.05, size=1) | |
b = np.random.normal(0, scale=0.2, size=1) | |
plt.plot(x.num_dist+a, x.dot_dist_3+b, 'ro') | |
plt.axis([0, 7, -7, 12]) | |
plt.xlabel("Numerical distanc") | |
plt.ylabel("Distance dot 3") | |
plt.show() | |
if __name__ == "__main__": | |
ed = ExpDesign(places=3, base=4, | |
distances= [1, 2, 6], | |
unbound_levels = [ [3], [2], [3,2] ]) | |
print ed | |
#plot_distance_distribution(ed) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment