@Test public void testWithMultipleDomains() { ConditionalWeightUpdater weightUpdate = new ConditionalWeightUpdater(0.1, 2, false); addDataOfNonParticipatingFeatures(weightUpdate); assertEquals(10, weightUpdate.calcWeightUpdate("f2", d1, 100), EPSILON); assetPendingWeightValues(weightUpdate, "f2", 90, 0, 0, 0); assertEquals(-9, weightUpdate.calcWeightUpdate("f2", d2, -90), EPSILON); assetPendingWeightValues(weightUpdate, "f2", 90, -81, 0, 0); assertEquals(80, weightUpdate.calcWeightUpdate("f2", d3, 80), EPSILON); assetPendingWeightValues(weightUpdate, "f2", 10, -81, 0, 0); assertEquals(10, weightUpdate.calcWeightUpdate("f2", d3, 70), EPSILON); assetPendingWeightValues(weightUpdate, "f2", 0, -81, 60, 0); assertEquals(5, weightUpdate.calcWeightUpdate("f2", d3, 50), EPSILON); assetPendingWeightValues(weightUpdate, "f2", 0, -81, 105, 0); assertEquals(105, weightUpdate.calcWeightUpdate("f2", d1, 200), EPSILON); assetPendingWeightValues(weightUpdate, "f2", 95, -81, 0, 0); assertEquals(-5, weightUpdate.calcWeightUpdate("f2", d1, -50), EPSILON); assetPendingWeightValues(weightUpdate, "f2", 50, -76, 0, 0); assertEquals(-50, weightUpdate.calcWeightUpdate("f2", d1, -100), EPSILON); assetPendingWeightValues(weightUpdate, "f2", 0, -26, 0, 0); }
public double calcWeightUpdate(String featureName, Domain domain, double requestedUpdate) { double unconditionalUpdate = requestedUpdate * unconditionalWeightUpdateFraction; addUpdateToAggregationMap(featureToSumOfAbsUnconditionalUpdatesSoFar, featureName, unconditionalUpdate); SafeMap<Domain, Double> domainToPendingUpdate = featureToDomainToPendingUpdate.safeGet(featureName); if (domainToPendingUpdate == null) { domainToPendingUpdate = new SafeHashMap<>(); featureToDomainToPendingUpdate.put(featureName, domainToPendingUpdate); } Double previousPendingUpdate = domainToPendingUpdate.safeGet(domain); if (previousPendingUpdate == null) previousPendingUpdate = 0.0; double newPendingUpdate = previousPendingUpdate + requestedUpdate; domainToPendingUpdate.put(domain, newPendingUpdate); double result = unconditionalUpdate; if (Math.signum(requestedUpdate) == Math.signum(newPendingUpdate) && domainToPendingUpdate.size() >= domainsNumberRequired) { ArrayList<Double> pendingUpdatesOfAllDomains = domainToPendingUpdate.values().stream() .sorted() .collect(Collectors.toCollection(ArrayList::new)); int indexOfUpdateToApply = requestedUpdate > 0 ? pendingUpdatesOfAllDomains.size() - domainsNumberRequired : domainsNumberRequired - 1; double pendingUpdateToApply = pendingUpdatesOfAllDomains.get(indexOfUpdateToApply); if (Math.signum(requestedUpdate) == Math.signum(pendingUpdateToApply) && Math.abs(pendingUpdateToApply) > Math.abs(unconditionalUpdate)) { result = pendingUpdateToApply; } } domainToPendingUpdate.put(domain, newPendingUpdate - result); double signOfResult = Math.signum(result); double finalResult = result; domainToPendingUpdate.entrySet().stream() .filter(entry->!entry.getKey().equals(domain)) .filter(entry->Math.signum(entry.getValue()) == signOfResult) .forEach(entry->entry.setValue(reduceOrClipToZero(entry.getValue(), finalResult))); List<Domain> domainsToRemove = domainToPendingUpdate.entrySet().stream() .filter(entry->Math.abs(entry.getValue()) < MIN_PENDING_UPDATE_ABS_VALUE_TO_KEEP) .map(Map.Entry::getKey) .collect(Collectors.toList()); for (Domain d : domainsToRemove) domainToPendingUpdate.safeRemove(d); if (domainToPendingUpdate.isEmpty()) featureToDomainToPendingUpdate.safeRemove(featureName); addUpdateToAggregationMap(featureToSumOfAbsUpdatesSoFar, featureName, result); return result; }
ConditionalWeightUpdater { public double calcWeightUpdate(String featureName, Domain domain, double requestedUpdate) { double unconditionalUpdate = requestedUpdate * unconditionalWeightUpdateFraction; addUpdateToAggregationMap(featureToSumOfAbsUnconditionalUpdatesSoFar, featureName, unconditionalUpdate); SafeMap<Domain, Double> domainToPendingUpdate = featureToDomainToPendingUpdate.safeGet(featureName); if (domainToPendingUpdate == null) { domainToPendingUpdate = new SafeHashMap<>(); featureToDomainToPendingUpdate.put(featureName, domainToPendingUpdate); } Double previousPendingUpdate = domainToPendingUpdate.safeGet(domain); if (previousPendingUpdate == null) previousPendingUpdate = 0.0; double newPendingUpdate = previousPendingUpdate + requestedUpdate; domainToPendingUpdate.put(domain, newPendingUpdate); double result = unconditionalUpdate; if (Math.signum(requestedUpdate) == Math.signum(newPendingUpdate) && domainToPendingUpdate.size() >= domainsNumberRequired) { ArrayList<Double> pendingUpdatesOfAllDomains = domainToPendingUpdate.values().stream() .sorted() .collect(Collectors.toCollection(ArrayList::new)); int indexOfUpdateToApply = requestedUpdate > 0 ? pendingUpdatesOfAllDomains.size() - domainsNumberRequired : domainsNumberRequired - 1; double pendingUpdateToApply = pendingUpdatesOfAllDomains.get(indexOfUpdateToApply); if (Math.signum(requestedUpdate) == Math.signum(pendingUpdateToApply) && Math.abs(pendingUpdateToApply) > Math.abs(unconditionalUpdate)) { result = pendingUpdateToApply; } } domainToPendingUpdate.put(domain, newPendingUpdate - result); double signOfResult = Math.signum(result); double finalResult = result; domainToPendingUpdate.entrySet().stream() .filter(entry->!entry.getKey().equals(domain)) .filter(entry->Math.signum(entry.getValue()) == signOfResult) .forEach(entry->entry.setValue(reduceOrClipToZero(entry.getValue(), finalResult))); List<Domain> domainsToRemove = domainToPendingUpdate.entrySet().stream() .filter(entry->Math.abs(entry.getValue()) < MIN_PENDING_UPDATE_ABS_VALUE_TO_KEEP) .map(Map.Entry::getKey) .collect(Collectors.toList()); for (Domain d : domainsToRemove) domainToPendingUpdate.safeRemove(d); if (domainToPendingUpdate.isEmpty()) featureToDomainToPendingUpdate.safeRemove(featureName); addUpdateToAggregationMap(featureToSumOfAbsUpdatesSoFar, featureName, result); return result; } }
ConditionalWeightUpdater { public double calcWeightUpdate(String featureName, Domain domain, double requestedUpdate) { double unconditionalUpdate = requestedUpdate * unconditionalWeightUpdateFraction; addUpdateToAggregationMap(featureToSumOfAbsUnconditionalUpdatesSoFar, featureName, unconditionalUpdate); SafeMap<Domain, Double> domainToPendingUpdate = featureToDomainToPendingUpdate.safeGet(featureName); if (domainToPendingUpdate == null) { domainToPendingUpdate = new SafeHashMap<>(); featureToDomainToPendingUpdate.put(featureName, domainToPendingUpdate); } Double previousPendingUpdate = domainToPendingUpdate.safeGet(domain); if (previousPendingUpdate == null) previousPendingUpdate = 0.0; double newPendingUpdate = previousPendingUpdate + requestedUpdate; domainToPendingUpdate.put(domain, newPendingUpdate); double result = unconditionalUpdate; if (Math.signum(requestedUpdate) == Math.signum(newPendingUpdate) && domainToPendingUpdate.size() >= domainsNumberRequired) { ArrayList<Double> pendingUpdatesOfAllDomains = domainToPendingUpdate.values().stream() .sorted() .collect(Collectors.toCollection(ArrayList::new)); int indexOfUpdateToApply = requestedUpdate > 0 ? pendingUpdatesOfAllDomains.size() - domainsNumberRequired : domainsNumberRequired - 1; double pendingUpdateToApply = pendingUpdatesOfAllDomains.get(indexOfUpdateToApply); if (Math.signum(requestedUpdate) == Math.signum(pendingUpdateToApply) && Math.abs(pendingUpdateToApply) > Math.abs(unconditionalUpdate)) { result = pendingUpdateToApply; } } domainToPendingUpdate.put(domain, newPendingUpdate - result); double signOfResult = Math.signum(result); double finalResult = result; domainToPendingUpdate.entrySet().stream() .filter(entry->!entry.getKey().equals(domain)) .filter(entry->Math.signum(entry.getValue()) == signOfResult) .forEach(entry->entry.setValue(reduceOrClipToZero(entry.getValue(), finalResult))); List<Domain> domainsToRemove = domainToPendingUpdate.entrySet().stream() .filter(entry->Math.abs(entry.getValue()) < MIN_PENDING_UPDATE_ABS_VALUE_TO_KEEP) .map(Map.Entry::getKey) .collect(Collectors.toList()); for (Domain d : domainsToRemove) domainToPendingUpdate.safeRemove(d); if (domainToPendingUpdate.isEmpty()) featureToDomainToPendingUpdate.safeRemove(featureName); addUpdateToAggregationMap(featureToSumOfAbsUpdatesSoFar, featureName, result); return result; } ConditionalWeightUpdater(double unconditionalWeightUpdateFraction, int domainsNumberRequired,
                                    boolean collectAggregatedAnalysisData); }
