From 564259f4c223833e67f97d41a1a74036f18eed57 Mon Sep 17 00:00:00 2001 From: xuyuan Date: Tue, 7 May 2024 11:32:49 +1200 Subject: [PATCH] change gompertz f0 version --- examples/coalescent/gompertzCoalescent.lphy | 21 +- .../populationmodel/GompertzPopulation.java | 161 ++++++------- .../GompertzPopulationFunction.java | 32 +-- .../GompertzPopulationTest.java | 219 +++++++++--------- 4 files changed, 209 insertions(+), 224 deletions(-) diff --git a/examples/coalescent/gompertzCoalescent.lphy b/examples/coalescent/gompertzCoalescent.lphy index 6aea85a4..b6ca5bb8 100644 --- a/examples/coalescent/gompertzCoalescent.lphy +++ b/examples/coalescent/gompertzCoalescent.lphy @@ -1,14 +1,17 @@ + data { - L = 500; + L = 200; } + model { - N0 ~ LogNormal(meanlog=3,sdlog=0.5); - b ~ LogNormal(meanlog=-0.9, sdlog=0.05); - NInfinity ~ LogNormal(meanlog=28, sdlog=0.5); - gompertzPopFunc = gompertz(N0=N0, b=b, NInfinity=NInfinity); + f0 ~ Beta(alpha=20, beta=7); - tree ~ CoalescentPopFunc(popFunc=gompertzPopFunc, n=16); - // rootAge = tree.rootAge(); - D ~ PhyloCTMC(tree=tree, L=L, Q=jukesCantor(), mu=1e-9); -} + b ~ LogNormal(meanlog=-0.3, sdlog=0.05); + NInfinity ~ LogNormal(meanlog=35, sdlog=0.5); + gompertzPopFunc = gompertz(f0=f0, b=b, NInfinity=NInfinity); + + tree ~ CoalescentPopFunc(popFunc=gompertzPopFunc, n=16); + rootAge = tree.rootAge(); + D ~ PhyloCTMC(tree=tree, L=L, Q=jukesCantor(), mu=1e-2); +} \ No newline at end of file diff --git a/lphy-base/src/main/java/lphy/base/evolution/coalescent/populationmodel/GompertzPopulation.java b/lphy-base/src/main/java/lphy/base/evolution/coalescent/populationmodel/GompertzPopulation.java index 5fb41150..481c89ab 100644 --- a/lphy-base/src/main/java/lphy/base/evolution/coalescent/populationmodel/GompertzPopulation.java +++ b/lphy-base/src/main/java/lphy/base/evolution/coalescent/populationmodel/GompertzPopulation.java @@ -22,10 +22,6 @@ public class GompertzPopulation implements PopulationFunction { public static final String T50ParamName = "t50"; public static final String F0ParamName = "f0"; - public static final String N0ParamName = "N0"; - - - private double N0; // Initial population size private double b; // Initial growth rate of tumor growth private double NInfinity; // Carrying capacity @@ -41,9 +37,9 @@ public static double computeT50(double NInfinity, double N0, double b) { } double ratio = NInfinity / N0; double proportion = 0.5; -// if (proportion <= 0 || proportion >= 1) { -// throw new IllegalArgumentException("Proportion must be between 0 and 1."); -// } + // if (proportion <= 0 || proportion >= 1) { + // throw new IllegalArgumentException("Proportion must be between 0 and 1."); + // } double t50 = Math.log(1 - Math.log(proportion) / Math.log(ratio)) / b; return t50; } @@ -89,38 +85,37 @@ private IterativeLegendreGaussIntegrator createIntegrator() { * @param b * @param NInfinity */ -// public GompertzPopulation(double t50, double b, double NInfinity) { //(this is for t50 ) -// this.b = b; -// this.t50 = t50; -// this.NInfinity = NInfinity; -// // Calculate N0 based on t50, b, and NInfinity -// // N(t50) = NInfinity / 2 -// // t50 is a time location given by the user, t50 < 0 means it is in the early exponential phase -// this.N0 = NInfinity * Math.pow(2, -Math.exp(-b * this.t50)); -// } - -// public GompertzPopulation(double f0, double b, double NInfinity) { //(this is for f0 ) -// this.f0 = f0; -// this.b = b; -// this.NInfinity = NInfinity; -// this.N0 = NInfinity * this .f0; -// } - - public GompertzPopulation(double N0, double b, double NInfinity) { - // this.f0 = f0; + // public GompertzPopulation(double t50, double b, double NInfinity) { //(this is for t50 ) + // this.b = b; + // this.t50 = t50; + // this.NInfinity = NInfinity; + // // Calculate N0 based on t50, b, and NInfinity + // // N(t50) = NInfinity / 2 + // // t50 is a time location given by the user, t50 < 0 means it is in the early exponential phase + // this.N0 = NInfinity * Math.pow(2, -Math.exp(-b * this.t50)); + // } + + public GompertzPopulation(double f0, double b, double NInfinity) { //(this is for f0 ) + this.f0 = f0; this.b = b; this.NInfinity = NInfinity; - this.N0 = N0; - //this.N0 = NInfinity * this.f0; + this.N0 = NInfinity * this .f0; } -// @Override //(this is for t50 ) -// public double getTheta(double t) { -// // the sign of b * t is such that t = 0 is present time and t > 0 is time in the past -// return N0 * Math.exp(Math.log(NInfinity / N0) * (1 - Math.exp(b * t))); -// } + /** + * Implement the Gompertz function to calculate theta at time t + * Assuming theta is proportional to population size for simplicity + * + * @param t time, where t > 0 is time in the past + * @return N0 * Math.exp(Math.log(NInfinity / N0) * (1 - Math.exp(b * t))) + */ + // @Override //(this is for t50 ) + // public double getTheta(double t) { + // // the sign of b * t is such that t = 0 is present time and t > 0 is time in the past + // return N0 * Math.exp(Math.log(NInfinity / N0) * (1 - Math.exp(b * t))); + // } @Override //(this is for f0 ) public double getTheta(double t) { @@ -137,13 +132,13 @@ public double getIntensity(double t) { UnivariateFunction function = time -> 1 / getTheta(time); // Use the separate method to create the integrator -// return legrandeIntegrator(function, t); + // return legrandeIntegrator(function, t); IterativeLegendreGaussIntegrator integrator = createIntegrator(); return integrator.integrate(Integer.MAX_VALUE, function, 0, t); } -// return rombergIntegrator(function, t); -//} + // return rombergIntegrator(function, t); + //} private double legrandeIntegrator(UnivariateFunction function, double t) { IterativeLegendreGaussIntegrator integrator = createIntegrator(); @@ -153,7 +148,7 @@ private double legrandeIntegrator(UnivariateFunction function, double t) { private double rombergIntegrator(UnivariateFunction function, double t) { int maxBound = Integer.MAX_VALUE; -// int maxBound = 100000; + // int maxBound = 100000; RombergIntegrator integrator = new RombergIntegrator(); double absoluteAccuracy = 1e-6; @@ -161,11 +156,11 @@ private double rombergIntegrator(UnivariateFunction function, double t) { absoluteAccuracy, RombergIntegrator.DEFAULT_MIN_ITERATIONS_COUNT, RombergIntegrator.ROMBERG_MAX_ITERATIONS_COUNT); -// try { -// System.out.println("Absolute accuracy = " + integrator.getAbsoluteAccuracy()); -// System.out.println("Relative accuracy = " + integrator.getRelativeAccuracy()); + // try { + // System.out.println("Absolute accuracy = " + integrator.getAbsoluteAccuracy()); + // System.out.println("Relative accuracy = " + integrator.getRelativeAccuracy()); return integrator.integrate(maxBound, function, 0, t); -// } + // } } @@ -173,48 +168,48 @@ private double rombergIntegrator(UnivariateFunction function, double t) { -// @Override -// public double getIntensity(double t) { -// -// if (t == 0) return 0; -// -// if (getTheta(t) < NInfinity/resolution_magic_number) { -// throw new RuntimeException("Theta too small to calculate intensity!"); -// } -// -// UnivariateFunction function = time -> 1.0 / getTheta(time); -// UnivariateIntegrator integrator = new TrapezoidIntegrator(); -// // The number 10000 here represents a very high number of iterations for accuracy. -// return integrator.integrate(100000, function, 0, t); -// } -// + // @Override + // public double getIntensity(double t) { + // + // if (t == 0) return 0; + // + // if (getTheta(t) < NInfinity/resolution_magic_number) { + // throw new RuntimeException("Theta too small to calculate intensity!"); + // } + // + // UnivariateFunction function = time -> 1.0 / getTheta(time); + // UnivariateIntegrator integrator = new TrapezoidIntegrator(); + // // The number 10000 here represents a very high number of iterations for accuracy. + // return integrator.integrate(100000, function, 0, t); + // } + // // passes unit test without magic number -// Error when running LPhy script that signs at interval endpoints are not different -// @Override -// public double getInverseIntensity(double x) { -//// -//// -//// UnivariateFunction thetaFunction = time -> getTheta(time) - NInfinity / resolution_magic_number; -//// UnivariateSolver thetaSolver = new BrentSolver(); -//// double startValue = thetaFunction.value(0); -//// double endValue = thetaFunction.value(1000); -//// -//// System.out.println("Function value at start of the interval (0): " + startValue); -//// System.out.println("Function value at end of the interval (1000): " + endValue); -//// double maxTime = thetaSolver.solve(100, thetaFunction, 1e-6, t50 * 10); -//// System.out.println("maxTime = " + maxTime); -//// -//// UnivariateFunction function = time -> getIntensity(time) - x; -//// UnivariateSolver solver = new BrentSolver(); -//// // The range [0, 100] might need to be adjusted depending on the growth model and expected time range. -////// return solver.solve(100, function, 0, 100); -//// return solver.solve(100, function, 0.001, maxTime); -//// -////} -// -// + // Error when running LPhy script that signs at interval endpoints are not different + // @Override + // public double getInverseIntensity(double x) { + //// + //// + //// UnivariateFunction thetaFunction = time -> getTheta(time) - NInfinity / resolution_magic_number; + //// UnivariateSolver thetaSolver = new BrentSolver(); + //// double startValue = thetaFunction.value(0); + //// double endValue = thetaFunction.value(1000); + //// + //// System.out.println("Function value at start of the interval (0): " + startValue); + //// System.out.println("Function value at end of the interval (1000): " + endValue); + //// double maxTime = thetaSolver.solve(100, thetaFunction, 1e-6, t50 * 10); + //// System.out.println("maxTime = " + maxTime); + //// + //// UnivariateFunction function = time -> getIntensity(time) - x; + //// UnivariateSolver solver = new BrentSolver(); + //// // The range [0, 100] might need to be adjusted depending on the growth model and expected time range. + ////// return solver.solve(100, function, 0, 100); + //// return solver.solve(100, function, 0.001, maxTime); + //// + ////} + // + // @@ -295,8 +290,4 @@ public static void main(String[] args) { -} - - - - +} \ No newline at end of file diff --git a/lphy-base/src/main/java/lphy/base/evolution/coalescent/populationmodel/GompertzPopulationFunction.java b/lphy-base/src/main/java/lphy/base/evolution/coalescent/populationmodel/GompertzPopulationFunction.java index df4e0450..9c0aee31 100644 --- a/lphy-base/src/main/java/lphy/base/evolution/coalescent/populationmodel/GompertzPopulationFunction.java +++ b/lphy-base/src/main/java/lphy/base/evolution/coalescent/populationmodel/GompertzPopulationFunction.java @@ -1,3 +1,4 @@ + package lphy.base.evolution.coalescent.populationmodel; import lphy.base.evolution.coalescent.PopulationFunction; @@ -11,20 +12,15 @@ public class GompertzPopulationFunction extends DeterministicFunction { public GompertzPopulationFunction(//@ParameterInfo(name = T50ParamName, description = "Time when population is half of carrying capacity.") Value t50, - @ParameterInfo(name = N0ParamName, description = "Time when population is half of carrying capacity.") Value N0, - // @ParameterInfo(name = F0ParamName, description = "Time when population is half of carrying capacity.") Value f0, - @ParameterInfo(name = BParamName, description = "Initial growth rate of tumor growth.") Value b, - @ParameterInfo(name = NINFINITYParamName, description = "Limiting population size (carrying capacity).") Value NInfinity) { + @ParameterInfo(name = F0ParamName, description = "Time when population is half of carrying capacity.") Value f0, + @ParameterInfo(name = BParamName, description = "Initial growth rate of tumor growth.") Value b, + @ParameterInfo(name = NINFINITYParamName, description = "Limiting population size (carrying capacity).") Value NInfinity) { //setParam(T50ParamName, t50); - // setParam(F0ParamName, f0); + setParam(F0ParamName, f0); setParam(BParamName, b); setParam(NINFINITYParamName, NInfinity); - - setParam(N0ParamName, N0); - } - @GeneratorInfo(name="gompertz", narrativeName = "Gompertz growth function", category = GeneratorCategory.COAL_TREE, examples = {" .lphy" }, description = "Models population growth using the Gompertz growth function.") @@ -33,27 +29,19 @@ public GompertzPopulationFunction(//@ParameterInfo(name = T50ParamName, descript public Value apply() { //double t50 = ((Number) getParams().get(T50ParamName).value()).doubleValue(); - //double f0 = ((Number) getParams().get(F0ParamName).value()).doubleValue(); + double f0 = ((Number) getParams().get(F0ParamName).value()).doubleValue(); double b = ((Number) getParams().get(BParamName).value()).doubleValue(); double NInfinity = ((Number) getParams().get(NINFINITYParamName).value()).doubleValue(); - double N0 = ((Number) getParams().get(N0ParamName).value()).doubleValue(); //PopulationFunction gompertzPopulation = new GompertzPopulation(t50, b, NInfinity); - //PopulationFunction gompertzPopulation = new GompertzPopulation(f0, b, NInfinity); - PopulationFunction gompertzPopulation = new GompertzPopulation(N0, b, NInfinity); + PopulationFunction gompertzPopulation = new GompertzPopulation(f0, b, NInfinity); - return new Value<>(gompertzPopulation, this); + return new Value<>( gompertzPopulation, this); } - - -// public Value getF0() { -// return getParams().get(F0ParamName); -// } - - public Value getN0() { - return getParams().get(N0ParamName); + public Value getF0() { + return getParams().get(F0ParamName); } public Value getB() { diff --git a/lphy-base/src/test/java/lphy/base/evolution/coalescent/populationmodel/GompertzPopulationTest.java b/lphy-base/src/test/java/lphy/base/evolution/coalescent/populationmodel/GompertzPopulationTest.java index c7ded34b..1541d4a1 100644 --- a/lphy-base/src/test/java/lphy/base/evolution/coalescent/populationmodel/GompertzPopulationTest.java +++ b/lphy-base/src/test/java/lphy/base/evolution/coalescent/populationmodel/GompertzPopulationTest.java @@ -1,162 +1,165 @@ + package lphy.base.evolution.coalescent.populationmodel; + import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertEquals; + class GompertzPopulationTest { private static final double DELTA = 1e-6; @Test - public void testGetThetaAtTimeZero() { - double N0 = 500; - double b = 0.1; - double NInfinity = 1000; - GompertzPopulation gompertzPopulation = new GompertzPopulation(N0, b, NInfinity); - - double expectedThetaAtZero = N0; - double resultThetaAtZero = gompertzPopulation.getTheta(0); - assertEquals(expectedThetaAtZero, resultThetaAtZero, DELTA, "Theta at time zero should be equal to N0."); + public void testGetPopSize() { + + // Set the parameters for the Gompertz growth model + double f0 = 0.5; // Example initial proportion + double b = 0.1; // Example growth rate + double NInfinity = 1000; // Example carrying capacity + + GompertzPopulation gompertzPopulation = new GompertzPopulation(f0, b, NInfinity); + + double expectedTheta = gompertzPopulation.getN0() * Math.exp(Math.log(NInfinity / gompertzPopulation.getN0()) * (1 - Math.exp(b * 10))); + double result = gompertzPopulation.getTheta(10); + assertEquals( expectedTheta, result, DELTA); } + @Test - public void testGetTheta() { - double N0 = 500; - double b = 0.1; - double NInfinity = 1000; - double t = 10; // Test at time t = 10 - GompertzPopulation gompertzPopulation = new GompertzPopulation(N0, b, NInfinity); - - double expectedTheta = N0 * Math.exp(Math.log(NInfinity / N0) * (1 - Math.exp(b * t))); - double resultTheta = gompertzPopulation.getTheta(t); - assertEquals(expectedTheta, resultTheta, DELTA, "Theta at time t should match the expected value."); + public void testGetIntensity() { + // Set the parameters for the Gompertz growth model + double f0 = 0.1058; // Example initial proportion + double b = 2.4982; // Example growth rate + double NInfinity = 6016.7644; // Example carrying capacity + GompertzPopulation gompertzPopulation = new GompertzPopulation(f0, b, NInfinity); + double t = 0.625; + + double expectedIntensity = 0.309539; // Calculate based on the Gompertz model's Wolfram alpha + + assertEquals(expectedIntensity, gompertzPopulation.getIntensity(t), DELTA, "Intensity calculation should be correct."); } + + + @Test - public void testIntensityCalculation() { - double N0 = 500; - double b = 0.1; - double NInfinity = 1000; - double t = 5; // Test at time t = 5 - GompertzPopulation gompertzPopulation = new GompertzPopulation(N0, b, NInfinity); - - double expectedIntensity = 0.012393784; - double resultIntensity = gompertzPopulation.getIntensity(t); - assertEquals(expectedIntensity, resultIntensity, DELTA, "Intensity calculation should match the expected value."); + public void testIntensityAndInverseIntensity() { + double f0 = 0.1058; // Example initial proportion + double b = 2.4982; // Example growth rate + double NInfinity = 6016.7644; // Example carrying capacity + GompertzPopulation gompertzPopulation = new GompertzPopulation(f0, b, NInfinity); + + double t = 0.625; + + // Calculate intensity at given time t + double intensity = gompertzPopulation.getIntensity(t); + + // Now calculate time for the given intensity, should approximately match t + double estimatedTime = gompertzPopulation.getInverseIntensity(0.309539); + + // Assert that the time calculated by getInverseIntensity is close to the original time t + assertEquals(t, estimatedTime, DELTA); + + // Optionally, verify the intensity value itself if you have an expected value + // Example expected value calculation (this would be your expected model output, based on your formula) + // double expectedIntensity = ...; // Depends on your intensity calculation model + // assertEquals("Intensity at time should match expected", expectedIntensity, intensity, DELTA); } + @Test public void testInverseIntensity() { - double N0 = 500; - double b = 0.1; - double NInfinity = 1000; - double t = 5; // Time for which we know the intensity - GompertzPopulation gompertzPopulation = new GompertzPopulation(N0, b, NInfinity); + double f0 = 0.1058; + double b = 2.4982; + double NInfinity = 6016.7644; + GompertzPopulation gompertz = new GompertzPopulation(f0, b, NInfinity); - // Calculate intensity at time t using getIntensity - double intensity = gompertzPopulation.getIntensity(t); + double targetIntensity = 0.309539; // The intensity for which we want to find the time + double expectedTime = 0.625; // The time at which the intensity should be targetIntensity - // Now calculate the time for the given intensity using getInverseIntensity - double calculatedTime = gompertzPopulation.getInverseIntensity(intensity); + double calculatedTime = gompertz.getInverseIntensity(targetIntensity); + double calculatedIntensityAtCalculatedTime = gompertz.getIntensity(calculatedTime); - // Assert that the time calculated by getInverseIntensity is close to the original time t - assertEquals(t, calculatedTime, DELTA, "Inverse intensity calculation should return the correct time."); + assertEquals(targetIntensity, calculatedIntensityAtCalculatedTime, DELTA); } } + + + + + //package lphy.base.evolution.coalescent.populationmodel; // +// import org.junit.jupiter.api.Test; // -//import org.junit.jupiter.api.Test; -// -//import static org.junit.jupiter.api.Assertions.assertEquals; -// +// import static org.junit.jupiter.api.Assertions.assertEquals; // //class GompertzPopulationTest { // // private static final double DELTA = 1e-6; -// + // @Test -// public void testGetPopSize() { -// -// // Set the parameters for the Gompertz growth model -// double f0 = 0.5; // Example initial proportion -// double b = 0.1; // Example growth rate -// double NInfinity = 1000; // Example carrying capacity -// -// GompertzPopulation gompertzPopulation = new GompertzPopulation(f0, b, NInfinity); -// -// double expectedTheta = gompertzPopulation.getN0() * Math.exp(Math.log(NInfinity / gompertzPopulation.getN0()) * (1 - Math.exp(b * 10))); -// double result = gompertzPopulation.getTheta(10); -// assertEquals( expectedTheta, result, DELTA); +// public void testGetThetaAtTimeZero() { +// double N0 = 500; +// double b = 0.1; +// double NInfinity = 1000; +// GompertzPopulation gompertzPopulation = new GompertzPopulation(N0, b, NInfinity); +// +// double expectedThetaAtZero = N0; +// double resultThetaAtZero = gompertzPopulation.getTheta(0); +// assertEquals(expectedThetaAtZero, resultThetaAtZero, DELTA, "Theta at time zero should be equal to N0."); // } // -// // @Test -// public void testGetIntensity() { -// // Set the parameters for the Gompertz growth model -// double f0 = 0.1058; // Example initial proportion -// double b = 2.4982; // Example growth rate -// double NInfinity = 6016.7644; // Example carrying capacity -// GompertzPopulation gompertzPopulation = new GompertzPopulation(f0, b, NInfinity); -// double t = 0.625; -// -// double expectedIntensity = 0.309539; // Calculate based on the Gompertz model's Wolfram alpha -// -// assertEquals(expectedIntensity, gompertzPopulation.getIntensity(t), DELTA, "Intensity calculation should be correct."); +// public void testGetTheta() { +// double N0 = 500; +// double b = 0.1; +// double NInfinity = 1000; +// double t = 10; // Test at time t = 10 +// GompertzPopulation gompertzPopulation = new GompertzPopulation(N0, b, NInfinity); +// +// double expectedTheta = N0 * Math.exp(Math.log(NInfinity / N0) * (1 - Math.exp(b * t))); +// double resultTheta = gompertzPopulation.getTheta(t); +// assertEquals(expectedTheta, resultTheta, DELTA, "Theta at time t should match the expected value."); // } // -// -// -// // @Test -// public void testIntensityAndInverseIntensity() { -// double f0 = 0.1058; // Example initial proportion -// double b = 2.4982; // Example growth rate -// double NInfinity = 6016.7644; // Example carrying capacity -// GompertzPopulation gompertzPopulation = new GompertzPopulation(f0, b, NInfinity); -// -// double t = 0.625; -// -// // Calculate intensity at given time t -// double intensity = gompertzPopulation.getIntensity(t); -// -// // Now calculate time for the given intensity, should approximately match t -// double estimatedTime = gompertzPopulation.getInverseIntensity(0.309539); -// -// // Assert that the time calculated by getInverseIntensity is close to the original time t -// assertEquals(t, estimatedTime, DELTA); -// -// // Optionally, verify the intensity value itself if you have an expected value -// // Example expected value calculation (this would be your expected model output, based on your formula) -// // double expectedIntensity = ...; // Depends on your intensity calculation model -// // assertEquals("Intensity at time should match expected", expectedIntensity, intensity, DELTA); +// public void testIntensityCalculation() { +// double N0 = 500; +// double b = 0.1; +// double NInfinity = 1000; +// double t = 5; // Test at time t = 5 +// GompertzPopulation gompertzPopulation = new GompertzPopulation(N0, b, NInfinity); +// +// double expectedIntensity = 0.012393784; +// double resultIntensity = gompertzPopulation.getIntensity(t); +// assertEquals(expectedIntensity, resultIntensity, DELTA, "Intensity calculation should match the expected value."); // } // -// // @Test // public void testInverseIntensity() { -// double f0 = 0.1058; -// double b = 2.4982; -// double NInfinity = 6016.7644; -// GompertzPopulation gompertz = new GompertzPopulation(f0, b, NInfinity); +// double N0 = 500; +// double b = 0.1; +// double NInfinity = 1000; +// double t = 5; // Time for which we know the intensity +// GompertzPopulation gompertzPopulation = new GompertzPopulation(N0, b, NInfinity); // -// double targetIntensity = 0.309539; // The intensity for which we want to find the time -// double expectedTime = 0.625; // The time at which the intensity should be targetIntensity +// // Calculate intensity at time t using getIntensity +// double intensity = gompertzPopulation.getIntensity(t); // -// double calculatedTime = gompertz.getInverseIntensity(targetIntensity); -// double calculatedIntensityAtCalculatedTime = gompertz.getIntensity(calculatedTime); +// // Now calculate the time for the given intensity using getInverseIntensity +// double calculatedTime = gompertzPopulation.getInverseIntensity(intensity); // -// assertEquals(targetIntensity, calculatedIntensityAtCalculatedTime, DELTA); +// // Assert that the time calculated by getInverseIntensity is close to the original time t +// assertEquals(t, calculatedTime, DELTA, "Inverse intensity calculation should return the correct time."); // } // //} -// -// -// -// -// + +