/** gate score = smallest noise margin (distance in log(REU) of input REU to margin REU) */ public static void evaluateGateNoiseMargin(Gate g, Args options) { if (options.is_noise_margin() == false) { g.get_scores().set_noise_margin_contract(true); return; } if (g.Type == GateType.INPUT || g.Type == GateType.OUTPUT || g.Type == GateType.OUTPUT_OR) { return; } // "x" to value HashMap<String, Double> lowest_on_reu = GateUtil.getIncomingONlow(g); HashMap<String, Double> highest_off_reu = GateUtil.getIncomingOFFhigh(g); ArrayList<Double> all_margins = new ArrayList<Double>(); for (String var : highest_off_reu.keySet()) { if (g.get_variable_thresholds().get(var) != null) { // IL is the input-low threshold Double IL = g.get_variable_thresholds().get(var)[0]; // actual REU Double log_input_reu = Math.log10(highest_off_reu.get(var)); // NML is the margin/width between the actual REU and the threshold REU Double NML = Math.log10(IL) - log_input_reu; all_margins.add(NML); } } for (String var : lowest_on_reu.keySet()) { if (g.get_variable_thresholds().get(var) != null) { Double IH = g.get_variable_thresholds().get(var)[1]; Double NMH = Math.log10(lowest_on_reu.get(var)) - Math.log10(IH); all_margins.add(NMH); } } if (all_margins.isEmpty()) { g.get_scores().set_noise_margin(0.0); g.get_scores().set_noise_margin_contract(true); } else { Collections.sort(all_margins); g.get_scores().set_noise_margin(all_margins.get(0)); if (all_margins.get(0) < 0) { g.get_scores().set_noise_margin_contract(false); } else { g.get_scores().set_noise_margin_contract(true); } } }