ConditionalWeightUpdater { public double calcWeightUpdate(String featureName, Domain domain, double requestedUpdate) { double unconditionalUpdate = requestedUpdate * unconditionalWeightUpdateFraction; addUpdateToAggregationMap(featureToSumOfAbsUnconditionalUpdatesSoFar, featureName, unconditionalUpdate); SafeMap<Domain, Double> domainToPendingUpdate = featureToDomainToPendingUpdate.safeGet(featureName); if (domainToPendingUpdate == null) { domainToPendingUpdate = new SafeHashMap<>(); featureToDomainToPendingUpdate.put(featureName, domainToPendingUpdate); } Double previousPendingUpdate = domainToPendingUpdate.safeGet(domain); if (previousPendingUpdate == null) previousPendingUpdate = 0.0; double newPendingUpdate = previousPendingUpdate + requestedUpdate; domainToPendingUpdate.put(domain, newPendingUpdate); double result = unconditionalUpdate; if (Math.signum(requestedUpdate) == Math.signum(newPendingUpdate) && domainToPendingUpdate.size() >= domainsNumberRequired) { ArrayList<Double> pendingUpdatesOfAllDomains = domainToPendingUpdate.values().stream() .sorted() .collect(Collectors.toCollection(ArrayList::new)); int indexOfUpdateToApply = requestedUpdate > 0 ? pendingUpdatesOfAllDomains.size() - domainsNumberRequired : domainsNumberRequired - 1; double pendingUpdateToApply = pendingUpdatesOfAllDomains.get(indexOfUpdateToApply); if (Math.signum(requestedUpdate) == Math.signum(pendingUpdateToApply) && Math.abs(pendingUpdateToApply) > Math.abs(unconditionalUpdate)) { result = pendingUpdateToApply; } } domainToPendingUpdate.put(domain, newPendingUpdate - result); double signOfResult = Math.signum(result); double finalResult = result; domainToPendingUpdate.entrySet().stream() .filter(entry->!entry.getKey().equals(domain)) .filter(entry->Math.signum(entry.getValue()) == signOfResult) .forEach(entry->entry.setValue(reduceOrClipToZero(entry.getValue(), finalResult))); List<Domain> domainsToRemove = domainToPendingUpdate.entrySet().stream() .filter(entry->Math.abs(entry.getValue()) < MIN_PENDING_UPDATE_ABS_VALUE_TO_KEEP) .map(Map.Entry::getKey) .collect(Collectors.toList()); for (Domain d : domainsToRemove) domainToPendingUpdate.safeRemove(d); if (domainToPendingUpdate.isEmpty()) featureToDomainToPendingUpdate.safeRemove(featureName); addUpdateToAggregationMap(featureToSumOfAbsUpdatesSoFar, featureName, result); return result; } ConditionalWeightUpdater(double unconditionalWeightUpdateFraction, int domainsNumberRequired,
                                    boolean collectAggregatedAnalysisData); double calcWeightUpdate(String featureName, Domain domain, double requestedUpdate); String getAggregatedAnalysisDataString(); @Override String toString(); }
