Skip to content

Commit

Permalink
add new Calibrator class that allows starting from seed scenarios
Browse files Browse the repository at this point in the history
  • Loading branch information
nicolaspayette committed Apr 2, 2024
1 parent 65b5a9e commit 01dad80
Show file tree
Hide file tree
Showing 3 changed files with 474 additions and 59 deletions.
Original file line number Diff line number Diff line change
@@ -1,21 +1,17 @@
/*
* POSEIDON, an agent-based model of fisheries
* Copyright (C) 2018 CoHESyS Lab [email protected]
* POSEIDON, an agent-based model of fisheries
* Copyright (c) 2018-2024 CoHESyS Lab [email protected]
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* This program is free software: you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation, either version 3
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program.
* If not, see <http://www.gnu.org/licenses/>.
*/

package uk.ac.ox.oxfish.maximization.generic;
Expand All @@ -33,11 +29,9 @@
*/
public class SimpleOptimizationParameter implements OptimizationParameter, Serializable {


private static final long serialVersionUID = 1148689356037897712L;
private String addressToModify = "literPerKilometer";


/**
* assuming x comes in ranges of -10 to 10 (EVA dumb default), this represents -10
*/
Expand All @@ -48,20 +42,22 @@ public class SimpleOptimizationParameter implements OptimizationParameter, Seria
*/
private double maximum = 5;


private boolean alwaysPositive = false;

/**
* when this is set to true, it means the argument could never be a DoubleParameter. This usually doesn't matter
* but unfortunately it seems that YAML struggles with map<String,Number> and turn them into string,string maps
* when this is set to true, it means the argument could never be a DoubleParameter. This usually doesn't matter but
* unfortunately it seems that YAML struggles with map<String,Number> and turn them into string,string maps
*/
private boolean isRawNumber = false;


public SimpleOptimizationParameter() {
}

public SimpleOptimizationParameter(final String addressToModify, final double minimum, final double maximum) {
public SimpleOptimizationParameter(
final String addressToModify,
final double minimum,
final double maximum
) {
this.addressToModify = addressToModify;
this.minimum = minimum;
this.maximum = maximum;
Expand Down Expand Up @@ -99,14 +95,16 @@ public int size() {
* @return
*/
@Override
public String parametrize(final Scenario scenario, final double[] inputs) {
public String parametrize(
final Scenario scenario,
final double[] inputs
) {

Preconditions.checkArgument(maximum >= minimum, "invalid bounds " + addressToModify);
Preconditions.checkArgument(inputs.length == 1);

final double realValue = computeNumericValue(inputs[0]);


if (!isRawNumber)
quickParametrize(scenario, realValue, addressToModify);
else
Expand All @@ -120,15 +118,19 @@ public double computeNumericValue(final double input) {
return computeNumericValueFromEVABounds(input, minimum, maximum, alwaysPositive);
}

public static void quickParametrize(final Scenario scenario, final double realValue, final String addressToModify) {
public static void quickParametrize(
final Scenario scenario,
final double realValue,
final String addressToModify
) {
try {
//try as double parameter
// try as double parameter
OptimizationParameter.navigateAndSet(
scenario, addressToModify, new FixedDoubleParameter(realValue)

);
} catch (final Exception e) {
//try as raw number
// try as raw number
try {
OptimizationParameter.navigateAndSet(
scenario, addressToModify, realValue
Expand All @@ -145,7 +147,7 @@ public static void quickParametrizeRawNumber(
final double realValue,
final String addressToModify
) {
//try as raw number
// try as raw number
try {
OptimizationParameter.navigateAndSet(
scenario, addressToModify, realValue
Expand All @@ -157,7 +159,9 @@ public static void quickParametrizeRawNumber(
}

public static double computeNumericValueFromEVABounds(
final double input, final double minimum, final double maximum,
final double input,
final double minimum,
final double maximum,
final boolean forcePositive
) {
double realValue = minimum + ((maximum - minimum) / (10 - (-10))) * (input - (-10));
Expand All @@ -166,7 +170,14 @@ public static double computeNumericValueFromEVABounds(
return realValue;
}

public double parametrizeRealValue(final Scenario scenario, final double realValue) {
public double computeMappedValue(final double realValue) {
return -10 + ((realValue - minimum) / (maximum - minimum)) * 20;
}

public double parametrizeRealValue(
final Scenario scenario,
final double realValue
) {
quickParametrize(scenario, realValue, addressToModify);
return realValue;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,26 +1,22 @@
/*
* POSEIDON, an agent-based model of fisheries
* Copyright (C) 2018 CoHESyS Lab [email protected]
* POSEIDON, an agent-based model of fisheries
* Copyright (c) 2018-2024 CoHESyS Lab [email protected]
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* This program is free software: you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation, either version 3
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with this program.
* If not, see <http://www.gnu.org/licenses/>.
*/

package uk.ac.ox.oxfish.maximization.generic;

import org.junit.jupiter.api.Assertions;
import ec.util.MersenneTwisterFast;
import org.junit.jupiter.api.Test;
import uk.ac.ox.oxfish.biology.growers.CommonLogisticGrowerFactory;
import uk.ac.ox.oxfish.biology.initializer.factory.FromLeftToRightFactory;
Expand All @@ -30,9 +26,11 @@
import uk.ac.ox.poseidon.common.core.parameters.FixedDoubleParameter;

import java.lang.reflect.InvocationTargetException;
import java.util.stream.DoubleStream;

public class SimpleOptimizationParameterTest {
import static org.junit.jupiter.api.Assertions.assertEquals;

public class SimpleOptimizationParameterTest {

@Test
public void twoStepsWork() throws IllegalAccessException, NoSuchMethodException, InvocationTargetException {
Expand All @@ -42,8 +40,7 @@ public void twoStepsWork() throws IllegalAccessException, NoSuchMethodException,
biologyInitializer.setExponent(new FixedDoubleParameter(100));
scenario.setBiologyInitializer(biologyInitializer);


Assertions.assertEquals(((FixedDoubleParameter) biologyInitializer.getExponent()).getValue(), 100, .0001);
assertEquals(((FixedDoubleParameter) biologyInitializer.getExponent()).getValue(), 100, .0001);

final SimpleOptimizationParameter parameter = new SimpleOptimizationParameter(
"biologyInitializer.exponent",
Expand All @@ -55,17 +52,15 @@ public void twoStepsWork() throws IllegalAccessException, NoSuchMethodException,
new double[]{10}
);


Assertions.assertEquals(((FixedDoubleParameter) biologyInitializer.getExponent()).getValue(), 200, .0001);
assertEquals(((FixedDoubleParameter) biologyInitializer.getExponent()).getValue(), 200, .0001);
}

@Test
public void oneStepWork() throws IllegalAccessException, NoSuchMethodException, InvocationTargetException {
final PrototypeScenario scenario = new PrototypeScenario();
scenario.setSpeedInKmh(new FixedDoubleParameter(150));


Assertions.assertEquals(((FixedDoubleParameter) scenario.getSpeedInKmh()).getValue(), 150, .0001);
assertEquals(((FixedDoubleParameter) scenario.getSpeedInKmh()).getValue(), 150, .0001);

final SimpleOptimizationParameter parameter = new SimpleOptimizationParameter(
"speedInKmh",
Expand All @@ -77,7 +72,7 @@ public void oneStepWork() throws IllegalAccessException, NoSuchMethodException,
new double[]{0}
);

Assertions.assertEquals(((FixedDoubleParameter) scenario.getSpeedInKmh()).getValue(), 10, .0001);
assertEquals(((FixedDoubleParameter) scenario.getSpeedInKmh()).getValue(), 10, .0001);
}

@Test
Expand All @@ -94,19 +89,17 @@ public void indexedWorks() throws IllegalAccessException, NoSuchMethodException,
first.setGrower(new CommonLogisticGrowerFactory(.567));
second.setGrower(new CommonLogisticGrowerFactory(.567));


Assertions.assertEquals(
assertEquals(
((FixedDoubleParameter) ((CommonLogisticGrowerFactory) first.getGrower()).getSteepness()).getValue(),
.567,
.0001
);
Assertions.assertEquals(
assertEquals(
((FixedDoubleParameter) ((CommonLogisticGrowerFactory) second.getGrower()).getSteepness()).getValue(),
.567,
.0001
);


final SimpleOptimizationParameter parameter = new SimpleOptimizationParameter(
"biologyInitializer.factories$1.grower.steepness",
10, 20
Expand All @@ -123,18 +116,42 @@ public void indexedWorks() throws IllegalAccessException, NoSuchMethodException,
new FixedDoubleParameter(10)
);


Assertions.assertEquals(
assertEquals(
((FixedDoubleParameter) ((CommonLogisticGrowerFactory) first.getGrower()).getSteepness()).getValue(),
.567,
.0001
);
Assertions.assertEquals(
assertEquals(
((FixedDoubleParameter) ((CommonLogisticGrowerFactory) second.getGrower()).getSteepness()).getValue(),
10,
.0001
);
}

@Test
void computeMappedValue() {
final SimpleOptimizationParameter parameter =
new SimpleOptimizationParameter(null, -100, 100);
assertEquals(-20, parameter.computeMappedValue(-200));
assertEquals(-10, parameter.computeMappedValue(-100));
assertEquals(0, parameter.computeMappedValue(0));
assertEquals(10, parameter.computeMappedValue(100));
assertEquals(20, parameter.computeMappedValue(200));
}

@Test
void computeRandomMappedValues() {
final MersenneTwisterFast rng = new MersenneTwisterFast();
final double min = rng.nextGaussian();
final SimpleOptimizationParameter parameter =
new SimpleOptimizationParameter(null, min, min + rng.nextDouble());
DoubleStream
.generate(rng::nextGaussian)
.limit(100)
.forEach(v -> assertEquals(
v,
parameter.computeNumericValue(parameter.computeMappedValue(v)),
1E-10
));
}
}
Loading

0 comments on commit 01dad80

Please sign in to comment.