def decode(block: Block, solution: List[int]) -> dict: # Sort the list and remove any negative (false) variables solution.sort() solution = list(filter(lambda v: v > 0, solution)) # Separate into simple/complex variables. simple_variables = list( filter(lambda v: v <= block.grid_variables(), solution)) complex_variables = list( filter(lambda v: v > block.grid_variables(), solution)) experiment = cast(dict, {}) # Simple factors tuples = list(map(lambda v: block.decode_variable(v), simple_variables)) string_tuples = list( map(lambda t: (t[0].factor_name, t[1].external_name), tuples)) for (factor_name, level_name) in string_tuples: if factor_name not in experiment: experiment[factor_name] = [] experiment[factor_name].append(level_name) # Complex factors - The challenge here is knowing when to insert '', rather than using the variables. # Start after 'width' trials, and shift 'stride' trials for each variable. complex_factors = list( filter(lambda f: f.has_complex_window, block.design)) for f in complex_factors: # Get variables for this factor start = block.first_variable_for_level(f, f.levels[0]) + 1 end = start + block.variables_for_factor(f) variables = list( filter(lambda n: n in range(start, end), complex_variables)) # Get the level names for the variables in the solution. level_tuples = list( map(lambda v: block.decode_variable(v), variables)) level_names = list( map(lambda t: (t[1].external_name), level_tuples)) # Intersperse empty strings for the trials to which this factor does not apply. #level_names = list(intersperse('', level_names, f.levels[0].window.stride - 1)) #level_names = list(repeat('', f.levels[0].window.width - 1)) + level_names level_names_fill = [] for n in range(block.trials_per_sample()): level_names_fill.append( level_names.pop(0) if f.applies_to_trial(n + 1) else '') experiment[f.factor_name] = level_names_fill return experiment
def __decode(block: Block, solution: List[int]) -> dict: gt0 = lambda n: n > 0 simple_variables = list(filter(gt0, solution[:block.grid_variables()])) complex_variables = list( filter(gt0, solution[block.grid_variables():block.variables_per_sample()])) experiment = cast(dict, {}) # Simple factors tuples = list(map(lambda v: block.decode_variable(v), simple_variables)) for (factor_name, level_name) in tuples: if factor_name not in experiment: experiment[factor_name] = [] experiment[factor_name].append(level_name) # Complex factors - The challenge here is knowing when to insert '', rather than using the variables. # Start after 'width' trials, and shift 'stride' trials for each variable. complex_factors = list( filter(lambda f: f.has_complex_window(), block.design)) for f in complex_factors: # Get variables for this factor start = block.first_variable_for_level(f.name, f.levels[0].name) + 1 end = start + block.variables_for_factor(f) variables = list( filter(lambda n: n in range(start, end), complex_variables)) # Get the level names for the variables in the solution. level_names = list( map(lambda v: block.decode_variable(v)[1], variables)) # Intersperse empty strings for the trials to which this factor does not apply. level_names = list( intersperse('', level_names, f.levels[0].window.stride - 1)) level_names = list(repeat('', f.levels[0].window.width - 1)) + level_names experiment[f.name] = level_names return experiment
def __apply_derivation_with_complex_window(self, block: Block, backend_request: BackendRequest) -> None: trial_size = block.variables_per_trial() trial_count = block.trials_per_sample() iffs = [] f = self.factor window = f.levels[0].window t = 0 for n in range(trial_count): if not f.applies_to_trial(n + 1): continue num_levels = len(f.levels) get_trial_size = lambda x: trial_size if x < block.grid_variables() else len(block.decode_variable(x+1)[0].levels) or_clause = Or(list(And(list(map(lambda x: x + (t * window.stride * get_trial_size(x) + 1), l))) for l in self.dependent_idxs)) iffs.append(Iff(self.derived_idx + (t * num_levels) + 1, or_clause)) t += 1 (cnf, new_fresh) = block.cnf_fn(And(iffs), backend_request.fresh) backend_request.cnfs.append(cnf) backend_request.fresh = new_fresh
def is_complex(self, block: Block): return self.derived_idx < block.grid_variables()