Fix #2: Clean up duplicate imports and paste blocks in solver_core.py
Browse files- itt_solver/solver_core.py +10 -9
itt_solver/solver_core.py
CHANGED
|
@@ -1,8 +1,11 @@
|
|
| 1 |
import numpy as np
|
|
|
|
|
|
|
| 2 |
|
| 3 |
def initialize_potential(grid):
|
| 4 |
return np.array(grid, dtype=float)
|
| 5 |
|
|
|
|
| 6 |
def discrete_gradient(phi):
|
| 7 |
gx = np.zeros_like(phi)
|
| 8 |
gy = np.zeros_like(phi)
|
|
@@ -11,13 +14,16 @@ def discrete_gradient(phi):
|
|
| 11 |
mag = np.sqrt(gx**2 + gy**2)
|
| 12 |
return gx, gy, mag
|
| 13 |
|
|
|
|
| 14 |
def dirichlet_energy(phi):
|
| 15 |
_, _, mag = discrete_gradient(phi)
|
| 16 |
return np.sum(mag**2)
|
| 17 |
|
|
|
|
| 18 |
def sigma_l1(phi_current, phi_target):
|
| 19 |
return np.sum(np.abs(phi_target - phi_current))
|
| 20 |
|
|
|
|
| 21 |
def tile_transform(phi_in, out_shape):
|
| 22 |
h_in, w_in = phi_in.shape
|
| 23 |
h_out, w_out = out_shape
|
|
@@ -26,27 +32,21 @@ def tile_transform(phi_in, out_shape):
|
|
| 26 |
for j in range(w_out):
|
| 27 |
out[i, j] = phi_in[i % h_in, j % w_in]
|
| 28 |
return out
|
| 29 |
-
# paste into itt_solver/solver_core.py replacing old fill_enclosed
|
| 30 |
-
import numpy as np
|
| 31 |
-
from collections import Counter
|
| 32 |
-
from collections import deque
|
| 33 |
|
| 34 |
-
import numpy as _np
|
| 35 |
-
from collections import Counter, deque
|
| 36 |
|
| 37 |
def fill_enclosed(phi, boundary_mask=None):
|
| 38 |
"""
|
| 39 |
Fill zero regions that are fully enclosed by non-zero boundary.
|
| 40 |
Returns a new array with enclosed holes filled with modal neighbor color.
|
| 41 |
"""
|
| 42 |
-
arr =
|
| 43 |
h, w = arr.shape
|
| 44 |
if boundary_mask is None:
|
| 45 |
boundary = (arr != 0)
|
| 46 |
else:
|
| 47 |
-
boundary =
|
| 48 |
|
| 49 |
-
visited =
|
| 50 |
filled = arr.copy()
|
| 51 |
|
| 52 |
def flood(start_r, start_c):
|
|
@@ -107,6 +107,7 @@ class Transform:
|
|
| 107 |
def __repr__(self):
|
| 108 |
return f"<Transform {self.name}>"
|
| 109 |
|
|
|
|
| 110 |
def beam_minimize(phi_in, phi_target, atomic_library, beam_width=4, max_depth=4, lock_coeff=0.1):
|
| 111 |
identity = Transform(lambda p: p, "Id")
|
| 112 |
beam = [(identity, phi_in, 0.0)]
|
|
|
|
| 1 |
import numpy as np
|
| 2 |
+
from collections import Counter, deque
|
| 3 |
+
|
| 4 |
|
| 5 |
def initialize_potential(grid):
|
| 6 |
return np.array(grid, dtype=float)
|
| 7 |
|
| 8 |
+
|
| 9 |
def discrete_gradient(phi):
|
| 10 |
gx = np.zeros_like(phi)
|
| 11 |
gy = np.zeros_like(phi)
|
|
|
|
| 14 |
mag = np.sqrt(gx**2 + gy**2)
|
| 15 |
return gx, gy, mag
|
| 16 |
|
| 17 |
+
|
| 18 |
def dirichlet_energy(phi):
|
| 19 |
_, _, mag = discrete_gradient(phi)
|
| 20 |
return np.sum(mag**2)
|
| 21 |
|
| 22 |
+
|
| 23 |
def sigma_l1(phi_current, phi_target):
|
| 24 |
return np.sum(np.abs(phi_target - phi_current))
|
| 25 |
|
| 26 |
+
|
| 27 |
def tile_transform(phi_in, out_shape):
|
| 28 |
h_in, w_in = phi_in.shape
|
| 29 |
h_out, w_out = out_shape
|
|
|
|
| 32 |
for j in range(w_out):
|
| 33 |
out[i, j] = phi_in[i % h_in, j % w_in]
|
| 34 |
return out
|
|
|
|
|
|
|
|
|
|
|
|
|
| 35 |
|
|
|
|
|
|
|
| 36 |
|
| 37 |
def fill_enclosed(phi, boundary_mask=None):
|
| 38 |
"""
|
| 39 |
Fill zero regions that are fully enclosed by non-zero boundary.
|
| 40 |
Returns a new array with enclosed holes filled with modal neighbor color.
|
| 41 |
"""
|
| 42 |
+
arr = np.array(phi, dtype=int)
|
| 43 |
h, w = arr.shape
|
| 44 |
if boundary_mask is None:
|
| 45 |
boundary = (arr != 0)
|
| 46 |
else:
|
| 47 |
+
boundary = np.array(boundary_mask, dtype=bool)
|
| 48 |
|
| 49 |
+
visited = np.zeros((h, w), dtype=bool)
|
| 50 |
filled = arr.copy()
|
| 51 |
|
| 52 |
def flood(start_r, start_c):
|
|
|
|
| 107 |
def __repr__(self):
|
| 108 |
return f"<Transform {self.name}>"
|
| 109 |
|
| 110 |
+
|
| 111 |
def beam_minimize(phi_in, phi_target, atomic_library, beam_width=4, max_depth=4, lock_coeff=0.1):
|
| 112 |
identity = Transform(lambda p: p, "Id")
|
| 113 |
beam = [(identity, phi_in, 0.0)]
|