Skip to content
Snippets Groups Projects
Commit 9b6fb850 authored by xiyehu2's avatar xiyehu2
Browse files

added optimized table generation algorithm

parent e5c4caa3
No related branches found
No related tags found
No related merge requests found
......@@ -136,14 +136,51 @@ def create_path_table(wfm: Waveform) -> any:
# return path_table.astype(int), np.sum(path_table.diagonal().T, axis=0, dtype=int)
def stack_left(i_start, i_end, offset, stack_size=0):
# calculate first index where the reduced path algorithm is applied
# threshold = 0.01
# cutoff = np.ceil(np.log(threshold) / np.log(1-load_p))
# cutoff = int(cutoff)
# print(cutoff)
if stack_size == 0:
stack_size = np.floor((i_end - i_start) / 2)
stack_last = int(stack_size + i_start) - 1
dist_mod = (i_end - i_start - stack_size) / (i_end - i_start) # max_distance ratio
dist_add = offset
# get a list of moves to pre-generate
moves = []
max_dist = 0
for i in range(i_start, i_end):
moves.append([])
j_max = i if i < stack_last else stack_last
dist = np.ceil((i - i_start) * dist_mod + dist_add)
j_min = int(i - dist) if i - dist >= i_start else i_start
for j in range(j_min, j_max + 1):
moves[i - i_start].append(j) # add all paths between j_min and j_max
if max_dist < abs(j-i):
max_dist = abs(j-i)
return moves, max_dist
def stack_right(i_start, i_end, offset, stack_size=0):
moves, max_dist = stack_left(i_start, i_end, offset=offset, stack_size=stack_size)
moves.reverse()
for i in range(len(moves)):
moves[i].reverse()
for j in range(len(moves[i])):
moves[i][j] = i_end - 1 - moves[i][j] + i_start
return moves, max_dist
def create_path_table_reduced(
wfm: Waveform, target_idx, max_dist=np.inf, save_path=None
wfm: Waveform, target_idx, dist_offset=np.inf, save_path=None, partition=False
) -> Tuple[Dict[Tuple[int, int], np.ndarray], np.ndarray]:
"""
create a dim-3 look up table where the table[i,j] contains a sine wave to move tweezer i to tweezer j
:param save_path: file saving path
:param target_idx: indices of target pattern
:param max_dist: maximum move distance in indices
:param dist_offset: maximum move distance in indices
:param wfm: waveform object already initialized with basic parameters.
:return: dictionary containing rearrange paths
"""
......@@ -153,19 +190,38 @@ def create_path_table_reduced(
a = wfm.amplitude
omega_interp = interp1d(w, a, kind='cubic')
# obtain all move combinations:
n = len(wfm.omega) # total number of tweezers
nt = len(wfm.omega) # total number of tweezers
moves = []
target = np.zeros(nt)
target[target_idx] = 1
dw_max = 0 # longest move, this sets the size of path_table
for i in range(n):
moves.append([])
for j in target_idx:
if i < j and True: # only allow uni-direction moves
continue
if abs(i - j) <= max_dist:
moves[i].append(j)
dw = abs(wfm.omega[j] - wfm.omega[i])
if dw_max < dw: dw_max = dw
if not partition:
# obtain all move combinations, target based, non-partitioned:
for i in range(nt):
moves.append([])
for j in target_idx:
if i < j and True: # only allow uni-direction moves
continue
if abs(i - j) <= dist_offset:
moves[i].append(j)
dw = abs(wfm.omega[j] - wfm.omega[i])
if dw_max < dw: dw_max = dw
if partition:
offset = dist_offset
divide_idx = int(np.floor(np.median(target_idx)))
left_size = np.sum(target[:divide_idx], dtype=int)
right_size = np.sum(target[divide_idx:], dtype=int)
moves_l, dw_max_l = stack_right(0, divide_idx, offset, left_size) # stack left side to right
moves_r, dw_max_r = stack_left(divide_idx, nt, offset, right_size)
# print("stack size, half size, middle:", len(t_idx), left_size, right_size)
moves_l.extend(moves_r)
moves = moves_l
dw_max = dw_max_l if dw_max_l > dw_max_r else dw_max_r
dw_max = abs(wfm.omega[dw_max] - wfm.omega[0])
print(dw_max / 2 / np.pi)
# setup basic variables
twopi = 2 * np.pi
vmax = KILO(20) * MEGA(1) # convert units, 20 kHz/us -> 20e3 * 1e6 Hz/s
......@@ -271,13 +327,13 @@ def create_path_table_reduced(
def create_path_table_reduced_gpu(
wfm: Waveform, target_idx, max_dist=np.inf, save_path=None
wfm: Waveform, target_idx, dist_offset=np.inf, save_path=None, partition=False
) -> Tuple[Dict[Tuple[int, int], np.ndarray], np.ndarray]:
"""
create a dim-3 look up table where the table[i,j] contains a sine wave to move tweezer i to tweezer j
:param save_path: file saving path
:param target_idx: indices of target pattern
:param max_dist: maximum move distance in indices
:param dist_offset: maximum move distance in indices
:param wfm: waveform object already initialized with basic parameters.
:return: dictionary containing rearrange paths
"""
......@@ -289,19 +345,37 @@ def create_path_table_reduced_gpu(
a = wfm.amplitude
omega_interp = interp1d(w, a, kind='cubic')
# obtain all move combinations:
n = len(wfm.omega) # total number of tweezers
nt = len(wfm.omega) # total number of tweezers
moves = []
target = np.zeros(nt)
target[target_idx] = 1
dw_max = 0 # longest move, this sets the size of path_table
for i in range(n):
moves.append([])
for j in target_idx:
if i < j and True: # only allow uni-direction moves
continue
if abs(i - j) <= max_dist:
moves[i].append(j)
dw = abs(wfm.omega[j] - wfm.omega[i])
if dw_max < dw: dw_max = dw
if not partition:
# obtain all move combinations, target based, non-partitioned:
for i in range(nt):
moves.append([])
for j in target_idx:
if i < j and True: # only allow uni-direction moves
continue
if abs(i - j) <= dist_offset:
moves[i].append(j)
dw = abs(wfm.omega[j] - wfm.omega[i])
if dw_max < dw: dw_max = dw
if partition:
offset = dist_offset
divide_idx = int(np.floor(np.median(target_idx)))
left_size = np.sum(target[:divide_idx], dtype=int)
right_size = np.sum(target[divide_idx:], dtype=int)
moves_l, dw_max_l = stack_right(0, divide_idx, offset, left_size) # stack left side to right
moves_r, dw_max_r = stack_left(divide_idx, nt, offset, right_size)
# print("stack size, half size, middle:", len(t_idx), left_size, right_size)
moves_l.extend(moves_r)
moves = moves_l
dw_max = dw_max_l if dw_max_l > dw_max_r else dw_max_r
dw_max = abs(wfm.omega[dw_max] - wfm.omega[0])
print("max dw:", dw_max / 2 / np.pi)
# setup basic variables
twopi = 2 * np.pi
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment