com.farao_community.farao.dichotomy.api.index.BiDirectionalStepsWithReferenceIndexStrategy Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of farao-dichotomy-api Show documentation
Show all versions of farao-dichotomy-api Show documentation
API that enables launching dichotomy on an IIDM network
The newest version!
/*
* Copyright (c) 2022, RTE (http://www.rte-france.com)
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package com.farao_community.farao.dichotomy.api.index;
import com.farao_community.farao.dichotomy.api.results.DichotomyStepResult;
import com.farao_community.farao.dichotomy.api.results.ReasonInvalid;
import org.apache.commons.lang3.tuple.Pair;
import java.util.function.BiPredicate;
/**
* @author Joris Mancini {@literal }
*/
public class BiDirectionalStepsWithReferenceIndexStrategy implements IndexStrategy {
private final double startIndex;
private final double stepSize;
private final double referenceExchange;
private Pair> highestSecureStep;
private Pair> lowestUnsecureStep;
private Pair> closestGlskLimitationBelowReference;
private Pair> closestGlskLimitationAboveReference;
private Pair> highestAdmissibleStep;
private Pair> lowestInadmissibleStep;
public BiDirectionalStepsWithReferenceIndexStrategy(double startIndex, double stepSize, double referenceExchange) {
this.startIndex = startIndex;
this.stepSize = stepSize;
this.referenceExchange = referenceExchange;
}
@Override
public double nextValue(Index> index) {
updateDichotomyIntervalLimits(index);
if (highestAdmissibleStep == null && lowestInadmissibleStep == null) {
return startIndex;
} else if (highestAdmissibleStep == null) {
return Math.max(index.minValue(), lowestInadmissibleStep.getLeft() - stepSize);
} else if (lowestInadmissibleStep == null) {
return Math.min(index.maxValue(), highestAdmissibleStep.getLeft() + stepSize);
} else {
return (lowestInadmissibleStep.getLeft() + highestAdmissibleStep.getLeft()) / 2;
}
}
@Override
public boolean precisionReached(Index> index) {
updateDichotomyIntervalLimits(index);
if (highestAdmissibleStep == null && lowestInadmissibleStep == null) {
return false;
} else if (highestAdmissibleStep == null) {
return Math.abs(lowestInadmissibleStep.getLeft() - index.minValue()) < EPSILON;
} else if (lowestInadmissibleStep == null) {
return Math.abs(highestAdmissibleStep.getLeft() - index.maxValue()) < EPSILON;
} else {
return Math.abs(highestAdmissibleStep.getLeft() - lowestInadmissibleStep.getLeft()) < index.precision();
}
}
private void updateDichotomyIntervalLimits(Index> index) {
if (index.lowestInvalidStep() != null &&
(index.lowestInvalidStep().getRight().getReasonInvalid().equals(ReasonInvalid.UNSECURE_AFTER_VALIDATION)
|| index.lowestInvalidStep().getRight().getReasonInvalid().equals(ReasonInvalid.VALIDATION_FAILED))) {
lowestUnsecureStep = index.lowestInvalidStep();
}
if (index.highestValidStep() != null) {
highestSecureStep = index.highestValidStep();
}
if (index.lowestInvalidStep() != null && index.lowestInvalidStep().getRight().getReasonInvalid().equals(ReasonInvalid.GLSK_LIMITATION)) {
if (index.lowestInvalidStep().getLeft() < referenceExchange) {
closestGlskLimitationBelowReference = index.lowestInvalidStep();
} else {
closestGlskLimitationAboveReference = index.lowestInvalidStep();
}
}
highestAdmissibleStep = getHighestAdmissibleStep(closestGlskLimitationBelowReference, highestSecureStep);
lowestInadmissibleStep = getLowestInAdmissibleStep(lowestUnsecureStep, closestGlskLimitationAboveReference);
}
private Pair> getHighestAdmissibleStep(Pair> closestGlskLimitationBelowReference, Pair> highestSecureStep) {
return testAndGetStep(closestGlskLimitationBelowReference, highestSecureStep, (t, u) -> t > u);
}
private Pair> getLowestInAdmissibleStep(Pair> lowestUnsecureStep, Pair> closestGlskLimitationAboveReference) {
return testAndGetStep(lowestUnsecureStep, closestGlskLimitationAboveReference, (t, u) -> t < u);
}
private Pair> testAndGetStep(Pair> step1, Pair> step2, BiPredicate biPredicate) {
if (step1 == null && step2 == null) {
return null;
} else if (step1 == null) {
return step2;
} else if (step2 == null) {
return step1;
} else { // step1 && step2 are != null
if (biPredicate.test(step1.getLeft(), step2.getLeft())) {
return step1;
} else {
return step2;
}
}
}
}