ConditionalWeightUpdater { public double calcWeightUpdate(String featureName, Domain domain, double requestedUpdate) { double unconditionalUpdate = requestedUpdate * unconditionalWeightUpdateFraction; addUpdateToAggregationMap(featureToSumOfAbsUnconditionalUpdatesSoFar, featureName, unconditionalUpdate); SafeMap<Domain, Double> domainToPendingUpdate = featureToDomainToPendingUpdate.safeGet(featureName); if (domainToPendingUpdate == null) { domainToPendingUpdate = new SafeHashMap<>(); featureToDomainToPendingUpdate.put(featureName, domainToPendingUpdate); } Double previousPendingUpdate = domainToPendingUpdate.safeGet(domain); if (previousPendingUpdate == null) previousPendingUpdate = 0.0; double newPendingUpdate = previousPendingUpdate + requestedUpdate; domainToPendingUpdate.put(domain, newPendingUpdate); double result = unconditionalUpdate; if (Math.signum(requestedUpdate) == Math.signum(newPendingUpdate) && domainToPendingUpdate.size() >= domainsNumberRequired) { ArrayList<Double> pendingUpdatesOfAllDomains = domainToPendingUpdate.values().stream() .sorted() .collect(Collectors.toCollection(ArrayList::new)); int indexOfUpdateToApply = requestedUpdate > 0 ? pendingUpdatesOfAllDomains.size() - domainsNumberRequired : domainsNumberRequired - 1; double pendingUpdateToApply = pendingUpdatesOfAllDomains.get(indexOfUpdateToApply); if (Math.signum(requestedUpdate) == Math.signum(pendingUpdateToApply) && Math.abs(pendingUpdateToApply) > Math.abs(unconditionalUpdate)) { result = pendingUpdateToApply; } } domainToPendingUpdate.put(domain, newPendingUpdate - result); double signOfResult = Math.signum(result); double finalResult = result; domainToPendingUpdate.entrySet().stream() .filter(entry->!entry.getKey().equals(domain)) .filter(entry->Math.signum(entry.getValue()) == signOfResult) .forEach(entry->entry.setValue(reduceOrClipToZero(entry.getValue(), finalResult))); List<Domain> domainsToRemove = domainToPendingUpdate.entrySet().stream() .filter(entry->Math.abs(entry.getValue()) < MIN_PENDING_UPDATE_ABS_VALUE_TO_KEEP) .map(Map.Entry::getKey) .collect(Collectors.toList()); for (Domain d : domainsToRemove) domainToPendingUpdate.safeRemove(d); if (domainToPendingUpdate.isEmpty()) featureToDomainToPendingUpdate.safeRemove(featureName); addUpdateToAggregationMap(featureToSumOfAbsUpdatesSoFar, featureName, result); return result; } ConditionalWeightUpdater(double unconditionalWeightUpdateFraction, int domainsNumberRequired,
                                    boolean collectAggregatedAnalysisData); double calcWeightUpdate(String featureName, Domain domain, double requestedUpdate); String getAggregatedAnalysisDataString(); @Override String toString();  }