-
Notifications
You must be signed in to change notification settings - Fork 0
/
coarse.py
111 lines (92 loc) · 3.99 KB
/
coarse.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.patches import Rectangle
class TileCoding:
"""
Class for the tile coding. One tile coding has multiple tilings.
"""
def __init__(self, num_tilings, partitions, x_range, y_range, extra_lengths, offset_percent):
self.tilings = []
self.num_tilings = num_tilings
self.partitions = partitions
self.x_range = x_range
self.y_range = y_range
self.extra_lengths = extra_lengths
self.offset_percent = offset_percent
self._add_tilings()
def _add_tilings(self):
max_offset_x = self.extra_lengths[0] * self.offset_percent
max_offset_y = self.extra_lengths[1] * self.offset_percent
for i in range(self.num_tilings):
offset_x = np.random.uniform(0, max_offset_x)
offset_y = np.random.uniform(0, max_offset_y)
x_range = (self.x_range[0], self.x_range[1]+self.extra_lengths[0])
y_range = (self.y_range[0], self.y_range[1]+self.extra_lengths[1])
tiling = Tiling(self.partitions, x_range, y_range, offset_x, offset_y)
self.tilings.append(tiling)
def get_encoding(self, x, y):
encoding = np.array([])
for tiling in self.tilings:
encoding = np.concatenate((encoding, tiling.get_encoding(x, y)), axis=None)
return encoding
def visualize(self):
fig, ax = plt.subplots()
ax.plot([self.x_range[0]-self.extra_lengths[0], self.x_range[1]+self.extra_lengths[0]],
[self.y_range[0]-self.extra_lengths[1], self.y_range[1]+self.extra_lengths[0]],
alpha=0)
for tile in self.tilings:
x = tile.x_range[0] - tile.offset_x
y = tile.y_range[0] - tile.offset_y
width = tile.width * self.partitions
height = tile.height * self.partitions
ax.add_patch(Rectangle((x, y), width, height,
edgecolor='pink',
facecolor='blue',
fill=True,
lw=5,
alpha=0.3))
width = self.x_range[1] - self.x_range[0]
height = self.y_range[1] - self.y_range[0]
ax.add_patch(Rectangle((self.x_range[0], self.y_range[0]), width, height,
edgecolor='pink',
facecolor='grey',
fill=True,
lw=5,
alpha=0.5))
plt.show()
class Tiling:
"""
Class for a single tiling. Has an offset.
"""
def __init__(self, partitions, x_range, y_range, offset_x, offset_y):
self.partitions = partitions
self.x_range = x_range
self.y_range = y_range
self.offset_x = offset_x
self.offset_y = offset_y
self.width = (x_range[1] - x_range[0]) / partitions
self.height = (y_range[1] - y_range[0]) / partitions
def get_encoding(self, x, y):
encoding = np.zeros((self.partitions, self.partitions))
y_low = self.y_range[0] - self.offset_y
for i in range(self.partitions - 1, -1, -1):
x_low = self.x_range[0] - self.offset_x
for j in range(self.partitions):
x_range = (x_low, x_low + self.width)
y_range = (y_low, y_low + self.height)
if self._in_square(x, y, x_range, y_range):
encoding[i, j] = 1
return encoding.flatten()
x_low += self.width
y_low += self.height
raise ValueError("The point is outside the tiling")
@staticmethod
def _in_square(x, y, x_range, y_range):
if x_range[0] <= x < x_range[1] and y_range[0] <= y < y_range[1]:
return True
return False
if __name__ == "__main__":
tc = TileCoding(4, 4, (-1.2, 0.6), (-0.7, 0.7), (0.5, 0.5), 1)
tc.visualize()
print(tc.get_encoding(-1.2, -0.7))
pass