diff --git a/POSEIDON/src/main/java/uk/ac/ox/oxfish/fisher/purseseiner/fads/PerSpeciesCarryingCapacity.java b/POSEIDON/src/main/java/uk/ac/ox/oxfish/fisher/purseseiner/fads/PerSpeciesCarryingCapacity.java index ce987ec34..7292eb23f 100644 --- a/POSEIDON/src/main/java/uk/ac/ox/oxfish/fisher/purseseiner/fads/PerSpeciesCarryingCapacity.java +++ b/POSEIDON/src/main/java/uk/ac/ox/oxfish/fisher/purseseiner/fads/PerSpeciesCarryingCapacity.java @@ -12,6 +12,7 @@ public PerSpeciesCarryingCapacity(final double[] carryingCapacities) { this.carryingCapacities = carryingCapacities.clone(); } + @SuppressWarnings("unused") public PerSpeciesCarryingCapacity(final Map carryingCapacities) { this.carryingCapacities = makeArray(carryingCapacities); } diff --git a/POSEIDON/src/main/java/uk/ac/ox/oxfish/fisher/purseseiner/fads/PerSpeciesCarryingCapacityInitializer.java b/POSEIDON/src/main/java/uk/ac/ox/oxfish/fisher/purseseiner/fads/PerSpeciesCarryingCapacityInitializer.java index 6478e9369..5fd662789 100644 --- a/POSEIDON/src/main/java/uk/ac/ox/oxfish/fisher/purseseiner/fads/PerSpeciesCarryingCapacityInitializer.java +++ b/POSEIDON/src/main/java/uk/ac/ox/oxfish/fisher/purseseiner/fads/PerSpeciesCarryingCapacityInitializer.java @@ -5,9 +5,8 @@ import uk.ac.ox.oxfish.utility.parameters.DoubleParameter; import java.util.Map; -import java.util.stream.Stream; -import static com.google.common.collect.ImmutableMap.toImmutableMap; +import static java.util.Arrays.stream; public class PerSpeciesCarryingCapacityInitializer implements CarryingCapacityInitializer { @@ -20,24 +19,26 @@ public PerSpeciesCarryingCapacityInitializer( this.carryingCapacities = carryingCapacities; } - @SuppressWarnings("OptionalGetWithoutIsPresent") @Override public PerSpeciesCarryingCapacity apply(final MersenneTwisterFast rng) { - // generate maps of carrying capacities per species until we find one where there + // Generate arrays of carrying capacities per species until we find one where there // is at least one species for which the carrying capacity is greater than zero - // and use that map to construct the `PerSpeciesCarryingCapacity` object - return Stream.>generate(() -> - carryingCapacities - .entrySet() - .stream() - .collect(toImmutableMap( - Map.Entry::getKey, - entry -> entry.getValue().applyAsDouble(rng) - )) - ) - .filter(carryingCapacityMap -> carryingCapacityMap.values().stream().anyMatch(cc -> cc > 0)) - .map(PerSpeciesCarryingCapacity::new) - .findFirst() - .get(); + // and use that array to construct the `PerSpeciesCarryingCapacity` object. + // Done with an array for performance reasons. + // Assumes that `carryingCapacities` covers all species. + // We currently have to limit the number of attempts because some combinations + // of Weibull shape/scale parameters with their scaling factors only generate zeros + // and we get stuck in an infinite loop otherwise. + // TODO: need to find a more elegant solution for this + final int MAX_ATTEMPTS = 10; + int attempts = 0; + final double[] capacities = new double[carryingCapacities.size()]; + do { + attempts += 1; + carryingCapacities.forEach((species, doubleParameter) -> + capacities[species.getIndex()] = doubleParameter.applyAsDouble(rng) + ); + } while (attempts < MAX_ATTEMPTS && stream(capacities).allMatch(v -> v == 0)); + return new PerSpeciesCarryingCapacity(capacities); } }