def generate_heatmap(features = 8, zoom = 16):
= np.random.random((features,features))-0.5
heatmap = scipy.ndimage.zoom(heatmap, zoom)
large_heatmap return large_heatmap
= generate_heatmap()
large_heatmap
plt.imshow(large_heatmap)"x")
plt.xlabel("y")
plt.ylabel( plt.grid()
Local Generator
An Exception was encountered at ‘In [22]’.
Generating a latent space representation
To make it more “understandable” where material is placed we generate a slowly varying landscape by interpolation of a low resolution map.
Generating the brush
def circular_brush(diameter):
= diameter / 2
radius = np.mgrid[-radius : radius : 1j * diameter, -radius : radius : 1j * diameter]
X, Y = lambda x: np.array(x, dtype=int)
_int = _int(X) ** 2 + _int(Y) ** 2 < radius ** 2
brush return brush
=9
kernel_size= np.ones((kernel_size, kernel_size))
brush 0,0] = 0
brush[0,-1] = 0
brush[-1,0] = 0
brush[-1,-1] = 0
brush[
= circular_brush(kernel_size)
brush = brush.astype(bool)
brush
def show_brush(brush):
= brush.shape
nx, ny
plt.imshow(brush)= plt.gca()
ax +0.5)
ax.set_yticks(np.arange(nx)"" for i in range(nx)])
ax.set_yticklabels([+0.5)
ax.set_xticks(np.arange(ny)"" for i in range(ny)])
ax.set_xticklabels([=True)
ax.set_yticks(np.arange(nx), minorf"{i}" for i in range(nx)], minor=True)
ax.set_yticklabels([=True)
ax.set_xticks(np.arange(ny), minorf"{i}" for i in range(ny)], minor=True)
ax.set_xticklabels([
plt.grid()
show_brush(brush)
= scipy.ndimage.binary_dilation(np.pad(brush, len(brush)//2), brush)
conv_brush
show_brush(conv_brush)
plt.colorbar()
plt.figure()= scipy.ndimage.binary_dilation(np.pad(conv_brush, len(brush)//2), brush)
double_conv_brush
show_brush(double_conv_brush) plt.colorbar()
<matplotlib.colorbar.Colorbar at 0x7fe7d8cc67f0>
Running the Generator
dilate
dilate (img, brush, count_time=True)
Times
Times (update:float=0, dilate:float=0, required:float=0, resolving:float=0, select:float=0, convolute:float=0, existing:float=0, impossible:float=0, possible:float=0, valid:float=0, free:float=0, local_required:float=0, local_resolving:float=0, local_dilate:float=0)
GeneratorState
GeneratorState (heatmap, brush)
Initialize self. See help(type(self)) for accurate signature.
log
log (*args, level=1)
def compare(s_try, s_actual, v_try, v_actual, name):
"""
Compares properties of a new implementation and the original slow one.
Raises Error if they are not equal and plots the comparison
"""
= np.logical_xor(s_try,s_actual)
compare_s = np.logical_xor(v_try,v_actual)
compare_v
if compare_s.any() or compare_v.any():
= (6,9))
plt.figure(figsize 321)
plt.subplot("Compare Solid")
plt.title(=1, vmin=0)
plt.imshow(compare_s, vmax322)
plt.subplot("Compare Void")
plt.title(=1, vmin=0)
plt.imshow(compare_v, vmax323)
plt.subplot(f"{name} Solid")
plt.title(=1, vmin=0)
plt.imshow(s_try, vmax324)
plt.subplot(f"{name} Void")
plt.title(=1, vmin=0)
plt.imshow(v_try, vmax325)
plt.subplot(f"Actual {name} Solid")
plt.title(=1, vmin=0)
plt.imshow(s_actual, vmax326)
plt.subplot(f"Actual {name} Void")
plt.title(=1, vmin=0)
plt.imshow(v_actual, vmax
plt.show()raise ValueError(f"Calculation of {name} wrong")
def check_valid(state: GeneratorState):
if debug>2:
-= time.process_time()
times.possible = possible_pixels(state.t_s_valid,state.t_s,brush)
p_s_possible_real = possible_pixels(state.t_v_valid,state.t_v,brush)
p_v_possible_real += time.process_time()
times.possible "possible")
compare(state.p_s_possible,p_s_possible_real, state.p_v_possible,p_v_possible_real,
if debug>2:
= dilate(state.p_s_possible, state.brush, False)
p_s_possible_dilated_real = dilate(state.p_v_possible, state.brush, False)
p_v_possible_dilated_real "dilated possible")
compare(state.dilated_p_s_possible,p_s_possible_dilated_real, state.dilated_p_v_possible,p_v_possible_dilated_real,
= free_touches(state.p_v_possible, state.t_s_valid, state.brush)
t_s_free_real = free_touches(state.p_s_possible, state.t_v_valid, state.brush)
t_v_free_real "free")
compare(state.t_s_free,t_s_free_real, state.t_v_free,t_v_free_real,
if debug>1:
= valid_touches(state.t_s_impossible, state.t_s)
t_s_valid_real = valid_touches(state.t_v_impossible, state.t_v)
t_v_valid_real "valid")
compare(state.t_s_valid, t_s_valid_real, state.t_v_valid, t_v_valid_real,
if state.t_s_free.any() or state.t_v_free.any():
return
if debug>1:
= required_pixels(state.p_s_existing, state.p_v_possible)
p_s_required_real = required_pixels(state.p_v_existing, state.p_s_possible)
p_v_required_real "required")
compare(state.p_s_required,p_s_required_real, state.p_v_required,p_v_required_real,
if debug>1:
= dilate(state.p_s_required, state.brush)
p_s_required_dilated_real = dilate(state.p_v_required, state.brush)
p_v_required_dilated_real "dilated required")
compare(state.dilated_p_s_required, p_s_required_dilated_real, state.dilated_p_v_required, p_v_required_dilated_real,
= resolving_touches(state.p_s_required, state.t_s_valid, state.brush)
t_s_resolving_real = resolving_touches(state.p_v_required, state.t_v_valid, state.brush)
t_v_resolving_real "resolving") compare(state.t_s_resolving,t_s_resolving_real, state.t_v_resolving,t_v_resolving_real,
generate
generate (heatmap, brush, t_s:numpy.ndarray=None, t_v:numpy.ndarray=None)
Type | Default | Details | |
---|---|---|---|
heatmap | the latent space representation | ||
brush | the brush, determining the fabrication constraints | ||
t_s | ndarray | None | initial touches for the solid |
t_v | ndarray | None | initial touches for the void |
force_update
force_update (state)
update_resolving
update_resolving (state)
track
track (img, pos, brush, invert=False)
local_dilate
local_dilate (img, pos, brush, res, l=None, grow=True, plot=False, plot_name='')
touch
touch (flat_index:int, state:__main__.GeneratorState, solid:bool, track_possible:bool=True)
Perform a touch on the given index of the flattened map and track the consequences
select_single
select_single (s_valid, v_valid, state)
generate_feasible_design
generate_feasible_design (latent_t, brush, init_touches_solid=None, init_touches_void=None, verbose=False)
generate_feasible_design_mask
generate_feasible_design_mask (latent_t, brush, init_touches_solid=None, init_touches_void=None, verbose=False)
generate_feasible_design_mask_jvp
generate_feasible_design_mask_jvp (primals, tangents)
= Times()
times =0
debug generate(large_heatmap, brush)
<__main__.GeneratorState at 0x7fe7ca3efa60>
Times for 128 sidelength
No tracking: 6.94s
With partial tracking of existing: 6.09s
With full tracking of existing: 5.72s
With tracking of existing, impossible touches and possible pixels: 3.77s
times.__dict__
{'update': 1.4118364999999926,
'dilate': 1.3667193000000122,
'required': 0.004797800000002184,
'resolving': 1.3748482999999938,
'select': 2.172037500000017,
'convolute': 1.0879858000000011,
'existing': 0.2455430000000005,
'impossible': 0,
'possible': 0,
'valid': 0.014091300000004914,
'free': 0.08850650000001092,
'local_required': 0.0068542000000002545,
'local_resolving': 0.47692140000000016,
'local_dilate': 0.611862099999982}
import pandas as pd
import numpy as np
from tqdm.notebook import tqdm
debug=0 df = [] for features in tqdm([2, 4, 8, 10, 12, 13, 14, 15, 16, 17, 18], desc=“features”, position=0):
for i in tqdm(range(50//features), desc=“iteration”, position=1, leave=False): heatmap = generate_heatmap(features, zoom=16) times = Times() generate(heatmap) dic = times.__dict__ dic[“features”] = features df.append(dic)
df = pd.DataFrame(df)
#df.to_pickle("timing.pkl")
Execution using papermill encountered an exception here and stopped:
= pd.read_pickle("../resources/timing.pkl") df
FileNotFoundError: [Errno 2] No such file or directory: '../resources/timing.pkl'
"pixels"] = df["features"]**2*16**2
df["total"] = df["update"]+df["select"]
df[= ["local_dilate", "local_required", "local_resolving", "existing", "impossible", "possible", "valid", "free"]
linear "linear_ops"] = df[linear].sum(axis="columns")
df[= ["features", "required", "update+select", "features_sq", "update", "select"]
exclude = df.drop(columns=exclude)
df
= df.groupby("pixels").agg(np.mean)
t_mean = df.groupby("pixels").agg(np.std) t_std
def plot_timing(t_mean, t_std):
for ((col_mean,val_mean), (col_std, val_std)) in zip(t_mean.items(), t_std.items()):
*2, label=col_mean)
plt.errorbar(val_mean.index, val_mean, val_std#t_mean.drop(columns=linear).plot(y="mean", yerr="std")
"Time [s]")
plt.ylabel("Number Pixels") plt.xlabel(
=True)
plt.figure(constrained_layout=linear), t_std.drop(columns=linear))
plot_timing(t_mean.drop(columns
plt.legend()"total_time.png") plt.savefig(
=True)
plt.figure(constrained_layout
plot_timing(t_mean[linear], t_std[linear])
plt.legend()"linear_time.png") plt.savefig(